diff --git a/consensus/bor/api.go b/consensus/bor/api.go index 672d378215aea51b5d6a3d9f0b2b7bbdb55cadec..5af1ddbc39c2b6acd3c0531b71c3ba05d6e70d75 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -17,6 +17,7 @@ package bor import ( + "encoding/hex" "math" "math/big" "strconv" @@ -122,21 +123,21 @@ func (api *API) GetCurrentValidators() ([]*Validator, error) { } // GetRootHash returns the merkle root of the start to end block headers -func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { +func (api *API) GetRootHash(start uint64, end uint64) (string, error) { if err := api.initializeRootHashCache(); err != nil { - return nil, err + return "", err } key := getRootHashKey(start, end) if root, known := api.rootHashCache.Get(key); known { - return root.([]byte), nil + return root.(string), nil } length := uint64(end - start + 1) if length > MaxCheckpointLength { - return nil, &MaxCheckpointLengthExceededError{start, end} + return "", &MaxCheckpointLengthExceededError{start, end} } - currentHeaderNumber := api.chain.CurrentHeader().Number.Int64() + currentHeaderNumber := api.chain.CurrentHeader().Number.Uint64() if start > end || end > currentHeaderNumber { - return nil, &InvalidStartEndBlockError{start, end, currentHeaderNumber} + return "", &InvalidStartEndBlockError{start, end, currentHeaderNumber} } blockHeaders := make([]*types.Header, end-start+1) wg := new(sync.WaitGroup) @@ -144,7 +145,7 @@ func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { for i := start; i <= end; i++ { wg.Add(1) concurrent <- true - go func(number int64) { + go func(number uint64) { blockHeaders[number-start] = api.chain.GetHeaderByNumber(uint64(number)) <-concurrent wg.Done() @@ -170,9 +171,9 @@ func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { tree := merkle.NewTreeWithOpts(merkle.TreeOptions{EnableHashSorting: false, DisableHashLeaves: true}) if err := tree.Generate(convert(headers), sha3.NewLegacyKeccak256()); err != nil { - return nil, err + return "", err } - root := tree.Root().Hash + root := hex.EncodeToString(tree.Root().Hash) api.rootHashCache.Add(key, root) return root, nil } @@ -185,6 +186,6 @@ func (api *API) initializeRootHashCache() error { return err } -func getRootHashKey(start int64, end int64) string { - return strconv.FormatInt(start, 10) + "-" + strconv.FormatInt(end, 10) +func getRootHashKey(start uint64, end uint64) string { + return strconv.FormatUint(start, 10) + "-" + strconv.FormatUint(end, 10) } diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index ae7da982a7651cc19e6826186e46c6e78e14ea78..f9f99e2b6490c265a1296f811aa532fb6e6de165 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -42,9 +42,9 @@ func (e *TotalVotingPowerExceededError) Error() string { } type InvalidStartEndBlockError struct { - Start int64 - End int64 - CurrentHeader int64 + Start uint64 + End uint64 + CurrentHeader uint64 } func (e *InvalidStartEndBlockError) Error() string { @@ -56,8 +56,8 @@ func (e *InvalidStartEndBlockError) Error() string { } type MaxCheckpointLengthExceededError struct { - Start int64 - End int64 + Start uint64 + End uint64 } func (e *MaxCheckpointLengthExceededError) Error() string { diff --git a/eth/api_backend.go b/eth/api_backend.go index 7958f86b37c261d9a6d47eb85762d0473bf28d21..0be0376cf556b9b9916aa8da2a7dca9699c01b01 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -249,16 +249,16 @@ func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma } } -func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { +func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) { var api *bor.API for _, _api := range b.eth.Engine().APIs(b.eth.BlockChain()) { if _api.Namespace == "bor" { api = _api.Service.(*bor.API) } } - root, err := api.GetRootHash(starBlockNr.Int64(), endBlockNr.Int64()) + root, err := api.GetRootHash(starBlockNr, endBlockNr) if err != nil { - return nil, err + return "", err } return root, nil } diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 5d349a289b86f8875b4e59d4b38cdf22778a2f6f..7d44b0da034b1c5373fc2259308c637563c7e806 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -522,6 +522,15 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) } +// GetRootHash returns the merkle root of the block headers +func (ec *Client) GetRootHash(ctx context.Context, startBlockNumber uint64, endBlockNumber uint64) (string, error) { + var rootHash string + if err := ec.c.CallContext(ctx, &rootHash, "eth_getRootHash", startBlockNumber, endBlockNumber); err != nil { + return "", err + } + return rootHash, nil +} + func toCallArg(msg ethereum.CallMsg) interface{} { arg := map[string]interface{}{ "from": msg.From, diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 0ad624e7ed3dbf88787e096451291689b7a4ddac..cee5a575fb45cd30e27f4f2d9b4ed15c454e4875 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -716,10 +716,10 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A return res[:], state.Error() } -func (s *PublicBlockChainAPI) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { +func (s *PublicBlockChainAPI) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) { root, err := s.b.GetRootHash(ctx, starBlockNr, endBlockNr) if err != nil { - return nil, err + return "", err } return root, nil } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 21cef13f441506bdc7c7d38e356d9da287b03620..595a69b0cc2ebd6579b298e4aa01c15a6b76bec5 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -62,7 +62,7 @@ type Backend interface { SubscribeStateEvent(ch chan<- core.NewStateChangeEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription - GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) + GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) // Transaction pool API SendTx(ctx context.Context, signedTx *types.Transaction) error diff --git a/les/api_backend.go b/les/api_backend.go index 4739abcdebf951e96caefd8e46766dd391bbcbe2..3b228e7374625e5a23c82ebb706372969ee8439c 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -224,6 +224,6 @@ func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma } } -func (b *LesApiBackend) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { - return nil, errors.New("Not implemented") +func (b *LesApiBackend) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) { + return "", errors.New("Not implemented") }