mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
record total minted into smart contract (#1026)
* feat: record total minted into smart contract * feat: GetCurrentTotalMinted API
This commit is contained in:
parent
ae70b5dc14
commit
e13265a7d7
6 changed files with 84 additions and 0 deletions
|
|
@ -68,6 +68,7 @@ var (
|
|||
XDCXLendingFinalizedTradeAddressBinary = HexToAddress("0x0000000000000000000000000000000000000094")
|
||||
XDCNativeAddressBinary = HexToAddress("0x0000000000000000000000000000000000000001")
|
||||
LendingLockAddressBinary = HexToAddress("0x0000000000000000000000000000000000000011")
|
||||
MintedRecordAddressBinary = HexToAddress("0x000000000000000000000000000000000000009a")
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ func TestHookRewardAfterUpgrade(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
// set switch to 1800, so that it covers 901-1799, 1800-2700 two epochs
|
||||
config.XDPoS.V2.SwitchBlock.SetUint64(1800)
|
||||
config.XDPoS.V2.SwitchEpoch = 2
|
||||
// set upgrade number to 0
|
||||
backup := common.TIPUpgradeReward
|
||||
common.TIPUpgradeReward = big.NewInt(0)
|
||||
|
|
@ -296,6 +297,11 @@ func TestHookRewardAfterUpgrade(t *testing.T) {
|
|||
b, _ := big.NewInt(0).SetString("30012500000000000000", 10) // this value tests the float64 reward
|
||||
assert.Zero(t, b.Cmp(r[config.XDPoS.FoudationWalletAddr]), "real reward is", r[config.XDPoS.FoudationWalletAddr])
|
||||
}
|
||||
totalMinted := state.GetTotalMinted(statedb).Big()
|
||||
totalExpect, _ := big.NewInt(0).SetString("2100125000000000000000", 10)
|
||||
assert.Zero(t, totalMinted.Cmp(totalExpect), "statedb records wrong total minted")
|
||||
lastEpochNum := state.GetLastEpochNum(statedb).Big().Int64()
|
||||
assert.Equal(t, 3, int(lastEpochNum))
|
||||
common.TIPUpgradeReward = backup
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,3 +152,30 @@ func GetVoterCap(statedb *StateDB, candidate, voter common.Address) *big.Int {
|
|||
ret := statedb.GetState(common.MasternodeVotingSMCBinary, common.BytesToHash(retByte))
|
||||
return ret.Big()
|
||||
}
|
||||
|
||||
var (
|
||||
slotMintedRecordTotalMinted uint64 = 0
|
||||
slotMintedRecordLastEpochNum uint64 = 1
|
||||
)
|
||||
|
||||
func GetTotalMinted(statedb *StateDB) common.Hash {
|
||||
hash := GetLocSimpleVariable(slotMintedRecordTotalMinted)
|
||||
totalMinted := statedb.GetState(common.MintedRecordAddressBinary, hash)
|
||||
return totalMinted
|
||||
}
|
||||
|
||||
func PutTotalMinted(statedb *StateDB, value common.Hash) {
|
||||
hash := GetLocSimpleVariable(slotMintedRecordTotalMinted)
|
||||
statedb.SetState(common.MintedRecordAddressBinary, hash, value)
|
||||
}
|
||||
|
||||
func GetLastEpochNum(statedb *StateDB) common.Hash {
|
||||
hash := GetLocSimpleVariable(slotMintedRecordLastEpochNum)
|
||||
totalMinted := statedb.GetState(common.MintedRecordAddressBinary, hash)
|
||||
return totalMinted
|
||||
}
|
||||
|
||||
func PutLastEpochNum(statedb *StateDB, value common.Hash) {
|
||||
hash := GetLocSimpleVariable(slotMintedRecordLastEpochNum)
|
||||
statedb.SetState(common.MintedRecordAddressBinary, hash, value)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
|||
start := time.Now()
|
||||
|
||||
round, err := adaptor.EngineV2.GetRoundNumber(header)
|
||||
epochNum := chain.Config().XDPoS.V2.SwitchEpoch + uint64(round)/chain.Config().XDPoS.Epoch
|
||||
if err != nil {
|
||||
log.Error("[HookReward] Fail to get round", "error", err)
|
||||
return nil, err
|
||||
|
|
@ -233,6 +234,7 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
|||
} else {
|
||||
rewardsMap["signersProtector"] = signers[ProtectorNodeBeneficiary]
|
||||
rewardsMap["signersObserver"] = signers[ObserverNodeBeneficiary]
|
||||
rewardSum := new(big.Int)
|
||||
type rewardWithType struct {
|
||||
r float64
|
||||
t Beneficiary
|
||||
|
|
@ -262,12 +264,32 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
|||
if len(rewards) > 0 {
|
||||
for holder, reward := range rewards {
|
||||
stateBlock.AddBalance(holder, reward)
|
||||
rewardSum.Add(rewardSum, reward)
|
||||
}
|
||||
}
|
||||
rewardResults[signer] = rewards
|
||||
}
|
||||
rewardsMap[rwt.key] = rewardResults
|
||||
}
|
||||
// record the total reward into state db
|
||||
totalMinted := state.GetTotalMinted(stateBlock).Big()
|
||||
lastEpochNum := state.GetLastEpochNum(stateBlock)
|
||||
if lastEpochNum.IsZero() {
|
||||
// if `lastEpochNum` is zero, the total minted has not included tokens before TIPUpgradeReward
|
||||
// calculate the tokens before TIPUpgradeReward and set to totalMinted
|
||||
// for now no-do
|
||||
}
|
||||
totalMinted.Add(totalMinted, rewardSum)
|
||||
bigPower256 := new(big.Int).Lsh(big.NewInt(1), 256)
|
||||
bigMaxU256 := new(big.Int).Sub(bigPower256, big.NewInt(1))
|
||||
// if overflow, set to maxU256 and log a warning
|
||||
if totalMinted.Cmp(bigMaxU256) >= 0 {
|
||||
totalMinted.Set(bigMaxU256)
|
||||
log.Warn("[HookReward] total minted overflow max u256")
|
||||
}
|
||||
log.Debug("[HookReward] total minted in hook", "value", totalMinted)
|
||||
state.PutTotalMinted(stateBlock, common.BigToHash(totalMinted))
|
||||
state.PutLastEpochNum(stateBlock, common.Uint64ToHash(epochNum))
|
||||
}
|
||||
log.Debug("Time Calculated HookReward ", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start)))
|
||||
return rewardsMap, nil
|
||||
|
|
|
|||
|
|
@ -3639,3 +3639,26 @@ func (s *PublicBlockChainAPI) GetStakerROIMasternode(masternode common.Address)
|
|||
|
||||
return 100.0 / float64(totalCap.Div(totalCap, voterRewardAYear).Uint64())
|
||||
}
|
||||
|
||||
type currentTotalMinted struct {
|
||||
TotalMinted *hexutil.Big `json:"totalMinted"`
|
||||
LastEpochNum *hexutil.Big `json:"lastEpochNum"`
|
||||
BlockHash common.Hash `json:"blockHash"`
|
||||
BlockNumber *hexutil.Big `json:"blockNumber"`
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) GetCurrentTotalMinted(ctx context.Context) (*currentTotalMinted, error) {
|
||||
statedb, header, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
totalMinted := state.GetTotalMinted(statedb).Big()
|
||||
lastEpochNum := state.GetLastEpochNum(statedb).Big()
|
||||
result := ¤tTotalMinted{
|
||||
TotalMinted: (*hexutil.Big)(totalMinted),
|
||||
LastEpochNum: (*hexutil.Big)(lastEpochNum),
|
||||
BlockHash: header.Hash(),
|
||||
BlockNumber: (*hexutil.Big)(header.Number),
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,6 +555,11 @@ web3._extend({
|
|||
call: 'eth_getBlockReceipts',
|
||||
params: 1,
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'getCurrentTotalMinted',
|
||||
call: 'eth_getCurrentTotalMinted',
|
||||
params: 0,
|
||||
}),
|
||||
],
|
||||
properties: [
|
||||
new web3._extend.Property({
|
||||
|
|
|
|||
Loading…
Reference in a new issue