Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
649787a9
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
649787a9
编写于
12月 30, 2015
作者:
P
Péter Szilágyi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
core: fix transaction reorg issues within the tx pool
上级
36137623
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
344 addition
and
44 deletion
+344
-44
core/transaction_pool.go
core/transaction_pool.go
+78
-41
core/transaction_pool_test.go
core/transaction_pool_test.go
+266
-3
未找到文件。
core/transaction_pool.go
浏览文件 @
649787a9
...
...
@@ -140,7 +140,6 @@ func (pool *TxPool) resetState() {
}
}
}
// Check the queue and move transactions over to the pending if possible
// or remove those that have become invalid
pool
.
checkQueue
()
...
...
@@ -301,17 +300,15 @@ func (pool *TxPool) addTx(hash common.Hash, addr common.Address, tx *types.Trans
}
// Add queues a single transaction in the pool if it is valid.
func
(
self
*
TxPool
)
Add
(
tx
*
types
.
Transaction
)
(
err
error
)
{
func
(
self
*
TxPool
)
Add
(
tx
*
types
.
Transaction
)
error
{
self
.
mu
.
Lock
()
defer
self
.
mu
.
Unlock
()
err
=
self
.
add
(
tx
)
if
err
==
nil
{
// check and validate the queueue
self
.
checkQueue
()
if
err
:=
self
.
add
(
tx
);
err
!=
nil
{
return
err
}
return
self
.
checkQueue
()
return
nil
}
// AddTransactions attempts to queue all valid transactions in txs.
...
...
@@ -417,51 +414,55 @@ func (pool *TxPool) checkQueue() {
pool
.
resetState
()
}
var
addq
txQueue
var
promote
txQueue
for
address
,
txs
:=
range
pool
.
queue
{
// guessed nonce is the nonce currently kept by the tx pool (pending state)
guessedNonce
:=
pool
.
pendingState
.
GetNonce
(
address
)
// true nonce is the nonce known by the last state
currentState
,
err
:=
pool
.
currentState
()
if
err
!=
nil
{
glog
.
Errorf
(
"could not get current state: %v"
,
err
)
return
}
trueNonce
:=
currentState
.
GetNonce
(
address
)
addq
:=
addq
[
:
0
]
balance
:=
currentState
.
GetBalance
(
address
)
var
(
guessedNonce
=
pool
.
pendingState
.
GetNonce
(
address
)
// nonce currently kept by the tx pool (pending state)
trueNonce
=
currentState
.
GetNonce
(
address
)
// nonce known by the last state
)
promote
=
promote
[
:
0
]
for
hash
,
tx
:=
range
txs
{
if
tx
.
Nonce
()
<
trueNonce
{
// Drop queued transactions whose nonce is lower than
// the account nonce because they have been processed.
// Drop processed or out of fund transactions
if
tx
.
Nonce
()
<
trueNonce
||
balance
.
Cmp
(
tx
.
Cost
())
<
0
{
if
glog
.
V
(
logger
.
Core
)
{
glog
.
Infof
(
"removed tx (%v) from pool queue: low tx nonce or out of funds
\n
"
,
tx
)
}
delete
(
txs
,
hash
)
}
else
{
// Collect the remaining transactions for the next pass.
addq
=
append
(
addq
,
txQueueEntry
{
hash
,
address
,
tx
})
}
}
// Find the next consecutive nonce range starting at the
// current account nonce.
sort
.
Sort
(
addq
)
for
i
,
e
:=
range
addq
{
// start deleting the transactions from the queue if they exceed the limit
if
i
>
maxQueued
{
delete
(
pool
.
queue
[
address
],
e
.
hash
)
continue
}
if
e
.
Nonce
()
>
guessedNonce
{
if
len
(
addq
)
-
i
>
maxQueued
{
// Collect the remaining transactions for the next pass.
promote
=
append
(
promote
,
txQueueEntry
{
hash
,
address
,
tx
})
}
// Find the next consecutive nonce range starting at the current account nonce,
// pushing the guessed nonce forward if we add consecutive transactions.
sort
.
Sort
(
promote
)
for
i
,
entry
:=
range
promote
{
// If we reached a gap in the nonces, enforce transaction limit and stop
if
entry
.
Nonce
()
>
guessedNonce
{
if
len
(
promote
)
-
i
>
maxQueued
{
if
glog
.
V
(
logger
.
Debug
)
{
glog
.
Infof
(
"Queued tx limit exceeded for %s. Tx %s removed
\n
"
,
common
.
PP
(
address
[
:
]),
common
.
PP
(
e
.
hash
[
:
]))
glog
.
Infof
(
"Queued tx limit exceeded for %s. Tx %s removed
\n
"
,
common
.
PP
(
address
[
:
]),
common
.
PP
(
e
ntry
.
hash
[
:
]))
}
for
j
:=
i
+
maxQueued
;
j
<
len
(
addq
);
j
++
{
delete
(
txs
,
addq
[
j
]
.
hash
)
for
_
,
drop
:=
range
promote
[
i
+
maxQueued
:
]
{
delete
(
txs
,
drop
.
hash
)
}
}
break
}
delete
(
txs
,
e
.
hash
)
pool
.
addTx
(
e
.
hash
,
address
,
e
.
Transaction
)
// Otherwise promote the transaction and move the guess nonce if needed
pool
.
addTx
(
entry
.
hash
,
address
,
entry
.
Transaction
)
delete
(
txs
,
entry
.
hash
)
if
entry
.
Nonce
()
==
guessedNonce
{
guessedNonce
++
}
}
// Delete the entire queue entry if it became empty.
if
len
(
txs
)
==
0
{
...
...
@@ -471,20 +472,56 @@ func (pool *TxPool) checkQueue() {
}
// validatePool removes invalid and processed transactions from the main pool.
// If a transaction is removed for being invalid (e.g. out of funds), all sub-
// sequent (Still valid) transactions are moved back into the future queue. This
// is important to prevent a drained account from DOSing the network with non
// executable transactions.
func
(
pool
*
TxPool
)
validatePool
()
{
state
,
err
:=
pool
.
currentState
()
if
err
!=
nil
{
glog
.
V
(
logger
.
Info
)
.
Infoln
(
"failed to get current state: %v"
,
err
)
return
}
balanceCache
:=
make
(
map
[
common
.
Address
]
*
big
.
Int
)
// Clean up the pending pool, accumulating invalid nonces
gaps
:=
make
(
map
[
common
.
Address
]
uint64
)
for
hash
,
tx
:=
range
pool
.
pending
{
from
,
_
:=
tx
.
From
()
// err already checked
// perform light nonce validation
if
state
.
GetNonce
(
from
)
>
tx
.
Nonce
()
{
sender
,
_
:=
tx
.
From
()
// err already checked
// Perform light nonce and balance validation
balance
:=
balanceCache
[
sender
]
if
balance
==
nil
{
balance
=
state
.
GetBalance
(
sender
)
balanceCache
[
sender
]
=
balance
}
if
past
:=
state
.
GetNonce
(
sender
)
>
tx
.
Nonce
();
past
||
balance
.
Cmp
(
tx
.
Cost
())
<
0
{
// Remove an already past it invalidated transaction
if
glog
.
V
(
logger
.
Core
)
{
glog
.
Infof
(
"removed tx (%
x) from pool: low tx nonce
\n
"
,
hash
[
:
4
]
)
glog
.
Infof
(
"removed tx (%
v) from pool: low tx nonce or out of funds
\n
"
,
tx
)
}
delete
(
pool
.
pending
,
hash
)
// Track the smallest invalid nonce to postpone subsequent transactions
if
!
past
{
if
prev
,
ok
:=
gaps
[
sender
];
!
ok
||
tx
.
Nonce
()
<
prev
{
gaps
[
sender
]
=
tx
.
Nonce
()
}
}
}
}
// Move all transactions after a gap back to the future queue
if
len
(
gaps
)
>
0
{
for
hash
,
tx
:=
range
pool
.
pending
{
sender
,
_
:=
tx
.
From
()
if
gap
,
ok
:=
gaps
[
sender
];
ok
&&
tx
.
Nonce
()
>=
gap
{
if
glog
.
V
(
logger
.
Core
)
{
glog
.
Infof
(
"postponed tx (%v) due to introduced gap
\n
"
,
tx
)
}
pool
.
queueTx
(
hash
,
tx
)
delete
(
pool
.
pending
,
hash
)
}
}
}
}
...
...
core/transaction_pool_test.go
浏览文件 @
649787a9
...
...
@@ -90,7 +90,7 @@ func TestTransactionQueue(t *testing.T) {
tx
:=
transaction
(
0
,
big
.
NewInt
(
100
),
key
)
from
,
_
:=
tx
.
From
()
currentState
,
_
:=
pool
.
currentState
()
currentState
.
AddBalance
(
from
,
big
.
NewInt
(
1
))
currentState
.
AddBalance
(
from
,
big
.
NewInt
(
1
000
))
pool
.
queueTx
(
tx
.
Hash
(),
tx
)
pool
.
checkQueue
()
...
...
@@ -115,15 +115,17 @@ func TestTransactionQueue(t *testing.T) {
tx1
:=
transaction
(
0
,
big
.
NewInt
(
100
),
key
)
tx2
:=
transaction
(
10
,
big
.
NewInt
(
100
),
key
)
tx3
:=
transaction
(
11
,
big
.
NewInt
(
100
),
key
)
from
,
_
=
tx1
.
From
()
currentState
,
_
=
pool
.
currentState
()
currentState
.
AddBalance
(
from
,
big
.
NewInt
(
1000
))
pool
.
queueTx
(
tx1
.
Hash
(),
tx1
)
pool
.
queueTx
(
tx2
.
Hash
(),
tx2
)
pool
.
queueTx
(
tx3
.
Hash
(),
tx3
)
from
,
_
=
tx1
.
From
()
pool
.
checkQueue
()
if
len
(
pool
.
pending
)
!=
1
{
t
.
Error
(
"expected tx pool to be 1
="
)
t
.
Error
(
"expected tx pool to be 1
, got"
,
len
(
pool
.
pending
)
)
}
if
len
(
pool
.
queue
[
from
])
!=
2
{
t
.
Error
(
"expected len(queue) == 2, got"
,
len
(
pool
.
queue
[
from
]))
...
...
@@ -272,3 +274,264 @@ func TestRemovedTxEvent(t *testing.T) {
t
.
Error
(
"expected 1 pending tx, got"
,
len
(
pool
.
pending
))
}
}
// Tests that if an account runs out of funds, any pending and queued transactions
// are dropped.
func
TestTransactionDropping
(
t
*
testing
.
T
)
{
// Create a test account and fund it
pool
,
key
:=
setupTxPool
()
account
,
_
:=
transaction
(
0
,
big
.
NewInt
(
0
),
key
)
.
From
()
state
,
_
:=
pool
.
currentState
()
state
.
AddBalance
(
account
,
big
.
NewInt
(
1000
))
// Add some pending and some queued transactions
var
(
tx0
=
transaction
(
0
,
big
.
NewInt
(
100
),
key
)
tx1
=
transaction
(
1
,
big
.
NewInt
(
200
),
key
)
tx10
=
transaction
(
10
,
big
.
NewInt
(
100
),
key
)
tx11
=
transaction
(
11
,
big
.
NewInt
(
200
),
key
)
)
pool
.
addTx
(
tx0
.
Hash
(),
account
,
tx0
)
pool
.
addTx
(
tx1
.
Hash
(),
account
,
tx1
)
pool
.
queueTx
(
tx10
.
Hash
(),
tx10
)
pool
.
queueTx
(
tx11
.
Hash
(),
tx11
)
// Check that pre and post validations leave the pool as is
if
len
(
pool
.
pending
)
!=
2
{
t
.
Errorf
(
"pending transaction mismatch: have %d, want %d"
,
len
(
pool
.
pending
),
2
)
}
if
len
(
pool
.
queue
[
account
])
!=
2
{
t
.
Errorf
(
"queued transaction mismatch: have %d, want %d"
,
len
(
pool
.
queue
),
2
)
}
pool
.
resetState
()
if
len
(
pool
.
pending
)
!=
2
{
t
.
Errorf
(
"pending transaction mismatch: have %d, want %d"
,
len
(
pool
.
pending
),
2
)
}
if
len
(
pool
.
queue
[
account
])
!=
2
{
t
.
Errorf
(
"queued transaction mismatch: have %d, want %d"
,
len
(
pool
.
queue
),
2
)
}
// Reduce the balance of the account, and check that invalidated transactions are dropped
state
.
AddBalance
(
account
,
big
.
NewInt
(
-
750
))
pool
.
resetState
()
if
_
,
ok
:=
pool
.
pending
[
tx0
.
Hash
()];
!
ok
{
t
.
Errorf
(
"funded pending transaction missing: %v"
,
tx0
)
}
if
_
,
ok
:=
pool
.
pending
[
tx1
.
Hash
()];
ok
{
t
.
Errorf
(
"out-of-fund pending transaction present: %v"
,
tx1
)
}
if
_
,
ok
:=
pool
.
queue
[
account
][
tx10
.
Hash
()];
!
ok
{
t
.
Errorf
(
"funded queued transaction missing: %v"
,
tx10
)
}
if
_
,
ok
:=
pool
.
queue
[
account
][
tx11
.
Hash
()];
ok
{
t
.
Errorf
(
"out-of-fund queued transaction present: %v"
,
tx11
)
}
}
// Tests that if a transaction is dropped from the current pending pool (e.g. out
// of fund), all consecutive (still valid, but not executable) transactions are
// postponed back into the future queue to prevent broadcating them.
func
TestTransactionPostponing
(
t
*
testing
.
T
)
{
// Create a test account and fund it
pool
,
key
:=
setupTxPool
()
account
,
_
:=
transaction
(
0
,
big
.
NewInt
(
0
),
key
)
.
From
()
state
,
_
:=
pool
.
currentState
()
state
.
AddBalance
(
account
,
big
.
NewInt
(
1000
))
// Add a batch consecutive pending transactions for validation
txns
:=
[]
*
types
.
Transaction
{}
for
i
:=
0
;
i
<
100
;
i
++
{
var
tx
*
types
.
Transaction
if
i
%
2
==
0
{
tx
=
transaction
(
uint64
(
i
),
big
.
NewInt
(
100
),
key
)
}
else
{
tx
=
transaction
(
uint64
(
i
),
big
.
NewInt
(
500
),
key
)
}
pool
.
addTx
(
tx
.
Hash
(),
account
,
tx
)
txns
=
append
(
txns
,
tx
)
}
// Check that pre and post validations leave the pool as is
if
len
(
pool
.
pending
)
!=
len
(
txns
)
{
t
.
Errorf
(
"pending transaction mismatch: have %d, want %d"
,
len
(
pool
.
pending
),
len
(
txns
))
}
if
len
(
pool
.
queue
[
account
])
!=
0
{
t
.
Errorf
(
"queued transaction mismatch: have %d, want %d"
,
len
(
pool
.
queue
),
0
)
}
pool
.
resetState
()
if
len
(
pool
.
pending
)
!=
len
(
txns
)
{
t
.
Errorf
(
"pending transaction mismatch: have %d, want %d"
,
len
(
pool
.
pending
),
len
(
txns
))
}
if
len
(
pool
.
queue
[
account
])
!=
0
{
t
.
Errorf
(
"queued transaction mismatch: have %d, want %d"
,
len
(
pool
.
queue
),
0
)
}
// Reduce the balance of the account, and check that transactions are reorganized
state
.
AddBalance
(
account
,
big
.
NewInt
(
-
750
))
pool
.
resetState
()
if
_
,
ok
:=
pool
.
pending
[
txns
[
0
]
.
Hash
()];
!
ok
{
t
.
Errorf
(
"tx %d: valid and funded transaction missing from pending pool: %v"
,
0
,
txns
[
0
])
}
if
_
,
ok
:=
pool
.
queue
[
account
][
txns
[
0
]
.
Hash
()];
ok
{
t
.
Errorf
(
"tx %d: valid and funded transaction present in future queue: %v"
,
0
,
txns
[
0
])
}
for
i
,
tx
:=
range
txns
[
1
:
]
{
if
i
%
2
==
1
{
if
_
,
ok
:=
pool
.
pending
[
tx
.
Hash
()];
ok
{
t
.
Errorf
(
"tx %d: valid but future transaction present in pending pool: %v"
,
i
+
1
,
tx
)
}
if
_
,
ok
:=
pool
.
queue
[
account
][
tx
.
Hash
()];
!
ok
{
t
.
Errorf
(
"tx %d: valid but future transaction missing from future queue: %v"
,
i
+
1
,
tx
)
}
}
else
{
if
_
,
ok
:=
pool
.
pending
[
tx
.
Hash
()];
ok
{
t
.
Errorf
(
"tx %d: out-of-fund transaction present in pending pool: %v"
,
i
+
1
,
tx
)
}
if
_
,
ok
:=
pool
.
queue
[
account
][
tx
.
Hash
()];
ok
{
t
.
Errorf
(
"tx %d: out-of-fund transaction present in future queue: %v"
,
i
+
1
,
tx
)
}
}
}
}
// Tests that if the transaction count belonging to a single account goes above
// some threshold, the higher transactions are dropped to prevent DOS attacks.
func
TestTransactionQueueLimiting
(
t
*
testing
.
T
)
{
// Create a test account and fund it
pool
,
key
:=
setupTxPool
()
account
,
_
:=
transaction
(
0
,
big
.
NewInt
(
0
),
key
)
.
From
()
state
,
_
:=
pool
.
currentState
()
state
.
AddBalance
(
account
,
big
.
NewInt
(
1000000
))
// Keep queuing up transactions and make sure all above a limit are dropped
for
i
:=
uint64
(
1
);
i
<=
maxQueued
+
5
;
i
++
{
if
err
:=
pool
.
Add
(
transaction
(
i
,
big
.
NewInt
(
100000
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"tx %d: failed to add transaction: %v"
,
i
,
err
)
}
if
len
(
pool
.
pending
)
!=
0
{
t
.
Errorf
(
"tx %d: pending pool size mismatch: have %d, want %d"
,
i
,
len
(
pool
.
pending
),
0
)
}
if
i
<=
maxQueued
{
if
len
(
pool
.
queue
[
account
])
!=
int
(
i
)
{
t
.
Errorf
(
"tx %d: queue size mismatch: have %d, want %d"
,
i
,
len
(
pool
.
queue
[
account
]),
i
)
}
}
else
{
if
len
(
pool
.
queue
[
account
])
!=
maxQueued
{
t
.
Errorf
(
"tx %d: queue limit mismatch: have %d, want %d"
,
i
,
len
(
pool
.
queue
[
account
]),
maxQueued
)
}
}
}
}
// Tests that even if the transaction count belonging to a single account goes
// above some threshold, as long as the transactions are executable, they are
// accepted.
func
TestTransactionPendingLimiting
(
t
*
testing
.
T
)
{
// Create a test account and fund it
pool
,
key
:=
setupTxPool
()
account
,
_
:=
transaction
(
0
,
big
.
NewInt
(
0
),
key
)
.
From
()
state
,
_
:=
pool
.
currentState
()
state
.
AddBalance
(
account
,
big
.
NewInt
(
1000000
))
// Keep queuing up transactions and make sure all above a limit are dropped
for
i
:=
uint64
(
0
);
i
<
maxQueued
+
5
;
i
++
{
if
err
:=
pool
.
Add
(
transaction
(
i
,
big
.
NewInt
(
100000
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"tx %d: failed to add transaction: %v"
,
i
,
err
)
}
if
len
(
pool
.
pending
)
!=
int
(
i
)
+
1
{
t
.
Errorf
(
"tx %d: pending pool size mismatch: have %d, want %d"
,
i
,
len
(
pool
.
pending
),
i
+
1
)
}
if
len
(
pool
.
queue
[
account
])
!=
0
{
t
.
Errorf
(
"tx %d: queue size mismatch: have %d, want %d"
,
i
,
len
(
pool
.
queue
[
account
]),
0
)
}
}
}
// Tests that the transaction limits are enforced the same way irrelevant whether
// the transactions are added one by one or in batches.
func
TestTransactionQueueLimitingEquivalency
(
t
*
testing
.
T
)
{
testTransactionLimitingEquivalency
(
t
,
1
)
}
func
TestTransactionPendingLimitingEquivalency
(
t
*
testing
.
T
)
{
testTransactionLimitingEquivalency
(
t
,
0
)
}
func
testTransactionLimitingEquivalency
(
t
*
testing
.
T
,
origin
uint64
)
{
// Add a batch of transactions to a pool one by one
pool1
,
key1
:=
setupTxPool
()
account1
,
_
:=
transaction
(
0
,
big
.
NewInt
(
0
),
key1
)
.
From
()
state1
,
_
:=
pool1
.
currentState
()
state1
.
AddBalance
(
account1
,
big
.
NewInt
(
1000000
))
for
i
:=
uint64
(
0
);
i
<
maxQueued
+
5
;
i
++
{
if
err
:=
pool1
.
Add
(
transaction
(
origin
+
i
,
big
.
NewInt
(
100000
),
key1
));
err
!=
nil
{
t
.
Fatalf
(
"tx %d: failed to add transaction: %v"
,
i
,
err
)
}
}
// Add a batch of transactions to a pool in one bit batch
pool2
,
key2
:=
setupTxPool
()
account2
,
_
:=
transaction
(
0
,
big
.
NewInt
(
0
),
key2
)
.
From
()
state2
,
_
:=
pool2
.
currentState
()
state2
.
AddBalance
(
account2
,
big
.
NewInt
(
1000000
))
txns
:=
[]
*
types
.
Transaction
{}
for
i
:=
uint64
(
0
);
i
<
maxQueued
+
5
;
i
++
{
txns
=
append
(
txns
,
transaction
(
origin
+
i
,
big
.
NewInt
(
100000
),
key2
))
}
pool2
.
AddTransactions
(
txns
)
// Ensure the batch optimization honors the same pool mechanics
if
len
(
pool1
.
pending
)
!=
len
(
pool2
.
pending
)
{
t
.
Errorf
(
"pending transaction count mismatch: one-by-one algo: %d, batch algo: %d"
,
len
(
pool1
.
pending
),
len
(
pool2
.
pending
))
}
if
len
(
pool1
.
queue
[
account1
])
!=
len
(
pool2
.
queue
[
account2
])
{
t
.
Errorf
(
"queued transaction count mismatch: one-by-one algo: %d, batch algo: %d"
,
len
(
pool1
.
queue
[
account1
]),
len
(
pool2
.
queue
[
account2
]))
}
}
// Benchmarks the speed of validating the contents of the pending queue of the
// transaction pool.
func
BenchmarkValidatePool100
(
b
*
testing
.
B
)
{
benchmarkValidatePool
(
b
,
100
)
}
func
BenchmarkValidatePool1000
(
b
*
testing
.
B
)
{
benchmarkValidatePool
(
b
,
1000
)
}
func
BenchmarkValidatePool10000
(
b
*
testing
.
B
)
{
benchmarkValidatePool
(
b
,
10000
)
}
func
benchmarkValidatePool
(
b
*
testing
.
B
,
size
int
)
{
// Add a batch of transactions to a pool one by one
pool
,
key
:=
setupTxPool
()
account
,
_
:=
transaction
(
0
,
big
.
NewInt
(
0
),
key
)
.
From
()
state
,
_
:=
pool
.
currentState
()
state
.
AddBalance
(
account
,
big
.
NewInt
(
1000000
))
for
i
:=
0
;
i
<
size
;
i
++
{
tx
:=
transaction
(
uint64
(
i
),
big
.
NewInt
(
100000
),
key
)
pool
.
addTx
(
tx
.
Hash
(),
account
,
tx
)
}
// Benchmark the speed of pool validation
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
pool
.
validatePool
()
}
}
// Benchmarks the speed of scheduling the contents of the future queue of the
// transaction pool.
func
BenchmarkCheckQueue100
(
b
*
testing
.
B
)
{
benchmarkCheckQueue
(
b
,
100
)
}
func
BenchmarkCheckQueue1000
(
b
*
testing
.
B
)
{
benchmarkCheckQueue
(
b
,
1000
)
}
func
BenchmarkCheckQueue10000
(
b
*
testing
.
B
)
{
benchmarkCheckQueue
(
b
,
10000
)
}
func
benchmarkCheckQueue
(
b
*
testing
.
B
,
size
int
)
{
// Add a batch of transactions to a pool one by one
pool
,
key
:=
setupTxPool
()
account
,
_
:=
transaction
(
0
,
big
.
NewInt
(
0
),
key
)
.
From
()
state
,
_
:=
pool
.
currentState
()
state
.
AddBalance
(
account
,
big
.
NewInt
(
1000000
))
for
i
:=
0
;
i
<
size
;
i
++
{
tx
:=
transaction
(
uint64
(
1
+
i
),
big
.
NewInt
(
100000
),
key
)
pool
.
queueTx
(
tx
.
Hash
(),
tx
)
}
// Benchmark the speed of pool validation
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
pool
.
checkQueue
()
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录