Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
8fae53a
minimum code refactor for bitcoin RBF
ws4charlie Jan 21, 2025
2481654
add changelog entry
ws4charlie Jan 21, 2025
111d703
add unit test for FeeRateToSatPerByte
ws4charlie Jan 21, 2025
37f4ebb
make changelog descriptive; rename specialHandleFeeRate as GetFeeRate…
ws4charlie Jan 21, 2025
e3f2bc6
renaming sample function; make switch case in PostGasPrice to estimat…
ws4charlie Jan 22, 2025
28bd97c
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Jan 22, 2025
009b55b
remove redundant variable description
ws4charlie Jan 22, 2025
09fb0ac
make AddWithdrawTxOutputs a one-line call
ws4charlie Jan 23, 2025
aeceb26
implementation of Bitcoin RBF transaction
ws4charlie Jan 23, 2025
6c8f9f4
switch to bitcoin-core image with mempool RPCs enabled
ws4charlie Jan 23, 2025
e193580
bitcoin RBF E2E test
ws4charlie Jan 23, 2025
a80bd91
add changelog entry
ws4charlie Jan 23, 2025
6803a7c
add changelog entry
ws4charlie Jan 23, 2025
fc6f9a4
update changelog
ws4charlie Jan 23, 2025
c2a52c0
improve RBF test waiting mechanism
ws4charlie Jan 25, 2025
c501cf2
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Jan 25, 2025
1d2afef
rename sample function BTCAddressP2WPKH
ws4charlie Jan 25, 2025
1033a91
remove unused test and comment
ws4charlie Jan 27, 2025
bccf7e9
Merge branch 'develop' into feat-bitcoin-RBF-zetaclient-refactor-minimum
ws4charlie Jan 28, 2025
25cdfc7
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Jan 28, 2025
199bf2e
use 1.5 as multiplier to send outbound txs so that we slightly make p…
ws4charlie Jan 28, 2025
c156321
Merge branch 'develop' into feat-bitcoin-RBF-zetaclient-implementation
ws4charlie Jan 28, 2025
209e270
disable RBF test by default; it require one-line code change
ws4charlie Jan 28, 2025
f4ab7a2
Merge branch 'develop' into feat-bitcoin-RBF-zetaclient-refactor-minimum
ws4charlie Jan 28, 2025
3f5087b
include coin type to error message; make code cleaner
ws4charlie Jan 28, 2025
c31020b
return error if failed to get signer address; add BTCPayToAddrScript …
ws4charlie Jan 28, 2025
58fd340
Update zetaclient/chains/bitcoin/signer/signer.go
ws4charlie Jan 28, 2025
0f0b9aa
remove redundant test functions; use testlog for unit test
ws4charlie Jan 28, 2025
54bb4de
create observer in test suite; use testlog package
ws4charlie Jan 28, 2025
93b3a38
add description to fee estimation formula
ws4charlie Jan 28, 2025
4f83fdb
use structured logs
ws4charlie Jan 29, 2025
6fd51dd
make AddTxInputs independent method
ws4charlie Jan 29, 2025
a69d58b
add comments to explain function arguments; improve error wrapping; c…
ws4charlie Jan 29, 2025
5c09d39
replace ifs with switch case; return original err without overwriting
ws4charlie Jan 29, 2025
c19fa2b
seems safe to remove panic recovery in FetchUTXOs
ws4charlie Jan 29, 2025
0d41413
move Telemetry update to the line before acquiring observer lock
ws4charlie Jan 29, 2025
c0a2a23
use testlog package
ws4charlie Jan 29, 2025
8644a33
use retry package for Bitcoin tx broadcasting; let SaveBroadcastedTx …
ws4charlie Jan 29, 2025
bf9b4c4
use named return values to make GetEstimatedFeeRate more readable
ws4charlie Jan 29, 2025
9600442
move utxo unit tests to utxos.go and improved unit tests
ws4charlie Jan 30, 2025
8040ac1
wrap RPC error in LoadLastBlockScanned
ws4charlie Jan 30, 2025
a64f738
move last scanned block to log field; use Opt function for test suite
ws4charlie Jan 30, 2025
bb95935
move values to log fields
ws4charlie Jan 30, 2025
84f4b5c
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Jan 30, 2025
13efedc
add unit test for FetchUTXOs
ws4charlie Jan 30, 2025
416bd03
add unit for SignWithdrawTx; use structured log
ws4charlie Jan 30, 2025
1b369ca
Merge branch 'develop' into feat-bitcoin-RBF-zetaclient-refactor-minimum
ws4charlie Jan 30, 2025
79db16e
avoid creating log field map and add log fields right on the logger
ws4charlie Jan 30, 2025
0349246
fix client.GetEstimatedFeeRate
swift1337 Jan 31, 2025
6e8f900
Fix loadBroadcastedTxMap
swift1337 Jan 31, 2025
8cddb38
Fix SelectedUTXOs
swift1337 Jan 31, 2025
01e50df
Fix log naming
swift1337 Jan 31, 2025
d556b7e
fix e2e logging
swift1337 Jan 31, 2025
4c6b5bb
Fix setPendingNonce
swift1337 Jan 31, 2025
ed986e0
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Jan 31, 2025
1df7b53
Merge branch 'feat-bitcoin-RBF-zetaclient-refactor-minimum' of https:…
ws4charlie Jan 31, 2025
3ab710e
don't use GasPriorityFee as it's always empty
ws4charlie Jan 31, 2025
f7e72cc
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Jan 31, 2025
3925b6e
Merge branch 'feat-bitcoin-RBF-zetaclient-refactor-minimum' of https:…
ws4charlie Feb 3, 2025
f3cfdb6
Merge branch 'develop' into feat-bitcoin-RBF-zetaclient-implementation
ws4charlie Feb 3, 2025
03d366c
check if fee rate is bumped or not in zetaclient
ws4charlie Feb 3, 2025
277bd1c
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Mar 18, 2025
f952848
revert a few renamings because we will continue to use one single BTC…
ws4charlie Mar 18, 2025
a50132e
remove the method OutboundFeeRateFromCCTXRate; add additional field i…
ws4charlie Mar 18, 2025
83c78d3
adjust fee bumper to use new fee rate fed by zetacore
ws4charlie Mar 19, 2025
5d8d57e
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Mar 19, 2025
1627f03
adjust SignRBFTx to work with local E2E test
ws4charlie Mar 19, 2025
3776e30
code clean up; improve comments
ws4charlie Mar 19, 2025
43cb65a
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Mar 19, 2025
592d93e
handle invalid gas priority fee explicitly
ws4charlie Mar 19, 2025
50f70ff
Merge branch 'develop' of https://github.com/zeta-chain/node into fea…
ws4charlie Apr 30, 2025
0b4a632
fix withdraw failure and unit tests
ws4charlie May 1, 2025
7e4cd78
rename GetLastStuckOutbound -> LastStuckOutbound; unexport SetLastStu…
ws4charlie May 1, 2025
ccd6533
remove IncreaseIntByPercent and use IncreaseUintByPercent instead
ws4charlie May 2, 2025
f94d6ae
use same signer package for unit tests
ws4charlie May 2, 2025
6f57fb5
unexport FetchFeeBumpInfo
ws4charlie May 2, 2025
851a53e
have GetTotalMempoolParentsSizeNFees return a struct; add function Is…
ws4charlie May 2, 2025
da87ab5
move timeout handling into context
ws4charlie May 2, 2025
3843eb8
have BumpTxFee return a result struct BumpResult
ws4charlie May 2, 2025
1b77a0d
unexport fee bumper fields
ws4charlie May 2, 2025
b6a4426
remove Live prefix from live tests as we already have the env flag to…
ws4charlie May 2, 2025
bbea857
wrap live tests function into test runners so IDE can identify the tests
ws4charlie May 2, 2025
30251f4
Merge branch 'feat-bitcoin-RBF-zetaclient-implementation' of https://…
ws4charlie May 4, 2025
a1b7761
add comment to the disabled Bitcoin RBF E2E test for clarity
ws4charlie May 5, 2025
75343be
Merge branch 'develop' of https://github.com/zeta-chain/node into E2E…
ws4charlie May 7, 2025
073181a
Merge branch 'develop' of https://github.com/zeta-chain/node into E2E…
ws4charlie May 7, 2025
1441ee2
disable Bitcoin rbf test
ws4charlie May 7, 2025
fc88b12
keep the new line for better indentation
ws4charlie May 7, 2025
c549770
sync changelog file
ws4charlie May 7, 2025
63eea64
add explanation why RBF test is disabled by default
ws4charlie May 8, 2025
f1a1ca5
improve naming; add more description to the RBF e2e test; make 'appro…
ws4charlie May 8, 2025
4f31236
add dependency to E2E test structure; inject dependency for Bitcoin R…
ws4charlie May 8, 2025
142e0a4
move helper func BTCWithdraw to a bitcoin runner method
ws4charlie May 13, 2025
4ed0e89
Merge branch 'develop' into E2E-test-bitcoin-RBF
ws4charlie May 13, 2025
42dea6e
Merge branch 'develop' into E2E-test-bitcoin-RBF
ws4charlie May 14, 2025
8de2a68
fix upgrade test failure in CI
ws4charlie May 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
* [3831](https://github.com/zeta-chain/node/pull/3831) - e2e tests for sui fungible token withdraw and call
* [3582](https://github.com/zeta-chain/node/pull/3852) - add solana to tss migration e2e tests
* [3866](https://github.com/zeta-chain/node/pull/3866) - add e2e test for upgrading sui gateway package
* [3417](https://github.com/zeta-chain/node/pull/3417) - add e2e test for the Bitcoin RBF (Replace-By-Fee) feature


### Refactor

Expand Down
24 changes: 19 additions & 5 deletions cmd/zetae2e/local/bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import (
"github.com/zeta-chain/node/testutil"
)

const (
testGroupDepositName = "btc_deposit"
testGroupWithdrawName = "btc_withdraw"
)

// startBitcoinTests starts Bitcoin related tests
func startBitcoinTests(
eg *errgroup.Group,
Expand Down Expand Up @@ -58,6 +63,9 @@ func startBitcoinTests(
e2etests.TestBitcoinWithdrawP2WSHName,
e2etests.TestBitcoinWithdrawMultipleName,
e2etests.TestBitcoinWithdrawRestrictedName,
// to run RBF test, change the constant 'minTxConfirmations' to 1 in the Bitcoin observer
// https://github.com/zeta-chain/node/blob/5c2a8ffbc702130fd9538b1cd7640d0e04d3e4f6/zetaclient/chains/bitcoin/observer/outbound.go#L27
//e2etests.TestBitcoinWithdrawRBFName,
}

if !light {
Expand Down Expand Up @@ -89,7 +97,7 @@ func bitcoinTestRoutines(
// initialize runner for deposit tests
account := conf.AdditionalAccounts.UserBitcoinDeposit
runnerDeposit := initBitcoinRunner(
"btc_deposit",
testGroupDepositName,
account,
conf,
deployerRunner,
Expand All @@ -101,7 +109,7 @@ func bitcoinTestRoutines(
// initialize runner for withdraw tests
account = conf.AdditionalAccounts.UserBitcoinWithdraw
runnerWithdraw := initBitcoinRunner(
"btc_withdraw",
testGroupWithdrawName,
account,
conf,
deployerRunner,
Expand All @@ -123,8 +131,8 @@ func bitcoinTestRoutines(
}

// create test routines
routineDeposit := createBitcoinTestRoutine(runnerDeposit, depositTests)
routineWithdraw := createBitcoinTestRoutine(runnerWithdraw, withdrawTests)
routineDeposit := createBitcoinTestRoutine(runnerDeposit, depositTests, testGroupDepositName)
routineWithdraw := createBitcoinTestRoutine(runnerWithdraw, withdrawTests, testGroupWithdrawName)

return routineDeposit, routineWithdraw
}
Expand Down Expand Up @@ -177,7 +185,8 @@ func initBitcoinRunner(
}

// createBitcoinTestRoutine creates a test routine for given test names
func createBitcoinTestRoutine(r *runner.E2ERunner, testNames []string) func() error {
// The 'wgDependency' argument is used to wait for dependent routine to complete
func createBitcoinTestRoutine(r *runner.E2ERunner, testNames []string, name string) func() error {
return func() (err error) {
r.Logger.Print("🏃 starting bitcoin tests")
startTime := time.Now()
Expand All @@ -197,6 +206,11 @@ func createBitcoinTestRoutine(r *runner.E2ERunner, testNames []string) func() er

r.Logger.Print("🍾 bitcoin tests completed in %s", time.Since(startTime).String())

// mark deposit test group as done
if name == testGroupDepositName {
e2etests.DepdencyAllBitcoinDeposits.Done()
}

return err
}
}
17 changes: 17 additions & 0 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ const (
TestBitcoinWithdrawInvalidAddressName = "bitcoin_withdraw_invalid"
TestBitcoinWithdrawRestrictedName = "bitcoin_withdraw_restricted"
TestBitcoinDepositInvalidMemoRevertName = "bitcoin_deposit_invalid_memo_revert"
TestBitcoinWithdrawRBFName = "bitcoin_withdraw_rbf"

/*
Application tests
Expand Down Expand Up @@ -264,6 +265,12 @@ const (
CountArgDescription = "count"
)

// Here are all the dependencies for the e2e tests, add more dependencies here if needed
var (
// DepdencyAllBitcoinDeposits is a dependency to wait for all bitcoin deposit tests to complete
DepdencyAllBitcoinDeposits = runner.NewE2EDependency("all_bitcoin_deposits")
)

// AllE2ETests is an ordered list of all e2e tests
var AllE2ETests = []runner.E2ETest{
/*
Expand Down Expand Up @@ -1165,6 +1172,16 @@ var AllE2ETests = []runner.E2ETest{
TestBitcoinDepositInvalidMemoRevert,
runner.WithMinimumVersion("v29.0.0"),
),
runner.NewE2ETest(
TestBitcoinWithdrawRBFName,
"withdraw Bitcoin from ZEVM and replace the outbound using RBF",
[]runner.ArgDefinition{
{Description: "receiver address", DefaultValue: ""},
{Description: "amount in btc", DefaultValue: "0.001"},
},
TestBitcoinWithdrawRBF,
runner.WithDependencies(DepdencyAllBitcoinDeposits),
),
/*
Application tests
*/
Expand Down
31 changes: 2 additions & 29 deletions e2e/e2etests/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"

"github.com/zeta-chain/node/e2e/runner"
Expand All @@ -28,39 +27,13 @@ func randomPayload(r *runner.E2ERunner) string {
}

func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) *btcjson.TxRawResult {
_, gasFee, err := r.BTCZRC20.WithdrawGasFee(&bind.CallOpts{})
require.NoError(r, err)
minimumAmount := new(big.Int).Add(amount, gasFee)
currentBalance, err := r.BTCZRC20.BalanceOf(&bind.CallOpts{}, r.ZEVMAuth.From)
require.NoError(r, err)
require.Greater(
r,
currentBalance.Int64(),
minimumAmount.Int64(),
"current balance must be greater than amount + gasFee",
)

tx, err := r.BTCZRC20.Approve(
r.ZEVMAuth,
r.BTCZRC20Addr,
big.NewInt(amount.Int64()*2),
) // approve more to cover withdraw fee
require.NoError(r, err)

receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
utils.RequireTxSuccessful(r, receipt)
// approve and withdraw on ZRC20 contract
receipt := r.WithdrawBTC(to, amount, true)

// mine blocks if testing on regnet
stop := r.MineBlocksIfLocalBitcoin()
defer stop()

// withdraw 'amount' of BTC from ZRC20 to BTC address
tx, err = r.BTCZRC20.Withdraw(r.ZEVMAuth, []byte(to.EncodeAddress()), amount)
require.NoError(r, err)

receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
utils.RequireTxSuccessful(r, receipt)

// get cctx and check status
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ func TestBitcoinDepositAndWithdrawWithDust(r *runner.E2ERunner, args []string) {
require.Len(r, args, 0)

// ARRANGE

// Deploy the withdrawer contract on ZetaChain with a withdraw amount of 100 satoshis (dust amount is 1000 satoshis)
withdrawerAddr, tx, _, err := withdrawer.DeployWithdrawer(r.ZEVMAuth, r.ZEVMClient, big.NewInt(100))
require.NoError(r, err)
Expand Down
76 changes: 76 additions & 0 deletions e2e/e2etests/test_bitcoin_withdraw_rbf.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package e2etests

import (
"strconv"
"time"

"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/stretchr/testify/require"

"github.com/zeta-chain/node/e2e/runner"
"github.com/zeta-chain/node/e2e/utils"
crosschaintypes "github.com/zeta-chain/node/x/crosschain/types"
)

// TestBitcoinWithdrawRBF tests the RBF (Replace-By-Fee) feature in Zetaclient.
// It needs block mining to be stopped and runs as the last test in the suite.
//
// IMPORTANT: the test requires to simulate a stuck tx in the Bitcoin regnet.
// The challenge to simulate a stuck tx is to create overwhelming traffic in the local mempool.
//
// To work around this:
// 1. change the 'minTxConfirmations' to 1 to not include outbound tx right away (production should use 0)
// here: https://github.com/zeta-chain/node/blob/5c2a8ffbc702130fd9538b1cd7640d0e04d3e4f6/zetaclient/chains/bitcoin/observer/outbound.go#L27
// 2. stop block mining to let the pending tx sit in the mempool for longer time
func TestBitcoinWithdrawRBF(r *runner.E2ERunner, args []string) {
require.Len(r, args, 2)

// parse arguments
defaultReceiver := r.GetBtcAddress().EncodeAddress()
to, amount := utils.ParseBitcoinWithdrawArgs(r, args, defaultReceiver, r.GetBitcoinChainID())

// initiate a withdraw CCTX
receipt := r.WithdrawBTC(to, amount, true)
cctx := utils.GetCCTXByInboundHash(r.Ctx, r.CctxClient, receipt.TxHash.Hex())

// wait for the 1st outbound tracker hash to come in
nonce := cctx.GetCurrentOutboundParam().TssNonce
hashes := utils.WaitOutboundTracker(r.Ctx, r.CctxClient, r.GetBitcoinChainID(), nonce, 1, r.Logger, 3*time.Minute)
txHash, err := chainhash.NewHashFromStr(hashes[0])
r.Logger.Info("got 1st tracker hash: %s", txHash)

// get original tx
require.NoError(r, err)
txResult, err := r.BtcRPCClient.GetTransaction(r.Ctx, txHash)
require.NoError(r, err)
require.Zero(r, txResult.Confirmations)

// wait for RBF tx to kick in
hashes = utils.WaitOutboundTracker(r.Ctx, r.CctxClient, r.GetBitcoinChainID(), nonce, 2, r.Logger, 3*time.Minute)
txHashRBF, err := chainhash.NewHashFromStr(hashes[1])
require.NoError(r, err)
r.Logger.Info("got 2nd tracker hash: %s", txHashRBF)

// resume block mining
stop := r.MineBlocksIfLocalBitcoin()
defer stop()

// waiting for CCTX to be mined
cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined)

// ensure the original tx is dropped
utils.MustHaveDroppedBitcoinTx(r.Ctx, r.BtcRPCClient, txHash)

// ensure the RBF tx is mined
rawResult := utils.MustHaveMinedBitcoinTx(r.Ctx, r.BtcRPCClient, txHashRBF)

// ensure RBF fee rate > old rate
params := cctx.GetCurrentOutboundParam()
oldRate, err := strconv.ParseInt(params.GasPrice, 10, 64)
require.NoError(r, err)

_, newRate, err := r.BtcRPCClient.GetTransactionFeeAndRate(r.Ctx, rawResult)
require.NoError(r, err)
require.Greater(r, newRate, oldRate, "RBF fee rate should be higher than the original tx")
}
40 changes: 40 additions & 0 deletions e2e/runner/bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/hex"
"fmt"
"math/big"
"sort"
"time"

Expand All @@ -15,6 +16,7 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/rs/zerolog/log"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -182,6 +184,44 @@ func (r *E2ERunner) DepositBTC(receiver common.Address) {
require.Equal(r, 1, balance.Sign(), "balance should be positive")
}

// WithdrawBTC is a helper function to call 'withdraw' on BTCZRC20 contract with optional 'approve'
func (r *E2ERunner) WithdrawBTC(to btcutil.Address, amount *big.Int, approve bool) *ethtypes.Receipt {
// ensure enough balance to cover the withdrawal
_, gasFee, err := r.BTCZRC20.WithdrawGasFee(&bind.CallOpts{})
require.NoError(r, err)
minimumAmount := new(big.Int).Add(amount, gasFee)
currentBalance, err := r.BTCZRC20.BalanceOf(&bind.CallOpts{}, r.ZEVMAuth.From)
require.NoError(r, err)
require.Greater(
r,
currentBalance.Int64(),
minimumAmount.Int64(),
"current balance must be greater than amount + gasFee",
)

// approve more to cover withdraw fee
if approve {
tx, err := r.BTCZRC20.Approve(
r.ZEVMAuth,
r.BTCZRC20Addr,
big.NewInt(amount.Int64()*2),
)
require.NoError(r, err)

receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
utils.RequireTxSuccessful(r, receipt)
}

// withdraw 'amount' of BTC from ZRC20 to BTC address
tx, err := r.BTCZRC20.Withdraw(r.ZEVMAuth, []byte(to.EncodeAddress()), amount)
require.NoError(r, err)

receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
utils.RequireTxSuccessful(r, receipt)

return receipt
}

func (r *E2ERunner) SendToTSSWithMemo(
amount float64,
memo []byte,
Expand Down
41 changes: 40 additions & 1 deletion e2e/runner/e2etest.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package runner

import "fmt"
import (
"fmt"
"sync"
)

// E2ETestFunc is a function representing a E2E test
// It takes a E2ERunner as an argument
Expand All @@ -16,12 +19,20 @@ func WithMinimumVersion(version string) E2ETestOpt {
}
}

// WithDependencies sets dependencies to the E2ETest to wait for completion
func WithDependencies(dependencies ...E2EDependency) E2ETestOpt {
return func(t *E2ETest) {
t.Dependencies = dependencies
}
}

// E2ETest represents a E2E test with a name, args, description and test func
type E2ETest struct {
Name string
Description string
Args []string
ArgsDefinition []ArgDefinition
Dependencies []E2EDependency
E2ETest E2ETestFunc
MinimumVersion string
}
Expand All @@ -46,6 +57,33 @@ func NewE2ETest(
return test
}

// E2EDependency defines a structure that holds a E2E test dependency
type E2EDependency struct {
name string
waitGroup *sync.WaitGroup
}

// NewE2EDependency creates a new instance of E2Edependency with specified parameters.
func NewE2EDependency(name string) E2EDependency {
var wg sync.WaitGroup
wg.Add(1)

return E2EDependency{
name: name,
waitGroup: &wg,
}
}

// Wait waits for the E2EDependency to complete
func (d *E2EDependency) Wait() {
d.waitGroup.Wait()
}

// Done marks the E2EDependency as done
func (d *E2EDependency) Done() {
d.waitGroup.Done()
}

// ArgDefinition defines a structure for holding an argument's description along with it's default value.
type ArgDefinition struct {
Description string
Expand Down Expand Up @@ -110,6 +148,7 @@ func (r *E2ERunner) GetE2ETestsToRunByConfig(
Name: e2eTest.Name,
Description: e2eTest.Description,
ArgsDefinition: e2eTest.ArgsDefinition,
Dependencies: e2eTest.Dependencies,
E2ETest: e2eTest.E2ETest,
MinimumVersion: e2eTest.MinimumVersion,
}
Expand Down
Loading