Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ version=9.2.0
iexecCommonsPocoVersion=5.4.0
iexecCommonVersion=9.2.0
iexecCommonsContainersVersion=2.0.0
iexecResultVersion=9.0.0
iexecSmsVersion=9.0.0
iexecCoreVersion=9.0.0
iexecResultVersion=9.1.0
iexecSmsVersion=9.3.0
iexecCoreVersion=9.2.1
nexusUser
nexusPassword
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ public Contribution getContribution(ComputedFile computedFile) {
String enclaveChallenge = workerpoolAuthorization.getEnclaveChallenge();
String enclaveSignature = computedFile.getEnclaveSignature();

if (iexecHubService.getTaskDescription(chainTaskId).requiresSgx()) {
final TaskDescription taskDescription = iexecHubService.getTaskDescription(chainTaskId);
if (taskDescription.requiresSgx() || taskDescription.requiresTdx()) {
if (!enclaveAuthorizationService.isVerifiedEnclaveSignature(
chainTaskId, resultHash, resultSeal, enclaveSignature, enclaveChallenge)) {
log.error("Cannot get contribution with invalid enclave " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ public boolean isAppDownloaded(String imageUri) {
* @see PreComputeService#runTeePreCompute(TaskDescription)
*/
public PreComputeResponse runPreCompute(final TaskDescription taskDescription) {
log.info("Running pre-compute [chainTaskId:{}, requiresSgx:{}]",
taskDescription.getChainTaskId(), taskDescription.requiresSgx());
log.info("Running pre-compute [chainTaskId:{}, requiresSgx:{}, requiresTdx:{}]",
taskDescription.getChainTaskId(), taskDescription.requiresSgx(), taskDescription.requiresTdx());

if (taskDescription.requiresSgx()) {
if (taskDescription.requiresSgx() || taskDescription.requiresTdx()) {
return preComputeService.runTeePreCompute(taskDescription);
}
return PreComputeResponse.builder().build();
Expand All @@ -178,8 +178,8 @@ public PreComputeResponse runPreCompute(final TaskDescription taskDescription) {
*/
public AppComputeResponse runCompute(final TaskDescription taskDescription) {
final String chainTaskId = taskDescription.getChainTaskId();
log.info("Running compute [chainTaskId:{}, requiresSgx:{}]",
chainTaskId, taskDescription.requiresSgx());
log.info("Running compute [chainTaskId:{}, requiresSgx:{}, requiresTdx:{}]",
chainTaskId, taskDescription.requiresSgx(), taskDescription.requiresTdx());

final AppComputeResponse appComputeResponse = appComputeService.runCompute(taskDescription);

Expand Down Expand Up @@ -211,11 +211,11 @@ private void writeLogs(String chainTaskId, String filename, String logs) {
*/
public PostComputeResponse runPostCompute(final TaskDescription taskDescription) {
final String chainTaskId = taskDescription.getChainTaskId();
log.info("Running post-compute [chainTaskId:{}, requiresSgx:{}]",
chainTaskId, taskDescription.requiresSgx());
log.info("Running post-compute [chainTaskId:{}, requiresSgx:{}, requiresTdx:{}]",
chainTaskId, taskDescription.requiresSgx(), taskDescription.requiresTdx());

final PostComputeResponse postComputeResponse;
if (!taskDescription.requiresSgx()) {
if (!taskDescription.requiresSgx() && !taskDescription.requiresTdx()) {
postComputeResponse = postComputeService.runStandardPostCompute(taskDescription);
} else {
postComputeResponse = postComputeService.runTeePostCompute(taskDescription);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public AppComputeResponse runCompute(final TaskDescription taskDescription) {

final List<String> env;
final HostConfig hostConfig;
if (taskDescription.requiresSgx()) {
if (taskDescription.requiresSgx() || taskDescription.requiresTdx()) {
final TeeService teeService = teeServicesManager.getTeeService(taskDescription.getTeeFramework());
env = teeService.buildComputeDockerEnv(taskDescription);
binds.addAll(teeService.getAdditionalBindings().stream().map(Bind::parse).toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.iexec.worker.tee.TeeServicesPropertiesService;
import com.iexec.worker.workflow.WorkflowError;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
Expand Down Expand Up @@ -181,6 +182,10 @@ public PostComputeResponse runTeePostCompute(final TaskDescription taskDescripti
.withBinds(binds)
.withDevices(teeService.getDevices())
.withNetworkMode(workerConfigService.getDockerNetworkName());
// TDX specific config to access worker DNS from post-compute
if (taskDescription.requiresTdx() && !StringUtils.isBlank(workerConfigService.getDockerExtraHosts())) {
hostConfig.withExtraHosts(workerConfigService.getDockerExtraHosts());
}
final DockerRunRequest request = DockerRunRequest.builder()
.hostConfig(hostConfig)
.chainTaskId(chainTaskId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.iexec.worker.tee.TeeServicesPropertiesService;
import com.iexec.worker.workflow.WorkflowError;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.Duration;
Expand Down Expand Up @@ -147,6 +148,10 @@ private Integer prepareTeeInputData(final TaskDescription taskDescription) throw
.withBinds(binds)
.withDevices(teeService.getDevices())
.withNetworkMode(workerConfigService.getDockerNetworkName());
// TDX specific config to access worker DNS from pre-compute
if (taskDescription.requiresTdx() && !StringUtils.isBlank(workerConfigService.getDockerExtraHosts())) {
hostConfig.withExtraHosts(workerConfigService.getDockerExtraHosts());
}
final DockerRunRequest request = DockerRunRequest.builder()
.hostConfig(hostConfig)
.chainTaskId(chainTaskId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class WorkerConfigurationService {
private Integer overrideAvailableCpuCount;

@Value("${worker.gpu-enabled}")
@Getter
private boolean isGpuEnabled;

@Value("${worker.gas-price-multiplier}")
Expand All @@ -67,6 +68,10 @@ public class WorkerConfigurationService {
@Getter
private String dockerNetworkName;

@Value("${worker.docker-extra-hosts:}")
@Getter
private String dockerExtraHosts;

@PostConstruct
private void postConstruct() {
if (overrideAvailableCpuCount != null && overrideAvailableCpuCount <= 0) {
Expand All @@ -75,10 +80,6 @@ private void postConstruct() {
}
}

public boolean isGpuEnabled() {
return isGpuEnabled;
}

public String getWorkerBaseDir() {
return workerBaseDir + File.separator + workerName;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/iexec/worker/result/ResultService.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public String uploadResultAndGetLink(final WorkerpoolAuthorization workerpoolAut
}

// Cloud computing - tee
if (task.requiresSgx()) {
if (task.requiresSgx() || task.requiresTdx()) {
log.info("Web2 storage, already uploaded (with tee) [chainTaskId:{}]", chainTaskId);
return getWeb2ResultLink(task);
}
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/iexec/worker/task/TaskManagerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ ReplicateActionResponse start(final TaskDescription taskDescription) {
}

// result encryption is not supported for standard tasks
if (!taskDescription.requiresSgx() && taskDescription.getDealParams().isIexecResultEncryption()) {
if (!taskDescription.requiresSgx() && !taskDescription.requiresTdx() && taskDescription.getDealParams().isIexecResultEncryption()) {
return getFailureResponseAndPrintErrors(
List.of(new WorkflowError(TASK_DESCRIPTION_INVALID)), context, chainTaskId);
}

if (taskDescription.requiresSgx()) {
if (taskDescription.requiresSgx() || taskDescription.requiresTdx()) {
// If any TEE prerequisite is not met,
// then we won't be able to run the task.
// So it should be aborted right now.
Expand Down Expand Up @@ -195,7 +195,7 @@ ReplicateActionResponse downloadData(final TaskDescription taskDescription) {
requireNonNull(taskDescription, "task description must not be null");
final String chainTaskId = taskDescription.getChainTaskId();
// Return early if TEE task
if (taskDescription.requiresSgx()) {
if (taskDescription.requiresSgx() || taskDescription.requiresTdx()) {
log.info("Dataset and input files will be downloaded by the pre-compute enclave [chainTaskId:{}]", chainTaskId);
return ReplicateActionResponse.success();
}
Expand Down Expand Up @@ -256,7 +256,7 @@ ReplicateActionResponse compute(final TaskDescription taskDescription) {
List.of(new WorkflowError(APP_NOT_FOUND_LOCALLY)), context, chainTaskId);
}

if (taskDescription.requiresSgx()) {
if (taskDescription.requiresSgx() || taskDescription.requiresTdx()) {
final TeeService teeService = teeServicesManager.getTeeService(taskDescription.getTeeFramework());
if (!teeService.prepareTeeForTask(chainTaskId)) {
return getFailureResponseAndPrintErrors(
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/iexec/worker/tee/TeeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public List<WorkflowError> areTeePrerequisitesMetForTask(final String chainTaskI
// If it can't be loaded, then we won't be able to run the task.
smsService.getSmsClient(chainTaskId);
} catch (SmsClientCreationException e) {
log.error("Couldn't get SmsClient [chainTaskId: {}]", chainTaskId, e);
log.error("Couldn't get SmsClient [chainTaskId:{}]", chainTaskId, e);
return List.of(new WorkflowError(ReplicateStatusCause.UNKNOWN_SMS));
}

Expand Down
8 changes: 6 additions & 2 deletions src/main/java/com/iexec/worker/tee/TeeServicesManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@
import com.iexec.commons.poco.tee.TeeFramework;
import com.iexec.worker.tee.gramine.TeeGramineService;
import com.iexec.worker.tee.scone.TeeSconeService;
import com.iexec.worker.tee.tdx.TeeTdxService;
import org.springframework.stereotype.Service;

@Service
public class TeeServicesManager {

private final TeeTdxService teeTdxService;
private final TeeSconeService teeSconeService;
private final TeeGramineService teeGramineService;

public TeeServicesManager(final TeeSconeService teeSconeService,
public TeeServicesManager(final TeeTdxService teeTdxService,
final TeeSconeService teeSconeService,
final TeeGramineService teeGramineService) {
this.teeTdxService = teeTdxService;
this.teeSconeService = teeSconeService;
this.teeGramineService = teeGramineService;
}
Expand All @@ -39,9 +43,9 @@ public TeeService getTeeService(final TeeFramework teeFramework) {
}

return switch (teeFramework) {
case TDX -> teeTdxService;
case SCONE -> teeSconeService;
case GRAMINE -> teeGramineService;
default -> throw new IllegalArgumentException("No TEE service defined for this TEE framework.");
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,26 @@ public TeeServicesProperties getTeeServicesProperties(final String chainTaskId)
return propertiesForTask.get(chainTaskId);
}

public List<WorkflowError> putTeeServicesPropertiesForTask(final String chainTaskId, final TeeServicesProperties properties) {
final List<WorkflowError> errors = new ArrayList<>();

final String preComputeImage = properties.getPreComputeProperties().getImage();
final String postComputeImage = properties.getPostComputeProperties().getImage();
errors.addAll(checkImageIsPresentOrDownload(preComputeImage, chainTaskId, "preComputeImage"));
errors.addAll(checkImageIsPresentOrDownload(postComputeImage, chainTaskId, "postComputeImage"));

propertiesForTask.put(chainTaskId, properties);
log.info("TEE services properties storage in cache [chainTaskId:{}, contains-key:{}]",
chainTaskId, propertiesForTask.containsKey(chainTaskId));

return List.copyOf(errors);
}

public List<WorkflowError> retrieveTeeServicesProperties(final String chainTaskId) {
final TaskDescription taskDescription = iexecHubService.getTaskDescription(chainTaskId);
if (taskDescription.requiresTdx()) {
return List.of();
}

// TODO errors could be renamed for APP enclave checks
final TeeEnclaveConfiguration teeEnclaveConfiguration = taskDescription.getAppEnclaveConfiguration();
Expand Down Expand Up @@ -109,19 +127,7 @@ public List<WorkflowError> retrieveTeeServicesProperties(final String chainTaskI
}
log.info("TEE services properties received [chainTaskId:{}]", chainTaskId);

final String preComputeImage = properties.getPreComputeProperties().getImage();
final String postComputeImage = properties.getPostComputeProperties().getImage();
final List<WorkflowError> errors = new ArrayList<>();

errors.addAll(checkImageIsPresentOrDownload(preComputeImage, chainTaskId, "preComputeImage"));
errors.addAll(checkImageIsPresentOrDownload(postComputeImage, chainTaskId, "postComputeImage"));

if (errors.isEmpty()) {
propertiesForTask.put(chainTaskId, properties);
log.info("TEE services properties storage in cache [chainTaskId:{}, contains-key:{}]",
chainTaskId, propertiesForTask.containsKey(chainTaskId));
}
return List.copyOf(errors);
return putTeeServicesPropertiesForTask(chainTaskId, properties);
}

private List<WorkflowError> checkImageIsPresentOrDownload(final String image, final String chainTaskId, final String imageType) {
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/iexec/worker/tee/tdx/TdxSession.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.iexec.worker.tee.tdx;

import java.util.List;
import java.util.Map;

public record TdxSession(String name, String version, List<Service> services) {
public record Service(String name, String image_name, String fingerprint, Map<String, String> environment) {
}
}
Loading