From 466f230fd614576b8cd8d4001dcbfbe4a5ab7805 Mon Sep 17 00:00:00 2001 From: meywood <105049338+meywood@users.noreply.github.com> Date: Fri, 8 Mar 2024 11:56:58 +0000 Subject: [PATCH 1/7] issues/253 - Fix for byte serialization of nested maps --- .../casper/sdk/model/clvalue/CLValueMap.java | 12 ++++++--- .../sdk/model/clvalue/CLValueTests.java | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java index e7ea4d410..df716b6b3 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java @@ -76,8 +76,14 @@ protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeExc final byte keyTypeTag = (getClType().getKeyValueTypes().getKeyType().getClTypeData().getSerializationTag()); ser.writeU8(keyTypeTag); - final byte valueTypeTag = (getClType().getKeyValueTypes().getValueType().getClTypeData().getSerializationTag()); - ser.writeU8(valueTypeTag); + final Map, ? extends AbstractCLValue> value = this.getValue(); + final CLTypeData clTypeData = getClType().getKeyValueTypes().getValueType().getClTypeData(); + if (!value.isEmpty()) { + encodeChildType(ser, value.values().iterator().next(), clTypeData); + } else { + final byte valueTypeTag = (clTypeData.getSerializationTag()); + ser.writeU8(valueTypeTag); + } } @Override @@ -180,6 +186,6 @@ public int hashCode() { @Override public String toString() { - return getValue() != null ? getValue().keySet().stream().map(key -> key.getValue().toString() + "=" + key.getValue().toString()).collect(Collectors.joining(", ")) : null; + return getValue() != null ? getValue().entrySet().stream().map(entry -> entry.getKey().toString() + "=" + entry.getValue().toString()).collect(Collectors.joining(", ")) : null; } } diff --git a/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java b/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java index 2de521603..ebd14ee04 100644 --- a/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java +++ b/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.Test; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; @@ -197,4 +198,30 @@ void nestedTuple3Serialization() throws Exception { assertThat(ser.toByteArray(), is(expected)); } + + @Test + void nestedMapSerialization() throws Exception { + + Map map = new LinkedHashMap<>(); + map.put(new CLValueString("ONE"), new CLValueU32(1L)); + final CLValueMap innerMap1 = new CLValueMap(map); + + map = new LinkedHashMap<>(); + map.put(new CLValueString("TWO"), new CLValueU32(2L)); + final CLValueMap innerMap2 = new CLValueMap(map); + + + Map map2 = new LinkedHashMap<>(); + map2.put(new CLValueString("THREE"), innerMap1); + map2.put(new CLValueString("FOUR"), innerMap2); + + final CLValueMap outerMap = new CLValueMap(map2); + + final SerializerBuffer ser = new SerializerBuffer(); + outerMap.serialize(ser, Target.BYTE); + + byte[] expected = {51, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 84, 72, 82, 69, 69, 1, 0, 0, 0, 3, 0, 0, 0, 79, 78, 69, 1, 0, 0, 0, 4, 0, 0, 0, 70, 79, 85, 82, 1, 0, 0, 0, 3, 0, 0, 0, 84, 87, 79, 2, 0, 0, 0, 17, 10, 17, 10, 4}; + + assertThat(ser.toByteArray(), is(expected)); + } } From 14cec1af4e8fa3b7cdb844821b5d0c35bd375c4d Mon Sep 17 00:00:00 2001 From: meywood <105049338+meywood@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:37:12 +0000 Subject: [PATCH 2/7] issues/253 - Fix for byte serialization of nested maps --- .../sdk/model/clvalue/AbstractCLValue.java | 27 +++++-- .../clvalue/AbstractCLValueWithChildren.java | 14 ++-- .../casper/sdk/model/clvalue/CLValueMap.java | 12 ++- .../cltype/AbstractCLTypeWithChildren.java | 17 ++++- .../sdk/model/clvalue/cltype/CLTypeList.java | 13 +++- .../sdk/model/clvalue/cltype/CLTypeMap.java | 31 +++++++- .../model/clvalue/cltype/CLTypeOption.java | 13 +++- .../model/clvalue/cltype/CLTypeTuple1.java | 10 ++- .../model/clvalue/cltype/CLTypeTuple2.java | 10 ++- .../model/clvalue/cltype/CLTypeTuple3.java | 10 ++- .../sdk/model/clvalue/CLValueTests.java | 75 ++++++++++++++++++- 11 files changed, 200 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValue.java b/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValue.java index ad2ea93a3..6383157b5 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValue.java +++ b/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValue.java @@ -1,10 +1,13 @@ package com.casper.sdk.model.clvalue; import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport; +import com.casper.sdk.exception.DynamicInstanceException; import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.jackson.resolver.CLValueResolver; import com.casper.sdk.model.clvalue.cltype.AbstractCLType; +import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren; import com.casper.sdk.model.clvalue.cltype.CLTypeData; +import com.casper.sdk.model.clvalue.cltype.CLTypeMap; import com.casper.sdk.model.clvalue.serde.CasperDeserializableObject; import com.casper.sdk.model.clvalue.serde.CasperSerializableObject; import com.casper.sdk.model.clvalue.serde.Target; @@ -58,8 +61,15 @@ public void setValue(final T value) throws ValueSerializationException { final int length = deser.readI32(); final byte[] bytes = deser.readByteArray(length); final byte clType = deser.readU8(); + try { - final AbstractCLValue clValue = CLTypeData.getTypeBySerializationTag(clType).getClazz().getDeclaredConstructor().newInstance(); + CLTypeData clTypeData = CLTypeData.getTypeBySerializationTag(clType); + final AbstractCLValue clValue = clTypeData.getClazz().getDeclaredConstructor().newInstance(); + if (clValue instanceof AbstractCLValueWithChildren) { + // We have only obtained the parent type from the buffer now we need to read the child types + ((AbstractCLTypeWithChildren) clValue.getClType()).deserializeChildTypes(deser); + } + clValue.deserializeCustom(new DeserializerBuffer(Hex.encode(bytes))); return clValue; } catch (Exception e) { @@ -67,6 +77,16 @@ public void setValue(final T value) throws ValueSerializationException { } } + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + protected CLTypeData deserializeTypeData(DeserializerBuffer dser) throws NoSuchTypeException, ValueDeserializationException { + byte clType = dser.readU8(); + return CLTypeData.getTypeBySerializationTag(clType); + } + @SneakyThrows({ValueSerializationException.class, NoSuchTypeException.class}) @JsonGetter(value = "bytes") @ExcludeFromJacocoGeneratedReport @@ -84,10 +104,7 @@ protected String getJsonBytes() { @ExcludeFromJacocoGeneratedReport protected void setJsonBytes(final String bytes) { this.bytes = bytes; - - final DeserializerBuffer deser = new DeserializerBuffer(this.bytes); - - this.deserialize(deser); + this.deserialize( new DeserializerBuffer(this.bytes)); } @JsonIgnore diff --git a/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValueWithChildren.java b/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValueWithChildren.java index 0c1eeaebf..9a9fe9802 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValueWithChildren.java +++ b/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValueWithChildren.java @@ -32,8 +32,7 @@ public abstract class AbstractCLValueWithChildren, ? extends AbstractCLValue> value) { @@ -134,8 +142,8 @@ protected void setChildTypes(final Map, ? extend } // This needed to be customized to ensure equality is being checked correctly. - // The java Map equals method tries to get the "other" map entry's value by using "this" key object, - // which then fails to find the object since they are "different" and returns always null. +// The java Map equals method tries to get the "other" map entry's value by using "this" key object, +// which then fails to find the object since they are "different" and returns always null. @Override public boolean equals(final Object o) { if (o == this) return true; diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java index 438ec3740..88bb745f4 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java @@ -1,7 +1,10 @@ package com.casper.sdk.model.clvalue.cltype; +import com.casper.sdk.exception.DynamicInstanceException; import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonIgnore; +import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -27,10 +30,9 @@ public abstract class AbstractCLTypeWithChildren extends AbstractCLType { @JsonIgnore private List childTypes = new ArrayList<>(); - private List childTypeObjects; - protected void setChildTypeObjects(List childTypeObjects) + protected void setChildTypeObjects(final List childTypeObjects) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchTypeException { this.childTypeObjects = childTypeObjects; @@ -55,7 +57,7 @@ protected List getChildTypeObjects() { } @JsonIgnore - public CLTypeData getChildClTypeData(int index) throws NoSuchTypeException { + public CLTypeData getChildClTypeData(final int index) throws NoSuchTypeException { return CLTypeData.getTypeByName(getChildTypes().get(index).getTypeName()); } @@ -64,7 +66,7 @@ public boolean isDeserializable() { return getChildTypes().stream().allMatch(AbstractCLType::isDeserializable); } - protected void loadCLTypes(List childTypeObjects) + protected void loadCLTypes(final List childTypeObjects) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchTypeException { childTypes.clear(); @@ -97,4 +99,11 @@ private void addChildType(Object childTypeObject, List parent) } } } + + /** + * Update the child types from the deserializer buffer. + * + * @param deser the deserializer buffer + */ + public abstract void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException; } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeList.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeList.java index 018a21bf7..c0cb06e61 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeList.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeList.java @@ -1,9 +1,13 @@ package com.casper.sdk.model.clvalue.cltype; import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport; +import com.casper.sdk.exception.DynamicInstanceException; +import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonSetter; +import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -32,7 +36,7 @@ protected Object getJsonValue() { @JsonSetter(AbstractCLType.LIST) @ExcludeFromJacocoGeneratedReport - protected void setJsonValue(AbstractCLType clType) { + protected void setJsonValue(final AbstractCLType clType) { getChildTypes().add(clType); } @@ -46,7 +50,7 @@ public AbstractCLType getListType() { } @JsonIgnore - public void setListType(AbstractCLType listType) { + public void setListType(final AbstractCLType listType) { getChildTypes().clear(); getChildTypes().add(listType); } @@ -62,4 +66,9 @@ public boolean isDeserializable() { } }); } + + @Override + public void deserializeChildTypes(DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + // FIXME: 2021/10/20 + } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java index 01c158e43..975052347 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java @@ -1,10 +1,14 @@ package com.casper.sdk.model.clvalue.cltype; import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport; +import com.casper.sdk.exception.DynamicInstanceException; +import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; +import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.*; /** @@ -21,7 +25,7 @@ public class CLTypeMap extends AbstractCLTypeWithChildren { private final String typeName = AbstractCLType.MAP; @JsonProperty(MAP) - public void setKeyValueTypes(CLTypeMapEntryType keyValueTypes) { + public void setKeyValueTypes(final CLTypeMapEntryType keyValueTypes) { this.keyValueTypes = keyValueTypes; getChildTypes().add(this.keyValueTypes.getKeyType()); getChildTypes().add(this.keyValueTypes.getValueType()); @@ -36,7 +40,7 @@ public boolean isDeserializable() { // The map contains an 'Any' type therefore cannot be deserialized return false; } else if (getKeyValueTypes().valueType instanceof AbstractCLTypeWithChildren) { - return getChildTypes().stream().allMatch(childType -> { + return getChildTypes().stream().allMatch(childType -> { if (childType instanceof CLTypeAny) { return false; } else { @@ -69,7 +73,7 @@ public static class CLTypeMapEntryType { @JsonSetter("key") @ExcludeFromJacocoGeneratedReport - protected void setJsonKey(AbstractCLType clType) { + protected void setJsonKey(final AbstractCLType clType) { this.keyType = clType; } @@ -85,7 +89,7 @@ protected Object getJsonKey() { @JsonSetter("value") @ExcludeFromJacocoGeneratedReport - protected void setJsonValue(AbstractCLType clType) { + protected void setJsonValue(final AbstractCLType clType) { this.valueType = clType; } @@ -99,4 +103,23 @@ protected Object getJsonValue() { } } } + + @Override + public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + + // read child types + final int keyTypeTag = deser.readU8(); + final int valueTypeTag = deser.readU8(); + + final CLTypeData keyType = CLTypeData.getTypeBySerializationTag((byte) keyTypeTag); + final CLTypeData valueType = CLTypeData.getTypeBySerializationTag((byte) valueTypeTag); + final AbstractCLType clTypeKey = CLTypeData.createCLTypeFromCLTypeName(keyType.getClTypeName()); + AbstractCLType clTypeValue = CLTypeData.createCLTypeFromCLTypeName(valueType.getClTypeName()); + + if (clTypeValue instanceof AbstractCLTypeWithChildren) { + ((AbstractCLTypeWithChildren) clTypeValue).deserializeChildTypes(deser); + } + + setKeyValueTypes(new CLTypeMap.CLTypeMapEntryType(clTypeKey, clTypeValue)); + } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeOption.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeOption.java index 58d395ae1..ac52b8546 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeOption.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeOption.java @@ -1,9 +1,13 @@ package com.casper.sdk.model.clvalue.cltype; import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport; +import com.casper.sdk.exception.DynamicInstanceException; +import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonSetter; +import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @@ -34,7 +38,7 @@ protected Object getJsonClType() { @JsonSetter(OPTION) @ExcludeFromJacocoGeneratedReport - protected void setJsonClType(AbstractCLType clType) { + protected void setJsonClType(final AbstractCLType clType) { getChildTypes().add(clType); } @@ -48,7 +52,7 @@ public AbstractCLType getOptionType() { } @JsonIgnore - public void setOptionType(AbstractCLType listType) { + public void setOptionType(final AbstractCLType listType) { getChildTypes().clear(); getChildTypes().add(listType); } @@ -57,4 +61,9 @@ public void setOptionType(AbstractCLType listType) { public boolean isDeserializable() { return getOptionType().isDeserializable(); } + + @Override + public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + // FIXME: 2021/10/20 + } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple1.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple1.java index 3cb5ac403..c4f43ec6a 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple1.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple1.java @@ -1,7 +1,10 @@ package com.casper.sdk.model.clvalue.cltype; +import com.casper.sdk.exception.DynamicInstanceException; import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonProperty; +import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -23,7 +26,7 @@ public class CLTypeTuple1 extends AbstractCLTypeWithChildren { @Override @JsonProperty(TUPLE1) - protected void setChildTypeObjects(List childTypeObjects) + protected void setChildTypeObjects(final List childTypeObjects) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchTypeException { super.setChildTypeObjects(childTypeObjects); @@ -34,4 +37,9 @@ protected void setChildTypeObjects(List childTypeObjects) protected List getChildTypeObjects() { return super.getChildTypeObjects(); } + + @Override + public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + // FIXME: 2021/10/20 + } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java index 372d0a358..f004c60e6 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java @@ -1,7 +1,10 @@ package com.casper.sdk.model.clvalue.cltype; +import com.casper.sdk.exception.DynamicInstanceException; import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonProperty; +import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -23,7 +26,7 @@ public class CLTypeTuple2 extends AbstractCLTypeWithChildren { @Override @JsonProperty(AbstractCLType.TUPLE2) - protected void setChildTypeObjects(List childTypeObjects) + protected void setChildTypeObjects(final List childTypeObjects) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchTypeException { super.setChildTypeObjects(childTypeObjects); @@ -34,4 +37,9 @@ protected void setChildTypeObjects(List childTypeObjects) protected List getChildTypeObjects() { return super.getChildTypeObjects(); } + + @Override + public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + // FIXME: 2021/10/20 + } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java index abe4fad7a..827eae3c4 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java @@ -1,7 +1,10 @@ package com.casper.sdk.model.clvalue.cltype; +import com.casper.sdk.exception.DynamicInstanceException; import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonProperty; +import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -23,7 +26,7 @@ public class CLTypeTuple3 extends AbstractCLTypeWithChildren { @Override @JsonProperty(AbstractCLType.TUPLE3) - protected void setChildTypeObjects(List childTypeObjects) + protected void setChildTypeObjects(final List childTypeObjects) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchTypeException { super.setChildTypeObjects(childTypeObjects); @@ -34,4 +37,9 @@ protected void setChildTypeObjects(List childTypeObjects) protected List getChildTypeObjects() { return super.getChildTypeObjects(); } + + @Override + public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + // FIXME: 2021/10/20 + } } diff --git a/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java b/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java index ebd14ee04..13379fff9 100644 --- a/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java +++ b/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java @@ -2,10 +2,7 @@ import com.casper.sdk.exception.DynamicInstanceException; import com.casper.sdk.exception.NoSuchTypeException; -import com.casper.sdk.model.clvalue.cltype.CLTypeAny; -import com.casper.sdk.model.clvalue.cltype.CLTypeData; -import com.casper.sdk.model.clvalue.cltype.CLTypeMap; -import com.casper.sdk.model.clvalue.cltype.CLTypeTuple1; +import com.casper.sdk.model.clvalue.cltype.*; import com.casper.sdk.model.clvalue.serde.Target; import com.casper.sdk.model.deploy.NamedArg; import com.syntifi.crypto.key.encdec.Hex; @@ -16,11 +13,13 @@ import org.javatuples.Unit; import org.junit.jupiter.api.Test; +import java.math.BigInteger; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.core.Is.is; import static org.junit.jupiter.api.Assertions.*; @@ -224,4 +223,72 @@ void nestedMapSerialization() throws Exception { assertThat(ser.toByteArray(), is(expected)); } + + @Test + void nestedMapDeserialization() throws Exception { + + byte[] bytes = {51, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 84, 72, 82, 69, 69, 1, 0, 0, 0, 3, 0, 0, 0, 79, 78, 69, 1, 0, 0, 0, 4, 0, 0, 0, 70, 79, 85, 82, 1, 0, 0, 0, 3, 0, 0, 0, 84, 87, 79, 2, 0, 0, 0, 17, 10, 17, 10, 4}; + + final CLTypeMap innerType = new CLTypeMap(); + innerType.setKeyValueTypes(new CLTypeMap.CLTypeMapEntryType(new CLTypeString(), new CLTypeU32())); + + final CLTypeMap outerType = new CLTypeMap(); + outerType.setKeyValueTypes(new CLTypeMap.CLTypeMapEntryType(new CLTypeString(), innerType)); + + final CLValueMap outerMap = new CLValueMap(); + outerMap.setClType(outerType); + outerMap.deserialize(new DeserializerBuffer(bytes), Target.BYTE); + } + + @SuppressWarnings("unchecked") + @Test + void nestedMapDeserialization2() throws Exception { + + // a nested map is created {1: {11: {111: "ONE_ONE_ONE"}, 12: {121: "ONE_TWO_ONE"}}, 2: {21: {211: "TWO_ONE_ONE"}, 22: {221: "TWO_TWO_ONE"}}} + + Map map = new LinkedHashMap<>(); + map.put(new CLValueU256(BigInteger.valueOf(111L)), new CLValueString("ONE_ONE_ONE")); + final CLValueMap innerMap111 = new CLValueMap(map); + + map = new LinkedHashMap<>(); + map.put(new CLValueU256(BigInteger.valueOf(121L)), new CLValueString("ONE_TWO_ONE")); + final CLValueMap innerMap121 = new CLValueMap(map); + + map = new LinkedHashMap<>(); + map.put(new CLValueU256(BigInteger.valueOf(11L)), innerMap111); + map.put(new CLValueU256(BigInteger.valueOf(12L)), innerMap121); + final CLValueMap innerMap1 = new CLValueMap(map); + + map = new LinkedHashMap<>(); + map.put(new CLValueU256(BigInteger.valueOf(211L)), new CLValueString("TWO_ONE_ONE")); + final CLValueMap innerMap21 = new CLValueMap(map); + + map = new LinkedHashMap<>(); + map.put(new CLValueU256(BigInteger.valueOf(221)), new CLValueString("TWO_TWO_ONE")); + final CLValueMap innerMap22 = new CLValueMap(map); + + map = new LinkedHashMap<>(); + map.put(new CLValueU256(BigInteger.valueOf(21L)), innerMap21); + map.put(new CLValueU256(BigInteger.valueOf(22L)), innerMap22); + final CLValueMap innerMap2 = new CLValueMap(map); + + map = new LinkedHashMap<>(); + map.put(new CLValueU256(BigInteger.valueOf(1L)), innerMap1); + map.put(new CLValueU256(BigInteger.valueOf(2L)), innerMap2); + final CLValueMap outerMap = new CLValueMap(map); + + final SerializerBuffer ser = new SerializerBuffer(); + outerMap.serialize(ser, Target.BYTE); + + byte[] actualBytes = ser.toByteArray(); + + assertThat(actualBytes.length, is(greaterThan(0))); + + CLValueMap clValueMap = new CLValueMap(); + clValueMap = (CLValueMap) clValueMap.deserialize(new DeserializerBuffer(actualBytes), Target.BYTE); + + assertThat(clValueMap.getBytes(), is(outerMap.getBytes())); + } + + } From 7b1bdd08278fda9dcb1eea1695ef5acddafd0c8e Mon Sep 17 00:00:00 2001 From: meywood <105049338+meywood@users.noreply.github.com> Date: Mon, 11 Mar 2024 18:25:00 +0000 Subject: [PATCH 3/7] issues/253 - Tidy up of type classes --- .../casper/sdk/model/clvalue/cltype/AbstractCLTypeBasic.java | 2 +- .../sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java | 4 ++-- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeAny.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeBool.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeData.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeI32.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeI64.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeKey.java | 2 +- .../com/casper/sdk/model/clvalue/cltype/CLTypePublicKey.java | 2 +- .../com/casper/sdk/model/clvalue/cltype/CLTypeResult.java | 4 ++-- .../com/casper/sdk/model/clvalue/cltype/CLTypeString.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeU128.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeU256.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeU32.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeU512.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeU64.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeU8.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeURef.java | 2 +- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeUnit.java | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeBasic.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeBasic.java index 0a3104222..64a68421a 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeBasic.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeBasic.java @@ -11,7 +11,7 @@ */ @NoArgsConstructor public abstract class AbstractCLTypeBasic extends AbstractCLType { - protected AbstractCLTypeBasic(String typeName) { + protected AbstractCLTypeBasic(final String typeName) { if (!this.getTypeName().equals(typeName)) { throw new IllegalArgumentException( String.format("%s is an invalid type for %s", getClass().getSimpleName(), typeName)); diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java index 88bb745f4..ad0193bd8 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java @@ -78,7 +78,7 @@ protected void loadCLTypes(final List childTypeObjects) } } - private void addChildType(Object childTypeObject, List parent) + private void addChildType(final Object childTypeObject, final List parent) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchTypeException { if (childTypeObject instanceof String) { @@ -101,7 +101,7 @@ private void addChildType(Object childTypeObject, List parent) } /** - * Update the child types from the deserializer buffer. + * Updates the child types from the deserializer buffer. * * @param deser the deserializer buffer */ diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeAny.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeAny.java index c32c2151d..dedb0fbc0 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeAny.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeAny.java @@ -20,7 +20,7 @@ public class CLTypeAny extends AbstractCLTypeBasic { private final String typeName = AbstractCLType.ANY; @JsonCreator - protected CLTypeAny(String typeName) { + protected CLTypeAny(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeBool.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeBool.java index 9ccb7b54a..d882e53a6 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeBool.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeBool.java @@ -20,7 +20,7 @@ public class CLTypeBool extends AbstractCLTypeBasic { private final String typeName = AbstractCLType.BOOL; @JsonCreator - protected CLTypeBool(String typeName) { + protected CLTypeBool(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeData.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeData.java index 5336098ef..b2547421a 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeData.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeData.java @@ -59,7 +59,7 @@ public enum CLTypeData { * @return the requested {@link CLTypeData} * @throws NoSuchTypeException raised when the clType is not valid/found */ - public static CLTypeData getTypeBySerializationTag(byte serializationTag) throws NoSuchTypeException { + public static CLTypeData getTypeBySerializationTag(final byte serializationTag) throws NoSuchTypeException { for (CLTypeData clType : values()) { if (clType.serializationTag == serializationTag) { return clType; diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeI32.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeI32.java index 68024e797..a38537cf7 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeI32.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeI32.java @@ -20,7 +20,7 @@ public class CLTypeI32 extends AbstractCLTypeBasic { private final String typeName = I32; @JsonCreator - protected CLTypeI32(String typeName) { + protected CLTypeI32(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeI64.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeI64.java index 386a07927..a000c9542 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeI64.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeI64.java @@ -20,7 +20,7 @@ public class CLTypeI64 extends AbstractCLTypeBasic { private final String typeName = I64; @JsonCreator - protected CLTypeI64(String typeName) { + protected CLTypeI64(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeKey.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeKey.java index 0bd24f622..d84517d15 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeKey.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeKey.java @@ -20,7 +20,7 @@ public class CLTypeKey extends AbstractCLTypeBasic { private final String typeName = AbstractCLType.KEY; @JsonCreator - protected CLTypeKey(String typeName) { + protected CLTypeKey(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypePublicKey.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypePublicKey.java index 7645300b3..a226c4f56 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypePublicKey.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypePublicKey.java @@ -20,7 +20,7 @@ public class CLTypePublicKey extends AbstractCLTypeBasic { private final String typeName = PUBLIC_KEY; @JsonCreator - protected CLTypePublicKey(String typeName) { + protected CLTypePublicKey(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeResult.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeResult.java index ec3c26a60..9b89fae77 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeResult.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeResult.java @@ -46,7 +46,7 @@ public static class CLTypeResultOkErrTypes { @JsonSetter("ok") @ExcludeFromJacocoGeneratedReport - protected void setJsonKey(AbstractCLType clType) { + protected void setJsonKey(final AbstractCLType clType) { this.okClType = clType; } @@ -62,7 +62,7 @@ protected Object getJsonKey() { @JsonSetter("err") @ExcludeFromJacocoGeneratedReport - protected void setJsonValue(AbstractCLType clType) { + protected void setJsonValue(final AbstractCLType clType) { this.errClType = clType; } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeString.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeString.java index 04425eb44..c39c483b7 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeString.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeString.java @@ -20,7 +20,7 @@ public class CLTypeString extends AbstractCLTypeBasic { private final String typeName = STRING; @JsonCreator - protected CLTypeString(String typeName) { + protected CLTypeString(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU128.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU128.java index 7a0b03075..40852c4ca 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU128.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU128.java @@ -21,7 +21,7 @@ public class CLTypeU128 extends AbstractCLTypeBasic { private final String typeName = U128; @JsonCreator - protected CLTypeU128(String typeName) { + protected CLTypeU128(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU256.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU256.java index 2ff4c34b8..f645fb252 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU256.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU256.java @@ -21,7 +21,7 @@ public class CLTypeU256 extends AbstractCLTypeBasic { private final String typeName = U256; @JsonCreator - protected CLTypeU256(String typeName) { + protected CLTypeU256(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU32.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU32.java index 9e80e26e5..831a6a8e9 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU32.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU32.java @@ -20,7 +20,7 @@ public class CLTypeU32 extends AbstractCLTypeBasic { private final String typeName = U32; @JsonCreator - protected CLTypeU32(String typeName) { + protected CLTypeU32(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU512.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU512.java index cd515a81c..8b12cd99b 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU512.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU512.java @@ -21,7 +21,7 @@ public class CLTypeU512 extends AbstractCLTypeBasic { private final String typeName = AbstractCLType.U512; @JsonCreator - protected CLTypeU512(String typeName) { + protected CLTypeU512(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU64.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU64.java index a07e72b97..4e1e4cc66 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU64.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU64.java @@ -21,7 +21,7 @@ public class CLTypeU64 extends AbstractCLTypeBasic { private final String typeName = U64; @JsonCreator - protected CLTypeU64(String typeName) { + protected CLTypeU64(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU8.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU8.java index 52d9fa5ad..66015e45e 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU8.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeU8.java @@ -20,7 +20,7 @@ public class CLTypeU8 extends AbstractCLTypeBasic { private final String typeName = AbstractCLType.U8; @JsonCreator - protected CLTypeU8(String typeName) { + protected CLTypeU8(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeURef.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeURef.java index 8cf7129b8..06a0270e7 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeURef.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeURef.java @@ -21,7 +21,7 @@ public class CLTypeURef extends AbstractCLTypeBasic { private final String typeName = AbstractCLType.UREF; @JsonCreator - protected CLTypeURef(String typeName) { + protected CLTypeURef(final String typeName) { super(typeName); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeUnit.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeUnit.java index 847e3457d..9b9c57d27 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeUnit.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeUnit.java @@ -21,7 +21,7 @@ public class CLTypeUnit extends AbstractCLTypeBasic { private final String typeName = UNIT; @JsonCreator - protected CLTypeUnit(String typeName) { + protected CLTypeUnit(final String typeName) { super(typeName); } } From 3460378f28731d230d69598e3f1efe8e706ac98c Mon Sep 17 00:00:00 2001 From: meywood <105049338+meywood@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:26:52 +0000 Subject: [PATCH 4/7] issues/253 - Refactored CLTypes so that they are responsible for their own serialization, rather than depending upon the value to be able to serialize them. --- .../sdk/model/clvalue/AbstractCLValue.java | 16 +-- .../clvalue/AbstractCLValueWithChildren.java | 35 ----- .../sdk/model/clvalue/CLValueByteArray.java | 7 - .../casper/sdk/model/clvalue/CLValueList.java | 6 - .../casper/sdk/model/clvalue/CLValueMap.java | 19 --- .../sdk/model/clvalue/CLValueOption.java | 9 -- .../sdk/model/clvalue/CLValueTuple1.java | 6 - .../sdk/model/clvalue/CLValueTuple2.java | 8 -- .../sdk/model/clvalue/CLValueTuple3.java | 8 -- .../model/clvalue/cltype/AbstractCLType.java | 14 +- .../cltype/AbstractCLTypeWithChildren.java | 14 ++ .../model/clvalue/cltype/CLTypeByteArray.java | 8 ++ .../sdk/model/clvalue/cltype/CLTypeList.java | 20 ++- .../sdk/model/clvalue/cltype/CLTypeMap.java | 9 +- .../model/clvalue/cltype/CLTypeOption.java | 8 +- .../model/clvalue/cltype/CLTypeTuple1.java | 10 +- .../model/clvalue/cltype/CLTypeTuple2.java | 13 +- .../model/clvalue/cltype/CLTypeTuple3.java | 12 +- .../sdk/model/clvalue/CLValueTests.java | 132 +++++++++++++----- 19 files changed, 200 insertions(+), 154 deletions(-) diff --git a/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValue.java b/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValue.java index 6383157b5..1acfb0531 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValue.java +++ b/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValue.java @@ -1,13 +1,11 @@ package com.casper.sdk.model.clvalue; import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport; -import com.casper.sdk.exception.DynamicInstanceException; import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.jackson.resolver.CLValueResolver; import com.casper.sdk.model.clvalue.cltype.AbstractCLType; import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren; import com.casper.sdk.model.clvalue.cltype.CLTypeData; -import com.casper.sdk.model.clvalue.cltype.CLTypeMap; import com.casper.sdk.model.clvalue.serde.CasperDeserializableObject; import com.casper.sdk.model.clvalue.serde.CasperSerializableObject; import com.casper.sdk.model.clvalue.serde.Target; @@ -82,11 +80,6 @@ protected Object clone() throws CloneNotSupportedException { return super.clone(); } - protected CLTypeData deserializeTypeData(DeserializerBuffer dser) throws NoSuchTypeException, ValueDeserializationException { - byte clType = dser.readU8(); - return CLTypeData.getTypeBySerializationTag(clType); - } - @SneakyThrows({ValueSerializationException.class, NoSuchTypeException.class}) @JsonGetter(value = "bytes") @ExcludeFromJacocoGeneratedReport @@ -104,7 +97,7 @@ protected String getJsonBytes() { @ExcludeFromJacocoGeneratedReport protected void setJsonBytes(final String bytes) { this.bytes = bytes; - this.deserialize( new DeserializerBuffer(this.bytes)); + this.deserialize(new DeserializerBuffer(this.bytes)); } @JsonIgnore @@ -141,7 +134,7 @@ public void serialize(final SerializerBuffer ser, final Target target) throws Va serializeValue(ser); if (Target.BYTE.equals(target)) { - this.encodeType(ser); + getClType().serialize(ser); } } @@ -157,9 +150,4 @@ public void deserialize(final DeserializerBuffer deserializerBuffer) throws Valu throw new ValueDeserializationException("Error deserializing value", e); } } - - protected void encodeType(final SerializerBuffer ser) throws NoSuchTypeException { - final byte typeTag = (getClType().getClTypeData().getSerializationTag()); - ser.writeU8(typeTag); - } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValueWithChildren.java b/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValueWithChildren.java index 9a9fe9802..5cd53ae4a 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValueWithChildren.java +++ b/src/main/java/com/casper/sdk/model/clvalue/AbstractCLValueWithChildren.java @@ -1,12 +1,9 @@ package com.casper.sdk.model.clvalue; import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport; -import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren; -import com.casper.sdk.model.clvalue.cltype.CLTypeData; import com.fasterxml.jackson.annotation.JsonSetter; import dev.oak3.sbs4j.DeserializerBuffer; -import dev.oak3.sbs4j.SerializerBuffer; import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.SneakyThrows; @@ -52,36 +49,4 @@ protected void setJsonBytes(String bytes) { this.deserialize(new DeserializerBuffer(this.getBytes())); } } - - protected void encodeType(final SerializerBuffer ser) throws NoSuchTypeException { - super.encodeType(ser); - encodeChildTypes(ser); - } - - protected abstract void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException; - - /** - * Encodes the bytes of the child type, if the child value is not present but the type is known from the parent type - * info, the childDataType is used to encode the bytes of the child rather than the child value. - * - * @param ser the serializer buffer - * @param child the child value whose type is to be encoded - * @param childDataType the data type of the child - * @throws NoSuchTypeException if the child type is not found - */ - protected void encodeChildType(final SerializerBuffer ser, - final AbstractCLValue child, - final CLTypeData childDataType) throws NoSuchTypeException { - if (child instanceof AbstractCLValueWithChildren) { - child.encodeType(ser); - } else { - // If there are no AbstractCLValueWithChildren as children we just need a simple tag - byte element0TypeTag = childDataType.getSerializationTag(); - ser.writeU8(element0TypeTag); - } - } - - public void populateChildTypes(final DeserializerBuffer dser) { - - } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueByteArray.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueByteArray.java index 1d960d98e..c5743323b 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueByteArray.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueByteArray.java @@ -1,7 +1,6 @@ package com.casper.sdk.model.clvalue; import com.casper.sdk.annotation.ExcludeFromJacocoGeneratedReport; -import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.model.clvalue.cltype.CLTypeByteArray; import com.fasterxml.jackson.annotation.JsonProperty; import dev.oak3.sbs4j.DeserializerBuffer; @@ -42,12 +41,6 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat this.setBytes(Hex.toHexString(getValue())); } - @Override - protected void encodeType(final SerializerBuffer ser) throws NoSuchTypeException { - super.encodeType(ser); - ser.writeI32(this.getClType().getLength()); - } - @Override public void deserializeCustom(final DeserializerBuffer deser) throws Exception { this.setValue(deser.readByteArray(this.getClType().getLength())); diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueList.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueList.java index 1a67ac1e2..8200d59da 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueList.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueList.java @@ -1,6 +1,5 @@ package com.casper.sdk.model.clvalue; -import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren; import com.casper.sdk.model.clvalue.cltype.CLTypeData; import com.casper.sdk.model.clvalue.cltype.CLTypeList; @@ -67,11 +66,6 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat this.setBytes(Hex.toHexString(bytes)); } - @Override - protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException { - final byte val = (getClType().getListType().getClTypeData().getSerializationTag()); - ser.writeU8(val); - } @Override public void deserializeCustom(final DeserializerBuffer deser) throws Exception { diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java index b04dd30d2..009d9d4f9 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java @@ -1,8 +1,5 @@ package com.casper.sdk.model.clvalue; -import com.casper.sdk.exception.DynamicInstanceException; -import com.casper.sdk.exception.NoSuchTypeException; -import com.casper.sdk.model.clvalue.cltype.AbstractCLType; import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren; import com.casper.sdk.model.clvalue.cltype.CLTypeData; import com.casper.sdk.model.clvalue.cltype.CLTypeMap; @@ -11,7 +8,6 @@ import com.fasterxml.jackson.annotation.JsonSetter; import dev.oak3.sbs4j.DeserializerBuffer; import dev.oak3.sbs4j.SerializerBuffer; -import dev.oak3.sbs4j.exception.ValueDeserializationException; import dev.oak3.sbs4j.exception.ValueSerializationException; import lombok.Getter; import lombok.NoArgsConstructor; @@ -73,21 +69,6 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat this.setBytes(Hex.toHexString(bytes)); } - @Override - protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException { - - final byte keyTypeTag = (getClType().getKeyValueTypes().getKeyType().getClTypeData().getSerializationTag()); - ser.writeU8(keyTypeTag); - - final Map, ? extends AbstractCLValue> value = this.getValue(); - final CLTypeData clTypeData = getClType().getKeyValueTypes().getValueType().getClTypeData(); - if (!value.isEmpty()) { - encodeChildType(ser, value.values().iterator().next(), clTypeData); - } else { - final byte valueTypeTag = (clTypeData.getSerializationTag()); - ser.writeU8(valueTypeTag); - } - } @Override public void deserializeCustom(final DeserializerBuffer deser) throws Exception { diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueOption.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueOption.java index 38e5ab2f5..ded0ed933 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueOption.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueOption.java @@ -1,6 +1,5 @@ package com.casper.sdk.model.clvalue; -import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.model.clvalue.cltype.*; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; @@ -92,14 +91,6 @@ public void deserializeCustom(final DeserializerBuffer deser) throws Exception { setValue(Optional.of(child)); } - @Override - protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException { - final Optional> child = getValue(); - if (child.isPresent()) { - encodeChildType(ser, child.get(), this.getClType().getOptionType().getClTypeData()); - } - } - @Override protected void setChildTypes(final Optional> value) { if (value.isPresent()) { diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple1.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple1.java index 710a1d1f3..3d7be7f85 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple1.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple1.java @@ -1,6 +1,5 @@ package com.casper.sdk.model.clvalue; -import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren; import com.casper.sdk.model.clvalue.cltype.CLTypeData; import com.casper.sdk.model.clvalue.cltype.CLTypeTuple1; @@ -56,11 +55,6 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat this.setBytes(Hex.toHexString(bytes)); } - @Override - protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException { - encodeChildType(ser, this.getValue().getValue0(), getClType().getChildClTypeData(0)); - } - @Override public void deserializeCustom(final DeserializerBuffer deser) throws Exception { CLTypeData childTypeData1 = clType.getChildClTypeData(0); diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple2.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple2.java index 3e02df674..1fcf0fd8f 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple2.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple2.java @@ -1,6 +1,5 @@ package com.casper.sdk.model.clvalue; -import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren; import com.casper.sdk.model.clvalue.cltype.CLTypeData; import com.casper.sdk.model.clvalue.cltype.CLTypeTuple2; @@ -59,13 +58,6 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat } - @Override - protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException { - encodeChildType(ser, this.getValue().getValue0(), getClType().getChildClTypeData(0)); - encodeChildType(ser, this.getValue().getValue1(), getClType().getChildClTypeData(1)); - } - - @Override public void deserializeCustom(final DeserializerBuffer deser) throws Exception { final CLTypeData childTypeData1 = clType.getChildClTypeData(0); diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple3.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple3.java index d52a314c4..e48e1674d 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple3.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueTuple3.java @@ -1,6 +1,5 @@ package com.casper.sdk.model.clvalue; -import com.casper.sdk.exception.NoSuchTypeException; import com.casper.sdk.model.clvalue.cltype.AbstractCLTypeWithChildren; import com.casper.sdk.model.clvalue.cltype.CLTypeData; import com.casper.sdk.model.clvalue.cltype.CLTypeTuple3; @@ -59,13 +58,6 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat this.setBytes(Hex.toHexString(bytes)); } - @Override - protected void encodeChildTypes(SerializerBuffer ser) throws NoSuchTypeException { - encodeChildType(ser, this.getValue().getValue0(), getClType().getChildClTypeData(0)); - encodeChildType(ser, this.getValue().getValue1(), getClType().getChildClTypeData(1)); - encodeChildType(ser, this.getValue().getValue2(), getClType().getChildClTypeData(2)); - } - @Override public void deserializeCustom(final DeserializerBuffer deser) throws Exception { final CLTypeData childTypeData1 = clType.getChildClTypeData(0); diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLType.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLType.java index f3d4974eb..8b9f89a80 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLType.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLType.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.annotation.JsonTypeResolver; +import dev.oak3.sbs4j.SerializerBuffer; import lombok.Getter; import lombok.Setter; @@ -67,7 +68,7 @@ public CLTypeData getClTypeData() throws NoSuchTypeException { } /** - * Indicates if the CLType does not contains and 'Any', or other un-deserializable child type from bytes. The reason + * Indicates if the CLType does not contain an 'Any', or other un-deserializable child type from bytes. The reason * for this is the 'Any' type does not provide a length for its bytes. This type information is obtained from the * JSON metadata. * @@ -76,4 +77,15 @@ public CLTypeData getClTypeData() throws NoSuchTypeException { */ @JsonIgnore public abstract boolean isDeserializable(); + + + /** + * Serializes the type to the provided buffer + * + * @param ser the buffer to serialize to + * @throws NoSuchTypeException if the type is not supported + */ + public void serialize(final SerializerBuffer ser) throws NoSuchTypeException { + ser.writeU8(getClTypeData().getSerializationTag()); + } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java index ad0193bd8..98ee0e7fa 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java @@ -4,6 +4,7 @@ import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonIgnore; import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.SerializerBuffer; import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -100,10 +101,23 @@ private void addChildType(final Object childTypeObject, final List getChildTypeObjects() { return super.getChildTypeObjects(); } + @Override + public void serializeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException { + if (!getChildTypes().isEmpty()) { + getChildTypes().get(0).serialize(ser); + } + } + @Override public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - // FIXME: 2021/10/20 + // FIXME } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java index f004c60e6..a40b82d56 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java @@ -4,6 +4,7 @@ import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonProperty; import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.SerializerBuffer; import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -22,6 +23,7 @@ @Getter @EqualsAndHashCode(callSuper = true, of = {"typeName"}) public class CLTypeTuple2 extends AbstractCLTypeWithChildren { + private final String typeName = AbstractCLType.TUPLE2; @Override @@ -38,8 +40,17 @@ protected List getChildTypeObjects() { return super.getChildTypeObjects(); } + @Override + public void serializeChildTypes(SerializerBuffer ser) throws NoSuchTypeException { + + if (getChildTypes().size() >= 2) { + getChildTypes().get(0).serialize(ser); + getChildTypes().get(1).serialize(ser); + } + } + @Override public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - // FIXME: 2021/10/20 + // FIXME } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java index 827eae3c4..7c6c1fd70 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java @@ -4,6 +4,7 @@ import com.casper.sdk.exception.NoSuchTypeException; import com.fasterxml.jackson.annotation.JsonProperty; import dev.oak3.sbs4j.DeserializerBuffer; +import dev.oak3.sbs4j.SerializerBuffer; import dev.oak3.sbs4j.exception.ValueDeserializationException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -38,8 +39,17 @@ protected List getChildTypeObjects() { return super.getChildTypeObjects(); } + public void serializeChildTypes(SerializerBuffer ser) throws NoSuchTypeException { + + if (getChildTypes().size() >= 3) { + getChildTypes().get(0).serialize(ser); + getChildTypes().get(1).serialize(ser); + getChildTypes().get(2).serialize(ser); + } + } + @Override public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - // FIXME: 2021/10/20 + // FIXME } } diff --git a/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java b/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java index 13379fff9..153283097 100644 --- a/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java +++ b/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java @@ -14,9 +14,7 @@ import org.junit.jupiter.api.Test; import java.math.BigInteger; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; @@ -245,37 +243,37 @@ void nestedMapDeserialization() throws Exception { void nestedMapDeserialization2() throws Exception { // a nested map is created {1: {11: {111: "ONE_ONE_ONE"}, 12: {121: "ONE_TWO_ONE"}}, 2: {21: {211: "TWO_ONE_ONE"}, 22: {221: "TWO_TWO_ONE"}}} - - Map map = new LinkedHashMap<>(); - map.put(new CLValueU256(BigInteger.valueOf(111L)), new CLValueString("ONE_ONE_ONE")); - final CLValueMap innerMap111 = new CLValueMap(map); - - map = new LinkedHashMap<>(); - map.put(new CLValueU256(BigInteger.valueOf(121L)), new CLValueString("ONE_TWO_ONE")); - final CLValueMap innerMap121 = new CLValueMap(map); - - map = new LinkedHashMap<>(); - map.put(new CLValueU256(BigInteger.valueOf(11L)), innerMap111); - map.put(new CLValueU256(BigInteger.valueOf(12L)), innerMap121); - final CLValueMap innerMap1 = new CLValueMap(map); - - map = new LinkedHashMap<>(); - map.put(new CLValueU256(BigInteger.valueOf(211L)), new CLValueString("TWO_ONE_ONE")); - final CLValueMap innerMap21 = new CLValueMap(map); - - map = new LinkedHashMap<>(); - map.put(new CLValueU256(BigInteger.valueOf(221)), new CLValueString("TWO_TWO_ONE")); - final CLValueMap innerMap22 = new CLValueMap(map); - - map = new LinkedHashMap<>(); - map.put(new CLValueU256(BigInteger.valueOf(21L)), innerMap21); - map.put(new CLValueU256(BigInteger.valueOf(22L)), innerMap22); - final CLValueMap innerMap2 = new CLValueMap(map); - - map = new LinkedHashMap<>(); - map.put(new CLValueU256(BigInteger.valueOf(1L)), innerMap1); - map.put(new CLValueU256(BigInteger.valueOf(2L)), innerMap2); - final CLValueMap outerMap = new CLValueMap(map); + //noinspection rawtypes + Map innerMap = new LinkedHashMap<>(); + innerMap.put(new CLValueU256(BigInteger.valueOf(111L)), new CLValueString("ONE_ONE_ONE")); + final CLValueMap innerMap111 = new CLValueMap(innerMap); + + innerMap = new LinkedHashMap<>(); + innerMap.put(new CLValueU256(BigInteger.valueOf(121L)), new CLValueString("ONE_TWO_ONE")); + final CLValueMap innerMap121 = new CLValueMap(innerMap); + + innerMap = new LinkedHashMap<>(); + innerMap.put(new CLValueU256(BigInteger.valueOf(11L)), innerMap111); + innerMap.put(new CLValueU256(BigInteger.valueOf(12L)), innerMap121); + final CLValueMap innerMap1 = new CLValueMap(innerMap); + + innerMap = new LinkedHashMap<>(); + innerMap.put(new CLValueU256(BigInteger.valueOf(211L)), new CLValueString("TWO_ONE_ONE")); + final CLValueMap innerMap21 = new CLValueMap(innerMap); + + innerMap = new LinkedHashMap<>(); + innerMap.put(new CLValueU256(BigInteger.valueOf(221)), new CLValueString("TWO_TWO_ONE")); + final CLValueMap innerMap22 = new CLValueMap(innerMap); + + innerMap = new LinkedHashMap<>(); + innerMap.put(new CLValueU256(BigInteger.valueOf(21L)), innerMap21); + innerMap.put(new CLValueU256(BigInteger.valueOf(22L)), innerMap22); + final CLValueMap innerMap2 = new CLValueMap(innerMap); + + innerMap = new LinkedHashMap<>(); + innerMap.put(new CLValueU256(BigInteger.valueOf(1L)), innerMap1); + innerMap.put(new CLValueU256(BigInteger.valueOf(2L)), innerMap2); + final CLValueMap outerMap = new CLValueMap(innerMap); final SerializerBuffer ser = new SerializerBuffer(); outerMap.serialize(ser, Target.BYTE); @@ -290,5 +288,71 @@ void nestedMapDeserialization2() throws Exception { assertThat(clValueMap.getBytes(), is(outerMap.getBytes())); } + @Test + void nestedListSerialization() throws Exception { + + /* + [0] = {u8} 24 [0x18] +[1] = {u8} 0 [0x0] +[2] = {u8} 0 [0x0] +[3] = {u8} 0 [0x0] +[4] = {u8} 2 [0x2] +[5] = {u8} 0 [0x0] +[6] = {u8} 0 [0x0] +[7] = {u8} 0 [0x0] +[8] = {u8} 3 [0x3] +[9] = {u8} 0 [0x0] +[10] = {u8} 0 [0x0] +[11] = {u8} 0 [0x0] +[12] = {u8} 1 [0x1] +[13] = {u8} 1 [0x1] +[14] = {u8} 1 [0x1] +[15] = {u8} 2 [0x2] +[16] = {u8} 1 [0x1] +[17] = {u8} 3 [0x3] +[18] = {u8} 3 [0x3] +[19] = {u8} 0 [0x0] +[20] = {u8} 0 [0x0] +[21] = {u8} 0 [0x0] +[22] = {u8} 1 [0x1] +[23] = {u8} 4 [0x4] +[24] = {u8} 1 [0x1] +[25] = {u8} 5 [0x5] +[26] = {u8} 1 [0x1] +[27] = {u8} 6 [0x6] +[28] = {u8} 14 [0xe] +[29] = {u8} 14 [0xe] +[30] = {u8} 7 [0x7] + */ + + final byte[] expectedBytes = {24, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 1, 1, 2, 1, 3, 3, 0, 0, 0, 1, 4, 1, 5, 1, 6, 14, 14, 7}; + + List innerInernalList = new ArrayList<>(); + innerInernalList.add(new CLValueU256(BigInteger.valueOf(1L))); + innerInernalList.add(new CLValueU256(BigInteger.valueOf(2L))); + innerInernalList.add(new CLValueU256(BigInteger.valueOf(3L))); + CLValueList innerList1 = new CLValueList(innerInernalList); + + innerInernalList = new ArrayList<>(); + innerInernalList.add(new CLValueU256(BigInteger.valueOf(4L))); + innerInernalList.add(new CLValueU256(BigInteger.valueOf(5L))); + innerInernalList.add(new CLValueU256(BigInteger.valueOf(6L))); + CLValueList innerList2 = new CLValueList(innerInernalList); + + List internalOutList = new ArrayList<>(); + internalOutList.add(innerList1); + internalOutList.add(innerList2); + CLValueList outerList = new CLValueList(internalOutList); + + final SerializerBuffer ser = new SerializerBuffer(); + outerList.serialize(ser, Target.BYTE); + byte[] actualBytes = ser.toByteArray(); + assertThat(actualBytes, is(expectedBytes)); + + CLValueList clValueList = (CLValueList) outerList.deserialize(new DeserializerBuffer(actualBytes), Target.BYTE); + + assertThat(clValueList.getBytes(), is(outerList.getBytes())); + + } } From 4ab2696d9ae8a032faacdef4a02324d5234f6a3a Mon Sep 17 00:00:00 2001 From: meywood <105049338+meywood@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:01:19 +0000 Subject: [PATCH 5/7] issues/253 - Refactored CLTypes so that they are responsible for their own serialization, rather than depending upon the value to be able to serialize them. --- .../casper/sdk/helper/CasperDeployHelper.java | 65 ++++++++++++------- .../cltype/AbstractCLTypeWithChildren.java | 16 ++++- .../sdk/model/clvalue/cltype/CLTypeMap.java | 18 ++--- .../model/clvalue/cltype/CLTypeOption.java | 2 +- .../model/clvalue/cltype/CLTypeTuple1.java | 5 +- .../model/clvalue/cltype/CLTypeTuple2.java | 8 ++- .../model/clvalue/cltype/CLTypeTuple3.java | 6 +- .../sdk/model/clvalue/CLValueTests.java | 38 +---------- 8 files changed, 77 insertions(+), 81 deletions(-) diff --git a/src/main/java/com/casper/sdk/helper/CasperDeployHelper.java b/src/main/java/com/casper/sdk/helper/CasperDeployHelper.java index e75a59e3c..9d34a9fa2 100644 --- a/src/main/java/com/casper/sdk/helper/CasperDeployHelper.java +++ b/src/main/java/com/casper/sdk/helper/CasperDeployHelper.java @@ -39,9 +39,13 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class CasperDeployHelper { - public static DeployHeader buildDeployHeader(PublicKey fromPublicKey, String chainName, - Long gasPrice, Ttl ttl, Date date, - List dependencies, byte[] bodyHash) { + public static DeployHeader buildDeployHeader(final PublicKey fromPublicKey, + final String chainName, + final Long gasPrice, + final Ttl ttl, + final Date date, + final List dependencies, + final byte[] bodyHash) { return DeployHeader .builder() .account(fromPublicKey) @@ -54,28 +58,29 @@ public static DeployHeader buildDeployHeader(PublicKey fromPublicKey, String cha .build(); } - public static HashAndSignature signDeployHeader(AbstractPrivateKey privateKey, DeployHeader deployHeader) + public static HashAndSignature signDeployHeader(final AbstractPrivateKey privateKey, final DeployHeader deployHeader) throws GeneralSecurityException, NoSuchTypeException, ValueSerializationException { - SerializerBuffer serializerBuffer = new SerializerBuffer(); - + final SerializerBuffer serializerBuffer = new SerializerBuffer(); deployHeader.serialize(serializerBuffer, Target.BYTE); - byte[] headerHash = Blake2b.digest(serializerBuffer.toByteArray(), 32); - Signature signature = Signature.sign(privateKey, headerHash); + final byte[] headerHash = Blake2b.digest(serializerBuffer.toByteArray(), 32); + final Signature signature = Signature.sign(privateKey, headerHash); return new HashAndSignature(headerHash, signature); } - public static byte[] getDeployItemAndModuleBytesHash(ExecutableDeployItem deployItem, ModuleBytes moduleBytes) + public static byte[] getDeployItemAndModuleBytesHash(final ExecutableDeployItem deployItem, final ModuleBytes moduleBytes) throws NoSuchTypeException, ValueSerializationException { - SerializerBuffer ser = new SerializerBuffer(); + final SerializerBuffer ser = new SerializerBuffer(); moduleBytes.serialize(ser, Target.BYTE); deployItem.serialize(ser, Target.BYTE); return Blake2b.digest(ser.toByteArray(), 32); } - public static ModuleBytes getPaymentModuleBytes(BigInteger paymentAmount) throws ValueSerializationException { - List> paymentArgs = new LinkedList<>(); - NamedArg paymentArg = new NamedArg<>("amount", - new CLValueU512(paymentAmount)); + public static ModuleBytes getPaymentModuleBytes(final BigInteger paymentAmount) throws ValueSerializationException { + final List> paymentArgs = new LinkedList<>(); + final NamedArg paymentArg = new NamedArg<>( + "amount", + new CLValueU512(paymentAmount) + ); paymentArgs.add(paymentArg); return ModuleBytes .builder() @@ -96,26 +101,38 @@ public static ModuleBytes getPaymentModuleBytes(BigInteger paymentAmount) throws * ms (30 minutes)) * @param date deploy date * @param dependencies list of digest dependencies - * @return + * @return the built deploy * @throws NoSuchTypeException * @throws GeneralSecurityException * @throws ValueSerializationException */ - public static Deploy buildDeploy(AbstractPrivateKey fromPrivateKey, String chainName, - ExecutableDeployItem session, ModuleBytes payment, - Long gasPrice, Ttl ttl, Date date, List dependencies) + public static Deploy buildDeploy(final AbstractPrivateKey fromPrivateKey, + final String chainName, + final ExecutableDeployItem session, + final ModuleBytes payment, + final Long gasPrice, + final Ttl ttl, + final Date date, + final List dependencies) throws NoSuchTypeException, GeneralSecurityException, ValueSerializationException { - byte[] sessionAnPaymentHash = getDeployItemAndModuleBytesHash(session, payment); + final byte[] sessionAnPaymentHash = getDeployItemAndModuleBytesHash(session, payment); - PublicKey fromPublicKey = PublicKey.fromAbstractPublicKey(fromPrivateKey.derivePublicKey()); + final PublicKey fromPublicKey = PublicKey.fromAbstractPublicKey(fromPrivateKey.derivePublicKey()); - DeployHeader deployHeader = buildDeployHeader(fromPublicKey, chainName, gasPrice, ttl, - date, dependencies, sessionAnPaymentHash); + final DeployHeader deployHeader = buildDeployHeader( + fromPublicKey, + chainName, + gasPrice, + ttl, + date, + dependencies, + sessionAnPaymentHash + ); - HashAndSignature hashAndSignature = signDeployHeader(fromPrivateKey, deployHeader); + final HashAndSignature hashAndSignature = signDeployHeader(fromPrivateKey, deployHeader); - List approvals = new LinkedList<>(); + final List approvals = new LinkedList<>(); approvals.add(Approval.builder() .signer(PublicKey.fromAbstractPublicKey(fromPrivateKey.derivePublicKey())) .signature(hashAndSignature.getSignature()) diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java index 98ee0e7fa..3729412b8 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/AbstractCLTypeWithChildren.java @@ -112,7 +112,8 @@ public void serialize(final SerializerBuffer ser) throws NoSuchTypeException { * * @param deser the deserializer buffer */ - public abstract void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException; + public abstract void deserializeChildTypes(final DeserializerBuffer deser) + throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException; /** * Writes the child types to the serialization buffer. @@ -120,4 +121,17 @@ public void serialize(final SerializerBuffer ser) throws NoSuchTypeException { * @param ser the serialization buffer */ protected abstract void serializeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException; + + protected AbstractCLType deserializeChildType(final DeserializerBuffer deser) + throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + final int childTypeTag = deser.readU8(); + final CLTypeData childType = CLTypeData.getTypeBySerializationTag((byte) childTypeTag); + final AbstractCLType clChildType = CLTypeData.createCLTypeFromCLTypeName(childType.getClTypeName()); + + if (clChildType instanceof AbstractCLTypeWithChildren) { + ((AbstractCLTypeWithChildren) clChildType).deserializeChildTypes(deser); + } + + return clChildType; + } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java index ca6b44965..276445161 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java @@ -112,21 +112,11 @@ public void serializeChildTypes(final SerializerBuffer ser) throws NoSuchTypeExc } @Override - public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - + public void deserializeChildTypes(final DeserializerBuffer deser) + throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { // read child types - final int keyTypeTag = deser.readU8(); - final int valueTypeTag = deser.readU8(); - - final CLTypeData keyType = CLTypeData.getTypeBySerializationTag((byte) keyTypeTag); - final CLTypeData valueType = CLTypeData.getTypeBySerializationTag((byte) valueTypeTag); - final AbstractCLType clTypeKey = CLTypeData.createCLTypeFromCLTypeName(keyType.getClTypeName()); - final AbstractCLType clTypeValue = CLTypeData.createCLTypeFromCLTypeName(valueType.getClTypeName()); - - if (clTypeValue instanceof AbstractCLTypeWithChildren) { - ((AbstractCLTypeWithChildren) clTypeValue).deserializeChildTypes(deser); - } - + final AbstractCLType clTypeKey = deserializeChildType(deser); + final AbstractCLType clTypeValue = deserializeChildType(deser); setKeyValueTypes(new CLTypeMap.CLTypeMapEntryType(clTypeKey, clTypeValue)); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeOption.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeOption.java index 3fc7bed0f..9c9744264 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeOption.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeOption.java @@ -70,6 +70,6 @@ public void serializeChildTypes(final SerializerBuffer ser) throws NoSuchTypeExc @Override public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - // FIXME + setOptionType(deserializeChildType(deser)); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple1.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple1.java index 7ea7537d5..43e9e9cf5 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple1.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple1.java @@ -47,7 +47,8 @@ public void serializeChildTypes(final SerializerBuffer ser) throws NoSuchTypeExc } @Override - public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - // FIXME + public void deserializeChildTypes(final DeserializerBuffer deser) + throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + getChildTypes().add(deserializeChildType(deser)); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java index a40b82d56..093d2ff8f 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java @@ -50,7 +50,11 @@ public void serializeChildTypes(SerializerBuffer ser) throws NoSuchTypeException } @Override - public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - // FIXME + public void deserializeChildTypes(final DeserializerBuffer deser) + throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + getChildTypes().add(deserializeChildType(deser)); + getChildTypes().add(deserializeChildType(deser)); } + + } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java index 7c6c1fd70..7ba6f64b4 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java @@ -49,7 +49,9 @@ public void serializeChildTypes(SerializerBuffer ser) throws NoSuchTypeException } @Override - public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - // FIXME + public void deserializeChildTypes(final DeserializerBuffer deser) + throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + getChildTypes().add(deserializeChildType(deser)); + getChildTypes().add(deserializeChildType(deser)); } } diff --git a/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java b/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java index 153283097..7d5562ac9 100644 --- a/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java +++ b/src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java @@ -166,6 +166,9 @@ void nestedTuple1Serialization() throws Exception { final byte[] expected = {4, 0, 0, 0, 1, 0, 0, 0, 18, 18, 4}; assertThat(ser.toByteArray(), is(expected)); + + final CLValueTuple1 deserialized = (CLValueTuple1) outerTuple1.deserialize(new DeserializerBuffer(expected), Target.BYTE); + assertThat(deserialized.getBytes(), is(outerTuple1.getBytes())); } @Test @@ -291,40 +294,6 @@ void nestedMapDeserialization2() throws Exception { @Test void nestedListSerialization() throws Exception { - /* - [0] = {u8} 24 [0x18] -[1] = {u8} 0 [0x0] -[2] = {u8} 0 [0x0] -[3] = {u8} 0 [0x0] -[4] = {u8} 2 [0x2] -[5] = {u8} 0 [0x0] -[6] = {u8} 0 [0x0] -[7] = {u8} 0 [0x0] -[8] = {u8} 3 [0x3] -[9] = {u8} 0 [0x0] -[10] = {u8} 0 [0x0] -[11] = {u8} 0 [0x0] -[12] = {u8} 1 [0x1] -[13] = {u8} 1 [0x1] -[14] = {u8} 1 [0x1] -[15] = {u8} 2 [0x2] -[16] = {u8} 1 [0x1] -[17] = {u8} 3 [0x3] -[18] = {u8} 3 [0x3] -[19] = {u8} 0 [0x0] -[20] = {u8} 0 [0x0] -[21] = {u8} 0 [0x0] -[22] = {u8} 1 [0x1] -[23] = {u8} 4 [0x4] -[24] = {u8} 1 [0x1] -[25] = {u8} 5 [0x5] -[26] = {u8} 1 [0x1] -[27] = {u8} 6 [0x6] -[28] = {u8} 14 [0xe] -[29] = {u8} 14 [0xe] -[30] = {u8} 7 [0x7] - */ - final byte[] expectedBytes = {24, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 1, 1, 2, 1, 3, 3, 0, 0, 0, 1, 4, 1, 5, 1, 6, 14, 14, 7}; List innerInernalList = new ArrayList<>(); @@ -353,6 +322,5 @@ void nestedListSerialization() throws Exception { CLValueList clValueList = (CLValueList) outerList.deserialize(new DeserializerBuffer(actualBytes), Target.BYTE); assertThat(clValueList.getBytes(), is(outerList.getBytes())); - } } From ec9c16f487f04c3b397f0a697e120dea270ff535 Mon Sep 17 00:00:00 2001 From: meywood <105049338+meywood@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:42:52 +0000 Subject: [PATCH 6/7] issues/253 - Tidy up for code review. --- .../casper/sdk/model/clvalue/CLValueMap.java | 22 +++++++++++++++---- .../sdk/model/clvalue/cltype/CLTypeList.java | 13 +++-------- .../model/clvalue/cltype/CLTypeTuple2.java | 4 +--- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java b/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java index 009d9d4f9..e5d81c638 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java +++ b/src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java @@ -122,9 +122,14 @@ protected void setChildTypes(final Map, ? extend } } - // This needed to be customized to ensure equality is being checked correctly. -// The java Map equals method tries to get the "other" map entry's value by using "this" key object, -// which then fails to find the object since they are "different" and returns always null. + /** + * This needed to be customized to ensure equality is being checked correctly. + * The java Map equals method tries to get the "other" map entry's value by using "this" key object, + * which then fails to find the object since they are "different" and returns always null. + * + * @param o the object to compare + * @return true if the objects are equal, false otherwise + */ @Override public boolean equals(final Object o) { if (o == this) return true; @@ -175,6 +180,15 @@ public int hashCode() { @Override public String toString() { - return getValue() != null ? getValue().entrySet().stream().map(entry -> entry.getKey().toString() + "=" + entry.getValue().toString()).collect(Collectors.joining(", ")) : null; + if (getValue() == null) { + return null; + } else { + return getValue() + .entrySet() + .stream() + .map(entry -> + entry.getKey().toString() + "=" + entry.getValue().toString()).collect(Collectors.joining(", ") + ); + } } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeList.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeList.java index a87222e5b..dbbea1761 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeList.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeList.java @@ -76,15 +76,8 @@ public void serializeChildTypes(final SerializerBuffer ser) throws NoSuchTypeExc } @Override - public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { - final int childTypeTag = deser.readU8(); - final CLTypeData childType = CLTypeData.getTypeBySerializationTag((byte) childTypeTag); - final AbstractCLType clChildType = CLTypeData.createCLTypeFromCLTypeName(childType.getClTypeName()); - - if (clChildType instanceof AbstractCLTypeWithChildren) { - ((AbstractCLTypeWithChildren) clChildType).deserializeChildTypes(deser); - } - - setListType(clChildType); + public void deserializeChildTypes(final DeserializerBuffer deser) + throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { + setListType(deserializeChildType(deser)); } } diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java index 093d2ff8f..bcf76fa06 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple2.java @@ -41,7 +41,7 @@ protected List getChildTypeObjects() { } @Override - public void serializeChildTypes(SerializerBuffer ser) throws NoSuchTypeException { + public void serializeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException { if (getChildTypes().size() >= 2) { getChildTypes().get(0).serialize(ser); @@ -55,6 +55,4 @@ public void deserializeChildTypes(final DeserializerBuffer deser) getChildTypes().add(deserializeChildType(deser)); getChildTypes().add(deserializeChildType(deser)); } - - } From 6e588c043bed6bb86f2681faf617c952e96c5544 Mon Sep 17 00:00:00 2001 From: meywood <105049338+meywood@users.noreply.github.com> Date: Tue, 12 Mar 2024 20:34:36 +0000 Subject: [PATCH 7/7] issues/253 - Fix for CLTypeTuple3 deserializeChildTypes --- .../java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java index 7ba6f64b4..f8177bc69 100644 --- a/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java +++ b/src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeTuple3.java @@ -53,5 +53,6 @@ public void deserializeChildTypes(final DeserializerBuffer deser) throws ValueDeserializationException, NoSuchTypeException, DynamicInstanceException { getChildTypes().add(deserializeChildType(deser)); getChildTypes().add(deserializeChildType(deser)); + getChildTypes().add(deserializeChildType(deser)); } }