diff --git a/src/main/java/com/casper/sdk/jackson/deserializer/EntryPointAccessDeserializer.java b/src/main/java/com/casper/sdk/jackson/deserializer/EntryPointAccessDeserializer.java new file mode 100644 index 000000000..916dbecc6 --- /dev/null +++ b/src/main/java/com/casper/sdk/jackson/deserializer/EntryPointAccessDeserializer.java @@ -0,0 +1,58 @@ +package com.casper.sdk.jackson.deserializer; + +import com.casper.sdk.model.contract.entrypoint.EntryPointAccess; +import com.casper.sdk.model.contract.entrypoint.GroupsAccess; +import com.casper.sdk.model.contract.entrypoint.PublicAccess; +import com.casper.sdk.model.contract.entrypoint.TemplateAccess; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Custom deserializer for {@link EntryPointAccess} + * @author ian@meywood.com + */ +public class EntryPointAccessDeserializer extends JsonDeserializer { + + @Override + public EntryPointAccess deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException, JacksonException { + + if (p.getCurrentToken() == JsonToken.START_OBJECT) { + // Nested rust enums are represented as objects in JSON + return createNestedEntryPointAccess(p.readValueAsTree()); + } else if (p.getCurrentToken() == JsonToken.VALUE_STRING) { + // Standard Rust enum types are read from string + return createSimpleEntryPointAccess(p.getValueAsString()); + } else { + throw new IllegalArgumentException("Unknown scheduling type: " + p); + } + } + + private EntryPointAccess createNestedEntryPointAccess(final ObjectNode treeNode) { + final ArrayNode groups = (ArrayNode) treeNode.get("Groups"); + final List groupNames = new ArrayList<>(); + if (groups != null) { + groups.forEach(jsonNode -> groupNames.add(jsonNode.asText())); + } + return new GroupsAccess(groupNames); + } + + private EntryPointAccess createSimpleEntryPointAccess(final String valueAsString) { + if ("Public".equals(valueAsString)) { + return new PublicAccess(); + } else if ("Template".equals(valueAsString)) { + return new TemplateAccess(); + } else { + throw new IllegalArgumentException("Unknown entry point access type: " + valueAsString); + } + } +} diff --git a/src/main/java/com/casper/sdk/jackson/deserializer/EntryPointV1Deserializer.java b/src/main/java/com/casper/sdk/jackson/deserializer/EntryPointV1Deserializer.java index 83e72f0b1..4590a4e4d 100644 --- a/src/main/java/com/casper/sdk/jackson/deserializer/EntryPointV1Deserializer.java +++ b/src/main/java/com/casper/sdk/jackson/deserializer/EntryPointV1Deserializer.java @@ -1,9 +1,10 @@ package com.casper.sdk.jackson.deserializer; import com.casper.sdk.model.clvalue.cltype.AbstractCLType; -import com.casper.sdk.model.contract.EntryPointArg; -import com.casper.sdk.model.contract.EntryPointType; -import com.casper.sdk.model.contract.EntryPointV1; +import com.casper.sdk.model.contract.entrypoint.EntryPointAccess; +import com.casper.sdk.model.contract.entrypoint.EntryPointArg; +import com.casper.sdk.model.contract.entrypoint.EntryPointType; +import com.casper.sdk.model.contract.entrypoint.EntryPointV1; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationContext; @@ -27,7 +28,7 @@ public EntryPointV1 deserialize(final JsonParser p, final DeserializationContext return EntryPointV1.builder() .name(mapNode.get("name").asText()) - .access(entryPointNode.get("access").asText()) + .access(getNestedObject(entryPointNode, ctxt, "access", EntryPointAccess.class)) .ret(getNestedObject(entryPointNode, ctxt, "ret", AbstractCLType.class)) .entryPointType(getNestedObject(entryPointNode, ctxt, "entry_point_type", EntryPointType.class)) .args(getNestedObject(entryPointNode, ctxt, "args", new TypeReference>() { diff --git a/src/main/java/com/casper/sdk/model/contract/Contract.java b/src/main/java/com/casper/sdk/model/contract/Contract.java index 19377e5e5..fa1231404 100644 --- a/src/main/java/com/casper/sdk/model/contract/Contract.java +++ b/src/main/java/com/casper/sdk/model/contract/Contract.java @@ -1,9 +1,11 @@ package com.casper.sdk.model.contract; +import com.casper.sdk.model.contract.entrypoint.EntryPointV1; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.*; import java.util.List; +import java.util.Optional; /** * Methods and type signatures supported by a contract. @@ -38,4 +40,8 @@ public class Contract { /** protocol_version(String) - ? */ @JsonProperty("protocol_version") private String protocolVersion; + + public Optional getEntryPoint(String name) { + return entryPoints.stream().filter(entryPoint -> entryPoint.getName().equals(name)).findFirst(); + } } diff --git a/src/main/java/com/casper/sdk/model/contract/EntryPoint.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPoint.java similarity index 97% rename from src/main/java/com/casper/sdk/model/contract/EntryPoint.java rename to src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPoint.java index ca1fbbe0b..5d9d7997a 100644 --- a/src/main/java/com/casper/sdk/model/contract/EntryPoint.java +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPoint.java @@ -1,8 +1,9 @@ -package com.casper.sdk.model.contract; +package com.casper.sdk.model.contract.entrypoint; import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport; import com.casper.sdk.model.clvalue.cltype.AbstractCLType; import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeBasic; +import com.casper.sdk.model.contract.Parameter; import com.fasterxml.jackson.annotation.*; import lombok.*; diff --git a/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointAccess.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointAccess.java new file mode 100644 index 000000000..628f80dcf --- /dev/null +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointAccess.java @@ -0,0 +1,14 @@ +package com.casper.sdk.model.contract.entrypoint; + +import com.casper.sdk.jackson.deserializer.EntryPointAccessDeserializer; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * Interface describing the possible access control options for a contract entry point (method). + * + * @author ian@meywood.com + */ +@JsonDeserialize(using = EntryPointAccessDeserializer.class) +public interface EntryPointAccess { + +} diff --git a/src/main/java/com/casper/sdk/model/contract/EntryPointArg.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointArg.java similarity index 88% rename from src/main/java/com/casper/sdk/model/contract/EntryPointArg.java rename to src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointArg.java index e9cd6596c..da0b83951 100644 --- a/src/main/java/com/casper/sdk/model/contract/EntryPointArg.java +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointArg.java @@ -1,4 +1,4 @@ -package com.casper.sdk.model.contract; +package com.casper.sdk.model.contract.entrypoint; import com.casper.sdk.model.clvalue.cltype.AbstractCLType; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/casper/sdk/model/contract/EntryPointType.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointType.java similarity index 84% rename from src/main/java/com/casper/sdk/model/contract/EntryPointType.java rename to src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointType.java index 87cf2bac1..fbe574528 100644 --- a/src/main/java/com/casper/sdk/model/contract/EntryPointType.java +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointType.java @@ -1,4 +1,4 @@ -package com.casper.sdk.model.contract; +package com.casper.sdk.model.contract.entrypoint; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/casper/sdk/model/contract/EntryPointV1.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointV1.java similarity index 90% rename from src/main/java/com/casper/sdk/model/contract/EntryPointV1.java rename to src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointV1.java index 14b344cd5..8c5d7445a 100644 --- a/src/main/java/com/casper/sdk/model/contract/EntryPointV1.java +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointV1.java @@ -1,4 +1,4 @@ -package com.casper.sdk.model.contract; +package com.casper.sdk.model.contract.entrypoint; import com.casper.sdk.jackson.deserializer.EntryPointV1Deserializer; import com.casper.sdk.model.clvalue.cltype.AbstractCLType; @@ -24,7 +24,7 @@ public class EntryPointV1 { private String name; - private String access; + private EntryPointAccess access; private AbstractCLType ret; @JsonProperty("entry_point_type") private EntryPointType entryPointType; diff --git a/src/main/java/com/casper/sdk/model/contract/EntryPointV2.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointV2.java similarity index 76% rename from src/main/java/com/casper/sdk/model/contract/EntryPointV2.java rename to src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointV2.java index 1a5d564bb..d5748a828 100644 --- a/src/main/java/com/casper/sdk/model/contract/EntryPointV2.java +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointV2.java @@ -1,11 +1,12 @@ -package com.casper.sdk.model.contract; +package com.casper.sdk.model.contract.entrypoint; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.*; - /** * The entry point for the V2 Casper VM. * + * TODO Delete this class there is no corresponding class in the Casper node + * * @author carl@stormeye.co.uk */ @Getter diff --git a/src/main/java/com/casper/sdk/model/contract/EntryPointValue.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointValue.java similarity index 92% rename from src/main/java/com/casper/sdk/model/contract/EntryPointValue.java rename to src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointValue.java index 3673e4982..4046f706b 100644 --- a/src/main/java/com/casper/sdk/model/contract/EntryPointValue.java +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/EntryPointValue.java @@ -1,4 +1,4 @@ -package com.casper.sdk.model.contract; +package com.casper.sdk.model.contract.entrypoint; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/casper/sdk/model/contract/entrypoint/GroupsAccess.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/GroupsAccess.java new file mode 100644 index 000000000..cc5775a3b --- /dev/null +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/GroupsAccess.java @@ -0,0 +1,32 @@ +package com.casper.sdk.model.contract.entrypoint; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.jetbrains.annotations.NotNull; + +import java.util.Iterator; +import java.util.List; + +/** + * Only users from the listed groups may call this method. Note: if the list is empty then this method is not callable + * from outside the contract. + * + * @author ian@meywood.com + */ +@JsonTypeName("Groups") +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class GroupsAccess implements EntryPointAccess, Iterable { + private List groups; + + @NotNull + @Override + public Iterator iterator() { + return groups.iterator(); + } +} diff --git a/src/main/java/com/casper/sdk/model/contract/entrypoint/PublicAccess.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/PublicAccess.java new file mode 100644 index 000000000..693049bcb --- /dev/null +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/PublicAccess.java @@ -0,0 +1,12 @@ +package com.casper.sdk.model.contract.entrypoint; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * Anyone can call this method (no access controls). + * + * @author ian@meywood.com + */ +@JsonTypeName("Public") +public class PublicAccess implements EntryPointAccess { +} diff --git a/src/main/java/com/casper/sdk/model/contract/entrypoint/TemplateAccess.java b/src/main/java/com/casper/sdk/model/contract/entrypoint/TemplateAccess.java new file mode 100644 index 000000000..f496e0505 --- /dev/null +++ b/src/main/java/com/casper/sdk/model/contract/entrypoint/TemplateAccess.java @@ -0,0 +1,12 @@ +package com.casper.sdk.model.contract.entrypoint; + +import com.fasterxml.jackson.annotation.JsonTypeName; + +/** + * Can't be accessed directly but are kept in the derived wasm bytes. + * + * @author ian@meywood.com + */ +@JsonTypeName("Template") +public class TemplateAccess implements EntryPointAccess { +} diff --git a/src/main/java/com/casper/sdk/model/deploy/executabledeploy/Transfer.java b/src/main/java/com/casper/sdk/model/deploy/executabledeploy/Transfer.java index 837a9946d..fa32deb8b 100644 --- a/src/main/java/com/casper/sdk/model/deploy/executabledeploy/Transfer.java +++ b/src/main/java/com/casper/sdk/model/deploy/executabledeploy/Transfer.java @@ -47,6 +47,4 @@ public void serialize(SerializerBuffer ser, Target target) throws ValueSerializa ser.writeU8(getOrder()); serializeNamedArgs(ser, target); } - - } diff --git a/src/main/java/com/casper/sdk/model/entity/AddressableEntity.java b/src/main/java/com/casper/sdk/model/entity/AddressableEntity.java index 8386971be..d8ced92b5 100644 --- a/src/main/java/com/casper/sdk/model/entity/AddressableEntity.java +++ b/src/main/java/com/casper/sdk/model/entity/AddressableEntity.java @@ -1,6 +1,6 @@ package com.casper.sdk.model.entity; -import com.casper.sdk.model.contract.EntryPointValue; +import com.casper.sdk.model.contract.entrypoint.EntryPointValue; import com.casper.sdk.model.contract.NamedKey; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.*; diff --git a/src/main/java/com/casper/sdk/model/entity/MessageTopicSummary.java b/src/main/java/com/casper/sdk/model/entity/MessageTopicSummary.java index e9b949fad..bfd5fcb90 100644 --- a/src/main/java/com/casper/sdk/model/entity/MessageTopicSummary.java +++ b/src/main/java/com/casper/sdk/model/entity/MessageTopicSummary.java @@ -7,6 +7,8 @@ import lombok.Setter; /** + * The summary for a message topic in a message topic kind. + * * @author ian@meywood.com */ @AllArgsConstructor diff --git a/src/main/java/com/casper/sdk/model/key/BidAddr.java b/src/main/java/com/casper/sdk/model/key/BidAddr.java index 8ab9d6220..bf53b4c27 100644 --- a/src/main/java/com/casper/sdk/model/key/BidAddr.java +++ b/src/main/java/com/casper/sdk/model/key/BidAddr.java @@ -17,9 +17,14 @@ public enum BidAddr { /// Validator BidAddr. VALIDATOR((byte) 1), /// Delegator BidAddr. - DELEGATOR((byte) 2), + DELEGATOR_ACCOUNT((byte) 2), + DELEGATOR_PURSE((byte) 3), /// Validator credit BidAddr. - CREDIT((byte) 4); + CREDIT((byte) 4), + RESERVED_DELEGATION_ACCOUNT((byte) 5), + RESERVED_DELEGATION_PURSE((byte) 6), + UNBOND_ACCOUNT((byte) 7), + UNBOND_PURSE((byte) 8); private final byte byteTag; diff --git a/src/main/java/com/casper/sdk/model/key/BidAddrKey.java b/src/main/java/com/casper/sdk/model/key/BidAddrKey.java index d09776188..cb0eb782d 100644 --- a/src/main/java/com/casper/sdk/model/key/BidAddrKey.java +++ b/src/main/java/com/casper/sdk/model/key/BidAddrKey.java @@ -35,7 +35,7 @@ protected void deserializeCustom(final DeserializerBuffer deser) throws Exceptio this.bidAddr = BidAddr.getByTag(deser.readU8()); final int len; - if (BidAddr.DELEGATOR == bidAddr) { + if (BidAddr.DELEGATOR_ACCOUNT == bidAddr) { len = 65; } else if (BidAddr.CREDIT == bidAddr) { len = 41; diff --git a/src/main/java/com/casper/sdk/model/transaction/entrypoint/TransactionEntryPoint.java b/src/main/java/com/casper/sdk/model/transaction/entrypoint/TransactionEntryPoint.java index fa487f858..abbf59abf 100644 --- a/src/main/java/com/casper/sdk/model/transaction/entrypoint/TransactionEntryPoint.java +++ b/src/main/java/com/casper/sdk/model/transaction/entrypoint/TransactionEntryPoint.java @@ -39,7 +39,6 @@ public abstract class TransactionEntryPoint implements CasperSerializableObject, protected static final int CHANGE_BID_PUBLIC_KEY_TAG = 8; protected static final int CALL_TAG = 9; - private final byte tag; private final String name; diff --git a/src/main/java/com/casper/sdk/model/transaction/field/Fields.java b/src/main/java/com/casper/sdk/model/transaction/field/Fields.java index 08d491774..c020cf1e3 100644 --- a/src/main/java/com/casper/sdk/model/transaction/field/Fields.java +++ b/src/main/java/com/casper/sdk/model/transaction/field/Fields.java @@ -16,6 +16,8 @@ import java.util.Map; /** + * The fields of a transaction. + * * @author ian@meywood.com */ @Builder diff --git a/src/main/java/com/casper/sdk/model/transaction/kind/ContractWasmKind.java b/src/main/java/com/casper/sdk/model/transaction/kind/ContractWasmKind.java index 0739a5b61..c690b6fef 100644 --- a/src/main/java/com/casper/sdk/model/transaction/kind/ContractWasmKind.java +++ b/src/main/java/com/casper/sdk/model/transaction/kind/ContractWasmKind.java @@ -9,6 +9,8 @@ import lombok.Setter; /** + * A StoredValue containing a ContractWasm. + * * @author ian@meywood.com */ @AllArgsConstructor diff --git a/src/main/java/com/casper/sdk/model/transaction/kind/EntryPointKind.java b/src/main/java/com/casper/sdk/model/transaction/kind/EntryPointKind.java index f5bb15f06..7b72d22ab 100644 --- a/src/main/java/com/casper/sdk/model/transaction/kind/EntryPointKind.java +++ b/src/main/java/com/casper/sdk/model/transaction/kind/EntryPointKind.java @@ -1,7 +1,7 @@ package com.casper.sdk.model.transaction.kind; -import com.casper.sdk.model.contract.EntryPoint; -import com.casper.sdk.model.contract.EntryPointValue; +import com.casper.sdk.model.contract.entrypoint.EntryPoint; +import com.casper.sdk.model.contract.entrypoint.EntryPointValue; import com.casper.sdk.model.storedvalue.StoredValue; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.*; diff --git a/src/main/java/com/casper/sdk/model/transaction/kind/MessageTopicKind.java b/src/main/java/com/casper/sdk/model/transaction/kind/MessageTopicKind.java index a5fe9611b..03fc34030 100644 --- a/src/main/java/com/casper/sdk/model/transaction/kind/MessageTopicKind.java +++ b/src/main/java/com/casper/sdk/model/transaction/kind/MessageTopicKind.java @@ -9,6 +9,8 @@ import lombok.Setter; /** + * A StoredValue containing a MessageTopicSummary. + * * @author ian@meywood.com */ @AllArgsConstructor diff --git a/src/test/java/com/casper/sdk/model/clvalue/CLValueKeyTest.java b/src/test/java/com/casper/sdk/model/clvalue/CLValueKeyTest.java index 3b2bca18f..d7ea237f6 100644 --- a/src/test/java/com/casper/sdk/model/clvalue/CLValueKeyTest.java +++ b/src/test/java/com/casper/sdk/model/clvalue/CLValueKeyTest.java @@ -140,7 +140,7 @@ void clValueKeyBidAddrKeyDelegatorJsonRoundTrip() throws JsonProcessingException assertThat(clValueKey.getParsed(), is("bid-addr-022f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c4580073099fa1fc0808d3a5b9ea9f3af4ca7c8c3655568fdf378d8afdf8a7e56e58abbfd4")); assertThat(clValueKey.getBytes(), is("0f02022f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c4580073099fa1fc0808d3a5b9ea9f3af4ca7c8c3655568fdf378d8afdf8a7e56e58abbfd4")); final BidAddrKey key = (BidAddrKey) clValueKey.getValue(); - assertThat(key.getBidAddr(), is(BidAddr.DELEGATOR)); + assertThat(key.getBidAddr(), is(BidAddr.DELEGATOR_ACCOUNT)); final String written = new ObjectMapper().writeValueAsString(clValueKey); JSONAssert.assertEquals(json, written, true); diff --git a/src/test/java/com/casper/sdk/model/entity/StateGetEntityTest.java b/src/test/java/com/casper/sdk/model/entity/StateGetEntityTest.java index 41c833f99..4b8e95b2f 100644 --- a/src/test/java/com/casper/sdk/model/entity/StateGetEntityTest.java +++ b/src/test/java/com/casper/sdk/model/entity/StateGetEntityTest.java @@ -1,9 +1,9 @@ package com.casper.sdk.model.entity; import com.casper.sdk.model.AbstractJsonTests; -import com.casper.sdk.model.contract.EntryPoint; -import com.casper.sdk.model.contract.EntryPointV2; -import com.casper.sdk.model.contract.EntryPointValue; +import com.casper.sdk.model.contract.entrypoint.EntryPoint; +import com.casper.sdk.model.contract.entrypoint.EntryPointV2; +import com.casper.sdk.model.contract.entrypoint.EntryPointValue; import org.junit.jupiter.api.Test; import java.io.IOException; diff --git a/src/test/java/com/casper/sdk/model/key/KeyTest.java b/src/test/java/com/casper/sdk/model/key/KeyTest.java index f825a79bb..909aa87d0 100644 --- a/src/test/java/com/casper/sdk/model/key/KeyTest.java +++ b/src/test/java/com/casper/sdk/model/key/KeyTest.java @@ -123,6 +123,18 @@ void bidKeyFromKeyString() throws Exception { assertThat(key.getAlgoTaggedHex(), is("070808080808080808080808080808080808080808080808080808080808080808")); } + @Test + void longBidKeyFromKeyString() throws Exception { + + final String strKey = "bid-addr-032f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c458007309de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae98"; + final Key key = fromJson(strKey); + assertThat(key, is(notNullValue(Key.class))); + assertThat(key.getTag(), is(KeyTag.BID_ADDR)); + assertThat(key.getKey(), is(Hex.decode("032f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c458007309de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae98"))); + assertThat(toJson(key), is(strKey)); + assertThat(key.getAlgoTaggedHex(), is("0f032f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c458007309de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae98")); + } + @Test void withdrawKeyFromKeyString() throws Exception { @@ -279,7 +291,7 @@ void bidAddrKeyDelegatorFromKeyString() throws Exception { assertThat(key.getKey(), is(Hex.decode("022f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c4580073099fa1fc0808d3a5b9ea9f3af4ca7c8c3655568fdf378d8afdf8a7e56e58abbfd4"))); assertThat(toJson(key), is(strKey)); assertThat(key.getAlgoTaggedHex(), is("0f022f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c4580073099fa1fc0808d3a5b9ea9f3af4ca7c8c3655568fdf378d8afdf8a7e56e58abbfd4")); - assertThat(((BidAddrKey) key).getBidAddr(), is(BidAddr.DELEGATOR)); + assertThat(((BidAddrKey) key).getBidAddr(), is(BidAddr.DELEGATOR_ACCOUNT)); } @Test @@ -391,7 +403,7 @@ void messageTopicKeyFromKeyString() throws Exception { @Test void basicMessageTopicKeyFromKeyString() throws Exception { - final String strKey ="message-topic-94b21891ae273b17eeb6a1899a52ab952bcc4da2e19626563f88d6cf7ab6a2bd-e0846cb0e9995ea903dd1b6a275f9c7d9f23e2f83b6918a8a01ba857ff7efdad"; + final String strKey = "message-topic-94b21891ae273b17eeb6a1899a52ab952bcc4da2e19626563f88d6cf7ab6a2bd-e0846cb0e9995ea903dd1b6a275f9c7d9f23e2f83b6918a8a01ba857ff7efdad"; final Key key = fromJson(strKey); assertThat(key, is(instanceOf(MessageKey.class))); assertThat(key.getTag(), is(KeyTag.MESSAGE)); @@ -492,7 +504,6 @@ void nullKeyFromJson() throws Exception { } private Key fromJson(final String strKey) throws JsonProcessingException { - //noinspection VulnerableCodeUsages return new ObjectMapper().readValue(strKey != null ? "\"" + strKey + "\"" : "null", Key.class); } diff --git a/src/test/java/com/casper/sdk/model/transaction/EffectTest.java b/src/test/java/com/casper/sdk/model/transaction/EffectTest.java index bb16a61f1..b4d50e1ef 100644 --- a/src/test/java/com/casper/sdk/model/transaction/EffectTest.java +++ b/src/test/java/com/casper/sdk/model/transaction/EffectTest.java @@ -6,8 +6,8 @@ import com.casper.sdk.model.bid.Delegator; import com.casper.sdk.model.bid.ValidatorCredit; import com.casper.sdk.model.clvalue.AbstractCLValue; -import com.casper.sdk.model.contract.EntryPoint; -import com.casper.sdk.model.contract.EntryPointValue; +import com.casper.sdk.model.contract.entrypoint.EntryPoint; +import com.casper.sdk.model.contract.entrypoint.EntryPointValue; import com.casper.sdk.model.deploy.transform.Transform; import com.casper.sdk.model.entity.Entity; import com.casper.sdk.model.entity.SmartContract; diff --git a/src/test/java/com/casper/sdk/service/CasperServiceTests.java b/src/test/java/com/casper/sdk/service/CasperServiceTests.java index 11025dae6..942de3ffa 100644 --- a/src/test/java/com/casper/sdk/service/CasperServiceTests.java +++ b/src/test/java/com/casper/sdk/service/CasperServiceTests.java @@ -25,7 +25,10 @@ import com.casper.sdk.model.clvalue.cltype.CLTypeUnit; import com.casper.sdk.model.common.Digest; import com.casper.sdk.model.common.Ttl; -import com.casper.sdk.model.contract.*; +import com.casper.sdk.model.contract.Contract; +import com.casper.sdk.model.contract.ContractPackage; +import com.casper.sdk.model.contract.NamedKey; +import com.casper.sdk.model.contract.entrypoint.*; import com.casper.sdk.model.deploy.Deploy; import com.casper.sdk.model.deploy.DeployData; import com.casper.sdk.model.deploy.NamedArg; @@ -701,7 +704,7 @@ void infoGetInstalledContractTransactionByHash() throws Exception { assertThat(value.getEntryPoints(), hasSize(25)); EntryPointV1 entryPoint = value.getEntryPoints().get(2); - assertThat(entryPoint.getAccess(), is("Public")); + assertThat(entryPoint.getAccess(), is(instanceOf(PublicAccess.class))); assertThat(entryPoint.getEntryPointType(), is(EntryPointType.CALLED)); assertThat(entryPoint.getRet().getTypeName(), is("Unit")); assertThat(entryPoint.getName(), is("approve")); @@ -714,9 +717,53 @@ void infoGetInstalledContractTransactionByHash() throws Exception { assertThat(value.getNamedKeys(), hasSize(5)); assertThat(value.getNamedKeys().get(4).getName(), is("state")); assertThat(value.getNamedKeys().get(4).getKey().toString(), is("uref-c5ae802a50fb72194d3c543805bab1a612186bdf2cc5d62758595694a1928fff-007")); + + Optional maybeEffectWithGroup = executionResult.getEffectByKey("hash-b71675d8cf701d9bc584cb5152706873110e5158b004fb966ed28be49c66b39a"); + assertThat(maybeEffectWithGroup.isPresent(), is(true)); + + Effect effectWithGroup = executionResult.getEffects().get(29); + assertThat(effectWithGroup.getKey().toString(), is("hash-b71675d8cf701d9bc584cb5152706873110e5158b004fb966ed28be49c66b39a")); + assertThat(effectWithGroup.getKind(), is(instanceOf(WriteKind.class))); + assertThat(((WriteKind) effectWithGroup.getKind()).getWrite().getValue(), is(instanceOf(ContractPackage.class))); + ContractPackage contractPackage = (ContractPackage) ((WriteKind) effectWithGroup.getKind()).getWrite().getValue(); + assertThat(contractPackage.getAccessKey(), is("uref-5268245ec93d03335ed91c860ac48885fa6ee15156871458a84daa93b2d04f06-007")); + + assertThat(contractPackage.getVersions(), hasSize(1)); + assertThat(contractPackage.getVersions().get(0).getHash(), is("contract-94b21891ae273b17eeb6a1899a52ab952bcc4da2e19626563f88d6cf7ab6a2bd")); + assertThat(contractPackage.getVersions().get(0).getVersion(), is(1)); + assertThat(contractPackage.getVersions().get(0).getProtocolVersionMajor(), is(2)); + + assertThat(contractPackage.getGroups(), hasSize(1)); + assertThat(contractPackage.getGroups().get(0).getName(), is("constructor_group")); + assertThat(contractPackage.getGroups().get(0).getKeys().get(0), is("uref-248a7b93a71529a51bf94824b76b047d9da6cd504532951ce8abff937355781a-007")); + + Optional maybeEntryPoint = value.getEntryPoint("init"); + assertThat(maybeEntryPoint.isPresent(), is(true)); + + entryPoint = maybeEntryPoint.get(); + assertThat(entryPoint.getName(), is("init")); + assertThat(entryPoint.getEntryPointType(), is(EntryPointType.CALLED)); + assertThat(entryPoint.getAccess(), is(instanceOf(GroupsAccess.class))); + assertThat(((GroupsAccess) entryPoint.getAccess()).getGroups(), is(hasSize(1))); + assertThat(((GroupsAccess) entryPoint.getAccess()).getGroups().get(0), is("constructor_group")); } + @Test + void infoGetTransactionWithDelegatorKind() throws Exception { + + mockNode.withRcpResponseDispatcher() + .withMethod("info_get_transaction") + .withBody("$.params.transaction_hash.Deploy", "67594388afce12d027d2098f0bee6742702738647fb8d422d85f1b2c8b72192c") + .thenDispatch(getClass().getResource("/transaction-samples/get_transaction_with_delegator_kind.json")); + + final GetTransactionResult result = casperServiceMock.getTransaction(new TransactionHashDeploy("67594388afce12d027d2098f0bee6742702738647fb8d422d85f1b2c8b72192c")); + assertNotNull(result); + assertThat(result.getTransaction().get(), is(instanceOf(TransactionV1.class))); + assertThat(result.getTransaction().get().getHash(), is(new Digest("67594388afce12d027d2098f0bee6742702738647fb8d422d85f1b2c8b72192c"))); + } + + @Test void accountPutTransferV1() throws Exception { final Secp256k1PublicKey delegator = (Secp256k1PublicKey) Secp256k1PrivateKey.deriveRandomKey().derivePublicKey(); diff --git a/src/test/resources/transaction-samples/get_transaction_with_delegator_kind.json b/src/test/resources/transaction-samples/get_transaction_with_delegator_kind.json new file mode 100644 index 000000000..e4057b27a --- /dev/null +++ b/src/test/resources/transaction-samples/get_transaction_with_delegator_kind.json @@ -0,0 +1,251 @@ +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "api_version": "2.0.0", + "transaction": { + "Version1": { + "hash": "67594388afce12d027d2098f0bee6742702738647fb8d422d85f1b2c8b72192c", + "payload": { + "initiator_addr": { + "PublicKey": "015adadaecbd299c594821a548d755f51a5e2124fb17983f9afae019add32beb21" + }, + "timestamp": "2024-12-04T14:54:15.400Z", + "ttl": "30m", + "chain_name": "casper-net-1", + "pricing_mode": { + "Fixed": { + "additional_computation_factor": 1, + "gas_price_tolerance": 1 + } + }, + "fields": { + "args": { + "Named": [ + [ + "delegator_purse", + { + "cl_type": "URef", + "bytes": "de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae9807", + "parsed": "uref-de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae98-007" + } + ], + [ + "amount", + { + "cl_type": "U512", + "bytes": "0500282e8cd1", + "parsed": "900000000000" + } + ], + [ + "validator", + { + "cl_type": "PublicKey", + "bytes": "01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b", + "parsed": "01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b" + } + ] + ] + }, + "entry_point": { + "Custom": "delegate" + }, + "scheduling": "Standard", + "target": { + "Stored": { + "id": { + "ByHash": "d39b360530484c6b3ed32e84a1198b368fe2bae3d5c9e8af6b0ae4d3eba73caa" + }, + "runtime": "VmCasperV1", + "transferred_value": 0 + } + } + } + }, + "approvals": [ + { + "signer": "015adadaecbd299c594821a548d755f51a5e2124fb17983f9afae019add32beb21", + "signature": "01dca399075db422c9d55976b050ef5cd221eae8a74b4dc0940d44d44c3c8743ca016f983491125e77f0e20a0aef2c1b7102c429141b5254536d453032a0f5c90a" + } + ] + } + }, + "execution_info": { + "block_hash": "c6d3dfe57580def4a7ccb0a2bacb294f4ef10dc392de2e7d845a8b76057f0f87", + "block_height": 11, + "execution_result": { + "Version2": { + "initiator": { + "PublicKey": "015adadaecbd299c594821a548d755f51a5e2124fb17983f9afae019add32beb21" + }, + "error_message": null, + "limit": "50000000000", + "consumed": "2500000000", + "cost": "50000000000", + "transfers": [ + { + "Version2": { + "transaction_hash": { + "Version1": "67594388afce12d027d2098f0bee6742702738647fb8d422d85f1b2c8b72192c" + }, + "from": { + "AccountHash": "account-hash-cdda4c2ed893a1ba91274237ea101030adb7283ecaab2441941a7fe8100cc631" + }, + "to": "account-hash-6174cf2e6f8fed1715c9a3bace9c50bfe572eecb763b0ed3f644532616452008", + "source": "uref-de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae98-002", + "target": "uref-94de0e38671dcf5f328134eecec56bb8349ad6ab575521ecb4ac6994eae9f638-007", + "amount": "900000000000", + "gas": "100000000", + "id": null + } + } + ], + "size_estimate": 624, + "effects": [ + { + "key": "balance-hold-01de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae9868292a9293010000", + "kind": { + "Write": { + "CLValue": { + "cl_type": "U512", + "bytes": "0500743ba40b", + "parsed": "50000000000" + } + } + } + }, + { + "key": "hash-d39b360530484c6b3ed32e84a1198b368fe2bae3d5c9e8af6b0ae4d3eba73caa", + "kind": "Identity" + }, + { + "key": "hash-8624f469c59e96f525abe85e9224440160d51ba1b46c641b947097fb8bfbbf06", + "kind": "Identity" + }, + { + "key": "bid-addr-012f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c458007309", + "kind": "Identity" + }, + { + "key": "hash-2a9716d5916c2e581648cc0a030870af60df4ecbf891d179a334ee8ff1fd7b99", + "kind": "Identity" + }, + { + "key": "hash-65b22b950127083ee0aa9e669c7c97534cd4825259fe480046043eb16c3146a5", + "kind": "Identity" + }, + { + "key": "uref-94de0e38671dcf5f328134eecec56bb8349ad6ab575521ecb4ac6994eae9f638-000", + "kind": { + "Write": { + "CLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + } + }, + { + "key": "balance-94de0e38671dcf5f328134eecec56bb8349ad6ab575521ecb4ac6994eae9f638", + "kind": { + "Write": { + "CLValue": { + "cl_type": "U512", + "bytes": "00", + "parsed": "0" + } + } + } + }, + { + "key": "hash-2a9716d5916c2e581648cc0a030870af60df4ecbf891d179a334ee8ff1fd7b99", + "kind": "Identity" + }, + { + "key": "hash-65b22b950127083ee0aa9e669c7c97534cd4825259fe480046043eb16c3146a5", + "kind": "Identity" + }, + { + "key": "balance-hold-01de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae9868292a9293010000", + "kind": "Identity" + }, + { + "key": "balance-de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae98", + "kind": { + "Write": { + "CLValue": { + "cl_type": "U512", + "bytes": "0e00d8d173385ac138938d44c64d31", + "parsed": "999999999999999999999100000000000" + } + } + } + }, + { + "key": "balance-94de0e38671dcf5f328134eecec56bb8349ad6ab575521ecb4ac6994eae9f638", + "kind": { + "AddUInt512": "900000000000" + } + }, + { + "key": "bid-addr-032f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c458007309de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae98", + "kind": { + "Write": { + "BidKind": { + "Delegator": { + "delegator_kind": { + "Purse": "de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae98" + }, + "staked_amount": "900000000000", + "bonding_purse": "uref-94de0e38671dcf5f328134eecec56bb8349ad6ab575521ecb4ac6994eae9f638-007", + "validator_public_key": "01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b", + "vesting_schedule": null + } + } + } + } + }, + { + "key": "balance-hold-01de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae9868292a9293010000", + "kind": { + "Prune": "balance-hold-01de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae9868292a9293010000" + } + }, + { + "key": "balance-hold-00de0ef381c12dc842e0872453d35aa4b49fa488c0427e68b7dd5ac63e151eae9868292a9293010000", + "kind": { + "Write": { + "CLValue": { + "cl_type": "U512", + "bytes": "0500743ba40b", + "parsed": "50000000000" + } + } + } + }, + { + "key": "bid-addr-012f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c458007309", + "kind": "Identity" + }, + { + "key": "bid-addr-042f3fb80d362ad0a922f446915a259c9aaec9ba99292b3e50ff2359c4580073090100000000000000", + "kind": { + "Write": { + "BidKind": { + "Credit": { + "validator_public_key": "01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b", + "era_id": 1, + "amount": "50000000000" + } + } + } + } + } + ] + } + } + } + } +}