The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
woop/staking/reward/values.go

156 lines
6.2 KiB

package reward
import (
"fmt"
"math/big"
"github.com/harmony-one/harmony/common/denominations"
"github.com/harmony-one/harmony/consensus/engine"
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard"
)
var (
// PreStakedBlocks is the block reward, to be split evenly among block signers in pre-staking era.
// 24 ONE per block
PreStakedBlocks = new(big.Int).Mul(big.NewInt(24), big.NewInt(denominations.One))
// StakedBlocks is the flat-rate block reward for epos staking launch.
// 28 ONE per block.
StakedBlocks = numeric.NewDecFromBigInt(new(big.Int).Mul(
big.NewInt(28), big.NewInt(denominations.One),
))
// FiveSecStakedBlocks is the flat-rate block reward after epoch 230.
// 17.5 ONE per block
FiveSecStakedBlocks = numeric.NewDecFromBigInt(new(big.Int).Mul(
big.NewInt(17.5*denominations.Nano), big.NewInt(denominations.Nano),
))
// TwoSecStakedBlocks is the flat-rate block reward after epoch 360.
// 7 ONE per block
TwoSecStakedBlocks = numeric.NewDecFromBigInt(new(big.Int).Mul(
big.NewInt(7*denominations.Nano), big.NewInt(denominations.Nano),
))
// TotalInitialTokens is the total amount of tokens (in ONE) at block 0 of the network.
// This should be set/change on the node's init according to the core.GenesisSpec.
TotalInitialTokens = numeric.Dec{Int: big.NewInt(0)}
// None ..
None = big.NewInt(0)
// ErrInvalidBeaconChain if given chain is not beacon chain
ErrInvalidBeaconChain = fmt.Errorf("given chain is not beaconchain")
)
// getPreStakingRewardsFromBlockNumber returns the number of tokens injected into the network
// in the pre-staking era (epoch < staking epoch) in ATTO.
//
// If the block number is > than the last block of an epoch, the last block of the epoch is
// used for the calculation by default.
//
// WARNING: This assumes beacon chain is at most the same block height as another shard in the
// transition from pre-staking to staking era/epoch.
func getPreStakingRewardsFromBlockNumber(id shardingconfig.NetworkID, blockNum *big.Int) *big.Int {
if blockNum.Cmp(big.NewInt(2)) == -1 {
// block 0 & 1 does not contain block rewards
return big.NewInt(0)
}
lastBlockInEpoch := blockNum
switch id {
case shardingconfig.MainNet:
lastBlockInEpoch = new(big.Int).SetUint64(shardingconfig.MainnetSchedule.EpochLastBlock(
params.MainnetChainConfig.StakingEpoch.Uint64() - 1,
))
case shardingconfig.TestNet:
lastBlockInEpoch = new(big.Int).SetUint64(shardingconfig.TestnetSchedule.EpochLastBlock(
params.TestnetChainConfig.StakingEpoch.Uint64() - 1,
))
case shardingconfig.LocalNet:
lastBlockInEpoch = new(big.Int).SetUint64(shardingconfig.LocalnetSchedule.EpochLastBlock(
params.LocalnetChainConfig.StakingEpoch.Uint64() - 1,
))
}
if blockNum.Cmp(lastBlockInEpoch) == 1 {
blockNum = lastBlockInEpoch
}
return new(big.Int).Mul(PreStakedBlocks, new(big.Int).Sub(blockNum, big.NewInt(1)))
}
// WARNING: the data collected here are calculated from a consumer of the Rosetta API.
// If data becomes mission critical, implement a cross-link based approach.
//
// Data Source: https://github.com/harmony-one/jupyter
//
// TODO (dm): use first crosslink of all shards to compute rewards on network instead of relying on constants.
var (
totalPreStakingNetworkRewardsInAtto = map[shardingconfig.NetworkID][]*big.Int{
shardingconfig.MainNet: {
// Below are all of the last blocks of pre-staking era for mainnet.
getPreStakingRewardsFromBlockNumber(shardingconfig.MainNet, big.NewInt(3375103)),
getPreStakingRewardsFromBlockNumber(shardingconfig.MainNet, big.NewInt(3286737)),
getPreStakingRewardsFromBlockNumber(shardingconfig.MainNet, big.NewInt(3326153)),
getPreStakingRewardsFromBlockNumber(shardingconfig.MainNet, big.NewInt(3313572)),
},
shardingconfig.TestNet: {
// Below are all of the placeholders 'last blocks' of pre-staking era for testnet.
getPreStakingRewardsFromBlockNumber(shardingconfig.TestNet, big.NewInt(999999)),
getPreStakingRewardsFromBlockNumber(shardingconfig.TestNet, big.NewInt(999999)),
getPreStakingRewardsFromBlockNumber(shardingconfig.TestNet, big.NewInt(999999)),
getPreStakingRewardsFromBlockNumber(shardingconfig.TestNet, big.NewInt(999999)),
},
shardingconfig.LocalNet: {
// Below are all of the placeholders 'last blocks' of pre-staking era for localnet.
getPreStakingRewardsFromBlockNumber(shardingconfig.LocalNet, big.NewInt(999999)),
getPreStakingRewardsFromBlockNumber(shardingconfig.LocalNet, big.NewInt(999999)),
},
}
)
// getTotalPreStakingNetworkRewards in ATTO for given NetworkID
func getTotalPreStakingNetworkRewards(id shardingconfig.NetworkID) *big.Int {
totalRewards := big.NewInt(0)
if allRewards, ok := totalPreStakingNetworkRewardsInAtto[id]; ok {
for _, reward := range allRewards {
totalRewards = new(big.Int).Add(reward, totalRewards)
}
}
return totalRewards
}
// GetTotalTokens in the network for all shards in ONE.
// This can only be computed with beaconchain if in staking era.
// If not in staking era, returns the rewards given out by the start of staking era.
func GetTotalTokens(chain engine.ChainReader) (numeric.Dec, error) {
currHeader := chain.CurrentHeader()
if !chain.Config().IsStaking(currHeader.Epoch()) {
return GetTotalPreStakingTokens(), nil
}
if chain.ShardID() != shard.BeaconChainShardID {
return numeric.Dec{}, ErrInvalidBeaconChain
}
stakingRewards, err := chain.ReadBlockRewardAccumulator(currHeader.Number().Uint64())
if err != nil {
return numeric.Dec{}, err
}
return GetTotalPreStakingTokens().Add(numeric.NewDecFromBigIntWithPrec(stakingRewards, 18)), nil
}
// GetTotalPreStakingTokens returns the total amount of tokens (in ONE) in the
// network at the the last block of the pre-staking era (epoch < staking epoch).
func GetTotalPreStakingTokens() numeric.Dec {
preStakingRewards := numeric.NewDecFromBigIntWithPrec(
getTotalPreStakingNetworkRewards(shard.Schedule.GetNetworkID()), 18,
)
return TotalInitialTokens.Add(preStakingRewards)
}
// SetTotalInitialTokens with the given initial tokens (from genesis in ATTO).
func SetTotalInitialTokens(initTokensAsAtto *big.Int) {
TotalInitialTokens = numeric.NewDecFromBigIntWithPrec(initTokensAsAtto, 18)
}