package indexer_test import ( "context" "fmt" "github.com/brianvoe/gofakeit/v6" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" . "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/synapsecns/sanguine/ethergo/backends/geth" "github.com/synapsecns/sanguine/services/scribe/backend" "github.com/synapsecns/sanguine/services/scribe/config" "github.com/synapsecns/sanguine/services/scribe/service/indexer" "github.com/synapsecns/sanguine/services/scribe/testutil" scribeTypes "github.com/synapsecns/sanguine/services/scribe/types" "os" "time" "sync" "github.com/synapsecns/sanguine/services/scribe/db" "github.com/synapsecns/sanguine/services/scribe/db/mocks" "math/big" ) // TestFailedStore tests that the ChainBackfiller continues backfilling after a failed store. func (x *IndexerSuite) TestFailedStore() { mockDB := new(mocks.EventDB) mockDB. // on a store receipt call On("StoreReceipt", mock.Anything, mock.Anything, mock.Anything). Return(fmt.Errorf("failed to store receipt")) mockDB. // on a store transaction call On("StoreEthTx", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(fmt.Errorf("failed to store transaction")) mockDB. // on a store log call On("StoreLogs", mock.Anything, mock.Anything, mock.Anything). Return(fmt.Errorf("failed to store log")) mockDB. // on retrieve last indexed call On("RetrieveLastIndexed", mock.Anything, mock.Anything, mock.Anything). Return(uint64(0), nil) mockDB.On("StoreBlockTime", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) chainID := gofakeit.Uint32() simulatedChain := geth.NewEmbeddedBackendForChainID(x.GetTestContext(), x.T(), big.NewInt(int64(chainID))) simulatedClient, err := backend.DialBackend(x.GetTestContext(), simulatedChain.RPCAddress(), x.metrics) Nil(x.T(), err) simulatedChain.FundAccount(x.GetTestContext(), x.wallet.Address(), *big.NewInt(params.Ether)) testContract, testRef := x.manager.GetTestContract(x.GetTestContext(), simulatedChain) transactOpts := simulatedChain.GetTxContext(x.GetTestContext(), nil) contractConfig := config.ContractConfig{ Address: testContract.Address().String(), StartBlock: 0, } simulatedChainArr := []backend.ScribeBackend{simulatedClient, simulatedClient} chainConfig := config.ChainConfig{ Confirmations: 1, ChainID: chainID, GetLogsBatchAmount: 1, StoreConcurrency: 1, GetLogsRange: 1, Contracts: []config.ContractConfig{contractConfig}, } blockHeightMeter, err := x.metrics.Metrics().NewHistogram(fmt.Sprint("scribe_block_meter", chainConfig.ChainID), "block_histogram", "a block height meter", "blocks") Nil(x.T(), err) contracts := []common.Address{common.HexToAddress(contractConfig.Address)} indexer, err := indexer.NewIndexer(chainConfig, contracts, mockDB, simulatedChainArr, x.metrics, blockHeightMeter, false) Nil(x.T(), err) tx, err := testRef.EmitEventA(transactOpts.TransactOpts, big.NewInt(1), big.NewInt(2), big.NewInt(3)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // Get the block that the last transaction was executed in. txBlockNumber, err := testutil.GetTxBlockNumber(x.GetTestContext(), simulatedChain, tx) Nil(x.T(), err) err = indexer.Index(x.GetTestContext(), contractConfig.StartBlock, txBlockNumber) NotNil(x.T(), err) // Check to ensure that StoreLastIndexed was never called. mockDB.AssertNotCalled(x.T(), "StoreLastIndexed", mock.Anything, mock.Anything, mock.Anything, mock.Anything) } // TestGetLogsSimulated tests the GetLogs function using a simulated blockchain. // //nolint:cyclop func (x *IndexerSuite) TestGetLogsSimulated() { // Get simulated blockchain, deploy the test contract, and set up test variables. simulatedChain := geth.NewEmbeddedBackendForChainID(x.GetSuiteContext(), x.T(), big.NewInt(3)) simulatedClient, err := backend.DialBackend(x.GetTestContext(), simulatedChain.RPCAddress(), x.metrics) Nil(x.T(), err) simulatedChain.FundAccount(x.GetTestContext(), x.wallet.Address(), *big.NewInt(params.Ether)) testContract, testRef := x.manager.GetTestContract(x.GetTestContext(), simulatedChain) transactOpts := simulatedChain.GetTxContext(x.GetTestContext(), nil) contractConfig := config.ContractConfig{ Address: testContract.Address().String(), StartBlock: 0, } simulatedChainArr := []backend.ScribeBackend{simulatedClient, simulatedClient} chainConfig := config.ChainConfig{ Confirmations: 1, ChainID: 3, GetLogsBatchAmount: 1, StoreConcurrency: 1, GetLogsRange: 1, Contracts: []config.ContractConfig{contractConfig}, } blockHeightMeter, err := x.metrics.Metrics().NewHistogram(fmt.Sprint("scribe_block_meter", chainConfig.ChainID), "block_histogram", "a block height meter", "blocks") Nil(x.T(), err) contracts := []common.Address{common.HexToAddress(contractConfig.Address)} contractIndexer, err := indexer.NewIndexer(chainConfig, contracts, x.testDB, simulatedChainArr, x.metrics, blockHeightMeter, false) Nil(x.T(), err) // Emit five events, and then fetch them with GetLogs. The first two will be fetched first, // then the last three after. tx, err := testRef.EmitEventA(transactOpts.TransactOpts, big.NewInt(1), big.NewInt(2), big.NewInt(3)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) tx, err = testRef.EmitEventB(transactOpts.TransactOpts, []byte{4}, big.NewInt(5), big.NewInt(6)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // Get the block that the second transaction was executed in. txBlockNumberA, err := testutil.GetTxBlockNumber(x.GetTestContext(), simulatedChain, tx) Nil(x.T(), err) tx, err = testRef.EmitEventA(transactOpts.TransactOpts, big.NewInt(7), big.NewInt(8), big.NewInt(9)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) tx, err = testRef.EmitEventB(transactOpts.TransactOpts, []byte{10}, big.NewInt(11), big.NewInt(12)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) tx, err = testRef.EmitEventA(transactOpts.TransactOpts, big.NewInt(13), big.NewInt(14), big.NewInt(15)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // Get the block that the last transaction was executed in. txBlockNumberB, err := testutil.GetTxBlockNumber(x.GetTestContext(), simulatedChain, tx) Nil(x.T(), err) // Get the logs for the first two events. collectedLogs := []types.Log{} indexerConfig := contractIndexer.GetIndexerConfig() logFetcher := indexer.NewLogFetcher(simulatedChainArr[0], big.NewInt(int64(contractConfig.StartBlock)), big.NewInt(int64(txBlockNumberA)), &indexerConfig, true) logsChan := logFetcher.GetFetchedLogsChan() fetchingContext, cancelFetching := context.WithTimeout(x.GetTestContext(), 10*time.Second) go func() { _ = logFetcher.Start(fetchingContext) }() for { select { case <-x.GetTestContext().Done(): x.T().Error("test timed out") case log, ok := <-*logsChan: if !ok { goto Done } collectedLogs = append(collectedLogs, log) } } Done: cancelFetching() // Check to see if 2 logs were collected. Equal(x.T(), 2, len(collectedLogs)) // Get the logs for the last three events. collectedLogs = []types.Log{} logFetcher = indexer.NewLogFetcher(simulatedChainArr[0], big.NewInt(int64(txBlockNumberA+1)), big.NewInt(int64(txBlockNumberB)), &indexerConfig, true) logsChan = logFetcher.GetFetchedLogsChan() fetchingContext, cancelFetching = context.WithTimeout(x.GetTestContext(), 10*time.Second) go func() { _ = logFetcher.Start(fetchingContext) }() for { select { case <-x.GetTestContext().Done(): x.T().Error("test timed out") case log, ok := <-*logsChan: if !ok { goto Done2 } collectedLogs = append(collectedLogs, log) } } Done2: cancelFetching() // Check to see if 3 logs were collected. Equal(x.T(), 3, len(collectedLogs)) } // TestContractBackfill tests using a contractBackfiller for recording receipts and logs in a database. func (x *IndexerSuite) TestContractBackfill() { // Get simulated blockchain, deploy the test contract, and set up test variables. simulatedChain := geth.NewEmbeddedBackendForChainID(x.GetSuiteContext(), x.T(), big.NewInt(142)) simulatedClient, err := backend.DialBackend(x.GetTestContext(), simulatedChain.RPCAddress(), x.metrics) Nil(x.T(), err) simulatedChain.FundAccount(x.GetTestContext(), x.wallet.Address(), *big.NewInt(params.Ether)) testContract, testRef := x.manager.GetTestContract(x.GetTestContext(), simulatedChain) transactOpts := simulatedChain.GetTxContext(x.GetTestContext(), nil) // Set config. contractConfig := config.ContractConfig{ Address: testContract.Address().String(), StartBlock: 0, } simulatedChainArr := []backend.ScribeBackend{simulatedClient, simulatedClient} chainConfig := config.ChainConfig{ ChainID: 142, GetLogsBatchAmount: 1, Confirmations: 1, StoreConcurrency: 1, GetLogsRange: 1, ConcurrencyThreshold: 100, Contracts: []config.ContractConfig{contractConfig}, } blockHeightMeter, err := x.metrics.Metrics().NewHistogram(fmt.Sprint("scribe_block_meter", chainConfig.ChainID), "block_histogram", "a block height meter", "blocks") Nil(x.T(), err) contracts := []common.Address{common.HexToAddress(contractConfig.Address)} contractIndexer, err := indexer.NewIndexer(chainConfig, contracts, x.testDB, simulatedChainArr, x.metrics, blockHeightMeter, false) x.Require().NoError(err) // Emit events for the backfiller to read. tx, err := testRef.EmitEventA(transactOpts.TransactOpts, big.NewInt(1), big.NewInt(2), big.NewInt(3)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) tx, err = testRef.EmitEventA(transactOpts.TransactOpts, big.NewInt(1), big.NewInt(2), big.NewInt(3)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) tx, err = testRef.EmitEventB(transactOpts.TransactOpts, []byte{4}, big.NewInt(5), big.NewInt(6)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // Emit two logs in one receipt. tx, err = testRef.EmitEventAandB(transactOpts.TransactOpts, big.NewInt(7), big.NewInt(8), big.NewInt(9)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // Get the block that the last transaction was executed in. txBlockNumber, err := testutil.GetTxBlockNumber(x.GetTestContext(), simulatedChain, tx) Nil(x.T(), err) // Backfill the events. The `0` will be replaced with the startBlock from the config. err = contractIndexer.Index(x.GetTestContext(), contractConfig.StartBlock, txBlockNumber) Nil(x.T(), err) // Get all receipts. receipts, err := x.testDB.RetrieveReceiptsWithFilter(x.GetTestContext(), db.ReceiptFilter{}, 1) Nil(x.T(), err) // Check to see if 3 receipts were collected. Equal(x.T(), 4, len(receipts)) // Get all logs. logs, err := x.testDB.RetrieveLogsWithFilter(x.GetTestContext(), db.LogFilter{}, 1) Nil(x.T(), err) // Check to see if 4 logs were collected. Equal(x.T(), 5, len(logs)) // Check to see if the last receipt has two logs. Equal(x.T(), 2, len(receipts[0].Logs)) // Ensure last indexed block is correct. lastIndexed, err := x.testDB.RetrieveLastIndexed(x.GetTestContext(), testContract.Address(), uint32(testContract.ChainID().Uint64()), scribeTypes.IndexingConfirmed) Nil(x.T(), err) Equal(x.T(), txBlockNumber, lastIndexed) } // TestContractBackfill tests using a contractBackfiller for recording receipts and logs in a database. func (x *IndexerSuite) TestContractBackfillFromPreIndexed() { // Get simulated blockchain, deploy the test contract, and set up test variables. simulatedChain := geth.NewEmbeddedBackendForChainID(x.GetSuiteContext(), x.T(), big.NewInt(142)) simulatedClient, err := backend.DialBackend(x.GetTestContext(), simulatedChain.RPCAddress(), x.metrics) Nil(x.T(), err) simulatedChain.FundAccount(x.GetTestContext(), x.wallet.Address(), *big.NewInt(params.Ether)) testContract, testRef := x.manager.GetTestContract(x.GetTestContext(), simulatedChain) transactOpts := simulatedChain.GetTxContext(x.GetTestContext(), nil) // Set config. contractConfig := config.ContractConfig{ Address: testContract.Address().String(), StartBlock: 0, } simulatedChainArr := []backend.ScribeBackend{simulatedClient, simulatedClient} chainConfig := config.ChainConfig{ ChainID: 142, GetLogsBatchAmount: 1, StoreConcurrency: 1, Confirmations: 1, GetLogsRange: 1, ConcurrencyThreshold: 1, Contracts: []config.ContractConfig{contractConfig}, } blockHeightMeter, err := x.metrics.Metrics().NewHistogram(fmt.Sprint("scribe_block_meter", chainConfig.ChainID), "block_histogram", "a block height meter", "blocks") Nil(x.T(), err) contracts := []common.Address{common.HexToAddress(contractConfig.Address)} backfiller, err := indexer.NewIndexer(chainConfig, contracts, x.testDB, simulatedChainArr, x.metrics, blockHeightMeter, false) Nil(x.T(), err) // 1 log 1 receipt: r:1 l:1 tx, err := testRef.EmitEventA(transactOpts.TransactOpts, big.NewInt(1), big.NewInt(2), big.NewInt(3)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // 1 log 1 receipt: r:2 l:2 tx, err = testRef.EmitEventB(transactOpts.TransactOpts, []byte{4}, big.NewInt(5), big.NewInt(6)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // 2 logs 1 receipt: r:3 l:4 tx, err = testRef.EmitEventAandB(transactOpts.TransactOpts, big.NewInt(7), big.NewInt(8), big.NewInt(9)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // Get the block that the last transaction was executed in. txBlockNumber, err := testutil.GetTxBlockNumber(x.GetTestContext(), simulatedChain, tx) Nil(x.T(), err) err = x.testDB.StoreLastIndexed(x.GetTestContext(), common.HexToAddress(contractConfig.Address), chainConfig.ChainID, txBlockNumber, false) Nil(x.T(), err) // 1 log 1 receipt: r:4 l:5 tx, err = testRef.EmitEventA(transactOpts.TransactOpts, big.NewInt(10), big.NewInt(11), big.NewInt(12)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // 1 log 1 receipt: r:5 l:6 tx, err = testRef.EmitEventB(transactOpts.TransactOpts, []byte{13}, big.NewInt(14), big.NewInt(15)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // 2 logs 1 receipt: r:6 l:8 tx, err = testRef.EmitEventAandB(transactOpts.TransactOpts, big.NewInt(16), big.NewInt(17), big.NewInt(18)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // 2 logs 1 receipt: r:7 l:10 tx, err = testRef.EmitEventAandB(transactOpts.TransactOpts, big.NewInt(19), big.NewInt(20), big.NewInt(21)) Nil(x.T(), err) simulatedChain.WaitForConfirmation(x.GetTestContext(), tx) // Get the block that the last transaction was executed in. txBlockNumber, err = testutil.GetTxBlockNumber(x.GetTestContext(), simulatedChain, tx) Nil(x.T(), err) err = backfiller.Index(x.GetTestContext(), contractConfig.StartBlock, txBlockNumber) Nil(x.T(), err) // Get all receipts. receipts, err := x.testDB.RetrieveReceiptsWithFilter(x.GetTestContext(), db.ReceiptFilter{}, 1) Nil(x.T(), err) Equal(x.T(), 7, len(receipts)) // Get all logs. logs, err := x.testDB.RetrieveLogsWithFilter(x.GetTestContext(), db.LogFilter{}, 1) Nil(x.T(), err) Equal(x.T(), 10, len(logs)) // Check to see if the last receipt has two logs (emit a and b). Equal(x.T(), 2, len(receipts[0].Logs)) // Ensure last indexed block is correct. lastIndexed, err := x.testDB.RetrieveLastIndexed(x.GetTestContext(), testContract.Address(), uint32(testContract.ChainID().Uint64()), scribeTypes.IndexingConfirmed) Nil(x.T(), err) Equal(x.T(), txBlockNumber, lastIndexed) } func (x *IndexerSuite) TestGetLogs() { const desiredBlockHeight = 10 var testChainHandler *testutil.TestChainHandler var err error var wg sync.WaitGroup wg.Add(2) testBackend := geth.NewEmbeddedBackend(x.GetTestContext(), x.T()) go func() { defer wg.Done() testChainHandler, err = testutil.PopulateWithLogs(x.GetTestContext(), x.T(), testBackend, desiredBlockHeight, []*testutil.DeployManager{x.manager}) Nil(x.T(), err) }() var host string go func() { defer wg.Done() host = testutil.StartOmnirpcServer(x.GetTestContext(), x.T(), testBackend) }() wg.Wait() scribeBackend, err := backend.DialBackend(x.GetTestContext(), host, x.metrics) Nil(x.T(), err) simulatedChainArr := []backend.ScribeBackend{scribeBackend, scribeBackend} chainID, err := scribeBackend.ChainID(x.GetTestContext()) Nil(x.T(), err) var contractConfigs []config.ContractConfig addresses := testChainHandler.Addresses for _, address := range addresses { contractConfig := config.ContractConfig{ Address: address.String(), } contractConfigs = append(contractConfigs, contractConfig) } chainConfig := config.ChainConfig{ ChainID: uint32(chainID.Uint64()), Confirmations: 1, GetLogsBatchAmount: 1, StoreConcurrency: 1, GetLogsRange: 1, Contracts: contractConfigs, } blockHeightMeter, err := x.metrics.Metrics().NewHistogram(fmt.Sprint("scribe_block_meter", chainConfig.ChainID), "block_histogram", "a block height meter", "blocks") Nil(x.T(), err) contractBackfiller, err := indexer.NewIndexer(chainConfig, addresses, x.testDB, simulatedChainArr, x.metrics, blockHeightMeter, false) Nil(x.T(), err) startHeight, endHeight := uint64(1), uint64(10) err = contractBackfiller.Index(x.GetTestContext(), startHeight, endHeight) Nil(x.T(), err) logs, err := x.testDB.RetrieveLogsWithFilter(x.GetTestContext(), db.LogFilter{}, 1) Equal(x.T(), 2, len(logs)) // test error handling cancelCtx, cancel := context.WithCancel(x.GetTestContext()) cancel() err = contractBackfiller.Index(cancelCtx, endHeight, endHeight+10) NotNil(x.T(), err) } // TestTxTypeNotSupported tests how the contract backfiller handles a transaction type that is not supported. // // nolint:dupl func (x *IndexerSuite) TestTxTypeNotSupported() { if os.Getenv("CI") != "" { x.T().Skip("Network test flake") } var backendClient backend.ScribeBackend omnirpcURL := "https://arbitrum.llamarpc.com" backendClient, err := backend.DialBackend(x.GetTestContext(), omnirpcURL, x.metrics) Nil(x.T(), err) // This config is using this block https://arbiscan.io/block/6262099 // and this tx https://arbiscan.io/tx/0x8800222adf9578fb576db0bd7fb4860fe89932549be084a3313939c03e4d279d // with a unique Arbitrum type to verify that anomalous tx type is handled correctly. contractConfig := config.ContractConfig{ Address: "0xA67b7147DcE20D6F25Fd9ABfBCB1c3cA74E11f0B", StartBlock: 6262099, } chainConfig := config.ChainConfig{ ChainID: 42161, Confirmations: 1, GetLogsRange: 1, GetLogsBatchAmount: 1, Contracts: []config.ContractConfig{contractConfig}, } addresses := []common.Address{common.HexToAddress(contractConfig.Address)} backendClientArr := []backend.ScribeBackend{backendClient, backendClient} blockHeightMeter, err := x.metrics.Metrics().NewHistogram(fmt.Sprint("scribe_block_meter", chainConfig.ChainID), "block_histogram", "a block height meter", "blocks") Nil(x.T(), err) contractIndexer, err := indexer.NewIndexer(chainConfig, addresses, x.testDB, backendClientArr, x.metrics, blockHeightMeter, false) Nil(x.T(), err) err = contractIndexer.Index(x.GetTestContext(), contractConfig.StartBlock, contractConfig.StartBlock+1) Nil(x.T(), err) logs, err := x.testDB.RetrieveLogsWithFilter(x.GetTestContext(), db.LogFilter{}, 1) Nil(x.T(), err) Equal(x.T(), 4, len(logs)) receipts, err := x.testDB.RetrieveReceiptsWithFilter(x.GetTestContext(), db.ReceiptFilter{}, 1) Nil(x.T(), err) Equal(x.T(), 1, len(receipts)) } // TestTxTypeNotSupported tests how the contract indexerer handles a transaction type that is not supported. // // nolint:dupl func (x IndexerSuite) TestInvalidTxVRS() { if os.Getenv("CI") != "" { x.T().Skip("Network test flake") } var backendClient backend.ScribeBackend omnirpcURL := "https://rpc.interoperability.institute/confirmations/1/rpc/1313161554" backendClient, err := backend.DialBackend(x.GetTestContext(), omnirpcURL, x.metrics) Nil(x.T(), err) // This config is using this block https://aurorascan.dev/block/58621373 // and this tx https://aurorascan.dev/tx/0x687282d7bd6c3d591f9ad79784e0983afabcac2a9074d368b7ca3d7caf4edee5 // to test handling of the v,r,s tx not found error. contractConfig := config.ContractConfig{ Address: "0xaeD5b25BE1c3163c907a471082640450F928DDFE", StartBlock: 58621373, } chainConfig := config.ChainConfig{ ChainID: 1313161554, Confirmations: 1, GetLogsRange: 1, GetLogsBatchAmount: 1, Contracts: []config.ContractConfig{contractConfig}, } addresses := []common.Address{common.HexToAddress(contractConfig.Address)} backendClientArr := []backend.ScribeBackend{backendClient, backendClient} blockHeightMeter, err := x.metrics.Metrics().NewHistogram(fmt.Sprint("scribe_block_meter", chainConfig.ChainID), "block_histogram", "a block height meter", "blocks") Nil(x.T(), err) contractIndexer, err := indexer.NewIndexer(chainConfig, addresses, x.testDB, backendClientArr, x.metrics, blockHeightMeter, false) Nil(x.T(), err) err = contractIndexer.Index(x.GetTestContext(), contractConfig.StartBlock, contractConfig.StartBlock+1) Nil(x.T(), err) logs, err := x.testDB.RetrieveLogsWithFilter(x.GetTestContext(), db.LogFilter{}, 1) Nil(x.T(), err) Equal(x.T(), 9, len(logs)) receipts, err := x.testDB.RetrieveReceiptsWithFilter(x.GetTestContext(), db.ReceiptFilter{}, 1) Nil(x.T(), err) Equal(x.T(), 1, len(receipts)) } func (x *IndexerSuite) TestLargeVolumeIndexer() { if os.Getenv("CI") != "" { x.T().Skip("Long running test") } const desiredBlockHeight = 20 var testChainHandler *testutil.TestChainHandler var err error var wg sync.WaitGroup wg.Add(2) testBackend := geth.NewEmbeddedBackend(x.GetTestContext(), x.T()) go func() { defer wg.Done() testChainHandler, err = testutil.PopulateWithLogs(x.GetTestContext(), x.T(), testBackend, desiredBlockHeight, []*testutil.DeployManager{x.manager}) Nil(x.T(), err) }() var host string go func() { defer wg.Done() host = testutil.StartOmnirpcServer(x.GetTestContext(), x.T(), testBackend) }() wg.Wait() scribeBackend, err := backend.DialBackend(x.GetTestContext(), host, x.metrics) Nil(x.T(), err) simulatedChainArr := []backend.ScribeBackend{scribeBackend, scribeBackend} chainID, err := scribeBackend.ChainID(x.GetTestContext()) Nil(x.T(), err) contractAddress := testChainHandler.Addresses[0] contractConfigs := []config.ContractConfig{ {Address: contractAddress.String()}, } addresses := testChainHandler.Addresses chainConfig := config.ChainConfig{ ChainID: uint32(chainID.Uint64()), Confirmations: 1, GetLogsBatchAmount: 1, StoreConcurrency: 1, GetLogsRange: 1, Contracts: contractConfigs, } blockHeightMeter, err := x.metrics.Metrics().NewHistogram(fmt.Sprint("scribe_block_meter", chainConfig.ChainID), "block_histogram", "a block height meter", "blocks") Nil(x.T(), err) contractBackfiller, err := indexer.NewIndexer(chainConfig, addresses, x.testDB, simulatedChainArr, x.metrics, blockHeightMeter, false) Nil(x.T(), err) endHeight, err := scribeBackend.BlockNumber(x.GetTestContext()) Nil(x.T(), err) err = contractBackfiller.Index(x.GetTestContext(), uint64(1), endHeight) Nil(x.T(), err) logs, err := testutil.GetLogsUntilNoneLeft(x.GetTestContext(), x.testDB, db.LogFilter{}) Equal(x.T(), int(testChainHandler.EventsEmitted[contractAddress]), len(logs)) }