add last block number for epoch api (#681)

Co-authored-by: Liam Lai <liam@home>
This commit is contained in:
benjamin202410 2024-10-20 23:43:23 -07:00 committed by GitHub
parent 3dac4dc014
commit 042c02ba8c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 18 deletions

View file

@ -350,13 +350,17 @@ An API exclusively for V2 consensus, designed to assist in getting rewards of th
Given the epoch number, search the epoch switch block. Given the epoch number, search the epoch switch block.
*/ */
func (api *API) GetBlockInfoByEpochNum(epochNumber uint64) (*utils.EpochNumInfo, error) { func (api *API) GetBlockInfoByEpochNum(epochNumber uint64) (*utils.EpochNumInfo, error) {
result, err := api.XDPoS.EngineV2.GetBlockByEpochNumber(api.chain, epochNumber) thisEpoch, nextEpoch, err := api.XDPoS.EngineV2.GetBlockByEpochNumber(api.chain, epochNumber)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &utils.EpochNumInfo{ info := &utils.EpochNumInfo{
EpochBlockHash: result.Hash, EpochBlockHash: thisEpoch.Hash,
EpochRound: result.Round, EpochRound: thisEpoch.Round,
EpochBlockNumber: result.Number, EpochFirstBlockNumber: thisEpoch.Number,
}, nil }
if nextEpoch != nil {
info.EpochLastBlockNumber = new(big.Int).Sub(nextEpoch.Number, big.NewInt(1))
}
return info, nil
} }

View file

@ -220,22 +220,22 @@ func (x *XDPoS_v2) CalculateMissingRounds(chain consensus.ChainReader, header *t
return missedRoundsMetadata, nil return missedRoundsMetadata, nil
} }
func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpochNum uint64) (*types.BlockInfo, error) { func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpochNum uint64) (*types.BlockInfo, *types.BlockInfo, error) {
currentHeader := chain.CurrentHeader() currentHeader := chain.CurrentHeader()
epochSwitchInfo, err := x.getEpochSwitchInfo(chain, currentHeader, currentHeader.Hash()) epochSwitchInfo, err := x.getEpochSwitchInfo(chain, currentHeader, currentHeader.Hash())
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch
// since below function GetEpochSwitchInfoBetween(chain, start, end) return nil if start == end, we early return the result // since below function GetEpochSwitchInfoBetween(chain, start, end) return nil if start == end, we early return the result
if targetEpochNum == epochNum { if targetEpochNum == epochNum {
return epochSwitchInfo.EpochSwitchBlockInfo, nil return epochSwitchInfo.EpochSwitchBlockInfo, nil, nil
} }
if targetEpochNum > epochNum { if targetEpochNum > epochNum {
return nil, errors.New("input epoch number > current epoch number") return nil, nil, errors.New("input epoch number > current epoch number")
} }
if targetEpochNum < x.config.V2.SwitchBlock.Uint64()/x.config.Epoch { if targetEpochNum < x.config.V2.SwitchBlock.Uint64()/x.config.Epoch {
return nil, errors.New("input epoch number < v2 begin epoch number") return nil, nil, errors.New("input epoch number < v2 begin epoch number")
} }
epoch := big.NewInt(int64(x.config.Epoch)) epoch := big.NewInt(int64(x.config.Epoch))
estblockNumDiff := new(big.Int).Mul(epoch, big.NewInt(int64(epochNum-targetEpochNum))) estblockNumDiff := new(big.Int).Mul(epoch, big.NewInt(int64(epochNum-targetEpochNum)))
@ -246,13 +246,17 @@ func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpoc
estBlockHeader := chain.GetHeaderByNumber(estBlockNum.Uint64()) estBlockHeader := chain.GetHeaderByNumber(estBlockNum.Uint64())
epochSwitchInfos, err := x.GetEpochSwitchInfoBetween(chain, estBlockHeader, currentHeader) epochSwitchInfos, err := x.GetEpochSwitchInfoBetween(chain, estBlockHeader, currentHeader)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
for _, info := range epochSwitchInfos { for i, info := range epochSwitchInfos {
epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(info.EpochSwitchBlockInfo.Round)/x.config.Epoch epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(info.EpochSwitchBlockInfo.Round)/x.config.Epoch
if epochNum == targetEpochNum { if epochNum == targetEpochNum {
return info.EpochSwitchBlockInfo, nil if i < len(epochSwitchInfos)-1 {
nextEpoch := epochSwitchInfos[i+1].EpochSwitchBlockInfo
return info.EpochSwitchBlockInfo, nextEpoch, nil
}
return info.EpochSwitchBlockInfo, nil, nil
} }
} }
return nil, errors.New("input epoch number not found (all rounds in this epoch are missed, which is very rare)") return nil, nil, errors.New("input epoch number not found (all rounds in this epoch are missed, which is very rare)")
} }

View file

@ -74,7 +74,8 @@ type PublicApiMissedRoundsMetadata struct {
// Given an epoch number, this struct records the epoch switch block (first block in epoch) infos such as block number // Given an epoch number, this struct records the epoch switch block (first block in epoch) infos such as block number
type EpochNumInfo struct { type EpochNumInfo struct {
EpochBlockHash common.Hash `json:"hash"` EpochBlockHash common.Hash `json:"hash"`
EpochRound types.Round `json:"round"` EpochRound types.Round `json:"round"`
EpochBlockNumber *big.Int `json:"number"` EpochFirstBlockNumber *big.Int `json:"firstBlock"`
EpochLastBlockNumber *big.Int `json:"lastBlock"`
} }

View file

@ -204,14 +204,20 @@ func TestGetBlockByEpochNumber(t *testing.T) {
assert.Nil(t, info) assert.Nil(t, info)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(1) info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(1)
assert.Equal(t, info.EpochFirstBlockNumber.Int64(), int64(901))
assert.Equal(t, info.EpochLastBlockNumber.Int64(), int64(1799))
assert.Equal(t, info.EpochRound, types.Round(1)) assert.Equal(t, info.EpochRound, types.Round(1))
assert.Nil(t, err) assert.Nil(t, err)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(2) info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(2)
assert.Equal(t, info.EpochFirstBlockNumber.Int64(), int64(1800))
assert.Equal(t, info.EpochLastBlockNumber.Int64(), int64(1802))
assert.Equal(t, info.EpochRound, types.Round(900)) assert.Equal(t, info.EpochRound, types.Round(900))
assert.Nil(t, err) assert.Nil(t, err)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(3) info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(3)
assert.Equal(t, info.EpochFirstBlockNumber.Int64(), int64(1803))
assert.Equal(t, info.EpochLastBlockNumber.Int64(), int64(1803))
assert.Equal(t, info.EpochRound, types.Round(largeRound)) assert.Equal(t, info.EpochRound, types.Round(largeRound))
assert.Nil(t, err) assert.Nil(t, err)
@ -221,6 +227,8 @@ func TestGetBlockByEpochNumber(t *testing.T) {
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(5) 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.EpochFirstBlockNumber.Int64(), int64(1804))
assert.Nil(t, info.EpochLastBlockNumber)
assert.Nil(t, err) assert.Nil(t, err)
info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(6) info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(6)