diff --git a/blockchain/error.go b/blockchain/error.go index 9ecbe07b39..410a2d68d5 100644 --- a/blockchain/error.go +++ b/blockchain/error.go @@ -448,6 +448,9 @@ const ( // ErrInvalidEarlyFinalState indicates that a block before stake validation // height had a non-zero final state. ErrInvalidEarlyFinalState + + // numErrorCodes is the maximum error code number used in tests. + numErrorCodes ) // Map of ErrorCode values back to their constant names for pretty printing. @@ -457,7 +460,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrBlockTooBig: "ErrBlockTooBig", ErrWrongBlockSize: "ErrWrongBlockSize", ErrBlockVersionTooOld: "ErrBlockVersionTooOld", - ErrBadStakeVersion: "ErrBlockStakeVersion", + ErrBadStakeVersion: "ErrBadStakeVersion", ErrInvalidTime: "ErrInvalidTime", ErrTimeTooOld: "ErrTimeTooOld", ErrTimeTooNew: "ErrTimeTooNew", diff --git a/blockchain/error_test.go b/blockchain/error_test.go index 02842d224a..1bcd864d8e 100644 --- a/blockchain/error_test.go +++ b/blockchain/error_test.go @@ -1,61 +1,124 @@ // Copyright (c) 2014 The btcsuite developers -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2018 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package blockchain_test +package blockchain import ( "testing" - - "github.com/decred/dcrd/blockchain" ) // TestErrorCodeStringer tests the stringized output for the ErrorCode type. func TestErrorCodeStringer(t *testing.T) { tests := []struct { - in blockchain.ErrorCode + in ErrorCode want string }{ - {blockchain.ErrDuplicateBlock, "ErrDuplicateBlock"}, - {blockchain.ErrBlockTooBig, "ErrBlockTooBig"}, - {blockchain.ErrBlockVersionTooOld, "ErrBlockVersionTooOld"}, - {blockchain.ErrInvalidTime, "ErrInvalidTime"}, - {blockchain.ErrTimeTooOld, "ErrTimeTooOld"}, - {blockchain.ErrTimeTooNew, "ErrTimeTooNew"}, - {blockchain.ErrDifficultyTooLow, "ErrDifficultyTooLow"}, - {blockchain.ErrUnexpectedDifficulty, "ErrUnexpectedDifficulty"}, - {blockchain.ErrHighHash, "ErrHighHash"}, - {blockchain.ErrBadMerkleRoot, "ErrBadMerkleRoot"}, - {blockchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, - {blockchain.ErrForkTooOld, "ErrForkTooOld"}, - {blockchain.ErrCheckpointTimeTooOld, "ErrCheckpointTimeTooOld"}, - {blockchain.ErrNoTransactions, "ErrNoTransactions"}, - {blockchain.ErrTooManyTransactions, "ErrTooManyTransactions"}, - {blockchain.ErrNoTxInputs, "ErrNoTxInputs"}, - {blockchain.ErrNoTxOutputs, "ErrNoTxOutputs"}, - {blockchain.ErrTxTooBig, "ErrTxTooBig"}, - {blockchain.ErrBadTxOutValue, "ErrBadTxOutValue"}, - {blockchain.ErrDuplicateTxInputs, "ErrDuplicateTxInputs"}, - {blockchain.ErrBadTxInput, "ErrBadTxInput"}, - {blockchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, - {blockchain.ErrMissingTxOut, "ErrMissingTxOut"}, - {blockchain.ErrUnfinalizedTx, "ErrUnfinalizedTx"}, - {blockchain.ErrDuplicateTx, "ErrDuplicateTx"}, - {blockchain.ErrOverwriteTx, "ErrOverwriteTx"}, - {blockchain.ErrImmatureSpend, "ErrImmatureSpend"}, - {blockchain.ErrSpendTooHigh, "ErrSpendTooHigh"}, - {blockchain.ErrBadFees, "ErrBadFees"}, - {blockchain.ErrTooManySigOps, "ErrTooManySigOps"}, - {blockchain.ErrFirstTxNotCoinbase, "ErrFirstTxNotCoinbase"}, - {blockchain.ErrMultipleCoinbases, "ErrMultipleCoinbases"}, - {blockchain.ErrBadCoinbaseScriptLen, "ErrBadCoinbaseScriptLen"}, - {blockchain.ErrBadCoinbaseValue, "ErrBadCoinbaseValue"}, - {blockchain.ErrScriptMalformed, "ErrScriptMalformed"}, - {blockchain.ErrScriptValidation, "ErrScriptValidation"}, + {ErrDuplicateBlock, "ErrDuplicateBlock"}, + {ErrMissingParent, "ErrMissingParent"}, + {ErrBlockTooBig, "ErrBlockTooBig"}, + {ErrWrongBlockSize, "ErrWrongBlockSize"}, + {ErrBlockVersionTooOld, "ErrBlockVersionTooOld"}, + {ErrBadStakeVersion, "ErrBadStakeVersion"}, + {ErrInvalidTime, "ErrInvalidTime"}, + {ErrTimeTooOld, "ErrTimeTooOld"}, + {ErrTimeTooNew, "ErrTimeTooNew"}, + {ErrDifficultyTooLow, "ErrDifficultyTooLow"}, + {ErrUnexpectedDifficulty, "ErrUnexpectedDifficulty"}, + {ErrHighHash, "ErrHighHash"}, + {ErrBadMerkleRoot, "ErrBadMerkleRoot"}, + {ErrBadCheckpoint, "ErrBadCheckpoint"}, + {ErrForkTooOld, "ErrForkTooOld"}, + {ErrCheckpointTimeTooOld, "ErrCheckpointTimeTooOld"}, + {ErrNoTransactions, "ErrNoTransactions"}, + {ErrTooManyTransactions, "ErrTooManyTransactions"}, + {ErrNoTxInputs, "ErrNoTxInputs"}, + {ErrNoTxOutputs, "ErrNoTxOutputs"}, + {ErrTxTooBig, "ErrTxTooBig"}, + {ErrBadTxOutValue, "ErrBadTxOutValue"}, + {ErrDuplicateTxInputs, "ErrDuplicateTxInputs"}, + {ErrBadTxInput, "ErrBadTxInput"}, + {ErrMissingTxOut, "ErrMissingTxOut"}, + {ErrUnfinalizedTx, "ErrUnfinalizedTx"}, + {ErrDuplicateTx, "ErrDuplicateTx"}, + {ErrOverwriteTx, "ErrOverwriteTx"}, + {ErrImmatureSpend, "ErrImmatureSpend"}, + {ErrSpendTooHigh, "ErrSpendTooHigh"}, + {ErrBadFees, "ErrBadFees"}, + {ErrTooManySigOps, "ErrTooManySigOps"}, + {ErrFirstTxNotCoinbase, "ErrFirstTxNotCoinbase"}, + {ErrCoinbaseHeight, "ErrCoinbaseHeight"}, + {ErrMultipleCoinbases, "ErrMultipleCoinbases"}, + {ErrStakeTxInRegularTree, "ErrStakeTxInRegularTree"}, + {ErrRegTxInStakeTree, "ErrRegTxInStakeTree"}, + {ErrBadCoinbaseScriptLen, "ErrBadCoinbaseScriptLen"}, + {ErrBadCoinbaseValue, "ErrBadCoinbaseValue"}, + {ErrBadCoinbaseOutpoint, "ErrBadCoinbaseOutpoint"}, + {ErrBadCoinbaseFraudProof, "ErrBadCoinbaseFraudProof"}, + {ErrBadCoinbaseAmountIn, "ErrBadCoinbaseAmountIn"}, + {ErrBadStakebaseAmountIn, "ErrBadStakebaseAmountIn"}, + {ErrBadStakebaseScriptLen, "ErrBadStakebaseScriptLen"}, + {ErrBadStakebaseScrVal, "ErrBadStakebaseScrVal"}, + {ErrScriptMalformed, "ErrScriptMalformed"}, + {ErrScriptValidation, "ErrScriptValidation"}, + {ErrNotEnoughStake, "ErrNotEnoughStake"}, + {ErrStakeBelowMinimum, "ErrStakeBelowMinimum"}, + {ErrNonstandardStakeTx, "ErrNonstandardStakeTx"}, + {ErrNotEnoughVotes, "ErrNotEnoughVotes"}, + {ErrTooManyVotes, "ErrTooManyVotes"}, + {ErrFreshStakeMismatch, "ErrFreshStakeMismatch"}, + {ErrTooManySStxs, "ErrTooManySStxs"}, + {ErrInvalidEarlyStakeTx, "ErrInvalidEarlyStakeTx"}, + {ErrTicketUnavailable, "ErrTicketUnavailable"}, + {ErrVotesOnWrongBlock, "ErrVotesOnWrongBlock"}, + {ErrVotesMismatch, "ErrVotesMismatch"}, + {ErrIncongruentVotebit, "ErrIncongruentVotebit"}, + {ErrInvalidSSRtx, "ErrInvalidSSRtx"}, + {ErrRevocationsMismatch, "ErrRevocationsMismatch"}, + {ErrTooManyRevocations, "ErrTooManyRevocations"}, + {ErrSStxCommitment, "ErrSStxCommitment"}, + {ErrInvalidSSGenInput, "ErrInvalidSSGenInput"}, + {ErrSSGenPayeeNum, "ErrSSGenPayeeNum"}, + {ErrSSGenPayeeOuts, "ErrSSGenPayeeOuts"}, + {ErrSSGenSubsidy, "ErrSSGenSubsidy"}, + {ErrSStxInImmature, "ErrSStxInImmature"}, + {ErrSStxInScrType, "ErrSStxInScrType"}, + {ErrInvalidSSRtxInput, "ErrInvalidSSRtxInput"}, + {ErrSSRtxPayeesMismatch, "ErrSSRtxPayeesMismatch"}, + {ErrSSRtxPayees, "ErrSSRtxPayees"}, + {ErrTxSStxOutSpend, "ErrTxSStxOutSpend"}, + {ErrRegTxSpendStakeOut, "ErrRegTxSpendStakeOut"}, + {ErrInvalidFinalState, "ErrInvalidFinalState"}, + {ErrPoolSize, "ErrPoolSize"}, + {ErrForceReorgWrongChain, "ErrForceReorgWrongChain"}, + {ErrForceReorgMissingChild, "ErrForceReorgMissingChild"}, + {ErrBadStakebaseValue, "ErrBadStakebaseValue"}, + {ErrDiscordantTxTree, "ErrDiscordantTxTree"}, + {ErrStakeFees, "ErrStakeFees"}, + {ErrNoStakeTx, "ErrNoStakeTx"}, + {ErrBadBlockHeight, "ErrBadBlockHeight"}, + {ErrBlockOneTx, "ErrBlockOneTx"}, + {ErrBlockOneInputs, "ErrBlockOneInputs"}, + {ErrBlockOneOutputs, "ErrBlockOneOutputs"}, + {ErrNoTax, "ErrNoTax"}, + {ErrExpiredTx, "ErrExpiredTx"}, + {ErrExpiryTxSpentEarly, "ErrExpiryTxSpentEarly"}, + {ErrFraudAmountIn, "ErrFraudAmountIn"}, + {ErrFraudBlockHeight, "ErrFraudBlockHeight"}, + {ErrFraudBlockIndex, "ErrFraudBlockIndex"}, + {ErrZeroValueOutputSpend, "ErrZeroValueOutputSpend"}, + {ErrInvalidEarlyVoteBits, "ErrInvalidEarlyVoteBits"}, + {ErrInvalidEarlyFinalState, "ErrInvalidEarlyFinalState"}, {0xffff, "Unknown ErrorCode (65535)"}, } + // Detect additional error codes that don't have the stringer added. + if len(tests)-1 != int(numErrorCodes) { + t.Errorf("It appears an error code was added without adding an " + + "associated stringer test") + } + t.Logf("Running %d tests", len(tests)) for i, test := range tests { result := test.in.String() @@ -70,15 +133,15 @@ func TestErrorCodeStringer(t *testing.T) { // TestRuleError tests the error output for the RuleError type. func TestRuleError(t *testing.T) { tests := []struct { - in blockchain.RuleError + in RuleError want string }{ { - blockchain.RuleError{Description: "duplicate block"}, + RuleError{Description: "duplicate block"}, "duplicate block", }, { - blockchain.RuleError{Description: "human-readable error"}, + RuleError{Description: "human-readable error"}, "human-readable error", }, }