Skip to content

Commit 77e1033

Browse files
authored
feat: RA-43 Refactoring and testing /block endpoint [no final asserts] (#88)
* feat: RA-43 added h2 config and maven profile, implement BlockApi * feat: RA-43 refactored findBlock method, added to pom assertj and modelmapper * feat: RA-43 pull main * feat: RA-43 add exception and test * feat: RA-43 rename and reformat * feat: RA-43 add tests * feat: RA-43 add tests * feat: RA-43 extract bean to h2 configuration * feat: RA-43 merge with master * feat: RA-43 reformat * feat: RA-43 pull main with merge errors in BlockToBlockResponse.java OperationDataMapper.java PoolRegistration.java * feat: RA-43 fix merger with main * feat: RA-43 h2 run OK * feat: RA-43 rm @slf4j from configuration bean
1 parent c3e6685 commit 77e1033

File tree

63 files changed

+2634
-1255
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2634
-1255
lines changed

.env.h2

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#Use envfile plugin for IDEA
2+
#https://plugins.jetbrains.com/plugin/7861-envfile
3+
4+
API_SPRING_PROFILES_ACTIVE=devh2
5+
6+
NETWORK=devkit # devkit, mainnet, testnet, preprod
7+
PROTOCOL_MAGIC=42
8+
9+
#common env
10+
DB_ADMIN_USER_NAME=rosetta_db_admin
11+
DB_ADMIN_USER_SECRET=weakpwd#123_d
12+
13+
DB_IMAGE_NAME=h2
14+
DB_IMAGE_TAG=14.11-bullseye
15+
DB_NAME=rosetta-java-preprod
16+
DB_HOST=db # Service name in docker-compose or local db
17+
DB_PORT=5432
18+
DB_SCHEMA=${NETWORK}
19+
MAXIMUM_POOL_SIZE=80
20+
JDBC_BATCH_SIZE=1000
21+
SCHEMA=${NETWORK}
22+
CARDANO_NODE_HOST=localhost # Service name in docker-compose or local cardano node
23+
CARDANO_NODE_PORT=3001 # Uncomment if you are using local cardano node
24+
CARDANO_NODE_VERSION=8.1.2
25+
LOG=INFO
26+
27+
#api env
28+
API_SPRING_PROFILES_ACTIVE_API=dev
29+
API_EXPOSED_PORT=8081
30+
API_BIND_PORT=8081
31+
TRANSACTION_TTL=3000
32+
33+
DB_CONNECTION_PARAMS_PROVIDER_TYPE=ENVIRONMENT
34+
DB_DRIVER_CLASS_NAME=org.h2.Driver
35+
36+
ROSETTA_VERSION=1.4.13
37+
TOPOLOGY_FILEPATH=config/${NETWORK}/topology.json
38+
GENESIS_SHELLEY_PATH=config/${NETWORK}/shelley-genesis.json
39+
GENESIS_BYRON_PATH=config/${NETWORK}/byron-genesis.json
40+
41+
PRINT_EXCEPTION=true
42+
43+
#api env
44+
API_SPRING_PROFILES_ACTIVE_YACI_INDEXER=postgres # database profiles: h2, postgres
45+
INDEXER_NODE_PORT=3001

api/api.iml

Lines changed: 0 additions & 10 deletions
This file was deleted.

api/pom.xml

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
<artifactId>api</artifactId>
1212
<name>api</name>
1313
<description>Rosetta API implementation for Cardano.</description>
14+
<properties>
15+
<spotbugs-annotations.version>4.8.3</spotbugs-annotations.version>
16+
</properties>
1417

1518
<packaging>jar</packaging>
1619

@@ -137,7 +140,7 @@
137140
<dependency>
138141
<groupId>com.github.spotbugs</groupId>
139142
<artifactId>spotbugs-annotations</artifactId>
140-
<version>4.8.3</version>
143+
<version>${spotbugs-annotations.version}</version>
141144
</dependency>
142145
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
143146
<dependency>
@@ -212,27 +215,6 @@
212215
<version>3.41.0</version>
213216
<scope>compile</scope>
214217
</dependency>
215-
216-
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.testcontainers/testcontainers &ndash;&gt;-->
217-
<!-- <dependency>-->
218-
<!-- <groupId>org.testcontainers</groupId>-->
219-
<!-- <artifactId>testcontainers</artifactId>-->
220-
<!-- <version>1.17.6</version>-->
221-
<!-- <scope>test</scope>-->
222-
<!-- </dependency>-->
223-
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.purejava/tweetnacl-java &ndash;&gt;-->
224-
<!-- <dependency>-->
225-
<!-- <groupId>org.purejava</groupId>-->
226-
<!-- <artifactId>tweetnacl-java</artifactId>-->
227-
<!-- <version>1.1.2</version>-->
228-
<!-- </dependency>-->
229-
<!-- <dependency>-->
230-
<!-- <groupId>org.mockito</groupId>-->
231-
<!-- <artifactId>mockito-inline</artifactId>-->
232-
<!-- <version>3.8.0</version>-->
233-
<!-- <scope>test</scope>-->
234-
<!-- </dependency>-->
235-
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
236218
<dependency>
237219
<groupId>javax.servlet</groupId>
238220
<artifactId>servlet-api</artifactId>
@@ -245,7 +227,20 @@
245227
<version>3.7.0</version>
246228
<scope>compile</scope>
247229
</dependency>
248-
230+
<dependency>
231+
<groupId>org.modelmapper</groupId>
232+
<artifactId>modelmapper</artifactId>
233+
</dependency>
234+
<dependency>
235+
<groupId>org.modelmapper.extensions</groupId>
236+
<artifactId>modelmapper-spring</artifactId>
237+
</dependency>
238+
<dependency>
239+
<groupId>org.assertj</groupId>
240+
<artifactId>assertj-core</artifactId>
241+
<version>${assertj-core.version}</version>
242+
<scope>test</scope>
243+
</dependency>
249244
</dependencies>
250245

251246
<build>
@@ -420,4 +415,17 @@
420415
</plugins>
421416
</build>
422417

418+
<profiles>
419+
<profile>
420+
<id>h2-api</id>
421+
<dependencies>
422+
<dependency>
423+
<groupId>com.h2database</groupId>
424+
<artifactId>h2</artifactId>
425+
<scope>runtime</scope>
426+
</dependency>
427+
</dependencies>
428+
</profile>
429+
</profiles>
430+
423431
</project>
Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package org.cardanofoundation.rosetta;
22

3-
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
4-
import io.swagger.v3.oas.annotations.info.Info;
3+
import java.util.List;
54
import jakarta.servlet.DispatcherType;
6-
import org.openapitools.jackson.nullable.JsonNullableModule;
5+
76
import org.springframework.boot.SpringApplication;
87
import org.springframework.boot.autoconfigure.SpringBootApplication;
98
import org.springframework.boot.autoconfigure.domain.EntityScan;
@@ -12,35 +11,46 @@
1211
import org.springframework.context.annotation.Profile;
1312
import org.springframework.core.Ordered;
1413
import org.springframework.web.filter.ForwardedHeaderFilter;
15-
16-
import java.util.List;
14+
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
15+
import io.swagger.v3.oas.annotations.info.Info;
16+
import org.modelmapper.ModelMapper;
17+
import org.openapitools.jackson.nullable.JsonNullableModule;
1718

1819

1920
@SpringBootApplication
2021
@EntityScan({
21-
"org.cardanofoundation.rosetta.api.account.model.entity",
22-
"org.cardanofoundation.rosetta.api.block.model.entity",
23-
"org.cardanofoundation.rosetta.api.construction.model.entity",
24-
"org.cardanofoundation.rosetta.api.network.model.entity",
25-
"org.cardanofoundation.rosetta.api.common.model.entity"})
22+
"org.cardanofoundation.rosetta.api.account.model.entity",
23+
"org.cardanofoundation.rosetta.api.block.model.entity",
24+
"org.cardanofoundation.rosetta.api.construction.model.entity",
25+
"org.cardanofoundation.rosetta.api.network.model.entity",
26+
"org.cardanofoundation.rosetta.api.common.model.entity"})
2627
@OpenAPIDefinition(info = @Info(title = "APIs", version = "1.0", description = "Rosetta APIs v1.0"))
2728
public class RosettaApiApplication {
28-
public static void main(String[] args) {
29-
SpringApplication.run(RosettaApiApplication.class, args);
30-
}
31-
32-
@Bean
33-
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
34-
final ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
35-
final FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(filter);
36-
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
37-
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
38-
registration.setUrlPatterns(List.of("/**"));
39-
return registration;
40-
}
41-
@Bean
42-
@Profile("!test-integration")
43-
public JsonNullableModule jsonNullableModule() {
44-
return new JsonNullableModule();
45-
}
29+
30+
public static void main(String[] args) {
31+
SpringApplication.run(RosettaApiApplication.class, args);
32+
}
33+
34+
@Bean
35+
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
36+
final ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
37+
final FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(
38+
filter);
39+
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC,
40+
DispatcherType.ERROR);
41+
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
42+
registration.setUrlPatterns(List.of("/**"));
43+
return registration;
44+
}
45+
46+
@Bean
47+
public ModelMapper modelMapper() {
48+
return new ModelMapper();
49+
}
50+
51+
@Bean
52+
@Profile("!test-integration")
53+
public JsonNullableModule jsonNullableModule() {
54+
return new JsonNullableModule();
55+
}
4656
}

api/src/main/java/org/cardanofoundation/rosetta/api/account/model/repository/AddressBalanceRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
public interface AddressBalanceRepository extends
1313
JpaRepository<AddressBalanceEntity, AddressBalanceId> {
1414

15-
// @Query(value =
15+
// @Query(value =
1616
// "SELECT new AddressBalanceEntity (b.address, b.unit, MAX(b.slot), b.quantity, b.addrFull, b.policy, b.assetName, b.paymentCredential, b.stakeAddress, b.blockHash, b.epoch) " +
1717
// "FROM AddressBalanceEntity b " +
1818
// "WHERE b.address = :address AND b.blockNumber <= :number " +

api/src/main/java/org/cardanofoundation/rosetta/api/account/service/impl/AccountServiceImpl.java

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import lombok.RequiredArgsConstructor;
77
import lombok.extern.slf4j.Slf4j;
88

9-
import org.cardanofoundation.rosetta.common.util.CardanoAddressUtil;
9+
import org.cardanofoundation.rosetta.common.util.CardanoAddressUtils;
1010
import org.cardanofoundation.rosetta.common.util.ValidationUtil;
1111
import org.springframework.stereotype.Service;
1212
import org.openapitools.client.model.AccountBalanceRequest;
@@ -16,10 +16,11 @@
1616
import org.openapitools.client.model.Currency;
1717
import org.openapitools.client.model.PartialBlockIdentifier;
1818

19+
import org.cardanofoundation.rosetta.api.account.model.domain.AddressBalance;
1920
import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
2021
import org.cardanofoundation.rosetta.api.account.service.AccountService;
2122
import org.cardanofoundation.rosetta.api.block.model.domain.Block;
22-
import org.cardanofoundation.rosetta.api.block.service.BlockService;
23+
import org.cardanofoundation.rosetta.api.block.model.domain.StakeAddressBalance;
2324
import org.cardanofoundation.rosetta.common.exception.ExceptionFactory;
2425
import org.cardanofoundation.rosetta.common.mapper.DataMapper;
2526
import org.cardanofoundation.rosetta.common.services.LedgerDataProviderService;
@@ -30,15 +31,14 @@
3031
@RequiredArgsConstructor
3132
public class AccountServiceImpl implements AccountService {
3233

33-
private final BlockService blockService;
3434
private final LedgerDataProviderService ledgerDataProviderService;
3535

3636
@Override
3737
public AccountBalanceResponse getAccountBalance(AccountBalanceRequest accountBalanceRequest) {
3838
Long index = null;
3939
String hash = null;
4040
String accountAddress = accountBalanceRequest.getAccountIdentifier().getAddress();
41-
if (Objects.isNull(CardanoAddressUtil.getEraAddressType(accountAddress))) {
41+
if (Objects.isNull(CardanoAddressUtils.getEraAddressType(accountAddress))) {
4242
throw ExceptionFactory.invalidAddressError(accountAddress);
4343
}
4444
PartialBlockIdentifier blockIdentifier = accountBalanceRequest.getBlockIdentifier();
@@ -49,7 +49,8 @@ public AccountBalanceResponse getAccountBalance(AccountBalanceRequest accountBal
4949
hash = blockIdentifier.getHash();
5050
}
5151

52-
return blockService.findBalanceDataByAddressAndBlock(accountAddress, index, hash);
52+
return findBalanceDataByAddressAndBlock(accountAddress, index, hash);
53+
5354
}
5455

5556
@Override
@@ -59,7 +60,7 @@ public AccountCoinsResponse getAccountCoins(AccountCoinsRequest accountCoinsRequ
5960
// accountCoinsRequest.getIncludeMempool(); // TODO
6061

6162
log.debug("[accountCoins] Request received {}", accountCoinsRequest);
62-
if (Objects.isNull(CardanoAddressUtil.getEraAddressType(accountAddress))) {
63+
if (Objects.isNull(CardanoAddressUtils.getEraAddressType(accountAddress))) {
6364
log.debug("[accountCoins] Address isn't Era");
6465
throw ExceptionFactory.invalidAddressError(accountAddress);
6566
}
@@ -76,4 +77,40 @@ public AccountCoinsResponse getAccountCoins(AccountCoinsRequest accountCoinsRequ
7677
log.debug("[accountCoins] found {} Utxos for Address {}", utxos.size(), accountAddress);
7778
return DataMapper.mapToAccountCoinsResponse(latestBlock, utxos);
7879
}
80+
81+
private AccountBalanceResponse findBalanceDataByAddressAndBlock(String address, Long number,
82+
String hash) {
83+
Block blockDto;
84+
if (number != null || hash != null) {
85+
blockDto = ledgerDataProviderService.findBlock(number, hash);
86+
} else {
87+
blockDto = ledgerDataProviderService.findLatestBlock();
88+
}
89+
90+
if (Objects.isNull(blockDto)) {
91+
log.error("[findBalanceDataByAddressAndBlock] Block not found");
92+
throw ExceptionFactory.blockNotFoundException();
93+
}
94+
log.info(
95+
"[findBalanceDataByAddressAndBlock] Looking for utxos for address {} and block {}",
96+
address,
97+
blockDto.getHash());
98+
if (CardanoAddressUtils.isStakeAddress(address)) {
99+
log.debug("[findBalanceDataByAddressAndBlock] Address is StakeAddress");
100+
log.debug("[findBalanceDataByAddressAndBlock] About to get balance for {}", address);
101+
List<StakeAddressBalance> balances = ledgerDataProviderService.findStakeAddressBalanceByAddressAndBlock(
102+
address, blockDto.getNumber());
103+
if (Objects.isNull(balances) || balances.isEmpty()) {
104+
log.error("[findBalanceDataByAddressAndBlock] No balance found for {}", address);
105+
throw ExceptionFactory.invalidAddressError();
106+
}
107+
return DataMapper.mapToStakeAddressBalanceResponse(blockDto, balances.getFirst());
108+
} else {
109+
log.debug("[findBalanceDataByAddressAndBlock] Address isn't StakeAddress");
110+
111+
List<AddressBalance> balances = ledgerDataProviderService.findBalanceByAddressAndBlock(
112+
address, blockDto.getNumber());
113+
return DataMapper.mapToAccountBalanceResponse(blockDto, balances);
114+
}
115+
}
79116
}

api/src/main/java/org/cardanofoundation/rosetta/api/block/controller/BlockApiDelegate.java

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)