Skip to content

Commit

Permalink
Merge pull request #252 from /issues/251
Browse files Browse the repository at this point in the history
Issues/251 - CLTuple(n) byte serialization fixe
  • Loading branch information
cnorburn authored Mar 8, 2024
2 parents 907f6af + 9ae710e commit e642b36
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ protected void serializePrefixWithLength(final SerializerBuffer ser) throws Valu
public void serialize(final SerializerBuffer ser, final Target target) throws ValueSerializationException, NoSuchTypeException {
if (this.getValue() == null) return;

if (target.equals(Target.BYTE)) {
if (Target.BYTE.equals(target)) {
serializePrefixWithLength(ser);
}

serializeValue(ser);

if (target.equals(Target.BYTE)) {
if (Target.BYTE.equals(target)) {
this.encodeType(ser);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
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;
Expand Down Expand Up @@ -51,4 +54,32 @@ protected void setJsonBytes(String bytes) {
this.deserialize(deser);
}
}

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);
}
}
}
6 changes: 2 additions & 4 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueList.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,8 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat
}

@Override
protected void encodeType(final SerializerBuffer ser) throws NoSuchTypeException {
super.encodeType(ser);

byte val = (getClType().getListType().getClTypeData().getSerializationTag());
protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException {
final byte val = (getClType().getListType().getClTypeData().getSerializationTag());
ser.writeU8(val);
}

Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat
}

@Override
protected void encodeType(final SerializerBuffer ser) throws NoSuchTypeException {
super.encodeType(ser);
protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException {

final byte keyTypeTag = (getClType().getKeyValueTypes().getKeyType().getClTypeData().getSerializationTag());
ser.writeU8(keyTypeTag);
Expand Down
8 changes: 3 additions & 5 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,10 @@ public void deserializeCustom(final DeserializerBuffer deser) throws Exception {
}

@Override
protected void encodeType(final SerializerBuffer ser) throws NoSuchTypeException {
super.encodeType(ser);

Optional<AbstractCLValue<?, ?>> child = getValue();
protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException {
final Optional<AbstractCLValue<?, ?>> child = getValue();
if (child.isPresent()) {
child.get().encodeType(ser);
encodeChildType(ser, child.get(), this.getClType().getOptionType().getClTypeData());
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueTuple1.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,8 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat
}

@Override
protected void encodeType(final SerializerBuffer ser) throws NoSuchTypeException {
super.encodeType(ser);

byte element0TypeTag = getClType().getChildClTypeData(0).getSerializationTag();
ser.writeU8(element0TypeTag);
protected void encodeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException {
encodeChildType(ser, this.getValue().getValue0(), getClType().getChildClTypeData(0));
}

@Override
Expand Down
11 changes: 4 additions & 7 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueTuple2.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,12 @@ protected void serializeValue(final SerializerBuffer ser) throws ValueSerializat
}

@Override
protected void encodeType(final SerializerBuffer ser) throws NoSuchTypeException {
super.encodeType(ser);

final byte element0TypeTag = getClType().getChildClTypeData(0).getSerializationTag();
ser.writeU8(element0TypeTag);
final byte element1TypeTag = getClType().getChildClTypeData(1).getSerializationTag();
ser.writeU8(element1TypeTag);
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);
Expand Down
39 changes: 17 additions & 22 deletions src/main/java/com/casper/sdk/model/clvalue/CLValueTuple3.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,61 +37,56 @@ public class CLValueTuple3 extends
private CLTypeTuple3 clType = new CLTypeTuple3();

@JsonSetter("cl_type")
public void setClType(CLTypeTuple3 clType) {
public void setClType(final CLTypeTuple3 clType) {
this.clType = clType;
childTypesSet();
}

public CLValueTuple3(Triplet<? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>> value) throws ValueSerializationException {
public CLValueTuple3(final Triplet<? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>> value) throws ValueSerializationException {
setChildTypes(value);
this.setValue(value);
}

@Override
protected void serializeValue(SerializerBuffer ser) throws ValueSerializationException {
SerializerBuffer serVal = new SerializerBuffer();
protected void serializeValue(final SerializerBuffer ser) throws ValueSerializationException {
final SerializerBuffer serVal = new SerializerBuffer();
setChildTypes(this.getValue());
getValue().getValue0().serialize(serVal);
getValue().getValue1().serialize(serVal);
getValue().getValue2().serialize(serVal);
byte[] bytes = serVal.toByteArray();
final byte[] bytes = serVal.toByteArray();
ser.writeByteArray(bytes);
this.setBytes(Hex.toHexString(bytes));
}

@Override
protected void encodeType(SerializerBuffer ser) throws NoSuchTypeException {
super.encodeType(ser);

byte element0TypeTag = getClType().getChildClTypeData(0).getSerializationTag();
ser.writeU8(element0TypeTag);
byte element1TypeTag = getClType().getChildClTypeData(1).getSerializationTag();
ser.writeU8(element1TypeTag);
byte element2TypeTag = getClType().getChildClTypeData(2).getSerializationTag();
ser.writeU8(element2TypeTag);
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(DeserializerBuffer deser) throws Exception {
CLTypeData childTypeData1 = clType.getChildClTypeData(0);
CLTypeData childTypeData2 = clType.getChildClTypeData(1);
CLTypeData childTypeData3 = clType.getChildClTypeData(2);
public void deserializeCustom(final DeserializerBuffer deser) throws Exception {
final CLTypeData childTypeData1 = clType.getChildClTypeData(0);
final CLTypeData childTypeData2 = clType.getChildClTypeData(1);
final CLTypeData childTypeData3 = clType.getChildClTypeData(2);

AbstractCLValue<?, ?> child1 = CLTypeData.createCLValueFromCLTypeData(childTypeData1);
final AbstractCLValue<?, ?> child1 = CLTypeData.createCLValueFromCLTypeData(childTypeData1);
if (child1.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child1.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(0)).getChildTypes());
}
child1.deserializeCustom(deser);

AbstractCLValue<?, ?> child2 = CLTypeData.createCLValueFromCLTypeData(childTypeData2);
final AbstractCLValue<?, ?> child2 = CLTypeData.createCLValueFromCLTypeData(childTypeData2);
if (child2.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child2.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(1)).getChildTypes());
}
child2.deserializeCustom(deser);

AbstractCLValue<?, ?> child3 = CLTypeData.createCLValueFromCLTypeData(childTypeData3);
final AbstractCLValue<?, ?> child3 = CLTypeData.createCLValueFromCLTypeData(childTypeData3);
if (child3.getClType() instanceof AbstractCLTypeWithChildren) {
((AbstractCLTypeWithChildren) child3.getClType())
.setChildTypes(((AbstractCLTypeWithChildren) clType.getChildTypes().get(2)).getChildTypes());
Expand All @@ -102,7 +97,7 @@ public void deserializeCustom(DeserializerBuffer deser) throws Exception {
}

@Override
protected void setChildTypes(Triplet<? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>> value) {
protected void setChildTypes(final Triplet<? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>, ? extends AbstractCLValue<?, ?>> value) {
if (value.getValue0() != null && value.getValue1() != null && value.getValue2() != null) {
clType.setChildTypes(Arrays.asList(value.getValue0().getClType(), value.getValue1().getClType(),
value.getValue2().getClType()));
Expand Down
70 changes: 70 additions & 0 deletions src/test/java/com/casper/sdk/model/clvalue/CLValueTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
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.serde.Target;
import com.casper.sdk.model.deploy.NamedArg;
import com.syntifi.crypto.key.encdec.Hex;
import dev.oak3.sbs4j.DeserializerBuffer;
import dev.oak3.sbs4j.SerializerBuffer;
import org.javatuples.Pair;
import org.javatuples.Triplet;
import org.javatuples.Unit;
import org.junit.jupiter.api.Test;

import java.util.HashMap;
Expand Down Expand Up @@ -82,6 +87,30 @@ void clValueAnyByteSerializationWithAndWithoutTypeInfo() throws Exception {
assertThat(ser.toByteArray(), is(Hex.decode("04000000d202964915")));
}


@Test
void clValueTupleOneSerialization() throws Exception {

final CLValueTuple1 clValueTuple1 = new CLValueTuple1(new Unit<>(new CLValueU32(1L)));

SerializerBuffer ser = new SerializerBuffer();
clValueTuple1.serialize(ser, Target.JSON);
assertThat(ser.toByteArray(), is(Hex.decode("01000000")));

ser = new SerializerBuffer();
clValueTuple1.serialize(ser, Target.BYTE);

byte[] expected = {4, 0, 0, 0, 1, 0, 0, 0, 18, 4};
assertThat(ser.toByteArray(), is(expected));

NamedArg<CLTypeTuple1> namedArg = new NamedArg<>("TUPLE_1", clValueTuple1);
ser = new SerializerBuffer();
namedArg.serialize(ser, Target.BYTE);
expected = new byte[]{7, 0, 0, 0, 84, 85, 80, 76, 69, 95, 49, 4, 0, 0, 0, 1, 0, 0, 0, 18, 4};

assertThat(ser.toByteArray(), is(expected));
}

@Test
void getTypeByName_from_CLTypeData_should_throw_NoSuchTypeException() {
assertThrows(NoSuchTypeException.class, () -> CLTypeData.getTypeByName("NE"));
Expand Down Expand Up @@ -127,4 +156,45 @@ void mapDeserialization() throws Exception {
assertThat(valueDeser, is(value));
assertThat(valueDeser.getBytes(), is(value.getBytes()));
}

@Test
void nestedTuple1Serialization() throws Exception {
final CLValueTuple1 innerTuple1 = new CLValueTuple1(new Unit<>(new CLValueU32(1L)));
final CLValueTuple1 outerTuple1 = new CLValueTuple1(new Unit<>(innerTuple1));

final SerializerBuffer ser = new SerializerBuffer();
outerTuple1.serialize(ser, Target.BYTE);

final byte[] expected = {4, 0, 0, 0, 1, 0, 0, 0, 18, 18, 4};

assertThat(ser.toByteArray(), is(expected));
}

@Test
void nestedTuple2Serialization() throws Exception {
final CLValueTuple2 innerTuple1 = new CLValueTuple2(new Pair<>(new CLValueU32(1L), new CLValueU32(2L)));
final CLValueTuple2 innerTuple2 = new CLValueTuple2(new Pair<>(new CLValueU32(3L), new CLValueU32(4L)));
final CLValueTuple2 outerTuple = new CLValueTuple2(new Pair<>(innerTuple1, innerTuple2));

final SerializerBuffer ser = new SerializerBuffer();
outerTuple.serialize(ser, Target.BYTE);

final byte[] expected = {16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 19, 19, 4, 4, 19, 4, 4};

assertThat(ser.toByteArray(), is(expected));
}

@Test
void nestedTuple3Serialization() throws Exception {
final CLValueTuple3 innerTuple1 = new CLValueTuple3(new Triplet<>(new CLValueU32(1L), new CLValueU32(2L), new CLValueU32(3L)));
final CLValueTuple3 innerTuple2 = new CLValueTuple3(new Triplet<>(innerTuple1, new CLValueU32(4L), new CLValueU32(5L)));
final CLValueTuple3 outerTuple = new CLValueTuple3(new Triplet<>(innerTuple2, new CLValueU32(6L), new CLValueU32(7L)));

final SerializerBuffer ser = new SerializerBuffer();
outerTuple.serialize(ser, Target.BYTE);

final byte[] expected = {28, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4};

assertThat(ser.toByteArray(), is(expected));
}
}

0 comments on commit e642b36

Please sign in to comment.