Skip to content

Commit

Permalink
feat: implement EboActor.onRequestCreated handler
Browse files Browse the repository at this point in the history
  • Loading branch information
0xyaco committed Aug 6, 2024
1 parent 5ae71e1 commit 3035c57
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 17 deletions.
5 changes: 3 additions & 2 deletions packages/automated-dispute/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"author": "",
"license": "ISC",
"dependencies": {
"viem": "2.17.11",
"@ebo-agent/blocknumber": "workspace:*"
"@ebo-agent/blocknumber": "workspace:*",
"@ebo-agent/shared": "workspace:*",
"viem": "2.17.11"
}
}
31 changes: 23 additions & 8 deletions packages/automated-dispute/src/eboActor.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import { BlockNumberService } from "@ebo-agent/blocknumber";

import { RequestMismatch } from "./exceptions/requestMismatch.js";
import { ProtocolProvider } from "./protocolProvider.js";
import { EboEvent } from "./types/events.js";
import { Dispute, Response } from "./types/prophet.js";

export class EboActor {
private requestActivity: unknown[];

constructor(
private readonly protocolProvider: ProtocolProvider,
private readonly blockNumberService: BlockNumberService,
private readonly requestId: string,
) {
this.requestActivity = [];
}
) {}

public async onRequestCreated(_event: EboEvent<"RequestCreated">): Promise<void> {
// TODO: implement
return;
public async onRequestCreated(event: EboEvent<"RequestCreated">): Promise<void> {
if (event.metadata.requestId != this.requestId)
throw new RequestMismatch(this.requestId, event.metadata.requestId);

// TODO: Update registry with the new event.metadata.request

const { chainId } = event.metadata;
const { currentEpoch, currentEpochTimestamp } =
await this.protocolProvider.getCurrentEpoch();

const epochBlockNumber = await this.blockNumberService.getEpochBlockNumber(
currentEpochTimestamp,
chainId,
);

await this.protocolProvider.proposeResponse(
this.requestId,
currentEpoch,
chainId,
epochBlockNumber,
);
}

public async onResponseProposed(_event: EboEvent<"ResponseDisputed">): Promise<void> {
Expand Down
9 changes: 9 additions & 0 deletions packages/automated-dispute/src/eboRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Dispute, Request, Response } from "./types/prophet.js";

class EboRegistry {
private requests: Map<string, Request>;
private responses: Map<string, Response>;
private dispute: Map<string, Dispute>;

constructor() {}
}
6 changes: 6 additions & 0 deletions packages/automated-dispute/src/exceptions/requestMismatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class RequestMismatch extends Error {
constructor(requestId: string, eventRequestId: string) {
super(`Actor handling request ${requestId} received a request ${eventRequestId} event.`);
this.name = "RequestMismatch";
}
}
7 changes: 6 additions & 1 deletion packages/automated-dispute/src/protocolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,12 @@ export class ProtocolProvider {
return;
}

async proposeResponse(_request: Request, _response: Response): Promise<void> {
async proposeResponse(
requestId: string,
epoch: bigint,
chainId: Caip2ChainId,
blockNumber: bigint,
): Promise<void> {
// TODO: implement actual method
return;
}
Expand Down
11 changes: 7 additions & 4 deletions packages/automated-dispute/src/types/events.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Caip2ChainId } from "@ebo-agent/blocknumber/dist/types.js";
import { Log } from "viem";

import { Dispute, Request } from "./prophet.js";
import { Dispute, Response } from "./prophet.js";

export type EboEventName =
| "NewEpoch"
Expand All @@ -17,14 +18,16 @@ export interface NewEpoch {
epochBlockNumber: bigint;
}

export interface ResponseCreated {
export interface ResponseProposed {
requestId: string;
request: Request;
responseId: Response;
response: Response;
}

export interface RequestCreated {
epoch: bigint;
chainId: Caip2ChainId;
requestId: string;
request: Request;
}

export interface ResponseDisputed {
Expand Down
120 changes: 118 additions & 2 deletions packages/automated-dispute/tests/eboActor.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,123 @@
import { describe } from "vitest";
import { BlockNumberService } from "@ebo-agent/blocknumber";
import { Caip2ChainId } from "@ebo-agent/blocknumber/dist/types.js";
import { Logger } from "@ebo-agent/shared";
import { Address } from "viem";
import { beforeEach, describe, expect, it, vi } from "vitest";

import { EboActor } from "../src/eboActor.js";
import { RequestMismatch } from "../src/exceptions/requestMismatch.js";
import { ProtocolProvider } from "../src/protocolProvider.js";
import { EboEvent } from "../src/types/events.js";

const logger = Logger.getInstance();

const protocolContracts = {
oracle: "0x123456" as Address,
epochManager: "0x654321" as Address,
};

describe("EboActor", () => {
describe.skip("onRequestCreated");
describe("onRequestCreated", () => {
const requestId: Address = "0x12345";
const indexedChainId: Caip2ChainId = "eip155:137";

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

const requestCreatedEvent: EboEvent<"RequestCreated"> = {
blockNumber: 34n,
logIndex: 1,
name: "RequestCreated",
metadata: {
chainId: "eip155:10",
epoch: protocolEpoch.currentEpoch,
requestId: requestId,
},
};

let protocolProvider: ProtocolProvider;
let blockNumberService: BlockNumberService;

beforeEach(() => {
protocolProvider = new ProtocolProvider(["http://localhost:8538"], protocolContracts);

const chainRpcUrls = new Map<Caip2ChainId, string[]>();
chainRpcUrls.set(indexedChainId, ["http://localhost:8539"]);

blockNumberService = new BlockNumberService(chainRpcUrls, logger);
});

it("proposes a response", async () => {
const indexedEpochBlockNumber = 48n;

vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(protocolEpoch);
vi.spyOn(blockNumberService, "getEpochBlockNumber").mockResolvedValue(
indexedEpochBlockNumber,
);

const proposeResponseMock = vi.spyOn(protocolProvider, "proposeResponse");

proposeResponseMock.mockImplementation(
(
_requestId: string,
_epoch: bigint,
_chainId: Caip2ChainId,
_blockNumbre: bigint,
) => Promise.resolve(),
);

const actor = new EboActor(protocolProvider, blockNumberService, requestId);

await actor.onRequestCreated(requestCreatedEvent);

expect(proposeResponseMock).toHaveBeenCalledWith(
requestCreatedEvent.metadata.requestId,
protocolEpoch.currentEpoch,
requestCreatedEvent.metadata.chainId,
indexedEpochBlockNumber,
);
});

it("throws if the event's request id does not match with actor's", () => {
const noMatchRequestCreatedEvent: EboEvent<"RequestCreated"> = {
blockNumber: 34n,
logIndex: 1,
name: "RequestCreated",
metadata: {
chainId: "eip155:10",
epoch: protocolEpoch.currentEpoch,
requestId: "0x000000" as Address,
},
};

const actor = new EboActor(protocolProvider, blockNumberService, requestId);

expect(actor.onRequestCreated(noMatchRequestCreatedEvent)).rejects.toBeInstanceOf(
RequestMismatch,
);
});

it("throws if current epoch cannot be fetched", () => {
vi.spyOn(protocolProvider, "getCurrentEpoch").mockRejectedValue(new Error());

const actor = new EboActor(protocolProvider, blockNumberService, requestId);

expect(actor.onRequestCreated(requestCreatedEvent)).rejects.toBeDefined();
});

it("throws if the indexed chain block number cannot be fetched", () => {
vi.spyOn(protocolProvider, "getCurrentEpoch").mockResolvedValue(protocolEpoch);
vi.spyOn(blockNumberService, "getEpochBlockNumber").mockRejectedValue(new Error());

const actor = new EboActor(protocolProvider, blockNumberService, requestId);

expect(actor.onRequestCreated(requestCreatedEvent)).rejects.toBeDefined();
});
});

describe.skip("onResponseProposed");
describe.skip("onResponseDisputed");
describe.skip("onFinalizeRequest");
Expand Down

0 comments on commit 3035c57

Please sign in to comment.