From e2c34d32bf903f00e896805321b2097e660e1785 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:19:50 -0600 Subject: [PATCH] fix: use different database file names for signet and testnet4 to avoid wrong height (#3224) * use different database file names for signet and testnet4 * stop fallback to old btc config if it is Signet or Testnet4 * sync with the fix made to develop * use chain name as bitcoin database suffix for regnet, signet and testnet4 --- zetaclient/config/types.go | 10 +++++- zetaclient/config/types_test.go | 18 +++++++++++ zetaclient/orchestrator/bootstap_test.go | 40 ++++++++++++++++++++++++ zetaclient/orchestrator/bootstrap.go | 22 ++++++++++--- 4 files changed, 84 insertions(+), 6 deletions(-) diff --git a/zetaclient/config/types.go b/zetaclient/config/types.go index e843397e0c..f41507994c 100644 --- a/zetaclient/config/types.go +++ b/zetaclient/config/types.go @@ -6,6 +6,8 @@ import ( "sync" "github.com/showa-93/go-mask" + + "github.com/zeta-chain/node/pkg/chains" ) // KeyringBackend is the type of keyring backend to use for the hotkey @@ -139,7 +141,13 @@ func (c Config) GetBTCConfig(chainID int64) (BTCConfig, bool) { // this will allow new 'zetaclientd' binary to work with old config file btcCfg, found := c.BTCChainConfigs[chainID] if !found || btcCfg.Empty() { - btcCfg = c.BitcoinConfig + // fallback to old 'BitcoinConfig' ONLY for mainnet and testnet. + // we don't want observers who hasn't setup their Signet/Testnet4 endpoints to use old config + // because old config is either testnet3 or mainnet which is the incorrect endpoint to use. + if chainID == chains.BitcoinMainnet.ChainId || + chainID == chains.BitcoinTestnet.ChainId { + btcCfg = c.BitcoinConfig + } } return btcCfg, !btcCfg.Empty() diff --git a/zetaclient/config/types_test.go b/zetaclient/config/types_test.go index 0b8884a30a..6ff0dadfc8 100644 --- a/zetaclient/config/types_test.go +++ b/zetaclient/config/types_test.go @@ -86,6 +86,24 @@ func Test_GetBTCConfig(t *testing.T) { }, want: false, }, + { + name: "should not fallback to old config if Signet config is not set in the new config", + chainID: chains.BitcoinSignetTestnet.ChainId, + oldCfg: config.BTCConfig{ + RPCHost: "localhost", + }, + btcCfg: nil, // new config is not set + want: false, + }, + { + name: "should not fallback to old config if Testnet4 config is not set in the new config", + chainID: chains.BitcoinTestnet4.ChainId, + oldCfg: config.BTCConfig{ + RPCHost: "localhost", + }, + btcCfg: nil, // new config is not set + want: false, + }, } for _, tt := range tests { diff --git a/zetaclient/orchestrator/bootstap_test.go b/zetaclient/orchestrator/bootstap_test.go index c93efada00..e9d69de752 100644 --- a/zetaclient/orchestrator/bootstap_test.go +++ b/zetaclient/orchestrator/bootstap_test.go @@ -395,6 +395,46 @@ func TestCreateChainObserverMap(t *testing.T) { }) } +func TestBtcDatabaseFileName(t *testing.T) { + tests := []struct { + name string + chain chains.Chain + expected string + }{ + { + name: "should use legacy file name for bitcoin mainnet", + chain: chains.BitcoinMainnet, + expected: "btc_chain_client", + }, + { + name: "should use legacy file name for bitcoin testnet3", + chain: chains.BitcoinTestnet, + expected: "btc_chain_client", + }, + { + name: "should use new file name for bitcoin regtest", + chain: chains.BitcoinRegtest, + expected: "btc_chain_client_btc_regtest", + }, + { + name: "should use new file name for bitcoin signet", + chain: chains.BitcoinSignetTestnet, + expected: "btc_chain_client_btc_signet_testnet", + }, + { + name: "should use new file name for bitcoin testnet4", + chain: chains.BitcoinTestnet4, + expected: "btc_chain_client_btc_testnet4", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, btcDatabaseFileName(tt.chain)) + }) + } +} + func chainParams(supportedChains []chains.Chain) ([]chains.Chain, map[int64]*observertypes.ChainParams) { params := make(map[int64]*observertypes.ChainParams) diff --git a/zetaclient/orchestrator/bootstrap.go b/zetaclient/orchestrator/bootstrap.go index e1d89df0fd..77793d341b 100644 --- a/zetaclient/orchestrator/bootstrap.go +++ b/zetaclient/orchestrator/bootstrap.go @@ -2,6 +2,7 @@ package orchestrator import ( "context" + "fmt" ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" @@ -11,6 +12,7 @@ import ( "github.com/pkg/errors" "github.com/tonkeeper/tongo/ton" + "github.com/zeta-chain/node/pkg/chains" toncontracts "github.com/zeta-chain/node/pkg/contracts/ton" "github.com/zeta-chain/node/zetaclient/chains/base" btcobserver "github.com/zeta-chain/node/zetaclient/chains/bitcoin/observer" @@ -32,10 +34,6 @@ import ( "github.com/zeta-chain/node/zetaclient/metrics" ) -// btcDatabaseFilename is the Bitcoin database file name now used in mainnet, -// so we keep using it here for backward compatibility -const btcDatabaseFilename = "btc_chain_client" - // CreateSignerMap creates a map of interfaces.ChainSigner (by chainID) for all chains in the config. // Note that signer construction failure for a chain does not prevent the creation of signers for other chains. func CreateSignerMap( @@ -363,7 +361,7 @@ func syncObserverMap( continue } - database, err := db.NewFromSqlite(dbpath, btcDatabaseFilename, true) + database, err := db.NewFromSqlite(dbpath, btcDatabaseFileName(*rawChain), true) if err != nil { logger.Std.Error().Err(err).Msgf("unable to open database for BTC chain %d", chainID) continue @@ -481,6 +479,20 @@ func syncObserverMap( return added, removed, nil } +func btcDatabaseFileName(chain chains.Chain) string { + // legacyBTCDatabaseFilename is the Bitcoin database file name now used in mainnet and testnet3 + // so we keep using it here for backward compatibility + const legacyBTCDatabaseFilename = "btc_chain_client" + + // For additional bitcoin networks, we use the chain name as the database file name + switch chain.ChainId { + case chains.BitcoinMainnet.ChainId, chains.BitcoinTestnet.ChainId: + return legacyBTCDatabaseFilename + default: + return fmt.Sprintf("%s_%s", legacyBTCDatabaseFilename, chain.Name) + } +} + func makeTONClient( ctx context.Context, cfg config.TONConfig,