5245bd7b20
This test showed the logic in the queue was slightly flawed sending out transactions to its peer it couldn't even resolve itself.
227 lines
5.3 KiB
Go
227 lines
5.3 KiB
Go
package core
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"math/big"
|
|
"testing"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/core/state"
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
"github.com/ethereum/go-ethereum/ethdb"
|
|
"github.com/ethereum/go-ethereum/event"
|
|
)
|
|
|
|
func transaction() *types.Transaction {
|
|
return types.NewTransactionMessage(common.Address{}, big.NewInt(100), big.NewInt(100), big.NewInt(100), nil)
|
|
}
|
|
|
|
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
|
db, _ := ethdb.NewMemDatabase()
|
|
statedb := state.New(common.Hash{}, db)
|
|
|
|
var m event.TypeMux
|
|
key, _ := crypto.GenerateKey()
|
|
return NewTxPool(&m, func() *state.StateDB { return statedb }, func() *big.Int { return big.NewInt(1000000) }), key
|
|
}
|
|
|
|
func TestInvalidTransactions(t *testing.T) {
|
|
pool, key := setupTxPool()
|
|
|
|
tx := transaction()
|
|
tx.SignECDSA(key)
|
|
err := pool.Add(tx)
|
|
if err != ErrNonExistentAccount {
|
|
t.Error("expected", ErrNonExistentAccount)
|
|
}
|
|
|
|
from, _ := tx.From()
|
|
pool.state.AddBalance(from, big.NewInt(1))
|
|
err = pool.Add(tx)
|
|
if err != ErrInsufficientFunds {
|
|
t.Error("expected", ErrInsufficientFunds)
|
|
}
|
|
|
|
balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(tx.Gas(), tx.GasPrice()))
|
|
pool.state.AddBalance(from, balance)
|
|
err = pool.Add(tx)
|
|
if err != ErrIntrinsicGas {
|
|
t.Error("expected", ErrIntrinsicGas, "got", err)
|
|
}
|
|
|
|
pool.state.SetNonce(from, 1)
|
|
pool.state.AddBalance(from, big.NewInt(0xffffffffffffff))
|
|
tx.GasLimit = big.NewInt(100000)
|
|
tx.Price = big.NewInt(1)
|
|
tx.SignECDSA(key)
|
|
|
|
err = pool.Add(tx)
|
|
if err != ErrNonce {
|
|
t.Error("expected", ErrNonce)
|
|
}
|
|
}
|
|
|
|
func TestTransactionQueue(t *testing.T) {
|
|
pool, key := setupTxPool()
|
|
tx := transaction()
|
|
tx.SignECDSA(key)
|
|
from, _ := tx.From()
|
|
pool.state.AddBalance(from, big.NewInt(1))
|
|
pool.queueTx(tx.Hash(), tx)
|
|
|
|
pool.checkQueue()
|
|
if len(pool.pending) != 1 {
|
|
t.Error("expected valid txs to be 1 is", len(pool.pending))
|
|
}
|
|
|
|
tx = transaction()
|
|
tx.SetNonce(1)
|
|
tx.SignECDSA(key)
|
|
from, _ = tx.From()
|
|
pool.state.SetNonce(from, 2)
|
|
pool.queueTx(tx.Hash(), tx)
|
|
pool.checkQueue()
|
|
if _, ok := pool.pending[tx.Hash()]; ok {
|
|
t.Error("expected transaction to be in tx pool")
|
|
}
|
|
|
|
if len(pool.queue[from]) > 0 {
|
|
t.Error("expected transaction queue to be empty. is", len(pool.queue[from]))
|
|
}
|
|
|
|
pool, key = setupTxPool()
|
|
tx1, tx2, tx3 := transaction(), transaction(), transaction()
|
|
tx2.SetNonce(10)
|
|
tx3.SetNonce(11)
|
|
tx1.SignECDSA(key)
|
|
tx2.SignECDSA(key)
|
|
tx3.SignECDSA(key)
|
|
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 =")
|
|
}
|
|
if len(pool.queue[from]) != 2 {
|
|
t.Error("expected len(queue) == 2, got", len(pool.queue[from]))
|
|
}
|
|
}
|
|
|
|
func TestRemoveTx(t *testing.T) {
|
|
pool, key := setupTxPool()
|
|
tx := transaction()
|
|
tx.SignECDSA(key)
|
|
from, _ := tx.From()
|
|
pool.state.AddBalance(from, big.NewInt(1))
|
|
pool.queueTx(tx.Hash(), tx)
|
|
pool.addTx(tx.Hash(), from, tx)
|
|
if len(pool.queue) != 1 {
|
|
t.Error("expected queue to be 1, got", len(pool.queue))
|
|
}
|
|
|
|
if len(pool.pending) != 1 {
|
|
t.Error("expected txs to be 1, got", len(pool.pending))
|
|
}
|
|
|
|
pool.removeTx(tx.Hash())
|
|
|
|
if len(pool.queue) > 0 {
|
|
t.Error("expected queue to be 0, got", len(pool.queue))
|
|
}
|
|
|
|
if len(pool.pending) > 0 {
|
|
t.Error("expected txs to be 0, got", len(pool.pending))
|
|
}
|
|
}
|
|
|
|
func TestNegativeValue(t *testing.T) {
|
|
pool, key := setupTxPool()
|
|
|
|
tx := transaction()
|
|
tx.Value().Set(big.NewInt(-1))
|
|
tx.SignECDSA(key)
|
|
from, _ := tx.From()
|
|
pool.state.AddBalance(from, big.NewInt(1))
|
|
err := pool.Add(tx)
|
|
if err != ErrNegativeValue {
|
|
t.Error("expected", ErrNegativeValue, "got", err)
|
|
}
|
|
}
|
|
|
|
func TestTransactionChainFork(t *testing.T) {
|
|
pool, key := setupTxPool()
|
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
|
pool.currentState().AddBalance(addr, big.NewInt(100000000000000))
|
|
tx := transaction()
|
|
tx.GasLimit = big.NewInt(100000)
|
|
tx.SignECDSA(key)
|
|
|
|
err := pool.add(tx)
|
|
if err != nil {
|
|
t.Error("didn't expect error", err)
|
|
}
|
|
pool.RemoveTransactions([]*types.Transaction{tx})
|
|
|
|
// reset the pool's internal state
|
|
pool.resetState()
|
|
err = pool.add(tx)
|
|
if err != nil {
|
|
t.Error("didn't expect error", err)
|
|
}
|
|
}
|
|
|
|
func TestTransactionDoubleNonce(t *testing.T) {
|
|
pool, key := setupTxPool()
|
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
|
pool.currentState().AddBalance(addr, big.NewInt(100000000000000))
|
|
tx := transaction()
|
|
tx.GasLimit = big.NewInt(100000)
|
|
tx.SignECDSA(key)
|
|
|
|
err := pool.add(tx)
|
|
if err != nil {
|
|
t.Error("didn't expect error", err)
|
|
}
|
|
|
|
tx2 := transaction()
|
|
tx2.GasLimit = big.NewInt(1000000)
|
|
tx2.SignECDSA(key)
|
|
|
|
err = pool.add(tx2)
|
|
if err != nil {
|
|
t.Error("didn't expect error", err)
|
|
}
|
|
|
|
if len(pool.pending) != 2 {
|
|
t.Error("expected 2 pending txs. Got", len(pool.pending))
|
|
}
|
|
}
|
|
|
|
func TestMissingNonce(t *testing.T) {
|
|
pool, key := setupTxPool()
|
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
|
pool.currentState().AddBalance(addr, big.NewInt(100000000000000))
|
|
tx := transaction()
|
|
tx.AccountNonce = 1
|
|
tx.GasLimit = big.NewInt(100000)
|
|
tx.SignECDSA(key)
|
|
|
|
err := pool.add(tx)
|
|
if err != nil {
|
|
t.Error("didn't expect error", err)
|
|
}
|
|
|
|
if len(pool.pending) != 0 {
|
|
t.Error("expected 0 pending transactions, got", len(pool.pending))
|
|
}
|
|
|
|
if len(pool.queue[addr]) != 1 {
|
|
t.Error("expected 1 queued transaction, got", len(pool.queue[addr]))
|
|
}
|
|
}
|