mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
consensus/XDPoS, eth: fix potential rpc.BlockNumber overflow, close XFN-69 (#1735)
This commit is contained in:
parent
0fc4c82350
commit
f24e68b015
3 changed files with 89 additions and 18 deletions
|
|
@ -139,6 +139,8 @@ func (api *API) GetSnapshot(number *rpc.BlockNumber) (*utils.PublicApiSnapshot,
|
|||
var header *types.Header
|
||||
if number == nil || *number == rpc.LatestBlockNumber {
|
||||
header = api.chain.CurrentHeader()
|
||||
} else if number.Int64() < 0 {
|
||||
return nil, fmt.Errorf("invalid block number %d", number.Int64())
|
||||
} else {
|
||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
||||
}
|
||||
|
|
@ -164,6 +166,8 @@ func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) {
|
|||
var header *types.Header
|
||||
if number == nil || *number == rpc.LatestBlockNumber {
|
||||
header = api.chain.CurrentHeader()
|
||||
} else if number.Int64() < 0 {
|
||||
return nil, fmt.Errorf("invalid block number %d", number.Int64())
|
||||
} else {
|
||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
||||
}
|
||||
|
|
@ -192,13 +196,22 @@ func (api *API) GetMasternodesByNumber(number *rpc.BlockNumber) MasternodesStatu
|
|||
if info := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo(); info != nil {
|
||||
header = api.chain.GetHeaderByHash(info.Hash)
|
||||
}
|
||||
} else if number.Int64() < 0 {
|
||||
return MasternodesStatus{
|
||||
Error: fmt.Errorf("invalid block number %d", number.Int64()),
|
||||
}
|
||||
} else {
|
||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
||||
}
|
||||
|
||||
if header == nil {
|
||||
if number == nil {
|
||||
return MasternodesStatus{
|
||||
Error: errors.New("can not get header by nil number"),
|
||||
}
|
||||
}
|
||||
return MasternodesStatus{
|
||||
Error: fmt.Errorf("can not get header by number: %v", number),
|
||||
Error: fmt.Errorf("can not get header by number %d", number.Int64()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +324,12 @@ func (api *API) GetV2BlockByHeader(header *types.Header, uncle bool) *V2BlockInf
|
|||
}
|
||||
|
||||
func (api *API) GetV2BlockByNumber(number *rpc.BlockNumber) *V2BlockInfo {
|
||||
header := api.getHeaderFromApiBlockNum(number)
|
||||
header, err := api.getHeaderFromApiBlockNum(number)
|
||||
if err != nil {
|
||||
return &V2BlockInfo{
|
||||
Error: err.Error(),
|
||||
}
|
||||
}
|
||||
if header == nil {
|
||||
if number == nil {
|
||||
return &V2BlockInfo{
|
||||
|
|
@ -368,10 +386,20 @@ func (api *API) NetworkInformation() NetworkInformation {
|
|||
An API exclusively for V2 consensus, designed to assist in troubleshooting miners by identifying who mined during their allocated term.
|
||||
*/
|
||||
func (api *API) GetMissedRoundsInEpochByBlockNum(number *rpc.BlockNumber) (*utils.PublicApiMissedRoundsMetadata, error) {
|
||||
return api.XDPoS.CalculateMissingRounds(api.chain, api.getHeaderFromApiBlockNum(number))
|
||||
header, err := api.getHeaderFromApiBlockNum(number)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if header == nil {
|
||||
if number == nil {
|
||||
return nil, errors.New("can not get header by nil number")
|
||||
}
|
||||
return nil, fmt.Errorf("can not get header by number %d", number.Int64())
|
||||
}
|
||||
return api.XDPoS.CalculateMissingRounds(api.chain, header)
|
||||
}
|
||||
|
||||
func (api *API) getHeaderFromApiBlockNum(number *rpc.BlockNumber) *types.Header {
|
||||
func (api *API) getHeaderFromApiBlockNum(number *rpc.BlockNumber) (*types.Header, error) {
|
||||
var header *types.Header
|
||||
if number == nil || *number == rpc.LatestBlockNumber {
|
||||
header = api.chain.CurrentHeader()
|
||||
|
|
@ -379,10 +407,12 @@ func (api *API) getHeaderFromApiBlockNum(number *rpc.BlockNumber) *types.Header
|
|||
if info := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo(); info != nil {
|
||||
header = api.chain.GetHeaderByHash(info.Hash)
|
||||
}
|
||||
} else if number.Int64() < 0 {
|
||||
return nil, fmt.Errorf("invalid block number %d", number.Int64())
|
||||
} else {
|
||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
||||
}
|
||||
return header
|
||||
return header, nil
|
||||
}
|
||||
|
||||
func calculateSigners(message map[string]SignerTypes, pool map[string]map[common.Hash]utils.PoolObj, masternodes []common.Address) {
|
||||
|
|
@ -464,16 +494,34 @@ func (api *API) GetRewardByAccount(account common.Address, begin rpc.BlockNumber
|
|||
}
|
||||
|
||||
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")
|
||||
beginHeader, err := api.getHeaderFromApiBlockNum(begin)
|
||||
if err != nil {
|
||||
if begin == nil {
|
||||
return nil, fmt.Errorf("can not get begin header from nil number, err: %w", err)
|
||||
}
|
||||
return nil, fmt.Errorf("can not get begin header from number %d, err: %w", begin.Int64(), err)
|
||||
}
|
||||
if beginHeader == nil {
|
||||
if begin == nil {
|
||||
return nil, errors.New("begin block number is nil")
|
||||
}
|
||||
return nil, fmt.Errorf("illegal begin block number %d", begin.Int64())
|
||||
}
|
||||
endHeader, err := api.getHeaderFromApiBlockNum(end)
|
||||
if err != nil {
|
||||
if end == nil {
|
||||
return nil, fmt.Errorf("can not get end header from nil number, err: %w", err)
|
||||
}
|
||||
return nil, fmt.Errorf("can not get end header from number %d, err: %w", end.Int64(), err)
|
||||
}
|
||||
endHeader := api.getHeaderFromApiBlockNum(end)
|
||||
if endHeader == nil {
|
||||
return nil, errors.New("illegal end block number")
|
||||
if end == nil {
|
||||
return nil, errors.New("end block number is nil")
|
||||
}
|
||||
return nil, fmt.Errorf("illegal end block number %d", end.Int64())
|
||||
}
|
||||
if beginHeader.Number.Cmp(endHeader.Number) > 0 {
|
||||
return nil, errors.New("illegal begin and end block number, begin > end")
|
||||
return nil, fmt.Errorf("illegal block numbers: begin(%d) > end(%d)", beginHeader.Number.Int64(), endHeader.Number.Int64())
|
||||
}
|
||||
diff := new(big.Int).Sub(endHeader.Number, beginHeader.Number).Int64()
|
||||
if diff < 0 {
|
||||
|
|
@ -621,18 +669,36 @@ func (rewardObj *AccountEpochReward) getRewardAndStatus(account string, data map
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (api *API) GetEpochNumbersBetween(begin, end *rpc.BlockNumber) ([]uint64, error) {
|
||||
beginHeader := api.getHeaderFromApiBlockNum(begin)
|
||||
beginHeader, err := api.getHeaderFromApiBlockNum(begin)
|
||||
if err != nil {
|
||||
if begin == nil {
|
||||
return nil, fmt.Errorf("can not get begin header from nil number, err: %w", err)
|
||||
}
|
||||
return nil, fmt.Errorf("can not get begin header from number %d, err: %w", begin.Int64(), err)
|
||||
}
|
||||
if beginHeader == nil {
|
||||
return nil, errors.New("illegal begin block number")
|
||||
if begin == nil {
|
||||
return nil, errors.New("begin block is nil")
|
||||
}
|
||||
return nil, fmt.Errorf("illegal begin block number %d", begin.Int64())
|
||||
}
|
||||
endHeader, err := api.getHeaderFromApiBlockNum(end)
|
||||
if err != nil {
|
||||
if end == nil {
|
||||
return nil, fmt.Errorf("can not get end header from nil number, err: %w", err)
|
||||
}
|
||||
return nil, fmt.Errorf("can not get end header from number %d, err: %w", end.Int64(), err)
|
||||
}
|
||||
endHeader := api.getHeaderFromApiBlockNum(end)
|
||||
if endHeader == nil {
|
||||
return nil, errors.New("illegal end block number")
|
||||
if end == nil {
|
||||
return nil, errors.New("end block number is nil")
|
||||
}
|
||||
return nil, fmt.Errorf("illegal end block number %d", end.Int64())
|
||||
}
|
||||
|
||||
diff := new(big.Int).Sub(endHeader.Number, beginHeader.Number).Int64()
|
||||
if diff < 0 {
|
||||
return nil, errors.New("illegal begin and end block number, begin > end")
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ func TestGetEpochNumbersBetween(t *testing.T) {
|
|||
numbers, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||
|
||||
assert.Nil(t, numbers)
|
||||
assert.EqualError(t, err, "illegal end block number")
|
||||
assert.EqualError(t, err, "illegal end block number 1803")
|
||||
|
||||
// 1803 not exist
|
||||
begin = rpc.BlockNumber(1803)
|
||||
|
|
@ -166,7 +166,7 @@ func TestGetEpochNumbersBetween(t *testing.T) {
|
|||
numbers, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end)
|
||||
|
||||
assert.Nil(t, numbers)
|
||||
assert.EqualError(t, err, "illegal begin block number")
|
||||
assert.EqualError(t, err, "illegal begin block number 1803")
|
||||
}
|
||||
func TestGetBlockByEpochNumber(t *testing.T) {
|
||||
blockchain, _, currentBlock, signer, signFn := PrepareXDCTestBlockChainWithPenaltyForV2Engine(t, 1802, params.TestXDPoSMockChainConfig)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -97,6 +98,8 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb
|
|||
} else {
|
||||
return nil, errors.New("PoS V1 does not support confirmed block lookup")
|
||||
}
|
||||
} else if number.Int64() < 0 {
|
||||
return nil, fmt.Errorf("invalid block number %d", number.Int64())
|
||||
}
|
||||
header := b.eth.blockchain.GetHeaderByNumber(uint64(number))
|
||||
if header == nil {
|
||||
|
|
@ -147,6 +150,8 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe
|
|||
} else {
|
||||
return nil, errors.New("PoS V1 does not support confirmed block lookup")
|
||||
}
|
||||
} else if number.Int64() < 0 {
|
||||
return nil, fmt.Errorf("invalid block number %d", number.Int64())
|
||||
}
|
||||
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue