Skip to content

Commit 19c97a3

Browse files
Harmonize YML internal variables to proper case (#154)
1 parent ebac1ef commit 19c97a3

File tree

8 files changed

+245
-19
lines changed

8 files changed

+245
-19
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44

55
## [[NEXT]](https://github.com/iExecBlockchainComputing/iexec-result-proxy/releases/tag/vNEXT) 2025
66

7+
### Quality
8+
9+
- Harmonize YML internal variables to proper case. (#154)
10+
711
### Breaking API changes
812

913
- Remove legacy authorization mechanism, allows to remove challenge services as well. (#150)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ You can configure the iExec Result Proxy with the following properties:
2424
| `MONGO_PORT` | Mongo server port. Cannot be set with URI. | Positive integer | `13202` |
2525
| `IEXEC_CHAIN_ID` | Chain ID of the blockchain network to connect. | `Integer | `134` |
2626
| `IEXEC_IS_SIDECHAIN` | Define whether iExec on-chain protocol is built on top of token (`false`) or native currency (`true`). | Boolean | `true` |
27-
| `IEXEC_PRIVATE_CHAIN_ADDRESS` | Private URL to connect to the blockchain node. | URL | `https://bellecour.iex.ec` |
27+
| `IEXEC_BLOCKCHAIN_NODE_ADDRESS` | Private URL to connect to the blockchain node. | URL | `https://bellecour.iex.ec` |
2828
| `IEXEC_HUB_ADDRESS` | Proxy contract address to interact with the iExec on-chain protocol. | Ethereum address | `0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f` |
2929
| `IEXEC_BLOCK_TIME` | Duration between consecutive blocks on the blockchain network. | String | `PT5S` |
3030
| `IEXEC_GAS_PRICE_MULTIPLIER` | Transactions will be sent with `networkGasPrice * IEXEC_GAS_PRICE_MULTIPLIER`. | Float | `1.0` |

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ dependencies {
5757
// spring
5858
implementation 'org.springframework.boot:spring-boot-starter-actuator'
5959
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
60+
implementation 'org.springframework.boot:spring-boot-starter-validation'
6061
implementation 'org.springframework.boot:spring-boot-starter-web'
6162
implementation "org.springframework.retry:spring-retry"
6263
// required for spring-retry

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,45 @@
1616

1717
package com.iexec.resultproxy.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;
29+
import org.springframework.validation.annotation.Validated;
2130

2231
import java.time.Duration;
2332

2433
@Value
34+
@Validated
2535
@ConfigurationProperties(prefix = "chain")
26-
//TODO: validate configuration property names and use the same set of names everywhere (blockchain-adapter-api, sms)
2736
public class ChainConfig {
37+
@Positive(message = "Chain id must be greater than 0")
38+
@NotNull(message = "Chain id must not be null")
2839
int id;
40+
2941
boolean sidechain;
30-
String privateAddress;
42+
43+
@URL(message = "Node address must be a valid URL")
44+
@NotEmpty(message = "Node address must not be empty")
45+
String nodeAddress;
46+
47+
@ValidNonZeroEthereumAddress(message = "Hub address must be a valid non zero Ethereum address")
3148
String hubAddress;
49+
50+
@DurationMin(millis = 100, message = "Block time must be greater than 100ms")
51+
@DurationMax(seconds = 20, message = "Block time must be less than 20s")
52+
@NotNull(message = "Block time must not be null")
3253
Duration blockTime;
54+
55+
@Positive(message = "Gas price multiplier must be greater than 0")
3356
float gasPriceMultiplier;
57+
58+
@PositiveOrZero(message = "Gas price cap must be greater or equal to 0")
3459
long gasPriceCap;
3560
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ public class Web3jService extends Web3jAbstractService {
2525
public Web3jService(ChainConfig chainConfig) {
2626
super(
2727
chainConfig.getId(),
28-
chainConfig.getPrivateAddress(),
28+
chainConfig.getNodeAddress(),
2929
chainConfig.getBlockTime(),
3030
chainConfig.getGasPriceMultiplier(),
3131
chainConfig.getGasPriceCap(),

src/main/resources/application.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ spring:
1212
chain:
1313
id: ${IEXEC_CHAIN_ID:134}
1414
sidechain: ${IEXEC_IS_SIDECHAIN:true}
15-
privateAddress: ${IEXEC_PRIVATE_CHAIN_ADDRESS:https://bellecour.iex.ec}
16-
hubAddress: ${IEXEC_HUB_ADDRESS:0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f}
17-
blockTime: ${IEXEC_BLOCK_TIME:PT5S}
18-
gasPriceMultiplier: ${IEXEC_GAS_PRICE_MULTIPLIER:1.0} # txs will be sent with networkGasPrice*gasPriceMultiplier, 4.0 means super fast
19-
gasPriceCap: ${IEXEC_GAS_PRICE_CAP:22000000000} #in Wei, will be used for txs if networkGasPrice*gasPriceMultiplier > gasPriceCap
15+
node-address: ${IEXEC_BLOCKCHAIN_NODE_ADDRESS:https://bellecour.iex.ec}
16+
hub-address: ${IEXEC_HUB_ADDRESS:0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f}
17+
block-time: ${IEXEC_BLOCK_TIME:PT5S}
18+
gas-price-multiplier: ${IEXEC_GAS_PRICE_MULTIPLIER:1.0} # txs will be sent with networkGasPrice*gasPriceMultiplier, 4.0 means super fast
19+
gas-price-cap: ${IEXEC_GAS_PRICE_CAP:22000000000} #in Wei, will be used for txs if networkGasPrice*gasPriceMultiplier > gasPriceCap
2020

2121
ipfs:
2222
host: ${IEXEC_IPFS_HOST:127.0.0.1}
@@ -26,5 +26,5 @@ jwt:
2626
key-path: /data/jwt-sign.key
2727

2828
springdoc:
29-
packagesToScan: com.iexec.resultproxy
30-
pathsToMatch: /**
29+
packages-to-scan: com.iexec.resultproxy
30+
paths-to-match: /**
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
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.resultproxy.chain;
18+
19+
import jakarta.validation.ConstraintViolation;
20+
import jakarta.validation.Validation;
21+
import jakarta.validation.Validator;
22+
import jakarta.validation.ValidatorFactory;
23+
import org.junit.jupiter.api.BeforeEach;
24+
import org.junit.jupiter.api.Test;
25+
26+
import java.time.Duration;
27+
import java.util.Set;
28+
29+
import static org.assertj.core.api.Assertions.assertThat;
30+
31+
class ChainConfigTest {
32+
private static final String IEXEC_NODE_ADDRESS = "https://bellecour.iex.ec";
33+
private static final String IEXEC_HUB_ADDRESS = "0x1a69b2eb604db8eba185df03ea4f5288dcbbd248";
34+
35+
private Validator validator;
36+
37+
@BeforeEach
38+
void setUp() {
39+
try (final ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
40+
validator = factory.getValidator();
41+
}
42+
}
43+
44+
@Test
45+
void idMustBePositive() {
46+
final ChainConfig config = new ChainConfig(
47+
0, // invalid id
48+
false,
49+
IEXEC_NODE_ADDRESS,
50+
IEXEC_HUB_ADDRESS,
51+
Duration.ofMillis(100),
52+
1.5f,
53+
100L
54+
);
55+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
56+
assertThat(violations)
57+
.extracting(ConstraintViolation::getMessage)
58+
.containsExactly("Chain id must be greater than 0");
59+
}
60+
61+
@Test
62+
void nodeAddressMustBeValidURL() {
63+
final ChainConfig config = new ChainConfig(
64+
1,
65+
false,
66+
"invalid-url", // invalid URL
67+
IEXEC_HUB_ADDRESS,
68+
Duration.ofMillis(100),
69+
1.5f,
70+
100L
71+
);
72+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
73+
assertThat(violations)
74+
.extracting(ConstraintViolation::getMessage)
75+
.containsExactly("Node address must be a valid URL");
76+
}
77+
78+
@Test
79+
void nodeAddressMustNotBeEmpty() {
80+
final ChainConfig config = new ChainConfig(
81+
1,
82+
false,
83+
"", // empty nodeAddress
84+
IEXEC_HUB_ADDRESS,
85+
Duration.ofMillis(100),
86+
1.5f,
87+
100L
88+
);
89+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
90+
assertThat(violations)
91+
.extracting(ConstraintViolation::getMessage)
92+
.containsExactly("Node address must not be empty");
93+
}
94+
95+
@Test
96+
void hubAddressMustBeValidEthereumAddress() {
97+
final ChainConfig config = new ChainConfig(
98+
1,
99+
false,
100+
IEXEC_NODE_ADDRESS,
101+
"0x0", // invalid address
102+
Duration.ofMillis(100),
103+
1.5f,
104+
100L
105+
);
106+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
107+
assertThat(violations)
108+
.extracting(ConstraintViolation::getMessage)
109+
.containsExactly("Hub address must be a valid non zero Ethereum address");
110+
}
111+
112+
@Test
113+
void blockTimeMustBeAtLeast100ms() {
114+
final ChainConfig config = new ChainConfig(
115+
1,
116+
false,
117+
IEXEC_NODE_ADDRESS,
118+
IEXEC_HUB_ADDRESS,
119+
Duration.ofMillis(99), // <100ms
120+
1.5f,
121+
100L
122+
);
123+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
124+
assertThat(violations)
125+
.extracting(ConstraintViolation::getMessage)
126+
.containsExactly("Block time must be greater than 100ms");
127+
}
128+
129+
@Test
130+
void blockTimeMustBeAtMost20Seconds() {
131+
final ChainConfig config = new ChainConfig(
132+
1,
133+
false,
134+
IEXEC_NODE_ADDRESS,
135+
IEXEC_HUB_ADDRESS,
136+
Duration.ofSeconds(21), // >20s
137+
1.5f,
138+
100L
139+
);
140+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
141+
assertThat(violations)
142+
.extracting(ConstraintViolation::getMessage)
143+
.containsExactly("Block time must be less than 20s");
144+
}
145+
146+
@Test
147+
void blockTimeMustNotBeNull() {
148+
final ChainConfig config = new ChainConfig(
149+
1,
150+
false,
151+
IEXEC_NODE_ADDRESS,
152+
IEXEC_HUB_ADDRESS,
153+
null, // null blockTime
154+
1.5f,
155+
100L
156+
);
157+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
158+
assertThat(violations)
159+
.extracting(ConstraintViolation::getMessage)
160+
.containsExactly("Block time must not be null");
161+
}
162+
163+
@Test
164+
void gasPriceMultiplierMustBePositive() {
165+
final ChainConfig config = new ChainConfig(
166+
1,
167+
false,
168+
IEXEC_NODE_ADDRESS,
169+
IEXEC_HUB_ADDRESS,
170+
Duration.ofMillis(100),
171+
0.0f, // invalid multiplier
172+
100L
173+
);
174+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
175+
assertThat(violations)
176+
.extracting(ConstraintViolation::getMessage)
177+
.containsExactly("Gas price multiplier must be greater than 0");
178+
}
179+
180+
@Test
181+
void gasPriceCapMustBePositiveOrZero() {
182+
final ChainConfig config = new ChainConfig(
183+
1,
184+
false,
185+
IEXEC_NODE_ADDRESS,
186+
IEXEC_HUB_ADDRESS,
187+
Duration.ofMillis(100),
188+
1.5f,
189+
-1L // invalid cap
190+
);
191+
final Set<ConstraintViolation<ChainConfig>> violations = validator.validate(config);
192+
assertThat(violations)
193+
.extracting(ConstraintViolation::getMessage)
194+
.containsExactly("Gas price cap must be greater or equal to 0");
195+
}
196+
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2023-2025 IEXEC BLOCKCHAIN TECH
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,18 +32,18 @@
3232
@TestPropertySource(properties = {
3333
"chain.id=134",
3434
"chain.sidechain=true",
35-
"chain.privateAddress=https://bellecour.iex.ec",
36-
"chain.hubAddress=0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f",
37-
"chain.blockTime=PT5S",
38-
"chain.gasPriceMultiplier=1.0",
39-
"chain.gasPriceCap=22000000000" })
35+
"chain.node-address=https://bellecour.iex.ec",
36+
"chain.hub-address=0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f",
37+
"chain.block-time=PT5S",
38+
"chain.gas-price-multiplier=1.0",
39+
"chain.gas-price-cap=22000000000"})
4040
class Web3jServiceTests {
4141
@Autowired
4242
private ChainConfig chainConfig;
4343

4444
@Test
4545
void checkChainConfig() {
46-
ChainConfig expextedConfig = new ChainConfig(
46+
final ChainConfig expextedConfig = new ChainConfig(
4747
134, true, "https://bellecour.iex.ec",
4848
"0x3eca1B216A7DF1C7689aEb259fFB83ADFB894E7f", Duration.ofSeconds(5),
4949
1.0f, 22000000000L

0 commit comments

Comments
 (0)