千家信息网

bytom启动后怎么连接别的节点

发表于:2025-02-09 作者:千家信息网编辑
千家信息网最后更新 2025年02月09日,本篇内容介绍了"bytom启动后怎么连接别的节点"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!比原启
千家信息网最后更新 2025年02月09日bytom启动后怎么连接别的节点

本篇内容介绍了"bytom启动后怎么连接别的节点"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

比原启动后去哪里连接别的节点

最开始我对于这个问题一直有个疑惑:区块链是一个分布式的网络,那么一个节点启动后,它怎么知道去哪里找别的节点从而加入网络呢?

看到代码之后,我才明白,原来在代码中硬编码了一些种子地址,这样在启动的时候,可以先通过种子地址加入网络。虽然整个网络是分布式的,但是最开始还是需要一定的中心化。

预编码内容

对于配置文件config.toml,比原的代码中硬编码了配置文件内容:

config/toml.go#L22-L45

var defaultConfigTmpl = `# This is a TOML config file.# For more information, see https://github.com/toml-lang/tomlfast_sync = truedb_backend = "leveldb"api_addr = "0.0.0.0:9888"`var mainNetConfigTmpl = `chain_id = "mainnet"[p2p]laddr = "tcp://0.0.0.0:46657"seeds = "45.79.213.28:46657,198.74.61.131:46657,212.111.41.245:46657,47.100.214.154:46657,47.100.109.199:46657,47.100.105.165:46657"`var testNetConfigTmpl = `chain_id = "testnet"[p2p]laddr = "tcp://0.0.0.0:46656"seeds = "47.96.42.1:46656,172.104.224.219:46656,45.118.132.164:46656"`var soloNetConfigTmpl = `chain_id = "solonet"[p2p]laddr = "tcp://0.0.0.0:46658"seeds = ""`

可以看出,对于不同的chain_id,预设的种子是不同的。

当然,如果我们自己知道某些节点的地址,也可以在初始化生成config.toml后,手动修改该文件添加进去。

启动syncManager

那么,比原在代码中是使用这些种子地址并连接它们的呢?关键在于,连接的代码位于SyncManager中,所以我们要找到启动syncManager的地方。

首先,当我们使用bytomd node启动后,下面的函数将被调用:

cmd/bytomd/commands/run_node.go#L41

func runNode(cmd *cobra.Command, args []string) error {    // Create & start node    n := node.NewNode(config)    if _, err := n.Start(); err != nil {        // ...    }    // ...}

这里调用了n.Start,其中的Start方法,来自于Node所嵌入的cmn.BaseService

node/node.go#L39

type Node struct {    cmn.BaseService    // ...}

所以n.Start对应的是下面这个方法:

vendor/github.com/tendermint/tmlibs/common/service.go#L97

func (bs *BaseService) Start() (bool, error) {    // ...    err := bs.impl.OnStart()    // ...}

在这里,由于bs.impl对应于Node,所以将继续调用Node.OnStart():

node/node.go#L169

func (n *Node) OnStart() error {    // ...    n.syncManager.Start()    // ...}

可以看到,我们终于走到了调用了syncManager.Start()的地方。

syncManager中的处理

然后就是在syncManager内部的一些处理了。

它主要是除了从config.toml中取得种子节点外,还需要把以前连接过并保存在本地的AddressBook.json中的节点也拿出来连接,这样就算预设的种子节点失败了,也还是有可能连接上网络(部分解决了前面提到的中心化的担忧)。

syncManager.Start()对应于:

netsync/handle.go#L141

func (sm *SyncManager) Start() {    go sm.netStart()    // ...}

其中sm.netStart(),对应于:

netsync/handle.go#L121

func (sm *SyncManager) netStart() error {    // ...    // If seeds exist, add them to the address book and dial out    if sm.config.P2P.Seeds != "" {        // dial out        seeds := strings.Split(sm.config.P2P.Seeds, ",")        if err := sm.DialSeeds(seeds); err != nil {            return err        }    }    // ...}

其中的sm.config.P2P.Seeds就对应于config.toml中的seeds。关于这两者是怎么对应起来的,会在后面文章中详解。

紧接着,再通过sm.DialSeeds(seeds)去连接这些seed,这个方法对应的代码位于:

netsync/handle.go#L229

func (sm *SyncManager) DialSeeds(seeds []string) error {    return sm.sw.DialSeeds(sm.addrBook, seeds)}

其实是是调用了sm.sw.DialSeeds,而sm.sw是指Switch。这时可以看到,有一个叫addrBook的东西参与了进来,它保存了该结点之前成功连接过的节点地址,我们这里暂不多做讨论。

Switch.DialSeeds对应于:

p2p/switch.go#L311

func (sw *Switch) DialSeeds(addrBook *AddrBook, seeds []string) error {    // ...    perm := rand.Perm(len(netAddrs))    for i := 0; i < len(perm)/2; i++ {        j := perm[i]        sw.dialSeed(netAddrs[j])    }   // ...}

这里引入了随机数,是为了将发起连接的顺序打乱,这样可以让每个种子都获得公平的连接机会。

sw.dialSeed(netAddrs[j])对应于:

p2p/switch.go#L342

func (sw *Switch) dialSeed(addr *NetAddress) {    peer, err := sw.DialPeerWithAddress(addr, false)    // ...}

sw.DialPeerWithAddress(addr, false)又对应于:

p2p/switch.go#L351

func (sw *Switch) DialPeerWithAddress(addr *NetAddress, persistent bool) (*Peer, error) {    // ...    log.WithField("address", addr).Info("Dialing peer")    peer, err := newOutboundPeerWithConfig(addr, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError, sw.nodePrivKey, sw.peerConfig)    // ...}

其中的persistent参数如果是true的话,表明这个peer比较重要,在某些情况下如果断开连接后,还会尝试重连。如果persistentfalse的,就没有这个待遇。

newOutboundPeerWithConfig对应于:

p2p/peer.go#L69

func newOutboundPeerWithConfig(addr *NetAddress, reactorsByCh map[byte]Reactor, chDescs []*ChannelDescriptor, onPeerError func(*Peer, interface{}), ourNodePrivKey crypto.PrivKeyEd25519, config *PeerConfig) (*Peer, error) {    conn, err := dial(addr, config)    // ...}

继续dial,加入了超时:

p2p/peer.go#L284

func dial(addr *NetAddress, config *PeerConfig) (net.Conn, error) {    conn, err := addr.DialTimeout(config.DialTimeout * time.Second)    if err != nil {        return nil, err    }    return conn, nil}

addr.DialTimeout对应于:

p2p/netaddress.go#L141

func (na *NetAddress) DialTimeout(timeout time.Duration) (net.Conn, error) {    conn, err := net.DialTimeout("tcp", na.String(), timeout)    if err != nil {        return nil, err    }    return conn, nil}

"bytom启动后怎么连接别的节点"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

节点 种子 代码 地址 网络 内容 文件 方法 编码 不同 分布式 地方 情况 文章 更多 知识 还是 中心化 处理 配置 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 教室借用管理系统的数据库的设计 乐淘软件开发有限公司 开启服务器远程管理功能 hive查询数据库表 上海金税盘安全接入服务器 网络安全背景图片横 台江区火炎焱燚网络技术服务 贵州通讯软件开发服务有哪些 计算机网络技术专业知识实习报告 注册会计师和软件开发 数据库中没有了个性化 哔哩漫游公共解析服务器地址 网络安全实验室详解 学校检查网络安全检查存在的问题 db2数据库日期操作 启东电子软件开发招聘 苹果手机网页打不开找不到服务器是什么问题 数据库二手房 权限管理数据库设计 数据库删掉表后怎么回滚 华为h22h 03服务器 cbm数据库可以检索图书吗 ubuntu 网站服务器 网络技术信息咨询经营范围 嘉兴运行智慧校园软件开发 二次灭绝服务器室 服务器管理员帐户密码不对 lua访问mysql数据库 网络安全和文明上网活动主题 网络安全部署会会议纪要
0