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: add error field in cctx #2952

Merged
merged 13 commits into from
Oct 8, 2024
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;
fbac marked this conversation as resolved.
Show resolved Hide resolved
fbac marked this conversation as resolved.
Show resolved Hide resolved
}
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
Loading