From 5cfece2e56fdeda2bd95db7223c4aba4beffd38d Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 22 Sep 2023 14:26:04 -0400 Subject: [PATCH 1/9] add begin blocked deployemnts for mock mainent --- ...er_deploy_system_contracts_mock_mainnet.go | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts_mock_mainnet.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts_mock_mainnet.go index 44a45dacc9..26e43983e3 100644 --- a/x/fungible/keeper/begin_blocker_deploy_system_contracts_mock_mainnet.go +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts_mock_mainnet.go @@ -5,9 +5,91 @@ package keeper import ( "context" + "fmt" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/zeta-chain/zetacore/common" ) -func (k Keeper) BlockOneDeploySystemContracts(_ context.Context) error { +func (k Keeper) BlockOneDeploySystemContracts(goCtx context.Context) error { + ctx := sdk.UnwrapSDKContext(goCtx) + + // setup uniswap v2 factory + uniswapV2Factory, err := k.DeployUniswapV2Factory(ctx) + if err != nil { + return sdkerrors.Wrapf(err, "failed to DeployUniswapV2Factory") + } + ctx.EventManager().EmitEvent( + sdk.NewEvent(sdk.EventTypeMessage, + sdk.NewAttribute("UniswapV2Factory", uniswapV2Factory.String()), + ), + ) + + // setup WZETA contract + wzeta, err := k.DeployWZETA(ctx) + if err != nil { + return sdkerrors.Wrapf(err, "failed to DeployWZetaContract") + } + ctx.EventManager().EmitEvent( + sdk.NewEvent(sdk.EventTypeMessage, + sdk.NewAttribute("DeployWZetaContract", wzeta.String()), + ), + ) + + router, err := k.DeployUniswapV2Router02(ctx, uniswapV2Factory, wzeta) + if err != nil { + return sdkerrors.Wrapf(err, "failed to DeployUniswapV2Router02") + } + ctx.EventManager().EmitEvent( + sdk.NewEvent(sdk.EventTypeMessage, + sdk.NewAttribute("DeployUniswapV2Router02", router.String()), + ), + ) + + connector, err := k.DeployConnectorZEVM(ctx, wzeta) + if err != nil { + return sdkerrors.Wrapf(err, "failed to DeployConnectorZEVM") + } + ctx.EventManager().EmitEvent( + sdk.NewEvent(sdk.EventTypeMessage, + sdk.NewAttribute("DeployConnectorZEVM", connector.String()), + ), + ) + ctx.Logger().Info("Deployed Connector ZEVM at " + connector.String()) + + SystemContractAddress, err := k.DeploySystemContract(ctx, wzeta, uniswapV2Factory, router) + if err != nil { + return sdkerrors.Wrapf(err, "failed to SystemContractAddress") + } + ctx.EventManager().EmitEvent( + sdk.NewEvent(sdk.EventTypeMessage, + sdk.NewAttribute("SystemContractAddress", SystemContractAddress.String()), + ), + ) + + // set the system contract + system, _ := k.GetSystemContract(ctx) + system.SystemContract = SystemContractAddress.String() + k.SetSystemContract(ctx, system) + //err = k.SetGasPrice(ctx, big.NewInt(1337), big.NewInt(1)) + if err != nil { + return err + } + _, err = k.SetupChainGasCoinAndPool(ctx, common.EthChain().ChainId, "ETH", "ETH", 18) + if err != nil { + return errorsmod.Wrapf(err, fmt.Sprintf("failed to setupChainGasCoinAndPool for %s", common.EthChain().ChainName)) + } + + _, err = k.SetupChainGasCoinAndPool(ctx, common.BscMainnetChain().ChainId, "BNB", "BNB", 18) + if err != nil { + return errorsmod.Wrapf(err, fmt.Sprintf("failed to setupChainGasCoinAndPool for %s", common.BscMainnetChain().ChainName)) + } + _, err = k.SetupChainGasCoinAndPool(ctx, common.BtcMainnetChain().ChainId, "BTC", "BTC", 8) + if err != nil { + return errorsmod.Wrapf(err, fmt.Sprintf("failed to setupChainGasCoinAndPool for %s", common.BtcMainnetChain().ChainName)) + } return nil } func (k Keeper) TestUpdateSystemContractAddress(_ context.Context) error { From 4ab084381d0b825abbe393e3a43d270763f8ca15 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Mon, 25 Sep 2023 19:38:53 -0500 Subject: [PATCH 2/9] panic when telemetry server does not start --- cmd/zetaclientd/start.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index f6fda1b60f..f6684c87c5 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -134,6 +134,7 @@ func start(_ *cobra.Command, _ []string) error { err := telemetryServer.Start() if err != nil { startLogger.Error().Err(err).Msg("telemetryServer error") + panic("telemetryServer error") } }() From 329b172ea76144bfecf40dd22ab8ab6c9e4d3d4c Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Mon, 9 Oct 2023 10:47:56 -0500 Subject: [PATCH 3/9] report bitcoin fee in sat/byte instead of stas/KB --- zetaclient/bitcoin_client.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index c2a306ff32..1be3c61f63 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -456,7 +456,8 @@ func (ob *BitcoinChainClient) PostGasPrice() error { return fmt.Errorf("error getting gas price: %s", feeResult.Errors) } gasPrice := big.NewFloat(0) - gasPriceU64, _ := gasPrice.Mul(big.NewFloat(*feeResult.FeeRate), big.NewFloat(1e8)).Uint64() + // feerate from RPC is BTC/KB, convert it to satoshi/byte + gasPriceU64, _ := gasPrice.Mul(big.NewFloat(*feeResult.FeeRate), big.NewFloat(1e5)).Uint64() bn, err := ob.rpcClient.GetBlockCount() if err != nil { return err @@ -467,8 +468,6 @@ func (ob *BitcoinChainClient) PostGasPrice() error { return err } _ = zetaHash - //ob.logger.WatchGasPrice.Debug().Msgf("PostGasPrice zeta tx: %s", zetaHash) - _ = feeResult return nil } From 2bb0665df9dd387c34046a8cbd5ec1d778db2b94 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Mon, 9 Oct 2023 11:03:50 -0500 Subject: [PATCH 4/9] compensate for the low gaslimit on BTC --- zetaclient/bitcoin_client.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 1be3c61f63..2e8c2fd766 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -457,7 +457,9 @@ func (ob *BitcoinChainClient) PostGasPrice() error { } gasPrice := big.NewFloat(0) // feerate from RPC is BTC/KB, convert it to satoshi/byte - gasPriceU64, _ := gasPrice.Mul(big.NewFloat(*feeResult.FeeRate), big.NewFloat(1e5)).Uint64() + // FIXME: in zetacore the gaslimit(vsize in BTC) is 100 which is too low for a typical outbound tx + // until we fix the gaslimit in BTC, we need to multiply the feerate by 20 to make sure the tx is confirmed + gasPriceU64, _ := gasPrice.Mul(big.NewFloat(*feeResult.FeeRate), big.NewFloat(20*1e5)).Uint64() bn, err := ob.rpcClient.GetBlockCount() if err != nil { return err From 22f91079fb1670e51d08eb184b47bad6064c25f1 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Tue, 10 Oct 2023 10:23:47 -0500 Subject: [PATCH 5/9] fix: Mock mainnet begin block deployment fix btc duplicate payment (#1259) * special handling to avoid duplicate payment on bitcoin outbound nonce 0 * use cctx amount instead of txResult's amount because it's not available in bitcoin mainnet --------- Co-authored-by: charliec --- zetaclient/bitcoin_client.go | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 2e8c2fd766..166c968c8b 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -344,15 +344,24 @@ func (ob *BitcoinChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64 res, included := ob.includedTxResults[outTxID] ob.mu.Unlock() + // Get original cctx parameters + params, err := ob.GetPendingCctxParams(nonce) + if err != nil { + ob.logger.ObserveOutTx.Info().Msgf("IsSendOutTxProcessed: can't find pending cctx for nonce %d", nonce) + return false, false, err + } + if !included { if !broadcasted { return false, false, nil } - // Get original cctx parameters - params, err := ob.GetPendingCctxParams(nonce) - if err != nil { - ob.logger.ObserveOutTx.Info().Msgf("IsSendOutTxProcessed: can't find pending cctx for nonce %d", nonce) - return false, false, nil + // If the broadcasted outTx is nonce 0, just wait for inclusion and don't schedule more keysign + // Schedule more than one keysign for nonce 0 can lead to duplicate payments. + // One purpose of nonce mark UTXO is to avoid duplicate payment based on the fact that Bitcoin + // prevents double spending of same UTXO. However, for nonce 0, we don't have a prior nonce (e.g., -1) + // for the signer to check against when making the payment. Signer treats nonce 0 as a special case in downstream code. + if nonce == 0 { + return true, false, nil } // Try including this outTx broadcasted by myself @@ -376,23 +385,13 @@ func (ob *BitcoinChainClient) IsSendOutTxProcessed(sendHash string, nonce uint64 ob.logger.ObserveOutTx.Info().Msgf("IsSendOutTxProcessed: checkNSaveIncludedTx succeeded for outTx %s", outTxID) } - var amount float64 - if res.Amount > 0 { - ob.logger.ObserveOutTx.Warn().Msg("IsSendOutTxProcessed: res.Amount > 0") - amount = res.Amount - } else if res.Amount == 0 { - ob.logger.ObserveOutTx.Error().Msg("IsSendOutTxProcessed: res.Amount == 0") - return false, false, nil - } else { - amount = -res.Amount - } - - amountInSat, _ := big.NewFloat(amount * 1e8).Int(nil) + // It's safe to use cctx's amount to post confirmation because it has already been verified in observeOutTx() + amountInSat := params.Amount.BigInt() if res.Confirmations < ob.ConfirmationsThreshold(amountInSat) { return true, false, nil } - logger.Debug().Msgf("Bitcoin outTx confirmed: txid %s, amount %f\n", res.TxID, res.Amount) + logger.Debug().Msgf("Bitcoin outTx confirmed: txid %s, amount %s\n", res.TxID, amountInSat.String()) zetaHash, err := ob.zetaClient.PostReceiveConfirmation( sendHash, res.TxID, From 70b94ff10188dad84433f78f71a07c9d13723fe6 Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Wed, 11 Oct 2023 09:49:07 -0500 Subject: [PATCH 6/9] fix: Mock mainnet begin block deployment fix btc duplicate payment (#1266) * special handling to avoid duplicate payment on bitcoin outbound nonce 0 * use cctx amount instead of txResult's amount because it's not available in bitcoin mainnet * mockmain bootstrap from double payment on nonce 0 --------- Co-authored-by: charliec --- zetaclient/bitcoin_client.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index fbb349f142..4d670f7f2b 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -682,6 +682,11 @@ func (ob *BitcoinChainClient) refreshPendingNonce() { // Set `test` flag to true in unit test to bypass query to zetacore func (ob *BitcoinChainClient) getOutTxidByNonce(nonce uint64, test bool) (string, error) { + // special case for nonce 0 to recover from duplicate payment incident + if nonce == 0 { + return "26aa6b32b7f16cc6671ac1419e91bac5fb78b5d24536df0da0120a3f75bf9116", nil + } + ob.mu.Lock() res, included := ob.includedTxResults[ob.GetTxID(nonce)] ob.mu.Unlock() From 5dd389caf8383b805bde4a825f08744c13ed0f0c Mon Sep 17 00:00:00 2001 From: charliec Date: Wed, 11 Oct 2023 12:08:42 -0500 Subject: [PATCH 7/9] revert hard coded outTx hash for nonce 0 --- zetaclient/bitcoin_client.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 48ca2de873..3b16a2d2b5 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -680,11 +680,6 @@ func (ob *BitcoinChainClient) refreshPendingNonce() { // Set `test` flag to true in unit test to bypass query to zetacore func (ob *BitcoinChainClient) getOutTxidByNonce(nonce uint64, test bool) (string, error) { - // special case for nonce 0 to recover from duplicate payment incident - if nonce == 0 { - return "26aa6b32b7f16cc6671ac1419e91bac5fb78b5d24536df0da0120a3f75bf9116", nil - } - ob.mu.Lock() res, included := ob.includedTxResults[ob.GetTxID(nonce)] ob.mu.Unlock() From c10fd2d7f263ad7772083d5a47475e5df04ab74f Mon Sep 17 00:00:00 2001 From: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> Date: Wed, 11 Oct 2023 16:38:09 -0500 Subject: [PATCH 8/9] removed division by 1000 in fee calculation (#1275) Co-authored-by: charliec --- zetaclient/btc_signer.go | 1 - 1 file changed, 1 deletion(-) diff --git a/zetaclient/btc_signer.go b/zetaclient/btc_signer.go index 07cf24df92..853507ce42 100644 --- a/zetaclient/btc_signer.go +++ b/zetaclient/btc_signer.go @@ -116,7 +116,6 @@ func (signer *BTCSigner) SignWithdrawTx(to *btcutil.AddressWitnessPubKeyHash, am // fee calculation fees := new(big.Int).Mul(big.NewInt(int64(txSize)), gasPrice) - fees.Div(fees, big.NewInt(bytesPerKB)) signer.logger.Info().Msgf("bitcoin outTx nonce %d gasPrice %s size %d fees %s", nonce, gasPrice.String(), txSize, fees.String()) // calculate remaining btc to TSS self From 9a65720e4b7f340ec22dd2e7070550fa3bbff489 Mon Sep 17 00:00:00 2001 From: brewmaster012 <88689859+brewmaster012@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:18:33 -0700 Subject: [PATCH 9/9] try to fix smoketest due to BTC ZRC20 audit --- contrib/localnet/orchestrator/smoketest/main.go | 2 +- zetaclient/bitcoin_client.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/localnet/orchestrator/smoketest/main.go b/contrib/localnet/orchestrator/smoketest/main.go index 9dd12669e0..7d01a5cadf 100644 --- a/contrib/localnet/orchestrator/smoketest/main.go +++ b/contrib/localnet/orchestrator/smoketest/main.go @@ -292,7 +292,7 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { smokeTest.CheckZRC20ReserveAndSupply() smokeTest.TestBitcoinWithdraw() - //smokeTest.CheckZRC20ReserveAndSupply() + smokeTest.CheckZRC20ReserveAndSupply() smokeTest.TestCrosschainSwap() smokeTest.CheckZRC20ReserveAndSupply() diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 4384086861..ece0c4e458 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -463,13 +463,13 @@ func (ob *BitcoinChainClient) WatchGasPrice() { } func (ob *BitcoinChainClient) PostGasPrice() error { - if ob.chain.ChainId == 18444 { //bitcoin regtest + if ob.chain.ChainId == 18444 { //bitcoin regtest; hardcode here since this RPC is not available on regtest bn, err := ob.rpcClient.GetBlockCount() if err != nil { return err } // #nosec G701 always in range - zetaHash, err := ob.zetaClient.PostGasPrice(ob.chain, 1000, "100", uint64(bn)) + zetaHash, err := ob.zetaClient.PostGasPrice(ob.chain, 1, "100", uint64(bn)) if err != nil { ob.logger.WatchGasPrice.Err(err).Msg("PostGasPrice:") return err