diff --git a/cmd/blockimporter/block_source.go b/cmd/blockimporter/block_source.go index b41e98c3590..790d6036273 100644 --- a/cmd/blockimporter/block_source.go +++ b/cmd/blockimporter/block_source.go @@ -341,3 +341,31 @@ func (decorator *retryBlockSourceDecorator) GetChainID() (int64, error) { return 0, err } + +type secondaryBlocksSourceDecorator struct { + primarySource BlockSource + secondaryBlocksSource BlockSource +} + +func WithSecondaryBlocksSource(primarySource BlockSource, secondaryBlocksSource BlockSource) BlockSource { + return &secondaryBlocksSourceDecorator{ + primarySource: primarySource, + secondaryBlocksSource: secondaryBlocksSource, + } +} + +func (decorator *secondaryBlocksSourceDecorator) PollBlocks(fromBlock uint64) ([]types.Block, error) { + if blocks, err := decorator.primarySource.PollBlocks(fromBlock); err == nil { + return blocks, err + } + + return decorator.secondaryBlocksSource.PollBlocks(fromBlock) +} + +func (decorator *secondaryBlocksSourceDecorator) GetInitialBalances() ([]BalanceEntry, error) { + return decorator.primarySource.GetInitialBalances() +} + +func (decorator *secondaryBlocksSourceDecorator) GetChainID() (int64, error) { + return decorator.primarySource.GetChainID() +} diff --git a/cmd/blockimporter/import_runner.go b/cmd/blockimporter/import_runner.go index 440a3d082a3..fee866aabaa 100644 --- a/cmd/blockimporter/import_runner.go +++ b/cmd/blockimporter/import_runner.go @@ -16,7 +16,7 @@ type Settings struct { PollInterval time.Duration } -func RunImport(settings *Settings, blockSource BlockSource) error { +func RunImport(settings *Settings, blockSource BlockSource, secondaryBlocksSource BlockSource) error { db, err := NewDB(settings.DBPath, settings.Logger) if err != nil { return err @@ -39,7 +39,7 @@ func RunImport(settings *Settings, blockSource BlockSource) error { } blockNum := state.BlockNum() - blockSource = makeBlockSource(settings, blockSource) + blockSource = makeBlockSource(settings, blockSource, secondaryBlocksSource) for { select { case <-settings.Terminated: @@ -66,7 +66,16 @@ func RunImport(settings *Settings, blockSource BlockSource) error { } } -func makeBlockSource(settings *Settings, blockSource BlockSource) BlockSource { +func makeBlockSource(settings *Settings, blockSource BlockSource, secondaryBlockSource BlockSource) BlockSource { + primarySource := makeSingleBlockSource(settings, blockSource) + if secondaryBlockSource != nil { + return WithSecondaryBlocksSource(primarySource, makeSingleBlockSource(settings, secondaryBlockSource)) + } else { + return primarySource + } +} + +func makeSingleBlockSource(settings *Settings, blockSource BlockSource) BlockSource { if settings.RetryCount > 0 { blockSource = WithRetries(blockSource, settings.RetryCount, settings.RetryInterval, settings.Terminated) } diff --git a/cmd/blockimporter/import_runner_test.go b/cmd/blockimporter/import_runner_test.go index ff5bcafcb67..80308fd767e 100644 --- a/cmd/blockimporter/import_runner_test.go +++ b/cmd/blockimporter/import_runner_test.go @@ -86,6 +86,6 @@ func TestImport(t *testing.T) { time.Sleep(time.Second) close(settings.Terminated) }() - err := RunImport(&settings, NewFileBasedMockBlockSource()) + err := RunImport(&settings, NewFileBasedMockBlockSource(), nil) require.Empty(t, err) } diff --git a/cmd/blockimporter/main.go b/cmd/blockimporter/main.go index 2905cfe84f9..0288e572bc8 100644 --- a/cmd/blockimporter/main.go +++ b/cmd/blockimporter/main.go @@ -13,8 +13,9 @@ import ( func main() { // Parse commandline arguments var ( - dbPath = flag.String("db", "./db", "database path") - evmUrl = flag.String("evm", "http://127.0.0.1:8545", "EVM canister HTTP endpoint URL") + dbPath = flag.String("db", "./db", "database path") + evmUrl = flag.String("evm", "http://127.0.0.1:8545", "EVM canister HTTP endpoint URL") + secondaryBlockSourceUrl = flag.String("secondary-blocks-url", "", "URL of the secondary blocks source") ) flag.Parse() @@ -36,7 +37,12 @@ func main() { }() blockSource := NewHttpBlockSource(*evmUrl) - err := RunImport(&settings, &blockSource) + var secondaryBlockSource BlockSource + if *secondaryBlockSourceUrl != "" { + secondarySource := NewHttpBlockSource(*secondaryBlockSourceUrl) + secondaryBlockSource = &secondarySource + } + err := RunImport(&settings, &blockSource, secondaryBlockSource) if err != nil { logger.Error(err.Error())