Skip to content

Commit 67dc99f

Browse files
authored
disputes: update attestation and dispute manager to use channel key instead of root keys (#198)
1 parent 810ee26 commit 67dc99f

File tree

4 files changed

+48
-224
lines changed

4 files changed

+48
-224
lines changed

contracts/DisputeManager.sol

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,13 @@ contract DisputeManager is Governed {
404404
// Decode attestation
405405
Attestation memory attestation = _parseAttestation(_attestationData);
406406

407-
// Get attestation signer
408-
address indexer = _recoverAttestationSigner(attestation);
407+
// Get attestation signer, channelID
408+
address channelID = _recoverAttestationSigner(attestation);
409+
410+
// Get the indexer that created the channel and signed the attestation
411+
(address indexer, bytes32 subgraphID) = staking.channels(channelID);
412+
require(indexer != address(0), "Indexer cannot be found with the attestation");
413+
require(subgraphID == attestation.subgraphID, "Channel and attestation subgraph must match");
409414

410415
// Create a disputeID
411416
bytes32 disputeID = keccak256(
@@ -421,7 +426,7 @@ contract DisputeManager is Governed {
421426
require(staking.hasStake(indexer), "Dispute has no stake by the indexer");
422427

423428
// Ensure that fisherman has staked at least the minimum amount
424-
require(_deposit >= minimumDeposit, "Dispute deposit under minimum required");
429+
require(_deposit >= minimumDeposit, "Dispute deposit is under minimum required");
425430

426431
// A fisherman can only open one dispute for a given indexer / subgraphID at a time
427432
require(!isDisputeCreated(disputeID), "Dispute already created"); // Must be empty

test/disputes.test.js

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ const NON_EXISTING_DISPUTE_ID = '0x0'
1414

1515
contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, otherIndexer]) => {
1616
beforeEach(async function() {
17-
// Private key for account #4
18-
this.indexerPrivKey = '0xadd53f9a7e588d003326d1cbf9e4a43c061aadd9bc938c843a79e7b4fd2ad743'
19-
// Private key for account #6
20-
this.otherIndexerPrivKey = '0xe485d098507f54e7733a205420dfddbe58db035fa577fc294ebd14db90767a52'
17+
// Channel keys for account #4
18+
this.indexerChannelPrivKey =
19+
'0xe9696cbe81b09b796be29055c8694eb422710940b44934b3a1d21c1ca0a03e9a'
20+
this.indexerChannelPubKey =
21+
'0x04417b6be970480e74a55182ee04279fdffa7431002af2150750d367999a59abead903fbd23c0da7bb4233fdbccd732a2f561e66460718b4c50084e736c1601555'
22+
// Channel keys for account #6
23+
this.otherIndexerChannelPrivKey =
24+
'0xb560ebb22d7369c8ffeb9aec92930adfab16054542eadc76de826bc7db6390c2'
25+
this.otherIndexerChannelPubKey =
26+
'0x0447b5891c07679d40d6dfd3c4f8e1974e068da36ac76a6507dbaf5e432b879b3d4cd8c950b0df035e621f5a55b91a224ecdaef8cc8e6bb8cd8afff4a74c1904cd'
2127

2228
// Deploy epoch contract
2329
this.epochManager = await deployment.deployEpochManagerContract(governor, { from: me })
@@ -210,7 +216,8 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
210216
this.dispute = await attestation.createDispute(
211217
receipt,
212218
this.disputeManager.address,
213-
this.indexerPrivKey,
219+
this.indexerChannelPrivKey,
220+
indexer,
214221
)
215222
})
216223

@@ -221,7 +228,7 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
221228
this.disputeManager.createDispute(this.dispute.attestation, this.fishermanDeposit, {
222229
from: fisherman,
223230
}),
224-
'Dispute has no stake by the indexer',
231+
'Indexer cannot be found with the attestation',
225232
)
226233
})
227234
})
@@ -235,7 +242,14 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
235242

236243
// Stake
237244
this.indexerTokens = web3.utils.toWei(new BN('100000'))
238-
for (const indexerAddress of [indexer, otherIndexer]) {
245+
this.indexerAllocatedTokens = web3.utils.toWei(new BN('10000'))
246+
const indexerList = [
247+
[indexer, this.indexerChannelPubKey],
248+
[otherIndexer, this.otherIndexerChannelPubKey],
249+
]
250+
for (const activeIndexer of indexerList) {
251+
const [indexerAddress, indexerPubKey] = activeIndexer
252+
239253
// Give some funds to the indexer
240254
await this.grt.mint(indexerAddress, this.indexerTokens, {
241255
from: governor,
@@ -246,6 +260,12 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
246260

247261
// Indexer stake funds
248262
await this.staking.stake(this.indexerTokens, { from: indexerAddress })
263+
await this.staking.allocate(
264+
this.dispute.receipt.subgraphID,
265+
this.indexerAllocatedTokens,
266+
indexerPubKey,
267+
{ from: indexerAddress },
268+
)
249269
}
250270
})
251271

@@ -274,7 +294,7 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
274294
this.disputeManager.createDispute(this.dispute.attestation, belowMinimumDeposit, {
275295
from: fisherman,
276296
}),
277-
'Dispute deposit under minimum required',
297+
'Dispute deposit is under minimum required',
278298
)
279299
})
280300

@@ -313,7 +333,8 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
313333
const newDispute = await attestation.createDispute(
314334
this.dispute.receipt,
315335
this.disputeManager.address,
316-
this.otherIndexerPrivKey,
336+
this.otherIndexerChannelPrivKey,
337+
otherIndexer,
317338
)
318339
const { logs } = await this.disputeManager.createDispute(
319340
newDispute.attestation,
@@ -384,7 +405,7 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
384405
const reward = await this.disputeManager.getTokensToReward(indexer)
385406

386407
// Perform transaction (accept)
387-
const { tx } = await this.disputeManager.acceptDispute(this.dispute.id, {
408+
const { logs } = await this.disputeManager.acceptDispute(this.dispute.id, {
388409
from: arbitrator,
389410
})
390411

@@ -404,7 +425,7 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
404425
expect(totalSupplyAfter).to.be.bignumber.eq(totalSupplyBefore.sub(tokensToBurn))
405426

406427
// Event emitted
407-
expectEvent.inTransaction(tx, this.disputeManager.constructor, 'DisputeAccepted', {
428+
expectEvent.inLogs(logs, 'DisputeAccepted', {
408429
disputeID: this.dispute.id,
409430
subgraphID: this.dispute.receipt.subgraphID,
410431
indexer: indexer,
@@ -438,7 +459,7 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
438459
const totalSupplyBefore = await this.grt.totalSupply()
439460

440461
// Perform transaction (reject)
441-
const { tx } = await this.disputeManager.rejectDispute(this.dispute.id, {
462+
const { logs } = await this.disputeManager.rejectDispute(this.dispute.id, {
442463
from: arbitrator,
443464
})
444465

@@ -452,7 +473,7 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
452473
expect(totalSupplyAfter).to.be.bignumber.eq(totalSupplyBefore.sub(burnedTokens))
453474

454475
// Event emitted
455-
expectEvent.inTransaction(tx, this.disputeManager.constructor, 'DisputeRejected', {
476+
expectEvent.inLogs(logs, 'DisputeRejected', {
456477
disputeID: this.dispute.id,
457478
subgraphID: this.dispute.receipt.subgraphID,
458479
indexer: indexer,
@@ -485,7 +506,7 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
485506
const fishermanBalanceBefore = await this.grt.balanceOf(fisherman)
486507

487508
// Perform transaction (draw)
488-
const { tx } = await this.disputeManager.drawDispute(this.dispute.id, {
509+
const { logs } = await this.disputeManager.drawDispute(this.dispute.id, {
489510
from: arbitrator,
490511
})
491512

@@ -496,7 +517,7 @@ contract('Disputes', ([me, other, governor, arbitrator, indexer, fisherman, othe
496517
)
497518

498519
// Event emitted
499-
expectEvent.inTransaction(tx, this.disputeManager.constructor, 'DisputeDrawn', {
520+
expectEvent.inLogs(logs, 'DisputeDrawn', {
500521
disputeID: this.dispute.id,
501522
subgraphID: this.dispute.receipt.subgraphID,
502523
indexer: indexer,

test/lib/attestation.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function createDisputeID(receipt, indexer) {
5656
)
5757
}
5858

59-
async function createDispute(receipt, contractAddress, signer) {
59+
async function createDispute(receipt, contractAddress, signer, indexer) {
6060
// Receipt
6161
const encodedReceipt = encodeReceipt(receipt)
6262

@@ -79,7 +79,7 @@ async function createDispute(receipt, contractAddress, signer) {
7979
const attestation = createAttestation(encodedReceipt, messageSig)
8080

8181
return {
82-
id: createDisputeID(receipt, ethers.utils.computeAddress(signingKey.publicKey)),
82+
id: createDisputeID(receipt, indexer),
8383
signer,
8484
attestation,
8585
receipt,

test/lib/testHelpers.js

Lines changed: 2 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -9,210 +9,8 @@ module.exports = {
99
zeroHex: () => '0x0000000000000000000000000000000000000000000000000000000000000000',
1010
zeroAddress: () => '0x0000000000000000000000000000000000000000',
1111

12-
topLevelDomainNames: [
13-
'tld1',
14-
'tld2',
15-
'tld3',
16-
'tld4',
17-
'tld5',
18-
'tld6',
19-
'tld7',
20-
'tld8',
21-
'tld9',
22-
'tld10',
23-
'tld11',
24-
'tld12',
25-
'tld13',
26-
'tld14',
27-
'tld15',
28-
'tld16',
29-
'tld17',
30-
'tld18',
31-
'tld19',
32-
'tld20',
33-
'tld21',
34-
'tld22',
35-
'tld23',
36-
'tld24',
37-
'tld25',
38-
'tld26',
39-
'tld27',
40-
'tld28',
41-
'tld29',
42-
'tld30',
43-
'tld31',
44-
'tld32',
45-
'tld33',
46-
'tld34',
47-
'tld35',
48-
'tld36',
49-
'tld37',
50-
'tld38',
51-
'tld39',
52-
'tld40',
53-
'tld41',
54-
'tld42',
55-
'tld43',
56-
'tld44',
57-
'tld45',
58-
'tld46',
59-
'tld47',
60-
'tld48',
61-
'tld49',
62-
'tld50',
63-
'tld51',
64-
'tld52',
65-
'tld53',
66-
'tld54',
67-
'tld55',
68-
'tld56',
69-
'tld57',
70-
'tld58',
71-
'tld59',
72-
'tld60',
73-
'tld61',
74-
'tld62',
75-
'tld63',
76-
'tld64',
77-
'tld65',
78-
'tld66',
79-
'tld67',
80-
'tld68',
81-
'tld69',
82-
'tld70',
83-
'tld71',
84-
'tld72',
85-
'tld73',
86-
'tld74',
87-
'tld75',
88-
'tld76',
89-
'tld77',
90-
'tld78',
91-
'tld79',
92-
'tld80',
93-
'tld81',
94-
'tld82',
95-
'tld83',
96-
'tld84',
97-
'tld85',
98-
'tld86',
99-
'tld87',
100-
'tld88',
101-
'tld89',
102-
'tld90',
103-
'tld91',
104-
'tld92',
105-
'tld93',
106-
'tld94',
107-
'tld95',
108-
'tld96',
109-
'tld97',
110-
'tld98',
111-
'tld99',
112-
'tld100',
113-
],
114-
subdomainNames: [
115-
'subDomain1',
116-
'subDomain2',
117-
'subDomain3',
118-
'subDomain4',
119-
'subDomain5',
120-
'subDomain6',
121-
'subDomain7',
122-
'subDomain8',
123-
'subDomain9',
124-
'subDomain10',
125-
'subDomain11',
126-
'subDomain12',
127-
'subDomain13',
128-
'subDomain14',
129-
'subDomain15',
130-
'subDomain16',
131-
'subDomain17',
132-
'subDomain18',
133-
'subDomain19',
134-
'subDomain20',
135-
'subDomain21',
136-
'subDomain22',
137-
'subDomain23',
138-
'subDomain24',
139-
'subDomain25',
140-
'subDomain26',
141-
'subDomain27',
142-
'subDomain28',
143-
'subDomain29',
144-
'subDomain30',
145-
'subDomain31',
146-
'subDomain32',
147-
'subDomain33',
148-
'subDomain34',
149-
'subDomain35',
150-
'subDomain36',
151-
'subDomain37',
152-
'subDomain38',
153-
'subDomain39',
154-
'subDomain40',
155-
'subDomain41',
156-
'subDomain42',
157-
'subDomain43',
158-
'subDomain44',
159-
'subDomain45',
160-
'subDomain46',
161-
'subDomain47',
162-
'subDomain48',
163-
'subDomain49',
164-
'subDomain50',
165-
'subDomain51',
166-
'subDomain52',
167-
'subDomain53',
168-
'subDomain54',
169-
'subDomain55',
170-
'subDomain56',
171-
'subDomain57',
172-
'subDomain58',
173-
'subDomain59',
174-
'subDomain60',
175-
'subDomain61',
176-
'subDomain62',
177-
'subDomain63',
178-
'subDomain64',
179-
'subDomain65',
180-
'subDomain66',
181-
'subDomain67',
182-
'subDomain68',
183-
'subDomain69',
184-
'subDomain70',
185-
'subDomain71',
186-
'subDomain72',
187-
'subDomain73',
188-
'subDomain74',
189-
'subDomain75',
190-
'subDomain76',
191-
'subDomain77',
192-
'subDomain78',
193-
'subDomain79',
194-
'subDomain80',
195-
'subDomain81',
196-
'subDomain82',
197-
'subDomain83',
198-
'subDomain84',
199-
'subDomain85',
200-
'subDomain86',
201-
'subDomain87',
202-
'subDomain88',
203-
'subDomain89',
204-
'subDomain90',
205-
'subDomain91',
206-
'subDomain92',
207-
'subDomain93',
208-
'subDomain94',
209-
'subDomain95',
210-
'subDomain96',
211-
'subDomain97',
212-
'subDomain98',
213-
'subDomain99',
214-
'subDomain100',
215-
],
12+
topLevelDomainNames: [...Array(100).keys()].map(e => 'tld' + e),
13+
subdomainNames: [...Array(100).keys()].map(e => 'subDomain' + e),
21614
testIPFSHashes: [
21715
'0xeb50d096ba95573ae31640e38e4ef64fd02eec174f586624a37ea04e7bd8c751',
21816
'0x3ab4598d9c0b61477f7b91502944a8e216d9e64de2116a840ca5f75692230864',

0 commit comments

Comments
 (0)