mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
- compare both hash and block num from reward filename to blockchain state
- complete error handling
This commit is contained in:
parent
4fc208b527
commit
8ca51b6ee4
1 changed files with 64 additions and 29 deletions
|
|
@ -98,6 +98,7 @@ type TotalRewards struct {
|
|||
TotalAccountReward *big.Int
|
||||
TotalDelegatedReward map[string]*big.Int
|
||||
}
|
||||
|
||||
type AccountRewardResponse struct {
|
||||
EpochRewards []AccountEpochReward
|
||||
Total TotalRewards
|
||||
|
|
@ -105,6 +106,11 @@ type AccountRewardResponse struct {
|
|||
|
||||
type AccountRewardStatus string
|
||||
|
||||
type rewardFileName struct {
|
||||
epochBlockNum int
|
||||
epochBlockHash common.Hash
|
||||
}
|
||||
|
||||
const (
|
||||
statusMasternode AccountRewardStatus = "MasterNode"
|
||||
statusProtectornode AccountRewardStatus = "ProtectorNode"
|
||||
|
|
@ -351,16 +357,21 @@ func calculateSigners(message map[string]SignerTypes, pool map[string]map[common
|
|||
}
|
||||
|
||||
func (api *API) GetRewardByAccount(account common.Address, begin rpc.BlockNumber, end rpc.BlockNumber) (AccountRewardResponse, error) {
|
||||
epochBlocks, err := api.getEpochNumbersFromRewardFiles(&begin, &end)
|
||||
rewardFileNames, err := api.getRewardFileNamesInRange(&begin, &end)
|
||||
if err != nil {
|
||||
return AccountRewardResponse{}, err
|
||||
}
|
||||
|
||||
epochRewards := []AccountEpochReward{}
|
||||
for _, epochBlock := range epochBlocks {
|
||||
header := api.chain.GetHeaderByNumber(epochBlock)
|
||||
for _, fileName := range rewardFileNames {
|
||||
header := api.chain.GetHeaderByHash(fileName.epochBlockHash)
|
||||
if header == nil {
|
||||
log.Error("[GetRewardByAccount] header not found, impossible case, please check your RPC", "err", err)
|
||||
return AccountRewardResponse{}, err
|
||||
// this is the case when there is chain rollback but the reward files of the old chain still remain, skip the reward of unknown blockhash
|
||||
continue
|
||||
}
|
||||
if int(header.Number.Int64()) != fileName.epochBlockNum {
|
||||
log.Error("[GetRewardByAccount] block number mismatch in reward filename", "reward file blocknum", fileName.epochBlockNum, "header blocknum", int(header.Number.Int64()), "blockhash", header.Hash())
|
||||
return AccountRewardResponse{}, errors.New("reward file block number mismatch")
|
||||
}
|
||||
epochReward, err := getEpochReward(account, header)
|
||||
if err != nil {
|
||||
|
|
@ -396,7 +407,7 @@ func (api *API) GetRewardByAccount(account common.Address, begin rpc.BlockNumber
|
|||
return response, nil
|
||||
}
|
||||
|
||||
func (api *API) getEpochNumbersFromRewardFiles(begin, end *rpc.BlockNumber) ([]uint64, error) {
|
||||
func (api *API) getRewardFileNamesInRange(begin, end *rpc.BlockNumber) ([]rewardFileName, error) {
|
||||
beginHeader := api.getHeaderFromApiBlockNum(begin)
|
||||
if beginHeader == nil {
|
||||
return nil, errors.New("illegal begin block number")
|
||||
|
|
@ -420,31 +431,43 @@ func (api *API) getEpochNumbersFromRewardFiles(begin, end *rpc.BlockNumber) ([]u
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var epochNumbers []int
|
||||
var rewardFileNames = []rewardFileName{}
|
||||
for _, file := range files {
|
||||
if !file.IsDir() {
|
||||
filePrefix, _, found := strings.Cut(file.Name(), ".")
|
||||
filePrefix, fileSuffix, found := strings.Cut(file.Name(), ".")
|
||||
if found {
|
||||
filePrefixInt, err := strconv.Atoi(filePrefix)
|
||||
if err != nil {
|
||||
log.Warn("[getEpochNumbersFromRewardFiles] found unknown filename format in rewards folder")
|
||||
return nil, err
|
||||
}
|
||||
epochNumbers = append(epochNumbers, filePrefixInt)
|
||||
fileSuffixHash := common.StringToHash(fileSuffix)
|
||||
rewardName := rewardFileName{
|
||||
epochBlockNum: filePrefixInt,
|
||||
epochBlockHash: fileSuffixHash,
|
||||
}
|
||||
rewardFileNames = append(rewardFileNames, rewardName)
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Ints(epochNumbers)
|
||||
|
||||
sort.Slice(rewardFileNames, func(i, j int) bool {
|
||||
return rewardFileNames[i].epochBlockNum < rewardFileNames[j].epochBlockNum
|
||||
})
|
||||
|
||||
epochNumbers := make([]int, len(rewardFileNames))
|
||||
for i, obj := range rewardFileNames {
|
||||
epochNumbers[i] = obj.epochBlockNum
|
||||
}
|
||||
|
||||
startIndex := sort.SearchInts(epochNumbers, int(beginHeader.Number.Int64()))
|
||||
endIndex := sort.SearchInts(epochNumbers, int(endHeader.Number.Int64()))
|
||||
|
||||
var epochNumbersInRange []uint64
|
||||
for i := startIndex; i <= endIndex; i++ {
|
||||
number := uint64(epochNumbers[i])
|
||||
epochNumbersInRange = append(epochNumbersInRange, number)
|
||||
var rewardfileNamesInRange []rewardFileName
|
||||
for i:= startIndex; i<= endIndex; i++{
|
||||
rewardfileNamesInRange = append(rewardfileNamesInRange, rewardFileNames[i])
|
||||
}
|
||||
|
||||
return epochNumbersInRange, nil
|
||||
return rewardfileNamesInRange, nil
|
||||
}
|
||||
|
||||
func getEpochReward(account common.Address, header *types.Header) (AccountEpochReward, error) {
|
||||
|
|
@ -467,7 +490,7 @@ func getEpochReward(account common.Address, header *types.Header) (AccountEpochR
|
|||
log.Warn("[getEpochReward] Failed to decode JSON:", "err", err)
|
||||
return AccountEpochReward{}, err
|
||||
}
|
||||
|
||||
|
||||
epochReward := AccountEpochReward{
|
||||
Address: account,
|
||||
EpochBlockNum: header.Number.Uint64(),
|
||||
|
|
@ -484,12 +507,16 @@ func (rewardObj *AccountEpochReward) getRewardAndStatus(account string, data map
|
|||
nodeReward := accountData.(map[string]interface{})["reward"]
|
||||
delegatedReward := data["rewards"].(map[string]interface{})[account]
|
||||
rewardObj.AccountStatus = statusMasternode
|
||||
nodeRewardBigInt, _ := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||
rewardObj.AccountReward = nodeRewardBigInt
|
||||
nodeRewardBigInt, ok := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||
if ok {
|
||||
rewardObj.AccountReward = nodeRewardBigInt
|
||||
}
|
||||
|
||||
for k, v := range delegatedReward.(map[string]interface{}) {
|
||||
delegatedBigInt, _ := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||
delegatedBigInt, ok := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||
if ok {
|
||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -500,12 +527,16 @@ func (rewardObj *AccountEpochReward) getRewardAndStatus(account string, data map
|
|||
nodeReward := accountData.(map[string]interface{})["reward"]
|
||||
delegatedReward := data["rewardsProtector"].(map[string]interface{})[account]
|
||||
rewardObj.AccountStatus = statusProtectornode
|
||||
nodeRewardBigInt, _ := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||
rewardObj.AccountReward = nodeRewardBigInt
|
||||
nodeRewardBigInt, successSetNodeReward := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||
if successSetNodeReward {
|
||||
rewardObj.AccountReward = nodeRewardBigInt
|
||||
}
|
||||
|
||||
for k, v := range delegatedReward.(map[string]interface{}) {
|
||||
delegatedBigInt, _ := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||
delegatedBigInt, successSetDelegatedReward := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||
if successSetDelegatedReward {
|
||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -517,12 +548,16 @@ func (rewardObj *AccountEpochReward) getRewardAndStatus(account string, data map
|
|||
nodeReward := accountData.(map[string]interface{})["reward"]
|
||||
delegatedReward := data["rewardsObserver"].(map[string]interface{})[account]
|
||||
rewardObj.AccountStatus = statusObservernode
|
||||
nodeRewardBigInt, _ := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||
rewardObj.AccountReward = nodeRewardBigInt
|
||||
nodeRewardBigInt, successSetNodeReward := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||
if successSetNodeReward {
|
||||
rewardObj.AccountReward = nodeRewardBigInt
|
||||
}
|
||||
|
||||
for k, v := range delegatedReward.(map[string]interface{}) {
|
||||
delegatedBigInt, _ := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||
delegatedBigInt, successSetDelegatedReward := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||
if successSetDelegatedReward {
|
||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue