forked from btcsuite/btcd
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Validate softforking mechanism with the fullblock tester.
All corner cases are thoroughly documented in the Generate function in file blockchain/stakeversiontests/generate.go. Fixes btcsuite#525
- Loading branch information
1 parent
e3eb40b
commit 88e4de2
Showing
4 changed files
with
2,498 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Copyright (c) 2016 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 | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/decred/dcrd/blockchain" | ||
"github.com/decred/dcrd/blockchain/stakeversiontests" | ||
"github.com/decred/dcrd/chaincfg" | ||
"github.com/decred/dcrutil" | ||
) | ||
|
||
// TestFullBlocksStakeVersion ensures all tests generated by the | ||
// stakeversiontests package have the expected result when processed via | ||
// ProcessBlock. | ||
func TestFullBlocksStakeVersion(t *testing.T) { | ||
// Skip tests when running with -short | ||
if testing.Short() { | ||
t.Skip("Skipping stake/voter full block tests in short mode") | ||
} | ||
|
||
tests, err := stakeversiontests.Generate() | ||
if err != nil { | ||
t.Fatalf("failed to generate tests: %v", err) | ||
} | ||
|
||
// Create a new database and chain instance to run tests against. | ||
chain, teardownFunc, err := chainSetup("stakeversiontest", | ||
&chaincfg.SimNetParams) | ||
if err != nil { | ||
t.Fatalf("Failed to setup chain instance: %v", err) | ||
} | ||
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 stakeversiontests.AcceptedBlock) { | ||
blockHeight := item.Block.Header.Height | ||
block := dcrutil.NewBlock(item.Block) | ||
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 stakeversiontests.RejectedBlock) { | ||
blockHeight := item.Block.Header.Height | ||
block := dcrutil.NewBlock(item.Block) | ||
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, item := range tests { | ||
switch item := item.(type) { | ||
case stakeversiontests.AcceptedBlock: | ||
testAcceptedBlock(item) | ||
case stakeversiontests.RejectedBlock: | ||
testRejectedBlock(item) | ||
default: | ||
t.Fatalf("test #%d, is not one of the supported test "+ | ||
"instance types -- got type: %T", testNum, | ||
testNum, item) | ||
} | ||
} | ||
} |
Oops, something went wrong.