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 : update cctx status object [WIP] #3326

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
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
5 changes: 5 additions & 0 deletions docs/openapi/openapi.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58504,6 +58504,11 @@ definitions:
type: string
format: int64
description: when the CCTX was created. only populated on new transactions.
error_message_revert:
type: string
title: |-
error_message_revert carries information about the revert outbound tx ,
which is created if the first outbound tx fails
zetacoreemissionsParams:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,8 @@ func TestBitcoinDepositAndCallRevertWithDust(r *runner.E2ERunner, args []string)
cctx := utils.WaitCctxAbortedByInboundHash(r.Ctx, r, txHash.String(), r.CctxClient)

require.True(r, cctx.GetCurrentOutboundParam().Amount.Uint64() < constant.BTCWithdrawalDustAmount)
require.True(r, strings.Contains(cctx.CctxStatus.ErrorMessage, crosschaintypes.ErrInvalidWithdrawalAmount.Error()))
require.True(
r,
strings.Contains(cctx.CctxStatus.ErrorMessageRevert, crosschaintypes.ErrInvalidWithdrawalAmount.Error()),
)
}
12 changes: 12 additions & 0 deletions proto/zetachain/zetacore/crosschain/cross_chain_tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ message Status {
bool isAbortRefunded = 4;
// when the CCTX was created. only populated on new transactions.
int64 created_timestamp = 5;
// error_message_revert carries information about the revert outbound tx ,
// which is created if the first outbound tx fails
string error_message_revert = 7;
}

// StatusMessages is a message that carries status and error messages for a
// cctx Currently this is only used internally to pass messages when updating
// the status
message StatusMessages {
string status_message = 1;
string error_message_outbound = 2;
string error_message_revert = 3;
}

// ProtocolContractVersion represents the version of the protocol contract used
Expand Down
46 changes: 46 additions & 0 deletions typescript/zetachain/zetacore/crosschain/cross_chain_tx_pb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,14 @@ export declare class Status extends Message<Status> {
*/
createdTimestamp: bigint;

/**
* error_message_revert carries information about the revert outbound tx ,
* which is created if the first outbound tx fails
*
* @generated from field: string error_message_revert = 7;
*/
errorMessageRevert: string;

constructor(data?: PartialMessage<Status>);

static readonly runtime: typeof proto3;
Expand All @@ -410,6 +418,44 @@ export declare class Status extends Message<Status> {
static equals(a: Status | PlainMessage<Status> | undefined, b: Status | PlainMessage<Status> | undefined): boolean;
}

/**
* StatusMessages is a message that carries status and error messages for a
* cctx Currently this is only used internally to pass messages when updating
* the status
*
* @generated from message zetachain.zetacore.crosschain.StatusMessages
*/
export declare class StatusMessages extends Message<StatusMessages> {
/**
* @generated from field: string status_message = 1;
*/
statusMessage: string;

/**
* @generated from field: string error_message_outbound = 2;
*/
errorMessageOutbound: string;

/**
* @generated from field: string error_message_revert = 3;
*/
errorMessageRevert: string;

constructor(data?: PartialMessage<StatusMessages>);

static readonly runtime: typeof proto3;
static readonly typeName = "zetachain.zetacore.crosschain.StatusMessages";
static readonly fields: FieldList;

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): StatusMessages;

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): StatusMessages;

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): StatusMessages;

static equals(a: StatusMessages | PlainMessage<StatusMessages> | undefined, b: StatusMessages | PlainMessage<StatusMessages> | undefined): boolean;
}

/**
* RevertOptions represents the options for reverting a cctx
*
Expand Down
5 changes: 4 additions & 1 deletion x/crosschain/keeper/cctx_gateway_observers.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ func (c CCTXGatewayObservers) InitiateOutbound(
}()
if err != nil {
// do not commit anything here as the CCTX should be aborted
config.CCTX.SetAbort("internal error", err.Error())
config.CCTX.SetAbort(types.StatusMessages{
StatusMessage: "Outbound preprocessing failed for cctx when initiating outbound",
ErrorMessageOutbound: err.Error(),
})
return types.CctxStatus_Aborted, err
}
commit()
Expand Down
7 changes: 4 additions & 3 deletions x/crosschain/keeper/cctx_gateway_zevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ func (c CCTXGatewayZEVM) InitiateOutbound(

if err != nil && !isContractReverted {
// exceptional case; internal error; should abort CCTX
config.CCTX.SetAbort(
"error during deposit that is not smart contract revert",
err.Error())
config.CCTX.SetAbort(types.StatusMessages{
StatusMessage: "Error processing outbound to ZEVM , but contract call did not revert",
ErrorMessageOutbound: err.Error(),
})
return types.CctxStatus_Aborted, err
}

Expand Down
57 changes: 43 additions & 14 deletions x/crosschain/keeper/cctx_orchestrator_validate_outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,17 @@
depositErr.Error(),
cctx.InboundParams.Amount,
)

if err != nil {
// Error here would mean the outbound tx failed and we also failed to create a revert tx.
// In this case the cctx can be aborted directly
cctx.SetAbort(
"revert failed",
fmt.Sprintf("deposit error: %s, processing error: %s", depositErr.Error(), err.Error()))
types.StatusMessages{
StatusMessage: fmt.Sprintf("Revert failed , Error : %s", depositErr.Error()),
ErrorMessageRevert: fmt.Sprintf("Processing error: %s", err.Error()),
})
return types.CctxStatus_Aborted
}

commitRevert()
return types.CctxStatus_PendingRevert
}
Expand Down Expand Up @@ -124,7 +128,9 @@
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 for admin tx")
cctx.SetAbort(types.StatusMessages{
StatusMessage: "outbound failed for admin tx",
})
} 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 @@ -139,7 +145,10 @@
default:
{
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
cctx.SetAbort("", "outbound failed for non-ZETA cctx")
cctx.SetAbort(types.StatusMessages{
StatusMessage: "outbound failed for non-ZETA cctx",
ErrorMessageOutbound: fmt.Sprintf("coin type %s not supported for revert when source chain is Zetachain", cctx.InboundParams.CoinType),
})
}
}
} else {
Expand Down Expand Up @@ -210,10 +219,16 @@
return err
}
// Not setting the finalization status here, the required changes have been made while creating the revert tx
cctx.SetPendingRevert("", revertMsg)
cctx.SetPendingRevert(types.StatusMessages{
StatusMessage: "Outbound failed",
ErrorMessageOutbound: revertMsg,
})
case types.CctxStatus_PendingRevert:
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
cctx.SetAbort("aborted while processing failed outbound", "outbound and revert failed")
cctx.SetAbort(types.StatusMessages{
StatusMessage: "Revert failed",
ErrorMessageRevert: revertMsg,
})
}
return nil
}
Expand All @@ -240,9 +255,9 @@
oldStatus := cctx.CctxStatus.Status
switch oldStatus {
case types.CctxStatus_PendingRevert:
cctx.SetReverted("", "")
cctx.SetReverted(types.StatusMessages{StatusMessage: "Revert successful"})
case types.CctxStatus_PendingOutbound:
cctx.SetOutboundMined("")
cctx.SetOutboundMined(types.StatusMessages{StatusMessage: "Outbound mined successfully"})
default:
return
}
Expand Down Expand Up @@ -271,7 +286,10 @@
}

// 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")
cctx.SetPendingRevert(types.StatusMessages{
StatusMessage: "Outbound failed",
ErrorMessageOutbound: "outbound failed to external chain ,start 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 @@ -305,7 +323,10 @@
return fmt.Errorf("failed ZETARevertAndCallContract: %s", err.Error())
}

cctx.SetReverted("", "outbound failed")
cctx.SetReverted(types.StatusMessages{
StatusMessage: "Reverted to ZEVM",
})

if len(ctx.TxBytes()) > 0 {
// add event for tendermint transaction hash format
hash := tmbytes.HexBytes(tmtypes.Tx(ctx.TxBytes()).Hash())
Expand Down Expand Up @@ -350,7 +371,10 @@
}

// update status
cctx.SetPendingRevert("", "outbound failed")
cctx.SetPendingRevert(types.StatusMessages{
StatusMessage: "Outbound failed",
ErrorMessageOutbound: "outbound failed to external chain",
})

Check warning on line 377 in x/crosschain/keeper/cctx_orchestrator_validate_outbound.go

View check run for this annotation

Codecov / codecov/patch

x/crosschain/keeper/cctx_orchestrator_validate_outbound.go#L374-L377

Added lines #L374 - L377 were not covered by tests

// process the revert on ZEVM
if err := k.fungibleKeeper.ProcessV2RevertDeposit(
Expand All @@ -368,7 +392,9 @@
}

// tx is reverted
cctx.SetReverted("", "outbound failed")
cctx.SetReverted(types.StatusMessages{
StatusMessage: "Reverted to ZEVM",
})

Check warning on line 397 in x/crosschain/keeper/cctx_orchestrator_validate_outbound.go

View check run for this annotation

Codecov / codecov/patch

x/crosschain/keeper/cctx_orchestrator_validate_outbound.go#L395-L397

Added lines #L395 - L397 were not covered by tests

// add event for tendermint transaction hash format
if len(ctx.TxBytes()) > 0 {
Expand All @@ -381,7 +407,10 @@
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
case types.CctxStatus_PendingRevert:
cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed
cctx.SetAbort("aborted while processing failed outbound", "outbound and revert failed")
cctx.SetAbort(types.StatusMessages{
StatusMessage: "Revert failed",
ErrorMessageRevert: "outbound and revert failed",
})

Check warning on line 413 in x/crosschain/keeper/cctx_orchestrator_validate_outbound.go

View check run for this annotation

Codecov / codecov/patch

x/crosschain/keeper/cctx_orchestrator_validate_outbound.go#L410-L413

Added lines #L410 - L413 were not covered by tests
}
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(types.StatusMessages{StatusMessage: "Initiating outbound"})
return cctxGateway.InitiateOutbound(ctx, config)
}
12 changes: 6 additions & 6 deletions x/crosschain/keeper/initiate_outbound_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestKeeper_InitiateOutboundZEVMDeposit(t *testing.T) {
require.Equal(t, types.CctxStatus_Aborted, newStatus)
require.Contains(
t,
cctx.CctxStatus.ErrorMessage,
cctx.CctxStatus.ErrorMessageRevert,
"chain not supported",
)
},
Expand Down Expand Up @@ -151,7 +151,7 @@ func TestKeeper_InitiateOutboundZEVMDeposit(t *testing.T) {
require.Equal(t, types.CctxStatus_Aborted, newStatus)
require.Contains(
t,
cctx.CctxStatus.ErrorMessage,
cctx.CctxStatus.ErrorMessageRevert,
"GetRevertGasLimit: foreign coin not found for sender chain",
)
})
Expand Down Expand Up @@ -194,7 +194,7 @@ func TestKeeper_InitiateOutboundZEVMDeposit(t *testing.T) {
require.Equal(t, types.CctxStatus_Aborted, newStatus)
require.Contains(
t,
cctx.CctxStatus.ErrorMessage,
cctx.CctxStatus.ErrorMessageRevert,
"chain not supported",
)
},
Expand Down Expand Up @@ -239,7 +239,7 @@ func TestKeeper_InitiateOutboundZEVMDeposit(t *testing.T) {
require.Equal(t, types.CctxStatus_Aborted, newStatus)
require.Contains(
t,
cctx.CctxStatus.ErrorMessage,
cctx.CctxStatus.ErrorMessageRevert,
"chain not supported",
)
},
Expand Down Expand Up @@ -284,7 +284,7 @@ func TestKeeper_InitiateOutboundZEVMDeposit(t *testing.T) {
require.NoError(t, err)
require.Equal(t, types.CctxStatus_Aborted, cctx.CctxStatus.Status)
require.Equal(t, types.CctxStatus_Aborted, newStatus)
require.Contains(t, cctx.CctxStatus.ErrorMessage, "cannot find receiver chain nonce")
require.Contains(t, cctx.CctxStatus.ErrorMessageRevert, "cannot find receiver chain nonce")
})

t.Run("unable to process zevm deposit HandleEVMDeposit revert successfully", func(t *testing.T) {
Expand Down Expand Up @@ -361,7 +361,7 @@ func TestKeeper_InitiateOutboundZEVMDeposit(t *testing.T) {
require.Equal(t, types.CctxStatus_Aborted, newStatus)
require.Contains(
t,
cctx.CctxStatus.ErrorMessage,
cctx.CctxStatus.ErrorMessageRevert,
"cannot revert a revert tx",
)
},
Expand Down
5 changes: 4 additions & 1 deletion x/crosschain/keeper/msg_server_abort_stuck_cctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ func (k msgServer) AbortStuckCCTX(
}

// update the status
cctx.CctxStatus.UpdateStatusAndErrorMessages(types.CctxStatus_Aborted, AbortMessage, "")

cctx.SetAbort(types.StatusMessages{
StatusMessage: AbortMessage,
})

// Save out outbound,
// We do not need to provide the tss-pubkey as NonceToCctx is not updated / New outbound is not added
Expand Down
2 changes: 1 addition & 1 deletion x/crosschain/keeper/msg_server_vote_inbound_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ func TestStatus_UpdateCctxStatus(t *testing.T) {
for _, test := range tt {
test := test
t.Run(test.Name, func(t *testing.T) {
test.Status.UpdateStatusAndErrorMessages(test.NonErrStatus, test.Msg, "")
test.Status.UpdateStatusAndErrorMessages(test.NonErrStatus, types.StatusMessages{StatusMessage: test.Msg})
if test.IsErr {
require.Equal(t, test.ErrStatus, test.Status.Status)
} else {
Expand Down
5 changes: 4 additions & 1 deletion x/crosschain/keeper/msg_server_vote_outbound_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,10 @@ 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(types.StatusMessages{
StatusMessage: "Outbound Failed",
ErrorMessageOutbound: errMessage,
})
ctx.Logger().Error(errMessage)
k.SaveOutbound(ctx, cctx, tssPubkey)
}
Expand Down
20 changes: 10 additions & 10 deletions x/crosschain/types/cctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,28 +183,28 @@ func (m *CrossChainTx) AddOutbound(
}

// SetAbort sets the CCTX status to Aborted with the given error message.
func (m CrossChainTx) SetAbort(statusMsg, errorMsg string) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_Aborted, statusMsg, errorMsg)
func (m CrossChainTx) SetAbort(messages StatusMessages) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_Aborted, messages)
}

// SetPendingRevert sets the CCTX status to PendingRevert with the given error message.
func (m CrossChainTx) SetPendingRevert(statusMsg, errorMsg string) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_PendingRevert, statusMsg, errorMsg)
func (m CrossChainTx) SetPendingRevert(messages StatusMessages) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_PendingRevert, messages)
}

// SetPendingOutbound sets the CCTX status to PendingOutbound with the given error message.
func (m CrossChainTx) SetPendingOutbound(statusMsg string) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_PendingOutbound, statusMsg, "")
func (m CrossChainTx) SetPendingOutbound(messages StatusMessages) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_PendingOutbound, messages)
}

// SetOutboundMined sets the CCTX status to OutboundMined with the given error message.
func (m CrossChainTx) SetOutboundMined(statusMsg string) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_OutboundMined, statusMsg, "")
func (m CrossChainTx) SetOutboundMined(messages StatusMessages) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_OutboundMined, messages)
}

// SetReverted sets the CCTX status to Reverted with the given error message.
func (m CrossChainTx) SetReverted(statusMsg, errorMsg string) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_Reverted, statusMsg, errorMsg)
func (m CrossChainTx) SetReverted(messages StatusMessages) {
m.CctxStatus.UpdateStatusAndErrorMessages(CctxStatus_Reverted, messages)
}

func (m CrossChainTx) GetCCTXIndexBytes() ([32]byte, error) {
Expand Down
Loading
Loading