mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00

* Replace the old blockSubsidy parameters with the new ones. * Return subsidyGenesisReward if blockHash is the genesis hash. * Traverse a block's past for the subsidy calculation. * Partially implement SubsidyStore. * Refer to SubsidyStore from CoinbaseManager. * Wrap calcBlockSubsidy in getBlockSubsidy, which first checks the database. * Fix finalityStore not calling GenerateShardingID. * Implement calculateAveragePastSubsidy. * Implement calculateMergeSetSubsidySum. * Implement calculateSubsidyRandomVariable. * Implement calcBlockSubsidy. * Add a TODO about floats. * Update the calcBlockSubsidy TODO. * Use binary.LittleEndian in calculateSubsidyRandomVariable. * Fix bad range in calculateSubsidyRandomVariable. * Replace float64 with big.Rat everywhere except for subsidyRandomVariable. * Fix a nil dereference. * Use a random walk to approximate the normal distribution. * In order to avoid unsupported fractional results from powInt64, flip the numerator and the denominator manually. * Set standardDeviation to 0.25, MaxSompi to 10_000_000_000 * SompiPerKaspa and defaultSubsidyGenesisReward to 1_000. * Set the standard deviation to 0.2. * Use a binomial distribution instead of trying to estimate the normal distribution. * Change some values around. * Clamp the block subsidy. * Remove the fake duplicate constants in the util package. * Reduce MaxSompi to only 100m Kaspa to avoid hitting the uint64 ceiling. * Lower MaxSompi further to avoid new and exciting ways for the uint64 ceiling to be hit. * Remove debug logs. * Fix a couple of failing tests. * Fix TestBlockWindow. * Fix limitTransactionCount sometimes crashing on index-out-of-bounds. * In TrustedDataDataDAABlock, replace BlockHeader with DomainBlock * In calculateAveragePastSubsidy, use blockWindow instead of doing a BFS manually. * Remove the reference to DAGTopologyManager in coinbaseManager. * Add subsidy to the coinbase payload. * Get rid of the subsidy store and extract subsidies out of coinbase transactions. * Keep a blockWindow amount of blocks under the virtual for IBD purposes. * Manually remove the virtual genesis from the merge set. * Fix simnet genesis. * Fix TestPruning. * Fix TestCheckBlockIsNotPruned. * Fix TestBlockWindow. * Fix TestCalculateSignatureHashSchnorr. * Fix TestCalculateSignatureHashECDSA. * Fix serializing the wrong value into the coinbase payload. * Rename coinbaseOutputForBlueBlock to coinbaseOutputAndSubsidyForBlueBlock. * Add a TODO about optimizing trusted data DAA window blocks. * Expand on a comment in TestCheckBlockIsNotPruned. * In calcBlockSubsidy, divide the big.Int numerator by the big.Int denominator instead of converting to float64. * Clarify a comment. * Rename SubsidyMinGenesisReward to MinSubsidy. * Properly handle trusted data blocks in calculateMergeSetSubsidySum. * Use the first two bytes of the selected parent's hash for randomness instead of math/rand. * Restore maxSompi to what it used to be. * Fix TestPruning. * Fix TestAmountCreation. * Fix TestBlockWindow. * Fix TestAmountUnitConversions. * Increase the timeout in many-tips to 30 minutes. * Check coinbase subsidy for every block * Re-rename functions * Use shift instead of powInt64 to determine subsidyRandom Co-authored-by: Ori Newman <orinewman1@gmail.com>
123 lines
4.0 KiB
Go
123 lines
4.0 KiB
Go
// Copyright (c) 2013, 2014 The btcsuite developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package util
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
|
"github.com/pkg/errors"
|
|
"math"
|
|
"strconv"
|
|
)
|
|
|
|
// AmountUnit describes a method of converting an Amount to something
|
|
// other than the base unit of a kaspa. The value of the AmountUnit
|
|
// is the exponent component of the decadic multiple to convert from
|
|
// an amount in kaspa to an amount counted in units.
|
|
type AmountUnit int
|
|
|
|
// These constants define various units used when describing a kaspa
|
|
// monetary amount.
|
|
const (
|
|
AmountMegaKAS AmountUnit = 6
|
|
AmountKiloKAS AmountUnit = 3
|
|
AmountKAS AmountUnit = 0
|
|
AmountMilliKAS AmountUnit = -3
|
|
AmountMicroKAS AmountUnit = -6
|
|
AmountSompi AmountUnit = -8
|
|
)
|
|
|
|
// String returns the unit as a string. For recognized units, the SI
|
|
// prefix is used, or "Sompi" for the base unit. For all unrecognized
|
|
// units, "1eN KAS" is returned, where N is the AmountUnit.
|
|
func (u AmountUnit) String() string {
|
|
switch u {
|
|
case AmountMegaKAS:
|
|
return "MKAS"
|
|
case AmountKiloKAS:
|
|
return "kKAS"
|
|
case AmountKAS:
|
|
return "KAS"
|
|
case AmountMilliKAS:
|
|
return "mKAS"
|
|
case AmountMicroKAS:
|
|
return "μKAS"
|
|
case AmountSompi:
|
|
return "Sompi"
|
|
default:
|
|
return "1e" + strconv.FormatInt(int64(u), 10) + " KAS"
|
|
}
|
|
}
|
|
|
|
// Amount represents the base kaspa monetary unit (colloquially referred
|
|
// to as a `Sompi'). A single Amount is equal to 1e-8 of a kaspa.
|
|
type Amount uint64
|
|
|
|
// round converts a floating point number, which may or may not be representable
|
|
// as an integer, to the Amount integer type by rounding to the nearest integer.
|
|
// This is performed by adding or subtracting 0.5 depending on the sign, and
|
|
// relying on integer truncation to round the value to the nearest Amount.
|
|
func round(f float64) Amount {
|
|
if f < 0 {
|
|
return Amount(f - 0.5)
|
|
}
|
|
return Amount(f + 0.5)
|
|
}
|
|
|
|
// NewAmount creates an Amount from a floating point value representing
|
|
// some value in kaspa. NewAmount errors if f is NaN or +-Infinity, but
|
|
// does not check that the amount is within the total amount of kaspa
|
|
// producible as f may not refer to an amount at a single moment in time.
|
|
//
|
|
// NewAmount is for specifically for converting KAS to Sompi.
|
|
// For creating a new Amount with an int64 value which denotes a quantity of Sompi,
|
|
// do a simple type conversion from type int64 to Amount.
|
|
func NewAmount(f float64) (Amount, error) {
|
|
// The amount is only considered invalid if it cannot be represented
|
|
// as an integer type. This may happen if f is NaN or +-Infinity.
|
|
switch {
|
|
case math.IsNaN(f):
|
|
fallthrough
|
|
case math.IsInf(f, 1):
|
|
fallthrough
|
|
case math.IsInf(f, -1):
|
|
return 0, errors.New("invalid kaspa amount")
|
|
}
|
|
|
|
return round(f * constants.SompiPerKaspa), nil
|
|
}
|
|
|
|
// ToUnit converts a monetary amount counted in kaspa base units to a
|
|
// floating point value representing an amount of kaspa.
|
|
func (a Amount) ToUnit(u AmountUnit) float64 {
|
|
return float64(a) / math.Pow10(int(u+8))
|
|
}
|
|
|
|
// ToKAS is the equivalent of calling ToUnit with AmountKAS.
|
|
func (a Amount) ToKAS() float64 {
|
|
return a.ToUnit(AmountKAS)
|
|
}
|
|
|
|
// Format formats a monetary amount counted in kaspa base units as a
|
|
// string for a given unit. The conversion will succeed for any unit,
|
|
// however, known units will be formated with an appended label describing
|
|
// the units with SI notation, or "Sompi" for the base unit.
|
|
func (a Amount) Format(u AmountUnit) string {
|
|
units := " " + u.String()
|
|
return strconv.FormatFloat(a.ToUnit(u), 'f', -int(u+8), 64) + units
|
|
}
|
|
|
|
// String is the equivalent of calling Format with AmountKAS.
|
|
func (a Amount) String() string {
|
|
return a.Format(AmountKAS)
|
|
}
|
|
|
|
// MulF64 multiplies an Amount by a floating point value. While this is not
|
|
// an operation that must typically be done by a full node or wallet, it is
|
|
// useful for services that build on top of kaspa (for example, calculating
|
|
// a fee by multiplying by a percentage).
|
|
func (a Amount) MulF64(f float64) Amount {
|
|
return round(float64(a) * f)
|
|
}
|