Skip to content

Commit c73b567

Browse files
committed
feat: manipulate list of ReplicateStatusCause in TaskManagerService
1 parent 38c0457 commit c73b567

File tree

8 files changed

+158
-165
lines changed

8 files changed

+158
-165
lines changed

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.web3j.protocol.core.methods.response.Log;
2828

2929
import java.math.BigInteger;
30+
import java.util.List;
3031
import java.util.Optional;
3132

3233
import static com.iexec.common.replicate.ReplicateStatusCause.*;
@@ -54,57 +55,57 @@ public boolean isChainTaskInitialized(String chainTaskId) {
5455
return iexecHubService.getTaskDescription(chainTaskId) != null;
5556
}
5657

57-
public Optional<ReplicateStatusCause> getCannotContributeStatusCause(final String chainTaskId) {
58+
public List<ReplicateStatusCause> getCannotContributeStatusCause(final String chainTaskId) {
5859
if (!isWorkerpoolAuthorizationPresent(chainTaskId)) {
59-
return Optional.of(WORKERPOOL_AUTHORIZATION_NOT_FOUND);
60+
return List.of(WORKERPOOL_AUTHORIZATION_NOT_FOUND);
6061
}
6162

6263
final TaskDescription taskDescription = iexecHubService.getTaskDescription(chainTaskId);
6364

6465
final ChainTask chainTask = iexecHubService.getChainTask(chainTaskId).orElse(null);
6566
if (chainTask == null) {
66-
return Optional.of(CHAIN_UNREACHABLE);
67+
return List.of(CHAIN_UNREACHABLE);
6768
}
6869

6970
// No staking in contributeAndFinalize
7071
if (taskDescription != null && !taskDescription.isEligibleToContributeAndFinalize()
7172
&& !hasEnoughStakeToContribute(chainTask)) {
72-
return Optional.of(STAKE_TOO_LOW);
73+
return List.of(STAKE_TOO_LOW);
7374
}
7475

7576
if (chainTask.getStatus() != ChainTaskStatus.ACTIVE) {
76-
return Optional.of(TASK_NOT_ACTIVE);
77+
return List.of(TASK_NOT_ACTIVE);
7778
}
7879

7980
if (chainTask.isContributionDeadlineReached()) {
80-
return Optional.of(CONTRIBUTION_TIMEOUT);
81+
return List.of(CONTRIBUTION_TIMEOUT);
8182
}
8283

8384
if (chainTask.hasContributionFrom(workerWalletAddress)) {
84-
return Optional.of(CONTRIBUTION_ALREADY_SET);
85+
return List.of(CONTRIBUTION_ALREADY_SET);
8586
}
8687

87-
return Optional.empty();
88+
return List.of();
8889
}
8990

90-
public Optional<ReplicateStatusCause> getCannotContributeAndFinalizeStatusCause(final String chainTaskId) {
91+
public List<ReplicateStatusCause> getCannotContributeAndFinalizeStatusCause(final String chainTaskId) {
9192
// check TRUST is 1
9293
final TaskDescription taskDescription = iexecHubService.getTaskDescription(chainTaskId);
9394
if (taskDescription == null || !BigInteger.ONE.equals(taskDescription.getTrust())) {
94-
return Optional.of(TRUST_NOT_1);
95+
return List.of(TRUST_NOT_1);
9596
}
9697

9798
final ChainTask chainTask = iexecHubService.getChainTask(chainTaskId).orElse(null);
9899
if (chainTask == null) {
99-
return Optional.of(CHAIN_UNREACHABLE);
100+
return List.of(CHAIN_UNREACHABLE);
100101
}
101102

102103
// check TASK_ALREADY_CONTRIBUTED
103104
if (chainTask.hasContributions()) {
104-
return Optional.of(TASK_ALREADY_CONTRIBUTED);
105+
return List.of(TASK_ALREADY_CONTRIBUTED);
105106
}
106107

107-
return Optional.empty();
108+
return List.of();
108109
}
109110

110111
private boolean isWorkerpoolAuthorizationPresent(String chainTaskId) {

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

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import lombok.extern.slf4j.Slf4j;
4646
import org.springframework.stereotype.Service;
4747

48+
import java.util.List;
4849
import java.util.Optional;
4950

5051
import static com.iexec.common.replicate.ReplicateStatus.APP_DOWNLOAD_FAILED;
@@ -95,17 +96,16 @@ public TaskManagerService(
9596

9697
ReplicateActionResponse start(TaskDescription taskDescription) {
9798
final String chainTaskId = taskDescription.getChainTaskId();
98-
Optional<ReplicateStatusCause> oErrorStatus =
99+
List<ReplicateStatusCause> oErrorStatus =
99100
contributionService.getCannotContributeStatusCause(chainTaskId);
100101
String context = "start";
101-
if (oErrorStatus.isPresent()) {
102-
return getFailureResponseAndPrintError(oErrorStatus.get(),
103-
context, chainTaskId);
102+
if (!oErrorStatus.isEmpty()) {
103+
return getFailureResponseAndPrintError(oErrorStatus, context, chainTaskId);
104104
}
105105

106106
// result encryption is not supported for standard tasks
107107
if (!taskDescription.isTeeTask() && taskDescription.getDealParams().isIexecResultEncryption()) {
108-
return getFailureResponseAndPrintError(TASK_DESCRIPTION_INVALID,
108+
return getFailureResponseAndPrintError(List.of(TASK_DESCRIPTION_INVALID),
109109
context, chainTaskId);
110110
}
111111

@@ -114,10 +114,10 @@ ReplicateActionResponse start(TaskDescription taskDescription) {
114114
// then we won't be able to run the task.
115115
// So it should be aborted right now.
116116
final TeeService teeService = teeServicesManager.getTeeService(taskDescription.getTeeFramework());
117-
final Optional<ReplicateStatusCause> teePrerequisitesIssue = teeService.areTeePrerequisitesMetForTask(chainTaskId);
118-
if (teePrerequisitesIssue.isPresent()) {
119-
log.error("TEE prerequisites are not met [chainTaskId: {}, issue: {}]", chainTaskId, teePrerequisitesIssue.get());
120-
return getFailureResponseAndPrintError(teePrerequisitesIssue.get(), context, chainTaskId);
117+
final List<ReplicateStatusCause> teePrerequisitesIssues = teeService.areTeePrerequisitesMetForTask(chainTaskId);
118+
if (!teePrerequisitesIssues.isEmpty()) {
119+
log.error("TEE prerequisites are not met [chainTaskId: {}, issues: {}]", chainTaskId, teePrerequisitesIssues);
120+
return getFailureResponseAndPrintError(teePrerequisitesIssues, context, chainTaskId);
121121
}
122122

123123
final WorkerpoolAuthorization workerpoolAuthorization = contributionService.getWorkerpoolAuthorization(chainTaskId);
@@ -131,12 +131,11 @@ ReplicateActionResponse start(TaskDescription taskDescription) {
131131

132132
ReplicateActionResponse downloadApp(TaskDescription taskDescription) {
133133
final String chainTaskId = taskDescription.getChainTaskId();
134-
Optional<ReplicateStatusCause> oErrorStatus =
134+
List<ReplicateStatusCause> oErrorStatus =
135135
contributionService.getCannotContributeStatusCause(chainTaskId);
136136
String context = "download app";
137-
if (oErrorStatus.isPresent()) {
138-
return getFailureResponseAndPrintError(oErrorStatus.get(),
139-
context, chainTaskId);
137+
if (!oErrorStatus.isEmpty()) {
138+
return getFailureResponseAndPrintError(oErrorStatus, context, chainTaskId);
140139
}
141140

142141
if (computeManagerService.downloadApp(taskDescription)) {
@@ -174,12 +173,11 @@ ReplicateActionResponse downloadData(final TaskDescription taskDescription) {
174173
log.info("Dataset and input files will be downloaded by the pre-compute enclave [chainTaskId:{}]", chainTaskId);
175174
return ReplicateActionResponse.success();
176175
}
177-
Optional<ReplicateStatusCause> errorStatus =
176+
List<ReplicateStatusCause> errorStatus =
178177
contributionService.getCannotContributeStatusCause(chainTaskId);
179178
String context = "download data";
180-
if (errorStatus.isPresent()) {
181-
return getFailureResponseAndPrintError(errorStatus.get(),
182-
context, chainTaskId);
179+
if (!errorStatus.isEmpty()) {
180+
return getFailureResponseAndPrintError(errorStatus, context, chainTaskId);
183181
}
184182
try {
185183
// download dataset for standard task
@@ -222,22 +220,21 @@ private ReplicateActionResponse triggerPostComputeHookOnError(String chainTaskId
222220

223221
ReplicateActionResponse compute(TaskDescription taskDescription) {
224222
final String chainTaskId = taskDescription.getChainTaskId();
225-
final ReplicateStatusCause errorStatus = contributionService.getCannotContributeStatusCause(chainTaskId)
226-
.orElse(null);
223+
final List<ReplicateStatusCause> errorStatus = contributionService.getCannotContributeStatusCause(chainTaskId);
227224
final String context = "compute";
228-
if (errorStatus != null) {
225+
if (!errorStatus.isEmpty()) {
229226
return getFailureResponseAndPrintError(errorStatus, context, chainTaskId);
230227
}
231228

232229
if (!computeManagerService.isAppDownloaded(taskDescription.getAppUri())) {
233-
return getFailureResponseAndPrintError(APP_NOT_FOUND_LOCALLY,
230+
return getFailureResponseAndPrintError(List.of(APP_NOT_FOUND_LOCALLY),
234231
context, chainTaskId);
235232
}
236233

237234
if (taskDescription.isTeeTask()) {
238235
TeeService teeService = teeServicesManager.getTeeService(taskDescription.getTeeFramework());
239236
if (!teeService.prepareTeeForTask(chainTaskId)) {
240-
return getFailureResponseAndPrintError(TEE_PREPARATION_FAILED,
237+
return getFailureResponseAndPrintError(List.of(TEE_PREPARATION_FAILED),
241238
context, chainTaskId);
242239
}
243240
}
@@ -250,7 +247,7 @@ ReplicateActionResponse compute(TaskDescription taskDescription) {
250247
workerpoolAuthorization);
251248
if (!preResponse.isSuccessful()) {
252249
return getFailureResponseAndPrintError(
253-
preResponse.getExitCauses().get(0), //TODO: Handle list of causes
250+
preResponse.getExitCauses(),
254251
context,
255252
chainTaskId
256253
);
@@ -303,14 +300,13 @@ ReplicateActionResponse compute(TaskDescription taskDescription) {
303300
* @return The response of the 'contribute' or 'contributeAndFinalize' action
304301
*/
305302
private ReplicateActionResponse contributeOrContributeAndFinalize(String chainTaskId, String context) {
306-
Optional<ReplicateStatusCause> oErrorStatus = contributionService.getCannotContributeStatusCause(chainTaskId);
307-
if (oErrorStatus.isPresent()) {
308-
return getFailureResponseAndPrintError(oErrorStatus.get(),
309-
context, chainTaskId);
303+
List<ReplicateStatusCause> oErrorStatus = contributionService.getCannotContributeStatusCause(chainTaskId);
304+
if (!oErrorStatus.isEmpty()) {
305+
return getFailureResponseAndPrintError(oErrorStatus, context, chainTaskId);
310306
}
311307

312308
if (!hasEnoughGas()) {
313-
return getFailureResponseAndPrintError(OUT_OF_GAS, context, chainTaskId);
309+
return getFailureResponseAndPrintError(List.of(OUT_OF_GAS), context, chainTaskId);
314310
}
315311

316312
ComputedFile computedFile = resultService.getComputedFile(chainTaskId);
@@ -335,9 +331,8 @@ private ReplicateActionResponse contributeOrContributeAndFinalize(String chainTa
335331
}
336332
} else if (context.equals(CONTRIBUTE_AND_FINALIZE)) {
337333
oErrorStatus = contributionService.getCannotContributeAndFinalizeStatusCause(chainTaskId);
338-
if (oErrorStatus.isPresent()) {
339-
return getFailureResponseAndPrintError(oErrorStatus.get(),
340-
context, chainTaskId);
334+
if (!oErrorStatus.isEmpty()) {
335+
return getFailureResponseAndPrintError(oErrorStatus, context, chainTaskId);
341336
}
342337

343338
final WorkerpoolAuthorization workerpoolAuthorization = contributionService.getWorkerpoolAuthorization(chainTaskId);
@@ -370,7 +365,7 @@ ReplicateActionResponse reveal(String chainTaskId,
370365
TaskNotificationExtra extra) {
371366
String context = "reveal";
372367
if (extra == null || extra.getBlockNumber() == 0) {
373-
return getFailureResponseAndPrintError(CONSENSUS_BLOCK_MISSING, context, chainTaskId);
368+
return getFailureResponseAndPrintError(List.of(CONSENSUS_BLOCK_MISSING), context, chainTaskId);
374369
}
375370
long consensusBlock = extra.getBlockNumber();
376371

@@ -384,12 +379,12 @@ ReplicateActionResponse reveal(String chainTaskId,
384379
}
385380

386381
if (!revealService.isConsensusBlockReached(chainTaskId, consensusBlock)) {
387-
return getFailureResponseAndPrintError(BLOCK_NOT_REACHED, context, chainTaskId
382+
return getFailureResponseAndPrintError(List.of(BLOCK_NOT_REACHED), context, chainTaskId
388383
);
389384
}
390385

391386
if (!revealService.repeatCanReveal(chainTaskId, resultDigest)) {
392-
return getFailureResponseAndPrintError(CANNOT_REVEAL, context, chainTaskId);
387+
return getFailureResponseAndPrintError(List.of(CANNOT_REVEAL), context, chainTaskId);
393388
}
394389

395390
if (!hasEnoughGas()) {
@@ -402,7 +397,7 @@ ReplicateActionResponse reveal(String chainTaskId,
402397
revealService.reveal(chainTaskId, resultDigest);
403398
if (oChainReceipt.isEmpty() ||
404399
!isValidChainReceipt(chainTaskId, oChainReceipt.get())) {
405-
return getFailureResponseAndPrintError(CHAIN_RECEIPT_NOT_VALID,
400+
return getFailureResponseAndPrintError(List.of(CHAIN_RECEIPT_NOT_VALID),
406401
context, chainTaskId
407402
);
408403
}
@@ -415,7 +410,7 @@ ReplicateActionResponse uploadResult(String chainTaskId) {
415410
String resultLink = resultService.uploadResultAndGetLink(workerpoolAuthorization);
416411
String context = "upload result";
417412
if (resultLink.isEmpty()) {
418-
return getFailureResponseAndPrintError(RESULT_LINK_MISSING,
413+
return getFailureResponseAndPrintError(List.of(RESULT_LINK_MISSING),
419414
context, chainTaskId
420415
);
421416
}
@@ -494,9 +489,13 @@ boolean isValidChainReceipt(String chainTaskId,
494489
return true;
495490
}
496491

497-
private ReplicateActionResponse getFailureResponseAndPrintError(ReplicateStatusCause cause, String context, String chainTaskId) {
498-
logError(cause, context, chainTaskId);
499-
return ReplicateActionResponse.failure(cause);
492+
private ReplicateActionResponse getFailureResponseAndPrintError(List<ReplicateStatusCause> causes, String context, String chainTaskId) {
493+
if (causes == null || causes.isEmpty()) {
494+
log.error("Failed to {} [chainTaskId:'{}', cause:'UNKNOWN']", context, chainTaskId);
495+
return ReplicateActionResponse.failure();
496+
}
497+
causes.forEach(cause -> logError(cause, context, chainTaskId));
498+
return ReplicateActionResponse.failure(causes.get(0));
500499
}
501500

502501
/**

src/main/java/com/iexec/worker/tee/TeeService.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
import java.util.Collection;
2828
import java.util.List;
29-
import java.util.Optional;
3029

3130
import static com.iexec.common.replicate.ReplicateStatusCause.*;
3231

@@ -48,9 +47,9 @@ public boolean isTeeEnabled() {
4847
return sgxService.isSgxEnabled();
4948
}
5049

51-
public Optional<ReplicateStatusCause> areTeePrerequisitesMetForTask(String chainTaskId) {
50+
public List<ReplicateStatusCause> areTeePrerequisitesMetForTask(String chainTaskId) {
5251
if (!isTeeEnabled()) {
53-
return Optional.of(TEE_NOT_SUPPORTED);
52+
return List.of(TEE_NOT_SUPPORTED);
5453
}
5554

5655
try {
@@ -59,21 +58,21 @@ public Optional<ReplicateStatusCause> areTeePrerequisitesMetForTask(String chain
5958
smsService.getSmsClient(chainTaskId);
6059
} catch (SmsClientCreationException e) {
6160
log.error("Couldn't get SmsClient [chainTaskId: {}]", chainTaskId, e);
62-
return Optional.of(UNKNOWN_SMS);
61+
return List.of(UNKNOWN_SMS);
6362
}
6463
try {
6564
// Try to load the `TeeServicesProperties` relative to the task.
6665
// If it can't be loaded, then we won't be able to run the task.
6766
teeServicesPropertiesService.getTeeServicesProperties(chainTaskId);
6867
} catch (NullPointerException e) {
6968
log.error("TEE enclave configuration is null [chainTaskId: {}]", chainTaskId, e);
70-
return Optional.of(PRE_COMPUTE_MISSING_ENCLAVE_CONFIGURATION);
69+
return List.of(PRE_COMPUTE_MISSING_ENCLAVE_CONFIGURATION);
7170
} catch (RuntimeException e) {
7271
log.error("Couldn't get TeeServicesProperties [chainTaskId: {}]", chainTaskId, e);
73-
return Optional.of(GET_TEE_SERVICES_CONFIGURATION_FAILED);
72+
return List.of(GET_TEE_SERVICES_CONFIGURATION_FAILED);
7473
}
7574

76-
return Optional.empty();
75+
return List.of();
7776
}
7877

7978
/**

src/main/java/com/iexec/worker/tee/scone/TeeSconeService.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2024 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,7 +32,6 @@
3232
import java.util.Collection;
3333
import java.util.Collections;
3434
import java.util.List;
35-
import java.util.Optional;
3635

3736
import static com.iexec.common.replicate.ReplicateStatusCause.TEE_PREPARATION_FAILED;
3837

@@ -65,12 +64,12 @@ public TeeSconeService(
6564
}
6665

6766
@Override
68-
public Optional<ReplicateStatusCause> areTeePrerequisitesMetForTask(String chainTaskId) {
69-
final Optional<ReplicateStatusCause> teePrerequisiteIssue = super.areTeePrerequisitesMetForTask(chainTaskId);
70-
if (teePrerequisiteIssue.isPresent()) {
67+
public List<ReplicateStatusCause> areTeePrerequisitesMetForTask(String chainTaskId) {
68+
final List<ReplicateStatusCause> teePrerequisiteIssue = super.areTeePrerequisitesMetForTask(chainTaskId);
69+
if (!teePrerequisiteIssue.isEmpty()) {
7170
return teePrerequisiteIssue;
7271
}
73-
return prepareTeeForTask(chainTaskId) ? Optional.empty() : Optional.of(TEE_PREPARATION_FAILED);
72+
return prepareTeeForTask(chainTaskId) ? List.of() : List.of(TEE_PREPARATION_FAILED);
7473
}
7574

7675
@Override

0 commit comments

Comments
 (0)