Skip to content

Commit d05cb46

Browse files
authored
Harmonize YML internal variables to proper case (#299)
1 parent fb432c2 commit d05cb46

File tree

8 files changed

+295
-14
lines changed

8 files changed

+295
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file.
1919
- Remove deprecated code from `AppComputeSecretController` and `SmsClient`. (#293)
2020
- Rename `blockchain` package to `chain` and `BlockchainConfig` class to `ChainConfig`. (#294)
2121
- Fix several SonarQube Cloud issues. (#295)
22+
- Harmonize YML internal variables to proper case. (#299)
2223

2324
### Breaking API changes
2425

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ To support:
5656
| `IEXEC_SMS_ADMIN_STORAGE_LOCATION` | Storage location where to persist replicated backups. It must be an absolute directory path. | String | `/backup` | `/backup` |
5757
| `IEXEC_CHAIN_ID` | Chain ID of the blockchain network to connect. | Positive integer | `134` | `134` |
5858
| `IEXEC_IS_SIDECHAIN` | Define whether iExec on-chain protocol is built on top of token (`false`) or native currency (`true`). | Boolean | `true` | `true` |
59-
| `IEXEC_SMS_BLOCKCHAIN_NODE_ADDRESS` | URL to connect to the blockchain node. | URL | `https://bellecour.iex.ec` | `https://bellecour.iex.ec` |
59+
| `IEXEC_BLOCKCHAIN_NODE_ADDRESS` | URL to connect to the blockchain node. | URL | `https://bellecour.iex.ec` | `https://bellecour.iex.ec` |
6060
| `IEXEC_HUB_ADDRESS` | Proxy contract address to interact with the iExec on-chain protocol. | String | `0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f` | `0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f` |
6161
| `IEXEC_BLOCK_TIME` | Duration between consecutive blocks on the blockchain network. | String | `PT5S` | `PT5S` |
6262
| `IEXEC_GAS_PRICE_MULTIPLIER` | Transactions will be sent with `networkGasPrice * IEXEC_GAS_PRICE_MULTIPLIER`. | Float | `1.0` | `1.0` |

src/itest/resources/application-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ spring:
66
encryption:
77
# Will get previous key or else create one on this path
88
# this file shouldn't be clearly readable outside the enclave (but encrypted content could be copied outside)
9-
aesKeyPath: src/test/resources/iexec-sms-aes.key
9+
aes-key-path: src/test/resources/iexec-sms-aes.key
1010

1111
tee:
1212
worker:

src/main/java/com/iexec/sms/chain/ChainConfig.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,47 @@
1616

1717
package com.iexec.sms.chain;
1818

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;
1924
import lombok.Value;
25+
import org.hibernate.validator.constraints.URL;
26+
import org.hibernate.validator.constraints.time.DurationMax;
27+
import org.hibernate.validator.constraints.time.DurationMin;
2028
import org.springframework.boot.context.properties.ConfigurationProperties;
2129

30+
import org.springframework.validation.annotation.Validated;
31+
2232
import java.time.Duration;
2333

2434
@Value
35+
@Validated
2536
@ConfigurationProperties(prefix = "chain")
2637
public class ChainConfig {
38+
39+
@Positive(message = "Chain id must be greater than 0")
40+
@NotNull(message = "Chain id must not be null")
2741
int id;
28-
boolean isSidechain;
42+
43+
boolean sidechain;
44+
45+
@URL(message = "Node address must be a valid URL")
46+
@NotEmpty(message = "Node address must not be empty")
2947
String nodeAddress;
48+
49+
@ValidNonZeroEthereumAddress(message = "Hub address must be a valid non zero Ethereum address")
3050
String hubAddress;
51+
52+
@DurationMin(millis = 100, message = "Block time must be greater than 100ms")
53+
@DurationMax(seconds = 20, message = "Block time must be less than 20s")
54+
@NotNull(message = "Block time must not be null")
3155
Duration blockTime;
56+
57+
@Positive(message = "Gas price multiplier must be greater than 0")
3258
float gasPriceMultiplier;
59+
60+
@PositiveOrZero(message = "Gas price cap must be greater than or equal to 0")
3361
long gasPriceCap;
3462
}

src/main/java/com/iexec/sms/chain/Web3jService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ public Web3jService(final ChainConfig chainConfig) {
3333
);
3434
}
3535

36-
}
36+
}

src/main/resources/application.yml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ spring:
2121
h2:
2222
console:
2323
enabled: ${IEXEC_SMS_H2_CONSOLE:false} # http://localhost:13300/h2-console/
24-
settings.web-allow-others: ${IEXEC_SMS_H2_CONSOLE:false} # Get console if Docker run
24+
settings:
25+
web-allow-others: ${IEXEC_SMS_H2_CONSOLE:false} # Get console if Docker run
2526

2627
admin:
2728
api-key: ${IEXEC_SMS_ADMIN_API_KEY:}
@@ -30,12 +31,12 @@ admin:
3031
encryption:
3132
# Will get previous key or else create one on this path
3233
# this file shouldn't be clearly readable outside the enclave (but encrypted content could be copied outside)
33-
aesKeyPath: ${IEXEC_SMS_STORAGE_ENCRYPTION_AES_KEY_PATH:/data/iexec-sms-aes.key}
34+
aes-key-path: ${IEXEC_SMS_STORAGE_ENCRYPTION_AES_KEY_PATH:/data/iexec-sms-aes.key}
3435

3536
chain:
3637
id: ${IEXEC_CHAIN_ID:134}
37-
is-sidechain: ${IEXEC_IS_SIDECHAIN:true}
38-
node-address: ${IEXEC_SMS_BLOCKCHAIN_NODE_ADDRESS:https://bellecour.iex.ec}
38+
sidechain: ${IEXEC_IS_SIDECHAIN:true}
39+
node-address: ${IEXEC_BLOCKCHAIN_NODE_ADDRESS:https://bellecour.iex.ec}
3940
hub-address: ${IEXEC_HUB_ADDRESS:0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f}
4041
block-time: ${IEXEC_BLOCK_TIME:PT5S}
4142
gas-price-multiplier: ${IEXEC_GAS_PRICE_MULTIPLIER:1.0} # txs will be sent with networkGasPrice*gasPriceMultiplier, 4.0 means superfast
@@ -46,10 +47,12 @@ metrics:
4647
refresh-interval: ${IEXEC_SMS_METRICS_STORAGE_REFRESH_INTERVAL:30} # In seconds
4748

4849
springdoc:
49-
packagesToScan: com.iexec.sms
50-
pathsToMatch: /**
50+
packages-to-scan: com.iexec.sms
51+
paths-to-match: /**
5152

5253
tee:
53-
challenge.cleanup.cron: ${IEXEC_TEE_CHALLENGE_CLEANUP_CRON:@hourly}
54-
challenge.cleanup.missing-deadline-max-batch-size: ${IEXEC_TEE_CHALLENGE_CLEANUP_MAX_BATCH_SIZE:500}
55-
challenge.cleanup.missing-deadline-retention-duration: ${IEXEC_TEE_CHALLENGE_CLEANUP_RETENTION_DURATION:P5D}
54+
challenge:
55+
cleanup:
56+
cron: ${IEXEC_TEE_CHALLENGE_CLEANUP_CRON:@hourly}
57+
missing-deadline-max-batch-size: ${IEXEC_TEE_CHALLENGE_CLEANUP_MAX_BATCH_SIZE:500}
58+
missing-deadline-retention-duration: ${IEXEC_TEE_CHALLENGE_CLEANUP_RETENTION_DURATION:P5D}
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
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.sms.chain;
18+
19+
import jakarta.validation.ConstraintViolation;
20+
import jakarta.validation.Validation;
21+
import jakarta.validation.ValidatorFactory;
22+
import lombok.extern.slf4j.Slf4j;
23+
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.params.ParameterizedTest;
25+
import org.junit.jupiter.params.provider.Arguments;
26+
import org.junit.jupiter.params.provider.MethodSource;
27+
28+
import java.time.Duration;
29+
import java.util.Set;
30+
import java.util.stream.Stream;
31+
32+
import static org.assertj.core.api.Assertions.assertThat;
33+
34+
@Slf4j
35+
class ChainConfigTests {
36+
37+
private static final int CHAIN_ID = 1;
38+
private static final String HUB_ADDRESS = "0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f";
39+
private static final String NODE_ADDRESS = "https://bellecour.iex.ec";
40+
private static final Duration BLOCK_TIME = Duration.ofSeconds(1);
41+
private static final float GAS_PRICE_MULTIPLIER = 1.0f;
42+
private static final long GAS_PRICE_CAP = 22_000_000_000L;
43+
44+
private Set<ConstraintViolation<ChainConfig>> validate(ChainConfig chainConfig) {
45+
try (final ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
46+
return factory.getValidator().validate(chainConfig);
47+
}
48+
}
49+
50+
// region Valid data
51+
static Stream<Arguments> validData() {
52+
return Stream.of(
53+
Arguments.of(100, true, "http://localhost:8545", "0xBF6B2B07e47326B7c8bfCb4A5460bef9f0Fd2002", "PT0.1S", 1.0f, 11_000_000_000L),
54+
Arguments.of(42, true, "https://localhost:8545", "0x0000000000000000000000000000000000000001", "PT10S", 1.0f, 22_000_000_000L),
55+
Arguments.of(10, true, "https://www.classic-url.com", "0xBF6B2B07e47326B7c8bfCb4A5460bef9f0Fd2002", "PT20S", 1.0f, 22_000_000_000L),
56+
Arguments.of(1, true, "http://ibaa.iex.ec:443/test?validation=should:be@OK", "0xBF6B2B07e47326B7c8bfCb4A5460bef9f0Fd2002", "PT5S", 1.0f, 0L),
57+
Arguments.of(CHAIN_ID, true, NODE_ADDRESS, HUB_ADDRESS, BLOCK_TIME, GAS_PRICE_MULTIPLIER, GAS_PRICE_CAP)
58+
);
59+
}
60+
61+
@ParameterizedTest
62+
@MethodSource("validData")
63+
void shouldValidate(int chainId,
64+
boolean sidechain,
65+
String nodeAddress,
66+
String hubAddress,
67+
Duration blockTime,
68+
float gasPriceMultiplier,
69+
long gasPriceCap) {
70+
final ChainConfig chainConfig = new ChainConfig(
71+
chainId,
72+
sidechain,
73+
nodeAddress,
74+
hubAddress,
75+
blockTime,
76+
gasPriceMultiplier,
77+
gasPriceCap);
78+
assertThat(validate(chainConfig)).isEmpty();
79+
}
80+
// endregion
81+
82+
// region Invalid chain ids
83+
static Stream<Integer> invalidChainIds() {
84+
return Stream.of(
85+
0, // Chain id should be strictly positive
86+
-1 // Chain id should be strictly positive
87+
);
88+
}
89+
90+
@ParameterizedTest
91+
@MethodSource("invalidChainIds")
92+
void shouldNotValidateChainId(int chainId) {
93+
final ChainConfig chainConfig = new ChainConfig(
94+
chainId,
95+
true,
96+
NODE_ADDRESS,
97+
HUB_ADDRESS,
98+
BLOCK_TIME,
99+
GAS_PRICE_MULTIPLIER,
100+
GAS_PRICE_CAP);
101+
assertThat(validate(chainConfig))
102+
.extracting(ConstraintViolation::getMessage)
103+
.containsExactly("Chain id must be greater than 0");
104+
}
105+
// endregion
106+
107+
// region Invalid node addresses
108+
static Stream<Arguments> invalidNodeAddresses() {
109+
return Stream.of(
110+
Arguments.of(null, "Node address must not be empty"), // Node address should not be null
111+
Arguments.of("", "Node address must not be empty"), // Node address should be a valid URL
112+
Arguments.of("12345", "Node address must be a valid URL"), // Node address should be a valid URL
113+
Arguments.of("0xBF6B2B07e47326B7c8bfCb4A5460bef9f0Fd2002", "Node address must be a valid URL") // Node address should be a valid URL
114+
);
115+
}
116+
117+
@ParameterizedTest
118+
@MethodSource("invalidNodeAddresses")
119+
void shouldNotValidateNodeAddress(String nodeAddress, String errorMessage) {
120+
final ChainConfig chainConfig = new ChainConfig(
121+
CHAIN_ID,
122+
true,
123+
nodeAddress,
124+
HUB_ADDRESS,
125+
BLOCK_TIME,
126+
GAS_PRICE_MULTIPLIER,
127+
GAS_PRICE_CAP);
128+
assertThat(validate(chainConfig))
129+
.extracting(ConstraintViolation::getMessage)
130+
.containsExactly(errorMessage);
131+
}
132+
// endregion
133+
134+
// region Invalid hub address
135+
static Stream<String> invalidHubAddresses() {
136+
return Stream.of(
137+
null, // Hub address should not be null
138+
"0xBF6B2B07e47326B7c8bfCb4A5460bef9f0Fd200211111111111111", // Hub address size should be exactly 40
139+
"0xBF6B2B07e47326B7c8bfCb4A5460bef9f0Fd200", // Hub address size should be exactly 40
140+
"0x0000000000000000000000000000000000000000", // Hub address should not be zero
141+
"http://hub.address" // Hub address should be an Ethereum address
142+
);
143+
}
144+
145+
@ParameterizedTest
146+
@MethodSource("invalidHubAddresses")
147+
void shouldNotValidateHubAddress(String hubAddress) {
148+
final ChainConfig chainConfig = new ChainConfig(
149+
CHAIN_ID,
150+
true,
151+
NODE_ADDRESS,
152+
hubAddress,
153+
BLOCK_TIME,
154+
GAS_PRICE_MULTIPLIER,
155+
GAS_PRICE_CAP);
156+
assertThat(validate(chainConfig))
157+
.extracting(ConstraintViolation::getMessage)
158+
.containsExactly("Hub address must be a valid non zero Ethereum address");
159+
}
160+
// endregion
161+
162+
// region Invalid block time
163+
static Stream<Arguments> invalidBlockTimes() {
164+
return Stream.of(
165+
Arguments.of(Duration.ofSeconds(0), "Block time must be greater than 100ms"),
166+
Arguments.of(Duration.ofSeconds(25), "Block time must be less than 20s"),
167+
Arguments.of(Duration.ofSeconds(-1), "Block time must be greater than 100ms"),
168+
Arguments.of(null, "Block time must not be null")
169+
);
170+
}
171+
172+
@ParameterizedTest
173+
@MethodSource("invalidBlockTimes")
174+
void shouldNotValidateBlockTime(Duration blockTime, String errorMessage) {
175+
final ChainConfig chainConfig = new ChainConfig(
176+
CHAIN_ID,
177+
true,
178+
NODE_ADDRESS,
179+
HUB_ADDRESS,
180+
blockTime,
181+
GAS_PRICE_MULTIPLIER,
182+
GAS_PRICE_CAP);
183+
assertThat(validate(chainConfig))
184+
.extracting(ConstraintViolation::getMessage)
185+
.containsExactly(errorMessage);
186+
}
187+
// endregion
188+
189+
// region Invalid gas price multiplier
190+
static Stream<Float> invalidGasPriceMultiplier() {
191+
return Stream.of(
192+
0f, // Gas Price Multiplier should be strictly positive
193+
-0.5f // Gas Price Multiplier should be strictly positive
194+
);
195+
}
196+
197+
@ParameterizedTest
198+
@MethodSource("invalidGasPriceMultiplier")
199+
void shouldNotValidateGasPriceMultiplier(Float gasPriceMultiplier) {
200+
final ChainConfig chainConfig = new ChainConfig(
201+
CHAIN_ID,
202+
true,
203+
NODE_ADDRESS,
204+
HUB_ADDRESS,
205+
BLOCK_TIME,
206+
gasPriceMultiplier,
207+
GAS_PRICE_CAP);
208+
final Set<ConstraintViolation<ChainConfig>> violations = validate(chainConfig);
209+
assertThat(violations)
210+
.extracting(ConstraintViolation::getMessage)
211+
.containsExactly("Gas price multiplier must be greater than 0");
212+
}
213+
// endregion
214+
215+
// region Invalid gas price cap
216+
@Test
217+
void negativeGasPriceCapShouldFailValidation() {
218+
final ChainConfig config = new ChainConfig(
219+
134,
220+
true,
221+
NODE_ADDRESS,
222+
HUB_ADDRESS,
223+
Duration.ofSeconds(5),
224+
1.0f,
225+
-1L // Invalid: should be positive or zero
226+
);
227+
final Set<ConstraintViolation<ChainConfig>> violations = validate(config);
228+
assertThat(violations)
229+
.extracting(ConstraintViolation::getMessage)
230+
.containsExactly("Gas price cap must be greater than or equal to 0");
231+
}
232+
// endregion
233+
234+
@Test
235+
void multipleViolationsShouldBeReported() {
236+
final ChainConfig config = new ChainConfig(
237+
0, // Invalid
238+
true,
239+
"", // Invalid
240+
"0x0000000000000000000000000000000000000000", // Invalid
241+
Duration.ofMillis(50), // Invalid
242+
-1.0f, // Invalid
243+
-1L // Invalid
244+
);
245+
final Set<ConstraintViolation<ChainConfig>> violations = validate(config);
246+
assertThat(violations).hasSize(6); // All fields except sidechain have violations
247+
}
248+
249+
}

src/test/java/com/iexec/sms/chain/Web3jServiceTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
@EnableConfigurationProperties(value = ChainConfig.class)
3232
@TestPropertySource(properties = {
3333
"chain.id=134",
34-
"chain.is-sidechain=true",
34+
"chain.sidechain=true",
3535
"chain.node-address=https://bellecour.iex.ec",
3636
"chain.hub-address=0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f",
3737
"chain.block-time=PT5S",

0 commit comments

Comments
 (0)