Skip to content

Commit dea6ebc

Browse files
authored
Merge pull request #105 from iExecBlockchainComputing/feature/immutable-chain-config
Feature/immutable chain config
2 parents e39faba + fd9ebb5 commit dea6ebc

File tree

9 files changed

+84
-108
lines changed

9 files changed

+84
-108
lines changed

CHANGELOG.md

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

55
## [[NEXT]](https://github.com/iExecBlockchainComputing/iexec-blockchain-adapter-api/releases/tag/vNEXT) 2023
66

7-
### New Features
8-
- Remove `nexus.intra.iex.ec` repository. (#96)
97
### Bug Fixes
108
- Fix and harmonize `Dockerfile entrypoint` in all Spring Boot applications. (#102)
119
### Quality
10+
- Remove `nexus.intra.iex.ec` repository. (#96)
1211
- Upgrade to Gradle 8.2.1 with up-to-date plugins. (#100)
1312
- Clean TODOs. (#104)
13+
- `ChainConfig` instance is immutable and validated. Application will fail to start if chain config parameters violate constraints. (#105)
1414
### Dependency Upgrades
1515
- Upgrade to `eclipse-temurin` 11.0.20. (#98)
1616
- Upgrade to Spring Boot 2.7.14. (#99)

src/main/java/com/iexec/blockchain/Application.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import org.springframework.boot.SpringApplication;
44
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
56
import org.springframework.scheduling.annotation.EnableScheduling;
67

7-
@SpringBootApplication
88
@EnableScheduling
9+
@SpringBootApplication
10+
@ConfigurationPropertiesScan
911
public class Application {
1012

1113
public static void main(String[] args) {

src/main/java/com/iexec/blockchain/config/PublicConfigurationController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ public PublicConfigurationController(ChainConfig chainConfig) {
3939
*/
4040
@GetMapping("/chain")
4141
public ResponseEntity<PublicChainConfig> getPublicChainConfig() {
42-
final Integer blockTime = chainConfig.getBlockTime();
42+
final int blockTime = chainConfig.getBlockTime();
4343
final PublicChainConfig publicChainConfig = PublicChainConfig
4444
.builder()
45-
.chainId(chainConfig.getChainId())
45+
.chainId(chainConfig.getId())
4646
.sidechain(chainConfig.isSidechain())
4747
.chainNodeUrl(chainConfig.getNodeAddress())
4848
.iexecHubContractAddress(chainConfig.getHubAddress())

src/main/java/com/iexec/blockchain/signer/SignerService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public class SignerService {
3131
private final OrderSigner orderSigner;
3232

3333
public SignerService(ChainConfig chainConfig, CredentialsService credentialsService) {
34-
this.orderSigner = new OrderSigner(chainConfig.getChainId(),
34+
this.orderSigner = new OrderSigner(
35+
chainConfig.getId(),
3536
chainConfig.getHubAddress(),
3637
credentialsService.getCredentials().getEcKeyPair());
3738
}
Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2020-2023 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.
@@ -17,66 +17,56 @@
1717
package com.iexec.blockchain.tool;
1818

1919
import com.iexec.common.chain.validation.ValidNonZeroEthereumAddress;
20-
import lombok.*;
20+
import lombok.Builder;
21+
import lombok.Value;
22+
import lombok.extern.slf4j.Slf4j;
2123
import org.hibernate.validator.constraints.URL;
22-
import org.springframework.beans.factory.annotation.Autowired;
23-
import org.springframework.beans.factory.annotation.Value;
24-
import org.springframework.stereotype.Component;
24+
import org.springframework.boot.context.properties.ConfigurationProperties;
25+
import org.springframework.boot.context.properties.ConstructorBinding;
2526

2627
import javax.annotation.PostConstruct;
27-
import javax.validation.ConstraintViolationException;
28-
import javax.validation.Validator;
28+
import javax.validation.*;
2929
import javax.validation.constraints.NotEmpty;
3030
import javax.validation.constraints.NotNull;
3131
import javax.validation.constraints.Positive;
32+
import java.util.Set;
3233

33-
@Component
34-
@Getter
35-
@ToString
34+
@Slf4j
35+
@Value
3636
@Builder
37-
@AllArgsConstructor
37+
@ConstructorBinding
38+
@ConfigurationProperties(prefix = "chain")
3839
public class ChainConfig {
3940

40-
@Value("${chain.id}")
4141
@Positive(message = "Chain id should be positive")
4242
@NotNull
43-
private Integer chainId;
43+
int id;
4444

45-
@Value("${chain.node-address}")
4645
@URL
4746
@NotEmpty
48-
private String nodeAddress;
47+
String nodeAddress;
4948

50-
@Value("${chain.block-time}")
5149
@Positive(message = "Block time should be positive")
5250
@NotNull
53-
private Integer blockTime;
51+
int blockTime;
5452

55-
@Value("${chain.hub-address}")
5653
@ValidNonZeroEthereumAddress
57-
private String hubAddress;
54+
String hubAddress;
5855

59-
@Value("${chain.is-sidechain}")
60-
private boolean isSidechain;
56+
boolean isSidechain;
6157

62-
@Value("${chain.gas-price-multiplier}")
63-
private float gasPriceMultiplier;
58+
float gasPriceMultiplier;
6459

65-
@Value("${chain.gas-price-cap}")
66-
private long gasPriceCap;
67-
68-
@Getter(AccessLevel.NONE) // no getter
69-
private final Validator validator;
70-
71-
@Autowired
72-
public ChainConfig(Validator validator) {
73-
this.validator = validator;
74-
}
60+
long gasPriceCap;
7561

7662
@PostConstruct
7763
private void validate() {
78-
if (!validator.validate(this).isEmpty()) {
79-
throw new ConstraintViolationException(validator.validate(this));
64+
try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
65+
Validator validator = factory.getValidator();
66+
Set<ConstraintViolation<ChainConfig>> violations = validator.validate(this);
67+
if (!violations.isEmpty()) {
68+
throw new ConstraintViolationException(violations);
69+
}
8070
}
8171
}
8272
}

src/main/java/com/iexec/blockchain/tool/Web3jService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class Web3jService extends Web3jAbstractService {
2626

2727
public Web3jService(ChainConfig chainConfig) {
2828
super(
29-
chainConfig.getChainId(),
29+
chainConfig.getId(),
3030
chainConfig.getNodeAddress(),
3131
Duration.ofSeconds(chainConfig.getBlockTime()),
3232
chainConfig.getGasPriceMultiplier(),

src/test/java/com/iexec/blockchain/config/PublicConfigurationControllerTests.java

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,45 +20,45 @@
2020
import com.iexec.common.config.PublicChainConfig;
2121
import org.junit.jupiter.api.BeforeEach;
2222
import org.junit.jupiter.api.Test;
23-
import org.mockito.InjectMocks;
24-
import org.mockito.Mock;
25-
import org.mockito.MockitoAnnotations;
2623
import org.springframework.http.ResponseEntity;
2724

2825
import java.time.Duration;
2926

3027
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
31-
import static org.mockito.Mockito.when;
3228

3329
class PublicConfigurationControllerTests {
3430

35-
@Mock
36-
ChainConfig chainConfig;
31+
private static final int ID = 65535;
32+
private static final String NODE_ADDRESS = "http://localhost:8545";
33+
private static final String HUB_ADDRESS = "0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca";
34+
private static final int BLOCK_TIME = 5;
35+
private static final boolean IS_SIDECHAIN = true;
36+
37+
ChainConfig chainConfig = ChainConfig.builder()
38+
.id(ID)
39+
.nodeAddress(NODE_ADDRESS)
40+
.hubAddress(HUB_ADDRESS)
41+
.blockTime(BLOCK_TIME)
42+
.isSidechain(IS_SIDECHAIN)
43+
.build();
3744

38-
@InjectMocks
3945
PublicConfigurationController controller;
4046

4147
@BeforeEach
4248
void init() {
43-
MockitoAnnotations.openMocks(this);
49+
controller = new PublicConfigurationController(chainConfig);
4450
}
4551

4652
@Test
4753
void shouldReturnConfig() {
48-
int blockTime = 5;
4954
PublicChainConfig expectedConfig = PublicChainConfig
5055
.builder()
51-
.sidechain(true)
52-
.chainId(65535)
53-
.chainNodeUrl("http://localhost:8545")
54-
.iexecHubContractAddress("0xC129e7917b7c7DeDfAa5Fff1FB18d5D7050fE8ca")
55-
.blockTime(Duration.ofSeconds(blockTime))
56+
.sidechain(IS_SIDECHAIN)
57+
.chainId(ID)
58+
.chainNodeUrl(NODE_ADDRESS)
59+
.iexecHubContractAddress(HUB_ADDRESS)
60+
.blockTime(Duration.ofSeconds(BLOCK_TIME))
5661
.build();
57-
when(chainConfig.getChainId()).thenReturn(expectedConfig.getChainId());
58-
when(chainConfig.isSidechain()).thenReturn(expectedConfig.isSidechain());
59-
when(chainConfig.getNodeAddress()).thenReturn(expectedConfig.getChainNodeUrl());
60-
when(chainConfig.getHubAddress()).thenReturn(expectedConfig.getIexecHubContractAddress());
61-
when(chainConfig.getBlockTime()).thenReturn(blockTime);
6262
ResponseEntity<PublicChainConfig> response = controller.getPublicChainConfig();
6363
assertThat(response.getBody())
6464
.isNotNull()

0 commit comments

Comments
 (0)