Skip to content

Commit

Permalink
feat: RA-78 Refactor LedgerBlockServiceImpl
Browse files Browse the repository at this point in the history
  • Loading branch information
shleger committed Apr 25, 2024
1 parent 383c6dc commit 062ac3a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 99 deletions.
Original file line number Diff line number Diff line change
@@ -1,40 +1,24 @@
package org.cardanofoundation.rosetta.api.block.model.repository;

import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import org.cardanofoundation.rosetta.api.block.model.entity.BlockEntity;
import org.cardanofoundation.rosetta.api.block.model.entity.TxnEntity;


public interface BlockRepository extends JpaRepository<BlockEntity, Long> {

@Query(value =
"SELECT b " +
"FROM BlockEntity b " +
"WHERE b.prev.hash IS NULL")
List<BlockEntity> findGenesisBlock();
@Query(value = "SELECT b FROM BlockEntity b WHERE b.prev.hash IS NULL")
Optional<BlockEntity> findGenesisBlock();

Optional<BlockEntity> findByNumber(Long blockNumber);

Optional<BlockEntity> findByHash(String blockHash);

Optional<BlockEntity> findByNumberAndHash(Long blockNumber, String blockHash);

@Query("SELECT number FROM BlockEntity " +
"ORDER BY number DESC LIMIT 1")
@Query("SELECT number FROM BlockEntity ORDER BY number DESC LIMIT 1")
Long findLatestBlockNumber();

@Query("SELECT tx "
+ "FROM TxnEntity tx "
+ "WHERE tx.txHash = :hash "
+ "AND tx.block.hash = :blockHash")
List<TxnEntity> findTransactionByHashAndBlock(
@Param("hash") String hash,
@Param("blockHash") String blockHash);

}
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package org.cardanofoundation.rosetta.api.block.service;

import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.TimeZone;
import java.util.stream.Collectors;

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

import org.springframework.stereotype.Component;

import org.apache.commons.lang3.ObjectUtils;
import org.modelmapper.ModelMapper;

import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
import org.cardanofoundation.rosetta.api.account.model.entity.AddressUtxoEntity;
import org.cardanofoundation.rosetta.api.account.model.repository.AddressUtxoRepository;
import org.cardanofoundation.rosetta.api.block.mapper.BlockToEntity;
Expand All @@ -39,8 +37,6 @@
import org.cardanofoundation.rosetta.api.block.model.repository.TxRepository;
import org.cardanofoundation.rosetta.api.block.model.repository.WithdrawalRepository;
import org.cardanofoundation.rosetta.common.exception.ExceptionFactory;

import org.cardanofoundation.rosetta.api.account.model.domain.Utxo;
import org.cardanofoundation.rosetta.common.services.ProtocolParamService;


Expand All @@ -67,7 +63,6 @@ public class LedgerBlockServiceImpl implements LedgerBlockService {
private final WithdrawalEntityToWithdrawal withdrawalEntityToWithdrawal;



@Override
public Block findBlock(Long blockNumber, String blockHash) {
log.debug("Query blockNumber: {} , blockHash: {}", blockNumber, blockHash);
Expand All @@ -81,35 +76,28 @@ public Block findBlock(Long blockNumber, String blockHash) {
}
if (block.isPresent()) {
log.debug("Block found! {}", block);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
// Populating transactions
Block model = mapperBlock.fromEntity(block.get());
populateTransactions(model.getTransactions());
model.getTransactions().forEach(this::populateTransaction);
return model;
}
log.debug("[findBlock] No block was found");
return null;
}

@Override
public List<BlockTx> findTransactionsByBlock(Long blockNumber, String blockHash) {
log.debug(
"[findTransactionsByBlock] Parameters received for run query blockNumber: {} blockHash: {}",
blockNumber, blockHash);

Optional<BlockEntity> byNumberAndHash = blockRepository.findByNumberAndHash(blockNumber, blockHash);
if (byNumberAndHash.isEmpty()) {
log.debug("[findTransactionsByBlock] No block found for blockNumber: {} blockHash: {}",
blockNumber, blockHash);
public List<BlockTx> findTransactionsByBlock(Long blk, String blkHash) {
log.debug("[findTransactionsByBlock] query blockNumber: {} blockHash: {}", blk, blkHash);
Optional<BlockEntity> blkEntity = blockRepository.findByNumberAndHash(blk, blkHash);
if (blkEntity.isEmpty()) {
log.debug("[findTransactionsByBlock] Block Not found: {} blockHash: {}", blk, blkHash);
return Collections.emptyList();
}
List<TxnEntity> txList = txRepository.
findTransactionsByBlockHash(byNumberAndHash.get().getHash());
List<TxnEntity> txList = txRepository.findTransactionsByBlockHash(blkEntity.get().getHash());
log.debug("[findTransactionsByBlock] Found {} transactions", txList.size());
if (ObjectUtils.isNotEmpty(txList)) {
List<BlockTx> transactions = txList.stream().map(mapperTran::fromEntity).toList();
populateTransactions(transactions);
transactions.forEach(this::populateTransaction);
return transactions;
}
return Collections.emptyList();
Expand All @@ -133,70 +121,68 @@ public Block findLatestBlock() {
@Override
public GenesisBlock findGenesisBlock() {
log.debug("[findGenesisBlock] About to run findGenesisBlock query");
List<BlockEntity> blocks = blockRepository.findGenesisBlock();
if (!blocks.isEmpty()) {
BlockEntity genesis = blocks.getFirst();
return GenesisBlock.builder().hash(genesis.getHash())
.number(genesis.getNumber())
.build();
}
log.error("[findGenesisBlock] Genesis block was not found");
throw ExceptionFactory.genesisBlockNotFound();
return blockRepository.findGenesisBlock()
.map(b -> mapper.map(b, GenesisBlock.class))
.orElseThrow(ExceptionFactory::genesisBlockNotFound);
}



private void populateTransactions(List<BlockTx> transactions) {
for (BlockTx transaction : transactions) {
populateUtxo(transaction.getInputs());
populateUtxo(transaction.getOutputs());

transaction.setStakeRegistrations(
stakeRegistrationRepository
.findByTxHash(transaction.getHash())
.stream()
.map(m -> mapper.map(m, StakeRegistration.class))
.collect(Collectors.toList()));

transaction.setDelegations(
delegationRepository
.findByTxHash(transaction.getHash())
.stream()
.map(m -> mapper.map(m, Delegation.class))
.collect(Collectors.toList()));

transaction.setPoolRegistrations(poolRegistrationRepository
.findByTxHash(transaction.getHash())
.stream()
.map(PoolRegistration::fromEntity)
.toList()); // TODO Refacotring - do this via JPA

transaction.setPoolRetirements(poolRetirementRepository
.findByTxHash(transaction.getHash())
.stream()
.map(m -> mapper.map(m, PoolRetirement.class))
.collect(Collectors.toList()));

transaction.setWithdrawals(withdrawalRepository
.findByTxHash(transaction.getHash())
.stream()
.map(withdrawalEntityToWithdrawal::fromEntity)
.toList());

ProtocolParams protocolParametersFromIndexerAndConfig = protocolParamService.findProtocolParametersFromIndexerAndConfig();
transaction.setSize((Long.parseLong(transaction.getFee()) - protocolParametersFromIndexerAndConfig.getMinFeeB().longValue()) / protocolParametersFromIndexerAndConfig.getMinFeeA().longValue());
}
private void populateTransaction(BlockTx transaction) {

Optional.ofNullable(transaction.getInputs())
.stream()
.flatMap(List::stream)
.forEach(this::populateUtxo);

Optional.ofNullable(transaction.getOutputs())
.stream()
.flatMap(List::stream)
.forEach(this::populateUtxo);

transaction.setStakeRegistrations(
stakeRegistrationRepository
.findByTxHash(transaction.getHash())
.stream()
.map(m -> mapper.map(m, StakeRegistration.class))
.collect(Collectors.toList()));

transaction.setDelegations(
delegationRepository
.findByTxHash(transaction.getHash())
.stream()
.map(m -> mapper.map(m, Delegation.class))
.collect(Collectors.toList()));

transaction.setPoolRegistrations(poolRegistrationRepository
.findByTxHash(transaction.getHash())
.stream()
.map(PoolRegistration::fromEntity)
.toList()); // TODO Refacotring - do this via JPA

transaction.setPoolRetirements(poolRetirementRepository
.findByTxHash(transaction.getHash())
.stream()
.map(m -> mapper.map(m, PoolRetirement.class))
.collect(Collectors.toList()));

transaction.setWithdrawals(withdrawalRepository
.findByTxHash(transaction.getHash())
.stream()
.map(withdrawalEntityToWithdrawal::fromEntity)
.toList());

ProtocolParams pps = protocolParamService.findProtocolParametersFromIndexerAndConfig();
transaction.setSize(calcSize(transaction, pps));
}

private void populateUtxo(List<Utxo> inputs) {
for (Utxo utxo : inputs) {
AddressUtxoEntity first = addressUtxoRepository.findAddressUtxoEntitiesByOutputIndexAndTxHash(
utxo.getOutputIndex(), utxo.getTxHash()).getFirst();
if (first != null) {
// Populating the values from entity to model
mapper.map(first, utxo);
}
}
private static long calcSize(BlockTx tx, ProtocolParams p) {
return (Long.parseLong(tx.getFee()) - p.getMinFeeB().longValue()) / p.getMinFeeA().longValue();
}

private void populateUtxo(Utxo utxo) {
AddressUtxoEntity first = addressUtxoRepository
.findAddressUtxoEntitiesByOutputIndexAndTxHash(utxo.getOutputIndex(), utxo.getTxHash())
.getFirst();
Optional.ofNullable(first).ifPresent(m -> mapper.map(m, utxo));
}
}

0 comments on commit 062ac3a

Please sign in to comment.