Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
7b32d2a4
Unverified
Commit
7b32d2a4
authored
Sep 18, 2019
by
Péter Szilágyi
Committed by
GitHub
Sep 18, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #20085 from karalabe/txpool-api-fix
core: fix tx dedup return error count
parents
0ac9bbba
f40ff23b
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
90 additions
and
6 deletions
+90
-6
tx_pool.go
core/tx_pool.go
+25
-6
tx_pool_test.go
core/tx_pool_test.go
+65
-0
No files found.
core/tx_pool.go
View file @
7b32d2a4
...
...
@@ -766,21 +766,40 @@ func (pool *TxPool) AddRemote(tx *types.Transaction) error {
// addTxs attempts to queue a batch of transactions if they are valid.
func
(
pool
*
TxPool
)
addTxs
(
txs
[]
*
types
.
Transaction
,
local
,
sync
bool
)
[]
error
{
// Filter out known ones without obtaining the pool lock or recovering signatures
for
i
:=
0
;
i
<
len
(
txs
);
i
++
{
if
pool
.
all
.
Get
(
txs
[
i
]
.
Hash
())
!=
nil
{
var
(
errs
=
make
([]
error
,
len
(
txs
))
news
=
make
([]
*
types
.
Transaction
,
0
,
len
(
txs
))
)
for
i
,
tx
:=
range
txs
{
// If the transaction is known, pre-set the error slot
if
pool
.
all
.
Get
(
tx
.
Hash
())
!=
nil
{
errs
[
i
]
=
fmt
.
Errorf
(
"known transaction: %x"
,
tx
.
Hash
())
knownTxMeter
.
Mark
(
1
)
txs
=
append
(
txs
[
:
i
],
txs
[
i
+
1
:
]
...
)
i
--
continue
}
// Accumulate all unknown transactions for deeper processing
news
=
append
(
news
,
tx
)
}
if
len
(
news
)
==
0
{
return
errs
}
// Cache senders in transactions before obtaining lock (pool.signer is immutable)
for
_
,
tx
:=
range
tx
s
{
for
_
,
tx
:=
range
new
s
{
types
.
Sender
(
pool
.
signer
,
tx
)
}
// Process all the new transaction and merge any errors into the original slice
pool
.
mu
.
Lock
()
errs
,
dirtyAddrs
:=
pool
.
addTxsLocked
(
tx
s
,
local
)
newErrs
,
dirtyAddrs
:=
pool
.
addTxsLocked
(
new
s
,
local
)
pool
.
mu
.
Unlock
()
var
nilSlot
=
0
for
_
,
err
:=
range
newErrs
{
for
errs
[
nilSlot
]
!=
nil
{
nilSlot
++
}
errs
[
nilSlot
]
=
err
}
// Reorg the pool internals if needed and return
done
:=
pool
.
requestPromoteExecutables
(
dirtyAddrs
)
if
sync
{
<-
done
...
...
core/tx_pool_test.go
View file @
7b32d2a4
...
...
@@ -1438,6 +1438,71 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
}
}
// Tests that the pool rejects duplicate transactions.
func
TestTransactionDeduplication
(
t
*
testing
.
T
)
{
t
.
Parallel
()
// Create the pool to test the pricing enforcement with
statedb
,
_
:=
state
.
New
(
common
.
Hash
{},
state
.
NewDatabase
(
rawdb
.
NewMemoryDatabase
()))
blockchain
:=
&
testBlockChain
{
statedb
,
1000000
,
new
(
event
.
Feed
)}
pool
:=
NewTxPool
(
testTxPoolConfig
,
params
.
TestChainConfig
,
blockchain
)
defer
pool
.
Stop
()
// Create a test account to add transactions with
key
,
_
:=
crypto
.
GenerateKey
()
pool
.
currentState
.
AddBalance
(
crypto
.
PubkeyToAddress
(
key
.
PublicKey
),
big
.
NewInt
(
1000000000
))
// Create a batch of transactions and add a few of them
txs
:=
make
([]
*
types
.
Transaction
,
16
)
for
i
:=
0
;
i
<
len
(
txs
);
i
++
{
txs
[
i
]
=
pricedTransaction
(
uint64
(
i
),
100000
,
big
.
NewInt
(
1
),
key
)
}
var
firsts
[]
*
types
.
Transaction
for
i
:=
0
;
i
<
len
(
txs
);
i
+=
2
{
firsts
=
append
(
firsts
,
txs
[
i
])
}
errs
:=
pool
.
AddRemotesSync
(
firsts
)
if
len
(
errs
)
!=
len
(
firsts
)
{
t
.
Fatalf
(
"first add mismatching result count: have %d, want %d"
,
len
(
errs
),
len
(
firsts
))
}
for
i
,
err
:=
range
errs
{
if
err
!=
nil
{
t
.
Errorf
(
"add %d failed: %v"
,
i
,
err
)
}
}
pending
,
queued
:=
pool
.
Stats
()
if
pending
!=
1
{
t
.
Fatalf
(
"pending transactions mismatched: have %d, want %d"
,
pending
,
1
)
}
if
queued
!=
len
(
txs
)
/
2
-
1
{
t
.
Fatalf
(
"queued transactions mismatched: have %d, want %d"
,
queued
,
len
(
txs
)
/
2
-
1
)
}
// Try to add all of them now and ensure previous ones error out as knowns
errs
=
pool
.
AddRemotesSync
(
txs
)
if
len
(
errs
)
!=
len
(
txs
)
{
t
.
Fatalf
(
"all add mismatching result count: have %d, want %d"
,
len
(
errs
),
len
(
txs
))
}
for
i
,
err
:=
range
errs
{
if
i
%
2
==
0
&&
err
==
nil
{
t
.
Errorf
(
"add %d succeeded, should have failed as known"
,
i
)
}
if
i
%
2
==
1
&&
err
!=
nil
{
t
.
Errorf
(
"add %d failed: %v"
,
i
,
err
)
}
}
pending
,
queued
=
pool
.
Stats
()
if
pending
!=
len
(
txs
)
{
t
.
Fatalf
(
"pending transactions mismatched: have %d, want %d"
,
pending
,
len
(
txs
))
}
if
queued
!=
0
{
t
.
Fatalf
(
"queued transactions mismatched: have %d, want %d"
,
queued
,
0
)
}
if
err
:=
validateTxPoolInternals
(
pool
);
err
!=
nil
{
t
.
Fatalf
(
"pool internal state corrupted: %v"
,
err
)
}
}
// Tests that the pool rejects replacement transactions that don't meet the minimum
// price bump required.
func
TestTransactionReplacement
(
t
*
testing
.
T
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment