diff --git a/src/main/java/com/iexec/commons/poco/chain/SignerService.java b/src/main/java/com/iexec/commons/poco/chain/SignerService.java index 9ea109a..fe8d266 100644 --- a/src/main/java/com/iexec/commons/poco/chain/SignerService.java +++ b/src/main/java/com/iexec/commons/poco/chain/SignerService.java @@ -16,7 +16,10 @@ package com.iexec.commons.poco.chain; +import com.iexec.commons.poco.eip712.EIP712Domain; import com.iexec.commons.poco.eip712.EIP712Entity; +import com.iexec.commons.poco.eip712.EIP712TypedData; +import com.iexec.commons.poco.order.Order; import com.iexec.commons.poco.security.Signature; import com.iexec.commons.poco.utils.BytesUtils; import com.iexec.commons.poco.utils.EthAddress; @@ -111,6 +114,10 @@ public Signature signMessageHash(String messageHash) { return SignatureUtils.signMessageHashAndGetSignature(messageHash, credentials.getEcKeyPair()); } + /** + * @deprecated use signTypedDataForDomain instead + */ + @Deprecated(forRemoval = true) public String signEIP712Entity(EIP712Entity eip712Entity) { final String signature = eip712Entity.signMessage(credentials.getEcKeyPair()); if (StringUtils.isEmpty(signature)) { @@ -120,6 +127,23 @@ public String signEIP712Entity(EIP712Entity eip712Entity) { return signature; } + /** + * Hashes and signs structured type data following EIP-712 + * + * @param typedData structured data implementing {@link EIP712TypedData} to hash and sign + * @param domain EIP712 domain describing the target for which the data is hashed and signed + * @return a valid signature + * @see EIP-712 + */ + public String signTypedDataForDomain(final EIP712TypedData typedData, final EIP712Domain domain) { + return typedData.sign(credentials.getEcKeyPair(), domain); + } + + public Order signOrderForDomain(final Order order, final EIP712Domain domain) { + final String sig = signTypedDataForDomain(order, domain); + return order.withSignature(sig); + } + /** * Builds an authorization token for given {@link EIP712Entity}. *

diff --git a/src/main/java/com/iexec/commons/poco/eip712/EIP712Entity.java b/src/main/java/com/iexec/commons/poco/eip712/EIP712Entity.java index 2986869..7fb1d6e 100644 --- a/src/main/java/com/iexec/commons/poco/eip712/EIP712Entity.java +++ b/src/main/java/com/iexec/commons/poco/eip712/EIP712Entity.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +/** + * @deprecated implements {@code EIP712TypedData} interface instead + */ +@Deprecated(forRemoval = true) @Slf4j @NoArgsConstructor public abstract class EIP712Entity implements EIP712 { diff --git a/src/main/java/com/iexec/commons/poco/eip712/EIP712TypedData.java b/src/main/java/com/iexec/commons/poco/eip712/EIP712TypedData.java new file mode 100644 index 0000000..2573d61 --- /dev/null +++ b/src/main/java/com/iexec/commons/poco/eip712/EIP712TypedData.java @@ -0,0 +1,45 @@ +/* + * Copyright 2025 IEXEC BLOCKCHAIN TECH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.iexec.commons.poco.eip712; + +import com.iexec.commons.poco.utils.HashUtils; +import com.iexec.commons.poco.utils.SignatureUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.web3j.crypto.ECKeyPair; + +public interface EIP712TypedData { + Logger log = LoggerFactory.getLogger(EIP712TypedData.class); + + default String computeHash(final EIP712Domain domain) { + final String domainSeparator = domain.getDomainSeparator(); + final String messageHash = computeMessageHash(); + final String hash = HashUtils.concatenateAndHash("0x1901", domainSeparator, messageHash); + if (log.isDebugEnabled()) { + log.debug("domainSeparator {}", domainSeparator); + log.debug("messageHash {}", messageHash); + log.debug("hash {}", hash); + } + return hash; + } + + String computeMessageHash(); + + default String sign(final ECKeyPair ecKeyPair, final EIP712Domain domain) { + return SignatureUtils.signAsString(computeHash(domain), ecKeyPair); + } +} diff --git a/src/main/java/com/iexec/commons/poco/order/AppOrder.java b/src/main/java/com/iexec/commons/poco/order/AppOrder.java index debd90f..18a2aad 100644 --- a/src/main/java/com/iexec/commons/poco/order/AppOrder.java +++ b/src/main/java/com/iexec/commons/poco/order/AppOrder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,18 +19,25 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.eip712.EIP712Utils; +import com.iexec.commons.poco.utils.HashUtils; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Value; +import lombok.extern.slf4j.Slf4j; import org.web3j.utils.Numeric; import java.math.BigInteger; +import java.util.stream.Stream; +@Slf4j @Value @EqualsAndHashCode(callSuper = true) @JsonDeserialize(builder = AppOrder.AppOrderBuilder.class) public class AppOrder extends Order { + private static final String EIP712_TYPE = "AppOrder(address app,uint256 appprice,uint256 volume,bytes32 tag,address datasetrestrict,address workerpoolrestrict,address requesterrestrict,bytes32 salt)"; + String app; BigInteger appprice; String datasetrestrict; @@ -70,6 +77,25 @@ public AppOrder withSignature(String signature) { ); } + // region EIP-712 + public String computeMessageHash() { + final String[] encodedValues = Stream.of(EIP712_TYPE, app, appprice, volume, tag, datasetrestrict, workerpoolrestrict, requesterrestrict, salt) + .map(EIP712Utils::encodeData) + .toArray(String[]::new); + if (log.isDebugEnabled()) { + log.debug("{}", EIP712_TYPE); + for (String value : encodedValues) { + log.debug("{}", value); + } + } + return HashUtils.concatenateAndHash(encodedValues); + } + // endregion + + /** + * @deprecated no more used + */ + @Deprecated(forRemoval = true) public IexecHubContract.AppOrder toHubContract() { return new IexecHubContract.AppOrder( this.app, diff --git a/src/main/java/com/iexec/commons/poco/order/DatasetOrder.java b/src/main/java/com/iexec/commons/poco/order/DatasetOrder.java index 75765d2..93c9673 100644 --- a/src/main/java/com/iexec/commons/poco/order/DatasetOrder.java +++ b/src/main/java/com/iexec/commons/poco/order/DatasetOrder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,18 +19,25 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.eip712.EIP712Utils; +import com.iexec.commons.poco.utils.HashUtils; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Value; +import lombok.extern.slf4j.Slf4j; import org.web3j.utils.Numeric; import java.math.BigInteger; +import java.util.stream.Stream; +@Slf4j @Value @EqualsAndHashCode(callSuper = true) @JsonDeserialize(builder = DatasetOrder.DatasetOrderBuilder.class) public class DatasetOrder extends Order { + private static final String EIP712_TYPE = "DatasetOrder(address dataset,uint256 datasetprice,uint256 volume,bytes32 tag,address apprestrict,address workerpoolrestrict,address requesterrestrict,bytes32 salt)"; + String dataset; BigInteger datasetprice; String apprestrict; @@ -69,6 +76,25 @@ public DatasetOrder withSignature(String signature) { ); } + // region EIP-712 + public String computeMessageHash() { + final String[] encodedValues = Stream.of(EIP712_TYPE, dataset, datasetprice, volume, tag, apprestrict, workerpoolrestrict, requesterrestrict, salt) + .map(EIP712Utils::encodeData) + .toArray(String[]::new); + if (log.isDebugEnabled()) { + log.debug("{}", EIP712_TYPE); + for (String value : encodedValues) { + log.debug("{}", value); + } + } + return HashUtils.concatenateAndHash(encodedValues); + } + // endregion + + /** + * @deprecated no more used + */ + @Deprecated(forRemoval = true) public IexecHubContract.DatasetOrder toHubContract() { return new IexecHubContract.DatasetOrder( this.dataset, diff --git a/src/main/java/com/iexec/commons/poco/order/Order.java b/src/main/java/com/iexec/commons/poco/order/Order.java index b7580fa..66afa18 100644 --- a/src/main/java/com/iexec/commons/poco/order/Order.java +++ b/src/main/java/com/iexec/commons/poco/order/Order.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,18 @@ package com.iexec.commons.poco.order; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.iexec.commons.poco.eip712.EIP712TypedData; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import java.math.BigInteger; +@Slf4j @Getter @AllArgsConstructor(access = AccessLevel.PROTECTED) -public abstract class Order { +public abstract class Order implements EIP712TypedData { protected final BigInteger volume; protected final String tag; diff --git a/src/main/java/com/iexec/commons/poco/order/RequestOrder.java b/src/main/java/com/iexec/commons/poco/order/RequestOrder.java index 0172083..8cc673d 100644 --- a/src/main/java/com/iexec/commons/poco/order/RequestOrder.java +++ b/src/main/java/com/iexec/commons/poco/order/RequestOrder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,18 +19,25 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.eip712.EIP712Utils; +import com.iexec.commons.poco.utils.HashUtils; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Value; +import lombok.extern.slf4j.Slf4j; import org.web3j.utils.Numeric; import java.math.BigInteger; +import java.util.stream.Stream; +@Slf4j @Value @EqualsAndHashCode(callSuper = true) @JsonDeserialize(builder = RequestOrder.RequestOrderBuilder.class) public class RequestOrder extends Order { + private static final String EIP712_TYPE = "RequestOrder(address app,uint256 appmaxprice,address dataset,uint256 datasetmaxprice,address workerpool,uint256 workerpoolmaxprice,address requester,uint256 volume,bytes32 tag,uint256 category,uint256 trust,address beneficiary,address callback,string params,bytes32 salt)"; + String app; BigInteger appmaxprice; String dataset; @@ -92,6 +99,25 @@ public RequestOrder withSignature(String signature) { ); } + // region EIP-712 + public String computeMessageHash() { + final String[] encodedValues = Stream.of(EIP712_TYPE, app, appmaxprice, dataset, datasetmaxprice, workerpool, workerpoolmaxprice, requester, volume, tag, category, trust, beneficiary, callback, params, salt) + .map(EIP712Utils::encodeData) + .toArray(String[]::new); + if (log.isDebugEnabled()) { + log.debug("{}", EIP712_TYPE); + for (String value : encodedValues) { + log.debug("{}", value); + } + } + return HashUtils.concatenateAndHash(encodedValues); + } + // endregion + + /** + * @deprecated no more used + */ + @Deprecated(forRemoval = true) public IexecHubContract.RequestOrder toHubContract() { return new IexecHubContract.RequestOrder( this.app, diff --git a/src/main/java/com/iexec/commons/poco/order/WorkerpoolOrder.java b/src/main/java/com/iexec/commons/poco/order/WorkerpoolOrder.java index 30cfbc7..53e06ee 100644 --- a/src/main/java/com/iexec/commons/poco/order/WorkerpoolOrder.java +++ b/src/main/java/com/iexec/commons/poco/order/WorkerpoolOrder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 IEXEC BLOCKCHAIN TECH + * Copyright 2020-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,20 +19,25 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.eip712.EIP712Utils; +import com.iexec.commons.poco.utils.HashUtils; import lombok.Builder; import lombok.EqualsAndHashCode; -import lombok.ToString; import lombok.Value; +import lombok.extern.slf4j.Slf4j; import org.web3j.utils.Numeric; import java.math.BigInteger; +import java.util.stream.Stream; +@Slf4j @Value @EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) @JsonDeserialize(builder = WorkerpoolOrder.WorkerpoolOrderBuilder.class) public class WorkerpoolOrder extends Order { + private static final String EIP712_TYPE = "WorkerpoolOrder(address workerpool,uint256 workerpoolprice,uint256 volume,bytes32 tag,uint256 category,uint256 trust,address apprestrict,address datasetrestrict,address requesterrestrict,bytes32 salt)"; + String workerpool; BigInteger workerpoolprice; BigInteger trust; @@ -78,6 +83,25 @@ public WorkerpoolOrder withSignature(String signature) { ); } + // region EIP-712 + public String computeMessageHash() { + final String[] encodedValues = Stream.of(EIP712_TYPE, workerpool, workerpoolprice, volume, tag, category, trust, apprestrict, datasetrestrict, requesterrestrict, salt) + .map(EIP712Utils::encodeData) + .toArray(String[]::new); + if (log.isDebugEnabled()) { + log.debug("{}", EIP712_TYPE); + for (String value : encodedValues) { + log.debug("{}", value); + } + } + return HashUtils.concatenateAndHash(encodedValues); + } + // endregion + + /** + * @deprecated no more used + */ + @Deprecated(forRemoval = true) public IexecHubContract.WorkerpoolOrder toHubContract() { return new IexecHubContract.WorkerpoolOrder( this.workerpool, diff --git a/src/test/java/com/iexec/commons/poco/itest/OrdersService.java b/src/test/java/com/iexec/commons/poco/itest/OrdersService.java index 5e844b6..bdeeffa 100644 --- a/src/test/java/com/iexec/commons/poco/itest/OrdersService.java +++ b/src/test/java/com/iexec/commons/poco/itest/OrdersService.java @@ -19,10 +19,6 @@ import com.iexec.commons.poco.chain.DealParams; import com.iexec.commons.poco.chain.SignerService; import com.iexec.commons.poco.eip712.EIP712Domain; -import com.iexec.commons.poco.eip712.entity.EIP712AppOrder; -import com.iexec.commons.poco.eip712.entity.EIP712DatasetOrder; -import com.iexec.commons.poco.eip712.entity.EIP712RequestOrder; -import com.iexec.commons.poco.eip712.entity.EIP712WorkerpoolOrder; import com.iexec.commons.poco.encoding.MatchOrdersDataEncoder; import com.iexec.commons.poco.order.*; import com.iexec.commons.poco.utils.BytesUtils; @@ -64,8 +60,7 @@ public AppOrder buildSignedAppOrder(String appAddress) { .requesterrestrict(BytesUtils.EMPTY_ADDRESS) .salt(Hash.sha3String(RandomStringUtils.randomAlphanumeric(20))) .build(); - final String sig = signerService.signEIP712Entity(new EIP712AppOrder(domain, appOrder)); - return appOrder.withSignature(sig); + return (AppOrder) signerService.signOrderForDomain(appOrder, domain); } public DatasetOrder buildSignedDatasetOrder(String datasetAddress) { @@ -79,8 +74,7 @@ public DatasetOrder buildSignedDatasetOrder(String datasetAddress) { .requesterrestrict(BytesUtils.EMPTY_ADDRESS) .salt(Hash.sha3String(RandomStringUtils.randomAlphanumeric(20))) .build(); - final String sig = signerService.signEIP712Entity(new EIP712DatasetOrder(domain, datasetOrder)); - return datasetOrder.withSignature(sig); + return (DatasetOrder) signerService.signOrderForDomain(datasetOrder, domain); } public WorkerpoolOrder buildSignedWorkerpoolOrder(String workerpoolAddress, BigInteger trust) { @@ -96,8 +90,7 @@ public WorkerpoolOrder buildSignedWorkerpoolOrder(String workerpoolAddress, BigI .requesterrestrict(BytesUtils.EMPTY_ADDRESS) .salt(Hash.sha3String(RandomStringUtils.randomAlphanumeric(20))) .build(); - final String sig = signerService.signEIP712Entity(new EIP712WorkerpoolOrder(domain, workerpoolOrder)); - return workerpoolOrder.withSignature(sig); + return (WorkerpoolOrder) signerService.signOrderForDomain(workerpoolOrder, domain); } public RequestOrder buildSignedRequestOrder(AppOrder appOrder, DatasetOrder datasetOrder, WorkerpoolOrder workerpoolOrder, BigInteger trust) { @@ -128,8 +121,7 @@ public RequestOrder buildSignedRequestOrder(AppOrder appOrder, DatasetOrder data .params(dealParams.toJsonString()) .salt(Hash.sha3String(RandomStringUtils.randomAlphanumeric(20))) .build(); - final String sig = signerService.signEIP712Entity(new EIP712RequestOrder(domain, requestOrder)); - return requestOrder.withSignature(sig); + return (RequestOrder) signerService.signOrderForDomain(requestOrder, domain); } public DealOrders buildAllSignedOrders(final String appAddress, final String datasetAddress, final String workerpoolAddress, final BigInteger trust) { diff --git a/src/test/java/com/iexec/commons/poco/order/AppOrderTests.java b/src/test/java/com/iexec/commons/poco/order/AppOrderTests.java index 3678bc7..7d882c5 100644 --- a/src/test/java/com/iexec/commons/poco/order/AppOrderTests.java +++ b/src/test/java/com/iexec/commons/poco/order/AppOrderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 IEXEC BLOCKCHAIN TECH + * Copyright 2023-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.iexec.commons.poco.chain.SignerService; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.eip712.EIP712Domain; import com.iexec.commons.poco.utils.BytesUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; @@ -81,4 +83,24 @@ void shouldCastToHubContract() { ); } + @Test + void shouldSignAppOrder() throws Exception { + final int chainId = 133; + final String walletPath = getClass().getClassLoader().getResource("wallet.json").getPath(); + final SignerService signer = new SignerService(null, chainId, "whatever", walletPath); + final AppOrder appOrder = AppOrder.builder() + .app("0x2EbD509d777B187E8394566bA6ec093B9dd73DF1") + .appprice(BigInteger.ZERO) + .volume(BigInteger.ONE) + .tag("0x0000000000000000000000000000000000000000000000000000000000000000") + .datasetrestrict(BytesUtils.EMPTY_ADDRESS) + .workerpoolrestrict(BytesUtils.EMPTY_ADDRESS) + .requesterrestrict(BytesUtils.EMPTY_ADDRESS) + .salt("0xbe858b0eee90cf2e85297bd3df81373f6b4de20c67a3e1f5db1a9d5be8abc3c4") + .build(); + final EIP712Domain domain = new EIP712Domain(chainId, "0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f"); + final AppOrder signedOrder = (AppOrder) signer.signOrderForDomain(appOrder, domain); + assertThat(signedOrder.getSign()).isEqualTo("0x82c2d8a5f59f1088eb0b9a627c367ae7dae1772c8bd98c394699ae24830611e1171026f4e28d2c60302c34a04c60c4fc2f1363e165072dca04a9f203734978671c"); + } + } diff --git a/src/test/java/com/iexec/commons/poco/order/DatasetOrderTests.java b/src/test/java/com/iexec/commons/poco/order/DatasetOrderTests.java index a103eb8..b4fb892 100644 --- a/src/test/java/com/iexec/commons/poco/order/DatasetOrderTests.java +++ b/src/test/java/com/iexec/commons/poco/order/DatasetOrderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 IEXEC BLOCKCHAIN TECH + * Copyright 2023-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.iexec.commons.poco.chain.SignerService; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.eip712.EIP712Domain; import com.iexec.commons.poco.utils.BytesUtils; import org.apache.commons.lang3.RandomStringUtils; import org.assertj.core.api.Assertions; @@ -80,4 +82,24 @@ void shouldCastToHubContract() { ); } + @Test + void shouldSignDatasetOrder() throws Exception { + final int chainId = 133; + final String walletPath = getClass().getClassLoader().getResource("wallet.json").getPath(); + final SignerService signer = new SignerService(null, chainId, "whatever", walletPath); + final DatasetOrder datasetOrder = DatasetOrder.builder() + .dataset("0x2550E5B60f48742aBce2275F34417e7cBf5AcA86") + .datasetprice(BigInteger.valueOf(0)) + .volume(BigInteger.valueOf(1000000)) + .tag("0x0000000000000000000000000000000000000000000000000000000000000001") + .apprestrict(BytesUtils.EMPTY_ADDRESS) + .workerpoolrestrict(BytesUtils.EMPTY_ADDRESS) + .requesterrestrict(BytesUtils.EMPTY_ADDRESS) + .salt("0xc49d07f99c47096900653b6ade4ccde4c52f773a5ad68f1da0a47c993cad4595") + .build(); + final EIP712Domain domain = new EIP712Domain(chainId, "0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f"); + final DatasetOrder signedOrder = (DatasetOrder) signer.signOrderForDomain(datasetOrder, domain); + assertThat(signedOrder.getSign()).isEqualTo("0x94661cab25380e7a6e1c20762988f6f854c5123a17ad27c65580d7c3edcfa2025a9d255c679c4cf7d489560917c17d3af3da83737b3722824918d39aecfedf711c"); + } + } diff --git a/src/test/java/com/iexec/commons/poco/order/RequestOrderTests.java b/src/test/java/com/iexec/commons/poco/order/RequestOrderTests.java index 2b828e6..0da948e 100644 --- a/src/test/java/com/iexec/commons/poco/order/RequestOrderTests.java +++ b/src/test/java/com/iexec/commons/poco/order/RequestOrderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 IEXEC BLOCKCHAIN TECH + * Copyright 2023-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.iexec.commons.poco.chain.SignerService; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.eip712.EIP712Domain; import com.iexec.commons.poco.utils.BytesUtils; import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.Test; @@ -98,4 +100,31 @@ void shouldCastToHubContract() { ); } + @Test + void shouldSignRequestOrder() throws Exception { + final int chainId = 133; + final String walletPath = getClass().getClassLoader().getResource("wallet.json").getPath(); + final SignerService signer = new SignerService(null, chainId, "whatever", walletPath); + final RequestOrder requestOrder = RequestOrder.builder() + .app("0x6709CAe77CDa2cbA8Cb90A4F5a4eFfb5c8Fe8367") + .appmaxprice(BigInteger.ZERO) + .dataset(BytesUtils.EMPTY_ADDRESS) + .datasetmaxprice(BigInteger.ZERO) + .workerpool("0x506fA5EaCa52B5d2F133452a45FFA68aD1CfB3C5") + .workerpoolmaxprice(BigInteger.ZERO) + .requester("0x1ec09e1782a43a770d54e813379c730e0b29ad4b") + .volume(BigInteger.ONE) + .tag(BytesUtils.toByte32HexString(0x1)) // any tag here + .category(BigInteger.ZERO) + .trust(BigInteger.ZERO) + .beneficiary(BytesUtils.EMPTY_ADDRESS) + .callback(BytesUtils.EMPTY_ADDRESS) + .params("{\"iexec_tee_post_compute_fingerprint\":\"76bfdee97e692b729e989694f3a566cf0e1de95fc456ff5ee88c75b1cb865e33|1eb627c1c94bbca03178b099b13fb4d1|13076027fc67accba753a3ed2edf03227dfd013b450d68833a5589ec44132100\",\"iexec_tee_post_compute_image\":\"iexechub/tee-worker-post-compute:1.0.0\",\"iexec_result_storage_provider\":\"ipfs\",\"iexec_result_storage_proxy\":\"https://result.viviani.iex.ec\",\"iexec_result_encryption\":false,\"iexec_input_files\":[],\"iexec_args\":\"Alice\"}") + .salt("0xee5c64cd59eaa084f59dbaa8f20b87260c4d6ac35c83214da657681bfe4e7632") + .build(); + final EIP712Domain domain = new EIP712Domain(chainId, "0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f"); + final RequestOrder signedOrder = (RequestOrder) signer.signOrderForDomain(requestOrder, domain); + assertThat(signedOrder.getSign()).isEqualTo("0x611511fa5169dff40f7b4c0013e9f149e79dfddacd80a19852a1e9b42294eaef4329367f01eb48930f990a418befed0c5634e493809f2e9a6a60727137964df51c"); + } + } diff --git a/src/test/java/com/iexec/commons/poco/order/WorkerpoolOrderTests.java b/src/test/java/com/iexec/commons/poco/order/WorkerpoolOrderTests.java index f3534fa..9ee3f62 100644 --- a/src/test/java/com/iexec/commons/poco/order/WorkerpoolOrderTests.java +++ b/src/test/java/com/iexec/commons/poco/order/WorkerpoolOrderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 IEXEC BLOCKCHAIN TECH + * Copyright 2023-2025 IEXEC BLOCKCHAIN TECH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.iexec.commons.poco.chain.SignerService; import com.iexec.commons.poco.contract.generated.IexecHubContract; +import com.iexec.commons.poco.eip712.EIP712Domain; import com.iexec.commons.poco.utils.BytesUtils; import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.Test; @@ -85,4 +87,26 @@ void shouldCastToHubContract() { ); } + @Test + void shouldSignWorkerpoolOrder() throws Exception { + final int chainId = 133; + final String walletPath = getClass().getClassLoader().getResource("wallet.json").getPath(); + final SignerService signer = new SignerService(null, chainId, "whatever", walletPath); + final WorkerpoolOrder workerpoolOrder = WorkerpoolOrder.builder() + .workerpool("0x53Ef1328a96E40E125bca15b9a4da045C5e63E1A") + .workerpoolprice(BigInteger.ZERO) + .volume(BigInteger.ONE) + .tag("0x0000000000000000000000000000000000000000000000000000000000000000") + .category(BigInteger.ZERO) + .trust(BigInteger.ZERO) + .datasetrestrict(BytesUtils.EMPTY_ADDRESS) + .apprestrict(BytesUtils.EMPTY_ADDRESS) + .requesterrestrict(BytesUtils.EMPTY_ADDRESS) + .salt("0x40af1a4975ca6ca7285d7738e51c8da91a9daee4a23fb45d105068be56f85e56") + .build(); + final EIP712Domain domain = new EIP712Domain(chainId, "0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f"); + final WorkerpoolOrder signedOrder = (WorkerpoolOrder) signer.signOrderForDomain(workerpoolOrder, domain); + assertThat(signedOrder.getSign()).isEqualTo("0x18bb5dbf608ade315c9e81f0b89929a93aa36aee0a1d51e9119c66799af126596c6cfd1e676ea394e346c616710a675388d5b270a195e494e75d107c87a45dce1c"); + } + } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 49f9db6..bcb42fe 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -1,27 +1,4 @@ - - - - - - - @@ -32,4 +9,6 @@ + +