diff --git a/rpc/contract.go b/rpc/contract.go index e0eb3b7c2..a770bb284 100644 --- a/rpc/contract.go +++ b/rpc/contract.go @@ -39,6 +39,13 @@ 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.ContractNonce(&address) + if err != nil { + return nil, ErrContractNotFound + } + 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 8f9e100aa..dc84a37fd 100644 --- a/rpc/contract_test.go +++ b/rpc/contract_test.go @@ -123,7 +123,8 @@ 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")) + // we check if the contract exists by getting its nonce + mockState.EXPECT().ContractNonce(gomock.Any()).Return(nil, errors.New("non-existent contract")) storage, rpcErr := handler.StorageAt(felt.Zero, felt.Zero, rpc.BlockID{Latest: true}) require.Nil(t, storage) @@ -132,7 +133,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")) + // we check if the contract exists by getting its nonce + mockState.EXPECT().ContractNonce(gomock.Any()).Return(nil, errors.New("non-existent contract")) storage, rpcErr := handler.StorageAt(felt.Zero, felt.Zero, rpc.BlockID{Latest: true}) require.Nil(t, storage) @@ -143,6 +145,7 @@ func TestStorageAt(t *testing.T) { t.Run("blockID - latest", func(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) + mockState.EXPECT().ContractNonce(&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 +155,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().ContractNonce(&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 +165,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().ContractNonce(&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})