mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +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
|
TotalAccountReward *big.Int
|
||||||
TotalDelegatedReward map[string]*big.Int
|
TotalDelegatedReward map[string]*big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccountRewardResponse struct {
|
type AccountRewardResponse struct {
|
||||||
EpochRewards []AccountEpochReward
|
EpochRewards []AccountEpochReward
|
||||||
Total TotalRewards
|
Total TotalRewards
|
||||||
|
|
@ -105,6 +106,11 @@ type AccountRewardResponse struct {
|
||||||
|
|
||||||
type AccountRewardStatus string
|
type AccountRewardStatus string
|
||||||
|
|
||||||
|
type rewardFileName struct {
|
||||||
|
epochBlockNum int
|
||||||
|
epochBlockHash common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
statusMasternode AccountRewardStatus = "MasterNode"
|
statusMasternode AccountRewardStatus = "MasterNode"
|
||||||
statusProtectornode AccountRewardStatus = "ProtectorNode"
|
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) {
|
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 {
|
if err != nil {
|
||||||
return AccountRewardResponse{}, err
|
return AccountRewardResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
epochRewards := []AccountEpochReward{}
|
epochRewards := []AccountEpochReward{}
|
||||||
for _, epochBlock := range epochBlocks {
|
for _, fileName := range rewardFileNames {
|
||||||
header := api.chain.GetHeaderByNumber(epochBlock)
|
header := api.chain.GetHeaderByHash(fileName.epochBlockHash)
|
||||||
if header == nil {
|
if header == nil {
|
||||||
log.Error("[GetRewardByAccount] header not found, impossible case, please check your RPC", "err", 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
|
||||||
return AccountRewardResponse{}, err
|
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)
|
epochReward, err := getEpochReward(account, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -396,7 +407,7 @@ func (api *API) GetRewardByAccount(account common.Address, begin rpc.BlockNumber
|
||||||
return response, nil
|
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)
|
beginHeader := api.getHeaderFromApiBlockNum(begin)
|
||||||
if beginHeader == nil {
|
if beginHeader == nil {
|
||||||
return nil, errors.New("illegal begin block number")
|
return nil, errors.New("illegal begin block number")
|
||||||
|
|
@ -420,31 +431,43 @@ func (api *API) getEpochNumbersFromRewardFiles(begin, end *rpc.BlockNumber) ([]u
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var epochNumbers []int
|
var rewardFileNames = []rewardFileName{}
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
if !file.IsDir() {
|
if !file.IsDir() {
|
||||||
filePrefix, _, found := strings.Cut(file.Name(), ".")
|
filePrefix, fileSuffix, found := strings.Cut(file.Name(), ".")
|
||||||
if found {
|
if found {
|
||||||
filePrefixInt, err := strconv.Atoi(filePrefix)
|
filePrefixInt, err := strconv.Atoi(filePrefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("[getEpochNumbersFromRewardFiles] found unknown filename format in rewards folder")
|
log.Warn("[getEpochNumbersFromRewardFiles] found unknown filename format in rewards folder")
|
||||||
return nil, err
|
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()))
|
startIndex := sort.SearchInts(epochNumbers, int(beginHeader.Number.Int64()))
|
||||||
endIndex := sort.SearchInts(epochNumbers, int(endHeader.Number.Int64()))
|
endIndex := sort.SearchInts(epochNumbers, int(endHeader.Number.Int64()))
|
||||||
|
|
||||||
var epochNumbersInRange []uint64
|
var rewardfileNamesInRange []rewardFileName
|
||||||
for i := startIndex; i <= endIndex; i++ {
|
for i:= startIndex; i<= endIndex; i++{
|
||||||
number := uint64(epochNumbers[i])
|
rewardfileNamesInRange = append(rewardfileNamesInRange, rewardFileNames[i])
|
||||||
epochNumbersInRange = append(epochNumbersInRange, number)
|
|
||||||
}
|
}
|
||||||
|
return rewardfileNamesInRange, nil
|
||||||
return epochNumbersInRange, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEpochReward(account common.Address, header *types.Header) (AccountEpochReward, error) {
|
func getEpochReward(account common.Address, header *types.Header) (AccountEpochReward, error) {
|
||||||
|
|
@ -484,12 +507,16 @@ func (rewardObj *AccountEpochReward) getRewardAndStatus(account string, data map
|
||||||
nodeReward := accountData.(map[string]interface{})["reward"]
|
nodeReward := accountData.(map[string]interface{})["reward"]
|
||||||
delegatedReward := data["rewards"].(map[string]interface{})[account]
|
delegatedReward := data["rewards"].(map[string]interface{})[account]
|
||||||
rewardObj.AccountStatus = statusMasternode
|
rewardObj.AccountStatus = statusMasternode
|
||||||
nodeRewardBigInt, _ := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
nodeRewardBigInt, ok := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||||
rewardObj.AccountReward = nodeRewardBigInt
|
if ok {
|
||||||
|
rewardObj.AccountReward = nodeRewardBigInt
|
||||||
|
}
|
||||||
|
|
||||||
for k, v := range delegatedReward.(map[string]interface{}) {
|
for k, v := range delegatedReward.(map[string]interface{}) {
|
||||||
delegatedBigInt, _ := new(big.Int).SetString(v.(json.Number).String(), 10)
|
delegatedBigInt, ok := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
if ok {
|
||||||
|
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -500,12 +527,16 @@ func (rewardObj *AccountEpochReward) getRewardAndStatus(account string, data map
|
||||||
nodeReward := accountData.(map[string]interface{})["reward"]
|
nodeReward := accountData.(map[string]interface{})["reward"]
|
||||||
delegatedReward := data["rewardsProtector"].(map[string]interface{})[account]
|
delegatedReward := data["rewardsProtector"].(map[string]interface{})[account]
|
||||||
rewardObj.AccountStatus = statusProtectornode
|
rewardObj.AccountStatus = statusProtectornode
|
||||||
nodeRewardBigInt, _ := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
nodeRewardBigInt, successSetNodeReward := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||||
rewardObj.AccountReward = nodeRewardBigInt
|
if successSetNodeReward {
|
||||||
|
rewardObj.AccountReward = nodeRewardBigInt
|
||||||
|
}
|
||||||
|
|
||||||
for k, v := range delegatedReward.(map[string]interface{}) {
|
for k, v := range delegatedReward.(map[string]interface{}) {
|
||||||
delegatedBigInt, _ := new(big.Int).SetString(v.(json.Number).String(), 10)
|
delegatedBigInt, successSetDelegatedReward := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
if successSetDelegatedReward {
|
||||||
|
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -517,12 +548,16 @@ func (rewardObj *AccountEpochReward) getRewardAndStatus(account string, data map
|
||||||
nodeReward := accountData.(map[string]interface{})["reward"]
|
nodeReward := accountData.(map[string]interface{})["reward"]
|
||||||
delegatedReward := data["rewardsObserver"].(map[string]interface{})[account]
|
delegatedReward := data["rewardsObserver"].(map[string]interface{})[account]
|
||||||
rewardObj.AccountStatus = statusObservernode
|
rewardObj.AccountStatus = statusObservernode
|
||||||
nodeRewardBigInt, _ := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
nodeRewardBigInt, successSetNodeReward := new(big.Int).SetString(nodeReward.(json.Number).String(), 10)
|
||||||
rewardObj.AccountReward = nodeRewardBigInt
|
if successSetNodeReward {
|
||||||
|
rewardObj.AccountReward = nodeRewardBigInt
|
||||||
|
}
|
||||||
|
|
||||||
for k, v := range delegatedReward.(map[string]interface{}) {
|
for k, v := range delegatedReward.(map[string]interface{}) {
|
||||||
delegatedBigInt, _ := new(big.Int).SetString(v.(json.Number).String(), 10)
|
delegatedBigInt, successSetDelegatedReward := new(big.Int).SetString(v.(json.Number).String(), 10)
|
||||||
rewardObj.DelegatedReward[k] = delegatedBigInt
|
if successSetDelegatedReward {
|
||||||
|
rewardObj.DelegatedReward[k] = delegatedBigInt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue