mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-08-23 02:53:14 +00:00
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.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
|
|
}
|