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

feature: Handle cancellations: Reduce errors and logs #52

Merged
merged 2 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
51 changes: 43 additions & 8 deletions actions/checkForAndPlaceOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,36 @@ async function _processConditionalOrder(
): Promise<{ deleteConditionalOrder: boolean; error: boolean }> {
let error = false;
try {
// Do a basic auth check (for singleOrders) // TODO: Check also Merkle auth
// Check in case the user invalidated it (this reduces errors in logs)
if (!conditionalOrder.proof) {
const ctx = await contract.callStatic.hash(conditionalOrder.params);
const authorised = await contract.callStatic
.singleOrders(owner, ctx)
.catch((error) => {
console.log(
"[processConditionalOrder] Error checking singleOrders auth",
{ owner, ctx, conditionalOrder },
error
);
return undefined; // returns undefined if it cannot be checked
});

// Return early if the order is not authorised (if its not authorised)
// Note we continue in case of an error (this is just to let _getTradeableOrderWithSignature handle the error and log the Tenderly simulation link)
if (authorised === false) {
console.log(
`[processConditionalOrder] Single order not authed. Deleting order...`,
{ owner, ctx, conditionalOrder }
);
return { deleteConditionalOrder: true, error: false };
}
}

// Get GPv2 Order
const tradeableOrderResult = await _getTradeableOrderWithSignature(
owner,
network,
conditionalOrder,
contract
);
Expand Down Expand Up @@ -316,6 +344,7 @@ type GetTradeableOrderWithSignatureError = {

async function _getTradeableOrderWithSignature(
owner: string,
network: string,
conditionalOrder: ConditionalOrder,
contract: ComposableCoW
): Promise<GetTradeableOrderWithSignatureResult> {
Expand All @@ -329,10 +358,9 @@ async function _getTradeableOrderWithSignature(
proof
);

console.log("[getTradeableOrderWithSignature] Simulate", {
to,
data,
});
console.log(
`[getTradeableOrderWithSignature] Simulate: https://dashboard.tenderly.co/gp-v2/watch-tower-prod/simulator/new?network=${network}&contractAddress=${to}&rawFunctionInput=${data}`
);

try {
const data = await contract.callStatic.getTradeableOrderWithSignature(
Expand Down Expand Up @@ -400,11 +428,18 @@ function _handleGetTradableOrderCall(
result: CallResult.FailedButIsExpected,
deleteConditionalOrder: true,
};
default:
// If there's no authorization we delete the order
// - One reason could be, because the user CANCELLED the order
// - for now it doesn't support more advanced cases where the order is auth during a pre-interaction
const errorName = error.errorName ? ` (${error.errorName})` : "";
console.error(
`${errorMessagePrefix} for unexpected reasons${errorName}`,
error
);
// If we don't know the reason, is better to not delete the order
return { result: CallResult.Failed, deleteConditionalOrder: false };
}

console.error(errorMessagePrefix + " for unexpected reasons", error);
// If we don't know the reason, is better to not delete the order
return { result: CallResult.Failed, deleteConditionalOrder: false };
}

console.error("[getTradeableOrderWithSignature] Unexpected error", error);
Expand Down
89 changes: 45 additions & 44 deletions actions/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { CaptureConsole as CaptureConsoleIntegration } from "@sentry/integration

import { ExecutionContext, OrderStatus, Registry } from "./model";

const TENDERLY_LOG_LIMIT = 3800; // 4000 is the limit, we just leave some margin for printing the chunk index
// const TENDERLY_LOG_LIMIT = 3800; // 4000 is the limit, we just leave some margin for printing the chunk index
const NOTIFICATION_WAIT_PERIOD = 1000 * 60 * 60 * 2; // 2h - Don't send more than one notification every 2h

let executionContext: ExecutionContext | undefined;
Expand Down Expand Up @@ -244,52 +244,53 @@ var consoleOriginal = {
debug: console.debug,
};

/**
* Tenderly has a limit of 4Kb per log message. When you surpass this limit, the log is not printed any more making it super hard to debug anything
*
* This tool will print
*
* @param data T
*/
const logWithLimit =
(level: "log" | "warn" | "error" | "debug") =>
(...data: any[]) => {
const bigLogText = data
.map((item) => {
if (typeof item === "string") {
return item;
}
return JSON.stringify(item, null, 2);
})
.join(" ");

const numChunks = Math.ceil(bigLogText.length / TENDERLY_LOG_LIMIT);

for (let i = 0; i < numChunks; i += 1) {
const chartStart = i * TENDERLY_LOG_LIMIT;
const prefix = numChunks > 1 ? `[${i + 1}/${numChunks}] ` : "";
const message =
prefix +
bigLogText.substring(chartStart, chartStart + TENDERLY_LOG_LIMIT);
consoleOriginal[level](message);

// if (level === "error") {
// sendSlack(message);
// }

// // Used to debug the Tenderly log Limit issues
// consoleOriginal[level](
// prefix + "TEST for bigLogText of " + bigLogText.length + " bytes"
// );
}
};
// TODO: Delete this code after we sort out the Tenderly log limit issue
mfw78 marked this conversation as resolved.
Show resolved Hide resolved
// /**
// * Tenderly has a limit of 4Kb per log message. When you surpass this limit, the log is not printed any more making it super hard to debug anything
// *
// * This tool will print
// *
// * @param data T
// */
// const logWithLimit =
// (level: "log" | "warn" | "error" | "debug") =>
// (...data: any[]) => {
// const bigLogText = data
// .map((item) => {
// if (typeof item === "string") {
// return item;
// }
// return JSON.stringify(item, null, 2);
// })
// .join(" ");

// const numChunks = Math.ceil(bigLogText.length / TENDERLY_LOG_LIMIT);

// for (let i = 0; i < numChunks; i += 1) {
// const chartStart = i * TENDERLY_LOG_LIMIT;
// const prefix = numChunks > 1 ? `[${i + 1}/${numChunks}] ` : "";
// const message =
// prefix +
// bigLogText.substring(chartStart, chartStart + TENDERLY_LOG_LIMIT);
// consoleOriginal[level](message);

// // if (level === "error") {
// // sendSlack(message);
// // }

// // // Used to debug the Tenderly log Limit issues
// // consoleOriginal[level](
// // prefix + "TEST for bigLogText of " + bigLogText.length + " bytes"
// // );
// }
// };

// Override the log function since some internal libraries might print something and breaks Tenderly

console.warn = logWithLimit("warn");
console.error = logWithLimit("error");
console.debug = logWithLimit("debug");
console.log = logWithLimit("log");
// console.warn = logWithLimit["warn"];
anxolin marked this conversation as resolved.
Show resolved Hide resolved
// console.error = logWithLimit("error");
// console.debug = logWithLimit("debug");
// console.log = logWithLimit("log");

export function sendSlack(message: string): boolean {
if (!executionContext) {
Expand Down