From 2d5519f4d64bb05b64e6f2c7ec9ef6a87e97610f Mon Sep 17 00:00:00 2001 From: Dmitry S <11892559+swift1337@users.noreply.github.com> Date: Mon, 1 Jul 2024 21:04:06 +0200 Subject: [PATCH] feat(zetaclient): converge AppContext with ZetaCoreContext (#2395) * Converge AppContext and ZetaCoreContext * Embed AppContext into context.Context * Fix code after converging AppContext with ZetaCoreContext * Update changelog * Address PR comments * Add more test cases for AppContext --- changelog.md | 1 + cmd/zetaclientd/debug.go | 282 +++++++-------- cmd/zetaclientd/keygen_tss.go | 2 +- cmd/zetaclientd/start.go | 8 +- cmd/zetaclientd/utils.go | 16 +- zetaclient/chains/base/observer.go | 20 +- zetaclient/chains/base/observer_test.go | 25 +- zetaclient/chains/base/signer.go | 25 +- zetaclient/chains/base/signer_test.go | 13 +- zetaclient/chains/bitcoin/observer/inbound.go | 7 +- .../chains/bitcoin/observer/observer.go | 4 +- .../chains/bitcoin/observer/observer_test.go | 10 +- .../chains/bitcoin/observer/outbound.go | 3 +- zetaclient/chains/bitcoin/signer/signer.go | 6 +- zetaclient/chains/evm/observer/inbound.go | 9 +- zetaclient/chains/evm/observer/observer.go | 4 +- .../chains/evm/observer/observer_test.go | 9 +- zetaclient/chains/evm/observer/outbound.go | 3 +- zetaclient/chains/evm/signer/signer.go | 6 +- zetaclient/chains/evm/signer/signer_test.go | 6 +- zetaclient/config/config_chain.go | 7 +- zetaclient/context/app.go | 287 +++++++++++++++ zetaclient/context/app_context.go | 46 --- zetaclient/context/app_context_test.go | 1 - .../{zetacore_context_test.go => app_test.go} | 331 ++++++++++++------ zetaclient/context/context.go | 26 ++ zetaclient/context/context_test.go | 40 +++ zetaclient/context/zetacore_context.go | 253 ------------- zetaclient/orchestrator/orchestrator.go | 19 +- zetaclient/orchestrator/orchestrator_test.go | 23 +- .../supplychecker/zeta_supply_checker.go | 10 +- zetaclient/tss/tss_signer.go | 2 +- zetaclient/zetacore/client.go | 7 +- zetaclient/zetacore/tx.go | 2 +- zetaclient/zetacore/tx_test.go | 4 +- 35 files changed, 835 insertions(+), 682 deletions(-) create mode 100644 zetaclient/context/app.go delete mode 100644 zetaclient/context/app_context.go delete mode 100644 zetaclient/context/app_context_test.go rename zetaclient/context/{zetacore_context_test.go => app_test.go} (55%) create mode 100644 zetaclient/context/context.go create mode 100644 zetaclient/context/context_test.go delete mode 100644 zetaclient/context/zetacore_context.go diff --git a/changelog.md b/changelog.md index a16cd90d2d..4e7cd838a0 100644 --- a/changelog.md +++ b/changelog.md @@ -55,6 +55,7 @@ * [2357](https://github.com/zeta-chain/node/pull/2357) - integrate base Signer structure into EVM/Bitcoin Signer * [2359](https://github.com/zeta-chain/node/pull/2359) - integrate base Observer structure into EVM/Bitcoin Observer * [2375](https://github.com/zeta-chain/node/pull/2375) - improve & speedup code formatting +* [2395](https://github.com/zeta-chain/node/pull/2395) - converge AppContext with ZetaCoreContext in zetaclient ### Tests diff --git a/cmd/zetaclientd/debug.go b/cmd/zetaclientd/debug.go index 8aaeb6384e..08aadbe8a4 100644 --- a/cmd/zetaclientd/debug.go +++ b/cmd/zetaclientd/debug.go @@ -11,6 +11,7 @@ import ( ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" "github.com/onrik/ethrpc" + "github.com/rs/zerolog" "github.com/spf13/cobra" "github.com/zeta-chain/zetacore/pkg/chains" @@ -42,163 +43,166 @@ func init() { } func DebugCmd() *cobra.Command { - cmd := &cobra.Command{ + return &cobra.Command{ Use: "get-inbound-ballot [inboundHash] [chainID]", Short: "provide txHash and chainID to get the ballot status for the txHash", - RunE: func(_ *cobra.Command, args []string) error { - cobra.ExactArgs(2) - cfg, err := config.Load(debugArgs.zetaCoreHome) - if err != nil { - return err - } - coreContext := clientcontext.NewZetacoreContext(cfg) - chainID, err := strconv.ParseInt(args[1], 10, 64) - if err != nil { - return err - } - inboundHash := args[0] - var ballotIdentifier string - - // create a new zetacore client - client, err := zetacore.NewClient( - &keys.Keys{OperatorAddress: sdk.MustAccAddressFromBech32(sample.AccAddress())}, - debugArgs.zetaNode, - "", - debugArgs.zetaChainID, - false, - nil) - if err != nil { - return err - } - chainParams, err := client.GetChainParams() - if err != nil { - return err - } - tssEthAddress, err := client.GetEthTssAddress() - if err != nil { - return err - } - chain := chains.GetChainFromChainID(chainID) - if chain == nil { - return fmt.Errorf("invalid chain id") - } + RunE: debugCmd, + } +} - // get ballot identifier according to the chain type - if chains.IsEVMChain(chain.ChainId) { - evmObserver := evmobserver.Observer{} - evmObserver.WithZetacoreClient(client) - var ethRPC *ethrpc.EthRPC - var client *ethclient.Client - coinType := coin.CoinType_Cmd - for chain, evmConfig := range cfg.GetAllEVMConfigs() { - if chainID == chain { - ethRPC = ethrpc.NewEthRPC(evmConfig.Endpoint) - client, err = ethclient.Dial(evmConfig.Endpoint) - if err != nil { - return err - } - evmObserver.WithEvmClient(client) - evmObserver.WithEvmJSONRPC(ethRPC) - evmObserver.WithChain(*chains.GetChainFromChainID(chainID)) - } - } - hash := ethcommon.HexToHash(inboundHash) - tx, isPending, err := evmObserver.TransactionByHash(inboundHash) - if err != nil { - return fmt.Errorf("tx not found on chain %s , %d", err.Error(), chain.ChainId) - } - if isPending { - return fmt.Errorf("tx is still pending") - } - receipt, err := client.TransactionReceipt(context.Background(), hash) - if err != nil { - return fmt.Errorf("tx receipt not found on chain %s, %d", err.Error(), chain.ChainId) - } +func debugCmd(_ *cobra.Command, args []string) error { + cobra.ExactArgs(2) + cfg, err := config.Load(debugArgs.zetaCoreHome) + if err != nil { + return err + } - for _, chainParams := range chainParams { - if chainParams.ChainId == chainID { - evmObserver.SetChainParams(observertypes.ChainParams{ - ChainId: chainID, - ConnectorContractAddress: chainParams.ConnectorContractAddress, - ZetaTokenContractAddress: chainParams.ZetaTokenContractAddress, - Erc20CustodyContractAddress: chainParams.Erc20CustodyContractAddress, - }) - evmChainParams, found := coreContext.GetEVMChainParams(chainID) - if !found { - return fmt.Errorf("missing chain params for chain %d", chainID) - } - evmChainParams.ZetaTokenContractAddress = chainParams.ZetaTokenContractAddress - if strings.EqualFold(tx.To, chainParams.ConnectorContractAddress) { - coinType = coin.CoinType_Zeta - } else if strings.EqualFold(tx.To, chainParams.Erc20CustodyContractAddress) { - coinType = coin.CoinType_ERC20 - } else if strings.EqualFold(tx.To, tssEthAddress) { - coinType = coin.CoinType_Gas - } - } - } + appContext := clientcontext.New(cfg, zerolog.Nop()) - switch coinType { - case coin.CoinType_Zeta: - ballotIdentifier, err = evmObserver.CheckAndVoteInboundTokenZeta(tx, receipt, false) - if err != nil { - return err - } - - case coin.CoinType_ERC20: - ballotIdentifier, err = evmObserver.CheckAndVoteInboundTokenERC20(tx, receipt, false) - if err != nil { - return err - } - - case coin.CoinType_Gas: - ballotIdentifier, err = evmObserver.CheckAndVoteInboundTokenGas(tx, receipt, false) - if err != nil { - return err - } - default: - fmt.Println("CoinType not detected") - } - fmt.Println("CoinType : ", coinType) - } else if chains.IsBitcoinChain(chain.ChainId) { - btcObserver := btcobserver.Observer{} - btcObserver.WithZetacoreClient(client) - btcObserver.WithChain(*chains.GetChainFromChainID(chainID)) - connCfg := &rpcclient.ConnConfig{ - Host: cfg.BitcoinConfig.RPCHost, - User: cfg.BitcoinConfig.RPCUsername, - Pass: cfg.BitcoinConfig.RPCPassword, - HTTPPostMode: true, - DisableTLS: true, - Params: cfg.BitcoinConfig.RPCParams, - } + chainID, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return err + } + + inboundHash := args[0] + var ballotIdentifier string + + // create a new zetacore client + client, err := zetacore.NewClient( + &keys.Keys{OperatorAddress: sdk.MustAccAddressFromBech32(sample.AccAddress())}, + debugArgs.zetaNode, + "", + debugArgs.zetaChainID, + false, + nil) + if err != nil { + return err + } + chainParams, err := client.GetChainParams() + if err != nil { + return err + } + tssEthAddress, err := client.GetEthTssAddress() + if err != nil { + return err + } + chain := chains.GetChainFromChainID(chainID) + if chain == nil { + return fmt.Errorf("invalid chain id") + } - btcClient, err := rpcclient.New(connCfg, nil) + // get ballot identifier according to the chain type + if chains.IsEVMChain(chain.ChainId) { + evmObserver := evmobserver.Observer{} + evmObserver.WithZetacoreClient(client) + var ethRPC *ethrpc.EthRPC + var client *ethclient.Client + coinType := coin.CoinType_Cmd + for chain, evmConfig := range cfg.GetAllEVMConfigs() { + if chainID == chain { + ethRPC = ethrpc.NewEthRPC(evmConfig.Endpoint) + client, err = ethclient.Dial(evmConfig.Endpoint) if err != nil { return err } - btcObserver.WithBtcClient(btcClient) - ballotIdentifier, err = btcObserver.CheckReceiptForBtcTxHash(inboundHash, false) - if err != nil { - return err + evmObserver.WithEvmClient(client) + evmObserver.WithEvmJSONRPC(ethRPC) + evmObserver.WithChain(*chains.GetChainFromChainID(chainID)) + } + } + hash := ethcommon.HexToHash(inboundHash) + tx, isPending, err := evmObserver.TransactionByHash(inboundHash) + if err != nil { + return fmt.Errorf("tx not found on chain %s , %d", err.Error(), chain.ChainId) + } + if isPending { + return fmt.Errorf("tx is still pending") + } + receipt, err := client.TransactionReceipt(context.Background(), hash) + if err != nil { + return fmt.Errorf("tx receipt not found on chain %s, %d", err.Error(), chain.ChainId) + } + + for _, chainParams := range chainParams { + if chainParams.ChainId == chainID { + evmObserver.SetChainParams(observertypes.ChainParams{ + ChainId: chainID, + ConnectorContractAddress: chainParams.ConnectorContractAddress, + ZetaTokenContractAddress: chainParams.ZetaTokenContractAddress, + Erc20CustodyContractAddress: chainParams.Erc20CustodyContractAddress, + }) + evmChainParams, found := appContext.GetEVMChainParams(chainID) + if !found { + return fmt.Errorf("missing chain params for chain %d", chainID) + } + evmChainParams.ZetaTokenContractAddress = chainParams.ZetaTokenContractAddress + if strings.EqualFold(tx.To, chainParams.ConnectorContractAddress) { + coinType = coin.CoinType_Zeta + } else if strings.EqualFold(tx.To, chainParams.Erc20CustodyContractAddress) { + coinType = coin.CoinType_ERC20 + } else if strings.EqualFold(tx.To, tssEthAddress) { + coinType = coin.CoinType_Gas } } - fmt.Println("BallotIdentifier : ", ballotIdentifier) + } - // query ballot - ballot, err := client.GetBallot(ballotIdentifier) + switch coinType { + case coin.CoinType_Zeta: + ballotIdentifier, err = evmObserver.CheckAndVoteInboundTokenZeta(tx, receipt, false) if err != nil { return err } - for _, vote := range ballot.Voters { - fmt.Printf("%s : %s \n", vote.VoterAddress, vote.VoteType) + case coin.CoinType_ERC20: + ballotIdentifier, err = evmObserver.CheckAndVoteInboundTokenERC20(tx, receipt, false) + if err != nil { + return err } - fmt.Println("BallotStatus : ", ballot.BallotStatus) - return nil - }, + case coin.CoinType_Gas: + ballotIdentifier, err = evmObserver.CheckAndVoteInboundTokenGas(tx, receipt, false) + if err != nil { + return err + } + default: + fmt.Println("CoinType not detected") + } + fmt.Println("CoinType : ", coinType) + } else if chains.IsBitcoinChain(chain.ChainId) { + btcObserver := btcobserver.Observer{} + btcObserver.WithZetacoreClient(client) + btcObserver.WithChain(*chains.GetChainFromChainID(chainID)) + connCfg := &rpcclient.ConnConfig{ + Host: cfg.BitcoinConfig.RPCHost, + User: cfg.BitcoinConfig.RPCUsername, + Pass: cfg.BitcoinConfig.RPCPassword, + HTTPPostMode: true, + DisableTLS: true, + Params: cfg.BitcoinConfig.RPCParams, + } + + btcClient, err := rpcclient.New(connCfg, nil) + if err != nil { + return err + } + btcObserver.WithBtcClient(btcClient) + ballotIdentifier, err = btcObserver.CheckReceiptForBtcTxHash(inboundHash, false) + if err != nil { + return err + } + } + fmt.Println("BallotIdentifier : ", ballotIdentifier) + + // query ballot + ballot, err := client.GetBallot(ballotIdentifier) + if err != nil { + return err + } + + for _, vote := range ballot.Voters { + fmt.Printf("%s : %s \n", vote.VoterAddress, vote.VoteType) } + fmt.Println("BallotStatus : ", ballot.BallotStatus) - return cmd + return nil } diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 007ce9ec8c..63b5d98041 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -74,7 +74,7 @@ func GenerateTss( // This loop will try keygen at the keygen block and then wait for keygen to be successfully reported by all nodes before breaking out of the loop. // If keygen is unsuccessful, it will reset the triedKeygenAtBlock flag and try again at a new keygen block. - keyGen := appContext.ZetacoreContext().GetKeygen() + keyGen := appContext.GetKeygen() if keyGen.Status == observertypes.KeygenStatus_KeyGenSuccess { return tss, nil } diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index c815b616c0..3546cec8ad 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -144,8 +144,8 @@ func start(_ *cobra.Command, _ []string) error { startLogger.Debug().Msgf("CreateAuthzSigner is ready") // Initialize core parameters from zetacore - appContext := context.NewAppContext(context.NewZetacoreContext(cfg), cfg) - err = zetacoreClient.UpdateZetacoreContext(appContext.ZetacoreContext(), true, startLogger) + appContext := context.New(cfg, masterLogger) + err = zetacoreClient.UpdateZetacoreContext(appContext, true, startLogger) if err != nil { startLogger.Error().Err(err).Msg("Error getting core parameters") return err @@ -226,7 +226,7 @@ func start(_ *cobra.Command, _ []string) error { // For existing keygen, this should directly proceed to the next step ticker := time.NewTicker(time.Second * 1) for range ticker.C { - keyGen := appContext.ZetacoreContext().GetKeygen() + keyGen := appContext.GetKeygen() if keyGen.Status != observerTypes.KeygenStatus_KeyGenSuccess { startLogger.Info().Msgf("Waiting for TSS Keygen to be a success, current status %s", keyGen.Status) continue @@ -250,7 +250,7 @@ func start(_ *cobra.Command, _ []string) error { } startLogger.Info(). Msgf("Current TSS address \n ETH : %s \n BTC : %s \n PubKey : %s ", tss.EVMAddress(), tss.BTCAddress(), tss.CurrentPubkey) - if len(appContext.ZetacoreContext().GetEnabledChains()) == 0 { + if len(appContext.GetEnabledChains()) == 0 { startLogger.Error().Msgf("No chains enabled in updated config %s ", cfg.String()) } diff --git a/cmd/zetaclientd/utils.go b/cmd/zetaclientd/utils.go index 99dd26c487..99f6e03e59 100644 --- a/cmd/zetaclientd/utils.go +++ b/cmd/zetaclientd/utils.go @@ -65,7 +65,6 @@ func CreateSignerMap( logger base.Logger, ts *metrics.TelemetryServer, ) (map[int64]interfaces.ChainSigner, error) { - zetacoreContext := appContext.ZetacoreContext() signerMap := make(map[int64]interfaces.ChainSigner) // EVM signers @@ -73,7 +72,7 @@ func CreateSignerMap( if evmConfig.Chain.IsZetaChain() { continue } - evmChainParams, found := zetacoreContext.GetEVMChainParams(evmConfig.Chain.ChainId) + evmChainParams, found := appContext.GetEVMChainParams(evmConfig.Chain.ChainId) if !found { logger.Std.Error().Msgf("ChainParam not found for chain %s", evmConfig.Chain.String()) continue @@ -82,7 +81,7 @@ func CreateSignerMap( erc20CustodyAddress := ethcommon.HexToAddress(evmChainParams.Erc20CustodyContractAddress) signer, err := evmsigner.NewSigner( evmConfig.Chain, - zetacoreContext, + appContext, tss, ts, logger, @@ -100,7 +99,7 @@ func CreateSignerMap( // BTC signer btcChain, btcConfig, enabled := appContext.GetBTCChainAndConfig() if enabled { - signer, err := btcsigner.NewSigner(btcChain, zetacoreContext, tss, ts, logger, btcConfig) + signer, err := btcsigner.NewSigner(btcChain, appContext, tss, ts, logger, btcConfig) if err != nil { logger.Std.Error().Err(err).Msgf("NewBTCSigner error for chain %s", btcChain.String()) } else { @@ -120,14 +119,13 @@ func CreateChainObserverMap( logger base.Logger, ts *metrics.TelemetryServer, ) (map[int64]interfaces.ChainObserver, error) { - zetacoreContext := appContext.ZetacoreContext() observerMap := make(map[int64]interfaces.ChainObserver) // EVM observers for _, evmConfig := range appContext.Config().GetAllEVMConfigs() { if evmConfig.Chain.IsZetaChain() { continue } - chainParams, found := zetacoreContext.GetEVMChainParams(evmConfig.Chain.ChainId) + chainParams, found := appContext.GetEVMChainParams(evmConfig.Chain.ChainId) if !found { logger.Std.Error().Msgf("ChainParam not found for chain %s", evmConfig.Chain.String()) continue @@ -145,7 +143,7 @@ func CreateChainObserverMap( evmConfig, evmClient, *chainParams, - zetacoreContext, + appContext, zetacoreClient, tss, dbpath, @@ -160,7 +158,7 @@ func CreateChainObserverMap( } // BTC observer - _, chainParams, found := zetacoreContext.GetBTCChainParams() + _, chainParams, found := appContext.GetBTCChainParams() if !found { return nil, fmt.Errorf("bitcoin chains params not found") } @@ -177,7 +175,7 @@ func CreateChainObserverMap( btcChain, btcClient, *chainParams, - zetacoreContext, + appContext, zetacoreClient, tss, dbpath, diff --git a/zetaclient/chains/base/observer.go b/zetaclient/chains/base/observer.go index 1f3fc2d0ca..edfef83629 100644 --- a/zetaclient/chains/base/observer.go +++ b/zetaclient/chains/base/observer.go @@ -45,8 +45,8 @@ type Observer struct { // chainParams contains the dynamic chain parameters of the observed chain chainParams observertypes.ChainParams - // coreContext contains context data of ZetaChain - zetacoreContext *context.ZetacoreContext + // appContext contains context data for zetaclient & zetacore (e.g. supported chains) + appContext *context.AppContext // zetacoreClient is the client to interact with ZetaChain zetacoreClient interfaces.ZetacoreClient @@ -87,7 +87,7 @@ type Observer struct { func NewObserver( chain chains.Chain, chainParams observertypes.ChainParams, - zetacoreContext *context.ZetacoreContext, + appContext *context.AppContext, zetacoreClient interfaces.ZetacoreClient, tss interfaces.TSSSigner, blockCacheSize int, @@ -98,7 +98,7 @@ func NewObserver( ob := Observer{ chain: chain, chainParams: chainParams, - zetacoreContext: zetacoreContext, + appContext: appContext, zetacoreClient: zetacoreClient, tss: tss, lastBlock: 0, @@ -164,15 +164,9 @@ func (ob *Observer) WithChainParams(params observertypes.ChainParams) *Observer return ob } -// ZetacoreContext returns the zetacore context for the observer. -func (ob *Observer) ZetacoreContext() *context.ZetacoreContext { - return ob.zetacoreContext -} - -// WithZetacoreContext attaches a new zetacore context to the observer. -func (ob *Observer) WithZetacoreContext(context *context.ZetacoreContext) *Observer { - ob.zetacoreContext = context - return ob +// AppContext returns the zetacore context for the observer. +func (ob *Observer) AppContext() *context.AppContext { + return ob.appContext } // ZetacoreClient returns the zetacore client for the observer. diff --git a/zetaclient/chains/base/observer_test.go b/zetaclient/chains/base/observer_test.go index a04a48fcc3..e6d5a088a9 100644 --- a/zetaclient/chains/base/observer_test.go +++ b/zetaclient/chains/base/observer_test.go @@ -5,6 +5,7 @@ import ( "testing" lru "github.com/hashicorp/golang-lru" + "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/zetaclient/testutils" @@ -25,7 +26,7 @@ func createObserver(t *testing.T) *base.Observer { // constructor parameters chain := chains.Ethereum chainParams := *sample.ChainParams(chain.ChainId) - zetacoreContext := context.NewZetacoreContext(config.NewConfig()) + appContext := context.New(config.NewConfig(), zerolog.Nop()) zetacoreClient := mocks.NewMockZetacoreClient() tss := mocks.NewTSSMainnet() @@ -34,7 +35,7 @@ func createObserver(t *testing.T) *base.Observer { ob, err := base.NewObserver( chain, chainParams, - zetacoreContext, + appContext, zetacoreClient, tss, base.DefaultBlockCacheSize, @@ -51,7 +52,7 @@ func TestNewObserver(t *testing.T) { // constructor parameters chain := chains.Ethereum chainParams := *sample.ChainParams(chain.ChainId) - zetacoreContext := context.NewZetacoreContext(config.NewConfig()) + appContext := context.New(config.NewConfig(), zerolog.Nop()) zetacoreClient := mocks.NewMockZetacoreClient() tss := mocks.NewTSSMainnet() blockCacheSize := base.DefaultBlockCacheSize @@ -62,7 +63,7 @@ func TestNewObserver(t *testing.T) { name string chain chains.Chain chainParams observertypes.ChainParams - zetacoreContext *context.ZetacoreContext + appContext *context.AppContext zetacoreClient interfaces.ZetacoreClient tss interfaces.TSSSigner blockCacheSize int @@ -74,7 +75,7 @@ func TestNewObserver(t *testing.T) { name: "should be able to create new observer", chain: chain, chainParams: chainParams, - zetacoreContext: zetacoreContext, + appContext: appContext, zetacoreClient: zetacoreClient, tss: tss, blockCacheSize: blockCacheSize, @@ -85,7 +86,7 @@ func TestNewObserver(t *testing.T) { name: "should return error on invalid block cache size", chain: chain, chainParams: chainParams, - zetacoreContext: zetacoreContext, + appContext: appContext, zetacoreClient: zetacoreClient, tss: tss, blockCacheSize: 0, @@ -97,7 +98,7 @@ func TestNewObserver(t *testing.T) { name: "should return error on invalid header cache size", chain: chain, chainParams: chainParams, - zetacoreContext: zetacoreContext, + appContext: appContext, zetacoreClient: zetacoreClient, tss: tss, blockCacheSize: blockCacheSize, @@ -113,7 +114,7 @@ func TestNewObserver(t *testing.T) { ob, err := base.NewObserver( tt.chain, tt.chainParams, - tt.zetacoreContext, + tt.appContext, tt.zetacoreClient, tt.tss, tt.blockCacheSize, @@ -161,14 +162,6 @@ func TestObserverGetterAndSetter(t *testing.T) { ob = ob.WithChainParams(newChainParams) require.True(t, observertypes.ChainParamsEqual(newChainParams, ob.ChainParams())) }) - t.Run("should be able to update zetacore context", func(t *testing.T) { - ob := createObserver(t) - - // update zetacore context - newZetacoreContext := context.NewZetacoreContext(config.NewConfig()) - ob = ob.WithZetacoreContext(newZetacoreContext) - require.Equal(t, newZetacoreContext, ob.ZetacoreContext()) - }) t.Run("should be able to update zetacore client", func(t *testing.T) { ob := createObserver(t) diff --git a/zetaclient/chains/base/signer.go b/zetaclient/chains/base/signer.go index bc5ad7934f..0fc9ca4837 100644 --- a/zetaclient/chains/base/signer.go +++ b/zetaclient/chains/base/signer.go @@ -15,8 +15,7 @@ type Signer struct { // chain contains static information about the external chain chain chains.Chain - // zetacoreContext is the Zetacore client to interact with ZetaChain - zetacoreContext *context.ZetacoreContext + appContext *context.AppContext // tss is the TSS signer tss interfaces.TSSSigner @@ -35,16 +34,16 @@ type Signer struct { // NewSigner creates a new base signer func NewSigner( chain chains.Chain, - zetacoreContext *context.ZetacoreContext, + zetacoreContext *context.AppContext, tss interfaces.TSSSigner, ts *metrics.TelemetryServer, logger Logger, ) *Signer { return &Signer{ - chain: chain, - zetacoreContext: zetacoreContext, - tss: tss, - ts: ts, + chain: chain, + appContext: zetacoreContext, + tss: tss, + ts: ts, logger: Logger{ Std: logger.Std.With().Int64("chain", chain.ChainId).Str("module", "signer").Logger(), Compliance: logger.Compliance, @@ -63,15 +62,9 @@ func (s *Signer) WithChain(chain chains.Chain) *Signer { return s } -// ZetacoreContext returns the zetacore context for the signer -func (s *Signer) ZetacoreContext() *context.ZetacoreContext { - return s.zetacoreContext -} - -// WithZetacoreContext attaches a new zetacore context to the signer -func (s *Signer) WithZetacoreContext(context *context.ZetacoreContext) *Signer { - s.zetacoreContext = context - return s +// AppContext returns the zetacore context for the signer +func (s *Signer) AppContext() *context.AppContext { + return s.appContext } // Tss returns the tss signer for the signer diff --git a/zetaclient/chains/base/signer_test.go b/zetaclient/chains/base/signer_test.go index 960c508d6e..a0e2696b92 100644 --- a/zetaclient/chains/base/signer_test.go +++ b/zetaclient/chains/base/signer_test.go @@ -3,6 +3,7 @@ package base_test import ( "testing" + "github.com/rs/zerolog" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/pkg/chains" @@ -17,12 +18,12 @@ import ( func createSigner(_ *testing.T) *base.Signer { // constructor parameters chain := chains.Ethereum - zetacoreContext := context.NewZetacoreContext(config.NewConfig()) + appContext := context.New(config.NewConfig(), zerolog.Nop()) tss := mocks.NewTSSMainnet() logger := base.DefaultLogger() // create signer - return base.NewSigner(chain, zetacoreContext, tss, nil, logger) + return base.NewSigner(chain, appContext, tss, nil, logger) } func TestNewSigner(t *testing.T) { @@ -39,14 +40,6 @@ func TestSignerGetterAndSetter(t *testing.T) { signer = signer.WithChain(chains.BscMainnet) require.Equal(t, newChain, signer.Chain()) }) - t.Run("should be able to update zetacore context", func(t *testing.T) { - signer := createSigner(t) - - // update zetacore context - newZetacoreContext := context.NewZetacoreContext(config.NewConfig()) - signer = signer.WithZetacoreContext(newZetacoreContext) - require.Equal(t, newZetacoreContext, signer.ZetacoreContext()) - }) t.Run("should be able to update tss", func(t *testing.T) { signer := createSigner(t) diff --git a/zetaclient/chains/bitcoin/observer/inbound.go b/zetaclient/chains/bitcoin/observer/inbound.go index 037fd11cd1..1d528a7c62 100644 --- a/zetaclient/chains/bitcoin/observer/inbound.go +++ b/zetaclient/chains/bitcoin/observer/inbound.go @@ -20,7 +20,6 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "github.com/zeta-chain/zetacore/zetaclient/compliance" "github.com/zeta-chain/zetacore/zetaclient/config" - "github.com/zeta-chain/zetacore/zetaclient/context" "github.com/zeta-chain/zetacore/zetaclient/types" "github.com/zeta-chain/zetacore/zetaclient/zetacore" ) @@ -43,7 +42,7 @@ func (ob *Observer) WatchInbound() { for { select { case <-ticker.C(): - if !context.IsInboundObservationEnabled(ob.ZetacoreContext(), ob.GetChainParams()) { + if !ob.AppContext().IsInboundObservationEnabled(ob.GetChainParams()) { sampledLogger.Info(). Msgf("WatchInbound: inbound observation is disabled for chain %d", ob.Chain().ChainId) continue @@ -109,7 +108,7 @@ func (ob *Observer) ObserveInbound() error { // https://github.com/zeta-chain/node/issues/1847 // TODO: move this logic in its own routine // https://github.com/zeta-chain/node/issues/2204 - blockHeaderVerification, found := ob.ZetacoreContext().GetBlockHeaderEnabledChains(ob.Chain().ChainId) + blockHeaderVerification, found := ob.AppContext().GetBlockHeaderEnabledChains(ob.Chain().ChainId) if found && blockHeaderVerification.Enabled { // #nosec G701 always in range err = ob.postBlockHeader(int64(blockNumber)) @@ -187,7 +186,7 @@ func (ob *Observer) WatchInboundTracker() { for { select { case <-ticker.C(): - if !context.IsInboundObservationEnabled(ob.ZetacoreContext(), ob.GetChainParams()) { + if !ob.AppContext().IsInboundObservationEnabled(ob.GetChainParams()) { continue } err := ob.ProcessInboundTrackers() diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index 11ccc5460a..a04188da80 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -112,7 +112,7 @@ func NewObserver( chain chains.Chain, btcClient interfaces.BTCRPCClient, chainParams observertypes.ChainParams, - zetacoreContext *context.ZetacoreContext, + appContext *context.AppContext, zetacoreClient interfaces.ZetacoreClient, tss interfaces.TSSSigner, dbpath string, @@ -123,7 +123,7 @@ func NewObserver( baseObserver, err := base.NewObserver( chain, chainParams, - zetacoreContext, + appContext, zetacoreClient, tss, btcBlocksPerDay, diff --git a/zetaclient/chains/bitcoin/observer/observer_test.go b/zetaclient/chains/bitcoin/observer/observer_test.go index c79209e3fc..8fb8838ae3 100644 --- a/zetaclient/chains/bitcoin/observer/observer_test.go +++ b/zetaclient/chains/bitcoin/observer/observer_test.go @@ -113,7 +113,7 @@ func Test_NewObserver(t *testing.T) { chain chains.Chain btcClient interfaces.BTCRPCClient chainParams observertypes.ChainParams - coreContext *context.ZetacoreContext + appContext *context.AppContext coreClient interfaces.ZetacoreClient tss interfaces.TSSSigner dbpath string @@ -127,7 +127,7 @@ func Test_NewObserver(t *testing.T) { chain: chain, btcClient: mocks.NewMockBTCRPCClient().WithBlockCount(100), chainParams: params, - coreContext: nil, + appContext: nil, coreClient: nil, tss: mocks.NewTSSMainnet(), dbpath: sample.CreateTempDir(t), @@ -140,7 +140,7 @@ func Test_NewObserver(t *testing.T) { chain: chains.Chain{ChainId: 111}, // invalid chain id btcClient: mocks.NewMockBTCRPCClient().WithBlockCount(100), chainParams: params, - coreContext: nil, + appContext: nil, coreClient: nil, tss: mocks.NewTSSMainnet(), dbpath: sample.CreateTempDir(t), @@ -153,7 +153,7 @@ func Test_NewObserver(t *testing.T) { name: "should fail on invalid dbpath", chain: chain, chainParams: params, - coreContext: nil, + appContext: nil, coreClient: nil, btcClient: mocks.NewMockBTCRPCClient().WithBlockCount(100), tss: mocks.NewTSSMainnet(), @@ -173,7 +173,7 @@ func Test_NewObserver(t *testing.T) { tt.chain, tt.btcClient, tt.chainParams, - tt.coreContext, + tt.appContext, tt.coreClient, tt.tss, tt.dbpath, diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index 5f4684f50f..681604d48b 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -16,7 +16,6 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/rpc" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "github.com/zeta-chain/zetacore/zetaclient/compliance" - "github.com/zeta-chain/zetacore/zetaclient/context" "github.com/zeta-chain/zetacore/zetaclient/types" ) @@ -44,7 +43,7 @@ func (ob *Observer) WatchOutbound() { for { select { case <-ticker.C(): - if !context.IsOutboundObservationEnabled(ob.ZetacoreContext(), ob.GetChainParams()) { + if !ob.AppContext().IsOutboundObservationEnabled(ob.GetChainParams()) { sampledLogger.Info(). Msgf("WatchOutbound: outbound observation is disabled for chain %d", chainID) continue diff --git a/zetaclient/chains/bitcoin/signer/signer.go b/zetaclient/chains/bitcoin/signer/signer.go index eae11a68ce..259f55bc53 100644 --- a/zetaclient/chains/bitcoin/signer/signer.go +++ b/zetaclient/chains/bitcoin/signer/signer.go @@ -58,13 +58,13 @@ type Signer struct { // NewSigner creates a new Bitcoin signer func NewSigner( chain chains.Chain, - zetacoreContext *context.ZetacoreContext, + appContext *context.AppContext, tss interfaces.TSSSigner, ts *metrics.TelemetryServer, logger base.Logger, cfg config.BTCConfig) (*Signer, error) { // create base signer - baseSigner := base.NewSigner(chain, zetacoreContext, tss, ts, logger) + baseSigner := base.NewSigner(chain, appContext, tss, ts, logger) // create the bitcoin rpc client using the provided config connCfg := &rpcclient.ConnConfig{ @@ -350,7 +350,7 @@ func (signer *Signer) TryProcessOutbound( logger.Error().Msgf("chain observer is not a bitcoin observer") return } - flags := signer.ZetacoreContext().GetCrossChainFlags() + flags := signer.AppContext().GetCrossChainFlags() if !flags.IsOutboundEnabled { logger.Info().Msgf("outbound is disabled") return diff --git a/zetaclient/chains/evm/observer/inbound.go b/zetaclient/chains/evm/observer/inbound.go index 40844ddbd7..20823f533b 100644 --- a/zetaclient/chains/evm/observer/inbound.go +++ b/zetaclient/chains/evm/observer/inbound.go @@ -27,7 +27,6 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/chains/evm" "github.com/zeta-chain/zetacore/zetaclient/compliance" "github.com/zeta-chain/zetacore/zetaclient/config" - clientcontext "github.com/zeta-chain/zetacore/zetaclient/context" "github.com/zeta-chain/zetacore/zetaclient/metrics" clienttypes "github.com/zeta-chain/zetacore/zetaclient/types" "github.com/zeta-chain/zetacore/zetaclient/zetacore" @@ -52,7 +51,7 @@ func (ob *Observer) WatchInbound() { for { select { case <-ticker.C(): - if !clientcontext.IsInboundObservationEnabled(ob.ZetacoreContext(), ob.GetChainParams()) { + if !ob.AppContext().IsInboundObservationEnabled(ob.GetChainParams()) { sampledLogger.Info(). Msgf("WatchInbound: inbound observation is disabled for chain %d", ob.Chain().ChainId) continue @@ -87,7 +86,7 @@ func (ob *Observer) WatchInboundTracker() { for { select { case <-ticker.C(): - if !clientcontext.IsInboundObservationEnabled(ob.ZetacoreContext(), ob.GetChainParams()) { + if !ob.AppContext().IsInboundObservationEnabled(ob.GetChainParams()) { continue } err := ob.ProcessInboundTrackers() @@ -395,7 +394,7 @@ func (ob *Observer) ObserverTSSReceive(startBlock, toBlock uint64) uint64 { // post new block header (if any) to zetacore and ignore error // TODO: consider having a independent ticker(from TSS scaning) for posting block headers // https://github.com/zeta-chain/node/issues/1847 - blockHeaderVerification, found := ob.ZetacoreContext().GetBlockHeaderEnabledChains(ob.Chain().ChainId) + blockHeaderVerification, found := ob.AppContext().GetBlockHeaderEnabledChains(ob.Chain().ChainId) if found && blockHeaderVerification.Enabled { // post block header for supported chains // TODO: move this logic in its own routine @@ -659,7 +658,7 @@ func (ob *Observer) BuildInboundVoteMsgForZetaSentEvent( } if !destChain.IsZetaChain() { - paramsDest, found := ob.ZetacoreContext().GetEVMChainParams(destChain.ChainId) + paramsDest, found := ob.AppContext().GetEVMChainParams(destChain.ChainId) if !found { ob.Logger().Inbound.Warn(). Msgf("chain id not present in EVMChainParams %d", event.DestinationChainId.Int64()) diff --git a/zetaclient/chains/evm/observer/observer.go b/zetaclient/chains/evm/observer/observer.go index 0a33603196..3a60b16e40 100644 --- a/zetaclient/chains/evm/observer/observer.go +++ b/zetaclient/chains/evm/observer/observer.go @@ -58,7 +58,7 @@ func NewObserver( evmCfg config.EVMConfig, evmClient interfaces.EVMRPCClient, chainParams observertypes.ChainParams, - zetacoreContext *clientcontext.ZetacoreContext, + appClient *clientcontext.AppContext, zetacoreClient interfaces.ZetacoreClient, tss interfaces.TSSSigner, dbpath string, @@ -69,7 +69,7 @@ func NewObserver( baseObserver, err := base.NewObserver( evmCfg.Chain, chainParams, - zetacoreContext, + appClient, zetacoreClient, tss, base.DefaultBlockCacheSize, diff --git a/zetaclient/chains/evm/observer/observer_test.go b/zetaclient/chains/evm/observer/observer_test.go index f149d1bae2..6cb97dd65d 100644 --- a/zetaclient/chains/evm/observer/observer_test.go +++ b/zetaclient/chains/evm/observer/observer_test.go @@ -37,7 +37,7 @@ func getZetacoreContext( evmChain chains.Chain, endpoint string, evmChainParams *observertypes.ChainParams, -) (*context.ZetacoreContext, config.EVMConfig) { +) (*context.AppContext, config.EVMConfig) { // use default endpoint if not provided if endpoint == "" { endpoint = "http://localhost:8545" @@ -51,12 +51,12 @@ func getZetacoreContext( } // create zetacore context - coreCtx := context.NewZetacoreContext(cfg) + appContext := context.New(cfg, zerolog.Nop()) evmChainParamsMap := make(map[int64]*observertypes.ChainParams) evmChainParamsMap[evmChain.ChainId] = evmChainParams // feed chain params - coreCtx.Update( + appContext.Update( &observertypes.Keygen{}, []chains.Chain{evmChain}, evmChainParamsMap, @@ -65,10 +65,9 @@ func getZetacoreContext( *sample.CrosschainFlags(), sample.HeaderSupportedChains(), true, - zerolog.Logger{}, ) // create app context - return coreCtx, cfg.EVMChainConfigs[evmChain.ChainId] + return appContext, cfg.EVMChainConfigs[evmChain.ChainId] } // MockEVMObserver creates a mock ChainObserver with custom chain, TSS, params etc diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index 2f3d3c136f..84103620dd 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -23,7 +23,6 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/chains/evm" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "github.com/zeta-chain/zetacore/zetaclient/compliance" - clientcontext "github.com/zeta-chain/zetacore/zetaclient/context" clienttypes "github.com/zeta-chain/zetacore/zetaclient/types" ) @@ -52,7 +51,7 @@ func (ob *Observer) WatchOutbound() { for { select { case <-ticker.C(): - if !clientcontext.IsOutboundObservationEnabled(ob.ZetacoreContext(), ob.GetChainParams()) { + if !ob.AppContext().IsOutboundObservationEnabled(ob.GetChainParams()) { sampledLogger.Info(). Msgf("WatchOutbound: outbound observation is disabled for chain %d", ob.Chain().ChainId) continue diff --git a/zetaclient/chains/evm/signer/signer.go b/zetaclient/chains/evm/signer/signer.go index 3ea7852766..8bba72d777 100644 --- a/zetaclient/chains/evm/signer/signer.go +++ b/zetaclient/chains/evm/signer/signer.go @@ -82,7 +82,7 @@ type Signer struct { // NewSigner creates a new EVM signer func NewSigner( chain chains.Chain, - zetacoreContext *clientcontext.ZetacoreContext, + appContext *clientcontext.AppContext, tss interfaces.TSSSigner, ts *metrics.TelemetryServer, logger base.Logger, @@ -93,7 +93,7 @@ func NewSigner( erc20CustodyAddress ethcommon.Address, ) (*Signer, error) { // create base signer - baseSigner := base.NewSigner(chain, zetacoreContext, tss, ts, logger) + baseSigner := base.NewSigner(chain, appContext, tss, ts, logger) // create EVM client client, ethSigner, err := getEVMRPC(endpoint) @@ -376,7 +376,7 @@ func (signer *Signer) TryProcessOutbound( toChain := chains.GetChainFromChainID(txData.toChainID.Int64()) // Get cross-chain flags - crossChainflags := signer.ZetacoreContext().GetCrossChainFlags() + crossChainflags := signer.AppContext().GetCrossChainFlags() // https://github.com/zeta-chain/node/issues/2050 var tx *ethtypes.Transaction // compliance check goes first diff --git a/zetaclient/chains/evm/signer/signer_test.go b/zetaclient/chains/evm/signer/signer_test.go index ea27152b97..13aaac87b1 100644 --- a/zetaclient/chains/evm/signer/signer_test.go +++ b/zetaclient/chains/evm/signer/signer_test.go @@ -47,7 +47,7 @@ func getNewEvmSigner(tss interfaces.TSSSigner) (*Signer, error) { return NewSigner( chains.BscMainnet, - context.NewZetacoreContext(cfg), + context.New(cfg, zerolog.Nop()), tss, nil, logger, @@ -71,7 +71,7 @@ func getNewEvmChainObserver(t *testing.T, tss interfaces.TSSSigner) (*observer.O evmClient := mocks.NewMockEvmClient().WithBlockNumber(1000) params := mocks.MockChainParams(evmcfg.Chain.ChainId, 10) cfg.EVMChainConfigs[chains.BscMainnet.ChainId] = evmcfg - coreCTX := context.NewZetacoreContext(cfg) + appContext := context.New(cfg, zerolog.Nop()) dbpath := sample.CreateTempDir(t) logger := base.Logger{} ts := &metrics.TelemetryServer{} @@ -80,7 +80,7 @@ func getNewEvmChainObserver(t *testing.T, tss interfaces.TSSSigner) (*observer.O evmcfg, evmClient, params, - coreCTX, + appContext, mocks.NewMockZetacoreClient(), tss, dbpath, diff --git a/zetaclient/config/config_chain.go b/zetaclient/config/config_chain.go index 5c2ed1d077..5946c4ca62 100644 --- a/zetaclient/config/config_chain.go +++ b/zetaclient/config/config_chain.go @@ -1,6 +1,10 @@ package config -import "github.com/zeta-chain/zetacore/pkg/chains" +import ( + "sync" + + "github.com/zeta-chain/zetacore/pkg/chains" +) const ( MaxBlocksPerPeriod = 100 @@ -32,6 +36,7 @@ func GetERC20CustodyABI() string { // It is initialize with default chain configs func New() Config { return Config{ + cfgLock: &sync.RWMutex{}, EVMChainConfigs: evmChainsConfigs, BitcoinConfig: bitcoinConfigRegnet, } diff --git a/zetaclient/context/app.go b/zetaclient/context/app.go new file mode 100644 index 0000000000..c40e769492 --- /dev/null +++ b/zetaclient/context/app.go @@ -0,0 +1,287 @@ +// Package context provides global app context for ZetaClient +package context + +import ( + "sort" + "sync" + + "github.com/rs/zerolog" + + "github.com/zeta-chain/zetacore/pkg/chains" + lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" + "github.com/zeta-chain/zetacore/zetaclient/config" +) + +// AppContext represents application context. +type AppContext struct { + config config.Config + logger zerolog.Logger + + keygen observertypes.Keygen + chainsEnabled []chains.Chain + evmChainParams map[int64]*observertypes.ChainParams + bitcoinChainParams *observertypes.ChainParams + currentTssPubkey string + crosschainFlags observertypes.CrosschainFlags + + // blockHeaderEnabledChains is used to store the list of chains that have block header verification enabled + // All chains in this list will have Enabled flag set to true + blockHeaderEnabledChains []lightclienttypes.HeaderSupportedChain + + mu sync.RWMutex +} + +// New creates and returns new AppContext +func New(cfg config.Config, logger zerolog.Logger) *AppContext { + evmChainParams := make(map[int64]*observertypes.ChainParams) + for _, e := range cfg.EVMChainConfigs { + evmChainParams[e.Chain.ChainId] = &observertypes.ChainParams{} + } + + var bitcoinChainParams *observertypes.ChainParams + _, found := cfg.GetBTCConfig() + if found { + bitcoinChainParams = &observertypes.ChainParams{} + } + + return &AppContext{ + config: cfg, + logger: logger.With().Str("module", "appcontext").Logger(), + + chainsEnabled: []chains.Chain{}, + evmChainParams: evmChainParams, + bitcoinChainParams: bitcoinChainParams, + crosschainFlags: observertypes.CrosschainFlags{}, + blockHeaderEnabledChains: []lightclienttypes.HeaderSupportedChain{}, + + currentTssPubkey: "", + keygen: observertypes.Keygen{}, + mu: sync.RWMutex{}, + } +} + +// Config returns the config of the app +func (a *AppContext) Config() config.Config { + return a.config +} + +// GetBTCChainAndConfig returns btc chain and config if enabled +func (a *AppContext) GetBTCChainAndConfig() (chains.Chain, config.BTCConfig, bool) { + btcConfig, configEnabled := a.Config().GetBTCConfig() + btcChain, _, paramsEnabled := a.GetBTCChainParams() + + if !configEnabled || !paramsEnabled { + return chains.Chain{}, config.BTCConfig{}, false + } + + return btcChain, btcConfig, true +} + +// IsOutboundObservationEnabled returns true if the chain is supported and outbound flag is enabled +func (a *AppContext) IsOutboundObservationEnabled(chainParams observertypes.ChainParams) bool { + flags := a.GetCrossChainFlags() + return chainParams.IsSupported && flags.IsOutboundEnabled +} + +// IsInboundObservationEnabled returns true if the chain is supported and inbound flag is enabled +func (a *AppContext) IsInboundObservationEnabled(chainParams observertypes.ChainParams) bool { + flags := a.GetCrossChainFlags() + return chainParams.IsSupported && flags.IsInboundEnabled +} + +// GetKeygen returns the current keygen +func (a *AppContext) GetKeygen() observertypes.Keygen { + a.mu.RLock() + defer a.mu.RUnlock() + + var copiedPubkeys []string + if a.keygen.GranteePubkeys != nil { + copiedPubkeys = make([]string, len(a.keygen.GranteePubkeys)) + copy(copiedPubkeys, a.keygen.GranteePubkeys) + } + + return observertypes.Keygen{ + Status: a.keygen.Status, + GranteePubkeys: copiedPubkeys, + BlockNumber: a.keygen.BlockNumber, + } +} + +// GetCurrentTssPubKey returns the current tss pubkey +func (a *AppContext) GetCurrentTssPubKey() string { + a.mu.RLock() + defer a.mu.RUnlock() + + return a.currentTssPubkey +} + +// GetEnabledChains returns all enabled chains including zetachain +func (a *AppContext) GetEnabledChains() []chains.Chain { + a.mu.RLock() + defer a.mu.RUnlock() + + copiedChains := make([]chains.Chain, len(a.chainsEnabled)) + copy(copiedChains, a.chainsEnabled) + + return copiedChains +} + +// GetEnabledExternalChains returns all enabled external chains +func (a *AppContext) GetEnabledExternalChains() []chains.Chain { + a.mu.RLock() + defer a.mu.RUnlock() + + externalChains := make([]chains.Chain, 0) + for _, chain := range a.chainsEnabled { + if chain.IsExternal { + externalChains = append(externalChains, chain) + } + } + return externalChains +} + +// GetEVMChainParams returns chain params for a specific EVM chain +func (a *AppContext) GetEVMChainParams(chainID int64) (*observertypes.ChainParams, bool) { + a.mu.RLock() + defer a.mu.RUnlock() + + evmChainParams, found := a.evmChainParams[chainID] + return evmChainParams, found +} + +// GetAllEVMChainParams returns all chain params for EVM chains +func (a *AppContext) GetAllEVMChainParams() map[int64]*observertypes.ChainParams { + a.mu.RLock() + defer a.mu.RUnlock() + + // deep copy evm chain params + copied := make(map[int64]*observertypes.ChainParams, len(a.evmChainParams)) + for chainID, evmConfig := range a.evmChainParams { + copied[chainID] = &observertypes.ChainParams{} + *copied[chainID] = *evmConfig + } + return copied +} + +// GetBTCChainParams returns (chain, chain params, found) for bitcoin chain +func (a *AppContext) GetBTCChainParams() (chains.Chain, *observertypes.ChainParams, bool) { + a.mu.RLock() + defer a.mu.RUnlock() + + if a.bitcoinChainParams == nil { // bitcoin is not enabled + return chains.Chain{}, nil, false + } + + chain := chains.GetChainFromChainID(a.bitcoinChainParams.ChainId) + if chain == nil { + return chains.Chain{}, nil, false + } + + return *chain, a.bitcoinChainParams, true +} + +// GetCrossChainFlags returns crosschain flags +func (a *AppContext) GetCrossChainFlags() observertypes.CrosschainFlags { + a.mu.RLock() + defer a.mu.RUnlock() + + return a.crosschainFlags +} + +// GetAllHeaderEnabledChains returns all verification flags +func (a *AppContext) GetAllHeaderEnabledChains() []lightclienttypes.HeaderSupportedChain { + a.mu.RLock() + defer a.mu.RUnlock() + + return a.blockHeaderEnabledChains +} + +// GetBlockHeaderEnabledChains checks if block header verification is enabled for a specific chain +func (a *AppContext) GetBlockHeaderEnabledChains(chainID int64) (lightclienttypes.HeaderSupportedChain, bool) { + a.mu.RLock() + defer a.mu.RUnlock() + + for _, flags := range a.blockHeaderEnabledChains { + if flags.ChainId == chainID { + return flags, true + } + } + + return lightclienttypes.HeaderSupportedChain{}, false +} + +// Update updates zetacore context and params for all chains +// this must be the ONLY function that writes to zetacore context +func (a *AppContext) Update( + keygen *observertypes.Keygen, + newChains []chains.Chain, + evmChainParams map[int64]*observertypes.ChainParams, + btcChainParams *observertypes.ChainParams, + tssPubKey string, + crosschainFlags observertypes.CrosschainFlags, + blockHeaderEnabledChains []lightclienttypes.HeaderSupportedChain, + init bool, +) { + // Ignore whatever order zetacore organizes chain list in state + sort.SliceStable(newChains, func(i, j int) bool { + return newChains[i].ChainId < newChains[j].ChainId + }) + + if len(newChains) == 0 { + a.logger.Warn().Msg("UpdateChainParams: No chains enabled in ZeroCore") + } + + a.mu.Lock() + defer a.mu.Unlock() + + // Add some warnings if chain list changes at runtime + if !init && !chainsEqual(a.chainsEnabled, newChains) { + a.logger.Warn(). + Interface("chains.current", a.chainsEnabled). + Interface("chains.new", newChains). + Msg("UpdateChainParams: ChainsEnabled changed at runtime!") + } + + if keygen != nil { + a.keygen = *keygen + } + + a.chainsEnabled = newChains + a.crosschainFlags = crosschainFlags + a.blockHeaderEnabledChains = blockHeaderEnabledChains + + // update chain params for bitcoin if it has config in file + if a.bitcoinChainParams != nil && btcChainParams != nil { + a.bitcoinChainParams = btcChainParams + } + + // update core params for evm chains we have configs in file + for _, params := range evmChainParams { + _, found := a.evmChainParams[params.ChainId] + if !found { + continue + } + a.evmChainParams[params.ChainId] = params + } + + if tssPubKey != "" { + a.currentTssPubkey = tssPubKey + } +} + +func chainsEqual(a []chains.Chain, b []chains.Chain) bool { + if len(a) != len(b) { + return false + } + + for i, left := range a { + right := b[i] + + if left.ChainId != right.ChainId || left.ChainName != right.ChainName { + return false + } + } + + return true +} diff --git a/zetaclient/context/app_context.go b/zetaclient/context/app_context.go deleted file mode 100644 index ffdfa05604..0000000000 --- a/zetaclient/context/app_context.go +++ /dev/null @@ -1,46 +0,0 @@ -// Package context provides global app context for ZetaClient -package context - -import ( - "github.com/zeta-chain/zetacore/pkg/chains" - "github.com/zeta-chain/zetacore/zetaclient/config" -) - -// AppContext contains global app structs like config, zetacore context and logger -type AppContext struct { - coreContext *ZetacoreContext - config config.Config -} - -// NewAppContext creates and returns new AppContext -func NewAppContext( - coreContext *ZetacoreContext, - config config.Config, -) *AppContext { - return &AppContext{ - coreContext: coreContext, - config: config, - } -} - -// Config returns the config of the app -func (a AppContext) Config() config.Config { - return a.config -} - -// ZetacoreContext returns the context for ZetaChain -func (a AppContext) ZetacoreContext() *ZetacoreContext { - return a.coreContext -} - -// GetBTCChainAndConfig returns btc chain and config if enabled -func (a AppContext) GetBTCChainAndConfig() (chains.Chain, config.BTCConfig, bool) { - btcConfig, configEnabled := a.Config().GetBTCConfig() - btcChain, _, paramsEnabled := a.coreContext.GetBTCChainParams() - - if !configEnabled || !paramsEnabled { - return chains.Chain{}, config.BTCConfig{}, false - } - - return btcChain, btcConfig, true -} diff --git a/zetaclient/context/app_context_test.go b/zetaclient/context/app_context_test.go deleted file mode 100644 index 960b2b7c5a..0000000000 --- a/zetaclient/context/app_context_test.go +++ /dev/null @@ -1 +0,0 @@ -package context_test diff --git a/zetaclient/context/zetacore_context_test.go b/zetaclient/context/app_test.go similarity index 55% rename from zetaclient/context/zetacore_context_test.go rename to zetaclient/context/app_test.go index d8117e124b..99b56c7d88 100644 --- a/zetaclient/context/zetacore_context_test.go +++ b/zetaclient/context/app_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/rs/zerolog" - "github.com/rs/zerolog/log" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/pkg/chains" @@ -12,68 +12,40 @@ import ( lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/config" - context "github.com/zeta-chain/zetacore/zetaclient/context" + "github.com/zeta-chain/zetacore/zetaclient/context" ) -func getTestCoreContext( - evmChain chains.Chain, - evmChainParams *observertypes.ChainParams, - ccFlags observertypes.CrosschainFlags, - headerSupportedChains []lightclienttypes.HeaderSupportedChain, -) *context.ZetacoreContext { - // create config - cfg := config.NewConfig() - cfg.EVMChainConfigs[evmChain.ChainId] = config.EVMConfig{ - Chain: evmChain, - } - // create zetacore context - coreContext := context.NewZetacoreContext(cfg) - evmChainParamsMap := make(map[int64]*observertypes.ChainParams) - evmChainParamsMap[evmChain.ChainId] = evmChainParams - - // feed chain params - coreContext.Update( - &observertypes.Keygen{}, - []chains.Chain{evmChain}, - evmChainParamsMap, - nil, - "", - ccFlags, - headerSupportedChains, - true, - zerolog.Logger{}, +func TestNew(t *testing.T) { + var ( + testCfg = config.NewConfig() + logger = zerolog.Nop() ) - return coreContext -} -func TestNewZetaCoreContext(t *testing.T) { t.Run("should create new zetacore context with empty config", func(t *testing.T) { - testCfg := config.NewConfig() - - zetaContext := context.NewZetacoreContext(testCfg) - require.NotNil(t, zetaContext) + appContext := context.New(testCfg, logger) + require.NotNil(t, appContext) // assert keygen - keyGen := zetaContext.GetKeygen() + keyGen := appContext.GetKeygen() require.Equal(t, observertypes.Keygen{}, keyGen) // assert enabled chains - require.Empty(t, len(zetaContext.GetEnabledChains())) + require.Empty(t, len(appContext.GetEnabledChains())) // assert external chains - require.Empty(t, len(zetaContext.GetEnabledExternalChains())) + require.Empty(t, len(appContext.GetEnabledExternalChains())) // assert current tss pubkey - require.Equal(t, "", zetaContext.GetCurrentTssPubkey()) + require.Equal(t, "", appContext.GetCurrentTssPubKey()) // assert btc chain params - chain, btcChainParams, btcChainParamsFound := zetaContext.GetBTCChainParams() + chain, btcChainParams, btcChainParamsFound := appContext.GetBTCChainParams() require.Equal(t, chains.Chain{}, chain) require.False(t, btcChainParamsFound) require.Nil(t, btcChainParams) // assert evm chain params - allEVMChainParams := zetaContext.GetAllEVMChainParams() + allEVMChainParams := appContext.GetAllEVMChainParams() require.Empty(t, allEVMChainParams) }) @@ -86,11 +58,11 @@ func TestNewZetaCoreContext(t *testing.T) { } // create zetacore context with 0 chain id - zetaContext := context.NewZetacoreContext(testCfg) - require.NotNil(t, zetaContext) + appContext := context.New(testCfg, logger) + require.NotNil(t, appContext) // assert btc chain params - chain, btcChainParams, btcChainParamsFound := zetaContext.GetBTCChainParams() + chain, btcChainParams, btcChainParamsFound := appContext.GetBTCChainParams() require.Equal(t, chains.Chain{}, chain) require.False(t, btcChainParamsFound) require.Nil(t, btcChainParams) @@ -112,20 +84,20 @@ func TestNewZetaCoreContext(t *testing.T) { }, }, } - zetaContext := context.NewZetacoreContext(testCfg) - require.NotNil(t, zetaContext) + appContext := context.New(testCfg, logger) + require.NotNil(t, appContext) // assert evm chain params - allEVMChainParams := zetaContext.GetAllEVMChainParams() + allEVMChainParams := appContext.GetAllEVMChainParams() require.Equal(t, 2, len(allEVMChainParams)) require.Equal(t, &observertypes.ChainParams{}, allEVMChainParams[1]) require.Equal(t, &observertypes.ChainParams{}, allEVMChainParams[2]) - evmChainParams1, found := zetaContext.GetEVMChainParams(1) + evmChainParams1, found := appContext.GetEVMChainParams(1) require.True(t, found) require.Equal(t, &observertypes.ChainParams{}, evmChainParams1) - evmChainParams2, found := zetaContext.GetEVMChainParams(2) + evmChainParams2, found := appContext.GetEVMChainParams(2) require.True(t, found) require.Equal(t, &observertypes.ChainParams{}, evmChainParams2) }) @@ -138,17 +110,20 @@ func TestNewZetaCoreContext(t *testing.T) { RPCHost: "test host", RPCParams: "test params", } - zetaContext := context.NewZetacoreContext(testCfg) - require.NotNil(t, zetaContext) + appContext := context.New(testCfg, logger) + require.NotNil(t, appContext) }) } -func TestUpdateZetacoreContext(t *testing.T) { - t.Run("should update zetacore context after being created from empty config", func(t *testing.T) { - testCfg := config.NewConfig() +func TestAppContextUpdate(t *testing.T) { + var ( + testCfg = config.NewConfig() + logger = zerolog.Nop() + ) - zetaContext := context.NewZetacoreContext(testCfg) - require.NotNil(t, zetaContext) + t.Run("should update zetacore context after being created from empty config", func(t *testing.T) { + appContext := context.New(testCfg, logger) + require.NotNil(t, appContext) keyGenToUpdate := observertypes.Keygen{ Status: observertypes.KeygenStatus_KeyGenSuccess, @@ -183,7 +158,7 @@ func TestUpdateZetacoreContext(t *testing.T) { verificationFlags := sample.HeaderSupportedChains() require.NotNil(t, crosschainFlags) - zetaContext.Update( + appContext.Update( &keyGenToUpdate, enabledChainsToUpdate, evmChainParamsToUpdate, @@ -192,36 +167,35 @@ func TestUpdateZetacoreContext(t *testing.T) { *crosschainFlags, verificationFlags, false, - log.Logger, ) // assert keygen updated - keyGen := zetaContext.GetKeygen() + keyGen := appContext.GetKeygen() require.Equal(t, keyGenToUpdate, keyGen) // assert enabled chains updated - require.Equal(t, enabledChainsToUpdate, zetaContext.GetEnabledChains()) + require.Equal(t, enabledChainsToUpdate, appContext.GetEnabledChains()) // assert enabled external chains - require.Equal(t, enabledChainsToUpdate[0:2], zetaContext.GetEnabledExternalChains()) + require.Equal(t, enabledChainsToUpdate[0:2], appContext.GetEnabledExternalChains()) // assert current tss pubkey updated - require.Equal(t, tssPubKeyToUpdate, zetaContext.GetCurrentTssPubkey()) + require.Equal(t, tssPubKeyToUpdate, appContext.GetCurrentTssPubKey()) // assert btc chain params still empty because they were not specified in config - chain, btcChainParams, btcChainParamsFound := zetaContext.GetBTCChainParams() + chain, btcChainParams, btcChainParamsFound := appContext.GetBTCChainParams() require.Equal(t, chains.Chain{}, chain) require.False(t, btcChainParamsFound) require.Nil(t, btcChainParams) // assert evm chain params still empty because they were not specified in config - allEVMChainParams := zetaContext.GetAllEVMChainParams() + allEVMChainParams := appContext.GetAllEVMChainParams() require.Empty(t, allEVMChainParams) - ccFlags := zetaContext.GetCrossChainFlags() + ccFlags := appContext.GetCrossChainFlags() require.Equal(t, *crosschainFlags, ccFlags) - verFlags := zetaContext.GetAllHeaderEnabledChains() + verFlags := appContext.GetAllHeaderEnabledChains() require.Equal(t, verificationFlags, verFlags) }) @@ -250,8 +224,8 @@ func TestUpdateZetacoreContext(t *testing.T) { RPCParams: "test params", } - zetaContext := context.NewZetacoreContext(testCfg) - require.NotNil(t, zetaContext) + appContext := context.New(testCfg, logger) + require.NotNil(t, appContext) keyGenToUpdate := observertypes.Keygen{ Status: observertypes.KeygenStatus_KeyGenSuccess, @@ -284,7 +258,7 @@ func TestUpdateZetacoreContext(t *testing.T) { crosschainFlags := sample.CrosschainFlags() verificationFlags := sample.HeaderSupportedChains() require.NotNil(t, crosschainFlags) - zetaContext.Update( + appContext.Update( &keyGenToUpdate, enabledChainsToUpdate, evmChainParamsToUpdate, @@ -293,41 +267,40 @@ func TestUpdateZetacoreContext(t *testing.T) { *crosschainFlags, verificationFlags, false, - log.Logger, ) // assert keygen updated - keyGen := zetaContext.GetKeygen() + keyGen := appContext.GetKeygen() require.Equal(t, keyGenToUpdate, keyGen) // assert enabled chains updated - require.Equal(t, enabledChainsToUpdate, zetaContext.GetEnabledChains()) + require.Equal(t, enabledChainsToUpdate, appContext.GetEnabledChains()) // assert current tss pubkey updated - require.Equal(t, tssPubKeyToUpdate, zetaContext.GetCurrentTssPubkey()) + require.Equal(t, tssPubKeyToUpdate, appContext.GetCurrentTssPubKey()) // assert btc chain params - chain, btcChainParams, btcChainParamsFound := zetaContext.GetBTCChainParams() + chain, btcChainParams, btcChainParamsFound := appContext.GetBTCChainParams() require.Equal(t, testBtcChain, chain) require.True(t, btcChainParamsFound) require.Equal(t, btcChainParamsToUpdate, btcChainParams) // assert evm chain params - allEVMChainParams := zetaContext.GetAllEVMChainParams() + allEVMChainParams := appContext.GetAllEVMChainParams() require.Equal(t, evmChainParamsToUpdate, allEVMChainParams) - evmChainParams1, found := zetaContext.GetEVMChainParams(1) + evmChainParams1, found := appContext.GetEVMChainParams(1) require.True(t, found) require.Equal(t, evmChainParamsToUpdate[1], evmChainParams1) - evmChainParams2, found := zetaContext.GetEVMChainParams(2) + evmChainParams2, found := appContext.GetEVMChainParams(2) require.True(t, found) require.Equal(t, evmChainParamsToUpdate[2], evmChainParams2) - ccFlags := zetaContext.GetCrossChainFlags() + ccFlags := appContext.GetCrossChainFlags() require.Equal(t, ccFlags, *crosschainFlags) - verFlags := zetaContext.GetAllHeaderEnabledChains() + verFlags := appContext.GetAllHeaderEnabledChains() require.Equal(t, verFlags, verificationFlags) }, ) @@ -344,22 +317,22 @@ func TestIsOutboundObservationEnabled(t *testing.T) { } t.Run("should return true if chain is supported and outbound flag is enabled", func(t *testing.T) { - coreCTX := getTestCoreContext(evmChain, chainParams, ccFlags, verificationFlags) - require.True(t, context.IsOutboundObservationEnabled(coreCTX, *chainParams)) + appContext := makeAppContext(evmChain, chainParams, ccFlags, verificationFlags) + + require.True(t, appContext.IsOutboundObservationEnabled(*chainParams)) }) t.Run("should return false if chain is not supported yet", func(t *testing.T) { - paramsUnsupported := &observertypes.ChainParams{ - ChainId: evmChain.ChainId, - IsSupported: false, - } - coreCTXUnsupported := getTestCoreContext(evmChain, paramsUnsupported, ccFlags, verificationFlags) - require.False(t, context.IsOutboundObservationEnabled(coreCTXUnsupported, *paramsUnsupported)) + paramsUnsupported := &observertypes.ChainParams{ChainId: evmChain.ChainId, IsSupported: false} + appContextUnsupported := makeAppContext(evmChain, paramsUnsupported, ccFlags, verificationFlags) + + require.False(t, appContextUnsupported.IsOutboundObservationEnabled(*paramsUnsupported)) }) t.Run("should return false if outbound flag is disabled", func(t *testing.T) { flagsDisabled := ccFlags flagsDisabled.IsOutboundEnabled = false - coreCTXDisabled := getTestCoreContext(evmChain, chainParams, flagsDisabled, verificationFlags) - require.False(t, context.IsOutboundObservationEnabled(coreCTXDisabled, *chainParams)) + coreContextDisabled := makeAppContext(evmChain, chainParams, flagsDisabled, verificationFlags) + + require.False(t, coreContextDisabled.IsOutboundObservationEnabled(*chainParams)) }) } @@ -374,21 +347,179 @@ func TestIsInboundObservationEnabled(t *testing.T) { } t.Run("should return true if chain is supported and inbound flag is enabled", func(t *testing.T) { - coreCTX := getTestCoreContext(evmChain, chainParams, ccFlags, verificationFlags) - require.True(t, context.IsInboundObservationEnabled(coreCTX, *chainParams)) + appContext := makeAppContext(evmChain, chainParams, ccFlags, verificationFlags) + + require.True(t, appContext.IsInboundObservationEnabled(*chainParams)) }) + t.Run("should return false if chain is not supported yet", func(t *testing.T) { - paramsUnsupported := &observertypes.ChainParams{ - ChainId: evmChain.ChainId, - IsSupported: false, - } - coreCTXUnsupported := getTestCoreContext(evmChain, paramsUnsupported, ccFlags, verificationFlags) - require.False(t, context.IsInboundObservationEnabled(coreCTXUnsupported, *paramsUnsupported)) + paramsUnsupported := &observertypes.ChainParams{ChainId: evmChain.ChainId, IsSupported: false} + appContextUnsupported := makeAppContext(evmChain, paramsUnsupported, ccFlags, verificationFlags) + + require.False(t, appContextUnsupported.IsInboundObservationEnabled(*paramsUnsupported)) }) + t.Run("should return false if inbound flag is disabled", func(t *testing.T) { flagsDisabled := ccFlags flagsDisabled.IsInboundEnabled = false - coreCTXDisabled := getTestCoreContext(evmChain, chainParams, flagsDisabled, verificationFlags) - require.False(t, context.IsInboundObservationEnabled(coreCTXDisabled, *chainParams)) + appContextDisabled := makeAppContext(evmChain, chainParams, flagsDisabled, verificationFlags) + + require.False(t, appContextDisabled.IsInboundObservationEnabled(*chainParams)) }) } + +func TestGetBTCChainAndConfig(t *testing.T) { + logger := zerolog.Nop() + + emptyConfig := config.NewConfig() + nonEmptyConfig := config.New() + + assertEmpty := func(t *testing.T, chain chains.Chain, btcConfig config.BTCConfig, enabled bool) { + assert.Empty(t, chain) + assert.Empty(t, btcConfig) + assert.False(t, enabled) + } + + for _, tt := range []struct { + name string + cfg config.Config + setup func(app *context.AppContext) + assert func(t *testing.T, chain chains.Chain, btcConfig config.BTCConfig, enabled bool) + }{ + { + name: "no btc config", + cfg: emptyConfig, + setup: nil, + assert: assertEmpty, + }, + { + name: "btc config exists, but not chain params are set", + cfg: nonEmptyConfig, + setup: nil, + assert: assertEmpty, + }, + { + name: "btc config exists but chain is invalid", + cfg: nonEmptyConfig, + setup: func(app *context.AppContext) { + app.Update( + &observertypes.Keygen{}, + []chains.Chain{}, + nil, + &observertypes.ChainParams{ChainId: 123}, + "", + observertypes.CrosschainFlags{}, + nil, + true, + ) + }, + assert: assertEmpty, + }, + { + name: "btc config exists and chain params are set", + cfg: nonEmptyConfig, + setup: func(app *context.AppContext) { + app.Update( + &observertypes.Keygen{}, + []chains.Chain{}, + nil, + &observertypes.ChainParams{ChainId: chains.BitcoinMainnet.ChainId}, + "", + observertypes.CrosschainFlags{}, + nil, + true, + ) + }, + assert: func(t *testing.T, chain chains.Chain, btcConfig config.BTCConfig, enabled bool) { + assert.Equal(t, chains.BitcoinMainnet.ChainId, chain.ChainId) + assert.Equal(t, "smoketest", btcConfig.RPCUsername) + assert.True(t, enabled) + }, + }, + } { + t.Run(tt.name, func(t *testing.T) { + // ARRANGE + // Given app context + appContext := context.New(tt.cfg, logger) + + // And optional setup + if tt.setup != nil { + tt.setup(appContext) + } + + // ACT + chain, btcConfig, enabled := appContext.GetBTCChainAndConfig() + + // ASSERT + tt.assert(t, chain, btcConfig, enabled) + }) + } +} + +func TestGetBlockHeaderEnabledChains(t *testing.T) { + // ARRANGE + // Given app config + appContext := context.New(config.New(), zerolog.Nop()) + + // That was eventually updated + appContext.Update( + &observertypes.Keygen{}, + []chains.Chain{}, + nil, + &observertypes.ChainParams{ChainId: chains.BitcoinMainnet.ChainId}, + "", + observertypes.CrosschainFlags{}, + []lightclienttypes.HeaderSupportedChain{ + {ChainId: 1, Enabled: true}, + }, + true, + ) + + // ACT #1 (found) + chain, found := appContext.GetBlockHeaderEnabledChains(1) + + // ASSERT #1 + assert.True(t, found) + assert.Equal(t, int64(1), chain.ChainId) + assert.True(t, chain.Enabled) + + // ACT #2 (not found) + chain, found = appContext.GetBlockHeaderEnabledChains(2) + + // ASSERT #2 + assert.False(t, found) + assert.Empty(t, chain) +} + +func makeAppContext( + evmChain chains.Chain, + evmChainParams *observertypes.ChainParams, + ccFlags observertypes.CrosschainFlags, + headerSupportedChains []lightclienttypes.HeaderSupportedChain, +) *context.AppContext { + // create config + cfg := config.NewConfig() + logger := zerolog.Nop() + cfg.EVMChainConfigs[evmChain.ChainId] = config.EVMConfig{ + Chain: evmChain, + } + + // create zetacore context + coreContext := context.New(cfg, logger) + evmChainParamsMap := make(map[int64]*observertypes.ChainParams) + evmChainParamsMap[evmChain.ChainId] = evmChainParams + + // feed chain params + coreContext.Update( + &observertypes.Keygen{}, + []chains.Chain{evmChain}, + evmChainParamsMap, + nil, + "", + ccFlags, + headerSupportedChains, + true, + ) + + return coreContext +} diff --git a/zetaclient/context/context.go b/zetaclient/context/context.go new file mode 100644 index 0000000000..3f8b6177fa --- /dev/null +++ b/zetaclient/context/context.go @@ -0,0 +1,26 @@ +package context + +import ( + goctx "context" + + "github.com/pkg/errors" +) + +type appContextKey struct{} + +var ErrNotSet = errors.New("AppContext is not set in the context.Context") + +// WithAppContext applied AppContext to standard Go context.Context. +func WithAppContext(ctx goctx.Context, app *AppContext) goctx.Context { + return goctx.WithValue(ctx, appContextKey{}, app) +} + +// FromContext extracts AppContext from context.Context +func FromContext(ctx goctx.Context) (*AppContext, error) { + app, ok := ctx.Value(appContextKey{}).(*AppContext) + if !ok || app == nil { + return nil, ErrNotSet + } + + return app, nil +} diff --git a/zetaclient/context/context_test.go b/zetaclient/context/context_test.go new file mode 100644 index 0000000000..5bde4596d6 --- /dev/null +++ b/zetaclient/context/context_test.go @@ -0,0 +1,40 @@ +package context_test + +import ( + goctx "context" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/zeta-chain/zetacore/zetaclient/config" + "github.com/zeta-chain/zetacore/zetaclient/context" +) + +func TestFromContext(t *testing.T) { + // ARRANGE #1 + // Given default go ctx + ctx := goctx.Background() + + // ACT #1 + // Extract App + _, err := context.FromContext(ctx) + + // ASSERT #1 + assert.ErrorIs(t, err, context.ErrNotSet) + + // ARRANGE #2 + // Given basic app + app := context.New(config.NewConfig(), zerolog.Nop()) + + // That is included in the ctx + ctx = context.WithAppContext(ctx, app) + + // ACT #2 + app2, err := context.FromContext(ctx) + + // ASSERT #2 + assert.NoError(t, err) + assert.NotNil(t, app2) + assert.Equal(t, app, app2) + assert.NotEmpty(t, app.Config()) +} diff --git a/zetaclient/context/zetacore_context.go b/zetaclient/context/zetacore_context.go deleted file mode 100644 index 17d4cc5c3d..0000000000 --- a/zetaclient/context/zetacore_context.go +++ /dev/null @@ -1,253 +0,0 @@ -package context - -import ( - "sort" - "sync" - - "github.com/rs/zerolog" - - "github.com/zeta-chain/zetacore/pkg/chains" - lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" - "github.com/zeta-chain/zetacore/zetaclient/config" -) - -// ZetacoreContext contains zetacore context params -// these are initialized and updated at runtime at every height -type ZetacoreContext struct { - coreContextLock *sync.RWMutex - keygen observertypes.Keygen - chainsEnabled []chains.Chain - evmChainParams map[int64]*observertypes.ChainParams - bitcoinChainParams *observertypes.ChainParams - currentTssPubkey string - crosschainFlags observertypes.CrosschainFlags - - // blockHeaderEnabledChains is used to store the list of chains that have block header verification enabled - // All chains in this list will have Enabled flag set to true - blockHeaderEnabledChains []lightclienttypes.HeaderSupportedChain -} - -// NewZetacoreContext creates and returns new ZetacoreContext -// it is initializing chain params from provided config -func NewZetacoreContext(cfg config.Config) *ZetacoreContext { - evmChainParams := make(map[int64]*observertypes.ChainParams) - for _, e := range cfg.EVMChainConfigs { - evmChainParams[e.Chain.ChainId] = &observertypes.ChainParams{} - } - - var bitcoinChainParams *observertypes.ChainParams - _, found := cfg.GetBTCConfig() - if found { - bitcoinChainParams = &observertypes.ChainParams{} - } - - return &ZetacoreContext{ - coreContextLock: new(sync.RWMutex), - chainsEnabled: []chains.Chain{}, - evmChainParams: evmChainParams, - bitcoinChainParams: bitcoinChainParams, - crosschainFlags: observertypes.CrosschainFlags{}, - blockHeaderEnabledChains: []lightclienttypes.HeaderSupportedChain{}, - } -} - -// GetKeygen returns the current keygen -func (c *ZetacoreContext) GetKeygen() observertypes.Keygen { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - - var copiedPubkeys []string - if c.keygen.GranteePubkeys != nil { - copiedPubkeys = make([]string, len(c.keygen.GranteePubkeys)) - copy(copiedPubkeys, c.keygen.GranteePubkeys) - } - - return observertypes.Keygen{ - Status: c.keygen.Status, - GranteePubkeys: copiedPubkeys, - BlockNumber: c.keygen.BlockNumber, - } -} - -// GetCurrentTssPubkey returns the current tss pubkey -func (c *ZetacoreContext) GetCurrentTssPubkey() string { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - return c.currentTssPubkey -} - -// GetEnabledChains returns all enabled chains including zetachain -func (c *ZetacoreContext) GetEnabledChains() []chains.Chain { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - - copiedChains := make([]chains.Chain, len(c.chainsEnabled)) - copy(copiedChains, c.chainsEnabled) - return copiedChains -} - -// GetEnabledExternalChains returns all enabled external chains -func (c *ZetacoreContext) GetEnabledExternalChains() []chains.Chain { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - - externalChains := make([]chains.Chain, 0) - for _, chain := range c.chainsEnabled { - if chain.IsExternal { - externalChains = append(externalChains, chain) - } - } - return externalChains -} - -// GetEVMChainParams returns chain params for a specific EVM chain -func (c *ZetacoreContext) GetEVMChainParams(chainID int64) (*observertypes.ChainParams, bool) { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - - evmChainParams, found := c.evmChainParams[chainID] - return evmChainParams, found -} - -// GetAllEVMChainParams returns all chain params for EVM chains -func (c *ZetacoreContext) GetAllEVMChainParams() map[int64]*observertypes.ChainParams { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - - // deep copy evm chain params - copied := make(map[int64]*observertypes.ChainParams, len(c.evmChainParams)) - for chainID, evmConfig := range c.evmChainParams { - copied[chainID] = &observertypes.ChainParams{} - *copied[chainID] = *evmConfig - } - return copied -} - -// GetBTCChainParams returns (chain, chain params, found) for bitcoin chain -func (c *ZetacoreContext) GetBTCChainParams() (chains.Chain, *observertypes.ChainParams, bool) { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - - if c.bitcoinChainParams == nil { // bitcoin is not enabled - return chains.Chain{}, nil, false - } - - chain := chains.GetChainFromChainID(c.bitcoinChainParams.ChainId) - if chain == nil { - return chains.Chain{}, nil, false - } - - return *chain, c.bitcoinChainParams, true -} - -// GetCrossChainFlags returns crosschain flags -func (c *ZetacoreContext) GetCrossChainFlags() observertypes.CrosschainFlags { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - return c.crosschainFlags -} - -// GetAllHeaderEnabledChains returns all verification flags -func (c *ZetacoreContext) GetAllHeaderEnabledChains() []lightclienttypes.HeaderSupportedChain { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - return c.blockHeaderEnabledChains -} - -// GetBlockHeaderEnabledChains checks if block header verification is enabled for a specific chain -func (c *ZetacoreContext) GetBlockHeaderEnabledChains(chainID int64) (lightclienttypes.HeaderSupportedChain, bool) { - c.coreContextLock.RLock() - defer c.coreContextLock.RUnlock() - for _, flags := range c.blockHeaderEnabledChains { - if flags.ChainId == chainID { - return flags, true - } - } - return lightclienttypes.HeaderSupportedChain{}, false -} - -// Update updates zetacore context and params for all chains -// this must be the ONLY function that writes to zetacore context -func (c *ZetacoreContext) Update( - keygen *observertypes.Keygen, - newChains []chains.Chain, - evmChainParams map[int64]*observertypes.ChainParams, - btcChainParams *observertypes.ChainParams, - tssPubKey string, - crosschainFlags observertypes.CrosschainFlags, - blockHeaderEnabledChains []lightclienttypes.HeaderSupportedChain, - init bool, - logger zerolog.Logger, -) { - c.coreContextLock.Lock() - defer c.coreContextLock.Unlock() - - // Ignore whatever order zetacore organizes chain list in state - sort.SliceStable(newChains, func(i, j int) bool { - return newChains[i].ChainId < newChains[j].ChainId - }) - - if len(newChains) == 0 { - logger.Warn().Msg("UpdateChainParams: No chains enabled in ZeroCore") - } - - // Add some warnings if chain list changes at runtime - if !init { - if len(c.chainsEnabled) != len(newChains) { - logger.Warn().Msgf( - "UpdateChainParams: ChainsEnabled changed at runtime!! current: %v, new: %v", - c.chainsEnabled, - newChains, - ) - } else { - for i, chain := range newChains { - if chain != c.chainsEnabled[i] { - logger.Warn().Msgf( - "UpdateChainParams: ChainsEnabled changed at runtime!! current: %v, new: %v", - c.chainsEnabled, - newChains, - ) - } - } - } - } - - if keygen != nil { - c.keygen = *keygen - } - - c.chainsEnabled = newChains - c.crosschainFlags = crosschainFlags - c.blockHeaderEnabledChains = blockHeaderEnabledChains - - // update chain params for bitcoin if it has config in file - if c.bitcoinChainParams != nil && btcChainParams != nil { - c.bitcoinChainParams = btcChainParams - } - - // update core params for evm chains we have configs in file - for _, params := range evmChainParams { - _, found := c.evmChainParams[params.ChainId] - if !found { - continue - } - c.evmChainParams[params.ChainId] = params - } - - if tssPubKey != "" { - c.currentTssPubkey = tssPubKey - } -} - -// IsOutboundObservationEnabled returns true if the chain is supported and outbound flag is enabled -func IsOutboundObservationEnabled(c *ZetacoreContext, chainParams observertypes.ChainParams) bool { - flags := c.GetCrossChainFlags() - return chainParams.IsSupported && flags.IsOutboundEnabled -} - -// IsInboundObservationEnabled returns true if the chain is supported and inbound flag is enabled -func IsInboundObservationEnabled(c *ZetacoreContext, chainParams observertypes.ChainParams) bool { - flags := c.GetCrossChainFlags() - return chainParams.IsSupported && flags.IsInboundEnabled -} diff --git a/zetaclient/orchestrator/orchestrator.go b/zetaclient/orchestrator/orchestrator.go index 2c5ea2d2de..348baac514 100644 --- a/zetaclient/orchestrator/orchestrator.go +++ b/zetaclient/orchestrator/orchestrator.go @@ -127,7 +127,7 @@ func (oc *Orchestrator) MonitorCore(appContext *context.AppContext) error { // GetUpdatedSigner returns signer with updated chain parameters func (oc *Orchestrator) GetUpdatedSigner( - coreContext *context.ZetacoreContext, + appContext *context.AppContext, chainID int64, ) (interfaces.ChainSigner, error) { signer, found := oc.signerMap[chainID] @@ -136,7 +136,7 @@ func (oc *Orchestrator) GetUpdatedSigner( } // update EVM signer parameters only. BTC signer doesn't use chain parameters for now. if chains.IsEVMChain(chainID) { - evmParams, found := coreContext.GetEVMChainParams(chainID) + evmParams, found := appContext.GetEVMChainParams(chainID) if found { // update zeta connector and ERC20 custody addresses zetaConnectorAddress := ethcommon.HexToAddress(evmParams.GetConnectorContractAddress()) @@ -158,7 +158,7 @@ func (oc *Orchestrator) GetUpdatedSigner( // GetUpdatedChainObserver returns chain observer with updated chain parameters func (oc *Orchestrator) GetUpdatedChainObserver( - coreContext *context.ZetacoreContext, + appContext *context.AppContext, chainID int64, ) (interfaces.ChainObserver, error) { observer, found := oc.observerMap[chainID] @@ -168,14 +168,14 @@ func (oc *Orchestrator) GetUpdatedChainObserver( // update chain observer chain parameters curParams := observer.GetChainParams() if chains.IsEVMChain(chainID) { - evmParams, found := coreContext.GetEVMChainParams(chainID) + evmParams, found := appContext.GetEVMChainParams(chainID) if found && !observertypes.ChainParamsEqual(curParams, *evmParams) { observer.SetChainParams(*evmParams) oc.logger.Std.Info().Msgf( "updated chain params for chainID %d, new params: %v", chainID, *evmParams) } } else if chains.IsBitcoinChain(chainID) { - _, btcParams, found := coreContext.GetBTCChainParams() + _, btcParams, found := appContext.GetBTCChainParams() if found && !observertypes.ChainParamsEqual(curParams, *btcParams) { observer.SetChainParams(*btcParams) @@ -281,8 +281,7 @@ func (oc *Orchestrator) StartCctxScheduler(appContext *context.AppContext) { metrics.HotKeyBurnRate.Set(float64(oc.ts.HotKeyBurnRate.GetBurnRate().Int64())) // get supported external chains - coreContext := appContext.ZetacoreContext() - externalChains := coreContext.GetEnabledExternalChains() + externalChains := appContext.GetEnabledExternalChains() // query pending cctxs across all external chains within rate limit cctxMap, err := oc.GetPendingCctxsWithinRatelimit(externalChains) @@ -300,21 +299,21 @@ func (oc *Orchestrator) StartCctxScheduler(appContext *context.AppContext) { } // update chain parameters for signer and chain observer - signer, err := oc.GetUpdatedSigner(coreContext, c.ChainId) + signer, err := oc.GetUpdatedSigner(appContext, c.ChainId) if err != nil { oc.logger.Std.Error(). Err(err). Msgf("StartCctxScheduler: GetUpdatedSigner failed for chain %d", c.ChainId) continue } - ob, err := oc.GetUpdatedChainObserver(coreContext, c.ChainId) + ob, err := oc.GetUpdatedChainObserver(appContext, c.ChainId) if err != nil { oc.logger.Std.Error(). Err(err). Msgf("StartCctxScheduler: GetUpdatedChainObserver failed for chain %d", c.ChainId) continue } - if !context.IsOutboundObservationEnabled(coreContext, ob.GetChainParams()) { + if !appContext.IsOutboundObservationEnabled(ob.GetChainParams()) { continue } diff --git a/zetaclient/orchestrator/orchestrator_test.go b/zetaclient/orchestrator/orchestrator_test.go index 131dc29656..69930bdbcf 100644 --- a/zetaclient/orchestrator/orchestrator_test.go +++ b/zetaclient/orchestrator/orchestrator_test.go @@ -53,10 +53,10 @@ func MockOrchestrator( return orchestrator } -func CreateCoreContext( +func CreateAppContext( evmChain, btcChain chains.Chain, evmChainParams, btcChainParams *observertypes.ChainParams, -) *context.ZetacoreContext { +) *context.AppContext { // new config cfg := config.NewConfig() cfg.EVMChainConfigs[evmChain.ChainId] = config.EVMConfig{ @@ -66,14 +66,14 @@ func CreateCoreContext( RPCHost: "localhost", } // new zetacore context - coreContext := context.NewZetacoreContext(cfg) + appContext := context.New(cfg, zerolog.Nop()) evmChainParamsMap := make(map[int64]*observertypes.ChainParams) evmChainParamsMap[evmChain.ChainId] = evmChainParams ccFlags := sample.CrosschainFlags() verificationFlags := sample.HeaderSupportedChains() // feed chain params - coreContext.Update( + appContext.Update( &observertypes.Keygen{}, []chains.Chain{evmChain, btcChain}, evmChainParamsMap, @@ -82,9 +82,8 @@ func CreateCoreContext( *ccFlags, verificationFlags, true, - zerolog.Logger{}, ) - return coreContext + return appContext } func Test_GetUpdatedSigner(t *testing.T) { @@ -107,14 +106,14 @@ func Test_GetUpdatedSigner(t *testing.T) { t.Run("signer should not be found", func(t *testing.T) { orchestrator := MockOrchestrator(t, nil, evmChain, btcChain, evmChainParams, btcChainParams) - context := CreateCoreContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) + context := CreateAppContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) // BSC signer should not be found _, err := orchestrator.GetUpdatedSigner(context, chains.BscMainnet.ChainId) require.ErrorContains(t, err, "signer not found") }) t.Run("should be able to update connector and erc20 custody address", func(t *testing.T) { orchestrator := MockOrchestrator(t, nil, evmChain, btcChain, evmChainParams, btcChainParams) - context := CreateCoreContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) + context := CreateAppContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) // update signer with new connector and erc20 custody address signer, err := orchestrator.GetUpdatedSigner(context, evmChain.ChainId) require.NoError(t, err) @@ -172,14 +171,14 @@ func Test_GetUpdatedChainObserver(t *testing.T) { t.Run("evm chain observer should not be found", func(t *testing.T) { orchestrator := MockOrchestrator(t, nil, evmChain, btcChain, evmChainParams, btcChainParams) - coreContext := CreateCoreContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) + coreContext := CreateAppContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) // BSC chain observer should not be found _, err := orchestrator.GetUpdatedChainObserver(coreContext, chains.BscMainnet.ChainId) require.ErrorContains(t, err, "chain observer not found") }) t.Run("chain params in evm chain observer should be updated successfully", func(t *testing.T) { orchestrator := MockOrchestrator(t, nil, evmChain, btcChain, evmChainParams, btcChainParams) - coreContext := CreateCoreContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) + coreContext := CreateAppContext(evmChain, btcChain, evmChainParamsNew, btcChainParams) // update evm chain observer with new chain params chainOb, err := orchestrator.GetUpdatedChainObserver(coreContext, evmChain.ChainId) require.NoError(t, err) @@ -188,14 +187,14 @@ func Test_GetUpdatedChainObserver(t *testing.T) { }) t.Run("btc chain observer should not be found", func(t *testing.T) { orchestrator := MockOrchestrator(t, nil, evmChain, btcChain, evmChainParams, btcChainParams) - coreContext := CreateCoreContext(btcChain, btcChain, evmChainParams, btcChainParamsNew) + coreContext := CreateAppContext(btcChain, btcChain, evmChainParams, btcChainParamsNew) // BTC testnet chain observer should not be found _, err := orchestrator.GetUpdatedChainObserver(coreContext, chains.BitcoinTestnet.ChainId) require.ErrorContains(t, err, "chain observer not found") }) t.Run("chain params in btc chain observer should be updated successfully", func(t *testing.T) { orchestrator := MockOrchestrator(t, nil, evmChain, btcChain, evmChainParams, btcChainParams) - coreContext := CreateCoreContext(btcChain, btcChain, evmChainParams, btcChainParamsNew) + coreContext := CreateAppContext(btcChain, btcChain, evmChainParams, btcChainParamsNew) // update btc chain observer with new chain params chainOb, err := orchestrator.GetUpdatedChainObserver(coreContext, btcChain.ChainId) require.NoError(t, err) diff --git a/zetaclient/supplychecker/zeta_supply_checker.go b/zetaclient/supplychecker/zeta_supply_checker.go index 10ad1d5db1..4c16ffd203 100644 --- a/zetaclient/supplychecker/zeta_supply_checker.go +++ b/zetaclient/supplychecker/zeta_supply_checker.go @@ -23,7 +23,7 @@ import ( // ZetaSupplyChecker is a utility to check the total supply of Zeta tokens type ZetaSupplyChecker struct { - coreContext *context.ZetacoreContext + appContext *context.AppContext evmClient map[int64]*ethclient.Client zetaClient *zetacore.Client ticker *clienttypes.DynamicTicker @@ -52,8 +52,8 @@ func NewZetaSupplyChecker( logger: logger.With(). Str("module", "ZetaSupplyChecker"). Logger(), - coreContext: appContext.ZetacoreContext(), - zetaClient: zetaClient, + appContext: appContext, + zetaClient: zetaClient, } for _, evmConfig := range appContext.Config().GetAllEVMConfigs() { @@ -120,7 +120,7 @@ func (zs *ZetaSupplyChecker) Stop() { func (zs *ZetaSupplyChecker) CheckZetaTokenSupply() error { externalChainTotalSupply := sdkmath.ZeroInt() for _, chain := range zs.externalEvmChain { - externalEvmChainParams, ok := zs.coreContext.GetEVMChainParams(chain.ChainId) + externalEvmChainParams, ok := zs.appContext.GetEVMChainParams(chain.ChainId) if !ok { return fmt.Errorf("externalEvmChainParams not found for chain id %d", chain.ChainId) } @@ -146,7 +146,7 @@ func (zs *ZetaSupplyChecker) CheckZetaTokenSupply() error { externalChainTotalSupply = externalChainTotalSupply.Add(totalSupplyInt) } - evmChainParams, ok := zs.coreContext.GetEVMChainParams(zs.ethereumChain.ChainId) + evmChainParams, ok := zs.appContext.GetEVMChainParams(zs.ethereumChain.ChainId) if !ok { return fmt.Errorf("eth config not found for chain id %d", zs.ethereumChain.ChainId) } diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 08d48833db..e00252db55 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -109,7 +109,7 @@ func NewTSS( newTss := TSS{ Server: server, Keys: make(map[string]*Key), - CurrentPubkey: appContext.ZetacoreContext().GetCurrentTssPubkey(), + CurrentPubkey: appContext.GetCurrentTssPubKey(), logger: logger, ZetacoreClient: client, KeysignsTracker: NewKeysignsTracker(logger), diff --git a/zetaclient/zetacore/client.go b/zetaclient/zetacore/client.go index 4443316a4a..140520fe11 100644 --- a/zetaclient/zetacore/client.go +++ b/zetaclient/zetacore/client.go @@ -193,11 +193,7 @@ func (c *Client) WaitForZetacoreToCreateBlocks() error { // UpdateZetacoreContext updates zetacore context // zetacore stores zetacore context for all clients -func (c *Client) UpdateZetacoreContext( - coreContext *context.ZetacoreContext, - init bool, - sampledLogger zerolog.Logger, -) error { +func (c *Client) UpdateZetacoreContext(coreContext *context.AppContext, init bool, sampledLogger zerolog.Logger) error { bn, err := c.GetBlockHeight() if err != nil { return fmt.Errorf("failed to get zetablock height: %w", err) @@ -278,7 +274,6 @@ func (c *Client) UpdateZetacoreContext( crosschainFlags, blockHeaderEnabledChains, init, - c.logger, ) return nil diff --git a/zetaclient/zetacore/tx.go b/zetaclient/zetacore/tx.go index 0a28336b04..1cf1c5c40e 100644 --- a/zetaclient/zetacore/tx.go +++ b/zetaclient/zetacore/tx.go @@ -185,7 +185,7 @@ func (c *Client) ZetacoreContextUpdater(appContext *appcontext.AppContext) { select { case <-ticker.C: c.logger.Debug().Msg("Running Updater") - err := c.UpdateZetacoreContext(appContext.ZetacoreContext(), false, sampledLogger) + err := c.UpdateZetacoreContext(appContext, false, sampledLogger) if err != nil { c.logger.Err(err).Msg("ZetacoreContextUpdater failed to update config") } diff --git a/zetaclient/zetacore/tx_test.go b/zetaclient/zetacore/tx_test.go index 1d00f33d1a..fbf9a10e7d 100644 --- a/zetaclient/zetacore/tx_test.go +++ b/zetaclient/zetacore/tx_test.go @@ -333,9 +333,9 @@ func TestZetacore_UpdateZetacoreContext(t *testing.T) { t.Run("zetacore update success", func(t *testing.T) { cfg := config.NewConfig() - coreCtx := context.NewZetacoreContext(cfg) + appContext := context.New(cfg, zerolog.Nop()) zetacoreBroadcast = MockBroadcast - err := client.UpdateZetacoreContext(coreCtx, false, zerolog.Logger{}) + err := client.UpdateZetacoreContext(appContext, false, zerolog.Logger{}) require.NoError(t, err) }) }