Skip to content

Commit

Permalink
Merge pull request #619 from iExecBlockchainComputing/feature/is-elig…
Browse files Browse the repository at this point in the history
…ible-to-contribute-and-finalize

Add `isEligibleToContributeAndFinalize` method to `Task`
  • Loading branch information
mcornaton authored Sep 28, 2023
2 parents 307cbfc + b5b4861 commit 0fe52d6
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Add blockchain connection health indicator. (#601)
- Block some connections and messages when blockchain connection is down. (#604)
- Block deal watching mechanisms when communication with the blockchain node is lost. (#606)
- Use `isEligibleToContributeAndFinalize` method from `TaskDescription`. (#619)
### Bug Fixes
- Clean call to `iexecHubService#getTaskDescriptionFromChain` in test. (#597)
- Reject deal if TEE tag but trust not in {0,1}. (#598)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.iexec.common.replicate.ReplicateStatus;
import com.iexec.commons.poco.chain.ChainTask;
import com.iexec.commons.poco.chain.ChainTaskStatus;
import com.iexec.commons.poco.task.TaskDescription;
import com.iexec.core.chain.IexecHubService;
import com.iexec.core.detector.Detector;
import com.iexec.core.replicate.Replicate;
Expand Down Expand Up @@ -89,8 +90,8 @@ boolean isChainTaskCompleted(Task task) {
}

boolean isTaskContributeAndFinalizeDone(Task task) {
// Only TEE tasks can follow ContributeAndFinalize workflow
if (!task.isTeeTask()) {
final TaskDescription taskDescription = iexecHubService.getTaskDescription(task.getChainTaskId());
if (!taskDescription.isEligibleToContributeAndFinalize()) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.iexec.commons.poco.chain.ChainReceipt;
import com.iexec.commons.poco.chain.ChainTask;
import com.iexec.commons.poco.chain.ChainTaskStatus;
import com.iexec.commons.poco.task.TaskDescription;
import com.iexec.core.chain.IexecHubService;
import com.iexec.core.chain.adapter.BlockchainAdapterService;
import com.iexec.core.replicate.Replicate;
Expand Down Expand Up @@ -331,7 +332,8 @@ void running2Finalized2Completed(Task task) {
boolean isTaskInRunningStatus = task.getCurrentStatus() == RUNNING;
final String chainTaskId = task.getChainTaskId();

if (!task.isTeeTask()) {
final TaskDescription taskDescription = iexecHubService.getTaskDescription(task.getChainTaskId());
if (!taskDescription.isEligibleToContributeAndFinalize()) {
log.debug("Task not running in a TEE, flow running2Finalized2Completed is not possible"
+ " [chainTaskId:{}]", chainTaskId);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ TaskNotificationType getNextActionWhenStatusAndCause(ReplicateStatus whenStatus,
return PLEASE_ABORT;
}
// We must check CallBack is empty because there is an issue in poco (transaction is revert)
if (taskDescription.isTeeTask() && !taskDescription.containsCallback()) {
if (taskDescription.isEligibleToContributeAndFinalize()) {
return PLEASE_CONTRIBUTE_AND_FINALIZE;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.iexec.common.replicate.ReplicateStatusModifier;
import com.iexec.commons.poco.chain.ChainTask;
import com.iexec.commons.poco.chain.ChainTaskStatus;
import com.iexec.commons.poco.task.TaskDescription;
import com.iexec.core.chain.IexecHubService;
import com.iexec.core.replicate.Replicate;
import com.iexec.core.replicate.ReplicatesService;
Expand All @@ -32,6 +33,7 @@
import org.junit.jupiter.api.Test;
import org.mockito.*;

import java.math.BigInteger;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -68,6 +70,7 @@ void shouldDetectTasks() {
final String contributedAndFinalizedChainTaskId = "0x75bc5e94ed1486b940bd6cc0013c418efad58a0a52a3d08cee89faaa21970426";
final Task contributeAndFinalizeTask = getContributeAndFinalizeDoneTask(contributedAndFinalizedChainTaskId).build();
when(taskService.findByCurrentStatus(TaskStatus.RUNNING)).thenReturn(List.of(contributeAndFinalizeTask));
mockTaskDescriptionFromTask(contributeAndFinalizeTask);

detector.detect();

Expand Down Expand Up @@ -106,6 +109,7 @@ void shouldDetectContributeAndFinalizeDoneTask() {
final Task task = getContributeAndFinalizeDoneTask(CHAIN_TASK_ID).build();

when(taskService.findByCurrentStatus(TaskStatus.RUNNING)).thenReturn(List.of(task));
mockTaskDescriptionFromTask(task);

detector.detectContributeAndFinalizeDoneTasks();

Expand All @@ -117,6 +121,7 @@ void shouldDetectNoContributeAndFinalizeDoneTaskAsTaskIsRevealing() {
final Task task = getOnchainRevealingTask(CHAIN_DEAL_ID).build();

when(taskService.findByCurrentStatus(TaskStatus.RUNNING)).thenReturn(List.of(task));
mockTaskDescriptionFromTask(task);

detector.detectContributeAndFinalizeDoneTasks();

Expand Down Expand Up @@ -162,6 +167,7 @@ void shouldChainTaskNotBeCompletedAsChainTaskNotCompleted() {
@Test
void shouldTaskBeContributeAndFinalizeDone() {
final Task task = getContributeAndFinalizeDoneTask(CHAIN_TASK_ID).build();
mockTaskDescriptionFromTask(task);

final boolean taskContributeAndFinalizeDone = detector.isTaskContributeAndFinalizeDone(task);

Expand All @@ -175,6 +181,7 @@ void shouldTaskNotBeContributeAndFinalizeDoneAsNotTee() {
.currentStatus(TaskStatus.FINALIZING)
.tag(NO_TEE_TAG)
.build();
mockTaskDescriptionFromTask(task);

final boolean taskContributeAndFinalizeDone = detector.isTaskContributeAndFinalizeDone(task);

Expand All @@ -197,6 +204,7 @@ void shouldTaskNotBeContributeAndFinalizeDoneAsMultipleReplicates() {

when(replicatesService.getReplicates(CHAIN_TASK_ID)).thenReturn(List.of(replicate1, replicate2));
when(iexecHubService.getChainTask(CHAIN_TASK_ID)).thenReturn(Optional.of(chainTask));
mockTaskDescriptionFromTask(task);

final boolean taskContributeAndFinalizeDone = detector.isTaskContributeAndFinalizeDone(task);

Expand All @@ -214,6 +222,7 @@ void shouldTaskNotBeContributeAndFinalizeDoneAsReplicateNotDone() {
replicate.updateStatus(ReplicateStatus.COMPUTING, ReplicateStatusModifier.WORKER);

when(replicatesService.getReplicates(CHAIN_TASK_ID)).thenReturn(List.of(replicate));
mockTaskDescriptionFromTask(task);

final boolean taskContributeAndFinalizeDone = detector.isTaskContributeAndFinalizeDone(task);

Expand All @@ -236,6 +245,7 @@ void shouldTaskNotBeContributeAndFinalizeDoneAsChainTaskNotCompleted() {

when(replicatesService.getReplicates(CHAIN_TASK_ID)).thenReturn(List.of(replicate));
when(iexecHubService.getChainTask(CHAIN_TASK_ID)).thenReturn(Optional.of(chainTask));
mockTaskDescriptionFromTask(task);

final boolean taskContributeAndFinalizeDone = detector.isTaskContributeAndFinalizeDone(task);

Expand Down Expand Up @@ -291,7 +301,18 @@ private Task.TaskBuilder getContributeAndFinalizeDoneTask(String chainTaskId) {
when(replicatesService.getReplicates(chainTaskId)).thenReturn(List.of(replicate));

return getOnchainCompletedTask(chainTaskId)
.tag(TEE_TAG);
.tag(TEE_TAG)
.trust(1);
}

private void mockTaskDescriptionFromTask(Task task) {
final TaskDescription taskDescription = TaskDescription.builder()
.chainTaskId(task.getChainTaskId())
.isTeeTask(task.isTeeTask())
.trust(BigInteger.valueOf(task.getTrust()))
.callback("")
.build();
when(iexecHubService.getTaskDescription(task.getChainTaskId())).thenReturn(taskDescription);
}
// endregion
}
2 changes: 1 addition & 1 deletion src/test/java/com/iexec/core/task/TaskTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
import java.util.Date;
import java.util.List;

import static com.iexec.core.task.TaskStatus.CONSENSUS_REACHED;
import static com.iexec.common.utils.DateTimeUtils.addMinutesToDate;
import static com.iexec.common.utils.DateTimeUtils.now;
import static com.iexec.core.task.TaskStatus.CONSENSUS_REACHED;
import static org.assertj.core.api.Assertions.assertThat;

class TaskTests {
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/com/iexec/core/task/TaskTestsUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class TaskTestsUtils {
public final static String RESULT_LINK = "/ipfs/the_result_string";

public static Task getStubTask(long maxExecutionTime) {
Task task = new Task(CHAIN_DEAL_ID, 0, DAPP_NAME, COMMAND_LINE, 0, maxExecutionTime, NO_TEE_TAG);
Task task = new Task(CHAIN_DEAL_ID, 0, DAPP_NAME, COMMAND_LINE, 1, maxExecutionTime, NO_TEE_TAG);
task.setFinalDeadline(Date.from(Instant.now().plus(1, ChronoUnit.MINUTES)));
return task;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.iexec.commons.poco.chain.ChainReceipt;
import com.iexec.commons.poco.chain.ChainTask;
import com.iexec.commons.poco.chain.ChainTaskStatus;
import com.iexec.commons.poco.task.TaskDescription;
import com.iexec.commons.poco.tee.TeeUtils;
import com.iexec.commons.poco.utils.BytesUtils;
import com.iexec.core.chain.IexecHubService;
Expand All @@ -48,6 +49,7 @@
import org.mockito.MockitoAnnotations;
import org.springframework.context.ApplicationEventPublisher;

import java.math.BigInteger;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
Expand Down Expand Up @@ -689,6 +691,7 @@ void shouldNotUpdateRunning2Finalized2CompletedWhenTaskNotRunning() {
Task task = getStubTask(maxExecutionTime);
task.changeStatus(INITIALIZED);
task.setTag(TeeUtils.TEE_SCONE_ONLY_TAG);
mockTaskDescriptionFromTask(task);

taskUpdateManager.running2Finalized2Completed(task);
assertThat(task.getCurrentStatus()).isEqualTo(INITIALIZED);
Expand All @@ -701,6 +704,7 @@ void shouldNotUpdateRunning2Finalized2CompletedWhenNoReplicates() {
task.setTag(TeeUtils.TEE_SCONE_ONLY_TAG);

when(replicatesService.getReplicatesList(CHAIN_TASK_ID)).thenReturn(Optional.empty());
mockTaskDescriptionFromTask(task);

taskUpdateManager.running2Finalized2Completed(task);
assertThat(task.getCurrentStatus()).isEqualTo(RUNNING);
Expand All @@ -714,6 +718,7 @@ void shouldNotUpdateRunning2Finalized2CompletedWhenTaskIsNotTee() {
final ReplicatesList replicatesList = Mockito.spy(new ReplicatesList(CHAIN_TASK_ID));

when(replicatesService.getReplicatesList(CHAIN_TASK_ID)).thenReturn(Optional.of(replicatesList));
mockTaskDescriptionFromTask(task);
taskUpdateManager.running2Finalized2Completed(task);
assertThat(task.getCurrentStatus()).isEqualTo(RUNNING);
}
Expand All @@ -728,6 +733,7 @@ void shouldNotUpdateRunning2Finalized2CompletedWhenNoReplicatesOnContributeAndFi

when(replicatesService.getReplicatesList(CHAIN_TASK_ID)).thenReturn(Optional.of(replicatesList));
when(replicatesList.getNbReplicatesWithCurrentStatus(ReplicateStatus.CONTRIBUTE_AND_FINALIZE_DONE)).thenReturn(0);
mockTaskDescriptionFromTask(task);

taskUpdateManager.running2Finalized2Completed(task);
assertThat(task.getCurrentStatus()).isEqualTo(RUNNING);
Expand All @@ -744,6 +750,7 @@ void shouldNotUpdateRunning2Finalized2CompletedWhenMoreThanOneReplicatesOnContri
when(replicatesService.getReplicatesList(CHAIN_TASK_ID)).thenReturn(Optional.of(replicatesList));
when(replicatesList.getNbReplicatesWithCurrentStatus(ReplicateStatus.CONTRIBUTE_AND_FINALIZE_DONE)).thenReturn(2);
doNothing().when(applicationEventPublisher).publishEvent(any());
mockTaskDescriptionFromTask(task);

taskUpdateManager.running2Finalized2Completed(task);
assertThat(task.getCurrentStatus()).isEqualTo(FAILED);
Expand All @@ -770,6 +777,7 @@ void shouldUpdateRunning2ConsensusReached() {
when(iexecHubService.getConsensusBlock(anyString(), anyLong())).thenReturn(ChainReceipt.builder().blockNumber(1L).build());
doNothing().when(applicationEventPublisher).publishEvent(any());
when(replicatesList.getNbValidContributedWinners(any())).thenReturn(2);
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(task.getChainTaskId());
assertThat(task.getCurrentStatus()).isEqualTo(CONSENSUS_REACHED);
Expand Down Expand Up @@ -857,6 +865,7 @@ void shouldUpdateRunning2RunningFailedOn1Worker() {
when(replicatesService.getReplicatesList(task.getChainTaskId())).thenReturn(Optional.of(replicatesList));
when(workerService.getAliveWorkers()).thenReturn(workersList);
doNothing().when(applicationEventPublisher).publishEvent(any());
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(task.getChainTaskId());
assertThat(task.getDateOfStatus(RUNNING_FAILED)).isPresent();
Expand Down Expand Up @@ -893,6 +902,7 @@ void shouldUpdateRunning2RunningFailedOn2Workers() {
when(replicatesService.getReplicatesList(task.getChainTaskId())).thenReturn(Optional.of(replicatesList));
when(workerService.getAliveWorkers()).thenReturn(workersList);
doNothing().when(applicationEventPublisher).publishEvent(any());
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(task.getChainTaskId());
assertThat(task.getDateOfStatus(RUNNING_FAILED)).isPresent();
Expand Down Expand Up @@ -924,6 +934,7 @@ void shouldNotUpdateRunning2RunningFailedOn1WorkerAsNonTeeTask() {
when(replicatesService.getReplicatesList(task.getChainTaskId())).thenReturn(Optional.of(replicatesList));
when(workerService.getAliveWorkers()).thenReturn(workersList);
doNothing().when(applicationEventPublisher).publishEvent(any());
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(task.getChainTaskId());
assertThat(task.getDateOfStatus(RUNNING)).isPresent();
Expand Down Expand Up @@ -959,6 +970,7 @@ void shouldNotUpdateRunning2RunningFailedOn2WorkersAsNonTeeTask() {
when(replicatesService.getReplicatesList(task.getChainTaskId())).thenReturn(Optional.of(replicatesList));
when(workerService.getAliveWorkers()).thenReturn(workersList);
doNothing().when(applicationEventPublisher).publishEvent(any());
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(task.getChainTaskId());
assertThat(task.getDateOfStatus(RUNNING)).isPresent();
Expand Down Expand Up @@ -994,6 +1006,7 @@ void shouldNotUpdateRunning2AllWorkersFailedSinceOneStillComputing() {
when(replicatesService.getReplicatesList(task.getChainTaskId())).thenReturn(Optional.of(replicatesList));
when(workerService.getAliveWorkers()).thenReturn(workersList);
doNothing().when(applicationEventPublisher).publishEvent(any());
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(task.getChainTaskId());
assertThat(task.getDateOfStatus(RUNNING_FAILED)).isEmpty();
Expand Down Expand Up @@ -1028,6 +1041,7 @@ void shouldNotUpdateRunning2AllWorkersFailedSinceOneHasReachedComputed() {
when(replicatesService.getReplicatesList(task.getChainTaskId())).thenReturn(Optional.of(replicatesList));
when(workerService.getAliveWorkers()).thenReturn(workersList);
doNothing().when(applicationEventPublisher).publishEvent(any());
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(task.getChainTaskId());
assertThat(task.getDateOfStatus(RUNNING_FAILED)).isEmpty();
Expand Down Expand Up @@ -1058,6 +1072,7 @@ void shouldNotUpdateRunning2AllWorkersFailedSinceOneStillHasToBeLaunched() {
when(replicatesService.getReplicatesList(task.getChainTaskId())).thenReturn(Optional.of(replicatesList));
when(workerService.getAliveWorkers()).thenReturn(workersList);
doNothing().when(applicationEventPublisher).publishEvent(any());
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(task.getChainTaskId());
assertThat(task.getDateOfStatus(RUNNING_FAILED)).isEmpty();
Expand Down Expand Up @@ -1709,6 +1724,7 @@ void shouldUpdateTaskRunning2Finalized2Completed() {
doNothing().when(applicationEventPublisher).publishEvent(any());

when(taskService.getTaskByChainTaskId(CHAIN_TASK_ID)).thenReturn(Optional.of(task));
mockTaskDescriptionFromTask(task);

taskUpdateManager.updateTask(CHAIN_TASK_ID);
assertThat(task.getCurrentStatus()).isEqualTo(COMPLETED);
Expand Down Expand Up @@ -1875,4 +1891,16 @@ void shouldTriggerUpdateTaskAsynchronously() {
taskUpdateRequestManager.publishRequest(CHAIN_TASK_ID);
verify(taskUpdateRequestManager).publishRequest(CHAIN_TASK_ID);
}

// region utils
private void mockTaskDescriptionFromTask(Task task) {
final TaskDescription taskDescription = TaskDescription.builder()
.chainTaskId(task.getChainTaskId())
.isTeeTask(task.isTeeTask())
.trust(BigInteger.valueOf(task.getTrust()))
.callback("")
.build();
when(iexecHubService.getTaskDescription(task.getChainTaskId())).thenReturn(taskDescription);
}
// endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -166,7 +167,7 @@ void shouldGetNextActionOnComputedWithTeeTaskShouldBePleaseContributeAndFinalize
assertThat(replicateWorkflow
.getNextAction(COMPUTED,
null,
TaskDescription.builder().isTeeTask(true).callback(BytesUtils.EMPTY_ADDRESS).build()))
TaskDescription.builder().isTeeTask(true).trust(BigInteger.ONE).callback(BytesUtils.EMPTY_ADDRESS).build()))
.isEqualTo(PLEASE_CONTRIBUTE_AND_FINALIZE);
}

Expand Down

0 comments on commit 0fe52d6

Please sign in to comment.