mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 01:40:07 +01:00
rpcclient, integration: Add invalidateblock and reconsiderblock
invalidateblock and reconsiderblock are added to the rpcclient package and an integration test is added to test the added functions.
This commit is contained in:
parent
cd5e5bab63
commit
1cb4d3a503
244
integration/invalidate_reconsider_block_test.go
Normal file
244
integration/invalidate_reconsider_block_test.go
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
|
"github.com/btcsuite/btcd/integration/rpctest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInvalidateAndReconsiderBlock(t *testing.T) {
|
||||||
|
// Set up regtest chain.
|
||||||
|
r, err := rpctest.New(&chaincfg.RegressionNetParams, nil, nil, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail."+
|
||||||
|
"Unable to create primary harness: %v", err)
|
||||||
|
}
|
||||||
|
if err := r.SetUp(true, 0); err != nil {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. "+
|
||||||
|
"Unable to setup test chain: %v", err)
|
||||||
|
}
|
||||||
|
defer r.TearDown()
|
||||||
|
|
||||||
|
// Generate 4 blocks.
|
||||||
|
//
|
||||||
|
// Our chain view looks like so:
|
||||||
|
// (genesis block) -> 1 -> 2 -> 3 -> 4
|
||||||
|
_, err = r.Client.Generate(4)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache the active tip hash.
|
||||||
|
block4ActiveTipHash, err := r.Client.GetBestBlockHash()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache block 1 hash as this will be our chaintip after we invalidate block 2.
|
||||||
|
block1Hash, err := r.Client.GetBlockHash(1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalidate block 2.
|
||||||
|
//
|
||||||
|
// Our chain view looks like so:
|
||||||
|
// (genesis block) -> 1 (active)
|
||||||
|
// \ -> 2 -> 3 -> 4 (invalid)
|
||||||
|
block2Hash, err := r.Client.GetBlockHash(2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = r.Client.InvalidateBlock(block2Hash)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that block 1 is the active chaintip.
|
||||||
|
bestHash, err := r.Client.GetBestBlockHash()
|
||||||
|
if *bestHash != *block1Hash {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. Expected the "+
|
||||||
|
"best block hash to be block 1 with hash %s but got %s",
|
||||||
|
block1Hash.String(), bestHash.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate 2 blocks.
|
||||||
|
//
|
||||||
|
// Our chain view looks like so:
|
||||||
|
// (genesis block) -> 1 -> 2a -> 3a (active)
|
||||||
|
// \ -> 2 -> 3 -> 4 (invalid)
|
||||||
|
_, err = r.Client.Generate(2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache the active tip hash for the current active tip.
|
||||||
|
block3aActiveTipHash, err := r.Client.GetBestBlockHash()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tips, err := r.Client.GetChainTips()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that there are two branches.
|
||||||
|
if len(tips) != 2 {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. "+
|
||||||
|
"Expected 2 chaintips but got %d", len(tips))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tip := range tips {
|
||||||
|
if tip.Hash == block4ActiveTipHash.String() &&
|
||||||
|
tip.Status != "invalid" {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. Expected "+
|
||||||
|
"invalidated branch tip of %s to be invalid but got %s",
|
||||||
|
tip.Hash, tip.Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconsider the invalidated block 2.
|
||||||
|
//
|
||||||
|
// Our chain view looks like so:
|
||||||
|
// (genesis block) -> 1 -> 2a -> 3a (valid-fork)
|
||||||
|
// \ -> 2 -> 3 -> 4 (active)
|
||||||
|
err = r.Client.ReconsiderBlock(block2Hash)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tips, err = r.Client.GetChainTips()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// Assert that there are two branches.
|
||||||
|
if len(tips) != 2 {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. "+
|
||||||
|
"Expected 2 chaintips but got %d", len(tips))
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkedTips int
|
||||||
|
for _, tip := range tips {
|
||||||
|
if tip.Hash == block4ActiveTipHash.String() {
|
||||||
|
if tip.Status != "active" {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. Expected "+
|
||||||
|
"the reconsidered branch tip of %s to be active but got %s",
|
||||||
|
tip.Hash, tip.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedTips++
|
||||||
|
}
|
||||||
|
|
||||||
|
if tip.Hash == block3aActiveTipHash.String() {
|
||||||
|
if tip.Status != "valid-fork" {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. Expected "+
|
||||||
|
"invalidated branch tip of %s to be valid-fork but got %s",
|
||||||
|
tip.Hash, tip.Status)
|
||||||
|
}
|
||||||
|
checkedTips++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if checkedTips != 2 {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. "+
|
||||||
|
"Expected to check %d chaintips, checked %d", 2, checkedTips)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalidate block 3a.
|
||||||
|
//
|
||||||
|
// Our chain view looks like so:
|
||||||
|
// (genesis block) -> 1 -> 2a -> 3a (invalid)
|
||||||
|
// \ -> 2 -> 3 -> 4 (active)
|
||||||
|
err = r.Client.InvalidateBlock(block3aActiveTipHash)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tips, err = r.Client.GetChainTips()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that there are two branches.
|
||||||
|
if len(tips) != 2 {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. "+
|
||||||
|
"Expected 2 chaintips but got %d", len(tips))
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedTips = 0
|
||||||
|
for _, tip := range tips {
|
||||||
|
if tip.Hash == block4ActiveTipHash.String() {
|
||||||
|
if tip.Status != "active" {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. Expected "+
|
||||||
|
"an active branch tip of %s but got %s",
|
||||||
|
tip.Hash, tip.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedTips++
|
||||||
|
}
|
||||||
|
|
||||||
|
if tip.Hash == block3aActiveTipHash.String() {
|
||||||
|
if tip.Status != "invalid" {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. Expected "+
|
||||||
|
"the invalidated tip of %s to be invalid but got %s",
|
||||||
|
tip.Hash, tip.Status)
|
||||||
|
}
|
||||||
|
checkedTips++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if checkedTips != 2 {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. "+
|
||||||
|
"Expected to check %d chaintips, checked %d", 2, checkedTips)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconsider block 3a.
|
||||||
|
//
|
||||||
|
// Our chain view looks like so:
|
||||||
|
// (genesis block) -> 1 -> 2a -> 3a (valid-fork)
|
||||||
|
// \ -> 2 -> 3 -> 4 (active)
|
||||||
|
err = r.Client.ReconsiderBlock(block3aActiveTipHash)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tips, err = r.Client.GetChainTips()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that there are two branches.
|
||||||
|
if len(tips) != 2 {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. "+
|
||||||
|
"Expected 2 chaintips but got %d", len(tips))
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedTips = 0
|
||||||
|
for _, tip := range tips {
|
||||||
|
if tip.Hash == block4ActiveTipHash.String() {
|
||||||
|
if tip.Status != "active" {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. Expected "+
|
||||||
|
"an active branch tip of %s but got %s",
|
||||||
|
tip.Hash, tip.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedTips++
|
||||||
|
}
|
||||||
|
|
||||||
|
if tip.Hash == block3aActiveTipHash.String() {
|
||||||
|
if tip.Status != "valid-fork" {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. Expected "+
|
||||||
|
"the reconsidered tip of %s to be a valid-fork but got %s",
|
||||||
|
tip.Hash, tip.Status)
|
||||||
|
}
|
||||||
|
checkedTips++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if checkedTips != 2 {
|
||||||
|
t.Fatalf("TestInvalidateAndReconsiderBlock fail. "+
|
||||||
|
"Expected to check %d chaintips, checked %d", 2, checkedTips)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user