Skip to content

Commit

Permalink
fix: improve actor termination checks
Browse files Browse the repository at this point in the history
  • Loading branch information
0xyaco committed Sep 16, 2024
1 parent fb2e843 commit e77f764
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 9 deletions.
9 changes: 7 additions & 2 deletions packages/automated-dispute/src/services/eboActor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
DisputeStatus,
EboEvent,
EboEventName,
Epoch,
Request,
RequestId,
Response,
Expand Down Expand Up @@ -431,15 +432,19 @@ export class EboActor {
*
* Be aware that a request can be finalized but some of its disputes can still be pending resolution.
*
* At last, actors must be kept alive until their epoch concludes, to ensure no actor/request duplication.
*
* @param currentEpoch the epoch to check against actor termination
* @param blockNumber block number to check entities at
* @returns `true` if all entities are settled, otherwise `false`
*/
public canBeTerminated(blockNumber: bigint): boolean {
public canBeTerminated(currentEpoch: Epoch["epoch"], blockNumber: bigint): boolean {
const request = this.getActorRequest();
const isPastEpoch = currentEpoch > request.epoch;
const isRequestFinalized = request.status === "Finalized";
const nonSettledProposals = this.activeProposals(blockNumber);

return isRequestFinalized && nonSettledProposals.length === 0;
return isPastEpoch && isRequestFinalized && nonSettledProposals.length === 0;
}

/**
Expand Down
12 changes: 9 additions & 3 deletions packages/automated-dispute/src/services/eboProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class EboProcessor {
try {
const events = eventsByRequestId.get(requestId) ?? [];

await this.syncRequest(requestId, events, lastBlock);
await this.syncRequest(requestId, events, currentEpoch.epoch, lastBlock);
} catch (err) {
this.onActorError(requestId, err as Error);
}
Expand Down Expand Up @@ -187,9 +187,15 @@ export class EboProcessor {
*
* @param requestId the ID of the `Request`
* @param events a stream of consumed events
* @param currentEpoch the current epoch based on the last block
* @param lastBlock the last block checked
*/
private async syncRequest(requestId: RequestId, events: EboEventStream, lastBlock: bigint) {
private async syncRequest(
requestId: RequestId,
events: EboEventStream,
currentEpoch: Epoch["epoch"],
lastBlock: bigint,
) {
const firstEvent = events[0];
const actor = this.getOrCreateActor(requestId, firstEvent);

Expand All @@ -204,7 +210,7 @@ export class EboProcessor {
await actor.processEvents();
await actor.onLastBlockUpdated(lastBlock);

if (actor.canBeTerminated(lastBlock)) {
if (actor.canBeTerminated(currentEpoch, lastBlock)) {
this.terminateActor(requestId);
}
}
Expand Down
73 changes: 69 additions & 4 deletions packages/automated-dispute/tests/services/eboActor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ describe("EboActor", () => {
vi.spyOn(registry, "getRequest").mockReturnValue(request);
vi.spyOn(registry, "getResponses").mockReturnValue([]);

expect(actor.canBeTerminated(currentBlockNumber)).toBe(false);
expect(actor.canBeTerminated(actor.actorRequest.epoch + 1n, currentBlockNumber)).toBe(
false,
);
});

it("returns false if there's one disputable response", () => {
Expand All @@ -266,7 +268,9 @@ describe("EboActor", () => {
vi.spyOn(registry, "getResponses").mockReturnValue([response]);
vi.spyOn(registry, "getResponseDispute").mockReturnValue(undefined);

expect(actor.canBeTerminated(currentBlockNumber)).toBe(false);
expect(actor.canBeTerminated(actor.actorRequest.epoch + 1n, currentBlockNumber)).toBe(
false,
);
});

it("returns false if the request is finalized but there's one active dispute", () => {
Expand All @@ -286,11 +290,69 @@ describe("EboActor", () => {
vi.spyOn(registry, "getResponses").mockReturnValue([response]);
vi.spyOn(registry, "getResponseDispute").mockReturnValue(dispute);

const canBeTerminated = actor.canBeTerminated(currentBlockNumber);
const canBeTerminated = actor.canBeTerminated(
actor.actorRequest.epoch + 1n,
currentBlockNumber,
);

expect(canBeTerminated).toBe(false);
});

it("returns false if we are still in the same epoch", () => {
const request: Request = {
...DEFAULT_MOCKED_REQUEST_CREATED_DATA,
status: "Finalized",
};

const disputedResponse = mocks.buildResponse(request, { id: "0x01" });
const undisputedResponse = mocks.buildResponse(request, {
id: "0x02",
createdAt: request.prophetData.responseModuleData.deadline - 1n,
});

const escalatedDispute = mocks.buildDispute(request, disputedResponse, {
status: "Escalated",
});

const { actor, registry } = mocks.buildEboActor(request, logger);
const currentBlockNumber =
undisputedResponse.createdAt +
request.prophetData.disputeModuleData.disputeWindow +
1n;

vi.spyOn(registry, "getRequest").mockReturnValue(request);

vi.spyOn(registry, "getResponses").mockReturnValue([
disputedResponse,
undisputedResponse,
]);

vi.spyOn(registry, "getResponseDispute").mockImplementation((response) => {
switch (response.id) {
case disputedResponse.id:
return escalatedDispute;

case undisputedResponse.id:
return undefined;
}
});

const canBeTerminatedDuringCurrentEpoch = actor.canBeTerminated(
actor.actorRequest.epoch,
currentBlockNumber,
);

const canBeTerminatedDuringNextEpoch = actor.canBeTerminated(
actor.actorRequest.epoch + 1n,
currentBlockNumber,
);

expect(canBeTerminatedDuringCurrentEpoch).toBe(false);
// This is to validate that the change in the current epoch is the one that
// changes the output
expect(canBeTerminatedDuringNextEpoch).toBe(true);
});

it("returns true once everything is settled", () => {
const request: Request = {
...DEFAULT_MOCKED_REQUEST_CREATED_DATA,
Expand Down Expand Up @@ -330,7 +392,10 @@ describe("EboActor", () => {
}
});

const canBeTerminated = actor.canBeTerminated(currentBlockNumber);
const canBeTerminated = actor.canBeTerminated(
actor.actorRequest.epoch + 1n,
currentBlockNumber,
);

expect(canBeTerminated).toBe(true);
});
Expand Down

0 comments on commit e77f764

Please sign in to comment.