Skip to content

Commit

Permalink
Merge pull request #107 from /issues/99
Browse files Browse the repository at this point in the history
Issues/99 CLMap byte serialization fix
  • Loading branch information
cnorburn authored Jun 22, 2022
2 parents 4ab9580 + 3e242e1 commit 7077094
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 18 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>network.casper</groupId>
<artifactId>casper-java-sdk</artifactId>
<version>0.3.5</version>
<version>0.3.6</version>
<name>Casper Java SDK</name>
<description>Casper Java SDK</description>
<url>https://casperlabs.io/</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ public static CLMap map(final Map<CLValue, CLValue> map) {
throw new ValueNotFoundException("Maps must contain at least one key pair");
}

return new CLMap(TYPES_FACTORY.getInstance(CLType.MAP).serialize(map),
final byte[] bytes = TYPES_FACTORY.getInstance(CLType.MAP).serialize(map);

return new CLMap(
bytes,
new CLMapTypeInfo(
map.keySet().iterator().next().getCLTypeInfo(),
map.values().iterator().next().getCLTypeInfo()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,38 @@ public MapSerializer(final TypesFactory typesFactory) {
public byte[] serialize(final Object toSerialize) {

if (toSerialize instanceof CLMap) {
if (((CLMap) toSerialize).isModified() || ((CLMap) toSerialize).getBytes() == null) {

// The map is mutable to the bytes need to be reserialized if modified or not yet created
if (isModifiedOrNotYetSerialized((CLMap) toSerialize)) {
((CLMap) toSerialize).setModified(false);
return ByteUtils.concat(
typesFactory.getInstance(CLType.U32).serialize(((CLMap) toSerialize).size()),
buildMapBytes((CLMap)toSerialize)
);
//noinspection unchecked
return serializeMap((Map<CLValue, CLValue>) toSerialize);

} else {
// The map has not been modified so write as is
// The map is not new and has not been modified so write as is
return ((CLMap) toSerialize).getBytes();
}
} else if (toSerialize instanceof Map) {
//noinspection unchecked
return serializeMap((Map<CLValue, CLValue>) toSerialize);
} else {
return new byte[0];
}
}

private byte[] buildMapBytes(final CLMap clMap) {
private boolean isModifiedOrNotYetSerialized(final CLMap toSerialize) {
return toSerialize.isModified() || toSerialize.getBytes() == null;
}

private byte[] serializeMap(final Map<CLValue, CLValue> toSerialize) {
return ByteUtils.concat(
typesFactory.getInstance(CLType.U32).serialize(toSerialize.size()),
buildKeyValueBytes(toSerialize)
);
}

private byte[] buildKeyValueBytes(final Map<CLValue, CLValue> clMap) {

final ByteArrayBuilder builder = new ByteArrayBuilder();

for (Map.Entry<CLValue, CLValue> entry : clMap.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
import com.casper.sdk.service.serialization.cltypes.TypesFactory;
import com.casper.sdk.service.serialization.cltypes.TypesSerializer;
import com.casper.sdk.service.serialization.util.ByteArrayBuilder;
import com.casper.sdk.types.CLByteArrayInfo;
import com.casper.sdk.types.CLOptionTypeInfo;
import com.casper.sdk.types.CLType;
import com.casper.sdk.types.CLTypeInfo;
import com.casper.sdk.types.*;

abstract class AbstractByteSerializer<T> implements ByteSerializer<T> {

Expand Down Expand Up @@ -40,11 +37,22 @@ byte[] toBytesForCLTypeInfo(final CLTypeInfo typeInfo) {
case OPTION:
return getOptionType(typeInfo);

case MAP:
return getMapType((CLMapTypeInfo) typeInfo);

default:
throw new IllegalArgumentException("Wrong type " + typeInfo.getType());
}
}

private byte[] getMapType(final CLMapTypeInfo typeInfo) {
return new ByteArrayBuilder()
.append(getTypeBytes(typeInfo))
.append(getTypeBytes(typeInfo.getKeyType()))
.append(getTypeBytes(typeInfo.getValueType()))
.toByteArray();
}

public TypesSerializer getU32Serializer() {
return u32Serializer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

import com.casper.sdk.service.serialization.cltypes.CLValueBuilder;
import com.casper.sdk.service.serialization.cltypes.TypesFactory;
import com.casper.sdk.service.serialization.util.CollectionUtils;
import com.casper.sdk.types.*;
import org.junit.jupiter.api.Test;

import java.util.LinkedHashMap;
import java.util.Map;

import static com.casper.sdk.service.serialization.util.ByteUtils.concat;
import static com.casper.sdk.service.serialization.util.ByteUtils.decodeHex;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -40,7 +38,6 @@ void u64toBytes() {
@Test
void u512ValueToBytes() {


final CLValue source = new CLValue(
decodeHex("0500e40b5402"),
CLType.U512,
Expand Down Expand Up @@ -95,7 +92,6 @@ void byteOptionArrayKeyValue() {
assertThat(byteSerializer.toBytes(optionValue), is(expected));
}


@Test
void keyValueToBytes() {

Expand All @@ -118,4 +114,23 @@ void keyValueToBytes() {

assertThat(byteSerializer.toBytes(clKeyValue), is(expected));
}


@Test
void clMapTypeBytesTest() {

final CLValue key = CLValueBuilder.string("ABC");
final CLValue value = CLValueBuilder.i32(10);
final byte[] expectedBytes = {1, 0, 0, 0, 3, 0, 0, 0, 65, 66, 67, 10, 0, 0, 0};

// Assert the value builder can generate the bytes
final CLMap clMap = CLValueBuilder.map(CollectionUtils.Map.of(key, value));
assertThat(clMap.getBytes(), is(expectedBytes));

final byte[] expectedWithTypeBytes = {15, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 65, 66, 67, 10, 0, 0, 0, 17, 10, 1};

// Obtain the value with its type info
final byte[] bytes = byteSerializer.toBytes(clMap);
assertThat(bytes, is(expectedWithTypeBytes));
}
}

0 comments on commit 7077094

Please sign in to comment.