Merge pull request #1230 from XinFinOrg/v1compatible-getblockbyepochnumber

make XDPoS_getBlockInfoByEpochNum work with v1 epoch number
This commit is contained in:
Wanwiset Peerapatanapokin 2025-07-19 09:30:08 +07:00 committed by GitHub
commit 957d6093a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 13 deletions

View file

@ -19,6 +19,7 @@ import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"math/big"
"os"
"path/filepath"
@ -468,7 +469,7 @@ func (api *API) getRewardFileNamesInRange(begin, end *rpc.BlockNumber) ([]reward
startIndex := sort.SearchInts(epochNumbers, int(beginHeader.Number.Int64()))
endIndex := sort.SearchInts(epochNumbers, int(endHeader.Number.Int64()))
if endIndex == len(epochNumbers) {
endIndex-- //this is to prevent endIndex out of bounds when endInput is higher than last reward(epoch) block but lower than latest block
endIndex-- //this is to prevent endIndex out of bounds when endInput is higher than last reward(epoch) block but lower than latest block
}
var rewardfileNamesInRange []rewardFileName
@ -604,15 +605,16 @@ func (api *API) GetEpochNumbersBetween(begin, end *rpc.BlockNumber) ([]uint64, e
An API exclusively for V2 consensus, designed to assist in getting rewards of the epoch number.
Given the epoch number, search the epoch switch block.
*/
func (api *API) GetBlockInfoByEpochNum(epochNumber uint64) (*utils.EpochNumInfo, error) {
func (api *API) GetBlockInfoByV2EpochNum(epochNumber uint64) (*utils.EpochNumInfo, error) {
thisEpoch, err := api.XDPoS.EngineV2.GetBlockByEpochNumber(api.chain, epochNumber)
if err != nil {
return nil, err
}
info := &utils.EpochNumInfo{
EpochBlockHash: thisEpoch.Hash,
EpochRound: thisEpoch.Round,
EpochRound: &thisEpoch.Round,
EpochFirstBlockNumber: thisEpoch.Number,
EpochConsensusVersion: "v2",
}
nextEpoch, err := api.XDPoS.EngineV2.GetBlockByEpochNumber(api.chain, epochNumber+1)
@ -621,3 +623,28 @@ func (api *API) GetBlockInfoByEpochNum(epochNumber uint64) (*utils.EpochNumInfo,
}
return info, nil
}
func (api *API) CalculateBlockInfoByV1EpochNum(targetEpochNum uint64) (*utils.EpochNumInfo, error) {
epoch := api.XDPoS.config.Epoch //900
epochBlockNum := targetEpochNum*epoch + 1
currentBlock := api.chain.CurrentHeader().Number.Uint64()
if currentBlock < epochBlockNum {
return nil, fmt.Errorf("epoch not reached: current block number %d, epoch block number %d", currentBlock, epochBlockNum)
}
epochLastBlockNum := epochBlockNum + epoch - 1
return &utils.EpochNumInfo{
EpochBlockHash: api.chain.GetHeaderByNumber(epochBlockNum).Hash(),
EpochFirstBlockNumber: big.NewInt(int64(epochBlockNum)),
EpochLastBlockNumber: big.NewInt(int64(epochLastBlockNum)),
EpochConsensusVersion: "v1",
}, nil
}
func (api *API) GetBlockInfoByEpochNum(epochNumber uint64) (*utils.EpochNumInfo, error) {
if epochNumber < api.XDPoS.config.V2.SwitchEpoch {
return api.CalculateBlockInfoByV1EpochNum(epochNumber)
}
return api.GetBlockInfoByV2EpochNum(epochNumber)
}

View file

@ -75,10 +75,11 @@ type PublicApiMissedRoundsMetadata struct {
// Given an epoch number, this struct records the epoch switch block (first block in epoch) infos such as block number
type EpochNumInfo struct {
EpochBlockHash common.Hash `json:"hash"`
EpochRound types.Round `json:"round"`
EpochFirstBlockNumber *big.Int `json:"firstBlock"`
EpochLastBlockNumber *big.Int `json:"lastBlock"`
EpochBlockHash common.Hash `json:"hash"`
EpochRound *types.Round `json:"round,omitempty"`
EpochFirstBlockNumber *big.Int `json:"firstBlock"`
EpochLastBlockNumber *big.Int `json:"lastBlock"`
EpochConsensusVersion string `json:"consensusVersion"`
}
type SigLRU = lru.Cache[common.Hash, common.Address]

View file

@ -200,19 +200,22 @@ func TestGetBlockByEpochNumber(t *testing.T) {
assert.Nil(t, err)
info, err := engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(0)
assert.NotNil(t, err)
assert.Nil(t, info)
assert.Equal(t, info.EpochConsensusVersion, "v1")
assert.Nil(t, err)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(1)
assert.Equal(t, info.EpochRound, types.Round(1))
assert.Equal(t, *info.EpochRound, types.Round(1))
assert.Equal(t, info.EpochConsensusVersion, "v2")
assert.Nil(t, err)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(2)
assert.Equal(t, info.EpochRound, types.Round(900))
assert.Equal(t, *info.EpochRound, types.Round(900))
assert.Equal(t, info.EpochConsensusVersion, "v2")
assert.Nil(t, err)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(3)
assert.Equal(t, info.EpochRound, types.Round(largeRound))
assert.Equal(t, *info.EpochRound, types.Round(largeRound))
assert.Equal(t, info.EpochConsensusVersion, "v2")
assert.Nil(t, err)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(4)
@ -220,7 +223,8 @@ func TestGetBlockByEpochNumber(t *testing.T) {
assert.Nil(t, info)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(5)
assert.Equal(t, info.EpochRound, types.Round(largeRound2))
assert.Equal(t, *info.EpochRound, types.Round(largeRound2))
assert.Equal(t, info.EpochConsensusVersion, "v2")
assert.Nil(t, err)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(6)