以太坊网络中,我们发送一笔交易时,可能发送成功,也可能发送失败,那么交易是如何判断能否发送成功的呢。当我们发送交易后,交易会被广播到矿工,矿工会监听交易的广播,然后把交易放到本地的交易池中等待处理,但是交易能否放到交易池中,以及在交易池中的交易如何处理的,
具体如下:
当交易进入交易池(tx_pool)时,矿工节点会做以下验证:
- 通过交易Hash判断交易在交易池中是否存在,如果存在就使用新的交易替换以前的交易
- 验证交易的合法性,如长度、value、是否溢出当前区块的GasLimit、Nonce值等、Gas是否足够,如果验证不通过就会返回对应的错误代码
- 验证是否孤儿交易,如果是就本地保存,不转发,防止DDOS攻击
- 如果交易池满了,就会验证交易Gas是否比当前交易池中的最低Gas低,如果低于交易池的最低Gas会返回ErrUnderpriced,如果高于最低值,就剔除最低Gas的交易。发生这种情况后,在etherscan中会发现在这笔交易pending中消失了(也有很大机率依然能够查到这笔交易在pending列表中,因为etherscan连接了很多节点,每个节点的交易池的状态都是不一样的,那条被踢出的交易可能在别的节点中仍然处于pending状态)
- 如果交易已经在交易池中,会判断Gas是否高于上一条相同Nonce的交易Gas某一个阈值(默认10%),如果Gas高于,就剔除前一笔交易,就使用新的交易替换前一笔交易,如果没有高于当前的交易就会返回失败
- 按顺序放入到交易池中,等待打包
- 等待新的交易加入到交易池,会重复上述步骤。
在明白上述逻辑之前我们需要了解几个细节
- 矿工不能在一个区块中打包任意多的tx(只能尽可能多的打包),因为一个区块有GasLimit限制和区块大小限制。
- 矿工运行以太坊实例时,是可以根据需要修改最低的GasPrice值,这样可以过滤很多低Gas的交易。
- 交易池容纳的交易数默认是有上限的。以太坊的txpool中的pending集合(miner是从pending中拿交易组装block的)中容纳的交易数量默认设置为最大4096。但是在Geth v1.6.2中支持外部重置交易池默认配置。具体是
–txpool.globalslots value
- 。在Parity v1.6.8中也支持外部设置,具体是
--tx-queue-size LIMIT
- 。Parity默认是1024。一个账户默认只能放16条交易到pending中,满了以后,第17条乃至以后更多的交易会有一套规则来替换先前位于pending中的16条交易。
交易池的源码位于:core/tx_pool.go文件
txpool交易池由两部分构成分别是pending和queued组成。主要适用于存放当前提交等待被区块确认提交的交易,本地交易和网络远程交易都有
1、pending:等待执行的交易会被放在pending队列中
2、queued:提交但是不能够执行的交易,放在queue中等待执行
1、检查交易的信息数据是否合法,包括Gas,余额是否不足,Nonce大小等等
2、检查时间状态,将nonce过高的交易放在queue队列,将可以执行的交易放在 pending队列
3、在资源有限的情况下(例如当前池满了,或者网络拥堵),会优先执行GasPrice高的交易
4、如果当前交易的额度大于当前账户的额度,交易会被删除
5、对于相同的account对应的相同nonce的交易只会保存GasPrice高的哪个交易
6、本地交易会使用journal的功能将信息存在本地磁盘
7、如果account没有余额了,那么对应queue队列和pending队列中的交易会被删除
?
注册有任何问题请添加 微信:MVIP619 拉你进入群
打开微信扫一扫
添加客服
进入交流群
发表评论