Skip to content

Commit

Permalink
feat: explicit check on enqueue with same priority (#563)
Browse files Browse the repository at this point in the history
* feat: explicit check on enqueue with same priority

It is invalid to do so as it would break the framework. Add explicit check instead of rely on
the correct implementation of ExitGame contracts.

issue: #559

* fix: for PR comments
  • Loading branch information
boolafish authored Jan 20, 2020
1 parent 914b6eb commit 3308650
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ contract ExitGameController is ExitGameRegistry {
* priority queue to enforce the priority of exit during 'processExits'
* @dev emits ExitQueued event, which can be used to back trace the priority inside the queue
* @dev Caller of this function should add "pragma experimental ABIEncoderV2;" on top of file
* @dev Priority (exitableAt, txPos, exitId) must be unique per queue. Do not enqueue when the same priority is already in the queue.
* @param vaultId Vault ID of the vault that stores exiting funds
* @param token Token for the exit
* @param exitableAt The earliest time a specified exit can be processed
Expand Down Expand Up @@ -133,6 +134,7 @@ contract ExitGameController is ExitGameRegistry {
queue.insert(priority);

bytes32 delegationKey = getDelegationKey(priority, vaultId, token);
require(address(delegations[delegationKey]) == address(0), "The same priority is already enqueued");
delegations[delegationKey] = exitProcessor;

emit ExitQueued(exitId, priority);
Expand Down
60 changes: 59 additions & 1 deletion plasma_framework/test/src/framework/ExitGameController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ contract('ExitGameController', () => {
);
});

it('can enqueue with the same exitable timestamp (priority) multiple times', async () => {
it('rejects when the same priority is already enqueued', async () => {
await this.dummyExitGame.enqueue(
VAULT_ID,
this.dummyExit.token,
Expand All @@ -144,6 +144,23 @@ contract('ExitGameController', () => {
this.dummyExit.exitProcessor,
);

await expectRevert(
this.dummyExitGame.enqueue(
VAULT_ID,
this.dummyExit.token,
this.dummyExit.exitableAt,
this.dummyExit.txPos,
this.dummyExit.exitId,
this.dummyExit.exitProcessor,
),
'The same priority is already enqueued',
);
});

it('can enqueue with the exact same priority to different priority queue', async () => {
const vaultId2 = VAULT_ID + 1;
await this.controller.addExitQueue(vaultId2, this.dummyToken);

await this.dummyExitGame.enqueue(
VAULT_ID,
this.dummyExit.token,
Expand All @@ -153,6 +170,47 @@ contract('ExitGameController', () => {
this.dummyExit.exitProcessor,
);

await this.dummyExitGame.enqueue(
vaultId2,
this.dummyExit.token,
this.dummyExit.exitableAt,
this.dummyExit.txPos,
this.dummyExit.exitId,
this.dummyExit.exitProcessor,
);

const key = exitQueueKey(VAULT_ID, this.dummyToken);
const priorityQueueAddress = await this.controller.exitsQueues(key);
const priorityQueue = await PriorityQueue.at(priorityQueueAddress);
expect(await priorityQueue.currentSize()).to.be.bignumber.equal(new BN(1));

const key2 = exitQueueKey(vaultId2, this.dummyToken);
const priorityQueueAddress2 = await this.controller.exitsQueues(key2);
const priorityQueue2 = await PriorityQueue.at(priorityQueueAddress2);
expect(await priorityQueue2.currentSize()).to.be.bignumber.equal(new BN(1));
});

it('can enqueue with the same exitable timestamp and txPos but with different exitId multiple times to the same queue', async () => {
const exitId1 = 111111;
const exitId2 = 22222;
await this.dummyExitGame.enqueue(
VAULT_ID,
this.dummyExit.token,
this.dummyExit.exitableAt,
this.dummyExit.txPos,
exitId1,
this.dummyExit.exitProcessor,
);

await this.dummyExitGame.enqueue(
VAULT_ID,
this.dummyExit.token,
this.dummyExit.exitableAt,
this.dummyExit.txPos,
exitId2,
this.dummyExit.exitProcessor,
);

const key = exitQueueKey(VAULT_ID, this.dummyToken);
const priorityQueueAddress = await this.controller.exitsQueues(key);
const priorityQueue = await PriorityQueue.at(priorityQueueAddress);
Expand Down

0 comments on commit 3308650

Please sign in to comment.