Skip to content

Commit

Permalink
update apply tx logic and add logic for remove reserved domains when …
Browse files Browse the repository at this point in the history
…tx failed
  • Loading branch information
MrFoxogen committed Mar 12, 2024
1 parent 07db0a2 commit f272cc5
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class DomainEntity {
@Column(name = "owner_address", columnDefinition = "TEXT")
private String ownerAddress;

@ManyToOne
@ManyToOne(cascade = CascadeType.REMOVE)
@JoinColumn(name="transaction", nullable=false)
@JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="txHash")
@JsonIdentityReference(alwaysAsId=true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
@RequiredArgsConstructor
public enum TxStatus {
PENDING,
APPLIED
APPLIED,
FAILED
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.List;

@Repository
@ConditionalOnProperty(value = "spring.minascan-datasource.enabled", havingValue = "true")
public interface TransactionRepository extends JpaRepository<UserCommandsEntity, Integer> {

@Query(nativeQuery = true,
value = """
SELECT buc.status as status
SELECT uc.hash as txHash,
buc.status as status,
(cast(uc.amount as bigint) + cast(uc.fee as bigint)) as amount
FROM user_commands uc
JOIN blocks_user_commands buc ON uc.id = buc.user_command_id
JOIN a_canonical_blocks cb ON cb.id = buc.block_id
WHERE uc.hash = :txHash
WHERE uc.hash in (:txHash)
""")
String getTxStatusByTxHash(String txHash);
List<TxProjection> getTxStatusByTxHashIn(Collection<String> txHash);
}
10 changes: 10 additions & 0 deletions src/main/java/com/staketab/minanames/minascan/TxProjection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.staketab.minanames.minascan;

public interface TxProjection {

String getTxHash();

String getStatus();

Long getAmount();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class CheckerReservedTransactionScheduler {
private final TxService txService;

@Scheduled(fixedDelayString = "${scheduled.checker-tx-reserve.upload-mills}")
public void updateProjects() {
public void checkReservedTxs() {
txService.checkTransactions();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@
import com.staketab.minanames.entity.PayableTransactionEntity;
import com.staketab.minanames.entity.dto.TxStatus;
import com.staketab.minanames.minascan.TransactionRepository;
import com.staketab.minanames.minascan.TxProjection;
import com.staketab.minanames.repository.DomainRepository;
import com.staketab.minanames.repository.PayableTransactionRepository;
import com.staketab.minanames.service.abstraction.TxService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
Expand All @@ -18,28 +25,50 @@ public class TxServiceImpl implements TxService {

private final PayableTransactionRepository payableTransactionRepository;
private final TransactionRepository transactionRepository;
private final DomainRepository domainRepository;

@Override
public PayableTransactionEntity getOrCreate(String txHash) {
return payableTransactionRepository.findById(txHash).orElseGet(() -> createTx(txHash));
}

@Override
@Transactional
public void checkTransactions() {
List<PayableTransactionEntity> resultTxs = payableTransactionRepository
.findAllByTxStatus(TxStatus.PENDING)
.stream()
.filter(this::txStatusPredicate)
List<PayableTransactionEntity> pendingTxs = payableTransactionRepository.findAllByTxStatus(TxStatus.PENDING);
Map<TxStatus, List<PayableTransactionEntity>> txStatusListMap = generateMapOfFailedAndAppliedTxs(pendingTxs);

applyReservedTxs(txStatusListMap.get(TxStatus.APPLIED));
domainRepository.deleteAllByTransactionIn(txStatusListMap.get(TxStatus.FAILED));
}

private void applyReservedTxs(List<PayableTransactionEntity> pendingTxs) {
List<PayableTransactionEntity> appliedTxs = pendingTxs.stream()
.peek(payableTransaction -> payableTransaction.setTxStatus(TxStatus.APPLIED))
.toList();

payableTransactionRepository.saveAll(resultTxs);
payableTransactionRepository.saveAll(appliedTxs);
}

private Map<TxStatus, List<PayableTransactionEntity>> generateMapOfFailedAndAppliedTxs(List<PayableTransactionEntity> payableTransactions) {
Map<String, PayableTransactionEntity> mapPayableTransactions = payableTransactions.stream()
.collect(Collectors.toMap(PayableTransactionEntity::getTxHash, Function.identity()));
List<TxProjection> txStatusProjections = transactionRepository.getTxStatusByTxHashIn(mapPayableTransactions.keySet());
return getSplitedMap(txStatusProjections, mapPayableTransactions);
}

private boolean txStatusPredicate(PayableTransactionEntity payableTransaction) {
String txHash = payableTransaction.getTxHash();
String txStatusByTxHash = transactionRepository.getTxStatusByTxHash(txHash);
return txStatusByTxHash != null && TxStatus.APPLIED.name().equals(txStatusByTxHash.toUpperCase());
private static Map<TxStatus, List<PayableTransactionEntity>> getSplitedMap(List<TxProjection> txStatusByTxHashIn, Map<String, PayableTransactionEntity> mapPayableTransactions) {
List<PayableTransactionEntity> failed = new ArrayList<>();
List<PayableTransactionEntity> applied = new ArrayList<>();
for (TxProjection txProjection : txStatusByTxHashIn) {
if (TxStatus.APPLIED.name().equals(txProjection.getStatus().toUpperCase())) {
applied.add(mapPayableTransactions.get(txProjection.getTxHash()));
}
if (TxStatus.FAILED.name().equals(txProjection.getStatus().toUpperCase())) {
failed.add(mapPayableTransactions.get(txProjection.getTxHash()));
}
}
return Map.of(TxStatus.APPLIED, applied, TxStatus.FAILED, failed);
}

private PayableTransactionEntity createTx(String txHash) {
Expand Down

0 comments on commit f272cc5

Please sign in to comment.