Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/gramine #515

Merged
merged 29 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0f36999
Single TEE tag
jeremyjams Jun 28, 2022
426c236
Removed old TEE tags
jeremyjams Jun 28, 2022
7472811
Merge branch 'develop' of github.com:iExecBlockchainComputing/iexec-c…
jeremyjams Jul 22, 2022
f3fa31e
Use gramine version
jeremyjams Jul 22, 2022
a916062
Run Gramine task on worker
Aug 12, 2022
c56b433
Remove static SMS configuration
Aug 12, 2022
fff5132
Get `SmsClient` on task start or abort
Aug 24, 2022
d92a873
Create `SmsService#isSmsClientReady`
Aug 24, 2022
2a083ed
Rename `SmsClientConfiguration` into `SmsClientProviderConfiguration`
Aug 25, 2022
22ca38d
Get SmsClient from ChainDeal for uninitialized tasks
Aug 25, 2022
564d3fe
Fix SmsService tests
Aug 25, 2022
aa7fcef
Merge pull request #519 from iExecBlockchainComputing/feature/read-gr…
mcornaton Aug 30, 2022
86f802f
Merge branch 'develop' into feature/gramine
mcornaton Aug 31, 2022
64cd0da
Update `SmsClientProvider` to avoid calling the chain too often
mcornaton Aug 31, 2022
56ea2ea
Simplify `SmslClient#getTeeServicesConfiguration` calls
mcornaton Sep 1, 2022
dd8cb6c
Purge maps storing task after completion or failure
mcornaton Sep 5, 2022
488a037
Check SMS TEE enclave configuration before initializing task
mcornaton Sep 5, 2022
cd6dab8
Merge branch 'feature/gramine-refactor-tee-configuration' into featur…
mcornaton Sep 7, 2022
5d7d297
Merge pull request #521 from iExecBlockchainComputing/feature/gramine…
mcornaton Sep 9, 2022
9d2d3c6
Merge branch 'feature/gramine' into feature/gramine-purge-maps
mcornaton Sep 9, 2022
45b5fed
Add `PurgeConfigurationTests`
mcornaton Sep 9, 2022
1a9d33b
Add documentation and log to `purgeService` related methods
mcornaton Sep 14, 2022
4e1ebb8
Move purge elements to `com.iexec.common.lifecycle.purge` package
mcornaton Sep 14, 2022
a029c7d
Update `ReplicateSupplyService` to implement `Purgeable`
mcornaton Sep 14, 2022
d1303ba
Introduce `CategoriesUtils`
mcornaton Sep 14, 2022
d3e5d4f
Move `CategoriesUtils` to package `com.iexec.common.chain`
mcornaton Sep 15, 2022
301ff7b
Merge pull request #522 from iExecBlockchainComputing/feature/gramine…
mcornaton Sep 16, 2022
82186dc
Update gradle.properties
jeremyjams Sep 19, 2022
a99765b
Update gradle.properties
jeremyjams Sep 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
version=7.1.0
iexecCommonVersion=6.0.0
iexecCommonVersion=6.0.1
iexecBlockchainAdapterVersion=7.1.1
iexecResultVersion=7.1.0
iexecSmsVersion=7.1.0
jeremyjams marked this conversation as resolved.
Show resolved Hide resolved
jeremyjams marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/iexec/core/configuration/PurgeConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.iexec.core.configuration;

import com.iexec.common.lifecycle.purge.PurgeService;
import com.iexec.common.lifecycle.purge.Purgeable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
@Slf4j
public class PurgeConfiguration {
/**
* Creates a {@link PurgeService} bean, with a list of all {@link Purgeable} beans as a parameter.
* <p>
* If no {@link Purgeable} bean is known, then an empty list is passed as a parameter.
* This is a special case of Spring IoC, please see
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-autowired-annotation">Spring documentation</a>.
* @param purgeableServices List of services that can be purged on a task completion
* @return An instance of {@link PurgeService} containing a list of all {@link Purgeable} beans.
*/
@Bean
PurgeService purgeService(List<Purgeable> purgeableServices) {
return new PurgeService(purgeableServices);
}
}
52 changes: 0 additions & 52 deletions src/main/java/com/iexec/core/configuration/SmsConfiguration.java

This file was deleted.

25 changes: 17 additions & 8 deletions src/main/java/com/iexec/core/replicate/ReplicateSupplyService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package com.iexec.core.replicate;

import com.iexec.common.chain.WorkerpoolAuthorization;
import com.iexec.common.lifecycle.purge.ExpiringTaskMapFactory;
import com.iexec.common.lifecycle.purge.Purgeable;
import com.iexec.common.notification.TaskNotification;
import com.iexec.common.notification.TaskNotificationExtra;
import com.iexec.common.notification.TaskNotificationType;
Expand All @@ -33,33 +35,27 @@
import com.iexec.core.task.update.TaskUpdateRequestManager;
import com.iexec.core.worker.Worker;
import com.iexec.core.worker.WorkerService;
import net.jodah.expiringmap.ExpiringMap;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static com.iexec.common.replicate.ReplicateStatus.*;
import static com.iexec.core.task.Task.LONGEST_TASK_TIMEOUT;


@Service
public class ReplicateSupplyService {
public class ReplicateSupplyService implements Purgeable {

private final ReplicatesService replicatesService;
private final SignatureService signatureService;
private final TaskService taskService;
private final TaskUpdateRequestManager taskUpdateRequestManager;
private final WorkerService workerService;
private final Web3jService web3jService;
final Map<String, Lock> taskAccessForNewReplicateLocks =
ExpiringMap.builder()
.expiration(LONGEST_TASK_TIMEOUT.getSeconds(), TimeUnit.SECONDS)
.build();
final Map<String, Lock> taskAccessForNewReplicateLocks = ExpiringTaskMapFactory.getExpiringTaskMap();

public ReplicateSupplyService(ReplicatesService replicatesService,
SignatureService signatureService,
Expand Down Expand Up @@ -532,4 +528,17 @@ private TaskAbortCause getTaskAbortCause(Task task) {
return TaskAbortCause.UNKNOWN;
}
}

// region purge locks
@Override
public boolean purgeTask(String chainTaskId) {
taskAccessForNewReplicateLocks.remove(chainTaskId);
return !taskAccessForNewReplicateLocks.containsKey(chainTaskId);
}

@Override
public void purgeAllTasksData() {
taskAccessForNewReplicateLocks.clear();
}
// endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.iexec.core.sms;

import com.iexec.sms.api.SmsClientProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SmsClientProviderConfiguration {

@Bean
SmsClientProvider smsClientProvider() {
return new SmsClientProvider();
}
}
74 changes: 70 additions & 4 deletions src/main/java/com/iexec/core/sms/SmsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,15 @@

package com.iexec.core.sms;

import com.iexec.common.chain.ChainDeal;
import com.iexec.common.chain.IexecHubAbstractService;
import com.iexec.common.task.TaskDescription;
import com.iexec.common.tee.TeeEnclaveProvider;
import com.iexec.common.tee.TeeUtils;
import com.iexec.common.utils.BytesUtils;
import com.iexec.sms.api.SmsClient;
import com.iexec.sms.api.SmsClientCreationException;
import com.iexec.sms.api.SmsClientProvider;
import feign.FeignException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.annotation.Recover;
Expand All @@ -30,10 +37,63 @@
@Slf4j
@Service
public class SmsService {
private final SmsClient smsClient;
private final SmsClientProvider smsClientProvider;
private final IexecHubAbstractService iexecHubService;

public SmsService(SmsClient smsClient) {
this.smsClient = smsClient;
public SmsService(SmsClientProvider smsClientProvider, IexecHubAbstractService iexecHubService) {
this.smsClientProvider = smsClientProvider;
this.iexecHubService = iexecHubService;
}

/**
* Checks the following conditions:
* <ul>
* <li>Given deal exists on-chain;</li>
* <li>The {@link SmsClient} can be created, based on the on-chain deal definition;</li>
* <li>The targeted SMS is configured to run with the task's TEE enclave provider.</li>
* </ul>
* <p>
* If any of these conditions is wrong, then the {@link SmsClient} is considered to be not-ready.
*
* @param chainDealId ID of the on-chain deal related to the task to execute.
* @param chainTaskId ID of the on-chain task.
* @return {@literal true} if previous conditions are met, {@literal false} otherwise.
*/
public boolean isSmsClientReady(String chainDealId, String chainTaskId) {
try {
final Optional<ChainDeal> chainDeal = iexecHubService.getChainDeal(chainDealId);
if (chainDeal.isEmpty()) {
log.error("No chain deal for given ID [chainDealId: {}]", chainDealId);
return false;
}
final SmsClient smsClient = smsClientProvider.getOrCreateSmsClientForUninitializedTask(chainDeal.get(), chainTaskId);
final TeeEnclaveProvider teeEnclaveProviderForDeal = TeeUtils.getTeeEnclaveProvider(chainDeal.get().getTag());
return checkSmsTeeEnclaveProvider(smsClient, teeEnclaveProviderForDeal, chainTaskId);
} catch (SmsClientCreationException e) {
log.error("SmsClient is not ready [chainTaskId: {}]", chainTaskId, e);
return false;
}
}

private boolean checkSmsTeeEnclaveProvider(SmsClient smsClient,
TeeEnclaveProvider teeEnclaveProviderForDeal,
String chainTaskId) {
final TeeEnclaveProvider smsTeeEnclaveProvider;
try {
smsTeeEnclaveProvider = smsClient.getTeeEnclaveProvider();
} catch (FeignException e) {
log.error("Can't retrieve SMS TEE enclave provider [chainTaskId:{}]",
chainTaskId, e);
return false;
}

if (smsTeeEnclaveProvider != teeEnclaveProviderForDeal) {
log.error("SMS is configured for another TEE enclave provider " +
"[chainTaskId:{}, teeEnclaveProviderForDeal:{}, smsTeeEnclaveProvider:{}]",
chainTaskId, teeEnclaveProviderForDeal, smsTeeEnclaveProvider);
return false;
}
return true;
}

public Optional<String> getEnclaveChallenge(String chainTaskId, boolean isTeeEnabled) {
Expand All @@ -44,8 +104,14 @@ public Optional<String> getEnclaveChallenge(String chainTaskId, boolean isTeeEna

@Retryable(value = FeignException.class)
Optional<String> generateEnclaveChallenge(String chainTaskId) {
final TaskDescription taskDescription = iexecHubService.getTaskDescription(chainTaskId);

// SMS client should already have been created once before.
// If it couldn't be created, then the task would have been aborted.
// So the following won't throw an exception.
final SmsClient smsClient = smsClientProvider.getOrCreateSmsClientForTask(taskDescription);

String teeChallengePublicKey = smsClient.generateTeeChallenge(chainTaskId);
final String teeChallengePublicKey = smsClient.generateTeeChallenge(chainTaskId);

if (teeChallengePublicKey == null || teeChallengePublicKey.isEmpty()) {
log.error("An error occurred while getting teeChallengePublicKey [chainTaskId:{}]", chainTaskId);
Expand Down
4 changes: 0 additions & 4 deletions src/main/java/com/iexec/core/task/Task.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ public class Task {

public static final String CURRENT_STATUS_FIELD_NAME = "currentStatus";
public static final String CONTRIBUTION_DEADLINE_FIELD_NAME = "contributionDeadline";
/**
* An XL task timeout happens after 100 hours.
*/
public static final Duration LONGEST_TASK_TIMEOUT = Duration.ofHours(100);

@Id
private String id;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/iexec/core/task/TaskRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ interface TaskRepository extends MongoRepository<Task, String> {
* </ul>
*
* @param statuses The task status should be one of this list.
* @param excludedTag The task tag should not be this tag
* @param excludedTags The task tag should not be one this tag list
* - use {@literal null} if no tag should be excluded.
* @param excludedChainTaskIds The chain task ID should not be one of this list.
* @param sort How to prioritize tasks.
* @return The first task matching with the criteria, according to the {@code sort} parameter.
*/
Optional<Task> findFirstByCurrentStatusInAndTagNotAndChainTaskIdNotIn(List<TaskStatus> statuses, String excludedTag, List<String> excludedChainTaskIds, Sort sort);
Optional<Task> findFirstByCurrentStatusInAndTagNotInAndChainTaskIdNotIn(List<TaskStatus> statuses, List<String> excludedTags, List<String> excludedChainTaskIds, Sort sort);

@Query("{ 'currentStatus': {$nin: ?0} }")
List<Task> findByCurrentStatusNotIn(List<TaskStatus> statuses);
Expand Down
19 changes: 8 additions & 11 deletions src/main/java/com/iexec/core/task/TaskService.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;

import static com.iexec.core.task.TaskStatus.*;
Expand Down Expand Up @@ -149,19 +146,19 @@ public List<Task> findByCurrentStatus(List<TaskStatus> statusList) {
public Optional<Task> getPrioritizedInitializedOrRunningTask(
boolean shouldExcludeTeeTasks,
List<String> excludedChainTaskIds) {
final String excludedTag = shouldExcludeTeeTasks
? TeeUtils.TEE_TAG
final List<String> excludedTags = shouldExcludeTeeTasks
? List.of(TeeUtils.TEE_SCONE_ONLY_TAG, TeeUtils.TEE_GRAMINE_ONLY_TAG)
: null;
return findPrioritizedTask(
Arrays.asList(INITIALIZED, RUNNING),
excludedTag,
excludedTags,
excludedChainTaskIds,
Sort.by(Sort.Order.desc(Task.CURRENT_STATUS_FIELD_NAME),
Sort.Order.asc(Task.CONTRIBUTION_DEADLINE_FIELD_NAME)));
}

/**
* Shortcut for {@link TaskRepository#findFirstByCurrentStatusInAndTagNotAndChainTaskIdNotIn}.
* Shortcut for {@link TaskRepository#findFirstByCurrentStatusInAndTagNotInAndChainTaskIdNotIn}.
* Retrieves the prioritized task matching with given criteria:
* <ul>
* <li>Task is in one of given {@code statuses};</li>
Expand All @@ -180,12 +177,12 @@ public Optional<Task> getPrioritizedInitializedOrRunningTask(
* @return The first task matching with the criteria, according to the {@code sort} parameter.
*/
private Optional<Task> findPrioritizedTask(List<TaskStatus> statuses,
String excludedTag,
List<String> excludedTags,
List<String> excludedChainTaskIds,
Sort sort) {
return taskRepository.findFirstByCurrentStatusInAndTagNotAndChainTaskIdNotIn(
return taskRepository.findFirstByCurrentStatusInAndTagNotInAndChainTaskIdNotIn(
statuses,
excludedTag,
excludedTags,
excludedChainTaskIds,
sort
);
Expand Down
Loading