mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-10-14 00:59:33 +00:00
Tests validateDifficulty ( ValidatePruningPointViolationAndProofOfWorkAndDifficulty) (#1532)
* Adds tests for validateDifficulty * fixes according to the review notes: adding the test's goal and fix an unmatch test name on the NewTestConsensus. * Fixes according to the review notes:delete the function genesisBits - No usages. * Fix according to review - fix comments. Co-authored-by: tal <tal@daglabs.com> Co-authored-by: Ori Newman <orinewman1@gmail.com>
This commit is contained in:
parent
a250f697ee
commit
35e555e959
@ -1,6 +1,17 @@
|
|||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import "github.com/kaspanet/kaspad/domain/consensus/model"
|
import (
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
|
"math/big"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// GHOSTDAGManagerConstructor is the function signature for a constructor of a type implementing model.GHOSTDAGManager
|
// GHOSTDAGManagerConstructor is the function signature for a constructor of a type implementing model.GHOSTDAGManager
|
||||||
type GHOSTDAGManagerConstructor func(model.DBReader, model.DAGTopologyManager, model.GHOSTDAGDataStore, model.BlockHeaderStore, model.KType) model.GHOSTDAGManager
|
type GHOSTDAGManagerConstructor func(model.DBReader, model.DAGTopologyManager,
|
||||||
|
model.GHOSTDAGDataStore, model.BlockHeaderStore, model.KType) model.GHOSTDAGManager
|
||||||
|
|
||||||
|
// DifficultyManagerConstructor is the function signature for a constructor of a type implementing model.DifficultyManager
|
||||||
|
type DifficultyManagerConstructor func(model.DBReader, model.GHOSTDAGManager, model.GHOSTDAGDataStore,
|
||||||
|
model.BlockHeaderStore, model.DAGTopologyManager, model.DAGTraversalManager, *big.Int, int, bool, time.Duration,
|
||||||
|
*externalapi.DomainHash) model.DifficultyManager
|
||||||
|
@ -63,19 +63,22 @@ type Factory interface {
|
|||||||
SetTestGHOSTDAGManager(ghostdagConstructor GHOSTDAGManagerConstructor)
|
SetTestGHOSTDAGManager(ghostdagConstructor GHOSTDAGManagerConstructor)
|
||||||
SetTestLevelDBCacheSize(cacheSizeMiB int)
|
SetTestLevelDBCacheSize(cacheSizeMiB int)
|
||||||
SetTestPreAllocateCache(preallocateCaches bool)
|
SetTestPreAllocateCache(preallocateCaches bool)
|
||||||
|
SetTestDifficultyManager(difficultyConstructor DifficultyManagerConstructor)
|
||||||
}
|
}
|
||||||
|
|
||||||
type factory struct {
|
type factory struct {
|
||||||
dataDir string
|
dataDir string
|
||||||
ghostdagConstructor GHOSTDAGManagerConstructor
|
ghostdagConstructor GHOSTDAGManagerConstructor
|
||||||
cacheSizeMiB *int
|
difficultyConstructor DifficultyManagerConstructor
|
||||||
preallocateCaches *bool
|
cacheSizeMiB *int
|
||||||
|
preallocateCaches *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFactory creates a new Consensus factory
|
// NewFactory creates a new Consensus factory
|
||||||
func NewFactory() Factory {
|
func NewFactory() Factory {
|
||||||
return &factory{
|
return &factory{
|
||||||
ghostdagConstructor: ghostdagmanager.New,
|
ghostdagConstructor: ghostdagmanager.New,
|
||||||
|
difficultyConstructor: difficultymanager.New,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +162,7 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
|
|||||||
dbManager,
|
dbManager,
|
||||||
pastMedianTimeManager,
|
pastMedianTimeManager,
|
||||||
ghostdagDataStore)
|
ghostdagDataStore)
|
||||||
difficultyManager := difficultymanager.New(
|
difficultyManager := f.difficultyConstructor(
|
||||||
dbManager,
|
dbManager,
|
||||||
ghostdagManager,
|
ghostdagManager,
|
||||||
ghostdagDataStore,
|
ghostdagDataStore,
|
||||||
@ -466,6 +469,11 @@ func (f *factory) SetTestGHOSTDAGManager(ghostdagConstructor GHOSTDAGManagerCons
|
|||||||
f.ghostdagConstructor = ghostdagConstructor
|
f.ghostdagConstructor = ghostdagConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTestDifficultyManager is a setter for the difficultyManager field on the factory.
|
||||||
|
func (f *factory) SetTestDifficultyManager(difficultyConstructor DifficultyManagerConstructor) {
|
||||||
|
f.difficultyConstructor = difficultyConstructor
|
||||||
|
}
|
||||||
|
|
||||||
func (f *factory) SetTestLevelDBCacheSize(cacheSizeMiB int) {
|
func (f *factory) SetTestLevelDBCacheSize(cacheSizeMiB int) {
|
||||||
f.cacheSizeMiB = &cacheSizeMiB
|
f.cacheSizeMiB = &cacheSizeMiB
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package blockvalidator_test
|
package blockvalidator_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/pow"
|
"github.com/kaspanet/kaspad/domain/consensus/model/pow"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/blockheader"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/blockheader"
|
||||||
@ -12,8 +13,8 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus"
|
"github.com/kaspanet/kaspad/domain/consensus"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
@ -241,3 +242,60 @@ func TestCheckPruningPointViolation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestValidateDifficulty verifies that in case of a block with an unexpected difficulty,
|
||||||
|
// an appropriate error message (ErrUnexpectedDifficulty) will be returned on the
|
||||||
|
// function ValidatePruningPointViolationAndProofOfWorkAndDifficulty. The required difficulty is
|
||||||
|
// "calculated" by the function (dm *mocDifficultyManager) RequiredDifficulty ,
|
||||||
|
// where mocDifficultyManager is special implementation of the type DifficultyManager for this test (defined below).
|
||||||
|
func TestValidateDifficulty(t *testing.T) {
|
||||||
|
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {
|
||||||
|
|
||||||
|
factory := consensus.NewFactory()
|
||||||
|
mocDifficulty := &mocDifficultyManager{}
|
||||||
|
factory.SetTestDifficultyManager(func(model.DBReader, model.GHOSTDAGManager, model.GHOSTDAGDataStore,
|
||||||
|
model.BlockHeaderStore, model.DAGTopologyManager, model.DAGTraversalManager, *big.Int, int, bool, time.Duration,
|
||||||
|
*externalapi.DomainHash) model.DifficultyManager {
|
||||||
|
return mocDifficulty
|
||||||
|
})
|
||||||
|
genesisDifficulty := params.GenesisBlock.Header.Bits()
|
||||||
|
mocDifficulty.testDifficulty = genesisDifficulty
|
||||||
|
mocDifficulty.testGenesisBits = genesisDifficulty
|
||||||
|
tc, teardown, err := factory.NewTestConsensus(params, false, "TestValidateDifficulty")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error setting up consensus: %+v", err)
|
||||||
|
}
|
||||||
|
defer teardown(false)
|
||||||
|
|
||||||
|
emptyCoinbase := externalapi.DomainCoinbaseData{
|
||||||
|
ScriptPublicKey: &externalapi.ScriptPublicKey{
|
||||||
|
Script: nil,
|
||||||
|
Version: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
block, _, err := tc.BuildBlockWithParents([]*externalapi.DomainHash{params.GenesisHash}, &emptyCoinbase, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("TestValidateDifficulty: Failed build block with parents: %v.", err)
|
||||||
|
}
|
||||||
|
blockHash := consensushashing.BlockHash(block)
|
||||||
|
tc.BlockStore().Stage(blockHash, block)
|
||||||
|
tc.BlockHeaderStore().Stage(blockHash, block.Header)
|
||||||
|
wrongTestDifficulty := mocDifficulty.testDifficulty + uint32(5)
|
||||||
|
mocDifficulty.testDifficulty = wrongTestDifficulty
|
||||||
|
|
||||||
|
err = tc.BlockValidator().ValidatePruningPointViolationAndProofOfWorkAndDifficulty(blockHash)
|
||||||
|
if err == nil || !errors.Is(err, ruleerrors.ErrUnexpectedDifficulty) {
|
||||||
|
t.Fatalf("Expected block to be invalid with err: %v, instead found: %v", ruleerrors.ErrUnexpectedDifficulty, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type mocDifficultyManager struct {
|
||||||
|
testDifficulty uint32
|
||||||
|
testGenesisBits uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequiredDifficulty returns the difficulty required for the test
|
||||||
|
func (dm *mocDifficultyManager) RequiredDifficulty(*externalapi.DomainHash) (uint32, error) {
|
||||||
|
return dm.testDifficulty, nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user