以太坊网络中,我们发送一笔交易时,可能发送成功,也可能发送失败,那么交易是如何判断能否发送成功的呢。当我们发送交易后,交易会被广播到矿工,矿工会监听交易的广播,然后把交易放到本地的交易池中等待处理,但是交易能否放到交易池中,以及在交易池中的交易如何处理的,具体如下:
当交易进入交易池(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条交易。
博客地址:http://www.jouypub.com
简书主页:https://www.jianshu.com/u/756c9c8ae984
segmentfault主页:https://segmentfault.com/blog/jouypub
腾讯云主页:https://cloud.tencent.com/developer/column/72548
网友评论