Improved transaction pool
The transaction pool will now some easily be able to pre determine the validity of a transaction by checking the following: * Account existst * gas limit higher than the instrinsic gas * enough funds to pay upfront costs * nonce check
This commit is contained in:
@ -13,87 +13,50 @@ import (
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
)
|
||||
|
||||
// State query interface
|
||||
type stateQuery struct{ db common.Database }
|
||||
|
||||
func SQ() stateQuery {
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
return stateQuery{db: db}
|
||||
}
|
||||
|
||||
func (self stateQuery) GetAccount(addr []byte) *state.StateObject {
|
||||
return state.NewStateObject(common.BytesToAddress(addr), self.db)
|
||||
}
|
||||
|
||||
func transaction() *types.Transaction {
|
||||
return types.NewTransactionMessage(common.Address{}, common.Big0, common.Big0, common.Big0, nil)
|
||||
return types.NewTransactionMessage(common.Address{}, big.NewInt(100), big.NewInt(100), big.NewInt(100), nil)
|
||||
}
|
||||
|
||||
func setup() (*TxPool, *ecdsa.PrivateKey) {
|
||||
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
statedb := state.New(common.Hash{}, db)
|
||||
|
||||
var m event.TypeMux
|
||||
key, _ := crypto.GenerateKey()
|
||||
return NewTxPool(&m), key
|
||||
return NewTxPool(&m, func() *state.StateDB { return statedb }), key
|
||||
}
|
||||
|
||||
func TestTxAdding(t *testing.T) {
|
||||
pool, key := setup()
|
||||
tx1 := transaction()
|
||||
tx1.SignECDSA(key)
|
||||
err := pool.Add(tx1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
func TestInvalidTransactions(t *testing.T) {
|
||||
pool, key := setupTxPool()
|
||||
|
||||
tx := transaction()
|
||||
tx.SignECDSA(key)
|
||||
err := pool.Add(tx)
|
||||
if err != ErrNonExistentAccount {
|
||||
t.Error("expected", ErrNonExistentAccount)
|
||||
}
|
||||
|
||||
err = pool.Add(tx1)
|
||||
if err == nil {
|
||||
t.Error("added tx twice")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddInvalidTx(t *testing.T) {
|
||||
pool, _ := setup()
|
||||
tx1 := transaction()
|
||||
err := pool.Add(tx1)
|
||||
if err == nil {
|
||||
t.Error("expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveSet(t *testing.T) {
|
||||
pool, _ := setup()
|
||||
tx1 := transaction()
|
||||
pool.addTx(tx1)
|
||||
pool.RemoveSet(types.Transactions{tx1})
|
||||
if pool.Size() > 0 {
|
||||
t.Error("expected pool size to be 0")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveInvalid(t *testing.T) {
|
||||
pool, key := setup()
|
||||
tx1 := transaction()
|
||||
pool.addTx(tx1)
|
||||
pool.RemoveInvalid(SQ())
|
||||
if pool.Size() > 0 {
|
||||
t.Error("expected pool size to be 0")
|
||||
}
|
||||
|
||||
tx1.SetNonce(1)
|
||||
tx1.SignECDSA(key)
|
||||
pool.addTx(tx1)
|
||||
pool.RemoveInvalid(SQ())
|
||||
if pool.Size() != 1 {
|
||||
t.Error("expected pool size to be 1, is", pool.Size())
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidSender(t *testing.T) {
|
||||
pool, _ := setup()
|
||||
tx := new(types.Transaction)
|
||||
tx.R = new(big.Int)
|
||||
tx.S = new(big.Int)
|
||||
err := pool.ValidateTransaction(tx)
|
||||
if err != ErrInvalidSender {
|
||||
t.Errorf("expected %v, got %v", ErrInvalidSender, err)
|
||||
from, _ := tx.From()
|
||||
pool.currentState().AddBalance(from, big.NewInt(1))
|
||||
err = pool.Add(tx)
|
||||
if err != ErrInsufficientFunds {
|
||||
t.Error("expected", ErrInsufficientFunds)
|
||||
}
|
||||
|
||||
pool.currentState().AddBalance(from, big.NewInt(100*100))
|
||||
err = pool.Add(tx)
|
||||
if err != ErrIntrinsicGas {
|
||||
t.Error("expected", ErrIntrinsicGas)
|
||||
}
|
||||
|
||||
pool.currentState().SetNonce(from, 1)
|
||||
pool.currentState().AddBalance(from, big.NewInt(0xffffffffffffff))
|
||||
tx.GasLimit = big.NewInt(100000)
|
||||
tx.Price = big.NewInt(1)
|
||||
tx.SignECDSA(key)
|
||||
|
||||
err = pool.Add(tx)
|
||||
if err != ErrImpossibleNonce {
|
||||
t.Error("expected", ErrImpossibleNonce)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user