diff --git a/pkg/eth/backend.go b/pkg/eth/backend.go index 07e4c709..b2a4d438 100644 --- a/pkg/eth/backend.go +++ b/pkg/eth/backend.go @@ -51,6 +51,8 @@ import ( var ( errPendingBlockNumber = errors.New("pending block number not supported") errNegativeBlockNumber = errors.New("negative block number not supported") + errHeaderHashNotFound = errors.New("header for hash not found") + errHeaderNotFound = errors.New("header not found") ) const ( @@ -599,7 +601,7 @@ func (b *Backend) GetAccountByNumber(ctx context.Context, address common.Address } hash, err := b.GetCanonicalHash(uint64(number)) if err == sql.ErrNoRows { - return nil, fmt.Errorf("header not found") + return nil, errHeaderNotFound } else if err != nil { return nil, err } @@ -611,7 +613,9 @@ func (b *Backend) GetAccountByNumber(ctx context.Context, address common.Address func (b *Backend) GetAccountByHash(ctx context.Context, address common.Address, hash common.Hash) (*state.Account, error) { _, err := b.HeaderByHash(context.Background(), hash) if err == sql.ErrNoRows { - return nil, fmt.Errorf("no canoncial block found for provided hash (%s)", hash) + return nil, errHeaderHashNotFound + } else if err != nil { + return nil, err } _, accountRlp, err := b.IPLDRetriever.RetrieveAccountByAddressAndBlockHash(address, hash) @@ -725,17 +729,24 @@ func (b *Backend) GetStorageByNumber(ctx context.Context, address common.Address return nil, errPendingBlockNumber } hash, err := b.GetCanonicalHash(uint64(number)) - if err != nil { + if err == sql.ErrNoRows { + return nil, errHeaderNotFound + } else if err != nil { return nil, err } - if hash == (common.Hash{}) { - return nil, fmt.Errorf("no canoncial block hash found for provided height (%d)", number) - } + return b.GetStorageByHash(ctx, address, storageLeafKey, hash) } // GetStorageByHash returns the storage value for the provided contract address an storage key at the block corresponding to the provided hash func (b *Backend) GetStorageByHash(ctx context.Context, address common.Address, storageLeafKey, hash common.Hash) (hexutil.Bytes, error) { + _, err := b.HeaderByHash(context.Background(), hash) + if err == sql.ErrNoRows { + return nil, errHeaderHashNotFound + } else if err != nil { + return nil, err + } + _, storageRlp, err := b.IPLDRetriever.RetrieveStorageAtByAddressAndStorageKeyAndBlockHash(address, storageLeafKey, hash) return storageRlp, err } diff --git a/pkg/eth/eth_state_test.go b/pkg/eth/eth_state_test.go index e9a45e43..d824be19 100644 --- a/pkg/eth/eth_state_test.go +++ b/pkg/eth/eth_state_test.go @@ -59,6 +59,7 @@ func init() { } var _ = Describe("eth state reading tests", func() { + const chainLength = 5 var ( blocks []*types.Block receipts []types.Receipts @@ -85,7 +86,7 @@ var _ = Describe("eth state reading tests", func() { api = eth.NewPublicEthAPI(backend, nil, false) // make the test blockchain (and state) - blocks, receipts, chain = test_helpers.MakeChain(5, test_helpers.Genesis, test_helpers.TestChainGen) + blocks, receipts, chain = test_helpers.MakeChain(chainLength, test_helpers.Genesis, test_helpers.TestChainGen) params := statediff.Params{ IntermediateStateNodes: true, IntermediateStorageNodes: true, @@ -491,6 +492,16 @@ var _ = Describe("eth state reading tests", func() { Expect(err).ToNot(HaveOccurred()) Expect(val).To(Equal(hexutil.Bytes{})) }) + It("Throws an error for a non-existing block hash", func() { + _, err := api.GetStorageAt(ctx, test_helpers.ContractAddr, test_helpers.IndexOne, rpc.BlockNumberOrHashWithHash(randomHash, true)) + Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError("header for hash not found")) + }) + It("Throws an error for a non-existing block number", func() { + _, err := api.GetStorageAt(ctx, test_helpers.ContractAddr, test_helpers.IndexOne, rpc.BlockNumberOrHashWithNumber(chainLength+1)) + Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError("header not found")) + }) }) Describe("eth_getHeaderByNumber", func() { diff --git a/test/integration_test.go b/test/integration_test.go index f883ffc6..43cb8626 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -380,6 +380,17 @@ var _ = Describe("Integration test", func() { Expect(err).ToNot(HaveOccurred()) Expect(gethStorage).To(Equal(ipldStorage)) }) + It("gets storage for non-existing block number", func() { + blockNum := contract.BlockNumber + 100 + totalSupplyIndex := "0x2" + + gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(int64(blockNum))) + Expect(err).To(MatchError("header not found")) + + ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(int64(blockNum))) + Expect(err).To(MatchError("header not found")) + Expect(gethStorage).To(Equal(ipldStorage)) + }) }) Describe("eth call", func() {