diff --git a/build.gradle b/build.gradle index 04d55e661..aedc76bf1 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ apply plugin: 'java' group = 'network.casper' // Version number update for release -version='2.5.4' +version='2.5.5' sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -26,9 +26,6 @@ repositories { dependencies { implementation "dev.oak3:sbs4j:${sbs4jVersion}" implementation "io.github.oak:jsonrpc4j:${jsonrpc4jVersion}" -// implementation "com.syntifi.crypto:crypto-key-common:${cryptokeyVersion}" -// implementation "com.syntifi.crypto:crypto-key-ed25519:${cryptokeyVersion}" -// implementation "com.syntifi.crypto:crypto-key-secp256k1:${cryptokeyVersion}" implementation "org.bouncycastle:bcpkix-jdk15on:${bouncyCastleVersion}" implementation "org.web3j:core:${web3jVersion}" implementation "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" diff --git a/src/main/java/com/casper/sdk/model/deploy/executabledeploy/AbstractStoredVersionedContract.java b/src/main/java/com/casper/sdk/model/deploy/executabledeploy/AbstractStoredVersionedContract.java new file mode 100644 index 000000000..0ecc1bd60 --- /dev/null +++ b/src/main/java/com/casper/sdk/model/deploy/executabledeploy/AbstractStoredVersionedContract.java @@ -0,0 +1,63 @@ +package com.casper.sdk.model.deploy.executabledeploy; + +import com.casper.sdk.exception.NoSuchTypeException; +import com.casper.sdk.model.clvalue.AbstractCLValue; +import com.casper.sdk.model.clvalue.CLValueOption; +import com.casper.sdk.model.clvalue.CLValueU32; +import com.casper.sdk.model.clvalue.serde.Target; +import com.casper.sdk.model.deploy.NamedArg; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import dev.oak3.sbs4j.SerializerBuffer; +import dev.oak3.sbs4j.exception.ValueSerializationException; +import lombok.*; + +import java.util.List; +import java.util.Optional; + +/** + * Base class for versioned contracts. + * + * @author ian@meywood.com + */ +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +abstract class AbstractStoredVersionedContract extends ExecutableDeployItemWithEntryPoint { + + /** contract version */ + @JsonProperty("version") + private Long version; + + /** Entry Point */ + @JsonProperty("entry_point") + private String entryPoint; + + /** @see NamedArg */ + private List> args; + + @JsonIgnore + public Optional getVersion() { + return Optional.ofNullable(version); + } + + @Override + public void serialize(final SerializerBuffer ser, final Target target) throws NoSuchTypeException, ValueSerializationException { + ser.writeU8(getOrder()); + serializeCustom(ser); + + final Optional> innerValue; + if (version == null) { + innerValue = Optional.empty(); + } else { + innerValue = Optional.of(new CLValueU32(version)); + } + new CLValueOption(innerValue).serialize(ser, Target.JSON); + + ser.writeString(getEntryPoint()); + serializeNamedArgs(ser, target); + } + + protected abstract void serializeCustom(final SerializerBuffer ser); +} diff --git a/src/main/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByHash.java b/src/main/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByHash.java index 029c79ba2..365c7686f 100644 --- a/src/main/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByHash.java +++ b/src/main/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByHash.java @@ -1,18 +1,15 @@ package com.casper.sdk.model.deploy.executabledeploy; -import com.casper.sdk.exception.NoSuchTypeException; -import com.casper.sdk.model.clvalue.serde.Target; import com.casper.sdk.model.deploy.NamedArg; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; import dev.oak3.sbs4j.SerializerBuffer; -import dev.oak3.sbs4j.exception.ValueSerializationException; import lombok.*; import java.util.List; /** - * Abstract Executable Deploy Item containing the StoredVersionedContractByHash. + * Executable Deploy Item containing the StoredVersionedContractByHash. * * @author Alexandre Carvalho * @author Andre Bertolace @@ -21,50 +18,29 @@ */ @Getter @Setter -@Builder -@AllArgsConstructor @NoArgsConstructor @JsonTypeName("StoredVersionedContractByHash") -public class StoredVersionedContractByHash extends ExecutableDeployItemWithEntryPoint { +public class StoredVersionedContractByHash extends AbstractStoredVersionedContract { - /** - * Hex-encoded Hash - */ - private String hash; - - /** - * contract version - */ - private long version; + @Builder + public StoredVersionedContractByHash(final String hash, final Long version, final String entryPoint, final List> args) { + super(version, entryPoint, args); + this.hash = hash; + } - /** - * Entry Point - */ - @JsonProperty("entry_point") - private String entryPoint; + /** Hex-encoded Hash */ + @JsonProperty("hash") + private String hash; - /** - * @see NamedArg - */ - private List> args; - /** - * {@link ExecutableDeployItem} order 3 - */ + /** {@link ExecutableDeployItem} order 3 */ @Override public byte getOrder() { return 0x3; } - /** - * Implements the StoredVersionedContractByHash encoder - */ @Override - public void serialize(final SerializerBuffer ser, final Target target) throws NoSuchTypeException, ValueSerializationException { - ser.writeU8(getOrder()); + protected void serializeCustom(final SerializerBuffer ser) { ser.writeString(getHash()); - ser.writeI64(getVersion()); - ser.writeString(getEntryPoint()); - serializeNamedArgs(ser, target); } } diff --git a/src/main/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByName.java b/src/main/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByName.java index 812d45b6f..e24434980 100644 --- a/src/main/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByName.java +++ b/src/main/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByName.java @@ -1,18 +1,14 @@ package com.casper.sdk.model.deploy.executabledeploy; -import com.casper.sdk.exception.NoSuchTypeException; -import com.casper.sdk.model.clvalue.serde.Target; import com.casper.sdk.model.deploy.NamedArg; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; import dev.oak3.sbs4j.SerializerBuffer; -import dev.oak3.sbs4j.exception.ValueSerializationException; import lombok.*; import java.util.List; /** - * Abstract Executable Deploy Item containing the StoredVersionedContractByName. + * Executable Deploy Item containing the StoredVersionedContractByName. * * @author Alexandre Carvalho * @author Andre Bertolace @@ -21,51 +17,29 @@ */ @Getter @Setter -@Builder +@Builder(access = AccessLevel.PROTECTED) @AllArgsConstructor @NoArgsConstructor @JsonTypeName("StoredVersionedContractByName") -public class StoredVersionedContractByName extends ExecutableDeployItemWithEntryPoint { +public class StoredVersionedContractByName extends AbstractStoredVersionedContract { - /** - * Contract Name - */ + /** Contract Name */ private String name; - /** - * contract version - */ - private long version; - - /** - * Entry Point - */ - @JsonProperty("entry_point") - private String entryPoint; - - /** - * List of @see NamedArg - */ - private List> args; + @Builder + public StoredVersionedContractByName(final String name, final Long version, final String entryPoint, final List> args) { + super(version, entryPoint, args); + this.name = name; + } - /** - * {@link ExecutableDeployItem} order 4 - */ + /** {@link ExecutableDeployItem} order 4 */ @Override public byte getOrder() { return 0x4; } - /** - * Implements the StoredVersionedContractName encoder - */ @Override - public void serialize(final SerializerBuffer ser, final Target target) throws ValueSerializationException, NoSuchTypeException { - ser.writeU8(getOrder()); + protected void serializeCustom(final SerializerBuffer ser) { ser.writeString(getName()); - ser.writeI64(getVersion()); - ser.writeString(getEntryPoint()); - serializeNamedArgs(ser, target); } - } diff --git a/src/test/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByHashTest.java b/src/test/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByHashTest.java new file mode 100644 index 000000000..b58f1de3f --- /dev/null +++ b/src/test/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByHashTest.java @@ -0,0 +1,66 @@ +package com.casper.sdk.model.deploy.executabledeploy; + +import com.casper.sdk.model.clvalue.CLValueI32; +import com.casper.sdk.model.clvalue.serde.Target; +import com.casper.sdk.model.deploy.NamedArg; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.syntifi.crypto.key.encdec.Hex; +import dev.oak3.sbs4j.SerializerBuffer; +import dev.oak3.sbs4j.exception.ValueSerializationException; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNull.notNullValue; + +/** + * Unit tests for the StoredVersionedContractByHash class. + * + * @author ian@meywood.com + */ +class StoredVersionedContractByHashTest { + + @Test + void jsonSerializeStoredVersionedContractByHash() throws ValueSerializationException, JsonProcessingException { + + final StoredVersionedContractByHash versionedContractByHash = StoredVersionedContractByHash.builder() + .hash("92173d49744c790d47e50d011d89e1b5a33ed2d9fae8d9459325224d8f98f3e5") + .version(1L) + .entryPoint("counter_inc") + .args(Arrays.asList(new NamedArg<>("one", new CLValueI32(1)), new NamedArg<>("two", new CLValueI32(2)))) + .build(); + + final String json = new ObjectMapper().writeValueAsString(versionedContractByHash); + + assertThat(json, is(notNullValue())); + + JsonNode root = new ObjectMapper().reader().readTree(json); + assertThat(root.at("/StoredVersionedContractByHash/hash").asText(), is("92173d49744c790d47e50d011d89e1b5a33ed2d9fae8d9459325224d8f98f3e5")); + assertThat(root.at("/StoredVersionedContractByHash/entry_point").asText(), is("counter_inc")); + assertThat(root.at("/StoredVersionedContractByHash/version").asInt(), is(1)); + assertThat(root.at("/StoredVersionedContractByHash/args/0/0").asText(), is("one")); + assertThat(root.at("/StoredVersionedContractByHash/args/0/1/bytes").asText(), is("01000000")); + assertThat(root.at("/StoredVersionedContractByHash/args/0/1/cl_type").asText(), is("I32")); + } + + @Test + void serializeStoredVersionedContractByHashTest() throws Exception { + + final StoredVersionedContractByHash versionedContractByHash = StoredVersionedContractByHash.builder() + .hash("92173d49744c790d47e50d011d89e1b5a33ed2d9fae8d9459325224d8f98f3e5") + .version(1L) + .entryPoint("transfer") + .args(Arrays.asList(new NamedArg<>("one", new CLValueI32(1)), new NamedArg<>("two", new CLValueI32(2)))) + .build(); + + final SerializerBuffer serializerBuffer = new SerializerBuffer(); + versionedContractByHash.serialize(serializerBuffer, Target.BYTE); + final String expectedBytes = "0340000000393231373364343937343463373930643437653530643031316438396531623561333365643264396661653864393435393332353232346438663938663365350101000000080000007472616e7366657202000000030000006f6e650400000001000000010300000074776f040000000200000001"; + final String actual = Hex.encode(serializerBuffer.toByteArray()); + assertThat(actual, is(expectedBytes)); + } +} diff --git a/src/test/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByNameTest.java b/src/test/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByNameTest.java new file mode 100644 index 000000000..a6956a17c --- /dev/null +++ b/src/test/java/com/casper/sdk/model/deploy/executabledeploy/StoredVersionedContractByNameTest.java @@ -0,0 +1,71 @@ +package com.casper.sdk.model.deploy.executabledeploy; + +import com.casper.sdk.model.clvalue.CLValueI32; +import com.casper.sdk.model.clvalue.serde.Target; +import com.casper.sdk.model.deploy.NamedArg; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.syntifi.crypto.key.encdec.Hex; +import dev.oak3.sbs4j.SerializerBuffer; +import dev.oak3.sbs4j.exception.ValueSerializationException; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNull.notNullValue; + +/** + * Unit tests for the StoredVersionedContractByName class + * + * @author ian@meywood.com + */ +class StoredVersionedContractByNameTest { + + @Test + void jsonSerializeStoredVersionedContractByName() throws ValueSerializationException, JsonProcessingException { + + final StoredVersionedContractByName versionedContractByName = new StoredVersionedContractByName(); + + versionedContractByName.setName("counter"); + versionedContractByName.setEntryPoint("counter_inc"); + versionedContractByName.setVersion(1L); + versionedContractByName.setArgs(Arrays.asList( + new NamedArg<>("one", new CLValueI32(1)), + new NamedArg<>("two", new CLValueI32(2)) + )); + + final String json = new ObjectMapper().writeValueAsString(versionedContractByName); + + assertThat(json, is(notNullValue())); + + JsonNode root = new ObjectMapper().reader().readTree(json); + assertThat(root.at("/StoredVersionedContractByName/name").asText(), is("counter")); + assertThat(root.at("/StoredVersionedContractByName/entry_point").asText(), is("counter_inc")); + assertThat(root.at("/StoredVersionedContractByName/version").asInt(), is(1)); + assertThat(root.at("/StoredVersionedContractByName/args/0/0").asText(), is("one")); + assertThat(root.at("/StoredVersionedContractByName/args/0/1/bytes").asText(), is("01000000")); + assertThat(root.at("/StoredVersionedContractByName/args/0/1/cl_type").asText(), is("I32")); + } + + @Test + void serializeStoredVersionedContractByHash() throws Exception { + + final StoredVersionedContractByName versionedContractByName = new StoredVersionedContractByName(); + + versionedContractByName.setName("counter"); + versionedContractByName.setEntryPoint("transfer"); + versionedContractByName.setArgs(Arrays.asList( + new NamedArg<>("one", new CLValueI32(1)), + new NamedArg<>("two", new CLValueI32(2)) + )); + + final SerializerBuffer serializerBuffer = new SerializerBuffer(); + versionedContractByName.serialize(serializerBuffer, Target.BYTE); + final String expectedBytes = "0407000000636f756e74657200080000007472616e7366657202000000030000006f6e650400000001000000010300000074776f040000000200000001"; + final String actual = Hex.encode(serializerBuffer.toByteArray()); + assertThat(actual, is(expectedBytes)); + } +}