Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: public schema by default. [WIP] #343

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.IntegrationTest
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ DB_SECRET=weakpwd#123_d
DB_HOST=db
# Service name in docker-compose or local db
DB_PORT=5432
DB_SCHEMA=${NETWORK}
DB_SCHEMA=public
DB_PATH=data
UPDATE_GENESIS_BLOCK_QUERY="UPDATE devkit.block SET number = 0 WHERE number = -1; UPDATE devkit.block SET prev_hash = 'Genesis' WHERE number = 1"

Expand Down
2 changes: 1 addition & 1 deletion .env.docker-compose
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ DB_SECRET=weakpwd#123_d
DB_HOST=db
# Service name in docker-compose or local db
DB_PORT=5432
DB_SCHEMA=${NETWORK}
DB_SCHEMA=public
DB_PATH=data

## Cardano Node variables
Expand Down
8 changes: 1 addition & 7 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -104,11 +103,6 @@
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jakarta.validation.constraints.NotNull;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.lang3.ObjectUtils;
Expand All @@ -32,10 +31,9 @@
import org.cardanofoundation.rosetta.api.block.model.repository.*;
import org.cardanofoundation.rosetta.common.exception.ExceptionFactory;

import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

@Slf4j
@RequiredArgsConstructor
@Component
@Transactional(readOnly = true)
public class LedgerBlockServiceImpl implements LedgerBlockService {
Expand All @@ -53,9 +51,39 @@ public class LedgerBlockServiceImpl implements LedgerBlockService {
private final BlockMapper blockMapper;
private final TransactionMapper transactionMapper;
private final AddressUtxoEntityToUtxo addressUtxoEntityToUtxo;
private final ExecutorService ioBoundExecutorService;

public LedgerBlockServiceImpl(BlockRepository blockRepository,
TxRepository txRepository,
StakeRegistrationRepository stakeRegistrationRepository,
DelegationRepository delegationRepository,
PoolRegistrationRepository poolRegistrationRepository,
PoolRetirementRepository poolRetirementRepository,
WithdrawalRepository withdrawalRepository,
AddressUtxoRepository addressUtxoRepository,
InvalidTransactionRepository invalidTransactionRepository,
BlockMapper blockMapper,
TransactionMapper transactionMapper,
AddressUtxoEntityToUtxo addressUtxoEntityToUtxo,
@Qualifier("ioBoundExecutorService") ExecutorService ioBoundExecutorService) {
this.blockRepository = blockRepository;
this.txRepository = txRepository;
this.stakeRegistrationRepository = stakeRegistrationRepository;
this.delegationRepository = delegationRepository;
this.poolRegistrationRepository = poolRegistrationRepository;
this.poolRetirementRepository = poolRetirementRepository;
this.withdrawalRepository = withdrawalRepository;
this.addressUtxoRepository = addressUtxoRepository;
this.invalidTransactionRepository = invalidTransactionRepository;
this.blockMapper = blockMapper;
this.transactionMapper = transactionMapper;
this.addressUtxoEntityToUtxo = addressUtxoEntityToUtxo;
this.ioBoundExecutorService = ioBoundExecutorService;
}

private BlockIdentifierExtended cachedGenesisBlock;


@Override
public Optional<Block> findBlock(Long blockNumber, String blockHash) {
log.debug("Query blockNumber: {} , blockHash: {}", blockNumber, blockHash);
Expand All @@ -75,6 +103,7 @@ public Optional<Block> findBlock(Long blockNumber, String blockHash) {
@Override
public Optional<BlockIdentifierExtended> findBlockIdentifier(Long blockNumber, String blockHash) {
log.debug("Query blockNumber: {} , blockHash: {}", blockNumber, blockHash);

if (blockHash == null && blockNumber != null) {
return blockRepository.findBlockIdentifierByNumber(blockNumber)
.map(blockMapper::mapToBlockIdentifierExtended);
Expand Down Expand Up @@ -171,15 +200,22 @@ private TransactionInfo findByTxHash(List<BlockTx> transactions) {
.map(Utxo::getTxHash)
.toList();

try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
var utxos = executor.submit(() -> addressUtxoRepository.findByTxHashIn(utxHashes));
var sReg = executor.submit(() -> stakeRegistrationRepository.findByTxHashIn(txHashes));
var delegations = executor.submit(() -> delegationRepository.findByTxHashIn(txHashes));
var pReg = executor.submit(() -> poolRegistrationRepository.findByTxHashIn(txHashes));
var pRet = executor.submit(() -> poolRetirementRepository.findByTxHashIn(txHashes));
var withdrawals = executor.submit(() -> withdrawalRepository.findByTxHashIn(txHashes));

return new TransactionInfo(utxos.get(10, MINUTES), sReg.get(10, MINUTES), delegations.get(10, MINUTES), pReg.get(10, MINUTES), pRet.get(10, MINUTES), withdrawals.get(10, MINUTES));
try {
var utxos = ioBoundExecutorService.submit(() -> addressUtxoRepository.findByTxHashIn(utxHashes));
var sReg = ioBoundExecutorService.submit(() -> stakeRegistrationRepository.findByTxHashIn(txHashes));
var delegations = ioBoundExecutorService.submit(() -> delegationRepository.findByTxHashIn(txHashes));
var pReg = ioBoundExecutorService.submit(() -> poolRegistrationRepository.findByTxHashIn(txHashes));
var pRet = ioBoundExecutorService.submit(() -> poolRetirementRepository.findByTxHashIn(txHashes));
var withdrawals = ioBoundExecutorService.submit(() -> withdrawalRepository.findByTxHashIn(txHashes));

return new TransactionInfo(
utxos.get(10, SECONDS),
sReg.get(10, SECONDS),
delegations.get(10, SECONDS),
pReg.get(10, SECONDS),
pRet.get(10, SECONDS),
withdrawals.get(10, SECONDS)
);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
log.error("Error fetching transaction data", e);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import jakarta.validation.constraints.NotNull;
import javax.annotation.Nullable;

Expand Down Expand Up @@ -35,7 +32,6 @@
import com.bloxbean.cardano.client.exception.CborDeserializationException;
import com.bloxbean.cardano.client.exception.CborSerializationException;
import com.bloxbean.cardano.client.transaction.spec.*;
import com.bloxbean.cardano.client.transaction.spec.Transaction;
import com.bloxbean.cardano.client.transaction.spec.TransactionBody.TransactionBodyBuilder;
import com.bloxbean.cardano.client.util.HexUtil;
import org.apache.commons.lang3.ObjectUtils;
Expand Down Expand Up @@ -79,8 +75,6 @@ public class CardanoConstructionServiceImpl implements CardanoConstructionServic
private final RestTemplate restTemplate;
private final OfflineSlotService offlineSlotService;

private final ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor(); // TODO this probably gives more overhead than it should

@Value("${cardano.rosetta.NODE_SUBMIT_API_PORT}")
private int nodeSubmitApiPort;

Expand Down Expand Up @@ -201,23 +195,18 @@ public String buildTransaction(String unsignedTransaction,
log.info("[buildTransaction] About to signed a transaction with {} signatures",
signaturesList.size());

CompletableFuture<TransactionBody> transactionBodyFuture =
CompletableFuture.supplyAsync(() -> deserializeTransactionBody(unsignedTransaction), executorService);

CompletableFuture<TransactionWitnessSet> witnessesFuture =
CompletableFuture.supplyAsync(() -> getWitnessesForTransaction(signaturesList), executorService);

CompletableFuture<AuxiliaryData> auxiliaryDataFuture =
CompletableFuture.supplyAsync(() -> deserializeAuxiliaryData(transactionMetadata), executorService);
TransactionBody transactionBody = deserializeTransactionBody(unsignedTransaction);
TransactionWitnessSet witnesses = getWitnessesForTransaction(signaturesList);
AuxiliaryData auxiliaryData = deserializeAuxiliaryData(transactionMetadata);

try {
log.info(
"[buildTransaction] Creating transaction using transaction body and extracted witnesses");

Transaction transaction = new Transaction();
transaction.setBody(transactionBodyFuture.join());
transaction.setAuxiliaryData(auxiliaryDataFuture.join());
transaction.setWitnessSet(witnessesFuture.join());
var transaction = new com.bloxbean.cardano.client.transaction.spec.Transaction();
transaction.setBody(transactionBody);
transaction.setAuxiliaryData(auxiliaryData);
transaction.setWitnessSet(witnesses);
transaction.setValid(true);

Array cborTransactionsArray = (Array) CborSerializationUtil.deserialize(transaction.serialize());
Expand Down Expand Up @@ -379,21 +368,25 @@ public List<SigningPayload> constructPayloadsForTransactionBody(String transacti
transactionBodyHash, SignatureType.ED25519)).toList();
}

private ProcessOperationsReturn processOperations(Network network,
List<Operation> operations) {
private ProcessOperationsReturn processOperations(Network network, List<Operation> operations) {
ProcessOperations result = convertRosettaOperations(network, operations);

ProcessOperationsReturn operationsReturn = new ProcessOperationsReturn();
operationsReturn.setTransactionInputs(result.getTransactionInputs());
operationsReturn.setTransactionOutputs(result.getTransactionOutputs());
operationsReturn.setCertificates(result.getCertificates());
operationsReturn.setWithdrawals(result.getWithdrawals());
return fillProcessOperationsReturnObject(result);
}

@NotNull
private ProcessOperationsReturn fillProcessOperationsReturnObject(ProcessOperations result) {
ProcessOperationsReturn processOperationsDto = new ProcessOperationsReturn();
processOperationsDto.setTransactionInputs(result.getTransactionInputs());
processOperationsDto.setTransactionOutputs(result.getTransactionOutputs());
processOperationsDto.setCertificates(result.getCertificates());
processOperationsDto.setWithdrawals(result.getWithdrawals());
Set<String> addresses = new HashSet<>(result.getAddresses());
operationsReturn.setAddresses(addresses);
operationsReturn.setFee(MIN_DUMMY_FEE);
operationsReturn.setVoteRegistrationMetadata(result.getVoteRegistrationMetadata());
processOperationsDto.setAddresses(addresses);
processOperationsDto.setFee(MIN_DUMMY_FEE);
processOperationsDto.setVoteRegistrationMetadata(result.getVoteRegistrationMetadata());

return operationsReturn;
return processOperationsDto;
}

@Override
Expand All @@ -402,17 +395,14 @@ public ProcessOperations convertRosettaOperations(Network network, List<Operatio

for (Operation operation : operations) {
String type = operation.getType();

processor = OperationParseUtil.parseOperation(operation, network, processor, type);

processor = OperationParseUtil.parseOperation(operation, network, processor,
type);
if (processor == null) {
log.error("[processOperations] Operation with id {} has invalid type",
operation.getOperationIdentifier());

throw ExceptionFactory.invalidOperationTypeError();
}
}

return processor;
}

Expand Down Expand Up @@ -461,7 +451,6 @@ public String submitTransaction(String signedTransaction) throws ApiException {
@Override
public DepositParameters getDepositParameters() {
ProtocolParams pp = protocolParamService.findProtocolParameters();

return new DepositParameters(pp.getKeyDeposit().toString(), pp.getPoolDeposit().toString());
}

Expand Down Expand Up @@ -546,7 +535,6 @@ public HdPublicKey getHdPublicKeyFromRosettaKey(PublicKey publicKey) {
log.error("Invalid public key length: {}", pubKeyBytes.length);
throw new IllegalArgumentException("Invalid public key length");
}

return pubKey;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.cardanofoundation.rosetta.config;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ThreadPoolsConfig {

@Bean
@Qualifier("ioBoundExecutorService")
@SuppressWarnings("java:S6831")
// we use green threads from JDK 21 in this project so no need to use real operating system threads thread pool for IO bound tasks
public ExecutorService ioBoundExecutorService() {
return Executors.newVirtualThreadPerTaskExecutor();
}

}
2 changes: 1 addition & 1 deletion api/src/main/resources/config/application-online.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ spring:
datasource:
username: ${DB_USER:rosetta_db_admin}
password: ${DB_SECRET:weakpwd#123_d}
url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5433}/${DB_NAME:test}?currentSchema=${DB_SCHEMA:preprod}
url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5433}/${DB_NAME:test}?currentSchema=${DB_SCHEMA:public}
hikari:
connectionTimeout: 100000 #default connection-timeout is 30 seconds
minimumIdle: 10 # default minimumIdle is 10
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/resources/config/application-staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ spring:
datasource:
username: rosetta_db_service_user
password: weakerpwd#123_d
url: jdbc:postgresql://172.16.1.217:5432/rosetta?currentSchema=${DB_SCHEMA:preprod}
url: jdbc:postgresql://172.16.1.217:5432/rosetta?currentSchema=${DB_SCHEMA:public}
jpa:
properties:
hibernate:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import lombok.val;

import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;

import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -72,6 +75,9 @@ class LedgerBlockServiceImplTest {
@Mock
private InvalidTransactionRepository invalidTransactionRepository;

@Spy
private ExecutorService ioBoundExecutorService = Executors.newSingleThreadExecutor();

@Test
void testExecutorServiceExceptions() {
//given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.CompletionException;

import org.springframework.beans.factory.annotation.Autowired;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -72,20 +71,19 @@ void combineWithByronAddressMissingChaincodeTest() throws IOException {
ConstructionCombineRequest combineRequest = getCombineRequest(
"testdata/construction/combine/combine_with_byron_addresses_missing_chaincode.json");

// API Exception is wrapped in CompletionException when thrown from CompletableFuture
CompletionException actualException = assertThrows(CompletionException.class, () ->
ApiException actualException = assertThrows(ApiException.class, () ->
constructionApiService.constructionCombineService(combineRequest));

assertInstanceOf(ApiException.class, actualException.getCause());
ApiException apiException = (ApiException) actualException.getCause();
assertEquals(RosettaErrorType.CHAIN_CODE_MISSING.getCode(), apiException.getError().getCode());
assertEquals(RosettaErrorType.CHAIN_CODE_MISSING.getMessage(), apiException.getError().getMessage());
assertEquals(RosettaErrorType.CHAIN_CODE_MISSING.getCode(), actualException.getError().getCode());
assertEquals(RosettaErrorType.CHAIN_CODE_MISSING.getMessage(), actualException.getError().getMessage());
}

private ConstructionCombineRequest getCombineRequest(String fileName) throws IOException {
File file = new File(
Objects.requireNonNull(this.getClass().getClassLoader().getResource(fileName)).getFile());
ObjectMapper mapper = new ObjectMapper();

return mapper.readValue(file, ConstructionCombineRequest.class);
}

}
Loading
Loading