diff --git a/zetaclient/orchestrator/bootstap_test.go b/zetaclient/orchestrator/bootstap_test.go index 5b94b8151b..33c4326ece 100644 --- a/zetaclient/orchestrator/bootstap_test.go +++ b/zetaclient/orchestrator/bootstap_test.go @@ -170,6 +170,36 @@ func TestCreateSignerMap(t *testing.T) { hasSigner(t, signers, chains.BitcoinMainnet.ChainId) }) + t.Run("Polygon is there but not supported, should be disabled", func(t *testing.T) { + // ARRANGE + // Given updated data from zetacore containing polygon chain + supportedChain, evmParams, btcParams := chainParams([]chains.Chain{ + chains.Ethereum, + chains.Polygon, + chains.BitcoinMainnet, + }) + + // BUT (!) it's disabled via zetacore + evmParams[chains.Polygon.ChainId].IsSupported = false + + mustUpdateAppContext(t, app, supportedChain, evmParams, btcParams) + + // Should have signer BEFORE disabling + hasSigner(t, signers, chains.Polygon.ChainId) + + // ACT + added, removed, err := syncSignerMap(ctx, tss, baseLogger, ts, &signers) + + // ASSERT + assert.NoError(t, err) + assert.Equal(t, 0, added) + assert.Equal(t, 1, removed) + + hasSigner(t, signers, chains.Ethereum.ChainId) + missesSigner(t, signers, chains.Polygon.ChainId) + hasSigner(t, signers, chains.BitcoinMainnet.ChainId) + }) + t.Run("No changes", func(t *testing.T) { // ARRANGE before := len(signers) @@ -340,6 +370,36 @@ func TestCreateChainObserverMap(t *testing.T) { hasObserver(t, observers, chains.BitcoinMainnet.ChainId) }) + t.Run("Polygon is there but not supported, should be disabled", func(t *testing.T) { + // ARRANGE + // Given updated data from zetacore containing polygon chain + supportedChain, evmParams, btcParams := chainParams([]chains.Chain{ + chains.Ethereum, + chains.Polygon, + chains.BitcoinMainnet, + }) + + // BUT (!) it's disabled via zetacore + evmParams[chains.Polygon.ChainId].IsSupported = false + + mustUpdateAppContext(t, app, supportedChain, evmParams, btcParams) + + // Should have signer BEFORE disabling + hasObserver(t, observers, chains.Polygon.ChainId) + + // ACT + added, removed, err := syncObserverMap(ctx, client, tss, dbPath, baseLogger, ts, &observers) + + // ASSERT + assert.NoError(t, err) + assert.Equal(t, 0, added) + assert.Equal(t, 1, removed) + + hasObserver(t, observers, chains.Ethereum.ChainId) + missesObserver(t, observers, chains.Polygon.ChainId) + hasObserver(t, observers, chains.BitcoinMainnet.ChainId) + }) + t.Run("No changes", func(t *testing.T) { // ARRANGE before := len(observers) @@ -369,7 +429,8 @@ func chainParams(supportedChains []chains.Chain) ( for _, chain := range supportedChains { if chains.IsBitcoinChain(chain.ChainId, nil) { btcParams = &observertypes.ChainParams{ - ChainId: chain.ChainId, + ChainId: chain.ChainId, + IsSupported: true, } continue diff --git a/zetaclient/orchestrator/bootstrap.go b/zetaclient/orchestrator/bootstrap.go index b68823b07f..6dae56fe35 100644 --- a/zetaclient/orchestrator/bootstrap.go +++ b/zetaclient/orchestrator/bootstrap.go @@ -84,9 +84,13 @@ func syncSignerMap( } evmChainParams, found := app.GetEVMChainParams(chainID) - if !found { + switch { + case !found: logger.Std.Warn().Msgf("Unable to find chain params for EVM chain %d", chainID) continue + case !evmChainParams.IsSupported: + logger.Std.Warn().Msgf("EVM chain %d is not supported", chainID) + continue } presentChainIDs = append(presentChainIDs, chainID) @@ -122,20 +126,36 @@ func syncSignerMap( } // BTC signer - btcChain, btcConfig, btcFound := app.GetBTCChainAndConfig() - if btcFound { - chainID := btcChain.ChainId + // Emulate same loop semantics as for EVM chains + for i := 0; i < 1; i++ { + btcChain, btcChainParams, btcChainParamsFound := app.GetBTCChainParams() + switch { + case !btcChainParamsFound: + logger.Std.Warn().Msgf("Unable to find chain params for BTC chain") + continue + case !btcChainParams.IsSupported: + logger.Std.Warn().Msgf("BTC chain is not supported") + continue + } + + chainID := btcChainParams.ChainId presentChainIDs = append(presentChainIDs, chainID) - if !mapHas(signers, chainID) { - utxoSigner, err := btcsigner.NewSigner(btcChain, tss, ts, logger, btcConfig) - if err != nil { - logger.Std.Error().Err(err).Msgf("Unable to construct signer for UTXO chain %d", chainID) - } else { - mapSet[int64, interfaces.ChainSigner](signers, chainID, utxoSigner, onAfterSet) - } + // noop + if mapHas(signers, chainID) { + continue } + + cfg, _ := app.Config().GetBTCConfig() + + utxoSigner, err := btcsigner.NewSigner(btcChain, tss, ts, logger, cfg) + if err != nil { + logger.Std.Error().Err(err).Msgf("Unable to construct signer for UTXO chain %d", chainID) + continue + } + + mapSet[int64, interfaces.ChainSigner](signers, chainID, utxoSigner, onAfterSet) } // Remove all disabled signers @@ -210,9 +230,13 @@ func syncObserverMap( } chainParams, found := app.GetEVMChainParams(evmConfig.Chain.ChainId) - if !found { + switch { + case !found: logger.Std.Error().Msgf("Unable to find chain params for EVM chain %d", chainID) continue + case !chainParams.IsSupported: + logger.Std.Error().Msgf("EVM chain %d is not supported", chainID) + continue } presentChainIDs = append(presentChainIDs, chainID) @@ -232,6 +256,7 @@ func syncObserverMap( database, err := db.NewFromSqlite(dbpath, chainName, true) if err != nil { logger.Std.Error().Err(err).Msgf("Unable to open a database for EVM chain %q", chainName) + continue } // create EVM chain observer @@ -250,46 +275,65 @@ func syncObserverMap( logger.Std.Error().Err(err).Msgf("NewObserver error for EVM chain %s", evmConfig.Chain.String()) continue } + mapSet[int64, interfaces.ChainObserver](observerMap, chainID, observer, onAfterSet) } + // Emulate same loop semantics as for EVM chains // create BTC chain observer - if btcChain, btcConfig, btcEnabled := app.GetBTCChainAndConfig(); btcEnabled { + for i := 0; i < 1; i++ { + btcChain, btcConfig, btcEnabled := app.GetBTCChainAndConfig() + if !btcEnabled { + continue + } + + chainID := btcChain.ChainId + _, btcChainParams, found := app.GetBTCChainParams() - if !found { - mapDeleteMissingKeys(observerMap, presentChainIDs, onBeforeUnset) - return added, removed, fmt.Errorf("BTC is enabled, but chains params not found") + switch { + case !found: + logger.Std.Warn().Msgf("Unable to find chain params for BTC chain %d", chainID) + continue + case !btcChainParams.IsSupported: + logger.Std.Warn().Msgf("BTC chain %d is not supported", chainID) + continue } - presentChainIDs = append(presentChainIDs, btcChain.ChainId) - - if !mapHas(observerMap, btcChain.ChainId) { - btcRPC, err := rpc.NewRPCClient(btcConfig) - if err != nil { - return added, removed, errors.Wrap(err, "unable to create rpc client for BTC chain") - } - - database, err := db.NewFromSqlite(dbpath, btcDatabaseFilename, true) - if err != nil { - return added, removed, errors.Wrap(err, "unable to open a database for BTC chain") - } - - btcObserver, err := btcobserver.NewObserver( - btcChain, - btcRPC, - *btcChainParams, - client, - tss, - database, - logger, - ts, - ) - if err != nil { - logger.Std.Error().Err(err).Msgf("NewObserver error for BTC chain %s", btcChain.ChainName.String()) - } else { - mapSet[int64, interfaces.ChainObserver](observerMap, btcChain.ChainId, btcObserver, onAfterSet) - } + presentChainIDs = append(presentChainIDs, chainID) + + // noop + if mapHas(observerMap, chainID) { + continue + } + + btcRPC, err := rpc.NewRPCClient(btcConfig) + if err != nil { + logger.Std.Error().Err(err).Msgf("unable to create rpc client for BTC chain %d", chainID) + continue + } + + database, err := db.NewFromSqlite(dbpath, btcDatabaseFilename, true) + if err != nil { + logger.Std.Error().Err(err).Msgf("unable to open database for BTC chain %d", chainID) + continue + } + + btcObserver, err := btcobserver.NewObserver( + btcChain, + btcRPC, + *btcChainParams, + client, + tss, + database, + logger, + ts, + ) + if err != nil { + logger.Std.Error().Err(err).Msgf("NewObserver error for BTC chain %d", chainID) + continue } + + mapSet[int64, interfaces.ChainObserver](observerMap, btcChain.ChainId, btcObserver, onAfterSet) } // Remove all disabled observers diff --git a/zetaclient/orchestrator/mapping.go b/zetaclient/orchestrator/mapping.go index 74203c19fd..7f685d655c 100644 --- a/zetaclient/orchestrator/mapping.go +++ b/zetaclient/orchestrator/mapping.go @@ -36,13 +36,13 @@ func mapUnset[K cmp.Ordered, V any](m *map[K]V, key K, beforeUnset func(K, V)) b // mapDeleteMissingKeys removes signers from the map IF they are not in the presentKeys. func mapDeleteMissingKeys[K cmp.Ordered, V any](m *map[K]V, presentKeys []K, beforeUnset func(K, V)) { - set := make(map[K]struct{}, len(presentKeys)) + presentKeysSet := make(map[K]struct{}, len(presentKeys)) for _, id := range presentKeys { - set[id] = struct{}{} + presentKeysSet[id] = struct{}{} } for key := range *m { - if _, ok := set[key]; !ok { + if _, isPresent := presentKeysSet[key]; !isPresent { mapUnset(m, key, beforeUnset) } }