From 36375ce576340e6c3dad25004d717b22041b364b Mon Sep 17 00:00:00 2001 From: iuwqyir Date: Tue, 8 Oct 2024 19:39:21 +0300 Subject: [PATCH] test setup and reorg tests --- .dockerignore | 1 + .github/workflows/format.yml | 2 +- .github/workflows/test.yml | 29 ++ .mockery.yaml | 16 + Dockerfile | 2 +- README.md | 2 +- docker-compose.yml | 2 +- go.mod | 4 + go.sum | 2 + internal/orchestrator/reorg_handler.go | 82 ++-- internal/orchestrator/reorg_handler_test.go | 502 ++++++++++++++++++++ test/mocks/MockIMainStorage.go | 480 +++++++++++++++++++ test/mocks/MockIOrchestratorStorage.go | 296 ++++++++++++ test/mocks/MockIRPCClient.go | 419 ++++++++++++++++ test/mocks/MockIStagingStorage.go | 250 ++++++++++ 15 files changed, 2051 insertions(+), 38 deletions(-) create mode 100644 .github/workflows/test.yml create mode 100644 .mockery.yaml create mode 100644 internal/orchestrator/reorg_handler_test.go create mode 100644 test/mocks/MockIMainStorage.go create mode 100644 test/mocks/MockIOrchestratorStorage.go create mode 100644 test/mocks/MockIRPCClient.go create mode 100644 test/mocks/MockIStagingStorage.go diff --git a/.dockerignore b/.dockerignore index d6e55a9..53ecbed 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ .env +.mockery.yaml configs/secrets* \ No newline at end of file diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 5b484c6..b89435b 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..6bf6bee --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,29 @@ +name: Go Unit Tests + +on: + push: + branches: [main] + pull_request: + types: [opened, synchronize] + workflow_dispatch: + +jobs: + test: + name: Test + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.23' + + - name: Install dependencies + run: go mod download + + - name: Run Unit Tests + run: go test ./... -v + env: + GO_ENV: "test" diff --git a/.mockery.yaml b/.mockery.yaml new file mode 100644 index 0000000..6f0d628 --- /dev/null +++ b/.mockery.yaml @@ -0,0 +1,16 @@ +with-expecter: true +mockname: "Mock{{.InterfaceName}}" +filename: "{{.MockName}}.go" +outpkg: mocks +dir: test/mocks +mock-build-tags: "!production" +packages: + github.com/thirdweb-dev/indexer/internal/rpc: + interfaces: + IRPCClient: + github.com/thirdweb-dev/indexer/internal/storage: + interfaces: + IStorage: + IMainStorage: + IStagingStorage: + IOrchestratorStorage: diff --git a/Dockerfile b/Dockerfile index ca901bc..34b0a6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN go mod download COPY . . -RUN go build -o /bin/app main.go +RUN go build -o /bin/app -tags=production main.go FROM alpine:3.18 diff --git a/README.md b/README.md index 6af284a..3e210d5 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ git clone https://github.com/thirdweb-dev/insight.git 4. Create `secrets.yml` from `secrects.example.yml` and set the needed credentials 5. Build an instance ``` -go build -o main +go build -o main -tags=production ``` 6. Run insight ``` diff --git a/docker-compose.yml b/docker-compose.yml index 8ca8f03..580ad48 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,7 +14,7 @@ services: image: clickhouse/clickhouse-server:latest ports: - "8123:8123" - - "9000:9000" + - "9440:9000" volumes: - clickhouse_data:/var/lib/clickhouse ulimits: diff --git a/go.mod b/go.mod index 88a3dc4..e174c4b 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.18.0 + github.com/stretchr/testify v1.9.0 github.com/swaggo/files v1.0.1 github.com/swaggo/gin-swagger v1.6.0 github.com/swaggo/swag v1.16.3 @@ -35,6 +36,7 @@ require ( github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -76,6 +78,7 @@ require ( github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -88,6 +91,7 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect diff --git a/go.sum b/go.sum index a84ca05..00e34e6 100644 --- a/go.sum +++ b/go.sum @@ -276,6 +276,8 @@ github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/internal/orchestrator/reorg_handler.go b/internal/orchestrator/reorg_handler.go index 412dfe7..3f34d11 100644 --- a/internal/orchestrator/reorg_handler.go +++ b/internal/orchestrator/reorg_handler.go @@ -71,38 +71,20 @@ func (rh *ReorgHandler) Start() { log.Debug().Msgf("Reorg handler running") go func() { for range ticker.C { - lookbackFrom := new(big.Int).Add(rh.lastCheckedBlock, big.NewInt(int64(rh.blocksPerScan))) - blockHeaders, err := rh.storage.MainStorage.LookbackBlockHeaders(rh.rpc.GetChainID(), rh.blocksPerScan, lookbackFrom) + // need to include lastCheckedBlock to check if next block's parent matches + lookbackFrom := new(big.Int).Add(rh.lastCheckedBlock, big.NewInt(int64(rh.blocksPerScan-1))) + mostRecentBlockChecked, err := rh.RunFromBlock(lookbackFrom) if err != nil { - log.Error().Err(err).Msg("Error getting recent block headers") + log.Error().Err(err).Msg("Error during reorg handling") continue } - if len(blockHeaders) == 0 { - log.Warn().Msg("No block headers found") + if mostRecentBlockChecked == nil { continue } - mostRecentBlockHeader := blockHeaders[0] - reorgEndIndex := findReorgEndIndex(blockHeaders) - if reorgEndIndex == -1 { - rh.lastCheckedBlock = mostRecentBlockHeader.Number - rh.storage.OrchestratorStorage.SetLastReorgCheckedBlockNumber(rh.rpc.GetChainID(), mostRecentBlockHeader.Number) - metrics.ReorgHandlerLastCheckedBlock.Set(float64(mostRecentBlockHeader.Number.Int64())) - continue - } - metrics.ReorgCounter.Inc() - forkPoint, err := rh.findForkPoint(blockHeaders[reorgEndIndex:]) - if err != nil { - log.Error().Err(err).Msg("Error while finding fork point") - continue - } - err = rh.handleReorg(forkPoint, lookbackFrom) - if err != nil { - log.Error().Err(err).Msg("Error while handling reorg") - continue - } - rh.lastCheckedBlock = mostRecentBlockHeader.Number - rh.storage.OrchestratorStorage.SetLastReorgCheckedBlockNumber(rh.rpc.GetChainID(), mostRecentBlockHeader.Number) - metrics.ReorgHandlerLastCheckedBlock.Set(float64(mostRecentBlockHeader.Number.Int64())) + + rh.lastCheckedBlock = mostRecentBlockChecked + rh.storage.OrchestratorStorage.SetLastReorgCheckedBlockNumber(rh.rpc.GetChainID(), mostRecentBlockChecked) + metrics.ReorgHandlerLastCheckedBlock.Set(float64(mostRecentBlockChecked.Int64())) } }() @@ -110,6 +92,34 @@ func (rh *ReorgHandler) Start() { select {} } +func (rh *ReorgHandler) RunFromBlock(lookbackFrom *big.Int) (lastCheckedBlock *big.Int, err error) { + blockHeaders, err := rh.storage.MainStorage.LookbackBlockHeaders(rh.rpc.GetChainID(), rh.blocksPerScan, lookbackFrom) + if err != nil { + return nil, fmt.Errorf("error getting recent block headers: %w", err) + } + if len(blockHeaders) == 0 { + log.Warn().Msg("No block headers found during reorg handling") + return nil, nil + } + mostRecentBlockHeader := blockHeaders[0] + log.Debug().Msgf("Checking for reorgs from block %s to %s", mostRecentBlockHeader.Number.String(), blockHeaders[len(blockHeaders)-1].Number.String()) + reorgEndIndex := findReorgEndIndex(blockHeaders) + if reorgEndIndex == -1 { + return mostRecentBlockHeader.Number, nil + } + reorgEndBlock := blockHeaders[reorgEndIndex].Number + metrics.ReorgCounter.Inc() + forkPoint, err := rh.findFirstForkedBlockNumber(blockHeaders[reorgEndIndex:]) + if err != nil { + return nil, fmt.Errorf("error while finding fork point: %w", err) + } + err = rh.handleReorg(forkPoint, reorgEndBlock) + if err != nil { + return nil, fmt.Errorf("error while handling reorg: %w", err) + } + return mostRecentBlockHeader.Number, nil +} + func findReorgEndIndex(reversedBlockHeaders []common.BlockHeader) (index int) { for i := 0; i < len(reversedBlockHeaders)-1; i++ { currentBlock := reversedBlockHeaders[i] @@ -129,20 +139,21 @@ func findReorgEndIndex(reversedBlockHeaders []common.BlockHeader) (index int) { return -1 } -func (rh *ReorgHandler) findForkPoint(reversedBlockHeaders []common.BlockHeader) (forkPoint *big.Int, err error) { +func (rh *ReorgHandler) findFirstForkedBlockNumber(reversedBlockHeaders []common.BlockHeader) (forkPoint *big.Int, err error) { newBlocksByNumber, err := rh.getNewBlocksByNumber(reversedBlockHeaders) if err != nil { return nil, err } - for i := 0; i < len(reversedBlockHeaders)-1; i++ { + // skip first because that is the reorg end block + for i := 1; i < len(reversedBlockHeaders); i++ { blockHeader := reversedBlockHeaders[i] block, ok := (*newBlocksByNumber)[blockHeader.Number.String()] if !ok { return nil, fmt.Errorf("block not found: %s", blockHeader.Number.String()) } - if block.Hash == blockHeader.Hash { - previousBlock := reversedBlockHeaders[i+1] + if blockHeader.ParentHash == block.ParentHash && blockHeader.Hash == block.Hash { + previousBlock := reversedBlockHeaders[i-1] return previousBlock.Number, nil } } @@ -151,7 +162,7 @@ func (rh *ReorgHandler) findForkPoint(reversedBlockHeaders []common.BlockHeader) if err != nil { return nil, fmt.Errorf("error getting next headers batch: %w", err) } - return rh.findForkPoint(nextHeadersBatch) + return rh.findFirstForkedBlockNumber(nextHeadersBatch) } func (rh *ReorgHandler) getNewBlocksByNumber(reversedBlockHeaders []common.BlockHeader) (*map[string]common.Block, error) { @@ -171,6 +182,7 @@ func (rh *ReorgHandler) getNewBlocksByNumber(reversedBlockHeaders []common.Block } func (rh *ReorgHandler) handleReorg(reorgStart *big.Int, reorgEnd *big.Int) error { + log.Debug().Msgf("Handling reorg from block %s to %s", reorgStart.String(), reorgEnd.String()) blockRange := make([]*big.Int, 0, new(big.Int).Sub(reorgEnd, reorgStart).Int64()) for i := new(big.Int).Set(reorgStart); i.Cmp(reorgEnd) <= 0; i.Add(i, big.NewInt(1)) { blockRange = append(blockRange, new(big.Int).Set(i)) @@ -178,6 +190,7 @@ func (rh *ReorgHandler) handleReorg(reorgStart *big.Int, reorgEnd *big.Int) erro results := rh.worker.Run(blockRange) data := make([]common.BlockData, 0, len(results)) + blocksToDelete := make([]*big.Int, 0, len(results)) for _, result := range results { if result.Error != nil { return fmt.Errorf("cannot fix reorg: failed block %s: %w", result.BlockNumber.String(), result.Error) @@ -188,10 +201,11 @@ func (rh *ReorgHandler) handleReorg(reorgStart *big.Int, reorgEnd *big.Int) erro Transactions: result.Data.Transactions, Traces: result.Data.Traces, }) + blocksToDelete = append(blocksToDelete, result.BlockNumber) } // TODO make delete and insert atomic - if err := rh.storage.MainStorage.DeleteBlockData(rh.rpc.GetChainID(), blockRange); err != nil { - return fmt.Errorf("error deleting data for blocks %v: %w", blockRange, err) + if err := rh.storage.MainStorage.DeleteBlockData(rh.rpc.GetChainID(), blocksToDelete); err != nil { + return fmt.Errorf("error deleting data for blocks %v: %w", blocksToDelete, err) } if err := rh.storage.MainStorage.InsertBlockData(&data); err != nil { return fmt.Errorf("error saving data to main storage: %w", err) diff --git a/internal/orchestrator/reorg_handler_test.go b/internal/orchestrator/reorg_handler_test.go new file mode 100644 index 0000000..20d6069 --- /dev/null +++ b/internal/orchestrator/reorg_handler_test.go @@ -0,0 +1,502 @@ +package orchestrator + +import ( + "math/big" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + config "github.com/thirdweb-dev/indexer/configs" + "github.com/thirdweb-dev/indexer/internal/common" + "github.com/thirdweb-dev/indexer/internal/rpc" + "github.com/thirdweb-dev/indexer/internal/storage" + mocks "github.com/thirdweb-dev/indexer/test/mocks" +) + +func TestNewReorgHandler(t *testing.T) { + defer func() { config.Cfg = config.Config{} }() + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + config.Cfg.ReorgHandler.Interval = 500 + config.Cfg.ReorgHandler.BlocksPerScan = 50 + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(0), nil) + + handler := NewReorgHandler(mockRPC, mockStorage) + + assert.Equal(t, 500, handler.triggerInterval) + assert.Equal(t, 50, handler.blocksPerScan) + assert.Equal(t, big.NewInt(0), handler.lastCheckedBlock) +} + +func TestNewReorgHandlerStartsFromStoredBlock(t *testing.T) { + defer func() { config.Cfg = config.Config{} }() + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + config.Cfg.ReorgHandler.BlocksPerScan = 50 + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(99), nil) + + handler := NewReorgHandler(mockRPC, mockStorage) + + assert.Equal(t, big.NewInt(99), handler.lastCheckedBlock) +} + +func TestNewReorgHandlerStartsFromConfiguredBlock(t *testing.T) { + defer func() { config.Cfg = config.Config{} }() + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + config.Cfg.ReorgHandler.BlocksPerScan = 50 + config.Cfg.ReorgHandler.FromBlock = 1000 + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(0), nil) + + handler := NewReorgHandler(mockRPC, mockStorage) + + assert.Equal(t, big.NewInt(1000), handler.lastCheckedBlock) +} + +func TestFindReorgEndIndex(t *testing.T) { + tests := []struct { + name string + reversedBlockHeaders []common.BlockHeader + expectedIndex int + }{ + { + name: "No reorg", + reversedBlockHeaders: []common.BlockHeader{ + {Number: big.NewInt(3), Hash: "hash3", ParentHash: "hash2"}, + {Number: big.NewInt(2), Hash: "hash2", ParentHash: "hash1"}, + {Number: big.NewInt(1), Hash: "hash1", ParentHash: "hash0"}, + }, + expectedIndex: -1, + }, + { + name: "Single block reorg detected", + reversedBlockHeaders: []common.BlockHeader{ + {Number: big.NewInt(3), Hash: "hash3", ParentHash: "hash2b"}, + {Number: big.NewInt(2), Hash: "hash2b", ParentHash: "hash1b"}, + {Number: big.NewInt(1), Hash: "hash1", ParentHash: "hash0"}, + }, + expectedIndex: 1, + }, + { + name: "Reorg detected", + reversedBlockHeaders: []common.BlockHeader{ + {Number: big.NewInt(6), Hash: "hash6", ParentHash: "hash5"}, + {Number: big.NewInt(5), Hash: "hash5", ParentHash: "hash4"}, + {Number: big.NewInt(4), Hash: "hash4", ParentHash: "hash3"}, + {Number: big.NewInt(3), Hash: "hash3a", ParentHash: "hash2a"}, + {Number: big.NewInt(2), Hash: "hash2a", ParentHash: "hash1a"}, + {Number: big.NewInt(1), Hash: "hash1", ParentHash: "hash0"}, + }, + expectedIndex: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := findReorgEndIndex(tt.reversedBlockHeaders) + assert.Equal(t, tt.expectedIndex, result) + }) + } +} + +func TestNewReorgHandlerWithForceFromBlock(t *testing.T) { + defer func() { config.Cfg = config.Config{} }() + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + config.Cfg.ReorgHandler.BlocksPerScan = 50 + config.Cfg.ReorgHandler.FromBlock = 2000 + config.Cfg.ReorgHandler.ForceFromBlock = true + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + + handler := NewReorgHandler(mockRPC, mockStorage) + + assert.Equal(t, big.NewInt(2000), handler.lastCheckedBlock) +} + +func TestFindFirstForkedBlockNumber(t *testing.T) { + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(3), nil) + handler := NewReorgHandler(mockRPC, mockStorage) + + reversedBlockHeaders := []common.BlockHeader{ + {Number: big.NewInt(3), Hash: "hash3a", ParentHash: "hash2"}, // <- fork starts and ends here + {Number: big.NewInt(2), Hash: "hash2", ParentHash: "hash1"}, + {Number: big.NewInt(1), Hash: "hash1", ParentHash: "hash0"}, + } + + mockRPC.EXPECT().GetBlocks([]*big.Int{big.NewInt(3), big.NewInt(2), big.NewInt(1)}).Return([]rpc.GetBlocksResult{ + {BlockNumber: big.NewInt(3), Data: common.Block{Hash: "hash3", ParentHash: "hash2"}}, + {BlockNumber: big.NewInt(2), Data: common.Block{Hash: "hash2", ParentHash: "hash1"}}, + {BlockNumber: big.NewInt(1), Data: common.Block{Hash: "hash1", ParentHash: "hash0"}}, + }) + + forkPoint, err := handler.findFirstForkedBlockNumber(reversedBlockHeaders) + + assert.NoError(t, err) + assert.Equal(t, big.NewInt(3), forkPoint) +} + +func TestFindFirstForkedBlockNumberWithLastBlockInSlice(t *testing.T) { + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(3), nil) + handler := NewReorgHandler(mockRPC, mockStorage) + + reversedBlockHeaders := []common.BlockHeader{ + {Number: big.NewInt(3), Hash: "hash3a", ParentHash: "hash2a"}, + {Number: big.NewInt(2), Hash: "hash2a", ParentHash: "hash1"}, // <- fork starts from here + {Number: big.NewInt(1), Hash: "hash1", ParentHash: "hash0"}, + } + + mockRPC.EXPECT().GetBlocks([]*big.Int{big.NewInt(3), big.NewInt(2), big.NewInt(1)}).Return([]rpc.GetBlocksResult{ + {BlockNumber: big.NewInt(3), Data: common.Block{Hash: "hash3", ParentHash: "hash2"}}, + {BlockNumber: big.NewInt(2), Data: common.Block{Hash: "hash2", ParentHash: "hash1"}}, + {BlockNumber: big.NewInt(1), Data: common.Block{Hash: "hash1", ParentHash: "hash0"}}, + }) + + forkPoint, err := handler.findFirstForkedBlockNumber(reversedBlockHeaders) + + assert.NoError(t, err) + assert.Equal(t, big.NewInt(2), forkPoint) +} + +func TestFindFirstForkedBlockNumberRecursively(t *testing.T) { + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(3), nil) + handler := NewReorgHandler(mockRPC, mockStorage) + + mockRPC.EXPECT().GetBlocks([]*big.Int{big.NewInt(6), big.NewInt(5), big.NewInt(4)}).Return([]rpc.GetBlocksResult{ + {BlockNumber: big.NewInt(6), Data: common.Block{Hash: "hash6", ParentHash: "hash5"}}, + {BlockNumber: big.NewInt(5), Data: common.Block{Hash: "hash5", ParentHash: "hash4"}}, + {BlockNumber: big.NewInt(4), Data: common.Block{Hash: "hash4", ParentHash: "hash3"}}, + }).Once() + + mockRPC.EXPECT().GetBlocks([]*big.Int{big.NewInt(4), big.NewInt(3), big.NewInt(2), big.NewInt(1)}).Return([]rpc.GetBlocksResult{ + {BlockNumber: big.NewInt(4), Data: common.Block{Hash: "hash4", ParentHash: "hash3"}}, + {BlockNumber: big.NewInt(3), Data: common.Block{Hash: "hash3", ParentHash: "hash2"}}, + {BlockNumber: big.NewInt(2), Data: common.Block{Hash: "hash2", ParentHash: "hash1"}}, + {BlockNumber: big.NewInt(1), Data: common.Block{Hash: "hash1", ParentHash: "hash0"}}, + }).Once() + + initialBlockHeaders := []common.BlockHeader{ + {Number: big.NewInt(6), Hash: "hash6a", ParentHash: "hash5a"}, + {Number: big.NewInt(5), Hash: "hash5a", ParentHash: "hash4a"}, + {Number: big.NewInt(4), Hash: "hash4a", ParentHash: "hash3a"}, + } + + mockMainStorage.EXPECT().LookbackBlockHeaders(big.NewInt(1), mock.Anything, big.NewInt(4)).Return([]common.BlockHeader{ + {Number: big.NewInt(4), Hash: "hash4a", ParentHash: "hash3a"}, + {Number: big.NewInt(3), Hash: "hash3a", ParentHash: "hash2"}, // <- fork starts from here + {Number: big.NewInt(2), Hash: "hash2", ParentHash: "hash1"}, + {Number: big.NewInt(1), Hash: "hash1", ParentHash: "hash0"}, + }, nil) + + forkPoint, err := handler.findFirstForkedBlockNumber(initialBlockHeaders) + + assert.NoError(t, err) + assert.Equal(t, big.NewInt(3), forkPoint) +} + +func TestHandleReorg(t *testing.T) { + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockRPC.EXPECT().GetBlocksPerRequest().Return(rpc.BlocksPerRequestConfig{Blocks: 100}) + mockRPC.EXPECT().GetFullBlocks(mock.Anything).Return([]rpc.GetFullBlockResult{ + {BlockNumber: big.NewInt(1), Data: common.BlockData{}}, + {BlockNumber: big.NewInt(2), Data: common.BlockData{}}, + {BlockNumber: big.NewInt(3), Data: common.BlockData{}}, + }) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(3), nil) + + reorgStart := big.NewInt(1) + reorgEnd := big.NewInt(3) + + mockMainStorage.EXPECT().DeleteBlockData(big.NewInt(1), mock.Anything).Return(nil) + mockMainStorage.EXPECT().InsertBlockData(mock.Anything).Return(nil) + + handler := NewReorgHandler(mockRPC, mockStorage) + err := handler.handleReorg(reorgStart, reorgEnd) + + assert.NoError(t, err) +} + +func TestStart(t *testing.T) { + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)).Times(5) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(2000), nil).Times(1) + handler := NewReorgHandler(mockRPC, mockStorage) + handler.triggerInterval = 100 // Set a short interval for testing + + mockMainStorage.EXPECT().LookbackBlockHeaders(mock.Anything, mock.Anything, mock.Anything).Return([]common.BlockHeader{ + {Number: big.NewInt(3), Hash: "hash3", ParentHash: "hash2"}, + {Number: big.NewInt(2), Hash: "hash2", ParentHash: "hash1"}, + {Number: big.NewInt(1), Hash: "hash1", ParentHash: "hash0"}, + }, nil).Times(2) + + mockOrchestratorStorage.EXPECT().SetLastReorgCheckedBlockNumber(mock.Anything, mock.Anything).Return(nil).Times(2) + + go handler.Start() + + // Allow some time for the goroutine to run + time.Sleep(250 * time.Millisecond) +} + +func TestHandleReorgWithSingleBlockReorg(t *testing.T) { + defer func() { config.Cfg = config.Config{} }() + config.Cfg.ReorgHandler.BlocksPerScan = 10 + + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockRPC.EXPECT().GetBlocksPerRequest().Return(rpc.BlocksPerRequestConfig{Blocks: 100}) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(100), nil) + + mockMainStorage.EXPECT().LookbackBlockHeaders(big.NewInt(1), 10, big.NewInt(109)).Return([]common.BlockHeader{ + {Number: big.NewInt(109), Hash: "hash109", ParentHash: "hash108"}, + {Number: big.NewInt(108), Hash: "hash108", ParentHash: "hash107"}, + {Number: big.NewInt(107), Hash: "hash107", ParentHash: "hash106"}, + {Number: big.NewInt(106), Hash: "hash106", ParentHash: "hash105"}, // <-- fork ends here + {Number: big.NewInt(105), Hash: "hash105a", ParentHash: "hash104"}, // <-- fork starts here + {Number: big.NewInt(104), Hash: "hash104", ParentHash: "hash103"}, + {Number: big.NewInt(103), Hash: "hash103", ParentHash: "hash102"}, + {Number: big.NewInt(102), Hash: "hash102", ParentHash: "hash101"}, + {Number: big.NewInt(101), Hash: "hash101", ParentHash: "hash100"}, + {Number: big.NewInt(100), Hash: "hash100", ParentHash: "hash99"}, + }, nil) + + mockRPC.EXPECT().GetBlocks([]*big.Int{big.NewInt(106), big.NewInt(105), big.NewInt(104), big.NewInt(103), big.NewInt(102), big.NewInt(101), big.NewInt(100)}).Return([]rpc.GetBlocksResult{ + {BlockNumber: big.NewInt(106), Data: common.Block{Hash: "hash106", ParentHash: "hash105"}}, + {BlockNumber: big.NewInt(105), Data: common.Block{Hash: "hash105", ParentHash: "hash104"}}, + {BlockNumber: big.NewInt(104), Data: common.Block{Hash: "hash104", ParentHash: "hash103"}}, + {BlockNumber: big.NewInt(103), Data: common.Block{Hash: "hash103", ParentHash: "hash102"}}, + {BlockNumber: big.NewInt(102), Data: common.Block{Hash: "hash102", ParentHash: "hash101"}}, + {BlockNumber: big.NewInt(101), Data: common.Block{Hash: "hash101", ParentHash: "hash100"}}, + {BlockNumber: big.NewInt(100), Data: common.Block{Hash: "hash100", ParentHash: "hash99"}}, + }) + + mockRPC.EXPECT().GetFullBlocks([]*big.Int{big.NewInt(105), big.NewInt(106)}).Return([]rpc.GetFullBlockResult{ + {BlockNumber: big.NewInt(105), Data: common.BlockData{}}, + {BlockNumber: big.NewInt(106), Data: common.BlockData{}}, + }) + + mockMainStorage.EXPECT().DeleteBlockData(big.NewInt(1), mock.MatchedBy(func(blocks []*big.Int) bool { + return len(blocks) == 2 + })).Return(nil) + mockMainStorage.EXPECT().InsertBlockData(mock.MatchedBy(func(data *[]common.BlockData) bool { + return data != nil && len(*data) == 2 + })).Return(nil) + + handler := NewReorgHandler(mockRPC, mockStorage) + mostRecentBlockChecked, err := handler.RunFromBlock(big.NewInt(109)) + + assert.NoError(t, err) + assert.Equal(t, big.NewInt(109), mostRecentBlockChecked) +} + +func TestHandleReorgWithLatestBlockReorged(t *testing.T) { + defer func() { config.Cfg = config.Config{} }() + config.Cfg.ReorgHandler.BlocksPerScan = 10 + + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockRPC.EXPECT().GetBlocksPerRequest().Return(rpc.BlocksPerRequestConfig{Blocks: 100}) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(100), nil) + + mockMainStorage.EXPECT().LookbackBlockHeaders(big.NewInt(1), 10, big.NewInt(109)).Return([]common.BlockHeader{ + {Number: big.NewInt(109), Hash: "hash109", ParentHash: "hash108a"}, // <-- fork starts here + {Number: big.NewInt(108), Hash: "hash108", ParentHash: "hash107"}, + {Number: big.NewInt(107), Hash: "hash107", ParentHash: "hash106"}, + {Number: big.NewInt(106), Hash: "hash106", ParentHash: "hash105"}, + {Number: big.NewInt(105), Hash: "hash105", ParentHash: "hash104"}, + {Number: big.NewInt(104), Hash: "hash104", ParentHash: "hash103"}, + {Number: big.NewInt(103), Hash: "hash103", ParentHash: "hash102"}, + {Number: big.NewInt(102), Hash: "hash102", ParentHash: "hash101"}, + {Number: big.NewInt(101), Hash: "hash101", ParentHash: "hash100"}, + {Number: big.NewInt(100), Hash: "hash100", ParentHash: "hash99"}, + }, nil) + + mockRPC.EXPECT().GetBlocks([]*big.Int{big.NewInt(109), big.NewInt(108), big.NewInt(107), big.NewInt(106), big.NewInt(105), big.NewInt(104), big.NewInt(103), big.NewInt(102), big.NewInt(101), big.NewInt(100)}).Return([]rpc.GetBlocksResult{ + {BlockNumber: big.NewInt(109), Data: common.Block{Hash: "hash109", ParentHash: "hash108"}}, + {BlockNumber: big.NewInt(108), Data: common.Block{Hash: "hash108", ParentHash: "hash107"}}, + {BlockNumber: big.NewInt(107), Data: common.Block{Hash: "hash107", ParentHash: "hash106"}}, + {BlockNumber: big.NewInt(106), Data: common.Block{Hash: "hash106", ParentHash: "hash105"}}, + {BlockNumber: big.NewInt(105), Data: common.Block{Hash: "hash105", ParentHash: "hash104"}}, + {BlockNumber: big.NewInt(104), Data: common.Block{Hash: "hash104", ParentHash: "hash103"}}, + {BlockNumber: big.NewInt(103), Data: common.Block{Hash: "hash103", ParentHash: "hash102"}}, + {BlockNumber: big.NewInt(102), Data: common.Block{Hash: "hash102", ParentHash: "hash101"}}, + {BlockNumber: big.NewInt(101), Data: common.Block{Hash: "hash101", ParentHash: "hash100"}}, + {BlockNumber: big.NewInt(100), Data: common.Block{Hash: "hash100", ParentHash: "hash99"}}, + }) + + mockRPC.EXPECT().GetFullBlocks([]*big.Int{big.NewInt(109)}).Return([]rpc.GetFullBlockResult{ + {BlockNumber: big.NewInt(109), Data: common.BlockData{}}, + }) + + mockMainStorage.EXPECT().DeleteBlockData(big.NewInt(1), mock.MatchedBy(func(blocks []*big.Int) bool { + return len(blocks) == 1 + })).Return(nil) + mockMainStorage.EXPECT().InsertBlockData(mock.MatchedBy(func(data *[]common.BlockData) bool { + return data != nil && len(*data) == 1 + })).Return(nil) + + handler := NewReorgHandler(mockRPC, mockStorage) + mostRecentBlockChecked, err := handler.RunFromBlock(big.NewInt(109)) + + assert.NoError(t, err) + assert.Equal(t, big.NewInt(109), mostRecentBlockChecked) +} + +func TestHandleReorgWithManyBlocks(t *testing.T) { + defer func() { config.Cfg = config.Config{} }() + config.Cfg.ReorgHandler.BlocksPerScan = 10 + + mockRPC := mocks.NewMockIRPCClient(t) + mockMainStorage := mocks.NewMockIMainStorage(t) + mockOrchestratorStorage := mocks.NewMockIOrchestratorStorage(t) + + mockStorage := storage.IStorage{ + MainStorage: mockMainStorage, + OrchestratorStorage: mockOrchestratorStorage, + } + + mockRPC.EXPECT().GetChainID().Return(big.NewInt(1)) + mockRPC.EXPECT().GetBlocksPerRequest().Return(rpc.BlocksPerRequestConfig{Blocks: 100}) + mockOrchestratorStorage.EXPECT().GetLastReorgCheckedBlockNumber(big.NewInt(1)).Return(big.NewInt(100), nil) + + mockMainStorage.EXPECT().LookbackBlockHeaders(big.NewInt(1), 10, big.NewInt(109)).Return([]common.BlockHeader{ + {Number: big.NewInt(109), Hash: "hash109", ParentHash: "hash108"}, + {Number: big.NewInt(108), Hash: "hash108", ParentHash: "hash107"}, // <-- fork ends here + {Number: big.NewInt(107), Hash: "hash107a", ParentHash: "hash106a"}, + {Number: big.NewInt(106), Hash: "hash106a", ParentHash: "hash105a"}, + {Number: big.NewInt(105), Hash: "hash105a", ParentHash: "hash104a"}, + {Number: big.NewInt(104), Hash: "hash104a", ParentHash: "hash103a"}, + {Number: big.NewInt(103), Hash: "hash103a", ParentHash: "hash102a"}, // <-- fork starts here + {Number: big.NewInt(102), Hash: "hash102", ParentHash: "hash101"}, + {Number: big.NewInt(101), Hash: "hash101", ParentHash: "hash100"}, + {Number: big.NewInt(100), Hash: "hash100", ParentHash: "hash99"}, + }, nil) + + mockRPC.EXPECT().GetBlocks([]*big.Int{big.NewInt(108), big.NewInt(107), big.NewInt(106), big.NewInt(105), big.NewInt(104), big.NewInt(103), big.NewInt(102), big.NewInt(101), big.NewInt(100)}).Return([]rpc.GetBlocksResult{ + {BlockNumber: big.NewInt(108), Data: common.Block{Hash: "hash108", ParentHash: "hash107"}}, + {BlockNumber: big.NewInt(107), Data: common.Block{Hash: "hash107", ParentHash: "hash106"}}, + {BlockNumber: big.NewInt(106), Data: common.Block{Hash: "hash106", ParentHash: "hash105"}}, + {BlockNumber: big.NewInt(105), Data: common.Block{Hash: "hash105", ParentHash: "hash104"}}, + {BlockNumber: big.NewInt(104), Data: common.Block{Hash: "hash104", ParentHash: "hash103"}}, + {BlockNumber: big.NewInt(103), Data: common.Block{Hash: "hash103", ParentHash: "hash102"}}, + {BlockNumber: big.NewInt(102), Data: common.Block{Hash: "hash102", ParentHash: "hash101"}}, + {BlockNumber: big.NewInt(101), Data: common.Block{Hash: "hash101", ParentHash: "hash100"}}, + {BlockNumber: big.NewInt(100), Data: common.Block{Hash: "hash100", ParentHash: "hash99"}}, + }) + + mockRPC.EXPECT().GetFullBlocks([]*big.Int{big.NewInt(103), big.NewInt(104), big.NewInt(105), big.NewInt(106), big.NewInt(107), big.NewInt(108)}).Return([]rpc.GetFullBlockResult{ + {BlockNumber: big.NewInt(103), Data: common.BlockData{}}, + {BlockNumber: big.NewInt(104), Data: common.BlockData{}}, + {BlockNumber: big.NewInt(105), Data: common.BlockData{}}, + {BlockNumber: big.NewInt(106), Data: common.BlockData{}}, + {BlockNumber: big.NewInt(107), Data: common.BlockData{}}, + {BlockNumber: big.NewInt(108), Data: common.BlockData{}}, + }) + + mockMainStorage.EXPECT().DeleteBlockData(big.NewInt(1), mock.MatchedBy(func(blocks []*big.Int) bool { + return len(blocks) == 6 + })).Return(nil) + mockMainStorage.EXPECT().InsertBlockData(mock.MatchedBy(func(data *[]common.BlockData) bool { + return data != nil && len(*data) == 6 + })).Return(nil) + + handler := NewReorgHandler(mockRPC, mockStorage) + mostRecentBlockChecked, err := handler.RunFromBlock(big.NewInt(109)) + + assert.NoError(t, err) + assert.Equal(t, big.NewInt(109), mostRecentBlockChecked) +} diff --git a/test/mocks/MockIMainStorage.go b/test/mocks/MockIMainStorage.go new file mode 100644 index 0000000..8800917 --- /dev/null +++ b/test/mocks/MockIMainStorage.go @@ -0,0 +1,480 @@ +// Code generated by mockery v2.46.2. DO NOT EDIT. + +//go:build !production + +package mocks + +import ( + big "math/big" + + mock "github.com/stretchr/testify/mock" + common "github.com/thirdweb-dev/indexer/internal/common" + + storage "github.com/thirdweb-dev/indexer/internal/storage" +) + +// MockIMainStorage is an autogenerated mock type for the IMainStorage type +type MockIMainStorage struct { + mock.Mock +} + +type MockIMainStorage_Expecter struct { + mock *mock.Mock +} + +func (_m *MockIMainStorage) EXPECT() *MockIMainStorage_Expecter { + return &MockIMainStorage_Expecter{mock: &_m.Mock} +} + +// DeleteBlockData provides a mock function with given fields: chainId, blockNumbers +func (_m *MockIMainStorage) DeleteBlockData(chainId *big.Int, blockNumbers []*big.Int) error { + ret := _m.Called(chainId, blockNumbers) + + if len(ret) == 0 { + panic("no return value specified for DeleteBlockData") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*big.Int, []*big.Int) error); ok { + r0 = rf(chainId, blockNumbers) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockIMainStorage_DeleteBlockData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteBlockData' +type MockIMainStorage_DeleteBlockData_Call struct { + *mock.Call +} + +// DeleteBlockData is a helper method to define mock.On call +// - chainId *big.Int +// - blockNumbers []*big.Int +func (_e *MockIMainStorage_Expecter) DeleteBlockData(chainId interface{}, blockNumbers interface{}) *MockIMainStorage_DeleteBlockData_Call { + return &MockIMainStorage_DeleteBlockData_Call{Call: _e.mock.On("DeleteBlockData", chainId, blockNumbers)} +} + +func (_c *MockIMainStorage_DeleteBlockData_Call) Run(run func(chainId *big.Int, blockNumbers []*big.Int)) *MockIMainStorage_DeleteBlockData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].([]*big.Int)) + }) + return _c +} + +func (_c *MockIMainStorage_DeleteBlockData_Call) Return(_a0 error) *MockIMainStorage_DeleteBlockData_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIMainStorage_DeleteBlockData_Call) RunAndReturn(run func(*big.Int, []*big.Int) error) *MockIMainStorage_DeleteBlockData_Call { + _c.Call.Return(run) + return _c +} + +// GetBlocks provides a mock function with given fields: qf +func (_m *MockIMainStorage) GetBlocks(qf storage.QueryFilter) ([]common.Block, error) { + ret := _m.Called(qf) + + if len(ret) == 0 { + panic("no return value specified for GetBlocks") + } + + var r0 []common.Block + var r1 error + if rf, ok := ret.Get(0).(func(storage.QueryFilter) ([]common.Block, error)); ok { + return rf(qf) + } + if rf, ok := ret.Get(0).(func(storage.QueryFilter) []common.Block); ok { + r0 = rf(qf) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Block) + } + } + + if rf, ok := ret.Get(1).(func(storage.QueryFilter) error); ok { + r1 = rf(qf) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIMainStorage_GetBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlocks' +type MockIMainStorage_GetBlocks_Call struct { + *mock.Call +} + +// GetBlocks is a helper method to define mock.On call +// - qf storage.QueryFilter +func (_e *MockIMainStorage_Expecter) GetBlocks(qf interface{}) *MockIMainStorage_GetBlocks_Call { + return &MockIMainStorage_GetBlocks_Call{Call: _e.mock.On("GetBlocks", qf)} +} + +func (_c *MockIMainStorage_GetBlocks_Call) Run(run func(qf storage.QueryFilter)) *MockIMainStorage_GetBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(storage.QueryFilter)) + }) + return _c +} + +func (_c *MockIMainStorage_GetBlocks_Call) Return(blocks []common.Block, err error) *MockIMainStorage_GetBlocks_Call { + _c.Call.Return(blocks, err) + return _c +} + +func (_c *MockIMainStorage_GetBlocks_Call) RunAndReturn(run func(storage.QueryFilter) ([]common.Block, error)) *MockIMainStorage_GetBlocks_Call { + _c.Call.Return(run) + return _c +} + +// GetLogs provides a mock function with given fields: qf +func (_m *MockIMainStorage) GetLogs(qf storage.QueryFilter) (storage.QueryResult[common.Log], error) { + ret := _m.Called(qf) + + if len(ret) == 0 { + panic("no return value specified for GetLogs") + } + + var r0 storage.QueryResult[common.Log] + var r1 error + if rf, ok := ret.Get(0).(func(storage.QueryFilter) (storage.QueryResult[common.Log], error)); ok { + return rf(qf) + } + if rf, ok := ret.Get(0).(func(storage.QueryFilter) storage.QueryResult[common.Log]); ok { + r0 = rf(qf) + } else { + r0 = ret.Get(0).(storage.QueryResult[common.Log]) + } + + if rf, ok := ret.Get(1).(func(storage.QueryFilter) error); ok { + r1 = rf(qf) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIMainStorage_GetLogs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLogs' +type MockIMainStorage_GetLogs_Call struct { + *mock.Call +} + +// GetLogs is a helper method to define mock.On call +// - qf storage.QueryFilter +func (_e *MockIMainStorage_Expecter) GetLogs(qf interface{}) *MockIMainStorage_GetLogs_Call { + return &MockIMainStorage_GetLogs_Call{Call: _e.mock.On("GetLogs", qf)} +} + +func (_c *MockIMainStorage_GetLogs_Call) Run(run func(qf storage.QueryFilter)) *MockIMainStorage_GetLogs_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(storage.QueryFilter)) + }) + return _c +} + +func (_c *MockIMainStorage_GetLogs_Call) Return(logs storage.QueryResult[common.Log], err error) *MockIMainStorage_GetLogs_Call { + _c.Call.Return(logs, err) + return _c +} + +func (_c *MockIMainStorage_GetLogs_Call) RunAndReturn(run func(storage.QueryFilter) (storage.QueryResult[common.Log], error)) *MockIMainStorage_GetLogs_Call { + _c.Call.Return(run) + return _c +} + +// GetMaxBlockNumber provides a mock function with given fields: chainId +func (_m *MockIMainStorage) GetMaxBlockNumber(chainId *big.Int) (*big.Int, error) { + ret := _m.Called(chainId) + + if len(ret) == 0 { + panic("no return value specified for GetMaxBlockNumber") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int) (*big.Int, error)); ok { + return rf(chainId) + } + if rf, ok := ret.Get(0).(func(*big.Int) *big.Int); ok { + r0 = rf(chainId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int) error); ok { + r1 = rf(chainId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIMainStorage_GetMaxBlockNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetMaxBlockNumber' +type MockIMainStorage_GetMaxBlockNumber_Call struct { + *mock.Call +} + +// GetMaxBlockNumber is a helper method to define mock.On call +// - chainId *big.Int +func (_e *MockIMainStorage_Expecter) GetMaxBlockNumber(chainId interface{}) *MockIMainStorage_GetMaxBlockNumber_Call { + return &MockIMainStorage_GetMaxBlockNumber_Call{Call: _e.mock.On("GetMaxBlockNumber", chainId)} +} + +func (_c *MockIMainStorage_GetMaxBlockNumber_Call) Run(run func(chainId *big.Int)) *MockIMainStorage_GetMaxBlockNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int)) + }) + return _c +} + +func (_c *MockIMainStorage_GetMaxBlockNumber_Call) Return(maxBlockNumber *big.Int, err error) *MockIMainStorage_GetMaxBlockNumber_Call { + _c.Call.Return(maxBlockNumber, err) + return _c +} + +func (_c *MockIMainStorage_GetMaxBlockNumber_Call) RunAndReturn(run func(*big.Int) (*big.Int, error)) *MockIMainStorage_GetMaxBlockNumber_Call { + _c.Call.Return(run) + return _c +} + +// GetTraces provides a mock function with given fields: qf +func (_m *MockIMainStorage) GetTraces(qf storage.QueryFilter) ([]common.Trace, error) { + ret := _m.Called(qf) + + if len(ret) == 0 { + panic("no return value specified for GetTraces") + } + + var r0 []common.Trace + var r1 error + if rf, ok := ret.Get(0).(func(storage.QueryFilter) ([]common.Trace, error)); ok { + return rf(qf) + } + if rf, ok := ret.Get(0).(func(storage.QueryFilter) []common.Trace); ok { + r0 = rf(qf) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Trace) + } + } + + if rf, ok := ret.Get(1).(func(storage.QueryFilter) error); ok { + r1 = rf(qf) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIMainStorage_GetTraces_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTraces' +type MockIMainStorage_GetTraces_Call struct { + *mock.Call +} + +// GetTraces is a helper method to define mock.On call +// - qf storage.QueryFilter +func (_e *MockIMainStorage_Expecter) GetTraces(qf interface{}) *MockIMainStorage_GetTraces_Call { + return &MockIMainStorage_GetTraces_Call{Call: _e.mock.On("GetTraces", qf)} +} + +func (_c *MockIMainStorage_GetTraces_Call) Run(run func(qf storage.QueryFilter)) *MockIMainStorage_GetTraces_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(storage.QueryFilter)) + }) + return _c +} + +func (_c *MockIMainStorage_GetTraces_Call) Return(traces []common.Trace, err error) *MockIMainStorage_GetTraces_Call { + _c.Call.Return(traces, err) + return _c +} + +func (_c *MockIMainStorage_GetTraces_Call) RunAndReturn(run func(storage.QueryFilter) ([]common.Trace, error)) *MockIMainStorage_GetTraces_Call { + _c.Call.Return(run) + return _c +} + +// GetTransactions provides a mock function with given fields: qf +func (_m *MockIMainStorage) GetTransactions(qf storage.QueryFilter) (storage.QueryResult[common.Transaction], error) { + ret := _m.Called(qf) + + if len(ret) == 0 { + panic("no return value specified for GetTransactions") + } + + var r0 storage.QueryResult[common.Transaction] + var r1 error + if rf, ok := ret.Get(0).(func(storage.QueryFilter) (storage.QueryResult[common.Transaction], error)); ok { + return rf(qf) + } + if rf, ok := ret.Get(0).(func(storage.QueryFilter) storage.QueryResult[common.Transaction]); ok { + r0 = rf(qf) + } else { + r0 = ret.Get(0).(storage.QueryResult[common.Transaction]) + } + + if rf, ok := ret.Get(1).(func(storage.QueryFilter) error); ok { + r1 = rf(qf) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIMainStorage_GetTransactions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTransactions' +type MockIMainStorage_GetTransactions_Call struct { + *mock.Call +} + +// GetTransactions is a helper method to define mock.On call +// - qf storage.QueryFilter +func (_e *MockIMainStorage_Expecter) GetTransactions(qf interface{}) *MockIMainStorage_GetTransactions_Call { + return &MockIMainStorage_GetTransactions_Call{Call: _e.mock.On("GetTransactions", qf)} +} + +func (_c *MockIMainStorage_GetTransactions_Call) Run(run func(qf storage.QueryFilter)) *MockIMainStorage_GetTransactions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(storage.QueryFilter)) + }) + return _c +} + +func (_c *MockIMainStorage_GetTransactions_Call) Return(transactions storage.QueryResult[common.Transaction], err error) *MockIMainStorage_GetTransactions_Call { + _c.Call.Return(transactions, err) + return _c +} + +func (_c *MockIMainStorage_GetTransactions_Call) RunAndReturn(run func(storage.QueryFilter) (storage.QueryResult[common.Transaction], error)) *MockIMainStorage_GetTransactions_Call { + _c.Call.Return(run) + return _c +} + +// InsertBlockData provides a mock function with given fields: data +func (_m *MockIMainStorage) InsertBlockData(data *[]common.BlockData) error { + ret := _m.Called(data) + + if len(ret) == 0 { + panic("no return value specified for InsertBlockData") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*[]common.BlockData) error); ok { + r0 = rf(data) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockIMainStorage_InsertBlockData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InsertBlockData' +type MockIMainStorage_InsertBlockData_Call struct { + *mock.Call +} + +// InsertBlockData is a helper method to define mock.On call +// - data *[]common.BlockData +func (_e *MockIMainStorage_Expecter) InsertBlockData(data interface{}) *MockIMainStorage_InsertBlockData_Call { + return &MockIMainStorage_InsertBlockData_Call{Call: _e.mock.On("InsertBlockData", data)} +} + +func (_c *MockIMainStorage_InsertBlockData_Call) Run(run func(data *[]common.BlockData)) *MockIMainStorage_InsertBlockData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*[]common.BlockData)) + }) + return _c +} + +func (_c *MockIMainStorage_InsertBlockData_Call) Return(_a0 error) *MockIMainStorage_InsertBlockData_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIMainStorage_InsertBlockData_Call) RunAndReturn(run func(*[]common.BlockData) error) *MockIMainStorage_InsertBlockData_Call { + _c.Call.Return(run) + return _c +} + +// LookbackBlockHeaders provides a mock function with given fields: chainId, limit, lookbackStart +func (_m *MockIMainStorage) LookbackBlockHeaders(chainId *big.Int, limit int, lookbackStart *big.Int) ([]common.BlockHeader, error) { + ret := _m.Called(chainId, limit, lookbackStart) + + if len(ret) == 0 { + panic("no return value specified for LookbackBlockHeaders") + } + + var r0 []common.BlockHeader + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, int, *big.Int) ([]common.BlockHeader, error)); ok { + return rf(chainId, limit, lookbackStart) + } + if rf, ok := ret.Get(0).(func(*big.Int, int, *big.Int) []common.BlockHeader); ok { + r0 = rf(chainId, limit, lookbackStart) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.BlockHeader) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int, int, *big.Int) error); ok { + r1 = rf(chainId, limit, lookbackStart) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIMainStorage_LookbackBlockHeaders_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LookbackBlockHeaders' +type MockIMainStorage_LookbackBlockHeaders_Call struct { + *mock.Call +} + +// LookbackBlockHeaders is a helper method to define mock.On call +// - chainId *big.Int +// - limit int +// - lookbackStart *big.Int +func (_e *MockIMainStorage_Expecter) LookbackBlockHeaders(chainId interface{}, limit interface{}, lookbackStart interface{}) *MockIMainStorage_LookbackBlockHeaders_Call { + return &MockIMainStorage_LookbackBlockHeaders_Call{Call: _e.mock.On("LookbackBlockHeaders", chainId, limit, lookbackStart)} +} + +func (_c *MockIMainStorage_LookbackBlockHeaders_Call) Run(run func(chainId *big.Int, limit int, lookbackStart *big.Int)) *MockIMainStorage_LookbackBlockHeaders_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(int), args[2].(*big.Int)) + }) + return _c +} + +func (_c *MockIMainStorage_LookbackBlockHeaders_Call) Return(blockHeaders []common.BlockHeader, err error) *MockIMainStorage_LookbackBlockHeaders_Call { + _c.Call.Return(blockHeaders, err) + return _c +} + +func (_c *MockIMainStorage_LookbackBlockHeaders_Call) RunAndReturn(run func(*big.Int, int, *big.Int) ([]common.BlockHeader, error)) *MockIMainStorage_LookbackBlockHeaders_Call { + _c.Call.Return(run) + return _c +} + +// NewMockIMainStorage creates a new instance of MockIMainStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockIMainStorage(t interface { + mock.TestingT + Cleanup(func()) +}) *MockIMainStorage { + mock := &MockIMainStorage{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/test/mocks/MockIOrchestratorStorage.go b/test/mocks/MockIOrchestratorStorage.go new file mode 100644 index 0000000..284134a --- /dev/null +++ b/test/mocks/MockIOrchestratorStorage.go @@ -0,0 +1,296 @@ +// Code generated by mockery v2.46.2. DO NOT EDIT. + +//go:build !production + +package mocks + +import ( + big "math/big" + + mock "github.com/stretchr/testify/mock" + common "github.com/thirdweb-dev/indexer/internal/common" + + storage "github.com/thirdweb-dev/indexer/internal/storage" +) + +// MockIOrchestratorStorage is an autogenerated mock type for the IOrchestratorStorage type +type MockIOrchestratorStorage struct { + mock.Mock +} + +type MockIOrchestratorStorage_Expecter struct { + mock *mock.Mock +} + +func (_m *MockIOrchestratorStorage) EXPECT() *MockIOrchestratorStorage_Expecter { + return &MockIOrchestratorStorage_Expecter{mock: &_m.Mock} +} + +// DeleteBlockFailures provides a mock function with given fields: failures +func (_m *MockIOrchestratorStorage) DeleteBlockFailures(failures []common.BlockFailure) error { + ret := _m.Called(failures) + + if len(ret) == 0 { + panic("no return value specified for DeleteBlockFailures") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]common.BlockFailure) error); ok { + r0 = rf(failures) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockIOrchestratorStorage_DeleteBlockFailures_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteBlockFailures' +type MockIOrchestratorStorage_DeleteBlockFailures_Call struct { + *mock.Call +} + +// DeleteBlockFailures is a helper method to define mock.On call +// - failures []common.BlockFailure +func (_e *MockIOrchestratorStorage_Expecter) DeleteBlockFailures(failures interface{}) *MockIOrchestratorStorage_DeleteBlockFailures_Call { + return &MockIOrchestratorStorage_DeleteBlockFailures_Call{Call: _e.mock.On("DeleteBlockFailures", failures)} +} + +func (_c *MockIOrchestratorStorage_DeleteBlockFailures_Call) Run(run func(failures []common.BlockFailure)) *MockIOrchestratorStorage_DeleteBlockFailures_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]common.BlockFailure)) + }) + return _c +} + +func (_c *MockIOrchestratorStorage_DeleteBlockFailures_Call) Return(_a0 error) *MockIOrchestratorStorage_DeleteBlockFailures_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIOrchestratorStorage_DeleteBlockFailures_Call) RunAndReturn(run func([]common.BlockFailure) error) *MockIOrchestratorStorage_DeleteBlockFailures_Call { + _c.Call.Return(run) + return _c +} + +// GetBlockFailures provides a mock function with given fields: qf +func (_m *MockIOrchestratorStorage) GetBlockFailures(qf storage.QueryFilter) ([]common.BlockFailure, error) { + ret := _m.Called(qf) + + if len(ret) == 0 { + panic("no return value specified for GetBlockFailures") + } + + var r0 []common.BlockFailure + var r1 error + if rf, ok := ret.Get(0).(func(storage.QueryFilter) ([]common.BlockFailure, error)); ok { + return rf(qf) + } + if rf, ok := ret.Get(0).(func(storage.QueryFilter) []common.BlockFailure); ok { + r0 = rf(qf) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.BlockFailure) + } + } + + if rf, ok := ret.Get(1).(func(storage.QueryFilter) error); ok { + r1 = rf(qf) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIOrchestratorStorage_GetBlockFailures_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlockFailures' +type MockIOrchestratorStorage_GetBlockFailures_Call struct { + *mock.Call +} + +// GetBlockFailures is a helper method to define mock.On call +// - qf storage.QueryFilter +func (_e *MockIOrchestratorStorage_Expecter) GetBlockFailures(qf interface{}) *MockIOrchestratorStorage_GetBlockFailures_Call { + return &MockIOrchestratorStorage_GetBlockFailures_Call{Call: _e.mock.On("GetBlockFailures", qf)} +} + +func (_c *MockIOrchestratorStorage_GetBlockFailures_Call) Run(run func(qf storage.QueryFilter)) *MockIOrchestratorStorage_GetBlockFailures_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(storage.QueryFilter)) + }) + return _c +} + +func (_c *MockIOrchestratorStorage_GetBlockFailures_Call) Return(_a0 []common.BlockFailure, _a1 error) *MockIOrchestratorStorage_GetBlockFailures_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockIOrchestratorStorage_GetBlockFailures_Call) RunAndReturn(run func(storage.QueryFilter) ([]common.BlockFailure, error)) *MockIOrchestratorStorage_GetBlockFailures_Call { + _c.Call.Return(run) + return _c +} + +// GetLastReorgCheckedBlockNumber provides a mock function with given fields: chainId +func (_m *MockIOrchestratorStorage) GetLastReorgCheckedBlockNumber(chainId *big.Int) (*big.Int, error) { + ret := _m.Called(chainId) + + if len(ret) == 0 { + panic("no return value specified for GetLastReorgCheckedBlockNumber") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int) (*big.Int, error)); ok { + return rf(chainId) + } + if rf, ok := ret.Get(0).(func(*big.Int) *big.Int); ok { + r0 = rf(chainId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int) error); ok { + r1 = rf(chainId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastReorgCheckedBlockNumber' +type MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call struct { + *mock.Call +} + +// GetLastReorgCheckedBlockNumber is a helper method to define mock.On call +// - chainId *big.Int +func (_e *MockIOrchestratorStorage_Expecter) GetLastReorgCheckedBlockNumber(chainId interface{}) *MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call { + return &MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call{Call: _e.mock.On("GetLastReorgCheckedBlockNumber", chainId)} +} + +func (_c *MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call) Run(run func(chainId *big.Int)) *MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int)) + }) + return _c +} + +func (_c *MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call) Return(_a0 *big.Int, _a1 error) *MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call) RunAndReturn(run func(*big.Int) (*big.Int, error)) *MockIOrchestratorStorage_GetLastReorgCheckedBlockNumber_Call { + _c.Call.Return(run) + return _c +} + +// SetLastReorgCheckedBlockNumber provides a mock function with given fields: chainId, blockNumber +func (_m *MockIOrchestratorStorage) SetLastReorgCheckedBlockNumber(chainId *big.Int, blockNumber *big.Int) error { + ret := _m.Called(chainId, blockNumber) + + if len(ret) == 0 { + panic("no return value specified for SetLastReorgCheckedBlockNumber") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) error); ok { + r0 = rf(chainId, blockNumber) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetLastReorgCheckedBlockNumber' +type MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call struct { + *mock.Call +} + +// SetLastReorgCheckedBlockNumber is a helper method to define mock.On call +// - chainId *big.Int +// - blockNumber *big.Int +func (_e *MockIOrchestratorStorage_Expecter) SetLastReorgCheckedBlockNumber(chainId interface{}, blockNumber interface{}) *MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call { + return &MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call{Call: _e.mock.On("SetLastReorgCheckedBlockNumber", chainId, blockNumber)} +} + +func (_c *MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call) Run(run func(chainId *big.Int, blockNumber *big.Int)) *MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int)) + }) + return _c +} + +func (_c *MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call) Return(_a0 error) *MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call) RunAndReturn(run func(*big.Int, *big.Int) error) *MockIOrchestratorStorage_SetLastReorgCheckedBlockNumber_Call { + _c.Call.Return(run) + return _c +} + +// StoreBlockFailures provides a mock function with given fields: failures +func (_m *MockIOrchestratorStorage) StoreBlockFailures(failures []common.BlockFailure) error { + ret := _m.Called(failures) + + if len(ret) == 0 { + panic("no return value specified for StoreBlockFailures") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]common.BlockFailure) error); ok { + r0 = rf(failures) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockIOrchestratorStorage_StoreBlockFailures_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StoreBlockFailures' +type MockIOrchestratorStorage_StoreBlockFailures_Call struct { + *mock.Call +} + +// StoreBlockFailures is a helper method to define mock.On call +// - failures []common.BlockFailure +func (_e *MockIOrchestratorStorage_Expecter) StoreBlockFailures(failures interface{}) *MockIOrchestratorStorage_StoreBlockFailures_Call { + return &MockIOrchestratorStorage_StoreBlockFailures_Call{Call: _e.mock.On("StoreBlockFailures", failures)} +} + +func (_c *MockIOrchestratorStorage_StoreBlockFailures_Call) Run(run func(failures []common.BlockFailure)) *MockIOrchestratorStorage_StoreBlockFailures_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]common.BlockFailure)) + }) + return _c +} + +func (_c *MockIOrchestratorStorage_StoreBlockFailures_Call) Return(_a0 error) *MockIOrchestratorStorage_StoreBlockFailures_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIOrchestratorStorage_StoreBlockFailures_Call) RunAndReturn(run func([]common.BlockFailure) error) *MockIOrchestratorStorage_StoreBlockFailures_Call { + _c.Call.Return(run) + return _c +} + +// NewMockIOrchestratorStorage creates a new instance of MockIOrchestratorStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockIOrchestratorStorage(t interface { + mock.TestingT + Cleanup(func()) +}) *MockIOrchestratorStorage { + mock := &MockIOrchestratorStorage{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/test/mocks/MockIRPCClient.go b/test/mocks/MockIRPCClient.go new file mode 100644 index 0000000..5a078ed --- /dev/null +++ b/test/mocks/MockIRPCClient.go @@ -0,0 +1,419 @@ +// Code generated by mockery v2.46.2. DO NOT EDIT. + +//go:build !production + +package mocks + +import ( + big "math/big" + + mock "github.com/stretchr/testify/mock" + rpc "github.com/thirdweb-dev/indexer/internal/rpc" +) + +// MockIRPCClient is an autogenerated mock type for the IRPCClient type +type MockIRPCClient struct { + mock.Mock +} + +type MockIRPCClient_Expecter struct { + mock *mock.Mock +} + +func (_m *MockIRPCClient) EXPECT() *MockIRPCClient_Expecter { + return &MockIRPCClient_Expecter{mock: &_m.Mock} +} + +// GetBlocks provides a mock function with given fields: blockNumbers +func (_m *MockIRPCClient) GetBlocks(blockNumbers []*big.Int) []rpc.GetBlocksResult { + ret := _m.Called(blockNumbers) + + if len(ret) == 0 { + panic("no return value specified for GetBlocks") + } + + var r0 []rpc.GetBlocksResult + if rf, ok := ret.Get(0).(func([]*big.Int) []rpc.GetBlocksResult); ok { + r0 = rf(blockNumbers) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]rpc.GetBlocksResult) + } + } + + return r0 +} + +// MockIRPCClient_GetBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlocks' +type MockIRPCClient_GetBlocks_Call struct { + *mock.Call +} + +// GetBlocks is a helper method to define mock.On call +// - blockNumbers []*big.Int +func (_e *MockIRPCClient_Expecter) GetBlocks(blockNumbers interface{}) *MockIRPCClient_GetBlocks_Call { + return &MockIRPCClient_GetBlocks_Call{Call: _e.mock.On("GetBlocks", blockNumbers)} +} + +func (_c *MockIRPCClient_GetBlocks_Call) Run(run func(blockNumbers []*big.Int)) *MockIRPCClient_GetBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]*big.Int)) + }) + return _c +} + +func (_c *MockIRPCClient_GetBlocks_Call) Return(_a0 []rpc.GetBlocksResult) *MockIRPCClient_GetBlocks_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRPCClient_GetBlocks_Call) RunAndReturn(run func([]*big.Int) []rpc.GetBlocksResult) *MockIRPCClient_GetBlocks_Call { + _c.Call.Return(run) + return _c +} + +// GetBlocksPerRequest provides a mock function with given fields: +func (_m *MockIRPCClient) GetBlocksPerRequest() rpc.BlocksPerRequestConfig { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetBlocksPerRequest") + } + + var r0 rpc.BlocksPerRequestConfig + if rf, ok := ret.Get(0).(func() rpc.BlocksPerRequestConfig); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(rpc.BlocksPerRequestConfig) + } + + return r0 +} + +// MockIRPCClient_GetBlocksPerRequest_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlocksPerRequest' +type MockIRPCClient_GetBlocksPerRequest_Call struct { + *mock.Call +} + +// GetBlocksPerRequest is a helper method to define mock.On call +func (_e *MockIRPCClient_Expecter) GetBlocksPerRequest() *MockIRPCClient_GetBlocksPerRequest_Call { + return &MockIRPCClient_GetBlocksPerRequest_Call{Call: _e.mock.On("GetBlocksPerRequest")} +} + +func (_c *MockIRPCClient_GetBlocksPerRequest_Call) Run(run func()) *MockIRPCClient_GetBlocksPerRequest_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockIRPCClient_GetBlocksPerRequest_Call) Return(_a0 rpc.BlocksPerRequestConfig) *MockIRPCClient_GetBlocksPerRequest_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRPCClient_GetBlocksPerRequest_Call) RunAndReturn(run func() rpc.BlocksPerRequestConfig) *MockIRPCClient_GetBlocksPerRequest_Call { + _c.Call.Return(run) + return _c +} + +// GetChainID provides a mock function with given fields: +func (_m *MockIRPCClient) GetChainID() *big.Int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetChainID") + } + + var r0 *big.Int + if rf, ok := ret.Get(0).(func() *big.Int); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + return r0 +} + +// MockIRPCClient_GetChainID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetChainID' +type MockIRPCClient_GetChainID_Call struct { + *mock.Call +} + +// GetChainID is a helper method to define mock.On call +func (_e *MockIRPCClient_Expecter) GetChainID() *MockIRPCClient_GetChainID_Call { + return &MockIRPCClient_GetChainID_Call{Call: _e.mock.On("GetChainID")} +} + +func (_c *MockIRPCClient_GetChainID_Call) Run(run func()) *MockIRPCClient_GetChainID_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockIRPCClient_GetChainID_Call) Return(_a0 *big.Int) *MockIRPCClient_GetChainID_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRPCClient_GetChainID_Call) RunAndReturn(run func() *big.Int) *MockIRPCClient_GetChainID_Call { + _c.Call.Return(run) + return _c +} + +// GetFullBlocks provides a mock function with given fields: blockNumbers +func (_m *MockIRPCClient) GetFullBlocks(blockNumbers []*big.Int) []rpc.GetFullBlockResult { + ret := _m.Called(blockNumbers) + + if len(ret) == 0 { + panic("no return value specified for GetFullBlocks") + } + + var r0 []rpc.GetFullBlockResult + if rf, ok := ret.Get(0).(func([]*big.Int) []rpc.GetFullBlockResult); ok { + r0 = rf(blockNumbers) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]rpc.GetFullBlockResult) + } + } + + return r0 +} + +// MockIRPCClient_GetFullBlocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFullBlocks' +type MockIRPCClient_GetFullBlocks_Call struct { + *mock.Call +} + +// GetFullBlocks is a helper method to define mock.On call +// - blockNumbers []*big.Int +func (_e *MockIRPCClient_Expecter) GetFullBlocks(blockNumbers interface{}) *MockIRPCClient_GetFullBlocks_Call { + return &MockIRPCClient_GetFullBlocks_Call{Call: _e.mock.On("GetFullBlocks", blockNumbers)} +} + +func (_c *MockIRPCClient_GetFullBlocks_Call) Run(run func(blockNumbers []*big.Int)) *MockIRPCClient_GetFullBlocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]*big.Int)) + }) + return _c +} + +func (_c *MockIRPCClient_GetFullBlocks_Call) Return(_a0 []rpc.GetFullBlockResult) *MockIRPCClient_GetFullBlocks_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRPCClient_GetFullBlocks_Call) RunAndReturn(run func([]*big.Int) []rpc.GetFullBlockResult) *MockIRPCClient_GetFullBlocks_Call { + _c.Call.Return(run) + return _c +} + +// GetLatestBlockNumber provides a mock function with given fields: +func (_m *MockIRPCClient) GetLatestBlockNumber() (*big.Int, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetLatestBlockNumber") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func() (*big.Int, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() *big.Int); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIRPCClient_GetLatestBlockNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLatestBlockNumber' +type MockIRPCClient_GetLatestBlockNumber_Call struct { + *mock.Call +} + +// GetLatestBlockNumber is a helper method to define mock.On call +func (_e *MockIRPCClient_Expecter) GetLatestBlockNumber() *MockIRPCClient_GetLatestBlockNumber_Call { + return &MockIRPCClient_GetLatestBlockNumber_Call{Call: _e.mock.On("GetLatestBlockNumber")} +} + +func (_c *MockIRPCClient_GetLatestBlockNumber_Call) Run(run func()) *MockIRPCClient_GetLatestBlockNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockIRPCClient_GetLatestBlockNumber_Call) Return(_a0 *big.Int, _a1 error) *MockIRPCClient_GetLatestBlockNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockIRPCClient_GetLatestBlockNumber_Call) RunAndReturn(run func() (*big.Int, error)) *MockIRPCClient_GetLatestBlockNumber_Call { + _c.Call.Return(run) + return _c +} + +// GetURL provides a mock function with given fields: +func (_m *MockIRPCClient) GetURL() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetURL") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockIRPCClient_GetURL_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetURL' +type MockIRPCClient_GetURL_Call struct { + *mock.Call +} + +// GetURL is a helper method to define mock.On call +func (_e *MockIRPCClient_Expecter) GetURL() *MockIRPCClient_GetURL_Call { + return &MockIRPCClient_GetURL_Call{Call: _e.mock.On("GetURL")} +} + +func (_c *MockIRPCClient_GetURL_Call) Run(run func()) *MockIRPCClient_GetURL_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockIRPCClient_GetURL_Call) Return(_a0 string) *MockIRPCClient_GetURL_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRPCClient_GetURL_Call) RunAndReturn(run func() string) *MockIRPCClient_GetURL_Call { + _c.Call.Return(run) + return _c +} + +// IsWebsocket provides a mock function with given fields: +func (_m *MockIRPCClient) IsWebsocket() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsWebsocket") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// MockIRPCClient_IsWebsocket_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsWebsocket' +type MockIRPCClient_IsWebsocket_Call struct { + *mock.Call +} + +// IsWebsocket is a helper method to define mock.On call +func (_e *MockIRPCClient_Expecter) IsWebsocket() *MockIRPCClient_IsWebsocket_Call { + return &MockIRPCClient_IsWebsocket_Call{Call: _e.mock.On("IsWebsocket")} +} + +func (_c *MockIRPCClient_IsWebsocket_Call) Run(run func()) *MockIRPCClient_IsWebsocket_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockIRPCClient_IsWebsocket_Call) Return(_a0 bool) *MockIRPCClient_IsWebsocket_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRPCClient_IsWebsocket_Call) RunAndReturn(run func() bool) *MockIRPCClient_IsWebsocket_Call { + _c.Call.Return(run) + return _c +} + +// SupportsTraceBlock provides a mock function with given fields: +func (_m *MockIRPCClient) SupportsTraceBlock() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for SupportsTraceBlock") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// MockIRPCClient_SupportsTraceBlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SupportsTraceBlock' +type MockIRPCClient_SupportsTraceBlock_Call struct { + *mock.Call +} + +// SupportsTraceBlock is a helper method to define mock.On call +func (_e *MockIRPCClient_Expecter) SupportsTraceBlock() *MockIRPCClient_SupportsTraceBlock_Call { + return &MockIRPCClient_SupportsTraceBlock_Call{Call: _e.mock.On("SupportsTraceBlock")} +} + +func (_c *MockIRPCClient_SupportsTraceBlock_Call) Run(run func()) *MockIRPCClient_SupportsTraceBlock_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockIRPCClient_SupportsTraceBlock_Call) Return(_a0 bool) *MockIRPCClient_SupportsTraceBlock_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIRPCClient_SupportsTraceBlock_Call) RunAndReturn(run func() bool) *MockIRPCClient_SupportsTraceBlock_Call { + _c.Call.Return(run) + return _c +} + +// NewMockIRPCClient creates a new instance of MockIRPCClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockIRPCClient(t interface { + mock.TestingT + Cleanup(func()) +}) *MockIRPCClient { + mock := &MockIRPCClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/test/mocks/MockIStagingStorage.go b/test/mocks/MockIStagingStorage.go new file mode 100644 index 0000000..56ca2cc --- /dev/null +++ b/test/mocks/MockIStagingStorage.go @@ -0,0 +1,250 @@ +// Code generated by mockery v2.46.2. DO NOT EDIT. + +//go:build !production + +package mocks + +import ( + big "math/big" + + mock "github.com/stretchr/testify/mock" + common "github.com/thirdweb-dev/indexer/internal/common" + + storage "github.com/thirdweb-dev/indexer/internal/storage" +) + +// MockIStagingStorage is an autogenerated mock type for the IStagingStorage type +type MockIStagingStorage struct { + mock.Mock +} + +type MockIStagingStorage_Expecter struct { + mock *mock.Mock +} + +func (_m *MockIStagingStorage) EXPECT() *MockIStagingStorage_Expecter { + return &MockIStagingStorage_Expecter{mock: &_m.Mock} +} + +// DeleteStagingData provides a mock function with given fields: data +func (_m *MockIStagingStorage) DeleteStagingData(data *[]common.BlockData) error { + ret := _m.Called(data) + + if len(ret) == 0 { + panic("no return value specified for DeleteStagingData") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*[]common.BlockData) error); ok { + r0 = rf(data) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockIStagingStorage_DeleteStagingData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteStagingData' +type MockIStagingStorage_DeleteStagingData_Call struct { + *mock.Call +} + +// DeleteStagingData is a helper method to define mock.On call +// - data *[]common.BlockData +func (_e *MockIStagingStorage_Expecter) DeleteStagingData(data interface{}) *MockIStagingStorage_DeleteStagingData_Call { + return &MockIStagingStorage_DeleteStagingData_Call{Call: _e.mock.On("DeleteStagingData", data)} +} + +func (_c *MockIStagingStorage_DeleteStagingData_Call) Run(run func(data *[]common.BlockData)) *MockIStagingStorage_DeleteStagingData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*[]common.BlockData)) + }) + return _c +} + +func (_c *MockIStagingStorage_DeleteStagingData_Call) Return(_a0 error) *MockIStagingStorage_DeleteStagingData_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIStagingStorage_DeleteStagingData_Call) RunAndReturn(run func(*[]common.BlockData) error) *MockIStagingStorage_DeleteStagingData_Call { + _c.Call.Return(run) + return _c +} + +// GetLastStagedBlockNumber provides a mock function with given fields: chainId, rangeEnd +func (_m *MockIStagingStorage) GetLastStagedBlockNumber(chainId *big.Int, rangeEnd *big.Int) (*big.Int, error) { + ret := _m.Called(chainId, rangeEnd) + + if len(ret) == 0 { + panic("no return value specified for GetLastStagedBlockNumber") + } + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) (*big.Int, error)); ok { + return rf(chainId, rangeEnd) + } + if rf, ok := ret.Get(0).(func(*big.Int, *big.Int) *big.Int); ok { + r0 = rf(chainId, rangeEnd) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(*big.Int, *big.Int) error); ok { + r1 = rf(chainId, rangeEnd) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIStagingStorage_GetLastStagedBlockNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastStagedBlockNumber' +type MockIStagingStorage_GetLastStagedBlockNumber_Call struct { + *mock.Call +} + +// GetLastStagedBlockNumber is a helper method to define mock.On call +// - chainId *big.Int +// - rangeEnd *big.Int +func (_e *MockIStagingStorage_Expecter) GetLastStagedBlockNumber(chainId interface{}, rangeEnd interface{}) *MockIStagingStorage_GetLastStagedBlockNumber_Call { + return &MockIStagingStorage_GetLastStagedBlockNumber_Call{Call: _e.mock.On("GetLastStagedBlockNumber", chainId, rangeEnd)} +} + +func (_c *MockIStagingStorage_GetLastStagedBlockNumber_Call) Run(run func(chainId *big.Int, rangeEnd *big.Int)) *MockIStagingStorage_GetLastStagedBlockNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*big.Int), args[1].(*big.Int)) + }) + return _c +} + +func (_c *MockIStagingStorage_GetLastStagedBlockNumber_Call) Return(maxBlockNumber *big.Int, err error) *MockIStagingStorage_GetLastStagedBlockNumber_Call { + _c.Call.Return(maxBlockNumber, err) + return _c +} + +func (_c *MockIStagingStorage_GetLastStagedBlockNumber_Call) RunAndReturn(run func(*big.Int, *big.Int) (*big.Int, error)) *MockIStagingStorage_GetLastStagedBlockNumber_Call { + _c.Call.Return(run) + return _c +} + +// GetStagingData provides a mock function with given fields: qf +func (_m *MockIStagingStorage) GetStagingData(qf storage.QueryFilter) (*[]common.BlockData, error) { + ret := _m.Called(qf) + + if len(ret) == 0 { + panic("no return value specified for GetStagingData") + } + + var r0 *[]common.BlockData + var r1 error + if rf, ok := ret.Get(0).(func(storage.QueryFilter) (*[]common.BlockData, error)); ok { + return rf(qf) + } + if rf, ok := ret.Get(0).(func(storage.QueryFilter) *[]common.BlockData); ok { + r0 = rf(qf) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]common.BlockData) + } + } + + if rf, ok := ret.Get(1).(func(storage.QueryFilter) error); ok { + r1 = rf(qf) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockIStagingStorage_GetStagingData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetStagingData' +type MockIStagingStorage_GetStagingData_Call struct { + *mock.Call +} + +// GetStagingData is a helper method to define mock.On call +// - qf storage.QueryFilter +func (_e *MockIStagingStorage_Expecter) GetStagingData(qf interface{}) *MockIStagingStorage_GetStagingData_Call { + return &MockIStagingStorage_GetStagingData_Call{Call: _e.mock.On("GetStagingData", qf)} +} + +func (_c *MockIStagingStorage_GetStagingData_Call) Run(run func(qf storage.QueryFilter)) *MockIStagingStorage_GetStagingData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(storage.QueryFilter)) + }) + return _c +} + +func (_c *MockIStagingStorage_GetStagingData_Call) Return(data *[]common.BlockData, err error) *MockIStagingStorage_GetStagingData_Call { + _c.Call.Return(data, err) + return _c +} + +func (_c *MockIStagingStorage_GetStagingData_Call) RunAndReturn(run func(storage.QueryFilter) (*[]common.BlockData, error)) *MockIStagingStorage_GetStagingData_Call { + _c.Call.Return(run) + return _c +} + +// InsertStagingData provides a mock function with given fields: data +func (_m *MockIStagingStorage) InsertStagingData(data []common.BlockData) error { + ret := _m.Called(data) + + if len(ret) == 0 { + panic("no return value specified for InsertStagingData") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]common.BlockData) error); ok { + r0 = rf(data) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockIStagingStorage_InsertStagingData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InsertStagingData' +type MockIStagingStorage_InsertStagingData_Call struct { + *mock.Call +} + +// InsertStagingData is a helper method to define mock.On call +// - data []common.BlockData +func (_e *MockIStagingStorage_Expecter) InsertStagingData(data interface{}) *MockIStagingStorage_InsertStagingData_Call { + return &MockIStagingStorage_InsertStagingData_Call{Call: _e.mock.On("InsertStagingData", data)} +} + +func (_c *MockIStagingStorage_InsertStagingData_Call) Run(run func(data []common.BlockData)) *MockIStagingStorage_InsertStagingData_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]common.BlockData)) + }) + return _c +} + +func (_c *MockIStagingStorage_InsertStagingData_Call) Return(_a0 error) *MockIStagingStorage_InsertStagingData_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockIStagingStorage_InsertStagingData_Call) RunAndReturn(run func([]common.BlockData) error) *MockIStagingStorage_InsertStagingData_Call { + _c.Call.Return(run) + return _c +} + +// NewMockIStagingStorage creates a new instance of MockIStagingStorage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockIStagingStorage(t interface { + mock.TestingT + Cleanup(func()) +}) *MockIStagingStorage { + mock := &MockIStagingStorage{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +}