From df934990d7bb70a319d245c6d145f8e289ed3046 Mon Sep 17 00:00:00 2001 From: Ori Newman Date: Tue, 7 Apr 2020 12:45:12 +0300 Subject: [PATCH] [NOD-822] Don't return rule errors from utxoset code (#693) * [NOD-822] Remove rule errors from the UTXO diff code * [NOD-822] Rename applyTransactions -> applyAndVerifyBlockTransactionsToPastUTXO * [NOD-822] Fix comment --- blockdag/dag.go | 17 +++++++++-------- blockdag/utxoset.go | 19 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/blockdag/dag.go b/blockdag/dag.go index 00dbc949a..ee117f3b7 100644 --- a/blockdag/dag.go +++ b/blockdag/dag.go @@ -1058,11 +1058,16 @@ func (dag *BlockDAG) meldVirtualUTXO(newVirtualUTXODiffSet *DiffUTXOSet) error { return newVirtualUTXODiffSet.meldToBase() } -func (node *blockNode) diffFromTxs(pastUTXO UTXOSet, transactions []*util.Tx) (*UTXODiff, error) { +// applyAndVerifyBlockTransactionsToPastUTXO applies a block's transactions to its +// given past UTXO, and verifies that there are no double spends with its past. +func applyAndVerifyBlockTransactionsToPastUTXO(pastUTXO UTXOSet, blockTransactions []*util.Tx) (UTXOSet, error) { diff := NewUTXODiff() - for _, tx := range transactions { + for _, tx := range blockTransactions { txDiff, err := pastUTXO.diffFromTx(tx.MsgTx(), UnacceptedBlueScore) + if errors.Is(err, errUTXOMissingTxOut) { + return nil, ruleError(ErrMissingTxOut, err.Error()) + } if err != nil { return nil, err } @@ -1072,7 +1077,7 @@ func (node *blockNode) diffFromTxs(pastUTXO UTXOSet, transactions []*util.Tx) (* } } - return diff, nil + return pastUTXO.WithDiff(diff) } // verifyAndBuildUTXO verifies all transactions in the given block and builds its UTXO @@ -1096,11 +1101,7 @@ func (node *blockNode) verifyAndBuildUTXO(dag *BlockDAG, transactions []*util.Tx return nil, nil, nil, nil, err } - diffFromTxs, err := node.diffFromTxs(pastUTXO, transactions) - if err != nil { - return nil, nil, nil, nil, err - } - utxo, err := pastUTXO.WithDiff(diffFromTxs) + utxo, err := applyAndVerifyBlockTransactionsToPastUTXO(pastUTXO, transactions) if err != nil { return nil, nil, nil, nil, err } diff --git a/blockdag/utxoset.go b/blockdag/utxoset.go index f56f6801d..eb5a134c2 100644 --- a/blockdag/utxoset.go +++ b/blockdag/utxoset.go @@ -293,8 +293,8 @@ func (d *UTXODiff) withDiffInPlace(diff *UTXODiff) error { } if d.toRemove.contains(outpoint) { // If already exists - this is an error - return ruleError(ErrWithDiff, fmt.Sprintf( - "withDiffInPlace: outpoint %s both in d.toRemove and in diff.toRemove", outpoint)) + return errors.Errorf( + "withDiffInPlace: outpoint %s both in d.toRemove and in diff.toRemove", outpoint) } // If not exists neither in toAdd nor in toRemove - add to toRemove @@ -305,9 +305,9 @@ func (d *UTXODiff) withDiffInPlace(diff *UTXODiff) error { if d.toRemove.containsWithBlueScore(outpoint, entryToAdd.blockBlueScore) { // If already exists in toRemove with the same blueScore - remove from toRemove if d.toAdd.contains(outpoint) && !diff.toRemove.contains(outpoint) { - return ruleError(ErrWithDiff, fmt.Sprintf( + return errors.Errorf( "withDiffInPlace: outpoint %s both in d.toAdd and in diff.toAdd with no "+ - "corresponding entry in diff.toRemove", outpoint)) + "corresponding entry in diff.toRemove", outpoint) } d.toRemove.remove(outpoint) continue @@ -316,8 +316,8 @@ func (d *UTXODiff) withDiffInPlace(diff *UTXODiff) error { (existingEntry.blockBlueScore == entryToAdd.blockBlueScore || !diff.toRemove.containsWithBlueScore(outpoint, existingEntry.blockBlueScore)) { // If already exists - this is an error - return ruleError(ErrWithDiff, fmt.Sprintf( - "withDiffInPlace: outpoint %s both in d.toAdd and in diff.toAdd", outpoint)) + return errors.Errorf( + "withDiffInPlace: outpoint %s both in d.toAdd and in diff.toAdd", outpoint) } // If not exists neither in toAdd nor in toRemove, or exists in toRemove with different blueScore - add to toAdd @@ -406,6 +406,8 @@ type UTXOSet interface { Get(outpoint wire.Outpoint) (*UTXOEntry, bool) } +var errUTXOMissingTxOut = errors.New("missing transaction output in the utxo set") + // diffFromTx is a common implementation for diffFromTx, that works // for both diff-based and full UTXO sets // Returns a diff that is equivalent to provided transaction, @@ -421,9 +423,8 @@ func diffFromTx(u UTXOSet, tx *wire.MsgTx, acceptingBlueScore uint64) (*UTXODiff return nil, err } } else { - return nil, ruleError(ErrMissingTxOut, fmt.Sprintf( - "Transaction %s is invalid because spends outpoint %s that is not in utxo set", - tx.TxID(), txIn.PreviousOutpoint)) + return nil, errors.Wrapf(errUTXOMissingTxOut, "Transaction %s is invalid because it spends "+ + "outpoint %s that is not in utxo set", tx.TxID(), txIn.PreviousOutpoint) } } }