diff --git a/rpc/contract.go b/rpc/contract.go index e0eb3b7c2a..a33f84399e 100644 --- a/rpc/contract.go +++ b/rpc/contract.go @@ -1,7 +1,10 @@ package rpc import ( + "errors" + "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/db" "github.com/NethermindEth/juno/jsonrpc" ) @@ -39,6 +42,17 @@ func (h *Handler) StorageAt(address, key felt.Felt, id BlockID) (*felt.Felt, *js } defer h.callAndLogErr(stateCloser, "Error closing state reader in getStorageAt") + // This checks if the contract exists because if a key doesn't exist in contract storage, + // the returned value is always zero and error is nil. + _, err := stateReader.ContractClassHash(&address) + if err != nil { + if errors.Is(err, db.ErrKeyNotFound) { + return nil, ErrContractNotFound + } + h.log.Errorw("Failed to get contract nonce", "err", err) + return nil, ErrInternal + } + value, err := stateReader.ContractStorage(&address, &key) if err != nil { return nil, ErrContractNotFound diff --git a/rpc/contract_test.go b/rpc/contract_test.go index 8f9e100aa3..c9abb5214e 100644 --- a/rpc/contract_test.go +++ b/rpc/contract_test.go @@ -123,7 +123,7 @@ func TestStorageAt(t *testing.T) { t.Run("non-existent contract", func(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) - mockState.EXPECT().ContractStorage(gomock.Any(), gomock.Any()).Return(nil, errors.New("non-existent contract")) + mockState.EXPECT().ContractClassHash(gomock.Any()).Return(nil, db.ErrKeyNotFound) storage, rpcErr := handler.StorageAt(felt.Zero, felt.Zero, rpc.BlockID{Latest: true}) require.Nil(t, storage) @@ -132,7 +132,8 @@ func TestStorageAt(t *testing.T) { t.Run("non-existent key", func(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) - mockState.EXPECT().ContractStorage(gomock.Any(), gomock.Any()).Return(&felt.Zero, errors.New("non-existent key")) + mockState.EXPECT().ContractClassHash(&felt.Zero).Return(nil, nil) + mockState.EXPECT().ContractStorage(gomock.Any(), gomock.Any()).Return(nil, db.ErrKeyNotFound) storage, rpcErr := handler.StorageAt(felt.Zero, felt.Zero, rpc.BlockID{Latest: true}) require.Nil(t, storage) @@ -143,6 +144,7 @@ func TestStorageAt(t *testing.T) { t.Run("blockID - latest", func(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) + mockState.EXPECT().ContractClassHash(&felt.Zero).Return(nil, nil) mockState.EXPECT().ContractStorage(gomock.Any(), gomock.Any()).Return(expectedStorage, nil) storage, rpcErr := handler.StorageAt(felt.Zero, felt.Zero, rpc.BlockID{Latest: true}) @@ -152,6 +154,7 @@ func TestStorageAt(t *testing.T) { t.Run("blockID - hash", func(t *testing.T) { mockReader.EXPECT().StateAtBlockHash(&felt.Zero).Return(mockState, nopCloser, nil) + mockState.EXPECT().ContractClassHash(&felt.Zero).Return(nil, nil) mockState.EXPECT().ContractStorage(gomock.Any(), gomock.Any()).Return(expectedStorage, nil) storage, rpcErr := handler.StorageAt(felt.Zero, felt.Zero, rpc.BlockID{Hash: &felt.Zero}) @@ -161,6 +164,7 @@ func TestStorageAt(t *testing.T) { t.Run("blockID - number", func(t *testing.T) { mockReader.EXPECT().StateAtBlockNumber(uint64(0)).Return(mockState, nopCloser, nil) + mockState.EXPECT().ContractClassHash(&felt.Zero).Return(nil, nil) mockState.EXPECT().ContractStorage(gomock.Any(), gomock.Any()).Return(expectedStorage, nil) storage, rpcErr := handler.StorageAt(felt.Zero, felt.Zero, rpc.BlockID{Number: 0})