Skip to content

Commit

Permalink
feat: RA-43 Refactoring and testing /block endpoint [no final asserts] (
Browse files Browse the repository at this point in the history
#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
  • Loading branch information
shleger authored Mar 21, 2024
1 parent c3e6685 commit 77e1033
Show file tree
Hide file tree
Showing 63 changed files with 2,634 additions and 1,255 deletions.
45 changes: 45 additions & 0 deletions .env.h2
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#Use envfile plugin for IDEA
#https://plugins.jetbrains.com/plugin/7861-envfile

API_SPRING_PROFILES_ACTIVE=devh2

NETWORK=devkit # devkit, mainnet, testnet, preprod
PROTOCOL_MAGIC=42

#common env
DB_ADMIN_USER_NAME=rosetta_db_admin
DB_ADMIN_USER_SECRET=weakpwd#123_d

DB_IMAGE_NAME=h2
DB_IMAGE_TAG=14.11-bullseye
DB_NAME=rosetta-java-preprod
DB_HOST=db # Service name in docker-compose or local db
DB_PORT=5432
DB_SCHEMA=${NETWORK}
MAXIMUM_POOL_SIZE=80
JDBC_BATCH_SIZE=1000
SCHEMA=${NETWORK}
CARDANO_NODE_HOST=localhost # Service name in docker-compose or local cardano node
CARDANO_NODE_PORT=3001 # Uncomment if you are using local cardano node
CARDANO_NODE_VERSION=8.1.2
LOG=INFO

#api env
API_SPRING_PROFILES_ACTIVE_API=dev
API_EXPOSED_PORT=8081
API_BIND_PORT=8081
TRANSACTION_TTL=3000

DB_CONNECTION_PARAMS_PROVIDER_TYPE=ENVIRONMENT
DB_DRIVER_CLASS_NAME=org.h2.Driver

ROSETTA_VERSION=1.4.13
TOPOLOGY_FILEPATH=config/${NETWORK}/topology.json
GENESIS_SHELLEY_PATH=config/${NETWORK}/shelley-genesis.json
GENESIS_BYRON_PATH=config/${NETWORK}/byron-genesis.json

PRINT_EXCEPTION=true

#api env
API_SPRING_PROFILES_ACTIVE_YACI_INDEXER=postgres # database profiles: h2, postgres
INDEXER_NODE_PORT=3001
10 changes: 0 additions & 10 deletions api/api.iml

This file was deleted.

54 changes: 31 additions & 23 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
<artifactId>api</artifactId>
<name>api</name>
<description>Rosetta API implementation for Cardano.</description>
<properties>
<spotbugs-annotations.version>4.8.3</spotbugs-annotations.version>
</properties>

<packaging>jar</packaging>

Expand Down Expand Up @@ -137,7 +140,7 @@
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
<version>4.8.3</version>
<version>${spotbugs-annotations.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
Expand Down Expand Up @@ -212,27 +215,6 @@
<version>3.41.0</version>
<scope>compile</scope>
</dependency>

<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.testcontainers/testcontainers &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.testcontainers</groupId>-->
<!-- <artifactId>testcontainers</artifactId>-->
<!-- <version>1.17.6</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.purejava/tweetnacl-java &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.purejava</groupId>-->
<!-- <artifactId>tweetnacl-java</artifactId>-->
<!-- <version>1.1.2</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.mockito</groupId>-->
<!-- <artifactId>mockito-inline</artifactId>-->
<!-- <version>3.8.0</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
Expand All @@ -245,7 +227,20 @@
<version>3.7.0</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
</dependency>
<dependency>
<groupId>org.modelmapper.extensions</groupId>
<artifactId>modelmapper-spring</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-core.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -420,4 +415,17 @@
</plugins>
</build>

<profiles>
<profile>
<id>h2-api</id>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package org.cardanofoundation.rosetta;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import java.util.List;
import jakarta.servlet.DispatcherType;
import org.openapitools.jackson.nullable.JsonNullableModule;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
Expand All @@ -12,35 +11,46 @@
import org.springframework.context.annotation.Profile;
import org.springframework.core.Ordered;
import org.springframework.web.filter.ForwardedHeaderFilter;

import java.util.List;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import org.modelmapper.ModelMapper;
import org.openapitools.jackson.nullable.JsonNullableModule;


@SpringBootApplication
@EntityScan({
"org.cardanofoundation.rosetta.api.account.model.entity",
"org.cardanofoundation.rosetta.api.block.model.entity",
"org.cardanofoundation.rosetta.api.construction.model.entity",
"org.cardanofoundation.rosetta.api.network.model.entity",
"org.cardanofoundation.rosetta.api.common.model.entity"})
"org.cardanofoundation.rosetta.api.account.model.entity",
"org.cardanofoundation.rosetta.api.block.model.entity",
"org.cardanofoundation.rosetta.api.construction.model.entity",
"org.cardanofoundation.rosetta.api.network.model.entity",
"org.cardanofoundation.rosetta.api.common.model.entity"})
@OpenAPIDefinition(info = @Info(title = "APIs", version = "1.0", description = "Rosetta APIs v1.0"))
public class RosettaApiApplication {
public static void main(String[] args) {
SpringApplication.run(RosettaApiApplication.class, args);
}

@Bean
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
final ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
final FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(filter);
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
registration.setUrlPatterns(List.of("/**"));
return registration;
}
@Bean
@Profile("!test-integration")
public JsonNullableModule jsonNullableModule() {
return new JsonNullableModule();
}

public static void main(String[] args) {
SpringApplication.run(RosettaApiApplication.class, args);
}

@Bean
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
final ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
final FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(
filter);
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC,
DispatcherType.ERROR);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
registration.setUrlPatterns(List.of("/**"));
return registration;
}

@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}

@Bean
@Profile("!test-integration")
public JsonNullableModule jsonNullableModule() {
return new JsonNullableModule();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public interface AddressBalanceRepository extends
JpaRepository<AddressBalanceEntity, AddressBalanceId> {

// @Query(value =
// @Query(value =
// "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) " +
// "FROM AddressBalanceEntity b " +
// "WHERE b.address = :address AND b.blockNumber <= :number " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.cardanofoundation.rosetta.common.util.CardanoAddressUtil;
import org.cardanofoundation.rosetta.common.util.CardanoAddressUtils;
import org.cardanofoundation.rosetta.common.util.ValidationUtil;
import org.springframework.stereotype.Service;
import org.openapitools.client.model.AccountBalanceRequest;
Expand All @@ -16,10 +16,11 @@
import org.openapitools.client.model.Currency;
import org.openapitools.client.model.PartialBlockIdentifier;

import org.cardanofoundation.rosetta.api.account.model.domain.AddressBalance;
import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
import org.cardanofoundation.rosetta.api.account.service.AccountService;
import org.cardanofoundation.rosetta.api.block.model.domain.Block;
import org.cardanofoundation.rosetta.api.block.service.BlockService;
import org.cardanofoundation.rosetta.api.block.model.domain.StakeAddressBalance;
import org.cardanofoundation.rosetta.common.exception.ExceptionFactory;
import org.cardanofoundation.rosetta.common.mapper.DataMapper;
import org.cardanofoundation.rosetta.common.services.LedgerDataProviderService;
Expand All @@ -30,15 +31,14 @@
@RequiredArgsConstructor
public class AccountServiceImpl implements AccountService {

private final BlockService blockService;
private final LedgerDataProviderService ledgerDataProviderService;

@Override
public AccountBalanceResponse getAccountBalance(AccountBalanceRequest accountBalanceRequest) {
Long index = null;
String hash = null;
String accountAddress = accountBalanceRequest.getAccountIdentifier().getAddress();
if (Objects.isNull(CardanoAddressUtil.getEraAddressType(accountAddress))) {
if (Objects.isNull(CardanoAddressUtils.getEraAddressType(accountAddress))) {
throw ExceptionFactory.invalidAddressError(accountAddress);
}
PartialBlockIdentifier blockIdentifier = accountBalanceRequest.getBlockIdentifier();
Expand All @@ -49,7 +49,8 @@ public AccountBalanceResponse getAccountBalance(AccountBalanceRequest accountBal
hash = blockIdentifier.getHash();
}

return blockService.findBalanceDataByAddressAndBlock(accountAddress, index, hash);
return findBalanceDataByAddressAndBlock(accountAddress, index, hash);

}

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

log.debug("[accountCoins] Request received {}", accountCoinsRequest);
if (Objects.isNull(CardanoAddressUtil.getEraAddressType(accountAddress))) {
if (Objects.isNull(CardanoAddressUtils.getEraAddressType(accountAddress))) {
log.debug("[accountCoins] Address isn't Era");
throw ExceptionFactory.invalidAddressError(accountAddress);
}
Expand All @@ -76,4 +77,40 @@ public AccountCoinsResponse getAccountCoins(AccountCoinsRequest accountCoinsRequ
log.debug("[accountCoins] found {} Utxos for Address {}", utxos.size(), accountAddress);
return DataMapper.mapToAccountCoinsResponse(latestBlock, utxos);
}

private AccountBalanceResponse findBalanceDataByAddressAndBlock(String address, Long number,
String hash) {
Block blockDto;
if (number != null || hash != null) {
blockDto = ledgerDataProviderService.findBlock(number, hash);
} else {
blockDto = ledgerDataProviderService.findLatestBlock();
}

if (Objects.isNull(blockDto)) {
log.error("[findBalanceDataByAddressAndBlock] Block not found");
throw ExceptionFactory.blockNotFoundException();
}
log.info(
"[findBalanceDataByAddressAndBlock] Looking for utxos for address {} and block {}",
address,
blockDto.getHash());
if (CardanoAddressUtils.isStakeAddress(address)) {
log.debug("[findBalanceDataByAddressAndBlock] Address is StakeAddress");
log.debug("[findBalanceDataByAddressAndBlock] About to get balance for {}", address);
List<StakeAddressBalance> balances = ledgerDataProviderService.findStakeAddressBalanceByAddressAndBlock(
address, blockDto.getNumber());
if (Objects.isNull(balances) || balances.isEmpty()) {
log.error("[findBalanceDataByAddressAndBlock] No balance found for {}", address);
throw ExceptionFactory.invalidAddressError();
}
return DataMapper.mapToStakeAddressBalanceResponse(blockDto, balances.getFirst());
} else {
log.debug("[findBalanceDataByAddressAndBlock] Address isn't StakeAddress");

List<AddressBalance> balances = ledgerDataProviderService.findBalanceByAddressAndBlock(
address, blockDto.getNumber());
return DataMapper.mapToAccountBalanceResponse(blockDto, balances);
}
}
}

This file was deleted.

Loading

0 comments on commit 77e1033

Please sign in to comment.