diff --git a/app/protocol/protocol.go b/app/protocol/protocol.go index 74e046314..cbac4dbe4 100644 --- a/app/protocol/protocol.go +++ b/app/protocol/protocol.go @@ -23,7 +23,7 @@ func (m *Manager) routerInitializer(router *routerpkg.Router, netConnection *net // errChan is used by the flow goroutines to return to runFlows when an error occurs. // They are both initialized here and passed to register flows. isStopping := uint32(0) - errChan := make(chan error) + errChan := make(chan error, 1) receiveVersionRoute, sendVersionRoute, receiveReadyRoute := registerHandshakeRoutes(router) diff --git a/cmd/kaspawallet/libkaspawallet/transaction_test.go b/cmd/kaspawallet/libkaspawallet/transaction_test.go index e2622e005..1d183080e 100644 --- a/cmd/kaspawallet/libkaspawallet/transaction_test.go +++ b/cmd/kaspawallet/libkaspawallet/transaction_test.go @@ -2,10 +2,7 @@ package libkaspawallet_test import ( "fmt" - "github.com/kaspanet/kaspad/domain/consensus/model" - "github.com/kaspanet/kaspad/domain/consensus/ruleerrors" "github.com/kaspanet/kaspad/domain/consensus/utils/constants" - "github.com/pkg/errors" "strings" "testing" @@ -321,7 +318,6 @@ func TestMaxSompi(t *testing.T) { cfg := *consensusConfig cfg.BlockCoinbaseMaturity = 0 cfg.PreDeflationaryPhaseBaseSubsidy = 20e6 * constants.SompiPerKaspa - cfg.HF1DAAScore = cfg.GenesisBlock.Header.DAAScore() + 10 tc, teardown, err := consensus.NewFactory().NewTestConsensus(&cfg, "TestMaxSompi") if err != nil { t.Fatalf("Error setting up tc: %+v", err) @@ -457,8 +453,8 @@ func TestMaxSompi(t *testing.T) { TransactionID: *consensushashing.TransactionID(txWithLargeInputAmount), Index: 0, } - if virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO1) { - t.Fatalf("Transaction was accepted in the DAG") + if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO1) { + t.Fatalf("Transaction wasn't accepted in the DAG") } selectedUTXOsForTxWithLargeInputAndOutputAmount := []*libkaspawallet.UTXO{ @@ -499,34 +495,13 @@ func TestMaxSompi(t *testing.T) { t.Fatalf("ExtractTransaction: %+v", err) } - _, _, err = tc.AddBlock([]*externalapi.DomainHash{block1Hash}, nil, []*externalapi.DomainTransaction{txWithLargeInputAndOutputAmount}) - if !errors.Is(err, ruleerrors.ErrBadTxOutValue) { + // We're creating a new longer chain so we can double spend txWithLargeInputAmount + newChainRoot, _, err := tc.AddBlock([]*externalapi.DomainHash{block1Hash}, nil, nil) + if err != nil { t.Fatalf("AddBlock: %+v", err) } - tip := block1Hash - for { - tip, _, err = tc.AddBlock([]*externalapi.DomainHash{tip}, nil, nil) - if err != nil { - t.Fatalf("AddBlock: %+v", err) - } - - selectedTip, err := tc.GetVirtualSelectedParent() - if err != nil { - t.Fatalf("GetVirtualDAAScore: %+v", err) - } - - daaScore, err := tc.DAABlocksStore().DAAScore(tc.DatabaseContext(), model.NewStagingArea(), selectedTip) - if err != nil { - t.Fatalf("DAAScore: %+v", err) - } - - if daaScore >= cfg.HF1DAAScore { - break - } - } - - tip, virtualChangeSet, err = tc.AddBlock([]*externalapi.DomainHash{tip}, nil, []*externalapi.DomainTransaction{txWithLargeInputAndOutputAmount}) + _, virtualChangeSet, err = tc.AddBlock([]*externalapi.DomainHash{newChainRoot}, nil, []*externalapi.DomainTransaction{txWithLargeInputAndOutputAmount}) if err != nil { t.Fatalf("AddBlock: %+v", err) } @@ -539,14 +514,5 @@ func TestMaxSompi(t *testing.T) { if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO2) { t.Fatalf("txWithLargeInputAndOutputAmount weren't accepted in the DAG") } - - _, virtualChangeSet, err = tc.AddBlock([]*externalapi.DomainHash{tip}, nil, []*externalapi.DomainTransaction{txWithLargeInputAmount}) - if err != nil { - t.Fatalf("AddBlock: %+v", err) - } - - if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO1) { - t.Fatalf("txWithLargeInputAmount wasn't accepted in the DAG") - } }) } diff --git a/domain/consensus/factory.go b/domain/consensus/factory.go index f5acfd5d9..020e41d50 100644 --- a/domain/consensus/factory.go +++ b/domain/consensus/factory.go @@ -217,8 +217,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas pastMedianTimeManager, ghostdagDataStore, daaBlocksStore, - txMassCalculator, - config.HF1DAAScore) + txMassCalculator) difficultyManager := f.difficultyConstructor( dbManager, ghostdagManager, @@ -266,7 +265,6 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas finalityManager, genesisHash, config.MergeDepth, - config.HF1DAAScore, ghostdagDataStore, mergeDepthRootStore, daaBlocksStore, @@ -344,7 +342,6 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas config.MaxBlockParents, config.TimestampDeviationTolerance, config.TargetTimePerBlock, - config.HF1DAAScore, config.MaxBlockLevel, dbManager, @@ -393,7 +390,6 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas blockBuilder := blockbuilder.New( dbManager, genesisHash, - config.HF1DAAScore, difficultyManager, pastMedianTimeManager, diff --git a/domain/consensus/finality_test.go b/domain/consensus/finality_test.go index 07adb7b40..f828be0ad 100644 --- a/domain/consensus/finality_test.go +++ b/domain/consensus/finality_test.go @@ -185,7 +185,6 @@ func TestBoundedMergeDepth(t *testing.T) { consensusConfig.K = 5 consensusConfig.MergeDepth = 7 consensusConfig.FinalityDuration = 20 * consensusConfig.TargetTimePerBlock - consensusConfig.HF1DAAScore = consensusConfig.GenesisBlock.Header.DAAScore() + 200 if uint64(consensusConfig.K) >= consensusConfig.FinalityDepth() { t.Fatal("K must be smaller than finality duration for this test to run") @@ -483,56 +482,6 @@ func TestBoundedMergeDepth(t *testing.T) { } } - test(consensusConfig.FinalityDepth(), consensusConfig.GenesisHash, true, true) - virtualDAAScore, err := consensusReal.GetVirtualDAAScore() - if err != nil { - t.Fatalf("GetVirtualDAAScore: %+v", err) - } - - if virtualDAAScore > consensusConfig.HF1DAAScore { - t.Fatalf("Hard fork is already activated") - } - - tipBeforeHFActivated, err := consensusReal.GetVirtualSelectedParent() - if err != nil { - t.Fatalf("GetVirtualSelectedParent: %+v", err) - } - - tip := tipBeforeHFActivated - for { - tip, _, err = consensusReal.AddBlock([]*externalapi.DomainHash{tip}, nil, nil) - if err != nil { - t.Fatalf("Failed adding block: %+v", err) - } - - daaScore, err := consensusReal.DAABlocksStore().DAAScore(consensusReal.DatabaseContext(), model.NewStagingArea(), tip) - if err != nil { - t.Fatalf("Failed adding block: %+v", err) - } - - // We check what happens when on the transition between rules: if we merge a chain that - // started before the HF was activated, but the HF was already activated for the merging - // block, the HF rules should apply. - // The checked block in `test` is going to have a DAA score of `tip.DAAScore + depth + 5`, - // so this is why we started to test from this depth. - if daaScore == consensusConfig.HF1DAAScore-consensusConfig.MergeDepth-5 { - test(consensusConfig.MergeDepth, tip, true, true) - } - - if daaScore > consensusConfig.HF1DAAScore { - virtualSelectedParent, err := consensusReal.GetVirtualSelectedParent() - if err != nil { - t.Fatalf("GetVirtualSelectedParent: %+v", err) - } - - if virtualSelectedParent.Equal(tip) { - break - } - } - } - - test(consensusConfig.MergeDepth, tip, true, true) - test(consensusConfig.FinalityDepth(), tipBeforeHFActivated, false, true) - test(consensusConfig.MergeDepth, tipBeforeHFActivated, false, false) + test(consensusConfig.MergeDepth, consensusConfig.GenesisHash, true, true) }) } diff --git a/domain/consensus/processes/blockbuilder/block_builder.go b/domain/consensus/processes/blockbuilder/block_builder.go index 8e6bd39c7..bef78afd8 100644 --- a/domain/consensus/processes/blockbuilder/block_builder.go +++ b/domain/consensus/processes/blockbuilder/block_builder.go @@ -20,7 +20,6 @@ import ( type blockBuilder struct { databaseContext model.DBManager genesisHash *externalapi.DomainHash - hf1DAAScore uint64 difficultyManager model.DifficultyManager pastMedianTimeManager model.PastMedianTimeManager @@ -43,7 +42,6 @@ type blockBuilder struct { func New( databaseContext model.DBManager, genesisHash *externalapi.DomainHash, - hf1DAAScore uint64, difficultyManager model.DifficultyManager, pastMedianTimeManager model.PastMedianTimeManager, @@ -65,7 +63,6 @@ func New( return &blockBuilder{ databaseContext: databaseContext, genesisHash: genesisHash, - hf1DAAScore: hf1DAAScore, difficultyManager: difficultyManager, pastMedianTimeManager: pastMedianTimeManager, @@ -227,13 +224,8 @@ func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions return nil, err } - version := constants.BlockVersionBeforeHF1 - if daaScore >= bb.hf1DAAScore { - version = constants.BlockVersionAfterHF1 - } - return blockheader.NewImmutableBlockHeader( - version, + constants.BlockVersion, parents, hashMerkleRoot, acceptedIDMerkleRoot, diff --git a/domain/consensus/processes/blockbuilder/test_block_builder.go b/domain/consensus/processes/blockbuilder/test_block_builder.go index f4fae58a7..d7089cc8d 100644 --- a/domain/consensus/processes/blockbuilder/test_block_builder.go +++ b/domain/consensus/processes/blockbuilder/test_block_builder.go @@ -94,14 +94,9 @@ func (bb *testBlockBuilder) buildUTXOInvalidHeader(stagingArea *model.StagingAre }) } - version := constants.BlockVersionBeforeHF1 - if daaScore >= bb.hf1DAAScore { - version = constants.BlockVersionAfterHF1 - } - bb.nonceCounter++ return blockheader.NewImmutableBlockHeader( - version, + constants.BlockVersion, parents, hashMerkleRoot, &externalapi.DomainHash{}, diff --git a/domain/consensus/processes/blockvalidator/block_body_in_isolation.go b/domain/consensus/processes/blockvalidator/block_body_in_isolation.go index 5c5539caa..ea2999895 100644 --- a/domain/consensus/processes/blockvalidator/block_body_in_isolation.go +++ b/domain/consensus/processes/blockvalidator/block_body_in_isolation.go @@ -220,10 +220,6 @@ func (v *blockValidator) validateGasLimit(block *externalapi.DomainBlock) error func (v *blockValidator) checkBlockMass(block *externalapi.DomainBlock) error { mass := uint64(0) - if block.Header.DAAScore() < v.hf1DAAScore { - mass += v.headerEstimatedSerializedSize(block.Header) - } - for _, transaction := range block.Transactions { v.transactionValidator.PopulateMass(transaction) diff --git a/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go b/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go index 112c516cc..78befde5d 100644 --- a/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go +++ b/domain/consensus/processes/blockvalidator/block_body_in_isolation_test.go @@ -1307,7 +1307,7 @@ func initBlockWithFirstTransactionDifferentThanCoinbase(consensusConfig *consens return &externalapi.DomainBlock{ Header: blockheader.NewImmutableBlockHeader( - constants.BlockVersionBeforeHF1, + constants.BlockVersion, []externalapi.BlockLevelParents{[]*externalapi.DomainHash{consensusConfig.GenesisHash}}, merkle.CalculateHashMerkleRoot([]*externalapi.DomainTransaction{tx}), &externalapi.DomainHash{}, diff --git a/domain/consensus/processes/blockvalidator/block_header_in_context_test.go b/domain/consensus/processes/blockvalidator/block_header_in_context_test.go index 6ff8dd553..c81130a94 100644 --- a/domain/consensus/processes/blockvalidator/block_header_in_context_test.go +++ b/domain/consensus/processes/blockvalidator/block_header_in_context_test.go @@ -108,11 +108,7 @@ func TestCheckParentsIncest(t *testing.T) { t.Fatalf("AddBlock: %+v", err) } - version := constants.BlockVersionBeforeHF1 - if consensusConfig.HF1DAAScore == 0 { - version = constants.BlockVersionAfterHF1 - } - + version := constants.BlockVersion directParentsRelationBlock := &externalapi.DomainBlock{ Header: blockheader.NewImmutableBlockHeader( version, diff --git a/domain/consensus/processes/blockvalidator/block_header_in_isolation.go b/domain/consensus/processes/blockvalidator/block_header_in_isolation.go index bf203a7ee..841f59415 100644 --- a/domain/consensus/processes/blockvalidator/block_header_in_isolation.go +++ b/domain/consensus/processes/blockvalidator/block_header_in_isolation.go @@ -56,16 +56,9 @@ func (v *blockValidator) checkParentsLimit(header externalapi.BlockHeader) error } func (v *blockValidator) checkBlockVersion(header externalapi.BlockHeader) error { - if header.DAAScore() >= v.hf1DAAScore { - if header.Version() != constants.BlockVersionAfterHF1 { - return errors.Wrapf( - ruleerrors.ErrWrongBlockVersion, "After HF1 the block version should be %d", constants.BlockVersionAfterHF1) - } - } else { - if header.Version() != constants.BlockVersionBeforeHF1 { - return errors.Wrapf( - ruleerrors.ErrWrongBlockVersion, "Beofre HF1 the block version should be %d", constants.BlockVersionBeforeHF1) - } + if header.Version() != constants.BlockVersion { + return errors.Wrapf( + ruleerrors.ErrWrongBlockVersion, "The block version should be %d", constants.BlockVersion) } return nil } diff --git a/domain/consensus/processes/blockvalidator/block_header_in_isolation_test.go b/domain/consensus/processes/blockvalidator/block_header_in_isolation_test.go index 85b4f2fdb..d78538e7b 100644 --- a/domain/consensus/processes/blockvalidator/block_header_in_isolation_test.go +++ b/domain/consensus/processes/blockvalidator/block_header_in_isolation_test.go @@ -62,11 +62,7 @@ func CheckBlockVersion(t *testing.T, tc testapi.TestConsensus, consensusConfig * t.Fatalf("BuildBlockWithParents: %+v", err) } - expectedVersion := constants.BlockVersionBeforeHF1 - if consensusConfig.HF1DAAScore == 0 { - expectedVersion = constants.BlockVersionAfterHF1 - } - + expectedVersion := constants.BlockVersion block.Header = blockheader.NewImmutableBlockHeader( expectedVersion+1, block.Header.Parents(), diff --git a/domain/consensus/processes/blockvalidator/blockvalidator.go b/domain/consensus/processes/blockvalidator/blockvalidator.go index e91bdaf6f..7788a49b5 100644 --- a/domain/consensus/processes/blockvalidator/blockvalidator.go +++ b/domain/consensus/processes/blockvalidator/blockvalidator.go @@ -24,7 +24,6 @@ type blockValidator struct { maxBlockParents externalapi.KType timestampDeviationTolerance int targetTimePerBlock time.Duration - hf1DAAScore uint64 maxBlockLevel int databaseContext model.DBReader @@ -64,7 +63,6 @@ func New(powMax *big.Int, maxBlockParents externalapi.KType, timestampDeviationTolerance int, targetTimePerBlock time.Duration, - hf1DAAScore uint64, maxBlockLevel int, databaseContext model.DBReader, @@ -104,7 +102,6 @@ func New(powMax *big.Int, maxBlockMass: maxBlockMass, mergeSetSizeLimit: mergeSetSizeLimit, maxBlockParents: maxBlockParents, - hf1DAAScore: hf1DAAScore, maxBlockLevel: maxBlockLevel, timestampDeviationTolerance: timestampDeviationTolerance, diff --git a/domain/consensus/processes/blockvalidator/header_estimated_size.go b/domain/consensus/processes/blockvalidator/header_estimated_size.go deleted file mode 100644 index 2dcbda919..000000000 --- a/domain/consensus/processes/blockvalidator/header_estimated_size.go +++ /dev/null @@ -1,28 +0,0 @@ -package blockvalidator - -import ( - "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" -) - -// headerEstimatedSerializedSize is the estimated size of a block header in some -// serialization. This has to be deterministic, but not necessarily accurate, since -// it's only used to check block size limit violation. -func (v *blockValidator) headerEstimatedSerializedSize(header externalapi.BlockHeader) uint64 { - size := uint64(0) - size += 2 // Version (uint16) - - size += 8 // number of block levels (uint64) - for _, blockLevelParents := range header.Parents() { - size += 8 // number of parents in the block level (uint64) - size += uint64(externalapi.DomainHashSize * len(blockLevelParents)) // parents - } - - size += externalapi.DomainHashSize // HashMerkleRoot - size += externalapi.DomainHashSize // AcceptedIDMerkleRoot - size += externalapi.DomainHashSize // UTXOCommitment - size += 8 // TimeInMilliseconds (int64) - size += 4 // Bits (uint32) - size += 8 // Nonce (uint64) - - return size -} diff --git a/domain/consensus/processes/ghostdagmanager/ghostdag_test.go b/domain/consensus/processes/ghostdagmanager/ghostdag_test.go index 4527c44f7..b373ba104 100644 --- a/domain/consensus/processes/ghostdagmanager/ghostdag_test.go +++ b/domain/consensus/processes/ghostdagmanager/ghostdag_test.go @@ -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.BlockVersionBeforeHF1, + constants.BlockVersion, []externalapi.BlockLevelParents{StringToDomainHashSlice(testBlockData.Parents)}, nil, nil, diff --git a/domain/consensus/processes/mergedepthmanager/merge_depth_manager.go b/domain/consensus/processes/mergedepthmanager/merge_depth_manager.go index 4c0638104..15fb778d7 100644 --- a/domain/consensus/processes/mergedepthmanager/merge_depth_manager.go +++ b/domain/consensus/processes/mergedepthmanager/merge_depth_manager.go @@ -16,7 +16,6 @@ type mergeDepthManager struct { genesisHash *externalapi.DomainHash mergeDepth uint64 - hf1DAAScore uint64 ghostdagDataStore model.GHOSTDAGDataStore mergeDepthRootStore model.MergeDepthRootStore @@ -34,7 +33,6 @@ func New( genesisHash *externalapi.DomainHash, mergeDepth uint64, - hf1DAAScore uint64, ghostdagDataStore model.GHOSTDAGDataStore, mergeDepthRootStore model.MergeDepthRootStore, @@ -49,7 +47,6 @@ func New( finalityManager: finalityManager, genesisHash: genesisHash, mergeDepth: mergeDepth, - hf1DAAScore: hf1DAAScore, ghostdagDataStore: ghostdagDataStore, mergeDepthRootStore: mergeDepthRootStore, daaBlocksStore: daaBlocksStore, @@ -71,19 +68,24 @@ func (mdm *mergeDepthManager) CheckBoundedMergeDepth(stagingArea *model.StagingA return nil } - // For validation, we must follow the HF1 DAA score in order to determine the correct depth to verify - mergeDepthRootByHF1, err := mdm.mergeDepthRootByHF1DAAScoreForValidationOnly(stagingArea, blockHash, isBlockWithTrustedData) + mergeDepthRoot, err := mdm.MergeDepthRoot(stagingArea, blockHash, isBlockWithTrustedData) if err != nil { return err } - nonBoundedMergeDepthViolatingBlues, err := mdm.NonBoundedMergeDepthViolatingBlues(stagingArea, blockHash, mergeDepthRootByHF1) + // We call FinalityPoint in order to save it to storage. + _, err = mdm.finalityManager.FinalityPoint(stagingArea, blockHash, isBlockWithTrustedData) + if err != nil { + return err + } + + nonBoundedMergeDepthViolatingBlues, err := mdm.NonBoundedMergeDepthViolatingBlues(stagingArea, blockHash, mergeDepthRoot) if err != nil { return err } for _, red := range ghostdagData.MergeSetReds() { - doesRedHaveMergeRootInPast, err := mdm.dagTopologyManager.IsAncestorOf(stagingArea, mergeDepthRootByHF1, red) + doesRedHaveMergeRootInPast, err := mdm.dagTopologyManager.IsAncestorOf(stagingArea, mergeDepthRoot, red) if err != nil { return err } @@ -133,34 +135,6 @@ func (mdm *mergeDepthManager) NonBoundedMergeDepthViolatingBlues( return nonBoundedMergeDepthViolatingBlues, nil } -func (mdm *mergeDepthManager) mergeDepthRootByHF1DAAScoreForValidationOnly( - stagingArea *model.StagingArea, blockHash *externalapi.DomainHash, isBlockWithTrustedData bool) (*externalapi.DomainHash, error) { - daaScore, err := mdm.daaBlocksStore.DAAScore(mdm.databaseContext, stagingArea, blockHash) - if err != nil { - return nil, err - } - - // We call both, merge depth root and finality, in order to trigger storage persistency for both, - // although only one of them is used below - mergeDepthRoot, err := mdm.MergeDepthRoot(stagingArea, blockHash, isBlockWithTrustedData) - if err != nil { - return nil, err - } - // As noted above, this line should not be removed following the HF, unless we validate that storage of - // finality point is not needed any more - finalityPoint, err := mdm.finalityManager.FinalityPoint(stagingArea, blockHash, isBlockWithTrustedData) - if err != nil { - return nil, err - } - - if daaScore >= mdm.hf1DAAScore { - return mergeDepthRoot, nil - } - - // We fall back to the merge depth root before the HF, which was the finality point - return finalityPoint, nil -} - func (mdm *mergeDepthManager) VirtualMergeDepthRoot(stagingArea *model.StagingArea) (*externalapi.DomainHash, error) { log.Tracef("VirtualMergeDepthRoot start") defer log.Tracef("VirtualMergeDepthRoot end") diff --git a/domain/consensus/processes/pruningmanager/pruning_test.go b/domain/consensus/processes/pruningmanager/pruning_test.go index bcda918c8..0f74d6f10 100644 --- a/domain/consensus/processes/pruningmanager/pruning_test.go +++ b/domain/consensus/processes/pruningmanager/pruning_test.go @@ -37,7 +37,7 @@ func TestPruning(t *testing.T) { }, "dag-for-test-pruning.json": { dagconfig.MainnetParams.Name: "503", - dagconfig.TestnetParams.Name: "502", + dagconfig.TestnetParams.Name: "503", dagconfig.DevnetParams.Name: "503", dagconfig.SimnetParams.Name: "503", }, diff --git a/domain/consensus/processes/transactionvalidator/transaction_in_context.go b/domain/consensus/processes/transactionvalidator/transaction_in_context.go index 8366f4cac..159c2e74c 100644 --- a/domain/consensus/processes/transactionvalidator/transaction_in_context.go +++ b/domain/consensus/processes/transactionvalidator/transaction_in_context.go @@ -58,14 +58,6 @@ func (v *transactionValidator) ValidateTransactionInContextIgnoringUTXO(stagingA return errors.Wrapf(ruleerrors.ErrUnfinalizedTx, "unfinalized transaction %v", tx) } - // TODO: Remove checkTransactionAmountRanges from here once HF was activated. It's only temporary - // because in the HF transition period checkTransactionAmountRanges is not context free. - isHF1Activated := povBlockDAAScore >= v.hf1DAAScore - err = v.checkTransactionAmountRanges(tx, isHF1Activated) - if err != nil { - return err - } - return nil } @@ -81,13 +73,7 @@ func (v *transactionValidator) ValidateTransactionInContextAndPopulateFee(stagin return err } - daaScore, err := v.daaBlocksStore.DAAScore(v.databaseContext, stagingArea, povBlockHash) - if err != nil { - return err - } - - isHF1Activated := daaScore >= v.hf1DAAScore - totalSompiIn, err := v.checkTransactionInputAmounts(tx, isHF1Activated) + totalSompiIn, err := v.checkTransactionInputAmounts(tx) if err != nil { return err } @@ -149,7 +135,7 @@ func (v *transactionValidator) checkTransactionCoinbaseMaturity(stagingArea *mod return nil } -func (v *transactionValidator) checkTransactionInputAmounts(tx *externalapi.DomainTransaction, isHF1Activated bool) (totalSompiIn uint64, err error) { +func (v *transactionValidator) checkTransactionInputAmounts(tx *externalapi.DomainTransaction) (totalSompiIn uint64, err error) { totalSompiIn = 0 var missingOutpoints []*externalapi.DomainOutpoint @@ -166,7 +152,7 @@ func (v *transactionValidator) checkTransactionInputAmounts(tx *externalapi.Doma // a transaction are in a unit value known as a sompi. One // kaspa is a quantity of sompi as defined by the // SompiPerKaspa constant. - totalSompiIn, err = v.checkEntryAmounts(utxoEntry, totalSompiIn, isHF1Activated) + totalSompiIn, err = v.checkEntryAmounts(utxoEntry, totalSompiIn) if err != nil { return 0, err } @@ -179,24 +165,19 @@ func (v *transactionValidator) checkTransactionInputAmounts(tx *externalapi.Doma return totalSompiIn, nil } -func (v *transactionValidator) checkEntryAmounts(entry externalapi.UTXOEntry, totalSompiInBefore uint64, isHF1Activated bool) (totalSompiInAfter uint64, err error) { +func (v *transactionValidator) checkEntryAmounts(entry externalapi.UTXOEntry, totalSompiInBefore uint64) (totalSompiInAfter uint64, err error) { // The total of all outputs must not be more than the max // allowed per transaction. Also, we could potentially overflow // the accumulator so check for overflow. - maxSompi := constants.MaxSompiBeforeHF1 - if isHF1Activated { - maxSompi = constants.MaxSompiAfterHF1 - } - originTxSompi := entry.Amount() totalSompiInAfter = totalSompiInBefore + originTxSompi if totalSompiInAfter < totalSompiInBefore || - totalSompiInAfter > maxSompi { + totalSompiInAfter > constants.MaxSompi { return 0, errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+ "inputs is %d which is higher than max "+ "allowed value of %d", totalSompiInBefore, - maxSompi) + constants.MaxSompi) } return totalSompiInAfter, nil } diff --git a/domain/consensus/processes/transactionvalidator/transaction_in_isolation.go b/domain/consensus/processes/transactionvalidator/transaction_in_isolation.go index 13a6f4757..ef04f9b0b 100644 --- a/domain/consensus/processes/transactionvalidator/transaction_in_isolation.go +++ b/domain/consensus/processes/transactionvalidator/transaction_in_isolation.go @@ -11,12 +11,11 @@ import ( // ValidateTransactionInIsolation validates the parts of the transaction that can be validated context-free func (v *transactionValidator) ValidateTransactionInIsolation(tx *externalapi.DomainTransaction, povDAAScore uint64) error { - isHF1Activated := povDAAScore >= v.hf1DAAScore err := v.checkTransactionInputCount(tx) if err != nil { return err } - err = v.checkTransactionAmountRanges(tx, isHF1Activated) + err = v.checkTransactionAmountRanges(tx) if err != nil { return err } @@ -63,18 +62,13 @@ func (v *transactionValidator) checkTransactionInputCount(tx *externalapi.Domain return nil } -func (v *transactionValidator) checkTransactionAmountRanges(tx *externalapi.DomainTransaction, isHF1Activated bool) error { +func (v *transactionValidator) checkTransactionAmountRanges(tx *externalapi.DomainTransaction) error { // Ensure the transaction amounts are in range. Each transaction // output must not be negative or more than the max allowed per // transaction. Also, the total of all outputs must abide by the same // restrictions. All amounts in a transaction are in a unit value known // as a sompi. One kaspa is a quantity of sompi as defined by the // sompiPerKaspa constant. - maxSompi := constants.MaxSompiBeforeHF1 - if isHF1Activated { - maxSompi = constants.MaxSompiAfterHF1 - } - var totalSompi uint64 for _, txOut := range tx.Outputs { sompi := txOut.Value @@ -82,9 +76,9 @@ func (v *transactionValidator) checkTransactionAmountRanges(tx *externalapi.Doma return errors.Wrap(ruleerrors.ErrTxOutValueZero, "zero value outputs are forbidden") } - if sompi > maxSompi { + if sompi > constants.MaxSompi { return errors.Wrapf(ruleerrors.ErrBadTxOutValue, "transaction output value of %d is "+ - "higher than max allowed value of %d", sompi, maxSompi) + "higher than max allowed value of %d", sompi, constants.MaxSompi) } // Binary arithmetic guarantees that any overflow is detected and reported. @@ -94,14 +88,14 @@ func (v *transactionValidator) checkTransactionAmountRanges(tx *externalapi.Doma if newTotalSompi < totalSompi { return errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+ "outputs exceeds max allowed value of %d", - maxSompi) + constants.MaxSompi) } totalSompi = newTotalSompi - if totalSompi > maxSompi { + if totalSompi > constants.MaxSompi { return errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+ "outputs is %d which is higher than max "+ "allowed value of %d", totalSompi, - maxSompi) + constants.MaxSompi) } } diff --git a/domain/consensus/processes/transactionvalidator/transaction_in_isolation_test.go b/domain/consensus/processes/transactionvalidator/transaction_in_isolation_test.go index 4c53ea8c0..e95f714c2 100644 --- a/domain/consensus/processes/transactionvalidator/transaction_in_isolation_test.go +++ b/domain/consensus/processes/transactionvalidator/transaction_in_isolation_test.go @@ -22,7 +22,6 @@ type txSubnetworkData struct { func TestValidateTransactionInIsolationAndPopulateMass(t *testing.T) { testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) { cfg := *consensusConfig - cfg.HF1DAAScore = 20 factory := consensus.NewFactory() tc, teardown, err := factory.NewTestConsensus(&cfg, "TestValidateTransactionInIsolationAndPopulateMass") @@ -45,22 +44,22 @@ func TestValidateTransactionInIsolationAndPopulateMass(t *testing.T) { {"good one", 1, 1, 1, subnetworks.SubnetworkIDNative, nil, nil, nil, 0}, {"no inputs", 0, 1, 1, subnetworks.SubnetworkIDNative, nil, nil, ruleerrors.ErrNoTxInputs, 0}, {"no outputs", 1, 0, 1, subnetworks.SubnetworkIDNative, nil, nil, nil, 0}, - {"too much sompi in one output", 1, 1, constants.MaxSompiBeforeHF1 + 1, + {"too much sompi in one output", 1, 1, constants.MaxSompi + 1, subnetworks.SubnetworkIDNative, nil, nil, ruleerrors.ErrBadTxOutValue, 0}, - {"too much sompi before- valid now", 1, 1, constants.MaxSompiBeforeHF1 + 1, + {"too much sompi before- valid now", 1, 1, 21e14 + 1, subnetworks.SubnetworkIDNative, nil, nil, - nil, cfg.HF1DAAScore}, - {"too much sompi in one output - after hf", 1, 1, constants.MaxSompiAfterHF1 + 1, + nil, 0}, + {"too much sompi in one output - after hf", 1, 1, constants.MaxSompi + 1, subnetworks.SubnetworkIDNative, nil, nil, - ruleerrors.ErrBadTxOutValue, cfg.HF1DAAScore}, - {"too much sompi in one output", 1, 1, constants.MaxSompiAfterHF1 + 1, + ruleerrors.ErrBadTxOutValue, 0}, + {"too much sompi in one output", 1, 1, constants.MaxSompi + 1, subnetworks.SubnetworkIDNative, nil, nil, diff --git a/domain/consensus/processes/transactionvalidator/transactionvalidator.go b/domain/consensus/processes/transactionvalidator/transactionvalidator.go index b939bf876..73621e756 100644 --- a/domain/consensus/processes/transactionvalidator/transactionvalidator.go +++ b/domain/consensus/processes/transactionvalidator/transactionvalidator.go @@ -21,7 +21,6 @@ type transactionValidator struct { sigCache *txscript.SigCache sigCacheECDSA *txscript.SigCacheECDSA txMassCalculator *txmass.Calculator - hf1DAAScore uint64 } // New instantiates a new TransactionValidator @@ -32,8 +31,7 @@ func New(blockCoinbaseMaturity uint64, pastMedianTimeManager model.PastMedianTimeManager, ghostdagDataStore model.GHOSTDAGDataStore, daaBlocksStore model.DAABlocksStore, - txMassCalculator *txmass.Calculator, - hf1DAAScore uint64) model.TransactionValidator { + txMassCalculator *txmass.Calculator) model.TransactionValidator { return &transactionValidator{ blockCoinbaseMaturity: blockCoinbaseMaturity, @@ -46,6 +44,5 @@ func New(blockCoinbaseMaturity uint64, sigCache: txscript.NewSigCache(sigCacheSize), sigCacheECDSA: txscript.NewSigCacheECDSA(sigCacheSize), txMassCalculator: txMassCalculator, - hf1DAAScore: hf1DAAScore, } } diff --git a/domain/consensus/processes/transactionvalidator/transactionvalidator_test.go b/domain/consensus/processes/transactionvalidator/transactionvalidator_test.go index 5e7001491..f5db9a468 100644 --- a/domain/consensus/processes/transactionvalidator/transactionvalidator_test.go +++ b/domain/consensus/processes/transactionvalidator/transactionvalidator_test.go @@ -21,7 +21,6 @@ import ( func TestValidateTransactionInContextAndPopulateFee(t *testing.T) { testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) { - consensusConfig.HF1DAAScore = consensusConfig.GenesisBlock.Header.DAAScore() + 1000 factory := consensus.NewFactory() tc, tearDown, err := factory.NewTestConsensus(consensusConfig, "TestValidateTransactionInContextAndPopulateFee") @@ -92,7 +91,7 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) { Sequence: constants.MaxTxInSequenceNum, SigOpCount: 1, UTXOEntry: utxo.NewUTXOEntry( - constants.MaxSompiBeforeHF1+1, + 21e14+1, scriptPublicKey, false, 0), @@ -104,7 +103,7 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) { Sequence: constants.MaxTxInSequenceNum, SigOpCount: 1, UTXOEntry: utxo.NewUTXOEntry( - constants.MaxSompiAfterHF1+1, + constants.MaxSompi+1, scriptPublicKey, false, 0), @@ -163,7 +162,7 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) { Gas: 0, LockTime: 0} - txWithLargeAmountAfterHF := externalapi.DomainTransaction{ + txWithInvalidAmount := externalapi.DomainTransaction{ Version: constants.MaxTransactionVersion, Inputs: []*externalapi.DomainTransactionInput{&txInputWithLargeAmountAfterHF}, Outputs: []*externalapi.DomainTransactionOutput{&txOutput}, @@ -207,9 +206,6 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) { povBlockHash := externalapi.NewDomainHashFromByteArray(&[32]byte{0x01}) tc.DAABlocksStore().StageDAAScore(stagingArea, povBlockHash, consensusConfig.BlockCoinbaseMaturity+txInput.UTXOEntry.BlockDAAScore()) - povAfterHFBlockHash := externalapi.NewDomainHashFromByteArray(&[32]byte{0x02}) - tc.DAABlocksStore().StageDAAScore(stagingArea, povAfterHFBlockHash, consensusConfig.HF1DAAScore) - // Just use some stub ghostdag data tc.GHOSTDAGDataStore().Stage(stagingArea, povBlockHash, externalapi.NewBlockGHOSTDAGData( 0, @@ -242,24 +238,17 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) { isValid: false, expectedError: ruleerrors.ErrImmatureSpend, }, - { // The total inputs amount is bigger than the allowed maximum (constants.MaxSompiBeforeHF1) - name: "checkTransactionInputAmounts - invalid - before HF", + { // The total inputs amount is bigger than the allowed maximum before the HF (21e14) + name: "checkTransactionInputAmounts - valid", tx: &txWithLargeAmountBeforeHF, povBlockHash: povBlockHash, - isValid: false, - expectedError: ruleerrors.ErrBadTxOutValue, - }, - { // The total inputs amount is bigger than the allowed maximum (constants.MaxSompiBeforeHF1) - name: "checkTransactionInputAmounts - valid - after HF", - tx: &txWithLargeAmountBeforeHF, - povBlockHash: povAfterHFBlockHash, isValid: true, expectedError: nil, }, - { // The total inputs amount is bigger than the allowed maximum (constants.MaxSompiBeforeHF1) + { // The total inputs amount is bigger than the allowed maximum (constants.MaxSompi) name: "checkTransactionInputAmounts - invalid - after HF", - tx: &txWithLargeAmountAfterHF, - povBlockHash: povAfterHFBlockHash, + tx: &txWithInvalidAmount, + povBlockHash: povBlockHash, isValid: false, expectedError: ruleerrors.ErrBadTxOutValue, }, diff --git a/domain/consensus/utils/constants/constants.go b/domain/consensus/utils/constants/constants.go index 9482e7cf9..ab9b3fafd 100644 --- a/domain/consensus/utils/constants/constants.go +++ b/domain/consensus/utils/constants/constants.go @@ -3,11 +3,8 @@ package constants import "math" const ( - // BlockVersionBeforeHF1 represents the current version of blocks mined before HF1 - BlockVersionBeforeHF1 uint16 = 0 - - // BlockVersionAfterHF1 represents the current version of blocks mined after HF1 - BlockVersionAfterHF1 uint16 = 1 + // BlockVersion represents the current block version + BlockVersion uint16 = 1 // MaxTransactionVersion is the current latest supported transaction version. MaxTransactionVersion uint16 = 0 @@ -18,11 +15,8 @@ const ( // SompiPerKaspa is the number of sompi in one kaspa (1 KAS). SompiPerKaspa = 100_000_000 - // MaxSompiBeforeHF1 is the maximum transaction amount allowed in sompi before the HF1 hard fork is activated. - MaxSompiBeforeHF1 = uint64(21_000_000 * SompiPerKaspa) - - // MaxSompiAfterHF1 is the maximum transaction amount allowed in sompi after the HF1 hard fork is activated. - MaxSompiAfterHF1 = uint64(29_000_000_000 * SompiPerKaspa) + // MaxSompi is the maximum transaction amount allowed in sompi. + MaxSompi = uint64(29_000_000_000 * SompiPerKaspa) // MaxTxInSequenceNum is the maximum sequence number the sequence field // of a transaction input can be. diff --git a/domain/dagconfig/params.go b/domain/dagconfig/params.go index c49beecd1..52b3cfb6e 100644 --- a/domain/dagconfig/params.go +++ b/domain/dagconfig/params.go @@ -187,8 +187,7 @@ type Params struct { // MaxBlockLevel is the maximum possible block level. MaxBlockLevel int - MergeDepth uint64 - HF1DAAScore uint64 + MergeDepth uint64 } // NormalizeRPCServerAddress returns addr with the current network default @@ -288,7 +287,6 @@ var MainnetParams = Params{ // This means that any block that has a level lower or equal to genesis will be level 0. MaxBlockLevel: 225, MergeDepth: defaultMergeDepth, - HF1DAAScore: 14687583, } // TestnetParams defines the network parameters for the test Kaspa network. @@ -351,7 +349,6 @@ var TestnetParams = Params{ MaxBlockLevel: 250, MergeDepth: defaultMergeDepth, - HF1DAAScore: 172800, } // SimnetParams defines the network parameters for the simulation test Kaspa diff --git a/domain/miningmanager/factory.go b/domain/miningmanager/factory.go index c6bb92db6..9f304b8c9 100644 --- a/domain/miningmanager/factory.go +++ b/domain/miningmanager/factory.go @@ -5,7 +5,6 @@ import ( "github.com/kaspanet/kaspad/domain/dagconfig" "github.com/kaspanet/kaspad/domain/miningmanager/blocktemplatebuilder" mempoolpkg "github.com/kaspanet/kaspad/domain/miningmanager/mempool" - "github.com/pkg/errors" "sync" "time" ) @@ -22,15 +21,7 @@ func (f *factory) NewMiningManager(consensusReference consensusreference.Consens mempoolConfig *mempoolpkg.Config) MiningManager { mempool := mempoolpkg.New(mempoolConfig, consensusReference) - // In the current pruning window (according to 06/04/2022) the header with the most mass weighted 5294 grams. - // We take a 10x factor for safety. - // TODO: Remove this behaviour once `ignoreHeaderMass` is set to true in all networks. - const estimatedHeaderUpperBound = 60000 - if estimatedHeaderUpperBound > params.MaxBlockMass { - panic(errors.Errorf("Estimated header mass upper bound is higher than the max block mass allowed")) - } - maxBlockMass := params.MaxBlockMass - estimatedHeaderUpperBound - blockTemplateBuilder := blocktemplatebuilder.New(consensusReference, mempool, maxBlockMass, params.CoinbasePayloadScriptPublicKeyMaxLength) + blockTemplateBuilder := blocktemplatebuilder.New(consensusReference, mempool, params.MaxBlockMass, params.CoinbasePayloadScriptPublicKeyMaxLength) return &miningManager{ consensusReference: consensusReference, diff --git a/domain/miningmanager/mempool/check_transaction_standard.go b/domain/miningmanager/mempool/check_transaction_standard.go index 5b0fc4db1..9a66e2b67 100644 --- a/domain/miningmanager/mempool/check_transaction_standard.go +++ b/domain/miningmanager/mempool/check_transaction_standard.go @@ -198,9 +198,8 @@ func (mp *mempool) minimumRequiredTransactionRelayFee(mass uint64) uint64 { // Set the minimum fee to the maximum possible value if the calculated // fee is not in the valid range for monetary amounts. - // TODO: Replace it with constants.MaxSompiAfterHF1 once HF is activated - if minimumFee > constants.MaxSompiBeforeHF1 { - minimumFee = constants.MaxSompiBeforeHF1 + if minimumFee > constants.MaxSompi { + minimumFee = constants.MaxSompi } return minimumFee diff --git a/domain/miningmanager/mempool/check_transaction_standard_test.go b/domain/miningmanager/mempool/check_transaction_standard_test.go index 2c11b4558..1482c2b8c 100644 --- a/domain/miningmanager/mempool/check_transaction_standard_test.go +++ b/domain/miningmanager/mempool/check_transaction_standard_test.go @@ -50,12 +50,6 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) { defaultMinimumRelayTransactionFee, 100000, }, - { - "max standard tx size with max sompi relay fee", - MaximumStandardTransactionMass, - util.Amount(constants.MaxSompiBeforeHF1), - constants.MaxSompiBeforeHF1, - }, { "1500 bytes with 5000 relay fee", 1500, @@ -156,8 +150,8 @@ func TestIsTransactionOutputDust(t *testing.T) { { // Maximum allowed value is never dust. "max sompi amount is never dust", - externalapi.DomainTransactionOutput{Value: constants.MaxSompiBeforeHF1, ScriptPublicKey: scriptPublicKey}, - util.Amount(constants.MaxSompiBeforeHF1), + externalapi.DomainTransactionOutput{Value: constants.MaxSompi, ScriptPublicKey: scriptPublicKey}, + util.Amount(1000), false, }, { diff --git a/infrastructure/network/netadapter/id/id.go b/infrastructure/network/netadapter/id/id.go index 93b350cdf..8e273dd2f 100644 --- a/infrastructure/network/netadapter/id/id.go +++ b/infrastructure/network/netadapter/id/id.go @@ -58,12 +58,12 @@ func (id *ID) SerializeToBytes() ([]byte, error) { } // FromBytes returns an ID deserialized from the given byte slice. -func FromBytes(serializedID []byte) *ID { +func FromBytes(serializedID []byte) (*ID, error) { r := bytes.NewReader(serializedID) newID := new(ID) err := newID.Deserialize(r) if err != nil { - panic(err) + return nil, err } - return newID + return newID, nil } diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/p2p_version.go b/infrastructure/network/netadapter/server/grpcserver/protowire/p2p_version.go index 9880cdc28..0453e3930 100644 --- a/infrastructure/network/netadapter/server/grpcserver/protowire/p2p_version.go +++ b/infrastructure/network/netadapter/server/grpcserver/protowire/p2p_version.go @@ -35,13 +35,22 @@ func (x *VersionMessage) toAppMessage() (appmessage.Message, error) { return nil, err } + if x.Id == nil { + return nil, errors.Wrapf(errorNil, "VersionMessage.Id is nil") + } + + appMsgID, err := id.FromBytes(x.Id) + if err != nil { + return nil, err + } + return &appmessage.MsgVersion{ ProtocolVersion: x.ProtocolVersion, Network: x.Network, Services: appmessage.ServiceFlag(x.Services), Timestamp: mstime.UnixMilliseconds(x.Timestamp), Address: address, - ID: id.FromBytes(x.Id), + ID: appMsgID, UserAgent: x.UserAgent, DisableRelayTx: x.DisableRelayTx, SubnetworkID: subnetworkID, diff --git a/util/amount_test.go b/util/amount_test.go index 1288a84c8..962af6ad6 100644 --- a/util/amount_test.go +++ b/util/amount_test.go @@ -28,15 +28,9 @@ func TestAmountCreation(t *testing.T) { }, { name: "max producible", - amount: 21e6, + amount: 29e9, valid: true, - expected: Amount(constants.MaxSompiBeforeHF1), - }, - { - name: "exceeds max producible", - amount: 21e6 + 1e-8, - valid: true, - expected: Amount(constants.MaxSompiBeforeHF1) + 1, + expected: Amount(constants.MaxSompi), }, { name: "one hundred", @@ -109,10 +103,10 @@ func TestAmountUnitConversions(t *testing.T) { }{ { name: "MKAS", - amount: Amount(constants.MaxSompiBeforeHF1), + amount: Amount(constants.MaxSompi), unit: AmountMegaKAS, - converted: 21, - s: "21 MKAS", + converted: 29000, + s: "29000 MKAS", }, { name: "kKAS",