Skip to content

Commit

Permalink
feat: add error field in cctx
Browse files Browse the repository at this point in the history
  • Loading branch information
fbac committed Oct 1, 2024
1 parent f9cbcfc commit 2580332
Show file tree
Hide file tree
Showing 14 changed files with 235 additions and 125 deletions.
3 changes: 2 additions & 1 deletion proto/zetachain/zetacore/crosschain/cross_chain_tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ enum CctxStatus {
Reverted = 5; // inbound reverted.
Aborted =
6; // inbound tx error or invalid paramters and cannot revert; just abort.
// But the amount can be refunded to zetachain using and admin proposal
// But the amount can be refunded to zetachain using and admin proposal
}

enum TxFinalizationStatus {
Expand Down Expand Up @@ -135,4 +135,5 @@ message CrossChainTx {
repeated OutboundParams outbound_params = 10;
ProtocolContractVersion protocol_contract_version = 11;
RevertOptions revert_options = 12 [ (gogoproto.nullable) = false ];
string error = 13;
}
1 change: 1 addition & 0 deletions testutil/sample/crosschain.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ func CrossChainTx(t *testing.T, index string) *types.CrossChainTx {
OutboundParams: []*types.OutboundParams{OutboundParams(r), OutboundParams(r)},
ProtocolContractVersion: types.ProtocolContractVersion_V1,
RevertOptions: types.NewEmptyRevertOptions(),
Error: "",
}
}

Expand Down
2 changes: 1 addition & 1 deletion x/crosschain/keeper/cctx_gateway_observers.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (c CCTXGatewayObservers) InitiateOutbound(
}()
if err != nil {
// do not commit anything here as the CCTX should be aborted
config.CCTX.SetAbort(err.Error())
config.CCTX.SetAbort(true, err.Error())
return types.CctxStatus_Aborted, err
}
commit()
Expand Down
2 changes: 1 addition & 1 deletion x/crosschain/keeper/cctx_gateway_zevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (c CCTXGatewayZEVM) InitiateOutbound(

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

Expand Down
24 changes: 12 additions & 12 deletions x/crosschain/keeper/cctx_orchestrator_validate_outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (k Keeper) ValidateOutboundZEVM(
cctx.InboundParams.Amount,
)
if err != nil {
cctx.SetAbort(fmt.Sprintf("%s : %s", depositErr, err.Error()))
cctx.SetAbort(true, fmt.Sprintf("%s : %s", depositErr, err.Error()))
return types.CctxStatus_Aborted
}

Expand Down Expand Up @@ -122,7 +122,7 @@ func (k Keeper) processFailedOutboundObservers(ctx sdk.Context, cctx *types.Cros
if cctx.InboundParams.CoinType == coin.CoinType_Cmd {
// if the cctx is of coin type cmd or the sender chain is zeta chain, then we do not revert, the cctx is aborted
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
cctx.SetAbort("Outbound failed, cmd cctx reverted")
cctx.SetAbort(true, "Outbound failed: cmd cctx reverted")
} else if chains.IsZetaChain(cctx.InboundParams.SenderChainId, k.GetAuthorityKeeper().GetAdditionalChainList(ctx)) {
switch cctx.InboundParams.CoinType {
// Try revert if the coin-type is ZETA
Expand All @@ -137,7 +137,7 @@ func (k Keeper) processFailedOutboundObservers(ctx sdk.Context, cctx *types.Cros
default:
{
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
cctx.SetAbort("Outbound failed for non-ZETA cctx")
cctx.SetAbort(true, "Outbound failed for non-ZETA cctx")
}
}
} else {
Expand Down Expand Up @@ -195,10 +195,10 @@ func (k Keeper) processFailedOutboundOnExternalChain(
return err
}
// Not setting the finalization status here, the required changes have been made while creating the revert tx
cctx.SetPendingRevert(revertMsg)
cctx.SetPendingRevert(true, revertMsg)
case types.CctxStatus_PendingRevert:
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
cctx.SetAbort("Outbound failed: revert failed; abort TX")
cctx.SetAbort(true, "Outbound failed: revert failed; abort TX")
}
return nil
}
Expand All @@ -225,9 +225,9 @@ func (k Keeper) processSuccessfulOutbound(
oldStatus := cctx.CctxStatus.Status
switch oldStatus {
case types.CctxStatus_PendingRevert:
cctx.SetReverted("Outbound succeeded, revert executed")
cctx.SetReverted(false, "Outbound succeeded: revert executed")
case types.CctxStatus_PendingOutbound:
cctx.SetOutboundMined("Outbound succeeded, mined")
cctx.SetOutboundMined(false, "Outbound succeeded: mined")
default:
return
}
Expand Down Expand Up @@ -256,7 +256,7 @@ func (k Keeper) processFailedZETAOutboundOnZEVM(ctx sdk.Context, cctx *types.Cro
}

// Trying to revert the transaction this would get set to a finalized status in the same block as this does not need a TSS singing
cctx.SetPendingRevert("Outbound failed, trying revert")
cctx.SetPendingRevert(true, "Outbound failed: trying to revert")
data, err := base64.StdEncoding.DecodeString(cctx.RelayedMessage)
if err != nil {
return fmt.Errorf("failed decoding relayed message: %s", err.Error())
Expand Down Expand Up @@ -290,7 +290,7 @@ func (k Keeper) processFailedZETAOutboundOnZEVM(ctx sdk.Context, cctx *types.Cro
return fmt.Errorf("failed ZETARevertAndCallContract: %s", err.Error())
}

cctx.SetReverted("Outbound failed, revert executed")
cctx.SetReverted(true, "Outbound failed: revert executed")
if len(ctx.TxBytes()) > 0 {
// add event for tendermint transaction hash format
hash := tmbytes.HexBytes(tmtypes.Tx(ctx.TxBytes()).Hash())
Expand Down Expand Up @@ -336,7 +336,7 @@ func (k Keeper) processFailedOutboundV2(ctx sdk.Context, cctx *types.CrossChainT
}

// update status
cctx.SetPendingRevert("Outbound failed, trying revert")
cctx.SetPendingRevert(true, "Outbound failed: trying revert")

// process the revert on ZEVM
if err := k.fungibleKeeper.ProcessV2RevertDeposit(
Expand All @@ -354,7 +354,7 @@ func (k Keeper) processFailedOutboundV2(ctx sdk.Context, cctx *types.CrossChainT
}

// tx is reverted
cctx.SetReverted("Outbound failed, revert executed")
cctx.SetReverted(true, "Outbound failed: revert executed")

// add event for tendermint transaction hash format
if len(ctx.TxBytes()) > 0 {
Expand All @@ -367,7 +367,7 @@ func (k Keeper) processFailedOutboundV2(ctx sdk.Context, cctx *types.CrossChainT
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
case types.CctxStatus_PendingRevert:
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
cctx.SetAbort("Outbound failed: revert failed; abort TX")
cctx.SetAbort(true, "Outbound failed: revert failed; abort TX")
}
return nil
}
2 changes: 1 addition & 1 deletion x/crosschain/keeper/initiate_outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ func (k Keeper) InitiateOutbound(ctx sdk.Context, config InitiateOutboundConfig)
)
}

config.CCTX.SetPendingOutbound("")
config.CCTX.SetPendingOutbound(false, "")
return cctxGateway.InitiateOutbound(ctx, config)
}
3 changes: 1 addition & 2 deletions x/crosschain/keeper/msg_server_migrate_tss_funds.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
tmbytes "github.com/cometbft/cometbft/libs/bytes"
tmtypes "github.com/cometbft/cometbft/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/errors"

authoritytypes "github.com/zeta-chain/node/x/authority/types"
"github.com/zeta-chain/node/x/crosschain/types"
Expand All @@ -26,7 +25,7 @@ func (k msgServer) MigrateTssFunds(
// check if authorized
err := k.GetAuthorityKeeper().CheckAuthorization(ctx, msg)
if err != nil {
return nil, errors.Wrap(authoritytypes.ErrUnauthorized, err.Error())
return nil, errorsmod.Wrap(authoritytypes.ErrUnauthorized, err.Error())
}

if k.zetaObserverKeeper.IsInboundEnabled(ctx) {
Expand Down
2 changes: 1 addition & 1 deletion x/crosschain/keeper/msg_server_vote_outbound_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ SaveFailedOutbound saves a failed outbound transaction.It does the following thi
*/

func (k Keeper) SaveFailedOutbound(ctx sdk.Context, cctx *types.CrossChainTx, errMessage string, tssPubkey string) {
cctx.SetAbort(errMessage)
cctx.SetAbort(true, errMessage)
ctx.Logger().Error(errMessage)
k.SaveOutbound(ctx, cctx, tssPubkey)
}
Expand Down
1 change: 1 addition & 0 deletions x/crosschain/migrations/v5/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ func SetZetaAccounting(

return nil
}

func GetAbortedAmount(cctx types.CrossChainTx) sdkmath.Uint {
if cctx.OutboundParams != nil && !cctx.GetCurrentOutboundParam().Amount.IsZero() {
return cctx.GetCurrentOutboundParam().Amount
Expand Down
34 changes: 24 additions & 10 deletions x/crosschain/types/cctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,29 +170,42 @@ func (m *CrossChainTx) AddOutbound(
return nil
}

func (m *CrossChainTx) ChangeStatus(newStatus CctxStatus, isError bool, msg string) {
switch {
case isError && msg == "":
m.CctxStatus.ChangeStatus(newStatus, "")
m.Error = "unexpected error"
case isError && msg != "":
m.CctxStatus.ChangeStatus(newStatus, "")
m.Error = msg
case !isError:
m.CctxStatus.ChangeStatus(newStatus, msg)
}
}

// SetAbort sets the CCTX status to Aborted with the given error message.
func (m CrossChainTx) SetAbort(message string) {
m.CctxStatus.ChangeStatus(CctxStatus_Aborted, message)
func (m *CrossChainTx) SetAbort(isError bool, msg string) {
m.ChangeStatus(CctxStatus_Aborted, isError, msg)
}

// SetPendingRevert sets the CCTX status to PendingRevert with the given error message.
func (m CrossChainTx) SetPendingRevert(message string) {
m.CctxStatus.ChangeStatus(CctxStatus_PendingRevert, message)
func (m *CrossChainTx) SetPendingRevert(isError bool, msg string) {
m.ChangeStatus(CctxStatus_PendingRevert, isError, msg)
}

// SetPendingOutbound sets the CCTX status to PendingOutbound with the given error message.
func (m CrossChainTx) SetPendingOutbound(message string) {
m.CctxStatus.ChangeStatus(CctxStatus_PendingOutbound, message)
func (m *CrossChainTx) SetPendingOutbound(isError bool, msg string) {
m.ChangeStatus(CctxStatus_PendingOutbound, isError, msg)
}

// SetOutboundMined sets the CCTX status to OutboundMined with the given error message.
func (m CrossChainTx) SetOutboundMined(message string) {
m.CctxStatus.ChangeStatus(CctxStatus_OutboundMined, message)
func (m *CrossChainTx) SetOutboundMined(isError bool, msg string) {
m.ChangeStatus(CctxStatus_OutboundMined, isError, msg)
}

// SetReverted sets the CCTX status to Reverted with the given error message.
func (m CrossChainTx) SetReverted(message string) {
m.CctxStatus.ChangeStatus(CctxStatus_Reverted, message)
func (m *CrossChainTx) SetReverted(isError bool, msg string) {
m.ChangeStatus(CctxStatus_Reverted, isError, msg)
}

func (m CrossChainTx) GetCCTXIndexBytes() ([32]byte, error) {
Expand Down Expand Up @@ -273,6 +286,7 @@ func NewCCTX(ctx sdk.Context, msg MsgVoteInbound, tssPubkey string) (CrossChainT
OutboundParams: []*OutboundParams{outboundParams},
ProtocolContractVersion: msg.ProtocolContractVersion,
RevertOptions: msg.RevertOptions,
Error: "",
}

// TODO: remove this validate call
Expand Down
56 changes: 50 additions & 6 deletions x/crosschain/types/cctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,39 +150,83 @@ func Test_SetRevertOutboundValues(t *testing.T) {

func TestCrossChainTx_SetAbort(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.SetAbort("test")
cctx.SetAbort(false, "test")
require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status)
require.Equal(t, "test", "test")
require.Contains(t, cctx.CctxStatus.StatusMessage, "test")
}

func TestCrossChainTx_SetAbortWithError(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.SetAbort(true, "test")
require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status)
require.NotContains(t, cctx.CctxStatus.StatusMessage, "test")
require.Equal(t, "test", cctx.Error)
}

func TestCrossChainTx_SetPendingRevert(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound
cctx.SetPendingRevert("test")
cctx.SetPendingRevert(false, "test")
require.Equal(t, types.CctxStatus_PendingRevert, cctx.CctxStatus.Status)
require.Contains(t, cctx.CctxStatus.StatusMessage, "test")
}

func TestCrossChainTx_SetPendingWithError(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound
cctx.SetPendingRevert(true, "test")
require.Equal(t, types.CctxStatus_PendingRevert, cctx.CctxStatus.Status)
require.NotContains(t, cctx.CctxStatus.StatusMessage, "test")
require.Equal(t, "test", cctx.Error)
}

func TestCrossChainTx_SetPendingOutbound(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.CctxStatus.Status = types.CctxStatus_PendingInbound
cctx.SetPendingOutbound("test")
cctx.SetPendingOutbound(false, "test")
require.Equal(t, types.CctxStatus_PendingOutbound, cctx.CctxStatus.Status)
require.Contains(t, cctx.CctxStatus.StatusMessage, "test")
}

func TestCrossChainTx_SetPendingOutboundWithError(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.CctxStatus.Status = types.CctxStatus_PendingInbound
cctx.SetPendingOutbound(true, "test")
require.Equal(t, types.CctxStatus_PendingOutbound, cctx.CctxStatus.Status)
require.NotContains(t, cctx.CctxStatus.StatusMessage, "test")
require.Equal(t, "test", cctx.Error)
}

func TestCrossChainTx_SetOutboundMined(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound
cctx.SetOutboundMined("test")
cctx.SetOutboundMined(false, "test")
require.Equal(t, types.CctxStatus_OutboundMined, cctx.CctxStatus.Status)
require.Contains(t, cctx.CctxStatus.StatusMessage, "test")
}

func TestCrossChainTx_SetOutboundMinedWithError(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound
cctx.SetOutboundMined(true, "test")
require.Equal(t, types.CctxStatus_OutboundMined, cctx.CctxStatus.Status)
require.NotContains(t, cctx.CctxStatus.StatusMessage, "test")
require.Contains(t, cctx.Error, "test")
}

func TestCrossChainTx_SetReverted(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.CctxStatus.Status = types.CctxStatus_PendingRevert
cctx.SetReverted("test")
cctx.SetReverted(false, "test")
require.Equal(t, types.CctxStatus_Reverted, cctx.CctxStatus.Status)
require.Contains(t, cctx.CctxStatus.StatusMessage, "test")
}

func TestCrossChainTx_SetRevertedWithError(t *testing.T) {
cctx := sample.CrossChainTx(t, "test")
cctx.CctxStatus.Status = types.CctxStatus_PendingRevert
cctx.SetReverted(true, "test")
require.Equal(t, types.CctxStatus_Reverted, cctx.CctxStatus.Status)
require.NotContains(t, cctx.CctxStatus.StatusMessage, "test")
require.Contains(t, cctx.Error, "test")
}
Loading

0 comments on commit 2580332

Please sign in to comment.