From f5d8ac31576b3522facae871921eaaefaa2a87b7 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:21:58 +0200 Subject: [PATCH 01/27] add helper with setup --- tests/helpers.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/helpers.go b/tests/helpers.go index 4c59609b..a1d169d5 100644 --- a/tests/helpers.go +++ b/tests/helpers.go @@ -100,14 +100,26 @@ func startEmulator(createTestAccounts bool) (*server.EmulatorServer, error) { // runWeb3Test will run the test by name, the name // must match an existing js test file (without the extension) func runWeb3Test(t *testing.T, name string) { - stop := servicesSetup(t) + _, stop := servicesSetup(t) + executeTest(t, name) + stop() +} + +func runWeb3TestWithSetup( + t *testing.T, + name string, + setupFunc func(emu emulator.Emulator) error, +) { + emu, stop := servicesSetup(t) + err := setupFunc(emu) + require.NoError(t, err) executeTest(t, name) stop() } // servicesSetup starts up an emulator and the gateway // engines required for operation of the evm gateway. -func servicesSetup(t *testing.T) func() { +func servicesSetup(t *testing.T) (emulator.Emulator, func()) { srv, err := startEmulator(true) require.NoError(t, err) @@ -144,7 +156,7 @@ func servicesSetup(t *testing.T) func() { }() time.Sleep(1 * time.Second) // some time to startup - return func() { + return emu, func() { cancel() srv.Stop() } From 5a767fe17185b9c50c1217c14a628c1150a660ee Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:26:11 +0200 Subject: [PATCH 02/27] add test for batch --- tests/web3js/eth_batch_retrival_test.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/web3js/eth_batch_retrival_test.js diff --git a/tests/web3js/eth_batch_retrival_test.js b/tests/web3js/eth_batch_retrival_test.js new file mode 100644 index 00000000..2a38d57d --- /dev/null +++ b/tests/web3js/eth_batch_retrival_test.js @@ -0,0 +1,25 @@ +const { assert } = require('chai') +const conf = require('./config') +const helpers = require('./helpers') +const web3 = conf.web3 + +it('retrieve batch transactions', async() => { + let latestHeight = await web3.eth.getBlockNumber() + let block = await web3.eth.getBlock(latestHeight) + console.log(block) + assert.lengthOf(block.transactions, 2) + + let deployTx = await web3.eth.getTransactionFromBlock(latestHeight, 0) + console.log(deployTx) + assert.equal(block.number, deployTx.blockNumber) + assert.equal(block.hash, deployTx.blockHash) + assert.equal(0, deployTx.type) + assert.equal(0, deployTx.transactionIndex) + + let callTx = await web3.eth.getTransactionFromBlock(latestHeight, 1) + console.log(callTx) + assert.equal(block.number, callTx.blockNumber) + assert.equal(block.hash, callTx.blockHash) + assert.equal(0, callTx.type) + assert.equal(1, callTx.transactionIndex) +}) \ No newline at end of file From ca9197b29b6f5f7c1b628cea1e34cd49d05c9631 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:15:29 +0200 Subject: [PATCH 03/27] change interface to return list of receipts --- storage/index.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/index.go b/storage/index.go index e7357e25..0fae0a58 100644 --- a/storage/index.go +++ b/storage/index.go @@ -64,8 +64,7 @@ type ReceiptIndexer interface { // GetByBlockHeight returns the receipt for the block height. // Expected errors: // - errors.NotFound if the receipt is not found - // TODO right now one transaction per block, but this might change in future so the API needs to be updated. - GetByBlockHeight(height *big.Int) (*gethTypes.Receipt, error) + GetByBlockHeight(height *big.Int) ([]*gethTypes.Receipt, error) // BloomsForBlockRange returns slice of bloom values and a slice of block heights // corresponding to each item in the bloom slice. It only matches the blooms between From 0fc58f2b502bdb37cbaef13cf27482a54ebb5127 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:15:37 +0200 Subject: [PATCH 04/27] add comments --- storage/pebble/receipts.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/storage/pebble/receipts.go b/storage/pebble/receipts.go index 78e6c27a..5cb429d2 100644 --- a/storage/pebble/receipts.go +++ b/storage/pebble/receipts.go @@ -29,6 +29,13 @@ func NewReceipts(store *Storage) *Receipts { } } +// Store receipt in the index. +// +// Storing receipt will create multiple indexes, each receipt has a transaction ID, +// and a block height. We create following mappings: +// - receipt transaction ID => block height bytes +// - receipt block height => list of encoded receipts (1+ per block) +// - receipt block height => list of bloom filters (1+ per block) func (r *Receipts) Store(receipt *gethTypes.Receipt) error { r.mux.Lock() defer r.mux.Unlock() @@ -81,13 +88,13 @@ func (r *Receipts) GetByTransactionID(ID common.Hash) (*gethTypes.Receipt, error return rcp, nil } -func (r *Receipts) GetByBlockHeight(height *big.Int) (*gethTypes.Receipt, error) { +func (r *Receipts) GetByBlockHeight(height *big.Int) ([]*gethTypes.Receipt, error) { r.mux.RLock() defer r.mux.RUnlock() return r.getByBlockHeight(height.Bytes()) } -func (r *Receipts) getByBlockHeight(height []byte) (*gethTypes.Receipt, error) { +func (r *Receipts) getByBlockHeight(height []byte) ([]*gethTypes.Receipt, error) { val, err := r.store.get(receiptHeightKey, height) if err != nil { return nil, err From 4b169c22dc2b03ce5b84c83f1a64049d4fe19d86 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:28:52 +0200 Subject: [PATCH 05/27] change events to return map of height to tx/receipt --- models/events.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/models/events.go b/models/events.go index 942d4bb4..eb4cba42 100644 --- a/models/events.go +++ b/models/events.go @@ -60,33 +60,37 @@ func (c *CadenceEvents) Blocks() ([]*types.Block, error) { return blocks, nil } -// Transactions finds all the transactions evm events and decodes them into transaction slice, +// Transactions finds all the transactions evm events and decodes them into transaction map, +// that has block height as the key, and all transactions at that height as the value, // if no transactions is found nil is returned. // // Return values: -// []transaction, nil - if transactions are found +// block_height => []transaction, nil - if transactions are found // nil, nil - if no transactions are found // nil, err - unexpected error -func (c *CadenceEvents) Transactions() ([]Transaction, []*gethTypes.Receipt, error) { - txs := make([]Transaction, 0) - rcps := make([]*gethTypes.Receipt, 0) +func (c *CadenceEvents) Transactions() (map[uint64][]*Transaction, map[uint64][]*gethTypes.Receipt, error) { + txs := make(map[uint64][]*Transaction) + receipts := make(map[uint64][]*gethTypes.Receipt) + for _, e := range c.events.Events { if isTransactionExecutedEvent(e.Value) { tx, err := decodeTransaction(e.Value) if err != nil { return nil, nil, err } + rcp, err := decodeReceipt(e.Value) if err != nil { return nil, nil, err } - txs = append(txs, tx) - rcps = append(rcps, rcp) + height := rcp.BlockNumber.Uint64() + txs[height] = append(txs[height], &tx) + receipts[height] = append(receipts[height], rcp) } } - return txs, rcps, nil + return txs, receipts, nil } // Empty checks if there are any evm block or transactions events. From 399133abce546d2ac43b76c7d9ad05f05b329482 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:24:50 +0200 Subject: [PATCH 06/27] add test for batched txs --- tests/e2e_web3js_test.go | 47 +++++++++++++++++++ ...al_test.js => eth_batch_retrieval_test.js} | 0 2 files changed, 47 insertions(+) rename tests/web3js/{eth_batch_retrival_test.js => eth_batch_retrieval_test.js} (100%) diff --git a/tests/e2e_web3js_test.go b/tests/e2e_web3js_test.go index d8f12f86..2551138c 100644 --- a/tests/e2e_web3js_test.go +++ b/tests/e2e_web3js_test.go @@ -1,6 +1,8 @@ package tests import ( + "github.com/onflow/cadence" + "github.com/onflow/flow-emulator/emulator" "testing" ) @@ -33,4 +35,49 @@ func TestWeb3_E2E(t *testing.T) { t.Run("streaming of entities and subscription", func(t *testing.T) { runWeb3Test(t, "eth_streaming_test") }) + + t.Run("batch run transactions", func(t *testing.T) { + runWeb3TestWithSetup(t, "eth_batch_retrieval_test", func(emu emulator.Emulator) error { + code := ` + transaction(tx1: String, tx2: String) { + let coa: &EVM.CadenceOwnedAccount + prepare(signer: auth(Storage) &Account) { + self.coa = signer.storage.borrow<&EVM.CadenceOwnedAccount>( + from: /storage/evm + ) ?? panic("Could not borrow reference to the COA!") + } + execute { + let txs: [[UInt8]] = [tx1.decodeHex(), tx2.decodeHex()] + let txResults = EVM.batchRun( + txs: txs, + coinbase: self.coa.address() + ) + for txResult in txResults { + assert( + txResult.status == EVM.Status.successful, + message: "failed to execute evm transaction: ".concat(txResult.errorCode.toString()) + ) + } + } + } + ` + + tx1, err := cadence.NewString("f9015880808301e8488080b901086060604052341561000f57600080fd5b60eb8061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60007f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da600783026040518082815260200191505060405180910390a16007820290509190505600a165627a7a7230582040383f19d9f65246752244189b02f56e8d0980ed44e7a56c0b200458caad20bb002982052fa09c05a7389284dc02b356ec7dee8a023c5efd3a9d844fa3c481882684b0640866a057e96d0a71a857ed509bb2b7333e78b2408574b8cc7f51238f25c58812662653") + if err != nil { + return err + } + tx2, err := cadence.NewString("f885018082c3509499466ed2e37b892a2ee3e9cd55a98b68f5735db280a4c6888fa10000000000000000000000000000000000000000000000000000000000000006820530a03547bcd56e6c6103e78c8c3b34f480108f66ad37282d887033b8c5951f0c70a0a00f5136f6033244a265e1ebaf48cf83d4fdf13f53b468d8fd924c9deb1537dd8d") + if err != nil { + return err + } + res, err := flowSendTransaction(emu, code, tx1, tx2) + if err != nil { + return err + } + if res.Error != nil { + return res.Error + } + return nil + }) + }) } diff --git a/tests/web3js/eth_batch_retrival_test.js b/tests/web3js/eth_batch_retrieval_test.js similarity index 100% rename from tests/web3js/eth_batch_retrival_test.js rename to tests/web3js/eth_batch_retrieval_test.js From e2db84abaa6b1e52d9ac6a9e6bffaa12fd986d52 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:25:54 +0200 Subject: [PATCH 07/27] Revert "change events to return map of height to tx/receipt" This reverts commit 4b169c22dc2b03ce5b84c83f1a64049d4fe19d86. --- models/events.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/models/events.go b/models/events.go index eb4cba42..942d4bb4 100644 --- a/models/events.go +++ b/models/events.go @@ -60,37 +60,33 @@ func (c *CadenceEvents) Blocks() ([]*types.Block, error) { return blocks, nil } -// Transactions finds all the transactions evm events and decodes them into transaction map, -// that has block height as the key, and all transactions at that height as the value, +// Transactions finds all the transactions evm events and decodes them into transaction slice, // if no transactions is found nil is returned. // // Return values: -// block_height => []transaction, nil - if transactions are found +// []transaction, nil - if transactions are found // nil, nil - if no transactions are found // nil, err - unexpected error -func (c *CadenceEvents) Transactions() (map[uint64][]*Transaction, map[uint64][]*gethTypes.Receipt, error) { - txs := make(map[uint64][]*Transaction) - receipts := make(map[uint64][]*gethTypes.Receipt) - +func (c *CadenceEvents) Transactions() ([]Transaction, []*gethTypes.Receipt, error) { + txs := make([]Transaction, 0) + rcps := make([]*gethTypes.Receipt, 0) for _, e := range c.events.Events { if isTransactionExecutedEvent(e.Value) { tx, err := decodeTransaction(e.Value) if err != nil { return nil, nil, err } - rcp, err := decodeReceipt(e.Value) if err != nil { return nil, nil, err } - height := rcp.BlockNumber.Uint64() - txs[height] = append(txs[height], &tx) - receipts[height] = append(receipts[height], rcp) + txs = append(txs, tx) + rcps = append(rcps, rcp) } } - return txs, receipts, nil + return txs, rcps, nil } // Empty checks if there are any evm block or transactions events. From 3de63ad14fd85c4cd2ba2789ac0130eaeb71b299 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:45:23 +0200 Subject: [PATCH 08/27] change receipt to store list of receipts --- storage/pebble/receipts.go | 74 ++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/storage/pebble/receipts.go b/storage/pebble/receipts.go index 5cb429d2..3910715f 100644 --- a/storage/pebble/receipts.go +++ b/storage/pebble/receipts.go @@ -2,6 +2,7 @@ package pebble import ( "encoding/binary" + "errors" "fmt" "math/big" "sync" @@ -9,7 +10,7 @@ import ( "github.com/cockroachdb/pebble" "github.com/onflow/flow-evm-gateway/models" "github.com/onflow/flow-evm-gateway/storage" - "github.com/onflow/flow-evm-gateway/storage/errors" + errs "github.com/onflow/flow-evm-gateway/storage/errors" "github.com/onflow/go-ethereum/common" gethTypes "github.com/onflow/go-ethereum/core/types" "github.com/onflow/go-ethereum/rlp" @@ -40,26 +41,44 @@ func (r *Receipts) Store(receipt *gethTypes.Receipt) error { r.mux.Lock() defer r.mux.Unlock() - // convert to storage receipt to preserve all values - rr := (*models.StorageReceipt)(receipt) - val, err := rlp.EncodeToBytes(rr) - if err != nil { - return err + // we must first retrieve any already saved receipts at the provided height, + // and if found we must add to the list, because this method can be called multiple + // times when indexing a single EVM height, which can contain multiple receipts + receipts, err := r.GetByBlockHeight(receipt.BlockNumber) + if !errors.Is(err, errs.ErrNotFound) { // anything but not found is failure + return fmt.Errorf("failed to store receipt to height, retrieve errror: %w", err) } + // add new receipt to the list of all receipts, if the receipts do not yet exist at the + // provided height, the above get will return ErrNotFound (which we ignore) and the bellow + // line will init an empty receipts slice with only the provided receipt + receipts = append(receipts, receipt) + batch := r.store.newBatch() defer batch.Close() + // convert to storage receipt to preserve all values + storeReceipts := make([]*models.StorageReceipt, len(receipts)) + for i, rr := range receipts { + storeReceipts[i] = (*models.StorageReceipt)(rr) + } + + val, err := rlp.EncodeToBytes(storeReceipts) + if err != nil { + return err + } + height := receipt.BlockNumber.Bytes() + if err := r.store.set(receiptTxIDToHeightKey, receipt.TxHash.Bytes(), height, batch); err != nil { return fmt.Errorf("failed to store receipt tx height: %w", err) } - // todo if there are more transactions per block we need to update this if err := r.store.set(receiptHeightKey, height, val, batch); err != nil { return fmt.Errorf("failed to store receipt height: %w", err) } + // todo support multiple heights if err := r.store.set(bloomHeightKey, height, receipt.Bloom.Bytes(), batch); err != nil { return fmt.Errorf("failed to store bloom height: %w", err) } @@ -80,12 +99,18 @@ func (r *Receipts) GetByTransactionID(ID common.Hash) (*gethTypes.Receipt, error return nil, fmt.Errorf("failed to get receipt by tx ID: %w", err) } - rcp, err := r.getByBlockHeight(height) + receipts, err := r.getByBlockHeight(height) if err != nil { return nil, fmt.Errorf("failed to get receipt by height: %w", err) } - return rcp, nil + for _, rcp := range receipts { + if rcp.TxHash.Cmp(ID) == 0 { + return rcp, nil + } + } + + return nil, errs.ErrNotFound } func (r *Receipts) GetByBlockHeight(height *big.Int) ([]*gethTypes.Receipt, error) { @@ -100,27 +125,32 @@ func (r *Receipts) getByBlockHeight(height []byte) ([]*gethTypes.Receipt, error) return nil, err } - var rcp models.StorageReceipt - err = rlp.DecodeBytes(val, &rcp) + var storeReceipts []*models.StorageReceipt + err = rlp.DecodeBytes(val, &storeReceipts) if err != nil { return nil, err } - // dynamically populate the values since they are not stored to save space - for i, l := range rcp.Logs { - l.BlockHash = rcp.BlockHash - l.BlockNumber = rcp.BlockNumber.Uint64() - l.TxHash = rcp.TxHash - l.TxIndex = rcp.TransactionIndex - l.Index = uint(i) + receipts := make([]*gethTypes.Receipt, len(storeReceipts)) + for i, rcp := range storeReceipts { + // dynamically populate the values since they are not stored to save space + for i, l := range rcp.Logs { + l.BlockHash = rcp.BlockHash + l.BlockNumber = rcp.BlockNumber.Uint64() + l.TxHash = rcp.TxHash + l.TxIndex = rcp.TransactionIndex + l.Index = uint(i) + } + + receipts[i] = (*gethTypes.Receipt)(rcp) } - return (*gethTypes.Receipt)(&rcp), nil + return receipts, nil } func (r *Receipts) BloomsForBlockRange(start, end *big.Int) ([]*gethTypes.Bloom, []*big.Int, error) { if start.Cmp(end) > 0 { - return nil, nil, fmt.Errorf("start is bigger than end: %w", errors.ErrInvalidRange) + return nil, nil, fmt.Errorf("start is bigger than end: %w", errs.ErrInvalidRange) } // make sure the first and last height are within indexed values @@ -134,7 +164,7 @@ func (r *Receipts) BloomsForBlockRange(start, end *big.Int) ([]*gethTypes.Bloom, "start value %d is not within the indexed range of [0 - %d]: %w", start, last, - errors.ErrInvalidRange, + errs.ErrInvalidRange, ) } @@ -143,7 +173,7 @@ func (r *Receipts) BloomsForBlockRange(start, end *big.Int) ([]*gethTypes.Bloom, "end value %d is not within the indexed range of [0 - %d]: %w", end, last, - errors.ErrInvalidRange, + errs.ErrInvalidRange, ) } From 5de73d7dbc560f0a2d8d477486d68192cdd0f855 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:49:30 +0200 Subject: [PATCH 09/27] add filters for multiple receipts --- services/logs/filter.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/services/logs/filter.go b/services/logs/filter.go index 113da269..5ef41e72 100644 --- a/services/logs/filter.go +++ b/services/logs/filter.go @@ -65,14 +65,16 @@ func (r *RangeFilter) Match() ([]*gethTypes.Log, error) { } // todo do this concurrently - receipt, err := r.receipts.GetByBlockHeight(heights[i]) + receipts, err := r.receipts.GetByBlockHeight(heights[i]) if err != nil { return nil, err } - for _, log := range receipt.Logs { - if exactMatch(log, r.criteria) { - logs = append(logs, log) + for _, receipt := range receipts { + for _, log := range receipt.Logs { + if exactMatch(log, r.criteria) { + logs = append(logs, log) + } } } } @@ -109,15 +111,17 @@ func (i *IDFilter) Match() ([]*gethTypes.Log, error) { return nil, err } - receipt, err := i.receipts.GetByBlockHeight(big.NewInt(int64(blk.Height))) + receipts, err := i.receipts.GetByBlockHeight(big.NewInt(int64(blk.Height))) if err != nil { return nil, err } logs := make([]*gethTypes.Log, 0) - for _, log := range receipt.Logs { - if exactMatch(log, i.criteria) { - logs = append(logs, log) + for _, receipt := range receipts { + for _, log := range receipt.Logs { + if exactMatch(log, i.criteria) { + logs = append(logs, log) + } } } From 583a421d55f87dae4eed3d6b3f6e1afa6a6b71e2 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:49:34 +0200 Subject: [PATCH 10/27] fix test --- storage/index_testsuite.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/index_testsuite.go b/storage/index_testsuite.go index 64ea152c..6d587cbe 100644 --- a/storage/index_testsuite.go +++ b/storage/index_testsuite.go @@ -161,9 +161,9 @@ func (s *ReceiptTestSuite) TestGetReceiptByBlockID() { err := s.ReceiptIndexer.Store(receipt) s.Require().NoError(err) - retReceipt, err := s.ReceiptIndexer.GetByBlockHeight(receipt.BlockNumber) + retReceipts, err := s.ReceiptIndexer.GetByBlockHeight(receipt.BlockNumber) s.Require().NoError(err) - s.compareReceipts(receipt, retReceipt) + s.compareReceipts(receipt, retReceipts[0]) }) s.Run("non-existing block height", func() { From a84996aa1d29bd134f78023f0c0ea3af848b33b7 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:51:40 +0200 Subject: [PATCH 11/27] update mocks --- go.mod | 6 ++++++ go.sum | 8 ++++++++ storage/mocks/ReceiptIndexer.go | 10 +++++----- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index b0fc0d37..2361b959 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chigopher/pathlib v0.12.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect @@ -84,6 +85,7 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/goprocess v0.1.4 // indirect + github.com/jinzhu/copier v0.3.5 // indirect github.com/k0kubun/pp v3.0.1+incompatible // indirect github.com/kevinburke/go-bindata v3.24.0+incompatible // indirect github.com/klauspost/compress v1.17.4 // indirect @@ -99,6 +101,7 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/minio/sha256-simd v1.0.1 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect @@ -155,6 +158,7 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/vektra/mockery/v2 v2.21.4 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.11 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect @@ -174,6 +178,7 @@ require ( golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect @@ -185,6 +190,7 @@ require ( google.golang.org/grpc v1.63.2 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect diff --git a/go.sum b/go.sum index 80eb63f1..d05c13c7 100644 --- a/go.sum +++ b/go.sum @@ -1092,6 +1092,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chigopher/pathlib v0.12.0 h1:1GM7fN/IwXXmOHbd1jkMqHD2wUhYqUvafgxTwmLT/q8= +github.com/chigopher/pathlib v0.12.0/go.mod h1:EJ5UtJ/sK8Nt6q3VWN+EwZLZ3g0afJiG8NegYiQQ/gQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -1667,6 +1669,8 @@ github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0 github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= +github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= +github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= @@ -1866,6 +1870,7 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -2123,6 +2128,7 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= @@ -2209,6 +2215,8 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vektra/mockery/v2 v2.21.4 h1:QInaL4ma4Bz/cVipKeBLggB5XyPenpksiz8sJpgBZSE= +github.com/vektra/mockery/v2 v2.21.4/go.mod h1:le9nnD50TkeV8QGwrkza7v/xd3DA7YbSZYBEyiuAlsI= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.11 h1:Q47CePddpNGNhk4GCnAx9DDtASi2rasatE0cd26cZoE= diff --git a/storage/mocks/ReceiptIndexer.go b/storage/mocks/ReceiptIndexer.go index cb9a08ca..638b369b 100644 --- a/storage/mocks/ReceiptIndexer.go +++ b/storage/mocks/ReceiptIndexer.go @@ -52,19 +52,19 @@ func (_m *ReceiptIndexer) BloomsForBlockRange(start *big.Int, end *big.Int) ([]* } // GetByBlockHeight provides a mock function with given fields: height -func (_m *ReceiptIndexer) GetByBlockHeight(height *big.Int) (*types.Receipt, error) { +func (_m *ReceiptIndexer) GetByBlockHeight(height *big.Int) ([]*types.Receipt, error) { ret := _m.Called(height) - var r0 *types.Receipt + var r0 []*types.Receipt var r1 error - if rf, ok := ret.Get(0).(func(*big.Int) (*types.Receipt, error)); ok { + if rf, ok := ret.Get(0).(func(*big.Int) ([]*types.Receipt, error)); ok { return rf(height) } - if rf, ok := ret.Get(0).(func(*big.Int) *types.Receipt); ok { + if rf, ok := ret.Get(0).(func(*big.Int) []*types.Receipt); ok { r0 = rf(height) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Receipt) + r0 = ret.Get(0).([]*types.Receipt) } } From 191d6675f770e8f7fc541b0e2ef4cd53e8abb8ef Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 19:08:12 +0200 Subject: [PATCH 12/27] add test for multiple receipts --- services/logs/filter_test.go | 12 +++++++++--- storage/index_testsuite.go | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/services/logs/filter_test.go b/services/logs/filter_test.go index ad0f0267..c2f13393 100644 --- a/services/logs/filter_test.go +++ b/services/logs/filter_test.go @@ -110,13 +110,19 @@ func receiptStorage() storage.ReceiptIndexer { receiptStorage := &mocks.ReceiptIndexer{} receiptStorage. On("GetByBlockHeight", mock.AnythingOfType("*big.Int")). - Return(func(height *big.Int) (*gethTypes.Receipt, error) { + Return(func(height *big.Int) ([]*gethTypes.Receipt, error) { + rcps := make([]*gethTypes.Receipt, 0) for _, r := range receipts { if r.BlockNumber.Cmp(height) == 0 { - return r, nil + rcps = append(rcps, r) } } - return nil, errors.ErrNotFound + + if len(rcps) == 0 { + return nil, errors.ErrNotFound + } + + return rcps, nil }) receiptStorage. diff --git a/storage/index_testsuite.go b/storage/index_testsuite.go index 6d587cbe..d459f5ac 100644 --- a/storage/index_testsuite.go +++ b/storage/index_testsuite.go @@ -134,6 +134,24 @@ func (s *ReceiptTestSuite) TestStoreReceipt() { err := s.ReceiptIndexer.Store(receipt) s.Require().NoError(err) }) + + s.Run("store multiple receipts at same height", func() { + const height = 1 + receipts := []*types.Receipt{ + mocks.NewReceipt(height, common.HexToHash("0xf1")), + mocks.NewReceipt(height, common.HexToHash("0xf2")), + mocks.NewReceipt(height, common.HexToHash("0xf3")), + } + + for _, r := range receipts { + err := s.ReceiptIndexer.Store(r) + s.Require().NoError(err) + } + + storeReceipts, err := s.ReceiptIndexer.GetByBlockHeight(big.NewInt(height)) + s.Require().NoError(err) + s.Require().Equal(receipts, storeReceipts) + }) } func (s *ReceiptTestSuite) TestGetReceiptByTransactionID() { From 1910040e2403c9d9aad38296638076e84c6720d2 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 19:12:14 +0200 Subject: [PATCH 13/27] fix bugs --- storage/pebble/receipts.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/pebble/receipts.go b/storage/pebble/receipts.go index 3910715f..e2c6607c 100644 --- a/storage/pebble/receipts.go +++ b/storage/pebble/receipts.go @@ -44,8 +44,8 @@ func (r *Receipts) Store(receipt *gethTypes.Receipt) error { // we must first retrieve any already saved receipts at the provided height, // and if found we must add to the list, because this method can be called multiple // times when indexing a single EVM height, which can contain multiple receipts - receipts, err := r.GetByBlockHeight(receipt.BlockNumber) - if !errors.Is(err, errs.ErrNotFound) { // anything but not found is failure + receipts, err := r.getByBlockHeight(receipt.BlockNumber.Bytes()) + if err != nil && !errors.Is(err, errs.ErrNotFound) { // anything but not found is failure return fmt.Errorf("failed to store receipt to height, retrieve errror: %w", err) } From d41698840d8052cfd3cbf1ef5223ebd4a7f9592b Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 19:27:02 +0200 Subject: [PATCH 14/27] add test for receipts --- storage/index_testsuite.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/storage/index_testsuite.go b/storage/index_testsuite.go index d459f5ac..651991b3 100644 --- a/storage/index_testsuite.go +++ b/storage/index_testsuite.go @@ -128,19 +128,19 @@ type ReceiptTestSuite struct { } func (s *ReceiptTestSuite) TestStoreReceipt() { - receipt := mocks.NewReceipt(1, common.HexToHash("0xf1")) s.Run("store receipt successfully", func() { + receipt := mocks.NewReceipt(1, common.HexToHash("0xf1")) err := s.ReceiptIndexer.Store(receipt) s.Require().NoError(err) }) s.Run("store multiple receipts at same height", func() { - const height = 1 + const height = 5 receipts := []*types.Receipt{ - mocks.NewReceipt(height, common.HexToHash("0xf1")), - mocks.NewReceipt(height, common.HexToHash("0xf2")), - mocks.NewReceipt(height, common.HexToHash("0xf3")), + mocks.NewReceipt(height, common.HexToHash("0x1")), + mocks.NewReceipt(height, common.HexToHash("0x2")), + mocks.NewReceipt(height, common.HexToHash("0x3")), } for _, r := range receipts { @@ -150,7 +150,10 @@ func (s *ReceiptTestSuite) TestStoreReceipt() { storeReceipts, err := s.ReceiptIndexer.GetByBlockHeight(big.NewInt(height)) s.Require().NoError(err) - s.Require().Equal(receipts, storeReceipts) + + for i, sr := range storeReceipts { + s.compareReceipts(receipts[i], sr) + } }) } From 20c7e2d19dd3edb664fde218dc57b32c53ac71b1 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 19:47:29 +0200 Subject: [PATCH 15/27] add logging index --- services/ingestion/engine.go | 1 + 1 file changed, 1 insertion(+) diff --git a/services/ingestion/engine.go b/services/ingestion/engine.go index 29529e1f..6af99305 100644 --- a/services/ingestion/engine.go +++ b/services/ingestion/engine.go @@ -234,6 +234,7 @@ func (e *Engine) indexTransaction(tx models.Transaction, receipt *gethTypes.Rece Str("contract-address", receipt.ContractAddress.String()). Int("log-count", len(receipt.Logs)). Uint64("evm-height", receipt.BlockNumber.Uint64()). + Uint("tx-index", receipt.TransactionIndex). Str("receipt-tx-hash", receipt.TxHash.String()). Str("tx-hash", txHash.String()). Msg("ingesting new transaction executed event") From 1da46e3d86e4d0593f8ea51b83f5167bf8b81801 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 19:50:26 +0200 Subject: [PATCH 16/27] fix test --- tests/web3js/eth_batch_retrieval_test.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/web3js/eth_batch_retrieval_test.js b/tests/web3js/eth_batch_retrieval_test.js index 2a38d57d..73321e6b 100644 --- a/tests/web3js/eth_batch_retrieval_test.js +++ b/tests/web3js/eth_batch_retrieval_test.js @@ -6,20 +6,17 @@ const web3 = conf.web3 it('retrieve batch transactions', async() => { let latestHeight = await web3.eth.getBlockNumber() let block = await web3.eth.getBlock(latestHeight) - console.log(block) assert.lengthOf(block.transactions, 2) let deployTx = await web3.eth.getTransactionFromBlock(latestHeight, 0) - console.log(deployTx) assert.equal(block.number, deployTx.blockNumber) assert.equal(block.hash, deployTx.blockHash) assert.equal(0, deployTx.type) - assert.equal(0, deployTx.transactionIndex) + //assert.equal(0, deployTx.transactionIndex) let callTx = await web3.eth.getTransactionFromBlock(latestHeight, 1) - console.log(callTx) assert.equal(block.number, callTx.blockNumber) assert.equal(block.hash, callTx.blockHash) assert.equal(0, callTx.type) - assert.equal(1, callTx.transactionIndex) + // todo wait for flow-go PR assert.equal(1, callTx.transactionIndex) }) \ No newline at end of file From a42429b841cb7c405aa7d7a52e2d6ddbab95976d Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:43:43 +0200 Subject: [PATCH 17/27] update flow-go --- go.mod | 8 +------- go.sum | 12 ++---------- tests/go.mod | 2 +- tests/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 2361b959..4dedfb95 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/goccy/go-json v0.10.2 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/onflow/cadence v1.0.0-preview.23 - github.com/onflow/flow-go v0.34.0-crescendo-preview.16 + github.com/onflow/flow-go v0.34.0-crescendo-preview.17 github.com/onflow/flow-go-sdk v1.0.0-preview.22 github.com/onflow/go-ethereum v1.13.4 github.com/rs/cors v1.8.0 @@ -29,7 +29,6 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chigopher/pathlib v0.12.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect @@ -85,7 +84,6 @@ require ( github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/goprocess v0.1.4 // indirect - github.com/jinzhu/copier v0.3.5 // indirect github.com/k0kubun/pp v3.0.1+incompatible // indirect github.com/kevinburke/go-bindata v3.24.0+incompatible // indirect github.com/klauspost/compress v1.17.4 // indirect @@ -101,7 +99,6 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/minio/sha256-simd v1.0.1 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect @@ -158,7 +155,6 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/vektra/mockery/v2 v2.21.4 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v4 v4.3.11 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect @@ -178,7 +174,6 @@ require ( golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect @@ -190,7 +185,6 @@ require ( google.golang.org/grpc v1.63.2 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect diff --git a/go.sum b/go.sum index d05c13c7..d7861465 100644 --- a/go.sum +++ b/go.sum @@ -1092,8 +1092,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chigopher/pathlib v0.12.0 h1:1GM7fN/IwXXmOHbd1jkMqHD2wUhYqUvafgxTwmLT/q8= -github.com/chigopher/pathlib v0.12.0/go.mod h1:EJ5UtJ/sK8Nt6q3VWN+EwZLZ3g0afJiG8NegYiQQ/gQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -1669,8 +1667,6 @@ github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0 github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= -github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= -github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= @@ -1870,7 +1866,6 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -1947,8 +1942,8 @@ github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e h1:jl7SYAui/gYRmBofrY//Ln8ixRJwvLzvwLstNfRKmWY= github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= -github.com/onflow/flow-go v0.34.0-crescendo-preview.16 h1:GTOLB2FTG4En91WAd51ReNM5zGJ56KJY9k7AN/ZsCMw= -github.com/onflow/flow-go v0.34.0-crescendo-preview.16/go.mod h1:WbsDXtDBGRil+pQevdxTlP2r3a67/Aq5Y7+ab/P0aFw= +github.com/onflow/flow-go v0.34.0-crescendo-preview.17 h1:HnISCj+nZkfwDHmVF1VmbmyuVbOH76GNGKFTMbthD7c= +github.com/onflow/flow-go v0.34.0-crescendo-preview.17/go.mod h1:WbsDXtDBGRil+pQevdxTlP2r3a67/Aq5Y7+ab/P0aFw= github.com/onflow/flow-go-sdk v1.0.0-M1/go.mod h1:TDW0MNuCs4SvqYRUzkbRnRmHQL1h4X8wURsCw9P9beo= github.com/onflow/flow-go-sdk v1.0.0-preview.22 h1:ahHlppdDd4TjHMfnE73SD15AR16KTgbczdhFjGjAtFM= github.com/onflow/flow-go-sdk v1.0.0-preview.22/go.mod h1:0hJfpIajLtBvaAUfJAdvWx6WBVp5hS0DJidc0NJLgE4= @@ -2128,7 +2123,6 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= @@ -2215,8 +2209,6 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/vektra/mockery/v2 v2.21.4 h1:QInaL4ma4Bz/cVipKeBLggB5XyPenpksiz8sJpgBZSE= -github.com/vektra/mockery/v2 v2.21.4/go.mod h1:le9nnD50TkeV8QGwrkza7v/xd3DA7YbSZYBEyiuAlsI= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.11 h1:Q47CePddpNGNhk4GCnAx9DDtASi2rasatE0cd26cZoE= diff --git a/tests/go.mod b/tests/go.mod index 453de5e7..7c5a9f08 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -7,7 +7,7 @@ require ( github.com/onflow/cadence v1.0.0-preview.23 github.com/onflow/flow-emulator v1.0.0-preview.20 github.com/onflow/flow-evm-gateway v0.0.0-20240201154855-4d4d3d3f19c7 - github.com/onflow/flow-go v0.34.0-crescendo-preview.10-staged-contracts-3.0.20240430105130-26cb8ee40436 + github.com/onflow/flow-go v0.34.0-crescendo-preview.17 github.com/onflow/flow-go-sdk v1.0.0-preview.22 github.com/onflow/go-ethereum v1.13.4 github.com/rs/zerolog v1.31.0 diff --git a/tests/go.sum b/tests/go.sum index 8562fe4b..37728164 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -2081,8 +2081,8 @@ github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e h1:jl7SYAui/gYRmBofrY//Ln8ixRJwvLzvwLstNfRKmWY= github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= -github.com/onflow/flow-go v0.34.0-crescendo-preview.10-staged-contracts-3.0.20240430105130-26cb8ee40436 h1:AfvKudxJYjIqpNMixLaM2rbgAi0HDSUeGjdTDe8fZv8= -github.com/onflow/flow-go v0.34.0-crescendo-preview.10-staged-contracts-3.0.20240430105130-26cb8ee40436/go.mod h1:WbsDXtDBGRil+pQevdxTlP2r3a67/Aq5Y7+ab/P0aFw= +github.com/onflow/flow-go v0.34.0-crescendo-preview.17 h1:HnISCj+nZkfwDHmVF1VmbmyuVbOH76GNGKFTMbthD7c= +github.com/onflow/flow-go v0.34.0-crescendo-preview.17/go.mod h1:WbsDXtDBGRil+pQevdxTlP2r3a67/Aq5Y7+ab/P0aFw= github.com/onflow/flow-go-sdk v1.0.0-M1/go.mod h1:TDW0MNuCs4SvqYRUzkbRnRmHQL1h4X8wURsCw9P9beo= github.com/onflow/flow-go-sdk v1.0.0-preview.22 h1:ahHlppdDd4TjHMfnE73SD15AR16KTgbczdhFjGjAtFM= github.com/onflow/flow-go-sdk v1.0.0-preview.22/go.mod h1:0hJfpIajLtBvaAUfJAdvWx6WBVp5hS0DJidc0NJLgE4= From 81cb1d4ac75592946fd092b084294768ce9da7de Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:46:23 +0200 Subject: [PATCH 18/27] update emulator --- tests/go.mod | 2 +- tests/go.sum | 2 ++ tests/web3js/eth_batch_retrieval_test.js | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index 7c5a9f08..9b5a7ed4 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/goccy/go-json v0.10.2 github.com/onflow/cadence v1.0.0-preview.23 - github.com/onflow/flow-emulator v1.0.0-preview.20 + github.com/onflow/flow-emulator v1.0.0-preview.20.0.20240430203709-1d102ef5a708 github.com/onflow/flow-evm-gateway v0.0.0-20240201154855-4d4d3d3f19c7 github.com/onflow/flow-go v0.34.0-crescendo-preview.17 github.com/onflow/flow-go-sdk v1.0.0-preview.22 diff --git a/tests/go.sum b/tests/go.sum index 37728164..ae69bdce 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -2077,6 +2077,8 @@ github.com/onflow/flow-core-contracts/lib/go/templates v0.15.2-0.20240429192223- github.com/onflow/flow-core-contracts/lib/go/templates v0.15.2-0.20240429192223-e696a8e439b5/go.mod h1:0oTx6Nkc+LdOXaZe3PRtV1cY+J5z5ig08alR8d+OPHs= github.com/onflow/flow-emulator v1.0.0-preview.20 h1:LwIrvrRIEkqln1czNwMcayCEwPi3SXIinu4BuzZN8Os= github.com/onflow/flow-emulator v1.0.0-preview.20/go.mod h1:pW0DJKT3uQ4lRVNsckhMa0YddgSCrnH1RKCCNfjYY3s= +github.com/onflow/flow-emulator v1.0.0-preview.20.0.20240430203709-1d102ef5a708 h1:PkDvbiR2BMAYg3a4YuHJHe1ZA8M9gb4DylrzA9/z9A8= +github.com/onflow/flow-emulator v1.0.0-preview.20.0.20240430203709-1d102ef5a708/go.mod h1:Q9tMIfY3p0SLaoNJ/4GRxnm0LRGXRk4ElsvzOeX2Xvc= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e h1:2LO6Rtmz2PVfH+ZXnMwvTwVeIz3PCy0fs3lQraqog14= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e h1:jl7SYAui/gYRmBofrY//Ln8ixRJwvLzvwLstNfRKmWY= diff --git a/tests/web3js/eth_batch_retrieval_test.js b/tests/web3js/eth_batch_retrieval_test.js index 73321e6b..db3b556c 100644 --- a/tests/web3js/eth_batch_retrieval_test.js +++ b/tests/web3js/eth_batch_retrieval_test.js @@ -12,11 +12,11 @@ it('retrieve batch transactions', async() => { assert.equal(block.number, deployTx.blockNumber) assert.equal(block.hash, deployTx.blockHash) assert.equal(0, deployTx.type) - //assert.equal(0, deployTx.transactionIndex) + assert.equal(0, deployTx.transactionIndex) let callTx = await web3.eth.getTransactionFromBlock(latestHeight, 1) assert.equal(block.number, callTx.blockNumber) assert.equal(block.hash, callTx.blockHash) assert.equal(0, callTx.type) - // todo wait for flow-go PR assert.equal(1, callTx.transactionIndex) + assert.equal(1, callTx.transactionIndex) }) \ No newline at end of file From e0b6384df54ec549582931953a5c9558cf81e030 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:50:55 +0200 Subject: [PATCH 19/27] update test --- tests/e2e_web3js_test.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/tests/e2e_web3js_test.go b/tests/e2e_web3js_test.go index 2551138c..0e9b4bcc 100644 --- a/tests/e2e_web3js_test.go +++ b/tests/e2e_web3js_test.go @@ -40,23 +40,14 @@ func TestWeb3_E2E(t *testing.T) { runWeb3TestWithSetup(t, "eth_batch_retrieval_test", func(emu emulator.Emulator) error { code := ` transaction(tx1: String, tx2: String) { - let coa: &EVM.CadenceOwnedAccount prepare(signer: auth(Storage) &Account) { - self.coa = signer.storage.borrow<&EVM.CadenceOwnedAccount>( - from: /storage/evm - ) ?? panic("Could not borrow reference to the COA!") - } - execute { let txs: [[UInt8]] = [tx1.decodeHex(), tx2.decodeHex()] let txResults = EVM.batchRun( txs: txs, - coinbase: self.coa.address() + coinbase: EVM.EVMAddress(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) ) for txResult in txResults { - assert( - txResult.status == EVM.Status.successful, - message: "failed to execute evm transaction: ".concat(txResult.errorCode.toString()) - ) + assert(txResult.status == EVM.Status.successful, message: "failed to execute tx")) } } } From 6b66045dec9e3d46b05353518e29661f7f5a966d Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:57:47 +0200 Subject: [PATCH 20/27] add one more test --- storage/index_testsuite.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/storage/index_testsuite.go b/storage/index_testsuite.go index 651991b3..fc087f96 100644 --- a/storage/index_testsuite.go +++ b/storage/index_testsuite.go @@ -176,11 +176,13 @@ func (s *ReceiptTestSuite) TestGetReceiptByTransactionID() { }) } -func (s *ReceiptTestSuite) TestGetReceiptByBlockID() { - s.Run("existing block ID", func() { +func (s *ReceiptTestSuite) TestGetReceiptByBlockHeight() { + s.Run("existing block height", func() { receipt := mocks.NewReceipt(3, common.HexToHash("0x1")) err := s.ReceiptIndexer.Store(receipt) s.Require().NoError(err) + // add one more receipt that shouldn't be retrieved + s.Require().NoError(s.ReceiptIndexer.Store(mocks.NewReceipt(4, common.HexToHash("0x2")))) retReceipts, err := s.ReceiptIndexer.GetByBlockHeight(receipt.BlockNumber) s.Require().NoError(err) @@ -214,7 +216,11 @@ func (s *ReceiptTestSuite) TestBloomsForBlockRange() { s.Require().Len(heights, len(testBlooms)) s.Require().Equal(testBlooms, blooms) - // todo smaller block range + blooms, heights, err = s.ReceiptIndexer.BloomsForBlockRange(start, big.NewInt(13)) + s.Require().NoError(err) + s.Require().Len(blooms, 3) + s.Require().Len(heights, 3) + s.Require().Equal(testBlooms[0:3], blooms) }) s.Run("invalid block range", func() { From 5c8ffb5d9cd84d5f475e1b079e459200f2754c75 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:02:13 +0200 Subject: [PATCH 21/27] add test for blooms multiple per block --- storage/index_testsuite.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/storage/index_testsuite.go b/storage/index_testsuite.go index fc087f96..d0d776c0 100644 --- a/storage/index_testsuite.go +++ b/storage/index_testsuite.go @@ -218,9 +218,29 @@ func (s *ReceiptTestSuite) TestBloomsForBlockRange() { blooms, heights, err = s.ReceiptIndexer.BloomsForBlockRange(start, big.NewInt(13)) s.Require().NoError(err) - s.Require().Len(blooms, 3) - s.Require().Len(heights, 3) - s.Require().Equal(testBlooms[0:3], blooms) + s.Require().Len(blooms, 4) + s.Require().Len(heights, 4) + s.Require().Equal(testBlooms[0:4], blooms) + }) + + s.Run("valid block range with multiple receipts per block", func() { + start := big.NewInt(10) + end := big.NewInt(15) + testBlooms := make([]*types.Bloom, 0) + + for i := start.Uint64(); i < end.Uint64(); i++ { + r1 := mocks.NewReceipt(i, common.HexToHash(fmt.Sprintf("0x%d", i))) + r2 := mocks.NewReceipt(i, common.HexToHash(fmt.Sprintf("0x%d", i))) + testBlooms = append(testBlooms, &r1.Bloom, &r2.Bloom) + s.Require().NoError(s.ReceiptIndexer.Store(r1)) + s.Require().NoError(s.ReceiptIndexer.Store(r2)) + } + + blooms, heights, err := s.ReceiptIndexer.BloomsForBlockRange(start, end) + s.Require().NoError(err) + s.Require().Len(blooms, len(testBlooms)) + s.Require().Len(heights, len(testBlooms)) + s.Require().Equal(testBlooms, blooms) }) s.Run("invalid block range", func() { From e210e0f62914d002f044b2b958a67bbfedce79e6 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:18:10 +0200 Subject: [PATCH 22/27] index bloom list for height --- storage/pebble/receipts.go | 41 ++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/storage/pebble/receipts.go b/storage/pebble/receipts.go index e2c6607c..0581152d 100644 --- a/storage/pebble/receipts.go +++ b/storage/pebble/receipts.go @@ -44,15 +44,23 @@ func (r *Receipts) Store(receipt *gethTypes.Receipt) error { // we must first retrieve any already saved receipts at the provided height, // and if found we must add to the list, because this method can be called multiple // times when indexing a single EVM height, which can contain multiple receipts - receipts, err := r.getByBlockHeight(receipt.BlockNumber.Bytes()) + blockHeight := receipt.BlockNumber.Bytes() + receipts, err := r.getByBlockHeight(blockHeight) if err != nil && !errors.Is(err, errs.ErrNotFound) { // anything but not found is failure - return fmt.Errorf("failed to store receipt to height, retrieve errror: %w", err) + return fmt.Errorf("failed to store receipt to height, retrieve exisint receipt errror: %w", err) + } + + // same goes for blooms + blooms, err := r.getBloomsByBlockHeight(blockHeight) + if err != nil && !errors.Is(err, errs.ErrNotFound) { + return fmt.Errorf("failed to store receipt to height, retrieve existing blooms error: %w", err) } // add new receipt to the list of all receipts, if the receipts do not yet exist at the // provided height, the above get will return ErrNotFound (which we ignore) and the bellow // line will init an empty receipts slice with only the provided receipt receipts = append(receipts, receipt) + blooms = append(blooms, &receipt.Bloom) batch := r.store.newBatch() defer batch.Close() @@ -78,8 +86,8 @@ func (r *Receipts) Store(receipt *gethTypes.Receipt) error { return fmt.Errorf("failed to store receipt height: %w", err) } - // todo support multiple heights - if err := r.store.set(bloomHeightKey, height, receipt.Bloom.Bytes(), batch); err != nil { + bloomVal, err := rlp.EncodeToBytes(blooms) + if err := r.store.set(bloomHeightKey, height, bloomVal, batch); err != nil { return fmt.Errorf("failed to store bloom height: %w", err) } @@ -148,7 +156,24 @@ func (r *Receipts) getByBlockHeight(height []byte) ([]*gethTypes.Receipt, error) return receipts, nil } +func (r *Receipts) getBloomsByBlockHeight(height []byte) ([]*gethTypes.Bloom, error) { + val, err := r.store.get(bloomHeightKey, height) + if err != nil { + return nil, fmt.Errorf("failed to get bloom at height: %w", err) + } + + var blooms []*gethTypes.Bloom + if err := rlp.DecodeBytes(val, &blooms); err != nil { + return nil, fmt.Errorf("failed to decode blooms at height: %w", err) + } + + return blooms, nil +} + func (r *Receipts) BloomsForBlockRange(start, end *big.Int) ([]*gethTypes.Bloom, []*big.Int, error) { + r.mux.RLock() + defer r.mux.RUnlock() + if start.Cmp(end) > 0 { return nil, nil, fmt.Errorf("start is bigger than end: %w", errs.ErrInvalidRange) } @@ -203,11 +228,15 @@ func (r *Receipts) BloomsForBlockRange(start, end *big.Int) ([]*gethTypes.Bloom, return nil, nil, err } - bloom := gethTypes.BytesToBloom(val) + var bloomsHeight []*gethTypes.Bloom + if err := rlp.DecodeBytes(val, &bloomsHeight); err != nil { + return nil, nil, fmt.Errorf("failed to decode blooms: %w", err) + } + h := stripPrefix(iterator.Key()) height := new(big.Int).SetBytes(h) - blooms = append(blooms, &bloom) + blooms = append(blooms, bloomsHeight...) heights = append(heights, height) } From c529aeeee0836ae199010524ca4c98f3bf87def3 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:25:06 +0200 Subject: [PATCH 23/27] add tests for bloom heights --- storage/index_testsuite.go | 10 ++++++---- storage/pebble/storage_test.go | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/storage/index_testsuite.go b/storage/index_testsuite.go index d0d776c0..da073b95 100644 --- a/storage/index_testsuite.go +++ b/storage/index_testsuite.go @@ -224,22 +224,24 @@ func (s *ReceiptTestSuite) TestBloomsForBlockRange() { }) s.Run("valid block range with multiple receipts per block", func() { - start := big.NewInt(10) - end := big.NewInt(15) + start := big.NewInt(15) + end := big.NewInt(20) testBlooms := make([]*types.Bloom, 0) + testHeights := make([]*big.Int, 0) for i := start.Uint64(); i < end.Uint64(); i++ { r1 := mocks.NewReceipt(i, common.HexToHash(fmt.Sprintf("0x%d", i))) r2 := mocks.NewReceipt(i, common.HexToHash(fmt.Sprintf("0x%d", i))) - testBlooms = append(testBlooms, &r1.Bloom, &r2.Bloom) s.Require().NoError(s.ReceiptIndexer.Store(r1)) s.Require().NoError(s.ReceiptIndexer.Store(r2)) + testBlooms = append(testBlooms, &r1.Bloom, &r2.Bloom) + testHeights = append(testHeights, big.NewInt(int64(i))) } blooms, heights, err := s.ReceiptIndexer.BloomsForBlockRange(start, end) s.Require().NoError(err) s.Require().Len(blooms, len(testBlooms)) - s.Require().Len(heights, len(testBlooms)) + s.Require().Len(heights, len(testHeights)) s.Require().Equal(testBlooms, blooms) }) diff --git a/storage/pebble/storage_test.go b/storage/pebble/storage_test.go index cf40a617..8fe12a0e 100644 --- a/storage/pebble/storage_test.go +++ b/storage/pebble/storage_test.go @@ -32,7 +32,7 @@ func TestReceipts(t *testing.T) { require.NoError(t, err) err = bl.Store(30, mocks.NewBlock(10)) // update first and latest height require.NoError(t, err) - err = bl.Store(30, mocks.NewBlock(20)) // update latest + err = bl.Store(30, mocks.NewBlock(30)) // update latest require.NoError(t, err) suite.Run(t, &storage.ReceiptTestSuite{ReceiptIndexer: NewReceipts(db)}) From d6117a91b3532f052ed57e6a5e54c62f658fa39a Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:34:25 +0200 Subject: [PATCH 24/27] test fixes --- tests/e2e_web3js_test.go | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/tests/e2e_web3js_test.go b/tests/e2e_web3js_test.go index 0e9b4bcc..c5782580 100644 --- a/tests/e2e_web3js_test.go +++ b/tests/e2e_web3js_test.go @@ -38,21 +38,6 @@ func TestWeb3_E2E(t *testing.T) { t.Run("batch run transactions", func(t *testing.T) { runWeb3TestWithSetup(t, "eth_batch_retrieval_test", func(emu emulator.Emulator) error { - code := ` - transaction(tx1: String, tx2: String) { - prepare(signer: auth(Storage) &Account) { - let txs: [[UInt8]] = [tx1.decodeHex(), tx2.decodeHex()] - let txResults = EVM.batchRun( - txs: txs, - coinbase: EVM.EVMAddress(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) - ) - for txResult in txResults { - assert(txResult.status == EVM.Status.successful, message: "failed to execute tx")) - } - } - } - ` - tx1, err := cadence.NewString("f9015880808301e8488080b901086060604052341561000f57600080fd5b60eb8061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60007f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da600783026040518082815260200191505060405180910390a16007820290509190505600a165627a7a7230582040383f19d9f65246752244189b02f56e8d0980ed44e7a56c0b200458caad20bb002982052fa09c05a7389284dc02b356ec7dee8a023c5efd3a9d844fa3c481882684b0640866a057e96d0a71a857ed509bb2b7333e78b2408574b8cc7f51238f25c58812662653") if err != nil { return err @@ -61,7 +46,24 @@ func TestWeb3_E2E(t *testing.T) { if err != nil { return err } - res, err := flowSendTransaction(emu, code, tx1, tx2) + + res, err := flowSendTransaction( + emu, + `transaction(tx1: String, tx2: String) { + prepare(signer: auth(Storage) &Account) { + let txs: [[UInt8]] = [tx1.decodeHex(), tx2.decodeHex()] + let txResults = EVM.batchRun( + txs: txs, + coinbase: EVM.EVMAddress(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) + ) + for txResult in txResults { + assert(txResult.status == EVM.Status.successful, message: "failed to execute tx")) + } + } + }`, + tx1, + tx2, + ) if err != nil { return err } From 4c391ca2309c03a1c7170fd7dcfc865c740aa097 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:35:24 +0200 Subject: [PATCH 25/27] update emulator --- tests/go.mod | 2 +- tests/go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index 9b5a7ed4..ee6ca870 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/goccy/go-json v0.10.2 github.com/onflow/cadence v1.0.0-preview.23 - github.com/onflow/flow-emulator v1.0.0-preview.20.0.20240430203709-1d102ef5a708 + github.com/onflow/flow-emulator v1.0.0-preview.21 github.com/onflow/flow-evm-gateway v0.0.0-20240201154855-4d4d3d3f19c7 github.com/onflow/flow-go v0.34.0-crescendo-preview.17 github.com/onflow/flow-go-sdk v1.0.0-preview.22 diff --git a/tests/go.sum b/tests/go.sum index ae69bdce..ce0fd53b 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -2075,10 +2075,8 @@ github.com/onflow/flow-core-contracts/lib/go/contracts v0.15.2-0.20240429192223- github.com/onflow/flow-core-contracts/lib/go/contracts v0.15.2-0.20240429192223-e696a8e439b5/go.mod h1:+4JWLclBOT+emyBh6NAZSEbqEwzHcWHpIbfsXmRASgY= github.com/onflow/flow-core-contracts/lib/go/templates v0.15.2-0.20240429192223-e696a8e439b5 h1:6Cg0h+8Iyy/Nnefk5j0gdeVoMTNpUooAMjyV8sk6zoA= github.com/onflow/flow-core-contracts/lib/go/templates v0.15.2-0.20240429192223-e696a8e439b5/go.mod h1:0oTx6Nkc+LdOXaZe3PRtV1cY+J5z5ig08alR8d+OPHs= -github.com/onflow/flow-emulator v1.0.0-preview.20 h1:LwIrvrRIEkqln1czNwMcayCEwPi3SXIinu4BuzZN8Os= -github.com/onflow/flow-emulator v1.0.0-preview.20/go.mod h1:pW0DJKT3uQ4lRVNsckhMa0YddgSCrnH1RKCCNfjYY3s= -github.com/onflow/flow-emulator v1.0.0-preview.20.0.20240430203709-1d102ef5a708 h1:PkDvbiR2BMAYg3a4YuHJHe1ZA8M9gb4DylrzA9/z9A8= -github.com/onflow/flow-emulator v1.0.0-preview.20.0.20240430203709-1d102ef5a708/go.mod h1:Q9tMIfY3p0SLaoNJ/4GRxnm0LRGXRk4ElsvzOeX2Xvc= +github.com/onflow/flow-emulator v1.0.0-preview.21 h1:ysrlVUPyvhojvaWLQsTGbpgLgR7h3f7Hjcwm9GuFn+U= +github.com/onflow/flow-emulator v1.0.0-preview.21/go.mod h1:Q9tMIfY3p0SLaoNJ/4GRxnm0LRGXRk4ElsvzOeX2Xvc= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e h1:2LO6Rtmz2PVfH+ZXnMwvTwVeIz3PCy0fs3lQraqog14= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240424211859-3ff4c0fe2a1e/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= github.com/onflow/flow-ft/lib/go/templates v0.7.1-0.20240424211859-3ff4c0fe2a1e h1:jl7SYAui/gYRmBofrY//Ln8ixRJwvLzvwLstNfRKmWY= From 5a910a38a4fb2ff767b69507330f7cc47be62aab Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:45:57 +0200 Subject: [PATCH 26/27] fix typo --- tests/e2e_web3js_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_web3js_test.go b/tests/e2e_web3js_test.go index c5782580..1c21f5ae 100644 --- a/tests/e2e_web3js_test.go +++ b/tests/e2e_web3js_test.go @@ -57,7 +57,7 @@ func TestWeb3_E2E(t *testing.T) { coinbase: EVM.EVMAddress(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) ) for txResult in txResults { - assert(txResult.status == EVM.Status.successful, message: "failed to execute tx")) + assert(txResult.status == EVM.Status.successful, message: "failed to execute tx") } } }`, From 08ddfaf8e278a2e0c559111e0619fccada06a472 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:47:35 +0200 Subject: [PATCH 27/27] handle err --- storage/pebble/receipts.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storage/pebble/receipts.go b/storage/pebble/receipts.go index 0581152d..e456423e 100644 --- a/storage/pebble/receipts.go +++ b/storage/pebble/receipts.go @@ -87,6 +87,10 @@ func (r *Receipts) Store(receipt *gethTypes.Receipt) error { } bloomVal, err := rlp.EncodeToBytes(blooms) + if err != nil { + return fmt.Errorf("failed to encode blooms: %w", err) + } + if err := r.store.set(bloomHeightKey, height, bloomVal, batch); err != nil { return fmt.Errorf("failed to store bloom height: %w", err) }