diff --git a/changelog.md b/changelog.md index b6ad87bd52..7347b78b58 100644 --- a/changelog.md +++ b/changelog.md @@ -1,11 +1,14 @@ # CHANGELOG -## Unreleasd +## Unreleased ### Features ### Fixes +* [1372](https://github.com/zeta-chain/node/pull/1372) - Include Event Index as part for inbound tx digest +* [1358](https://github.com/zeta-chain/node/pull/1358) - add a new thread to zetaclient which checks zeta supply in all connected chains in every block + ### Refactoring ### Chores @@ -67,12 +70,3 @@ * [1218](https://github.com/zeta-chain/node/pull/1218) - cross-compile release binaries and simplify PR testings * [1302](https://github.com/zeta-chain/node/pull/1302) - add mainnet builds to goreleaser - - - - -### Unreleased: -* add a new thread to zetaclient which checks zeta supply in all connected chains in every block - - - diff --git a/contrib/localnet/orchestrator/smoketest/main.go b/contrib/localnet/orchestrator/smoketest/main.go index ab0c598976..e5b2e4391c 100644 --- a/contrib/localnet/orchestrator/smoketest/main.go +++ b/contrib/localnet/orchestrator/smoketest/main.go @@ -276,7 +276,6 @@ func LocalSmokeTest(_ *cobra.Command, _ []string) { smokeTest.CheckZRC20ReserveAndSupply() smokeTest.TestERC20Withdraw() - //smokeTest.WithdrawBitcoinMultipleTimes(5) smokeTest.CheckZRC20ReserveAndSupply() smokeTest.TestSendZetaOut() diff --git a/contrib/localnet/orchestrator/smoketest/test_erc20.go b/contrib/localnet/orchestrator/smoketest/test_erc20.go deleted file mode 100644 index 309916c3de..0000000000 --- a/contrib/localnet/orchestrator/smoketest/test_erc20.go +++ /dev/null @@ -1,194 +0,0 @@ -//go:build PRIVNET -// +build PRIVNET - -package main - -import ( - "context" - "fmt" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - ethcommon "github.com/ethereum/go-ethereum/common" - zrc20 "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" - "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/erc20" -) - -func (sm *SmokeTest) TestERC20Deposit() { - startTime := time.Now() - defer func() { - fmt.Printf("test finishes in %s\n", time.Since(startTime)) - }() - LoudPrintf("Deposit USDT ERC20 into ZEVM\n") - - initialBal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) - if err != nil { - panic(err) - } - txhash := sm.DepositERC20(big.NewInt(1e9), []byte{}) - WaitCctxMinedByInTxHash(txhash.Hex(), sm.cctxClient) - - bal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) - if err != nil { - panic(err) - } - - diff := big.NewInt(0) - diff.Sub(bal, initialBal) - - fmt.Printf("balance of deployer on USDT ZRC20: %d\n", bal) - supply, err := sm.USDTZRC20.TotalSupply(&bind.CallOpts{}) - if err != nil { - panic(err) - } - fmt.Printf("supply of USDT ZRC20: %d\n", supply) - if diff.Int64() != 1e9 { - panic("balance is not correct") - } -} - -func (sm *SmokeTest) DepositERC20(amount *big.Int, msg []byte) ethcommon.Hash { - USDT := sm.USDTERC20 - tx, err := USDT.Mint(sm.goerliAuth, big.NewInt(1e10)) - if err != nil { - panic(err) - } - receipt := MustWaitForTxReceipt(sm.goerliClient, tx) - fmt.Printf("Mint receipt tx hash: %s\n", tx.Hash().Hex()) - - tx, err = USDT.Approve(sm.goerliAuth, sm.ERC20CustodyAddr, big.NewInt(1e10)) - if err != nil { - panic(err) - } - receipt = MustWaitForTxReceipt(sm.goerliClient, tx) - fmt.Printf("USDT Approve receipt tx hash: %s\n", tx.Hash().Hex()) - - tx, err = sm.ERC20Custody.Deposit(sm.goerliAuth, DeployerAddress.Bytes(), sm.USDTERC20Addr, amount, msg) - if err != nil { - panic(err) - } - receipt = MustWaitForTxReceipt(sm.goerliClient, tx) - if receipt.Status == 0 { - panic("deposit failed") - } - fmt.Printf("Deposit receipt tx hash: %s, status %d\n", receipt.TxHash.Hex(), receipt.Status) - for _, log := range receipt.Logs { - event, err := sm.ERC20Custody.ParseDeposited(*log) - if err != nil { - continue - } - fmt.Printf("Deposited event: \n") - fmt.Printf(" Recipient address: %x, \n", event.Recipient) - fmt.Printf(" ERC20 address: %s, \n", event.Asset.Hex()) - fmt.Printf(" Amount: %d, \n", event.Amount) - fmt.Printf(" Message: %x, \n", event.Message) - } - fmt.Printf("gas limit %d\n", sm.zevmAuth.GasLimit) - return tx.Hash() -} - -func (sm *SmokeTest) TestERC20Withdraw() { - startTime := time.Now() - defer func() { - fmt.Printf("test finishes in %s\n", time.Since(startTime)) - }() - LoudPrintf("Withdraw USDT ZRC20\n") - sm.WithdrawERC20() -} - -func (sm *SmokeTest) WithdrawERC20() { - zevmClient := sm.zevmClient - goerliClient := sm.goerliClient - cctxClient := sm.cctxClient - - usdtZRC20, err := zrc20.NewZRC20(ethcommon.HexToAddress(USDTZRC20Addr), zevmClient) - if err != nil { - panic(err) - } - bal, err := usdtZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) - if err != nil { - panic(err) - } - fmt.Printf("balance of deployer on USDT ZRC20: %d\n", bal) - supply, err := usdtZRC20.TotalSupply(&bind.CallOpts{}) - if err != nil { - panic(err) - } - fmt.Printf("supply of USDT ZRC20: %d\n", supply) - - gasZRC20, gasFee, err := usdtZRC20.WithdrawGasFee(&bind.CallOpts{}) - if err != nil { - panic(err) - } - fmt.Printf("gasZRC20: %s, gasFee: %d\n", gasZRC20.Hex(), gasFee) - - ethZRC20, err := zrc20.NewZRC20(gasZRC20, zevmClient) - if err != nil { - panic(err) - } - bal, err = ethZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) - if err != nil { - panic(err) - } - fmt.Printf("balance of deployer on ETH ZRC20: %d\n", bal) - if bal.Int64() <= 0 { - panic("not enough ETH ZRC20 balance!") - } - - // Approve - tx, err := ethZRC20.Approve(sm.zevmAuth, ethcommon.HexToAddress(USDTZRC20Addr), big.NewInt(1e18)) - if err != nil { - panic(err) - } - receipt := MustWaitForTxReceipt(zevmClient, tx) - fmt.Printf("eth zrc20 approve receipt: status %d\n", receipt.Status) - // Withdraw - tx, err = usdtZRC20.Withdraw(sm.zevmAuth, DeployerAddress.Bytes(), big.NewInt(100)) - if err != nil { - panic(err) - } - receipt = MustWaitForTxReceipt(zevmClient, tx) - fmt.Printf("Receipt txhash %s status %d\n", receipt.TxHash, receipt.Status) - for _, log := range receipt.Logs { - event, err := usdtZRC20.ParseWithdrawal(*log) - if err != nil { - continue - } - fmt.Printf(" logs: from %s, to %x, value %d, gasfee %d\n", event.From.Hex(), event.To, event.Value, event.Gasfee) - } - - sm.wg.Add(1) - go func() { - defer sm.wg.Done() - cctx := WaitCctxMinedByInTxHash(receipt.TxHash.Hex(), cctxClient) - fmt.Printf("outTx hash %s\n", cctx.GetCurrentOutTxParam().OutboundTxHash) - - USDTERC20, err := erc20.NewUSDT(ethcommon.HexToAddress(USDTERC20Addr), goerliClient) - if err != nil { - panic(err) - } - bal, err = USDTERC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) - if err != nil { - panic(err) - } - fmt.Printf("USDT ERC20 bal: %d\n", bal) - - receipt, err := sm.goerliClient.TransactionReceipt(context.Background(), ethcommon.HexToHash(cctx.GetCurrentOutTxParam().OutboundTxHash)) - if err != nil { - panic(err) - } - fmt.Printf("Receipt txhash %s status %d\n", receipt.TxHash, receipt.Status) - for _, log := range receipt.Logs { - event, err := USDTERC20.ParseTransfer(*log) - if err != nil { - continue - } - fmt.Printf(" logs: from %s, to %s, value %d\n", event.From.Hex(), event.To.Hex(), event.Value) - if event.Value.Int64() != 100 { - panic("value is not correct") - } - } - }() - sm.wg.Wait() -} diff --git a/contrib/localnet/orchestrator/smoketest/test_erc20_deposit.go b/contrib/localnet/orchestrator/smoketest/test_erc20_deposit.go new file mode 100644 index 0000000000..6df4d94647 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/test_erc20_deposit.go @@ -0,0 +1,163 @@ +//go:build PRIVNET +// +build PRIVNET + +package main + +import ( + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethcommon "github.com/ethereum/go-ethereum/common" + testcontract "github.com/zeta-chain/zetacore/testutil/contracts" +) + +func (sm *SmokeTest) TestERC20Deposit() { + startTime := time.Now() + defer func() { + fmt.Printf("test finishes in %s\n", time.Since(startTime)) + }() + LoudPrintf("Deposit USDT ERC20 into ZEVM\n") + + initialBal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + txhash := sm.DepositERC20(big.NewInt(1e9), []byte{}) + WaitCctxMinedByInTxHash(txhash.Hex(), sm.cctxClient) + + bal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + + diff := big.NewInt(0) + diff.Sub(bal, initialBal) + + fmt.Printf("balance of deployer on USDT ZRC20: %d\n", bal) + supply, err := sm.USDTZRC20.TotalSupply(&bind.CallOpts{}) + if err != nil { + panic(err) + } + fmt.Printf("supply of USDT ZRC20: %d\n", supply) + if diff.Int64() != 1e9 { + panic("balance is not correct") + } + + LoudPrintf("Same-transaction multiple deposit USDT ERC20 into ZEVM\n") + initialBal, err = sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + txhash = sm.MultipleDeposits(big.NewInt(1e9), big.NewInt(10)) + cctxs := WaitCctxsMinedByInTxHash(txhash.Hex(), sm.cctxClient) + if len(cctxs) != 10 { + panic(fmt.Sprintf("cctxs length is not correct: %d", len(cctxs))) + } + + // check new balance is increased by 1e9 * 10 + bal, err = sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + diff = big.NewInt(0).Sub(bal, initialBal) + if diff.Int64() != 1e10 { + panic(fmt.Sprintf("balance difference is not correct: %d", diff.Int64())) + } +} + +func (sm *SmokeTest) DepositERC20(amount *big.Int, msg []byte) ethcommon.Hash { + USDT := sm.USDTERC20 + tx, err := USDT.Mint(sm.goerliAuth, big.NewInt(1e10)) + if err != nil { + panic(err) + } + receipt := MustWaitForTxReceipt(sm.goerliClient, tx) + fmt.Printf("Mint receipt tx hash: %s\n", tx.Hash().Hex()) + + tx, err = USDT.Approve(sm.goerliAuth, sm.ERC20CustodyAddr, big.NewInt(1e10)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.goerliClient, tx) + fmt.Printf("USDT Approve receipt tx hash: %s\n", tx.Hash().Hex()) + + tx, err = sm.ERC20Custody.Deposit(sm.goerliAuth, DeployerAddress.Bytes(), sm.USDTERC20Addr, amount, msg) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.goerliClient, tx) + if receipt.Status == 0 { + panic("deposit failed") + } + fmt.Printf("Deposit receipt tx hash: %s, status %d\n", receipt.TxHash.Hex(), receipt.Status) + for _, log := range receipt.Logs { + event, err := sm.ERC20Custody.ParseDeposited(*log) + if err != nil { + continue + } + fmt.Printf("Deposited event: \n") + fmt.Printf(" Recipient address: %x, \n", event.Recipient) + fmt.Printf(" ERC20 address: %s, \n", event.Asset.Hex()) + fmt.Printf(" Amount: %d, \n", event.Amount) + fmt.Printf(" Message: %x, \n", event.Message) + } + fmt.Printf("gas limit %d\n", sm.zevmAuth.GasLimit) + return tx.Hash() +} + +func (sm *SmokeTest) MultipleDeposits(amount, count *big.Int) ethcommon.Hash { + // deploy depositor + depositorAddr, _, depositor, err := testcontract.DeployDepositor(sm.goerliAuth, sm.goerliClient, sm.ERC20CustodyAddr) + if err != nil { + panic(err) + } + + // mint + tx, err := sm.USDTERC20.Mint(sm.goerliAuth, big.NewInt(0).Mul(amount, count)) + if err != nil { + panic(err) + } + receipt := MustWaitForTxReceipt(sm.goerliClient, tx) + if receipt.Status == 0 { + panic("mint failed") + } + fmt.Printf("Mint receipt tx hash: %s\n", tx.Hash().Hex()) + + // approve + tx, err = sm.USDTERC20.Approve(sm.goerliAuth, depositorAddr, big.NewInt(1e10)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.goerliClient, tx) + if receipt.Status == 0 { + panic("approve failed") + } + fmt.Printf("USDT Approve receipt tx hash: %s\n", tx.Hash().Hex()) + + // deposit + tx, err = depositor.RunDeposits(sm.goerliAuth, DeployerAddress.Bytes(), sm.USDTERC20Addr, amount, []byte{}, count) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.goerliClient, tx) + if receipt.Status == 0 { + panic("deposits failed") + } + fmt.Printf("Deposits receipt tx hash: %s\n", tx.Hash().Hex()) + + for _, log := range receipt.Logs { + event, err := sm.ERC20Custody.ParseDeposited(*log) + if err != nil { + continue + } + fmt.Printf("Multiple deposit event: \n") + fmt.Printf(" Recipient address: %x, \n", event.Recipient) + fmt.Printf(" ERC20 address: %s, \n", event.Asset.Hex()) + fmt.Printf(" Amount: %d, \n", event.Amount) + fmt.Printf(" Message: %x, \n", event.Message) + } + fmt.Printf("gas limit %d\n", sm.zevmAuth.GasLimit) + return tx.Hash() +} diff --git a/contrib/localnet/orchestrator/smoketest/test_erc20_withdraw.go b/contrib/localnet/orchestrator/smoketest/test_erc20_withdraw.go new file mode 100644 index 0000000000..fde1079b18 --- /dev/null +++ b/contrib/localnet/orchestrator/smoketest/test_erc20_withdraw.go @@ -0,0 +1,181 @@ +//go:build PRIVNET +// +build PRIVNET + +package main + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethcommon "github.com/ethereum/go-ethereum/common" + zrc20 "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" + "github.com/zeta-chain/zetacore/contrib/localnet/orchestrator/smoketest/contracts/erc20" + testcontract "github.com/zeta-chain/zetacore/testutil/contracts" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func (sm *SmokeTest) TestERC20Withdraw() { + startTime := time.Now() + defer func() { + fmt.Printf("test finishes in %s\n", time.Since(startTime)) + }() + + bal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + fmt.Printf("balance of deployer on USDT ZRC20: %d\n", bal) + supply, err := sm.USDTZRC20.TotalSupply(&bind.CallOpts{}) + if err != nil { + panic(err) + } + fmt.Printf("supply of USDT ZRC20: %d\n", supply) + + gasZRC20, gasFee, err := sm.USDTZRC20.WithdrawGasFee(&bind.CallOpts{}) + if err != nil { + panic(err) + } + fmt.Printf("gasZRC20: %s, gasFee: %d\n", gasZRC20.Hex(), gasFee) + + ethZRC20, err := zrc20.NewZRC20(gasZRC20, sm.zevmClient) + if err != nil { + panic(err) + } + bal, err = ethZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + fmt.Printf("balance of deployer on ETH ZRC20: %d\n", bal) + if bal.Int64() <= 0 { + panic("not enough ETH ZRC20 balance!") + } + + LoudPrintf("Withdraw USDT ZRC20\n") + sm.WithdrawERC20(ethZRC20) + + LoudPrintf("Multiple withdraws USDT ZRC20\n") + sm.MultipleWithdraws(ethZRC20) +} + +func (sm *SmokeTest) WithdrawERC20(ethZRC20 *zrc20.ZRC20) { + // approve + tx, err := ethZRC20.Approve(sm.zevmAuth, ethcommon.HexToAddress(USDTZRC20Addr), big.NewInt(1e18)) + if err != nil { + panic(err) + } + receipt := MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status == 0 { + panic("approve failed") + } + fmt.Printf("eth zrc20 approve receipt: status %d\n", receipt.Status) + + // withdraw + tx, err = sm.USDTZRC20.Withdraw(sm.zevmAuth, DeployerAddress.Bytes(), big.NewInt(100)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + fmt.Printf("Receipt txhash %s status %d\n", receipt.TxHash, receipt.Status) + for _, log := range receipt.Logs { + event, err := sm.USDTZRC20.ParseWithdrawal(*log) + if err != nil { + continue + } + fmt.Printf(" logs: from %s, to %x, value %d, gasfee %d\n", event.From.Hex(), event.To, event.Value, event.Gasfee) + } + + // verify the withdraw value + cctx := WaitCctxMinedByInTxHash(receipt.TxHash.Hex(), sm.cctxClient) + sm.verifyTransferAmountFromCCTX(cctx, 100) +} + +func (sm *SmokeTest) MultipleWithdraws(ethZRC20 *zrc20.ZRC20) { + // deploy withdrawer + withdrawerAddr, _, withdrawer, err := testcontract.DeployWithdrawer(sm.zevmAuth, sm.zevmClient) + if err != nil { + panic(err) + } + + // approve + tx, err := sm.USDTZRC20.Approve(sm.zevmAuth, withdrawerAddr, big.NewInt(1e18)) + if err != nil { + panic(err) + } + receipt := MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status == 0 { + panic("approve failed") + } + fmt.Printf("USDT ZRC20 approve receipt: status %d\n", receipt.Status) + + // approve gas token + tx, err = ethZRC20.Approve(sm.zevmAuth, withdrawerAddr, big.NewInt(1e18)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status == 0 { + panic("approve gas token failed") + } + fmt.Printf("eth zrc20 approve receipt: status %d\n", receipt.Status) + + // check the balance + bal, err := sm.USDTZRC20.BalanceOf(&bind.CallOpts{}, DeployerAddress) + if err != nil { + panic(err) + } + fmt.Printf("balance of deployer on USDT ZRC20: %d\n", bal) + + if bal.Int64() < 1000 { + panic("not enough USDT ZRC20 balance!") + } + + // withdraw + tx, err = withdrawer.RunWithdraws(sm.zevmAuth, DeployerAddress.Bytes(), sm.USDTZRC20Addr, big.NewInt(100), big.NewInt(10)) + if err != nil { + panic(err) + } + receipt = MustWaitForTxReceipt(sm.zevmClient, tx) + if receipt.Status == 0 { + panic("withdraw failed") + } + fmt.Printf("Withdraws receipt: status %d\n", receipt.Status) + + cctxs := WaitCctxsMinedByInTxHash(tx.Hash().Hex(), sm.cctxClient) + if len(cctxs) != 10 { + panic(fmt.Sprintf("cctxs length is not correct: %d", len(cctxs))) + } + + // verify the withdraw value + for _, cctx := range cctxs { + sm.verifyTransferAmountFromCCTX(cctx, 100) + } +} + +// verifyTransferAmountFromCCTX verifies the transfer amount from the CCTX on Goerli +func (sm *SmokeTest) verifyTransferAmountFromCCTX(cctx *crosschaintypes.CrossChainTx, amount int64) { + fmt.Printf("outTx hash %s\n", cctx.GetCurrentOutTxParam().OutboundTxHash) + + USDTERC20, err := erc20.NewUSDT(ethcommon.HexToAddress(USDTERC20Addr), sm.goerliClient) + if err != nil { + panic(err) + } + + receipt, err := sm.goerliClient.TransactionReceipt(context.Background(), ethcommon.HexToHash(cctx.GetCurrentOutTxParam().OutboundTxHash)) + if err != nil { + panic(err) + } + fmt.Printf("Receipt txhash %s status %d\n", receipt.TxHash, receipt.Status) + for _, log := range receipt.Logs { + event, err := USDTERC20.ParseTransfer(*log) + if err != nil { + continue + } + fmt.Printf(" logs: from %s, to %s, value %d\n", event.From.Hex(), event.To.Hex(), event.Value) + if event.Value.Int64() != amount { + panic("value is not correct") + } + } +} diff --git a/contrib/localnet/orchestrator/smoketest/test_setup.go b/contrib/localnet/orchestrator/smoketest/test_setup.go index 1a77089023..b2df135a03 100644 --- a/contrib/localnet/orchestrator/smoketest/test_setup.go +++ b/contrib/localnet/orchestrator/smoketest/test_setup.go @@ -218,7 +218,7 @@ func (sm *SmokeTest) setContracts() { panic(err) } - //Set ZetaEthAddr + // Set ZetaEthAddr sm.ZetaEthAddr = ethcommon.HexToAddress(contracts.ZetaEthAddress) fmt.Println("Connector Eth address: ", contracts.ZetaEthAddress) sm.ZetaEth, err = zetaeth.NewZetaEth(sm.ZetaEthAddr, sm.goerliClient) @@ -226,42 +226,42 @@ func (sm *SmokeTest) setContracts() { panic(err) } - //Set ConnectorEthAddr + // Set ConnectorEthAddr sm.ConnectorEthAddr = ethcommon.HexToAddress(contracts.ConnectorEthAddr) sm.ConnectorEth, err = zetaconnectoreth.NewZetaConnectorEth(sm.ConnectorEthAddr, sm.goerliClient) if err != nil { panic(err) } - //Set ERC20CustodyAddr + // Set ERC20CustodyAddr sm.ERC20CustodyAddr = ethcommon.HexToAddress(ERC20CustodyAddr) sm.ERC20Custody, err = erc20custody.NewERC20Custody(sm.ERC20CustodyAddr, sm.goerliClient) if err != nil { panic(err) } - //Set USDTERC20Addr + // Set USDTERC20Addr sm.USDTERC20Addr = ethcommon.HexToAddress(USDTERC20Addr) sm.USDTERC20, err = erc20.NewUSDT(sm.USDTERC20Addr, sm.goerliClient) if err != nil { panic(err) } - //Set USDTZRC20Addr + // Set USDTZRC20Addr sm.USDTZRC20Addr = ethcommon.HexToAddress(USDTZRC20Addr) sm.USDTZRC20, err = zrc20.NewZRC20(sm.USDTZRC20Addr, sm.zevmClient) if err != nil { panic(err) } - //UniswapV2FactoryAddr + // UniswapV2FactoryAddr sm.UniswapV2FactoryAddr = ethcommon.HexToAddress(UniswapV2FactoryAddr) sm.UniswapV2Factory, err = uniswapv2factory.NewUniswapV2Factory(sm.UniswapV2FactoryAddr, sm.zevmClient) if err != nil { panic(err) } - //UniswapV2RouterAddr + // UniswapV2RouterAddr sm.UniswapV2RouterAddr = ethcommon.HexToAddress(UniswapV2RouterAddr) sm.UniswapV2Router, err = uniswapv2router.NewUniswapV2Router02(sm.UniswapV2RouterAddr, sm.zevmClient) if err != nil { diff --git a/contrib/localnet/orchestrator/smoketest/utils.go b/contrib/localnet/orchestrator/smoketest/utils.go index be9dd03f5f..866dd8e413 100644 --- a/contrib/localnet/orchestrator/smoketest/utils.go +++ b/contrib/localnet/orchestrator/smoketest/utils.go @@ -11,21 +11,25 @@ import ( "sync" "time" - rpchttp "github.com/tendermint/tendermint/rpc/client/http" - coretypes "github.com/tendermint/tendermint/rpc/core/types" - - "github.com/ethereum/go-ethereum" - "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcutil" + "github.com/ethereum/go-ethereum" ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" + rpchttp "github.com/tendermint/tendermint/rpc/client/http" + coretypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/zeta-chain/zetacore/x/crosschain/types" ) // WaitCctxMinedByInTxHash waits until cctx is mined; returns the cctxIndex (the last one) func WaitCctxMinedByInTxHash(inTxHash string, cctxClient types.QueryClient) *types.CrossChainTx { + cctxs := WaitCctxsMinedByInTxHash(inTxHash, cctxClient) + return cctxs[len(cctxs)-1] +} + +// WaitCctxsMinedByInTxHash waits until cctx is mined; returns the cctxIndex (the last one) +func WaitCctxsMinedByInTxHash(inTxHash string, cctxClient types.QueryClient) []*types.CrossChainTx { var cctxIndexes []string for { time.Sleep(5 * time.Second) @@ -59,7 +63,7 @@ func WaitCctxMinedByInTxHash(inTxHash string, cctxClient types.QueryClient) *typ }() } wg.Wait() - return cctxs[len(cctxs)-1] + return cctxs } func IsTerminalStatus(status types.CctxStatus) bool { diff --git a/docs/cli/zetacored/zetacored_tx_crosschain_inbound-voter.md b/docs/cli/zetacored/zetacored_tx_crosschain_inbound-voter.md index 2e419e9158..cfa72e72c6 100644 --- a/docs/cli/zetacored/zetacored_tx_crosschain_inbound-voter.md +++ b/docs/cli/zetacored/zetacored_tx_crosschain_inbound-voter.md @@ -3,7 +3,7 @@ Broadcast message sendVoter ``` -zetacored tx crosschain inbound-voter [sender] [senderChainID] [txOrigin] [receiver] [receiverChainID] [amount] [message] [inTxHash] [inBlockHeight] [coinType] [asset] [flags] +zetacored tx crosschain inbound-voter [sender] [senderChainID] [txOrigin] [receiver] [receiverChainID] [amount] [message] [inTxHash] [inBlockHeight] [coinType] [asset] [eventIndex] [flags] ``` ### Options diff --git a/docs/spec/crosschain/messages.md b/docs/spec/crosschain/messages.md index f167df5c94..6c65cf8098 100644 --- a/docs/spec/crosschain/messages.md +++ b/docs/spec/crosschain/messages.md @@ -219,6 +219,7 @@ message MsgVoteOnObservedInboundTx { common.CoinType coin_type = 12; string tx_origin = 13; string asset = 14; + uint64 event_index = 15; } ``` diff --git a/proto/crosschain/tx.proto b/proto/crosschain/tx.proto index eabdbf19e1..657caa7f55 100644 --- a/proto/crosschain/tx.proto +++ b/proto/crosschain/tx.proto @@ -157,6 +157,8 @@ message MsgVoteOnObservedInboundTx { common.CoinType coin_type = 12; string tx_origin = 13; string asset = 14; + // event index of the sent asset in the observed tx + uint64 event_index = 15; } message MsgVoteOnObservedInboundTxResponse {} diff --git a/testutil/contracts/Depositor.abi b/testutil/contracts/Depositor.abi new file mode 100644 index 0000000000..63cc3e693f --- /dev/null +++ b/testutil/contracts/Depositor.abi @@ -0,0 +1,46 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "custody_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "recipient", + "type": "bytes" + }, + { + "internalType": "contract IERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "runDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/testutil/contracts/Depositor.bin b/testutil/contracts/Depositor.bin new file mode 100644 index 0000000000..6a04cda63a --- /dev/null +++ b/testutil/contracts/Depositor.bin @@ -0,0 +1 @@ +60a060405234801561001057600080fd5b5060405161078a38038061078a833981810160405281019061003291906100cf565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506100fc565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061009c82610071565b9050919050565b6100ac81610091565b81146100b757600080fd5b50565b6000815190506100c9816100a3565b92915050565b6000602082840312156100e5576100e461006c565b5b60006100f3848285016100ba565b91505092915050565b60805161066d61011d6000396000818160e4015261016b015261066d6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80633d496c9314610030575b600080fd5b61004a60048036038101906100459190610330565b61004c565b005b8473ffffffffffffffffffffffffffffffffffffffff166323b872dd33308488610076919061041b565b6040518463ffffffff1660e01b81526004016100949392919061047b565b600060405180830381600087803b1580156100ae57600080fd5b505af11580156100c2573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000838761010f919061041b565b6040518363ffffffff1660e01b815260040161012c9291906104b2565b600060405180830381600087803b15801561014657600080fd5b505af115801561015a573d6000803e3d6000fd5b5050505060005b81811015610211577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e609055e8989898989896040518763ffffffff1660e01b81526004016101cc96959493929190610598565b600060405180830381600087803b1580156101e657600080fd5b505af11580156101fa573d6000803e3d6000fd5b505050508080610209906105ef565b915050610161565b5050505050505050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261024a57610249610225565b5b8235905067ffffffffffffffff8111156102675761026661022a565b5b6020830191508360018202830111156102835761028261022f565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102b58261028a565b9050919050565b60006102c7826102aa565b9050919050565b6102d7816102bc565b81146102e257600080fd5b50565b6000813590506102f4816102ce565b92915050565b6000819050919050565b61030d816102fa565b811461031857600080fd5b50565b60008135905061032a81610304565b92915050565b600080600080600080600060a0888a03121561034f5761034e61021b565b5b600088013567ffffffffffffffff81111561036d5761036c610220565b5b6103798a828b01610234565b9750975050602061038c8a828b016102e5565b955050604061039d8a828b0161031b565b945050606088013567ffffffffffffffff8111156103be576103bd610220565b5b6103ca8a828b01610234565b935093505060806103dd8a828b0161031b565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610426826102fa565b9150610431836102fa565b925082820261043f816102fa565b91508282048414831517610456576104556103ec565b5b5092915050565b610466816102aa565b82525050565b610475816102fa565b82525050565b6000606082019050610490600083018661045d565b61049d602083018561045d565b6104aa604083018461046c565b949350505050565b60006040820190506104c7600083018561045d565b6104d4602083018461046c565b9392505050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061051883856104db565b93506105258385846104ec565b61052e836104fb565b840190509392505050565b6000819050919050565b600061055e6105596105548461028a565b610539565b61028a565b9050919050565b600061057082610543565b9050919050565b600061058282610565565b9050919050565b61059281610577565b82525050565b600060808201905081810360008301526105b381888a61050c565b90506105c26020830187610589565b6105cf604083018661046c565b81810360608301526105e281848661050c565b9050979650505050505050565b60006105fa826102fa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361062c5761062b6103ec565b5b60018201905091905056fea264697066735822122052c5caf083af6e05e3cd0c0e628630fe7cba46565021425413eabeb4a56b4b5464736f6c63430008150033 diff --git a/testutil/contracts/Depositor.go b/testutil/contracts/Depositor.go new file mode 100644 index 0000000000..2fa459f0d7 --- /dev/null +++ b/testutil/contracts/Depositor.go @@ -0,0 +1,224 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// DepositorMetaData contains all meta data concerning the Depositor contract. +var DepositorMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"custody_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"recipient\",\"type\":\"bytes\"},{\"internalType\":\"contractIERC20\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"runDeposits\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a060405234801561001057600080fd5b5060405161078a38038061078a833981810160405281019061003291906100cf565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506100fc565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061009c82610071565b9050919050565b6100ac81610091565b81146100b757600080fd5b50565b6000815190506100c9816100a3565b92915050565b6000602082840312156100e5576100e461006c565b5b60006100f3848285016100ba565b91505092915050565b60805161066d61011d6000396000818160e4015261016b015261066d6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80633d496c9314610030575b600080fd5b61004a60048036038101906100459190610330565b61004c565b005b8473ffffffffffffffffffffffffffffffffffffffff166323b872dd33308488610076919061041b565b6040518463ffffffff1660e01b81526004016100949392919061047b565b600060405180830381600087803b1580156100ae57600080fd5b505af11580156100c2573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000838761010f919061041b565b6040518363ffffffff1660e01b815260040161012c9291906104b2565b600060405180830381600087803b15801561014657600080fd5b505af115801561015a573d6000803e3d6000fd5b5050505060005b81811015610211577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e609055e8989898989896040518763ffffffff1660e01b81526004016101cc96959493929190610598565b600060405180830381600087803b1580156101e657600080fd5b505af11580156101fa573d6000803e3d6000fd5b505050508080610209906105ef565b915050610161565b5050505050505050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261024a57610249610225565b5b8235905067ffffffffffffffff8111156102675761026661022a565b5b6020830191508360018202830111156102835761028261022f565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102b58261028a565b9050919050565b60006102c7826102aa565b9050919050565b6102d7816102bc565b81146102e257600080fd5b50565b6000813590506102f4816102ce565b92915050565b6000819050919050565b61030d816102fa565b811461031857600080fd5b50565b60008135905061032a81610304565b92915050565b600080600080600080600060a0888a03121561034f5761034e61021b565b5b600088013567ffffffffffffffff81111561036d5761036c610220565b5b6103798a828b01610234565b9750975050602061038c8a828b016102e5565b955050604061039d8a828b0161031b565b945050606088013567ffffffffffffffff8111156103be576103bd610220565b5b6103ca8a828b01610234565b935093505060806103dd8a828b0161031b565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610426826102fa565b9150610431836102fa565b925082820261043f816102fa565b91508282048414831517610456576104556103ec565b5b5092915050565b610466816102aa565b82525050565b610475816102fa565b82525050565b6000606082019050610490600083018661045d565b61049d602083018561045d565b6104aa604083018461046c565b949350505050565b60006040820190506104c7600083018561045d565b6104d4602083018461046c565b9392505050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061051883856104db565b93506105258385846104ec565b61052e836104fb565b840190509392505050565b6000819050919050565b600061055e6105596105548461028a565b610539565b61028a565b9050919050565b600061057082610543565b9050919050565b600061058282610565565b9050919050565b61059281610577565b82525050565b600060808201905081810360008301526105b381888a61050c565b90506105c26020830187610589565b6105cf604083018661046c565b81810360608301526105e281848661050c565b9050979650505050505050565b60006105fa826102fa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361062c5761062b6103ec565b5b60018201905091905056fea264697066735822122052c5caf083af6e05e3cd0c0e628630fe7cba46565021425413eabeb4a56b4b5464736f6c63430008150033", +} + +// DepositorABI is the input ABI used to generate the binding from. +// Deprecated: Use DepositorMetaData.ABI instead. +var DepositorABI = DepositorMetaData.ABI + +// DepositorBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use DepositorMetaData.Bin instead. +var DepositorBin = DepositorMetaData.Bin + +// DeployDepositor deploys a new Ethereum contract, binding an instance of Depositor to it. +func DeployDepositor(auth *bind.TransactOpts, backend bind.ContractBackend, custody_ common.Address) (common.Address, *types.Transaction, *Depositor, error) { + parsed, err := DepositorMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DepositorBin), backend, custody_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Depositor{DepositorCaller: DepositorCaller{contract: contract}, DepositorTransactor: DepositorTransactor{contract: contract}, DepositorFilterer: DepositorFilterer{contract: contract}}, nil +} + +// Depositor is an auto generated Go binding around an Ethereum contract. +type Depositor struct { + DepositorCaller // Read-only binding to the contract + DepositorTransactor // Write-only binding to the contract + DepositorFilterer // Log filterer for contract events +} + +// DepositorCaller is an auto generated read-only Go binding around an Ethereum contract. +type DepositorCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DepositorTransactor is an auto generated write-only Go binding around an Ethereum contract. +type DepositorTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DepositorFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type DepositorFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// DepositorSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type DepositorSession struct { + Contract *Depositor // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// DepositorCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type DepositorCallerSession struct { + Contract *DepositorCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// DepositorTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type DepositorTransactorSession struct { + Contract *DepositorTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// DepositorRaw is an auto generated low-level Go binding around an Ethereum contract. +type DepositorRaw struct { + Contract *Depositor // Generic contract binding to access the raw methods on +} + +// DepositorCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type DepositorCallerRaw struct { + Contract *DepositorCaller // Generic read-only contract binding to access the raw methods on +} + +// DepositorTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type DepositorTransactorRaw struct { + Contract *DepositorTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewDepositor creates a new instance of Depositor, bound to a specific deployed contract. +func NewDepositor(address common.Address, backend bind.ContractBackend) (*Depositor, error) { + contract, err := bindDepositor(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Depositor{DepositorCaller: DepositorCaller{contract: contract}, DepositorTransactor: DepositorTransactor{contract: contract}, DepositorFilterer: DepositorFilterer{contract: contract}}, nil +} + +// NewDepositorCaller creates a new read-only instance of Depositor, bound to a specific deployed contract. +func NewDepositorCaller(address common.Address, caller bind.ContractCaller) (*DepositorCaller, error) { + contract, err := bindDepositor(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &DepositorCaller{contract: contract}, nil +} + +// NewDepositorTransactor creates a new write-only instance of Depositor, bound to a specific deployed contract. +func NewDepositorTransactor(address common.Address, transactor bind.ContractTransactor) (*DepositorTransactor, error) { + contract, err := bindDepositor(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &DepositorTransactor{contract: contract}, nil +} + +// NewDepositorFilterer creates a new log filterer instance of Depositor, bound to a specific deployed contract. +func NewDepositorFilterer(address common.Address, filterer bind.ContractFilterer) (*DepositorFilterer, error) { + contract, err := bindDepositor(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &DepositorFilterer{contract: contract}, nil +} + +// bindDepositor binds a generic wrapper to an already deployed contract. +func bindDepositor(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := DepositorMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Depositor *DepositorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Depositor.Contract.DepositorCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Depositor *DepositorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Depositor.Contract.DepositorTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Depositor *DepositorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Depositor.Contract.DepositorTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Depositor *DepositorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Depositor.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Depositor *DepositorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Depositor.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Depositor *DepositorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Depositor.Contract.contract.Transact(opts, method, params...) +} + +// RunDeposits is a paid mutator transaction binding the contract method 0x3d496c93. +// +// Solidity: function runDeposits(bytes recipient, address asset, uint256 amount, bytes message, uint256 count) returns() +func (_Depositor *DepositorTransactor) RunDeposits(opts *bind.TransactOpts, recipient []byte, asset common.Address, amount *big.Int, message []byte, count *big.Int) (*types.Transaction, error) { + return _Depositor.contract.Transact(opts, "runDeposits", recipient, asset, amount, message, count) +} + +// RunDeposits is a paid mutator transaction binding the contract method 0x3d496c93. +// +// Solidity: function runDeposits(bytes recipient, address asset, uint256 amount, bytes message, uint256 count) returns() +func (_Depositor *DepositorSession) RunDeposits(recipient []byte, asset common.Address, amount *big.Int, message []byte, count *big.Int) (*types.Transaction, error) { + return _Depositor.Contract.RunDeposits(&_Depositor.TransactOpts, recipient, asset, amount, message, count) +} + +// RunDeposits is a paid mutator transaction binding the contract method 0x3d496c93. +// +// Solidity: function runDeposits(bytes recipient, address asset, uint256 amount, bytes message, uint256 count) returns() +func (_Depositor *DepositorTransactorSession) RunDeposits(recipient []byte, asset common.Address, amount *big.Int, message []byte, count *big.Int) (*types.Transaction, error) { + return _Depositor.Contract.RunDeposits(&_Depositor.TransactOpts, recipient, asset, amount, message, count) +} diff --git a/testutil/contracts/Depositor.json b/testutil/contracts/Depositor.json new file mode 100644 index 0000000000..0cd3488806 --- /dev/null +++ b/testutil/contracts/Depositor.json @@ -0,0 +1,49 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "custody_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "recipient", + "type": "bytes" + }, + { + "internalType": "contract IERC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "message", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "runDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "60a060405234801561001057600080fd5b5060405161078a38038061078a833981810160405281019061003291906100cf565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506100fc565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061009c82610071565b9050919050565b6100ac81610091565b81146100b757600080fd5b50565b6000815190506100c9816100a3565b92915050565b6000602082840312156100e5576100e461006c565b5b60006100f3848285016100ba565b91505092915050565b60805161066d61011d6000396000818160e4015261016b015261066d6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80633d496c9314610030575b600080fd5b61004a60048036038101906100459190610330565b61004c565b005b8473ffffffffffffffffffffffffffffffffffffffff166323b872dd33308488610076919061041b565b6040518463ffffffff1660e01b81526004016100949392919061047b565b600060405180830381600087803b1580156100ae57600080fd5b505af11580156100c2573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f0000000000000000000000000000000000000000000000000000000000000000838761010f919061041b565b6040518363ffffffff1660e01b815260040161012c9291906104b2565b600060405180830381600087803b15801561014657600080fd5b505af115801561015a573d6000803e3d6000fd5b5050505060005b81811015610211577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e609055e8989898989896040518763ffffffff1660e01b81526004016101cc96959493929190610598565b600060405180830381600087803b1580156101e657600080fd5b505af11580156101fa573d6000803e3d6000fd5b505050508080610209906105ef565b915050610161565b5050505050505050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f84011261024a57610249610225565b5b8235905067ffffffffffffffff8111156102675761026661022a565b5b6020830191508360018202830111156102835761028261022f565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102b58261028a565b9050919050565b60006102c7826102aa565b9050919050565b6102d7816102bc565b81146102e257600080fd5b50565b6000813590506102f4816102ce565b92915050565b6000819050919050565b61030d816102fa565b811461031857600080fd5b50565b60008135905061032a81610304565b92915050565b600080600080600080600060a0888a03121561034f5761034e61021b565b5b600088013567ffffffffffffffff81111561036d5761036c610220565b5b6103798a828b01610234565b9750975050602061038c8a828b016102e5565b955050604061039d8a828b0161031b565b945050606088013567ffffffffffffffff8111156103be576103bd610220565b5b6103ca8a828b01610234565b935093505060806103dd8a828b0161031b565b91505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610426826102fa565b9150610431836102fa565b925082820261043f816102fa565b91508282048414831517610456576104556103ec565b5b5092915050565b610466816102aa565b82525050565b610475816102fa565b82525050565b6000606082019050610490600083018661045d565b61049d602083018561045d565b6104aa604083018461046c565b949350505050565b60006040820190506104c7600083018561045d565b6104d4602083018461046c565b9392505050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061051883856104db565b93506105258385846104ec565b61052e836104fb565b840190509392505050565b6000819050919050565b600061055e6105596105548461028a565b610539565b61028a565b9050919050565b600061057082610543565b9050919050565b600061058282610565565b9050919050565b61059281610577565b82525050565b600060808201905081810360008301526105b381888a61050c565b90506105c26020830187610589565b6105cf604083018661046c565b81810360608301526105e281848661050c565b9050979650505050505050565b60006105fa826102fa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361062c5761062b6103ec565b5b60018201905091905056fea264697066735822122052c5caf083af6e05e3cd0c0e628630fe7cba46565021425413eabeb4a56b4b5464736f6c63430008150033" +} diff --git a/testutil/contracts/Depositor.sol b/testutil/contracts/Depositor.sol new file mode 100644 index 0000000000..15163a5973 --- /dev/null +++ b/testutil/contracts/Depositor.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + +interface IERC20 { + function approve(address spender, uint256 amount) external; + function transferFrom(address sender, address recipient, uint256 amount) external; +} + +interface ERC20Custody { + function deposit( + bytes calldata recipient, + IERC20 asset, + uint256 amount, + bytes calldata message + ) external; +} + +// Sample contract for running deposit on EVM +contract Depositor { + ERC20Custody immutable private _custody; + + constructor(address custody_) { + _custody = ERC20Custody(custody_); + } + + // Run n deposits of amount on asset to custody + function runDeposits( + bytes calldata recipient, + IERC20 asset, + uint256 amount, + bytes calldata message, + uint256 count + ) external { + asset.transferFrom(msg.sender, address(this), amount * count); + asset.approve(address(_custody), amount * count); + for (uint256 i = 0; i < count; i++) { + _custody.deposit(recipient, asset, amount, message); + } + } +} \ No newline at end of file diff --git a/testutil/contracts/Withdrawer.abi b/testutil/contracts/Withdrawer.abi new file mode 100644 index 0000000000..407b59e1a9 --- /dev/null +++ b/testutil/contracts/Withdrawer.abi @@ -0,0 +1,30 @@ +[ + { + "inputs": [ + { + "internalType": "bytes", + "name": "recipient", + "type": "bytes" + }, + { + "internalType": "contract IZRC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "runWithdraws", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/testutil/contracts/Withdrawer.bin b/testutil/contracts/Withdrawer.bin new file mode 100644 index 0000000000..3d5994f09b --- /dev/null +++ b/testutil/contracts/Withdrawer.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5061075a806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063e3be6f6814610030575b600080fd5b61004a600480360381019061004591906103ef565b61004c565b005b6000808473ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b815260040160408051808303816000875af115801561009b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bf91906104b8565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3330600a856100ee9190610527565b6040518463ffffffff1660e01b815260040161010c93929190610587565b600060405180830381600087803b15801561012657600080fd5b505af115801561013a573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663095ea7b386600a846101689190610527565b6040518363ffffffff1660e01b81526004016101859291906105be565b600060405180830381600087803b15801561019f57600080fd5b505af11580156101b3573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff166323b872dd333086886101e19190610527565b6040518463ffffffff1660e01b81526004016101ff93929190610587565b600060405180830381600087803b15801561021957600080fd5b505af115801561022d573d6000803e3d6000fd5b5050505060005b838110156102d0578573ffffffffffffffffffffffffffffffffffffffff1663c70126268989886040518463ffffffff1660e01b815260040161027993929190610645565b6020604051808303816000875af1158015610298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102bc91906106af565b5080806102c8906106dc565b915050610234565b5050505050505050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112610309576103086102e4565b5b8235905067ffffffffffffffff811115610326576103256102e9565b5b602083019150836001820283011115610342576103416102ee565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061037482610349565b9050919050565b600061038682610369565b9050919050565b6103968161037b565b81146103a157600080fd5b50565b6000813590506103b38161038d565b92915050565b6000819050919050565b6103cc816103b9565b81146103d757600080fd5b50565b6000813590506103e9816103c3565b92915050565b60008060008060006080868803121561040b5761040a6102da565b5b600086013567ffffffffffffffff811115610429576104286102df565b5b610435888289016102f3565b95509550506020610448888289016103a4565b9350506040610459888289016103da565b925050606061046a888289016103da565b9150509295509295909350565b61048081610369565b811461048b57600080fd5b50565b60008151905061049d81610477565b92915050565b6000815190506104b2816103c3565b92915050565b600080604083850312156104cf576104ce6102da565b5b60006104dd8582860161048e565b92505060206104ee858286016104a3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610532826103b9565b915061053d836103b9565b925082820261054b816103b9565b91508282048414831517610562576105616104f8565b5b5092915050565b61057281610369565b82525050565b610581816103b9565b82525050565b600060608201905061059c6000830186610569565b6105a96020830185610569565b6105b66040830184610578565b949350505050565b60006040820190506105d36000830185610569565b6105e06020830184610578565b9392505050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061062483856105e7565b93506106318385846105f8565b61063a83610607565b840190509392505050565b60006040820190508181036000830152610660818587610618565b905061066f6020830184610578565b949350505050565b60008115159050919050565b61068c81610677565b811461069757600080fd5b50565b6000815190506106a981610683565b92915050565b6000602082840312156106c5576106c46102da565b5b60006106d38482850161069a565b91505092915050565b60006106e7826103b9565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610719576107186104f8565b5b60018201905091905056fea2646970667358221220facf63a05707c7ee9b4b53c5ddd9a2d42e779dd5790d95ba8e4526d32232b9d664736f6c63430008150033 diff --git a/testutil/contracts/Withdrawer.go b/testutil/contracts/Withdrawer.go new file mode 100644 index 0000000000..1c4e5f4350 --- /dev/null +++ b/testutil/contracts/Withdrawer.go @@ -0,0 +1,224 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// WithdrawerMetaData contains all meta data concerning the Withdrawer contract. +var WithdrawerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"recipient\",\"type\":\"bytes\"},{\"internalType\":\"contractIZRC20\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"runWithdraws\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b5061075a806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063e3be6f6814610030575b600080fd5b61004a600480360381019061004591906103ef565b61004c565b005b6000808473ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b815260040160408051808303816000875af115801561009b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bf91906104b8565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3330600a856100ee9190610527565b6040518463ffffffff1660e01b815260040161010c93929190610587565b600060405180830381600087803b15801561012657600080fd5b505af115801561013a573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663095ea7b386600a846101689190610527565b6040518363ffffffff1660e01b81526004016101859291906105be565b600060405180830381600087803b15801561019f57600080fd5b505af11580156101b3573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff166323b872dd333086886101e19190610527565b6040518463ffffffff1660e01b81526004016101ff93929190610587565b600060405180830381600087803b15801561021957600080fd5b505af115801561022d573d6000803e3d6000fd5b5050505060005b838110156102d0578573ffffffffffffffffffffffffffffffffffffffff1663c70126268989886040518463ffffffff1660e01b815260040161027993929190610645565b6020604051808303816000875af1158015610298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102bc91906106af565b5080806102c8906106dc565b915050610234565b5050505050505050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112610309576103086102e4565b5b8235905067ffffffffffffffff811115610326576103256102e9565b5b602083019150836001820283011115610342576103416102ee565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061037482610349565b9050919050565b600061038682610369565b9050919050565b6103968161037b565b81146103a157600080fd5b50565b6000813590506103b38161038d565b92915050565b6000819050919050565b6103cc816103b9565b81146103d757600080fd5b50565b6000813590506103e9816103c3565b92915050565b60008060008060006080868803121561040b5761040a6102da565b5b600086013567ffffffffffffffff811115610429576104286102df565b5b610435888289016102f3565b95509550506020610448888289016103a4565b9350506040610459888289016103da565b925050606061046a888289016103da565b9150509295509295909350565b61048081610369565b811461048b57600080fd5b50565b60008151905061049d81610477565b92915050565b6000815190506104b2816103c3565b92915050565b600080604083850312156104cf576104ce6102da565b5b60006104dd8582860161048e565b92505060206104ee858286016104a3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610532826103b9565b915061053d836103b9565b925082820261054b816103b9565b91508282048414831517610562576105616104f8565b5b5092915050565b61057281610369565b82525050565b610581816103b9565b82525050565b600060608201905061059c6000830186610569565b6105a96020830185610569565b6105b66040830184610578565b949350505050565b60006040820190506105d36000830185610569565b6105e06020830184610578565b9392505050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061062483856105e7565b93506106318385846105f8565b61063a83610607565b840190509392505050565b60006040820190508181036000830152610660818587610618565b905061066f6020830184610578565b949350505050565b60008115159050919050565b61068c81610677565b811461069757600080fd5b50565b6000815190506106a981610683565b92915050565b6000602082840312156106c5576106c46102da565b5b60006106d38482850161069a565b91505092915050565b60006106e7826103b9565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610719576107186104f8565b5b60018201905091905056fea2646970667358221220facf63a05707c7ee9b4b53c5ddd9a2d42e779dd5790d95ba8e4526d32232b9d664736f6c63430008150033", +} + +// WithdrawerABI is the input ABI used to generate the binding from. +// Deprecated: Use WithdrawerMetaData.ABI instead. +var WithdrawerABI = WithdrawerMetaData.ABI + +// WithdrawerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use WithdrawerMetaData.Bin instead. +var WithdrawerBin = WithdrawerMetaData.Bin + +// DeployWithdrawer deploys a new Ethereum contract, binding an instance of Withdrawer to it. +func DeployWithdrawer(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Withdrawer, error) { + parsed, err := WithdrawerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(WithdrawerBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Withdrawer{WithdrawerCaller: WithdrawerCaller{contract: contract}, WithdrawerTransactor: WithdrawerTransactor{contract: contract}, WithdrawerFilterer: WithdrawerFilterer{contract: contract}}, nil +} + +// Withdrawer is an auto generated Go binding around an Ethereum contract. +type Withdrawer struct { + WithdrawerCaller // Read-only binding to the contract + WithdrawerTransactor // Write-only binding to the contract + WithdrawerFilterer // Log filterer for contract events +} + +// WithdrawerCaller is an auto generated read-only Go binding around an Ethereum contract. +type WithdrawerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// WithdrawerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type WithdrawerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// WithdrawerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type WithdrawerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// WithdrawerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type WithdrawerSession struct { + Contract *Withdrawer // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// WithdrawerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type WithdrawerCallerSession struct { + Contract *WithdrawerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// WithdrawerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type WithdrawerTransactorSession struct { + Contract *WithdrawerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// WithdrawerRaw is an auto generated low-level Go binding around an Ethereum contract. +type WithdrawerRaw struct { + Contract *Withdrawer // Generic contract binding to access the raw methods on +} + +// WithdrawerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type WithdrawerCallerRaw struct { + Contract *WithdrawerCaller // Generic read-only contract binding to access the raw methods on +} + +// WithdrawerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type WithdrawerTransactorRaw struct { + Contract *WithdrawerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewWithdrawer creates a new instance of Withdrawer, bound to a specific deployed contract. +func NewWithdrawer(address common.Address, backend bind.ContractBackend) (*Withdrawer, error) { + contract, err := bindWithdrawer(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Withdrawer{WithdrawerCaller: WithdrawerCaller{contract: contract}, WithdrawerTransactor: WithdrawerTransactor{contract: contract}, WithdrawerFilterer: WithdrawerFilterer{contract: contract}}, nil +} + +// NewWithdrawerCaller creates a new read-only instance of Withdrawer, bound to a specific deployed contract. +func NewWithdrawerCaller(address common.Address, caller bind.ContractCaller) (*WithdrawerCaller, error) { + contract, err := bindWithdrawer(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &WithdrawerCaller{contract: contract}, nil +} + +// NewWithdrawerTransactor creates a new write-only instance of Withdrawer, bound to a specific deployed contract. +func NewWithdrawerTransactor(address common.Address, transactor bind.ContractTransactor) (*WithdrawerTransactor, error) { + contract, err := bindWithdrawer(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &WithdrawerTransactor{contract: contract}, nil +} + +// NewWithdrawerFilterer creates a new log filterer instance of Withdrawer, bound to a specific deployed contract. +func NewWithdrawerFilterer(address common.Address, filterer bind.ContractFilterer) (*WithdrawerFilterer, error) { + contract, err := bindWithdrawer(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &WithdrawerFilterer{contract: contract}, nil +} + +// bindWithdrawer binds a generic wrapper to an already deployed contract. +func bindWithdrawer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := WithdrawerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Withdrawer *WithdrawerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Withdrawer.Contract.WithdrawerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Withdrawer *WithdrawerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Withdrawer.Contract.WithdrawerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Withdrawer *WithdrawerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Withdrawer.Contract.WithdrawerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Withdrawer *WithdrawerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Withdrawer.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Withdrawer *WithdrawerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Withdrawer.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Withdrawer *WithdrawerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Withdrawer.Contract.contract.Transact(opts, method, params...) +} + +// RunWithdraws is a paid mutator transaction binding the contract method 0xe3be6f68. +// +// Solidity: function runWithdraws(bytes recipient, address asset, uint256 amount, uint256 count) returns() +func (_Withdrawer *WithdrawerTransactor) RunWithdraws(opts *bind.TransactOpts, recipient []byte, asset common.Address, amount *big.Int, count *big.Int) (*types.Transaction, error) { + return _Withdrawer.contract.Transact(opts, "runWithdraws", recipient, asset, amount, count) +} + +// RunWithdraws is a paid mutator transaction binding the contract method 0xe3be6f68. +// +// Solidity: function runWithdraws(bytes recipient, address asset, uint256 amount, uint256 count) returns() +func (_Withdrawer *WithdrawerSession) RunWithdraws(recipient []byte, asset common.Address, amount *big.Int, count *big.Int) (*types.Transaction, error) { + return _Withdrawer.Contract.RunWithdraws(&_Withdrawer.TransactOpts, recipient, asset, amount, count) +} + +// RunWithdraws is a paid mutator transaction binding the contract method 0xe3be6f68. +// +// Solidity: function runWithdraws(bytes recipient, address asset, uint256 amount, uint256 count) returns() +func (_Withdrawer *WithdrawerTransactorSession) RunWithdraws(recipient []byte, asset common.Address, amount *big.Int, count *big.Int) (*types.Transaction, error) { + return _Withdrawer.Contract.RunWithdraws(&_Withdrawer.TransactOpts, recipient, asset, amount, count) +} diff --git a/testutil/contracts/Withdrawer.json b/testutil/contracts/Withdrawer.json new file mode 100644 index 0000000000..eaedb8b992 --- /dev/null +++ b/testutil/contracts/Withdrawer.json @@ -0,0 +1,33 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "bytes", + "name": "recipient", + "type": "bytes" + }, + { + "internalType": "contract IZRC20", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "runWithdraws", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bin": "608060405234801561001057600080fd5b5061075a806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063e3be6f6814610030575b600080fd5b61004a600480360381019061004591906103ef565b61004c565b005b6000808473ffffffffffffffffffffffffffffffffffffffff1663d9eeebed6040518163ffffffff1660e01b815260040160408051808303816000875af115801561009b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bf91906104b8565b915091508173ffffffffffffffffffffffffffffffffffffffff166323b872dd3330600a856100ee9190610527565b6040518463ffffffff1660e01b815260040161010c93929190610587565b600060405180830381600087803b15801561012657600080fd5b505af115801561013a573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663095ea7b386600a846101689190610527565b6040518363ffffffff1660e01b81526004016101859291906105be565b600060405180830381600087803b15801561019f57600080fd5b505af11580156101b3573d6000803e3d6000fd5b505050508473ffffffffffffffffffffffffffffffffffffffff166323b872dd333086886101e19190610527565b6040518463ffffffff1660e01b81526004016101ff93929190610587565b600060405180830381600087803b15801561021957600080fd5b505af115801561022d573d6000803e3d6000fd5b5050505060005b838110156102d0578573ffffffffffffffffffffffffffffffffffffffff1663c70126268989886040518463ffffffff1660e01b815260040161027993929190610645565b6020604051808303816000875af1158015610298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102bc91906106af565b5080806102c8906106dc565b915050610234565b5050505050505050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112610309576103086102e4565b5b8235905067ffffffffffffffff811115610326576103256102e9565b5b602083019150836001820283011115610342576103416102ee565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061037482610349565b9050919050565b600061038682610369565b9050919050565b6103968161037b565b81146103a157600080fd5b50565b6000813590506103b38161038d565b92915050565b6000819050919050565b6103cc816103b9565b81146103d757600080fd5b50565b6000813590506103e9816103c3565b92915050565b60008060008060006080868803121561040b5761040a6102da565b5b600086013567ffffffffffffffff811115610429576104286102df565b5b610435888289016102f3565b95509550506020610448888289016103a4565b9350506040610459888289016103da565b925050606061046a888289016103da565b9150509295509295909350565b61048081610369565b811461048b57600080fd5b50565b60008151905061049d81610477565b92915050565b6000815190506104b2816103c3565b92915050565b600080604083850312156104cf576104ce6102da565b5b60006104dd8582860161048e565b92505060206104ee858286016104a3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610532826103b9565b915061053d836103b9565b925082820261054b816103b9565b91508282048414831517610562576105616104f8565b5b5092915050565b61057281610369565b82525050565b610581816103b9565b82525050565b600060608201905061059c6000830186610569565b6105a96020830185610569565b6105b66040830184610578565b949350505050565b60006040820190506105d36000830185610569565b6105e06020830184610578565b9392505050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b600061062483856105e7565b93506106318385846105f8565b61063a83610607565b840190509392505050565b60006040820190508181036000830152610660818587610618565b905061066f6020830184610578565b949350505050565b60008115159050919050565b61068c81610677565b811461069757600080fd5b50565b6000815190506106a981610683565b92915050565b6000602082840312156106c5576106c46102da565b5b60006106d38482850161069a565b91505092915050565b60006106e7826103b9565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610719576107186104f8565b5b60018201905091905056fea2646970667358221220facf63a05707c7ee9b4b53c5ddd9a2d42e779dd5790d95ba8e4526d32232b9d664736f6c63430008150033" +} diff --git a/testutil/contracts/Withdrawer.sol b/testutil/contracts/Withdrawer.sol new file mode 100644 index 0000000000..cc19e29391 --- /dev/null +++ b/testutil/contracts/Withdrawer.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + +interface IZRC20 { + function approve(address spender, uint256 amount) external; + function transferFrom(address sender, address recipient, uint256 amount) external; + function withdraw(bytes memory to, uint256 amount) external returns (bool); + function withdrawGasFee() external returns (address, uint256); +} + +// Sample contract for running withdraw on zEVM +contract Withdrawer { + // Run n withdraws of amount on asset to custody + function runWithdraws( + bytes calldata recipient, + IZRC20 asset, + uint256 amount, + uint256 count + ) external { + // transfer gas for the transactions and approve it in the zrc20 + (address gas, uint256 gasFee) = asset.withdrawGasFee(); + IZRC20(gas).transferFrom(msg.sender, address(this), gasFee * 10); + IZRC20(gas).approve(address(asset), gasFee * 10); + + // perform the withdraws + asset.transferFrom(msg.sender, address(this), amount * count); + for (uint256 i = 0; i < count; i++) { + asset.withdraw(recipient, amount); + } + } +} \ No newline at end of file diff --git a/testutil/contracts/bindings.go b/testutil/contracts/bindings.go index bb64d01778..88052fa2b2 100644 --- a/testutil/contracts/bindings.go +++ b/testutil/contracts/bindings.go @@ -10,4 +10,16 @@ //go:generate sh -c "cat Reverter.json | jq .bin | tr -d '\"' > Reverter.bin" //go:generate sh -c "abigen --abi Reverter.abi --bin Reverter.bin --pkg contracts --type Reverter --out Reverter.go" +// Depositor +//go:generate sh -c "solc --evm-version paris Depositor.sol --combined-json abi,bin | jq '.contracts.\"Depositor.sol:Depositor\"' > Depositor.json" +//go:generate sh -c "cat Depositor.json | jq .abi > Depositor.abi" +//go:generate sh -c "cat Depositor.json | jq .bin | tr -d '\"' > Depositor.bin" +//go:generate sh -c "abigen --abi Depositor.abi --bin Depositor.bin --pkg contracts --type Depositor --out Depositor.go" + +// Withdrawer +//go:generate sh -c "solc --evm-version paris Withdrawer.sol --combined-json abi,bin | jq '.contracts.\"Withdrawer.sol:Withdrawer\"' > Withdrawer.json" +//go:generate sh -c "cat Withdrawer.json | jq .abi > Withdrawer.abi" +//go:generate sh -c "cat Withdrawer.json | jq .bin | tr -d '\"' > Withdrawer.bin" +//go:generate sh -c "abigen --abi Withdrawer.abi --bin Withdrawer.bin --pkg contracts --type Withdrawer --out Withdrawer.go" + package contracts diff --git a/typescript/crosschain/tx_pb.d.ts b/typescript/crosschain/tx_pb.d.ts index 98f7fd5c3a..23ed750398 100644 --- a/typescript/crosschain/tx_pb.d.ts +++ b/typescript/crosschain/tx_pb.d.ts @@ -742,6 +742,13 @@ export declare class MsgVoteOnObservedInboundTx extends Message); static readonly runtime: typeof proto3; diff --git a/x/crosschain/client/cli/cli_cctx.go b/x/crosschain/client/cli/cli_cctx.go index 070764ca44..b97bc649f2 100644 --- a/x/crosschain/client/cli/cli_cctx.go +++ b/x/crosschain/client/cli/cli_cctx.go @@ -113,9 +113,10 @@ func CmdShowSend() *cobra.Command { func CmdCCTXInboundVoter() *cobra.Command { cmd := &cobra.Command{ - Use: "inbound-voter [sender] [senderChainID] [txOrigin] [receiver] [receiverChainID] [amount] [message] [inTxHash] [inBlockHeight] [coinType] [asset]", + Use: "inbound-voter [sender] [senderChainID] [txOrigin] [receiver] [receiverChainID] [amount] [message" + + "] [inTxHash] [inBlockHeight] [coinType] [asset] [eventIndex]", Short: "Broadcast message sendVoter", - Args: cobra.ExactArgs(11), + Args: cobra.ExactArgs(12), RunE: func(cmd *cobra.Command, args []string) error { argsSender := args[0] argsSenderChain, err := strconv.ParseInt(args[1], 10, 64) @@ -147,6 +148,12 @@ func CmdCCTXInboundVoter() *cobra.Command { argsAsset := args[10] + // parse argsp[11] to uint type and not uint64 + argsEventIndex, err := strconv.ParseUint(args[11], 10, 32) + if err != nil { + return err + } + clientCtx, err := client.GetClientTxContext(cmd) if err != nil { return err @@ -166,6 +173,7 @@ func CmdCCTXInboundVoter() *cobra.Command { 250_000, argsCoinType, argsAsset, + uint(argsEventIndex), ) if err := msg.ValidateBasic(); err != nil { return err diff --git a/x/crosschain/client/integrationtests/cli_helpers.go b/x/crosschain/client/integrationtests/cli_helpers.go index e86f1021c5..eee042daf5 100644 --- a/x/crosschain/client/integrationtests/cli_helpers.go +++ b/x/crosschain/client/integrationtests/cli_helpers.go @@ -169,6 +169,7 @@ func BuildSignedInboundVote(t testing.TB, val *network.Validator, denom string, "100", "Zeta", "", + "0", } txArgs := []string{ fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), @@ -201,6 +202,7 @@ func GetBallotIdentifier(message string) string { 250_000, common.CoinType_Zeta, "", + 0, ) return msg.Digest() } diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index c575598cf1..a3f4dc5eee 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -147,9 +147,10 @@ func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20W "", event.Raw.TxHash.String(), event.Raw.BlockNumber, - gasLimit.Uint64()+uint64(event.Raw.Index), + gasLimit.Uint64(), foreignCoin.CoinType, foreignCoin.Asset, + event.Raw.Index, ) sendHash := msg.Digest() @@ -220,9 +221,10 @@ func (k Keeper) ProcessZetaSentEvent(ctx sdk.Context, event *connectorzevm.ZetaC "", event.Raw.TxHash.String(), event.Raw.BlockNumber, - 90000+uint64(event.Raw.Index), + 90000, common.CoinType_Zeta, "", + event.Raw.Index, ) sendHash := msg.Digest() diff --git a/x/crosschain/types/messages_migrate_tss_funds.go b/x/crosschain/types/message_migrate_tss_funds.go similarity index 100% rename from x/crosschain/types/messages_migrate_tss_funds.go rename to x/crosschain/types/message_migrate_tss_funds.go diff --git a/x/crosschain/types/messages_migrate_tss_funds_test.go b/x/crosschain/types/message_migrate_tss_funds_test.go similarity index 100% rename from x/crosschain/types/messages_migrate_tss_funds_test.go rename to x/crosschain/types/message_migrate_tss_funds_test.go diff --git a/x/crosschain/types/messages_tss_voter.go b/x/crosschain/types/message_tss_voter.go similarity index 100% rename from x/crosschain/types/messages_tss_voter.go rename to x/crosschain/types/message_tss_voter.go diff --git a/x/crosschain/types/messages_update_tss_address.go b/x/crosschain/types/message_update_tss_address.go similarity index 100% rename from x/crosschain/types/messages_update_tss_address.go rename to x/crosschain/types/message_update_tss_address.go diff --git a/x/crosschain/types/message_vote_on_observed_inbound_tx.go b/x/crosschain/types/message_vote_on_observed_inbound_tx.go index 12da3a6963..b94b0567a4 100644 --- a/x/crosschain/types/message_vote_on_observed_inbound_tx.go +++ b/x/crosschain/types/message_vote_on_observed_inbound_tx.go @@ -30,6 +30,7 @@ func NewMsgVoteOnObservedInboundTx( gasLimit uint64, coinType common.CoinType, asset string, + eventIndex uint, ) *MsgVoteOnObservedInboundTx { return &MsgVoteOnObservedInboundTx{ Creator: creator, @@ -45,6 +46,7 @@ func NewMsgVoteOnObservedInboundTx( GasLimit: gasLimit, CoinType: coinType, Asset: asset, + EventIndex: uint64(eventIndex), } } diff --git a/x/crosschain/types/message_vote_on_observed_inbound_tx_test.go b/x/crosschain/types/message_vote_on_observed_inbound_tx_test.go index 9fba3d71bb..777fb6f244 100644 --- a/x/crosschain/types/message_vote_on_observed_inbound_tx_test.go +++ b/x/crosschain/types/message_vote_on_observed_inbound_tx_test.go @@ -37,6 +37,7 @@ func TestMsgVoteOnObservedInboundTx_ValidateBasic(t *testing.T) { GasLimit: 42, CoinType: common.CoinType_Zeta, Asset: sample.String(), + EventIndex: 42, }, }, { @@ -55,6 +56,7 @@ func TestMsgVoteOnObservedInboundTx_ValidateBasic(t *testing.T) { GasLimit: 42, CoinType: common.CoinType_Zeta, Asset: sample.String(), + EventIndex: 42, }, err: sdkerrors.ErrInvalidAddress, }, @@ -74,6 +76,7 @@ func TestMsgVoteOnObservedInboundTx_ValidateBasic(t *testing.T) { GasLimit: 42, CoinType: common.CoinType_Zeta, Asset: sample.String(), + EventIndex: 42, }, err: types.ErrInvalidChainID, }, @@ -93,6 +96,7 @@ func TestMsgVoteOnObservedInboundTx_ValidateBasic(t *testing.T) { GasLimit: 42, CoinType: common.CoinType_Zeta, Asset: sample.String(), + EventIndex: 42, }, err: types.ErrInvalidChainID, }, @@ -112,6 +116,7 @@ func TestMsgVoteOnObservedInboundTx_ValidateBasic(t *testing.T) { GasLimit: 42, CoinType: common.CoinType_Zeta, Asset: sample.String(), + EventIndex: 42, }, err: sdkerrors.ErrInvalidRequest, }, @@ -145,6 +150,7 @@ func TestMsgVoteOnObservedInboundTx_Digest(t *testing.T) { GasLimit: 42, CoinType: common.CoinType_Zeta, Asset: sample.String(), + EventIndex: 42, } hash := msg.Digest() require.NotEmpty(t, hash, "hash should not be empty") @@ -226,4 +232,10 @@ func TestMsgVoteOnObservedInboundTx_Digest(t *testing.T) { msg2.Asset = sample.StringRandom(r, 32) hash2 = msg2.Digest() require.NotEqual(t, hash, hash2, "asset should change hash") + + // event index used + msg2 = msg + msg2.EventIndex = 43 + hash2 = msg2.Digest() + require.NotEqual(t, hash, hash2, "event index should change hash") } diff --git a/x/crosschain/types/tx.pb.go b/x/crosschain/types/tx.pb.go index a5615c8450..0e789fcb04 100644 --- a/x/crosschain/types/tx.pb.go +++ b/x/crosschain/types/tx.pb.go @@ -1194,6 +1194,8 @@ type MsgVoteOnObservedInboundTx struct { CoinType common.CoinType `protobuf:"varint,12,opt,name=coin_type,json=coinType,proto3,enum=common.CoinType" json:"coin_type,omitempty"` TxOrigin string `protobuf:"bytes,13,opt,name=tx_origin,json=txOrigin,proto3" json:"tx_origin,omitempty"` Asset string `protobuf:"bytes,14,opt,name=asset,proto3" json:"asset,omitempty"` + // event index of the sent asset in the observed tx + EventIndex uint64 `protobuf:"varint,15,opt,name=event_index,json=eventIndex,proto3" json:"event_index,omitempty"` } func (m *MsgVoteOnObservedInboundTx) Reset() { *m = MsgVoteOnObservedInboundTx{} } @@ -1313,6 +1315,13 @@ func (m *MsgVoteOnObservedInboundTx) GetAsset() string { return "" } +func (m *MsgVoteOnObservedInboundTx) GetEventIndex() uint64 { + if m != nil { + return m.EventIndex + } + return 0 +} + type MsgVoteOnObservedInboundTxResponse struct { } @@ -1475,101 +1484,102 @@ func init() { func init() { proto.RegisterFile("crosschain/tx.proto", fileDescriptor_81d6d611190b7635) } var fileDescriptor_81d6d611190b7635 = []byte{ - // 1504 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcd, 0x6e, 0xdb, 0xc6, - 0x16, 0x36, 0xaf, 0x6d, 0x59, 0x3c, 0xb6, 0x1c, 0x9b, 0x76, 0x62, 0x86, 0x8e, 0x7f, 0x42, 0xdf, - 0xe4, 0x1a, 0x17, 0xb1, 0x94, 0x28, 0x2d, 0x9a, 0xa4, 0x2d, 0xd0, 0xd8, 0x48, 0x1c, 0x37, 0x95, - 0x1d, 0xd0, 0x4a, 0x0b, 0x64, 0x43, 0x50, 0xe4, 0x98, 0x22, 0x2c, 0x72, 0x04, 0xce, 0xc8, 0x90, - 0x8c, 0x02, 0x05, 0x0a, 0x74, 0xd1, 0x5d, 0x51, 0x14, 0x68, 0xd1, 0x17, 0xe8, 0xab, 0x64, 0xd7, - 0xa0, 0xab, 0xa6, 0x8b, 0xa0, 0x4d, 0x9e, 0xa0, 0x7d, 0x82, 0x82, 0x33, 0x43, 0x5a, 0x94, 0xad, - 0x3f, 0x07, 0x59, 0x69, 0xce, 0xe1, 0x7c, 0xe7, 0xff, 0xcc, 0x9c, 0x11, 0xcc, 0xd9, 0x21, 0x26, - 0xc4, 0xae, 0x5a, 0x5e, 0x50, 0xa0, 0xcd, 0x7c, 0x3d, 0xc4, 0x14, 0x2b, 0x4b, 0xc7, 0x88, 0x5a, - 0x8c, 0x97, 0x67, 0x2b, 0x1c, 0xa2, 0xfc, 0xc9, 0x3e, 0x6d, 0xce, 0xc6, 0xbe, 0x8f, 0x83, 0x02, - 0xff, 0xe1, 0x18, 0x6d, 0xde, 0xc5, 0x2e, 0x66, 0xcb, 0x42, 0xb4, 0xe2, 0x5c, 0xfd, 0x7b, 0x09, - 0x94, 0x12, 0x71, 0x4b, 0x9e, 0x1b, 0x5a, 0x14, 0x95, 0x09, 0x79, 0xd8, 0x08, 0x1c, 0xa2, 0xa8, - 0x30, 0x61, 0x87, 0xc8, 0xa2, 0x38, 0x54, 0xa5, 0x55, 0x69, 0x5d, 0x36, 0x62, 0x52, 0xb9, 0x0c, - 0x59, 0xa6, 0xc4, 0xf4, 0x1c, 0xf5, 0x3f, 0xab, 0xd2, 0xfa, 0xa8, 0x31, 0xc1, 0xe8, 0x1d, 0x47, - 0xd9, 0x86, 0x8c, 0xe5, 0xe3, 0x46, 0x40, 0xd5, 0xd1, 0x08, 0xb3, 0x59, 0x78, 0xfe, 0x6a, 0x65, - 0xe4, 0x8f, 0x57, 0x2b, 0xff, 0x73, 0x3d, 0x5a, 0x6d, 0x54, 0xf2, 0x36, 0xf6, 0x0b, 0x36, 0x26, - 0x3e, 0x26, 0xe2, 0x67, 0x83, 0x38, 0x87, 0x05, 0xda, 0xaa, 0x23, 0x92, 0x7f, 0xea, 0x05, 0xd4, - 0x10, 0x70, 0xfd, 0x0a, 0x68, 0xa7, 0x6d, 0x32, 0x10, 0xa9, 0xe3, 0x80, 0x20, 0xfd, 0x6f, 0x09, - 0xe6, 0x4a, 0xc4, 0xbd, 0xef, 0x38, 0x65, 0xbc, 0x13, 0x94, 0x9b, 0xe5, 0xd0, 0xb2, 0x0f, 0x51, - 0x78, 0x3e, 0x9b, 0x17, 0x60, 0x82, 0x36, 0xcd, 0xaa, 0x45, 0xaa, 0xdc, 0x68, 0x23, 0x43, 0x9b, - 0x8f, 0x2c, 0x52, 0x55, 0x36, 0x40, 0xb6, 0xb1, 0x17, 0x98, 0x91, 0x79, 0xea, 0xd8, 0xaa, 0xb4, - 0x3e, 0x5d, 0x9c, 0xc9, 0x8b, 0x80, 0x6e, 0x61, 0x2f, 0x28, 0xb7, 0xea, 0xc8, 0xc8, 0xda, 0x62, - 0xa5, 0xac, 0xc1, 0x78, 0x3d, 0xc4, 0xf8, 0x40, 0x1d, 0x5f, 0x95, 0xd6, 0x27, 0x8b, 0xb9, 0x78, - 0xeb, 0x93, 0x88, 0x69, 0xf0, 0x6f, 0xca, 0x12, 0x40, 0xa5, 0x86, 0xed, 0x43, 0xae, 0x2f, 0xc3, - 0xf4, 0xc9, 0x8c, 0xc3, 0x54, 0x5e, 0x86, 0x2c, 0x6d, 0x9a, 0x5e, 0xe0, 0xa0, 0xa6, 0x3a, 0xc1, - 0xcd, 0xa4, 0xcd, 0x9d, 0x88, 0xd4, 0x97, 0x60, 0xf1, 0x0c, 0x97, 0x93, 0x90, 0xec, 0xb2, 0x88, - 0x3c, 0xad, 0x3b, 0x3c, 0x5e, 0xf7, 0x1d, 0x27, 0x44, 0xa4, 0x57, 0x16, 0x97, 0x00, 0x28, 0x21, - 0x66, 0xbd, 0x51, 0x39, 0x44, 0x2d, 0x16, 0x13, 0xd9, 0x90, 0x29, 0x21, 0x4f, 0x18, 0x43, 0xa8, - 0xeb, 0x94, 0x97, 0xa8, 0xfb, 0x4d, 0x82, 0xd9, 0x12, 0x71, 0xbf, 0xa8, 0x7a, 0x14, 0xd5, 0x3c, - 0x42, 0x1f, 0x18, 0x5b, 0xc5, 0x9b, 0x3d, 0xb4, 0xad, 0x41, 0x0e, 0x85, 0x76, 0xf1, 0xa6, 0x69, - 0x71, 0x41, 0x42, 0xe1, 0x14, 0x63, 0xc6, 0xc6, 0xb6, 0x27, 0x69, 0x34, 0x9d, 0x24, 0x05, 0xc6, - 0x02, 0xcb, 0xe7, 0x69, 0x90, 0x0d, 0xb6, 0x56, 0x2e, 0x41, 0x86, 0xb4, 0xfc, 0x0a, 0xae, 0xb1, - 0x88, 0xcb, 0x86, 0xa0, 0x14, 0x0d, 0xb2, 0x0e, 0xb2, 0x3d, 0xdf, 0xaa, 0x11, 0x16, 0xe1, 0x9c, - 0x91, 0xd0, 0xca, 0x22, 0xc8, 0xae, 0x45, 0xcc, 0x9a, 0xe7, 0x7b, 0x54, 0x44, 0x38, 0xeb, 0x5a, - 0xe4, 0xb3, 0x88, 0xd6, 0x4d, 0xb8, 0x7c, 0xca, 0xa7, 0xd8, 0xe3, 0xc8, 0x83, 0xe3, 0x94, 0x07, - 0xdc, 0xc3, 0xa9, 0xe3, 0x76, 0x0f, 0x96, 0x00, 0x6c, 0x3b, 0xc9, 0xa0, 0x08, 0x6a, 0xc4, 0xe1, - 0x39, 0x7c, 0x29, 0xc1, 0x7c, 0x9c, 0xc4, 0xbd, 0x06, 0x7d, 0xcb, 0xc2, 0x9d, 0x87, 0xf1, 0x00, - 0x07, 0x36, 0x62, 0xb1, 0x1a, 0x33, 0x38, 0xd1, 0x5e, 0xce, 0x63, 0xa9, 0x72, 0x7e, 0xc7, 0xf5, - 0xf9, 0x31, 0x5c, 0x39, 0xcb, 0xb5, 0x24, 0x7e, 0x4b, 0x00, 0x1e, 0x31, 0x43, 0xe4, 0xe3, 0x23, - 0xe4, 0x30, 0x2f, 0xb3, 0x86, 0xec, 0x11, 0x83, 0x33, 0xf4, 0x03, 0x16, 0x7b, 0x4e, 0x3d, 0x0c, - 0xb1, 0xff, 0x8e, 0xc2, 0xa3, 0xaf, 0xc1, 0xd5, 0xae, 0x7a, 0x92, 0xea, 0xfe, 0x85, 0x57, 0xf7, - 0x56, 0xa4, 0x04, 0x95, 0xf7, 0xf7, 0x3f, 0xc7, 0xb4, 0xa7, 0x15, 0xbd, 0x7b, 0x49, 0xf9, 0x3f, - 0xcc, 0x1c, 0xa2, 0xd6, 0x36, 0x0a, 0x9e, 0x21, 0x6a, 0x3d, 0x42, 0x9e, 0x5b, 0xa5, 0xa2, 0xbe, - 0x4f, 0xf1, 0x95, 0x0d, 0xc8, 0x10, 0x6a, 0xd1, 0x06, 0x11, 0x27, 0xce, 0xc5, 0x38, 0x4d, 0x06, - 0xb2, 0x91, 0x77, 0x84, 0xf6, 0xd9, 0x47, 0x43, 0x6c, 0xd2, 0x17, 0x59, 0xd8, 0xd2, 0x86, 0x26, - 0x6e, 0xfc, 0x24, 0xc1, 0x4c, 0x89, 0xb8, 0xdb, 0x16, 0x79, 0x12, 0x7a, 0x36, 0xea, 0xe7, 0x45, - 0xef, 0x58, 0xd6, 0x23, 0x11, 0x71, 0x2c, 0x19, 0xa1, 0x5c, 0x85, 0x29, 0x5e, 0x2c, 0x41, 0xc3, - 0xaf, 0xa0, 0x90, 0x59, 0x3c, 0x66, 0x4c, 0x32, 0xde, 0x2e, 0x63, 0xb1, 0x1e, 0x6d, 0xd4, 0xeb, - 0xb5, 0x56, 0xd2, 0xa3, 0x8c, 0xd2, 0x35, 0x50, 0x3b, 0x2d, 0x4b, 0xcc, 0x7e, 0x06, 0xb9, 0x12, - 0x71, 0x77, 0xa3, 0x74, 0xbd, 0x9d, 0xc9, 0x67, 0xa4, 0x7f, 0x01, 0x2e, 0xa6, 0x64, 0x27, 0x4a, - 0x5f, 0x8e, 0xb3, 0x03, 0x2f, 0x62, 0xee, 0x05, 0x7b, 0x15, 0x82, 0xc2, 0x23, 0xe4, 0xec, 0x35, - 0x68, 0x05, 0x37, 0x02, 0xa7, 0xdc, 0xec, 0x61, 0xc3, 0x22, 0xb0, 0x0e, 0xe7, 0x1d, 0xc3, 0x73, - 0x9f, 0x8d, 0x18, 0xac, 0x61, 0xf2, 0x30, 0x87, 0x85, 0x30, 0x13, 0x47, 0xa5, 0xd6, 0x7e, 0xd1, - 0xcc, 0xe2, 0x13, 0x3d, 0x65, 0xbe, 0xff, 0x23, 0xd0, 0x3a, 0xf6, 0xf3, 0xe6, 0xe3, 0x45, 0xc3, - 0x03, 0xac, 0xa6, 0x60, 0x9b, 0x27, 0xdf, 0x95, 0xf7, 0x61, 0xa1, 0x03, 0x1d, 0x1d, 0x76, 0x0d, - 0x82, 0x1c, 0x15, 0x18, 0x74, 0x3e, 0x05, 0xdd, 0xb6, 0xc8, 0x53, 0x82, 0x1c, 0xe5, 0x18, 0xf4, - 0x0e, 0x18, 0x3a, 0x38, 0x40, 0x36, 0xf5, 0x8e, 0x10, 0x13, 0xc0, 0x53, 0x3f, 0xc9, 0x6e, 0xf4, - 0xbc, 0xb8, 0xd1, 0xaf, 0x0f, 0x70, 0xa3, 0xef, 0x04, 0xd4, 0x58, 0x4e, 0x69, 0x7c, 0x10, 0xcb, - 0x8d, 0x33, 0xaf, 0x7c, 0xda, 0x47, 0x37, 0x3f, 0xa9, 0xa7, 0x98, 0xf5, 0xdd, 0x65, 0xb1, 0xf3, - 0x5b, 0xc1, 0x30, 0x7d, 0x64, 0xd5, 0x1a, 0xc8, 0x0c, 0x79, 0xaf, 0x38, 0xbc, 0xe8, 0x36, 0x1f, - 0x0d, 0x39, 0x85, 0xfc, 0xf3, 0x6a, 0xe5, 0x62, 0xcb, 0xf2, 0x6b, 0xf7, 0xf4, 0xb4, 0x38, 0xdd, - 0xc8, 0x31, 0x86, 0x68, 0x45, 0xa7, 0xad, 0x59, 0x33, 0x03, 0x34, 0xab, 0xb2, 0x02, 0x93, 0xdc, - 0x45, 0x56, 0xa3, 0xe2, 0x00, 0x05, 0xc6, 0xda, 0x8a, 0x38, 0xca, 0x75, 0xb8, 0xc0, 0x37, 0x44, - 0xa7, 0x09, 0xaf, 0xde, 0x2c, 0xf3, 0x3c, 0xc7, 0xd8, 0x65, 0x42, 0x58, 0xe5, 0xa6, 0x27, 0x13, - 0xb9, 0xdf, 0x64, 0xa2, 0x5f, 0x83, 0xb5, 0x1e, 0xa5, 0x9d, 0xb4, 0xc0, 0x5f, 0xa3, 0x6c, 0xe8, - 0x4a, 0xef, 0xdb, 0x09, 0xfa, 0x77, 0x40, 0xd4, 0xe4, 0x28, 0x70, 0x50, 0x28, 0xca, 0x5f, 0x50, - 0x91, 0x3b, 0x7c, 0x65, 0x76, 0x5c, 0xeb, 0x39, 0xce, 0xde, 0x12, 0xad, 0xaa, 0x41, 0x56, 0x84, - 0x38, 0x14, 0x77, 0x56, 0x42, 0x2b, 0xd7, 0x60, 0x3a, 0x5e, 0x8b, 0xb0, 0x8d, 0x73, 0x11, 0x31, - 0x97, 0x47, 0xee, 0x64, 0xf0, 0xcc, 0xbc, 0xd5, 0xe0, 0x19, 0x79, 0xe9, 0x23, 0x42, 0x2c, 0x97, - 0x87, 0x5e, 0x36, 0x62, 0x52, 0xb9, 0x02, 0x10, 0x85, 0x5c, 0x74, 0xb0, 0xcc, 0xed, 0xf4, 0x02, - 0xd1, 0xb8, 0xd7, 0xe1, 0x82, 0x17, 0x98, 0xe2, 0xee, 0xe4, 0xdd, 0xca, 0x5b, 0x2e, 0xe7, 0x05, - 0xed, 0x2d, 0x9a, 0x1a, 0x40, 0x26, 0xd9, 0x8e, 0x64, 0x00, 0x49, 0xe7, 0x75, 0xaa, 0xef, 0xc4, - 0xb9, 0x08, 0x32, 0x6d, 0x9a, 0x38, 0xf4, 0x5c, 0x2f, 0x50, 0x73, 0xdc, 0x20, 0xda, 0xdc, 0x63, - 0x74, 0x74, 0xfe, 0x59, 0x84, 0x20, 0xaa, 0x4e, 0xb3, 0x0f, 0x9c, 0xd0, 0xff, 0x0b, 0x7a, 0xf7, - 0x14, 0x27, 0x95, 0xf0, 0xad, 0x04, 0xd3, 0x25, 0xe2, 0xee, 0x23, 0xba, 0x8b, 0x1d, 0xf4, 0x18, - 0xb5, 0x7a, 0x0d, 0x92, 0x05, 0x90, 0xf9, 0xc5, 0xb7, 0x8f, 0x28, 0x2b, 0x80, 0xc9, 0xe2, 0x6c, - 0x32, 0x5b, 0x34, 0x2a, 0x8f, 0xd9, 0x07, 0xe3, 0x64, 0x8f, 0x72, 0x03, 0x94, 0xa8, 0xbe, 0x89, - 0xe7, 0x06, 0x28, 0x34, 0xc5, 0xe8, 0x24, 0x8e, 0xc4, 0x19, 0x4a, 0xc8, 0x3e, 0xfb, 0x20, 0xf8, - 0xba, 0x0a, 0x97, 0xd2, 0xa6, 0xc4, 0x56, 0x16, 0x7f, 0x9d, 0x84, 0xd1, 0x12, 0x71, 0x95, 0x6f, - 0x24, 0x98, 0x3d, 0x3d, 0x52, 0xdd, 0xce, 0xf7, 0x7c, 0x21, 0xe5, 0xcf, 0x1a, 0x56, 0xb4, 0x0f, - 0xcf, 0x01, 0x4a, 0x26, 0x9c, 0xaf, 0x25, 0x98, 0x39, 0xf5, 0x24, 0x29, 0x0e, 0x28, 0xb1, 0x0d, - 0xa3, 0xdd, 0x1b, 0x1e, 0x93, 0x18, 0xf1, 0x83, 0x04, 0x97, 0xba, 0x4c, 0x51, 0x77, 0xfa, 0x8b, - 0x3d, 0x1b, 0xa9, 0x7d, 0x72, 0x5e, 0x64, 0x62, 0xd6, 0x97, 0x30, 0xdd, 0x31, 0x4d, 0xdd, 0xec, - 0x2f, 0x33, 0x8d, 0xd0, 0xee, 0x0c, 0x8b, 0x48, 0xb4, 0xb7, 0x20, 0x97, 0x1e, 0x82, 0x0a, 0xfd, - 0x45, 0xa5, 0x00, 0xda, 0x07, 0x43, 0x02, 0x12, 0xd5, 0x75, 0x80, 0xb6, 0x49, 0xe6, 0x46, 0x7f, - 0x31, 0x27, 0xbb, 0xb5, 0xf7, 0x86, 0xd9, 0x9d, 0x68, 0xfc, 0x59, 0x02, 0xb5, 0xeb, 0x18, 0x33, - 0x40, 0x69, 0x75, 0xc3, 0x6a, 0x9b, 0xe7, 0xc7, 0x26, 0xc6, 0xfd, 0x28, 0xc1, 0x42, 0xb7, 0x0b, - 0xe6, 0xee, 0xb0, 0xf2, 0x13, 0xa8, 0x76, 0xff, 0xdc, 0xd0, 0xf6, 0x0a, 0xed, 0x78, 0xcd, 0x0e, - 0x50, 0xa1, 0x69, 0xc4, 0x20, 0x15, 0xda, 0xe5, 0x75, 0x19, 0x9d, 0x1d, 0xa7, 0x1e, 0xef, 0x03, - 0x9c, 0x1d, 0x9d, 0x98, 0x41, 0xce, 0x8e, 0x6e, 0x8f, 0x7a, 0xe5, 0x2b, 0xb8, 0xd0, 0xf9, 0x2f, - 0xd0, 0xad, 0xfe, 0xe2, 0x3a, 0x20, 0xda, 0xdd, 0xa1, 0x21, 0xb1, 0x01, 0x9b, 0x8f, 0x9f, 0xbf, - 0x5e, 0x96, 0x5e, 0xbc, 0x5e, 0x96, 0xfe, 0x7c, 0xbd, 0x2c, 0x7d, 0xf7, 0x66, 0x79, 0xe4, 0xc5, - 0x9b, 0xe5, 0x91, 0xdf, 0xdf, 0x2c, 0x8f, 0x3c, 0xbb, 0xd5, 0x76, 0x8f, 0x47, 0x42, 0x37, 0xf8, - 0xdf, 0x61, 0xb1, 0xfc, 0x42, 0xb3, 0xd0, 0xfe, 0x27, 0x59, 0x74, 0xad, 0x57, 0x32, 0xec, 0xef, - 0xad, 0xdb, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x34, 0xdd, 0xf5, 0x5e, 0x3f, 0x13, 0x00, 0x00, + // 1516 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x5f, 0x6f, 0xdb, 0x54, + 0x14, 0xaf, 0x69, 0x9b, 0xc6, 0xa7, 0x4d, 0xff, 0xb8, 0xdd, 0xea, 0xb9, 0xeb, 0x9f, 0xb9, 0x6c, + 0x54, 0x68, 0x4d, 0xb6, 0x0e, 0xc4, 0x36, 0x40, 0x62, 0xad, 0xb6, 0xae, 0x8c, 0xb4, 0x93, 0x9b, + 0x81, 0xb4, 0x17, 0xcb, 0xb1, 0x6f, 0x1d, 0xab, 0xb1, 0x6f, 0xe4, 0x7b, 0x53, 0x25, 0x15, 0x12, + 0xd2, 0x24, 0x1e, 0x78, 0x43, 0x08, 0x09, 0xc4, 0x17, 0xe0, 0xab, 0xec, 0x8d, 0x89, 0x27, 0xc6, + 0xc3, 0x84, 0xb6, 0x4f, 0x00, 0x9f, 0x00, 0xf9, 0xde, 0x6b, 0x37, 0x4e, 0x9b, 0x7f, 0x9d, 0xf6, + 0x14, 0x9f, 0xe3, 0xfb, 0x3b, 0xff, 0xcf, 0x3d, 0xc7, 0x81, 0x59, 0x3b, 0xc4, 0x84, 0xd8, 0x15, + 0xcb, 0x0b, 0x0a, 0xb4, 0x91, 0xaf, 0x85, 0x98, 0x62, 0x65, 0xf1, 0x18, 0x51, 0x8b, 0xf1, 0xf2, + 0xec, 0x09, 0x87, 0x28, 0x7f, 0x72, 0x4e, 0x9b, 0xb5, 0xb1, 0xef, 0xe3, 0xa0, 0xc0, 0x7f, 0x38, + 0x46, 0x9b, 0x73, 0xb1, 0x8b, 0xd9, 0x63, 0x21, 0x7a, 0xe2, 0x5c, 0xfd, 0x27, 0x09, 0x94, 0x22, + 0x71, 0x8b, 0x9e, 0x1b, 0x5a, 0x14, 0x95, 0x08, 0x79, 0x50, 0x0f, 0x1c, 0xa2, 0xa8, 0x30, 0x66, + 0x87, 0xc8, 0xa2, 0x38, 0x54, 0xa5, 0x15, 0x69, 0x4d, 0x36, 0x62, 0x52, 0xb9, 0x04, 0x59, 0xa6, + 0xc4, 0xf4, 0x1c, 0xf5, 0xbd, 0x15, 0x69, 0x6d, 0xd8, 0x18, 0x63, 0xf4, 0x8e, 0xa3, 0x6c, 0x43, + 0xc6, 0xf2, 0x71, 0x3d, 0xa0, 0xea, 0x70, 0x84, 0xd9, 0x2c, 0x3c, 0x7f, 0xb5, 0x3c, 0xf4, 0xf7, + 0xab, 0xe5, 0x0f, 0x5c, 0x8f, 0x56, 0xea, 0xe5, 0xbc, 0x8d, 0xfd, 0x82, 0x8d, 0x89, 0x8f, 0x89, + 0xf8, 0x59, 0x27, 0xce, 0x61, 0x81, 0x36, 0x6b, 0x88, 0xe4, 0x9f, 0x78, 0x01, 0x35, 0x04, 0x5c, + 0xbf, 0x0c, 0xda, 0x69, 0x9b, 0x0c, 0x44, 0x6a, 0x38, 0x20, 0x48, 0xff, 0x57, 0x82, 0xd9, 0x22, + 0x71, 0xef, 0x39, 0x4e, 0x09, 0xef, 0x04, 0xa5, 0x46, 0x29, 0xb4, 0xec, 0x43, 0x14, 0x9e, 0xcf, + 0xe6, 0x79, 0x18, 0xa3, 0x0d, 0xb3, 0x62, 0x91, 0x0a, 0x37, 0xda, 0xc8, 0xd0, 0xc6, 0x43, 0x8b, + 0x54, 0x94, 0x75, 0x90, 0x6d, 0xec, 0x05, 0x66, 0x64, 0x9e, 0x3a, 0xb2, 0x22, 0xad, 0x4d, 0x6e, + 0x4c, 0xe7, 0x45, 0x40, 0xb7, 0xb0, 0x17, 0x94, 0x9a, 0x35, 0x64, 0x64, 0x6d, 0xf1, 0xa4, 0xac, + 0xc2, 0x68, 0x2d, 0xc4, 0xf8, 0x40, 0x1d, 0x5d, 0x91, 0xd6, 0xc6, 0x37, 0x72, 0xf1, 0xd1, 0xc7, + 0x11, 0xd3, 0xe0, 0xef, 0x94, 0x45, 0x80, 0x72, 0x15, 0xdb, 0x87, 0x5c, 0x5f, 0x86, 0xe9, 0x93, + 0x19, 0x87, 0xa9, 0xbc, 0x04, 0x59, 0xda, 0x30, 0xbd, 0xc0, 0x41, 0x0d, 0x75, 0x8c, 0x9b, 0x49, + 0x1b, 0x3b, 0x11, 0xa9, 0x2f, 0xc2, 0xc2, 0x19, 0x2e, 0x27, 0x21, 0xd9, 0x65, 0x11, 0x79, 0x52, + 0x73, 0x78, 0xbc, 0xee, 0x39, 0x4e, 0x88, 0x48, 0xb7, 0x2c, 0x2e, 0x02, 0x50, 0x42, 0xcc, 0x5a, + 0xbd, 0x7c, 0x88, 0x9a, 0x2c, 0x26, 0xb2, 0x21, 0x53, 0x42, 0x1e, 0x33, 0x86, 0x50, 0xd7, 0x2e, + 0x2f, 0x51, 0xf7, 0xa7, 0x04, 0x33, 0x45, 0xe2, 0x7e, 0x53, 0xf1, 0x28, 0xaa, 0x7a, 0x84, 0xde, + 0x37, 0xb6, 0x36, 0x6e, 0x74, 0xd1, 0xb6, 0x0a, 0x39, 0x14, 0xda, 0x1b, 0x37, 0x4c, 0x8b, 0x0b, + 0x12, 0x0a, 0x27, 0x18, 0x33, 0x36, 0xb6, 0x35, 0x49, 0xc3, 0xe9, 0x24, 0x29, 0x30, 0x12, 0x58, + 0x3e, 0x4f, 0x83, 0x6c, 0xb0, 0x67, 0xe5, 0x22, 0x64, 0x48, 0xd3, 0x2f, 0xe3, 0x2a, 0x8b, 0xb8, + 0x6c, 0x08, 0x4a, 0xd1, 0x20, 0xeb, 0x20, 0xdb, 0xf3, 0xad, 0x2a, 0x61, 0x11, 0xce, 0x19, 0x09, + 0xad, 0x2c, 0x80, 0xec, 0x5a, 0xc4, 0xac, 0x7a, 0xbe, 0x47, 0x45, 0x84, 0xb3, 0xae, 0x45, 0xbe, + 0x8a, 0x68, 0xdd, 0x84, 0x4b, 0xa7, 0x7c, 0x8a, 0x3d, 0x8e, 0x3c, 0x38, 0x4e, 0x79, 0xc0, 0x3d, + 0x9c, 0x38, 0x6e, 0xf5, 0x60, 0x11, 0xc0, 0xb6, 0x93, 0x0c, 0x8a, 0xa0, 0x46, 0x1c, 0x9e, 0xc3, + 0x97, 0x12, 0xcc, 0xc5, 0x49, 0xdc, 0xab, 0xd3, 0xb7, 0x2c, 0xdc, 0x39, 0x18, 0x0d, 0x70, 0x60, + 0x23, 0x16, 0xab, 0x11, 0x83, 0x13, 0xad, 0xe5, 0x3c, 0x92, 0x2a, 0xe7, 0x77, 0x5c, 0x9f, 0x9f, + 0xc3, 0xe5, 0xb3, 0x5c, 0x4b, 0xe2, 0xb7, 0x08, 0xe0, 0x11, 0x33, 0x44, 0x3e, 0x3e, 0x42, 0x0e, + 0xf3, 0x32, 0x6b, 0xc8, 0x1e, 0x31, 0x38, 0x43, 0x3f, 0x60, 0xb1, 0xe7, 0xd4, 0x83, 0x10, 0xfb, + 0xef, 0x28, 0x3c, 0xfa, 0x2a, 0x5c, 0xe9, 0xa8, 0x27, 0xa9, 0xee, 0xdf, 0x79, 0x75, 0x6f, 0x45, + 0x4a, 0x50, 0x69, 0x7f, 0xff, 0x6b, 0x4c, 0xbb, 0x5a, 0xd1, 0xbd, 0x97, 0x94, 0x0f, 0x61, 0xfa, + 0x10, 0x35, 0xb7, 0x51, 0xf0, 0x14, 0x51, 0xeb, 0x21, 0xf2, 0xdc, 0x0a, 0x15, 0xf5, 0x7d, 0x8a, + 0xaf, 0xac, 0x43, 0x86, 0x50, 0x8b, 0xd6, 0x89, 0xb8, 0x71, 0x2e, 0xc4, 0x69, 0x32, 0x90, 0x8d, + 0xbc, 0x23, 0xb4, 0xcf, 0x5e, 0x1a, 0xe2, 0x90, 0xbe, 0xc0, 0xc2, 0x96, 0x36, 0x34, 0x71, 0xe3, + 0x57, 0x09, 0xa6, 0x8b, 0xc4, 0xdd, 0xb6, 0xc8, 0xe3, 0xd0, 0xb3, 0x51, 0x2f, 0x2f, 0xba, 0xc7, + 0xb2, 0x16, 0x89, 0x88, 0x63, 0xc9, 0x08, 0xe5, 0x0a, 0x4c, 0xf0, 0x62, 0x09, 0xea, 0x7e, 0x19, + 0x85, 0xcc, 0xe2, 0x11, 0x63, 0x9c, 0xf1, 0x76, 0x19, 0x8b, 0xf5, 0x68, 0xbd, 0x56, 0xab, 0x36, + 0x93, 0x1e, 0x65, 0x94, 0xae, 0x81, 0xda, 0x6e, 0x59, 0x62, 0xf6, 0x53, 0xc8, 0x15, 0x89, 0xbb, + 0x1b, 0xa5, 0xeb, 0xed, 0x4c, 0x3e, 0x23, 0xfd, 0xf3, 0x70, 0x21, 0x25, 0x3b, 0x51, 0xfa, 0x72, + 0x94, 0x5d, 0x78, 0x11, 0x73, 0x2f, 0xd8, 0x2b, 0x13, 0x14, 0x1e, 0x21, 0x67, 0xaf, 0x4e, 0xcb, + 0xb8, 0x1e, 0x38, 0xa5, 0x46, 0x17, 0x1b, 0x16, 0x80, 0x75, 0x38, 0xef, 0x18, 0x9e, 0xfb, 0x6c, + 0xc4, 0x60, 0x0d, 0x93, 0x87, 0x59, 0x2c, 0x84, 0x99, 0x38, 0x2a, 0xb5, 0xd6, 0x41, 0x33, 0x83, + 0x4f, 0xf4, 0x94, 0xf8, 0xf9, 0xcf, 0x40, 0x6b, 0x3b, 0xcf, 0x9b, 0x8f, 0x17, 0x0d, 0x0f, 0xb0, + 0x9a, 0x82, 0x6d, 0x9e, 0xbc, 0x57, 0x3e, 0x86, 0xf9, 0x36, 0x74, 0x74, 0xd9, 0xd5, 0x09, 0x72, + 0x54, 0x60, 0xd0, 0xb9, 0x14, 0x74, 0xdb, 0x22, 0x4f, 0x08, 0x72, 0x94, 0x63, 0xd0, 0xdb, 0x60, + 0xe8, 0xe0, 0x00, 0xd9, 0xd4, 0x3b, 0x42, 0x4c, 0x00, 0x4f, 0xfd, 0x38, 0x9b, 0xe8, 0x79, 0x31, + 0xd1, 0xaf, 0xf5, 0x31, 0xd1, 0x77, 0x02, 0x6a, 0x2c, 0xa5, 0x34, 0xde, 0x8f, 0xe5, 0xc6, 0x99, + 0x57, 0xbe, 0xec, 0xa1, 0x9b, 0xdf, 0xd4, 0x13, 0xcc, 0xfa, 0xce, 0xb2, 0xd8, 0xfd, 0xad, 0x60, + 0x98, 0x3c, 0xb2, 0xaa, 0x75, 0x64, 0x86, 0xbc, 0x57, 0x1c, 0x5e, 0x74, 0x9b, 0x0f, 0x07, 0xdc, + 0x42, 0xfe, 0x7b, 0xb5, 0x7c, 0xa1, 0x69, 0xf9, 0xd5, 0xbb, 0x7a, 0x5a, 0x9c, 0x6e, 0xe4, 0x18, + 0x43, 0xb4, 0xa2, 0xd3, 0xd2, 0xac, 0x99, 0x3e, 0x9a, 0x55, 0x59, 0x86, 0x71, 0xee, 0x22, 0xab, + 0x51, 0x71, 0x81, 0x02, 0x63, 0x6d, 0x45, 0x1c, 0xe5, 0x1a, 0x4c, 0xf1, 0x03, 0xd1, 0x6d, 0xc2, + 0xab, 0x37, 0xcb, 0x3c, 0xcf, 0x31, 0x76, 0x89, 0x10, 0x56, 0xb9, 0xe9, 0xcd, 0x44, 0xee, 0xb5, + 0x99, 0xe8, 0x57, 0x61, 0xb5, 0x4b, 0x69, 0x27, 0x2d, 0xf0, 0x6c, 0x84, 0x2d, 0x5d, 0xe9, 0x73, + 0x3b, 0x41, 0xef, 0x0e, 0x88, 0x9a, 0x1c, 0x05, 0x0e, 0x0a, 0x45, 0xf9, 0x0b, 0x2a, 0x72, 0x87, + 0x3f, 0x99, 0x6d, 0x63, 0x3d, 0xc7, 0xd9, 0x5b, 0xa2, 0x55, 0x35, 0xc8, 0x8a, 0x10, 0x87, 0x62, + 0x66, 0x25, 0xb4, 0x72, 0x15, 0x26, 0xe3, 0x67, 0x11, 0xb6, 0x51, 0x2e, 0x22, 0xe6, 0xf2, 0xc8, + 0x9d, 0x2c, 0x9e, 0x99, 0xb7, 0x5a, 0x3c, 0x23, 0x2f, 0x7d, 0x44, 0x88, 0xe5, 0xf2, 0xd0, 0xcb, + 0x46, 0x4c, 0x2a, 0x97, 0x01, 0xa2, 0x90, 0x8b, 0x0e, 0x96, 0xb9, 0x9d, 0x5e, 0x20, 0x1a, 0xf7, + 0x1a, 0x4c, 0x79, 0x81, 0x29, 0x66, 0x27, 0xef, 0x56, 0xde, 0x72, 0x39, 0x2f, 0x68, 0x6d, 0xd1, + 0xd4, 0x02, 0x32, 0xce, 0x4e, 0x24, 0x0b, 0x48, 0x3a, 0xaf, 0x13, 0x3d, 0x37, 0xce, 0x05, 0x90, + 0x69, 0xc3, 0xc4, 0xa1, 0xe7, 0x7a, 0x81, 0x9a, 0xe3, 0x06, 0xd1, 0xc6, 0x1e, 0xa3, 0xa3, 0xfb, + 0xcf, 0x22, 0x04, 0x51, 0x75, 0x92, 0xbd, 0xe0, 0x44, 0x54, 0x82, 0xe8, 0x08, 0x05, 0x54, 0xcc, + 0xf0, 0x29, 0x66, 0x00, 0x30, 0x16, 0x1f, 0xe3, 0xef, 0x83, 0xde, 0xb9, 0x06, 0x92, 0x52, 0xf9, + 0x41, 0x82, 0xc9, 0x22, 0x71, 0xf7, 0x11, 0xdd, 0xc5, 0x0e, 0x7a, 0x84, 0x9a, 0xdd, 0x36, 0xcd, + 0x02, 0xc8, 0x7c, 0x32, 0xee, 0x23, 0xca, 0x2a, 0x64, 0x7c, 0x63, 0x26, 0x59, 0x3e, 0xea, 0xe5, + 0x47, 0xec, 0x85, 0x71, 0x72, 0x46, 0xb9, 0x0e, 0x4a, 0xd4, 0x00, 0xc4, 0x73, 0x03, 0x14, 0x9a, + 0x62, 0xb7, 0x12, 0x77, 0xe6, 0x34, 0x25, 0x64, 0x9f, 0xbd, 0x10, 0x7c, 0x5d, 0x85, 0x8b, 0x69, + 0x53, 0x62, 0x2b, 0x37, 0xfe, 0x18, 0x87, 0xe1, 0x22, 0x71, 0x95, 0xef, 0x25, 0x98, 0x39, 0xbd, + 0x73, 0xdd, 0xca, 0x77, 0xfd, 0x84, 0xca, 0x9f, 0xb5, 0xcd, 0x68, 0x9f, 0x9e, 0x03, 0x94, 0xac, + 0x40, 0xcf, 0x24, 0x98, 0x3e, 0xf5, 0xcd, 0xb2, 0xd1, 0xa7, 0xc4, 0x16, 0x8c, 0x76, 0x77, 0x70, + 0x4c, 0x62, 0xc4, 0xcf, 0x12, 0x5c, 0xec, 0xb0, 0x66, 0xdd, 0xee, 0x2d, 0xf6, 0x6c, 0xa4, 0xf6, + 0xc5, 0x79, 0x91, 0x89, 0x59, 0xdf, 0xc2, 0x64, 0xdb, 0xba, 0x75, 0xa3, 0xb7, 0xcc, 0x34, 0x42, + 0xbb, 0x3d, 0x28, 0x22, 0xd1, 0xde, 0x84, 0x5c, 0x7a, 0x4b, 0x2a, 0xf4, 0x16, 0x95, 0x02, 0x68, + 0x9f, 0x0c, 0x08, 0x48, 0x54, 0xd7, 0x00, 0x5a, 0x56, 0x9d, 0xeb, 0xbd, 0xc5, 0x9c, 0x9c, 0xd6, + 0x3e, 0x1a, 0xe4, 0x74, 0xa2, 0xf1, 0x37, 0x09, 0xd4, 0x8e, 0x7b, 0x4e, 0x1f, 0xa5, 0xd5, 0x09, + 0xab, 0x6d, 0x9e, 0x1f, 0x9b, 0x18, 0xf7, 0x8b, 0x04, 0xf3, 0x9d, 0x26, 0xd0, 0x9d, 0x41, 0xe5, + 0x27, 0x50, 0xed, 0xde, 0xb9, 0xa1, 0xad, 0x15, 0xda, 0xf6, 0xb9, 0xdb, 0x47, 0x85, 0xa6, 0x11, + 0xfd, 0x54, 0x68, 0x87, 0xcf, 0xcf, 0xe8, 0xee, 0x38, 0xf5, 0x75, 0xdf, 0xc7, 0xdd, 0xd1, 0x8e, + 0xe9, 0xe7, 0xee, 0xe8, 0xf4, 0xd5, 0xaf, 0x7c, 0x07, 0x53, 0xed, 0x7f, 0x13, 0xdd, 0xec, 0x2d, + 0xae, 0x0d, 0xa2, 0xdd, 0x19, 0x18, 0x12, 0x1b, 0xb0, 0xf9, 0xe8, 0xf9, 0xeb, 0x25, 0xe9, 0xc5, + 0xeb, 0x25, 0xe9, 0x9f, 0xd7, 0x4b, 0xd2, 0x8f, 0x6f, 0x96, 0x86, 0x5e, 0xbc, 0x59, 0x1a, 0xfa, + 0xeb, 0xcd, 0xd2, 0xd0, 0xd3, 0x9b, 0x2d, 0x83, 0x3e, 0x12, 0xba, 0xce, 0xff, 0x2f, 0x8b, 0xe5, + 0x17, 0x1a, 0x85, 0xd6, 0x7f, 0xd1, 0xa2, 0xb9, 0x5f, 0xce, 0xb0, 0xff, 0xbf, 0x6e, 0xfd, 0x1f, + 0x00, 0x00, 0xff, 0xff, 0x3f, 0x94, 0xa8, 0x99, 0x60, 0x13, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2854,6 +2864,11 @@ func (m *MsgVoteOnObservedInboundTx) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if m.EventIndex != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.EventIndex)) + i-- + dAtA[i] = 0x78 + } if len(m.Asset) > 0 { i -= len(m.Asset) copy(dAtA[i:], m.Asset) @@ -3469,6 +3484,9 @@ func (m *MsgVoteOnObservedInboundTx) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + if m.EventIndex != 0 { + n += 1 + sovTx(uint64(m.EventIndex)) + } return n } @@ -6355,6 +6373,25 @@ func (m *MsgVoteOnObservedInboundTx) Unmarshal(dAtA []byte) error { } m.Asset = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EventIndex", wireType) + } + m.EventIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EventIndex |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/zetaclient/bitcoin_client.go b/zetaclient/bitcoin_client.go index 200e985405..1d8c93db7c 100644 --- a/zetaclient/bitcoin_client.go +++ b/zetaclient/bitcoin_client.go @@ -611,6 +611,7 @@ func (ob *BitcoinChainClient) GetInboundVoteMessageFromBtcEvent(inTx *BTCInTxEvn common.CoinType_Gas, "", ob.zetaClient.GetKeys().GetOperatorAddress().String(), + 0, ) } diff --git a/zetaclient/tx.go b/zetaclient/tx.go index d5d9c89571..9006e402da 100644 --- a/zetaclient/tx.go +++ b/zetaclient/tx.go @@ -31,8 +31,39 @@ const ( DefaultRetryInterval = 5 ) -func GetInBoundVoteMessage(sender string, senderChain int64, txOrigin string, receiver string, receiverChain int64, amount math.Uint, message string, inTxHash string, inBlockHeight uint64, gasLimit uint64, coinType common.CoinType, asset string, signerAddress string) *types.MsgVoteOnObservedInboundTx { - msg := types.NewMsgVoteOnObservedInboundTx(signerAddress, sender, senderChain, txOrigin, receiver, receiverChain, amount, message, inTxHash, inBlockHeight, gasLimit, coinType, asset) +// GetInBoundVoteMessage returns a new MsgVoteOnObservedInboundTx +func GetInBoundVoteMessage( + sender string, + senderChain int64, + txOrigin string, + receiver string, + receiverChain int64, + amount math.Uint, + message string, + inTxHash string, + inBlockHeight uint64, + gasLimit uint64, + coinType common.CoinType, + asset string, + signerAddress string, + eventIndex uint, +) *types.MsgVoteOnObservedInboundTx { + msg := types.NewMsgVoteOnObservedInboundTx( + signerAddress, + sender, + senderChain, + txOrigin, + receiver, + receiverChain, + amount, + message, + inTxHash, + inBlockHeight, + gasLimit, + coinType, + asset, + eventIndex, + ) return msg } diff --git a/zetaclient/utils.go b/zetaclient/utils.go index 389732f684..98b5d51787 100644 --- a/zetaclient/utils.go +++ b/zetaclient/utils.go @@ -125,6 +125,7 @@ func (ob *EVMChainClient) GetInboundVoteMsgForDepositedEvent(event *erc20custody common.CoinType_ERC20, event.Asset.String(), ob.zetaClient.GetKeys().GetOperatorAddress().String(), + event.Raw.Index, ), nil } @@ -160,6 +161,7 @@ func (ob *EVMChainClient) GetInboundVoteMsgForZetaSentEvent(event *zetaconnector common.CoinType_Zeta, "", ob.zetaClient.GetKeys().GetOperatorAddress().String(), + event.Raw.Index, ), nil } @@ -185,5 +187,6 @@ func (ob *EVMChainClient) GetInboundVoteMsgForTokenSentToTSS(txhash ethcommon.Ha common.CoinType_Gas, "", ob.zetaClient.GetKeys().GetOperatorAddress().String(), + 0, // not a smart contract call ) }