mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
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:
parent
52fbeedf20
commit
7390651072
@ -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)
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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{},
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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{},
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
@ -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,
|
||||
|
@ -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")
|
||||
|
@ -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",
|
||||
},
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
},
|
||||
{
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user