mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-06 06:06:49 +00:00
Implement the new monetary policy (#1892)
* Remove unused functions, constants, and variables. * Rename maxSubsidy to baseSubsidy. * Remove unused parameters from CalcBlockSubsidy. * Remove link to old monetary policy. * If a block's DAA score is smaller than half a year, it should have a base subsidy. * Fix merge errors. * Fix more merge errors. * Add DeflationaryPhaseBaseSubsidy to the params. * Implement TestCalcDeflationaryPeriodBlockSubsidy. * Implement calcDeflationaryPeriodBlockSubsidy naively. * Implement calcDeflationaryPeriodBlockSubsidy not naively. * Adjust the subsidy based on target block rate. * Fix deflationaryPhaseDaaScore in TestCalcDeflationaryPeriodBlockSubsidy. * Explain how secondsPerMonth is calculated. * Don't adjust the subsidy based on the target block rate. * Update defaultDeflationaryPhaseDaaScore and add an explanation. * Use a pre-calculated table for subsidy per month * Make the generation function fail if base subsidy is changed * go fmt * Use test logger for printing + simplify print loop Co-authored-by: msutton <mikisiton2@gmail.com> Co-authored-by: Ori Newman <orinewman1@gmail.com>
This commit is contained in:
parent
7c1cddff11
commit
0bdd19136f
@ -203,14 +203,11 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
|
|||||||
coinbaseManager := coinbasemanager.New(
|
coinbaseManager := coinbasemanager.New(
|
||||||
dbManager,
|
dbManager,
|
||||||
config.SubsidyGenesisReward,
|
config.SubsidyGenesisReward,
|
||||||
config.MinSubsidy,
|
config.PreDeflationaryPhaseBaseSubsidy,
|
||||||
config.MaxSubsidy,
|
|
||||||
config.SubsidyPastRewardMultiplier,
|
|
||||||
config.SubsidyMergeSetRewardMultiplier,
|
|
||||||
config.CoinbasePayloadScriptPublicKeyMaxLength,
|
config.CoinbasePayloadScriptPublicKeyMaxLength,
|
||||||
config.GenesisHash,
|
config.GenesisHash,
|
||||||
config.FixedSubsidySwitchPruningPointInterval,
|
config.DeflationaryPhaseDaaScore,
|
||||||
config.FixedSubsidySwitchHashRateThreshold,
|
config.DeflationaryPhaseBaseSubsidy,
|
||||||
dagTraversalManager,
|
dagTraversalManager,
|
||||||
ghostdagDataStore,
|
ghostdagDataStore,
|
||||||
acceptanceDataStore,
|
acceptanceDataStore,
|
||||||
|
@ -7,6 +7,6 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|||||||
type CoinbaseManager interface {
|
type CoinbaseManager interface {
|
||||||
ExpectedCoinbaseTransaction(stagingArea *StagingArea, blockHash *externalapi.DomainHash,
|
ExpectedCoinbaseTransaction(stagingArea *StagingArea, blockHash *externalapi.DomainHash,
|
||||||
coinbaseData *externalapi.DomainCoinbaseData) (*externalapi.DomainTransaction, error)
|
coinbaseData *externalapi.DomainCoinbaseData) (*externalapi.DomainTransaction, error)
|
||||||
CalcBlockSubsidy(blockHash *externalapi.DomainHash) (uint64, error)
|
CalcBlockSubsidy(stagingArea *StagingArea, blockHash *externalapi.DomainHash) (uint64, error)
|
||||||
ExtractCoinbaseDataBlueScoreAndSubsidy(coinbaseTx *externalapi.DomainTransaction) (blueScore uint64, coinbaseData *externalapi.DomainCoinbaseData, subsidy uint64, err error)
|
ExtractCoinbaseDataBlueScoreAndSubsidy(coinbaseTx *externalapi.DomainTransaction) (blueScore uint64, coinbaseData *externalapi.DomainCoinbaseData, subsidy uint64, err error)
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ func (v *blockValidator) checkCoinbaseSubsidy(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedSubsidy, err := v.coinbaseManager.CalcBlockSubsidy(blockHash)
|
expectedSubsidy, err := v.coinbaseManager.CalcBlockSubsidy(stagingArea, blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
package coinbasemanager
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
||||||
"math/big"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *coinbaseManager) isBlockRewardFixed(stagingArea *model.StagingArea, blockPruningPoint *externalapi.DomainHash) (bool, error) {
|
|
||||||
blockPruningPointIndex, found, err := c.findPruningPointIndex(stagingArea, blockPruningPoint)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// The given `pruningPointBlock` may only not be found under one circumstance:
|
|
||||||
// we're currently in the process of building the next pruning point. As such,
|
|
||||||
// we must manually set highIndex to currentIndex + 1 because the next pruning
|
|
||||||
// point is not yet stored in the database
|
|
||||||
highPruningPointIndex := blockPruningPointIndex
|
|
||||||
highPruningPointHash := blockPruningPoint
|
|
||||||
if !found {
|
|
||||||
currentPruningPointIndex, err := c.pruningStore.CurrentPruningPointIndex(c.databaseContext, stagingArea)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
highPruningPointIndex = currentPruningPointIndex + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
if highPruningPointIndex <= c.fixedSubsidySwitchPruningPointInterval {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
lowPruningPointIndex := highPruningPointIndex - c.fixedSubsidySwitchPruningPointInterval
|
|
||||||
lowPruningPointHash, err := c.pruningStore.PruningPointByIndex(c.databaseContext, stagingArea, lowPruningPointIndex)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
highPruningPointHeader, err := c.blockHeaderStore.BlockHeader(c.databaseContext, stagingArea, highPruningPointHash)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
lowPruningPointHeader, err := c.blockHeaderStore.BlockHeader(c.databaseContext, stagingArea, lowPruningPointHash)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
blueWorkDifference := new(big.Int).Sub(highPruningPointHeader.BlueWork(), lowPruningPointHeader.BlueWork())
|
|
||||||
blueScoreDifference := new(big.Int).SetUint64(highPruningPointHeader.BlueScore() - lowPruningPointHeader.BlueScore())
|
|
||||||
estimatedAverageHashRate := new(big.Int).Div(blueWorkDifference, blueScoreDifference)
|
|
||||||
if estimatedAverageHashRate.Cmp(c.fixedSubsidySwitchHashRateThreshold) >= 0 {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
highPruningPointIndex--
|
|
||||||
highPruningPointHash, err = c.pruningStore.PruningPointByIndex(c.databaseContext, stagingArea, highPruningPointIndex)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *coinbaseManager) findPruningPointIndex(stagingArea *model.StagingArea, pruningPointHash *externalapi.DomainHash) (uint64, bool, error) {
|
|
||||||
currentPruningPointHash, err := c.pruningStore.PruningPoint(c.databaseContext, stagingArea)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false, err
|
|
||||||
}
|
|
||||||
currentPruningPointIndex, err := c.pruningStore.CurrentPruningPointIndex(c.databaseContext, stagingArea)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false, err
|
|
||||||
}
|
|
||||||
for !currentPruningPointHash.Equal(pruningPointHash) && currentPruningPointIndex > 0 {
|
|
||||||
currentPruningPointIndex--
|
|
||||||
currentPruningPointHash, err = c.pruningStore.PruningPointByIndex(c.databaseContext, stagingArea, currentPruningPointIndex)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if currentPruningPointIndex == 0 && !currentPruningPointHash.Equal(pruningPointHash) {
|
|
||||||
return 0, false, nil
|
|
||||||
}
|
|
||||||
return currentPruningPointIndex, true, nil
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
package coinbasemanager_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus"
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
|
||||||
"github.com/kaspanet/kaspad/util/difficulty"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBlockRewardSwitch(t *testing.T) {
|
|
||||||
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
|
||||||
// Set the pruning depth to 10
|
|
||||||
consensusConfig.MergeSetSizeLimit = 1
|
|
||||||
consensusConfig.K = 1
|
|
||||||
consensusConfig.FinalityDuration = 1 * time.Second
|
|
||||||
consensusConfig.TargetTimePerBlock = 1 * time.Second
|
|
||||||
|
|
||||||
// Disable difficulty adjustment so that we could reason about blue work
|
|
||||||
consensusConfig.DisableDifficultyAdjustment = true
|
|
||||||
|
|
||||||
// Disable pruning so that we could have access to all the blocks
|
|
||||||
consensusConfig.IsArchival = true
|
|
||||||
|
|
||||||
// Set the interval to 10
|
|
||||||
consensusConfig.FixedSubsidySwitchPruningPointInterval = 10
|
|
||||||
|
|
||||||
// Set the hash rate difference such that the switch would trigger exactly
|
|
||||||
// on the `FixedSubsidySwitchPruningPointInterval + 1`th pruning point
|
|
||||||
workToAcceptGenesis := difficulty.CalcWork(consensusConfig.GenesisBlock.Header.Bits())
|
|
||||||
consensusConfig.FixedSubsidySwitchHashRateThreshold = workToAcceptGenesis
|
|
||||||
|
|
||||||
// Set the min, max, and post-switch subsidies to values that would make it
|
|
||||||
// easy to tell whether the switch happened
|
|
||||||
consensusConfig.MinSubsidy = 2 * constants.SompiPerKaspa
|
|
||||||
consensusConfig.MaxSubsidy = 2 * constants.SompiPerKaspa
|
|
||||||
consensusConfig.SubsidyGenesisReward = 1 * constants.SompiPerKaspa
|
|
||||||
|
|
||||||
factory := consensus.NewFactory()
|
|
||||||
tc, teardown, err := factory.NewTestConsensus(consensusConfig, "TestBlockRewardSwitch")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error setting up consensus: %+v", err)
|
|
||||||
}
|
|
||||||
defer teardown(false)
|
|
||||||
|
|
||||||
// Make the pruning point move FixedSubsidySwitchPruningPointInterval times
|
|
||||||
tipHash := consensusConfig.GenesisHash
|
|
||||||
for i := uint64(0); i < consensusConfig.PruningDepth()+consensusConfig.FixedSubsidySwitchPruningPointInterval; i++ {
|
|
||||||
addedBlockHash, _, err := tc.AddBlock([]*externalapi.DomainHash{tipHash}, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("AddBlock: %+v", err)
|
|
||||||
}
|
|
||||||
tipHash = addedBlockHash
|
|
||||||
}
|
|
||||||
|
|
||||||
// We expect to see `FixedSubsidySwitchPruningPointInterval` pruning points + the genesis
|
|
||||||
pruningPointHeaders, err := tc.PruningPointHeaders()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("PruningPointHeaders: %+v", pruningPointHeaders)
|
|
||||||
}
|
|
||||||
expectedPruningPointHeaderAmount := consensusConfig.FixedSubsidySwitchPruningPointInterval + 1
|
|
||||||
if uint64(len(pruningPointHeaders)) != expectedPruningPointHeaderAmount {
|
|
||||||
t.Fatalf("Unexpected amount of pruning point headers. "+
|
|
||||||
"Want: %d, got: %d", expectedPruningPointHeaderAmount, len(pruningPointHeaders))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure that all the headers thus far had a non-fixed subsidies
|
|
||||||
// Note that we skip the genesis, since that always has the post-switch
|
|
||||||
// value
|
|
||||||
for _, pruningPointHeader := range pruningPointHeaders[1:] {
|
|
||||||
pruningPointHash := consensushashing.HeaderHash(pruningPointHeader)
|
|
||||||
pruningPoint, err := tc.GetBlock(pruningPointHash)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("GetBlock: %+v", err)
|
|
||||||
}
|
|
||||||
pruningPointCoinbase := pruningPoint.Transactions[transactionhelper.CoinbaseTransactionIndex]
|
|
||||||
_, _, subsidy, err := tc.CoinbaseManager().ExtractCoinbaseDataBlueScoreAndSubsidy(pruningPointCoinbase)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("ExtractCoinbaseDataBlueScoreAndSubsidy: %+v", err)
|
|
||||||
}
|
|
||||||
if subsidy != consensusConfig.MinSubsidy {
|
|
||||||
t.Fatalf("Subsidy has unexpected value. Want: %d, got: %d", consensusConfig.MinSubsidy, subsidy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,9 +1,6 @@
|
|||||||
package coinbasemanager
|
package coinbasemanager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||||
@ -12,18 +9,16 @@ import (
|
|||||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||||
"github.com/kaspanet/kaspad/infrastructure/db/database"
|
"github.com/kaspanet/kaspad/infrastructure/db/database"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
type coinbaseManager struct {
|
type coinbaseManager struct {
|
||||||
subsidyGenesisReward uint64
|
subsidyGenesisReward uint64
|
||||||
minSubsidy uint64
|
preDeflationaryPhaseBaseSubsidy uint64
|
||||||
maxSubsidy uint64
|
|
||||||
subsidyPastRewardMultiplier *big.Rat
|
|
||||||
subsidyMergeSetRewardMultiplier *big.Rat
|
|
||||||
coinbasePayloadScriptPublicKeyMaxLength uint8
|
coinbasePayloadScriptPublicKeyMaxLength uint8
|
||||||
genesisHash *externalapi.DomainHash
|
genesisHash *externalapi.DomainHash
|
||||||
fixedSubsidySwitchPruningPointInterval uint64
|
deflationaryPhaseDaaScore uint64
|
||||||
fixedSubsidySwitchHashRateThreshold *big.Int
|
deflationaryPhaseBaseSubsidy uint64
|
||||||
|
|
||||||
databaseContext model.DBReader
|
databaseContext model.DBReader
|
||||||
dagTraversalManager model.DAGTraversalManager
|
dagTraversalManager model.DAGTraversalManager
|
||||||
@ -84,7 +79,7 @@ func (c *coinbaseManager) ExpectedCoinbaseTransaction(stagingArea *model.Staging
|
|||||||
txOuts = append(txOuts, txOut)
|
txOuts = append(txOuts, txOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
subsidy, err := c.CalcBlockSubsidy(blockHash)
|
subsidy, err := c.CalcBlockSubsidy(stagingArea, blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -182,97 +177,68 @@ func acceptanceDataFromArrayToMap(acceptanceData externalapi.AcceptanceData) map
|
|||||||
// should have. This is mainly used for determining how much the coinbase for
|
// should have. This is mainly used for determining how much the coinbase for
|
||||||
// newly generated blocks awards as well as validating the coinbase for blocks
|
// newly generated blocks awards as well as validating the coinbase for blocks
|
||||||
// has the expected value.
|
// has the expected value.
|
||||||
//
|
func (c *coinbaseManager) CalcBlockSubsidy(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (uint64, error) {
|
||||||
// Further details: https://hashdag.medium.com/kaspa-launch-plan-9a63f4d754a6
|
|
||||||
func (c *coinbaseManager) CalcBlockSubsidy(blockHash *externalapi.DomainHash) (uint64, error) {
|
|
||||||
if blockHash.Equal(c.genesisHash) {
|
if blockHash.Equal(c.genesisHash) {
|
||||||
return c.subsidyGenesisReward, nil
|
return c.subsidyGenesisReward, nil
|
||||||
}
|
}
|
||||||
|
blockDaaScore, err := c.daaBlocksStore.DAAScore(c.databaseContext, stagingArea, blockHash)
|
||||||
return c.maxSubsidy, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *coinbaseManager) calculateAveragePastSubsidy(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (*big.Rat, error) {
|
|
||||||
const subsidyPastWindowSize = 100
|
|
||||||
blockWindow, err := c.dagTraversalManager.BlockWindow(stagingArea, blockHash, subsidyPastWindowSize)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(blockWindow) == 0 {
|
|
||||||
return new(big.Rat).SetFrac64(int64(c.subsidyGenesisReward), 1), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pastBlocks, err := c.blockStore.Blocks(c.databaseContext, stagingArea, blockWindow)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pastBlockSubsidySum := int64(0)
|
|
||||||
for _, pastBlock := range pastBlocks {
|
|
||||||
coinbaseTransaction := pastBlock.Transactions[transactionhelper.CoinbaseTransactionIndex]
|
|
||||||
_, _, pastBlockSubsidy, err := c.ExtractCoinbaseDataBlueScoreAndSubsidy(coinbaseTransaction)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pastBlockSubsidySum += int64(pastBlockSubsidy)
|
|
||||||
}
|
|
||||||
return big.NewRat(pastBlockSubsidySum, int64(len(blockWindow))), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *coinbaseManager) calculateMergeSetSubsidySum(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (*big.Rat, error) {
|
|
||||||
ghostdagData, err := c.ghostdagDataStore.Get(c.databaseContext, stagingArea, blockHash, true)
|
|
||||||
if !database.IsNotFoundError(err) && err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there's ghostdag data with trusted data we prefer it because we need the original merge set non-pruned merge set.
|
|
||||||
if database.IsNotFoundError(err) {
|
|
||||||
ghostdagData, err = c.ghostdagDataStore.Get(c.databaseContext, stagingArea, blockHash, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mergeSet := append(ghostdagData.MergeSetBlues(), ghostdagData.MergeSetReds()...)
|
|
||||||
mergeSetBlocks, err := c.blockStore.Blocks(c.databaseContext, stagingArea, mergeSet)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
mergeSetSubsidySum := int64(0)
|
|
||||||
for _, mergeSetBlock := range mergeSetBlocks {
|
|
||||||
coinbaseTransaction := mergeSetBlock.Transactions[transactionhelper.CoinbaseTransactionIndex]
|
|
||||||
_, _, mergeSetBlockSubsidy, err := c.ExtractCoinbaseDataBlueScoreAndSubsidy(coinbaseTransaction)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mergeSetSubsidySum += int64(mergeSetBlockSubsidy)
|
|
||||||
}
|
|
||||||
return big.NewRat(mergeSetSubsidySum, 1), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *coinbaseManager) calculateSubsidyRandomVariable(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) (int64, error) {
|
|
||||||
ghostdagData, err := c.ghostdagDataStore.Get(c.databaseContext, stagingArea, blockHash, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
selectedParentHash := ghostdagData.SelectedParent()
|
if blockDaaScore < c.deflationaryPhaseDaaScore {
|
||||||
if selectedParentHash == nil {
|
return c.preDeflationaryPhaseBaseSubsidy, nil
|
||||||
return 0, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const binomialSteps = 10
|
blockSubsidy := c.calcDeflationaryPeriodBlockSubsidy(blockDaaScore)
|
||||||
binomialSum := int64(0)
|
return blockSubsidy, nil
|
||||||
|
}
|
||||||
|
|
||||||
// The first two bytes of a hash are a good deterministic source
|
func (c *coinbaseManager) calcDeflationaryPeriodBlockSubsidy(blockDaaScore uint64) uint64 {
|
||||||
// of randomness, so we use that instead of any rand implementation
|
// We define a year as 365.25 days and a month as 365.25 / 12 = 30.4375
|
||||||
firstTwoBytes := binary.LittleEndian.Uint16(selectedParentHash.ByteSlice()[:2])
|
// secondsPerMonth = 30.4375 * 24 * 60 * 60
|
||||||
for i := 0; i < binomialSteps; i++ {
|
const secondsPerMonth = 2629800
|
||||||
step := firstTwoBytes & 1
|
// Note that this calculation implicitly assumes that block per second = 1 (by assuming daa score diff is in second units).
|
||||||
firstTwoBytes >>= 1
|
monthsSinceDeflationaryPhaseStarted := (blockDaaScore - c.deflationaryPhaseDaaScore) / secondsPerMonth
|
||||||
binomialSum += int64(step)
|
// Return the pre-calculated value from subsidy-per-month table
|
||||||
|
return c.getDeflationaryPeriodBlockSubsidyFromTable(monthsSinceDeflationaryPhaseStarted)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This table was pre-calculated by calling `calcDeflationaryPeriodBlockSubsidyFloatCalc` for all months until reaching 0 subsidy.
|
||||||
|
To regenerate this table, run `TestBuildSubsidyTable` in coinbasemanager_test.go (note the `deflationaryPhaseBaseSubsidy` therein)
|
||||||
|
*/
|
||||||
|
var subsidyByDeflationaryMonthTable = []uint64{
|
||||||
|
44000000000, 41530469757, 39199543598, 36999442271, 34922823143, 32962755691, 31112698372, 29366476791, 27718263097, 26162556530, 24694165062, 23308188075, 22000000000, 20765234878, 19599771799, 18499721135, 17461411571, 16481377845, 15556349186, 14683238395, 13859131548, 13081278265, 12347082531, 11654094037, 11000000000,
|
||||||
|
10382617439, 9799885899, 9249860567, 8730705785, 8240688922, 7778174593, 7341619197, 6929565774, 6540639132, 6173541265, 5827047018, 5500000000, 5191308719, 4899942949, 4624930283, 4365352892, 4120344461, 3889087296, 3670809598, 3464782887, 3270319566, 3086770632, 2913523509, 2750000000, 2595654359,
|
||||||
|
2449971474, 2312465141, 2182676446, 2060172230, 1944543648, 1835404799, 1732391443, 1635159783, 1543385316, 1456761754, 1375000000, 1297827179, 1224985737, 1156232570, 1091338223, 1030086115, 972271824, 917702399, 866195721, 817579891, 771692658, 728380877, 687500000, 648913589, 612492868,
|
||||||
|
578116285, 545669111, 515043057, 486135912, 458851199, 433097860, 408789945, 385846329, 364190438, 343750000, 324456794, 306246434, 289058142, 272834555, 257521528, 243067956, 229425599, 216548930, 204394972, 192923164, 182095219, 171875000, 162228397, 153123217, 144529071,
|
||||||
|
136417277, 128760764, 121533978, 114712799, 108274465, 102197486, 96461582, 91047609, 85937500, 81114198, 76561608, 72264535, 68208638, 64380382, 60766989, 57356399, 54137232, 51098743, 48230791, 45523804, 42968750, 40557099, 38280804, 36132267, 34104319,
|
||||||
|
32190191, 30383494, 28678199, 27068616, 25549371, 24115395, 22761902, 21484375, 20278549, 19140402, 18066133, 17052159, 16095095, 15191747, 14339099, 13534308, 12774685, 12057697, 11380951, 10742187, 10139274, 9570201, 9033066, 8526079, 8047547,
|
||||||
|
7595873, 7169549, 6767154, 6387342, 6028848, 5690475, 5371093, 5069637, 4785100, 4516533, 4263039, 4023773, 3797936, 3584774, 3383577, 3193671, 3014424, 2845237, 2685546, 2534818, 2392550, 2258266, 2131519, 2011886, 1898968,
|
||||||
|
1792387, 1691788, 1596835, 1507212, 1422618, 1342773, 1267409, 1196275, 1129133, 1065759, 1005943, 949484, 896193, 845894, 798417, 753606, 711309, 671386, 633704, 598137, 564566, 532879, 502971, 474742, 448096,
|
||||||
|
422947, 399208, 376803, 355654, 335693, 316852, 299068, 282283, 266439, 251485, 237371, 224048, 211473, 199604, 188401, 177827, 167846, 158426, 149534, 141141, 133219, 125742, 118685, 112024, 105736,
|
||||||
|
99802, 94200, 88913, 83923, 79213, 74767, 70570, 66609, 62871, 59342, 56012, 52868, 49901, 47100, 44456, 41961, 39606, 37383, 35285, 33304, 31435, 29671, 28006, 26434, 24950,
|
||||||
|
23550, 22228, 20980, 19803, 18691, 17642, 16652, 15717, 14835, 14003, 13217, 12475, 11775, 11114, 10490, 9901, 9345, 8821, 8326, 7858, 7417, 7001, 6608, 6237, 5887,
|
||||||
|
5557, 5245, 4950, 4672, 4410, 4163, 3929, 3708, 3500, 3304, 3118, 2943, 2778, 2622, 2475, 2336, 2205, 2081, 1964, 1854, 1750, 1652, 1559, 1471, 1389,
|
||||||
|
1311, 1237, 1168, 1102, 1040, 982, 927, 875, 826, 779, 735, 694, 655, 618, 584, 551, 520, 491, 463, 437, 413, 389, 367, 347, 327,
|
||||||
|
309, 292, 275, 260, 245, 231, 218, 206, 194, 183, 173, 163, 154, 146, 137, 130, 122, 115, 109, 103, 97, 91, 86, 81, 77,
|
||||||
|
73, 68, 65, 61, 57, 54, 51, 48, 45, 43, 40, 38, 36, 34, 32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18,
|
||||||
|
17, 16, 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4,
|
||||||
|
4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
0,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *coinbaseManager) getDeflationaryPeriodBlockSubsidyFromTable(month uint64) uint64 {
|
||||||
|
if month >= uint64(len(subsidyByDeflationaryMonthTable)) {
|
||||||
|
month = uint64(len(subsidyByDeflationaryMonthTable) - 1)
|
||||||
}
|
}
|
||||||
return binomialSum - (binomialSteps / 2), nil
|
return subsidyByDeflationaryMonthTable[month]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *coinbaseManager) calcDeflationaryPeriodBlockSubsidyFloatCalc(month uint64) uint64 {
|
||||||
|
baseSubsidy := c.deflationaryPhaseBaseSubsidy
|
||||||
|
subsidy := float64(baseSubsidy) / math.Pow(2, float64(month)/12)
|
||||||
|
return uint64(subsidy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *coinbaseManager) calcMergedBlockReward(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash,
|
func (c *coinbaseManager) calcMergedBlockReward(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash,
|
||||||
@ -312,14 +278,11 @@ func New(
|
|||||||
databaseContext model.DBReader,
|
databaseContext model.DBReader,
|
||||||
|
|
||||||
subsidyGenesisReward uint64,
|
subsidyGenesisReward uint64,
|
||||||
minSubsidy uint64,
|
preDeflationaryPhaseBaseSubsidy uint64,
|
||||||
maxSubsidy uint64,
|
|
||||||
subsidyPastRewardMultiplier *big.Rat,
|
|
||||||
subsidyMergeSetRewardMultiplier *big.Rat,
|
|
||||||
coinbasePayloadScriptPublicKeyMaxLength uint8,
|
coinbasePayloadScriptPublicKeyMaxLength uint8,
|
||||||
genesisHash *externalapi.DomainHash,
|
genesisHash *externalapi.DomainHash,
|
||||||
fixedSubsidySwitchPruningPointInterval uint64,
|
deflationaryPhaseDaaScore uint64,
|
||||||
fixedSubsidySwitchHashRateThreshold *big.Int,
|
deflationaryPhaseBaseSubsidy uint64,
|
||||||
|
|
||||||
dagTraversalManager model.DAGTraversalManager,
|
dagTraversalManager model.DAGTraversalManager,
|
||||||
ghostdagDataStore model.GHOSTDAGDataStore,
|
ghostdagDataStore model.GHOSTDAGDataStore,
|
||||||
@ -333,14 +296,11 @@ func New(
|
|||||||
databaseContext: databaseContext,
|
databaseContext: databaseContext,
|
||||||
|
|
||||||
subsidyGenesisReward: subsidyGenesisReward,
|
subsidyGenesisReward: subsidyGenesisReward,
|
||||||
minSubsidy: minSubsidy,
|
preDeflationaryPhaseBaseSubsidy: preDeflationaryPhaseBaseSubsidy,
|
||||||
maxSubsidy: maxSubsidy,
|
|
||||||
subsidyPastRewardMultiplier: subsidyPastRewardMultiplier,
|
|
||||||
subsidyMergeSetRewardMultiplier: subsidyMergeSetRewardMultiplier,
|
|
||||||
coinbasePayloadScriptPublicKeyMaxLength: coinbasePayloadScriptPublicKeyMaxLength,
|
coinbasePayloadScriptPublicKeyMaxLength: coinbasePayloadScriptPublicKeyMaxLength,
|
||||||
genesisHash: genesisHash,
|
genesisHash: genesisHash,
|
||||||
fixedSubsidySwitchPruningPointInterval: fixedSubsidySwitchPruningPointInterval,
|
deflationaryPhaseDaaScore: deflationaryPhaseDaaScore,
|
||||||
fixedSubsidySwitchHashRateThreshold: fixedSubsidySwitchHashRateThreshold,
|
deflationaryPhaseBaseSubsidy: deflationaryPhaseBaseSubsidy,
|
||||||
|
|
||||||
dagTraversalManager: dagTraversalManager,
|
dagTraversalManager: dagTraversalManager,
|
||||||
ghostdagDataStore: ghostdagDataStore,
|
ghostdagDataStore: ghostdagDataStore,
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
package coinbasemanager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||||
|
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||||
|
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCalcDeflationaryPeriodBlockSubsidy(t *testing.T) {
|
||||||
|
const secondsPerMonth = 2629800
|
||||||
|
const secondsPerHalving = secondsPerMonth * 12
|
||||||
|
const deflationaryPhaseDaaScore = secondsPerMonth * 6
|
||||||
|
const deflationaryPhaseBaseSubsidy = 440 * constants.SompiPerKaspa
|
||||||
|
coinbaseManagerInterface := New(
|
||||||
|
nil,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&externalapi.DomainHash{},
|
||||||
|
deflationaryPhaseDaaScore,
|
||||||
|
deflationaryPhaseBaseSubsidy,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil)
|
||||||
|
coinbaseManagerInstance := coinbaseManagerInterface.(*coinbaseManager)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
blockDaaScore uint64
|
||||||
|
expectedBlockSubsidy uint64
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "start of deflationary phase",
|
||||||
|
blockDaaScore: deflationaryPhaseDaaScore,
|
||||||
|
expectedBlockSubsidy: deflationaryPhaseBaseSubsidy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "after one halving",
|
||||||
|
blockDaaScore: deflationaryPhaseDaaScore + secondsPerHalving,
|
||||||
|
expectedBlockSubsidy: deflationaryPhaseBaseSubsidy / 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "after two halvings",
|
||||||
|
blockDaaScore: deflationaryPhaseDaaScore + secondsPerHalving*2,
|
||||||
|
expectedBlockSubsidy: deflationaryPhaseBaseSubsidy / 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "after five halvings",
|
||||||
|
blockDaaScore: deflationaryPhaseDaaScore + secondsPerHalving*5,
|
||||||
|
expectedBlockSubsidy: deflationaryPhaseBaseSubsidy / 32,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "after 32 halvings",
|
||||||
|
blockDaaScore: deflationaryPhaseDaaScore + secondsPerHalving*32,
|
||||||
|
expectedBlockSubsidy: deflationaryPhaseBaseSubsidy / 4294967296,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "just before subsidy depleted",
|
||||||
|
blockDaaScore: deflationaryPhaseDaaScore + secondsPerHalving*35,
|
||||||
|
expectedBlockSubsidy: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "after subsidy depleted",
|
||||||
|
blockDaaScore: deflationaryPhaseDaaScore + secondsPerHalving*36,
|
||||||
|
expectedBlockSubsidy: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
blockSubsidy := coinbaseManagerInstance.calcDeflationaryPeriodBlockSubsidy(test.blockDaaScore)
|
||||||
|
if blockSubsidy != test.expectedBlockSubsidy {
|
||||||
|
t.Errorf("TestCalcDeflationaryPeriodBlockSubsidy: test '%s' failed. Want: %d, got: %d",
|
||||||
|
test.name, test.expectedBlockSubsidy, blockSubsidy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildSubsidyTable(t *testing.T) {
|
||||||
|
deflationaryPhaseBaseSubsidy := dagconfig.MainnetParams.DeflationaryPhaseBaseSubsidy
|
||||||
|
if deflationaryPhaseBaseSubsidy != 440*constants.SompiPerKaspa {
|
||||||
|
t.Errorf("TestBuildSubsidyTable: table generation function was not updated to reflect "+
|
||||||
|
"the new base subsidy %d. Please fix the constant above and replace subsidyByDeflationaryMonthTable "+
|
||||||
|
"in coinbasemanager.go with the printed table", deflationaryPhaseBaseSubsidy)
|
||||||
|
}
|
||||||
|
coinbaseManagerInterface := New(
|
||||||
|
nil,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&externalapi.DomainHash{},
|
||||||
|
0,
|
||||||
|
deflationaryPhaseBaseSubsidy,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil)
|
||||||
|
coinbaseManagerInstance := coinbaseManagerInterface.(*coinbaseManager)
|
||||||
|
|
||||||
|
var subsidyTable []uint64
|
||||||
|
for M := uint64(0); ; M++ {
|
||||||
|
subsidy := coinbaseManagerInstance.calcDeflationaryPeriodBlockSubsidyFloatCalc(M)
|
||||||
|
subsidyTable = append(subsidyTable, subsidy)
|
||||||
|
if subsidy == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tableStr := "\n{\t"
|
||||||
|
for i := 0; i < len(subsidyTable); i++ {
|
||||||
|
tableStr += strconv.FormatUint(subsidyTable[i], 10) + ", "
|
||||||
|
if (i+1)%25 == 0 {
|
||||||
|
tableStr += "\n\t"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tableStr += "\n}"
|
||||||
|
t.Logf(tableStr)
|
||||||
|
}
|
@ -46,13 +46,11 @@ const (
|
|||||||
// Should be at least an order of magnitude smaller than defaultFinalityDuration/defaultTargetTimePerBlock.
|
// Should be at least an order of magnitude smaller than defaultFinalityDuration/defaultTargetTimePerBlock.
|
||||||
// (Higher values make pruning attacks easier by a constant, lower values make merging after a split or a spike
|
// (Higher values make pruning attacks easier by a constant, lower values make merging after a split or a spike
|
||||||
// in block take longer)
|
// in block take longer)
|
||||||
defaultMergeSetSizeLimit = defaultGHOSTDAGK * 10
|
defaultMergeSetSizeLimit = defaultGHOSTDAGK * 10
|
||||||
defaultSubsidyGenesisReward = 1 * constants.SompiPerKaspa
|
defaultSubsidyGenesisReward = 1 * constants.SompiPerKaspa
|
||||||
defaultMinSubsidy = 1 * constants.SompiPerKaspa
|
defaultPreDeflationaryPhaseBaseSubsidy = 500 * constants.SompiPerKaspa
|
||||||
defaultMaxSubsidy = 500 * constants.SompiPerKaspa
|
defaultDeflationaryPhaseBaseSubsidy = 440 * constants.SompiPerKaspa
|
||||||
defaultBaseSubsidy = 50 * constants.SompiPerKaspa
|
defaultCoinbasePayloadScriptPublicKeyMaxLength = 150
|
||||||
defaultFixedSubsidySwitchPruningPointInterval uint64 = 7
|
|
||||||
defaultCoinbasePayloadScriptPublicKeyMaxLength = 150
|
|
||||||
// defaultDifficultyAdjustmentWindowSize is the number of blocks in a block's past used to calculate its difficulty
|
// defaultDifficultyAdjustmentWindowSize is the number of blocks in a block's past used to calculate its difficulty
|
||||||
// target.
|
// target.
|
||||||
// The DAA should take the median of 2640 blocks, so in order to do that we need 2641 window size.
|
// The DAA should take the median of 2640 blocks, so in order to do that we need 2641 window size.
|
||||||
@ -76,4 +74,12 @@ const (
|
|||||||
defaultTargetTimePerBlock = 1 * time.Second
|
defaultTargetTimePerBlock = 1 * time.Second
|
||||||
|
|
||||||
defaultPruningProofM = 1000
|
defaultPruningProofM = 1000
|
||||||
|
|
||||||
|
// defaultDeflationaryPhaseDaaScore is the DAA score after which the pre-deflationary period
|
||||||
|
// switches to the deflationary period. This number is calculated as follows:
|
||||||
|
// We define a year as 365.25 days
|
||||||
|
// Half a year in seconds = 365.25 / 2 * 24 * 60 * 60 = 15778800
|
||||||
|
// The network was down for three days shortly after launch
|
||||||
|
// Three days in seconds = 3 * 24 * 60 * 60 = 259200
|
||||||
|
defaultDeflationaryPhaseDaaScore = 15778800 - 259200
|
||||||
)
|
)
|
||||||
|
@ -92,10 +92,8 @@ type Params struct {
|
|||||||
// SubsidyPastRewardMultiplier are part of the block subsidy equation.
|
// SubsidyPastRewardMultiplier are part of the block subsidy equation.
|
||||||
// Further details: https://hashdag.medium.com/kaspa-launch-plan-9a63f4d754a6
|
// Further details: https://hashdag.medium.com/kaspa-launch-plan-9a63f4d754a6
|
||||||
SubsidyGenesisReward uint64
|
SubsidyGenesisReward uint64
|
||||||
MinSubsidy uint64
|
PreDeflationaryPhaseBaseSubsidy uint64
|
||||||
MaxSubsidy uint64
|
DeflationaryPhaseBaseSubsidy uint64
|
||||||
SubsidyPastRewardMultiplier *big.Rat
|
|
||||||
SubsidyMergeSetRewardMultiplier *big.Rat
|
|
||||||
|
|
||||||
// TargetTimePerBlock is the desired amount of time to generate each
|
// TargetTimePerBlock is the desired amount of time to generate each
|
||||||
// block.
|
// block.
|
||||||
@ -180,12 +178,9 @@ type Params struct {
|
|||||||
// PruningProofM is the 'm' constant in the pruning proof. For more details see: https://github.com/kaspanet/research/issues/3
|
// PruningProofM is the 'm' constant in the pruning proof. For more details see: https://github.com/kaspanet/research/issues/3
|
||||||
PruningProofM uint64
|
PruningProofM uint64
|
||||||
|
|
||||||
// BaseSubsidy is the starting subsidy amount for mined blocks.
|
// DeflationaryPhaseDaaScore is the DAA score after which the monetary policy switches
|
||||||
BaseSubsidy uint64
|
// to its deflationary phase
|
||||||
|
DeflationaryPhaseDaaScore uint64
|
||||||
FixedSubsidySwitchPruningPointInterval uint64
|
|
||||||
|
|
||||||
FixedSubsidySwitchHashRateThreshold *big.Int
|
|
||||||
|
|
||||||
DisallowDirectBlocksOnTopOfGenesis bool
|
DisallowDirectBlocksOnTopOfGenesis bool
|
||||||
|
|
||||||
@ -243,10 +238,8 @@ var MainnetParams = Params{
|
|||||||
PowMax: mainPowMax,
|
PowMax: mainPowMax,
|
||||||
BlockCoinbaseMaturity: 100,
|
BlockCoinbaseMaturity: 100,
|
||||||
SubsidyGenesisReward: defaultSubsidyGenesisReward,
|
SubsidyGenesisReward: defaultSubsidyGenesisReward,
|
||||||
MinSubsidy: defaultMinSubsidy,
|
PreDeflationaryPhaseBaseSubsidy: defaultPreDeflationaryPhaseBaseSubsidy,
|
||||||
MaxSubsidy: defaultMaxSubsidy,
|
DeflationaryPhaseBaseSubsidy: defaultDeflationaryPhaseBaseSubsidy,
|
||||||
SubsidyPastRewardMultiplier: big.NewRat(9, 10),
|
|
||||||
SubsidyMergeSetRewardMultiplier: big.NewRat(1, 10),
|
|
||||||
TargetTimePerBlock: defaultTargetTimePerBlock,
|
TargetTimePerBlock: defaultTargetTimePerBlock,
|
||||||
FinalityDuration: defaultFinalityDuration,
|
FinalityDuration: defaultFinalityDuration,
|
||||||
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
|
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
|
||||||
@ -286,8 +279,7 @@ var MainnetParams = Params{
|
|||||||
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
||||||
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
||||||
PruningProofM: defaultPruningProofM,
|
PruningProofM: defaultPruningProofM,
|
||||||
FixedSubsidySwitchPruningPointInterval: defaultFixedSubsidySwitchPruningPointInterval,
|
DeflationaryPhaseDaaScore: defaultDeflationaryPhaseDaaScore,
|
||||||
FixedSubsidySwitchHashRateThreshold: big.NewInt(150_000_000_000),
|
|
||||||
DisallowDirectBlocksOnTopOfGenesis: true,
|
DisallowDirectBlocksOnTopOfGenesis: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,10 +298,8 @@ var TestnetParams = Params{
|
|||||||
PowMax: testnetPowMax,
|
PowMax: testnetPowMax,
|
||||||
BlockCoinbaseMaturity: 100,
|
BlockCoinbaseMaturity: 100,
|
||||||
SubsidyGenesisReward: defaultSubsidyGenesisReward,
|
SubsidyGenesisReward: defaultSubsidyGenesisReward,
|
||||||
MinSubsidy: defaultMinSubsidy,
|
PreDeflationaryPhaseBaseSubsidy: defaultPreDeflationaryPhaseBaseSubsidy,
|
||||||
MaxSubsidy: defaultMaxSubsidy,
|
DeflationaryPhaseBaseSubsidy: defaultDeflationaryPhaseBaseSubsidy,
|
||||||
SubsidyPastRewardMultiplier: big.NewRat(9, 10),
|
|
||||||
SubsidyMergeSetRewardMultiplier: big.NewRat(1, 10),
|
|
||||||
TargetTimePerBlock: defaultTargetTimePerBlock,
|
TargetTimePerBlock: defaultTargetTimePerBlock,
|
||||||
FinalityDuration: defaultFinalityDuration,
|
FinalityDuration: defaultFinalityDuration,
|
||||||
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
|
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
|
||||||
@ -349,8 +339,7 @@ var TestnetParams = Params{
|
|||||||
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
||||||
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
||||||
PruningProofM: defaultPruningProofM,
|
PruningProofM: defaultPruningProofM,
|
||||||
FixedSubsidySwitchPruningPointInterval: defaultFixedSubsidySwitchPruningPointInterval,
|
DeflationaryPhaseDaaScore: defaultDeflationaryPhaseDaaScore,
|
||||||
FixedSubsidySwitchHashRateThreshold: big.NewInt(150_000_000_000),
|
|
||||||
IgnoreHeaderMass: true,
|
IgnoreHeaderMass: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,10 +364,8 @@ var SimnetParams = Params{
|
|||||||
PowMax: simnetPowMax,
|
PowMax: simnetPowMax,
|
||||||
BlockCoinbaseMaturity: 100,
|
BlockCoinbaseMaturity: 100,
|
||||||
SubsidyGenesisReward: defaultSubsidyGenesisReward,
|
SubsidyGenesisReward: defaultSubsidyGenesisReward,
|
||||||
MinSubsidy: defaultMinSubsidy,
|
PreDeflationaryPhaseBaseSubsidy: defaultPreDeflationaryPhaseBaseSubsidy,
|
||||||
MaxSubsidy: defaultMaxSubsidy,
|
DeflationaryPhaseBaseSubsidy: defaultDeflationaryPhaseBaseSubsidy,
|
||||||
SubsidyPastRewardMultiplier: big.NewRat(9, 10),
|
|
||||||
SubsidyMergeSetRewardMultiplier: big.NewRat(1, 10),
|
|
||||||
TargetTimePerBlock: time.Millisecond,
|
TargetTimePerBlock: time.Millisecond,
|
||||||
FinalityDuration: time.Minute,
|
FinalityDuration: time.Minute,
|
||||||
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
|
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
|
||||||
@ -416,8 +403,7 @@ var SimnetParams = Params{
|
|||||||
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
||||||
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
||||||
PruningProofM: defaultPruningProofM,
|
PruningProofM: defaultPruningProofM,
|
||||||
FixedSubsidySwitchPruningPointInterval: defaultFixedSubsidySwitchPruningPointInterval,
|
DeflationaryPhaseDaaScore: defaultDeflationaryPhaseDaaScore,
|
||||||
FixedSubsidySwitchHashRateThreshold: big.NewInt(150_000_000_000),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DevnetParams defines the network parameters for the development Kaspa network.
|
// DevnetParams defines the network parameters for the development Kaspa network.
|
||||||
@ -435,10 +421,8 @@ var DevnetParams = Params{
|
|||||||
PowMax: devnetPowMax,
|
PowMax: devnetPowMax,
|
||||||
BlockCoinbaseMaturity: 100,
|
BlockCoinbaseMaturity: 100,
|
||||||
SubsidyGenesisReward: defaultSubsidyGenesisReward,
|
SubsidyGenesisReward: defaultSubsidyGenesisReward,
|
||||||
MinSubsidy: defaultMinSubsidy,
|
PreDeflationaryPhaseBaseSubsidy: defaultPreDeflationaryPhaseBaseSubsidy,
|
||||||
MaxSubsidy: defaultMaxSubsidy,
|
DeflationaryPhaseBaseSubsidy: defaultDeflationaryPhaseBaseSubsidy,
|
||||||
SubsidyPastRewardMultiplier: big.NewRat(9, 10),
|
|
||||||
SubsidyMergeSetRewardMultiplier: big.NewRat(1, 10),
|
|
||||||
TargetTimePerBlock: defaultTargetTimePerBlock,
|
TargetTimePerBlock: defaultTargetTimePerBlock,
|
||||||
FinalityDuration: defaultFinalityDuration,
|
FinalityDuration: defaultFinalityDuration,
|
||||||
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
|
DifficultyAdjustmentWindowSize: defaultDifficultyAdjustmentWindowSize,
|
||||||
@ -478,8 +462,7 @@ var DevnetParams = Params{
|
|||||||
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
MergeSetSizeLimit: defaultMergeSetSizeLimit,
|
||||||
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
CoinbasePayloadScriptPublicKeyMaxLength: defaultCoinbasePayloadScriptPublicKeyMaxLength,
|
||||||
PruningProofM: defaultPruningProofM,
|
PruningProofM: defaultPruningProofM,
|
||||||
FixedSubsidySwitchPruningPointInterval: defaultFixedSubsidySwitchPruningPointInterval,
|
DeflationaryPhaseDaaScore: defaultDeflationaryPhaseDaaScore,
|
||||||
FixedSubsidySwitchHashRateThreshold: big.NewInt(150_000_000_000),
|
|
||||||
IgnoreHeaderMass: true,
|
IgnoreHeaderMass: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user