mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
feat: GetEpochNumbersBetween API (#606)
* feat: GetEpochNumbersBetween API * style: refine GetEpochNumbersBetween API
This commit is contained in:
parent
3e4932e408
commit
3593abe815
5 changed files with 130 additions and 0 deletions
|
|
@ -550,3 +550,13 @@ func (x *XDPoS) CacheSigningTxs(hash common.Hash, txs []*types.Transaction) []*t
|
||||||
func (x *XDPoS) GetCachedSigningTxs(hash common.Hash) (interface{}, bool) {
|
func (x *XDPoS) GetCachedSigningTxs(hash common.Hash) (interface{}, bool) {
|
||||||
return x.signingTxsCache.Get(hash)
|
return x.signingTxsCache.Get(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *XDPoS) GetEpochSwitchInfoBetween(chain consensus.ChainReader, begin, end *types.Header) ([]*types.EpochSwitchInfo, error) {
|
||||||
|
beginBlockVersion := x.config.BlockConsensusVersion(begin.Number, begin.Extra, ExtraFieldCheck)
|
||||||
|
endBlockVersion := x.config.BlockConsensusVersion(end.Number, end.Extra, ExtraFieldCheck)
|
||||||
|
if beginBlockVersion == params.ConsensusEngineVersion2 && endBlockVersion == params.ConsensusEngineVersion2 {
|
||||||
|
return x.EngineV2.GetEpochSwitchInfoBetween(chain, begin, end)
|
||||||
|
}
|
||||||
|
// Default "v1"
|
||||||
|
return nil, errors.New("not supported in the v1 consensus")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ package XDPoS
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
|
@ -320,3 +321,26 @@ func calculateSigners(message map[string]SignerTypes, pool map[string]map[common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *API) GetEpochNumbersBetween(begin, end *rpc.BlockNumber) ([]uint64, error) {
|
||||||
|
beginHeader := api.getHeaderFromApiBlockNum(begin)
|
||||||
|
if beginHeader == nil {
|
||||||
|
return nil, errors.New("illegal begin block number")
|
||||||
|
}
|
||||||
|
endHeader := api.getHeaderFromApiBlockNum(end)
|
||||||
|
if endHeader == nil {
|
||||||
|
return nil, errors.New("illegal end block number")
|
||||||
|
}
|
||||||
|
if beginHeader.Number.Cmp(endHeader.Number) > 0 {
|
||||||
|
return nil, errors.New("illegal begin and end block number, begin > end")
|
||||||
|
}
|
||||||
|
epochSwitchInfos, err := api.XDPoS.GetEpochSwitchInfoBetween(api.chain, beginHeader, endHeader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
epochSwitchNumbers := make([]uint64, len(epochSwitchInfos))
|
||||||
|
for i, info := range epochSwitchInfos {
|
||||||
|
epochSwitchNumbers[i] = info.EpochSwitchBlockInfo.Number.Uint64()
|
||||||
|
}
|
||||||
|
return epochSwitchNumbers, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,3 +157,34 @@ func (x *XDPoS_v2) IsEpochSwitch(header *types.Header) (bool, uint64, error) {
|
||||||
log.Debug("[IsEpochSwitch]", "is", parentRound < epochStartRound, "parentRound", parentRound, "round", round, "number", header.Number.Uint64(), "epochNum", epochNum, "hash", header.Hash())
|
log.Debug("[IsEpochSwitch]", "is", parentRound < epochStartRound, "parentRound", parentRound, "round", round, "number", header.Number.Uint64(), "epochNum", epochNum, "hash", header.Hash())
|
||||||
return parentRound < epochStartRound, epochNum, nil
|
return parentRound < epochStartRound, epochNum, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetEpochSwitchInfoBetween get epoch switch between begin and end headers
|
||||||
|
// Search backwardly from end number to begin number
|
||||||
|
func (x *XDPoS_v2) GetEpochSwitchInfoBetween(chain consensus.ChainReader, begin, end *types.Header) ([]*types.EpochSwitchInfo, error) {
|
||||||
|
infos := make([]*types.EpochSwitchInfo, 0)
|
||||||
|
// after the first iteration, it becomes nil since epoch switch info does not have header info
|
||||||
|
iteratorHeader := end
|
||||||
|
// after the first iteration, it becomes the parent hash of the epoch switch block
|
||||||
|
iteratorHash := end.Hash()
|
||||||
|
iteratorNum := end.Number
|
||||||
|
// when iterator is strictly > begin number, do the search
|
||||||
|
for iteratorNum.Cmp(begin.Number) > 0 {
|
||||||
|
epochSwitchInfo, err := x.getEpochSwitchInfo(chain, iteratorHeader, iteratorHash)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[GetEpochSwitchInfoBetween] Adaptor v2 getEpochSwitchInfo has error, potentially bug", "err", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
iteratorHeader = nil
|
||||||
|
iteratorHash = epochSwitchInfo.EpochSwitchParentBlockInfo.Hash
|
||||||
|
iteratorNum = epochSwitchInfo.EpochSwitchBlockInfo.Number
|
||||||
|
if iteratorNum.Cmp(begin.Number) >= 0 {
|
||||||
|
infos = append(infos, epochSwitchInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// reverse the array
|
||||||
|
for i := 0; i < len(infos)/2; i++ {
|
||||||
|
infos[i], infos[len(infos)-1-i] = infos[len(infos)-1-i], infos[i]
|
||||||
|
}
|
||||||
|
return infos, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package engine_v2_tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||||
|
|
@ -109,3 +110,61 @@ func TestGetMissedRoundsInEpochByBlockNum(t *testing.T) {
|
||||||
|
|
||||||
assert.NotEqual(t, data.MissedRounds[0].Miner, data.MissedRounds[1].Miner)
|
assert.NotEqual(t, data.MissedRounds[0].Miner, data.MissedRounds[1].Miner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetEpochNumbersBetween(t *testing.T) {
|
||||||
|
_, bc, _, _, _ := PrepareXDCTestBlockChainWith128Candidates(t, 1802, params.TestXDPoSMockChainConfig)
|
||||||
|
|
||||||
|
engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS)
|
||||||
|
|
||||||
|
begin := rpc.BlockNumber(1800)
|
||||||
|
end := rpc.BlockNumber(1802)
|
||||||
|
numbers, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||||
|
|
||||||
|
assert.True(t, reflect.DeepEqual([]uint64{1800}, numbers))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
begin = rpc.BlockNumber(1799)
|
||||||
|
end = rpc.BlockNumber(1802)
|
||||||
|
numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||||
|
|
||||||
|
assert.True(t, reflect.DeepEqual([]uint64{1800}, numbers))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
begin = rpc.BlockNumber(1799)
|
||||||
|
end = rpc.BlockNumber(1802)
|
||||||
|
numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||||
|
|
||||||
|
assert.True(t, reflect.DeepEqual([]uint64{1800}, numbers))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
begin = rpc.BlockNumber(901)
|
||||||
|
end = rpc.BlockNumber(1802)
|
||||||
|
numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||||
|
|
||||||
|
assert.True(t, reflect.DeepEqual([]uint64{901, 1800}, numbers))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
// 900 is V1, not V2, so error
|
||||||
|
begin = rpc.BlockNumber(900)
|
||||||
|
end = rpc.BlockNumber(1802)
|
||||||
|
numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||||
|
|
||||||
|
assert.Nil(t, numbers)
|
||||||
|
assert.EqualError(t, err, "not supported in the v1 consensus")
|
||||||
|
|
||||||
|
// 1803 not exist
|
||||||
|
begin = rpc.BlockNumber(901)
|
||||||
|
end = rpc.BlockNumber(1803)
|
||||||
|
numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||||
|
|
||||||
|
assert.Nil(t, numbers)
|
||||||
|
assert.EqualError(t, err, "illegal end block number")
|
||||||
|
|
||||||
|
// 1803 not exist
|
||||||
|
begin = rpc.BlockNumber(1803)
|
||||||
|
end = rpc.BlockNumber(1803)
|
||||||
|
numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||||
|
|
||||||
|
assert.Nil(t, numbers)
|
||||||
|
assert.EqualError(t, err, "illegal begin block number")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,12 @@ web3._extend({
|
||||||
params: 1,
|
params: 1,
|
||||||
inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter]
|
inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter]
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'getEpochNumbersBetween',
|
||||||
|
call: 'XDPoS_getEpochNumbersBetween',
|
||||||
|
params: 2,
|
||||||
|
inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter, web3._extend.formatters.inputBlockNumberFormatter]
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
properties: [
|
properties: [
|
||||||
new web3._extend.Property({
|
new web3._extend.Property({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue