Remove HF1 activation code (#2042)

* Remove HF1 activation code

* Remove test with an overflow

* Fix "max sompi amount is never dust"

* Remove estimatedHeaderUpperBound logic
This commit is contained in:
Ori Newman 2022-05-05 20:35:17 +03:00 committed by GitHub
parent 52fbeedf20
commit 7390651072
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 84 additions and 324 deletions

View File

@ -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. // 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. // They are both initialized here and passed to register flows.
isStopping := uint32(0) isStopping := uint32(0)
errChan := make(chan error) errChan := make(chan error, 1)
receiveVersionRoute, sendVersionRoute, receiveReadyRoute := registerHandshakeRoutes(router) receiveVersionRoute, sendVersionRoute, receiveReadyRoute := registerHandshakeRoutes(router)

View File

@ -2,10 +2,7 @@ package libkaspawallet_test
import ( import (
"fmt" "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/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/pkg/errors"
"strings" "strings"
"testing" "testing"
@ -321,7 +318,6 @@ func TestMaxSompi(t *testing.T) {
cfg := *consensusConfig cfg := *consensusConfig
cfg.BlockCoinbaseMaturity = 0 cfg.BlockCoinbaseMaturity = 0
cfg.PreDeflationaryPhaseBaseSubsidy = 20e6 * constants.SompiPerKaspa cfg.PreDeflationaryPhaseBaseSubsidy = 20e6 * constants.SompiPerKaspa
cfg.HF1DAAScore = cfg.GenesisBlock.Header.DAAScore() + 10
tc, teardown, err := consensus.NewFactory().NewTestConsensus(&cfg, "TestMaxSompi") tc, teardown, err := consensus.NewFactory().NewTestConsensus(&cfg, "TestMaxSompi")
if err != nil { if err != nil {
t.Fatalf("Error setting up tc: %+v", err) t.Fatalf("Error setting up tc: %+v", err)
@ -457,8 +453,8 @@ func TestMaxSompi(t *testing.T) {
TransactionID: *consensushashing.TransactionID(txWithLargeInputAmount), TransactionID: *consensushashing.TransactionID(txWithLargeInputAmount),
Index: 0, Index: 0,
} }
if virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO1) { if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO1) {
t.Fatalf("Transaction was accepted in the DAG") t.Fatalf("Transaction wasn't accepted in the DAG")
} }
selectedUTXOsForTxWithLargeInputAndOutputAmount := []*libkaspawallet.UTXO{ selectedUTXOsForTxWithLargeInputAndOutputAmount := []*libkaspawallet.UTXO{
@ -499,34 +495,13 @@ func TestMaxSompi(t *testing.T) {
t.Fatalf("ExtractTransaction: %+v", err) t.Fatalf("ExtractTransaction: %+v", err)
} }
_, _, err = tc.AddBlock([]*externalapi.DomainHash{block1Hash}, nil, []*externalapi.DomainTransaction{txWithLargeInputAndOutputAmount}) // We're creating a new longer chain so we can double spend txWithLargeInputAmount
if !errors.Is(err, ruleerrors.ErrBadTxOutValue) { newChainRoot, _, err := tc.AddBlock([]*externalapi.DomainHash{block1Hash}, nil, nil)
t.Fatalf("AddBlock: %+v", err)
}
tip := block1Hash
for {
tip, _, err = tc.AddBlock([]*externalapi.DomainHash{tip}, nil, nil)
if err != nil { if err != nil {
t.Fatalf("AddBlock: %+v", err) t.Fatalf("AddBlock: %+v", err)
} }
selectedTip, err := tc.GetVirtualSelectedParent() _, virtualChangeSet, err = tc.AddBlock([]*externalapi.DomainHash{newChainRoot}, nil, []*externalapi.DomainTransaction{txWithLargeInputAndOutputAmount})
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})
if err != nil { if err != nil {
t.Fatalf("AddBlock: %+v", err) t.Fatalf("AddBlock: %+v", err)
} }
@ -539,14 +514,5 @@ func TestMaxSompi(t *testing.T) {
if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO2) { if !virtualChangeSet.VirtualUTXODiff.ToAdd().Contains(addedUTXO2) {
t.Fatalf("txWithLargeInputAndOutputAmount weren't accepted in the DAG") 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")
}
}) })
} }

View File

@ -217,8 +217,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
pastMedianTimeManager, pastMedianTimeManager,
ghostdagDataStore, ghostdagDataStore,
daaBlocksStore, daaBlocksStore,
txMassCalculator, txMassCalculator)
config.HF1DAAScore)
difficultyManager := f.difficultyConstructor( difficultyManager := f.difficultyConstructor(
dbManager, dbManager,
ghostdagManager, ghostdagManager,
@ -266,7 +265,6 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
finalityManager, finalityManager,
genesisHash, genesisHash,
config.MergeDepth, config.MergeDepth,
config.HF1DAAScore,
ghostdagDataStore, ghostdagDataStore,
mergeDepthRootStore, mergeDepthRootStore,
daaBlocksStore, daaBlocksStore,
@ -344,7 +342,6 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
config.MaxBlockParents, config.MaxBlockParents,
config.TimestampDeviationTolerance, config.TimestampDeviationTolerance,
config.TargetTimePerBlock, config.TargetTimePerBlock,
config.HF1DAAScore,
config.MaxBlockLevel, config.MaxBlockLevel,
dbManager, dbManager,
@ -393,7 +390,6 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
blockBuilder := blockbuilder.New( blockBuilder := blockbuilder.New(
dbManager, dbManager,
genesisHash, genesisHash,
config.HF1DAAScore,
difficultyManager, difficultyManager,
pastMedianTimeManager, pastMedianTimeManager,

View File

@ -185,7 +185,6 @@ func TestBoundedMergeDepth(t *testing.T) {
consensusConfig.K = 5 consensusConfig.K = 5
consensusConfig.MergeDepth = 7 consensusConfig.MergeDepth = 7
consensusConfig.FinalityDuration = 20 * consensusConfig.TargetTimePerBlock consensusConfig.FinalityDuration = 20 * consensusConfig.TargetTimePerBlock
consensusConfig.HF1DAAScore = consensusConfig.GenesisBlock.Header.DAAScore() + 200
if uint64(consensusConfig.K) >= consensusConfig.FinalityDepth() { if uint64(consensusConfig.K) >= consensusConfig.FinalityDepth() {
t.Fatal("K must be smaller than finality duration for this test to run") 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) test(consensusConfig.MergeDepth, 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)
}) })
} }

View File

@ -20,7 +20,6 @@ import (
type blockBuilder struct { type blockBuilder struct {
databaseContext model.DBManager databaseContext model.DBManager
genesisHash *externalapi.DomainHash genesisHash *externalapi.DomainHash
hf1DAAScore uint64
difficultyManager model.DifficultyManager difficultyManager model.DifficultyManager
pastMedianTimeManager model.PastMedianTimeManager pastMedianTimeManager model.PastMedianTimeManager
@ -43,7 +42,6 @@ type blockBuilder struct {
func New( func New(
databaseContext model.DBManager, databaseContext model.DBManager,
genesisHash *externalapi.DomainHash, genesisHash *externalapi.DomainHash,
hf1DAAScore uint64,
difficultyManager model.DifficultyManager, difficultyManager model.DifficultyManager,
pastMedianTimeManager model.PastMedianTimeManager, pastMedianTimeManager model.PastMedianTimeManager,
@ -65,7 +63,6 @@ func New(
return &blockBuilder{ return &blockBuilder{
databaseContext: databaseContext, databaseContext: databaseContext,
genesisHash: genesisHash, genesisHash: genesisHash,
hf1DAAScore: hf1DAAScore,
difficultyManager: difficultyManager, difficultyManager: difficultyManager,
pastMedianTimeManager: pastMedianTimeManager, pastMedianTimeManager: pastMedianTimeManager,
@ -227,13 +224,8 @@ func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions
return nil, err return nil, err
} }
version := constants.BlockVersionBeforeHF1
if daaScore >= bb.hf1DAAScore {
version = constants.BlockVersionAfterHF1
}
return blockheader.NewImmutableBlockHeader( return blockheader.NewImmutableBlockHeader(
version, constants.BlockVersion,
parents, parents,
hashMerkleRoot, hashMerkleRoot,
acceptedIDMerkleRoot, acceptedIDMerkleRoot,

View File

@ -94,14 +94,9 @@ func (bb *testBlockBuilder) buildUTXOInvalidHeader(stagingArea *model.StagingAre
}) })
} }
version := constants.BlockVersionBeforeHF1
if daaScore >= bb.hf1DAAScore {
version = constants.BlockVersionAfterHF1
}
bb.nonceCounter++ bb.nonceCounter++
return blockheader.NewImmutableBlockHeader( return blockheader.NewImmutableBlockHeader(
version, constants.BlockVersion,
parents, parents,
hashMerkleRoot, hashMerkleRoot,
&externalapi.DomainHash{}, &externalapi.DomainHash{},

View File

@ -220,10 +220,6 @@ func (v *blockValidator) validateGasLimit(block *externalapi.DomainBlock) error
func (v *blockValidator) checkBlockMass(block *externalapi.DomainBlock) error { func (v *blockValidator) checkBlockMass(block *externalapi.DomainBlock) error {
mass := uint64(0) mass := uint64(0)
if block.Header.DAAScore() < v.hf1DAAScore {
mass += v.headerEstimatedSerializedSize(block.Header)
}
for _, transaction := range block.Transactions { for _, transaction := range block.Transactions {
v.transactionValidator.PopulateMass(transaction) v.transactionValidator.PopulateMass(transaction)

View File

@ -1307,7 +1307,7 @@ func initBlockWithFirstTransactionDifferentThanCoinbase(consensusConfig *consens
return &externalapi.DomainBlock{ return &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader( Header: blockheader.NewImmutableBlockHeader(
constants.BlockVersionBeforeHF1, constants.BlockVersion,
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{consensusConfig.GenesisHash}}, []externalapi.BlockLevelParents{[]*externalapi.DomainHash{consensusConfig.GenesisHash}},
merkle.CalculateHashMerkleRoot([]*externalapi.DomainTransaction{tx}), merkle.CalculateHashMerkleRoot([]*externalapi.DomainTransaction{tx}),
&externalapi.DomainHash{}, &externalapi.DomainHash{},

View File

@ -108,11 +108,7 @@ func TestCheckParentsIncest(t *testing.T) {
t.Fatalf("AddBlock: %+v", err) t.Fatalf("AddBlock: %+v", err)
} }
version := constants.BlockVersionBeforeHF1 version := constants.BlockVersion
if consensusConfig.HF1DAAScore == 0 {
version = constants.BlockVersionAfterHF1
}
directParentsRelationBlock := &externalapi.DomainBlock{ directParentsRelationBlock := &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader( Header: blockheader.NewImmutableBlockHeader(
version, version,

View File

@ -56,16 +56,9 @@ func (v *blockValidator) checkParentsLimit(header externalapi.BlockHeader) error
} }
func (v *blockValidator) checkBlockVersion(header externalapi.BlockHeader) error { func (v *blockValidator) checkBlockVersion(header externalapi.BlockHeader) error {
if header.DAAScore() >= v.hf1DAAScore { if header.Version() != constants.BlockVersion {
if header.Version() != constants.BlockVersionAfterHF1 {
return errors.Wrapf( return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "After HF1 the block version should be %d", constants.BlockVersionAfterHF1) ruleerrors.ErrWrongBlockVersion, "The block version should be %d", constants.BlockVersion)
}
} else {
if header.Version() != constants.BlockVersionBeforeHF1 {
return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "Beofre HF1 the block version should be %d", constants.BlockVersionBeforeHF1)
}
} }
return nil return nil
} }

View File

@ -62,11 +62,7 @@ func CheckBlockVersion(t *testing.T, tc testapi.TestConsensus, consensusConfig *
t.Fatalf("BuildBlockWithParents: %+v", err) t.Fatalf("BuildBlockWithParents: %+v", err)
} }
expectedVersion := constants.BlockVersionBeforeHF1 expectedVersion := constants.BlockVersion
if consensusConfig.HF1DAAScore == 0 {
expectedVersion = constants.BlockVersionAfterHF1
}
block.Header = blockheader.NewImmutableBlockHeader( block.Header = blockheader.NewImmutableBlockHeader(
expectedVersion+1, expectedVersion+1,
block.Header.Parents(), block.Header.Parents(),

View File

@ -24,7 +24,6 @@ type blockValidator struct {
maxBlockParents externalapi.KType maxBlockParents externalapi.KType
timestampDeviationTolerance int timestampDeviationTolerance int
targetTimePerBlock time.Duration targetTimePerBlock time.Duration
hf1DAAScore uint64
maxBlockLevel int maxBlockLevel int
databaseContext model.DBReader databaseContext model.DBReader
@ -64,7 +63,6 @@ func New(powMax *big.Int,
maxBlockParents externalapi.KType, maxBlockParents externalapi.KType,
timestampDeviationTolerance int, timestampDeviationTolerance int,
targetTimePerBlock time.Duration, targetTimePerBlock time.Duration,
hf1DAAScore uint64,
maxBlockLevel int, maxBlockLevel int,
databaseContext model.DBReader, databaseContext model.DBReader,
@ -104,7 +102,6 @@ func New(powMax *big.Int,
maxBlockMass: maxBlockMass, maxBlockMass: maxBlockMass,
mergeSetSizeLimit: mergeSetSizeLimit, mergeSetSizeLimit: mergeSetSizeLimit,
maxBlockParents: maxBlockParents, maxBlockParents: maxBlockParents,
hf1DAAScore: hf1DAAScore,
maxBlockLevel: maxBlockLevel, maxBlockLevel: maxBlockLevel,
timestampDeviationTolerance: timestampDeviationTolerance, timestampDeviationTolerance: timestampDeviationTolerance,

View File

@ -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
}

View File

@ -111,7 +111,7 @@ func TestGHOSTDAG(t *testing.T) {
blockID := StringToDomainHash(testBlockData.ID) blockID := StringToDomainHash(testBlockData.ID)
dagTopology.parentsMap[*blockID] = StringToDomainHashSlice(testBlockData.Parents) dagTopology.parentsMap[*blockID] = StringToDomainHashSlice(testBlockData.Parents)
blockHeadersStore.dagMap[*blockID] = blockheader.NewImmutableBlockHeader( blockHeadersStore.dagMap[*blockID] = blockheader.NewImmutableBlockHeader(
constants.BlockVersionBeforeHF1, constants.BlockVersion,
[]externalapi.BlockLevelParents{StringToDomainHashSlice(testBlockData.Parents)}, []externalapi.BlockLevelParents{StringToDomainHashSlice(testBlockData.Parents)},
nil, nil,
nil, nil,

View File

@ -16,7 +16,6 @@ type mergeDepthManager struct {
genesisHash *externalapi.DomainHash genesisHash *externalapi.DomainHash
mergeDepth uint64 mergeDepth uint64
hf1DAAScore uint64
ghostdagDataStore model.GHOSTDAGDataStore ghostdagDataStore model.GHOSTDAGDataStore
mergeDepthRootStore model.MergeDepthRootStore mergeDepthRootStore model.MergeDepthRootStore
@ -34,7 +33,6 @@ func New(
genesisHash *externalapi.DomainHash, genesisHash *externalapi.DomainHash,
mergeDepth uint64, mergeDepth uint64,
hf1DAAScore uint64,
ghostdagDataStore model.GHOSTDAGDataStore, ghostdagDataStore model.GHOSTDAGDataStore,
mergeDepthRootStore model.MergeDepthRootStore, mergeDepthRootStore model.MergeDepthRootStore,
@ -49,7 +47,6 @@ func New(
finalityManager: finalityManager, finalityManager: finalityManager,
genesisHash: genesisHash, genesisHash: genesisHash,
mergeDepth: mergeDepth, mergeDepth: mergeDepth,
hf1DAAScore: hf1DAAScore,
ghostdagDataStore: ghostdagDataStore, ghostdagDataStore: ghostdagDataStore,
mergeDepthRootStore: mergeDepthRootStore, mergeDepthRootStore: mergeDepthRootStore,
daaBlocksStore: daaBlocksStore, daaBlocksStore: daaBlocksStore,
@ -71,19 +68,24 @@ func (mdm *mergeDepthManager) CheckBoundedMergeDepth(stagingArea *model.StagingA
return nil return nil
} }
// For validation, we must follow the HF1 DAA score in order to determine the correct depth to verify mergeDepthRoot, err := mdm.MergeDepthRoot(stagingArea, blockHash, isBlockWithTrustedData)
mergeDepthRootByHF1, err := mdm.mergeDepthRootByHF1DAAScoreForValidationOnly(stagingArea, blockHash, isBlockWithTrustedData)
if err != nil { if err != nil {
return err 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 { if err != nil {
return err return err
} }
for _, red := range ghostdagData.MergeSetReds() { for _, red := range ghostdagData.MergeSetReds() {
doesRedHaveMergeRootInPast, err := mdm.dagTopologyManager.IsAncestorOf(stagingArea, mergeDepthRootByHF1, red) doesRedHaveMergeRootInPast, err := mdm.dagTopologyManager.IsAncestorOf(stagingArea, mergeDepthRoot, red)
if err != nil { if err != nil {
return err return err
} }
@ -133,34 +135,6 @@ func (mdm *mergeDepthManager) NonBoundedMergeDepthViolatingBlues(
return nonBoundedMergeDepthViolatingBlues, nil 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) { func (mdm *mergeDepthManager) VirtualMergeDepthRoot(stagingArea *model.StagingArea) (*externalapi.DomainHash, error) {
log.Tracef("VirtualMergeDepthRoot start") log.Tracef("VirtualMergeDepthRoot start")
defer log.Tracef("VirtualMergeDepthRoot end") defer log.Tracef("VirtualMergeDepthRoot end")

View File

@ -37,7 +37,7 @@ func TestPruning(t *testing.T) {
}, },
"dag-for-test-pruning.json": { "dag-for-test-pruning.json": {
dagconfig.MainnetParams.Name: "503", dagconfig.MainnetParams.Name: "503",
dagconfig.TestnetParams.Name: "502", dagconfig.TestnetParams.Name: "503",
dagconfig.DevnetParams.Name: "503", dagconfig.DevnetParams.Name: "503",
dagconfig.SimnetParams.Name: "503", dagconfig.SimnetParams.Name: "503",
}, },

View File

@ -58,14 +58,6 @@ func (v *transactionValidator) ValidateTransactionInContextIgnoringUTXO(stagingA
return errors.Wrapf(ruleerrors.ErrUnfinalizedTx, "unfinalized transaction %v", tx) 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 return nil
} }
@ -81,13 +73,7 @@ func (v *transactionValidator) ValidateTransactionInContextAndPopulateFee(stagin
return err return err
} }
daaScore, err := v.daaBlocksStore.DAAScore(v.databaseContext, stagingArea, povBlockHash) totalSompiIn, err := v.checkTransactionInputAmounts(tx)
if err != nil {
return err
}
isHF1Activated := daaScore >= v.hf1DAAScore
totalSompiIn, err := v.checkTransactionInputAmounts(tx, isHF1Activated)
if err != nil { if err != nil {
return err return err
} }
@ -149,7 +135,7 @@ func (v *transactionValidator) checkTransactionCoinbaseMaturity(stagingArea *mod
return nil 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 totalSompiIn = 0
var missingOutpoints []*externalapi.DomainOutpoint 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 // a transaction are in a unit value known as a sompi. One
// kaspa is a quantity of sompi as defined by the // kaspa is a quantity of sompi as defined by the
// SompiPerKaspa constant. // SompiPerKaspa constant.
totalSompiIn, err = v.checkEntryAmounts(utxoEntry, totalSompiIn, isHF1Activated) totalSompiIn, err = v.checkEntryAmounts(utxoEntry, totalSompiIn)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -179,24 +165,19 @@ func (v *transactionValidator) checkTransactionInputAmounts(tx *externalapi.Doma
return totalSompiIn, nil 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 // The total of all outputs must not be more than the max
// allowed per transaction. Also, we could potentially overflow // allowed per transaction. Also, we could potentially overflow
// the accumulator so check for overflow. // the accumulator so check for overflow.
maxSompi := constants.MaxSompiBeforeHF1
if isHF1Activated {
maxSompi = constants.MaxSompiAfterHF1
}
originTxSompi := entry.Amount() originTxSompi := entry.Amount()
totalSompiInAfter = totalSompiInBefore + originTxSompi totalSompiInAfter = totalSompiInBefore + originTxSompi
if totalSompiInAfter < totalSompiInBefore || if totalSompiInAfter < totalSompiInBefore ||
totalSompiInAfter > maxSompi { totalSompiInAfter > constants.MaxSompi {
return 0, errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+ return 0, errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+
"inputs is %d which is higher than max "+ "inputs is %d which is higher than max "+
"allowed value of %d", totalSompiInBefore, "allowed value of %d", totalSompiInBefore,
maxSompi) constants.MaxSompi)
} }
return totalSompiInAfter, nil return totalSompiInAfter, nil
} }

View File

@ -11,12 +11,11 @@ import (
// ValidateTransactionInIsolation validates the parts of the transaction that can be validated context-free // ValidateTransactionInIsolation validates the parts of the transaction that can be validated context-free
func (v *transactionValidator) ValidateTransactionInIsolation(tx *externalapi.DomainTransaction, povDAAScore uint64) error { func (v *transactionValidator) ValidateTransactionInIsolation(tx *externalapi.DomainTransaction, povDAAScore uint64) error {
isHF1Activated := povDAAScore >= v.hf1DAAScore
err := v.checkTransactionInputCount(tx) err := v.checkTransactionInputCount(tx)
if err != nil { if err != nil {
return err return err
} }
err = v.checkTransactionAmountRanges(tx, isHF1Activated) err = v.checkTransactionAmountRanges(tx)
if err != nil { if err != nil {
return err return err
} }
@ -63,18 +62,13 @@ func (v *transactionValidator) checkTransactionInputCount(tx *externalapi.Domain
return nil 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 // Ensure the transaction amounts are in range. Each transaction
// output must not be negative or more than the max allowed per // output must not be negative or more than the max allowed per
// transaction. Also, the total of all outputs must abide by the same // transaction. Also, the total of all outputs must abide by the same
// restrictions. All amounts in a transaction are in a unit value known // 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 // as a sompi. One kaspa is a quantity of sompi as defined by the
// sompiPerKaspa constant. // sompiPerKaspa constant.
maxSompi := constants.MaxSompiBeforeHF1
if isHF1Activated {
maxSompi = constants.MaxSompiAfterHF1
}
var totalSompi uint64 var totalSompi uint64
for _, txOut := range tx.Outputs { for _, txOut := range tx.Outputs {
sompi := txOut.Value sompi := txOut.Value
@ -82,9 +76,9 @@ func (v *transactionValidator) checkTransactionAmountRanges(tx *externalapi.Doma
return errors.Wrap(ruleerrors.ErrTxOutValueZero, "zero value outputs are forbidden") 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 "+ 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. // Binary arithmetic guarantees that any overflow is detected and reported.
@ -94,14 +88,14 @@ func (v *transactionValidator) checkTransactionAmountRanges(tx *externalapi.Doma
if newTotalSompi < totalSompi { if newTotalSompi < totalSompi {
return errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+ return errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+
"outputs exceeds max allowed value of %d", "outputs exceeds max allowed value of %d",
maxSompi) constants.MaxSompi)
} }
totalSompi = newTotalSompi totalSompi = newTotalSompi
if totalSompi > maxSompi { if totalSompi > constants.MaxSompi {
return errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+ return errors.Wrapf(ruleerrors.ErrBadTxOutValue, "total value of all transaction "+
"outputs is %d which is higher than max "+ "outputs is %d which is higher than max "+
"allowed value of %d", totalSompi, "allowed value of %d", totalSompi,
maxSompi) constants.MaxSompi)
} }
} }

View File

@ -22,7 +22,6 @@ type txSubnetworkData struct {
func TestValidateTransactionInIsolationAndPopulateMass(t *testing.T) { func TestValidateTransactionInIsolationAndPopulateMass(t *testing.T) {
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) { testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
cfg := *consensusConfig cfg := *consensusConfig
cfg.HF1DAAScore = 20
factory := consensus.NewFactory() factory := consensus.NewFactory()
tc, teardown, err := factory.NewTestConsensus(&cfg, "TestValidateTransactionInIsolationAndPopulateMass") 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}, {"good one", 1, 1, 1, subnetworks.SubnetworkIDNative, nil, nil, nil, 0},
{"no inputs", 0, 1, 1, subnetworks.SubnetworkIDNative, nil, nil, ruleerrors.ErrNoTxInputs, 0}, {"no inputs", 0, 1, 1, subnetworks.SubnetworkIDNative, nil, nil, ruleerrors.ErrNoTxInputs, 0},
{"no outputs", 1, 0, 1, subnetworks.SubnetworkIDNative, nil, nil, nil, 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, subnetworks.SubnetworkIDNative,
nil, nil,
nil, nil,
ruleerrors.ErrBadTxOutValue, 0}, 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, subnetworks.SubnetworkIDNative,
nil, nil,
nil, nil,
nil, cfg.HF1DAAScore}, nil, 0},
{"too much sompi in one output - after hf", 1, 1, constants.MaxSompiAfterHF1 + 1, {"too much sompi in one output - after hf", 1, 1, constants.MaxSompi + 1,
subnetworks.SubnetworkIDNative, subnetworks.SubnetworkIDNative,
nil, nil,
nil, nil,
ruleerrors.ErrBadTxOutValue, cfg.HF1DAAScore}, ruleerrors.ErrBadTxOutValue, 0},
{"too much sompi in one output", 1, 1, constants.MaxSompiAfterHF1 + 1, {"too much sompi in one output", 1, 1, constants.MaxSompi + 1,
subnetworks.SubnetworkIDNative, subnetworks.SubnetworkIDNative,
nil, nil,
nil, nil,

View File

@ -21,7 +21,6 @@ type transactionValidator struct {
sigCache *txscript.SigCache sigCache *txscript.SigCache
sigCacheECDSA *txscript.SigCacheECDSA sigCacheECDSA *txscript.SigCacheECDSA
txMassCalculator *txmass.Calculator txMassCalculator *txmass.Calculator
hf1DAAScore uint64
} }
// New instantiates a new TransactionValidator // New instantiates a new TransactionValidator
@ -32,8 +31,7 @@ func New(blockCoinbaseMaturity uint64,
pastMedianTimeManager model.PastMedianTimeManager, pastMedianTimeManager model.PastMedianTimeManager,
ghostdagDataStore model.GHOSTDAGDataStore, ghostdagDataStore model.GHOSTDAGDataStore,
daaBlocksStore model.DAABlocksStore, daaBlocksStore model.DAABlocksStore,
txMassCalculator *txmass.Calculator, txMassCalculator *txmass.Calculator) model.TransactionValidator {
hf1DAAScore uint64) model.TransactionValidator {
return &transactionValidator{ return &transactionValidator{
blockCoinbaseMaturity: blockCoinbaseMaturity, blockCoinbaseMaturity: blockCoinbaseMaturity,
@ -46,6 +44,5 @@ func New(blockCoinbaseMaturity uint64,
sigCache: txscript.NewSigCache(sigCacheSize), sigCache: txscript.NewSigCache(sigCacheSize),
sigCacheECDSA: txscript.NewSigCacheECDSA(sigCacheSize), sigCacheECDSA: txscript.NewSigCacheECDSA(sigCacheSize),
txMassCalculator: txMassCalculator, txMassCalculator: txMassCalculator,
hf1DAAScore: hf1DAAScore,
} }
} }

View File

@ -21,7 +21,6 @@ import (
func TestValidateTransactionInContextAndPopulateFee(t *testing.T) { func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) { testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
consensusConfig.HF1DAAScore = consensusConfig.GenesisBlock.Header.DAAScore() + 1000
factory := consensus.NewFactory() factory := consensus.NewFactory()
tc, tearDown, err := factory.NewTestConsensus(consensusConfig, tc, tearDown, err := factory.NewTestConsensus(consensusConfig,
"TestValidateTransactionInContextAndPopulateFee") "TestValidateTransactionInContextAndPopulateFee")
@ -92,7 +91,7 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
Sequence: constants.MaxTxInSequenceNum, Sequence: constants.MaxTxInSequenceNum,
SigOpCount: 1, SigOpCount: 1,
UTXOEntry: utxo.NewUTXOEntry( UTXOEntry: utxo.NewUTXOEntry(
constants.MaxSompiBeforeHF1+1, 21e14+1,
scriptPublicKey, scriptPublicKey,
false, false,
0), 0),
@ -104,7 +103,7 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
Sequence: constants.MaxTxInSequenceNum, Sequence: constants.MaxTxInSequenceNum,
SigOpCount: 1, SigOpCount: 1,
UTXOEntry: utxo.NewUTXOEntry( UTXOEntry: utxo.NewUTXOEntry(
constants.MaxSompiAfterHF1+1, constants.MaxSompi+1,
scriptPublicKey, scriptPublicKey,
false, false,
0), 0),
@ -163,7 +162,7 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
Gas: 0, Gas: 0,
LockTime: 0} LockTime: 0}
txWithLargeAmountAfterHF := externalapi.DomainTransaction{ txWithInvalidAmount := externalapi.DomainTransaction{
Version: constants.MaxTransactionVersion, Version: constants.MaxTransactionVersion,
Inputs: []*externalapi.DomainTransactionInput{&txInputWithLargeAmountAfterHF}, Inputs: []*externalapi.DomainTransactionInput{&txInputWithLargeAmountAfterHF},
Outputs: []*externalapi.DomainTransactionOutput{&txOutput}, Outputs: []*externalapi.DomainTransactionOutput{&txOutput},
@ -207,9 +206,6 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
povBlockHash := externalapi.NewDomainHashFromByteArray(&[32]byte{0x01}) povBlockHash := externalapi.NewDomainHashFromByteArray(&[32]byte{0x01})
tc.DAABlocksStore().StageDAAScore(stagingArea, povBlockHash, consensusConfig.BlockCoinbaseMaturity+txInput.UTXOEntry.BlockDAAScore()) 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 // Just use some stub ghostdag data
tc.GHOSTDAGDataStore().Stage(stagingArea, povBlockHash, externalapi.NewBlockGHOSTDAGData( tc.GHOSTDAGDataStore().Stage(stagingArea, povBlockHash, externalapi.NewBlockGHOSTDAGData(
0, 0,
@ -242,24 +238,17 @@ func TestValidateTransactionInContextAndPopulateFee(t *testing.T) {
isValid: false, isValid: false,
expectedError: ruleerrors.ErrImmatureSpend, expectedError: ruleerrors.ErrImmatureSpend,
}, },
{ // The total inputs amount is bigger than the allowed maximum (constants.MaxSompiBeforeHF1) { // The total inputs amount is bigger than the allowed maximum before the HF (21e14)
name: "checkTransactionInputAmounts - invalid - before HF", name: "checkTransactionInputAmounts - valid",
tx: &txWithLargeAmountBeforeHF, tx: &txWithLargeAmountBeforeHF,
povBlockHash: povBlockHash, 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, isValid: true,
expectedError: nil, 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", name: "checkTransactionInputAmounts - invalid - after HF",
tx: &txWithLargeAmountAfterHF, tx: &txWithInvalidAmount,
povBlockHash: povAfterHFBlockHash, povBlockHash: povBlockHash,
isValid: false, isValid: false,
expectedError: ruleerrors.ErrBadTxOutValue, expectedError: ruleerrors.ErrBadTxOutValue,
}, },

View File

@ -3,11 +3,8 @@ package constants
import "math" import "math"
const ( const (
// BlockVersionBeforeHF1 represents the current version of blocks mined before HF1 // BlockVersion represents the current block version
BlockVersionBeforeHF1 uint16 = 0 BlockVersion uint16 = 1
// BlockVersionAfterHF1 represents the current version of blocks mined after HF1
BlockVersionAfterHF1 uint16 = 1
// MaxTransactionVersion is the current latest supported transaction version. // MaxTransactionVersion is the current latest supported transaction version.
MaxTransactionVersion uint16 = 0 MaxTransactionVersion uint16 = 0
@ -18,11 +15,8 @@ const (
// SompiPerKaspa is the number of sompi in one kaspa (1 KAS). // SompiPerKaspa is the number of sompi in one kaspa (1 KAS).
SompiPerKaspa = 100_000_000 SompiPerKaspa = 100_000_000
// MaxSompiBeforeHF1 is the maximum transaction amount allowed in sompi before the HF1 hard fork is activated. // MaxSompi is the maximum transaction amount allowed in sompi.
MaxSompiBeforeHF1 = uint64(21_000_000 * SompiPerKaspa) MaxSompi = uint64(29_000_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)
// MaxTxInSequenceNum is the maximum sequence number the sequence field // MaxTxInSequenceNum is the maximum sequence number the sequence field
// of a transaction input can be. // of a transaction input can be.

View File

@ -188,7 +188,6 @@ type Params struct {
MaxBlockLevel int MaxBlockLevel int
MergeDepth uint64 MergeDepth uint64
HF1DAAScore uint64
} }
// NormalizeRPCServerAddress returns addr with the current network default // 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. // This means that any block that has a level lower or equal to genesis will be level 0.
MaxBlockLevel: 225, MaxBlockLevel: 225,
MergeDepth: defaultMergeDepth, MergeDepth: defaultMergeDepth,
HF1DAAScore: 14687583,
} }
// TestnetParams defines the network parameters for the test Kaspa network. // TestnetParams defines the network parameters for the test Kaspa network.
@ -351,7 +349,6 @@ var TestnetParams = Params{
MaxBlockLevel: 250, MaxBlockLevel: 250,
MergeDepth: defaultMergeDepth, MergeDepth: defaultMergeDepth,
HF1DAAScore: 172800,
} }
// SimnetParams defines the network parameters for the simulation test Kaspa // SimnetParams defines the network parameters for the simulation test Kaspa

View File

@ -5,7 +5,6 @@ import (
"github.com/kaspanet/kaspad/domain/dagconfig" "github.com/kaspanet/kaspad/domain/dagconfig"
"github.com/kaspanet/kaspad/domain/miningmanager/blocktemplatebuilder" "github.com/kaspanet/kaspad/domain/miningmanager/blocktemplatebuilder"
mempoolpkg "github.com/kaspanet/kaspad/domain/miningmanager/mempool" mempoolpkg "github.com/kaspanet/kaspad/domain/miningmanager/mempool"
"github.com/pkg/errors"
"sync" "sync"
"time" "time"
) )
@ -22,15 +21,7 @@ func (f *factory) NewMiningManager(consensusReference consensusreference.Consens
mempoolConfig *mempoolpkg.Config) MiningManager { mempoolConfig *mempoolpkg.Config) MiningManager {
mempool := mempoolpkg.New(mempoolConfig, consensusReference) mempool := mempoolpkg.New(mempoolConfig, consensusReference)
// In the current pruning window (according to 06/04/2022) the header with the most mass weighted 5294 grams. blockTemplateBuilder := blocktemplatebuilder.New(consensusReference, mempool, params.MaxBlockMass, params.CoinbasePayloadScriptPublicKeyMaxLength)
// 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)
return &miningManager{ return &miningManager{
consensusReference: consensusReference, consensusReference: consensusReference,

View File

@ -198,9 +198,8 @@ func (mp *mempool) minimumRequiredTransactionRelayFee(mass uint64) uint64 {
// Set the minimum fee to the maximum possible value if the calculated // Set the minimum fee to the maximum possible value if the calculated
// fee is not in the valid range for monetary amounts. // fee is not in the valid range for monetary amounts.
// TODO: Replace it with constants.MaxSompiAfterHF1 once HF is activated if minimumFee > constants.MaxSompi {
if minimumFee > constants.MaxSompiBeforeHF1 { minimumFee = constants.MaxSompi
minimumFee = constants.MaxSompiBeforeHF1
} }
return minimumFee return minimumFee

View File

@ -50,12 +50,6 @@ func TestCalcMinRequiredTxRelayFee(t *testing.T) {
defaultMinimumRelayTransactionFee, defaultMinimumRelayTransactionFee,
100000, 100000,
}, },
{
"max standard tx size with max sompi relay fee",
MaximumStandardTransactionMass,
util.Amount(constants.MaxSompiBeforeHF1),
constants.MaxSompiBeforeHF1,
},
{ {
"1500 bytes with 5000 relay fee", "1500 bytes with 5000 relay fee",
1500, 1500,
@ -156,8 +150,8 @@ func TestIsTransactionOutputDust(t *testing.T) {
{ {
// Maximum allowed value is never dust. // Maximum allowed value is never dust.
"max sompi amount is never dust", "max sompi amount is never dust",
externalapi.DomainTransactionOutput{Value: constants.MaxSompiBeforeHF1, ScriptPublicKey: scriptPublicKey}, externalapi.DomainTransactionOutput{Value: constants.MaxSompi, ScriptPublicKey: scriptPublicKey},
util.Amount(constants.MaxSompiBeforeHF1), util.Amount(1000),
false, false,
}, },
{ {

View File

@ -58,12 +58,12 @@ func (id *ID) SerializeToBytes() ([]byte, error) {
} }
// FromBytes returns an ID deserialized from the given byte slice. // 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) r := bytes.NewReader(serializedID)
newID := new(ID) newID := new(ID)
err := newID.Deserialize(r) err := newID.Deserialize(r)
if err != nil { if err != nil {
panic(err) return nil, err
} }
return newID return newID, nil
} }

View File

@ -35,13 +35,22 @@ func (x *VersionMessage) toAppMessage() (appmessage.Message, error) {
return nil, err 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{ return &appmessage.MsgVersion{
ProtocolVersion: x.ProtocolVersion, ProtocolVersion: x.ProtocolVersion,
Network: x.Network, Network: x.Network,
Services: appmessage.ServiceFlag(x.Services), Services: appmessage.ServiceFlag(x.Services),
Timestamp: mstime.UnixMilliseconds(x.Timestamp), Timestamp: mstime.UnixMilliseconds(x.Timestamp),
Address: address, Address: address,
ID: id.FromBytes(x.Id), ID: appMsgID,
UserAgent: x.UserAgent, UserAgent: x.UserAgent,
DisableRelayTx: x.DisableRelayTx, DisableRelayTx: x.DisableRelayTx,
SubnetworkID: subnetworkID, SubnetworkID: subnetworkID,

View File

@ -28,15 +28,9 @@ func TestAmountCreation(t *testing.T) {
}, },
{ {
name: "max producible", name: "max producible",
amount: 21e6, amount: 29e9,
valid: true, valid: true,
expected: Amount(constants.MaxSompiBeforeHF1), expected: Amount(constants.MaxSompi),
},
{
name: "exceeds max producible",
amount: 21e6 + 1e-8,
valid: true,
expected: Amount(constants.MaxSompiBeforeHF1) + 1,
}, },
{ {
name: "one hundred", name: "one hundred",
@ -109,10 +103,10 @@ func TestAmountUnitConversions(t *testing.T) {
}{ }{
{ {
name: "MKAS", name: "MKAS",
amount: Amount(constants.MaxSompiBeforeHF1), amount: Amount(constants.MaxSompi),
unit: AmountMegaKAS, unit: AmountMegaKAS,
converted: 21, converted: 29000,
s: "21 MKAS", s: "29000 MKAS",
}, },
{ {
name: "kKAS", name: "kKAS",