Skip to content

Commit

Permalink
feat: skip unsupported chains
Browse files Browse the repository at this point in the history
  • Loading branch information
0xyaco committed Sep 17, 2024
1 parent 658f10e commit ae18b0c
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 16 deletions.
7 changes: 7 additions & 0 deletions packages/automated-dispute/src/guards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { EboEvent, EboEventName } from "./types/index.js";

export const isRequestCreatedEvent = (
event: EboEvent<EboEventName>,
): event is EboEvent<"RequestCreated"> => {
return event.name === "RequestCreated";
};
29 changes: 25 additions & 4 deletions packages/automated-dispute/src/services/eboProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { isNativeError } from "util/types";
import { BlockNumberService } from "@ebo-agent/blocknumber";
import { Caip2ChainId } from "@ebo-agent/blocknumber/dist/types.js";
import { Address, ILogger } from "@ebo-agent/shared";
import { Address, EBO_SUPPORTED_CHAIN_IDS, ILogger } from "@ebo-agent/shared";

import { ProcessorAlreadyStarted } from "../exceptions/index.js";
import { isRequestCreatedEvent } from "../guards.js";
import { ProtocolProvider } from "../providers/protocolProvider.js";
import { alreadyDeletedActorWarning, droppingUnhandledEventsWarning } from "../templates/index.js";
import { ActorRequest, EboEvent, EboEventName, Epoch, RequestId } from "../types/index.js";
Expand Down Expand Up @@ -222,15 +223,35 @@ export class EboProcessor {

if (actor) return actor;

if (firstEvent && firstEvent.name === "RequestCreated") {
this.logger.info(`Creating a new EboActor to handle request ${requestId}...`);
if (firstEvent && isRequestCreatedEvent(firstEvent)) {
const chainId = firstEvent.metadata.chainId;

return this.createNewActor(firstEvent as EboEvent<"RequestCreated">);
if (this.isChainSupported(chainId)) {
this.logger.info(`Creating a new EboActor to handle request ${requestId}...`);

return this.createNewActor(firstEvent as EboEvent<"RequestCreated">);
} else {
this.logger.warn(`Chain ${chainId} not supported by the agent. Skipping...`);

// TODO: notify

return null;
}
} else {
return null;
}
}

/**
* Returns true if the CAIP2 compliant chain ID is supported by the EBO agent.
*
* @param chainId CAIP2 chain ID
* @returns true if the chain is supported, otherwise false
*/
private isChainSupported(chainId: Caip2ChainId): boolean {
return EBO_SUPPORTED_CHAIN_IDS.includes(chainId);
}

/**
* Create a new actor based on the data provided by a `RequestCreated` event.
*
Expand Down
44 changes: 44 additions & 0 deletions packages/automated-dispute/tests/guards.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { describe, expect, it } from "vitest";

import { isRequestCreatedEvent } from "../src/guards.js";
import { EboEvent, EboEventName } from "../src/types/index.js";
import mocks from "./mocks/index.js";
import { DEFAULT_MOCKED_REQUEST_CREATED_DATA } from "./services/eboActor/fixtures.js";

describe("isRequestCreatedEvent", () => {
it("returns true when passing a RequestCreatedd event", () => {
const event: EboEvent<EboEventName> = {
name: "RequestCreated",
blockNumber: 1n,
logIndex: 1,
requestId: "0x01",
metadata: {
chainId: "eip155:1",
epoch: 1n,
requestId: "0x01",
request: DEFAULT_MOCKED_REQUEST_CREATED_DATA.prophetData,
},
};

expect(isRequestCreatedEvent(event)).toBe(true);
});

it("returns false when not passing a RequestCreated event", () => {
const request = DEFAULT_MOCKED_REQUEST_CREATED_DATA;
const response = mocks.buildResponse(request);

const event: EboEvent<"ResponseProposed"> = {
name: "ResponseProposed",
blockNumber: 1n,
logIndex: 1,
requestId: request.id,
metadata: {
requestId: request.id,
responseId: response.id,
response: response.prophetData,
},
};

expect(isRequestCreatedEvent(event)).toBe(false);
});
});
65 changes: 53 additions & 12 deletions packages/automated-dispute/tests/services/eboProcessor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

import { ProcessorAlreadyStarted } from "../../src/exceptions/index.js";
import { ProtocolProvider } from "../../src/providers/index.js";
import { EboEvent, EboEventName, RequestId } from "../../src/types/index.js";
import { EboEvent, EboEventName, Epoch, RequestId } from "../../src/types/index.js";
import mocks from "../mocks/index.js";
import { DEFAULT_MOCKED_REQUEST_CREATED_DATA } from "../services/eboActor/fixtures.js";

Expand All @@ -26,10 +26,10 @@ describe("EboProcessor", () => {
it("bootstraps actors with onchain active requests when starting", async () => {
const { processor, actorsManager, protocolProvider } = mocks.buildEboProcessor(logger);

const currentEpoch = {
currentEpoch: 1n,
currentEpochBlockNumber: 1n,
currentEpochTimestamp: BigInt(Date.UTC(2024, 1, 1, 0, 0, 0, 0)),
const currentEpoch: Epoch = {
number: 1n,
firstBlockNumber: 1n,
startTimestamp: BigInt(Date.UTC(2024, 1, 1, 0, 0, 0, 0)),
};

const requestCreatedEvent: EboEvent<"RequestCreated"> = {
Expand All @@ -47,7 +47,7 @@ describe("EboProcessor", () => {

vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
currentEpoch.currentEpochBlockNumber + 10n,
currentEpoch.firstBlockNumber + 10n,
);
vi.spyOn(protocolProvider, "getEvents").mockResolvedValue([requestCreatedEvent]);

Expand All @@ -58,7 +58,8 @@ describe("EboProcessor", () => {

const expectedActorRequest = expect.objectContaining({
id: requestCreatedEvent.requestId,
epoch: currentEpoch.currentEpoch,
epoch: currentEpoch.number,
chainId: request.chainId,
});

expect(mockCreateActor).toHaveBeenCalledWith(
Expand All @@ -69,18 +70,58 @@ describe("EboProcessor", () => {
);
});

it("does not create actors to handle unsupported chains", async () => {
const { processor, actorsManager, protocolProvider } = mocks.buildEboProcessor(logger);

const currentEpoch: Epoch = {
number: 1n,
firstBlockNumber: 1n,
startTimestamp: BigInt(Date.UTC(2024, 1, 1, 0, 0, 0, 0)),
};

const request = {
...DEFAULT_MOCKED_REQUEST_CREATED_DATA,
chainId: "eip155:61" as const, // ETC
};

const requestCreatedEvent: EboEvent<"RequestCreated"> = {
name: "RequestCreated",
blockNumber: 1n,
logIndex: 1,
requestId: request.id,
metadata: {
requestId: request.id,
epoch: request.epoch,
chainId: request.chainId,
request: request.prophetData,
},
};

vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
currentEpoch.firstBlockNumber + 10n,
);
vi.spyOn(protocolProvider, "getEvents").mockResolvedValue([requestCreatedEvent]);

const mockCreateActor = vi.spyOn(actorsManager, "createActor");

await processor.start(msBetweenChecks);

expect(mockCreateActor).not.toHaveBeenCalled();
});

it("throws if called more than once", async () => {
const { processor, protocolProvider } = mocks.buildEboProcessor(logger);

const currentEpoch = {
currentEpoch: 1n,
currentEpochBlockNumber: 1n,
currentEpochTimestamp: BigInt(Date.UTC(2024, 1, 1, 0, 0, 0, 0)),
const currentEpoch: Epoch = {
number: 1n,
firstBlockNumber: 1n,
startTimestamp: BigInt(Date.UTC(2024, 1, 1, 0, 0, 0, 0)),
};

vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(currentEpoch);
vi.spyOn(protocolProvider, "getLastFinalizedBlock").mockResolvedValue(
currentEpoch.currentEpochBlockNumber + 10n,
currentEpoch.firstBlockNumber + 10n,
);
vi.spyOn(protocolProvider, "getEvents").mockResolvedValue([]);

Expand Down

0 comments on commit ae18b0c

Please sign in to comment.