Skip to content

Commit ce32628

Browse files
committed
fix: allow creating multiple disputes for same allo/poi tuple
Signed-off-by: Tomás Migone <tomas@edgeandnode.com>
1 parent ba7d51e commit ce32628

File tree

9 files changed

+56
-33
lines changed

9 files changed

+56
-33
lines changed

packages/subgraph-service/contracts/DisputeManager.sol

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,16 @@ contract DisputeManager is
120120
}
121121

122122
/// @inheritdoc IDisputeManager
123-
function createIndexingDispute(address allocationId, bytes32 poi) external override returns (bytes32) {
123+
function createIndexingDispute(
124+
address allocationId,
125+
bytes32 poi,
126+
uint256 blockNumber
127+
) external override returns (bytes32) {
124128
// Get funds from fisherman
125129
_graphToken().pullTokens(msg.sender, disputeDeposit);
126130

127131
// Create a dispute
128-
return _createIndexingDisputeWithAllocation(msg.sender, disputeDeposit, allocationId, poi);
132+
return _createIndexingDisputeWithAllocation(msg.sender, disputeDeposit, allocationId, poi, blockNumber);
129133
}
130134

131135
/// @inheritdoc IDisputeManager
@@ -450,16 +454,18 @@ contract DisputeManager is
450454
* @param _deposit Amount of tokens staked as deposit
451455
* @param _allocationId Allocation disputed
452456
* @param _poi The POI being disputed
457+
* @param _blockNumber The block number for which the POI was calculated
453458
* @return The dispute id
454459
*/
455460
function _createIndexingDisputeWithAllocation(
456461
address _fisherman,
457462
uint256 _deposit,
458463
address _allocationId,
459-
bytes32 _poi
464+
bytes32 _poi,
465+
uint256 _blockNumber
460466
) private returns (bytes32) {
461467
// Create a disputeId
462-
bytes32 disputeId = keccak256(abi.encodePacked(_allocationId, _poi));
468+
bytes32 disputeId = keccak256(abi.encodePacked(_allocationId, _poi, _blockNumber));
463469

464470
// Only one dispute for an allocationId at a time
465471
require(!isDisputeCreated(disputeId), DisputeManagerDisputeAlreadyCreated(disputeId));
@@ -496,6 +502,7 @@ contract DisputeManager is
496502
_deposit,
497503
_allocationId,
498504
_poi,
505+
_blockNumber,
499506
stakeSnapshot,
500507
cancellableAt
501508
);

packages/subgraph-service/contracts/interfaces/IDisputeManager.sol

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ interface IDisputeManager {
123123
* @param tokens The amount of tokens deposited by the fisherman
124124
* @param allocationId The allocation id
125125
* @param poi The POI
126+
* @param blockNumber The block number for which the POI was calculated
126127
* @param stakeSnapshot The stake snapshot of the indexer at the time of the dispute
127128
* @param cancellableAt The timestamp when the dispute can be cancelled
128129
*/
@@ -133,6 +134,7 @@ interface IDisputeManager {
133134
uint256 tokens,
134135
address allocationId,
135136
bytes32 poi,
137+
uint256 blockNumber,
136138
uint256 stakeSnapshot,
137139
uint256 cancellableAt
138140
);
@@ -458,9 +460,10 @@ interface IDisputeManager {
458460
*
459461
* @param allocationId The allocation to dispute
460462
* @param poi The Proof of Indexing (POI) being disputed
463+
* @param blockNumber The block number for which the POI was calculated
461464
* @return The dispute id
462465
*/
463-
function createIndexingDispute(address allocationId, bytes32 poi) external returns (bytes32);
466+
function createIndexingDispute(address allocationId, bytes32 poi, uint256 blockNumber) external returns (bytes32);
464467

465468
/**
466469
* @notice Creates and auto-accepts a legacy dispute.

packages/subgraph-service/test/unit/disputeManager/DisputeManager.t.sol

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ contract DisputeManagerTest is SubgraphServiceSharedTest {
6969
assertEq(address(disputeManager.subgraphService()), _subgraphService, "Subgraph service should be set.");
7070
}
7171

72-
function _createIndexingDispute(address _allocationId, bytes32 _poi) internal returns (bytes32) {
72+
function _createIndexingDispute(address _allocationId, bytes32 _poi, uint256 _blockNumber) internal returns (bytes32) {
7373
(, address fisherman, ) = vm.readCallers();
74-
bytes32 expectedDisputeId = keccak256(abi.encodePacked(_allocationId, _poi));
74+
bytes32 expectedDisputeId = keccak256(abi.encodePacked(_allocationId, _poi, _blockNumber));
7575
uint256 disputeDeposit = disputeManager.disputeDeposit();
7676
uint256 beforeFishermanBalance = token.balanceOf(fisherman);
7777
Allocation.State memory alloc = subgraphService.getAllocation(_allocationId);
@@ -88,13 +88,14 @@ contract DisputeManagerTest is SubgraphServiceSharedTest {
8888
fisherman,
8989
disputeDeposit,
9090
_allocationId,
91-
_poi,
91+
_poi,
92+
_blockNumber,
9293
stakeSnapshot,
9394
cancellableAt
9495
);
9596

9697
// Create the indexing dispute
97-
bytes32 _disputeId = disputeManager.createIndexingDispute(_allocationId, _poi);
98+
bytes32 _disputeId = disputeManager.createIndexingDispute(_allocationId, _poi, _blockNumber);
9899

99100
// Check that the dispute was created and that it has the correct ID
100101
assertTrue(disputeManager.isDisputeCreated(_disputeId), "Dispute should be created.");

packages/subgraph-service/test/unit/disputeManager/disputes/disputes.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ contract DisputeManagerDisputeTest is DisputeManagerTest {
2929

3030
function test_Dispute_Accept_RevertIf_SlashZeroTokens(uint256 tokens) public useIndexer useAllocation(tokens) {
3131
resetPrank(users.fisherman);
32-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI101"));
32+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI101"), block.number);
3333

3434
// attempt to accept dispute with 0 tokens slashed
3535
resetPrank(users.arbitrator);

packages/subgraph-service/test/unit/disputeManager/disputes/indexing/accept.t.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ contract DisputeManagerIndexingAcceptDisputeTest is DisputeManagerTest {
1818
tokensSlash = bound(tokensSlash, 1, uint256(maxSlashingPercentage).mulPPM(tokens));
1919

2020
resetPrank(users.fisherman);
21-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
21+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
2222

2323
resetPrank(users.arbitrator);
2424
_acceptDispute(disputeID, tokensSlash);
@@ -31,7 +31,7 @@ contract DisputeManagerIndexingAcceptDisputeTest is DisputeManagerTest {
3131
tokensSlash = bound(tokensSlash, 1, uint256(maxSlashingPercentage).mulPPM(tokens));
3232

3333
resetPrank(users.fisherman);
34-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
34+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
3535

3636
resetPrank(users.arbitrator);
3737
// clear subgraph service address from storage
@@ -48,7 +48,7 @@ contract DisputeManagerIndexingAcceptDisputeTest is DisputeManagerTest {
4848
tokensSlash = bound(tokensSlash, 1, uint256(maxSlashingPercentage).mulPPM(tokens));
4949

5050
resetPrank(users.fisherman);
51-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
51+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
5252

5353
resetPrank(users.arbitrator);
5454
_acceptDispute(disputeID, tokensSlash);
@@ -61,7 +61,7 @@ contract DisputeManagerIndexingAcceptDisputeTest is DisputeManagerTest {
6161
tokensSlash = bound(tokensSlash, 1, uint256(maxSlashingPercentage).mulPPM(tokens));
6262

6363
resetPrank(users.fisherman);
64-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
64+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
6565

6666
// attempt to accept dispute as fisherman
6767
resetPrank(users.fisherman);
@@ -75,7 +75,7 @@ contract DisputeManagerIndexingAcceptDisputeTest is DisputeManagerTest {
7575
) public useIndexer useAllocation(tokens) {
7676
resetPrank(users.fisherman);
7777
tokensSlash = bound(tokensSlash, uint256(maxSlashingPercentage).mulPPM(tokens) + 1, type(uint256).max);
78-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI101"));
78+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI101"), block.number);
7979

8080
// max slashing percentage is 50%
8181
resetPrank(users.arbitrator);

packages/subgraph-service/test/unit/disputeManager/disputes/indexing/cancel.t.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ contract DisputeManagerIndexingCancelDisputeTest is DisputeManagerTest {
1313

1414
function test_Indexing_Cancel_Dispute(uint256 tokens) public useIndexer useAllocation(tokens) {
1515
resetPrank(users.fisherman);
16-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
16+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
1717

1818
// skip to end of dispute period
1919
uint256 disputePeriod = disputeManager.disputePeriod();
@@ -26,7 +26,7 @@ contract DisputeManagerIndexingCancelDisputeTest is DisputeManagerTest {
2626
uint256 tokens
2727
) public useIndexer useAllocation(tokens) {
2828
resetPrank(users.fisherman);
29-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
29+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
3030

3131
resetPrank(users.arbitrator);
3232
vm.expectRevert(abi.encodeWithSelector(IDisputeManager.DisputeManagerNotFisherman.selector));
@@ -37,15 +37,15 @@ contract DisputeManagerIndexingCancelDisputeTest is DisputeManagerTest {
3737
uint256 tokens
3838
) public useIndexer useAllocation(tokens) {
3939
resetPrank(users.fisherman);
40-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
40+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
4141

4242
vm.expectRevert(abi.encodeWithSelector(IDisputeManager.DisputeManagerDisputePeriodNotFinished.selector));
4343
disputeManager.cancelDispute(disputeID);
4444
}
4545

4646
function test_Indexing_Cancel_After_DisputePeriodIncreased(uint256 tokens) public useIndexer useAllocation(tokens) {
4747
resetPrank(users.fisherman);
48-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
48+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
4949

5050
// change the dispute period to a higher value
5151
uint256 oldDisputePeriod = disputeManager.disputePeriod();
@@ -62,7 +62,7 @@ contract DisputeManagerIndexingCancelDisputeTest is DisputeManagerTest {
6262

6363
function test_Indexing_Cancel_After_DisputePeriodDecreased(uint256 tokens) public useIndexer useAllocation(tokens) {
6464
resetPrank(users.fisherman);
65-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
65+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
6666

6767
// change the dispute period to a lower value
6868
uint256 oldDisputePeriod = disputeManager.disputePeriod();

packages/subgraph-service/test/unit/disputeManager/disputes/indexing/create.t.sol

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ contract DisputeManagerIndexingCreateDisputeTest is DisputeManagerTest {
1313

1414
function test_Indexing_Create_Dispute(uint256 tokens) public useIndexer useAllocation(tokens) {
1515
resetPrank(users.fisherman);
16-
_createIndexingDispute(allocationID, bytes32("POI1"));
16+
_createIndexingDispute(allocationID, bytes32("POI1"), block.number);
1717
}
1818

1919
function test_Indexing_Create_Dispute_WithDelegation(uint256 tokens, uint256 delegationTokens) public useIndexer {
@@ -37,7 +37,7 @@ contract DisputeManagerIndexingCreateDisputeTest is DisputeManagerTest {
3737
staking.delegate(users.indexer, address(subgraphService), delegationTokens, 0);
3838

3939
resetPrank(users.fisherman);
40-
_createIndexingDispute(allocationID, bytes32("POI1"));
40+
_createIndexingDispute(allocationID, bytes32("POI1"), block.number);
4141
}
4242

4343
function test_Indexing_Create_Dispute_RevertWhen_SubgraphServiceNotSet(
@@ -52,7 +52,7 @@ contract DisputeManagerIndexingCreateDisputeTest is DisputeManagerTest {
5252
token.approve(address(disputeManager), disputeDeposit);
5353

5454
vm.expectRevert(abi.encodeWithSelector(IDisputeManager.DisputeManagerSubgraphServiceNotSet.selector));
55-
disputeManager.createIndexingDispute(allocationID, bytes32("POI2"));
55+
disputeManager.createIndexingDispute(allocationID, bytes32("POI2"), block.number);
5656
}
5757

5858
function test_Indexing_Create_MultipleDisputes() public {
@@ -81,15 +81,15 @@ contract DisputeManagerIndexingCreateDisputeTest is DisputeManagerTest {
8181

8282
resetPrank(users.fisherman);
8383
for (uint i = 0; i < allocationIDPrivateKeys.length; i++) {
84-
_createIndexingDispute(vm.addr(allocationIDPrivateKeys[i]), bytes32("POI1"));
84+
_createIndexingDispute(vm.addr(allocationIDPrivateKeys[i]), bytes32("POI1"), block.number);
8585
}
8686
}
8787

8888
function test_Indexing_Create_RevertWhen_DisputeAlreadyCreated(
8989
uint256 tokens
9090
) public useIndexer useAllocation(tokens) {
9191
resetPrank(users.fisherman);
92-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
92+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
9393

9494
// Create another dispute with different fisherman
9595
address otherFisherman = makeAddr("otherFisherman");
@@ -101,10 +101,22 @@ contract DisputeManagerIndexingCreateDisputeTest is DisputeManagerTest {
101101
disputeID
102102
);
103103
vm.expectRevert(expectedError);
104-
disputeManager.createIndexingDispute(allocationID, bytes32("POI1"));
104+
disputeManager.createIndexingDispute(allocationID, bytes32("POI1"), block.number);
105105
vm.stopPrank();
106106
}
107107

108+
function test_Indexing_Create_DisputesSamePOIAndAllo(
109+
uint256 tokens
110+
) public useIndexer useAllocation(tokens) {
111+
resetPrank(users.fisherman);
112+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
113+
114+
resetPrank(users.arbitrator);
115+
disputeManager.acceptDispute(disputeID, 100);
116+
117+
_createIndexingDispute(allocationID, bytes32("POI1"), block.number + 1);
118+
}
119+
108120
function test_Indexing_Create_RevertIf_DepositUnderMinimum(uint256 tokensDeposit) public useFisherman {
109121
tokensDeposit = bound(tokensDeposit, 0, disputeDeposit - 1);
110122
token.approve(address(disputeManager), tokensDeposit);
@@ -115,7 +127,7 @@ contract DisputeManagerIndexingCreateDisputeTest is DisputeManagerTest {
115127
disputeDeposit
116128
);
117129
vm.expectRevert(expectedError);
118-
disputeManager.createIndexingDispute(allocationID, bytes32("POI3"));
130+
disputeManager.createIndexingDispute(allocationID, bytes32("POI3"), block.number);
119131
vm.stopPrank();
120132
}
121133

@@ -127,7 +139,7 @@ contract DisputeManagerIndexingCreateDisputeTest is DisputeManagerTest {
127139
allocationID
128140
);
129141
vm.expectRevert(expectedError);
130-
disputeManager.createIndexingDispute(allocationID, bytes32("POI4"));
142+
disputeManager.createIndexingDispute(allocationID, bytes32("POI4"), block.number);
131143
vm.stopPrank();
132144
}
133145

@@ -143,6 +155,6 @@ contract DisputeManagerIndexingCreateDisputeTest is DisputeManagerTest {
143155
resetPrank(users.fisherman);
144156
token.approve(address(disputeManager), tokens);
145157
vm.expectRevert(abi.encodeWithSelector(IDisputeManager.DisputeManagerZeroTokens.selector));
146-
disputeManager.createIndexingDispute(allocationID, bytes32("POI1"));
158+
disputeManager.createIndexingDispute(allocationID, bytes32("POI1"), block.number);
147159
}
148160
}

packages/subgraph-service/test/unit/disputeManager/disputes/indexing/draw.t.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ contract DisputeManagerIndexingDrawDisputeTest is DisputeManagerTest {
1414

1515
function test_Indexing_Draw_Dispute(uint256 tokens) public useIndexer useAllocation(tokens) {
1616
resetPrank(users.fisherman);
17-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI32"));
17+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI32"), block.number);
1818

1919
resetPrank(users.arbitrator);
2020
_drawDispute(disputeID);
2121
}
2222

2323
function test_Indexing_Draw_RevertIf_CallerIsNotArbitrator(uint256 tokens) public useIndexer useAllocation(tokens) {
2424
resetPrank(users.fisherman);
25-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
25+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
2626

2727
// attempt to draw dispute as fisherman
2828
vm.expectRevert(abi.encodeWithSelector(IDisputeManager.DisputeManagerNotArbitrator.selector));

packages/subgraph-service/test/unit/disputeManager/disputes/indexing/reject.t.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ contract DisputeManagerIndexingRejectDisputeTest is DisputeManagerTest {
1313

1414
function test_Indexing_Reject_Dispute(uint256 tokens) public useIndexer useAllocation(tokens) {
1515
resetPrank(users.fisherman);
16-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
16+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
1717

1818
resetPrank(users.arbitrator);
1919
_rejectDispute(disputeID);
@@ -23,7 +23,7 @@ contract DisputeManagerIndexingRejectDisputeTest is DisputeManagerTest {
2323
uint256 tokens
2424
) public useIndexer useAllocation(tokens) {
2525
resetPrank(users.fisherman);
26-
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"));
26+
bytes32 disputeID = _createIndexingDispute(allocationID, bytes32("POI1"), block.number);
2727

2828
// attempt to accept dispute as fisherman
2929
resetPrank(users.fisherman);

0 commit comments

Comments
 (0)