Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

以太坊源码分析:交易缓冲池txpool

星火车品
150 0 0
区块链就是何交易打交道,我们今天就介绍下,交易处理过程中的一个重要组成部分:txpool。这篇文章主要从功能角度介绍,通过这篇文章会了解:
2 m: u1 y6 z9 V) a3 q- ^txpool的在交易中的位置和作用。
5 N* s, H4 l% n$ R0 j; `txpool的功能,核心组成部分queued和pending。
  Y. d$ b1 U: a& w  ctxpool如何实现它的功能。
3 E: e% V) R. S' h3 u/ dtxpool源码的重要关注点。9 @1 ]7 @( J- ~, \
8 `/ x5 z3 l3 m8 c" V
以太坊内部有个重要的内部功能是txpool,从字面意思就能看出来,交易池就是存放交易的池子。它在以太坊中的位置如下图,只要有新交易,无论是本节点创建的,还是其他peer节点广播来的,都会先加入到交易池里,在打包区块的时候,就从这个池子里提取,区块产生之后,共识区块,交易上链。
* T! E* e+ E3 Z5 m& D' L" @! Mtxpool有4个功能:
5 S% b# |- i, ]! K$ b! {0 E作为存放交易的缓冲区,大量交易到来时,先存起来
$ D9 o3 m9 t( x- L% [2 ]为打包区块服务,合适交易会被打包到区块* S4 v1 ?) ]: v8 Z7 M2 Z
清理交易, M/ G! D- K/ X  O0 D- }7 k
当交易的数量多于缓冲区大小时,过滤/惩罚发送大量交易的账户(攻击者)
6 u  G/ L( _  F7 w6 f- ]; ?. Y6 x- j/ D我们来一张稍微详细点的模块交互图,看txpool怎么实现上面4个功能的。' U  z, a1 h$ O& @% y" S
/ m% s% w  ^7 j" z0 l9 z4 J- W, P
缓存功能的设计- G" r' Y8 T, S5 q8 t) E5 ]2 P
txpool中的交易分为queued和pending 2种,其中queued存放未来的、当前无法执行的交易。以太坊使用nonce值决定某个账户的交易顺序,多条交易值nonce值必须连续,如果和过去的交易不连续,则无法执行,我们不妨使用nonce值,标记交易的号码,nonce为10的交易,称为第10号交易。举个例子,当前账户的nonce是10,txpool中有该账户的第100号交易,但txpool中没有第11~99号交易,这些交易的缺失,造成第100号交易无法执行,所以第100号交易就是未来的交易、不可执行的交易,存放在queue中。. l9 ]: U1 l! \9 {* K6 R
pending存放可执行的交易。比如我们把上面的1199号交易补全了,那么11100号交易都可以进入到pending,因为这些交易都是连续的,都可以打包进区块。
9 O% i8 B" P; h当节点收到交易(本地节点发起的或peer广播来的)时,会先存放到queued,txpool在某些情况下,把queued中可执行的交易,转移到pending中。  E; d2 P+ V) K
为区块打包服务
" F7 n$ ^& A, E7 M这是txpool最核心的功能,worker在打包区块的时候,会获取所有的pending交易,但这些交易还存在txpool中,worker只是读取出来,至于txpool何时删除交易,稍后从txpool清理交易的角度单独在看。5 D6 ]$ |7 q6 z0 {% Q
清理交易! q# Y7 C# I8 l+ J1 z$ F3 k
txpool清理交易有以下几种条件,符合任意以下1条的,都是无效交易,会被从pending或者queued中移除:3 j- P3 T% k% t* O
交易的nonce值已经低于账户在当前高度上的nonce值,代表交易已过期,交易已经上链就属于这种情况
5 H- o# n0 J3 w& C. s7 I  x  @+ p交易的GasLimit大于区块的GasLimit,区块容不下交易
! e, L% O: v( ]账户的余额已不足以支持该交易要消耗的费用9 A8 P! t5 ^+ Z
交易的数量超过了queued和pending的缓冲区大小,需要进行清理
: b# S0 _2 d7 e8 c; O% @: g5 B" m
交易清理主要有3个场景:; e/ r* {6 O' L0 p& M

4 `" X, C" i  `5 {  D  m1 J, Etxpool订阅了ChainHeadEvent事件,该事件代表主链上有新区块产生,txpool会根据最新的区块,检查每个账号的交易,有些无效的会被删除,有些由于区块回滚会从pending移动到queued,然后把queued中可执行的交易移动到pending,为下一轮区块打包组号准备。, f9 _- y, a+ }0 Z6 K+ o% t
! g( [. b! v  J1 Q; b0 D' z# \) }
queued交易移动到pending被称为“提升”(promote),这个过程中,同样会检查交易,当交易不符合以上条件时,就会被直接从queued中删除。6 Q; C6 n& b/ T5 y
, M' \8 a  r: e! @, I/ G, E9 ]$ O
删除停留在queued中超过3小时的交易,3小时这个超时时间是可以通过geth的启动参数调整的。txpool记录了某个账户交易进入pending的时间,如果这个时间超过了3小时,代表该账号的交易迟迟不能被主链打包,既然无法被主链接受,就删除掉在queued中本来就无法执行的交易。8 J3 F# _9 G! P
3 Q/ a* n( Z1 k( ]3 t6 N  f9 v
- ~( g3 p9 W6 }3 Y( N
惩罚恶意账号) }! ~, h5 z5 c2 _9 V  V
这也是txpool很重要的一个属性,可以防止恶意账户以发起大量垃圾交易。防止恶意用户造成:  p3 {: o' M! u; |4 d5 \# z9 j
占用txpool空间
6 N  F; X& h4 x  `/ N* I浪费节点大量内存和CPU6 N* `5 [" p0 g
降低打包性能9 A9 h2 y2 i: B4 |5 f0 d5 F
. X  d6 `# n" W* ^$ W2 I+ k, J2 i! B
**只有当交易的总数量超过缓冲区大小时,txpool才会认为有恶意账户发起大量交易。**pending和queued缓冲区大小不同,但处理策略类似:
# M) H3 ?8 F" z8 qpending的缓冲区容量是4096,当pending的交易数量多于此时,就会运行检查,每个账号的交易数量是否多于16,把这些账号搜集出来,进行循环依次清理,什么意思呢?就是每轮只删除(移动到queued)这些账号的每个账号1条交易,然后看数量是否降下来了,不满足再进行下一轮,直到满足。
* g6 a8 |; j: }" D' _queued的缓冲区容量是1024,超过之后清理策略和pending差不多,但这里可是真删除了。8 [; N  T# X, R0 S# K; {7 ?' v
7 K6 s5 m7 O2 n) `8 C9 U
该部分功能未抽象成单独的函数,而是在promoteExecutables()中,就是在每次把queued交易转移到pending后执行的。3 q6 R3 e  e; P2 d( ^
本地交易的特权,txpool虽然对交易有诸多限制,但如果交易是本节点的账号发起的,以上数量限制等都对他无效。所以,如果你用本节点账号不停的发送交易,并不会被认为是攻击者,你用txpool.status命令,可以查看到交易的数量,肯定可以大于4096,我曾达到过60000+。2 e% u$ w1 c; x; Z4 d6 G) _
重点关注的源码
0 r( D1 f$ n7 C  z# Q3 e2 [+ Ntxpool的主要设计上面就讲完了,如果你想把txpool的代码阅读一番,我建议你重点关注一下这些函数和变量,按图索骥能就完全掌握txpool的实现。
. K1 X, H! ]- j  h: t2 uTxPoolConfig:txpool的配置参数
: D9 T" o& j5 Q3 \0 f# @* W% j) ]chainHeadCh:txpool订阅了新区块事件' v/ R# J& i2 n0 [) L
pending:pending的交易,每个账号都有一个交易列表, g- l4 s/ [, w. n. k5 A
queue:queued的交易,每个账号都有一个交易列表1 t3 x5 M3 K8 w3 ~* X
loop:txpool的事件处理函数
7 A3 t9 j& D7 Y: ?' p# [2 ]addTx:添加1条交易的源头,你能找到类似的函数
# g3 n% h- ?7 a. v4 npromoteExecutables:queued交易移动到pending0 l$ a1 z2 D3 B% r  v" }* ?8 @
reset:根据当前区块的最新高度,重置txpool中的交易
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

星火车品 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    12