Skip to content

Commit

Permalink
feat: add response and dispute fetchers
Browse files Browse the repository at this point in the history
  • Loading branch information
0xyaco committed Nov 22, 2024
1 parent f687dc5 commit c5bacd9
Show file tree
Hide file tree
Showing 3 changed files with 271 additions and 1 deletion.
16 changes: 16 additions & 0 deletions packages/automated-dispute/src/interfaces/protocolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import type {
AccessControl,
BondEscalation,
Dispute,
DisputeId,
EboEvent,
EboEventName,
Epoch,
Request,
RequestId,
Response,
ResponseId,
} from "../types/index.js";
import { ProtocolContractsNames } from "../constants.js";

Expand Down Expand Up @@ -80,6 +82,20 @@ export interface IReadProvider {
* @returns A Promise that resolves to the BondEscalation data.
*/
getEscalation(requestId: RequestId): Promise<BondEscalation>;

/**
* Fetches the response data for a given response ID.
*
* @param responseId response ID
*/
getResponse(responseId: ResponseId): Promise<Response["prophetData"] | undefined>;

/**
* Fetches the dispute data for a given dispute ID.
*
* @param disputeId dispute ID
*/
getDispute(disputeId: DisputeId): Promise<Dispute["prophetData"] | undefined>;
}

/**
Expand Down
51 changes: 51 additions & 0 deletions packages/automated-dispute/src/providers/protocolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ export class ProtocolProvider implements IProtocolProvider {
getAccountingModuleAddress: this.getAccountingModuleAddress.bind(this),
getApprovedModules: this.getApprovedModules.bind(this),
getEscalation: this.getEscalation.bind(this),
getResponse: this.getResponse.bind(this),
getDispute: this.getDispute.bind(this),
};

/**
Expand Down Expand Up @@ -1197,6 +1199,55 @@ export class ProtocolProvider implements IProtocolProvider {
}
}

async getResponse(responseId: ResponseId): Promise<Response["prophetData"] | undefined> {
const responses = await this.oracleContract.getEvents.ResponseProposed({
_responseId: responseId,
});

if (!responses || responses.length === 0) return undefined;
if (responses.length > 1) {
this.logger.warn("Multiple responses found for the same response ID", { responseId });

return undefined;
}

const response = responses[0]?.args?._response;

if (!response) return undefined;

return {
proposer: response.proposer as Address,
response: response.response as Hex,
requestId: response.requestId as RequestId,
};
}

async getDispute(disputeId: DisputeId): Promise<Dispute["prophetData"] | undefined> {
const disputes = await this.oracleContract.getEvents.ResponseDisputed({
_disputeId: disputeId,
});

if (!disputes || disputes.length === 0) return undefined;
if (disputes.length > 1) {
this.logger.warn("Multiple disputes found for the same dispute ID", {
disputeId: disputeId,
});

return undefined;
}

const dispute = disputes[0]?.args?._dispute;

if (!dispute) return undefined;

return {
disputer: dispute.disputer as Address,
proposer: dispute.proposer as Address,
requestId: dispute.requestId as RequestId,
responseId: dispute.responseId as ResponseId,
};
}

/**
* Fetches the escalation data for a given request ID.
*
Expand Down
205 changes: 204 additions & 1 deletion packages/automated-dispute/tests/services/protocolProvider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
} from "../../src/exceptions/index.js";
import { ProtocolProvider } from "../../src/index.js";
import { ProtocolContractsAddresses } from "../../src/interfaces/index.js";
import { EboEvent } from "../../src/types/index.js";
import { DisputeId, EboEvent, RequestId, ResponseId } from "../../src/types/index.js";
import { mockLogger } from "../mocks/logger.mocks.js";
import {
DEFAULT_MOCKED_DISPUTE_DATA,
Expand Down Expand Up @@ -1306,6 +1306,209 @@ describe("ProtocolProvider", () => {
});
});

describe("getResponse", () => {
it("returns the response", async () => {
const protocolProvider = new ProtocolProvider(
mockRpcConfigBase,
mockContractAddress,
mockedPrivateKey,
mockServiceProviderAddress,
mockLogger(),
mockBlockNumberService,
);

const responseId = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as ResponseId;

const mockResponse = {
proposer: "0x123",
requestId: "0x456",
response: "0x789",
};

protocolProvider["oracleContract"].getEvents = {
ResponseProposed: vi
.fn()
.mockResolvedValue([{ args: { _response: mockResponse } }]),
AccessModuleSet: vi.fn(),
DisputeEscalated: vi.fn(),
DisputeResolved: vi.fn(),
DisputeStatusUpdated: vi.fn(),
RequestCreated: vi.fn(),
OracleRequestFinalized: vi.fn(),
ResponseDisputed: vi.fn(),
};

await expect(protocolProvider.getResponse(responseId)).resolves.toEqual(mockResponse);
});

it("returns undefined when multiple responses found", async () => {
const protocolProvider = new ProtocolProvider(
mockRpcConfigBase,
mockContractAddress,
mockedPrivateKey,
mockServiceProviderAddress,
mockLogger(),
mockBlockNumberService,
);

const mockResponse = {
proposer: "0x123",
requestId: "0x456",
response: "0x789",
};

const responseId = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as ResponseId;

protocolProvider["oracleContract"].getEvents = {
ResponseProposed: vi
.fn()
.mockResolvedValue([
{ args: { _response: mockResponse } },
{ args: { _response: mockResponse } },
]),
AccessModuleSet: vi.fn(),
DisputeEscalated: vi.fn(),
DisputeResolved: vi.fn(),
DisputeStatusUpdated: vi.fn(),
RequestCreated: vi.fn(),
OracleRequestFinalized: vi.fn(),
ResponseDisputed: vi.fn(),
};

await expect(protocolProvider.getResponse(responseId)).resolves.toBeUndefined();
});

it("returns undefined when no response found", async () => {
const protocolProvider = new ProtocolProvider(
mockRpcConfigBase,
mockContractAddress,
mockedPrivateKey,
mockServiceProviderAddress,
mockLogger(),
mockBlockNumberService,
);

const responseId = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as ResponseId;

protocolProvider["oracleContract"].getEvents = {
ResponseProposed: vi.fn().mockResolvedValue([]),
AccessModuleSet: vi.fn(),
DisputeEscalated: vi.fn(),
DisputeResolved: vi.fn(),
DisputeStatusUpdated: vi.fn(),
RequestCreated: vi.fn(),
OracleRequestFinalized: vi.fn(),
ResponseDisputed: vi.fn(),
};

await expect(protocolProvider.getResponse(responseId)).resolves.toBeUndefined();
});
});

describe("getDispute", () => {
it("returns the dispute", async () => {
const protocolProvider = new ProtocolProvider(
mockRpcConfigBase,
mockContractAddress,
mockedPrivateKey,
mockServiceProviderAddress,
mockLogger(),
mockBlockNumberService,
);

const disputeId = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as DisputeId;

const mockDispute = {
_requestId: "0x123",
_disputeId: disputeId,
_dispute: {
disputer: "0x01" as Address,
proposer: "0x01" as Address,
requestId: "0x123" as RequestId,
responseId: "0x456" as ResponseId,
},
};

protocolProvider["oracleContract"].getEvents = {
ResponseDisputed: vi.fn().mockResolvedValue([{ args: mockDispute }]),
DisputeEscalated: vi.fn(),
AccessModuleSet: vi.fn(),
DisputeResolved: vi.fn(),
DisputeStatusUpdated: vi.fn(),
RequestCreated: vi.fn(),
OracleRequestFinalized: vi.fn(),
ResponseProposed: vi.fn(),
};

await expect(protocolProvider.getDispute(disputeId)).resolves.toEqual(
mockDispute._dispute,
);
});

it("returns undefined when multiple disputes found", async () => {
const protocolProvider = new ProtocolProvider(
mockRpcConfigBase,
mockContractAddress,
mockedPrivateKey,
mockServiceProviderAddress,
mockLogger(),
mockBlockNumberService,
);
const disputeId = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as DisputeId;

const mockDispute = {
args: {
_requestId: "0x123",
_disputeId: disputeId,
_dispute: {
disputer: "0x01" as Address,
proposer: "0x01" as Address,
requestId: "0x123" as RequestId,
responseId: "0x456" as ResponseId,
},
},
};

protocolProvider["oracleContract"].getEvents = {
ResponseDisputed: vi.fn().mockResolvedValue([mockDispute, mockDispute]),
AccessModuleSet: vi.fn(),
DisputeResolved: vi.fn(),
DisputeStatusUpdated: vi.fn(),
RequestCreated: vi.fn(),
OracleRequestFinalized: vi.fn(),
DisputeEscalated: vi.fn(),
ResponseProposed: vi.fn(),
};

await expect(protocolProvider.getDispute(disputeId)).resolves.toBeUndefined();
});

it("returns undefined when no dispute found", async () => {
const protocolProvider = new ProtocolProvider(
mockRpcConfigBase,
mockContractAddress,
mockedPrivateKey,
mockServiceProviderAddress,
mockLogger(),
mockBlockNumberService,
);
const disputeId = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as DisputeId;

protocolProvider["oracleContract"].getEvents = {
ResponseDisputed: vi.fn().mockResolvedValue([]),
AccessModuleSet: vi.fn(),
DisputeResolved: vi.fn(),
DisputeStatusUpdated: vi.fn(),
RequestCreated: vi.fn(),
OracleRequestFinalized: vi.fn(),
DisputeEscalated: vi.fn(),
ResponseProposed: vi.fn(),
};

await expect(protocolProvider.getDispute(disputeId)).resolves.toBeUndefined();
});
});

describe("Service Provider Address", () => {
it("uses the provided serviceProviderAddress from config", () => {
const protocolProvider = new ProtocolProvider(
Expand Down

0 comments on commit c5bacd9

Please sign in to comment.