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
48ee7f9d
Unverified
Commit
48ee7f9d
authored
Jul 05, 2017
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core, eth, les: polish txpool API around local/remote txs
parent
a633a2d7
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
153 additions
and
149 deletions
+153
-149
tx_list.go
core/tx_list.go
+6
-10
tx_pool.go
core/tx_pool.go
+86
-71
tx_pool_test.go
core/tx_pool_test.go
+51
-57
api_backend.go
eth/api_backend.go
+1
-2
handler.go
eth/handler.go
+1
-1
helper_test.go
eth/helper_test.go
+2
-2
protocol.go
eth/protocol.go
+2
-2
protocol_test.go
eth/protocol_test.go
+1
-1
handler.go
les/handler.go
+3
-3
No files found.
core/tx_list.go
View file @
48ee7f9d
...
...
@@ -420,7 +420,7 @@ func (l *txPricedList) Removed() {
heap
.
Init
(
l
.
items
)
}
//
Discard
finds all the transactions below the given price threshold, drops them
//
Cap
finds all the transactions below the given price threshold, drops them
// from the priced list and returs them for further removal from the entire pool.
func
(
l
*
txPricedList
)
Cap
(
threshold
*
big
.
Int
,
local
*
accountSet
)
types
.
Transactions
{
drop
:=
make
(
types
.
Transactions
,
0
,
128
)
// Remote underpriced transactions to drop
...
...
@@ -429,9 +429,7 @@ func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transact
for
len
(
*
l
.
items
)
>
0
{
// Discard stale transactions if found during cleanup
tx
:=
heap
.
Pop
(
l
.
items
)
.
(
*
types
.
Transaction
)
hash
:=
tx
.
Hash
()
if
_
,
ok
:=
(
*
l
.
all
)[
hash
];
!
ok
{
if
_
,
ok
:=
(
*
l
.
all
)[
tx
.
Hash
()];
!
ok
{
l
.
stales
--
continue
}
...
...
@@ -440,7 +438,7 @@ func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transact
break
}
// Non stale transaction found, discard unless local
if
local
.
contains
(
tx
)
{
if
local
.
contains
Tx
(
tx
)
{
save
=
append
(
save
,
tx
)
}
else
{
drop
=
append
(
drop
,
tx
)
...
...
@@ -456,7 +454,7 @@ func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transact
// lowest priced transaction currently being tracked.
func
(
l
*
txPricedList
)
Underpriced
(
tx
*
types
.
Transaction
,
local
*
accountSet
)
bool
{
// Local transactions cannot be underpriced
if
local
.
contains
(
tx
)
{
if
local
.
contains
Tx
(
tx
)
{
return
false
}
// Discard stale price points if found at the heap start
...
...
@@ -487,14 +485,12 @@ func (l *txPricedList) Discard(count int, local *accountSet) types.Transactions
for
len
(
*
l
.
items
)
>
0
&&
count
>
0
{
// Discard stale transactions if found during cleanup
tx
:=
heap
.
Pop
(
l
.
items
)
.
(
*
types
.
Transaction
)
hash
:=
tx
.
Hash
()
if
_
,
ok
:=
(
*
l
.
all
)[
hash
];
!
ok
{
if
_
,
ok
:=
(
*
l
.
all
)[
tx
.
Hash
()];
!
ok
{
l
.
stales
--
continue
}
// Non stale transaction found, discard unless local
if
local
.
contains
(
tx
)
{
if
local
.
contains
Tx
(
tx
)
{
save
=
append
(
save
,
tx
)
}
else
{
drop
=
append
(
drop
,
tx
)
...
...
core/tx_pool.go
View file @
48ee7f9d
...
...
@@ -176,12 +176,12 @@ type TxPool struct {
func
NewTxPool
(
config
TxPoolConfig
,
chainconfig
*
params
.
ChainConfig
,
eventMux
*
event
.
TypeMux
,
currentStateFn
stateFn
,
gasLimitFn
func
()
*
big
.
Int
)
*
TxPool
{
// Sanitize the input to ensure no vulnerable gas prices are set
config
=
(
&
config
)
.
sanitize
()
signer
:=
types
.
NewEIP155Signer
(
chainconfig
.
ChainId
)
// Create the transaction pool with its initial settings
pool
:=
&
TxPool
{
config
:
config
,
chainconfig
:
chainconfig
,
signer
:
signer
,
signer
:
types
.
NewEIP155Signer
(
chainconfig
.
ChainId
)
,
pending
:
make
(
map
[
common
.
Address
]
*
txList
),
queue
:
make
(
map
[
common
.
Address
]
*
txList
),
beats
:
make
(
map
[
common
.
Address
]
time
.
Time
),
...
...
@@ -191,10 +191,10 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, eventMux *e
gasLimit
:
gasLimitFn
,
gasPrice
:
new
(
big
.
Int
)
.
SetUint64
(
config
.
PriceLimit
),
pendingState
:
nil
,
locals
:
newAccountSet
(
signer
),
events
:
eventMux
.
Subscribe
(
ChainHeadEvent
{},
RemovedTransactionEvent
{}),
quit
:
make
(
chan
struct
{}),
}
pool
.
locals
=
newAccountSet
(
pool
.
signer
)
pool
.
priced
=
newTxPricedList
(
&
pool
.
all
)
pool
.
resetState
()
...
...
@@ -237,7 +237,7 @@ func (pool *TxPool) eventLoop() {
pool
.
mu
.
Unlock
()
case
RemovedTransactionEvent
:
pool
.
AddBatch
(
ev
.
Txs
)
pool
.
addTxs
(
ev
.
Txs
,
false
)
}
// Handle stats reporting ticks
...
...
@@ -371,52 +371,40 @@ func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
return
pending
,
nil
}
// SetLocal marks a transaction as local, skipping gas price
// check against local miner minimum in the future
func
(
pool
*
TxPool
)
SetLocal
(
tx
*
types
.
Transaction
)
{
pool
.
mu
.
Lock
()
defer
pool
.
mu
.
Unlock
()
pool
.
locals
.
add
(
tx
)
}
// validateTx checks whether a transaction is valid according
// to the consensus rules.
func
(
pool
*
TxPool
)
validateTx
(
tx
*
types
.
Transaction
)
error
{
// validateTx checks whether a transaction is valid according to the consensus
// rules and adheres to some heuristic limits of the local node (price and size).
func
(
pool
*
TxPool
)
validateTx
(
tx
*
types
.
Transaction
,
local
bool
)
error
{
// Heuristic limit, reject transactions over 32KB to prevent DOS attacks
if
tx
.
Size
()
>
32
*
1024
{
return
ErrOversizedData
}
// Transactions can't be negative. This may never happen using RLP decoded
// transactions but may occur if you create a transaction using the RPC.
if
tx
.
Value
()
.
Sign
()
<
0
{
return
ErrNegativeValue
}
// Ensure the transaction doesn't exceed the current block limit gas.
if
pool
.
gasLimit
()
.
Cmp
(
tx
.
Gas
())
<
0
{
return
ErrGasLimit
}
// Make sure the transaction is signed properly
from
,
err
:=
types
.
Sender
(
pool
.
signer
,
tx
)
if
err
!=
nil
{
return
ErrInvalidSender
}
local
:=
pool
.
locals
.
containsAddress
(
from
)
// Drop transactions under our own minimal accepted gas price
// Drop non-local transactions under our own minimal accepted gas price
local
=
local
||
pool
.
locals
.
contains
(
from
)
// account may be local even if the transaction arrived from the network
if
!
local
&&
pool
.
gasPrice
.
Cmp
(
tx
.
GasPrice
())
>
0
{
return
ErrUnderpriced
}
// Ensure the transaction adheres to nonce ordering
currentState
,
err
:=
pool
.
currentState
()
if
err
!=
nil
{
return
err
}
// Last but not least check for nonce errors
if
currentState
.
GetNonce
(
from
)
>
tx
.
Nonce
()
{
return
ErrNonceTooLow
}
// Check the transaction doesn't exceed the current
// block limit gas.
if
pool
.
gasLimit
()
.
Cmp
(
tx
.
Gas
())
<
0
{
return
ErrGasLimit
}
// Transactions can't be negative. This may never happen
// using RLP decoded transactions but may occur if you create
// a transaction using the RPC for example.
if
tx
.
Value
()
.
Sign
()
<
0
{
return
ErrNegativeValue
}
// Transactor should have enough funds to cover the costs
// cost == V + GP * GL
if
currentState
.
GetBalance
(
from
)
.
Cmp
(
tx
.
Cost
())
<
0
{
...
...
@@ -426,11 +414,6 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
if
tx
.
Gas
()
.
Cmp
(
intrGas
)
<
0
{
return
ErrIntrinsicGas
}
// Heuristic limit, reject transactions over 32KB to prevent DOS attacks
if
tx
.
Size
()
>
32
*
1024
{
return
ErrOversizedData
}
return
nil
}
...
...
@@ -438,7 +421,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
// later pending promotion and execution. If the transaction is a replacement for
// an already pending or queued one, it overwrites the previous and returns this
// so outer code doesn't uselessly call promote.
func
(
pool
*
TxPool
)
add
(
tx
*
types
.
Transaction
)
(
bool
,
error
)
{
//
// If a newly added transaction is marked as local, its sending account will be
// whitelisted, preventing any associated transaction from being dropped out of
// the pool due to pricing constraints.
func
(
pool
*
TxPool
)
add
(
tx
*
types
.
Transaction
,
local
bool
)
(
bool
,
error
)
{
// If the transaction is already known, discard it
hash
:=
tx
.
Hash
()
if
pool
.
all
[
hash
]
!=
nil
{
...
...
@@ -446,7 +433,7 @@ func (pool *TxPool) add(tx *types.Transaction) (bool, error) {
return
false
,
fmt
.
Errorf
(
"known transaction: %x"
,
hash
)
}
// If the transaction fails basic validation, discard it
if
err
:=
pool
.
validateTx
(
tx
);
err
!=
nil
{
if
err
:=
pool
.
validateTx
(
tx
,
local
);
err
!=
nil
{
log
.
Trace
(
"Discarding invalid transaction"
,
"hash"
,
hash
,
"err"
,
err
)
invalidTxCounter
.
Inc
(
1
)
return
false
,
err
...
...
@@ -488,11 +475,14 @@ func (pool *TxPool) add(tx *types.Transaction) (bool, error) {
log
.
Trace
(
"Pooled new executable transaction"
,
"hash"
,
hash
,
"from"
,
from
,
"to"
,
tx
.
To
())
return
old
!=
nil
,
nil
}
// New transaction isn't replacing a pending one, push into queue
// New transaction isn't replacing a pending one, push into queue
and potentially mark local
replace
,
err
:=
pool
.
enqueueTx
(
hash
,
tx
)
if
err
!=
nil
{
return
false
,
err
}
if
local
{
pool
.
locals
.
add
(
from
)
}
log
.
Trace
(
"Pooled new future transaction"
,
"hash"
,
hash
,
"from"
,
from
,
"to"
,
tx
.
To
())
return
replace
,
nil
}
...
...
@@ -560,13 +550,41 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T
go
pool
.
eventMux
.
Post
(
TxPreEvent
{
tx
})
}
// Add queues a single transaction in the pool if it is valid.
func
(
pool
*
TxPool
)
Add
(
tx
*
types
.
Transaction
)
error
{
// AddLocal enqueues a single transaction into the pool if it is valid, marking
// the sender as a local one in the mean time, ensuring it goes around the local
// pricing constraints.
func
(
pool
*
TxPool
)
AddLocal
(
tx
*
types
.
Transaction
)
error
{
return
pool
.
addTx
(
tx
,
true
)
}
// AddRemote enqueues a single transaction into the pool if it is valid. If the
// sender is not among the locally tracked ones, full pricing constraints will
// apply.
func
(
pool
*
TxPool
)
AddRemote
(
tx
*
types
.
Transaction
)
error
{
return
pool
.
addTx
(
tx
,
false
)
}
// AddLocals enqueues a batch of transactions into the pool if they are valid,
// marking the senders as a local ones in the mean time, ensuring they go around
// the local pricing constraints.
func
(
pool
*
TxPool
)
AddLocals
(
txs
[]
*
types
.
Transaction
)
error
{
return
pool
.
addTxs
(
txs
,
true
)
}
// AddRemotes enqueues a batch of transactions into the pool if they are valid.
// If the senders are not among the locally tracked ones, full pricing constraints
// will apply.
func
(
pool
*
TxPool
)
AddRemotes
(
txs
[]
*
types
.
Transaction
)
error
{
return
pool
.
addTxs
(
txs
,
false
)
}
// addTx enqueues a single transaction into the pool if it is valid.
func
(
pool
*
TxPool
)
addTx
(
tx
*
types
.
Transaction
,
local
bool
)
error
{
pool
.
mu
.
Lock
()
defer
pool
.
mu
.
Unlock
()
// Try to inject the transaction and update any state
replace
,
err
:=
pool
.
add
(
tx
)
replace
,
err
:=
pool
.
add
(
tx
,
local
)
if
err
!=
nil
{
return
err
}
...
...
@@ -582,15 +600,15 @@ func (pool *TxPool) Add(tx *types.Transaction) error {
return
nil
}
//
AddBatch attempts to queue a batch of transactions
.
func
(
pool
*
TxPool
)
AddBatch
(
txs
[]
*
types
.
Transaction
)
error
{
//
addTxs attempts to queue a batch of transactions if they are valid
.
func
(
pool
*
TxPool
)
addTxs
(
txs
[]
*
types
.
Transaction
,
local
bool
)
error
{
pool
.
mu
.
Lock
()
defer
pool
.
mu
.
Unlock
()
// Add the batch of transaction, tracking the accepted ones
dirty
:=
make
(
map
[
common
.
Address
]
struct
{})
for
_
,
tx
:=
range
txs
{
if
replace
,
err
:=
pool
.
add
(
tx
);
err
==
nil
{
if
replace
,
err
:=
pool
.
add
(
tx
,
local
);
err
==
nil
{
if
!
replace
{
from
,
_
:=
types
.
Sender
(
pool
.
signer
,
tx
)
// already validated
dirty
[
from
]
=
struct
{}{}
...
...
@@ -725,7 +743,7 @@ func (pool *TxPool) promoteExecutables(state *state.StateDB, accounts []common.A
pool
.
promoteTx
(
addr
,
hash
,
tx
)
}
// Drop all transactions over the allowed limit
if
!
pool
.
locals
.
contains
Address
(
addr
)
{
if
!
pool
.
locals
.
contains
(
addr
)
{
for
_
,
tx
:=
range
list
.
Cap
(
int
(
pool
.
config
.
AccountQueue
))
{
hash
:=
tx
.
Hash
()
delete
(
pool
.
all
,
hash
)
...
...
@@ -752,7 +770,7 @@ func (pool *TxPool) promoteExecutables(state *state.StateDB, accounts []common.A
spammers
:=
prque
.
New
()
for
addr
,
list
:=
range
pool
.
pending
{
// Only evict transactions from high rollers
if
!
pool
.
locals
.
contains
Address
(
addr
)
&&
uint64
(
list
.
Len
())
>
pool
.
config
.
AccountSlots
{
if
!
pool
.
locals
.
contains
(
addr
)
&&
uint64
(
list
.
Len
())
>
pool
.
config
.
AccountSlots
{
spammers
.
Push
(
addr
,
float32
(
list
.
Len
()))
}
}
...
...
@@ -818,7 +836,7 @@ func (pool *TxPool) promoteExecutables(state *state.StateDB, accounts []common.A
addresses
:=
make
(
addresssByHeartbeat
,
0
,
len
(
pool
.
queue
))
for
addr
:=
range
pool
.
queue
{
// Don't drop locals
if
!
pool
.
locals
.
contains
Address
(
addr
)
{
if
!
pool
.
locals
.
contains
(
addr
)
{
addresses
=
append
(
addresses
,
addressByHeartbeat
{
addr
,
pool
.
beats
[
addr
]})
}
}
...
...
@@ -930,13 +948,15 @@ func (a addresssByHeartbeat) Len() int { return len(a) }
func
(
a
addresssByHeartbeat
)
Less
(
i
,
j
int
)
bool
{
return
a
[
i
]
.
heartbeat
.
Before
(
a
[
j
]
.
heartbeat
)
}
func
(
a
addresssByHeartbeat
)
Swap
(
i
,
j
int
)
{
a
[
i
],
a
[
j
]
=
a
[
j
],
a
[
i
]
}
// accountSet is simply a
map of addresses, and a signer, to be able
//
to determine the address from a tx
// accountSet is simply a
set of addresses to check for existance, and a signer
//
capable of deriving addresses from transactions.
type
accountSet
struct
{
accounts
map
[
common
.
Address
]
struct
{}
signer
types
.
Signer
}
// newAccountSet creates a new address set with an associated signer for sender
// derivations.
func
newAccountSet
(
signer
types
.
Signer
)
*
accountSet
{
return
&
accountSet
{
accounts
:
make
(
map
[
common
.
Address
]
struct
{}),
...
...
@@ -944,27 +964,22 @@ func newAccountSet(signer types.Signer) *accountSet {
}
}
// contains
Address checks if a given address is within the set
func
(
as
*
accountSet
)
contains
Address
(
address
common
.
Address
)
bool
{
_
,
exist
:=
as
.
accounts
[
addr
ess
]
// contains
checks if a given address is contained within the set.
func
(
as
*
accountSet
)
contains
(
addr
common
.
Address
)
bool
{
_
,
exist
:=
as
.
accounts
[
addr
]
return
exist
}
// contains checks if the sender of a given tx is within the set
func
(
as
*
accountSet
)
contains
(
tx
*
types
.
Transaction
)
bool
{
if
address
,
err
:=
types
.
Sender
(
as
.
signer
,
tx
);
err
==
nil
{
return
as
.
containsAddress
(
address
)
// containsTx checks if the sender of a given tx is within the set. If the sender
// cannot be derived, this method returns false.
func
(
as
*
accountSet
)
containsTx
(
tx
*
types
.
Transaction
)
bool
{
if
addr
,
err
:=
types
.
Sender
(
as
.
signer
,
tx
);
err
==
nil
{
return
as
.
contains
(
addr
)
}
return
false
}
// add a transaction sender to the set
// if sender can't be derived, this is a no-op (no errors returned)
func
(
as
*
accountSet
)
add
(
tx
*
types
.
Transaction
)
{
if
address
,
err
:=
types
.
Sender
(
as
.
signer
,
tx
);
err
==
nil
{
if
_
,
exist
:=
as
.
accounts
[
address
];
!
exist
{
as
.
accounts
[
address
]
=
struct
{}{}
}
}
// add inserts a new address into the set to track.
func
(
as
*
accountSet
)
add
(
addr
common
.
Address
)
{
as
.
accounts
[
addr
]
=
struct
{}{}
}
core/tx_pool_test.go
View file @
48ee7f9d
...
...
@@ -133,7 +133,7 @@ func TestStateChangeDuringPoolReset(t *testing.T) {
t
.
Fatalf
(
"Invalid nonce, want 0, got %d"
,
nonce
)
}
txpool
.
Add
Batch
(
types
.
Transactions
{
tx0
,
tx1
})
txpool
.
Add
Remotes
(
types
.
Transactions
{
tx0
,
tx1
})
nonce
=
txpool
.
State
()
.
GetNonce
(
address
)
if
nonce
!=
2
{
...
...
@@ -167,31 +167,29 @@ func TestInvalidTransactions(t *testing.T) {
from
,
_
:=
deriveSender
(
tx
)
currentState
,
_
:=
pool
.
currentState
()
currentState
.
AddBalance
(
from
,
big
.
NewInt
(
1
))
if
err
:=
pool
.
Add
(
tx
);
err
!=
ErrInsufficientFunds
{
if
err
:=
pool
.
Add
Remote
(
tx
);
err
!=
ErrInsufficientFunds
{
t
.
Error
(
"expected"
,
ErrInsufficientFunds
)
}
balance
:=
new
(
big
.
Int
)
.
Add
(
tx
.
Value
(),
new
(
big
.
Int
)
.
Mul
(
tx
.
Gas
(),
tx
.
GasPrice
()))
currentState
.
AddBalance
(
from
,
balance
)
if
err
:=
pool
.
Add
(
tx
);
err
!=
ErrIntrinsicGas
{
if
err
:=
pool
.
Add
Remote
(
tx
);
err
!=
ErrIntrinsicGas
{
t
.
Error
(
"expected"
,
ErrIntrinsicGas
,
"got"
,
err
)
}
currentState
.
SetNonce
(
from
,
1
)
currentState
.
AddBalance
(
from
,
big
.
NewInt
(
0xffffffffffffff
))
tx
=
transaction
(
0
,
big
.
NewInt
(
100000
),
key
)
if
err
:=
pool
.
Add
(
tx
);
err
!=
ErrNonceTooLow
{
if
err
:=
pool
.
Add
Remote
(
tx
);
err
!=
ErrNonceTooLow
{
t
.
Error
(
"expected"
,
ErrNonceTooLow
)
}
tx
=
transaction
(
1
,
big
.
NewInt
(
100000
),
key
)
pool
.
gasPrice
=
big
.
NewInt
(
1000
)
if
err
:=
pool
.
Add
(
tx
);
err
!=
ErrUnderpriced
{
if
err
:=
pool
.
Add
Remote
(
tx
);
err
!=
ErrUnderpriced
{
t
.
Error
(
"expected"
,
ErrUnderpriced
,
"got"
,
err
)
}
pool
.
SetLocal
(
tx
)
if
err
:=
pool
.
Add
(
tx
);
err
!=
nil
{
if
err
:=
pool
.
AddLocal
(
tx
);
err
!=
nil
{
t
.
Error
(
"expected"
,
nil
,
"got"
,
err
)
}
}
...
...
@@ -282,7 +280,7 @@ func TestNegativeValue(t *testing.T) {
from
,
_
:=
deriveSender
(
tx
)
currentState
,
_
:=
pool
.
currentState
()
currentState
.
AddBalance
(
from
,
big
.
NewInt
(
1
))
if
err
:=
pool
.
Add
(
tx
);
err
!=
ErrNegativeValue
{
if
err
:=
pool
.
Add
Remote
(
tx
);
err
!=
ErrNegativeValue
{
t
.
Error
(
"expected"
,
ErrNegativeValue
,
"got"
,
err
)
}
}
...
...
@@ -301,14 +299,14 @@ func TestTransactionChainFork(t *testing.T) {
resetState
()
tx
:=
transaction
(
0
,
big
.
NewInt
(
100000
),
key
)
if
_
,
err
:=
pool
.
add
(
tx
);
err
!=
nil
{
if
_
,
err
:=
pool
.
add
(
tx
,
false
);
err
!=
nil
{
t
.
Error
(
"didn't expect error"
,
err
)
}
pool
.
RemoveBatch
([]
*
types
.
Transaction
{
tx
})
// reset the pool's internal state
resetState
()
if
_
,
err
:=
pool
.
add
(
tx
);
err
!=
nil
{
if
_
,
err
:=
pool
.
add
(
tx
,
false
);
err
!=
nil
{
t
.
Error
(
"didn't expect error"
,
err
)
}
}
...
...
@@ -332,10 +330,10 @@ func TestTransactionDoubleNonce(t *testing.T) {
tx3
,
_
:=
types
.
SignTx
(
types
.
NewTransaction
(
0
,
common
.
Address
{},
big
.
NewInt
(
100
),
big
.
NewInt
(
1000000
),
big
.
NewInt
(
1
),
nil
),
signer
,
key
)
// Add the first two transaction, ensure higher priced stays only
if
replace
,
err
:=
pool
.
add
(
tx1
);
err
!=
nil
||
replace
{
if
replace
,
err
:=
pool
.
add
(
tx1
,
false
);
err
!=
nil
||
replace
{
t
.
Errorf
(
"first transaction insert failed (%v) or reported replacement (%v)"
,
err
,
replace
)
}
if
replace
,
err
:=
pool
.
add
(
tx2
);
err
!=
nil
||
!
replace
{
if
replace
,
err
:=
pool
.
add
(
tx2
,
false
);
err
!=
nil
||
!
replace
{
t
.
Errorf
(
"second transaction insert failed (%v) or not reported replacement (%v)"
,
err
,
replace
)
}
state
,
_
:=
pool
.
currentState
()
...
...
@@ -347,7 +345,7 @@ func TestTransactionDoubleNonce(t *testing.T) {
t
.
Errorf
(
"transaction mismatch: have %x, want %x"
,
tx
.
Hash
(),
tx2
.
Hash
())
}
// Add the third transaction and ensure it's not saved (smaller price)
pool
.
add
(
tx3
)
pool
.
add
(
tx3
,
false
)
pool
.
promoteExecutables
(
state
,
[]
common
.
Address
{
addr
})
if
pool
.
pending
[
addr
]
.
Len
()
!=
1
{
t
.
Error
(
"expected 1 pending transactions, got"
,
pool
.
pending
[
addr
]
.
Len
())
...
...
@@ -367,7 +365,7 @@ func TestMissingNonce(t *testing.T) {
currentState
,
_
:=
pool
.
currentState
()
currentState
.
AddBalance
(
addr
,
big
.
NewInt
(
100000000000000
))
tx
:=
transaction
(
1
,
big
.
NewInt
(
100000
),
key
)
if
_
,
err
:=
pool
.
add
(
tx
);
err
!=
nil
{
if
_
,
err
:=
pool
.
add
(
tx
,
false
);
err
!=
nil
{
t
.
Error
(
"didn't expect error"
,
err
)
}
if
len
(
pool
.
pending
)
!=
0
{
...
...
@@ -390,7 +388,7 @@ func TestNonceRecovery(t *testing.T) {
currentState
.
AddBalance
(
addr
,
big
.
NewInt
(
100000000000000
))
pool
.
resetState
()
tx
:=
transaction
(
n
,
big
.
NewInt
(
100000
),
key
)
if
err
:=
pool
.
Add
(
tx
);
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
tx
);
err
!=
nil
{
t
.
Error
(
err
)
}
// simulate some weird re-order of transactions and missing nonce(s)
...
...
@@ -598,7 +596,7 @@ func TestTransactionQueueAccountLimiting(t *testing.T) {
// Keep queuing up transactions and make sure all above a limit are dropped
for
i
:=
uint64
(
1
);
i
<=
DefaultTxPoolConfig
.
AccountQueue
+
5
;
i
++
{
if
err
:=
pool
.
Add
(
transaction
(
i
,
big
.
NewInt
(
100000
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
transaction
(
i
,
big
.
NewInt
(
100000
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"tx %d: failed to add transaction: %v"
,
i
,
err
)
}
if
len
(
pool
.
pending
)
!=
0
{
...
...
@@ -653,7 +651,7 @@ func TestTransactionQueueGlobalLimiting(t *testing.T) {
nonces
[
addr
]
++
}
// Import the batch and verify that limits have been enforced
pool
.
Add
Batch
(
txs
)
pool
.
Add
Remotes
(
txs
)
queued
:=
0
for
addr
,
list
:=
range
pool
.
queue
{
...
...
@@ -686,7 +684,7 @@ func TestTransactionQueueTimeLimiting(t *testing.T) {
// Queue up a batch of transactions
for
i
:=
uint64
(
1
);
i
<=
DefaultTxPoolConfig
.
AccountQueue
;
i
++
{
if
err
:=
pool
.
Add
(
transaction
(
i
,
big
.
NewInt
(
100000
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
transaction
(
i
,
big
.
NewInt
(
100000
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"tx %d: failed to add transaction: %v"
,
i
,
err
)
}
}
...
...
@@ -711,7 +709,7 @@ func TestTransactionPendingLimiting(t *testing.T) {
// Keep queuing up transactions and make sure all above a limit are dropped
for
i
:=
uint64
(
0
);
i
<
DefaultTxPoolConfig
.
AccountQueue
+
5
;
i
++
{
if
err
:=
pool
.
Add
(
transaction
(
i
,
big
.
NewInt
(
100000
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
transaction
(
i
,
big
.
NewInt
(
100000
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"tx %d: failed to add transaction: %v"
,
i
,
err
)
}
if
pool
.
pending
[
account
]
.
Len
()
!=
int
(
i
)
+
1
{
...
...
@@ -739,7 +737,7 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
state1
.
AddBalance
(
account1
,
big
.
NewInt
(
1000000
))
for
i
:=
uint64
(
0
);
i
<
DefaultTxPoolConfig
.
AccountQueue
+
5
;
i
++
{
if
err
:=
pool1
.
Add
(
transaction
(
origin
+
i
,
big
.
NewInt
(
100000
),
key1
));
err
!=
nil
{
if
err
:=
pool1
.
Add
Remote
(
transaction
(
origin
+
i
,
big
.
NewInt
(
100000
),
key1
));
err
!=
nil
{
t
.
Fatalf
(
"tx %d: failed to add transaction: %v"
,
i
,
err
)
}
}
...
...
@@ -753,7 +751,7 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
for
i
:=
uint64
(
0
);
i
<
DefaultTxPoolConfig
.
AccountQueue
+
5
;
i
++
{
txns
=
append
(
txns
,
transaction
(
origin
+
i
,
big
.
NewInt
(
100000
),
key2
))
}
pool2
.
Add
Batch
(
txns
)
pool2
.
Add
Remotes
(
txns
)
// Ensure the batch optimization honors the same pool mechanics
if
len
(
pool1
.
pending
)
!=
len
(
pool2
.
pending
)
{
...
...
@@ -808,7 +806,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
}
}
// Import the batch and verify that limits have been enforced
pool
.
Add
Batch
(
txs
)
pool
.
Add
Remotes
(
txs
)
pending
:=
0
for
_
,
list
:=
range
pool
.
pending
{
...
...
@@ -852,7 +850,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
txs
=
append
(
txs
,
transaction
(
uint64
(
j
),
big
.
NewInt
(
100000
),
key
))
}
// Import the batch and verify that limits have been enforced
pool
.
Add
Batch
(
txs
)
pool
.
Add
Remotes
(
txs
)
if
err
:=
validateTxPoolInternals
(
pool
);
err
!=
nil
{
t
.
Fatalf
(
"pool internal state corrupted: %v"
,
err
)
}
...
...
@@ -893,7 +891,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
}
}
// Import the batch and verify that limits have been enforced
pool
.
Add
Batch
(
txs
)
pool
.
Add
Remotes
(
txs
)
for
addr
,
list
:=
range
pool
.
pending
{
if
list
.
Len
()
!=
int
(
DefaultTxPoolConfig
.
AccountSlots
)
{
...
...
@@ -937,11 +935,11 @@ func TestTransactionPoolRepricing(t *testing.T) {
txs
=
append
(
txs
,
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
1
]))
txs
=
append
(
txs
,
pricedTransaction
(
3
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
2
),
keys
[
1
]))
txs
=
append
(
txs
,
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
2
]))
pool
.
SetLocal
(
txs
[
len
(
txs
)
-
1
])
// prevent this one from ever being dropped
ltx
:=
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
2
])
// Import the batch and that both pending and queued transactions match up
pool
.
AddBatch
(
txs
)
pool
.
AddRemotes
(
txs
)
pool
.
AddLocal
(
ltx
)
pending
,
queued
:=
pool
.
stats
()
if
pending
!=
4
{
...
...
@@ -967,10 +965,10 @@ func TestTransactionPoolRepricing(t *testing.T) {
t
.
Fatalf
(
"pool internal state corrupted: %v"
,
err
)
}
// Check that we can't add the old transactions back
if
err
:=
pool
.
Add
(
pricedTransaction
(
1
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
0
]));
err
!=
ErrUnderpriced
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
1
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
0
]));
err
!=
ErrUnderpriced
{
t
.
Fatalf
(
"adding underpriced pending transaction error mismatch: have %v, want %v"
,
err
,
ErrUnderpriced
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
1
]));
err
!=
ErrUnderpriced
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
1
]));
err
!=
ErrUnderpriced
{
t
.
Fatalf
(
"adding underpriced queued transaction error mismatch: have %v, want %v"
,
err
,
ErrUnderpriced
)
}
if
err
:=
validateTxPoolInternals
(
pool
);
err
!=
nil
{
...
...
@@ -978,9 +976,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
}
// However we can add local underpriced transactions
tx
:=
pricedTransaction
(
1
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
2
])
pool
.
SetLocal
(
tx
)
// prevent this one from ever being dropped
if
err
:=
pool
.
Add
(
tx
);
err
!=
nil
{
if
err
:=
pool
.
AddLocal
(
tx
);
err
!=
nil
{
t
.
Fatalf
(
"failed to add underpriced local transaction: %v"
,
err
)
}
if
pending
,
_
=
pool
.
stats
();
pending
!=
3
{
...
...
@@ -1027,11 +1023,11 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
txs
=
append
(
txs
,
pricedTransaction
(
1
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
1
]))
txs
=
append
(
txs
,
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
2
]))
pool
.
SetLocal
(
txs
[
len
(
txs
)
-
1
])
// prevent this one from ever being dropped
ltx
:=
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
2
])
// Import the batch and that both pending and queued transactions match up
pool
.
AddBatch
(
txs
)
pool
.
AddRemotes
(
txs
)
pool
.
AddLocal
(
ltx
)
pending
,
queued
:=
pool
.
stats
()
if
pending
!=
3
{
...
...
@@ -1044,17 +1040,17 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
t
.
Fatalf
(
"pool internal state corrupted: %v"
,
err
)
}
// Ensure that adding an underpriced transaction on block limit fails
if
err
:=
pool
.
Add
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
1
]));
err
!=
ErrUnderpriced
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
keys
[
1
]));
err
!=
ErrUnderpriced
{
t
.
Fatalf
(
"adding underpriced pending transaction error mismatch: have %v, want %v"
,
err
,
ErrUnderpriced
)
}
// Ensure that adding high priced transactions drops cheap ones, but not own
if
err
:=
pool
.
Add
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
3
),
keys
[
1
]));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
3
),
keys
[
1
]));
err
!=
nil
{
t
.
Fatalf
(
"failed to add well priced transaction: %v"
,
err
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
4
),
keys
[
1
]));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
4
),
keys
[
1
]));
err
!=
nil
{
t
.
Fatalf
(
"failed to add well priced transaction: %v"
,
err
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
3
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
5
),
keys
[
1
]));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
3
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
5
),
keys
[
1
]));
err
!=
nil
{
t
.
Fatalf
(
"failed to add well priced transaction: %v"
,
err
)
}
pending
,
queued
=
pool
.
stats
()
...
...
@@ -1069,9 +1065,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
}
// Ensure that adding local transactions can push out even higher priced ones
tx
:=
pricedTransaction
(
1
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
0
),
keys
[
2
])
pool
.
SetLocal
(
tx
)
// prevent this one from ever being dropped
if
err
:=
pool
.
Add
(
tx
);
err
!=
nil
{
if
err
:=
pool
.
AddLocal
(
tx
);
err
!=
nil
{
t
.
Fatalf
(
"failed to add underpriced local transaction: %v"
,
err
)
}
pending
,
queued
=
pool
.
stats
()
...
...
@@ -1106,43 +1100,43 @@ func TestTransactionReplacement(t *testing.T) {
price
:=
int64
(
100
)
threshold
:=
(
price
*
(
100
+
int64
(
DefaultTxPoolConfig
.
PriceBump
)))
/
100
if
err
:=
pool
.
Add
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"failed to add original cheap pending transaction: %v"
,
err
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
0
,
big
.
NewInt
(
100001
),
big
.
NewInt
(
1
),
key
));
err
!=
ErrReplaceUnderpriced
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
0
,
big
.
NewInt
(
100001
),
big
.
NewInt
(
1
),
key
));
err
!=
ErrReplaceUnderpriced
{
t
.
Fatalf
(
"original cheap pending transaction replacement error mismatch: have %v, want %v"
,
err
,
ErrReplaceUnderpriced
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
2
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
2
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"failed to replace original cheap pending transaction: %v"
,
err
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
price
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
price
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"failed to add original proper pending transaction: %v"
,
err
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
threshold
),
key
));
err
!=
ErrReplaceUnderpriced
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
threshold
),
key
));
err
!=
ErrReplaceUnderpriced
{
t
.
Fatalf
(
"original proper pending transaction replacement error mismatch: have %v, want %v"
,
err
,
ErrReplaceUnderpriced
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
threshold
+
1
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
0
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
threshold
+
1
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"failed to replace original proper pending transaction: %v"
,
err
)
}
// Add queued transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
if
err
:=
pool
.
Add
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
1
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"failed to add original queued transaction: %v"
,
err
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
2
,
big
.
NewInt
(
100001
),
big
.
NewInt
(
1
),
key
));
err
!=
ErrReplaceUnderpriced
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
2
,
big
.
NewInt
(
100001
),
big
.
NewInt
(
1
),
key
));
err
!=
ErrReplaceUnderpriced
{
t
.
Fatalf
(
"original queued transaction replacement error mismatch: have %v, want %v"
,
err
,
ErrReplaceUnderpriced
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
2
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
2
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"failed to replace original queued transaction: %v"
,
err
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
price
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
price
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"failed to add original queued transaction: %v"
,
err
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
2
,
big
.
NewInt
(
100001
),
big
.
NewInt
(
threshold
),
key
));
err
!=
ErrReplaceUnderpriced
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
2
,
big
.
NewInt
(
100001
),
big
.
NewInt
(
threshold
),
key
));
err
!=
ErrReplaceUnderpriced
{
t
.
Fatalf
(
"original queued transaction replacement error mismatch: have %v, want %v"
,
err
,
ErrReplaceUnderpriced
)
}
if
err
:=
pool
.
Add
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
threshold
+
1
),
key
));
err
!=
nil
{
if
err
:=
pool
.
Add
Remote
(
pricedTransaction
(
2
,
big
.
NewInt
(
100000
),
big
.
NewInt
(
threshold
+
1
),
key
));
err
!=
nil
{
t
.
Fatalf
(
"failed to replace original queued transaction: %v"
,
err
)
}
if
err
:=
validateTxPoolInternals
(
pool
);
err
!=
nil
{
...
...
@@ -1213,7 +1207,7 @@ func BenchmarkPoolInsert(b *testing.B) {
// Benchmark importing the transactions into the queue
b
.
ResetTimer
()
for
_
,
tx
:=
range
txs
{
pool
.
Add
(
tx
)
pool
.
Add
Remote
(
tx
)
}
}
...
...
@@ -1239,6 +1233,6 @@ func benchmarkPoolBatchInsert(b *testing.B, size int) {
// Benchmark importing the transactions into the queue
b
.
ResetTimer
()
for
_
,
batch
:=
range
batches
{
pool
.
Add
Batch
(
batch
)
pool
.
Add
Remotes
(
batch
)
}
}
eth/api_backend.go
View file @
48ee7f9d
...
...
@@ -119,8 +119,7 @@ func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction)
b
.
eth
.
txMu
.
Lock
()
defer
b
.
eth
.
txMu
.
Unlock
()
b
.
eth
.
txPool
.
SetLocal
(
signedTx
)
return
b
.
eth
.
txPool
.
Add
(
signedTx
)
return
b
.
eth
.
txPool
.
AddLocal
(
signedTx
)
}
func
(
b
*
EthApiBackend
)
RemoveTx
(
txHash
common
.
Hash
)
{
...
...
eth/handler.go
View file @
48ee7f9d
...
...
@@ -661,7 +661,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
p
.
MarkTransaction
(
tx
.
Hash
())
}
pm
.
txpool
.
Add
Batch
(
txs
)
pm
.
txpool
.
Add
Remotes
(
txs
)
default
:
return
errResp
(
ErrInvalidMsgCode
,
"%v"
,
msg
.
Code
)
...
...
eth/helper_test.go
View file @
48ee7f9d
...
...
@@ -94,9 +94,9 @@ type testTxPool struct {
lock
sync
.
RWMutex
// Protects the transaction pool
}
// Add
Batch
appends a batch of transactions to the pool, and notifies any
// Add
Remotes
appends a batch of transactions to the pool, and notifies any
// listeners if the addition channel is non nil
func
(
p
*
testTxPool
)
Add
Batch
(
txs
[]
*
types
.
Transaction
)
error
{
func
(
p
*
testTxPool
)
Add
Remotes
(
txs
[]
*
types
.
Transaction
)
error
{
p
.
lock
.
Lock
()
defer
p
.
lock
.
Unlock
()
...
...
eth/protocol.go
View file @
48ee7f9d
...
...
@@ -94,8 +94,8 @@ var errorToString = map[int]string{
}
type
txPool
interface
{
// Add
Batch
should add the given transactions to the pool.
Add
Batch
([]
*
types
.
Transaction
)
error
// Add
Remotes
should add the given transactions to the pool.
Add
Remotes
([]
*
types
.
Transaction
)
error
// Pending should return pending transactions.
// The slice should be modifiable by the caller.
...
...
eth/protocol_test.go
View file @
48ee7f9d
...
...
@@ -130,7 +130,7 @@ func testSendTransactions(t *testing.T, protocol int) {
for
nonce
:=
range
alltxs
{
alltxs
[
nonce
]
=
newTestTransaction
(
testAccount
,
uint64
(
nonce
),
txsize
)
}
pm
.
txpool
.
Add
Batch
(
alltxs
)
pm
.
txpool
.
Add
Remotes
(
alltxs
)
// Connect several peers. They should all receive the pending transactions.
var
wg
sync
.
WaitGroup
...
...
les/handler.go
View file @
48ee7f9d
...
...
@@ -87,8 +87,8 @@ type BlockChain interface {
}
type
txPool
interface
{
// Add
Transaction
s should add the given transactions to the pool.
Add
Batch
([]
*
types
.
Transaction
)
error
// Add
Remote
s should add the given transactions to the pool.
Add
Remotes
([]
*
types
.
Transaction
)
error
}
type
ProtocolManager
struct
{
...
...
@@ -803,7 +803,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
return
errResp
(
ErrRequestRejected
,
""
)
}
if
err
:=
pm
.
txpool
.
Add
Batch
(
txs
);
err
!=
nil
{
if
err
:=
pm
.
txpool
.
Add
Remotes
(
txs
);
err
!=
nil
{
return
errResp
(
ErrUnexpectedResponse
,
"msg: %v"
,
err
)
}
...
...
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