From d98c1f908c48b6eb066a298ecff4fcf75e64fab5 Mon Sep 17 00:00:00 2001 From: buddh0 Date: Mon, 6 Jan 2025 14:48:10 +0800 Subject: [PATCH] internal/ethapi: support GetFinalizedBlock by common ratio validators --- ethclient/ethclient.go | 14 ++++---------- internal/ethapi/api.go | 23 ++++++++++++++++++----- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index e38ebd10f8..7ed02bd7ad 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -253,11 +253,9 @@ func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.H } // GetFinalizedHeader returns the requested finalized block header. -// - probabilisticFinalized should be in range [2,21], -// then the block header with number `max(fastFinalized, latest-probabilisticFinalized)` is returned -func (ec *Client) FinalizedHeader(ctx context.Context, probabilisticFinalized int64) (*types.Header, error) { +func (ec *Client) FinalizedHeader(ctx context.Context, verifiedValidatorNum int64) (*types.Header, error) { var head *types.Header - err := ec.c.CallContext(ctx, &head, "eth_getFinalizedHeader", probabilisticFinalized) + err := ec.c.CallContext(ctx, &head, "eth_getFinalizedHeader", verifiedValidatorNum) if err == nil && head == nil { err = ethereum.NotFound } @@ -265,12 +263,8 @@ func (ec *Client) FinalizedHeader(ctx context.Context, probabilisticFinalized in } // GetFinalizedBlock returns the requested finalized block. -// - probabilisticFinalized should be in range [2,21], -// then the block with number `max(fastFinalized, latest-probabilisticFinalized)` is returned -// - When fullTx is true all transactions in the block are returned, otherwise -// only the transaction hash is returned. -func (ec *Client) FinalizedBlock(ctx context.Context, probabilisticFinalized int64, fullTx bool) (*types.Block, error) { - return ec.getBlock(ctx, "eth_getFinalizedBlock", probabilisticFinalized, true) +func (ec *Client) FinalizedBlock(ctx context.Context, verifiedValidatorNum int64, fullTx bool) (*types.Block, error) { + return ec.getBlock(ctx, "eth_getFinalizedBlock", verifiedValidatorNum, fullTx) } func (ec *Client) GetRootByDiffHash(ctx context.Context, blockNr *big.Int, blockHash common.Hash, diffHash common.Hash) (*core.VerifyResult, error) { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 9c1365a57b..852f3a3615 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common/gopool" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" + cmath "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core" @@ -549,9 +550,15 @@ func (api *BlockChainAPI) getFinalizedNumber(ctx context.Context, verifiedValida if err != nil { // impossible return 0, err } - valLen := int64(len(curValidators)) - if verifiedValidatorNum < 1 || verifiedValidatorNum > valLen { - return 0, fmt.Errorf("%d out of range [1,%d]", verifiedValidatorNum, valLen) + valLen := len(curValidators) + if verifiedValidatorNum == -1 { + verifiedValidatorNum = int64(cmath.CeilDiv(valLen, 2)) + } else if verifiedValidatorNum == -2 { + verifiedValidatorNum = int64(cmath.CeilDiv(valLen*2, 3)) + } else if verifiedValidatorNum == -3 { + verifiedValidatorNum = int64(valLen) + } else if verifiedValidatorNum < 1 || verifiedValidatorNum > int64(valLen) { + return 0, fmt.Errorf("%d neither within the range [1,%d] nor the range [-3,-1]", verifiedValidatorNum, valLen) } fastFinalizedHeader, err := api.b.HeaderByNumber(ctx, rpc.FinalizedBlockNumber) @@ -582,7 +589,10 @@ func (api *BlockChainAPI) getFinalizedNumber(ctx context.Context, verifiedValida } // GetFinalizedHeader returns the finalized block header based on the specified parameters. -// - `verifiedValidatorNum` must be within the range [1, len(currentValidators)]. +// - `verifiedValidatorNum` must be within the range [1, len(currentValidators)],with the exception that: +// -1 represents at least len(currentValidators) * 1/2 +// -2 represents at least len(currentValidators) * 2/3 +// -3 represents at least len(currentValidators) // - The function calculates `probabilisticFinalizedHeight` as the highest height of the block verified by `verifiedValidatorNum` validators, // it then returns the block header with a height equal to `max(fastFinalizedHeight, probabilisticFinalizedHeight)`. // - The height of the returned block header is guaranteed to be monotonically increasing. @@ -595,7 +605,10 @@ func (api *BlockChainAPI) GetFinalizedHeader(ctx context.Context, verifiedValida } // GetFinalizedBlock returns the finalized block based on the specified parameters. -// - `verifiedValidatorNum` must be within the range [1, len(currentValidators)]. +// - `verifiedValidatorNum` must be within the range [1, len(currentValidators)],with the exception that: +// -1 represents at least len(currentValidators) * 1/2 +// -2 represents at least len(currentValidators) * 2/3 +// -3 represents at least len(currentValidators) // - The function calculates `probabilisticFinalizedHeight` as the highest height of the block verified by `verifiedValidatorNum` validators, // it then returns the block with a height equal to `max(fastFinalizedHeight, probabilisticFinalizedHeight)`. // - If `fullTx` is true, the block includes all transactions; otherwise, only transaction hashes are included.