Skip to content

Commit

Permalink
Refactor actions and move model
Browse files Browse the repository at this point in the history
  • Loading branch information
anxolin committed Aug 18, 2023
1 parent ee07f83 commit 62ab490
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 374 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ node_modules/
/actions/types/
/cli/artifacts
/cli/types
yarn.lock
157 changes: 2 additions & 155 deletions actions/register.ts → actions/addContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
Context,
Event,
TransactionEvent,
Storage,
Log,
} from "@tenderly/actions";
import { BytesLike, ethers } from "ethers";
Expand All @@ -14,14 +13,9 @@ import type {
IConditionalOrder,
} from "./types/ComposableCoW";
import { ComposableCoW__factory } from "./types/factories/ComposableCoW__factory";
import { handleExecutionError, init, writeRegistry } from "./utils";

// Standardise the storage key
const LAST_NOTIFIED_ERROR_STORAGE_KEY = "LAST_NOTIFIED_ERROR";

export const getOrdersStorageKey = (network: string): string => {
return `CONDITIONAL_ORDER_REGISTRY_${network}`;
};
import { handleExecutionError, init, writeRegistry } from "./utils";
import { Owner, Proof, Registry } from "./model";

/**
* Listens to these events on the `ComposableCoW` contract:
Expand Down Expand Up @@ -210,150 +204,3 @@ export const flush = async (
}
}
};

// --- Types ---

export enum OrderStatus {
SUBMITTED = 1,
FILLED = 2,
}

/**
* A merkle proof is a set of parameters:
* - `merkleRoot`: the merkle root of the conditional order
* - `path`: the path to the order in the merkle tree
*/
export type Proof = {
merkleRoot: BytesLike;
path: BytesLike[];
};

export type OrderUid = BytesLike;
export type Owner = string;

export type ConditionalOrder = {
tx: string; // the transaction hash that created the conditional order (useful for debugging purposes)

// the parameters of the conditional order
params: IConditionalOrder.ConditionalOrderParamsStruct;
// the merkle proof if the conditional order is belonging to a merkle root
// otherwise, if the conditional order is a single order, this is null
proof: Proof | null;
// a map of discrete order hashes to their status
orders: Map<OrderUid, OrderStatus>;
// the address to poll for orders
composableCow: string;
};

/**
* Models the state beteween executions.
* Contains a map of owners to conditional orders and the last time we sent an error.
*/
export class Registry {
ownerOrders: Map<Owner, Set<ConditionalOrder>>;
storage: Storage;
network: string;
lastNotifiedError: Date | null;

/**
* Instantiates a registry.
* @param ownerOrders What map to populate the registry with
* @param storage interface to the Tenderly storage
* @param network Which network the registry is for
*/
constructor(
ownerOrders: Map<Owner, Set<ConditionalOrder>>,
storage: Storage,
network: string,
lastNotifiedError: Date | null
) {
this.ownerOrders = ownerOrders;
this.storage = storage;
this.network = network;
this.lastNotifiedError = lastNotifiedError;
}

/**
* Load the registry from storage.
* @param context from which to load the registry
* @param network that the registry is for
* @returns a registry instance
*/
public static async load(
context: Context,
network: string
): Promise<Registry> {
const str = await context.storage.getStr(getOrdersStorageKey(network));
const lastNotifiedError = await context.storage
.getStr(LAST_NOTIFIED_ERROR_STORAGE_KEY)
.then((isoDate) => (isoDate ? new Date(isoDate) : null))
.catch(() => null);

if (str === null || str === undefined || str === "") {
return new Registry(
new Map<Owner, Set<ConditionalOrder>>(),
context.storage,
network,
lastNotifiedError
);
}

const ownerOrders = JSON.parse(str, reviver);
return new Registry(
ownerOrders,
context.storage,
network,
lastNotifiedError
);
}

/**
* Write the registry to storage.
*/
public async write(): Promise<void> {
const writeOrders = this.storage.putStr(
getOrdersStorageKey(this.network),
JSON.stringify(this.ownerOrders, replacer)
);

const writeLastNotifiedError =
this.lastNotifiedError !== null
? this.storage.putStr(
LAST_NOTIFIED_ERROR_STORAGE_KEY,
this.lastNotifiedError.toISOString()
)
: Promise.resolve();

return Promise.all([writeOrders, writeLastNotifiedError]).then(() => {});
}
}

// --- Helper Functions ---

// Serializing and deserializing Maps and Sets
export function replacer(_key: any, value: any) {
if (value instanceof Map) {
return {
dataType: "Map",
value: Array.from(value.entries()),
};
} else if (value instanceof Set) {
return {
dataType: "Set",
value: Array.from(value.values()),
};
} else {
return value;
}
}

export function reviver(_key: any, value: any) {
if (typeof value === "object" && value !== null) {
if (value.dataType === "Map") {
return new Map(value.value);
} else if (value.dataType === "Set") {
return new Set(value.value);
}
}
return value;
}
Loading

0 comments on commit 62ab490

Please sign in to comment.