mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-06 22:26:47 +00:00

* Avoid creating the chain iterator if high hash is actually low hash * Always use iterator in nextPruningPointAndCandidateByBlockHash * Initial failing test * Minimal failing test + some comments * go lint * Add simpler tests with two different errors * Missed some error checks * Minor * A workaround patch for preventing the missing utxo child diff bug * Make sure we fully resolve virtual * Move ResolveVirtualWithMaxParam to test consensus * Mark virtual not updated and loop in batches * Refactor: remove VirtualChangeSet from functions return values * Remove workaround comments * If block has no body, virtual is still considered updated * Remove special error ErrReverseUTXODiffsUTXODiffChildNotFound Co-authored-by: Ori Newman <orinewman1@gmail.com>
215 lines
7.0 KiB
Go
215 lines
7.0 KiB
Go
package consensusstatemanager_test
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
|
"testing"
|
|
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
|
|
"github.com/kaspanet/kaspad/domain/consensus"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
|
|
)
|
|
|
|
func TestAddBlockBetweenResolveVirtualCalls(t *testing.T) {
|
|
|
|
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
|
factory := consensus.NewFactory()
|
|
|
|
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestAddBlockBetweenResolveVirtualCalls")
|
|
if err != nil {
|
|
t.Fatalf("Error setting up consensus: %+v", err)
|
|
}
|
|
defer teardown(false)
|
|
|
|
// Create a chain of blocks
|
|
const initialChainLength = 10
|
|
previousBlockHash := consensusConfig.GenesisHash
|
|
for i := 0; i < initialChainLength; i++ {
|
|
previousBlockHash, _, err = tc.AddBlock([]*externalapi.DomainHash{previousBlockHash}, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in initial chain: %+v", i, err)
|
|
}
|
|
}
|
|
|
|
// Mine a chain with more blocks, to re-organize the DAG
|
|
const reorgChainLength = initialChainLength + 1
|
|
previousBlockHash = consensusConfig.GenesisHash
|
|
for i := 0; i < reorgChainLength; i++ {
|
|
previousBlock, _, err := tc.BuildBlockWithParents([]*externalapi.DomainHash{previousBlockHash}, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in re-org chain: %+v", i, err)
|
|
}
|
|
previousBlockHash = consensushashing.BlockHash(previousBlock)
|
|
|
|
// Do not UTXO validate in order to resolve virtual later
|
|
err = tc.ValidateAndInsertBlock(previousBlock, false)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in re-org chain: %+v", i, err)
|
|
}
|
|
}
|
|
|
|
// Resolve one step
|
|
_, err = tc.ResolveVirtualWithMaxParam(2)
|
|
if err != nil {
|
|
t.Fatalf("Error resolving virtual in re-org chain: %+v", err)
|
|
}
|
|
|
|
emptyCoinbase := &externalapi.DomainCoinbaseData{
|
|
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
|
Script: nil,
|
|
Version: 0,
|
|
},
|
|
}
|
|
|
|
// Get template based on current resolve state
|
|
blockTemplate, err := tc.BuildBlockTemplate(emptyCoinbase, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error building block template during virtual resolution of reorg: %+v", err)
|
|
}
|
|
|
|
// Resolve one more step
|
|
isCompletelyResolved, err := tc.ResolveVirtualWithMaxParam(2)
|
|
if err != nil {
|
|
t.Fatalf("Error resolving virtual in re-org chain: %+v", err)
|
|
}
|
|
|
|
// Add the mined block (now virtual was modified)
|
|
err = tc.ValidateAndInsertBlock(blockTemplate.Block, true)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block during virtual resolution of reorg: %+v", err)
|
|
}
|
|
|
|
// Complete resolving virtual
|
|
for !isCompletelyResolved {
|
|
isCompletelyResolved, err = tc.ResolveVirtualWithMaxParam(2)
|
|
if err != nil {
|
|
t.Fatalf("Error resolving virtual in re-org chain: %+v", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestAddGenesisChildAfterOneResolveVirtualCall(t *testing.T) {
|
|
|
|
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
|
factory := consensus.NewFactory()
|
|
|
|
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestAddGenesisChildAfterOneResolveVirtualCall")
|
|
if err != nil {
|
|
t.Fatalf("Error setting up consensus: %+v", err)
|
|
}
|
|
defer teardown(false)
|
|
|
|
// Create a chain of blocks
|
|
const initialChainLength = 6
|
|
previousBlockHash := consensusConfig.GenesisHash
|
|
for i := 0; i < initialChainLength; i++ {
|
|
previousBlockHash, _, err = tc.AddBlock([]*externalapi.DomainHash{previousBlockHash}, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in initial chain: %+v", i, err)
|
|
}
|
|
}
|
|
|
|
// Mine a chain with more blocks, to re-organize the DAG
|
|
const reorgChainLength = initialChainLength + 1
|
|
previousBlockHash = consensusConfig.GenesisHash
|
|
for i := 0; i < reorgChainLength; i++ {
|
|
previousBlock, _, err := tc.BuildBlockWithParents([]*externalapi.DomainHash{previousBlockHash}, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in re-org chain: %+v", i, err)
|
|
}
|
|
previousBlockHash = consensushashing.BlockHash(previousBlock)
|
|
|
|
// Do not UTXO validate in order to resolve virtual later
|
|
err = tc.ValidateAndInsertBlock(previousBlock, false)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in re-org chain: %+v", i, err)
|
|
}
|
|
}
|
|
|
|
// Resolve one step
|
|
isCompletelyResolved, err := tc.ResolveVirtualWithMaxParam(2)
|
|
if err != nil {
|
|
t.Fatalf("Error resolving virtual in re-org chain: %+v", err)
|
|
}
|
|
|
|
_, _, err = tc.AddBlock([]*externalapi.DomainHash{consensusConfig.GenesisHash}, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error adding block during virtual resolution of reorg: %+v", err)
|
|
}
|
|
|
|
// Complete resolving virtual
|
|
for !isCompletelyResolved {
|
|
isCompletelyResolved, err = tc.ResolveVirtualWithMaxParam(2)
|
|
if err != nil {
|
|
t.Fatalf("Error resolving virtual in re-org chain: %+v", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestAddGenesisChildAfterTwoResolveVirtualCalls(t *testing.T) {
|
|
|
|
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
|
factory := consensus.NewFactory()
|
|
|
|
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestAddGenesisChildAfterTwoResolveVirtualCalls")
|
|
if err != nil {
|
|
t.Fatalf("Error setting up consensus: %+v", err)
|
|
}
|
|
defer teardown(false)
|
|
|
|
// Create a chain of blocks
|
|
const initialChainLength = 6
|
|
previousBlockHash := consensusConfig.GenesisHash
|
|
for i := 0; i < initialChainLength; i++ {
|
|
previousBlockHash, _, err = tc.AddBlock([]*externalapi.DomainHash{previousBlockHash}, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in initial chain: %+v", i, err)
|
|
}
|
|
}
|
|
|
|
// Mine a chain with more blocks, to re-organize the DAG
|
|
const reorgChainLength = initialChainLength + 1
|
|
previousBlockHash = consensusConfig.GenesisHash
|
|
for i := 0; i < reorgChainLength; i++ {
|
|
previousBlock, _, err := tc.BuildBlockWithParents([]*externalapi.DomainHash{previousBlockHash}, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in re-org chain: %+v", i, err)
|
|
}
|
|
previousBlockHash = consensushashing.BlockHash(previousBlock)
|
|
|
|
// Do not UTXO validate in order to resolve virtual later
|
|
err = tc.ValidateAndInsertBlock(previousBlock, false)
|
|
if err != nil {
|
|
t.Fatalf("Error mining block no. %d in re-org chain: %+v", i, err)
|
|
}
|
|
}
|
|
|
|
// Resolve one step
|
|
_, err = tc.ResolveVirtualWithMaxParam(2)
|
|
if err != nil {
|
|
t.Fatalf("Error resolving virtual in re-org chain: %+v", err)
|
|
}
|
|
|
|
// Resolve one more step
|
|
isCompletelyResolved, err := tc.ResolveVirtualWithMaxParam(2)
|
|
if err != nil {
|
|
t.Fatalf("Error resolving virtual in re-org chain: %+v", err)
|
|
}
|
|
|
|
_, _, err = tc.AddBlock([]*externalapi.DomainHash{consensusConfig.GenesisHash}, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("Error adding block during virtual resolution of reorg: %+v", err)
|
|
}
|
|
|
|
// Complete resolving virtual
|
|
for !isCompletelyResolved {
|
|
isCompletelyResolved, err = tc.ResolveVirtualWithMaxParam(2)
|
|
if err != nil {
|
|
t.Fatalf("Error resolving virtual in re-org chain: %+v", err)
|
|
}
|
|
}
|
|
})
|
|
}
|