diff --git a/changelog.md b/changelog.md index 1ecd4cdaa7..9d68531972 100644 --- a/changelog.md +++ b/changelog.md @@ -27,6 +27,7 @@ * [2867](https://github.com/zeta-chain/node/pull/2867) - skip precompiles test for tss migration * [2833](https://github.com/zeta-chain/node/pull/2833) - add e2e framework for TON blockchain * [2874](https://github.com/zeta-chain/node/pull/2874) - add support for multiple runs for precompile tests +* [2895](https://github.com/zeta-chain/node/pull/2895) - add e2e test for bitcoin deposit and call * [2894](https://github.com/zeta-chain/node/pull/2894) - increase gas limit for TSS vote tx ### Fixes diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 7e31d4a407..d84a4ba9a4 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -290,6 +290,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { bitcoinTests := []string{ e2etests.TestBitcoinDepositName, + e2etests.TestBitcoinDepositAndCallName, e2etests.TestBitcoinDepositRefundName, e2etests.TestBitcoinWithdrawSegWitName, e2etests.TestBitcoinWithdrawInvalidAddressName, diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index a33737eb41..dd9409e4cf 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -73,6 +73,7 @@ const ( */ TestBitcoinDepositName = "bitcoin_deposit" TestBitcoinDepositRefundName = "bitcoin_deposit_refund" + TestBitcoinDepositAndCallName = "bitcoin_deposit_and_call" TestBitcoinWithdrawSegWitName = "bitcoin_withdraw_segwit" TestBitcoinWithdrawTaprootName = "bitcoin_withdraw_taproot" TestBitcoinWithdrawMultipleName = "bitcoin_withdraw_multiple" @@ -451,6 +452,14 @@ var AllE2ETests = []runner.E2ETest{ }, TestBitcoinDeposit, ), + runner.NewE2ETest( + TestBitcoinDepositAndCallName, + "deposit Bitcoin into ZEVM and call a contract", + []runner.ArgDefinition{ + {Description: "amount in btc", DefaultValue: "0.001"}, + }, + TestBitcoinDepositAndCall, + ), runner.NewE2ETest( TestBitcoinDepositRefundName, "deposit Bitcoin into ZEVM; expect refund", []runner.ArgDefinition{ diff --git a/e2e/e2etests/test_bitcoin_deposit_call.go b/e2e/e2etests/test_bitcoin_deposit_call.go new file mode 100644 index 0000000000..0f1fd6dc91 --- /dev/null +++ b/e2e/e2etests/test_bitcoin_deposit_call.go @@ -0,0 +1,55 @@ +package e2etests + +import ( + "math/big" + + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/utils" + testcontract "github.com/zeta-chain/node/testutil/contracts" + crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" + zetabitcoin "github.com/zeta-chain/node/zetaclient/chains/bitcoin" +) + +func TestBitcoinDepositAndCall(r *runner.E2ERunner, args []string) { + // ARRANGE + // Given BTC address + r.SetBtcAddress(r.Name, false) + + // Given "Live" BTC network + stop := r.MineBlocksIfLocalBitcoin() + defer stop() + + // Given amount to send + require.Len(r, args, 1) + amount := parseFloat(r, args[0]) + amountTotal := amount + zetabitcoin.DefaultDepositorFee + + // Given a list of UTXOs + utxos, err := r.ListDeployerUTXOs() + require.NoError(r, err) + require.NotEmpty(r, utxos) + + // deploy an example contract in ZEVM + contractAddr, _, contract, err := testcontract.DeployExample(r.ZEVMAuth, r.ZEVMClient) + require.NoError(r, err) + r.Logger.Print("Bitcoin: Example contract deployed at: %s", contractAddr.String()) + + // ACT + // Send BTC to TSS address with a dummy memo + data := []byte("hello satoshi") + memo := append(contractAddr.Bytes(), data...) + txHash, err := r.SendToTSSFromDeployerWithMemo(amountTotal, utxos, memo) + require.NoError(r, err) + + // wait for the cctx to be mined + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, txHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.CCTX(*cctx, "bitcoin_deposit_and_call") + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) + + // check if example contract has been called, 'bar' value should be set to amount + amoutSats, err := zetabitcoin.GetSatoshis(amount) + require.NoError(r, err) + utils.MustHaveCalledExampleContract(r, contract, big.NewInt(amoutSats)) +} diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index f861e8ce8f..10596e7e98 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -198,8 +198,11 @@ func (r *E2ERunner) SendToTSSFromDeployerWithMemo( scriptPubkeys[i] = utxo.ScriptPubKey } + // use static fee 0.0005 BTC to calculate change feeSats := btcutil.Amount(0.0005 * btcutil.SatoshiPerBitcoin) - amountSats := btcutil.Amount(amount * btcutil.SatoshiPerBitcoin) + amountInt, err := zetabitcoin.GetSatoshis(amount) + require.NoError(r, err) + amountSats := btcutil.Amount(amountInt) change := inputSats - feeSats - amountSats if change < 0 {