Skip to content

Commit

Permalink
feat(txs-tracer-core): ✨ improve ibc tracing
Browse files Browse the repository at this point in the history
improved ibc tracing, loading and events to parent.
  • Loading branch information
DavideSegullo committed Apr 17, 2023
1 parent f5a9c2f commit 4c5efb3
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Attribute, Event, IndexedTx } from '@cosmjs/stargate';
import {
assign,
createMachine,
Expand All @@ -9,15 +8,33 @@ import {
} from 'xstate';
import {
IBCTraceAckEventPayload,
IBCTraceRecvEventPayload,
IBCTraceContext,
IBCTraceEvents,
IBCTraceFinalState,
TxTraceDataResponse,
TxTraceFinalState,
} from '../../types';
import { txTraceMachine } from '../txs-trace-machine';
import { getPacketSequence } from '../../utils';

const { choose } = actions;
const { choose, sendParent } = actions;

const initialContext: IBCTraceContext = {
subscribeTimeout: 60_000,
connectionTimeout: 10_000,
websocketUrl: 'wss://juno.com',
dstWebsocketUrl: 'wss://rpc-osmosis.blockapsis.com',
loading: false,
currentStep: 0,
errorCode: 0,
query: '',
srcChannel: '', // ex: channel-140
dstChannel: '', // ex: channel-3316
transferTx: undefined,
recvTx: undefined,
ackTx: undefined,
};

export const ibcTraceMachine = createMachine(
{
Expand All @@ -38,6 +55,9 @@ export const ibcTraceMachine = createMachine(
websocketUrl: (_, event) => {
return event.data.websocketUrl;
},
dstWebsocketUrl: (_, event) => {
return event.data.dstWebsocketUrl;
},
query: (_, event) => {
return event.data.query;
},
Expand All @@ -58,7 +78,7 @@ export const ibcTraceMachine = createMachine(
actions: choose<
IBCTraceContext,
DoneInvokeEvent<TxTraceDataResponse>,
DoneInvokeEvent<TxTraceDataResponse | IBCTraceAckEventPayload>
DoneInvokeEvent<TxTraceDataResponse | IBCTraceRecvEventPayload>
>([
{
cond: (_, event) => {
Expand All @@ -72,10 +92,10 @@ export const ibcTraceMachine = createMachine(
actions: raise<
IBCTraceContext,
DoneInvokeEvent<TxTraceDataResponse>,
DoneInvokeEvent<IBCTraceAckEventPayload>
DoneInvokeEvent<IBCTraceRecvEventPayload>
>((_, event) => {
return {
type: 'TRACE_ACK',
type: 'TRACE_RECV',
data: {
tx: event.data.txs ? event.data.txs[0] : undefined,
},
Expand All @@ -98,8 +118,7 @@ export const ibcTraceMachine = createMachine(
},
},
entry: [
'toggleLoading',
'increaseStep',
'startLoading',
sendTo('sendPacketTrace', (ctx, event) => ({
type: 'TRACE',
data: {
Expand All @@ -108,12 +127,110 @@ export const ibcTraceMachine = createMachine(
},
})),
],
exit: ['toggleLoading'],
on: {
TRACE_RECV: {
target: 'receive_packet',
actions: assign({
transferTx: (_, event) => {
return event.data.tx;
},
}),
},
ON_ERROR: {
target: 'error',
actions: assign({
errorCode: (_, event) => {
return event.data.code;
},
}),
},
},
},
/**
* The receive packet on the destination chain.
*/
receive_packet: {
invoke: {
id: 'sendReceivePacketTrace',
src: txTraceMachine,
data: {
subscribeTimeout: (context: IBCTraceContext) => context.subscribeTimeout,
connectionTimeout: (context: IBCTraceContext) =>
context.connectionTimeout,
},
onDone: {
actions: choose<
IBCTraceContext,
DoneInvokeEvent<TxTraceDataResponse>,
DoneInvokeEvent<TxTraceDataResponse | IBCTraceAckEventPayload>
>([
{
cond: (_, event) => {
return (
event.data.state === TxTraceFinalState.Result &&
event.data.txs !== undefined &&
event.data.txs.length > 0 &&
event.data.txs[0].code === 0
);
},
actions: raise<
IBCTraceContext,
DoneInvokeEvent<TxTraceDataResponse>,
DoneInvokeEvent<IBCTraceAckEventPayload>
>((_, event) => {
return {
type: 'TRACE_ACK',
data: {
tx: event.data.txs ? event.data.txs[0] : undefined,
},
};
}),
},
{
actions: raise((_, event) => ({
type: 'ON_ERROR',
data: {
state: event.data.state,
code:
event.data.txs && event.data.txs.length > 0
? event.data.txs[0].code
: -1,
},
})),
},
]),
},
},
entry: [
'increaseStep',
sendParent('INCREASE_STEP'),
sendTo('sendReceivePacketTrace', ctx => {
const tx = ctx.transferTx;

if (tx) {
const { packetSequence } = getPacketSequence(tx, 'send_packet');

if (packetSequence) {
return {
type: 'TRACE',
data: {
query: `recv_packet.packet_src_channel='${ctx.srcChannel}' and recv_packet.packet_dst_channel='${ctx.dstChannel}' and recv_packet.packet_sequence=${packetSequence.value}`,
websocketUrl: ctx.dstWebsocketUrl,
},
};
}
}

return {
type: 'TRACE',
};
}),
],
on: {
TRACE_ACK: {
target: 'acknowledge_packet',
actions: assign({
ackTx: (_, event) => {
recvTx: (_, event) => {
return event.data.tx;
},
}),
Expand Down Expand Up @@ -152,7 +269,7 @@ export const ibcTraceMachine = createMachine(
event.data.txs[0].code === 0
);
},
actions: raise((ctx, event) => {
actions: raise((_, event) => {
return {
type: 'TRACE_COMPLETED',
data: {
Expand All @@ -177,30 +294,22 @@ export const ibcTraceMachine = createMachine(
},
},
entry: [
'toggleLoading',
'increaseStep',
sendTo('sendAckPacketTrace', (ctx, event) => {
const tx: IndexedTx | undefined =
event.type === 'TRACE_ACK' ? event.data.tx : undefined;
sendParent('INCREASE_STEP'),
sendTo('sendAckPacketTrace', ctx => {
const tx = ctx.transferTx;

if (tx) {
const sendPacket: Event | undefined = tx.events.find(
e => e.type === 'send_packet',
);

if (sendPacket) {
const packetSequence: Attribute | undefined =
sendPacket.attributes.find(e => e.key === 'packet_sequence');
const { packetSequence } = getPacketSequence(tx, 'send_packet');

if (packetSequence) {
return {
type: 'TRACE',
data: {
query: `acknowledge_packet.packet_src_channel='${ctx.srcChannel}' and acknowledge_packet.packet_dst_channel='${ctx.dstChannel}' and acknowledge_packet.packet_sequence=${packetSequence.value}`,
websocketUrl: ctx.websocketUrl,
},
};
}
if (packetSequence) {
return {
type: 'TRACE',
data: {
query: `acknowledge_packet.packet_src_channel='${ctx.srcChannel}' and acknowledge_packet.packet_dst_channel='${ctx.dstChannel}' and acknowledge_packet.packet_sequence=${packetSequence.value}`,
websocketUrl: ctx.websocketUrl,
},
};
}
}

Expand All @@ -209,7 +318,6 @@ export const ibcTraceMachine = createMachine(
};
}),
],
exit: ['toggleLoading'],
on: {
TRACE_COMPLETED: {
target: 'complete',
Expand All @@ -230,14 +338,17 @@ export const ibcTraceMachine = createMachine(
},
},
complete: {
entry: ['increaseStep'],
entry: ['stopLoading', 'increaseStep', sendParent('INCREASE_STEP')],
type: 'final',
data: ctx => ({
state: IBCTraceFinalState.Complete,
tx: ctx.ackTx,
transferTx: ctx.transferTx,
recvTx: ctx.recvTx,
ackTx: ctx.ackTx,
}),
},
error: {
entry: ['stopLoading'],
type: 'final',
data: ctx => ({
state: IBCTraceFinalState.Error,
Expand All @@ -250,23 +361,18 @@ export const ibcTraceMachine = createMachine(
events: {} as IBCTraceEvents,
},
context: {
subscribeTimeout: 60_000,
connectionTimeout: 10_000,
websocketUrl: 'wss://rpc-osmosis.blockapsis.com',
loading: false,
currentStep: 0,
errorCode: 0,
query: '',
srcChannel: '', // ex: channel-140
dstChannel: '', // ex: channel-3316
...initialContext,
},
predictableActionArguments: true,
preserveActionOrder: true,
},
{
actions: {
toggleLoading: context => {
context.loading = !context.loading;
startLoading: context => {
context.loading = true;
},
stopLoading: context => {
context.loading = false;
},
increaseStep: context => {
context.currentStep = context.currentStep + 1;
Expand Down
14 changes: 13 additions & 1 deletion packages/txs-tracer-core/src/lib/types/ibc-trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ export type IBCTraceContext = Omit<
currentStep: number;
srcChannel: string;
dstChannel: string;
dstWebsocketUrl: string;
errorCode?: number;
txs?: IndexedTx;
transferTx?: IndexedTx;
ackTx?: IndexedTx;
recvTx?: IndexedTx;
};

export type IBCTraceEventPayload = TxTraceEventPayload & {
dstWebsocketUrl: string;
srcChannel: string;
dstChannel: string;
};
Expand All @@ -32,6 +36,8 @@ export type IBCTraceAckEventPayload = {
tx?: IndexedTx;
};

export type IBCTraceRecvEventPayload = IBCTraceAckEventPayload;

export const IBCTraceFinalState = {
Complete: 'complete',
Error: 'error',
Expand All @@ -49,12 +55,18 @@ export type IBCTraceFinalStates =

export interface IBCTraceDataResponse {
state: IBCTraceFinalStates;
tx?: IndexedTx;
transferTx?: IndexedTx;
ackTx?: IndexedTx;
recvTx?: IndexedTx;
errorCode?: number;
}

export type IBCTraceParentEvents = { type: 'INCREASE_STEP' };

export type IBCTraceEvents =
| IBCTraceParentEvents
| { type: 'TRACE'; data: IBCTraceEventPayload }
| { type: 'TRACE_RECV'; data: IBCTraceRecvEventPayload }
| { type: 'TRACE_ACK'; data: IBCTraceAckEventPayload }
| { type: 'ON_ERROR'; data: IBCMachineResultErrorPayload }
| { type: 'TRACE_COMPLETED'; data: IBCTraceAckEventPayload };
21 changes: 21 additions & 0 deletions packages/txs-tracer-core/src/lib/utils/ibc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { IndexedTx } from '@cosmjs/stargate';

export const getPacketSequence = (tx: IndexedTx, name: string) => {
const packet = tx.events.find(e => e.type === name);

if (packet) {
const packetSequence = packet.attributes.find(
e => e.key === 'packet_sequence',
);

return {
packetSequence,
error: undefined,
};
}

return {
packetSequence: undefined,
error: undefined,
};
};
1 change: 1 addition & 0 deletions packages/txs-tracer-core/src/lib/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './tx';
export * from './stream';
export * from './cross-swap';
export * from './ibc';

0 comments on commit 4c5efb3

Please sign in to comment.