Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support depositAndCall and withdrawAndCall with empty message #3018

Merged
merged 20 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
* [2853](https://github.com/zeta-chain/node/pull/2853) - calling precompile through sc with sc state update
* [2925](https://github.com/zeta-chain/node/pull/2925) - add recover to init chainer to diplay informative message when starting a node from block 1
* [2909](https://github.com/zeta-chain/node/pull/2909) - add legacy messages back to codec for querier backward compatibility
* [3018](https://github.com/zeta-chain/node/pull/3018) - support `DepositAndCall` and `WithdrawAndCall` with empty payload
lumtis marked this conversation as resolved.
Show resolved Hide resolved

## v20.0.0

Expand Down
3 changes: 3 additions & 0 deletions cmd/zetae2e/local/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ func startV2Tests(eg *errgroup.Group, conf config.Config, deployerRunner *runner
e2etests.TestV2ZEVMToEVMCallName,
e2etests.TestV2ZEVMToEVMCallThroughContractName,
e2etests.TestV2EVMToZEVMCallName,
e2etests.TestV2ETHDepositAndCallNoMessageName,
e2etests.TestV2ETHWithdrawAndCallNoMessageName,
))

// Test happy paths for erc20 token workflow
Expand All @@ -36,6 +38,7 @@ func startV2Tests(eg *errgroup.Group, conf config.Config, deployerRunner *runner
e2etests.TestV2ERC20WithdrawName,
e2etests.TestV2ERC20WithdrawAndArbitraryCallName,
e2etests.TestV2ERC20WithdrawAndCallName,
e2etests.TestV2ERC20DepositAndCallNoMessageName,
))

// Test revert cases for gas token workflow
Expand Down
5 changes: 5 additions & 0 deletions docs/openapi/openapi.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57202,6 +57202,11 @@ definitions:
format: uint64
tx_finalization_status:
$ref: '#/definitions/crosschainTxFinalizationStatus'
is_cross_chain_call:
type: boolean
title: |-
this field describes if a smart contract call should be made for a inbound
with assets only used for protocol contract version 2
crosschainInboundTracker:
type: object
properties:
Expand Down
1 change: 1 addition & 0 deletions docs/spec/crosschain/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ message MsgVoteInbound {
ProtocolContractVersion protocol_contract_version = 16;
RevertOptions revert_options = 17;
CallOptions call_options = 18;
bool is_cross_chain_call = 19;
}
```

Expand Down
34 changes: 34 additions & 0 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,25 @@ const (
*/
TestV2ETHDepositName = "v2_eth_deposit"
TestV2ETHDepositAndCallName = "v2_eth_deposit_and_call"
TestV2ETHDepositAndCallNoMessageName = "v2_eth_deposit_and_call_no_message"
TestV2ETHDepositAndCallRevertName = "v2_eth_deposit_and_call_revert"
TestV2ETHDepositAndCallRevertWithCallName = "v2_eth_deposit_and_call_revert_with_call"
TestV2ETHWithdrawName = "v2_eth_withdraw"
TestV2ETHWithdrawAndArbitraryCallName = "v2_eth_withdraw_and_arbitrary_call"
TestV2ETHWithdrawAndCallName = "v2_eth_withdraw_and_call"
TestV2ETHWithdrawAndCallNoMessageName = "v2_eth_withdraw_and_call_no_message"
TestV2ETHWithdrawAndCallThroughContractName = "v2_eth_withdraw_and_call_through_contract"
TestV2ETHWithdrawAndCallRevertName = "v2_eth_withdraw_and_call_revert"
TestV2ETHWithdrawAndCallRevertWithCallName = "v2_eth_withdraw_and_call_revert_with_call"
TestV2ERC20DepositName = "v2_erc20_deposit"
TestV2ERC20DepositAndCallName = "v2_erc20_deposit_and_call"
TestV2ERC20DepositAndCallNoMessageName = "v2_erc20_deposit_and_call_no_message"
TestV2ERC20DepositAndCallRevertName = "v2_erc20_deposit_and_call_revert"
TestV2ERC20DepositAndCallRevertWithCallName = "v2_erc20_deposit_and_call_revert_with_call"
TestV2ERC20WithdrawName = "v2_erc20_withdraw"
TestV2ERC20WithdrawAndArbitraryCallName = "v2_erc20_withdraw_and_arbitrary_call"
TestV2ERC20WithdrawAndCallName = "v2_erc20_withdraw_and_call"
TestV2ERC20WithdrawAndCallNoMessageName = "v2_erc20_withdraw_and_call_no_message"
TestV2ERC20WithdrawAndCallRevertName = "v2_erc20_withdraw_and_call_revert"
TestV2ERC20WithdrawAndCallRevertWithCallName = "v2_erc20_withdraw_and_call_revert_with_call"
TestV2ZEVMToEVMArbitraryCallName = "v2_zevm_to_evm_arbitrary_call"
Expand Down Expand Up @@ -731,6 +735,14 @@ var AllE2ETests = []runner.E2ETest{
},
TestV2ETHDepositAndCall,
),
runner.NewE2ETest(
TestV2ETHDepositAndCallNoMessageName,
"deposit Ether into ZEVM and call a contract using V2 contract using no message content",
[]runner.ArgDefinition{
{Description: "amount in wei", DefaultValue: "10000000000000000"},
},
TestV2ETHDepositAndCallNoMessage,
),
runner.NewE2ETest(
TestV2ETHDepositAndCallRevertName,
"deposit Ether into ZEVM and call a contract using V2 contract that reverts",
Expand Down Expand Up @@ -771,6 +783,14 @@ var AllE2ETests = []runner.E2ETest{
},
TestV2ETHWithdrawAndCall,
),
runner.NewE2ETest(
TestV2ETHWithdrawAndCallNoMessageName,
"withdraw Ether from ZEVM call a contract using V2 contract with no message content",
[]runner.ArgDefinition{
{Description: "amount in wei", DefaultValue: "100000"},
},
TestV2ETHWithdrawAndCallNoMessage,
),
runner.NewE2ETest(
TestV2ETHWithdrawAndCallThroughContractName,
"withdraw Ether from ZEVM call a contract using V2 contract through intermediary contract",
Expand Down Expand Up @@ -811,6 +831,14 @@ var AllE2ETests = []runner.E2ETest{
},
TestV2ERC20DepositAndCall,
),
runner.NewE2ETest(
TestV2ERC20DepositAndCallNoMessageName,
"deposit ERC20 into ZEVM and call a contract using V2 contract with no message content",
[]runner.ArgDefinition{
{Description: "amount", DefaultValue: "100000"},
},
TestV2ERC20DepositAndCallNoMessage,
),
runner.NewE2ETest(
TestV2ERC20DepositAndCallRevertName,
"deposit ERC20 into ZEVM and call a contract using V2 contract that reverts",
Expand Down Expand Up @@ -849,6 +877,12 @@ var AllE2ETests = []runner.E2ETest{
[]runner.ArgDefinition{},
TestV2ERC20WithdrawAndCall,
),
runner.NewE2ETest(
TestV2ERC20WithdrawAndCallNoMessageName,
"withdraw ERC20 from ZEVM and authenticated call a contract using V2 contract with no message",
[]runner.ArgDefinition{},
TestV2ERC20WithdrawAndCallNoMessage,
),
runner.NewE2ETest(
TestV2ERC20WithdrawAndCallRevertName,
"withdraw ERC20 from ZEVM and call a contract using V2 contract that reverts",
Expand Down
2 changes: 1 addition & 1 deletion e2e/e2etests/test_v2_erc20_deposit_and_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestV2ERC20DepositAndCall(r *runner.E2ERunner, args []string) {

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit")
r.Logger.CCTX(*cctx, "deposit_and_call")
require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status)

// check the payload was received on the contract
Expand Down
48 changes: 48 additions & 0 deletions e2e/e2etests/test_v2_erc20_deposit_and_call_no_message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package e2etests

import (
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol"

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

func TestV2ERC20DepositAndCallNoMessage(r *runner.E2ERunner, args []string) {
require.Len(r, args, 1)
lumtis marked this conversation as resolved.
Show resolved Hide resolved

amount, ok := big.NewInt(0).SetString(args[0], 10)
require.True(r, ok, "Invalid amount specified for TestV2ERC20DepositAndCallNoMessage")
lumtis marked this conversation as resolved.
Show resolved Hide resolved

r.ApproveERC20OnEVM(r.GatewayEVMAddr)
lumtis marked this conversation as resolved.
Show resolved Hide resolved

oldBalance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.TestDAppV2ZEVMAddr)
require.NoError(r, err)

// perform the deposit
tx := r.V2ERC20DepositAndCall(
r.TestDAppV2ZEVMAddr,
amount,
[]byte{},
gatewayevm.RevertOptions{OnRevertGasLimit: big.NewInt(0)},
)
lumtis marked this conversation as resolved.
Show resolved Hide resolved

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit_and_call")
require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status)
lumtis marked this conversation as resolved.
Show resolved Hide resolved

// check the payload was received on the contract
messageIndex, err := r.TestDAppV2ZEVM.GetNoMessageIndex(&bind.CallOpts{}, r.EVMAddress())
require.NoError(r, err)
r.AssertTestDAppZEVMCalled(true, messageIndex, amount)
lumtis marked this conversation as resolved.
Show resolved Hide resolved

// check the balance was updated
newBalance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.TestDAppV2ZEVMAddr)
require.NoError(r, err)
require.Equal(r, new(big.Int).Add(oldBalance, amount), newBalance)
}
2 changes: 1 addition & 1 deletion e2e/e2etests/test_v2_erc20_deposit_and_call_revert.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestV2ERC20DepositAndCallRevert(r *runner.E2ERunner, args []string) {

// wait for the cctx to be reverted
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit")
r.Logger.CCTX(*cctx, "deposit_and_call")
require.Equal(r, crosschaintypes.CctxStatus_Reverted, cctx.CctxStatus.Status)

// check the balance is more than 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestV2ERC20DepositAndCallRevertWithCall(r *runner.E2ERunner, args []string)

// wait for the cctx to be reverted
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit")
r.Logger.CCTX(*cctx, "deposit_and_call")
require.Equal(r, crosschaintypes.CctxStatus_Reverted, cctx.CctxStatus.Status)

// check the payload was received on the contract
Expand Down
55 changes: 55 additions & 0 deletions e2e/e2etests/test_v2_erc20_withdraw_and_call_no_message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package e2etests

import (
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol"

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

func TestV2ERC20WithdrawAndCallNoMessage(r *runner.E2ERunner, args []string) {
require.Len(r, args, 1)

previousGasLimit := r.ZEVMAuth.GasLimit
r.ZEVMAuth.GasLimit = 10000000
defer func() {
r.ZEVMAuth.GasLimit = previousGasLimit
}()
lumtis marked this conversation as resolved.
Show resolved Hide resolved

amount, ok := big.NewInt(0).SetString(args[0], 10)
require.True(r, ok, "Invalid amount specified for TestV2ERC20WithdrawAndCallNoMessage")

r.ApproveERC20ZRC20(r.GatewayZEVMAddr)
r.ApproveETHZRC20(r.GatewayZEVMAddr)
lumtis marked this conversation as resolved.
Show resolved Hide resolved

// perform the withdraw
tx := r.V2ERC20WithdrawAndCall(
r.TestDAppV2EVMAddr,
amount,
[]byte{},
gatewayzevm.RevertOptions{OnRevertGasLimit: big.NewInt(0)},
)
lumtis marked this conversation as resolved.
Show resolved Hide resolved

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "withdraw_and_call")
require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status)
lumtis marked this conversation as resolved.
Show resolved Hide resolved

// check called
messageIndex, err := r.TestDAppV2EVM.GetNoMessageIndex(&bind.CallOpts{}, r.EVMAddress())
require.NoError(r, err)
r.AssertTestDAppEVMCalled(true, messageIndex, amount)

// check expected sender was used
senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage(
&bind.CallOpts{},
[]byte(messageIndex),
lumtis marked this conversation as resolved.
Show resolved Hide resolved
)
require.NoError(r, err)
require.Equal(r, r.ZEVMAuth.From, senderForMsg)
}
46 changes: 46 additions & 0 deletions e2e/e2etests/test_v2_eth_deposit_and_call_no_message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package e2etests

import (
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol"

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

func TestV2ETHDepositAndCallNoMessage(r *runner.E2ERunner, args []string) {
require.Len(r, args, 1)

amount, ok := big.NewInt(0).SetString(args[0], 10)
require.True(r, ok, "Invalid amount specified for TestV2ETHDepositAndCallNoMessage")

oldBalance, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.TestDAppV2ZEVMAddr)
require.NoError(r, err)

// perform the deposit and call to the TestDAppV2ZEVMAddr
tx := r.V2ETHDepositAndCall(
r.TestDAppV2ZEVMAddr,
amount,
[]byte{},
gatewayevm.RevertOptions{OnRevertGasLimit: big.NewInt(0)},
)

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit_and_call")
require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status)

// check the payload was received on the contract
messageIndex, err := r.TestDAppV2ZEVM.GetNoMessageIndex(&bind.CallOpts{}, r.EVMAddress())
require.NoError(r, err)
r.AssertTestDAppZEVMCalled(true, messageIndex, amount)

// check the balance was updated
newBalance, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.TestDAppV2ZEVMAddr)
require.NoError(r, err)
require.Equal(r, new(big.Int).Add(oldBalance, amount), newBalance)
}
54 changes: 54 additions & 0 deletions e2e/e2etests/test_v2_eth_withdraw_and_call_no_message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package e2etests

import (
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol"

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

func TestV2ETHWithdrawAndCallNoMessage(r *runner.E2ERunner, args []string) {
require.Len(r, args, 1)

previousGasLimit := r.ZEVMAuth.GasLimit
r.ZEVMAuth.GasLimit = 10000000
defer func() {
r.ZEVMAuth.GasLimit = previousGasLimit
}()

amount, ok := big.NewInt(0).SetString(args[0], 10)
require.True(r, ok, "Invalid amount specified for TestV2ETHWithdrawAndCallNoMessage")

r.ApproveETHZRC20(r.GatewayZEVMAddr)

// perform the withdraw
tx := r.V2ETHWithdrawAndCall(
r.TestDAppV2EVMAddr,
amount,
[]byte{},
gatewayzevm.RevertOptions{OnRevertGasLimit: big.NewInt(0)},
)

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "withdraw_and_call")
require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status)

// check called
messageIndex, err := r.TestDAppV2EVM.GetNoMessageIndex(&bind.CallOpts{}, r.EVMAddress())
require.NoError(r, err)
r.AssertTestDAppEVMCalled(true, messageIndex, amount)

// check expected sender was used
senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage(
&bind.CallOpts{},
[]byte(messageIndex),
)
lumtis marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(r, err)
require.Equal(r, r.ZEVMAuth.From, senderForMsg)
}
8 changes: 4 additions & 4 deletions e2e/runner/v2_zevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (r *E2ERunner) V2ETHWithdrawAndCall(
return tx
}

// V2ETHWithdrawAndCall calls WithdrawAndCall of Gateway with gas token on ZEVM using authenticated call
// V2ETHWithdrawAndCallThroughContract calls WithdrawAndCall of Gateway with gas token on ZEVM using authenticated call
// through contract
func (r *E2ERunner) V2ETHWithdrawAndCallThroughContract(
gatewayZEVMCaller *gatewayzevmcaller.GatewayZEVMCaller,
Expand Down Expand Up @@ -120,7 +120,7 @@ func (r *E2ERunner) V2ERC20Withdraw(
return tx
}

// V2ERC20WithdrawAndCall calls WithdrawAndCall of Gateway with erc20 token on ZEVM using arbitrary call
// V2ERC20WithdrawAndArbitraryCall calls WithdrawAndCall of Gateway with erc20 token on ZEVM using arbitrary call
func (r *E2ERunner) V2ERC20WithdrawAndArbitraryCall(
receiver ethcommon.Address,
amount *big.Int,
Expand Down Expand Up @@ -178,7 +178,7 @@ func (r *E2ERunner) V2ERC20WithdrawAndCall(
return tx
}

// V2ZEVMToEMVCall calls Call of Gateway on ZEVM using arbitrary call
// V2ZEVMToEMVArbitraryCall calls Call of Gateway on ZEVM using arbitrary call
func (r *E2ERunner) V2ZEVMToEMVArbitraryCall(
receiver ethcommon.Address,
payload []byte,
Expand Down Expand Up @@ -219,7 +219,7 @@ func (r *E2ERunner) V2ZEVMToEMVCall(
return tx
}

// V2ZEVMToEMVCall calls authenticated Call of Gateway on ZEVM through contract using authenticated call
// V2ZEVMToEMVCallThroughContract calls authenticated Call of Gateway on ZEVM through contract using authenticated call
func (r *E2ERunner) V2ZEVMToEMVCallThroughContract(
gatewayZEVMCaller *gatewayzevmcaller.GatewayZEVMCaller,
receiver ethcommon.Address,
Expand Down
Loading
Loading