Documentation ¶
Overview ¶
Package reward implements the Kaia Reward System. The Kaia reward system manages stakingInfo and distributes block rewards.
Managing stakingInfo ¶
Kaia uses WeightedRandom policy to choose a block proposer. It means, the percentage of becoming a block proposer depends on how much KAIA a node has staked. Therefore, a node with stakes more than others will have more opportunities than other nodes.
StakingInfo is a data including stakingAmount and addresses (node, staking, reward, KIF and KEF). StakingAmount is a balance how much KAIA each node has staked. Only CCO can stake KAIA. Each CCO stakes KAIA by a smart contract called staking contract. StakingAmount is derived by checking balance of staking contract. StakingInfo has 5 types of addresses. All addresses are obtained by the addressBookContract which is pre-deployed in the genesis block. stakingAddress are addresses of staking contracts of CCO. reward, KIF and KEF addresses are the addresses which get a block reward when a block has been created. StakingInfo is made every 86400 blocks (stakingInterval) and used in a next interval.
type StakingInfo struct { BlockNum uint64 CouncilNodeAddrs []common.Address // Address of Council CouncilStakingAddrs []common.Address // Address of Staking contract which holds staking balance CouncilRewardAddrs []common.Address // Address of Council account which will get a block reward KEFAddr common.Address // Address of KEF contract KIFAddr common.Address // Address of KIF contract UseGini bool // configure whether Gini is used or not Gini float64 // Gini coefficient CouncilStakingAmounts []uint64 // StakingAmounts of Council. They are derived from Staking addresses of council }
StakingInfo is managed by a StakingManager which has a cache for saving StakingInfos. The StakingManager calculates block number with interval to find a stakingInfo for current block and returns correct stakingInfo to use.
related struct - RewardDistributor - StakingManager - addressBookConnector - stakingInfoCache - stakingInfo
Distributing Reward ¶
Kaia distributes the reward of a block to proposer, KIF and KEF. The detail information of KIF and KEF is available on Kaia docs.
Token Economy - https://docs.kaia.io/docs/learn/token-economy/
Configurations related to the reward system such as mintingAmount, ratio and unitPrice are determined by the Kaia governance. All configurations are saved as rewardConfig on every epoch block (default 604,800 blocks) and managed by a rewardConfigCache.
A proposer which has made a current block will get the reward of the block. A block reward is calculated by following steps. First, calculate totalReward by adding mintingAmount and totalTxFee (unitPrice * gasUsed). Second, divide totalReward by ratio (default 34/54/12 - proposer/KIF/KEF). Last, distribute reward to each address (proposer, KIF, KEF).
related struct - RewardDistributor - rewardConfigCache
Index ¶
- Constants
- Variables
- func AddStakingInfoToDB(stakingInfo *StakingInfo) error
- func AddTestStakingInfoToCache(testInfo *StakingInfo)
- func CalcGiniCoefficient(stakingAmount float64Slice) float64
- func CalcRewardParamBlock(num, epoch uint64, rules params.Rules) uint64
- func DistributeBlockReward(b BalanceAdder, rewards map[common.Address]*big.Int)
- func GetTotalTxFee(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, ...) *big.Int
- func HasStakingInfoFromDB(blockNumber uint64) (bool, error)
- func IsRewardSimple(pset *params.GovParamSet) bool
- func NewRewardConfig(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, ...) (*rewardConfig, error)
- func NewSupplyManager(chain blockChain, gov governanceHelper, db database.DBManager) *supplyManager
- func PreloadStakingInfo(headers []*types.Header) ([]uint64, error)
- func PreloadStakingInfoWithState(header *types.Header, statedb *state.StateDB) error
- func PurgeStakingInfoCache()
- func SetTestAddressBookAddress(addr common.Address)
- func SetTestStakingManager(sm *StakingManager)
- func SetTestStakingManagerWithChain(bc blockChain, gh governanceHelper, db stakingInfoDB)
- func SetTestStakingManagerWithDB(testDB stakingInfoDB)
- func SetTestStakingManagerWithStakingInfoCache(testInfo *StakingInfo)
- func StakingManagerSubscribe()
- func StakingManagerUnsubscribe()
- func TestGetStakingCacheSize() int
- func TestGetStakingPreloadSize() int
- func UnloadStakingInfo(num uint64)
- type BalanceAdder
- type ConsolidatedStakingInfo
- func (c *ConsolidatedStakingInfo) CalcGiniCoefficientMinStake(minStake uint64) float64
- func (c *ConsolidatedStakingInfo) GetAllNodes() []consolidatedNode
- func (c *ConsolidatedStakingInfo) GetConsolidatedNode(nodeAddr common.Address) *consolidatedNode
- func (c *ConsolidatedStakingInfo) String() string
- type RewardDistributor
- type RewardSpec
- func CalcDeferredReward(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, ...) (*RewardSpec, error)
- func CalcDeferredRewardSimple(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, ...) (*RewardSpec, error)
- func GetBlockReward(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, ...) (*RewardSpec, error)
- func NewRewardSpec() *RewardSpec
- type StakingInfo
- func (s *StakingInfo) DecodeRLP(st *rlp.Stream) error
- func (s *StakingInfo) EncodeRLP(w io.Writer) error
- func (s *StakingInfo) GetConsolidatedStakingInfo() *ConsolidatedStakingInfo
- func (s *StakingInfo) GetIndexByNodeAddress(nodeAddress common.Address) (int, error)
- func (s *StakingInfo) GetStakingAmountByNodeId(nodeAddress common.Address) (uint64, error)
- func (st StakingInfo) MarshalJSON() ([]byte, error)
- func (s *StakingInfo) String() string
- func (st *StakingInfo) UnmarshalJSON(input []byte) error
- type StakingManager
- type SupplyManager
- type TotalReward
- type TotalSupply
Constants ¶
const ( AddrNotFoundInCouncilNodes = -1 DefaultGiniCoefficient = -1.0 )
Variables ¶
var ( // errors for staking manager ErrStakingManagerNotSet = errors.New("staking manager is not set") ErrChainHeadChanNotSet = errors.New("chain head channel is not set") )
var CalcDeferredRewardTimer time.Duration
var (
ErrAddrNotInStakingInfo = errors.New("Address is not in stakingInfo")
)
var ErrStakingDBNotSet = errors.New("stakingInfoDB is not set")
Functions ¶
func AddStakingInfoToDB ¶
func AddStakingInfoToDB(stakingInfo *StakingInfo) error
func AddTestStakingInfoToCache ¶
func AddTestStakingInfoToCache(testInfo *StakingInfo)
AddTestStakingInfoToCache adds the given test staking information to the cache. Note that it won't overwrite the existing cache.
func CalcGiniCoefficient ¶
func CalcGiniCoefficient(stakingAmount float64Slice) float64
func CalcRewardParamBlock ¶
CalcRewardParamBlock returns the block number with which governance parameters must be fetched This mimics the legacy reward config cache before Kore
func DistributeBlockReward ¶
func DistributeBlockReward(b BalanceAdder, rewards map[common.Address]*big.Int)
DistributeBlockReward distributes a given block's reward at the end of block processing
func GetTotalTxFee ¶
func HasStakingInfoFromDB ¶
HasStakingInfoFromDB returns existence of staking information from miscdb.
func IsRewardSimple ¶
func IsRewardSimple(pset *params.GovParamSet) bool
config.Istanbul must have been set
func NewRewardConfig ¶
func NewSupplyManager ¶
NewSupplyManager creates a new supply manager. The TotalSupply data is stored every checkpointInterval blocks.
func PreloadStakingInfo ¶
PreloadStakingInfo preloads staking info for the given headers. It first finds the first block that does not have state, and then it regenerates the state from the nearest block that has state to the target block to preload staking info. Note that the state is saved every 128 blocks to disk in full node.
func PreloadStakingInfoWithState ¶
PreloadStakingInfoWithState fetches the stakingInfo based on the given state trie and then stores it in the preloaded map. Because preloaded map does not have eviction policy, it should be removed manually after use. Note that preloaded info is for the next block of the given header.
func PurgeStakingInfoCache ¶
func PurgeStakingInfoCache()
func SetTestAddressBookAddress ¶
SetTestAddressBookAddress is only for testing purpose.
func SetTestStakingManager ¶
func SetTestStakingManager(sm *StakingManager)
SetTestStakingManager sets the staking manager for testing purpose. Note that this method is used only for testing purpose.
func SetTestStakingManagerWithChain ¶
func SetTestStakingManagerWithChain(bc blockChain, gh governanceHelper, db stakingInfoDB)
SetTestStakingManagerWithChain sets a full-featured staking manager with blockchain, database and cache. Note that this method is used only for testing purpose.
func SetTestStakingManagerWithDB ¶
func SetTestStakingManagerWithDB(testDB stakingInfoDB)
SetTestStakingManagerWithDB sets the staking manager with the given database. Note that this method is used only for testing purpose.
func SetTestStakingManagerWithStakingInfoCache ¶
func SetTestStakingManagerWithStakingInfoCache(testInfo *StakingInfo)
SetTestStakingManagerWithStakingInfoCache sets the staking manager with the given test staking information. Note that this method is used only for testing purpose.
func StakingManagerSubscribe ¶
func StakingManagerSubscribe()
StakingManagerSubscribe setups a channel to listen chain head event and starts a goroutine to update staking cache.
func StakingManagerUnsubscribe ¶
func StakingManagerUnsubscribe()
StakingManagerUnsubscribe can unsubscribe a subscription on chain head event.
func TestGetStakingCacheSize ¶
func TestGetStakingCacheSize() int
func TestGetStakingPreloadSize ¶
func TestGetStakingPreloadSize() int
func UnloadStakingInfo ¶
func UnloadStakingInfo(num uint64)
UnloadStakingInfo removes a stakingInfo from the preloaded map. Must be executed after PreloadStakingInfoWithState(Header{num}, state).
Types ¶
type ConsolidatedStakingInfo ¶
type ConsolidatedStakingInfo struct {
// contains filtered or unexported fields
}
func (*ConsolidatedStakingInfo) CalcGiniCoefficientMinStake ¶
func (c *ConsolidatedStakingInfo) CalcGiniCoefficientMinStake(minStake uint64) float64
Calculate Gini coefficient of the StakingAmounts. Only amounts greater or equal to `minStake` are included in the calculation. Set `minStake` to 0 to calculate Gini coefficient of all amounts.
func (*ConsolidatedStakingInfo) GetAllNodes ¶
func (c *ConsolidatedStakingInfo) GetAllNodes() []consolidatedNode
func (*ConsolidatedStakingInfo) GetConsolidatedNode ¶
func (c *ConsolidatedStakingInfo) GetConsolidatedNode(nodeAddr common.Address) *consolidatedNode
func (*ConsolidatedStakingInfo) String ¶
func (c *ConsolidatedStakingInfo) String() string
type RewardDistributor ¶
type RewardDistributor struct{}
TODO: this is for legacy, will be removed
func NewRewardDistributor ¶
func NewRewardDistributor(gh governanceHelper) *RewardDistributor
type RewardSpec ¶
type RewardSpec struct { Minted *big.Int `json:"minted"` // the amount newly minted TotalFee *big.Int `json:"totalFee"` // total tx fee spent BurntFee *big.Int `json:"burntFee"` // the amount burnt Proposer *big.Int `json:"proposer"` // the amount allocated to the block proposer Stakers *big.Int `json:"stakers"` // total amount allocated to stakers KIF *big.Int `json:"kif"` // the amount allocated to KIF KEF *big.Int `json:"kef"` // the amount allocated to KEF Rewards map[common.Address]*big.Int `json:"rewards"` // mapping from reward recipient to amounts }
Used in block reward distribution and klay_getReward RPC API
func CalcDeferredReward ¶
func CalcDeferredReward(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, rules params.Rules, pset *params.GovParamSet) (*RewardSpec, error)
CalcDeferredReward calculates the deferred rewards, which are determined at the end of block processing.
func CalcDeferredRewardSimple ¶
func CalcDeferredRewardSimple(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, rules params.Rules, pset *params.GovParamSet) (*RewardSpec, error)
CalcDeferredRewardSimple distributes rewards to proposer after optional fee burning this behaves similar to the previous MintKAIA MintKAIA has been superseded because we need to split reward distribution logic into (1) calculation, and (2) actual distribution. CalcDeferredRewardSimple does the former and DistributeBlockReward does the latter
func GetBlockReward ¶
func GetBlockReward(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, rules params.Rules, pset *params.GovParamSet) (*RewardSpec, error)
GetBlockReward returns the actual reward amounts paid in this block Used in kaia_getReward RPC API
func NewRewardSpec ¶
func NewRewardSpec() *RewardSpec
func (*RewardSpec) Add ¶
func (spec *RewardSpec) Add(delta *RewardSpec)
type StakingInfo ¶
type StakingInfo struct { BlockNum uint64 `json:"blockNum"` // Block number where staking information of Council is fetched // Information retrieved from AddressBook smart contract CouncilNodeAddrs []common.Address `json:"councilNodeAddrs"` // NodeIds of Council CouncilStakingAddrs []common.Address `json:"councilStakingAddrs"` // Address of Staking account which holds staking balance CouncilRewardAddrs []common.Address `json:"councilRewardAddrs"` // Address of Council account which will get block reward KEFAddr common.Address `json:"kefAddr"` // Address of KEF contract KIFAddr common.Address `json:"kifAddr"` // Address of KIF contract UseGini bool `json:"useGini"` Gini float64 `json:"gini"` // gini coefficient // Derived from CouncilStakingAddrs CouncilStakingAmounts []uint64 `json:"councilStakingAmounts"` // Staking amounts of Council }
StakingInfo contains staking information.
func GetStakingInfo ¶
func GetStakingInfo(blockNum uint64) *StakingInfo
GetStakingInfo returns a stakingInfo on the staking block of the given block number. Note that staking block is the block on which the associated staking information is stored and used during an interval. - Before kaia fork: staking block is calculated by params.CalcStakingBlockNumber(blockNum) - After kaia fork: staking block is the previous block of the given block number.
func GetStakingInfoForKaiaBlock ¶
func GetStakingInfoForKaiaBlock(blockNum uint64) *StakingInfo
GetStakingInfoForKaiaBlock returns a corresponding kaia StakingInfo for a given block number. Note that the given block number is a kaia staking info for the next block.
func GetStakingInfoOnStakingBlock ¶
func GetStakingInfoOnStakingBlock(stakingBlockNumber uint64) *StakingInfo
GetStakingInfoOnStakingBlock returns a corresponding StakingInfo for a staking block number. If the given number is not on the staking block, it returns nil.
Fixup for Gini coefficients: Kaia core stores Gini: -1 in its database. We ensure GetStakingInfoOnStakingBlock() to always return meaningful Gini. - If cache hit -> fillMissingGini -> modifies cached in-memory object - If db hit -> fillMissingGini -> write to cache - If read contract -> write to db (gini: -1) -> fillMissingGini -> write to cache
func (*StakingInfo) GetConsolidatedStakingInfo ¶
func (s *StakingInfo) GetConsolidatedStakingInfo() *ConsolidatedStakingInfo
func (*StakingInfo) GetIndexByNodeAddress ¶
func (s *StakingInfo) GetIndexByNodeAddress(nodeAddress common.Address) (int, error)
func (*StakingInfo) GetStakingAmountByNodeId ¶
func (s *StakingInfo) GetStakingAmountByNodeId(nodeAddress common.Address) (uint64, error)
func (StakingInfo) MarshalJSON ¶
func (st StakingInfo) MarshalJSON() ([]byte, error)
MarshalJSON supports json marshalling for both oldStakingInfo and StakingInfo TODO-Kaia-Mantle: remove this marshal function when backward-compatibility for KIR/PoC, KCF/KFF is not needed
func (*StakingInfo) String ¶
func (s *StakingInfo) String() string
func (*StakingInfo) UnmarshalJSON ¶
func (st *StakingInfo) UnmarshalJSON(input []byte) error
UnmarshalJSON supports json unmarshalling for both oldStakingInfo and StakingInfo
type StakingManager ¶
type StakingManager struct {
// contains filtered or unexported fields
}
func GetStakingManager ¶
func GetStakingManager() *StakingManager
func NewStakingManager ¶
func NewStakingManager(bc blockChain, gh governanceHelper, db stakingInfoDB) *StakingManager
NewStakingManager creates and returns StakingManager.
On the first call, a StakingManager is created with given parameters. From next calls, the existing StakingManager is returned. (Parameters from the next calls will not affect.)
type SupplyManager ¶
type SupplyManager interface { // Start starts the supply manager goroutine that catches up or tracks the block rewards. Start() // Stop stops the supply manager goroutine. Stop() // GetTotalSupply returns the total supply amounts at the given block number, // broken down by minted amount and burnt amounts of each methods. GetTotalSupply(num uint64) (*TotalSupply, error) }
SupplyManager tracks the total supply of native tokens. Note that SupplyManager only deals with the block rewards. Factors like KIP103, KIP160, 0xdead burning are not considered and must be accounted in the APIs that return the total supply.
type TotalReward ¶
Used in klay_totalSupply RPC API A minified version of RewardSpec that contains the total amount only.
func GetTotalReward ¶
func GetTotalReward(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt, rules params.Rules, pset *params.GovParamSet) (*TotalReward, error)
GetTotalReward returns the total rewards in this block, i.e. (minted - burntFee) Used in klay_totalSupply RPC API
type TotalSupply ¶
type TotalSupply struct { TotalSupply *big.Int // The total supply of the native token. i.e. Minted - Burnt. TotalMinted *big.Int // Total minted amount. TotalBurnt *big.Int // Total burnt amount. Sum of all burnt amounts below. BurntFee *big.Int // from tx fee burn. ZeroBurn *big.Int // balance of 0x0 (zero) address. DeadBurn *big.Int // balance of 0xdead (dead) address. Kip103Burn *big.Int // by KIP103 fork. Read from its memo. Kip160Burn *big.Int // by KIP160 fork. Read from its memo. }