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

refactor: cctx validate inbound #2340

Merged
merged 51 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
4abefdb
move code to validate outbound methods
skosito Jun 4, 2024
28aa31e
refactor
skosito Jun 4, 2024
e6609e5
renaming and moving code around
skosito Jun 5, 2024
2e826a7
fixes
skosito Jun 5, 2024
61a3594
Merge branch 'develop' into cctx-validate-outbound
skosito Jun 5, 2024
6cc517e
refactoring
skosito Jun 5, 2024
e2d3c8b
changelog
skosito Jun 5, 2024
5f91691
make generate
skosito Jun 5, 2024
6cb69cd
fix initiate outbound tests
skosito Jun 5, 2024
47b7b88
fix validate outbound tests
skosito Jun 5, 2024
08dfea1
fix tests
skosito Jun 5, 2024
0bba576
fix e2e test
skosito Jun 5, 2024
20c775e
fix unit tests
skosito Jun 5, 2024
1f153e8
make generate
skosito Jun 5, 2024
455bce5
Merge branch 'develop' into cctx-validate-outbound
skosito Jun 6, 2024
0b5f4be
cleanup
skosito Jun 6, 2024
9394425
try to split initiate and validate outbound for zevm
skosito Jun 6, 2024
4288868
Merge branch 'develop' into cctx-validate-outbound
skosito Jun 6, 2024
992c55b
make generate
skosito Jun 6, 2024
bd125a8
cleanup
skosito Jun 6, 2024
8333985
cleanup
skosito Jun 6, 2024
b497cbc
e2e test fix
skosito Jun 6, 2024
d437a39
PR comment
skosito Jun 7, 2024
f856cd4
Merge branch 'develop' into cctx-validate-outbound
skosito Jun 7, 2024
c683384
fix typo after merge
skosito Jun 7, 2024
a11d1b2
Merge branch 'develop' into cctx-validate-outbound
skosito Jun 10, 2024
16f858f
renaming
skosito Jun 10, 2024
59c6d5f
move validate inbound for observers logic to separate method
skosito Jun 10, 2024
36b38f8
Move cctx gateway outside of crosschain keeper wip
skosito Jun 12, 2024
5583307
cleanup
skosito Jun 12, 2024
ec7465e
changelog
skosito Jun 12, 2024
303c112
make generate
skosito Jun 12, 2024
f675251
lint fixes
skosito Jun 12, 2024
0ef2093
fix evm hooks tests
skosito Jun 12, 2024
a87f4cd
fix init outbound tests
skosito Jun 12, 2024
c89b079
Merge branch 'develop' into cctx-validate-inbound
skosito Jun 12, 2024
1dbfdb9
cleanup
skosito Jun 12, 2024
e7cedab
Merge branch 'develop' into cctx-validate-outbound
skosito Jun 12, 2024
be56c37
Merge branch 'cctx-validate-outbound' into cctx-validate-inbound
skosito Jun 12, 2024
4e468f7
cleanup
skosito Jun 12, 2024
dd56896
PR comments
skosito Jun 13, 2024
0a7234e
Merge branch 'cctx-validate-outbound' into cctx-validate-inbound
skosito Jun 13, 2024
b823a45
fix changelog
skosito Jun 17, 2024
0859a62
Merge branch 'cctx-validate-outbound' into cctx-validate-inbound
skosito Jun 17, 2024
665b2ff
PR comments pt1
skosito Jun 17, 2024
5c49a9c
PR comments pt2
skosito Jun 18, 2024
2c2d7e5
add todo
skosito Jun 18, 2024
86c1f5c
Merge branch 'develop' into cctx-validate-inbound
skosito Jun 19, 2024
ae38f3b
PR comments
skosito Jun 19, 2024
7f3bf86
Merge branch 'develop' into cctx-validate-inbound
skosito Jun 20, 2024
e835137
Merge branch 'develop' into cctx-validate-inbound
skosito Jun 20, 2024
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
9 changes: 0 additions & 9 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ import (

"github.com/zeta-chain/zetacore/app/ante"
"github.com/zeta-chain/zetacore/docs/openapi"
"github.com/zeta-chain/zetacore/pkg/chains"
zetamempool "github.com/zeta-chain/zetacore/pkg/mempool"
srvflags "github.com/zeta-chain/zetacore/server/flags"
authoritymodule "github.com/zeta-chain/zetacore/x/authority"
Expand Down Expand Up @@ -598,14 +597,6 @@ func New(
app.LightclientKeeper,
)

// initializing map of cctx gateways so crosschain module can decide which one to use
// based on chain info of destination chain
cctxGateways := map[chains.CCTXGateway]crosschainkeeper.CCTXGateway{
chains.CCTXGateway_observers: crosschainkeeper.NewCCTXGatewayObservers(app.CrosschainKeeper),
chains.CCTXGateway_zevm: crosschainkeeper.NewCCTXGatewayZEVM(app.CrosschainKeeper),
}
app.CrosschainKeeper.SetCCTXGateways(cctxGateways)
skosito marked this conversation as resolved.
Show resolved Hide resolved

// initialize ibccrosschain keeper and set it to the crosschain keeper
// there is a circular dependency between the two keepers, crosschain keeper must be initialized first

Expand Down
3 changes: 2 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@
* [2269](https://github.com/zeta-chain/node/pull/2269) - refactor MsgUpdateCrosschainFlags into MsgEnableCCTX, MsgDisableCCTX and MsgUpdateGasPriceIncreaseFlags
* [2306](https://github.com/zeta-chain/node/pull/2306) - refactor zetaclient outbound transaction signing logic
* [2296](https://github.com/zeta-chain/node/pull/2296) - move `testdata` package to `testutil` to organize test-related utilities
* [2344](https://github.com/zeta-chain/node/pull/2344) - group common data of EVM/Bitcoin signer and observer using base structs
* [2317](https://github.com/zeta-chain/node/pull/2317) - add ValidateOutbound method for cctx orchestrator
* [2340](https://github.com/zeta-chain/node/pull/2340) - add ValidateInbound method for cctx orchestrator
* [2344](https://github.com/zeta-chain/node/pull/2344) - group common data of EVM/Bitcoin signer and observer using base structs

### Tests

Expand Down
8 changes: 0 additions & 8 deletions testutil/keeper/crosschain.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,8 @@ func CrosschainKeeperWithMocks(
lightclientKeeper,
)

cctxGateways := map[chains.CCTXGateway]keeper.CCTXGateway{
chains.CCTXGateway_observers: keeper.NewCCTXGatewayObservers(*k),
chains.CCTXGateway_zevm: keeper.NewCCTXGatewayZEVM(*k),
}

k.SetCCTXGateways(cctxGateways)

// initialize ibccrosschain keeper and set it to the crosschain keeper
// there is a circular dependency between the two keepers, crosschain keeper must be initialized first

var ibcCrosschainKeeperTmp types.IBCCrosschainKeeper = initIBCCrosschainKeeper(
cdc,
db,
Expand Down
54 changes: 37 additions & 17 deletions x/crosschain/keeper/cctx_gateway_observers.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package keeper

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/zeta-chain/zetacore/pkg/chains"
"github.com/zeta-chain/zetacore/x/crosschain/types"
)

Expand Down Expand Up @@ -32,28 +35,45 @@ InitiateOutbound updates the store so observers can use the PendingCCTX query:
*/
func (c CCTXGatewayObservers) InitiateOutbound(
ctx sdk.Context,
cctx *types.CrossChainTx,
) (newCCTXStatus types.CctxStatus) {
config InitiateOutboundConfig,
skosito marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
) (newCCTXStatus types.CctxStatus, err error) {
tmpCtx, commit := ctx.CacheContext()
outboundReceiverChainID := cctx.GetCurrentOutboundParam().ReceiverChainId
err := func() error {
err := c.crosschainKeeper.PayGasAndUpdateCctx(
tmpCtx,
outboundReceiverChainID,
cctx,
cctx.InboundParams.Amount,
false,
)
if err != nil {
return err
outboundReceiverChainID := config.CCTX.GetCurrentOutboundParam().ReceiverChainId
// TODO (https://github.com/zeta-chain/node/issues/1010): workaround for this bug
noEthereumTxEvent := false
if chains.IsZetaChain(config.CCTX.InboundParams.SenderChainId) {
noEthereumTxEvent = true
}
lumtis marked this conversation as resolved.
Show resolved Hide resolved

err = func() error {
// If ShouldPayGas flag is set during ValidateInbound PayGasAndUpdateCctx should be called
// which will set GasPrice and Amount. Otherwise, use median gas price and InboundParams amount.
if config.ShouldPayGas {
err := c.crosschainKeeper.PayGasAndUpdateCctx(
tmpCtx,
outboundReceiverChainID,
config.CCTX,
config.CCTX.InboundParams.Amount,
noEthereumTxEvent,
)
if err != nil {
return err
}
} else {
gasPrice, found := c.crosschainKeeper.GetMedianGasPriceInUint(ctx, config.CCTX.GetCurrentOutboundParam().ReceiverChainId)
if !found {
return fmt.Errorf("gasprice not found for %d", config.CCTX.GetCurrentOutboundParam().ReceiverChainId)
}
config.CCTX.GetCurrentOutboundParam().GasPrice = gasPrice.String()
config.CCTX.GetCurrentOutboundParam().Amount = config.CCTX.InboundParams.Amount
}
return c.crosschainKeeper.UpdateNonce(tmpCtx, outboundReceiverChainID, cctx)
return c.crosschainKeeper.SetObserverOutboundInfo(tmpCtx, outboundReceiverChainID, config.CCTX)
}()
if err != nil {
// do not commit anything here as the CCTX should be aborted
cctx.SetAbort(err.Error())
return types.CctxStatus_Aborted
config.CCTX.SetAbort(err.Error())
return types.CctxStatus_Aborted, err
}
commit()
return types.CctxStatus_PendingOutbound
return types.CctxStatus_PendingOutbound, nil
}
15 changes: 9 additions & 6 deletions x/crosschain/keeper/cctx_gateway_zevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@ func NewCCTXGatewayZEVM(crosschainKeeper Keeper) CCTXGatewayZEVM {
}

// InitiateOutbound handles evm deposit and immediately validates pending outbound
func (c CCTXGatewayZEVM) InitiateOutbound(ctx sdk.Context, cctx *types.CrossChainTx) (newCCTXStatus types.CctxStatus) {
func (c CCTXGatewayZEVM) InitiateOutbound(
ctx sdk.Context,
config InitiateOutboundConfig,
) (newCCTXStatus types.CctxStatus, err error) {
tmpCtx, commit := ctx.CacheContext()
isContractReverted, err := c.crosschainKeeper.HandleEVMDeposit(tmpCtx, cctx)
isContractReverted, err := c.crosschainKeeper.HandleEVMDeposit(tmpCtx, config.CCTX)

if err != nil && !isContractReverted {
// exceptional case; internal error; should abort CCTX
cctx.SetAbort(err.Error())
return types.CctxStatus_Aborted
config.CCTX.SetAbort(err.Error())
return types.CctxStatus_Aborted, err
}

newCCTXStatus = c.crosschainKeeper.ValidateOutboundZEVM(ctx, cctx, err, isContractReverted)
newCCTXStatus = c.crosschainKeeper.ValidateOutboundZEVM(ctx, config.CCTX, err, isContractReverted)
if newCCTXStatus == types.CctxStatus_OutboundMined {
commit()
}

return newCCTXStatus
return newCCTXStatus, nil
}
29 changes: 29 additions & 0 deletions x/crosschain/keeper/cctx_gateways.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/zeta-chain/zetacore/pkg/chains"
"github.com/zeta-chain/zetacore/x/crosschain/types"
)

// CCTXGateway is interface implemented by every gateway. It is one of interfaces used for communication
// between CCTX gateways and crosschain module, and it is called by crosschain module.
type CCTXGateway interface {
// Initiate a new outbound, this tells the CCTXGateway to carry out the action to execute the outbound.
// It is the only entry point to initiate an outbound and it returns new CCTX status after it is completed.
InitiateOutbound(ctx sdk.Context, config InitiateOutboundConfig) (newCCTXStatus types.CctxStatus, err error)
}

var cctxGateways map[chains.CCTXGateway]CCTXGateway

// ResolveCCTXGateway respolves cctx gateway implementation based on provided cctx gateway
func ResolveCCTXGateway(c chains.CCTXGateway, keeper Keeper) (CCTXGateway, bool) {
cctxGateways = map[chains.CCTXGateway]CCTXGateway{
chains.CCTXGateway_observers: NewCCTXGatewayObservers(keeper),
chains.CCTXGateway_zevm: NewCCTXGatewayZEVM(keeper),
}

cctxGateway, ok := cctxGateways[c]
return cctxGateway, ok
}
50 changes: 50 additions & 0 deletions x/crosschain/keeper/cctx_orchestrator_validate_inbound.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/zeta-chain/zetacore/x/crosschain/types"
observertypes "github.com/zeta-chain/zetacore/x/observer/types"
)

// ValidateInbound is the only entry-point to create new CCTX (eg. when observers voting is done or new inbound event is detected).
// It creates new CCTX object and calls InitiateOutbound method.
func (k Keeper) ValidateInbound(
skosito marked this conversation as resolved.
Show resolved Hide resolved
ctx sdk.Context,
msg *types.MsgVoteInbound,
shouldPayGas bool,
) (*types.CrossChainTx, error) {
tss, tssFound := k.zetaObserverKeeper.GetTSS(ctx)
if !tssFound {
return nil, types.ErrCannotFindTSSKeys
}

// Do not process if inbound is disabled
if !k.zetaObserverKeeper.IsInboundEnabled(ctx) {
return nil, observertypes.ErrInboundDisabled
}

// create a new CCTX from the inbound message. The status of the new CCTX is set to PendingInbound.
cctx, err := types.NewCCTX(ctx, *msg, tss.TssPubkey)
if err != nil {
return nil, err
}
skosito marked this conversation as resolved.
Show resolved Hide resolved

// Initiate outbound, the process function manages the state commit and cctx status change.
// If the process fails, the changes to the evm state are rolled back.
_, err = k.InitiateOutbound(ctx, InitiateOutboundConfig{
CCTX: &cctx,
ShouldPayGas: shouldPayGas,
})
if err != nil {
return nil, err
}

inCctxIndex, ok := ctx.Value(InCCTXIndexKey).(string)
if ok {
cctx.InboundParams.ObservedHash = inCctxIndex
}
k.SetCctxAndNonceToCctxAndInboundHashToCctx(ctx, cctx)

return &cctx, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (k Keeper) validateFailedOutbound(
if err != nil {
return err
}
err = k.UpdateNonce(ctx, cctx.InboundParams.SenderChainId, cctx)
err = k.SetObserverOutboundInfo(ctx, cctx.InboundParams.SenderChainId, cctx)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions x/crosschain/keeper/cctx_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (
zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types"
)

// UpdateNonce sets the CCTX outbound nonce to the next nonce, and updates the nonce of blockchain state.
// SetObserverOutboundInfo sets the CCTX outbound nonce to the next available nonce for the TSS address, and updates the nonce of blockchain state.
// It also updates the PendingNonces that is used to track the unfulfilled outbound txs.
func (k Keeper) UpdateNonce(ctx sdk.Context, receiveChainID int64, cctx *types.CrossChainTx) error {
func (k Keeper) SetObserverOutboundInfo(ctx sdk.Context, receiveChainID int64, cctx *types.CrossChainTx) error {
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
chain := k.GetObserverKeeper().GetSupportedChainFromChainID(ctx, receiveChainID)
if chain == nil {
return zetaObserverTypes.ErrSupportedChains
Expand Down
14 changes: 7 additions & 7 deletions x/crosschain/keeper/cctx_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func Test_IsPending(t *testing.T) {
}
}

func TestKeeper_UpdateNonce(t *testing.T) {
func TestKeeper_SetObserverOutboundInfo(t *testing.T) {
t.Run("should error if supported chain is nil", func(t *testing.T) {
k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{
UseObserverMock: true,
Expand All @@ -236,7 +236,7 @@ func TestKeeper_UpdateNonce(t *testing.T) {
// mock failed GetSupportedChainFromChainID
keepertest.MockFailedGetSupportedChainFromChainID(observerMock, nil)

err := k.UpdateNonce(ctx, 5, nil)
err := k.SetObserverOutboundInfo(ctx, 5, nil)
require.Error(t, err)
})

Expand All @@ -262,7 +262,7 @@ func TestKeeper_UpdateNonce(t *testing.T) {
{Amount: sdkmath.NewUint(1)},
},
}
err := k.UpdateNonce(ctx, 5, &cctx)
err := k.SetObserverOutboundInfo(ctx, 5, &cctx)
require.Error(t, err)
})

Expand Down Expand Up @@ -291,7 +291,7 @@ func TestKeeper_UpdateNonce(t *testing.T) {
{Amount: sdkmath.NewUint(1)},
},
}
err := k.UpdateNonce(ctx, 5, &cctx)
err := k.SetObserverOutboundInfo(ctx, 5, &cctx)
require.Error(t, err)
require.Equal(t, uint64(100), cctx.GetCurrentOutboundParam().TssNonce)
})
Expand Down Expand Up @@ -324,7 +324,7 @@ func TestKeeper_UpdateNonce(t *testing.T) {
{Amount: sdkmath.NewUint(1)},
},
}
err := k.UpdateNonce(ctx, 5, &cctx)
err := k.SetObserverOutboundInfo(ctx, 5, &cctx)
require.Error(t, err)
})

Expand Down Expand Up @@ -358,7 +358,7 @@ func TestKeeper_UpdateNonce(t *testing.T) {
{Amount: sdkmath.NewUint(1)},
},
}
err := k.UpdateNonce(ctx, 5, &cctx)
err := k.SetObserverOutboundInfo(ctx, 5, &cctx)
require.Error(t, err)
})

Expand Down Expand Up @@ -395,7 +395,7 @@ func TestKeeper_UpdateNonce(t *testing.T) {
{Amount: sdkmath.NewUint(1)},
},
}
err := k.UpdateNonce(ctx, 5, &cctx)
err := k.SetObserverOutboundInfo(ctx, 5, &cctx)
require.NoError(t, err)
})
}
Expand Down
4 changes: 3 additions & 1 deletion x/crosschain/keeper/evm_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types"
)

const InCCTXIndexKey = "inCctxIndex"

// HandleEVMDeposit handles a deposit from an inbound tx
// returns (isContractReverted, err)
// (true, non-nil) means CallEVM() reverted
Expand Down Expand Up @@ -102,7 +104,7 @@ func (k Keeper) HandleEVMDeposit(ctx sdk.Context, cctx *types.CrossChainTx) (boo
if !evmTxResponse.Failed() && contractCall {
logs := evmtypes.LogsToEthereum(evmTxResponse.Logs)
if len(logs) > 0 {
ctx = ctx.WithValue("inCctxIndex", cctx.Index)
ctx = ctx.WithValue(InCCTXIndexKey, cctx.Index)
txOrigin := cctx.InboundParams.TxOrigin
if txOrigin == "" {
txOrigin = inboundSender
Expand Down
Loading
Loading