diff --git a/jsonrpc/filter_manager.go b/jsonrpc/filter_manager.go index fda97a77ce..a0c2b278ad 100644 --- a/jsonrpc/filter_manager.go +++ b/jsonrpc/filter_manager.go @@ -212,6 +212,9 @@ type filterManagerStore interface { // GetReceiptsByHash returns the receipts for a block hash GetReceiptsByHash(hash types.Hash) ([]*types.Receipt, error) + + // GetBlockByHash returns the block using the block hash + GetBlockByHash(hash types.Hash, full bool) (*types.Block, bool) } // FilterManager manages all running filters @@ -485,7 +488,18 @@ func (f *FilterManager) appendLogsToFilters(header *types.Header, removed bool) return nil } + block, ok := f.store.GetBlockByHash(header.Hash, true) + if !ok { + f.logger.Error("could not find block in store", "hash", header.Hash.String()) + + return nil + } + for indx, receipt := range receipts { + if receipt.TxHash == types.ZeroHash { + // Extract tx Hash + receipt.TxHash = block.Transactions[indx].Hash + } // check the logs with the filters for _, log := range receipt.Logs { nn := &Log{ diff --git a/jsonrpc/filter_manager_test.go b/jsonrpc/filter_manager_test.go index a043f8fe96..43e9cf440a 100644 --- a/jsonrpc/filter_manager_test.go +++ b/jsonrpc/filter_manager_test.go @@ -38,6 +38,7 @@ func TestFilterLog(t *testing.T) { }, }, }, + TxHash: hash3, }, }, }, @@ -56,6 +57,7 @@ func TestFilterLog(t *testing.T) { }, }, }, + TxHash: hash3, }, }, }, diff --git a/jsonrpc/mocks_test.go b/jsonrpc/mocks_test.go index 05fb47ccde..0c5ef06a51 100644 --- a/jsonrpc/mocks_test.go +++ b/jsonrpc/mocks_test.go @@ -114,6 +114,10 @@ func (m *mockStore) SubscribeEvents() blockchain.Subscription { return m.subscription } +func (m *mockStore) GetBlockByHash(hash types.Hash, full bool) (*types.Block, bool) { + return nil, false +} + func (m *mockStore) GetBlockByNumber(num uint64, full bool) (*types.Block, bool) { return nil, false } diff --git a/types/rlp_encoding_test.go b/types/rlp_encoding_test.go index 1a18fb6beb..3bedd8b0fb 100644 --- a/types/rlp_encoding_test.go +++ b/types/rlp_encoding_test.go @@ -65,8 +65,62 @@ func TestRLPMarshall_And_Unmarshall_Transaction(t *testing.T) { } } +func TestRLPStorage_Marshall_And_Unmarshall_Receipt(t *testing.T) { + addr := StringToAddress("11") + hash := StringToHash("10") + + testTable := []struct { + name string + receipt *Receipt + setStatus bool + }{ + { + "Marshal receipt with status", + &Receipt{ + CumulativeGasUsed: 10, + GasUsed: 100, + ContractAddress: addr, + TxHash: hash, + }, + true, + }, + { + "Marshal receipt without status", + &Receipt{ + Root: hash, + CumulativeGasUsed: 10, + GasUsed: 100, + ContractAddress: addr, + TxHash: hash, + }, + false, + }, + } + + for _, testCase := range testTable { + t.Run(testCase.name, func(t *testing.T) { + receipt := testCase.receipt + + if testCase.setStatus { + receipt.SetStatus(ReceiptSuccess) + } + + unmarshalledReceipt := new(Receipt) + marshaledRlp := receipt.MarshalStoreRLPTo(nil) + + if err := unmarshalledReceipt.UnmarshalStoreRLP(marshaledRlp); err != nil { + t.Fatal(err) + } + + if !assert.Exactly(t, receipt, unmarshalledReceipt) { + t.Fatal("[ERROR] Unmarshalled receipt not equal to base receipt") + } + }) + } +} + func TestRLPUnmarshal_Header_ComputeHash(t *testing.T) { - // header computes hash after unmarshaling + // header computes hash after unmarshalling h := &Header{} h.ComputeHash() diff --git a/types/rlp_marshal_storage.go b/types/rlp_marshal_storage.go index 254d2fc650..b6f8373d17 100644 --- a/types/rlp_marshal_storage.go +++ b/types/rlp_marshal_storage.go @@ -1,6 +1,8 @@ package types -import "github.com/umbracle/fastrlp" +import ( + "github.com/umbracle/fastrlp" +) type RLPStoreMarshaler interface { MarshalStoreRLPTo(dst []byte) []byte @@ -80,5 +82,8 @@ func (r *Receipt) MarshalStoreRLPWith(a *fastrlp.Arena) *fastrlp.Value { // gas used vv.Set(a.NewUint(r.GasUsed)) + // TxHash + vv.Set(a.NewBytes(r.TxHash.Bytes())) + return vv } diff --git a/types/rlp_unmarshal_storage.go b/types/rlp_unmarshal_storage.go index 3650778825..4845a74ec1 100644 --- a/types/rlp_unmarshal_storage.go +++ b/types/rlp_unmarshal_storage.go @@ -115,24 +115,23 @@ func (r *Receipt) UnmarshalStoreRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) err return err } - if len(elems) != 3 { - return fmt.Errorf("expected 3 elements") + if len(elems) < 3 { + return fmt.Errorf("expected at least 3 elements") } if err := r.UnmarshalRLPFrom(p, elems[0]); err != nil { return err } - { - // contract address - vv, err := elems[1].Bytes() - if err != nil { - return err - } - if len(vv) == 20 { - // address - r.ContractAddress = BytesToAddress(vv) - } + // contract address + vv, err := elems[1].Bytes() + if err != nil { + return err + } + + if len(vv) == 20 { + // address + r.ContractAddress = BytesToAddress(vv) } // gas used @@ -140,5 +139,16 @@ func (r *Receipt) UnmarshalStoreRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) err return err } + // tx hash + // backwards compatibility, old receipts did not marshal a TxHash + if len(elems) == 4 { + vv, err := elems[3].Bytes() + if err != nil { + return err + } + + r.TxHash = BytesToHash(vv) + } + return nil }