Skip to content

Commit

Permalink
chore: Added parsed redeemer info to transaction_scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
satran004 committed Nov 16, 2023
1 parent ac12d37 commit 5c6116a
Show file tree
Hide file tree
Showing 15 changed files with 150 additions and 94 deletions.
9 changes: 8 additions & 1 deletion config/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@ spring.h2.console.enabled=true
#spring.datasource.username=user
#spring.datasource.password=password

#################### Connection Pool Setting ##########
#################### Other DB Settings ##########
#spring.datasource.hikari.maximum-pool-size=30
#spring.datasource.hikari.minimum-idle=5
#spring.jpa.properties.hibernate.jdbc.batch_size=100
#spring.jpa.show-sql=true

#########################################################
# Log Configuration
Expand Down Expand Up @@ -139,6 +141,11 @@ store.account.history-cleanup-enabled=false
store.account.batch-balance-aggregation-enabled=true
store.account.batch-balance-aggregation-scheduler-enabled=true

############### Additional configurations for balance batch aggregation ##########
#store.account.batch-balance-aggregation-schedule-delay=5
#store.account.batch-balance-aggregation-batch-size=4320
#store.account.batch-balance-aggregation-safe-block-diff=500

###################################################
# Parallel processing configuration
###################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.math.BigInteger;

@Getter
@AllArgsConstructor
@NoArgsConstructor
Expand All @@ -20,7 +18,7 @@
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class Redeemer {
private RedeemerTag tag;
private BigInteger index;
private Integer index;
private String data;
private ExUnits exUnits;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.bloxbean.cardano.yaci.store.script.domain;

import com.bloxbean.cardano.client.plutus.spec.RedeemerTag;
import com.bloxbean.cardano.yaci.store.common.domain.BlockAwareDomain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.math.BigInteger;

@Data
@NoArgsConstructor
@AllArgsConstructor
Expand All @@ -16,7 +19,13 @@ public class TxScript extends BlockAwareDomain {
private Long slot;
private String blockHash;
private ScriptType type;
private String redeemer;
private String redeemerCbor;
private String datum;
private String datumHash;
private BigInteger unitMem;
private BigInteger unitSteps;
private RedeemerTag purpose;
private Integer redeemerIndex;
private String redeemerData;
private String redeemerDatahash;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class TxRedeemerDto {
private Integer txIndex;
private String purpose;
private String scriptHash;
private String datumHash;
private String redeemerDataHash;
private String unitMem;
private String unitSteps;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package com.bloxbean.cardano.yaci.store.script.helper;

import com.bloxbean.cardano.client.address.Address;
import com.bloxbean.cardano.client.plutus.spec.Redeemer;
import com.bloxbean.cardano.client.plutus.spec.RedeemerTag;
import com.bloxbean.cardano.client.util.HexUtil;
import com.bloxbean.cardano.yaci.store.common.domain.UtxoKey;
import com.bloxbean.cardano.yaci.store.common.util.Util;
import com.bloxbean.cardano.client.util.Tuple;
import com.bloxbean.cardano.yaci.core.model.PlutusScript;
import com.bloxbean.cardano.yaci.core.model.Redeemer;
import com.bloxbean.cardano.yaci.core.model.TransactionInput;
import com.bloxbean.cardano.yaci.core.model.certs.*;
import com.bloxbean.cardano.yaci.helper.model.Transaction;
import com.bloxbean.cardano.yaci.store.client.utxo.UtxoClient;
import com.bloxbean.cardano.yaci.store.common.domain.UtxoKey;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -47,48 +48,33 @@ public List<ScriptContext> findScriptsForRedeemers(Transaction transaction, Map<
List<TransactionInput> inputs = new ArrayList<>(transaction.getBody().getInputs());
List<com.bloxbean.cardano.yaci.core.model.Redeemer> redeemers = transaction.getWitnesses().getRedeemers();
List<ScriptContext> scriptContexts = redeemers.stream()
.map(redeemer -> Util.deserialize(redeemer.getCbor())
.map(deRedeemer -> new Tuple<>(redeemer, deRedeemer)))
.filter(Optional::isPresent)
.map(redeemerTuple -> {
com.bloxbean.cardano.yaci.core.model.Redeemer orgRedeemer = redeemerTuple.get()._1;
com.bloxbean.cardano.client.plutus.spec.Redeemer deRedeemer = redeemerTuple.get()._2;

.map(redeemer -> {
ScriptContext scriptContext;
if (deRedeemer.getTag() == RedeemerTag.Spend) {
scriptContext = findSpendScriptFromRedeemer(deRedeemer, inputs, scriptsMap)
if (redeemer.getTag() == RedeemerTag.Spend) {
scriptContext = findSpendScriptFromRedeemer(redeemer, inputs, scriptsMap)
.orElse(new ScriptContext());
scriptContext.setRedeemer(orgRedeemer.getCbor()); //set redeemer here to save serialization cost
} else if (deRedeemer.getTag() == RedeemerTag.Mint) {
scriptContext.setRedeemer(redeemer); //set redeemer here to save serialization cost
} else if (redeemer.getTag() == RedeemerTag.Mint) {
if (log.isDebugEnabled())
log.debug("Mint tag : " + transaction.getTxHash());
//check mint policy
scriptContext = findMintScriptForRedeemer(deRedeemer, distinctPolicies, scriptsMap)
scriptContext = findMintScriptForRedeemer(redeemer, distinctPolicies, scriptsMap)
.orElse(new ScriptContext());
scriptContext.setRedeemer(orgRedeemer.getCbor());
} else if (deRedeemer.getTag() == RedeemerTag.Cert) {
scriptContext.setRedeemer(redeemer);
} else if (redeemer.getTag() == RedeemerTag.Cert) {
if (log.isDebugEnabled())
log.debug("Redeemer Cert : " + transaction.getTxHash());
scriptContext = findCertScriptForRedeemer(deRedeemer, transaction.getBody().getCertificates(), scriptsMap)
scriptContext = findCertScriptForRedeemer(redeemer, transaction.getBody().getCertificates(), scriptsMap)
.orElse(new ScriptContext());
scriptContext.setRedeemer(orgRedeemer.getCbor());
} else if (deRedeemer.getTag() == RedeemerTag.Reward) {
scriptContext.setRedeemer(redeemer);
} else if (redeemer.getTag() == RedeemerTag.Reward) {
if (log.isDebugEnabled())
log.info("Redeemer Reward : " + transaction.getTxHash());
scriptContext = findRewardScriptForRedeemer(deRedeemer, transaction, scriptsMap).orElse(new ScriptContext());
scriptContext.setRedeemer(orgRedeemer.getCbor());
scriptContext = findRewardScriptForRedeemer(redeemer, transaction, scriptsMap).orElse(new ScriptContext());
scriptContext.setRedeemer(redeemer);
} else {
scriptContext = new ScriptContext();
scriptContext.setRedeemer(orgRedeemer.getCbor());
}

//Set redeemer data and redeemer data hash
if (deRedeemer.getData() != null) {
String redeemerData = deRedeemer.getData().serializeToHex();
String redeemerDataHash = deRedeemer.getData().getDatumHash();

scriptContext.setRedeemerData(redeemerData);
scriptContext.setRedeemerDataHash(redeemerDataHash);
scriptContext.setRedeemer(redeemer);
}

return scriptContext;
Expand All @@ -98,7 +84,7 @@ public List<ScriptContext> findScriptsForRedeemers(Transaction transaction, Map<
}

public Optional<ScriptContext> findSpendScriptFromRedeemer(Redeemer redeemer,
List<TransactionInput> inputs, Map<String, PlutusScript> scriptsMap) {
List<TransactionInput> inputs, Map<String, PlutusScript> scriptsMap) {
//Sort inputs and find the right input for redeemer
TransactionInput input = getScriptInputFromRedeemer(redeemer, inputs);

Expand Down Expand Up @@ -136,7 +122,7 @@ public Optional<ScriptContext> findRewardScriptForRedeemer(Redeemer redeemer, Tr
.map(entry -> entry.getKey())
.collect(Collectors.toList());

int index = redeemer.getIndex().intValue();
int index = redeemer.getIndex();
String rewardAddress = rewardAddresses.get(index);

Address address = new Address(HexUtil.decodeHexString(rewardAddress));
Expand All @@ -156,7 +142,7 @@ public Optional<ScriptContext> findCertScriptForRedeemer(Redeemer redeemer, List
if (certificates == null ||certificates.size() == 0)
return Optional.empty();

int index = redeemer.getIndex().intValue();
int index = redeemer.getIndex();

if (index >= certificates.size())
return Optional.empty();
Expand Down Expand Up @@ -187,7 +173,7 @@ public Optional<ScriptContext> findMintScriptForRedeemer(Redeemer redeemer, List
if (policies == null)
return Optional.empty();

int index = redeemer.getIndex().intValue();
int index = redeemer.getIndex();
if (index >= policies.size()) {
return Optional.empty();
}
Expand All @@ -209,7 +195,7 @@ public static TransactionInput getScriptInputFromRedeemer(Redeemer redeemer, Lis
.collect(Collectors.toList());
copyInputs.sort((o1, o2) -> (o1.getTransactionId() + "#" + o1.getIndex()).compareTo(o2.getTransactionId() + "#" + o2.getIndex()));

int index = redeemer.getIndex().intValue();
int index = redeemer.getIndex();
return copyInputs.get(index);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.bloxbean.cardano.yaci.store.script.helper;

import com.bloxbean.cardano.yaci.core.model.PlutusScript;
import com.bloxbean.cardano.yaci.core.model.Redeemer;
import com.bloxbean.cardano.yaci.store.script.domain.ScriptType;
import lombok.AllArgsConstructor;
import lombok.Data;
Expand All @@ -11,11 +12,9 @@
@NoArgsConstructor
public class ScriptContext {
private PlutusScript plutusScript;
private String redeemer;
private Redeemer redeemer;
private String datum;
private String datumHash;
private String redeemerData;
private String redeemerDataHash;

public String getScriptHash() {
if (plutusScript == null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.bloxbean.cardano.yaci.store.script.processor;

import com.bloxbean.cardano.yaci.core.model.PlutusScript;
import com.bloxbean.cardano.yaci.core.model.Redeemer;
import com.bloxbean.cardano.yaci.helper.model.Transaction;
import com.bloxbean.cardano.yaci.store.common.util.JsonUtil;
import com.bloxbean.cardano.yaci.store.common.util.StringUtil;
Expand Down Expand Up @@ -135,6 +136,12 @@ private void handleScriptTransaction(EventMetadata metadata, Transaction transac
if (StringUtil.isEmpty(scriptContext.getDatumHash()) && !StringUtil.isEmpty(scriptContext.getDatum()))
scriptContext.setDatumHash(ScriptUtil.getDatumHash(scriptContext.getDatum()));

Redeemer redeemer;
if (scriptContext.getRedeemer() != null)
redeemer = scriptContext.getRedeemer();
else
redeemer = new Redeemer();

return TxScript.builder()
.txHash(transaction.getTxHash())
.slot(metadata.getSlot())
Expand All @@ -143,17 +150,24 @@ private void handleScriptTransaction(EventMetadata metadata, Transaction transac
.blockTime(metadata.getBlockTime())
.scriptHash(scriptContext.getScriptHash())
.type(scriptContext.getPlutusScriptType())
.redeemer(scriptContext.getRedeemer())
.datum(scriptContext.getDatum())
.datumHash(scriptContext.getDatumHash())
.redeemerCbor(redeemer.getCbor())
.unitMem(redeemer.getExUnits() != null? redeemer.getExUnits().getMem(): null)
.unitSteps(redeemer.getExUnits() != null? redeemer.getExUnits().getSteps(): null)
.purpose(redeemer.getTag())
.redeemerIndex(redeemer.getIndex())
.redeemerData(redeemer.getData() != null? redeemer.getData().getCbor(): null)
.redeemerDatahash(redeemer.getData() != null? redeemer.getData().getHash(): null)
.build();
}).collect(Collectors.toList());

//Save redeemer data by data hash in Datum storage
if (scriptContexts != null && scriptContexts.size() > 0) {
List<Datum> redeemerDataList = scriptContexts.stream()
.filter(scriptContext -> !StringUtil.isEmpty(scriptContext.getRedeemerDataHash()))
.map(scriptContext -> new Datum(scriptContext.getRedeemerDataHash(), scriptContext.getRedeemerData(), transaction.getTxHash()))
.map(scriptContext -> scriptContext.getRedeemer())
.filter(redeemer -> redeemer != null)
.map(redeemer -> new Datum(redeemer.getData().getHash(), redeemer.getData().getCbor(), transaction.getTxHash()))
.toList();

if (redeemerDataList.size() > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.bloxbean.cardano.yaci.store.script.service;

import com.bloxbean.cardano.client.plutus.spec.ExUnits;
import com.bloxbean.cardano.client.plutus.spec.PlutusData;
import com.bloxbean.cardano.client.plutus.spec.serializers.PlutusDataJsonConverter;
import com.bloxbean.cardano.client.util.HexUtil;
import com.bloxbean.cardano.yaci.store.script.domain.*;
import com.bloxbean.cardano.yaci.store.script.dto.TxRedeemerDto;
import com.bloxbean.cardano.yaci.store.script.helper.ScriptUtil;
import com.bloxbean.cardano.yaci.store.script.storage.DatumStorage;
import com.bloxbean.cardano.yaci.store.script.storage.ScriptStorage;
import com.bloxbean.cardano.yaci.store.script.storage.TxScriptStorage;
Expand Down Expand Up @@ -46,14 +46,12 @@ public List<TxContractDetails> getTransactionScripts(String txHash) {
.orElse(null);
}

Redeemer redeemerDto = ScriptUtil.deserializeRedeemer(txScript.getRedeemer())
.map(redeemer -> Redeemer.builder()
.tag(redeemer.getTag())
.index(redeemer.getIndex())
.exUnits(redeemer.getExUnits())
.data(redeemer.getData() != null ? redeemer.getData().serializeToHex() : null)
.build())
.orElse(null);
Redeemer redeemerDto = Redeemer.builder()
.tag(txScript.getPurpose())
.index(txScript.getRedeemerIndex())
.exUnits(new ExUnits(txScript.getUnitMem(), txScript.getUnitSteps()))
.data(txScript.getRedeemerData())
.build();

return TxContractDetails.builder()
.txHash(txHash)
Expand Down Expand Up @@ -91,21 +89,15 @@ public List<TxRedeemerDto> getTransactionRedeemers(String txHash) {
return Collections.EMPTY_LIST;

return txScripts.stream()
.filter(txScript -> txScript.getRedeemer() != null && !txScript.getRedeemer().isEmpty())
.map(txScript -> {
com.bloxbean.cardano.client.plutus.spec.Redeemer redeemer = ScriptUtil.deserializeRedeemer(txScript.getRedeemer())
.orElseThrow(() -> new IllegalStateException("Unable to deserialize redeemer : " + txScript.getRedeemer()));
String dataHash = redeemer.getData().getDatumHash();

return TxRedeemerDto.builder()
.txIndex(redeemer.getIndex().intValue())
.purpose(redeemer.getTag().toString().toLowerCase())
.scriptHash(txScript.getScriptHash())
.redeemerDataHash(dataHash)
.unitMem(String.valueOf(redeemer.getExUnits().getMem()))
.unitSteps(String.valueOf(redeemer.getExUnits().getSteps()))
//.fee(String.valueOf()) //TODO -- calcuate script cost from mem and steps
.build();
}).collect(Collectors.toList());
.map(txScript -> TxRedeemerDto.builder()
.txIndex(txScript.getRedeemerIndex())
.purpose(txScript.getPurpose().toString().toLowerCase())
.scriptHash(txScript.getScriptHash())
.datumHash(txScript.getDatumHash())
.redeemerDataHash(txScript.getRedeemerDatahash())
.unitMem(String.valueOf(txScript.getUnitMem()))
.unitSteps(String.valueOf(txScript.getUnitSteps()))
//.fee(String.valueOf()) //TODO -- calcuate script cost from mem and steps
.build()).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.List;

public interface TxScriptStorage {
List<TxScript> saveAll(List<TxScript> txScripts);
void saveAll(List<TxScript> txScripts);

int deleteBySlotGreaterThan(long slot);

Expand Down
Loading

0 comments on commit 5c6116a

Please sign in to comment.