mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
Add TestFinality back (#1129)
* Add VirtualFinalityPoint to TestConsensusStateManager * Add TestFinality back
This commit is contained in:
parent
950dd0cc8d
commit
b3a3121725
169
domain/consensus/finality_test.go
Normal file
169
domain/consensus/finality_test.go
Normal file
@ -0,0 +1,169 @@
|
||||
package consensus
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFinality(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||
// Set finalityInterval to 50 blocks, so that test runs quickly
|
||||
params.FinalityDuration = 50 * params.TargetTimePerBlock
|
||||
|
||||
factory := NewFactory()
|
||||
consensus, teardown, err := factory.NewTestConsensus(params, "TestFinality")
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up consensus: %+v", err)
|
||||
}
|
||||
defer teardown()
|
||||
|
||||
buildAndInsertBlock := func(parentHashes []*externalapi.DomainHash) (*externalapi.DomainBlock, error) {
|
||||
block, err := consensus.BuildBlockWithParents(parentHashes, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = consensus.ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return block, nil
|
||||
}
|
||||
|
||||
// Build a chain of `finalityInterval - 1` blocks
|
||||
finalityInterval := params.FinalityDepth()
|
||||
var mainChainTip *externalapi.DomainBlock
|
||||
mainChainTipHash := params.GenesisHash
|
||||
|
||||
for i := uint64(0); i < finalityInterval-1; i++ {
|
||||
mainChainTip, err = buildAndInsertBlock([]*externalapi.DomainHash{mainChainTipHash})
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed to process Block #%d: %v", i, err)
|
||||
}
|
||||
mainChainTipHash = consensusserialization.BlockHash(mainChainTip)
|
||||
|
||||
blockInfo, err := consensus.GetBlockInfo(mainChainTipHash)
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Block #%d failed to get info: %v", i, err)
|
||||
}
|
||||
if blockInfo.BlockStatus != externalapi.StatusValid {
|
||||
t.Fatalf("Block #%d in main chain expected to have status '%s', but got '%s'",
|
||||
i, externalapi.StatusValid, blockInfo.BlockStatus)
|
||||
}
|
||||
}
|
||||
|
||||
// Mine another chain of `finality-Interval - 2` blocks
|
||||
var sideChainTip *externalapi.DomainBlock
|
||||
sideChainTipHash := params.GenesisHash
|
||||
for i := uint64(0); i < finalityInterval-2; i++ {
|
||||
sideChainTip, err = buildAndInsertBlock([]*externalapi.DomainHash{sideChainTipHash})
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed to process sidechain Block #%d: %v", i, err)
|
||||
}
|
||||
sideChainTipHash = consensusserialization.BlockHash(sideChainTip)
|
||||
|
||||
blockInfo, err := consensus.GetBlockInfo(sideChainTipHash)
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Block #%d failed to get info: %v", i, err)
|
||||
} else if !blockInfo.Exists {
|
||||
t.Fatalf("TestFinality: Failed getting block info, doesn't exists")
|
||||
}
|
||||
if blockInfo.BlockStatus != externalapi.StatusUTXOPendingVerification {
|
||||
t.Fatalf("Block #%d in side chain expected to have status '%s', but got '%s'",
|
||||
i, externalapi.StatusUTXOPendingVerification, blockInfo.BlockStatus)
|
||||
}
|
||||
}
|
||||
|
||||
// Add two more blocks in the side-chain until it becomes the selected chain
|
||||
for i := uint64(0); i < 2; i++ {
|
||||
sideChainTip, err = buildAndInsertBlock([]*externalapi.DomainHash{sideChainTipHash})
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed to process sidechain Block #%d: %v", i, err)
|
||||
}
|
||||
sideChainTipHash = consensusserialization.BlockHash(sideChainTip)
|
||||
}
|
||||
|
||||
// Make sure that now the sideChainTip is valid and selectedTip
|
||||
blockInfo, err := consensus.GetBlockInfo(sideChainTipHash)
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed to get block info: %v", err)
|
||||
} else if !blockInfo.Exists {
|
||||
t.Fatalf("TestFinality: Failed getting block info, doesn't exists")
|
||||
}
|
||||
if blockInfo.BlockStatus != externalapi.StatusValid {
|
||||
t.Fatalf("TestFinality: Overtaking block in side-chain expected to have status '%s', but got '%s'",
|
||||
externalapi.StatusValid, blockInfo.BlockStatus)
|
||||
}
|
||||
selectedTip, err := consensus.GetVirtualSelectedParent()
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed getting virtual selectedParent: %v", err)
|
||||
}
|
||||
if *consensusserialization.BlockHash(selectedTip) != *sideChainTipHash {
|
||||
t.Fatalf("Overtaking block in side-chain is not selectedTip")
|
||||
}
|
||||
|
||||
// Add two more blocks to main chain, to move finality point to first non-genesis block in mainChain
|
||||
for i := uint64(0); i < 2; i++ {
|
||||
mainChainTip, err = buildAndInsertBlock([]*externalapi.DomainHash{mainChainTipHash})
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed to process sidechain Block #%d: %v", i, err)
|
||||
}
|
||||
mainChainTipHash = consensusserialization.BlockHash(mainChainTip)
|
||||
}
|
||||
|
||||
virtualFinality, err := consensus.ConsensusStateManager().VirtualFinalityPoint()
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed getting the virtual's finality point: %v", err)
|
||||
}
|
||||
|
||||
if *virtualFinality == *params.GenesisHash {
|
||||
t.Fatalf("virtual's finalityPoint is still genesis after adding finalityInterval + 1 blocks to the main chain")
|
||||
}
|
||||
|
||||
// TODO: Make sure that a finality conflict notification is sent
|
||||
// Add two more blocks to the side chain, so that it violates finality and gets status UTXOPendingVerification even
|
||||
// though it is the block with the highest blue score.
|
||||
for i := uint64(0); i < 2; i++ {
|
||||
sideChainTip, err = buildAndInsertBlock([]*externalapi.DomainHash{sideChainTipHash})
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed to process sidechain Block #%d: %v", i, err)
|
||||
}
|
||||
sideChainTipHash = consensusserialization.BlockHash(sideChainTip)
|
||||
}
|
||||
|
||||
// Check that sideChainTip hash higher blue score than the selected parent
|
||||
selectedTip, err = consensus.GetVirtualSelectedParent()
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed getting virtual selectedParent: %v", err)
|
||||
}
|
||||
selectedTipGhostDagData, err := consensus.GHOSTDAGDataStore().Get(consensus.DatabaseContext(), consensusserialization.BlockHash(selectedTip))
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed getting the ghost dag data of the selected tip: %v", err)
|
||||
}
|
||||
|
||||
sideChainTipGhostDagData, err := consensus.GHOSTDAGDataStore().Get(consensus.DatabaseContext(), sideChainTipHash)
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed getting the ghost dag data of the sidechain tip: %v", err)
|
||||
}
|
||||
|
||||
if selectedTipGhostDagData.BlueScore > sideChainTipGhostDagData.BlueScore {
|
||||
t.Fatalf("sideChainTip is not the bluest tip when it is expected to be")
|
||||
}
|
||||
|
||||
// Blocks violating finality should have a UTXOPendingVerification status
|
||||
blockInfo, err = consensus.GetBlockInfo(sideChainTipHash)
|
||||
if err != nil {
|
||||
t.Fatalf("TestFinality: Failed to get block info: %v", err)
|
||||
} else if !blockInfo.Exists {
|
||||
t.Fatalf("TestFinality: Failed getting block info, doesn't exists")
|
||||
}
|
||||
if blockInfo.BlockStatus != externalapi.StatusUTXOPendingVerification {
|
||||
t.Fatalf("TestFinality: Finality violating block expected to have status '%s', but got '%s'",
|
||||
externalapi.StatusUTXOPendingVerification, blockInfo.BlockStatus)
|
||||
}
|
||||
})
|
||||
}
|
@ -18,4 +18,5 @@ type TestConsensusStateManager interface {
|
||||
AddUTXOToMultiset(multiset Multiset, entry *externalapi.UTXOEntry,
|
||||
outpoint *externalapi.DomainOutpoint) error
|
||||
ResolveBlockStatus(blockHash *externalapi.DomainHash) (externalapi.BlockStatus, error)
|
||||
VirtualFinalityPoint() (*externalapi.DomainHash, error)
|
||||
}
|
||||
|
@ -23,3 +23,7 @@ func (csm testConsensusStateManager) AddUTXOToMultiset(
|
||||
func (csm testConsensusStateManager) ResolveBlockStatus(blockHash *externalapi.DomainHash) (externalapi.BlockStatus, error) {
|
||||
return csm.resolveBlockStatus(blockHash)
|
||||
}
|
||||
|
||||
func (csm testConsensusStateManager) VirtualFinalityPoint() (*externalapi.DomainHash, error) {
|
||||
return csm.virtualFinalityPoint()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user