Skip to content

Commit

Permalink
Merge pull request #414 from bloxbean/fix_411
Browse files Browse the repository at this point in the history
feat: #411 tier ref script fee implementation for Conway era
  • Loading branch information
satran004 authored Aug 19, 2024
2 parents 0427ecd + 0554996 commit 9197df3
Show file tree
Hide file tree
Showing 19 changed files with 798 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.bloxbean.cardano.client.backend.api;

import com.bloxbean.cardano.client.api.ScriptSupplier;
import com.bloxbean.cardano.client.api.exception.ApiException;
import com.bloxbean.cardano.client.api.exception.ApiRuntimeException;
import com.bloxbean.cardano.client.plutus.spec.PlutusScript;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Optional;

public class DefaultScriptSupplier implements ScriptSupplier {
private final static Logger log = LoggerFactory.getLogger(DefaultScriptSupplier.class);

private ScriptService scriptService;

public DefaultScriptSupplier(ScriptService scriptService) {
this.scriptService = scriptService;
}

@Override
public Optional<PlutusScript> getScript(String scriptHash) {
try {
var result = scriptService.getPlutusScript(scriptHash);
if (result.isSuccessful())
return Optional.of(result.getValue());
else {
log.debug("Error fetching script for hash: {}, {}", scriptHash, result.getResponse());
return Optional.empty();
}
} catch (ApiException e) {
log.debug("Error fetching script for hash: {}", scriptHash, e);
throw new ApiRuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.bloxbean.cardano.client.util;

/**
* A functional interface that represents a function which may throw a checked exception.
* This is useful in scenarios where you want to use lambda expressions or method references
* that throw checked exceptions, particularly in stream operations or other functional contexts.
*
* @param <T> The type of the input to the function.
*/
@FunctionalInterface
public interface CheckedFunction<T> {
T apply() throws Exception;
}
70 changes: 70 additions & 0 deletions common/src/main/java/com/bloxbean/cardano/client/util/Try.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.bloxbean.cardano.client.util;

/**
* A utility class that encapsulates a computation that may either result in a successful value
* or throw an exception. This class provides a way to handle checked exceptions in a functional
* style, allowing the use of such methods in stream operations without needing to use try-catch blocks.
*
* @param <T> The type of the result of the computation.
*/
public class Try<T> {
private final T result;
private final Exception exception;

/**
* Private constructor to initialize a Try instance.
*
* @param result The result of the computation, or null if an exception occurred.
* @param exception The exception thrown by the computation, or null if the computation was successful.
*/
private Try(T result, Exception exception) {
this.result = result;
this.exception = exception;
}

/**
* Executes the provided CheckedFunction, capturing any thrown exceptions.
*
* @param supplier A function that produces a result, potentially throwing an exception.
* @param <T> The type of the result produced by the function.
* @return A Try instance representing either a successful result or a captured exception.
*/
public static <T> Try<T> of(CheckedFunction<T> supplier) {
try {
return new Try<>(supplier.apply(), null);
} catch (Exception e) {
return new Try<>(null, e);
}
}

/**
* Checks whether the computation was successful.
*
* @return true if the computation was successful (i.e., no exception was thrown), false otherwise.
*/
public boolean isSuccess() {
return exception == null;
}

/**
* Returns the result of the computation, if it was successful.
*
* @return The result of the computation.
* @throws RuntimeException if the computation resulted in an exception.
*/
public T get() {
if (exception != null) {
throw new RuntimeException(exception);
}
return result;
}

/**
* Returns the exception that was thrown during the computation, if any.
*
* @return The exception thrown by the computation, or null if the computation was successful.
*/
public Exception getException() {
return exception;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import com.bloxbean.cardano.client.plutus.spec.PlutusScript;

import java.util.Optional;

/**
* Implement this interface to provide PlutusScript
*/
@FunctionalInterface
public interface ScriptSupplier {
PlutusScript getScript(String scriptHash);
Optional<PlutusScript> getScript(String scriptHash);
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ public class ProtocolParams {
private BigInteger govActionDeposit;
private BigInteger drepDeposit;
private Integer drepActivity;
private Integer minFeeRefScriptCostPerByte;
private BigDecimal minFeeRefScriptCostPerByte;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.bloxbean.cardano.client.api.model;

import java.util.Optional;

/**
* A generic wrapper class that encapsulates the result of an operation, which can either be a successful value or an error.
*
* <p>This class provides a way to handle operations that might return a result or throw an exception, without
* immediately throwing the exception. Instead, the result or error is stored in the `ResultWrapper`, allowing
* the caller to decide how to handle the success or failure.</p>
*
* @param <T> The type of the result value.
*/
public class ResultWrapper<T> {
private final Optional<T> value;
private final Exception error;

/**
* Private constructor to create a ResultWrapper instance.
*
* @param value the value of the result, wrapped in an Optional.
* @param error the exception that occurred, if any.
*/
private ResultWrapper(Optional<T> value, Exception error) {
this.value = value;
this.error = error;
}

/**
* Creates a ResultWrapper representing a successful result.
*
* @param value the result value.
* @param <T> the type of the result.
* @return a ResultWrapper containing the result value.
*/
public static <T> ResultWrapper<T> success(T value) {
return new ResultWrapper<>(Optional.ofNullable(value), null);
}

/**
* Creates a ResultWrapper representing a failure due to an exception.
*
* @param error the exception that occurred.
* @param <T> the type of the result that would have been returned on success.
* @return a ResultWrapper containing the exception.
*/
public static <T> ResultWrapper<T> failure(Exception error) {
return new ResultWrapper<>(Optional.empty(), error);
}

/**
* Returns the result value, if present.
*
* @return an Optional containing the result value, or an empty Optional if the operation failed.
*/
public Optional<T> getValue() {
return value;
}

/**
* Returns the exception that occurred, if any.
*
* @return an Optional containing the exception, or an empty Optional if the operation was successful.
*/
public Optional<Exception> getError() {
return Optional.ofNullable(error);
}

/**
* Checks if the operation was successful.
*
* @return true if the result is present (indicating success), false otherwise.
*/
public boolean isSuccess() {
return value.isPresent();
}

/**
* Checks if the operation resulted in a failure.
*
* @return true if an error occurred, false otherwise.
*/
public boolean isFailure() {
return error != null;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.bloxbean.cardano.client.api.util;

import com.bloxbean.cardano.client.api.ScriptSupplier;
import com.bloxbean.cardano.client.api.UtxoSupplier;
import com.bloxbean.cardano.client.util.Try;
import com.bloxbean.cardano.client.transaction.spec.Transaction;

import java.util.Optional;

public class ReferenceScriptUtil {

/**
* Fetches the reference scripts from the utxo supplier and calculates the size of the reference scripts
*
* @param utxoSupplier utxo supplier
* @param scriptSupplier script supplier
* @param transaction transaction
* @return size of the reference scripts
*/
public static long fetchAndCalculateReferenceScriptsSize(UtxoSupplier utxoSupplier, ScriptSupplier scriptSupplier, Transaction transaction) {
return transaction.getBody().getReferenceInputs()
.stream()
.flatMap(refInput -> utxoSupplier.getTxOutput(refInput.getTransactionId(), refInput.getIndex()).stream()
.map(utxo -> scriptSupplier.getScript(utxo.getReferenceScriptHash()))
.flatMap(Optional::stream))
.map(script -> Try.of(() -> script.scriptRefBytes().length))
.filter(Try::isSuccess)
.mapToLong(Try::get)
.sum();

}

}
Loading

0 comments on commit 9197df3

Please sign in to comment.