├── .gitignore ├── CHANGELOG.md ├── COPYRIGHT ├── Dockerfile ├── Jenkinsfile ├── LICENSE ├── README.md ├── build.gradle ├── docker-compose.yml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── iexec-core-library ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── iexec │ │ └── core │ │ ├── api │ │ ├── SchedulerClient.java │ │ └── SchedulerClientBuilder.java │ │ ├── config │ │ ├── PublicConfiguration.java │ │ └── WorkerModel.java │ │ ├── notification │ │ ├── TaskAbortCause.java │ │ ├── TaskNotification.java │ │ ├── TaskNotificationExtra.java │ │ └── TaskNotificationType.java │ │ └── replicate │ │ └── ReplicateTaskSummary.java │ └── test │ └── java │ └── com │ └── iexec │ └── core │ ├── api │ └── SchedulerClientTest.java │ ├── config │ ├── PublicConfigurationTests.java │ └── WorkerModelTests.java │ └── notification │ ├── TaskAbortCauseTests.java │ └── TaskNotificationTests.java ├── iexec-task-api ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── iexec │ │ └── core │ │ ├── api │ │ ├── TaskApiClient.java │ │ └── TaskApiClientBuilder.java │ │ ├── logs │ │ └── TaskLogsModel.java │ │ ├── metric │ │ └── PlatformMetric.java │ │ ├── replicate │ │ ├── ReplicateModel.java │ │ └── ReplicateStatusUpdateModel.java │ │ └── task │ │ ├── TaskModel.java │ │ ├── TaskStatus.java │ │ └── TaskStatusChange.java │ └── test │ └── java │ └── com │ └── iexec │ └── core │ ├── api │ └── TaskApiClientTests.java │ ├── metric │ └── PlatformMetricTests.java │ ├── replicate │ └── ReplicateStatusUpdateTests.java │ └── task │ └── TaskStatusTests.java ├── lombok.config ├── settings.gradle └── src ├── main ├── java │ └── com │ │ └── iexec │ │ └── core │ │ ├── AppConfig.java │ │ ├── Application.java │ │ ├── chain │ │ ├── BlockchainConnectionHealthIndicator.java │ │ ├── ChainConfig.java │ │ ├── DealEvent.java │ │ ├── DealWatcherService.java │ │ ├── IexecHubService.java │ │ ├── SignatureService.java │ │ ├── WalletConfiguration.java │ │ ├── Web3jService.java │ │ ├── WebSocketBlockchainListener.java │ │ ├── adapter │ │ │ └── BlockchainAdapterClientConfig.java │ │ └── event │ │ │ ├── ChainConnectedEvent.java │ │ │ ├── ChainDisconnectedEvent.java │ │ │ └── LatestBlockEvent.java │ │ ├── config │ │ ├── AsyncConfig.java │ │ ├── OpenApiConfig.java │ │ ├── RetryConfig.java │ │ ├── SchedulingConfig.java │ │ ├── WebMvcConfig.java │ │ └── WebSocketConfig.java │ │ ├── configuration │ │ ├── ConfigServerClientConfig.java │ │ ├── Configuration.java │ │ ├── ConfigurationRepository.java │ │ ├── ConfigurationRepositoryMigration.java │ │ ├── ConfigurationService.java │ │ ├── CronConfiguration.java │ │ ├── PublicConfigurationService.java │ │ ├── PurgeConfiguration.java │ │ ├── ReplayConfiguration.java │ │ ├── ReplayConfigurationRepository.java │ │ ├── ResultRepositoryConfiguration.java │ │ └── WorkerConfiguration.java │ │ ├── contribution │ │ ├── ConsensusHelper.java │ │ ├── ContributionHelper.java │ │ ├── Prediction.java │ │ └── PredictionHelper.java │ │ ├── detector │ │ ├── Detector.java │ │ ├── WorkerLostDetector.java │ │ ├── replicate │ │ │ ├── ContributionAndFinalizationUnnotifiedDetector.java │ │ │ ├── ContributionUnnotifiedDetector.java │ │ │ ├── ReplicateResultUploadTimeoutDetector.java │ │ │ ├── RevealTimeoutDetector.java │ │ │ ├── RevealUnnotifiedDetector.java │ │ │ └── UnnotifiedAbstractDetector.java │ │ └── task │ │ │ ├── ConsensusReachedTaskDetector.java │ │ │ ├── ContributionTimeoutTaskDetector.java │ │ │ ├── FinalDeadlineTaskDetector.java │ │ │ ├── FinalizedTaskDetector.java │ │ │ ├── InitializedTaskDetector.java │ │ │ ├── ReopenedTaskDetector.java │ │ │ └── UnstartedTxDetector.java │ │ ├── exception │ │ └── MultipleOccurrencesOfFieldNotAllowed.java │ │ ├── logs │ │ ├── ComputeLogsCronService.java │ │ ├── TaskLogs.java │ │ ├── TaskLogsRepository.java │ │ └── TaskLogsService.java │ │ ├── metric │ │ ├── MetricController.java │ │ └── MetricService.java │ │ ├── pubsub │ │ └── NotificationService.java │ │ ├── registry │ │ └── PlatformRegistryConfiguration.java │ │ ├── replicate │ │ ├── NoReplicateStatusException.java │ │ ├── Replicate.java │ │ ├── ReplicateComputedEvent.java │ │ ├── ReplicateStatusUpdateError.java │ │ ├── ReplicateSupplyService.java │ │ ├── ReplicateUpdatedEvent.java │ │ ├── ReplicatesController.java │ │ ├── ReplicatesList.java │ │ ├── ReplicatesRepository.java │ │ ├── ReplicatesService.java │ │ └── UpdateReplicateStatusArgs.java │ │ ├── result │ │ └── ResultService.java │ │ ├── security │ │ ├── ChallengeService.java │ │ ├── EIP712ChallengeService.java │ │ ├── JwtTokenProvider.java │ │ └── WebSecurityConfig.java │ │ ├── sms │ │ ├── SmsClientProviderConfiguration.java │ │ └── SmsService.java │ │ ├── task │ │ ├── Task.java │ │ ├── TaskController.java │ │ ├── TaskRepository.java │ │ ├── TaskService.java │ │ ├── event │ │ │ ├── ConsensusReachedEvent.java │ │ │ ├── ContributionTimeoutEvent.java │ │ │ ├── PleaseUploadEvent.java │ │ │ ├── ResultUploadTimeoutEvent.java │ │ │ ├── TaskCompletedEvent.java │ │ │ ├── TaskCreatedEvent.java │ │ │ ├── TaskFailedEvent.java │ │ │ ├── TaskInitializedEvent.java │ │ │ ├── TaskRunningFailedEvent.java │ │ │ └── TaskStatusesCountUpdatedEvent.java │ │ ├── listener │ │ │ ├── ReplicateListeners.java │ │ │ └── TaskListeners.java │ │ └── update │ │ │ ├── TaskUpdate.java │ │ │ ├── TaskUpdateManager.java │ │ │ ├── TaskUpdatePriorityBlockingQueue.java │ │ │ └── TaskUpdateRequestManager.java │ │ ├── utils │ │ ├── TaskExecutorUtils.java │ │ └── TaskSchedulerUtils.java │ │ ├── version │ │ └── VersionController.java │ │ ├── worker │ │ ├── AliveWorkerMetrics.java │ │ ├── Worker.java │ │ ├── WorkerController.java │ │ ├── WorkerRepository.java │ │ ├── WorkerService.java │ │ └── WorkerUtils.java │ │ └── workflow │ │ ├── ReplicateWorkflow.java │ │ ├── TaskWorkflow.java │ │ └── Workflow.java └── resources │ ├── application.yml │ ├── banner.txt │ ├── logback-spring.xml │ ├── ssl-keystore-dev.p12 │ ├── wallet │ └── encrypted-wallet_scheduler.json │ └── workflow │ ├── replicate-actions.json │ └── replicate-transitions.json └── test ├── java └── com │ └── iexec │ └── core │ ├── ChainConfigTest.java │ ├── TestUtils.java │ ├── chain │ ├── BlockchainConnectionHealthIndicatorTests.java │ ├── DealWatcherServiceTests.java │ ├── IexecHubServiceTests.java │ ├── SignatureServiceTests.java │ ├── WalletConfigurationTest.java │ ├── WebSocketBlockchainListenerTests.java │ └── adapter │ │ └── BlockchainAdapterClientConfigTests.java │ ├── config │ └── OpenApiConfigTest.java │ ├── configuration │ ├── ConfigServerClientConfigTests.java │ ├── ConfigurationRepositoryMigrationTest.java │ ├── ConfigurationServiceTests.java │ ├── PublicConfigurationServiceTests.java │ ├── PurgeConfigurationTests.java │ └── ResultRepositoryConfigurationTest.java │ ├── contribution │ ├── ConsensusHelperTests.java │ ├── ContributionHelperTests.java │ └── PredictionHelperTests.java │ ├── detector │ ├── WorkerLostDetectorTests.java │ ├── replicate │ │ ├── ContributionAndFinalizationUnnotifiedDetectorTests.java │ │ ├── ContributionUnnotifiedDetectorTests.java │ │ ├── ReplicateResultUploadTimeoutDetectorTests.java │ │ ├── RevealTimeoutDetectorTests.java │ │ └── RevealUnnotifiedDetectorTests.java │ └── task │ │ ├── ConsensusReachedTaskDetectorTests.java │ │ ├── ContributionTimeoutTaskDetectorTests.java │ │ ├── FinalDeadlineTaskDetectorTests.java │ │ ├── FinalizedTaskDetectorTests.java │ │ └── UnstartedTxDetectorTests.java │ ├── logs │ ├── ReplicateLogsCronServiceTests.java │ └── TaskLogsServiceTests.java │ ├── metric │ ├── MetricControllerTests.java │ └── MetricServiceTests.java │ ├── pubsub │ └── NotificationServiceTests.java │ ├── registry │ └── PlatformRegistryConfigurationTests.java │ ├── replicate │ ├── ReplicateControllerTests.java │ ├── ReplicateListenersTests.java │ ├── ReplicateModelTests.java │ ├── ReplicateServiceTests.java │ ├── ReplicateSupplyServiceTests.java │ ├── ReplicateTests.java │ └── ReplicatesListTests.java │ ├── result │ └── ResultServiceTests.java │ ├── security │ ├── ChallengeServiceTests.java │ ├── EIP712ChallengeServiceTests.java │ └── JwtTokenProviderTests.java │ ├── sms │ └── SmsServiceTests.java │ ├── task │ ├── TaskControllerTests.java │ ├── TaskModelTests.java │ ├── TaskRepositoryTest.java │ ├── TaskServiceTests.java │ ├── TaskTests.java │ ├── listener │ │ └── TaskListenerTest.java │ └── update │ │ ├── TaskUpdateManagerTests.java │ │ └── TaskUpdateRequestManagerTests.java │ ├── version │ └── VersionControllerTests.java │ ├── worker │ ├── WorkerControllerTests.java │ ├── WorkerServiceTests.java │ └── WorkerUtilsTests.java │ └── workflow │ ├── DummyWorkflow.java │ ├── ReplicateWorkflowTests.java │ └── WorkflowTests.java └── resources ├── logback-spring.xml ├── mockito-extensions └── org.mockito.plugins.MockMaker └── wiremock └── mappings └── chain-config.json /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build 3 | !gradle/wrapper/gradle-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | /out/ 20 | 21 | ### NetBeans ### 22 | /nbproject/private/ 23 | /nbbuild/ 24 | /dist/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | 28 | /bin/ 29 | .vscode/ 30 | .env 31 | .dockerignore 32 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright 2020 IEXEC BLOCKCHAIN TECH 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:17.0.13_11-jre-focal 2 | 3 | ARG jar 4 | 5 | RUN test -n "$jar" 6 | 7 | RUN apt-get update \ 8 | && apt-get install -y --no-install-recommends curl \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | RUN groupadd --system appuser \ 12 | && useradd -g appuser -s /sbin/nologin -c "Docker image user" appuser 13 | 14 | WORKDIR /app 15 | COPY $jar iexec-core.jar 16 | RUN chown -R appuser:appuser /app 17 | 18 | USER appuser 19 | ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "iexec-core.jar"] 20 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | @Library('global-jenkins-library@2.7.4') _ 2 | buildJavaProject( 3 | shouldPublishJars: true, 4 | shouldPublishDockerImages: true) 5 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | chain: 4 | image: docker-regis.iex.ec/poco-chain:1.0.0-poco-v5.5.0-voucher-v1.0.0-nethermind 5 | expose: 6 | - "8545" 7 | 8 | config-server: 9 | image: wiremock/wiremock:3.3.1 10 | expose: 11 | - "8080" 12 | volumes: 13 | - "./src/test/resources/wiremock/mappings:/home/wiremock/mappings" 14 | 15 | mongo: 16 | image: library/mongo:7.0.15-jammy 17 | expose: 18 | - "27017" 19 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=9.0.0 2 | iexecCommonsPocoVersion=5.0.0 3 | iexecCommonVersion=9.0.0 4 | iexecBlockchainAdapterVersion=9.0.0 5 | iexecResultVersion=9.0.0 6 | iexecSmsVersion=9.0.0 7 | nexusUser 8 | nexusPassword 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iExecBlockchainComputing/iexec-core/b89ed60ef43d78362aca15929070d7d600f3e9bd/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /iexec-core-library/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-library' 3 | id 'io.freefair.lombok' 4 | id 'jacoco' 5 | id 'maven-publish' 6 | } 7 | 8 | dependencies { 9 | implementation platform("org.springframework.boot:spring-boot-dependencies:3.3.8") 10 | 11 | implementation "com.iexec.commons:iexec-commons-poco:$iexecCommonsPocoVersion" 12 | implementation "com.iexec.common:iexec-common:$iexecCommonVersion" 13 | } 14 | 15 | java { 16 | sourceCompatibility = JavaVersion.VERSION_17 17 | targetCompatibility = JavaVersion.VERSION_17 18 | withJavadocJar() 19 | withSourcesJar() 20 | } 21 | 22 | tasks.withType(JavaCompile).configureEach { 23 | options.compilerArgs.add('-parameters') 24 | } 25 | 26 | testing { 27 | suites { 28 | test { 29 | useJUnitJupiter() 30 | dependencies { 31 | implementation 'org.assertj:assertj-core' 32 | } 33 | } 34 | } 35 | } 36 | 37 | tasks.withType(Test).configureEach { 38 | finalizedBy tasks.jacocoTestReport 39 | } 40 | 41 | // sonarqube code coverage requires jacoco XML report 42 | jacocoTestReport { 43 | reports { 44 | xml.required = true 45 | } 46 | } 47 | 48 | publishing { 49 | publications { 50 | maven(MavenPublication) { 51 | from components.java 52 | } 53 | } 54 | repositories { 55 | maven { 56 | credentials { 57 | username nexusUser 58 | password nexusPassword 59 | } 60 | url = project.hasProperty("nexusUrl") ? project.nexusUrl : '' 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /iexec-core-library/src/main/java/com/iexec/core/api/SchedulerClientBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.api; 18 | 19 | import com.iexec.common.utils.FeignBuilder; 20 | import feign.Logger; 21 | 22 | public class SchedulerClientBuilder { 23 | 24 | private SchedulerClientBuilder() {} 25 | 26 | public static SchedulerClient getInstance(Logger.Level logLevel, String url) { 27 | return FeignBuilder.createBuilder(logLevel) 28 | .target(SchedulerClient.class, url); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /iexec-core-library/src/main/java/com/iexec/core/config/PublicConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 20 | import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; 21 | import lombok.Builder; 22 | import lombok.Value; 23 | 24 | /** 25 | * Configuration exposed by the scheduler and available publicly to all workers. 26 | */ 27 | @Value 28 | @Builder 29 | @JsonDeserialize(builder = PublicConfiguration.PublicConfigurationBuilder.class) 30 | public class PublicConfiguration { 31 | String workerPoolAddress; 32 | String schedulerPublicAddress; 33 | String configServerUrl; 34 | String resultRepositoryURL; 35 | long askForReplicatePeriod; 36 | String requiredWorkerVersion; 37 | 38 | @JsonPOJOBuilder(withPrefix = "") 39 | public static class PublicConfigurationBuilder { 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /iexec-core-library/src/main/java/com/iexec/core/config/WorkerModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 20 | import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; 21 | import lombok.Builder; 22 | import lombok.Value; 23 | 24 | @Value 25 | @Builder 26 | @JsonDeserialize(builder = WorkerModel.WorkerModelBuilder.class) 27 | public class WorkerModel { 28 | String name; 29 | String walletAddress; 30 | String os; 31 | String cpu; 32 | int cpuNb; 33 | int memorySize; 34 | boolean teeEnabled; 35 | boolean gpuEnabled; 36 | 37 | @JsonPOJOBuilder(withPrefix = "") 38 | public static class WorkerModelBuilder { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /iexec-core-library/src/main/java/com/iexec/core/notification/TaskAbortCause.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.notification; 18 | 19 | import com.iexec.common.replicate.ReplicateStatusCause; 20 | 21 | public enum TaskAbortCause { 22 | CONTRIBUTION_TIMEOUT, 23 | CONSENSUS_REACHED, 24 | UNKNOWN; 25 | 26 | public ReplicateStatusCause toReplicateStatusCause() { 27 | return switch (this) { 28 | case CONSENSUS_REACHED -> ReplicateStatusCause.CONSENSUS_REACHED; 29 | case CONTRIBUTION_TIMEOUT -> ReplicateStatusCause.CONTRIBUTION_TIMEOUT; 30 | default -> ReplicateStatusCause.UNKNOWN; 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /iexec-core-library/src/main/java/com/iexec/core/notification/TaskNotification.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.notification; 18 | 19 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 20 | import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; 21 | import lombok.Builder; 22 | import lombok.Value; 23 | 24 | import java.util.List; 25 | 26 | @Value 27 | @Builder 28 | @JsonDeserialize(builder = TaskNotification.TaskNotificationBuilder.class) 29 | public class TaskNotification { 30 | // Id of the task concerned by the notification. 31 | String chainTaskId; 32 | 33 | // List of workers targeted by the notification. 34 | List workersAddress; 35 | 36 | // Type of the notification. 37 | TaskNotificationType taskNotificationType; 38 | 39 | // Optional extra metadata provided with the notification 40 | TaskNotificationExtra taskNotificationExtra; 41 | 42 | /** 43 | * Gets the abort cause of this task. 44 | * 45 | * @return the cause from the notification details if defined, {@code TaskAbortCause.UNKNOWN otherwise} 46 | */ 47 | public TaskAbortCause getTaskAbortCause() { 48 | return taskNotificationExtra != null && taskNotificationExtra.getTaskAbortCause() != null 49 | ? taskNotificationExtra.getTaskAbortCause() 50 | : TaskAbortCause.UNKNOWN; 51 | } 52 | 53 | @JsonPOJOBuilder(withPrefix = "") 54 | public static class TaskNotificationBuilder { 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /iexec-core-library/src/main/java/com/iexec/core/notification/TaskNotificationExtra.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.notification; 18 | 19 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 20 | import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; 21 | import com.iexec.commons.poco.chain.WorkerpoolAuthorization; 22 | import lombok.Builder; 23 | import lombok.Value; 24 | 25 | @Value 26 | @Builder 27 | @JsonDeserialize(builder = TaskNotificationExtra.TaskNotificationExtraBuilder.class) 28 | public class TaskNotificationExtra { 29 | WorkerpoolAuthorization workerpoolAuthorization; 30 | String smsUrl; 31 | 32 | // block number from which this notification makes sense 33 | // (it is not used for all notification types) 34 | long blockNumber; 35 | 36 | // The reason behind an "Abort" notification. Used only for 37 | // Abort notifications. 38 | TaskAbortCause taskAbortCause; 39 | 40 | @JsonPOJOBuilder(withPrefix = "") 41 | public static class TaskNotificationExtraBuilder { 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /iexec-core-library/src/main/java/com/iexec/core/notification/TaskNotificationType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.notification; 18 | 19 | public enum TaskNotificationType { 20 | PLEASE_CONTINUE, 21 | PLEASE_WAIT, // subscribe & do nothing (wait) 22 | PLEASE_START, 23 | PLEASE_DOWNLOAD_APP, 24 | PLEASE_DOWNLOAD_DATA, 25 | PLEASE_COMPUTE, 26 | PLEASE_CONTRIBUTE, // subscribe & contribute if result found, else compute 27 | PLEASE_REVEAL, // subscribe & reveal 28 | PLEASE_UPLOAD, // subscribe & upload result 29 | PLEASE_CONTRIBUTE_AND_FINALIZE, // contribute & finalize on-chain 30 | PLEASE_COMPLETE, // complete + unsubscribe 31 | PLEASE_ABORT, // abort + unsubscribe 32 | } 33 | -------------------------------------------------------------------------------- /iexec-core-library/src/main/java/com/iexec/core/replicate/ReplicateTaskSummary.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | import com.iexec.commons.poco.chain.WorkerpoolAuthorization; 20 | import lombok.AllArgsConstructor; 21 | import lombok.Builder; 22 | import lombok.Data; 23 | import lombok.NoArgsConstructor; 24 | 25 | @Data 26 | @NoArgsConstructor 27 | @AllArgsConstructor 28 | @Builder 29 | public class ReplicateTaskSummary { 30 | 31 | private WorkerpoolAuthorization workerpoolAuthorization; 32 | private String smsUrl; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /iexec-core-library/src/test/java/com/iexec/core/api/SchedulerClientTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.api; 18 | 19 | import feign.Logger; 20 | import org.junit.jupiter.api.Assertions; 21 | import org.junit.jupiter.api.Test; 22 | 23 | class SchedulerClientTest { 24 | 25 | @Test 26 | void instantiationTest() { 27 | Assertions.assertNotNull(SchedulerClientBuilder.getInstance(Logger.Level.FULL, "localhost")); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /iexec-core-library/src/test/java/com/iexec/core/config/PublicConfigurationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import com.fasterxml.jackson.core.JsonProcessingException; 20 | import com.fasterxml.jackson.databind.ObjectMapper; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 24 | 25 | class PublicConfigurationTests { 26 | 27 | private static final ObjectMapper mapper = new ObjectMapper(); 28 | 29 | @Test 30 | void shouldSerializeAndDeserialize() throws JsonProcessingException { 31 | final PublicConfiguration config = PublicConfiguration.builder().build(); 32 | final String jsonString = mapper.writeValueAsString(config); 33 | assertThat(jsonString).isEqualTo("{\"workerPoolAddress\":null,\"schedulerPublicAddress\":null," + 34 | "\"configServerUrl\":null,\"resultRepositoryURL\":null," + 35 | "\"askForReplicatePeriod\":0,\"requiredWorkerVersion\":null}"); 36 | final PublicConfiguration parsedConfig = mapper.readValue(jsonString, PublicConfiguration.class); 37 | assertThat(parsedConfig).isEqualTo(config); 38 | } 39 | 40 | @Test 41 | void shouldDeserializeWhenConfigServerUrlIsMissing() throws JsonProcessingException { 42 | final PublicConfiguration config = PublicConfiguration.builder().build(); 43 | final String jsonString = "{\"workerPoolAddress\":null,\"schedulerPublicAddress\":null," + 44 | "\"resultRepositoryURL\":null," + 45 | "\"askForReplicatePeriod\":0,\"requiredWorkerVersion\":null}"; 46 | final PublicConfiguration parsedConfig = mapper.readValue(jsonString, PublicConfiguration.class); 47 | assertThat(parsedConfig).isEqualTo(config); 48 | } 49 | 50 | @Test 51 | void shouldDeserializeWhenConfigServerUrlIsPresent() throws JsonProcessingException { 52 | final PublicConfiguration config = PublicConfiguration.builder() 53 | .configServerUrl("http://localhost:8888").build(); 54 | final String jsonString = "{\"workerPoolAddress\":null,\"schedulerPublicAddress\":null," + 55 | "\"configServerUrl\":\"http://localhost:8888\",\"resultRepositoryURL\":null," + 56 | "\"askForReplicatePeriod\":0,\"requiredWorkerVersion\":null}"; 57 | final PublicConfiguration parsedConfig = mapper.readValue(jsonString, PublicConfiguration.class); 58 | assertThat(parsedConfig).isEqualTo(config); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /iexec-core-library/src/test/java/com/iexec/core/config/WorkerModelTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import com.fasterxml.jackson.core.JsonProcessingException; 20 | import com.fasterxml.jackson.databind.ObjectMapper; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 24 | 25 | class WorkerModelTests { 26 | 27 | private static final ObjectMapper mapper = new ObjectMapper(); 28 | 29 | @Test 30 | void shouldSerializeAndDeserialize() throws JsonProcessingException { 31 | WorkerModel model = WorkerModel.builder().build(); 32 | String jsonString = mapper.writeValueAsString(model); 33 | assertThat(jsonString).isEqualTo("{\"name\":null,\"walletAddress\":null,\"os\":null,\"cpu\":null," + 34 | "\"cpuNb\":0,\"memorySize\":0,\"teeEnabled\":false,\"gpuEnabled\":false}"); 35 | WorkerModel parsedModel = mapper.readValue(jsonString, WorkerModel.class); 36 | assertThat(parsedModel).isEqualTo(model); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /iexec-core-library/src/test/java/com/iexec/core/notification/TaskAbortCauseTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.notification; 18 | 19 | import com.iexec.common.replicate.ReplicateStatusCause; 20 | import org.junit.jupiter.api.Test; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | 24 | class TaskAbortCauseTests { 25 | @Test 26 | void shouldConvertToReplicateStatusCause() { 27 | assertThat(TaskAbortCause.CONSENSUS_REACHED.toReplicateStatusCause()) 28 | .isEqualTo(ReplicateStatusCause.CONSENSUS_REACHED); 29 | assertThat(TaskAbortCause.CONTRIBUTION_TIMEOUT.toReplicateStatusCause()) 30 | .isEqualTo(ReplicateStatusCause.CONTRIBUTION_TIMEOUT); 31 | assertThat(TaskAbortCause.UNKNOWN.toReplicateStatusCause()) 32 | .isEqualTo(ReplicateStatusCause.UNKNOWN); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /iexec-core-library/src/test/java/com/iexec/core/notification/TaskNotificationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.notification; 18 | 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.params.ParameterizedTest; 21 | import org.junit.jupiter.params.provider.EnumSource; 22 | 23 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 24 | 25 | class TaskNotificationTests { 26 | @ParameterizedTest 27 | @EnumSource(value = TaskNotificationType.class) 28 | void shouldBuildTaskNotification(TaskNotificationType notificationType) { 29 | final TaskNotification notification = TaskNotification.builder() 30 | .taskNotificationType(notificationType) 31 | .build(); 32 | assertThat(notification.getTaskNotificationType()).isEqualTo(notificationType); 33 | } 34 | 35 | @Test 36 | void shouldGetAbortNotificationCause() { 37 | TaskNotification notif1 = TaskNotification.builder() 38 | .chainTaskId("chainTaskId") 39 | .taskNotificationExtra(TaskNotificationExtra.builder() 40 | .taskAbortCause(TaskAbortCause.CONTRIBUTION_TIMEOUT) 41 | .build()) 42 | .build(); 43 | assertThat(notif1.getTaskAbortCause()).isEqualTo(TaskAbortCause.CONTRIBUTION_TIMEOUT); 44 | 45 | TaskNotification notif2 = TaskNotification.builder() 46 | .chainTaskId("chainTaskId") 47 | // Reason not specified 48 | .build(); 49 | assertThat(notif2.getTaskAbortCause()).isEqualTo(TaskAbortCause.UNKNOWN); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /iexec-task-api/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-library' 3 | id 'io.freefair.lombok' 4 | id 'jacoco' 5 | id 'maven-publish' 6 | } 7 | 8 | dependencies { 9 | implementation platform("org.springframework.boot:spring-boot-dependencies:3.3.8") 10 | 11 | implementation "com.iexec.commons:iexec-commons-poco:$iexecCommonsPocoVersion" 12 | implementation "com.iexec.common:iexec-common:$iexecCommonVersion" 13 | } 14 | 15 | java { 16 | sourceCompatibility = JavaVersion.VERSION_17 17 | targetCompatibility = JavaVersion.VERSION_17 18 | withJavadocJar() 19 | withSourcesJar() 20 | } 21 | 22 | tasks.withType(JavaCompile).configureEach { 23 | options.compilerArgs.add('-parameters') 24 | } 25 | 26 | testing { 27 | suites { 28 | test { 29 | useJUnitJupiter() 30 | } 31 | } 32 | } 33 | 34 | tasks.withType(Test).configureEach { 35 | finalizedBy tasks.jacocoTestReport 36 | } 37 | 38 | // sonarqube code coverage requires jacoco XML report 39 | jacocoTestReport { 40 | reports { 41 | xml.required = true 42 | } 43 | } 44 | 45 | publishing { 46 | publications { 47 | maven(MavenPublication) { 48 | from components.java 49 | } 50 | } 51 | repositories { 52 | maven { 53 | credentials { 54 | username nexusUser 55 | password nexusPassword 56 | } 57 | url = project.hasProperty("nexusUrl") ? project.nexusUrl : '' 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/api/TaskApiClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.api; 18 | 19 | import com.iexec.common.replicate.ComputeLogs; 20 | import com.iexec.commons.poco.eip712.entity.EIP712Challenge; 21 | import com.iexec.core.logs.TaskLogsModel; 22 | import com.iexec.core.metric.PlatformMetric; 23 | import com.iexec.core.task.TaskModel; 24 | import feign.Headers; 25 | import feign.Param; 26 | import feign.RequestLine; 27 | 28 | public interface TaskApiClient { 29 | @RequestLine("GET /metrics") 30 | PlatformMetric getMetrics(); 31 | 32 | // region /tasks 33 | @RequestLine("GET /tasks/{chainTaskId}") 34 | TaskModel getTask(@Param("chainTaskId") String chainTaskId); 35 | 36 | @RequestLine("GET /tasks/logs/challenge?address={address}") 37 | EIP712Challenge getTaskLogsChallenge(@Param("address") String address); 38 | 39 | @Headers("Authorization: {authorization}") 40 | @RequestLine("GET /tasks/{chainTaskId}/logs") 41 | TaskLogsModel getTaskLogs( 42 | @Param("chainTaskId") String chainTaskId, 43 | @Param("authorization") String authorization); 44 | 45 | @Headers("Authorization: {authorization}") 46 | @RequestLine("GET /tasks/{chainTaskId}/replicates/{walletAddress}/logs") 47 | ComputeLogs getComputeLogs( 48 | @Param("chainTaskId") String chainTaskId, 49 | @Param("walletAddress") String walletAddress, 50 | @Param("authorization") String authorization); 51 | // endregion 52 | } 53 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/api/TaskApiClientBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.api; 18 | 19 | import com.iexec.common.utils.FeignBuilder; 20 | import feign.Logger; 21 | import lombok.AccessLevel; 22 | import lombok.NoArgsConstructor; 23 | 24 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 25 | public class TaskApiClientBuilder { 26 | public static TaskApiClient getInstance(Logger.Level logLevel, String url) { 27 | return FeignBuilder.createBuilder(logLevel) 28 | .target(TaskApiClient.class, url); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/logs/TaskLogsModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.logs; 18 | 19 | import com.iexec.common.replicate.ComputeLogs; 20 | import lombok.AllArgsConstructor; 21 | import lombok.Builder; 22 | import lombok.Data; 23 | import lombok.NoArgsConstructor; 24 | 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | 28 | @Data 29 | @Builder 30 | @NoArgsConstructor 31 | @AllArgsConstructor 32 | public class TaskLogsModel { 33 | String chainTaskId; 34 | @Builder.Default 35 | List computeLogsList = new ArrayList<>(); 36 | } 37 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/metric/PlatformMetric.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.metric; 18 | 19 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 20 | import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; 21 | import com.iexec.core.task.TaskStatus; 22 | import lombok.Builder; 23 | import lombok.Value; 24 | 25 | import java.math.BigInteger; 26 | import java.util.LinkedHashMap; 27 | 28 | @Value 29 | @Builder 30 | @JsonDeserialize(builder = PlatformMetric.PlatformMetricBuilder.class) 31 | public class PlatformMetric { 32 | int aliveWorkers; 33 | int aliveComputingCpu; 34 | int aliveRegisteredCpu; 35 | int aliveComputingGpu; 36 | int aliveRegisteredGpu; 37 | LinkedHashMap currentTaskStatusesCount; 38 | LatestBlockMetric latestBlockMetric; 39 | long dealEventsCount; 40 | long dealsCount; 41 | long replayDealsCount; 42 | BigInteger latestBlockNumberWithDeal; 43 | 44 | // region backward compatibility 45 | /** 46 | * @deprecated Use aliveComputingCpu = aliveRegisteredCpu - aliveComputingCpu instead 47 | */ 48 | @Deprecated(forRemoval = true, since = "9.0.0") 49 | int aliveAvailableCpu; 50 | /** 51 | * @deprecated Use aliveRegisteredCpu instead 52 | */ 53 | @Deprecated(forRemoval = true, since = "9.0.0") 54 | int aliveTotalCpu; 55 | /** 56 | * @deprecated Use aliveComputingGpu = aliveRegisteredGpu - aliveComputingGpu instead 57 | */ 58 | @Deprecated(forRemoval = true, since = "9.0.0") 59 | int aliveAvailableGpu; 60 | /** 61 | * @deprecated Use aliveRegisteredGpu instead 62 | */ 63 | @Deprecated(forRemoval = true, since = "9.0.0") 64 | int aliveTotalGpu; 65 | // endregion 66 | 67 | @JsonPOJOBuilder(withPrefix = "") 68 | public static class PlatformMetricBuilder { 69 | } 70 | 71 | public record LatestBlockMetric(long blockNumber, String blockHash, long blockTimestamp) { 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/replicate/ReplicateModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import com.iexec.common.replicate.ReplicateStatus; 21 | import lombok.*; 22 | 23 | import java.util.List; 24 | 25 | @Getter 26 | @Setter 27 | @Builder 28 | @NoArgsConstructor 29 | @AllArgsConstructor 30 | @JsonInclude(JsonInclude.Include.NON_EMPTY) 31 | public class ReplicateModel { 32 | private String self; 33 | private String chainTaskId; 34 | private String walletAddress; 35 | private ReplicateStatus currentStatus; 36 | private List statusUpdateList; 37 | private String resultLink; 38 | private String chainCallbackData; 39 | private String contributionHash; 40 | private String appLogs; 41 | private Integer appExitCode; //null means unset 42 | private String teeSessionGenerationError; // null means unset 43 | } 44 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/replicate/ReplicateStatusUpdateModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import com.iexec.common.replicate.ReplicateStatus; 21 | import com.iexec.common.replicate.ReplicateStatusCause; 22 | import com.iexec.common.replicate.ReplicateStatusDetails; 23 | import com.iexec.common.replicate.ReplicateStatusUpdate; 24 | import lombok.AllArgsConstructor; 25 | import lombok.Builder; 26 | import lombok.Data; 27 | import lombok.NoArgsConstructor; 28 | 29 | import java.util.Date; 30 | 31 | @Data 32 | @Builder 33 | @NoArgsConstructor 34 | @AllArgsConstructor 35 | @JsonInclude(JsonInclude.Include.NON_NULL) 36 | public class ReplicateStatusUpdateModel { 37 | private ReplicateStatus status; 38 | private Date date; 39 | private ReplicateStatusCause cause; 40 | 41 | public static ReplicateStatusUpdateModel fromEntity(ReplicateStatusUpdate update) { 42 | if (update == null) { 43 | return ReplicateStatusUpdateModel.builder().build(); 44 | } 45 | 46 | final ReplicateStatusDetails details = update.getDetails(); 47 | return ReplicateStatusUpdateModel.builder() 48 | .status(update.getStatus()) 49 | .date(update.getDate()) 50 | .cause(details == null ? null : details.getCause()) 51 | .build(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/task/TaskModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task; 18 | 19 | import com.iexec.commons.poco.dapp.DappType; 20 | import com.iexec.core.replicate.ReplicateModel; 21 | import lombok.*; 22 | 23 | import java.util.Date; 24 | import java.util.List; 25 | 26 | @Getter 27 | @Setter 28 | @NoArgsConstructor 29 | @AllArgsConstructor 30 | @Builder 31 | public class TaskModel { 32 | private String chainTaskId; 33 | private List replicates; 34 | private long maxExecutionTime; 35 | private String tag; 36 | private DappType dappType; 37 | private String dappName; 38 | private String commandLine; 39 | private long initializationBlockNumber; 40 | private TaskStatus currentStatus; 41 | private int trust; 42 | private String uploadingWorkerWalletAddress; 43 | private String consensus; 44 | private Date contributionDeadline; 45 | private Date revealDeadline; 46 | private Date finalDeadline; 47 | private String resultLink; 48 | private String chainCallbackData; 49 | private List dateStatusList; 50 | } 51 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/task/TaskStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Arrays; 21 | import java.util.Collections; 22 | import java.util.List; 23 | 24 | public enum TaskStatus { 25 | RECEIVED, 26 | INITIALIZING, 27 | INITIALIZED, 28 | INITIALIZE_FAILED, 29 | RUNNING, 30 | RUNNING_FAILED, 31 | CONTRIBUTION_TIMEOUT, 32 | CONSENSUS_REACHED, 33 | REOPENING, 34 | REOPENED, 35 | REOPEN_FAILED, 36 | AT_LEAST_ONE_REVEALED, 37 | RESULT_UPLOADING, 38 | RESULT_UPLOADED, 39 | RESULT_UPLOAD_TIMEOUT, 40 | FINALIZING, 41 | FINALIZED, 42 | FINALIZE_FAILED, 43 | FINAL_DEADLINE_REACHED, 44 | COMPLETED, 45 | FAILED; 46 | 47 | public static List getWaitingContributionStatuses() { 48 | return Arrays.asList( 49 | //RECEIVED, 50 | //INITIALIZING, -> contribution stage is only after INITIALIZED 51 | INITIALIZED, 52 | RUNNING 53 | ); 54 | } 55 | 56 | public static List getWaitingRevealStatuses() { 57 | return Arrays.asList( 58 | CONSENSUS_REACHED, 59 | AT_LEAST_ONE_REVEALED, 60 | RESULT_UPLOADING, 61 | RESULT_UPLOADED 62 | ); 63 | } 64 | 65 | public static List getFinalStatuses() { 66 | return List.of(FAILED, COMPLETED); 67 | } 68 | 69 | public static List getStatusesWhereFinalDeadlineIsImpossible() { 70 | List excludedStatuses = new ArrayList<>(getFinalStatuses()); 71 | Collections.addAll(excludedStatuses, FINAL_DEADLINE_REACHED); 72 | return excludedStatuses; 73 | } 74 | 75 | public static boolean isInContributionPhase(TaskStatus status) { 76 | return getWaitingContributionStatuses().contains(status); 77 | } 78 | 79 | public static boolean isInRevealPhase(TaskStatus status) { 80 | return getWaitingRevealStatuses().contains(status); 81 | } 82 | 83 | public static boolean isInResultUploadPhase(TaskStatus status) { 84 | return RESULT_UPLOADING == status; 85 | } 86 | 87 | public static boolean isInCompletionPhase(TaskStatus status) { 88 | return Arrays.asList( 89 | FINALIZING, 90 | FINALIZED, 91 | COMPLETED 92 | ).contains(status); 93 | } 94 | 95 | public static boolean isFinalStatus(TaskStatus status) { 96 | return getFinalStatuses().contains(status); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /iexec-task-api/src/main/java/com/iexec/core/task/TaskStatusChange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import com.iexec.commons.poco.chain.ChainReceipt; 21 | import lombok.AllArgsConstructor; 22 | import lombok.Builder; 23 | import lombok.Data; 24 | import lombok.NoArgsConstructor; 25 | 26 | import java.util.Date; 27 | 28 | @Data 29 | @NoArgsConstructor 30 | @Builder 31 | @AllArgsConstructor 32 | @JsonInclude(JsonInclude.Include.NON_NULL) 33 | public class TaskStatusChange { 34 | @Builder.Default 35 | private Date date = new Date(); 36 | private TaskStatus status; 37 | @Builder.Default 38 | private ChainReceipt chainReceipt = null; 39 | } 40 | -------------------------------------------------------------------------------- /iexec-task-api/src/test/java/com/iexec/core/api/TaskApiClientTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.api; 18 | 19 | import feign.Logger; 20 | import org.junit.jupiter.api.Assertions; 21 | import org.junit.jupiter.api.Test; 22 | 23 | class TaskApiClientTests { 24 | @Test 25 | void instantiationTest() { 26 | Assertions.assertNotNull(TaskApiClientBuilder.getInstance(Logger.Level.FULL, "localhost")); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /iexec-task-api/src/test/java/com/iexec/core/replicate/ReplicateStatusUpdateTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | import com.iexec.common.replicate.ReplicateStatus; 20 | import com.iexec.common.replicate.ReplicateStatusUpdate; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import java.util.Date; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertEquals; 26 | 27 | class ReplicateStatusUpdateTests { 28 | @Test 29 | void shouldGenerateModelFromNull() { 30 | assertEquals(ReplicateStatusUpdateModel.builder().build(), ReplicateStatusUpdateModel.fromEntity(null)); 31 | } 32 | 33 | @Test 34 | void shouldGenerateModeFromNonNull() { 35 | final Date now = new Date(); 36 | final ReplicateStatusUpdate statusUpdate = ReplicateStatusUpdate.builder() 37 | .status(ReplicateStatus.COMPLETED) 38 | .date(now) 39 | .build(); 40 | final ReplicateStatusUpdateModel expectedStatusUpdateModel = ReplicateStatusUpdateModel 41 | .builder() 42 | .status(ReplicateStatus.COMPLETED) 43 | .date(now) 44 | .build(); 45 | assertEquals(expectedStatusUpdateModel, ReplicateStatusUpdateModel.fromEntity(statusUpdate)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lombok.config: -------------------------------------------------------------------------------- 1 | # This file is generated by the 'io.freefair.lombok' Gradle plugin 2 | config.stopBubbling = true 3 | lombok.addLombokGeneratedAnnotation = true 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'iexec-core' 2 | include 'iexec-core-library', 'iexec-task-api' 3 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/AppConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core; 18 | 19 | import com.iexec.core.config.*; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.context.annotation.Import; 22 | 23 | @Configuration 24 | @Import({ 25 | AsyncConfig.class, 26 | OpenApiConfig.class, 27 | RetryConfig.class, 28 | SchedulingConfig.class, 29 | WebMvcConfig.class, 30 | WebSocketConfig.class, 31 | }) 32 | public class AppConfig { 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core; 18 | 19 | import io.mongock.runner.springboot.EnableMongock; 20 | import org.springframework.boot.SpringApplication; 21 | import org.springframework.boot.autoconfigure.SpringBootApplication; 22 | import org.springframework.boot.context.properties.ConfigurationPropertiesScan; 23 | 24 | @EnableMongock 25 | @SpringBootApplication 26 | @ConfigurationPropertiesScan 27 | public class Application { 28 | 29 | public static void main(String[] args) { 30 | SpringApplication.run(Application.class, args); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/ChainConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain; 18 | 19 | import com.iexec.commons.poco.chain.validation.ValidNonZeroEthereumAddress; 20 | import jakarta.validation.constraints.NotEmpty; 21 | import jakarta.validation.constraints.NotNull; 22 | import jakarta.validation.constraints.Positive; 23 | import jakarta.validation.constraints.PositiveOrZero; 24 | import lombok.AllArgsConstructor; 25 | import lombok.Getter; 26 | import lombok.NoArgsConstructor; 27 | import org.hibernate.validator.constraints.URL; 28 | import org.hibernate.validator.constraints.time.DurationMax; 29 | import org.hibernate.validator.constraints.time.DurationMin; 30 | import org.springframework.beans.factory.annotation.Value; 31 | import org.springframework.stereotype.Component; 32 | import org.springframework.validation.annotation.Validated; 33 | 34 | import java.time.Duration; 35 | 36 | @Component 37 | @Getter 38 | @AllArgsConstructor 39 | @NoArgsConstructor 40 | @Validated 41 | public class ChainConfig { 42 | 43 | @Value("#{publicChainConfig.chainId}") 44 | @Positive(message = "Chain id must be greater than 0") 45 | @NotNull(message = "Chain id must not be null") 46 | private int chainId; 47 | 48 | @Value("#{publicChainConfig.sidechain}") 49 | private boolean sidechain; 50 | 51 | @Value("#{publicChainConfig.iexecHubContractAddress}") 52 | @ValidNonZeroEthereumAddress(message = "Hub address must be a valid non zero Ethereum address") 53 | private String hubAddress; 54 | 55 | @Value("#{publicChainConfig.blockTime}") 56 | @DurationMin(millis = 100, message = "Block time must be greater than 100ms") 57 | @DurationMax(seconds = 20, message = "Block time must be less than 20s") 58 | @NotNull(message = "Block time must not be null") 59 | private Duration blockTime; 60 | 61 | @Value("${chain.node-address}") 62 | @URL(message = "Node address must be a valid URL") 63 | @NotEmpty(message = "Node address must not be empty") 64 | private String nodeAddress; 65 | 66 | @Value("${chain.pool-address}") 67 | private String poolAddress; 68 | 69 | @Value("${chain.start-block-number}") 70 | @PositiveOrZero(message = "Start Block Number must be greater or equal to 0") 71 | private long startBlockNumber; 72 | 73 | @Value("${chain.gas-price-multiplier}") 74 | @Positive(message = "Gas price multiplier must be greater than 0") 75 | private float gasPriceMultiplier; 76 | 77 | @Value("${chain.gas-price-cap}") 78 | @PositiveOrZero(message = "Gas price cap must be greater or equal to 0") 79 | private long gasPriceCap; 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/DealEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain; 18 | 19 | import com.iexec.commons.poco.contract.generated.IexecHubContract; 20 | import com.iexec.commons.poco.utils.BytesUtils; 21 | import lombok.Getter; 22 | 23 | import java.math.BigInteger; 24 | 25 | @Getter 26 | public class DealEvent { 27 | 28 | private final String chainDealId; 29 | private final BigInteger blockNumber; 30 | 31 | public DealEvent(IexecHubContract.SchedulerNoticeEventResponse schedulerNoticeEventResponse) { 32 | this.chainDealId = BytesUtils.bytesToString(schedulerNoticeEventResponse.dealid); 33 | this.blockNumber = schedulerNoticeEventResponse.log.getBlockNumber() != null ? 34 | schedulerNoticeEventResponse.log.getBlockNumber() : BigInteger.ZERO; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/SignatureService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain; 18 | 19 | import com.iexec.commons.poco.chain.SignerService; 20 | import com.iexec.commons.poco.chain.WorkerpoolAuthorization; 21 | import com.iexec.commons.poco.security.Signature; 22 | import com.iexec.commons.poco.utils.HashUtils; 23 | import org.springframework.stereotype.Service; 24 | 25 | @Service 26 | public class SignatureService { 27 | 28 | private final SignerService signerService; 29 | 30 | public SignatureService(SignerService signerService) { 31 | this.signerService = signerService; 32 | } 33 | 34 | public String getAddress() { 35 | return signerService.getAddress(); 36 | } 37 | 38 | public Signature sign(String hash) { 39 | return signerService.signMessageHash(hash); 40 | } 41 | 42 | public WorkerpoolAuthorization createAuthorization(String workerWallet, String chainTaskId, String enclaveChallenge) { 43 | final String hash = HashUtils.concatenateAndHash(workerWallet, chainTaskId, enclaveChallenge); 44 | return WorkerpoolAuthorization.builder() 45 | .workerWallet(workerWallet) 46 | .chainTaskId(chainTaskId) 47 | .enclaveChallenge(enclaveChallenge) 48 | .signature(sign(hash)) 49 | .build(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/WalletConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain; 18 | 19 | import com.iexec.common.config.PublicChainConfig; 20 | import com.iexec.commons.poco.chain.SignerService; 21 | import lombok.Value; 22 | import org.springframework.boot.context.properties.ConfigurationProperties; 23 | import org.springframework.context.annotation.Bean; 24 | 25 | @Value 26 | @ConfigurationProperties(prefix = "wallet") 27 | public class WalletConfiguration { 28 | String encryptedFilePath; 29 | String password; 30 | 31 | @Bean 32 | SignerService signerService(Web3jService web3jService, PublicChainConfig publicChainConfig) throws Exception { 33 | return new SignerService(web3jService.getWeb3j(), publicChainConfig.getChainId(), password, encryptedFilePath); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/Web3jService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain; 18 | 19 | import com.iexec.commons.poco.chain.Web3jAbstractService; 20 | import com.iexec.core.chain.event.LatestBlockEvent; 21 | import org.springframework.context.event.EventListener; 22 | import org.springframework.stereotype.Service; 23 | 24 | @Service 25 | public class Web3jService extends Web3jAbstractService { 26 | 27 | private long latestBlockNumber; 28 | 29 | public Web3jService(ChainConfig chainConfig) { 30 | super( 31 | chainConfig.getChainId(), 32 | chainConfig.getNodeAddress(), 33 | chainConfig.getBlockTime(), 34 | chainConfig.getGasPriceMultiplier(), 35 | chainConfig.getGasPriceCap(), 36 | chainConfig.isSidechain() 37 | ); 38 | } 39 | 40 | @EventListener 41 | private void onLatestBlockEvent(final LatestBlockEvent event) { 42 | this.latestBlockNumber = event.getBlockNumber(); 43 | } 44 | 45 | @Override 46 | public long getLatestBlockNumber() { 47 | return latestBlockNumber; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/adapter/BlockchainAdapterClientConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain.adapter; 18 | 19 | import com.iexec.blockchain.api.BlockchainAdapterApiClient; 20 | import com.iexec.blockchain.api.BlockchainAdapterApiClientBuilder; 21 | import com.iexec.blockchain.api.BlockchainAdapterService; 22 | import feign.Logger; 23 | import jakarta.validation.constraints.NotEmpty; 24 | import lombok.Value; 25 | import org.hibernate.validator.constraints.URL; 26 | import org.springframework.boot.context.properties.ConfigurationProperties; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.validation.annotation.Validated; 29 | 30 | import java.time.Duration; 31 | 32 | @Value 33 | @Validated 34 | @ConfigurationProperties(prefix = "blockchain-adapter") 35 | public class BlockchainAdapterClientConfig { 36 | 37 | // TODO add configuration parameters for next major version 38 | public static final int WATCH_PERIOD_SECONDS = 2; 39 | public static final int MAX_ATTEMPTS = 25; 40 | 41 | @URL(message = "URL must be a valid URL") 42 | @NotEmpty(message = "URL must not be empty") 43 | String url; 44 | 45 | BlockchainAdapterAuth auth; 46 | 47 | @Bean 48 | public BlockchainAdapterApiClient blockchainAdapterClient() { 49 | return BlockchainAdapterApiClientBuilder.getInstanceWithBasicAuth( 50 | Logger.Level.NONE, url, auth.username(), auth.password()); 51 | } 52 | 53 | @Bean 54 | public BlockchainAdapterService blockchainAdapterService(BlockchainAdapterApiClient blockchainAdapterClient) { 55 | return new BlockchainAdapterService(blockchainAdapterClient, Duration.ofSeconds(WATCH_PERIOD_SECONDS), MAX_ATTEMPTS); 56 | } 57 | 58 | record BlockchainAdapterAuth(String username, String password 59 | ) { 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/event/ChainConnectedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain.event; 18 | 19 | import org.springframework.context.ApplicationEvent; 20 | 21 | public class ChainConnectedEvent extends ApplicationEvent { 22 | public ChainConnectedEvent(Object source) { 23 | super(source); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/event/ChainDisconnectedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain.event; 18 | 19 | import org.springframework.context.ApplicationEvent; 20 | 21 | public class ChainDisconnectedEvent extends ApplicationEvent { 22 | public ChainDisconnectedEvent(Object source) { 23 | super(source); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/chain/event/LatestBlockEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain.event; 18 | 19 | import lombok.EqualsAndHashCode; 20 | import lombok.Value; 21 | import org.springframework.context.ApplicationEvent; 22 | 23 | @Value 24 | @EqualsAndHashCode(callSuper = true) 25 | public class LatestBlockEvent extends ApplicationEvent { 26 | long blockNumber; 27 | String blockHash; 28 | long blockTimestamp; 29 | 30 | public LatestBlockEvent(final Object source, final long blockNumber, final String blockHash, final long blockTimestamp) { 31 | super(source); 32 | this.blockNumber = blockNumber; 33 | this.blockHash = blockHash; 34 | this.blockTimestamp = blockTimestamp; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/config/AsyncConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import java.lang.reflect.Method; 20 | import java.util.concurrent.Executor; 21 | 22 | import com.iexec.core.utils.TaskExecutorUtils; 23 | 24 | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 25 | import org.springframework.context.annotation.Configuration; 26 | import org.springframework.scheduling.annotation.AsyncConfigurer; 27 | import org.springframework.scheduling.annotation.EnableAsync; 28 | 29 | import lombok.extern.slf4j.Slf4j; 30 | 31 | @Configuration 32 | @EnableAsync 33 | @Slf4j 34 | public class AsyncConfig implements AsyncConfigurer { 35 | 36 | /** 37 | * This executor is used for Async tasks. 38 | * 39 | * @return 40 | */ 41 | @Override 42 | public Executor getAsyncExecutor() { 43 | return TaskExecutorUtils.newThreadPoolTaskExecutor("Async-"); 44 | } 45 | 46 | /** 47 | * Handle uncaught exceptions raised by Async tasks. 48 | */ 49 | @Override 50 | public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 51 | return new Handler(); 52 | } 53 | 54 | private static class Handler implements AsyncUncaughtExceptionHandler { 55 | 56 | @Override 57 | public void handleUncaughtException( 58 | Throwable ex, 59 | Method method, 60 | Object... params 61 | ) { 62 | log.error("Exception in async task [method:{}, params:{}]", 63 | method, params, ex); 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/config/OpenApiConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import io.swagger.v3.oas.models.OpenAPI; 20 | import io.swagger.v3.oas.models.info.Info; 21 | import org.springframework.boot.info.BuildProperties; 22 | import org.springframework.context.annotation.Bean; 23 | import org.springframework.context.annotation.Configuration; 24 | 25 | @Configuration 26 | public class OpenApiConfig { 27 | 28 | public static final String TITLE = "iExec Core Scheduler"; 29 | private final BuildProperties buildProperties; 30 | 31 | public OpenApiConfig(BuildProperties buildProperties) { 32 | this.buildProperties = buildProperties; 33 | } 34 | 35 | /* 36 | * Swagger URI: /swagger-ui/index.html 37 | */ 38 | @Bean 39 | public OpenAPI api() { 40 | return new OpenAPI().info( 41 | new Info() 42 | .title(TITLE) 43 | .version(buildProperties.getVersion()) 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/config/RetryConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.retry.annotation.EnableRetry; 21 | 22 | @Configuration 23 | @EnableRetry 24 | public class RetryConfig { 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/config/SchedulingConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import com.iexec.core.utils.TaskSchedulerUtils; 20 | 21 | import org.springframework.context.annotation.Configuration; 22 | import org.springframework.scheduling.annotation.EnableScheduling; 23 | import org.springframework.scheduling.annotation.SchedulingConfigurer; 24 | import org.springframework.scheduling.config.ScheduledTaskRegistrar; 25 | 26 | @Configuration 27 | @EnableScheduling 28 | public class SchedulingConfig implements SchedulingConfigurer { 29 | 30 | @Override 31 | public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 32 | taskRegistrar.setTaskScheduler( 33 | TaskSchedulerUtils.newThreadPoolTaskScheduler("Scheduled-") 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/config/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 21 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 22 | 23 | @Configuration 24 | public class WebMvcConfig implements WebMvcConfigurer { 25 | 26 | @Override 27 | public void addCorsMappings(CorsRegistry registry) { 28 | registry.addMapping("/**"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/config/WebSocketConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.config; 18 | 19 | import com.iexec.core.utils.TaskSchedulerUtils; 20 | 21 | import org.springframework.context.annotation.Configuration; 22 | import org.springframework.messaging.simp.config.MessageBrokerRegistry; 23 | import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; 24 | import org.springframework.web.socket.config.annotation.StompEndpointRegistry; 25 | import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; 26 | 27 | @Configuration 28 | @EnableWebSocketMessageBroker 29 | public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { 30 | 31 | @Override 32 | public void configureMessageBroker(MessageBrokerRegistry config) { 33 | config.enableSimpleBroker("/topic"); 34 | } 35 | 36 | @Override 37 | public void registerStompEndpoints(StompEndpointRegistry registry) { 38 | registry.addEndpoint("/connect").withSockJS() 39 | .setWebSocketEnabled(false) 40 | .setHeartbeatTime(5000) 41 | .setTaskScheduler(TaskSchedulerUtils 42 | .newThreadPoolTaskScheduler("STOMP-")); 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/ConfigServerClientConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import com.iexec.common.config.ConfigServerClient; 20 | import com.iexec.common.config.ConfigServerClientBuilder; 21 | import com.iexec.common.config.PublicChainConfig; 22 | import feign.Logger; 23 | import jakarta.validation.constraints.NotEmpty; 24 | import lombok.Value; 25 | import org.hibernate.validator.constraints.URL; 26 | import org.springframework.boot.context.properties.ConfigurationProperties; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.validation.annotation.Validated; 29 | 30 | @Value 31 | @Validated 32 | @ConfigurationProperties(prefix = "config-server") 33 | public class ConfigServerClientConfig { 34 | 35 | @URL(message = "URL must be a valid URL") 36 | @NotEmpty(message = "URL must not be empty") 37 | String url; 38 | 39 | @Bean 40 | public ConfigServerClient configServerClient() { 41 | return ConfigServerClientBuilder.getInstance( 42 | Logger.Level.NONE, url); 43 | } 44 | 45 | @Bean 46 | public PublicChainConfig publicChainConfig(ConfigServerClient apiClient) { 47 | return apiClient.getPublicChainConfig(); 48 | } 49 | 50 | @Bean 51 | public int getChainId(PublicChainConfig publicChainConfig) { 52 | return publicChainConfig.getChainId(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/Configuration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.NoArgsConstructor; 23 | import org.springframework.data.annotation.Id; 24 | import org.springframework.data.annotation.Version; 25 | 26 | import java.math.BigInteger; 27 | import java.time.Instant; 28 | 29 | @Data 30 | @AllArgsConstructor 31 | @NoArgsConstructor 32 | @Builder 33 | class Configuration { 34 | 35 | @Id 36 | private String id; 37 | 38 | @Version 39 | private Long version; 40 | 41 | private BigInteger lastSeenBlockWithDeal; 42 | private Instant lastUpdate; 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/ConfigurationRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import org.springframework.data.mongodb.repository.MongoRepository; 20 | 21 | interface ConfigurationRepository extends MongoRepository { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/CronConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.configuration; 2 | 3 | import lombok.Getter; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component 8 | @Getter 9 | public class CronConfiguration { 10 | 11 | @Value("${cron.deal.replay}") 12 | private int dealReplay; 13 | 14 | @Value("${cron.detector.worker-lost}") 15 | private int workerLost; 16 | 17 | @Value("${cron.detector.chain.unstarted-tx}") 18 | private int unstartedTx; 19 | 20 | @Value("${cron.detector.chain.initialize}") 21 | private int initialize; 22 | 23 | @Value("${cron.detector.chain.contribute}") 24 | private int contribute; 25 | 26 | @Value("${cron.detector.chain.consensus-reached}") 27 | private int consensusReached; 28 | 29 | @Value("${cron.detector.chain.reveal}") 30 | private int reveal; 31 | 32 | @Value("${cron.detector.chain.contribute-and-finalize}") 33 | private int contributeAndFinalize; 34 | 35 | @Value("${cron.detector.chain.finalize}") 36 | private int finalize; 37 | 38 | @Value("${cron.detector.chain.final-deadline}") 39 | private int finalDeadline; 40 | 41 | @Value("${cron.detector.timeout.contribute}") 42 | private int contributeTimeout; 43 | 44 | @Value("${cron.detector.timeout.reveal}") 45 | private int revealTimeout; 46 | 47 | @Value("${cron.detector.timeout.result-upload}") 48 | private int resultUploadTimeout; 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/PurgeConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.configuration; 2 | 3 | import com.iexec.common.lifecycle.purge.PurgeService; 4 | import com.iexec.common.lifecycle.purge.Purgeable; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | import java.util.List; 9 | 10 | @Configuration 11 | public class PurgeConfiguration { 12 | /** 13 | * Creates a {@link PurgeService} bean, with a list of all {@link Purgeable} beans as a parameter. 14 | *

15 | * If no {@link Purgeable} bean is known, then an empty list is passed as a parameter. 16 | * This is a special case of Spring IoC, please see 17 | * Spring documentation. 18 | * @param purgeableServices List of services that can be purged on a task completion 19 | * @return An instance of {@link PurgeService} containing a list of all {@link Purgeable} beans. 20 | */ 21 | @Bean 22 | PurgeService purgeService(List purgeableServices) { 23 | return new PurgeService(purgeableServices); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/ReplayConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.NoArgsConstructor; 23 | import org.springframework.data.annotation.Id; 24 | import org.springframework.data.annotation.Version; 25 | 26 | import java.math.BigInteger; 27 | import java.time.Instant; 28 | 29 | @Data 30 | @AllArgsConstructor 31 | @NoArgsConstructor 32 | @Builder 33 | class ReplayConfiguration { 34 | 35 | @Id 36 | private String id; 37 | 38 | @Version 39 | private Long version; 40 | 41 | private BigInteger fromBlockNumber; 42 | private Instant lastUpdate; 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/ReplayConfigurationRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import org.springframework.data.mongodb.repository.MongoRepository; 20 | 21 | interface ReplayConfigurationRepository extends MongoRepository { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/ResultRepositoryConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import com.iexec.resultproxy.api.ResultProxyClient; 20 | import com.iexec.resultproxy.api.ResultProxyClientBuilder; 21 | import feign.Logger; 22 | import jakarta.validation.constraints.NotEmpty; 23 | import lombok.Value; 24 | import lombok.extern.slf4j.Slf4j; 25 | import org.apache.commons.lang3.StringUtils; 26 | import org.hibernate.validator.constraints.URL; 27 | import org.springframework.boot.context.properties.ConfigurationProperties; 28 | import org.springframework.validation.annotation.Validated; 29 | 30 | @Value 31 | @Validated 32 | @ConfigurationProperties(prefix = "result-repository") 33 | @Slf4j 34 | public class ResultRepositoryConfiguration { 35 | @URL(message = "URL must be a valid URL") 36 | @NotEmpty(message = "URL must not be empty") 37 | String url; 38 | 39 | public ResultProxyClient createResultProxyClientFromURL(final String url) { 40 | final boolean useDefaultUrl = StringUtils.isBlank(url); 41 | final String resultProxyClientURL = useDefaultUrl ? getUrl() : url; 42 | log.debug("result-proxy URL [url:{}, default-url:{}]", resultProxyClientURL, useDefaultUrl); 43 | return ResultProxyClientBuilder.getInstance(Logger.Level.NONE, resultProxyClientURL); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/configuration/WorkerConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import lombok.Value; 20 | import org.springframework.boot.context.properties.ConfigurationProperties; 21 | 22 | import java.util.List; 23 | 24 | @Value 25 | @ConfigurationProperties(prefix = "workers") 26 | public class WorkerConfiguration { 27 | long askForReplicatePeriod; 28 | String requiredWorkerVersion; 29 | List whitelist; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/contribution/ConsensusHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.contribution; 18 | 19 | import com.iexec.core.replicate.Replicate; 20 | import lombok.extern.slf4j.Slf4j; 21 | 22 | import java.util.List; 23 | 24 | @Slf4j 25 | public class ConsensusHelper { 26 | 27 | private ConsensusHelper() { 28 | } 29 | 30 | /* 31 | * 32 | * Estimating pending workers are going to contribute to the best prediction 33 | * 34 | * Return true means a consensus is not possible now, a new worker is welcome to add more weight 35 | * Return false means a consensus is possible now, no need to add new workers 36 | * 37 | */ 38 | public static boolean doesTaskNeedMoreContributionsForConsensus( 39 | String chainTaskId, 40 | List replicates, 41 | int trust, 42 | long maxExecutionTime) { 43 | trust = Math.max(trust, 1);//ensure trust equals 1 44 | 45 | int bestPredictionWeight = PredictionHelper.getBestPredictionWeight(replicates, maxExecutionTime); 46 | int worstPredictionsWeight = PredictionHelper.getWorstPredictionsWeight(replicates); 47 | 48 | int allPredictionsWeight = worstPredictionsWeight + bestPredictionWeight; 49 | 50 | boolean needsMoreContributions = !isConsensusPossibleNow(trust, bestPredictionWeight, allPredictionsWeight); 51 | 52 | if (needsMoreContributions){ 53 | log.info("More contributions needed [chainTaskId:{}, trust:{}, bestPredictionWeight:{}, " + 54 | "allPredictionsWeight:{}]", chainTaskId, trust, bestPredictionWeight, allPredictionsWeight); 55 | } 56 | 57 | return needsMoreContributions; 58 | } 59 | 60 | private static boolean isConsensusPossibleNow(int trust, int pendingAndContributedBestPredictionWeight, int allPredictionsWeight) { 61 | return pendingAndContributedBestPredictionWeight * trust > (1 + allPredictionsWeight) * (trust - 1); 62 | } 63 | } -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/contribution/Prediction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.contribution; 18 | 19 | import lombok.Builder; 20 | import lombok.Data; 21 | import lombok.Getter; 22 | import lombok.Setter; 23 | 24 | @Data 25 | @Getter 26 | @Setter 27 | @Builder 28 | public class Prediction { 29 | private String contribution; 30 | private int weight; 31 | } -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/Detector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector; 18 | 19 | public interface Detector { 20 | 21 | void detect(); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/replicate/ContributionAndFinalizationUnnotifiedDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.replicate; 18 | 19 | import com.iexec.common.replicate.ReplicateStatus; 20 | import com.iexec.commons.poco.chain.ChainContributionStatus; 21 | import com.iexec.core.chain.IexecHubService; 22 | import com.iexec.core.configuration.CronConfiguration; 23 | import com.iexec.core.replicate.Replicate; 24 | import com.iexec.core.replicate.ReplicatesService; 25 | import com.iexec.core.task.TaskService; 26 | import com.iexec.core.task.TaskStatus; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.springframework.scheduling.annotation.Scheduled; 29 | import org.springframework.stereotype.Service; 30 | 31 | @Slf4j 32 | @Service 33 | public class ContributionAndFinalizationUnnotifiedDetector extends UnnotifiedAbstractDetector { 34 | 35 | public ContributionAndFinalizationUnnotifiedDetector(TaskService taskService, 36 | ReplicatesService replicatesService, 37 | IexecHubService iexecHubService, 38 | CronConfiguration cronConfiguration) { 39 | super( 40 | taskService, 41 | replicatesService, 42 | iexecHubService, 43 | TaskStatus.getWaitingContributionStatuses(), 44 | ReplicateStatus.CONTRIBUTE_AND_FINALIZE_ONGOING, 45 | ReplicateStatus.CONTRIBUTE_AND_FINALIZE_DONE, 46 | ChainContributionStatus.REVEALED, 47 | cronConfiguration.getContributeAndFinalize()); 48 | } 49 | 50 | @Override 51 | @Scheduled(fixedRateString = "#{@cronConfiguration.getContributeAndFinalize()}") 52 | public void detectOnChainChanges() { 53 | super.detectOnChainChanges(); 54 | } 55 | 56 | @Override 57 | protected final boolean checkDetectionIsValid(Replicate replicate) { 58 | return iexecHubService.getTaskDescription(replicate.getChainTaskId()).isEligibleToContributeAndFinalize(); 59 | } 60 | 61 | @Override 62 | protected boolean detectStatusReachedOnChain(Replicate replicate) { 63 | return iexecHubService.isRevealed(replicate.getChainTaskId(), replicate.getWalletAddress()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/replicate/ContributionUnnotifiedDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.replicate; 18 | 19 | import com.iexec.common.replicate.ReplicateStatus; 20 | import com.iexec.commons.poco.chain.ChainContributionStatus; 21 | import com.iexec.core.chain.IexecHubService; 22 | import com.iexec.core.configuration.CronConfiguration; 23 | import com.iexec.core.replicate.Replicate; 24 | import com.iexec.core.replicate.ReplicatesService; 25 | import com.iexec.core.task.TaskService; 26 | import com.iexec.core.task.TaskStatus; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.springframework.scheduling.annotation.Scheduled; 29 | import org.springframework.stereotype.Service; 30 | 31 | @Slf4j 32 | @Service 33 | public class ContributionUnnotifiedDetector extends UnnotifiedAbstractDetector { 34 | 35 | public ContributionUnnotifiedDetector(TaskService taskService, 36 | ReplicatesService replicatesService, 37 | IexecHubService iexecHubService, 38 | CronConfiguration cronConfiguration) { 39 | super( 40 | taskService, 41 | replicatesService, 42 | iexecHubService, 43 | TaskStatus.getWaitingContributionStatuses(), 44 | ReplicateStatus.CONTRIBUTING, 45 | ReplicateStatus.CONTRIBUTED, 46 | ChainContributionStatus.CONTRIBUTED, 47 | cronConfiguration.getContribute()); 48 | } 49 | 50 | @Override 51 | @Scheduled(fixedRateString = "#{@cronConfiguration.getContribute()}") 52 | public void detectOnChainChanges() { 53 | super.detectOnChainChanges(); 54 | } 55 | 56 | @Override 57 | protected final boolean checkDetectionIsValid(Replicate replicate) { 58 | return !iexecHubService.getTaskDescription(replicate.getChainTaskId()).isEligibleToContributeAndFinalize(); 59 | } 60 | 61 | @Override 62 | protected boolean detectStatusReachedOnChain(Replicate replicate) { 63 | return iexecHubService.isContributed(replicate.getChainTaskId(), replicate.getWalletAddress()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/replicate/RevealUnnotifiedDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.replicate; 18 | 19 | import com.iexec.common.replicate.ReplicateStatus; 20 | import com.iexec.commons.poco.chain.ChainContributionStatus; 21 | import com.iexec.core.chain.IexecHubService; 22 | import com.iexec.core.configuration.CronConfiguration; 23 | import com.iexec.core.replicate.Replicate; 24 | import com.iexec.core.replicate.ReplicatesService; 25 | import com.iexec.core.task.TaskService; 26 | import com.iexec.core.task.TaskStatus; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.springframework.scheduling.annotation.Scheduled; 29 | import org.springframework.stereotype.Service; 30 | 31 | @Slf4j 32 | @Service 33 | public class RevealUnnotifiedDetector extends UnnotifiedAbstractDetector { 34 | 35 | public RevealUnnotifiedDetector(TaskService taskService, 36 | ReplicatesService replicatesService, 37 | IexecHubService iexecHubService, 38 | CronConfiguration cronConfiguration) { 39 | super( 40 | taskService, 41 | replicatesService, 42 | iexecHubService, 43 | TaskStatus.getWaitingRevealStatuses(), 44 | ReplicateStatus.REVEALING, 45 | ReplicateStatus.REVEALED, 46 | ChainContributionStatus.REVEALED, 47 | cronConfiguration.getReveal()); 48 | } 49 | 50 | @Override 51 | @Scheduled(fixedRateString = "#{@cronConfiguration.getReveal()}") 52 | public void detectOnChainChanges() { 53 | super.detectOnChainChanges(); 54 | } 55 | 56 | @Override 57 | protected final boolean checkDetectionIsValid(Replicate replicate) { 58 | return !iexecHubService.getTaskDescription(replicate.getChainTaskId()).isEligibleToContributeAndFinalize(); 59 | } 60 | 61 | @Override 62 | protected boolean detectStatusReachedOnChain(Replicate replicate) { 63 | return iexecHubService.isRevealed(replicate.getChainTaskId(), replicate.getWalletAddress()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/task/ConsensusReachedTaskDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.task; 18 | 19 | import com.iexec.core.chain.IexecHubService; 20 | import com.iexec.core.detector.Detector; 21 | import com.iexec.core.task.Task; 22 | import com.iexec.core.task.TaskService; 23 | import com.iexec.core.task.TaskStatus; 24 | import com.iexec.core.task.update.TaskUpdateRequestManager; 25 | import lombok.extern.slf4j.Slf4j; 26 | import org.springframework.scheduling.annotation.Scheduled; 27 | import org.springframework.stereotype.Service; 28 | 29 | import static com.iexec.commons.poco.chain.ChainTaskStatus.REVEALING; 30 | import static com.iexec.core.task.TaskStatus.RUNNING; 31 | 32 | @Slf4j 33 | @Service 34 | public class ConsensusReachedTaskDetector implements Detector { 35 | 36 | private final IexecHubService iexecHubService; 37 | private final TaskService taskService; 38 | private final TaskUpdateRequestManager taskUpdateRequestManager; 39 | 40 | public ConsensusReachedTaskDetector(IexecHubService iexecHubService, 41 | TaskService taskService, 42 | TaskUpdateRequestManager taskUpdateRequestManager) { 43 | this.iexecHubService = iexecHubService; 44 | this.taskService = taskService; 45 | this.taskUpdateRequestManager = taskUpdateRequestManager; 46 | } 47 | 48 | @Scheduled(fixedRateString = "#{@cronConfiguration.getConsensusReached()}") 49 | @Override 50 | public void detect() { 51 | log.debug("Trying to detect running tasks with on-chain consensus"); 52 | taskService.findByCurrentStatus(RUNNING).stream() 53 | .filter(this::isConsensusReached) 54 | .forEach(this::publishTaskUpdateRequest); 55 | } 56 | 57 | private boolean isConsensusReached(Task task) { 58 | return iexecHubService.getChainTask(task.getChainTaskId()).stream() 59 | .allMatch(chainTask -> chainTask.getStatus() == REVEALING); 60 | } 61 | 62 | private void publishTaskUpdateRequest(Task task) { 63 | log.info("Detected confirmed missing update (task) [is:{}, should:{}, taskId:{}]", 64 | task.getCurrentStatus(), TaskStatus.CONSENSUS_REACHED, task.getChainTaskId()); 65 | taskUpdateRequestManager.publishRequest(task.getChainTaskId()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/task/ContributionTimeoutTaskDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.task; 18 | 19 | import com.iexec.core.detector.Detector; 20 | import com.iexec.core.task.TaskService; 21 | import com.iexec.core.task.TaskStatus; 22 | import com.iexec.core.task.TaskStatusChange; 23 | import com.iexec.core.task.event.ContributionTimeoutEvent; 24 | import lombok.extern.slf4j.Slf4j; 25 | import org.springframework.context.ApplicationEventPublisher; 26 | import org.springframework.data.mongodb.core.query.Criteria; 27 | import org.springframework.data.mongodb.core.query.Query; 28 | import org.springframework.data.mongodb.core.query.Update; 29 | import org.springframework.scheduling.annotation.Scheduled; 30 | import org.springframework.stereotype.Service; 31 | 32 | import java.time.Instant; 33 | 34 | @Slf4j 35 | @Service 36 | public class ContributionTimeoutTaskDetector implements Detector { 37 | 38 | private final TaskService taskService; 39 | private final ApplicationEventPublisher applicationEventPublisher; 40 | 41 | public ContributionTimeoutTaskDetector(TaskService taskService, ApplicationEventPublisher applicationEventPublisher) { 42 | this.taskService = taskService; 43 | this.applicationEventPublisher = applicationEventPublisher; 44 | } 45 | 46 | @Scheduled(fixedRateString = "#{@cronConfiguration.getContribute()}") 47 | @Override 48 | public void detect() { 49 | log.debug("Trying to detect tasks after contribution deadline"); 50 | final Instant now = Instant.now(); 51 | final Query query = Query.query(Criteria.where("currentStatus").in(TaskStatus.INITIALIZED, TaskStatus.RUNNING) 52 | .and("contributionDeadline").lte(now) 53 | .and("finalDeadline").gt(now)); 54 | final Update update = Update.update("currentStatus", TaskStatus.FAILED) 55 | .push("dateStatusList").each( 56 | TaskStatusChange.builder().status(TaskStatus.CONTRIBUTION_TIMEOUT).build(), 57 | TaskStatusChange.builder().status(TaskStatus.FAILED).build()); 58 | taskService.updateMultipleTasksByQuery(query, update) 59 | .forEach(id -> applicationEventPublisher.publishEvent(new ContributionTimeoutEvent(id))); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/task/FinalDeadlineTaskDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.task; 18 | 19 | import com.iexec.core.detector.Detector; 20 | import com.iexec.core.task.TaskService; 21 | import com.iexec.core.task.TaskStatus; 22 | import com.iexec.core.task.TaskStatusChange; 23 | import com.iexec.core.task.event.TaskFailedEvent; 24 | import lombok.extern.slf4j.Slf4j; 25 | import org.springframework.context.ApplicationEventPublisher; 26 | import org.springframework.data.mongodb.core.query.Criteria; 27 | import org.springframework.data.mongodb.core.query.Query; 28 | import org.springframework.data.mongodb.core.query.Update; 29 | import org.springframework.scheduling.annotation.Scheduled; 30 | import org.springframework.stereotype.Service; 31 | 32 | import java.time.Instant; 33 | 34 | @Slf4j 35 | @Service 36 | public class FinalDeadlineTaskDetector implements Detector { 37 | 38 | private final TaskService taskService; 39 | private final ApplicationEventPublisher applicationEventPublisher; 40 | 41 | public FinalDeadlineTaskDetector(TaskService taskService, ApplicationEventPublisher applicationEventPublisher) { 42 | this.taskService = taskService; 43 | this.applicationEventPublisher = applicationEventPublisher; 44 | } 45 | 46 | @Scheduled(fixedRateString = "#{@cronConfiguration.getFinalDeadline()}") 47 | @Override 48 | public void detect() { 49 | log.debug("Trying to detect tasks after final deadline"); 50 | final Query query = Query.query(Criteria.where("currentStatus").nin(TaskStatus.getStatusesWhereFinalDeadlineIsImpossible()) 51 | .and("finalDeadline").lte(Instant.now())); 52 | final Update update = Update.update("currentStatus", TaskStatus.FAILED) 53 | .push("dateStatusList").each( 54 | TaskStatusChange.builder().status(TaskStatus.FINAL_DEADLINE_REACHED).build(), 55 | TaskStatusChange.builder().status(TaskStatus.FAILED).build()); 56 | taskService.updateMultipleTasksByQuery(query, update) 57 | .forEach(id -> applicationEventPublisher.publishEvent(new TaskFailedEvent(id))); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/task/InitializedTaskDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.task; 18 | 19 | import com.iexec.commons.poco.chain.ChainTask; 20 | import com.iexec.commons.poco.chain.ChainTaskStatus; 21 | import com.iexec.core.chain.IexecHubService; 22 | import com.iexec.core.detector.Detector; 23 | import com.iexec.core.task.Task; 24 | import com.iexec.core.task.TaskService; 25 | import com.iexec.core.task.TaskStatus; 26 | import com.iexec.core.task.update.TaskUpdateRequestManager; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.springframework.scheduling.annotation.Scheduled; 29 | import org.springframework.stereotype.Service; 30 | 31 | import java.util.Optional; 32 | 33 | @Slf4j 34 | @Service 35 | public class InitializedTaskDetector implements Detector { 36 | 37 | private final TaskService taskService; 38 | private final TaskUpdateRequestManager taskUpdateRequestManager; 39 | private final IexecHubService iexecHubService; 40 | 41 | public InitializedTaskDetector(TaskService taskService, 42 | TaskUpdateRequestManager taskUpdateRequestManager, 43 | IexecHubService iexecHubService) { 44 | this.taskService = taskService; 45 | this.taskUpdateRequestManager = taskUpdateRequestManager; 46 | this.iexecHubService = iexecHubService; 47 | } 48 | 49 | /** 50 | * Detector to detect tasks that are initializing but are not initialized yet. 51 | */ 52 | @Scheduled(fixedRateString = "#{@cronConfiguration.getInitialize()}") 53 | @Override 54 | public void detect() { 55 | log.debug("Trying to detect initializable tasks"); 56 | for (Task task : taskService.getInitializableTasks()) { 57 | Optional chainTask = iexecHubService.getChainTask(task.getChainTaskId()); 58 | if (chainTask.isEmpty() || chainTask.get().getStatus().equals(ChainTaskStatus.UNSET)) { 59 | continue; 60 | } 61 | log.info("Detected confirmed missing update (task) [is:{}, should:{}, taskId:{}]", 62 | task.getCurrentStatus(), TaskStatus.INITIALIZED, task.getChainTaskId()); 63 | taskUpdateRequestManager.publishRequest(task.getChainTaskId()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/task/ReopenedTaskDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.task; 18 | 19 | import com.iexec.commons.poco.chain.ChainTask; 20 | import com.iexec.commons.poco.chain.ChainTaskStatus; 21 | import com.iexec.core.chain.IexecHubService; 22 | import com.iexec.core.detector.Detector; 23 | import com.iexec.core.task.Task; 24 | import com.iexec.core.task.TaskService; 25 | import com.iexec.core.task.TaskStatus; 26 | import com.iexec.core.task.update.TaskUpdateRequestManager; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.springframework.scheduling.annotation.Scheduled; 29 | import org.springframework.stereotype.Service; 30 | 31 | import java.util.Optional; 32 | 33 | @Slf4j 34 | @Service 35 | public class ReopenedTaskDetector implements Detector { 36 | 37 | private final TaskService taskService; 38 | private final TaskUpdateRequestManager taskUpdateRequestManager; 39 | private final IexecHubService iexecHubService; 40 | 41 | public ReopenedTaskDetector(TaskService taskService, 42 | TaskUpdateRequestManager taskUpdateRequestManager, 43 | IexecHubService iexecHubService) { 44 | this.taskService = taskService; 45 | this.taskUpdateRequestManager = taskUpdateRequestManager; 46 | this.iexecHubService = iexecHubService; 47 | } 48 | 49 | /** 50 | * Detector to detect tasks that are reopening but are not reopened yet. 51 | */ 52 | @Scheduled(fixedRateString = "#{@cronConfiguration.getFinalize()}") 53 | @Override 54 | public void detect() { 55 | log.debug("Trying to detect reopened tasks"); 56 | for (Task task : taskService.findByCurrentStatus(TaskStatus.REOPENING)) { 57 | Optional oChainTask = iexecHubService.getChainTask(task.getChainTaskId()); 58 | if (oChainTask.isEmpty()) { 59 | continue; 60 | } 61 | 62 | ChainTask chainTask = oChainTask.get(); 63 | if (chainTask.getStatus().equals(ChainTaskStatus.ACTIVE)) { 64 | log.info("Detected confirmed missing update (task) [is:{}, should:{}, taskId:{}]", 65 | task.getCurrentStatus(), TaskStatus.REOPENED, task.getChainTaskId()); 66 | taskUpdateRequestManager.publishRequest(task.getChainTaskId()); 67 | } 68 | } 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/detector/task/UnstartedTxDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.detector.task; 18 | 19 | import com.iexec.core.detector.Detector; 20 | import com.iexec.core.task.Task; 21 | import com.iexec.core.task.TaskService; 22 | import com.iexec.core.task.TaskStatus; 23 | import com.iexec.core.task.update.TaskUpdateRequestManager; 24 | import lombok.extern.slf4j.Slf4j; 25 | import org.springframework.scheduling.annotation.Scheduled; 26 | import org.springframework.stereotype.Service; 27 | 28 | import java.util.List; 29 | 30 | @Slf4j 31 | @Service 32 | public class UnstartedTxDetector implements Detector { 33 | 34 | private final TaskService taskService; 35 | private final TaskUpdateRequestManager taskUpdateRequestManager; 36 | 37 | public UnstartedTxDetector(TaskService taskService, TaskUpdateRequestManager taskUpdateRequestManager) { 38 | this.taskService = taskService; 39 | this.taskUpdateRequestManager = taskUpdateRequestManager; 40 | } 41 | 42 | @Scheduled(fixedRateString = "#{@cronConfiguration.getUnstartedTx()}") 43 | @Override 44 | public void detect() { 45 | //start finalize when needed 46 | List notYetFinalizingTasks = taskService.findByCurrentStatus(TaskStatus.RESULT_UPLOADED); 47 | for (Task task : notYetFinalizingTasks) { 48 | log.info("Detected confirmed missing update (task) [is:{}, should:{}, chainTaskId:{}]", 49 | task.getCurrentStatus(), TaskStatus.FINALIZING, task.getChainTaskId()); 50 | taskUpdateRequestManager.publishRequest(task.getChainTaskId()); 51 | } 52 | 53 | //start initialize when needed 54 | List notYetInitializedTasks = taskService.getInitializableTasks(); 55 | for (Task task : notYetInitializedTasks) { 56 | log.info("Detected confirmed missing update (task) [is:{}, should:{}, chainTaskId:{}]", 57 | task.getCurrentStatus(), TaskStatus.INITIALIZING, task.getChainTaskId()); 58 | taskUpdateRequestManager.publishRequest(task.getChainTaskId()); 59 | } 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/exception/MultipleOccurrencesOfFieldNotAllowed.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.exception; 18 | 19 | public class MultipleOccurrencesOfFieldNotAllowed extends RuntimeException { 20 | private final String fieldName; 21 | public MultipleOccurrencesOfFieldNotAllowed(String fieldName) { 22 | this.fieldName = fieldName; 23 | } 24 | 25 | public String getFieldName() { 26 | return fieldName; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/logs/ComputeLogsCronService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.logs; 18 | 19 | import java.util.Date; 20 | import java.util.List; 21 | import java.util.concurrent.TimeUnit; 22 | 23 | import com.iexec.core.task.TaskService; 24 | 25 | import org.apache.commons.lang3.time.DateUtils; 26 | import org.springframework.beans.factory.annotation.Value; 27 | import org.springframework.scheduling.annotation.Scheduled; 28 | import org.springframework.stereotype.Service; 29 | 30 | @Service 31 | public class ComputeLogsCronService { 32 | 33 | @Value("${logs.availability-period-in-days}") 34 | private int availabilityDays; 35 | 36 | private final TaskLogsService taskLogsService; 37 | private final TaskService taskService; 38 | 39 | public ComputeLogsCronService( 40 | TaskLogsService taskLogsService, 41 | TaskService taskService 42 | ) { 43 | this.taskLogsService = taskLogsService; 44 | this.taskService = taskService; 45 | } 46 | 47 | @Scheduled( 48 | fixedRateString = "${logs.purge-rate-in-days}", 49 | timeUnit = TimeUnit.DAYS) 50 | void purgeLogs() { 51 | Date someDaysAgo = DateUtils.addDays(new Date(), -availabilityDays); 52 | List chainTaskIds = taskService 53 | .getChainTaskIdsOfTasksExpiredBefore(someDaysAgo); 54 | taskLogsService.delete(chainTaskIds); 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/logs/TaskLogs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.logs; 18 | 19 | import com.fasterxml.jackson.annotation.JsonIgnore; 20 | import com.iexec.common.replicate.ComputeLogs; 21 | import lombok.AllArgsConstructor; 22 | import lombok.Builder; 23 | import lombok.Data; 24 | import lombok.NoArgsConstructor; 25 | import org.springframework.data.annotation.Id; 26 | import org.springframework.data.annotation.Version; 27 | import org.springframework.data.mongodb.core.index.Indexed; 28 | import org.springframework.data.mongodb.core.mapping.Document; 29 | 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | 33 | @Document 34 | @Data 35 | @Builder 36 | @NoArgsConstructor 37 | @AllArgsConstructor 38 | public class TaskLogs { 39 | 40 | @Id 41 | @JsonIgnore 42 | private String id; 43 | 44 | @Version 45 | @JsonIgnore 46 | private Long version; 47 | 48 | @Indexed(unique = true) 49 | private String chainTaskId; 50 | 51 | private List computeLogsList; 52 | 53 | public TaskLogs(String chainTaskId) { 54 | this.chainTaskId = chainTaskId; 55 | this.computeLogsList = new ArrayList<>(); 56 | } 57 | 58 | public TaskLogs(String chainTaskId, List computeLogsList) { 59 | this.chainTaskId = chainTaskId; 60 | this.computeLogsList = computeLogsList; 61 | } 62 | 63 | public boolean containsWalletAddress(String walletAddress) { 64 | return computeLogsList.stream().anyMatch( 65 | computeLog -> computeLog.getWalletAddress().equals(walletAddress) 66 | ); 67 | } 68 | 69 | public TaskLogsModel generateModel() { 70 | return TaskLogsModel.builder() 71 | .chainTaskId(chainTaskId) 72 | .computeLogsList(computeLogsList) 73 | .build(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/logs/TaskLogsRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.logs; 18 | 19 | import org.springframework.data.mongodb.repository.MongoRepository; 20 | import org.springframework.data.mongodb.repository.Query; 21 | 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | public interface TaskLogsRepository extends MongoRepository { 26 | 27 | Optional findOneByChainTaskId(String chainTaskId); 28 | 29 | @Query(value = "{ chainTaskId: ?0 }", fields = "{ computeLogsList: { $elemMatch: { walletAddress: ?1 } } }") 30 | Optional findByChainTaskIdAndWalletAddress(String chainTaskId, String walletAddress); 31 | 32 | void deleteByChainTaskIdIn(List chainTaskIds); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/logs/TaskLogsService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.logs; 18 | 19 | import com.iexec.common.replicate.ComputeLogs; 20 | import org.springframework.stereotype.Service; 21 | 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | @Service 26 | public class TaskLogsService { 27 | 28 | private final TaskLogsRepository taskLogsRepository; 29 | 30 | public TaskLogsService(TaskLogsRepository taskLogsRepository) { 31 | this.taskLogsRepository = taskLogsRepository; 32 | } 33 | 34 | public void addComputeLogs(String chainTaskId, ComputeLogs computeLogs) { 35 | if (computeLogs == null) { 36 | return; 37 | } 38 | 39 | TaskLogs taskLogs = getTaskLogs(chainTaskId).orElse(new TaskLogs(chainTaskId)); 40 | if (taskLogs.containsWalletAddress(computeLogs.getWalletAddress())) { 41 | return; 42 | } 43 | taskLogs.getComputeLogsList().add(computeLogs); 44 | taskLogsRepository.save(taskLogs); 45 | } 46 | 47 | public Optional getTaskLogs(String chainTaskId) { 48 | return taskLogsRepository.findOneByChainTaskId(chainTaskId); 49 | } 50 | 51 | public Optional getComputeLogs(String chainTaskId, String walletAddress) { 52 | return taskLogsRepository.findByChainTaskIdAndWalletAddress(chainTaskId, walletAddress) 53 | .map(taskLogs -> taskLogs.getComputeLogsList().get(0)); 54 | } 55 | 56 | public void delete(List chainTaskIds) { 57 | taskLogsRepository.deleteByChainTaskIdIn(chainTaskIds); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/metric/MetricController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.metric; 18 | 19 | import org.springframework.http.ResponseEntity; 20 | import org.springframework.web.bind.annotation.GetMapping; 21 | import org.springframework.web.bind.annotation.RestController; 22 | 23 | import static org.springframework.http.ResponseEntity.ok; 24 | 25 | @RestController 26 | public class MetricController { 27 | 28 | private final MetricService metricService; 29 | 30 | public MetricController(MetricService metricService) { 31 | this.metricService = metricService; 32 | } 33 | 34 | @GetMapping("/metrics") 35 | public ResponseEntity getPlatformMetric() { 36 | return ok(metricService.getPlatformMetrics()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/pubsub/NotificationService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.pubsub; 18 | 19 | import com.iexec.core.notification.TaskNotification; 20 | import lombok.extern.slf4j.Slf4j; 21 | import org.springframework.messaging.simp.SimpMessagingTemplate; 22 | import org.springframework.stereotype.Service; 23 | 24 | @Slf4j 25 | @Service 26 | public class NotificationService { 27 | 28 | private final SimpMessagingTemplate sender; 29 | 30 | public NotificationService(SimpMessagingTemplate sender) { 31 | this.sender = sender; 32 | } 33 | 34 | public void sendTaskNotification(TaskNotification taskNotification) { 35 | sender.convertAndSend("/topic/task/" + taskNotification.getChainTaskId(), taskNotification); 36 | log.info("Sent TaskNotification [chainTaskId:{}, type:{}, workers:{}]", 37 | taskNotification.getChainTaskId(), taskNotification.getTaskNotificationType(), taskNotification.getWorkersAddress()); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/registry/PlatformRegistryConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.registry; 2 | 3 | import lombok.Getter; 4 | import org.hibernate.validator.constraints.URL; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Getter 9 | @Configuration 10 | public class PlatformRegistryConfiguration { 11 | 12 | @URL 13 | @Value("${sms.scone}") 14 | private String sconeSms; 15 | 16 | @URL 17 | @Value("${sms.gramine}") 18 | private String gramineSms; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/replicate/NoReplicateStatusException.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.replicate; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * Exception that can be thrown 8 | * when searching for a {@link com.iexec.common.replicate.ReplicateStatus} fails. 9 | */ 10 | @AllArgsConstructor 11 | @Getter 12 | public class NoReplicateStatusException extends RuntimeException { 13 | private final String chainTaskId; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/replicate/ReplicateComputedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | import lombok.*; 20 | 21 | @Data 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | @Getter 25 | @Setter 26 | public class ReplicateComputedEvent { 27 | 28 | private Replicate replicate; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/replicate/ReplicateStatusUpdateError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | public enum ReplicateStatusUpdateError { 20 | UNKNOWN_REPLICATE, 21 | UNKNOWN_TASK, 22 | BAD_WORKFLOW_TRANSITION, 23 | ALREADY_REPORTED, 24 | GENERIC_CANT_UPDATE, 25 | NO_ERROR 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/replicate/ReplicateUpdatedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | import com.iexec.common.replicate.ReplicateStatusUpdate; 20 | import lombok.Builder; 21 | import lombok.Value; 22 | 23 | @Value 24 | @Builder 25 | public class ReplicateUpdatedEvent { 26 | String chainTaskId; 27 | String walletAddress; 28 | ReplicateStatusUpdate replicateStatusUpdate; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/replicate/ReplicatesRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | import org.springframework.data.mongodb.repository.MongoRepository; 20 | 21 | import java.util.Optional; 22 | 23 | interface ReplicatesRepository extends MongoRepository { 24 | 25 | Optional findByChainTaskId(String chainTaskId); 26 | 27 | long countByChainTaskId(String chainTaskId); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/replicate/UpdateReplicateStatusArgs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.replicate; 18 | 19 | import com.iexec.commons.poco.chain.ChainContribution; 20 | import com.iexec.commons.poco.task.TaskDescription; 21 | import lombok.Builder; 22 | import lombok.Data; 23 | 24 | @Data 25 | @Builder 26 | public class UpdateReplicateStatusArgs { 27 | private final int workerWeight; 28 | private final ChainContribution chainContribution; 29 | private String resultLink; 30 | private String chainCallbackData; 31 | private TaskDescription taskDescription; 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/security/ChallengeService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.security; 18 | 19 | import net.jodah.expiringmap.ExpirationPolicy; 20 | import net.jodah.expiringmap.ExpiringMap; 21 | import org.springframework.stereotype.Service; 22 | 23 | import java.security.SecureRandom; 24 | import java.util.Base64; 25 | import java.util.concurrent.TimeUnit; 26 | 27 | @Service 28 | public class ChallengeService { 29 | 30 | private final ExpiringMap challengesMap = ExpiringMap.builder() 31 | .expiration(5, TimeUnit.MINUTES) 32 | .expirationPolicy(ExpirationPolicy.CREATED) 33 | .build(); 34 | 35 | public String computeChallenge() { 36 | SecureRandom secureRandom = new SecureRandom(); 37 | byte[] seed = new byte[32]; 38 | secureRandom.nextBytes(seed); 39 | return Base64.getEncoder().encodeToString(seed); 40 | } 41 | 42 | public String getChallenge(String workerWallet) { 43 | return challengesMap.computeIfAbsent(workerWallet, wallet -> computeChallenge()); 44 | } 45 | 46 | public void removeChallenge(String workerWallet, String challenge) { 47 | challengesMap.remove(workerWallet, challenge); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/security/EIP712ChallengeService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.security; 18 | 19 | import com.iexec.commons.poco.eip712.EIP712Domain; 20 | import com.iexec.commons.poco.eip712.entity.Challenge; 21 | import com.iexec.commons.poco.eip712.entity.EIP712Challenge; 22 | import net.jodah.expiringmap.ExpirationPolicy; 23 | import net.jodah.expiringmap.ExpiringMap; 24 | import org.springframework.stereotype.Service; 25 | import org.web3j.crypto.Keys; 26 | 27 | import java.security.SecureRandom; 28 | import java.util.Base64; 29 | import java.util.concurrent.TimeUnit; 30 | 31 | @Service 32 | public class EIP712ChallengeService { 33 | 34 | private final EIP712Domain domain; 35 | private final ExpiringMap challenges; 36 | private final SecureRandom secureRandom = new SecureRandom(); 37 | 38 | EIP712ChallengeService(int chainId) { 39 | this.domain = new EIP712Domain("iExec Core", "1", chainId, null); 40 | this.challenges = ExpiringMap.builder() 41 | .expiration(60, TimeUnit.MINUTES) 42 | .expirationPolicy(ExpirationPolicy.CREATED) 43 | .build(); 44 | } 45 | 46 | public EIP712Challenge generateChallenge() { 47 | byte[] token = new byte[32]; 48 | secureRandom.nextBytes(token); 49 | String challenge = Base64.getEncoder().encodeToString(token); 50 | return new EIP712Challenge(domain, Challenge.builder().challenge(challenge).build()); 51 | } 52 | 53 | public EIP712Challenge getChallenge(String walletAddress) { 54 | walletAddress = Keys.toChecksumAddress(walletAddress); 55 | challenges.computeIfAbsent(walletAddress, s -> this.generateChallenge()); 56 | return challenges.get(walletAddress); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/security/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.security; 18 | 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; 22 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 23 | import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; 24 | import org.springframework.security.config.http.SessionCreationPolicy; 25 | import org.springframework.security.web.SecurityFilterChain; 26 | 27 | @Configuration 28 | @EnableMethodSecurity 29 | public class WebSecurityConfig { 30 | 31 | @Bean 32 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 33 | // Disable CSRF (cross site request forgery) 34 | http.csrf(AbstractHttpConfigurer::disable); 35 | // No session will be created or used by spring security 36 | http.sessionManagement(sessionMgt -> sessionMgt.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); 37 | http.authorizeHttpRequests(request -> request.anyRequest().permitAll()); 38 | return http.build(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/sms/SmsClientProviderConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.sms; 2 | 3 | import com.iexec.sms.api.SmsClientProvider; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class SmsClientProviderConfiguration { 9 | 10 | @Bean 11 | SmsClientProvider smsClientProvider() { 12 | return new SmsClientProvider(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/TaskRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task; 18 | 19 | import org.springframework.data.domain.Sort; 20 | import org.springframework.data.mongodb.repository.MongoRepository; 21 | import org.springframework.data.mongodb.repository.Query; 22 | 23 | import java.util.Date; 24 | import java.util.List; 25 | import java.util.Optional; 26 | 27 | public interface TaskRepository extends MongoRepository { 28 | 29 | Optional findByChainTaskId(String id); 30 | 31 | @Query("{ 'chainTaskId': {$in: ?0} }") 32 | List findByChainTaskId(List ids); 33 | 34 | List findByCurrentStatus(TaskStatus status); 35 | 36 | @Query("{ 'currentStatus': {$in: ?0} }") 37 | List findByCurrentStatus(List statuses); 38 | 39 | /** 40 | * Retrieves the prioritized task matching with given criteria: 41 | *

    42 | *
  • Task is in one of given {@code statuses} 43 | *
  • Task contribution deadline is after a provided {@code timestamp} 44 | *
  • Task has not given {@code excludedTags}, this is mainly used to exclude TEE tasks 45 | *
  • Chain task ID is not one of the given {@code excludedChainTaskIds} 46 | *
  • Tasks are prioritized according to the {@code sort} parameter 47 | *
48 | * 49 | * @param statuses The task status should be one of this list. 50 | * @param timestamp The task contribution deadline should be after the provided timestamp. 51 | * @param excludedTags The task tag should not be one this tag list 52 | * - use {@literal null} if no tag should be excluded. 53 | * @param excludedChainTaskIds The chain task ID should not be one of this list. 54 | * @param sort How to prioritize tasks. 55 | * @return The first task matching with the criteria, according to the {@code sort} parameter. 56 | */ 57 | Optional findFirstByCurrentStatusInAndContributionDeadlineAfterAndTagNotInAndChainTaskIdNotIn( 58 | List statuses, Date timestamp, List excludedTags, List excludedChainTaskIds, Sort sort); 59 | 60 | @Query(value = "{ finalDeadline: {$lt : ?0} }", fields = "{ chainTaskId: true }") 61 | List findChainTaskIdsByFinalDeadlineBefore(Date date); 62 | 63 | List findByCurrentStatusInAndContributionDeadlineAfter(List status, Date date); 64 | 65 | long countByCurrentStatus(TaskStatus currentStatus); 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/ConsensusReachedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import lombok.Builder; 20 | import lombok.Value; 21 | 22 | @Value 23 | @Builder 24 | public class ConsensusReachedEvent { 25 | String chainTaskId; 26 | String consensus; 27 | long blockNumber; 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/ContributionTimeoutEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import lombok.*; 20 | 21 | @Value 22 | public class ContributionTimeoutEvent { 23 | String chainTaskId; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/PleaseUploadEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import lombok.Value; 20 | 21 | @Value 22 | public class PleaseUploadEvent { 23 | String chainTaskId; 24 | String workerWallet; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/ResultUploadTimeoutEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import lombok.Value; 20 | 21 | @Value 22 | public class ResultUploadTimeoutEvent { 23 | String chainTaskId; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/TaskCompletedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import com.iexec.core.task.Task; 20 | import lombok.Value; 21 | 22 | @Value 23 | public class TaskCompletedEvent { 24 | Task task; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/TaskCreatedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import lombok.Value; 20 | 21 | @Value 22 | public class TaskCreatedEvent { 23 | String chainTaskId; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/TaskFailedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import lombok.Value; 20 | 21 | @Value 22 | public class TaskFailedEvent { 23 | String chainTaskId; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/TaskInitializedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import lombok.Value; 20 | 21 | @Value 22 | public class TaskInitializedEvent { 23 | String chainTaskId; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/TaskRunningFailedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021-2023 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import lombok.Value; 20 | 21 | @Value 22 | public class TaskRunningFailedEvent { 23 | String chainTaskId; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/event/TaskStatusesCountUpdatedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.event; 18 | 19 | import com.iexec.core.task.TaskStatus; 20 | import lombok.Value; 21 | 22 | import java.util.LinkedHashMap; 23 | 24 | @Value 25 | public class TaskStatusesCountUpdatedEvent { 26 | LinkedHashMap currentTaskStatusesCount; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/task/update/TaskUpdate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task.update; 18 | 19 | import com.iexec.core.task.Task; 20 | import com.iexec.core.task.TaskStatus; 21 | import lombok.extern.slf4j.Slf4j; 22 | 23 | import java.util.Comparator; 24 | import java.util.Date; 25 | import java.util.Objects; 26 | import java.util.function.Consumer; 27 | 28 | @Slf4j 29 | class TaskUpdate implements Runnable, Comparable { 30 | private final Task task; 31 | private final Consumer taskUpdater; 32 | 33 | TaskUpdate(Task task, 34 | Consumer taskUpdater) { 35 | this.task = task; 36 | this.taskUpdater = taskUpdater; 37 | } 38 | 39 | public Task getTask() { 40 | return task; 41 | } 42 | 43 | public String getChainTaskId() { 44 | return task.getChainTaskId(); 45 | } 46 | 47 | private TaskStatus getCurrentStatus() { 48 | return task.getCurrentStatus(); 49 | } 50 | 51 | private Date getContributionDeadline() { 52 | return task.getContributionDeadline(); 53 | } 54 | 55 | /** 56 | * Updates a task. 57 | *
58 | * 2 updates can be run in parallel if they don't target the same task. 59 | * Otherwise, the second update will wait until the first one is achieved. 60 | */ 61 | @Override 62 | public void run() { 63 | if (task == null) { 64 | return; 65 | } 66 | 67 | String chainTaskId = task.getChainTaskId(); 68 | log.debug("Selected task [chainTaskId: {}, status: {}]", chainTaskId, task.getCurrentStatus()); 69 | taskUpdater.accept(chainTaskId); 70 | } 71 | 72 | @Override 73 | public int compareTo(TaskUpdate otherTaskUpdate) { 74 | if (otherTaskUpdate == null) { 75 | throw new NullPointerException("Can't compare a null task update."); 76 | } 77 | return Comparator.comparing(TaskUpdate::getCurrentStatus, Comparator.reverseOrder()) 78 | .thenComparing(TaskUpdate::getContributionDeadline) 79 | .compare(this, otherTaskUpdate); 80 | } 81 | 82 | @Override 83 | public boolean equals(Object o) { 84 | if (this == o) return true; 85 | if (o == null || getClass() != o.getClass()) return false; 86 | TaskUpdate that = (TaskUpdate) o; 87 | return Objects.equals(task, that.task); 88 | } 89 | 90 | @Override 91 | public int hashCode() { 92 | return Objects.hash(task); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/utils/TaskExecutorUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.utils; 18 | 19 | import lombok.AccessLevel; 20 | import lombok.NoArgsConstructor; 21 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 22 | 23 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 24 | public class TaskExecutorUtils { 25 | public static ThreadPoolTaskExecutor newThreadPoolTaskExecutor(final String threadNamePrefix) { 26 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 27 | executor.setCorePoolSize(Runtime.getRuntime().availableProcessors()); 28 | executor.setThreadNamePrefix(threadNamePrefix); 29 | executor.initialize(); 30 | return executor; 31 | } 32 | 33 | public static ThreadPoolTaskExecutor newThreadPoolTaskExecutor( 34 | final String threadNamePrefix, 35 | final int poolSize 36 | ) { 37 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 38 | executor.setCorePoolSize(poolSize); 39 | executor.setThreadNamePrefix(threadNamePrefix); 40 | executor.initialize(); 41 | return executor; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/utils/TaskSchedulerUtils.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.utils; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.NoArgsConstructor; 5 | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 6 | 7 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 8 | public class TaskSchedulerUtils { 9 | 10 | public static ThreadPoolTaskScheduler newThreadPoolTaskScheduler( 11 | String threadNamePrefix 12 | ) { 13 | ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); 14 | scheduler.setPoolSize(Runtime.getRuntime().availableProcessors()); 15 | scheduler.setThreadNamePrefix(threadNamePrefix); 16 | scheduler.initialize(); 17 | return scheduler; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/version/VersionController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.version; 18 | 19 | import io.micrometer.core.instrument.Gauge; 20 | import io.micrometer.core.instrument.Metrics; 21 | import jakarta.annotation.PostConstruct; 22 | import org.springframework.boot.info.BuildProperties; 23 | import org.springframework.http.ResponseEntity; 24 | import org.springframework.web.bind.annotation.GetMapping; 25 | import org.springframework.web.bind.annotation.RestController; 26 | 27 | 28 | @RestController 29 | public class VersionController { 30 | 31 | public static final String METRIC_INFO_GAUGE_NAME = "iexec.version.info"; 32 | public static final String METRIC_INFO_GAUGE_DESC = "A metric to expose version and application name."; 33 | public static final String METRIC_INFO_LABEL_APP_NAME = "iexecAppName"; 34 | public static final String METRIC_INFO_LABEL_APP_VERSION = "iexecAppVersion"; 35 | // Must be static final to avoid garbage collect and side effect on gauge 36 | public static final int METRIC_VALUE = 1; 37 | private final BuildProperties buildProperties; 38 | 39 | public VersionController(BuildProperties buildProperties) { 40 | this.buildProperties = buildProperties; 41 | } 42 | 43 | @PostConstruct 44 | void initializeGaugeVersion() { 45 | Gauge.builder(METRIC_INFO_GAUGE_NAME, METRIC_VALUE, n -> METRIC_VALUE) 46 | .description(METRIC_INFO_GAUGE_DESC) 47 | .tags(METRIC_INFO_LABEL_APP_VERSION, buildProperties.getVersion(), 48 | METRIC_INFO_LABEL_APP_NAME, buildProperties.getName()) 49 | .register(Metrics.globalRegistry); 50 | } 51 | 52 | @GetMapping("/version") 53 | public ResponseEntity getVersion() { 54 | return ResponseEntity.ok(buildProperties.getVersion()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/worker/AliveWorkerMetrics.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.worker; 18 | 19 | import lombok.Builder; 20 | 21 | @Builder 22 | public record AliveWorkerMetrics(int aliveWorkers, 23 | int aliveComputingCpu, 24 | int aliveRegisteredCpu, 25 | int aliveComputingGpu, 26 | int aliveRegisteredGpu) { 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/worker/Worker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.worker; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import org.springframework.data.annotation.Id; 23 | import org.springframework.data.mongodb.core.index.Indexed; 24 | import org.springframework.data.mongodb.core.mapping.Document; 25 | 26 | import java.util.Date; 27 | import java.util.List; 28 | 29 | @Document 30 | @Data 31 | @Builder 32 | @AllArgsConstructor 33 | public class Worker { 34 | 35 | @Id 36 | private String id; 37 | private String name; 38 | 39 | @Indexed(unique = true) 40 | private String walletAddress; 41 | 42 | private String os; 43 | private String cpu; 44 | private int cpuNb; 45 | private int maxNbTasks; 46 | private int memorySize; 47 | private boolean teeEnabled; 48 | private boolean gpuEnabled; 49 | @Builder.Default 50 | private List participatingChainTaskIds = List.of(); 51 | @Builder.Default 52 | private List computingChainTaskIds = List.of(); 53 | 54 | // TODO remove it cleanly in a release 55 | private Date lastAliveDate; 56 | private Date lastReplicateDemandDate; 57 | 58 | void addChainTaskId(String chainTaskId) { 59 | participatingChainTaskIds.add(chainTaskId); 60 | computingChainTaskIds.add(chainTaskId); 61 | } 62 | 63 | void removeChainTaskId(String chainTaskId) { 64 | participatingChainTaskIds.remove(chainTaskId); 65 | computingChainTaskIds.remove(chainTaskId); 66 | } 67 | 68 | void removeComputedChainTaskId(String chainTaskId) { 69 | computingChainTaskIds.remove(chainTaskId); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/worker/WorkerRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.worker; 18 | 19 | import org.springframework.data.mongodb.repository.MongoRepository; 20 | 21 | import java.util.Collection; 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | interface WorkerRepository extends MongoRepository { 26 | 27 | Optional findByWalletAddress(String walletAddress); 28 | 29 | List findByWalletAddressIn(Collection walletAddresses); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/worker/WorkerUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.worker; 18 | 19 | import lombok.AccessLevel; 20 | import lombok.NoArgsConstructor; 21 | import lombok.extern.slf4j.Slf4j; 22 | import org.apache.commons.lang3.StringUtils; 23 | 24 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 25 | @Slf4j 26 | public class WorkerUtils { 27 | 28 | /** 29 | * Utility function to log a message in the event of unauthorized access 30 | * Either because the worker is not whitelisted or because the worker address was not found in the JWT token 31 | * 32 | * @param workerWalletAddress Address of the worker who attempted access 33 | */ 34 | public static void emitWarnOnUnAuthorizedAccess(String workerWalletAddress) { 35 | final String workerAddress = StringUtils.isEmpty(workerWalletAddress) ? "NotAvailable" : workerWalletAddress; 36 | log.warn("Worker is not allowed to join this workerpool [workerAddress:{}]", workerAddress); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/iexec/core/workflow/TaskWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.workflow; 18 | 19 | import com.iexec.core.task.TaskStatus; 20 | 21 | import static com.iexec.core.task.TaskStatus.*; 22 | 23 | 24 | public class TaskWorkflow extends Workflow { 25 | 26 | private static TaskWorkflow instance; 27 | 28 | public static synchronized TaskWorkflow getInstance() { 29 | if (instance == null) { 30 | instance = new TaskWorkflow(); 31 | } 32 | return instance; 33 | } 34 | 35 | private TaskWorkflow() { 36 | super(); 37 | 38 | // This is where the whole workflow is defined 39 | addTransition(INITIALIZED, RUNNING); 40 | addTransition(RUNNING, CONSENSUS_REACHED); 41 | addTransition(RUNNING, RUNNING_FAILED); 42 | addTransition(CONSENSUS_REACHED, AT_LEAST_ONE_REVEALED); 43 | addTransition(AT_LEAST_ONE_REVEALED, RESULT_UPLOADING); 44 | addTransition(RESULT_UPLOADING, RESULT_UPLOADED); 45 | addTransition(RESULT_UPLOADED, COMPLETED); 46 | addTransition(RESULT_UPLOADING, FAILED); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ${Ansi.YELLOW} _ _____ ______ 2 | ${Ansi.YELLOW} __/\__ (_) ____|_ _____ ___ \ \ \ \ 3 | ${Ansi.YELLOW} \ / | | _| \ \/ / _ \/ __| \ \ \ \ 4 | ${Ansi.YELLOW} /_ _\ | | |___ > < __/ (__ / / / / 5 | ${Ansi.YELLOW} \/ |_|_____/_/\_\___|\___| /_/_/_/ 6 | ${Ansi.YELLOW} ========= 7 | ${Ansi.YELLOW} :: ${application.title}${application.formatted-version} built with Spring Boot${spring-boot.formatted-version} :: ${Ansi.DEFAULT} -------------------------------------------------------------------------------- /src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/resources/ssl-keystore-dev.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iExecBlockchainComputing/iexec-core/b89ed60ef43d78362aca15929070d7d600f3e9bd/src/main/resources/ssl-keystore-dev.p12 -------------------------------------------------------------------------------- /src/main/resources/wallet/encrypted-wallet_scheduler.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "000a9c787a972f70f0903890e266f41c795c4dca", 3 | "id": "10a5105f-d83e-4dd5-89b8-d5b470330e29", 4 | "version": 3, 5 | "Crypto": { 6 | "cipher": "aes-128-ctr", 7 | "cipherparams": { 8 | "iv": "29ff2f5f088592183fe151e69bd125ff" 9 | }, 10 | "ciphertext": "fb3222978811bc053964f229d63ee30f71126ab0af781cda4483f2a25096f0bd", 11 | "kdf": "scrypt", 12 | "kdfparams": { 13 | "salt": "9920c0d162772a166aebad00ec4f925270670879dee42574fae033363ba400c6", 14 | "n": 131072, 15 | "dklen": 32, 16 | "p": 1, 17 | "r": 8 18 | }, 19 | "mac": "8a2458428220a2169b01dbe8ad7c03f245c4121449e696749e3126b06353c5e1" 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/resources/workflow/replicate-actions.json: -------------------------------------------------------------------------------- 1 | { 2 | "STARTING" : "PLEASE_CONTINUE", 3 | "STARTED" : "PLEASE_DOWNLOAD_APP", 4 | "START_FAILED" : "PLEASE_ABORT", 5 | "APP_DOWNLOADING" : "PLEASE_CONTINUE", 6 | "APP_DOWNLOADED" : "PLEASE_DOWNLOAD_DATA", 7 | "APP_DOWNLOAD_FAILED" : "PLEASE_ABORT", 8 | "DATA_DOWNLOADING" : "PLEASE_CONTINUE", 9 | "DATA_DOWNLOADED" : "PLEASE_COMPUTE", 10 | "DATA_DOWNLOAD_FAILED" : "PLEASE_ABORT", 11 | "COMPUTING" : "PLEASE_CONTINUE", 12 | "COMPUTED" : "PLEASE_CONTRIBUTE", 13 | "COMPUTE_FAILED" : "PLEASE_ABORT", 14 | "CONTRIBUTING" : "PLEASE_CONTINUE", 15 | "CONTRIBUTED" : "PLEASE_WAIT", 16 | "CONTRIBUTE_FAILED" : "PLEASE_ABORT", 17 | "REVEALING" : "PLEASE_CONTINUE", 18 | "REVEALED" : "PLEASE_WAIT", 19 | "REVEAL_FAILED" : "PLEASE_ABORT", 20 | "RESULT_UPLOADING" : "PLEASE_CONTINUE", 21 | "RESULT_UPLOADED" : "PLEASE_WAIT", 22 | "RESULT_UPLOAD_FAILED" : "PLEASE_ABORT", 23 | "COMPLETING" : "PLEASE_CONTINUE", 24 | "COMPLETED" : "PLEASE_WAIT", 25 | "COMPLETE_FAILED" : "PLEASE_ABORT" 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/TestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core; 18 | 19 | import com.iexec.commons.poco.tee.TeeUtils; 20 | import com.iexec.commons.poco.utils.BytesUtils; 21 | import com.iexec.core.task.Task; 22 | import com.iexec.core.task.TaskStatus; 23 | import com.iexec.core.task.TaskStatusChange; 24 | 25 | import java.time.Instant; 26 | import java.time.temporal.ChronoUnit; 27 | import java.util.Date; 28 | 29 | public class TestUtils { 30 | public static final String CHAIN_DEAL_ID = "0xd82223e5feff6720792ffed1665e980da95e5d32b177332013eaba8edc07f31c"; 31 | public static final String CHAIN_TASK_ID = "0x65bc5e94ed1486b940bd6cc0013c418efad58a0a52a3d08cee89faaa21970426"; 32 | 33 | public static final String WORKER_ADDRESS = "0x87ae2b87b5db23830572988fb1f51242fbc471ce"; 34 | public static final String WALLET_WORKER_1 = "0x1a69b2eb604db8eba185df03ea4f5288dcbbd248"; 35 | public static final String WALLET_WORKER_2 = "0x2ab2674aa374fe6415d11f0a8fcbd8027fc1e6a9"; 36 | public static final String WALLET_WORKER_3 = "0x3a3406e69adf886c442ff1791cbf67cea679275d"; 37 | public static final String WALLET_WORKER_4 = "0x4aef50214110fdad4e8b9128347f2ba1ec72f614"; 38 | 39 | public static final String DAPP_NAME = "dappName"; 40 | public static final String COMMAND_LINE = "commandLine"; 41 | public static final String NO_TEE_TAG = BytesUtils.EMPTY_HEX_STRING_32; 42 | public static final String TEE_TAG = TeeUtils.TEE_SCONE_ONLY_TAG; //any supported TEE tag 43 | public static final String RESULT_LINK = "/ipfs/the_result_string"; 44 | 45 | public static Task getStubTask() { 46 | final Task task = new Task(CHAIN_DEAL_ID, 0, DAPP_NAME, COMMAND_LINE, 1, 60000, NO_TEE_TAG); 47 | task.setContributionDeadline(Date.from(Instant.now().plus(1, ChronoUnit.MINUTES))); 48 | task.setFinalDeadline(Date.from(Instant.now().plus(1, ChronoUnit.MINUTES))); 49 | return task; 50 | } 51 | 52 | public static Task getStubTask(TaskStatus status) { 53 | final Task task = getStubTask(); 54 | task.setCurrentStatus(status); 55 | task.getDateStatusList().add(TaskStatusChange.builder().status(status).build()); 56 | return task; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/chain/WalletConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain; 18 | 19 | import com.iexec.common.config.PublicChainConfig; 20 | import com.iexec.commons.poco.chain.SignerService; 21 | import org.junit.jupiter.api.Test; 22 | import org.junit.jupiter.api.io.TempDir; 23 | import org.springframework.boot.test.context.runner.ApplicationContextRunner; 24 | import org.web3j.crypto.WalletUtils; 25 | 26 | import java.io.File; 27 | import java.time.Duration; 28 | 29 | import static org.assertj.core.api.Assertions.assertThat; 30 | 31 | class WalletConfigurationTest { 32 | private final ApplicationContextRunner runner = new ApplicationContextRunner(); 33 | @TempDir 34 | private File tempWalletDir; 35 | 36 | @Test 37 | void shouldCreateBeans() throws Exception { 38 | final String tempWalletName = WalletUtils.generateFullNewWalletFile("changeit", tempWalletDir); 39 | final String tempWalletPath = tempWalletDir.getAbsolutePath() + File.separator + tempWalletName; 40 | runner.withPropertyValues("chain.node-address=http://localhost:8545", "chain.pool-address=0x1", "chain.start-block-number=0", "chain.gas-price-multiplier=1.0", "chain.gas-price-cap=0") 41 | .withBean(IexecHubService.class) 42 | .withBean(PublicChainConfig.class, 65535, true, "http://localhost:8545", "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca", Duration.ofSeconds(5)) 43 | .withBean(WalletConfiguration.class, tempWalletPath, "changeit") 44 | .withBean(Web3jService.class) 45 | .withUserConfiguration(ChainConfig.class) 46 | .run(context -> assertThat(context) 47 | .hasSingleBean(ChainConfig.class) 48 | .hasSingleBean(IexecHubService.class) 49 | .hasSingleBean(SignerService.class) 50 | .hasSingleBean(WalletConfiguration.class) 51 | .hasSingleBean(Web3jService.class)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/chain/adapter/BlockchainAdapterClientConfigTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.chain.adapter; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.junit.jupiter.api.Test; 21 | import org.junit.jupiter.api.extension.ExtendWith; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 24 | import org.springframework.context.ApplicationContext; 25 | import org.springframework.test.context.DynamicPropertyRegistry; 26 | import org.springframework.test.context.DynamicPropertySource; 27 | import org.springframework.test.context.junit.jupiter.SpringExtension; 28 | 29 | import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; 30 | import static org.junit.jupiter.api.Assertions.assertAll; 31 | 32 | @Slf4j 33 | @ExtendWith(SpringExtension.class) 34 | @EnableConfigurationProperties(value = BlockchainAdapterClientConfig.class) 35 | class BlockchainAdapterClientConfigTests { 36 | 37 | @Autowired 38 | private ApplicationContext context; 39 | 40 | @DynamicPropertySource 41 | static void registerProperties(DynamicPropertyRegistry registry) { 42 | registry.add("blockchain-adapter.url", () -> "http://localhost:13010"); 43 | registry.add("blockchain-adapter.auth.username", () -> "admin"); 44 | registry.add("blockchain-adapter.auth.password", () -> "whatever"); 45 | } 46 | 47 | @Test 48 | void shouldCreateBeanInstance() { 49 | assertAll( 50 | () -> assertThat(context.containsBean("blockchainAdapterClient")).isTrue(), 51 | () -> assertThat(context.containsBean("blockchainAdapterService")).isTrue() 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/config/OpenApiConfigTest.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.config; 2 | 3 | import io.swagger.v3.oas.models.OpenAPI; 4 | import io.swagger.v3.oas.models.info.Info; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.junit.jupiter.api.extension.ExtendWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration; 10 | import org.springframework.boot.info.BuildProperties; 11 | import org.springframework.context.annotation.Import; 12 | import org.springframework.test.context.junit.jupiter.SpringExtension; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | 16 | @ExtendWith(SpringExtension.class) 17 | @Import(ProjectInfoAutoConfiguration.class) 18 | class OpenApiConfigTest { 19 | 20 | @Autowired 21 | private BuildProperties buildProperties; 22 | 23 | private OpenApiConfig openApiConfig; 24 | 25 | @BeforeEach 26 | void setUp() { 27 | openApiConfig = new OpenApiConfig(buildProperties); 28 | } 29 | 30 | @Test 31 | void shouldReturnOpenAPIObjectWithCorrectInfo() { 32 | OpenAPI api = openApiConfig.api(); 33 | assertThat(api).isNotNull(). 34 | extracting(OpenAPI::getInfo).isNotNull(). 35 | extracting( 36 | Info::getVersion, 37 | Info::getTitle 38 | ) 39 | .containsExactly(buildProperties.getVersion(), OpenApiConfig.TITLE); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/configuration/ConfigServerClientConfigTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import com.iexec.common.config.PublicChainConfig; 20 | import lombok.extern.slf4j.Slf4j; 21 | import org.junit.jupiter.api.Test; 22 | import org.junit.jupiter.api.extension.ExtendWith; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 25 | import org.springframework.test.context.DynamicPropertyRegistry; 26 | import org.springframework.test.context.DynamicPropertySource; 27 | import org.springframework.test.context.junit.jupiter.SpringExtension; 28 | import org.testcontainers.containers.BindMode; 29 | import org.testcontainers.containers.GenericContainer; 30 | import org.testcontainers.junit.jupiter.Container; 31 | import org.testcontainers.junit.jupiter.Testcontainers; 32 | 33 | import java.time.Duration; 34 | 35 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; 36 | 37 | @Slf4j 38 | @ExtendWith(SpringExtension.class) 39 | @EnableConfigurationProperties(value = ConfigServerClientConfig.class) 40 | @Testcontainers 41 | class ConfigServerClientConfigTests { 42 | private static final int WIREMOCK_PORT = 8080; 43 | 44 | @Autowired 45 | private PublicChainConfig chainConfig; 46 | 47 | @Autowired 48 | private int getChainId; 49 | 50 | @Container 51 | static final GenericContainer wmServer = new GenericContainer<>("wiremock/wiremock:3.3.1") 52 | .withClasspathResourceMapping("wiremock", "/home/wiremock", BindMode.READ_ONLY) 53 | .withExposedPorts(WIREMOCK_PORT); 54 | 55 | @DynamicPropertySource 56 | static void registerProperties(DynamicPropertyRegistry registry) { 57 | registry.add("config-server.url", () -> "http://localhost:" + wmServer.getMappedPort(WIREMOCK_PORT)); 58 | } 59 | 60 | @Test 61 | void checkChainConfigInitialization() { 62 | PublicChainConfig expectedConfig = PublicChainConfig.builder() 63 | .chainId(65535) 64 | .sidechain(true) 65 | .iexecHubContractAddress("0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca") 66 | .blockTime(Duration.ofSeconds(5L)) 67 | .chainNodeUrl("http://localhost:8545") 68 | .build(); 69 | assertThat(chainConfig).isEqualTo(expectedConfig); 70 | } 71 | 72 | @Test 73 | void checkChainIdInitialization() { 74 | assertThat(getChainId).isEqualTo(65535); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/configuration/PublicConfigurationServiceTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.configuration; 18 | 19 | import com.iexec.commons.poco.chain.SignerService; 20 | import com.iexec.core.chain.ChainConfig; 21 | import org.junit.jupiter.api.Test; 22 | import org.junit.jupiter.api.extension.ExtendWith; 23 | import org.mockito.InjectMocks; 24 | import org.mockito.Mock; 25 | import org.mockito.junit.jupiter.MockitoExtension; 26 | 27 | import static org.junit.jupiter.api.Assertions.assertNotNull; 28 | import static org.junit.jupiter.api.Assertions.assertThrows; 29 | 30 | @ExtendWith(MockitoExtension.class) 31 | class PublicConfigurationServiceTests { 32 | @Mock 33 | private ChainConfig chainConfig; 34 | @Mock 35 | private SignerService signerService; 36 | @Mock 37 | private WorkerConfiguration workerConfiguration; 38 | @Mock 39 | private ResultRepositoryConfiguration resultRepoConfig; 40 | @Mock 41 | private ConfigServerClientConfig configServerClientConfig; 42 | 43 | @InjectMocks 44 | private PublicConfigurationService publicConfigurationService; 45 | 46 | // region getPublicConfiguration 47 | @Test 48 | void shouldGetPublicConfiguration() { 49 | // This would be done by Spring in production 50 | publicConfigurationService.buildPublicConfiguration(); 51 | 52 | assertNotNull(publicConfigurationService.getPublicConfiguration()); 53 | } 54 | 55 | @Test 56 | void shouldNotGetPublicConfigurationWhenNotInitialized() { 57 | assertThrows(IllegalArgumentException.class, publicConfigurationService::getPublicConfiguration); 58 | } 59 | // endregion 60 | 61 | // region getPublicConfiguration 62 | @Test 63 | void shouldGetPublicConfigurationHash() { 64 | // This would be done by Spring in production 65 | publicConfigurationService.buildPublicConfiguration(); 66 | 67 | assertNotNull(publicConfigurationService.getPublicConfigurationHash()); 68 | } 69 | 70 | @Test 71 | void shouldNotGetPublicConfigurationHashWhenNotInitialized() { 72 | assertThrows(IllegalArgumentException.class, publicConfigurationService::getPublicConfigurationHash); 73 | } 74 | // endregion 75 | } 76 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/configuration/PurgeConfigurationTests.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.configuration; 2 | 3 | import com.iexec.common.lifecycle.purge.PurgeService; 4 | import com.iexec.common.lifecycle.purge.Purgeable; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.*; 10 | import static org.mockito.Mockito.mock; 11 | 12 | class PurgeConfigurationTests { 13 | final PurgeConfiguration purgeConfiguration = new PurgeConfiguration(); 14 | 15 | @Test 16 | void createPurgeService() { 17 | final List purgeables = List.of( 18 | mock(Purgeable.class), 19 | mock(Purgeable.class), 20 | mock(Purgeable.class) 21 | ); 22 | final PurgeService purgeService = purgeConfiguration.purgeService(purgeables); 23 | assertNotNull(purgeService); 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/logs/ReplicateLogsCronServiceTests.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.logs; 2 | 3 | import static org.mockito.ArgumentMatchers.any; 4 | import static org.mockito.Mockito.verify; 5 | import static org.mockito.Mockito.when; 6 | 7 | import java.util.List; 8 | 9 | import com.iexec.core.task.TaskService; 10 | 11 | import org.junit.jupiter.api.BeforeEach; 12 | import org.junit.jupiter.api.Test; 13 | import org.mockito.InjectMocks; 14 | import org.mockito.Mock; 15 | import org.mockito.MockitoAnnotations; 16 | 17 | class ComputeLogsCronServiceTests { 18 | 19 | @Mock 20 | private TaskLogsService taskLogsService; 21 | 22 | @Mock 23 | private TaskService taskService; 24 | 25 | @InjectMocks 26 | private ComputeLogsCronService computeLogsCronService; 27 | 28 | @BeforeEach 29 | void init() { 30 | MockitoAnnotations.openMocks(this); 31 | } 32 | 33 | @Test 34 | void shouldCleanStdout() { 35 | List ids = List.of("id1", "id2"); 36 | when(taskService.getChainTaskIdsOfTasksExpiredBefore(any())) 37 | .thenReturn(ids); 38 | computeLogsCronService.purgeLogs(); 39 | verify(taskLogsService).delete(ids); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/metric/MetricControllerTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.metric; 18 | 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.api.extension.ExtendWith; 21 | import org.mockito.InjectMocks; 22 | import org.mockito.Mock; 23 | import org.mockito.junit.jupiter.MockitoExtension; 24 | import org.springframework.http.HttpStatus; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | import static org.mockito.Mockito.when; 28 | 29 | @ExtendWith(MockitoExtension.class) 30 | class MetricControllerTests { 31 | 32 | @Mock 33 | private MetricService metricService; 34 | 35 | @InjectMocks 36 | private MetricController metricController; 37 | 38 | @Test 39 | void shouldGetMetrics() { 40 | PlatformMetric metric = PlatformMetric.builder() 41 | .aliveRegisteredCpu(1) 42 | .aliveRegisteredCpu(1) 43 | .build(); 44 | when(metricService.getPlatformMetrics()).thenReturn(metric); 45 | assertThat(metricController.getPlatformMetric().getStatusCode()) 46 | .isEqualTo(HttpStatus.OK); 47 | assertThat(metricController.getPlatformMetric().getBody()) 48 | .isEqualTo(metric); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/pubsub/NotificationServiceTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.pubsub; 18 | 19 | import com.iexec.core.notification.TaskNotification; 20 | import org.junit.jupiter.api.BeforeEach; 21 | import org.junit.jupiter.api.Test; 22 | import org.mockito.*; 23 | import org.springframework.messaging.simp.SimpMessagingTemplate; 24 | 25 | class NotificationServiceTests { 26 | 27 | @Mock 28 | private SimpMessagingTemplate sender; 29 | 30 | @Spy 31 | @InjectMocks 32 | private NotificationService notificationService; 33 | 34 | @BeforeEach 35 | void init() { 36 | MockitoAnnotations.openMocks(this); 37 | } 38 | 39 | @Test 40 | void shouldSendTaskNotification() { 41 | String chainTaskId = "chainTaskId"; 42 | TaskNotification taskNotification = TaskNotification.builder() 43 | .chainTaskId(chainTaskId) 44 | .build(); 45 | 46 | notificationService.sendTaskNotification(taskNotification); 47 | 48 | String destination = "/topic/task/" + taskNotification.getChainTaskId(); 49 | 50 | Mockito.verify(sender, Mockito.times(1)) 51 | .convertAndSend(destination, taskNotification); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/registry/PlatformRegistryConfigurationTests.java: -------------------------------------------------------------------------------- 1 | package com.iexec.core.registry; 2 | 3 | import org.assertj.core.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.test.context.ContextConfiguration; 8 | import org.springframework.test.context.TestPropertySource; 9 | import org.springframework.test.context.junit.jupiter.SpringExtension; 10 | 11 | @ExtendWith(SpringExtension.class) 12 | @ContextConfiguration(classes = PlatformRegistryConfiguration.class) 13 | @TestPropertySource(properties = { 14 | "sms.scone=http://scone-sms", 15 | "sms.gramine=http://gramine-sms" 16 | }) 17 | class PlatformRegistryConfigurationTests { 18 | 19 | @Autowired 20 | PlatformRegistryConfiguration platformRegistryConfiguration; 21 | 22 | @Test 23 | void shouldGetValues() { 24 | Assertions.assertThat(platformRegistryConfiguration.getSconeSms()) 25 | .isEqualTo("http://scone-sms"); 26 | Assertions.assertThat(platformRegistryConfiguration.getGramineSms()) 27 | .isEqualTo("http://gramine-sms"); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/security/ChallengeServiceTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.security; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | class ChallengeServiceTests { 24 | 25 | private static final String WALLET_WORKER_1 = "0x1a69b2eb604db8eba185df03ea4f5288dcbbd248"; 26 | private static final String WALLET_WORKER_2 = "0x2a69b2eb604db8eba185df03ea4f5288dcbbd248"; 27 | 28 | private final ChallengeService challengeService = new ChallengeService(); 29 | 30 | @Test 31 | void shouldCreateNewChallengeAfterRemoval() { 32 | String challenge1 = challengeService.getChallenge(WALLET_WORKER_1); 33 | challengeService.removeChallenge(WALLET_WORKER_1, challenge1); 34 | String challenge2 = challengeService.getChallenge(WALLET_WORKER_1); 35 | assertThat(challenge1).isNotEqualTo(challenge2); 36 | } 37 | @Test 38 | void shouldGetSameChallengeForSameWallet() { 39 | String challenge1 = challengeService.getChallenge(WALLET_WORKER_1); 40 | String challenge2 = challengeService.getChallenge(WALLET_WORKER_1); 41 | assertThat(challenge1).isEqualTo(challenge2); 42 | } 43 | 44 | @Test 45 | void shouldGetDifferentChallengesForDifferentWallets() { 46 | String challenge1 = challengeService.getChallenge(WALLET_WORKER_1); 47 | String challenge2 = challengeService.getChallenge(WALLET_WORKER_2); 48 | assertThat(challenge1).isNotEqualTo(challenge2); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/security/EIP712ChallengeServiceTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.security; 18 | 19 | import com.iexec.commons.poco.eip712.entity.EIP712Challenge; 20 | import org.junit.jupiter.api.BeforeEach; 21 | import org.junit.jupiter.api.Test; 22 | import org.web3j.crypto.Keys; 23 | 24 | import static com.iexec.core.TestUtils.WALLET_WORKER_1; 25 | import static com.iexec.core.TestUtils.WALLET_WORKER_2; 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | class EIP712ChallengeServiceTests { 29 | 30 | private EIP712ChallengeService challengeService; 31 | 32 | @BeforeEach 33 | void preflight() { 34 | challengeService = new EIP712ChallengeService(1); 35 | } 36 | 37 | @Test 38 | void shouldGetSameChallengeForSameWallet() { 39 | final EIP712Challenge challenge1 = challengeService.getChallenge(WALLET_WORKER_1); 40 | final EIP712Challenge challenge2 = challengeService.getChallenge(WALLET_WORKER_1); 41 | assertThat(challenge1).usingRecursiveComparison().isEqualTo(challenge2); 42 | } 43 | 44 | @Test 45 | void shouldGetSameChallengeWithChecksumWallet() { 46 | final String checksumWallet = Keys.toChecksumAddress(WALLET_WORKER_1); 47 | assertThat(checksumWallet).isNotEqualTo(WALLET_WORKER_1); 48 | assertThat(challengeService.getChallenge(checksumWallet)) 49 | .usingRecursiveComparison() 50 | .isEqualTo(challengeService.getChallenge(WALLET_WORKER_1)); 51 | } 52 | 53 | @Test 54 | void shouldGetSameChallengeWithUppercaseWallet() { 55 | final String upperCaseWalletAddress = WALLET_WORKER_1.substring(2).toUpperCase(); // 0x prefix removal 56 | assertThat(upperCaseWalletAddress).isNotEqualTo(WALLET_WORKER_1); 57 | assertThat(challengeService.getChallenge(upperCaseWalletAddress)) 58 | .usingRecursiveComparison() 59 | .isEqualTo(challengeService.getChallenge(WALLET_WORKER_1)); 60 | } 61 | 62 | @Test 63 | void shouldGetDifferentChallengesForDifferentWallets() { 64 | final EIP712Challenge challenge1 = challengeService.getChallenge(WALLET_WORKER_1); 65 | final EIP712Challenge challenge2 = challengeService.getChallenge(WALLET_WORKER_2); 66 | assertThat(challenge1).usingRecursiveComparison().isNotEqualTo(challenge2); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/task/TaskTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.task; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import java.time.Instant; 22 | import java.time.temporal.ChronoUnit; 23 | import java.util.Date; 24 | 25 | import static com.iexec.core.TestUtils.COMMAND_LINE; 26 | import static com.iexec.core.TestUtils.DAPP_NAME; 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | class TaskTests { 30 | 31 | @Test 32 | void shouldInitializeProperly() { 33 | Task task = new Task(DAPP_NAME, COMMAND_LINE, 2); 34 | 35 | assertThat(task.getDateStatusList()).hasSize(1); 36 | assertThat(task.getDateStatusList().get(0).getStatus()).isEqualTo(TaskStatus.RECEIVED); 37 | } 38 | 39 | @Test 40 | void shouldContributionDeadlineBeReached() { 41 | Task task = new Task(); 42 | // contribution deadline in the past 43 | task.setContributionDeadline(Date.from(Instant.now().minus(60L, ChronoUnit.MINUTES))); 44 | assertThat(task.isContributionDeadlineReached()).isTrue(); 45 | } 46 | 47 | @Test 48 | void shouldContributionDeadlineNotBeReached() { 49 | Task task = new Task(); 50 | // contribution deadline in the future 51 | task.setContributionDeadline(Date.from(Instant.now().plus(60L, ChronoUnit.MINUTES))); 52 | assertThat(task.isContributionDeadlineReached()).isFalse(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/worker/WorkerUtilsTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-2024 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.worker; 18 | 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.api.extension.ExtendWith; 21 | import org.junit.jupiter.params.ParameterizedTest; 22 | import org.junit.jupiter.params.provider.NullSource; 23 | import org.junit.jupiter.params.provider.ValueSource; 24 | import org.springframework.boot.test.system.CapturedOutput; 25 | import org.springframework.boot.test.system.OutputCaptureExtension; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | @ExtendWith(OutputCaptureExtension.class) 30 | class WorkerUtilsTests { 31 | 32 | @Test 33 | void testEmitOnErrorWithWorkerAddress(CapturedOutput output) { 34 | final String workerAddress = "0x9d693a8fd049c607a6"; 35 | WorkerUtils.emitWarnOnUnAuthorizedAccess(workerAddress); 36 | assertThat(output.getOut()).contains("Worker is not allowed to join this workerpool [workerAddress:0x9d693a8fd049c607a6]"); 37 | } 38 | 39 | @ParameterizedTest 40 | @NullSource 41 | @ValueSource(strings = {""}) 42 | void testEmitOnErrorWithEmptyWorkerAddress(String value, CapturedOutput output) { 43 | WorkerUtils.emitWarnOnUnAuthorizedAccess(value); 44 | assertThat(output.getOut()).contains("Worker is not allowed to join this workerpool [workerAddress:NotAvailable]"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/workflow/DummyWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.workflow; 18 | 19 | class DummyWorkflow extends Workflow{ 20 | 21 | private static DummyWorkflow instance; 22 | 23 | static synchronized DummyWorkflow getInstance() { 24 | if (instance == null) { 25 | instance = new DummyWorkflow(); 26 | } 27 | return instance; 28 | } 29 | 30 | private DummyWorkflow() { 31 | super(); 32 | 33 | // This is where the whole workflow is defined 34 | // 1 -- 2 -- [3, 4] -- 5 35 | addTransition("STATUS_1", "STATUS_2"); 36 | 37 | addTransition("STATUS_2", "STATUS_3"); 38 | addTransition("STATUS_2", "STATUS_4"); 39 | 40 | addTransition("STATUS_3", "STATUS_5"); 41 | addTransition("STATUS_4", "STATUS_5"); 42 | } 43 | } -------------------------------------------------------------------------------- /src/test/java/com/iexec/core/workflow/WorkflowTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 IEXEC BLOCKCHAIN TECH 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.iexec.core.workflow; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | class WorkflowTests { 24 | 25 | 26 | 27 | @Test 28 | void shouldAllBeValidTransitions(){ 29 | // test simple case 30 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_1", "STATUS_2")).isTrue(); 31 | 32 | // test multiple targets 33 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_2", "STATUS_3")).isTrue(); 34 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_2", "STATUS_4")).isTrue(); 35 | 36 | // test same 'to' state 37 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_3", "STATUS_5")).isTrue(); 38 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_4", "STATUS_5")).isTrue(); 39 | } 40 | 41 | @Test 42 | void shouldAllBeUnvalidTransitions(){ 43 | // test non existing transition 44 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_1", "STATUS_3")).isFalse(); 45 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_1", "STATUS_5")).isFalse(); 46 | 47 | // test reverse transition 48 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_2", "STATUS_1")).isFalse(); 49 | 50 | // test non existing state 51 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_1", "DUMMY")).isFalse(); 52 | assertThat(DummyWorkflow.getInstance().isValidTransition("DUMMY", "STATUS_2")).isFalse(); 53 | } 54 | 55 | @Test 56 | void shouldAllBorderCasesBeUnvalid(){ 57 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_1", "")).isFalse(); 58 | assertThat(DummyWorkflow.getInstance().isValidTransition("", "STATUS_2")).isFalse(); 59 | 60 | assertThat(DummyWorkflow.getInstance().isValidTransition("STATUS_2", null)).isFalse(); 61 | assertThat(DummyWorkflow.getInstance().isValidTransition(null, "STATUS_2")).isFalse(); 62 | 63 | assertThat(DummyWorkflow.getInstance().isValidTransition(null, null)).isFalse(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /src/test/resources/wiremock/mappings/chain-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "request": { 3 | "method": "GET", 4 | "url": "/config/chain" 5 | }, 6 | "response": { 7 | "status": 200, 8 | "body": "{\"chainId\":65535,\"sidechain\":\"true\",\"iexecHubContractAddress\":\"0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca\",\"blockTime\":\"PT5s\",\"chainNodeUrl\":\"http://localhost:8545\"}", 9 | "headers": { 10 | "Content-Type": "application/json" 11 | } 12 | } 13 | } 14 | --------------------------------------------------------------------------------