dcrd/blockchain/stake/error_test.go
C Jepson d98fc8319f Replace the ticket database with an efficient, atomic implementation
The legacy ticket database, which was GOB serialized and stored on
shut down, has been removed.  Ticket state information is now held in
a stake node, which acts as a modularized "black box" to contain all
information about the state of the stake system.  Stake nodes are now
a component of the blockchain blockNode struct, and are updated with
them.

Stake nodes, like their internal treap primitives, are immutable
objects that are created with their connect and disconnect node
functions.  The blockchain database now stores all information about
the stake state of the best node in the block database.  The blockchain
makes the assumption that the stake state of the best node is known at
any given time.  If the states of former blocks or sidechains must be
evaluated, this can be achieved by iterating backwards along the
blockchain from the best node, and then connecting stake nodes
iteratively if necessary.

Performance improvements with this new module are dramatic.  The long
delays on start up and shut down are removed.  Blockchain
synchronization time is improved approximately 5-10x on the mainnet
chain.  The state of the database is atomic, so unexpected shut downs
should no longer have the ability to disrupt the chain state.

An upgrade path has been added for version 1 blockchain databases.
Users with this blockchain database will automatically update when
they start their clients.
2016-10-04 13:40:19 -04:00

97 lines
3.3 KiB
Go

// Copyright (c) 2014 Conformal Systems LLC.
// Copyright (c) 2015-2016 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package stake_test
import (
"testing"
"github.com/decred/dcrd/blockchain/stake"
)
// TestErrorCodeStringer tests the stringized output for the ErrorCode type.
func TestErrorCodeStringer(t *testing.T) {
tests := []struct {
in stake.ErrorCode
want string
}{
{stake.ErrSStxTooManyInputs, "ErrSStxTooManyInputs"},
{stake.ErrSStxTooManyOutputs, "ErrSStxTooManyOutputs"},
{stake.ErrSStxNoOutputs, "ErrSStxNoOutputs"},
{stake.ErrSStxInvalidInputs, "ErrSStxInvalidInputs"},
{stake.ErrSStxInvalidOutputs, "ErrSStxInvalidOutputs"},
{stake.ErrSStxInOutProportions, "ErrSStxInOutProportions"},
{stake.ErrSStxBadCommitAmount, "ErrSStxBadCommitAmount"},
{stake.ErrSStxBadChangeAmts, "ErrSStxBadChangeAmts"},
{stake.ErrSStxVerifyCalcAmts, "ErrSStxVerifyCalcAmts"},
{stake.ErrSSGenWrongNumInputs, "ErrSSGenWrongNumInputs"},
{stake.ErrSSGenTooManyOutputs, "ErrSSGenTooManyOutputs"},
{stake.ErrSSGenNoOutputs, "ErrSSGenNoOutputs"},
{stake.ErrSSGenWrongIndex, "ErrSSGenWrongIndex"},
{stake.ErrSSGenWrongTxTree, "ErrSSGenWrongTxTree"},
{stake.ErrSSGenNoStakebase, "ErrSSGenNoStakebase"},
{stake.ErrSSGenNoReference, "ErrSSGenNoReference"},
{stake.ErrSSGenBadReference, "ErrSSGenBadReference"},
{stake.ErrSSGenNoVotePush, "ErrSSGenNoVotePush"},
{stake.ErrSSGenBadVotePush, "ErrSSGenBadVotePush"},
{stake.ErrSSGenBadGenOuts, "ErrSSGenBadGenOuts"},
{stake.ErrSSRtxWrongNumInputs, "ErrSSRtxWrongNumInputs"},
{stake.ErrSSRtxTooManyOutputs, "ErrSSRtxTooManyOutputs"},
{stake.ErrSSRtxNoOutputs, "ErrSSRtxNoOutputs"},
{stake.ErrSSRtxWrongTxTree, "ErrSSRtxWrongTxTree"},
{stake.ErrSSRtxBadOuts, "ErrSSRtxBadOuts"},
{stake.ErrVerSStxAmts, "ErrVerSStxAmts"},
{stake.ErrVerifyInput, "ErrVerifyInput"},
{stake.ErrVerifyOutType, "ErrVerifyOutType"},
{stake.ErrVerifyTooMuchFees, "ErrVerifyTooMuchFees"},
{stake.ErrVerifySpendTooMuch, "ErrVerifySpendTooMuch"},
{stake.ErrVerifyOutputAmt, "ErrVerifyOutputAmt"},
{stake.ErrVerifyOutPkhs, "ErrVerifyOutPkhs"},
{stake.ErrDatabaseCorrupt, "ErrDatabaseCorrupt"},
{stake.ErrMissingDatabaseTx, "ErrMissingDatabaseTx"},
{stake.ErrMemoryCorruption, "ErrMemoryCorruption"},
{stake.ErrFindTicketIdxs, "ErrFindTicketIdxs"},
{stake.ErrMissingTicket, "ErrMissingTicket"},
{stake.ErrDuplicateTicket, "ErrDuplicateTicket"},
{stake.ErrUnknownTicketSpent, "ErrUnknownTicketSpent"},
{0xffff, "Unknown ErrorCode (65535)"},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
result := test.in.String()
if result != test.want {
t.Errorf("String #%d\n got: %s want: %s", i, result,
test.want)
continue
}
}
}
// TestRuleError tests the error output for the RuleError type.
func TestRuleError(t *testing.T) {
tests := []struct {
in stake.RuleError
want string
}{
{stake.RuleError{Description: "duplicate block"},
"duplicate block",
},
{stake.RuleError{Description: "human-readable error"},
"human-readable error",
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
result := test.in.Error()
if result != test.want {
t.Errorf("Error #%d\n got: %s want: %s", i, result,
test.want)
continue
}
}
}