diff --git a/blockdag/blocknode.go b/blockdag/blocknode.go index a11cb0e23..2f655c970 100644 --- a/blockdag/blocknode.go +++ b/blockdag/blocknode.go @@ -232,8 +232,8 @@ func (node *blockNode) isGenesis() bool { return len(node.parents) == 0 } -func (node *blockNode) finalityScore() uint64 { - return node.blueScore / FinalityInterval +func (node *blockNode) finalityScore(dag *BlockDAG) uint64 { + return node.blueScore / uint64(dag.dagParams.FinalityInterval) } // String returns a string that contains the block hash. diff --git a/blockdag/dag.go b/blockdag/dag.go index e647416e3..00bee8530 100644 --- a/blockdag/dag.go +++ b/blockdag/dag.go @@ -26,9 +26,6 @@ const ( // maxOrphanBlocks is the maximum number of orphan blocks that can be // queued. maxOrphanBlocks = 100 - - // FinalityInterval is the interval that determines the finality window of the DAG. - FinalityInterval = 100 ) // orphanBlock represents a block that we don't yet have the parent for. It @@ -736,14 +733,14 @@ func (dag *BlockDAG) updateFinalityPoint() { } // We are looking for a new finality point only if the new block's finality score is higher // by 2 than the existing finality point's - if selectedTip.finalityScore() < dag.lastFinalityPoint.finalityScore()+2 { + if selectedTip.finalityScore(dag) < dag.lastFinalityPoint.finalityScore(dag)+2 { return } var currentNode *blockNode for currentNode = selectedTip.selectedParent; ; currentNode = currentNode.selectedParent { // We look for the first node in the selected parent chain that has a higher finality score than the last finality point. - if currentNode.selectedParent.finalityScore() == dag.lastFinalityPoint.finalityScore() { + if currentNode.selectedParent.finalityScore(dag) == dag.lastFinalityPoint.finalityScore(dag) { break } } @@ -760,7 +757,7 @@ func (dag *BlockDAG) finalizeNodesBelowFinalityPoint(deleteDiffData bool) { } var blockHashesToDelete []*daghash.Hash if deleteDiffData { - blockHashesToDelete = make([]*daghash.Hash, 0, FinalityInterval) + blockHashesToDelete = make([]*daghash.Hash, 0, dag.dagParams.FinalityInterval) } for len(queue) > 0 { var current *blockNode diff --git a/blockdag/dag_test.go b/blockdag/dag_test.go index 16f566dfd..9e8983785 100644 --- a/blockdag/dag_test.go +++ b/blockdag/dag_test.go @@ -1234,22 +1234,22 @@ func testFinalizeNodesBelowFinalityPoint(t *testing.T, deleteDiffData bool) { flushUTXODiffStore() return node } - - nodes := make([]*blockNode, 0, FinalityInterval) + finalityInterval := dag.dagParams.FinalityInterval + nodes := make([]*blockNode, 0, finalityInterval) currentNode := dag.genesis nodes = append(nodes, currentNode) - for i := 0; i <= FinalityInterval*2; i++ { + for i := 0; i <= finalityInterval*2; i++ { currentNode = addNode(currentNode) nodes = append(nodes, currentNode) } // Manually set the last finality point - dag.lastFinalityPoint = nodes[FinalityInterval-1] + dag.lastFinalityPoint = nodes[finalityInterval-1] dag.finalizeNodesBelowFinalityPoint(deleteDiffData) flushUTXODiffStore() - for _, node := range nodes[:FinalityInterval-1] { + for _, node := range nodes[:finalityInterval-1] { if !node.isFinalized { t.Errorf("Node with blue score %d expected to be finalized", node.blueScore) } @@ -1267,7 +1267,7 @@ func testFinalizeNodesBelowFinalityPoint(t *testing.T, deleteDiffData bool) { } } - for _, node := range nodes[FinalityInterval-1:] { + for _, node := range nodes[finalityInterval-1:] { if node.isFinalized { t.Errorf("Node with blue score %d wasn't expected to be finalized", node.blueScore) } diff --git a/blockdag/external_dag_test.go b/blockdag/external_dag_test.go index 81e486dec..962e2bfe2 100644 --- a/blockdag/external_dag_test.go +++ b/blockdag/external_dag_test.go @@ -20,13 +20,13 @@ import ( // TestFinality checks that the finality mechanism works as expected. // This is how the flow goes: -// 1) We build a chain of blockdag.FinalityInterval blocks and call its tip altChainTip. -// 2) We build another chain (let's call it mainChain) of 2 * blockdag.FinalityInterval +// 1) We build a chain of params.FinalityInterval blocks and call its tip altChainTip. +// 2) We build another chain (let's call it mainChain) of 2 * params.FinalityInterval // blocks, which points to genesis, and then we check that the block in that -// chain with height of blockdag.FinalityInterval is marked as finality point (This is +// chain with height of params.FinalityInterval is marked as finality point (This is // very predictable, because the blue score of each new block in a chain is the // parents plus one). -// 3) We make a new child to block with height (2 * blockdag.FinalityInterval - 1) +// 3) We make a new child to block with height (2 * params.FinalityInterval - 1) // in mainChain, and we check that connecting it to the DAG // doesn't affect the last finality point. // 4) We make a block that points to genesis, and check that it @@ -38,6 +38,7 @@ import ( func TestFinality(t *testing.T) { params := dagconfig.SimNetParams params.K = 1 + params.FinalityInterval = 100 dag, teardownFunc, err := blockdag.DAGSetup("TestFinality", blockdag.Config{ DAGParams: ¶ms, }) @@ -70,8 +71,8 @@ func TestFinality(t *testing.T) { genesis := util.NewBlock(params.GenesisBlock) currentNode := genesis - // First we build a chain of blockdag.FinalityInterval blocks for future use - for i := 0; i < blockdag.FinalityInterval; i++ { + // First we build a chain of params.FinalityInterval blocks for future use + for i := 0; i < params.FinalityInterval; i++ { currentNode, err = buildNodeToDag([]*daghash.Hash{currentNode.Hash()}) if err != nil { t.Fatalf("TestFinality: buildNodeToDag unexpectedly returned an error: %v", err) @@ -80,10 +81,10 @@ func TestFinality(t *testing.T) { altChainTip := currentNode - // Now we build a new chain of 2 * blockdag.FinalityInterval blocks, pointed to genesis, and - // we expect the block with height 1 * blockdag.FinalityInterval to be the last finality point + // Now we build a new chain of 2 * params.FinalityInterval blocks, pointed to genesis, and + // we expect the block with height 1 * params.FinalityInterval to be the last finality point currentNode = genesis - for i := 0; i < blockdag.FinalityInterval; i++ { + for i := 0; i < params.FinalityInterval; i++ { currentNode, err = buildNodeToDag([]*daghash.Hash{currentNode.Hash()}) if err != nil { t.Fatalf("TestFinality: buildNodeToDag unexpectedly returned an error: %v", err) @@ -92,7 +93,7 @@ func TestFinality(t *testing.T) { expectedFinalityPoint := currentNode - for i := 0; i < blockdag.FinalityInterval; i++ { + for i := 0; i < params.FinalityInterval; i++ { currentNode, err = buildNodeToDag([]*daghash.Hash{currentNode.Hash()}) if err != nil { t.Fatalf("TestFinality: buildNodeToDag unexpectedly returned an error: %v", err) @@ -165,8 +166,9 @@ func TestFinality(t *testing.T) { // a getblocks message it should always be able to send // all the necessary invs. func TestFinalityInterval(t *testing.T) { - if blockdag.FinalityInterval > wire.MaxInvPerMsg { - t.Errorf("blockdag.FinalityInterval should be lower or equal to wire.MaxInvPerMsg") + params := dagconfig.SimNetParams + if params.FinalityInterval > wire.MaxInvPerMsg { + t.Errorf("dagconfig.SimNetParams.FinalityInterval should be lower or equal to wire.MaxInvPerMsg") } } diff --git a/dagconfig/params.go b/dagconfig/params.go index 2f39defe2..42e1c02c3 100644 --- a/dagconfig/params.go +++ b/dagconfig/params.go @@ -137,6 +137,9 @@ type Params struct { // block. TargetTimePerBlock time.Duration + // FinalityInterval is the interval that determines the finality window of the DAG. + FinalityInterval int + // TimestampDeviationTolerance is the maximum offset a block timestamp // is allowed to be in the future before it gets delayed TimestampDeviationTolerance uint64 @@ -205,6 +208,7 @@ var MainNetParams = Params{ BlockCoinbaseMaturity: 100, SubsidyReductionInterval: 210000, TargetTimePerBlock: time.Second * 1, // 1 second + FinalityInterval: 1000, DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize, TimestampDeviationTolerance: timestampDeviationTolerance, GenerateSupported: false, @@ -265,6 +269,7 @@ var RegressionNetParams = Params{ BlockCoinbaseMaturity: 100, SubsidyReductionInterval: 150, TargetTimePerBlock: time.Second * 1, // 1 second + FinalityInterval: 1000, DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize, TimestampDeviationTolerance: timestampDeviationTolerance, GenerateSupported: true, @@ -323,6 +328,7 @@ var TestNetParams = Params{ BlockCoinbaseMaturity: 100, SubsidyReductionInterval: 210000, TargetTimePerBlock: time.Second * 1, // 1 second + FinalityInterval: 1000, DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize, TimestampDeviationTolerance: timestampDeviationTolerance, GenerateSupported: true, @@ -387,6 +393,7 @@ var SimNetParams = Params{ BlockCoinbaseMaturity: 100, SubsidyReductionInterval: 210000, TargetTimePerBlock: time.Second * 1, // 1 second + FinalityInterval: 1000, DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize, TimestampDeviationTolerance: timestampDeviationTolerance, GenerateSupported: true, @@ -443,6 +450,7 @@ var DevNetParams = Params{ BlockCoinbaseMaturity: 100, SubsidyReductionInterval: 210000, TargetTimePerBlock: time.Second * 1, // 1 second + FinalityInterval: 1000, DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize, TimestampDeviationTolerance: timestampDeviationTolerance, GenerateSupported: true,