diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/DrepVoteThresholds.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/DrepVoteThresholds.java new file mode 100644 index 0000000..fd2daee --- /dev/null +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/DrepVoteThresholds.java @@ -0,0 +1,37 @@ +package com.bloxbean.cardano.yaci.core.model; + +import lombok.*; + +import java.math.BigDecimal; + +/** + * drep_voting_thresholds = + * [ unit_interval ; motion no confidence + * , unit_interval ; committee normal + * , unit_interval ; committee no confidence + * , unit_interval ; update constitution + * , unit_interval ; hard fork initiation + * , unit_interval ; PP network group + * , unit_interval ; PP economic group + * , unit_interval ; PP technical group + * , unit_interval ; PP governance group + * , unit_interval ; treasury withdrawal + * ] + */ +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@ToString +public class DrepVoteThresholds { + private BigDecimal motionNoConfidence; + private BigDecimal committeeNormal; + private BigDecimal committeeNoConfidence; + private BigDecimal updateConstitution; + private BigDecimal hardForkInitiation; + private BigDecimal ppNetworkGroup; + private BigDecimal ppEconomicGroup; + private BigDecimal ppTechnicalGroup; + private BigDecimal ppGovernanceGroup; + private BigDecimal treasuryWithdrawal; +} diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/PoolVotingThresholds.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/PoolVotingThresholds.java new file mode 100644 index 0000000..6302c27 --- /dev/null +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/PoolVotingThresholds.java @@ -0,0 +1,25 @@ +package com.bloxbean.cardano.yaci.core.model; + +import lombok.*; + +import java.math.BigDecimal; + +/** + * pool_voting_thresholds = + * [ unit_interval ; motion no confidence + * , unit_interval ; committee normal + * , unit_interval ; committee no confidence + * , unit_interval ; hard fork initiation + * ] + */ +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@ToString +public class PoolVotingThresholds { + private BigDecimal motionNoConfidence; + private BigDecimal committeeNormal; + private BigDecimal committeeNoConfidence; + private BigDecimal hardForkInitiation; +} diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/ProtocolParamUpdate.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/ProtocolParamUpdate.java index 8685431..bf8beed 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/ProtocolParamUpdate.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/ProtocolParamUpdate.java @@ -64,4 +64,14 @@ public class ProtocolParamUpdate { // private String coinsPerUtxoSize; // @Deprecated // private String coinsPerUtxoWord; + + //Conway era fields + private PoolVotingThresholds poolVotingThresholds; //25 + private DrepVoteThresholds dRepVoteThresholds; //26 + private Integer minCommitteeSize; //27 + private Integer committeeTermLimit; //28 + private Integer governanceActionValidityPeriod; //29 + private BigInteger governanceActionDeposit; //30 + private BigInteger drepDeposit; //31 + private Integer drepInactivityPeriod; //32 } diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/actions/UpdateCommittee.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/actions/UpdateCommittee.java index a53cb5d..d164499 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/actions/UpdateCommittee.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/governance/actions/UpdateCommittee.java @@ -12,7 +12,9 @@ import java.util.Set; /** + * {@literal * update_committee = (4, gov_action_id / null, set, { committee_cold_credential => epoch }, unit_interval) + * } */ @Getter @AllArgsConstructor diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/UpdateSerializer.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/UpdateSerializer.java index 3bd32b1..a616bfb 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/UpdateSerializer.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/UpdateSerializer.java @@ -2,6 +2,8 @@ import co.nstant.in.cbor.model.*; import com.bloxbean.cardano.client.crypto.Blake2bUtil; +import com.bloxbean.cardano.yaci.core.model.DrepVoteThresholds; +import com.bloxbean.cardano.yaci.core.model.PoolVotingThresholds; import com.bloxbean.cardano.yaci.core.model.ProtocolParamUpdate; import com.bloxbean.cardano.yaci.core.model.Update; import com.bloxbean.cardano.yaci.core.protocol.Serializer; @@ -180,6 +182,31 @@ public ProtocolParamUpdate getProtocolParams(Map genesisProtocolParamsMap) { itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(24)); Integer maxCollateralPercent = itemDI != null ? toInt(itemDI) : null; + //Conway era protocol parameters + itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(25)); + PoolVotingThresholds poolVotingThresholds = deserializePoolVotingThresholds(itemDI); + + itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(26)); + DrepVoteThresholds drepVoteThresholds = deserializeDrepVoteThresholds(itemDI); + + itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(27)); + Integer minCommitteeSize = itemDI != null ? toInt(itemDI) : null; + + itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(28)); + Integer committeeTermLimit = itemDI != null ? toInt(itemDI) : null; + + itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(29)); + Integer goveranceActionValidityPeriod = itemDI != null ? toInt(itemDI) : null; + + itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(30)); + BigInteger governanceActionDeposit = itemDI != null ? toBigInteger(itemDI) : null; + + itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(31)); + BigInteger drepDeposit = itemDI != null ? toBigInteger(itemDI) : null; + + itemDI = genesisProtocolParamsMap.get(new UnsignedInteger(32)); + Integer drepInactivityPeriod = itemDI != null ? toInt(itemDI) : null; + ProtocolParamUpdate protocolParamUpdate = ProtocolParamUpdate.builder() .minFeeA(minFeeA) .minFeeB(minFeeB) @@ -211,6 +238,14 @@ public ProtocolParamUpdate getProtocolParams(Map genesisProtocolParamsMap) { .maxValSize(maxValueSize) .collateralPercent(collateralPercent) .maxCollateralInputs(maxCollateralPercent) + .poolVotingThresholds(poolVotingThresholds) + .dRepVoteThresholds(drepVoteThresholds) + .minCommitteeSize(minCommitteeSize) + .committeeTermLimit(committeeTermLimit) + .governanceActionValidityPeriod(goveranceActionValidityPeriod) + .governanceActionDeposit(governanceActionDeposit) + .drepDeposit(drepDeposit) + .drepInactivityPeriod(drepInactivityPeriod) .build(); return protocolParamUpdate; } @@ -234,4 +269,79 @@ private Tuple getExUnitPrices(List exunits) { return new Tuple<>(memPrice, stepPrice); } + + /** + * pool_voting_thresholds = + * [ unit_interval ; motion no confidence + * , unit_interval ; committee normal + * , unit_interval ; committee no confidence + * , unit_interval ; hard fork initiation + * ] + * @param itemDI + * @return + */ + private PoolVotingThresholds deserializePoolVotingThresholds(DataItem itemDI) { + if (itemDI == null) + return null; + + List poolVotingThresholds = ((Array) itemDI).getDataItems(); + BigDecimal motionNoConfidence = toRationalNumber((RationalNumber) poolVotingThresholds.get(0)); + BigDecimal committeeNormal = toRationalNumber((RationalNumber) poolVotingThresholds.get(1)); + BigDecimal committeeNoConfidence = toRationalNumber((RationalNumber) poolVotingThresholds.get(2)); + BigDecimal hardForkInitiation = toRationalNumber((RationalNumber) poolVotingThresholds.get(3)); + + return PoolVotingThresholds.builder() + .motionNoConfidence(motionNoConfidence) + .committeeNormal(committeeNormal) + .committeeNoConfidence(committeeNoConfidence) + .hardForkInitiation(hardForkInitiation) + .build(); + + } + + /** + * drep_voting_thresholds = + * [ unit_interval ; motion no confidence + * , unit_interval ; committee normal + * , unit_interval ; committee no confidence + * , unit_interval ; update constitution + * , unit_interval ; hard fork initiation + * , unit_interval ; PP network group + * , unit_interval ; PP economic group + * , unit_interval ; PP technical group + * , unit_interval ; PP governance group + * , unit_interval ; treasury withdrawal + * ] + * @param itemDI + * @return + */ + private DrepVoteThresholds deserializeDrepVoteThresholds(DataItem itemDI) { + if (itemDI == null) + return null; + + List drepVotingThresholds = ((Array) itemDI).getDataItems(); + BigDecimal motionNoConfidence = toRationalNumber((RationalNumber) drepVotingThresholds.get(0)); + BigDecimal committeeNormal = toRationalNumber((RationalNumber) drepVotingThresholds.get(1)); + BigDecimal committeeNoConfidence = toRationalNumber((RationalNumber) drepVotingThresholds.get(2)); + BigDecimal updateConstitution = toRationalNumber((RationalNumber) drepVotingThresholds.get(3)); + BigDecimal hardForkInitiation = toRationalNumber((RationalNumber) drepVotingThresholds.get(4)); + BigDecimal ppNetworkGroup = toRationalNumber((RationalNumber) drepVotingThresholds.get(5)); + BigDecimal ppEconomicGroup = toRationalNumber((RationalNumber) drepVotingThresholds.get(6)); + BigDecimal ppTechnicalGroup = toRationalNumber((RationalNumber) drepVotingThresholds.get(7)); + BigDecimal ppGovernanceGroup = toRationalNumber((RationalNumber) drepVotingThresholds.get(8)); + BigDecimal treasuryWithdrawal = toRationalNumber((RationalNumber) drepVotingThresholds.get(9)); + + return DrepVoteThresholds.builder() + .motionNoConfidence(motionNoConfidence) + .committeeNormal(committeeNormal) + .committeeNoConfidence(committeeNoConfidence) + .updateConstitution(updateConstitution) + .hardForkInitiation(hardForkInitiation) + .ppNetworkGroup(ppNetworkGroup) + .ppEconomicGroup(ppEconomicGroup) + .ppTechnicalGroup(ppTechnicalGroup) + .ppGovernanceGroup(ppGovernanceGroup) + .treasuryWithdrawal(treasuryWithdrawal) + .build(); + } } diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/WintessesSerializer.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/WintessesSerializer.java index 4502d83..cf1fcd3 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/WintessesSerializer.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/WintessesSerializer.java @@ -16,6 +16,8 @@ import java.util.ArrayList; import java.util.List; +import static com.bloxbean.cardano.yaci.core.util.CborSerializationUtil.toHex; + //TODO -- More testing required for deserialization --> serialization public enum WintessesSerializer implements Serializer { INSTANCE; @@ -30,6 +32,7 @@ public Witnesses deserializeDI(DataItem di) { DataItem plutusDataArray = witnessMap.get(new UnsignedInteger(4)); DataItem redeemerArray = witnessMap.get(new UnsignedInteger(5)); DataItem plutusV2ScriptArray = witnessMap.get(new UnsignedInteger(6)); + DataItem plutusV3ScriptArray = witnessMap.get(new UnsignedInteger(7)); //vk witnesses List vkeyWitnessList = new ArrayList<>(); @@ -135,7 +138,25 @@ public Witnesses deserializeDI(DataItem di) { } } - return new Witnesses(vkeyWitnessList, nativeScripts, bootstrapWitnesses, plutusV1Scripts, datumList, redeemerList, plutusV2Scripts); + //plutus_v3 script (Conway era) + List plutusV3Scripts = new ArrayList<>(); + if (plutusV3ScriptArray != null) { + List plutusV3ScriptDIList = ((Array) plutusV3ScriptArray).getDataItems(); + try { + for (DataItem plutusV3ScriptDI : plutusV3ScriptDIList) { + if (plutusV3ScriptDI == Special.BREAK) continue; + String scriptCborHex = toHex(plutusV3ScriptArray); + + PlutusScript plutusScript = new PlutusScript(String.valueOf(3), scriptCborHex); + plutusV3Scripts.add(plutusScript); + + } + } catch (Exception e) { + throw new CborRuntimeException("Plutus V3 script deserialization failed", e); + } + } + + return new Witnesses(vkeyWitnessList, nativeScripts, bootstrapWitnesses, plutusV1Scripts, datumList, redeemerList, plutusV2Scripts, plutusV3Scripts); } private BootstrapWitness deserializeBootstrapWitness(Array bootstrapWitnessDI) { diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/governance/AnchorSerializer.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/governance/AnchorSerializer.java index 7f09059..beff0a2 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/governance/AnchorSerializer.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/governance/AnchorSerializer.java @@ -2,6 +2,7 @@ import co.nstant.in.cbor.model.Array; import co.nstant.in.cbor.model.DataItem; +import co.nstant.in.cbor.model.SimpleValue; import com.bloxbean.cardano.yaci.core.model.governance.Anchor; import com.bloxbean.cardano.yaci.core.protocol.Serializer; @@ -15,6 +16,9 @@ public enum AnchorSerializer implements Serializer { @Override public Anchor deserializeDI(DataItem di) { + if (di == null || di == SimpleValue.NULL) + return null; + return deserializeAnchor((Array) di); } @@ -28,9 +32,6 @@ public Anchor deserializeDI(DataItem di) { * @return */ private Anchor deserializeAnchor(Array array) { - if (array == null) - return null; - if (array != null && array.getDataItems().size() != 2) throw new IllegalArgumentException("Invalid anchor array. Expected 2 items. Found : " + array.getDataItems().size()); diff --git a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/governance/GovActionSerializer.java b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/governance/GovActionSerializer.java index c2f0aae..f9640e6 100644 --- a/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/governance/GovActionSerializer.java +++ b/core/src/main/java/com/bloxbean/cardano/yaci/core/model/serializers/governance/GovActionSerializer.java @@ -33,20 +33,15 @@ * // new_constitution * // info_action * ] - *

+ * {@literal * parameter_change_action = (0, gov_action_id / null, protocol_param_update) - *

* hard_fork_initiation_action = (1, gov_action_id / null, [protocol_version]) - *

* treasury_withdrawals_action = (2, { reward_account => coin }) - *

* no_confidence = (3, gov_action_id / null) - *

* update_committee = (4, gov_action_id / null, set, { committee_cold_credential => epoch }, unit_interval) - *

* new_constitution = (5, gov_action_id / null, constitution) - *

* committee = [{ committee_cold_credential => epoch }, unit_interval] + * } */ //TODO -- Test this class public enum GovActionSerializer implements Serializer {