diff --git a/e2e/e2etests/helper_bitcoin.go b/e2e/e2etests/helper_bitcoin.go index 338cd7027f..09cb4ded96 100644 --- a/e2e/e2etests/helper_bitcoin.go +++ b/e2e/e2etests/helper_bitcoin.go @@ -64,11 +64,7 @@ func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) } // mine blocks if testing on regnet - var stop chan struct{} - isRegnet := chains.IsBitcoinRegnet(r.GetBitcoinChainID()) - if isRegnet { - stop = r.MineBlocks() - } + stop := r.MineBlocksIfLocalBitcoin() // withdraw 'amount' of BTC from ZRC20 to BTC address tx, err = r.BTCZRC20.Withdraw(r.ZEVMAuth, []byte(to.EncodeAddress()), amount) @@ -81,7 +77,7 @@ func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) } // mine 10 blocks to confirm the withdraw tx - _, err = r.BtcRPCClient.GenerateToAddress(10, to, nil) + _, err = r.GenerateToAddressIfLocalBitcoin(10, to) if err != nil { panic(err) } @@ -118,9 +114,7 @@ func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) } // stop mining - if isRegnet { - stop <- struct{}{} - } + stop() return rawTx } diff --git a/e2e/e2etests/test_bitcoin_withdraw_invalid_address.go b/e2e/e2etests/test_bitcoin_withdraw_invalid_address.go index 8d4698f489..aaa0725a99 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_invalid_address.go +++ b/e2e/e2etests/test_bitcoin_withdraw_invalid_address.go @@ -9,7 +9,6 @@ import ( "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" - "github.com/zeta-chain/zetacore/pkg/chains" ) func TestBitcoinWithdrawToInvalidAddress(r *runner.E2ERunner, args []string) { @@ -47,11 +46,7 @@ func withdrawToInvalidAddress(r *runner.E2ERunner, amount *big.Int) { } // mine blocks if testing on regnet - var stop chan struct{} - isRegnet := chains.IsBitcoinRegnet(r.GetBitcoinChainID()) - if isRegnet { - stop = r.MineBlocks() - } + stop := r.MineBlocksIfLocalBitcoin() // withdraw amount provided as test arg BTC from ZRC20 to BTC legacy address // the address "1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3" is for mainnet, not regtest @@ -65,7 +60,5 @@ func withdrawToInvalidAddress(r *runner.E2ERunner, amount *big.Int) { } // stop mining - if isRegnet { - stop <- struct{}{} - } + stop() } diff --git a/e2e/e2etests/test_bitcoin_withdraw_multiple.go b/e2e/e2etests/test_bitcoin_withdraw_multiple.go index 683b9fb0f9..b9271b8b91 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_multiple.go +++ b/e2e/e2etests/test_bitcoin_withdraw_multiple.go @@ -42,7 +42,7 @@ package e2etests // go func() { // for { // time.Sleep(3 * time.Second) -// _, err = r.BtcRPCClient.GenerateToAddress(1, r.BTCDeployerAddress, nil) +// _, err = r.GenerateToAddressIfLocalBitcoin(1, r.BTCDeployerAddress) // if err != nil { // panic(err) // } @@ -64,7 +64,7 @@ package e2etests // if receipt.Status != 1 { // panic(fmt.Errorf("withdraw receipt status is not 1")) // } -// _, err = r.BtcRPCClient.GenerateToAddress(10, r.BTCDeployerAddress, nil) +// _, err = r.GenerateToAddressIfLocalBitcoin(10, r.BTCDeployerAddress) // if err != nil { // panic(err) // } diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index cb74056710..358e9ba7d7 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -10,7 +10,6 @@ import ( "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" - "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -110,17 +109,13 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { } // mine 10 blocks to confirm the outbound tx - _, err = r.BtcRPCClient.GenerateToAddress(10, r.BTCDeployerAddress, nil) + _, err = r.GenerateToAddressIfLocalBitcoin(10, r.BTCDeployerAddress) if err != nil { panic(err) } // mine blocks if testing on regnet - var stop chan struct{} - isRegnet := chains.IsBitcoinRegnet(r.GetBitcoinChainID()) - if isRegnet { - stop = r.MineBlocks() - } + stop := r.MineBlocksIfLocalBitcoin() // cctx1 index acts like the inboundHash for the second cctx (the one that withdraws BTC) cctx2 := utils.WaitCctxMinedByInboundHash(r.Ctx, cctx1.Index, r.CctxClient, r.Logger, r.CctxTimeout) @@ -137,8 +132,8 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.Logger.Info("cctx2 outbound tx hash %s", cctx2.GetCurrentOutboundParam().Hash) r.Logger.Info("******* Second test: BTC -> ERC20ZRC20") - // list deployer utxos that have at least 1 BTC - utxos, err := r.ListDeployerUTXOs(1.0) + // list deployer utxos + utxos, err := r.ListDeployerUTXOs() if err != nil { panic(err) } @@ -151,14 +146,7 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { memo = append(r.ZEVMSwapAppAddr.Bytes(), memo...) r.Logger.Info("memo length %d", len(memo)) - txID, err := r.SendToTSSFromDeployerWithMemo( - r.BTCTSSAddress, - 0.01, - utxos[0:1], - r.BtcRPCClient, - memo, - r.BTCDeployerAddress, - ) + txID, err := r.SendToTSSFromDeployerWithMemo(0.01, utxos[0:1], memo) if err != nil { panic(err) } @@ -200,14 +188,7 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.Logger.Info("memo length %d", len(memo)) amount := 0.1 - txid, err := r.SendToTSSFromDeployerWithMemo( - r.BTCTSSAddress, - amount, - utxos[1:2], - r.BtcRPCClient, - memo, - r.BTCDeployerAddress, - ) + txid, err := r.SendToTSSFromDeployerWithMemo(amount, utxos[1:2], memo) if err != nil { panic(err) } @@ -239,7 +220,5 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { } // stop mining - if isRegnet { - stop <- struct{}{} - } + stop() } diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index 9143926d06..493a7a3fd3 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -9,7 +9,6 @@ import ( "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" @@ -29,8 +28,8 @@ import ( var blockHeaderBTCTimeout = 5 * time.Minute -// ListDeployerUTXOs list the deployer's UTXOs that have at least `minAmount` -func (runner *E2ERunner) ListDeployerUTXOs(minAmount float64) ([]btcjson.ListUnspentResult, error) { +// ListDeployerUTXOs list the deployer's UTXOs +func (runner *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error) { // query UTXOs from node utxos, err := runner.BtcRPCClient.ListUnspentMinMaxAddresses( 1, @@ -41,23 +40,15 @@ func (runner *E2ERunner) ListDeployerUTXOs(minAmount float64) ([]btcjson.ListUns return nil, err } - // filter UTXOs by `minAmount` - filtered := []btcjson.ListUnspentResult{} - for _, utxo := range utxos { - if utxo.Amount >= minAmount { - filtered = append(filtered, utxo) - } - } - - return filtered, nil + return utxos, nil } // DepositBTCWithAmount deposits BTC on ZetaChain with a specific amount func (runner *E2ERunner) DepositBTCWithAmount(amount float64) (txHash *chainhash.Hash) { runner.Logger.Print("⏳ depositing BTC into ZEVM") - // list deployer utxos that have at least 1 BTC - utxos, err := runner.ListDeployerUTXOs(1.0) + // list deployer utxos + utxos, err := runner.ListDeployerUTXOs() if err != nil { panic(err) } @@ -72,7 +63,11 @@ func (runner *E2ERunner) DepositBTCWithAmount(amount float64) (txHash *chainhash } if spendableAmount < amount { - panic(fmt.Errorf("not enough spendable BTC to run the test; have %f", spendableAmount)) + panic(fmt.Errorf( + "not enough spendable BTC to run the test; have %f, require %f", + spendableAmount, + amount, + )) } runner.Logger.Info("ListUnspent:") @@ -81,13 +76,7 @@ func (runner *E2ERunner) DepositBTCWithAmount(amount float64) (txHash *chainhash runner.Logger.Info("Now sending two txs to TSS address...") amount = amount + zetabitcoin.DefaultDepositorFee - txHash, err = runner.SendToTSSFromDeployerToDeposit( - runner.BTCTSSAddress, - amount, - utxos, - runner.BtcRPCClient, - runner.BTCDeployerAddress, - ) + txHash, err = runner.SendToTSSFromDeployerToDeposit(amount, utxos) if err != nil { panic(err) } @@ -104,8 +93,8 @@ func (runner *E2ERunner) DepositBTC(testHeader bool) { runner.Logger.Print("✅ BTC deposited in %s", time.Since(startTime)) }() - // list deployer utxos that have at least 1 BTC - utxos, err := runner.ListDeployerUTXOs(1.0) + // list deployer utxos + utxos, err := runner.ListDeployerUTXOs() if err != nil { panic(err) } @@ -133,38 +122,19 @@ func (runner *E2ERunner) DepositBTC(testHeader bool) { // send two transactions to the TSS address amount1 := 1.1 + zetabitcoin.DefaultDepositorFee - txHash1, err := runner.SendToTSSFromDeployerToDeposit( - runner.BTCTSSAddress, - amount1, - utxos[:2], - runner.BtcRPCClient, - runner.BTCDeployerAddress, - ) + txHash1, err := runner.SendToTSSFromDeployerToDeposit(amount1, utxos[:2]) if err != nil { panic(err) } amount2 := 0.05 + zetabitcoin.DefaultDepositorFee - txHash2, err := runner.SendToTSSFromDeployerToDeposit( - runner.BTCTSSAddress, - amount2, - utxos[2:4], - runner.BtcRPCClient, - runner.BTCDeployerAddress, - ) + txHash2, err := runner.SendToTSSFromDeployerToDeposit(amount2, utxos[2:4]) if err != nil { panic(err) } // send a donation to the TSS address to compensate for the funds minted automatically during pool creation // and prevent accounting errors - _, err = runner.SendToTSSFromDeployerWithMemo( - runner.BTCTSSAddress, - 0.11, - utxos[4:5], - runner.BtcRPCClient, - []byte(constant.DonationMessage), - runner.BTCDeployerAddress, - ) + _, err = runner.SendToTSSFromDeployerWithMemo(0.11, utxos[4:5], []byte(constant.DonationMessage)) if err != nil { panic(err) } @@ -201,31 +171,22 @@ func (runner *E2ERunner) DepositBTC(testHeader bool) { } } -func (runner *E2ERunner) SendToTSSFromDeployerToDeposit( - to btcutil.Address, - amount float64, - inputUTXOs []btcjson.ListUnspentResult, - btc *rpcclient.Client, - btcDeployerAddress *btcutil.AddressWitnessPubKeyHash, -) (*chainhash.Hash, error) { - return runner.SendToTSSFromDeployerWithMemo( - to, - amount, - inputUTXOs, - btc, - runner.DeployerAddress.Bytes(), - btcDeployerAddress, - ) +func (runner *E2ERunner) SendToTSSFromDeployerToDeposit(amount float64, inputUTXOs []btcjson.ListUnspentResult) ( + *chainhash.Hash, + error, +) { + return runner.SendToTSSFromDeployerWithMemo(amount, inputUTXOs, runner.DeployerAddress.Bytes()) } func (runner *E2ERunner) SendToTSSFromDeployerWithMemo( - to btcutil.Address, amount float64, inputUTXOs []btcjson.ListUnspentResult, - btcRPC *rpcclient.Client, memo []byte, - btcDeployerAddress *btcutil.AddressWitnessPubKeyHash, ) (*chainhash.Hash, error) { + btcRPC := runner.BtcRPCClient + to := runner.BTCTSSAddress + btcDeployerAddress := runner.BTCDeployerAddress + // prepare inputs inputs := make([]btcjson.TransactionInput, len(inputUTXOs)) inputSats := btcutil.Amount(0) @@ -312,7 +273,7 @@ func (runner *E2ERunner) SendToTSSFromDeployerWithMemo( panic(err) } runner.Logger.Info("txid: %+v", txid) - _, err = btcRPC.GenerateToAddress(6, btcDeployerAddress, nil) + _, err = runner.GenerateToAddressIfLocalBitcoin(6, btcDeployerAddress) if err != nil { panic(err) } @@ -359,17 +320,36 @@ func (runner *E2ERunner) GetBitcoinChainID() int64 { return chainID } -// MineBlocks mines blocks on the BTC chain at a rate of 1 blocks every 5 seconds +// IsLocalBitcoin returns true if the runner is running on a local bitcoin network +func (runner *E2ERunner) IsLocalBitcoin() bool { + return runner.BitcoinParams.Name == chains.BitcoinRegnetParams.Name +} + +// GenerateToAddressIfLocalBitcoin generates blocks to an address if the runner is interacting +// with a local bitcoin network +func (runner *E2ERunner) GenerateToAddressIfLocalBitcoin( + numBlocks int64, + address btcutil.Address, +) ([]*chainhash.Hash, error) { + // if not local bitcoin network, do nothing + if runner.IsLocalBitcoin() { + return runner.BtcRPCClient.GenerateToAddress(numBlocks, address, nil) + } + return nil, nil +} + +// MineBlocksIfLocalBitcoin mines blocks on the local BTC chain at a rate of 1 blocks every 5 seconds // and returns a channel that can be used to stop the mining -func (runner *E2ERunner) MineBlocks() chan struct{} { - stop := make(chan struct{}) +// If the chain is not local, the function does nothing +func (runner *E2ERunner) MineBlocksIfLocalBitcoin() func() { + stopChan := make(chan struct{}) go func() { for { select { - case <-stop: + case <-stopChan: return default: - _, err := runner.BtcRPCClient.GenerateToAddress(1, runner.BTCDeployerAddress, nil) + _, err := runner.GenerateToAddressIfLocalBitcoin(1, runner.BTCDeployerAddress) if err != nil { panic(err) } @@ -377,7 +357,10 @@ func (runner *E2ERunner) MineBlocks() chan struct{} { } } }() - return stop + + return func() { + close(stopChan) + } } // ProveBTCTransaction proves that a BTC transaction is in a block header and that the block header is in ZetaChain diff --git a/e2e/runner/setup_bitcoin.go b/e2e/runner/setup_bitcoin.go index 5872fc4101..15af182915 100644 --- a/e2e/runner/setup_bitcoin.go +++ b/e2e/runner/setup_bitcoin.go @@ -34,12 +34,12 @@ func (runner *E2ERunner) SetupBitcoinAccount(initNetwork bool) { } // mine some blocks to get some BTC into the deployer address - _, err = runner.BtcRPCClient.GenerateToAddress(101, runner.BTCDeployerAddress, nil) + _, err = runner.GenerateToAddressIfLocalBitcoin(101, runner.BTCDeployerAddress) if err != nil { panic(err) } - _, err = runner.BtcRPCClient.GenerateToAddress(4, runner.BTCDeployerAddress, nil) + _, err = runner.GenerateToAddressIfLocalBitcoin(4, runner.BTCDeployerAddress) if err != nil { panic(err) }