Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mainnet karlsenhashv2 #52

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"runtime"
"time"

"github.com/karlsen-network/karlsend/domain/consensus/utils/pow"
"github.com/karlsen-network/karlsend/infrastructure/config"
"github.com/karlsen-network/karlsend/infrastructure/db/database"
"github.com/karlsen-network/karlsend/infrastructure/db/database/ldb"
Expand Down Expand Up @@ -82,6 +83,12 @@ func (app *karlsendApp) main(startedChan chan<- struct{}) error {

// Show version at startup.
log.Infof("Version %s", version.Version())
log.Infof("Using KarlsenHashV2 impl: %s", pow.GetHashingAlgoVersion())
if !app.cfg.Testnet && !app.cfg.Devnet && !app.cfg.Simnet {
log.Warnf("You are trying to connect to Mainnet")
log.Errorf("This version is using KarlsenHashV2, please add --testnet parameter")
os.Exit(42)
}

// Enable http profiling server if requested.
if app.cfg.Profile != "" {
Expand Down
3 changes: 3 additions & 0 deletions app/protocol/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ func (m *Manager) AddTransaction(tx *externalapi.DomainTransaction, allowOrphan

// AddBlock adds the given block to the DAG and propagates it.
func (m *Manager) AddBlock(block *externalapi.DomainBlock) error {
//TODO switch this to debug level
log.Infof("NEW BLOCK ADDED ***************************************")
log.Infof("BlueWork[%s] BlueScore[%d] DAAScore[%d] Bits[%d] Version[%d]", block.Header.BlueWork(), block.Header.BlueScore(), block.Header.DAAScore(), block.Header.Bits(), block.Header.Version())
return m.context.AddBlock(block)
}

Expand Down
2 changes: 2 additions & 0 deletions cmd/karlsenminer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

_ "net/http/pprof"

"github.com/karlsen-network/karlsend/domain/consensus/utils/pow"
"github.com/karlsen-network/karlsend/infrastructure/os/signal"
"github.com/karlsen-network/karlsend/util/panics"
"github.com/karlsen-network/karlsend/util/profiling"
Expand All @@ -29,6 +30,7 @@ func main() {

// Show version at startup.
log.Infof("Version %s", version.Version())
log.Infof("Using KarlsenHashV2 impl: %s", pow.GetHashingAlgoVersion())

// Enable http profiling server if requested.
if cfg.Profile != "" {
Expand Down
17 changes: 15 additions & 2 deletions cmd/karlsenminer/mineloop.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
)

var hashesTried uint64
var dagReady = false

const logHashRateInterval = 10 * time.Second

Expand Down Expand Up @@ -97,6 +98,12 @@ func logHashRate() {
spawn("logHashRate", func() {
lastCheck := time.Now()
for range time.Tick(logHashRateInterval) {

if !dagReady {
log.Infof("Generating DAG, please wait ...")
continue
}

currentHashesTried := atomic.LoadUint64(&hashesTried)
currentTime := time.Now()
kiloHashesTried := float64(currentHashesTried) / 1000.0
Expand Down Expand Up @@ -138,7 +145,11 @@ func handleFoundBlock(client *minerClient, block *externalapi.DomainBlock) error
func mineNextBlock(mineWhenNotSynced bool) *externalapi.DomainBlock {
nonce := rand.Uint64() // Use the global concurrent-safe random source.
for {
if !dagReady {
continue
}
nonce++
//fmt.Printf("mineNextBlock -- log1\n")
// For each nonce we try to build a block from the most up to date
// block template.
// In the rare case where the nonce space is exhausted for a specific
Expand All @@ -165,7 +176,6 @@ func getBlockForMining(mineWhenNotSynced bool) (*externalapi.DomainBlock, *pow.S

for {
tryCount++

shouldLog := (tryCount-1)%10 == 0
template, state, isSynced := templatemanager.Get()
if template == nil {
Expand Down Expand Up @@ -207,7 +217,10 @@ func templatesLoop(client *minerClient, miningAddr util.Address, errChan chan er
errChan <- errors.Wrapf(err, "Error getting block template from %s", client.Address())
return
}
err = templatemanager.Set(template)
err = templatemanager.Set(template, backendLog)
// after first template DAG is supposed to be ready
// TODO: refresh dag status in real time
dagReady = true
if err != nil {
errChan <- errors.Wrapf(err, "Error setting block template from %s", client.Address())
return
Expand Down
6 changes: 4 additions & 2 deletions cmd/karlsenminer/templatemanager/templatemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/karlsen-network/karlsend/app/appmessage"
"github.com/karlsen-network/karlsend/domain/consensus/model/externalapi"
"github.com/karlsen-network/karlsend/domain/consensus/utils/pow"
"github.com/karlsen-network/karlsend/infrastructure/logger"
)

var currentTemplate *externalapi.DomainBlock
Expand All @@ -27,15 +28,16 @@ func Get() (*externalapi.DomainBlock, *pow.State, bool) {
}

// Set sets the current template to work on
func Set(template *appmessage.GetBlockTemplateResponseMessage) error {
func Set(template *appmessage.GetBlockTemplateResponseMessage, backendLog *logger.Backend) error {
block, err := appmessage.RPCBlockToDomainBlock(template.Block)
if err != nil {
return err
}
lock.Lock()
defer lock.Unlock()
currentTemplate = block
currentState = pow.NewState(block.Header.ToMutable())
pow.SetLogger(backendLog, logger.LevelTrace)
currentState = pow.NewState(block.Header.ToMutable(), true)
isSynced = template.IsSynced
return nil
}
2 changes: 2 additions & 0 deletions domain/consensus/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
config.MaxBlockParents,
config.TimestampDeviationTolerance,
config.TargetTimePerBlock,
config.HFDAAScore,
config.MaxBlockLevel,

dbManager,
Expand Down Expand Up @@ -397,6 +398,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
blockBuilder := blockbuilder.New(
dbManager,
genesisHash,
config.HFDAAScore,

difficultyManager,
pastMedianTimeManager,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ type DifficultyManager interface {
StageDAADataAndReturnRequiredDifficulty(stagingArea *StagingArea, blockHash *externalapi.DomainHash, isBlockWithTrustedData bool) (uint32, error)
RequiredDifficulty(stagingArea *StagingArea, blockHash *externalapi.DomainHash) (uint32, error)
EstimateNetworkHashesPerSecond(startHash *externalapi.DomainHash, windowSize int) (uint64, error)
GenesisDifficulty() uint32
}
16 changes: 15 additions & 1 deletion domain/consensus/processes/blockbuilder/block_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
type blockBuilder struct {
databaseContext model.DBManager
genesisHash *externalapi.DomainHash
hfDAAScore uint64

difficultyManager model.DifficultyManager
pastMedianTimeManager model.PastMedianTimeManager
Expand All @@ -42,6 +43,7 @@ type blockBuilder struct {
func New(
databaseContext model.DBManager,
genesisHash *externalapi.DomainHash,
hfDAAScore uint64,

difficultyManager model.DifficultyManager,
pastMedianTimeManager model.PastMedianTimeManager,
Expand All @@ -63,6 +65,7 @@ func New(
return &blockBuilder{
databaseContext: databaseContext,
genesisHash: genesisHash,
hfDAAScore: hfDAAScore,

difficultyManager: difficultyManager,
pastMedianTimeManager: pastMedianTimeManager,
Expand Down Expand Up @@ -207,6 +210,12 @@ func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions
if err != nil {
return nil, err
}

// adjust the difficulty
/*if daaScore <= (bb.hfDAAScore+10) && daaScore >= bb.hfDAAScore {
bits = bb.difficultyManager.GenesisDifficulty()
}*/

hashMerkleRoot := bb.newBlockHashMerkleRoot(transactions)
acceptedIDMerkleRoot, err := bb.newBlockAcceptedIDMerkleRoot(stagingArea)
if err != nil {
Expand All @@ -225,8 +234,13 @@ func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions
return nil, err
}

version := constants.BlockVersionKHashV1
if daaScore >= bb.hfDAAScore {
version = constants.BlockVersionKHashV2
}

return blockheader.NewImmutableBlockHeader(
constants.BlockVersion,
version,
parents,
hashMerkleRoot,
acceptedIDMerkleRoot,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,14 @@ func (bb *testBlockBuilder) buildUTXOInvalidHeader(stagingArea *model.StagingAre
})
}

version := constants.BlockVersionKHashV1
if daaScore >= bb.hfDAAScore {
version = constants.BlockVersionKHashV2
}

bb.nonceCounter++
return blockheader.NewImmutableBlockHeader(
constants.BlockVersion,
version,
parents,
hashMerkleRoot,
&externalapi.DomainHash{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ func initBlockWithFirstTransactionDifferentThanCoinbase(consensusConfig *consens

return &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
constants.BlockVersion,
constants.BlockVersionKHashV1,
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{consensusConfig.GenesisHash}},
merkle.CalculateHashMerkleRoot([]*externalapi.DomainTransaction{tx}),
&externalapi.DomainHash{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ func TestCheckParentsIncest(t *testing.T) {
t.Fatalf("AddBlock: %+v", err)
}

version := constants.BlockVersion
version := constants.BlockVersionKHashV1
if consensusConfig.HFDAAScore == 0 {
version = constants.BlockVersionKHashV2
}
directParentsRelationBlock := &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,20 @@ func (v *blockValidator) checkParentsLimit(header externalapi.BlockHeader) error
}

func (v *blockValidator) checkBlockVersion(header externalapi.BlockHeader) error {
if header.Version() != constants.BlockVersion {
return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "The block version should be %d", constants.BlockVersion)
/*
if header.Version() != constants.BlockVersion {
return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "The block version should be %d", constants.BlockVersion)
}
*/
if header.DAAScore() >= v.hfDAAScore {
if header.Version() != constants.BlockVersionKHashV2 {
log.Warnf("After HF1 the block version should be %d - block[%d][v%d]", constants.BlockVersionKHashV2, header.DAAScore(), header.Version())
}
} else {
if header.Version() != constants.BlockVersionKHashV1 {
log.Warnf("Before HF1 the block version should be %d - block[%d][v%d]", constants.BlockVersionKHashV1, header.DAAScore(), header.Version())
}
}
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ func CheckBlockVersion(t *testing.T, tc testapi.TestConsensus, consensusConfig *
t.Fatalf("BuildBlockWithParents: %+v", err)
}

expectedVersion := constants.BlockVersion
expectedVersion := constants.BlockVersionKHashV1
if consensusConfig.HFDAAScore == 0 {
expectedVersion = constants.BlockVersionKHashV2
}

block.Header = blockheader.NewImmutableBlockHeader(
expectedVersion+1,
block.Header.Parents(),
Expand Down
3 changes: 3 additions & 0 deletions domain/consensus/processes/blockvalidator/blockvalidator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type blockValidator struct {
maxBlockParents externalapi.KType
timestampDeviationTolerance int
targetTimePerBlock time.Duration
hfDAAScore uint64
maxBlockLevel int

databaseContext model.DBReader
Expand Down Expand Up @@ -63,6 +64,7 @@ func New(powMax *big.Int,
maxBlockParents externalapi.KType,
timestampDeviationTolerance int,
targetTimePerBlock time.Duration,
hfDAAScore uint64,
maxBlockLevel int,

databaseContext model.DBReader,
Expand Down Expand Up @@ -102,6 +104,7 @@ func New(powMax *big.Int,
maxBlockMass: maxBlockMass,
mergeSetSizeLimit: mergeSetSizeLimit,
maxBlockParents: maxBlockParents,
hfDAAScore: hfDAAScore,
maxBlockLevel: maxBlockLevel,

timestampDeviationTolerance: timestampDeviationTolerance,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ func (v *blockValidator) validateDifficulty(stagingArea *model.StagingArea,
return err
}

// bypass the difficulty check during HF
if header.DAAScore() <= (v.hfDAAScore+10) && header.DAAScore() >= v.hfDAAScore {
expectedBits = v.difficultyManager.GenesisDifficulty()
}

if header.Bits() != expectedBits {
return errors.Wrapf(ruleerrors.ErrUnexpectedDifficulty, "block difficulty of %d is not the expected value of %d", header.Bits(), expectedBits)
}
Expand All @@ -150,7 +155,7 @@ func (v *blockValidator) validateDifficulty(stagingArea *model.StagingArea,
// difficulty is not performed.
func (v *blockValidator) checkProofOfWork(header externalapi.BlockHeader) error {
// The target difficulty must be larger than zero.
state := pow.NewState(header.ToMutable())
state := pow.NewState(header.ToMutable(), false)
target := &state.Target
if target.Sign() <= 0 {
return errors.Wrapf(ruleerrors.ErrNegativeTarget, "block target difficulty of %064x is too low",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func TestPOW(t *testing.T) {
// solveBlockWithWrongPOW increments the given block's nonce until it gets wrong POW (for test!).
func solveBlockWithWrongPOW(block *externalapi.DomainBlock) *externalapi.DomainBlock {
header := block.Header.ToMutable()
state := pow.NewState(header)
state := pow.NewState(header, false)
for i := uint64(0); i < math.MaxUint64; i++ {
state.Nonce = i
if !state.CheckProofOfWork() {
Expand Down Expand Up @@ -299,7 +299,9 @@ func TestCheckPruningPointViolation(t *testing.T) {
func TestValidateDifficulty(t *testing.T) {
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
factory := consensus.NewFactory()
mocDifficulty := &mocDifficultyManager{genesisDaaScore: consensusConfig.GenesisBlock.Header.DAAScore()}
mocDifficulty := &mocDifficultyManager{
genesisDaaScore: consensusConfig.GenesisBlock.Header.DAAScore(),
genesisBits: consensusConfig.GenesisBlock.Header.Bits()}
factory.SetTestDifficultyManager(func(_ model.DBReader, _ model.GHOSTDAGManager, _ model.GHOSTDAGDataStore,
_ model.BlockHeaderStore, daaBlocksStore model.DAABlocksStore, _ model.DAGTopologyManager,
_ model.DAGTraversalManager, _ *big.Int, _ int, _ bool, _ time.Duration,
Expand Down Expand Up @@ -346,6 +348,12 @@ type mocDifficultyManager struct {
testGenesisBits uint32
daaBlocksStore model.DAABlocksStore
genesisDaaScore uint64
genesisBits uint32
}

// GenesisDifficulty implements model.DifficultyManager.
func (dm *mocDifficultyManager) GenesisDifficulty() uint32 {
return dm.genesisBits
}

// RequiredDifficulty returns the difficulty required for the test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ func (dm *difficultyManager) RequiredDifficulty(stagingArea *model.StagingArea,
return dm.requiredDifficultyFromTargetsWindow(targetsWindow)
}

// GenesisDifficulty returns the difficulty current network genesis block
func (dm *difficultyManager) GenesisDifficulty() uint32 {
return dm.genesisBits
}

func (dm *difficultyManager) requiredDifficultyFromTargetsWindow(targetsWindow blockWindow) (uint32, error) {
if dm.disableDifficultyAdjustment {
return dm.genesisBits, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestGHOSTDAG(t *testing.T) {
blockID := StringToDomainHash(testBlockData.ID)
dagTopology.parentsMap[*blockID] = StringToDomainHashSlice(testBlockData.Parents)
blockHeadersStore.dagMap[*blockID] = blockheader.NewImmutableBlockHeader(
constants.BlockVersion,
constants.BlockVersionKHashV1,
[]externalapi.BlockLevelParents{StringToDomainHashSlice(testBlockData.Parents)},
nil,
nil,
Expand Down
7 changes: 5 additions & 2 deletions domain/consensus/utils/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package constants
import "math"

const (
// BlockVersion represents the current block version
BlockVersion uint16 = 1
// BlockVersionKHashV1 represents the block version before the HF
BlockVersionKHashV1 uint16 = 1

// BlockVersionKHashV2 represents the block version after the HF
BlockVersionKHashV2 uint16 = 2

// MaxTransactionVersion is the current latest supported transaction version.
MaxTransactionVersion uint16 = 0
Expand Down
2 changes: 1 addition & 1 deletion domain/consensus/utils/mining/solve.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
// SolveBlock increments the given block's nonce until it matches the difficulty requirements in its bits field
func SolveBlock(block *externalapi.DomainBlock, rd *rand.Rand) {
header := block.Header.ToMutable()
state := pow.NewState(header)
state := pow.NewState(header, false)
for state.Nonce = rd.Uint64(); state.Nonce < math.MaxUint64; state.Nonce++ {
if state.CheckProofOfWork() {
header.SetNonce(state.Nonce)
Expand Down
Loading