core: kill off managed state, use own tiny noncer for txpool
This commit is contained in:
parent
5873c01c3d
commit
a966425a1d
@ -1,143 +0,0 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package state
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
type account struct {
|
|
||||||
stateObject *stateObject
|
|
||||||
nstart uint64
|
|
||||||
nonces []bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type ManagedState struct {
|
|
||||||
*StateDB
|
|
||||||
|
|
||||||
mu sync.RWMutex
|
|
||||||
|
|
||||||
accounts map[common.Address]*account
|
|
||||||
}
|
|
||||||
|
|
||||||
// ManagedState returns a new managed state with the statedb as it's backing layer
|
|
||||||
func ManageState(statedb *StateDB) *ManagedState {
|
|
||||||
return &ManagedState{
|
|
||||||
StateDB: statedb.Copy(),
|
|
||||||
accounts: make(map[common.Address]*account),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetState sets the backing layer of the managed state
|
|
||||||
func (ms *ManagedState) SetState(statedb *StateDB) {
|
|
||||||
ms.mu.Lock()
|
|
||||||
defer ms.mu.Unlock()
|
|
||||||
ms.StateDB = statedb
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveNonce removed the nonce from the managed state and all future pending nonces
|
|
||||||
func (ms *ManagedState) RemoveNonce(addr common.Address, n uint64) {
|
|
||||||
if ms.hasAccount(addr) {
|
|
||||||
ms.mu.Lock()
|
|
||||||
defer ms.mu.Unlock()
|
|
||||||
|
|
||||||
account := ms.getAccount(addr)
|
|
||||||
if n-account.nstart <= uint64(len(account.nonces)) {
|
|
||||||
reslice := make([]bool, n-account.nstart)
|
|
||||||
copy(reslice, account.nonces[:n-account.nstart])
|
|
||||||
account.nonces = reslice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewNonce returns the new canonical nonce for the managed account
|
|
||||||
func (ms *ManagedState) NewNonce(addr common.Address) uint64 {
|
|
||||||
ms.mu.Lock()
|
|
||||||
defer ms.mu.Unlock()
|
|
||||||
|
|
||||||
account := ms.getAccount(addr)
|
|
||||||
for i, nonce := range account.nonces {
|
|
||||||
if !nonce {
|
|
||||||
return account.nstart + uint64(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
account.nonces = append(account.nonces, true)
|
|
||||||
|
|
||||||
return uint64(len(account.nonces)-1) + account.nstart
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNonce returns the canonical nonce for the managed or unmanaged account.
|
|
||||||
//
|
|
||||||
// Because GetNonce mutates the DB, we must take a write lock.
|
|
||||||
func (ms *ManagedState) GetNonce(addr common.Address) uint64 {
|
|
||||||
ms.mu.Lock()
|
|
||||||
defer ms.mu.Unlock()
|
|
||||||
|
|
||||||
if ms.hasAccount(addr) {
|
|
||||||
account := ms.getAccount(addr)
|
|
||||||
return uint64(len(account.nonces)) + account.nstart
|
|
||||||
} else {
|
|
||||||
return ms.StateDB.GetNonce(addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNonce sets the new canonical nonce for the managed state
|
|
||||||
func (ms *ManagedState) SetNonce(addr common.Address, nonce uint64) {
|
|
||||||
ms.mu.Lock()
|
|
||||||
defer ms.mu.Unlock()
|
|
||||||
|
|
||||||
so := ms.GetOrNewStateObject(addr)
|
|
||||||
so.SetNonce(nonce)
|
|
||||||
|
|
||||||
ms.accounts[addr] = newAccount(so)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasAccount returns whether the given address is managed or not
|
|
||||||
func (ms *ManagedState) HasAccount(addr common.Address) bool {
|
|
||||||
ms.mu.RLock()
|
|
||||||
defer ms.mu.RUnlock()
|
|
||||||
return ms.hasAccount(addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ms *ManagedState) hasAccount(addr common.Address) bool {
|
|
||||||
_, ok := ms.accounts[addr]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// populate the managed state
|
|
||||||
func (ms *ManagedState) getAccount(addr common.Address) *account {
|
|
||||||
if account, ok := ms.accounts[addr]; !ok {
|
|
||||||
so := ms.GetOrNewStateObject(addr)
|
|
||||||
ms.accounts[addr] = newAccount(so)
|
|
||||||
} else {
|
|
||||||
// Always make sure the state account nonce isn't actually higher
|
|
||||||
// than the tracked one.
|
|
||||||
so := ms.StateDB.getStateObject(addr)
|
|
||||||
if so != nil && uint64(len(account.nonces))+account.nstart < so.Nonce() {
|
|
||||||
ms.accounts[addr] = newAccount(so)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return ms.accounts[addr]
|
|
||||||
}
|
|
||||||
|
|
||||||
func newAccount(so *stateObject) *account {
|
|
||||||
return &account{so, so.Nonce(), nil}
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
// Copyright 2015 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package state
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
)
|
|
||||||
|
|
||||||
var addr = common.BytesToAddress([]byte("test"))
|
|
||||||
|
|
||||||
func create() (*ManagedState, *account) {
|
|
||||||
statedb, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
|
|
||||||
ms := ManageState(statedb)
|
|
||||||
ms.StateDB.SetNonce(addr, 100)
|
|
||||||
ms.accounts[addr] = newAccount(ms.StateDB.getStateObject(addr))
|
|
||||||
return ms, ms.accounts[addr]
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewNonce(t *testing.T) {
|
|
||||||
ms, _ := create()
|
|
||||||
|
|
||||||
nonce := ms.NewNonce(addr)
|
|
||||||
if nonce != 100 {
|
|
||||||
t.Error("expected nonce 100. got", nonce)
|
|
||||||
}
|
|
||||||
|
|
||||||
nonce = ms.NewNonce(addr)
|
|
||||||
if nonce != 101 {
|
|
||||||
t.Error("expected nonce 101. got", nonce)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRemove(t *testing.T) {
|
|
||||||
ms, account := create()
|
|
||||||
|
|
||||||
nn := make([]bool, 10)
|
|
||||||
for i := range nn {
|
|
||||||
nn[i] = true
|
|
||||||
}
|
|
||||||
account.nonces = append(account.nonces, nn...)
|
|
||||||
|
|
||||||
i := uint64(5)
|
|
||||||
ms.RemoveNonce(addr, account.nstart+i)
|
|
||||||
if len(account.nonces) != 5 {
|
|
||||||
t.Error("expected", i, "'th index to be false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReuse(t *testing.T) {
|
|
||||||
ms, account := create()
|
|
||||||
|
|
||||||
nn := make([]bool, 10)
|
|
||||||
for i := range nn {
|
|
||||||
nn[i] = true
|
|
||||||
}
|
|
||||||
account.nonces = append(account.nonces, nn...)
|
|
||||||
|
|
||||||
i := uint64(5)
|
|
||||||
ms.RemoveNonce(addr, account.nstart+i)
|
|
||||||
nonce := ms.NewNonce(addr)
|
|
||||||
if nonce != 105 {
|
|
||||||
t.Error("expected nonce to be 105. got", nonce)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRemoteNonceChange(t *testing.T) {
|
|
||||||
ms, account := create()
|
|
||||||
nn := make([]bool, 10)
|
|
||||||
for i := range nn {
|
|
||||||
nn[i] = true
|
|
||||||
}
|
|
||||||
account.nonces = append(account.nonces, nn...)
|
|
||||||
ms.NewNonce(addr)
|
|
||||||
|
|
||||||
ms.StateDB.stateObjects[addr].data.Nonce = 200
|
|
||||||
nonce := ms.NewNonce(addr)
|
|
||||||
if nonce != 200 {
|
|
||||||
t.Error("expected nonce after remote update to be", 200, "got", nonce)
|
|
||||||
}
|
|
||||||
ms.NewNonce(addr)
|
|
||||||
ms.NewNonce(addr)
|
|
||||||
ms.NewNonce(addr)
|
|
||||||
ms.StateDB.stateObjects[addr].data.Nonce = 200
|
|
||||||
nonce = ms.NewNonce(addr)
|
|
||||||
if nonce != 204 {
|
|
||||||
t.Error("expected nonce after remote update to be", 204, "got", nonce)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetNonce(t *testing.T) {
|
|
||||||
ms, _ := create()
|
|
||||||
|
|
||||||
var addr common.Address
|
|
||||||
ms.SetNonce(addr, 10)
|
|
||||||
|
|
||||||
if ms.GetNonce(addr) != 10 {
|
|
||||||
t.Error("Expected nonce of 10, got", ms.GetNonce(addr))
|
|
||||||
}
|
|
||||||
|
|
||||||
addr[0] = 1
|
|
||||||
ms.StateDB.SetNonce(addr, 1)
|
|
||||||
|
|
||||||
if ms.GetNonce(addr) != 1 {
|
|
||||||
t.Error("Expected nonce of 1, got", ms.GetNonce(addr))
|
|
||||||
}
|
|
||||||
}
|
|
53
core/tx_noncer.go
Normal file
53
core/tx_noncer.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2019 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
// txNoncer is a tiny virtual state database to manage the executable nonces of
|
||||||
|
// accounts in the pool, falling back to reading from a real state database if
|
||||||
|
// an account is unknown.
|
||||||
|
type txNoncer struct {
|
||||||
|
fallback *state.StateDB
|
||||||
|
nonces map[common.Address]uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// newTxNoncer creates a new virtual state database to track the pool nonces.
|
||||||
|
func newTxNoncer(statedb *state.StateDB) *txNoncer {
|
||||||
|
return &txNoncer{
|
||||||
|
fallback: statedb.Copy(),
|
||||||
|
nonces: make(map[common.Address]uint64),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get returns the current nonce of an account, falling back to a real state
|
||||||
|
// database if the account is unknown.
|
||||||
|
func (txn *txNoncer) get(addr common.Address) uint64 {
|
||||||
|
if _, ok := txn.nonces[addr]; !ok {
|
||||||
|
txn.nonces[addr] = txn.fallback.GetNonce(addr)
|
||||||
|
}
|
||||||
|
return txn.nonces[addr]
|
||||||
|
}
|
||||||
|
|
||||||
|
// set inserts a new virtual nonce into the virtual state database to be returned
|
||||||
|
// whenever the pool requests it instead of reaching into the real state database.
|
||||||
|
func (txn *txNoncer) set(addr common.Address, nonce uint64) {
|
||||||
|
txn.nonces[addr] = nonce
|
||||||
|
}
|
@ -217,9 +217,9 @@ type TxPool struct {
|
|||||||
signer types.Signer
|
signer types.Signer
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
currentState *state.StateDB // Current state in the blockchain head
|
currentState *state.StateDB // Current state in the blockchain head
|
||||||
pendingState *state.ManagedState // Pending state tracking virtual nonces
|
pendingNonces *txNoncer // Pending state tracking virtual nonces
|
||||||
currentMaxGas uint64 // Current gas limit for transaction caps
|
currentMaxGas uint64 // Current gas limit for transaction caps
|
||||||
|
|
||||||
locals *accountSet // Set of local transaction to exempt from eviction rules
|
locals *accountSet // Set of local transaction to exempt from eviction rules
|
||||||
journal *txJournal // Journal of local transaction to back up to disk
|
journal *txJournal // Journal of local transaction to back up to disk
|
||||||
@ -417,12 +417,13 @@ func (pool *TxPool) SetGasPrice(price *big.Int) {
|
|||||||
log.Info("Transaction pool price threshold updated", "price", price)
|
log.Info("Transaction pool price threshold updated", "price", price)
|
||||||
}
|
}
|
||||||
|
|
||||||
// State returns the virtual managed state of the transaction pool.
|
// Nonce returns the next nonce of an account, with all transactions executable
|
||||||
func (pool *TxPool) State() *state.ManagedState {
|
// by the pool already applied on top.
|
||||||
|
func (pool *TxPool) Nonce(addr common.Address) uint64 {
|
||||||
pool.mu.RLock()
|
pool.mu.RLock()
|
||||||
defer pool.mu.RUnlock()
|
defer pool.mu.RUnlock()
|
||||||
|
|
||||||
return pool.pendingState
|
return pool.pendingNonces.get(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stats retrieves the current pool stats, namely the number of pending and the
|
// Stats retrieves the current pool stats, namely the number of pending and the
|
||||||
@ -713,7 +714,7 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T
|
|||||||
}
|
}
|
||||||
// Set the potentially new pending nonce and notify any subsystems of the new tx
|
// Set the potentially new pending nonce and notify any subsystems of the new tx
|
||||||
pool.beats[addr] = time.Now()
|
pool.beats[addr] = time.Now()
|
||||||
pool.pendingState.SetNonce(addr, tx.Nonce()+1)
|
pool.pendingNonces.set(addr, tx.Nonce()+1)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -853,8 +854,8 @@ func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) {
|
|||||||
pool.enqueueTx(tx.Hash(), tx)
|
pool.enqueueTx(tx.Hash(), tx)
|
||||||
}
|
}
|
||||||
// Update the account nonce if needed
|
// Update the account nonce if needed
|
||||||
if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce {
|
if nonce := tx.Nonce(); pool.pendingNonces.get(addr) > nonce {
|
||||||
pool.pendingState.SetNonce(addr, nonce)
|
pool.pendingNonces.set(addr, nonce)
|
||||||
}
|
}
|
||||||
// Reduce the pending counter
|
// Reduce the pending counter
|
||||||
pendingCounter.Dec(int64(1 + len(invalids)))
|
pendingCounter.Dec(int64(1 + len(invalids)))
|
||||||
@ -990,7 +991,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
|
|||||||
|
|
||||||
// Nonces were reset, discard any events that became stale
|
// Nonces were reset, discard any events that became stale
|
||||||
for addr := range events {
|
for addr := range events {
|
||||||
events[addr].Forward(pool.pendingState.GetNonce(addr))
|
events[addr].Forward(pool.pendingNonces.get(addr))
|
||||||
if events[addr].Len() == 0 {
|
if events[addr].Len() == 0 {
|
||||||
delete(events, addr)
|
delete(events, addr)
|
||||||
}
|
}
|
||||||
@ -1023,7 +1024,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
|
|||||||
// Update all accounts to the latest known pending nonce
|
// Update all accounts to the latest known pending nonce
|
||||||
for addr, list := range pool.pending {
|
for addr, list := range pool.pending {
|
||||||
txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway
|
txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway
|
||||||
pool.pendingState.SetNonce(addr, txs[len(txs)-1].Nonce()+1)
|
pool.pendingNonces.set(addr, txs[len(txs)-1].Nonce()+1)
|
||||||
}
|
}
|
||||||
pool.mu.Unlock()
|
pool.mu.Unlock()
|
||||||
|
|
||||||
@ -1112,7 +1113,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
pool.currentState = statedb
|
pool.currentState = statedb
|
||||||
pool.pendingState = state.ManageState(statedb)
|
pool.pendingNonces = newTxNoncer(statedb)
|
||||||
pool.currentMaxGas = newHead.GasLimit
|
pool.currentMaxGas = newHead.GasLimit
|
||||||
|
|
||||||
// Inject any transactions discarded due to reorgs
|
// Inject any transactions discarded due to reorgs
|
||||||
@ -1151,7 +1152,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Trans
|
|||||||
queuedNofundsMeter.Mark(int64(len(drops)))
|
queuedNofundsMeter.Mark(int64(len(drops)))
|
||||||
|
|
||||||
// Gather all executable transactions and promote them
|
// Gather all executable transactions and promote them
|
||||||
readies := list.Ready(pool.pendingState.GetNonce(addr))
|
readies := list.Ready(pool.pendingNonces.get(addr))
|
||||||
for _, tx := range readies {
|
for _, tx := range readies {
|
||||||
hash := tx.Hash()
|
hash := tx.Hash()
|
||||||
if pool.promoteTx(addr, hash, tx) {
|
if pool.promoteTx(addr, hash, tx) {
|
||||||
@ -1231,8 +1232,8 @@ func (pool *TxPool) truncatePending() {
|
|||||||
pool.all.Remove(hash)
|
pool.all.Remove(hash)
|
||||||
|
|
||||||
// Update the account nonce to the dropped transaction
|
// Update the account nonce to the dropped transaction
|
||||||
if nonce := tx.Nonce(); pool.pendingState.GetNonce(offenders[i]) > nonce {
|
if nonce := tx.Nonce(); pool.pendingNonces.get(offenders[i]) > nonce {
|
||||||
pool.pendingState.SetNonce(offenders[i], nonce)
|
pool.pendingNonces.set(offenders[i], nonce)
|
||||||
}
|
}
|
||||||
log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
|
log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
|
||||||
}
|
}
|
||||||
@ -1260,8 +1261,8 @@ func (pool *TxPool) truncatePending() {
|
|||||||
pool.all.Remove(hash)
|
pool.all.Remove(hash)
|
||||||
|
|
||||||
// Update the account nonce to the dropped transaction
|
// Update the account nonce to the dropped transaction
|
||||||
if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce {
|
if nonce := tx.Nonce(); pool.pendingNonces.get(addr) > nonce {
|
||||||
pool.pendingState.SetNonce(addr, nonce)
|
pool.pendingNonces.set(addr, nonce)
|
||||||
}
|
}
|
||||||
log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
|
log.Trace("Removed fairness-exceeding pending transaction", "hash", hash)
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ func validateTxPoolInternals(pool *TxPool) error {
|
|||||||
last = nonce
|
last = nonce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if nonce := pool.pendingState.GetNonce(addr); nonce != last+1 {
|
if nonce := pool.Nonce(addr); nonce != last+1 {
|
||||||
return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1)
|
return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,14 +195,14 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
|
|||||||
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
|
||||||
defer pool.Stop()
|
defer pool.Stop()
|
||||||
|
|
||||||
nonce := pool.State().GetNonce(address)
|
nonce := pool.Nonce(address)
|
||||||
if nonce != 0 {
|
if nonce != 0 {
|
||||||
t.Fatalf("Invalid nonce, want 0, got %d", nonce)
|
t.Fatalf("Invalid nonce, want 0, got %d", nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
pool.addRemotesSync([]*types.Transaction{tx0, tx1})
|
pool.addRemotesSync([]*types.Transaction{tx0, tx1})
|
||||||
|
|
||||||
nonce = pool.State().GetNonce(address)
|
nonce = pool.Nonce(address)
|
||||||
if nonce != 2 {
|
if nonce != 2 {
|
||||||
t.Fatalf("Invalid nonce, want 2, got %d", nonce)
|
t.Fatalf("Invalid nonce, want 2, got %d", nonce)
|
||||||
}
|
}
|
||||||
@ -215,7 +215,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Could not fetch pending transactions: %v", err)
|
t.Fatalf("Could not fetch pending transactions: %v", err)
|
||||||
}
|
}
|
||||||
nonce = pool.State().GetNonce(address)
|
nonce = pool.Nonce(address)
|
||||||
if nonce != 2 {
|
if nonce != 2 {
|
||||||
t.Fatalf("Invalid nonce, want 2, got %d", nonce)
|
t.Fatalf("Invalid nonce, want 2, got %d", nonce)
|
||||||
}
|
}
|
||||||
@ -451,7 +451,7 @@ func TestTransactionNonceRecovery(t *testing.T) {
|
|||||||
// simulate some weird re-order of transactions and missing nonce(s)
|
// simulate some weird re-order of transactions and missing nonce(s)
|
||||||
pool.currentState.SetNonce(addr, n-1)
|
pool.currentState.SetNonce(addr, n-1)
|
||||||
<-pool.requestReset(nil, nil)
|
<-pool.requestReset(nil, nil)
|
||||||
if fn := pool.pendingState.GetNonce(addr); fn != n-1 {
|
if fn := pool.Nonce(addr); fn != n-1 {
|
||||||
t.Errorf("expected nonce to be %d, got %d", n-1, fn)
|
t.Errorf("expected nonce to be %d, got %d", n-1, fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
||||||
return b.eth.txPool.State().GetNonce(addr), nil
|
return b.eth.txPool.Nonce(addr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) Stats() (pending int, queued int) {
|
func (b *EthAPIBackend) Stats() (pending int, queued int) {
|
||||||
|
Loading…
Reference in New Issue
Block a user