以太坊之Downloader同步区块流程

随着以太坊的数据越来越多,同步也越来越慢,使用full sync mode同步的话恐怕得一两个礼拜也不见得能同步完。以太坊有fast sync mode,找了些文章还不是很明白具体内容,所以尝试着看懂写下来,如有错误之处欢迎指正。

关于fast sync mode的算法,是在这篇文章中讲述的,看完了也没看明白为什么同步的数据会少,速度会快,所以看看源代码的实现吧

https://github.com/ethereum/go-ethereum/pull/1889

图示


先大致讲下同步流程,以新加入网络的节点A和挖矿节点B为例:

1 两个节点先hadeshake同步下各自的genesis、td、head等信息

2 连接成功后,节点B发送TxMsg消息把自己的txpool中的tx同步给节点A

    然后各自循环监听对方的消息

3 节点A此时使用fast sync同步数据,依次发送GetBlockHeadersMsg、GetBlockBodiesMsg、GetReceiptsMsg、GetNodeDataMsg获取block header、block body、receipt和state数据

4 节点B对应的返回BlockHeadersMsg、BlockBodiesMsg、ReceiptsMsg、NodeDataMsg

5 节点A收到数据把header和body组成block存入自己的leveldb数据库,一并存入receipts和state数据

6 节点B挖出block后会向A同步区块,发送NewBlockMsg或者NewBlockHashesMsg(取决于节点A位于节点B的节点列表位置),如果是NewBlockMsg,那么节点A直接验证完存入本地;如果是NewBlockHashesMsg节点A会交给fetcher去获取header和body,然后再组织成block存入本地

基本概念

先简要介绍一下一些基本概念

header:区块的头

body:区块内的所有交易

block:区块,仅包含区块头和body

receipt:合约执行后的结果,log就放在这里。这个默认是不广播的。fast sync的过程中会有节点去获取。正常运行的节点(sync到最新后)收到block后,会执行block内的所有交易,就可以得到这个receipt了

statedb:世界状态,储存所有的账号状态,使用了MPT树存储。跟receipt一样,也不属于block的一部分,广播的时候也不广播。只在fast sync下,会从其他节点获取。正常运行的节点收到block执行所有的交易的时候也可以生成。

这几个数据都是存在节点的leveldb数据库中,正常情况下广播的块是区块,包含header和body(所有的交易)

开始

先从同步代码看起来吧,前面初始化的地方先不讲了,直接切入正题:如果运行geth不设置同步模式,默认是fast mode

func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, networkId uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
	
	// Figure out whether to allow fast sync or not
        // 如果是fast sync mode,并且当前blocknum大于0,切换为full sync模式
        // 那么如果sync了一段时间断掉之后再重新sync是fast mode还是full mode呢,答案还是fast mode
        // 为什么呢? 后面看到代码的时候再讲一下吧
	if mode == downloader.FastSync && blockchain.CurrentBlock().NumberU64() > 0 {
		log.Warn("Blockchain not empty, fast sync disabled")
		mode = downloader.FullSync
	}
	if mode == downloader.FastSync {
		manager.fastSync = uint32(1)
	}
	// Initiate a sub-protocol for every implemented version we can handle
	manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions))
	for i, version := range ProtocolVersions {
		// Skip protocol version if incompatible with the mode of operation
		if mode == downloader.FastSync && version < eth63 {
			continue
		}
		// Compatible; initialise the sub-protocol
		version := version // Closure for the run
		manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{
			Name:    ProtocolName,
			Version: version,
			Length:  ProtocolLengths[i],
			Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
				peer := manager.newPeer(int(version), p, rw)
				select {
				case manager.newPeerCh <- peer:
					manager.wg.Add(1)
					defer manager.wg.Done()
					return manager.handle(peer)
				case <-manager.quitSync:
					return p2p.DiscQuitting
				}
			},
			NodeInfo: func() interface{} {
				return manager.NodeInfo()
			},
			PeerInfo: func(id discover.NodeID) interface{} {
				if p := manager.peers.Peer(fmt.Sprint
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
Shellcode downloader(壳代码下载器)是一种恶意软件的一部分,用于在受感染的系统上下载和执行恶意shellcode。它通常由黑客或攻击者利用系统的弱点,如漏洞或错误配置,将其注入到受感染系统的进程中。 Shellcode downloader的主要目的是在感染的系统上建立一个后门,以便攻击者能够以后访问并对系统进行进一步的攻击。通过下载和执行远程恶意shellcode,攻击者可以获取系统上的敏感信息、执行远程命令、安装其他恶意软件以及执行各种潜在攻击。 Shellcode downloader通常通过各种方式传播,比如利用社交工程、垃圾邮件、恶意网站或网络钓鱼攻击等。一旦感染了一个系统,shellcode downloader将执行以下一些步骤: 1. 首先,shellcode downloader会与其指定的远程服务器建立连接,以获取后续恶意代码的位置和执行指令。 2. 下载恶意的shellcode文件到受感染系统中,并将其写入指定的文件或内存位置。 3. 执行shellcode,使其在系统的特定进程中运行。shellcode的目标是通过利用系统或应用程序的弱点来获取系统权限并执行恶意操作。 4. 一旦shellcode成功运行,它可能会执行许多不同的操作,比如建立远程访问通道、搜集系统信息、窃取敏感信息或执行其他攻击。 为了保护系统免受shellcode downloader的入侵,用户应该始终注意不点击垃圾邮件或未知来源的链接,并保持系统和应用程序的更新,以修复任何发现的漏洞。此外,安装有效的防病毒和防火墙软件也是防止shellcode downloader侵入的关键步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值