Skip to content

Commit 8f888a5

Browse files
committed
refactor: change signature requirements for justifications and user settings
1 parent 88263f6 commit 8f888a5

File tree

4 files changed

+66
-61
lines changed

4 files changed

+66
-61
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"commitmsg": "kleros-scripts commitmsg",
1414
"cz": "kleros-scripts cz",
1515
"invoke": "env-cmd ./.env serverless invoke -l -f",
16-
"build": "docker run --rm -v $PWD:/data -w /data node:8 npm rebuild scrypt",
16+
"build": "docker run --rm -v $PWD:/data -w /data lambci/lambda:build-nodejs8.10 npm rebuild scrypt",
1717
"deploy:function": "env-cmd ./.env serverless deploy function -f",
1818
"deploy:staging": "env-cmd ./.env serverless deploy",
1919
"deploy": "env-cmd ./.env serverless deploy -s production"

serverless.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,12 @@ functions:
251251
- {
252252
Effect: Allow,
253253
Action: ['dynamodb:Query'],
254-
Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/justifications',
254+
Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/kovan-justifications',
255+
}
256+
- {
257+
Effect: Allow,
258+
Action: ['dynamodb:Query'],
259+
Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/mainnet-justifications',
255260
}
256261
documentation:
257262
summary: 'Get justifications for a dispute round.'
@@ -290,7 +295,12 @@ functions:
290295
- {
291296
Effect: Allow,
292297
Action: ['dynamodb:PutItem'],
293-
Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/justifications',
298+
Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/kovan-justifications',
299+
}
300+
- {
301+
Effect: Allow,
302+
Action: ['dynamodb:PutItem'],
303+
Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/mainnet-justifications',
294304
}
295305
documentation:
296306
summary: 'Put justification for a vote.'

src/court/justifications.js

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module.exports.get = async (event, _context, callback) => {
1717
}
1818
},
1919
KeyConditionExpression: 'disputeIDAndAppeal = :disputeIDAndAppeal',
20-
TableName: 'justifications'
20+
TableName: `${payload.network}-justifications`
2121
})
2222
}
2323
})
@@ -32,71 +32,63 @@ module.exports.put = async (event, _context, callback) => {
3232
process.env.KLEROS_LIQUID_ADDRESS
3333
)
3434

35-
// Validate signature
3635
const payload = JSON.parse(event.body).payload
37-
try {
38-
if (
39-
(await web3.eth.accounts.recover(
40-
JSON.stringify(payload.justification),
41-
payload.signature
42-
)) !==
43-
(await dynamoDB.getItem({
44-
Key: { address: { S: payload.address } },
45-
TableName: 'user-settings',
46-
ProjectionExpression: 'derivedAccountAddress'
47-
})).Item.derivedAccountAddress.S
48-
)
49-
throw new Error(
50-
"Signature does not match the supplied address' derived account address for justifications."
51-
)
52-
} catch (err) {
53-
console.error(err)
54-
return callback(null, {
55-
statusCode: 403,
56-
headers: { 'Access-Control-Allow-Origin': '*' },
57-
body: JSON.stringify({
58-
error:
59-
"Signature is invalid or does not match the supplied address' derived account address for justifications."
60-
})
61-
})
62-
}
6336

6437
// Verify votes belong to user
65-
for (const voteID of payload.justification.voteIDs) {
38+
const dispute = await klerosLiquid.methods.getDispute(
39+
payload.justification.disputeID
40+
).call()
41+
42+
// Get number of votes in current round
43+
const votesInRound = dispute.votesLengths[payload.justification.appeal]
44+
45+
let drawn = false
46+
let voteID
47+
for (let i = 0; i < Number(votesInRound); i++) {
6648
const vote = await klerosLiquid.methods
67-
.getVote(
68-
payload.justification.disputeID,
69-
payload.justification.appeal,
70-
voteID
71-
)
49+
.getVote(payload.justification.disputeID, payload.justification.appeal, i)
7250
.call()
73-
if (vote.account !== payload.address || vote.voted)
74-
return callback(null, {
75-
statusCode: 403,
76-
headers: { 'Access-Control-Allow-Origin': '*' },
77-
body: JSON.stringify({
78-
error:
79-
'Not all of the supplied vote IDs belong to the supplied address and are not cast.'
51+
if (vote.account === payload.address) {
52+
// If voted, can no longer submit justification.
53+
if (vote.voted) {
54+
return callback(null, {
55+
statusCode: 403,
56+
headers: { 'Access-Control-Allow-Origin': '*' },
57+
body: JSON.stringify({
58+
error: 'This address has already cast their vote.'
59+
})
8060
})
61+
}
62+
// Once we know address has been drawn we can stop searching.
63+
drawn = true
64+
voteID = i
65+
break
66+
}
67+
}
68+
69+
if (!drawn) {
70+
return callback(null, {
71+
statusCode: 403,
72+
headers: { 'Access-Control-Allow-Origin': '*' },
73+
body: JSON.stringify({
74+
error: 'This address was not drawn.'
8175
})
76+
})
8277
}
8378

84-
// Save justification
79+
// Save justification.
8580
await dynamoDB.putItem({
8681
Item: {
8782
disputeIDAndAppeal: {
8883
S: `${payload.justification.disputeID}-${payload.justification.appeal}`
8984
},
90-
voteID: {
91-
N: String(
92-
payload.justification.voteIDs[
93-
payload.justification.voteIDs.length - 1
94-
]
95-
)
85+
address: {
86+
S: payload.address
9687
},
88+
voteID: { N: String(voteID) },
9789
justification: { S: payload.justification.justification }
9890
},
99-
TableName: 'justifications'
91+
TableName: `${payload.network}-justifications`
10092
})
10193
callback(null, {
10294
statusCode: 200,

src/global/user-settings.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,19 @@ module.exports.get = async (event, _context, callback) => {
2727
// Validate signature
2828
const payload = JSON.parse(event.body).payload
2929
try {
30+
const account = await web3.eth.accounts.recover(
31+
JSON.stringify(payload.settings),
32+
payload.signature
33+
)
34+
// accept if sig is from account or derived account
3035
if (
31-
(await web3.eth.accounts.recover(
32-
JSON.stringify(payload.settings),
33-
payload.signature
34-
)) !==
35-
(await dynamoDB.getItem({
36-
Key: { address: { S: payload.address } },
37-
TableName: 'user-settings',
38-
ProjectionExpression: 'derivedAccountAddress'
39-
})).Item.derivedAccountAddress.S
36+
account !== payload.address &&
37+
account !==
38+
(await dynamoDB.getItem({
39+
Key: { address: { S: payload.address } },
40+
TableName: 'user-settings',
41+
ProjectionExpression: 'derivedAccountAddress'
42+
})).Item.derivedAccountAddress.S
4043
)
4144
throw new Error('Signature does not match supplied address.')
4245
} catch (err) {

0 commit comments

Comments
 (0)