From 07be18aa8059fca534c52c39a0cd90e311b4461f Mon Sep 17 00:00:00 2001 From: Anxo Rodriguez Date: Wed, 14 Feb 2024 16:36:53 +0000 Subject: [PATCH 1/4] feat: add conditional order id in conditional order params --- src/domain/events/index.ts | 16 +++++++++++++-- src/types/model.ts | 41 ++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/domain/events/index.ts b/src/domain/events/index.ts index c6c8c33..8704be5 100644 --- a/src/domain/events/index.ts +++ b/src/domain/events/index.ts @@ -18,9 +18,9 @@ import { Proof, Registry, } from "../../types"; +import { ConditionalOrder, ConditionalOrderParams } from "@cowprotocol/cow-sdk"; import { ChainContext } from "../../services/chain"; -import { ConditionalOrderParams } from "@cowprotocol/cow-sdk"; /** * Listens to these events on the `ComposableCoW` contract: @@ -201,6 +201,8 @@ export function add( const log = getLogger("addContract:add"); const { handler, salt, staticInput } = params; const { network, ownerOrders } = registry; + + const conditionalOrderId = ConditionalOrder.leafToId(params); if (ownerOrders.has(owner)) { const conditionalOrders = ownerOrders.get(owner); log.info( @@ -220,6 +222,7 @@ export function add( // If the params are not in the conditionalOrder, add them if (!exists) { conditionalOrders?.add({ + id: conditionalOrderId, tx, params: { handler, salt, staticInput }, proof, @@ -237,7 +240,16 @@ export function add( }); registry.ownerOrders.set( owner, - new Set([{ tx, params, proof, orders: new Map(), composableCow }]) + new Set([ + { + id: conditionalOrderId, + tx, + params, + proof, + orders: new Map(), + composableCow, + }, + ]) ); metrics.activeOwnersTotal.labels(network).inc(); metrics.activeOrdersTotal.labels(network).inc(); diff --git a/src/types/model.ts b/src/types/model.ts index c31228e..3820f37 100644 --- a/src/types/model.ts +++ b/src/types/model.ts @@ -6,6 +6,7 @@ import type { ConditionalOrderCreatedEvent } from "./generated/ComposableCoW"; import { ConditionalOrderParams, PollResult } from "@cowprotocol/cow-sdk"; import { DBService } from "../services"; import { metrics } from "../utils"; +import { ConditionalOrder as ConditionalOrderSdk } from "@cowprotocol/cow-sdk"; // Standardise the storage key const LAST_NOTIFIED_ERROR_STORAGE_KEY = "LAST_NOTIFIED_ERROR"; @@ -13,7 +14,7 @@ const LAST_PROCESSED_BLOCK_STORAGE_KEY = "LAST_PROCESSED_BLOCK"; const CONDITIONAL_ORDER_REGISTRY_STORAGE_KEY = "CONDITIONAL_ORDER_REGISTRY"; const CONDITIONAL_ORDER_REGISTRY_VERSION_KEY = "CONDITIONAL_ORDER_REGISTRY_VERSION"; -const CONDITIONAL_ORDER_REGISTRY_VERSION = 1; +const CONDITIONAL_ORDER_REGISTRY_VERSION = 2; export const getNetworkStorageKey = (key: string, network: string): string => { return `${key}_${network}`; @@ -49,6 +50,13 @@ export enum OrderStatus { } export type ConditionalOrder = { + /** + * Id of the conditional order (which also happens to be the key used for `ctx` in the ComposableCoW contract). + * + * This is a `keccak256` hash of the serialized conditional order. + */ + id: string; + /** * The transaction hash that created the conditional order (useful for debugging purposes) */ @@ -279,15 +287,15 @@ async function loadOwnerOrders( getNetworkStorageKey(CONDITIONAL_ORDER_REGISTRY_STORAGE_KEY, network) ); // Get the persisted registry version - const version = await db.get( - getNetworkStorageKey(CONDITIONAL_ORDER_REGISTRY_VERSION_KEY, network) + + const version = Number( + await db.get( + getNetworkStorageKey(CONDITIONAL_ORDER_REGISTRY_VERSION_KEY, network) + ) ); // Parse conditional orders registry (for the persisted version, converting it to the last version) - const ownerOrders = parseConditionalOrders( - !!str ? str : undefined, - Number(version) - ); + const ownerOrders = parseConditionalOrders(!!str ? str : undefined, version); return ownerOrders; } @@ -299,7 +307,24 @@ function parseConditionalOrders( if (!serializedConditionalOrders) { return createNewOrderMap(); } - return JSON.parse(serializedConditionalOrders, _reviver); + const ownerOrders: Map< + Owner, + Set & { id?: string }> + > = JSON.parse(serializedConditionalOrders, _reviver); + + // The conditional order id was added in version 2 + if (_version && _version < 2) { + // Migrate model: Add the missing order Id + for (const orders of ownerOrders.values()) { + for (const order of orders.values()) { + if (!order.id) { + order.id = ConditionalOrderSdk.leafToId(order.params); + } + } + } + } + + return ownerOrders as Map>; } function createNewOrderMap(): Map> { From 36c6c00be5b83e6938fbefdade51ba68111c6297 Mon Sep 17 00:00:00 2001 From: Anxo Rodriguez Date: Wed, 14 Feb 2024 16:40:01 +0000 Subject: [PATCH 2/4] chore: print the conditional order id --- src/domain/polling/index.ts | 11 ++++++++--- src/domain/polling/poll.ts | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/domain/polling/index.ts b/src/domain/polling/index.ts index 7eccd30..961c53d 100644 --- a/src/domain/polling/index.ts +++ b/src/domain/polling/index.ts @@ -112,7 +112,7 @@ export async function checkForAndPlaceOrder( blockNumber.toString(), ownerRef ); - const logOrderDetails = `Processing order from TX ${conditionalOrder.tx} with params:`; + const logOrderDetails = `Processing order ${conditionalOrder.id} from TX ${conditionalOrder.tx} with params:`; const { result: lastHint } = conditionalOrder.pollResult || {}; @@ -259,8 +259,12 @@ async function _processConditionalOrder( "checkForAndPlaceOrder:_processConditionalOrder", orderRef ); - const id = ConditionalOrderSDK.leafToId(conditionalOrder.params); - const metricLabels = [chainId.toString(), handler, owner, id]; + const metricLabels = [ + chainId.toString(), + handler, + owner, + conditionalOrder.id, + ]; try { metrics.pollingRunsTotal.labels(...metricLabels).inc(); @@ -289,6 +293,7 @@ async function _processConditionalOrder( }, }; let pollResult = await pollConditionalOrder( + conditionalOrder.id, pollParams, conditionalOrder.params, orderRef diff --git a/src/domain/polling/poll.ts b/src/domain/polling/poll.ts index 36b0384..be1f139 100644 --- a/src/domain/polling/poll.ts +++ b/src/domain/polling/poll.ts @@ -15,6 +15,7 @@ const ordersFactory = new ConditionalOrderFactory( ); export async function pollConditionalOrder( + conditionalOrderId: string, pollParams: PollParams, conditionalOrderParams: ConditionalOrderParams, orderRef: string @@ -30,7 +31,7 @@ export async function pollConditionalOrder( : pollParams; log.debug( - `Polling for ${order.toString()} using block (${ + `Polling id ${conditionalOrderId}. Order ${order.toString()} using block (${ actualPollParams.blockInfo === undefined ? "latest" : actualPollParams.blockInfo.blockNumber From eba231895aea7f7a6ea92bd184408bcffd34b0b5 Mon Sep 17 00:00:00 2001 From: Anxo Rodriguez Date: Wed, 14 Feb 2024 16:55:42 +0000 Subject: [PATCH 3/4] chore: log id --- src/domain/events/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/domain/events/index.ts b/src/domain/events/index.ts index 8704be5..287b741 100644 --- a/src/domain/events/index.ts +++ b/src/domain/events/index.ts @@ -207,7 +207,7 @@ export function add( const conditionalOrders = ownerOrders.get(owner); log.info( `Adding conditional order to already existing owner contract ${owner}`, - { tx, handler, salt, staticInput } + { conditionalOrderId, tx, handler, salt, staticInput } ); let exists = false; // Iterate over the conditionalOrders to make sure that the params are not already in the registry @@ -233,6 +233,7 @@ export function add( } } else { log.info(`Adding conditional order to new owner contract ${owner}:`, { + conditionalOrderId, tx, handler, salt, From feb3b64d35b85dcb3f09a0b0493fd37e725708bb Mon Sep 17 00:00:00 2001 From: Anxo Rodriguez Date: Wed, 14 Feb 2024 17:05:13 +0000 Subject: [PATCH 4/4] chore: log id when errors --- src/domain/polling/index.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/domain/polling/index.ts b/src/domain/polling/index.ts index 961c53d..1f6cef0 100644 --- a/src/domain/polling/index.ts +++ b/src/domain/polling/index.ts @@ -201,12 +201,15 @@ export async function checkForAndPlaceOrder( (isError && pollResult.reason ? `. Reason: ${pollResult.reason}` : ""); log[unexpectedError ? "error" : "info"]( - `Check conditional order result: ${getEmojiByPollResult( - pollResult?.result - )} ${resultDescription}` + `Check conditional order result for ${ + conditionalOrder.id + }: ${getEmojiByPollResult(pollResult?.result)} ${resultDescription}` ); if (unexpectedError) { - log.error(`UNEXPECTED_ERROR Details:`, pollResult.error); + log.error( + `UNEXPECTED_ERROR for order ${conditionalOrder.id}. Details:`, + pollResult.error + ); } hasErrors ||= unexpectedError; @@ -217,7 +220,9 @@ export async function checkForAndPlaceOrder( const deleted = conditionalOrders.delete(conditionalOrder); const action = deleted ? "Stop Watching" : "Failed to stop watching"; - log.debug(`${action} conditional order from TX ${conditionalOrder.tx}`); + log.debug( + `${action} conditional order ${conditionalOrder.id} from TX ${conditionalOrder.tx}` + ); metrics.activeOrdersTotal.labels(chainId.toString()).dec(); } }