diff --git a/api/api.go b/api/api.go index 8cf478eb..beed8eb7 100644 --- a/api/api.go +++ b/api/api.go @@ -456,18 +456,16 @@ func (s *BlockChainAPI) GetLogs( if len(criteria.Topics) > maxTopics { return nil, errExceedMaxTopics } - log := &types.Log{ - Index: 1, - BlockNumber: 436, - BlockHash: common.HexToHash("0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d"), - TxHash: common.HexToHash("0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf"), - TxIndex: 0, - Address: common.HexToAddress("0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d"), - Data: []byte{0, 0, 0}, - Topics: []common.Hash{common.HexToHash("0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5")}, + + logs := []*types.Log{} + for _, topicList := range criteria.Topics { + for _, topic := range topicList { + matchingLogs := s.Store.LogsByTopic(topic.Hex()) + logs = append(logs, matchingLogs...) + } } - return []*types.Log{log}, nil + return logs, nil } // eth_newFilter diff --git a/api/api_test.go b/api/api_test.go index fd1792cf..1773637c 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -178,38 +178,20 @@ func TestBlockChainAPI(t *testing.T) { nonce := uint64(0) assert.Equal(t, txCount, (*hexutil.Uint64)(&nonce)) - evt := cadence.Event{ - EventType: cadence.NewEventType( - stdlib.FlowLocation{}, - "evm.TransactionExecuted", - []cadence.Field{ - cadence.NewField("blockHeight", cadence.UInt64Type{}), - cadence.NewField("transactionHash", cadence.StringType{}), - cadence.NewField("transaction", cadence.StringType{}), - cadence.NewField("failed", cadence.BoolType{}), - cadence.NewField("transactionType", cadence.UInt8Type{}), - cadence.NewField("gasConsumed", cadence.UInt64Type{}), - cadence.NewField("deployedContractAddress", cadence.StringType{}), - cadence.NewField("returnedValue", cadence.StringType{}), - cadence.NewField("logs", cadence.StringType{}), - }, - nil, - ), - Fields: []cadence.Value{ - cadence.NewUInt64(3), - cadence.String("0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c"), - cadence.String("b88c02f88982029a01808083124f809499466ed2e37b892a2ee3e9cd55a98b68f5735db280a4c6888fa10000000000000000000000000000000000000000000000000000000000000006c001a0f84168f821b427dc158c4d8083bdc4b43e178cf0977a2c5eefbcbedcc4e351b0a066a747a38c6c266b9dc2136523cef04395918de37773db63d574aabde59c12eb"), - cadence.NewBool(false), - cadence.NewUInt8(2), - cadence.NewUInt64(22514), - cadence.String("0000000000000000000000000000000000000000"), - cadence.String("000000000000000000000000000000000000000000000000000000000000002a"), - cadence.String("f85af8589499466ed2e37b892a2ee3e9cd55a98b68f5735db2e1a024abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503daa0000000000000000000000000000000000000000000000000000000000000002a"), - }, - } + event := transactionExecutedEvent( + 3, + "0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c", + "b88c02f88982029a01808083124f809499466ed2e37b892a2ee3e9cd55a98b68f5735db280a4c6888fa10000000000000000000000000000000000000000000000000000000000000006c001a0f84168f821b427dc158c4d8083bdc4b43e178cf0977a2c5eefbcbedcc4e351b0a066a747a38c6c266b9dc2136523cef04395918de37773db63d574aabde59c12eb", + false, + 2, + 22514, + "0000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000002a", + "f85af8589499466ed2e37b892a2ee3e9cd55a98b68f5735db2e1a024abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503daa0000000000000000000000000000000000000000000000000000000000000002a", + ) store := blockchainAPI.Store - store.UpdateAccountNonce(context.Background(), evt) + store.UpdateAccountNonce(context.Background(), event) txCount, err = blockchainAPI.GetTransactionCount( context.Background(), @@ -477,15 +459,46 @@ func TestBlockChainAPI(t *testing.T) { ) require.NoError(t, err) + assert.Equal(t, []*types.Log{}, logs) + + event := transactionExecutedEvent( + 3, + "0xb47d74ea64221eb941490bdc0c9a404dacd0a8573379a45c992ac60ee3e83c3c", + "b88c02f88982029a01808083124f809499466ed2e37b892a2ee3e9cd55a98b68f5735db280a4c6888fa10000000000000000000000000000000000000000000000000000000000000006c001a0f84168f821b427dc158c4d8083bdc4b43e178cf0977a2c5eefbcbedcc4e351b0a066a747a38c6c266b9dc2136523cef04395918de37773db63d574aabde59c12eb", + false, + 2, + 22514, + "0000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000002a", + "f85af8589499466ed2e37b892a2ee3e9cd55a98b68f5735db2e1a024abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503daa0000000000000000000000000000000000000000000000000000000000000002a", + ) + + store := blockchainAPI.Store + store.StoreLog(context.Background(), event) + + logs, err = blockchainAPI.GetLogs( + context.Background(), + filters.FilterCriteria{ + Topics: [][]common.Hash{ + { + common.HexToHash("0x24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da"), + }, + }, + }, + ) + require.NoError(t, err) + + data, err := hex.DecodeString("000000000000000000000000000000000000000000000000000000000000002a") + require.NoError(t, err) log := &types.Log{ - Index: 1, - BlockNumber: 436, - BlockHash: common.HexToHash("0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d"), - TxHash: common.HexToHash("0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf"), + Index: 0, + BlockNumber: 0, + BlockHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + TxHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), TxIndex: 0, - Address: common.HexToAddress("0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d"), - Data: []byte{0, 0, 0}, - Topics: []common.Hash{common.HexToHash("0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5")}, + Address: common.HexToAddress("0x99466ed2e37b892a2ee3e9cd55a98b68f5735db2"), + Data: data, + Topics: []common.Hash{common.HexToHash("0x24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da")}, } assert.Equal(t, []*types.Log{log}, logs) @@ -747,3 +760,45 @@ func TestBlockChainAPI(t *testing.T) { ) }) } + +func transactionExecutedEvent( + blockHeight uint64, + transactionHash string, + transaction string, + failed bool, + transactionType uint8, + gasConsumed uint64, + deployedContractAddress string, + returnedValue string, + logs string, +) cadence.Event { + return cadence.Event{ + EventType: cadence.NewEventType( + stdlib.FlowLocation{}, + "evm.TransactionExecuted", + []cadence.Field{ + cadence.NewField("blockHeight", cadence.UInt64Type{}), + cadence.NewField("transactionHash", cadence.StringType{}), + cadence.NewField("transaction", cadence.StringType{}), + cadence.NewField("failed", cadence.BoolType{}), + cadence.NewField("transactionType", cadence.UInt8Type{}), + cadence.NewField("gasConsumed", cadence.UInt64Type{}), + cadence.NewField("deployedContractAddress", cadence.StringType{}), + cadence.NewField("returnedValue", cadence.StringType{}), + cadence.NewField("logs", cadence.StringType{}), + }, + nil, + ), + Fields: []cadence.Value{ + cadence.NewUInt64(blockHeight), + cadence.String(transactionHash), + cadence.String(transaction), + cadence.NewBool(failed), + cadence.NewUInt8(transactionType), + cadence.NewUInt64(gasConsumed), + cadence.String(deployedContractAddress), + cadence.String(returnedValue), + cadence.String(logs), + }, + } +} diff --git a/api/fixtures/eth_json_rpc_requests.json b/api/fixtures/eth_json_rpc_requests.json index 7d368fa8..2166e21c 100644 --- a/api/fixtures/eth_json_rpc_requests.json +++ b/api/fixtures/eth_json_rpc_requests.json @@ -18,7 +18,7 @@ {"jsonrpc":"2.0","id":1,"method":"eth_getBlockTransactionCountByNumber","params":["0xe8"]} {"jsonrpc":"2.0","id":1,"method":"eth_getUncleCountByBlockHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"]} {"jsonrpc":"2.0","id":1,"method":"eth_getUncleCountByBlockNumber","params":["0xe8"]} -{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}]} +{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"topics":[]}]} {"jsonrpc":"2.0","id":1,"method":"eth_newFilter","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}]} {"jsonrpc":"2.0","id":1,"method":"eth_uninstallFilter","params":["0xb"]} {"jsonrpc":"2.0","id":1,"method":"eth_getFilterLogs","params":["0x16"]} diff --git a/api/fixtures/eth_json_rpc_responses.json b/api/fixtures/eth_json_rpc_responses.json index 0cf95f43..5543f85a 100644 --- a/api/fixtures/eth_json_rpc_responses.json +++ b/api/fixtures/eth_json_rpc_responses.json @@ -18,7 +18,7 @@ {"jsonrpc":"2.0","id":1,"result":"0x20a"} {"jsonrpc":"2.0","id":1,"result":"0x0"} {"jsonrpc":"2.0","id":1,"result":"0x0"} -{"jsonrpc":"2.0","id":1,"result":[{"address":"0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d","topics":["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"],"data":"0x000000","blockNumber":"0x1b4","transactionHash":"0x00df829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf","transactionIndex":"0x0","blockHash":"0x008216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d","logIndex":"0x1","removed":false}]} +{"jsonrpc":"2.0","id":1,"result":[]} {"jsonrpc":"2.0","id":1,"result":"filter0"} {"jsonrpc":"2.0","id":1,"result":true} {"jsonrpc":"2.0","id":1,"result":[{"address":"0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d","topics":["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"],"data":"0x000000","blockNumber":"0x1b4","transactionHash":"0x00df829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf","transactionIndex":"0x0","blockHash":"0x008216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d","logIndex":"0x1","removed":false}]} diff --git a/cmd/server/main.go b/cmd/server/main.go index cfa8fed8..d26a2581 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -140,6 +140,7 @@ func runIndexer(ctx context.Context, store *storage.Store, logger zerolog.Logger logger.Info().Msgf(" %s", event.Value) if event.Type == "flow.evm.TransactionExecuted" { store.UpdateAccountNonce(ctx, event.Value) + store.StoreLog(ctx, event.Value) } } diff --git a/storage/store.go b/storage/store.go index 2c915b71..e212dd26 100644 --- a/storage/store.go +++ b/storage/store.go @@ -14,6 +14,7 @@ import ( type Store struct { mu sync.RWMutex + logsByTopic map[string][]*types.Log latestHeight uint64 accountNonce map[common.Address]uint64 } @@ -26,6 +27,7 @@ type Store struct { func NewStore() *Store { return &Store{ accountNonce: make(map[common.Address]uint64), + logsByTopic: make(map[string][]*types.Log), } } @@ -90,6 +92,38 @@ func (s *Store) UpdateAccountNonce(ctx context.Context, event cadence.Event) { s.accountNonce[from] = s.accountNonce[from] + 1 } +func (s *Store) StoreLog(ctx context.Context, event cadence.Event) { + s.mu.Lock() + defer s.mu.Unlock() + + logValue := event.GetFieldValues()[8] + logC, ok := logValue.(cadence.String) + if !ok { + return + } + logS := logC.ToGoValue().(string) + if len(logS) == 0 { + return + } + bt, err := hex.DecodeString(logS) + if err != nil { + panic(err) + } + logs := []*types.Log{} + err = rlp.Decode(bytes.NewReader(bt), &logs) + if err != nil { + panic(err) + } + for _, log := range logs { + topic := log.Topics[0].Hex() + s.logsByTopic[topic] = append(s.logsByTopic[topic], logs...) + } +} + +func (s *Store) LogsByTopic(topic string) []*types.Log { + return s.logsByTopic[topic] +} + func (s *Store) StoreBlockHeight(ctx context.Context, blockHeight uint64) error { s.mu.Lock() defer s.mu.Unlock()