Skip to content

Commit 1769849

Browse files
authored
Merge pull request #3 from matiwinnetou/ex-budget
Support for passing InitialBudget.
2 parents 6005de1 + 09318cf commit 1769849

File tree

6 files changed

+98
-22
lines changed

6 files changed

+98
-22
lines changed

src/main/java/com/bloxbean/cardano/aiken/jna/CardanoJNA.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.bloxbean.cardano.aiken.jna;
22

3+
import com.bloxbean.cardano.aiken.tx.evaluator.InitialBudgetConfig;
34
import com.bloxbean.cardano.aiken.tx.evaluator.SlotConfig;
45
import com.sun.jna.Library;
56
import com.sun.jna.Native;
@@ -9,7 +10,11 @@ interface CardanoJNA extends Library {
910
CardanoJNA INSTANCE = Native.load(LibraryUtil.getAikenWrapperLib(),
1011
CardanoJNA.class);
1112

12-
Pointer eval_phase_two(String txBytes, String inputs, String outputs, String costMdlsBytes,
13+
Pointer eval_phase_two(String txBytes,
14+
String inputs,
15+
String outputs,
16+
String costMdlsBytes,
17+
InitialBudgetConfig.InitialBudgetByReference initialBudgetConfig,
1318
SlotConfig.SlotConfigByReference slotConfig);
1419

1520
void dropCharPointer(Pointer pointer);
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
package com.bloxbean.cardano.aiken.jna;
22

3+
import com.bloxbean.cardano.aiken.tx.evaluator.InitialBudgetConfig;
34
import com.bloxbean.cardano.aiken.tx.evaluator.SlotConfig;
45
import com.sun.jna.Pointer;
56

67
public class CardanoJNAUtil {
78

8-
public static String eval_phase_two_raw(String tx, String inputs, String outputs, String costMdls, SlotConfig.SlotConfigByReference slotConfig) {
9-
Pointer pointer = CardanoJNA.INSTANCE.eval_phase_two(tx, inputs, outputs, costMdls, slotConfig);
9+
public static String eval_phase_two_raw(String tx,
10+
String inputs,
11+
String outputs,
12+
String costMdls,
13+
InitialBudgetConfig.InitialBudgetByReference initialBudgetConfig,
14+
SlotConfig.SlotConfigByReference slotConfig) {
15+
Pointer pointer = CardanoJNA.INSTANCE.eval_phase_two(tx, inputs, outputs, costMdls, initialBudgetConfig, slotConfig);
1016
String result = pointer.getString(0);
1117

1218
CardanoJNA.INSTANCE.dropCharPointer(pointer);
19+
1320
return result;
1421
}
22+
1523
}
1624

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.bloxbean.cardano.aiken.tx.evaluator;
2+
3+
import com.sun.jna.Structure;
4+
import lombok.AllArgsConstructor;
5+
import lombok.NoArgsConstructor;
6+
7+
import java.io.Closeable;
8+
import java.io.IOException;
9+
10+
@AllArgsConstructor
11+
@NoArgsConstructor
12+
@Structure.FieldOrder({"mem", "cpu"})
13+
public class InitialBudgetConfig extends Structure implements Closeable {
14+
15+
public static class InitialBudgetByReference extends InitialBudgetConfig implements ByReference { }
16+
17+
public long mem;
18+
public long cpu;
19+
20+
@Override
21+
public void close() throws IOException {
22+
// Turn off "auto-synch". If it is on, JNA will automatically read all fields
23+
// from the struct's memory and update them on the Java object. This synchronization
24+
// occurs after every native method call. If it occurs after we drop the struct, JNA
25+
// will try to read from the freed memory and cause a segmentation fault.
26+
setAutoSynch(false);
27+
// Send the struct back to rust for the memory to be freed
28+
//Greetings.INSTANCE.dropGreeting(this);
29+
}
30+
31+
}

src/main/java/com/bloxbean/cardano/aiken/tx/evaluator/TxEvaluator.java

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,24 @@
2525
*/
2626
@Slf4j
2727
public class TxEvaluator {
28-
private final SlotConfig slotConfig;
28+
29+
private final SlotConfig.SlotConfigByReference slotConfig;
30+
private final InitialBudgetConfig.InitialBudgetByReference initialBudgetConfig;
2931

3032
public TxEvaluator() {
3133
this.slotConfig = getDefaultSlotConfig();
34+
this.initialBudgetConfig = getDefaultInitialBudgetConfig();
3235
}
3336

34-
public TxEvaluator(SlotConfig slotConfig) {
37+
public TxEvaluator(SlotConfig slotConfig, InitialBudgetConfig initialBudgetConfig) {
3538
this.slotConfig = new SlotConfig.SlotConfigByReference();
3639
this.slotConfig.zero_slot = slotConfig.zero_slot;
3740
this.slotConfig.zero_time = slotConfig.zero_time;
3841
this.slotConfig.slot_length = slotConfig.slot_length;
42+
43+
this.initialBudgetConfig = new InitialBudgetConfig.InitialBudgetByReference();
44+
this.initialBudgetConfig.mem = initialBudgetConfig.mem;
45+
this.initialBudgetConfig.cpu = initialBudgetConfig.cpu;
3946
}
4047

4148
/**
@@ -74,18 +81,25 @@ public List<Redeemer> evaluateTx(Transaction transaction, Set<Utxo> inputUtxos,
7481
}
7582
});
7683

77-
SlotConfig.SlotConfigByReference slotConfig = getDefaultSlotConfig();
7884
try {
7985
String costMdlsHex = HexUtil.encodeHexString(CborSerializationUtil.serialize(costMdls.serialize()));
80-
String response = CardanoJNAUtil.eval_phase_two_raw(transaction.serializeToHex(),
81-
HexUtil.encodeHexString(CborSerializationUtil.serialize(inputArray)),
82-
HexUtil.encodeHexString(CborSerializationUtil.serialize(outputArray)),
83-
costMdlsHex, slotConfig);
86+
String trxCbor = transaction.serializeToHex();
87+
String inputsCbor = HexUtil.encodeHexString(CborSerializationUtil.serialize(inputArray));
88+
String outputsCbor = HexUtil.encodeHexString(CborSerializationUtil.serialize(outputArray));
89+
90+
String response = CardanoJNAUtil.eval_phase_two_raw(
91+
trxCbor,
92+
inputsCbor,
93+
outputsCbor,
94+
costMdlsHex,
95+
initialBudgetConfig,
96+
slotConfig
97+
);
8498

8599
if (log.isTraceEnabled()) {
86-
log.trace("Transaction: " + transaction.serializeToHex());
87-
log.trace("Inputs : " + HexUtil.encodeHexString(CborSerializationUtil.serialize(inputArray)));
88-
log.trace("Outputs : " + HexUtil.encodeHexString(CborSerializationUtil.serialize(outputArray)));
100+
log.trace("Transaction: " + trxCbor);
101+
log.trace("Inputs : " + inputsCbor);
102+
log.trace("Outputs : " + outputsCbor);
89103
log.trace("CostMdlsHex : " + costMdlsHex);
90104
}
91105

@@ -118,25 +132,35 @@ private List<Redeemer> deserializeRedeemerArray(String response) {
118132
}
119133
}
120134

121-
private SlotConfig.SlotConfigByReference getDefaultSlotConfig() {
135+
private static SlotConfig.SlotConfigByReference getDefaultSlotConfig() {
122136
SlotConfig.SlotConfigByReference slotConfig = new SlotConfig.SlotConfigByReference();
123137
slotConfig.zero_time = 1660003200000L;
124138
slotConfig.zero_slot = 0;
125139
slotConfig.slot_length = 1000;
140+
126141
return slotConfig;
127142
}
128143

144+
private static InitialBudgetConfig.InitialBudgetByReference getDefaultInitialBudgetConfig() {
145+
InitialBudgetConfig.InitialBudgetByReference initialBudgetConfig = new InitialBudgetConfig.InitialBudgetByReference();
146+
initialBudgetConfig.mem = 1660003200000L;
147+
initialBudgetConfig.cpu = 0;
148+
149+
return initialBudgetConfig;
150+
}
151+
129152
private List<TransactionOutput> resolveTxInputs(List<TransactionInput> transactionInputs, Set<Utxo> utxos, List<PlutusScript> plutusScripts) {
130153
return transactionInputs.stream().map(input -> {
131154
try {
132-
133-
Utxo utxo = utxos.stream().filter(_utxo -> input.getTransactionId().equals(_utxo.getTxHash()) && input.getIndex() == _utxo.getOutputIndex())
155+
Utxo utxo = utxos.stream()
156+
.filter(_utxo -> input.getTransactionId().equals(_utxo.getTxHash()))
157+
.filter(_utxo -> input.getIndex() == _utxo.getOutputIndex())
134158
.findFirst()
135159
.orElseThrow();
136160

137161
String address = utxo.getAddress();
138162

139-
//Calculate script ref
163+
// Calculate script ref
140164
PlutusScript plutusScript = plutusScripts.stream().filter(script -> {
141165
try {
142166
return HexUtil.encodeHexString(script.getScriptHash()).equals(utxo.getReferenceScriptHash());
@@ -148,7 +172,6 @@ private List<TransactionOutput> resolveTxInputs(List<TransactionInput> transacti
148172
PlutusData inlineDatum = utxo.getInlineDatum() != null ? PlutusData.deserialize(HexUtil.decodeHexString(utxo.getInlineDatum())) : null;
149173
byte[] datumHash = utxo.getDataHash() != null ? HexUtil.decodeHexString(utxo.getDataHash()) : null;
150174

151-
152175
return TransactionOutput.builder()
153176
.address(address)
154177
.value(utxo.toValue())

src/test/java/com/bloxbean/cardano/aiken/tx/evaluator/EvalPhaseTwoTest.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@ void eval_phase_two() {
2929
slotConfig.zero_slot = 0;
3030
slotConfig.slot_length = 1000;
3131

32+
InitialBudgetConfig.InitialBudgetByReference initialBudgetConfig = new InitialBudgetConfig.InitialBudgetByReference();
33+
initialBudgetConfig.mem = 16000000L;
34+
initialBudgetConfig.cpu = 10000000000L;
35+
3236
for (int i=0; i<30; i++) { //Looping to check any occasional jvm crash error
33-
String redeemers = CardanoJNAUtil.eval_phase_two_raw(tx_hex, inputs, outputs, cost_mdls, slotConfig);
37+
String redeemers = CardanoJNAUtil.eval_phase_two_raw(tx_hex, inputs, outputs, cost_mdls, initialBudgetConfig, slotConfig);
3438
System.out.println(deserializeRedeemerArray(redeemers));
3539
}
36-
3740
}
3841

3942
@Test
@@ -48,8 +51,12 @@ void eval_phase_two_failed() {
4851
slotConfig.zero_slot = 0;
4952
slotConfig.slot_length = 1000;
5053

54+
InitialBudgetConfig.InitialBudgetByReference initialBudgetConfig = new InitialBudgetConfig.InitialBudgetByReference();
55+
initialBudgetConfig.mem = 16000000L;
56+
initialBudgetConfig.cpu = 10000000000L;
57+
5158
for (int i=0; i<30; i++) { //Looping to check any occasional jvm crash error
52-
String redeemers = CardanoJNAUtil.eval_phase_two_raw(tx_hex, inputs, outputs, cost_mdls, slotConfig);
59+
String redeemers = CardanoJNAUtil.eval_phase_two_raw(tx_hex, inputs, outputs, cost_mdls, initialBudgetConfig, slotConfig);
5360
assertThat(redeemers).contains("RedeemerError");
5461
}
5562
}

src/test/java/com/bloxbean/cardano/aiken/tx/evaluator/GuessSumContractTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ public void invokeContract() throws Exception {
116116
costMdls.add(CostModelUtil.PlutusV2CostModel);
117117

118118
//Evaluate ExUnits
119-
TxEvaluator txEvaluator = new TxEvaluator(new SlotConfig(1000, 0, 100));
119+
SlotConfig slotConfig = new SlotConfig(1000, 0, 100);
120+
InitialBudgetConfig initialBudgetConfig = new InitialBudgetConfig(16000000L, 10000000000L);
121+
TxEvaluator txEvaluator = new TxEvaluator(slotConfig, initialBudgetConfig);
120122
List<Redeemer> redeemerList = txEvaluator.evaluateTx(txn, context.getUtxos(), costMdls);
121123
txn.getWitnessSet().getRedeemers().get(0).setExUnits(redeemerList.get(0).getExUnits());
122124

0 commit comments

Comments
 (0)