Skip to content

Commit 0f31278

Browse files
author
Jérémy James Toussaint
committed
Using computed.json
1 parent a5ee4b4 commit 0f31278

File tree

14 files changed

+187
-348
lines changed

14 files changed

+187
-348
lines changed

src/main/java/com/iexec/worker/chain/ContributionService.java

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@
22

33
import com.iexec.common.chain.*;
44
import com.iexec.common.contract.generated.IexecHubContract;
5+
import com.iexec.common.contribution.Contribution;
56
import com.iexec.common.replicate.ReplicateStatusCause;
7+
import com.iexec.common.result.ComputedFile;
68
import com.iexec.common.security.Signature;
9+
import com.iexec.common.tee.TeeEnclaveChallengeSignature;
710
import com.iexec.common.utils.BytesUtils;
811
import com.iexec.common.utils.HashUtils;
912
import com.iexec.common.utils.SignatureUtils;
1013

14+
import com.iexec.common.worker.result.ResultUtils;
1115
import lombok.extern.slf4j.Slf4j;
1216
import org.springframework.stereotype.Service;
1317

1418
import java.util.Date;
1519
import java.util.Optional;
1620

1721
import static com.iexec.common.replicate.ReplicateStatusCause.*;
22+
import static com.iexec.common.utils.SignatureUtils.isExpectedSignerOnSignedMessageHash;
1823

1924

2025
@Slf4j
@@ -30,14 +35,6 @@ public ContributionService(IexecHubService iexecHubService,
3035
this.contributionAuthorizationService = contributionAuthorizationService;
3136
}
3237

33-
public static String computeResultSeal(String walletAddress, String chainTaskId, String deterministHash) {
34-
return HashUtils.concatenateAndHash(walletAddress, chainTaskId, deterministHash);
35-
}
36-
37-
public static String computeResultHash(String chainTaskId, String deterministHash) {
38-
return HashUtils.concatenateAndHash(chainTaskId, deterministHash);
39-
}
40-
4138
public boolean isChainTaskInitialized(String chainTaskId) {
4239
return iexecHubService.getChainTask(chainTaskId).isPresent();
4340
}
@@ -124,21 +121,18 @@ public boolean isContributionDeadlineReached(String chainTaskId) {
124121
}
125122

126123
// returns ChainReceipt of the contribution if successful, null otherwise
127-
public Optional<ChainReceipt> contribute(ContributionAuthorization contribAuth, String deterministHash, Signature enclaveSignature) {
128-
String resultSeal = computeResultSeal(contribAuth.getWorkerWallet(), contribAuth.getChainTaskId(), deterministHash);
129-
String resultHash = computeResultHash(contribAuth.getChainTaskId(), deterministHash);
130-
IexecHubContract.TaskContributeEventResponse contributeResponse = iexecHubService.contribute(contribAuth, resultHash, resultSeal, enclaveSignature);
124+
public Optional<ChainReceipt> contribute(Contribution contribution) {
125+
126+
IexecHubContract.TaskContributeEventResponse contributeResponse = iexecHubService.contribute(contribution);
131127

132128
if (contributeResponse == null) {
133-
log.error("ContributeTransactionReceipt received but was null [chainTaskId:{}]", contribAuth.getChainTaskId());
129+
log.error("ContributeTransactionReceipt received but was null [chainTaskId:{}]", contribution.getChainTaskId());
134130
return Optional.empty();
135131
}
136132

137-
ChainReceipt chainReceipt = ChainUtils.buildChainReceipt(contributeResponse.log, contribAuth.getChainTaskId(),
133+
ChainReceipt chainReceipt = ChainUtils.buildChainReceipt(contributeResponse.log, contribution.getChainTaskId(),
138134
iexecHubService.getLatestBlockNumber());
139135

140-
141-
142136
return Optional.of(chainReceipt);
143137
}
144138

@@ -150,4 +144,44 @@ public ContributionAuthorization getContributionAuthorization(String chainTaskId
150144
return contributionAuthorizationService.getContributionAuthorization(chainTaskId);
151145
}
152146

147+
//TODO Add unit test
148+
public Contribution getContribution(ComputedFile computedFile, ContributionAuthorization contributionAuthorization) {
149+
String chainTaskId = computedFile.getTaskId();
150+
String resultDigest = computedFile.getResultDigest();
151+
String resultHash = ResultUtils.computeResultHash(chainTaskId, resultDigest);
152+
String resultSeal = ResultUtils.computeResultSeal(contributionAuthorization.getWorkerWallet(), chainTaskId, resultDigest);
153+
String enclaveSignature = computedFile.getEnclaveSignature();
154+
155+
boolean isTeeTask = iexecHubService.isTeeTask(chainTaskId);
156+
if (isTeeTask) {
157+
if (enclaveSignature.isEmpty()){
158+
log.error("Cannot contribute enclave signature not found [chainTaskId:{}]", chainTaskId);
159+
return null;
160+
}
161+
162+
String messageHash = TeeEnclaveChallengeSignature.getMessageHash(resultHash, resultSeal);
163+
164+
boolean isExpectedSigner = isExpectedSignerOnSignedMessageHash(messageHash,
165+
new Signature(enclaveSignature), contributionAuthorization.getEnclaveChallenge());
166+
167+
if (!isExpectedSigner){
168+
log.error("Cannot contribute enclave signature invalid [chainTaskId:{}]", chainTaskId);
169+
return null;
170+
}
171+
172+
} else {
173+
enclaveSignature = BytesUtils.EMPTY_HEXASTRING_64;
174+
}
175+
176+
return Contribution.builder()
177+
.chainTaskId(chainTaskId)
178+
.resultDigest(resultDigest)
179+
.resultHash(resultHash)
180+
.resultSeal(resultSeal)
181+
.enclaveChallenge(contributionAuthorization.getEnclaveChallenge())
182+
.enclaveSignature(enclaveSignature)
183+
.workerPoolSignature(contributionAuthorization.getSignature().getValue())
184+
.build();
185+
}
186+
153187
}

src/main/java/com/iexec/worker/chain/IexecHubService.java

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import com.iexec.common.chain.*;
55
import com.iexec.common.contract.generated.IexecHubContract;
6+
import com.iexec.common.contribution.Contribution;
67
import com.iexec.common.security.Signature;
78
import com.iexec.common.task.TaskDescription;
89
import com.iexec.common.utils.BytesUtils;
@@ -49,40 +50,31 @@ public IexecHubService(CredentialsService credentialsService,
4950
this.executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
5051
}
5152

52-
IexecHubContract.TaskContributeEventResponse contribute(ContributionAuthorization contribAuth,
53-
String resultHash,
54-
String resultSeal,
55-
Signature enclaveSignature) {
53+
IexecHubContract.TaskContributeEventResponse contribute(Contribution contribution) {
5654
try {
5755
return CompletableFuture.supplyAsync(() -> {
5856
log.info("Requested contribute [chainTaskId:{}, waitingTxCount:{}]",
59-
contribAuth.getChainTaskId(), getWaitingTransactionCount());
60-
return sendContributeTransaction(contribAuth, resultHash, resultSeal, enclaveSignature);
57+
contribution.getChainTaskId(), getWaitingTransactionCount());
58+
return sendContributeTransaction(contribution);
6159
}, executor).get();
6260
} catch (InterruptedException | ExecutionException e) {
6361
e.printStackTrace();
6462
}
6563
return null;
6664
}
6765

68-
private IexecHubContract.TaskContributeEventResponse sendContributeTransaction(ContributionAuthorization contribAuth,
69-
String resultHash,
70-
String resultSeal,
71-
Signature enclaveSignature) {
66+
private IexecHubContract.TaskContributeEventResponse sendContributeTransaction(Contribution contribution) {
7267
TransactionReceipt contributeReceipt;
73-
String chainTaskId = contribAuth.getChainTaskId();
74-
75-
byte[] enclaveSign = BytesUtils.stringToBytes(enclaveSignature.getValue());
76-
byte[] workerPoolSign = BytesUtils.stringToBytes(contribAuth.getSignature().getValue());
68+
String chainTaskId = contribution.getChainTaskId();
7769

7870
RemoteCall<TransactionReceipt> contributeCall = getHubContract(web3jService.getWritingContractGasProvider()).contribute(
7971
stringToBytes(chainTaskId),
80-
stringToBytes(resultHash),
81-
stringToBytes(resultSeal),
82-
contribAuth.getEnclaveChallenge(),
83-
enclaveSign,
84-
workerPoolSign);
85-
log.info("Sent contribute [chainTaskId:{}, resultHash:{}]", chainTaskId, resultHash);
72+
stringToBytes(contribution.getResultHash()),
73+
stringToBytes(contribution.getResultSeal()),
74+
contribution.getEnclaveChallenge(),
75+
stringToBytes(contribution.getEnclaveSignature()),
76+
stringToBytes(contribution.getWorkerPoolSignature()));
77+
log.info("Sent contribute [chainTaskId:{}, contribution:{}]", chainTaskId, contribution);
8678

8779
try {
8880
contributeReceipt = contributeCall.send();
@@ -100,8 +92,8 @@ private IexecHubContract.TaskContributeEventResponse sendContributeTransaction(C
10092
}
10193

10294
if (isSuccessTx(chainTaskId, contributeEvent, CONTRIBUTED)) {
103-
log.info("Contributed [chainTaskId:{}, resultHash:{}, gasUsed:{}, log:{}]",
104-
chainTaskId, resultHash, contributeReceipt.getGasUsed(), contributeEvent.log);
95+
log.info("Contributed [chainTaskId:{}, contribution:{}, gasUsed:{}, log:{}]",
96+
chainTaskId, contribution, contributeReceipt.getGasUsed(), contributeEvent.log);
10597
return contributeEvent;
10698
}
10799

src/main/java/com/iexec/worker/chain/RevealService.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.iexec.common.chain.*;
44
import com.iexec.common.contract.generated.IexecHubContract;
55
import com.iexec.common.utils.HashUtils;
6+
import com.iexec.common.worker.result.ResultUtils;
67
import lombok.extern.slf4j.Slf4j;
78
import org.springframework.stereotype.Service;
89

@@ -25,17 +26,17 @@ public RevealService(IexecHubService iexecHubService,
2526
this.web3jService = web3jService;
2627
}
2728

28-
public boolean repeatCanReveal(String chainTaskId, String determinismHash) {
29+
public boolean repeatCanReveal(String chainTaskId, String resultDigest) {
2930
return web3jService.repeatCheck(6, 3, "canReveal",
30-
this::canReveal, chainTaskId, determinismHash);
31+
this::canReveal, chainTaskId, resultDigest);
3132
}
3233

3334
/*
3435
* params: String chainTaskId, String determinismHash
3536
* */
3637
public boolean canReveal(String... args) {
3738
String chainTaskId = args[0];
38-
String determinismHash = args[1];
39+
String resultDigest = args[1];
3940

4041
Optional<ChainTask> optionalChainTask = iexecHubService.getChainTask(chainTaskId);
4142
if (!optionalChainTask.isPresent()) {
@@ -59,12 +60,12 @@ public boolean canReveal(String... args) {
5960
boolean isContributionResultHashCorrect = false;
6061
boolean isContributionResultSealCorrect = false;
6162

62-
if (!determinismHash.isEmpty()) {//TODO
63-
isContributionResultHashCorrect = chainContribution.getResultHash().equals(HashUtils.concatenateAndHash(chainTaskId, determinismHash));
63+
if (!resultDigest.isEmpty()) {//TODO
64+
isContributionResultHashCorrect = chainContribution.getResultHash().equals(ResultUtils.computeResultHash(chainTaskId, resultDigest));
6465

6566
String walletAddress = credentialsService.getCredentials().getAddress();
6667
isContributionResultSealCorrect = chainContribution.getResultSeal().equals(
67-
HashUtils.concatenateAndHash(walletAddress, chainTaskId, determinismHash)
68+
ResultUtils.computeResultSeal(walletAddress, chainTaskId, resultDigest)
6869
);
6970
}
7071

@@ -96,13 +97,13 @@ public boolean isConsensusBlockReached(String chainTaskId, long consensusBlock)
9697
}
9798

9899
// returns the ChainReceipt of the reveal if successful, empty otherwise
99-
public Optional<ChainReceipt> reveal(String chainTaskId, String determinismHash) {
100+
public Optional<ChainReceipt> reveal(String chainTaskId, String resultDigest) {
100101

101-
if (determinismHash.isEmpty()) {
102+
if (resultDigest.isEmpty()) {
102103
return Optional.empty();
103104
}
104105

105-
IexecHubContract.TaskRevealEventResponse revealResponse = iexecHubService.reveal(chainTaskId, determinismHash);
106+
IexecHubContract.TaskRevealEventResponse revealResponse = iexecHubService.reveal(chainTaskId, resultDigest);
106107
if (revealResponse == null) {
107108
log.error("RevealTransactionReceipt received but was null [chainTaskId:{}]", chainTaskId);
108109
return Optional.empty();

src/main/java/com/iexec/worker/docker/CustomDockerClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public CustomDockerClient() throws DockerCertificateException {
5757

5858
public boolean pullImage(String chainTaskId, String image) {
5959
log.info("Image pull started [chainTaskId:{}, image:{}]", chainTaskId, image);
60+
/*
6061
try {
6162
docker.pull(image);
6263
} catch (DockerException | InterruptedException e) {
@@ -66,6 +67,7 @@ public boolean pullImage(String chainTaskId, String image) {
6667
}
6768
6869
log.info("Image pull completed [chainTaskId:{}, image:{}]", chainTaskId, image);
70+
*/
6971
return true;
7072
}
7173

src/main/java/com/iexec/worker/executor/TaskManagerService.java

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package com.iexec.worker.executor;
22

3+
import com.fasterxml.jackson.annotation.JsonIgnore;
34
import com.iexec.common.chain.ChainReceipt;
45
import com.iexec.common.chain.ContributionAuthorization;
6+
import com.iexec.common.contribution.Contribution;
57
import com.iexec.common.notification.TaskNotificationExtra;
68
import com.iexec.common.replicate.ReplicateActionResponse;
79
import com.iexec.common.replicate.ReplicateStatusCause;
10+
import com.iexec.common.result.ComputedFile;
811
import com.iexec.common.security.Signature;
912
import com.iexec.common.task.TaskDescription;
1013
import com.iexec.common.tee.TeeEnclaveChallengeSignature;
11-
import com.iexec.common.utils.SignatureUtils;
14+
import com.iexec.common.utils.BytesUtils;
15+
import com.iexec.common.worker.result.ResultUtils;
1216
import com.iexec.worker.chain.ContributionService;
1317
import com.iexec.worker.chain.IexecHubService;
1418
import com.iexec.worker.chain.RevealService;
@@ -232,24 +236,22 @@ ReplicateActionResponse contribute(String chainTaskId) {
232236
// System.exit(0);
233237
}
234238

235-
String determinismHash = resultService.getTaskDeterminismHash(chainTaskId);
236-
if (determinismHash.isEmpty()) {
237-
log.error("Cannot contribute, determinism hash not found [chainTaskId:{}]", chainTaskId);
239+
ComputedFile computedFile = resultService.getComputedFile(chainTaskId);
240+
if (computedFile == null){
241+
log.error("Cannot contribute, getComputedFile [chainTaskId:{}]", chainTaskId);
238242
return ReplicateActionResponse.failure(DETERMINISM_HASH_NOT_FOUND);
239243
}
240244

241245
ContributionAuthorization contributionAuthorization =
242246
contributionService.getContributionAuthorization(chainTaskId);
243247

244-
String enclaveChallenge = contributionAuthorization.getEnclaveChallenge();
245-
Optional<Signature> enclaveSignature = getVerifiedEnclaveChallengeSignature(chainTaskId, enclaveChallenge);
246-
if (enclaveSignature.isEmpty()) {//could be 0x0
247-
log.error("Cannot contribute enclave signature not found [chainTaskId:{}]", chainTaskId);
248-
return ReplicateActionResponse.failure(ENCLAVE_SIGNATURE_NOT_FOUND);
248+
Contribution contribution = contributionService.getContribution(computedFile, contributionAuthorization);
249+
if (contribution == null){
250+
log.error("Failed to getContribution [chainTaskId:{}]", chainTaskId);
251+
return ReplicateActionResponse.failure(ENCLAVE_SIGNATURE_NOT_FOUND);//TODO update status
249252
}
250253

251-
Optional<ChainReceipt> oChainReceipt =
252-
contributionService.contribute(contributionAuthorization, determinismHash, enclaveSignature.get());
254+
Optional<ChainReceipt> oChainReceipt = contributionService.contribute(contribution);
253255

254256
if (!isValidChainReceipt(chainTaskId, oChainReceipt)) {
255257
return ReplicateActionResponse.failure(CHAIN_RECEIPT_NOT_VALID);
@@ -261,9 +263,11 @@ ReplicateActionResponse contribute(String chainTaskId) {
261263
ReplicateActionResponse reveal(String chainTaskId, TaskNotificationExtra extra) {
262264
unsetTaskUsingCpu(chainTaskId);
263265

264-
String determinismHash = resultService.getTaskDeterminismHash(chainTaskId);
265-
if (determinismHash.isEmpty()) {
266-
log.error("Cannot reveal, determinism hash not found [chainTaskId:{}]", chainTaskId);
266+
ComputedFile computedFile = resultService.getComputedFile(chainTaskId);
267+
String resultDigest = computedFile != null ? computedFile.getResultDigest(): "";
268+
269+
if (resultDigest.isEmpty()) {
270+
log.error("Cannot reveal, resultDigest not found [chainTaskId:{}]", chainTaskId);
267271
return ReplicateActionResponse.failure(DETERMINISM_HASH_NOT_FOUND);
268272
}
269273

@@ -279,7 +283,7 @@ ReplicateActionResponse reveal(String chainTaskId, TaskNotificationExtra extra)
279283
return ReplicateActionResponse.failure(BLOCK_NOT_REACHED);
280284
}
281285

282-
boolean canReveal = revealService.repeatCanReveal(chainTaskId, determinismHash);
286+
boolean canReveal = revealService.repeatCanReveal(chainTaskId, resultDigest);
283287

284288
if (!canReveal) {
285289
log.error("Cannot reveal, one or more conditions are not satisfied [chainTaskId:{}]", chainTaskId);
@@ -292,7 +296,7 @@ ReplicateActionResponse reveal(String chainTaskId, TaskNotificationExtra extra)
292296
System.exit(0);
293297
}
294298

295-
Optional<ChainReceipt> oChainReceipt = revealService.reveal(chainTaskId, determinismHash);
299+
Optional<ChainReceipt> oChainReceipt = revealService.reveal(chainTaskId, resultDigest);
296300
if (!isValidChainReceipt(chainTaskId, oChainReceipt)) {
297301
return ReplicateActionResponse.failure(CHAIN_RECEIPT_NOT_VALID);
298302
}
@@ -321,7 +325,8 @@ ReplicateActionResponse uploadResult(String chainTaskId) {
321325
return ReplicateActionResponse.failure(RESULT_LINK_MISSING);
322326
}
323327

324-
String callbackData = resultService.getCallbackDataFromFile(chainTaskId);
328+
ComputedFile computedFile = resultService.getComputedFile(chainTaskId);
329+
String callbackData = computedFile != null ? computedFile.getCallbackData(): "";
325330

326331
log.info("Result uploaded [chainTaskId:{}, resultLink:{}, callbackData:{}]",
327332
chainTaskId, resultLink, callbackData);
@@ -343,38 +348,6 @@ boolean abort(String chainTaskId) {
343348
return resultService.removeResult(chainTaskId);
344349
}
345350

346-
347-
//TODO Move that to result service
348-
Optional<Signature> getVerifiedEnclaveChallengeSignature(String chainTaskId, String expectedSigner) {
349-
boolean isTeeTask = iexecHubService.isTeeTask(chainTaskId);
350-
if (!isTeeTask) {
351-
return Optional.of(SignatureUtils.emptySignature());
352-
}
353-
354-
Optional<TeeEnclaveChallengeSignature> optionalTeeEnclaveChallengeSignature =
355-
resultService.readTeeEnclaveChallengeSignatureFile(chainTaskId);
356-
if (optionalTeeEnclaveChallengeSignature.isEmpty()) {
357-
log.error("Error reading and parsing enclaveSig.iexec file [chainTaskId:{}]", chainTaskId);
358-
return Optional.empty();
359-
}
360-
TeeEnclaveChallengeSignature enclaveChallengeSignature = optionalTeeEnclaveChallengeSignature.get();
361-
362-
String messageHash = TeeEnclaveChallengeSignature.getMessageHash(
363-
enclaveChallengeSignature.getResultHash(),
364-
enclaveChallengeSignature.getResultSeal());
365-
366-
boolean isExpectedSigner = resultService.isExpectedSignerOnSignature(messageHash,
367-
enclaveChallengeSignature.getSignature(),
368-
expectedSigner);
369-
370-
if (!isExpectedSigner) {
371-
log.error("Scone enclave signature is not valid [chainTaskId:{}]", chainTaskId);
372-
return Optional.empty();
373-
}
374-
375-
return Optional.of(enclaveChallengeSignature.getSignature());
376-
}
377-
378351
boolean checkGasBalance(String chainTaskId) {
379352
if (iexecHubService.hasEnoughGas()) {
380353
return true;

0 commit comments

Comments
 (0)