From 69e745c537e442d4086986b02c01741d2a314cf1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 27 Oct 2014 16:52:58 +0100 Subject: [PATCH] Return erroneous txs (so we can remove them from the pool) --- ethchain/state_manager.go | 15 +++++++++------ ethchain/transaction.go | 2 +- ethchain/transaction_pool.go | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 1de46b371..dba3ff202 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -17,7 +17,7 @@ import ( "github.com/ethereum/go-ethereum/event" ) -var statelogger = ethlog.NewLogger("STATE") +var statelogger = ethlog.NewLogger("BLOCK") type Peer interface { Inbound() bool @@ -134,10 +134,11 @@ func (sm *StateManager) ChainManager() *ChainManager { return sm.bc } -func (self *StateManager) ProcessTransactions(coinbase *ethstate.StateObject, state *ethstate.State, block, parent *Block, txs Transactions) (Receipts, Transactions, Transactions, error) { +func (self *StateManager) ProcessTransactions(coinbase *ethstate.StateObject, state *ethstate.State, block, parent *Block, txs Transactions) (Receipts, Transactions, Transactions, Transactions, error) { var ( receipts Receipts handled, unhandled Transactions + erroneous Transactions totalUsedGas = big.NewInt(0) err error ) @@ -161,7 +162,9 @@ done: break done default: statelogger.Infoln(err) + erroneous = append(erroneous, tx) err = nil + continue //return nil, nil, nil, err } } @@ -182,7 +185,7 @@ done: err := fmt.Errorf("#%d receipt failed (r) %v ~ %x <=> (c) %v ~ %x (%x...)", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], receipt.Tx.Hash()[0:4]) - return nil, nil, nil, err + return nil, nil, nil, nil, err } } @@ -199,7 +202,7 @@ done: parent.GasUsed = totalUsedGas - return receipts, handled, unhandled, err + return receipts, handled, unhandled, erroneous, err } func (sm *StateManager) Process(block *Block, dontReact bool) (err error) { @@ -283,7 +286,7 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) { state.Manifest().Reset() } - sm.eth.TxPool().RemoveInvalid(state) + sm.eth.TxPool().RemoveSet(block.Transactions()) } else { statelogger.Errorln("total diff failed") } @@ -296,7 +299,7 @@ func (sm *StateManager) ApplyDiff(state *ethstate.State, parent, block *Block) ( coinbase.SetGasPool(block.CalcGasLimit(parent)) // Process the transactions on to current block - receipts, _, _, err = sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions()) + receipts, _, _, _, err = sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions()) if err != nil { return nil, err } diff --git a/ethchain/transaction.go b/ethchain/transaction.go index b0743097d..abf2e37ac 100644 --- a/ethchain/transaction.go +++ b/ethchain/transaction.go @@ -40,7 +40,7 @@ func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transa } func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction { - return &Transaction{Recipient: to, Value: value, GasPrice: gasPrice, Gas: gas, Data: data} + return &Transaction{Recipient: to, Value: value, GasPrice: gasPrice, Gas: gas, Data: data, contractCreation: IsContractAddr(to)} } func NewTransactionFromBytes(data []byte) *Transaction { diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go index 063688aa8..7f8a5de42 100644 --- a/ethchain/transaction_pool.go +++ b/ethchain/transaction_pool.go @@ -35,6 +35,14 @@ type TxMsg struct { Type TxMsgTy } +func EachTx(pool *list.List, it func(*Transaction, *list.Element) bool) { + for e := pool.Front(); e != nil; e = e.Next() { + if it(e.Value.(*Transaction), e) { + break + } + } +} + func FindTx(pool *list.List, finder func(*Transaction, *list.Element) bool) *Transaction { for e := pool.Front(); e != nil; e = e.Next() { if tx, ok := e.Value.(*Transaction); ok { @@ -191,6 +199,9 @@ func (pool *TxPool) CurrentTransactions() []*Transaction { } func (pool *TxPool) RemoveInvalid(state *ethstate.State) { + pool.mutex.Lock() + defer pool.mutex.Unlock() + for e := pool.pool.Front(); e != nil; e = e.Next() { tx := e.Value.(*Transaction) sender := state.GetAccount(tx.Sender()) @@ -201,6 +212,21 @@ func (pool *TxPool) RemoveInvalid(state *ethstate.State) { } } +func (self *TxPool) RemoveSet(txs Transactions) { + self.mutex.Lock() + defer self.mutex.Unlock() + + for _, tx := range txs { + EachTx(self.pool, func(t *Transaction, element *list.Element) bool { + if t == tx { + self.pool.Remove(element) + return true // To stop the loop + } + return false + }) + } +} + func (pool *TxPool) Flush() []*Transaction { txList := pool.CurrentTransactions()