From 269a7ee8d4c470a429f84965d796d14151b8b807 Mon Sep 17 00:00:00 2001 From: Bas van Kervel Date: Mon, 21 Nov 2016 12:31:24 +0100 Subject: [PATCH] core/quorum: check if transaction was already applied Due to the asynchronous eventing system its possible that transactions are applied on the pending state multiple times. Once with the TxPreEvent event and once as a result of the ChainHeadEvent that will fetch all processable transaction from the transaction pool. This leads to an invalid nonce message. This PR will keep track of transactions applied to the pending state and will verify that an transaction was not applied before. --- core/quorum/block_maker.go | 7 +++++++ core/quorum/block_voting.go | 3 +++ 2 files changed, 10 insertions(+) diff --git a/core/quorum/block_maker.go b/core/quorum/block_maker.go index a5e6b0aaf..233621023 100755 --- a/core/quorum/block_maker.go +++ b/core/quorum/block_maker.go @@ -26,6 +26,7 @@ type pendingState struct { gp *core.GasPool ownedAccounts *set.Set txs types.Transactions // set of transactions + txsHashes *set.Set lowGasTxs types.Transactions failedTxs types.Transactions parent *types.Block @@ -55,6 +56,7 @@ func (ps *pendingState) applyTransaction(tx *types.Transaction, bc *core.BlockCh return err, nil } ps.txs = append(ps.txs, tx) + ps.txsHashes.Add(tx.Hash()) ps.receipts = append(ps.receipts, receipt) return nil, logs @@ -73,6 +75,11 @@ func (ps *pendingState) applyTransactions(txs *types.TransactionsByPriorityAndNo if tx == nil { break } + + if ps.txsHashes.Has(tx.Hash()) { + continue + } + // Error may be ignored here. The error has already been checked // during transaction acceptance is the transaction pool. from, _ := tx.From() diff --git a/core/quorum/block_voting.go b/core/quorum/block_voting.go index ea30c467b..8271cb7df 100755 --- a/core/quorum/block_voting.go +++ b/core/quorum/block_voting.go @@ -110,6 +110,7 @@ func (bv *BlockVoting) resetPendingState(parent *types.Block) { header: bv.makeHeader(parent), gp: new(core.GasPool), ownedAccounts: accountAddressesSet(bv.am.Accounts()), + txsHashes: set.New(), } ps.gp.AddGas(ps.header.GasLimit) @@ -310,9 +311,11 @@ func (bv *BlockVoting) createBlock() (*types.Block, error) { ch, err := bv.canonHash(bv.pState.header.Number.Uint64()) if err != nil { + bv.resetPendingState(bv.bc.CurrentFastBlock()) return nil, err } if ch != bv.pState.parent.Hash() { + bv.resetPendingState(bv.bc.CurrentFastBlock()) return nil, fmt.Errorf("invalid canonical hash, expected %s got %s", ch.Hex(), bv.pState.header.Hash().Hex()) }