Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #348 from gcash/hardfork
May 2020 Hardfork
  • Loading branch information
cpacia committed Apr 26, 2020
2 parents 087c36c + 7cace3d commit 1ce6b60
Show file tree
Hide file tree
Showing 22 changed files with 813 additions and 142 deletions.
10 changes: 10 additions & 0 deletions blockchain/error.go
Expand Up @@ -115,6 +115,10 @@ const (
// number of signature operations.
ErrTxTooManySigOps

// ErrTxTooManySigChecks indicates a transaction exceeds the maximum allowable
// number of signature checks.
ErrTxTooManySigChecks

// ErrBadTxOutValue indicates an output value for a transaction is
// invalid in some way such as being out of range.
ErrBadTxOutValue
Expand Down Expand Up @@ -166,6 +170,10 @@ const (
// for a transaction or block exceed the maximum allowed limits.
ErrTooManySigOps

// ErrTooManySigChecks indicates that the block's signature checks exceeds
// the limit.
ErrTooManySigChecks

// ErrFirstTxNotCoinbase indicates the first transaction in a block
// is not a coinbase transaction.
ErrFirstTxNotCoinbase
Expand Down Expand Up @@ -270,6 +278,8 @@ var errorCodeStrings = map[ErrorCode]string{
ErrInvalidAncestorBlock: "ErrInvalidAncestorBlock",
ErrPrevBlockNotBest: "ErrPrevBlockNotBest",
ErrInvalidTxOrder: "ErrInvalidTxOrder",
ErrTooManySigChecks: "ErrTooManySigChecks",
ErrTxTooManySigChecks: "ErrTxTooManySigChecks",
}

// String returns the ErrorCode as a human-readable name.
Expand Down
2 changes: 2 additions & 0 deletions blockchain/error_test.go
Expand Up @@ -55,6 +55,8 @@ func TestErrorCodeStringer(t *testing.T) {
{ErrPreviousBlockUnknown, "ErrPreviousBlockUnknown"},
{ErrInvalidAncestorBlock, "ErrInvalidAncestorBlock"},
{ErrPrevBlockNotBest, "ErrPrevBlockNotBest"},
{ErrTooManySigChecks, "ErrTooManySigChecks"},
{ErrTxTooManySigChecks, "ErrTxTooManySigChecks"},
{0xffff, "Unknown ErrorCode (65535)"},
}

Expand Down
118 changes: 112 additions & 6 deletions blockchain/fullblocks_test.go
Expand Up @@ -60,7 +60,7 @@ func isSupportedDbType(dbType string) bool {
// chainSetup is used to create a new db and chain instance with the genesis
// block already inserted. In addition to the new chain instance, it returns
// a teardown function the caller should invoke when done testing to clean up.
func chainSetup(dbName string, params *chaincfg.Params) (*blockchain.BlockChain, func(), error) {
func chainSetup(dbName string, params *chaincfg.Params, excessiveBlockSize uint32) (*blockchain.BlockChain, func(), error) {
if !isSupportedDbType(testDbType) {
return nil, nil, fmt.Errorf("unsupported db type %v", testDbType)
}
Expand Down Expand Up @@ -121,7 +121,7 @@ func chainSetup(dbName string, params *chaincfg.Params) (*blockchain.BlockChain,
TimeSource: blockchain.NewMedianTime(),
SigCache: txscript.NewSigCache(1000),
UtxoCacheMaxSize: 250 * 1024 * 1024,
ExcessiveBlockSize: 1000000,
ExcessiveBlockSize: excessiveBlockSize,
})
if err != nil {
teardown()
Expand All @@ -141,7 +141,7 @@ func TestFullBlocks(t *testing.T) {

// Create a new database and chain instance to run tests against.
chain, teardownFunc, err := chainSetup("fullblocktest",
&chaincfg.RegressionNetParams)
&chaincfg.RegressionNetParams, 1000000)
if err != nil {
t.Errorf("Failed to setup chain instance: %v", err)
return
Expand Down Expand Up @@ -323,7 +323,7 @@ func TestCTORActivation(t *testing.T) {
params := &chaincfg.RegressionNetParams
params.MagneticAnonomalyForkHeight = 0
chain, teardownFunc, err := chainSetup("fullblocktest",
params)
params, 1000000)
if err != nil {
t.Errorf("Failed to setup chain instance: %v", err)
return
Expand Down Expand Up @@ -450,7 +450,7 @@ func TestGreatWallActivation(t *testing.T) {
params.GreatWallForkHeight = 0
params.MagneticAnonomalyForkHeight = 0
chain, teardownFunc, err := chainSetup("fullblocktest",
params)
params, 1000000)
if err != nil {
t.Errorf("Failed to setup chain instance: %v", err)
return
Expand Down Expand Up @@ -518,7 +518,113 @@ func TestGravitonActivation(t *testing.T) {
params.GravitonForkHeight = 0
params.MagneticAnonomalyForkHeight = 0
chain, teardownFunc, err := chainSetup("fullblocktest",
params)
params, 1000000)
if err != nil {
t.Errorf("Failed to setup chain instance: %v", err)
return
}
defer teardownFunc()

// testAcceptedBlock attempts to process the block in the provided test
// instance and ensures that it was accepted according to the flags
// specified in the test.
testAcceptedBlock := func(item fullblocktests.AcceptedBlock) {
blockHeight := item.Height
block := bchutil.NewBlock(item.Block)
block.SetHeight(blockHeight)
t.Logf("Testing block %s (hash %s, height %d)",
item.Name, block.Hash(), blockHeight)

isMainChain, isOrphan, err := chain.ProcessBlock(block,
blockchain.BFNone)
if err != nil {
t.Fatalf("block %q (hash %s, height %d) should "+
"have been accepted: %v", item.Name,
block.Hash(), blockHeight, err)
}

// Ensure the main chain and orphan flags match the values
// specified in the test.
if isMainChain != item.IsMainChain {
t.Fatalf("block %q (hash %s, height %d) unexpected main "+
"chain flag -- got %v, want %v", item.Name,
block.Hash(), blockHeight, isMainChain,
item.IsMainChain)
}
if isOrphan != item.IsOrphan {
t.Fatalf("block %q (hash %s, height %d) unexpected "+
"orphan flag -- got %v, want %v", item.Name,
block.Hash(), blockHeight, isOrphan,
item.IsOrphan)
}
}

// testRejectedBlock attempts to process the block in the provided test
// instance and ensures that it was rejected with the reject code
// specified in the test.
testRejectedBlock := func(item fullblocktests.RejectedBlock) {
blockHeight := item.Height
block := bchutil.NewBlock(item.Block)
block.SetHeight(blockHeight)
t.Logf("Testing block %s (hash %s, height %d)",
item.Name, block.Hash(), blockHeight)

_, _, err := chain.ProcessBlock(block, blockchain.BFNone)
if err == nil {
t.Fatalf("block %q (hash %s, height %d) should not "+
"have been accepted", item.Name, block.Hash(),
blockHeight)
}

// Ensure the error code is of the expected type and the reject
// code matches the value specified in the test instance.
rerr, ok := err.(blockchain.RuleError)
if !ok {
t.Fatalf("block %q (hash %s, height %d) returned "+
"unexpected error type -- got %T, want "+
"blockchain.RuleError", item.Name, block.Hash(),
blockHeight, err)
}
if rerr.ErrorCode != item.RejectCode {
t.Fatalf("block %q (hash %s, height %d) does not have "+
"expected reject code -- got %v, want %v",
item.Name, block.Hash(), blockHeight,
rerr.ErrorCode, item.RejectCode)
}
}

for testNum, test := range tests {
for itemNum, item := range test {
switch item := item.(type) {
case fullblocktests.AcceptedBlock:
testAcceptedBlock(item)
case fullblocktests.RejectedBlock:
testRejectedBlock(item)
default:
t.Fatalf("test #%d, item #%d is not one of "+
"the supported test instance types -- "+
"got type: %T", testNum, itemNum, item)
}
}
}
}

// TestPhononActivation tests that sigchecks rules and OP_REVERSEBYTES
// activates properly.
func TestPhononActivation(t *testing.T) {
tests, err := fullblocktests.GeneratePhononBlocks()
if err != nil {
t.Fatalf("failed to generate tests: %v", err)
}

// Create a new database and chain instance to run tests against.
params := &chaincfg.RegressionNetParams
params.PhononActivationTime = 0
params.GravitonForkHeight = 0
params.MagneticAnonomalyForkHeight = 0
params.UahfForkHeight = 0
chain, teardownFunc, err := chainSetup("fullblocktest",
params, 32000000)
if err != nil {
t.Errorf("Failed to setup chain instance: %v", err)
return
Expand Down

0 comments on commit 1ce6b60

Please sign in to comment.