Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

星火车品
70 0 0
区块链就是何交易打交道,我们今天就介绍下,交易处理过程中的一个重要组成部分:txpool。这篇文章主要从功能角度介绍,通过这篇文章会了解:2 W, A8 g$ n0 c" }5 {. J- p( b* _  A
txpool的在交易中的位置和作用。7 f8 N, w. d& \3 N% D% o8 H
txpool的功能,核心组成部分queued和pending。( x: x5 D' B8 e9 O
txpool如何实现它的功能。
+ F5 T" S% N  |( `3 Q( d% mtxpool源码的重要关注点。
/ p' X9 Q# F$ k) j, p( n/ m- A& q) E
以太坊内部有个重要的内部功能是txpool,从字面意思就能看出来,交易池就是存放交易的池子。它在以太坊中的位置如下图,只要有新交易,无论是本节点创建的,还是其他peer节点广播来的,都会先加入到交易池里,在打包区块的时候,就从这个池子里提取,区块产生之后,共识区块,交易上链。
5 C; U, [5 O2 E( vtxpool有4个功能:7 l$ k1 n2 T# j4 N$ I4 x  I
作为存放交易的缓冲区,大量交易到来时,先存起来
$ F4 P4 Z9 `+ ~( D1 R! x为打包区块服务,合适交易会被打包到区块$ X$ b# i1 c+ B: O" i$ b
清理交易
& B) R6 A8 f7 \  X  f当交易的数量多于缓冲区大小时,过滤/惩罚发送大量交易的账户(攻击者)
6 T& W. l5 N( K" h* U我们来一张稍微详细点的模块交互图,看txpool怎么实现上面4个功能的。
7 r" b4 R: N/ f  K: Y! A" d2 M" E% S" S' ?* N6 o
缓存功能的设计
% X/ t4 E* i8 K3 K: d8 i2 }txpool中的交易分为queued和pending 2种,其中queued存放未来的、当前无法执行的交易。以太坊使用nonce值决定某个账户的交易顺序,多条交易值nonce值必须连续,如果和过去的交易不连续,则无法执行,我们不妨使用nonce值,标记交易的号码,nonce为10的交易,称为第10号交易。举个例子,当前账户的nonce是10,txpool中有该账户的第100号交易,但txpool中没有第11~99号交易,这些交易的缺失,造成第100号交易无法执行,所以第100号交易就是未来的交易、不可执行的交易,存放在queue中。
" k) J. u9 _1 I! ?( w0 jpending存放可执行的交易。比如我们把上面的1199号交易补全了,那么11100号交易都可以进入到pending,因为这些交易都是连续的,都可以打包进区块。
" s) Q  x; b: W5 q当节点收到交易(本地节点发起的或peer广播来的)时,会先存放到queued,txpool在某些情况下,把queued中可执行的交易,转移到pending中。
! `1 o4 @8 g, Q) g# {为区块打包服务
( A$ r4 R* u: n这是txpool最核心的功能,worker在打包区块的时候,会获取所有的pending交易,但这些交易还存在txpool中,worker只是读取出来,至于txpool何时删除交易,稍后从txpool清理交易的角度单独在看。
' l- h' [2 U; b+ g# [清理交易$ G' K5 m$ r# L8 Z( K* `$ w
txpool清理交易有以下几种条件,符合任意以下1条的,都是无效交易,会被从pending或者queued中移除:
) O) d& @9 w; o, `交易的nonce值已经低于账户在当前高度上的nonce值,代表交易已过期,交易已经上链就属于这种情况
2 u: m0 ^1 O# T9 I交易的GasLimit大于区块的GasLimit,区块容不下交易
# F. q1 ]+ m0 J% d$ c9 z4 o/ H+ C账户的余额已不足以支持该交易要消耗的费用2 G, i3 D- c9 Q+ r/ V6 |" g
交易的数量超过了queued和pending的缓冲区大小,需要进行清理
7 s# I0 [: B7 V7 q7 Y5 b: e" N  t
交易清理主要有3个场景:
7 m5 B# f1 @; U* M1 a! x1 p) }4 Z( b  h
txpool订阅了ChainHeadEvent事件,该事件代表主链上有新区块产生,txpool会根据最新的区块,检查每个账号的交易,有些无效的会被删除,有些由于区块回滚会从pending移动到queued,然后把queued中可执行的交易移动到pending,为下一轮区块打包组号准备。
" ?8 i" L4 w. D% ?7 V- m
( J3 p: \, U* i/ r; oqueued交易移动到pending被称为“提升”(promote),这个过程中,同样会检查交易,当交易不符合以上条件时,就会被直接从queued中删除。
! I7 X8 C2 f' c8 Q0 h+ O
9 I) \1 T) m4 l* y& x4 f  U删除停留在queued中超过3小时的交易,3小时这个超时时间是可以通过geth的启动参数调整的。txpool记录了某个账户交易进入pending的时间,如果这个时间超过了3小时,代表该账号的交易迟迟不能被主链打包,既然无法被主链接受,就删除掉在queued中本来就无法执行的交易。
' o$ M  n- g2 v
9 g# K+ K  l+ ?7 B) }9 a) c' A6 n+ N5 |  a1 e+ L" m
惩罚恶意账号
7 ~9 c' m3 r" }1 s" b这也是txpool很重要的一个属性,可以防止恶意账户以发起大量垃圾交易。防止恶意用户造成:( e1 I3 k! D6 D' {/ D9 U) a
占用txpool空间  O9 L) y3 m& u$ n5 j3 [
浪费节点大量内存和CPU" h4 Y) U& g0 @( a. C
降低打包性能
0 N' c/ p) H1 E. w7 _" b: _* K" {0 x. z: E2 f
**只有当交易的总数量超过缓冲区大小时,txpool才会认为有恶意账户发起大量交易。**pending和queued缓冲区大小不同,但处理策略类似:
2 u) A6 C* Q, R( _5 T# Rpending的缓冲区容量是4096,当pending的交易数量多于此时,就会运行检查,每个账号的交易数量是否多于16,把这些账号搜集出来,进行循环依次清理,什么意思呢?就是每轮只删除(移动到queued)这些账号的每个账号1条交易,然后看数量是否降下来了,不满足再进行下一轮,直到满足。
+ [: \, H# K/ Y0 x" R1 A9 Yqueued的缓冲区容量是1024,超过之后清理策略和pending差不多,但这里可是真删除了。% {' j1 j* A* j7 v. d
0 E/ l; p# m7 N/ n1 Z
该部分功能未抽象成单独的函数,而是在promoteExecutables()中,就是在每次把queued交易转移到pending后执行的。
, i+ n* z9 m( o2 M! K本地交易的特权,txpool虽然对交易有诸多限制,但如果交易是本节点的账号发起的,以上数量限制等都对他无效。所以,如果你用本节点账号不停的发送交易,并不会被认为是攻击者,你用txpool.status命令,可以查看到交易的数量,肯定可以大于4096,我曾达到过60000+。
  b  G+ P' Y$ i6 H重点关注的源码
, f$ s6 U* `& j3 j, N& Gtxpool的主要设计上面就讲完了,如果你想把txpool的代码阅读一番,我建议你重点关注一下这些函数和变量,按图索骥能就完全掌握txpool的实现。1 r2 a/ m' p; c3 t; y: L1 N
TxPoolConfig:txpool的配置参数
* f/ E, n. v# H. n3 AchainHeadCh:txpool订阅了新区块事件# s( B7 V' U) t% _! @. c( Z9 L" o
pending:pending的交易,每个账号都有一个交易列表, F6 w8 [- v! z9 B' L" F
queue:queued的交易,每个账号都有一个交易列表
4 U9 i  `: D2 M5 I1 {: i  g' }loop:txpool的事件处理函数
8 M& o; B& f. Y. r# b4 D/ N5 yaddTx:添加1条交易的源头,你能找到类似的函数
3 x: [- T3 U% M# x4 Z. QpromoteExecutables:queued交易移动到pending
# d6 n: B! X, Y9 x, P% Areset:根据当前区块的最新高度,重置txpool中的交易
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

星火车品 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    12