【源码阅读】交易池txs_fetchertxs_noncer

txs_noncer

1、 txNoncer

type txNoncer struct {fallback evmtypes.IntraBlockStatenonces   map[types.Address]uint64lock     sync.Mutex
}
  1. fallback evmtypes.IntraBlockState:表示回退状态,用于在没有找到对应地址的nonce时使用。
  2. nonces map[types.Address]uint64:表示一个映射,用于存储每个地址对应的nonce值。
  3. lock sync.Mutex:表示一个互斥锁,用于在多线程环境下保护对nonces映射的操作。

1.1 newTxNoncer

func newTxNoncer(db evmtypes.IntraBlockState) *txNoncer {return &txNoncer{fallback: db,nonces:   make(map[types.Address]uint64),}
}

创建一个虚拟的状态数据库来追踪交易池里面的nonce

1.2 get

func (txn *txNoncer) get(addr types.Address) uint64
  • get 返回帐户的当前随机数return txn.nonces[addr]
  • 如果找不到,则回退到真实状态数据库txn.nonces[addr] = txn.fallback.GetNonce(addr)
  • 需要上锁txn.lock.Lock()

1.3 set

func (txn *txNoncer) set(addr types.Address, nonce uint64)
  • set 将新的虚拟随机数插入到虚拟状态数据库中txn.nonces[addr] = nonce
  • 需要上锁txn.lock.Lock()

1.4 setIfLower

func (txn *txNoncer) setIfLower(addr types.Address, nonce uint64)
  • 如果新的虚拟随机数较低,则 setIfLower 将新的虚拟随机数更新到虚拟状态数据库中。
if txn.nonces[addr] <= nonce {return}
txn.nonces[addr] = nonce
  • 需要上锁txn.lock.Lock()
  • 如果找不到,则回退到真实状态数据库txn.nonces[addr] = txn.fallback.GetNonce(addr)

1.5 setAll

func (txn *txNoncer) setAll(all map[types.Address]uint64)
  • setAll 将所有帐户的随机数设置为给定映射txn.nonces = all
  • 需要上锁txn.lock.Lock()

2、txsRequest

type txsRequest struct {hashes hashes       bloom  *types.Bloom peer   peer.ID      
}
  1. hashes hashes:表示交易哈希值。
  2. bloom *types.Bloom:表示布隆过滤器,用于快速检查某个哈希值是否在集合中。
  3. peer peer.ID:表示请求发送者的节点ID。

3、TxsFetcher

type TxsFetcher struct {quit chan struct{}finished  boolpeers     common.PeerMapp2pServer common.INetworkpeerRequests map[peer.ID]*txsRequest // other peer requestsbloom   *types.Bloomfetched map[types.Hash]bool //getTx      func(hash types.Hash) *transaction.TransactionaddTxs     func([]*transaction.Transaction) []errorpendingTxs func(enforceTips bool) map[types.Address][]*transaction.Transaction// fetchTxs//fetchTxs func(string, []types.Hash)// chpeerJoinCh chan *common.PeerJoinEventpeerDropCh chan *common.PeerDropEvent//ctx    context.Contextcancel context.CancelFunc
}
  1. quit chan struct{}:一个用于退出的通道。
  2. finished bool:表示是否已完成。
  3. peers common.PeerMap:表示节点映射。
  4. p2pServer common.INetwork:表示P2P网络接口。
  5. peerRequests map[peer.ID]*txsRequest:表示其他节点请求。
  6. bloom *types.Bloom:表示布隆过滤器。
  7. fetched map[types.Hash]bool:表示已获取的交易哈希值。
  8. getTx func(hash types.Hash) *transaction.Transaction:表示获取交易的函数。
  9. addTxs func([]*transaction.Transaction) []error:表示添加交易的函数。
  10. pendingTxs func(enforceTips bool) map[types.Address][]*transaction.Transaction:表示获取待处理交易的函数。
  11. peerJoinCh chan *common.PeerJoinEvent:表示节点加入事件的通道。
  12. peerDropCh chan *common.PeerDropEvent:表示节点离开事件的通道。
  13. ctx context.Context:表示上下文。
  14. cancel context.CancelFunc:表示取消函数。

3.1 Start

func (f TxsFetcher) Start() error {go f.sendBloomTransactionLoop()go f.bloomBroadcastLoop()return nil
}

调用sendBloomTransactionLoopbloomBroadcastLoop

3.1.1 sendBloomTransactionLoop

func (f TxsFetcher) sendBloomTransactionLoop()
  • 创建定时器tick := time.NewTicker(BloomSendTransactionTime),在时间内进行
  • 片段1
for i := 0; i < BloomSendMaxTransactions; i++ {hash := req.hashes.pop()tx := f.getTx(hash)txs = append(txs, tx.ToProtoMessage().(*types_pb.Transaction))
}

在定时时间内,根据网络获得hash,从而通过getTx获得交易,添加进交易列表中

  • 片段2
msg := &sync_proto.SyncTask{Id:       rand.Uint64(),Ok:       true,SyncType: sync_proto.SyncType_TransactionRes,Payload: &sync_proto.SyncTask_SyncTransactionResponse{SyncTransactionResponse: &sync_proto.SyncTransactionResponse{Transactions: txs,},},
}

这段代码的作用是创建一个同步任务,并将其赋值给msg变量。

  1. Id:一个随机生成的无符号64位整数,用于唯一标识同步任务。
  2. Ok:一个布尔值,表示同步任务是否成功。在这个例子中,它被设置为true
  3. SyncType:一个枚举类型,表示同步任务的类型。在这个例子中,它被设置为sync_proto.SyncType_TransactionRes,表示这是一个事务响应类型的同步任务。
  4. Payload:一个指向sync_proto.SyncTask_SyncTransactionResponse类型的指针,表示同步任务的有效载荷。在这个例子中,它包含了一个名为SyncTransactionResponse的字段,该字段是一个指向sync_proto.SyncTransactionResponse类型的指针,其中包含了一个名为Transactions的字段,该字段是一个包含多个交易信息的切片。
  • 如果获得通道信息,就表示已完成,则返回case <-f.ctx.Done():

3.1.2 bloomBroadcastLoop

func (f TxsFetcher) bloomBroadcastLoop()
  • 创建定时器tick := time.NewTicker(BloomFetcherMaxTime)
  • 序列化为字节bloom, err := f.bloom.Marshal()
  • 片段1
msg := &sync_proto.SyncTask{Id:       rand.Uint64(),Ok:       true,SyncType: sync_proto.SyncType_TransactionReq,Payload: &sync_proto.SyncTask_SyncTransactionRequest{SyncTransactionRequest: &sync_proto.SyncTransactionRequest{Bloom: bloom,},},
}

理解同上,创建一个同步任务,并将其赋值给msg变量。

  • 这段代码是Go语言编写的,它处理了一个名为peerJoinCh的通道。当从该通道接收到数据时,它会将数据存储在f.peers字典中,并使用WriteMsg方法向对应的peer发送一个消息。

以下是对代码的解析:

case peerId := <-f.peerJoinCh:// 从 f.peerJoinCh 通道接收数据,并将其赋值给 peerId 变量// peerId 是一个结构体,包含了要加入的 peer 的信息f.peers[peerId.Peer].WriteMsg(message.MsgTransaction, request)// 通过 peerId.Peer 获取对应的 peer 对象// 使用 WriteMsg 方法向该 peer 发送一个类型为 message.MsgTransaction 的消息,并将 request 作为参数传递
  • peerJoinCh 用于接收新加入的 peer 的信息,而 peers 用于存储已加入的 peer 对象。
case peerId := <-f.peerJoinCh:f.peers[peerId.Peer].WriteMsg(message.MsgTransaction, request)

4 ConnHandler

func (f TxsFetcher) ConnHandler(data []byte, ID peer.ID) error
  • 根据id是否能获取返回值_, ok := f.peers[ID]
  • 获取同步任务syncTask := sync_proto.SyncTask{}
  • 处理同步任务的请求
  1. 当接收到类型为sync_proto.SyncType_TransactionReq的同步任务时,它会解析请求中的事务信息,并检查是否已经存在该peer的请求_, ok := f.peerRequests[ID]
  2. 如果不存在,则创建一个新的bloom过滤器bloom := new(types.Bloom)并将请求中的bloom数据反序列化到新的bloom过滤器中
  3. 然后创建交易列表txs和哈希hash
  4. 遍历所有待处理的交易pending,将不在bloom过滤器中的交易哈希值if !bloom.Contain(hash.Bytes())添加到一个列表中hashes = append(hashes, hash)
  5. 将这些哈希值存储在f.peerRequests[ID]中,以便后续处理
f.peerRequests[ID] = &txsRequest{bloom:  bloom,hashes: hashes,peer:   ID,
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/611539.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二、MyBatis 基本使用

本章概要 向SQL语句传参数据输入 Mybatis总体机制概括概念说明单个简单类型参数实体类类型参数零散的简单类型数据Map类型参数 数据输出 输出概述单个简单类型返回实体类对象返回Map类型返回List类型返回主键值实体类属性和数据库字段对应关系 CRUD强化练习mapperXML标签总结 …

idea git回滚之前提交记录

提交代码时&#xff0c;如果不小心提交了不需要提交的内容&#xff0c;在本地仓库中&#xff0c;此时需要回滚版本&#xff0c;如何回滚 1.打开git控制台&#xff0c;左下角git,选择要处理的分支&#xff0c;选择刷新获取最新git提交记录 2&#xff09;选中自己commit需要回滚…

教你用SadTalker一键整合包轻松制作专属数字人

数字人的效果&#xff1a; &#x1f3b5;我用SadTalker制作了专属虚拟数字人&#xff0c;还会唱歌哦&#xff0c;多多点赞关注就出教程呦&#x1f497; SadTalker有独立离线版Ai数字人&#xff0c;也可以在Stable Diffusion以插件的形式使用&#xff0c;但是如果显卡小的话还是…

开始卷TED:第1篇 —— 《Embrace the near win》—— part: 3

She first hit a seven, I remember, and then a nine, and then two tens, and then the next arrow didn’t even hit the target. 她第一次射中了7环&#xff0c; 我记得接下来是个9环&#xff0c;然后是2个十环&#xff0c;接下来的那支箭甚至没有射到靶上。 And I saw tha…

强化学习10——免模型控制Q-learning算法

Q-learning算法 主要思路 由于 V π ( s ) ∑ a ∈ A π ( a ∣ s ) Q π ( s , a ) V_\pi(s)\sum_{a\in A}\pi(a\mid s)Q_\pi(s,a) Vπ​(s)∑a∈A​π(a∣s)Qπ​(s,a) &#xff0c;当我们直接预测动作价值函数&#xff0c;在决策中选择Q值最大即动作价值最大的动作&…

【Vue3】2-4 : 声明式渲染及响应式数据实现原理

本书目录&#xff1a;点击进入 一、声明式渲染 1.1 什么是JS表达式&#xff1a;能够进行赋值的操作 ▶ 正确 ▶ 错误示例 二、示例&#xff1a;2秒后&#xff0c;页面中 message 由 hello world 变成 hi vue ▶ 效果 三、原理&#xff1a;利用ES6的Proxy对象对底层进…

achievement_criteria_data

achievement_criteria_data&#xff08;335&#xff09; 此表用来确定获得成就所需条件 criteria_id &#xff1a;ID&#xff0c;取值参考 Achievement_Criteria.dbctype &#xff1a;这个字段决定 value1 和 value2 数据的作用&#xff0c;详细数据见下表ScriptName&#xf…

Linux网络编程(一-网络相关知识点)

目录 一、网络相关知识简介 二、网络协议的分层模型 2.1 OSI七层模型 2.2 TCP/IP五层模型 2.3 协议层报文间的封装与拆封 三、IP协议 3.1 MAC地址 3.2 IP地址 3.3 MAC地址与IP地址区别 一、网络相关知识简介 互联网通信的本质是数字通信&#xff0c;任何数字通信都离…

千问写作——论文写作

【千问写作】 千问写作是运用通义千问720亿参数的语言模型&#xff08;qwen-72b-chat&#xff09;进行基于目录的论文创作&#xff0c;通过python-docx设置文档格式然后写出文档 &#xff0c;其他免费模型&#xff08;qwen-1.8b-chat&#xff09;暂时无法生成目录 1. 请求延时 …

Docker实战10|实现volum数据卷

上一篇文章中&#xff0c;仔细讲解了Docker是如何改变当前的root文件系统以及mount等操作。 本文继续讲解Docker是如何实现Volum数据卷的。 实现Volume数据卷 获取代码 git clone https://gitee.com/mjreams/docker.git 上一小节介绍了如何使用AUFS包装busybox&#xff0c…

Windows11快速安装Android子系统

很多小伙伴想在电脑运行一下安卓程序&#xff0c;或则上班用手机摸鱼不方便&#xff0c;用电脑又没有想要的手机软件&#xff0c;那么怎么用电脑来安装安卓软件呢&#xff1f; 首先设置地区 安装Android子系统的前提需要安装 Amazon Appstore 这个应用&#xff0c;内地不能下载…

【博士每天一篇论文-算法】Optimal modularity and memory capacity of neural reservoirs

阅读时间&#xff1a;2023-11-15 1 介绍 年份&#xff1a;2019 作者&#xff1a;Nathaniel Rodriguez 印第安纳大学信息学、计算和工程学院&#xff0c;美国印第安纳州布卢明顿 期刊&#xff1a; Network Neuroscience 引用量&#xff1a;39 这篇论文主要研究了神经网络的模块…

SpringBoot+Redis实现接口防刷功能

场景描述&#xff1a; 在实际开发中&#xff0c;当前端请求后台时&#xff0c;如果后端处理比较慢&#xff0c;但是用户是不知情的&#xff0c;此时后端仍在处理&#xff0c;但是前端用户以为没点到&#xff0c;那么再次点击又发起请求&#xff0c;就会导致在短时间内有很多请求…

RK3568平台开发系列讲解(Linux系统篇)Linux 内核打印

🚀返回总目录 文章目录 一、方法一:dmseg 命令二、方法二:查看 kmsg 文件三、方法三:调整内核打印等级一、方法一:dmseg 命令 在终端使用 dmseg 命令可以获取内核打印信息,该命令的具体使用方法如下所示: 首先在串口终端使用 “dmseg”命令,可以看见相应的内核打印信息…

Java基础- 泛型

泛型是 Java 编程语言的一个特性&#xff0c;它允许在编写和使用类、接口和方法时添加类型参数。泛型的主要目的是提高代码的可重用性、类型安全性和可读性。 泛型方法允许在方法级别上指定类型参数&#xff0c;提供了极大的灵活性和类型安全性。以下是一个泛型方法的示例&…

Windows.OpenSSL生成ssl证书配置到nginx

一、下载OpenSSL程序安装 到E:\soft\OpenSSL-Win64 二、打开一个CMD控制台窗口&#xff0c;设置好openssl.cnf路径 E: cd E:\soft\OpenSSL-Win64\bin set OPENSSL_CONFE:\soft\OpenSSL-Win64\bin\openssl.cnf 三、在当前目录 E:\soft\OpenSSL-Win64\bin 里创建两个子目录 m…

力扣103. 二叉树的锯齿形层序遍历

广度优先搜索 思路&#xff1a; 需要逐层遍历结果&#xff0c;通过广度优先搜索即可&#xff1b; 使用 queue&#xff0c;初始将 root push 进入 queue&#xff1b;逐层搜索&#xff0c;直到 queue 为空&#xff1b; queue 里为当前层节点元素&#xff0c;一次循环处理&#x…

酿酒生产废水处理设备如何选型

选型酿酒生产废水处理设备是确保废水处理过程高效稳定的关键步骤。酿酒生产过程中&#xff0c;产生的废水中含有大量有机物和悬浮物&#xff0c;因此需要选择适合的设备来进行处理。 首先&#xff0c;要根据酿酒生产废水的特点进行选型。酿酒废水的主要特点是&#xff1a;水量较…

uni-app使用uni-ui加ts类型限制

uni-app使用uni-ui加ts类型限制 安装 uni-ui 组件库 pnpm i dcloudio/uni-ui配置自动导入组件 // pages.json {// 组件自动导入"easycom": {"autoscan": true,"custom": {// uni-ui 规则如下配置 "^uni-(.*)": "dcloudio/uni…

phpstorm配置ftp

1 选择设置ftp 2设置自动上传