diff --git a/core/tx_pool.go b/core/tx_pool.go index 20c5eccee5..374f443f6c 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -78,6 +78,8 @@ var ( // than some meaningful limit a user might use. This is not a consensus error // making the transaction invalid, rather a DOS protection. ErrOversizedData = errors.New("oversized data") + + ErrZeroGasPrice = errors.New("zero gas price") ) var ( @@ -586,8 +588,9 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { return ErrInsufficientFunds } - if tx.To() != nil && tx.To().String() != common.BlockSigners { - intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) + + if tx.To() == nil || (tx.To() != nil && tx.To().String() != common.BlockSigners) { + intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) if err != nil { return err } @@ -595,6 +598,11 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if tx.Gas() < intrGas { return ErrIntrinsicGas } + + // Check zero gas price. + if tx.GasPrice().Cmp(new(big.Int).SetInt64(0)) == 0 { + return ErrZeroGasPrice + } } return nil diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 1cf533aa65..2aba086d16 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -1287,12 +1287,12 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { // Create transaction (both pending and queued) with a linearly growing gasprice for i := uint64(0); i < 500; i++ { // Add pending - p_tx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2]) + p_tx := pricedTransaction(i, 100000, big.NewInt(int64(i+1)), keys[2]) if err := pool.AddLocal(p_tx); err != nil { t.Fatal(err) } // Add queued - q_tx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2]) + q_tx := pricedTransaction(i+501, 100000, big.NewInt(int64(i+1)), keys[2]) if err := pool.AddLocal(q_tx); err != nil { t.Fatal(err) } @@ -1411,7 +1411,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { t.Fatalf("pool internal state corrupted: %v", err) } // Ensure that adding local transactions can push out even higher priced ones - tx := pricedTransaction(1, 100000, big.NewInt(0), keys[2]) + tx := pricedTransaction(1, 100000, big.NewInt(1), keys[2]) if err := pool.AddLocal(tx); err != nil { t.Fatalf("failed to add underpriced local transaction: %v", err) } @@ -1776,4 +1776,4 @@ func benchmarkPoolBatchInsert(b *testing.B, size int) { for _, batch := range batches { pool.AddRemotes(batch) } -} +} \ No newline at end of file