mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-09-14 21:40:11 +00:00

* Implement isBlockRewardFixed. * Fix factory.go. * Call isBlockRewardFixed from calcBlockSubsidy. * Fix bad call to ghostdagDataStore.Get. * Extract blue score and blue work from the header instead of from the ghostdagDataStore. * Fix coinbasemanager constructor arguments order * Format consensus_defaults.go * Check the mainnet switch from the block's point of view rather than the virtual's. * Don't call newBlockPruningPoint twice in buildBlock. * Properly handle new pruning point blocks in isBlockRewardFixed. * Use the correct variable. * Add a comment explaining what we do when the pruning point is not found in isBlockRewardFixed. * Implement TestBlockRewardSwitch. * Add missing error handling. Co-authored-by: Ori Newman <orinewman1@gmail.com>
87 lines
3.2 KiB
Go
87 lines
3.2 KiB
Go
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.fixedSubsidySwitchHashRateDifference) >= 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
|
|
}
|