Skip to content

Commit

Permalink
Merge pull request #242 from /issues/200
Browse files Browse the repository at this point in the history
Issues/200 - Issues with nested Any in events
  • Loading branch information
cnorburn authored Feb 14, 2024
2 parents bf55cfa + dfed063 commit c6f2ad5
Show file tree
Hide file tree
Showing 13 changed files with 213 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ out/
.vscode/*
!.vscode/tasks.json
!.vscode/launch.json
/assets/
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ apply plugin: 'java'

group = 'network.casper'
// Version number update for release
version='2.4.1'
version='2.5.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ public abstract class AbstractCLValueWithChildren<T, P extends AbstractCLTypeWit
*/
@SneakyThrows({ValueDeserializationException.class})
protected void childTypesSet() {
if (getBytes().length() > 0) {
if (!getBytes().isEmpty()) {
DeserializerBuffer deser = new DeserializerBuffer(this.getBytes());

this.deserialize(deser);
}
}
Expand All @@ -47,9 +46,8 @@ protected void childTypesSet() {
protected void setJsonBytes(String bytes) {
this.setBytes(bytes);

if (!getClType().getChildTypes().isEmpty()) {
if (!getClType().getChildTypes().isEmpty() && getClType().isDeserializable()) {
DeserializerBuffer deser = new DeserializerBuffer(this.getBytes());

this.deserialize(deser);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,15 @@ public abstract class AbstractCLType {
public CLTypeData getClTypeData() throws NoSuchTypeException {
return CLTypeData.getTypeByName(getTypeName());
}

/**
* Indicates if the CLType does not contains and '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.
*
* @return true if can be serialized, i.e: a child, or child's child does not contain a deserializable value such
* as an 'Any' type.
*/
@JsonIgnore
public abstract boolean isDeserializable();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ protected AbstractCLTypeBasic(String typeName) {
String.format("%s is an invalid type for %s", getClass().getSimpleName(), typeName));
}
}

@Override
public boolean isDeserializable() {
// Basic type can always be serialized
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public CLTypeData getChildClTypeData(int index) throws NoSuchTypeException {
return CLTypeData.getTypeByName(getChildTypes().get(index).getTypeName());
}

@Override
public boolean isDeserializable() {
return getChildTypes().stream().allMatch(AbstractCLType::isDeserializable);
}

protected void loadCLTypes(List<Object> childTypeObjects)
throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException, NoSuchTypeException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ public class CLTypeByteArray extends AbstractCLType {
@Setter
@JsonProperty(AbstractCLType.BYTE_ARRAY)
private int length;

@Override
public boolean isDeserializable() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ protected void setJsonValue(AbstractCLType clType) {

@JsonIgnore
public AbstractCLType getListType() {
if (getChildTypes().size() > 0) {
if (!getChildTypes().isEmpty()) {
return getChildTypes().get(0);
}

Expand All @@ -50,4 +50,16 @@ public void setListType(AbstractCLType listType) {
getChildTypes().clear();
getChildTypes().add(listType);
}

@Override
public boolean isDeserializable() {

return getChildTypes().stream().allMatch(childType -> {
if (childType instanceof CLTypeAny) {
return false;
} else {
return childType.isDeserializable();
}
});
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/casper/sdk/model/clvalue/cltype/CLTypeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@ public void setKeyValueTypes(CLTypeMapEntryType keyValueTypes) {

private CLTypeMapEntryType keyValueTypes;

@Override
public boolean isDeserializable() {

if (getKeyValueTypes().keyType instanceof CLTypeAny || getKeyValueTypes().valueType instanceof CLTypeAny) {
// The map contains an 'Any' type therefore cannot be deserialized
return false;
} else if (getKeyValueTypes().valueType instanceof AbstractCLTypeWithChildren) {
return getChildTypes().stream().allMatch(childType -> {
if (childType instanceof CLTypeAny) {
return false;
} else {
return childType.isDeserializable();
}
});
} else {
return getKeyValueTypes().keyType.isDeserializable() || getKeyValueTypes().valueType.isDeserializable();
}
}

/**
* Support class for {@link AbstractCLType#MAP} entry types
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected void setJsonClType(AbstractCLType clType) {

@JsonIgnore
public AbstractCLType getOptionType() {
if (getChildTypes().size() > 0) {
if (!getChildTypes().isEmpty()) {
return getChildTypes().get(0);
}

Expand All @@ -52,4 +52,9 @@ public void setOptionType(AbstractCLType listType) {
getChildTypes().clear();
getChildTypes().add(listType);
}

@Override
public boolean isDeserializable() {
return getOptionType().isDeserializable();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
@EqualsAndHashCode(callSuper = false, of = {"typeName", "okErrTypes"})
public class CLTypeResult extends AbstractCLType {

private final String typeName = RESULT;

@Setter
@JsonProperty(RESULT)
private CLTypeResultOkErrTypes okErrTypes;

/**
* Support class for {@link AbstractCLType#RESULT} ok/err types
*
Expand Down Expand Up @@ -71,9 +77,8 @@ protected Object getJsonValue() {
}
}

private final String typeName = RESULT;

@Setter
@JsonProperty(RESULT)
private CLTypeResultOkErrTypes okErrTypes;
@Override
public boolean isDeserializable() {
return true;
}
}
129 changes: 129 additions & 0 deletions src/test/java/com/casper/sdk/model/clvalue/NestedAnyTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package com.casper.sdk.model.clvalue;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;

/**
* Test that a AbstractCLValueWithChildren provides a byte array string for undeserializable types (e.g. Any)
*
* @author ian@meywood.com
*/
public class NestedAnyTest {

@Test
void readStepEventWithMapContainingAnyValue() throws Exception {

// This is a hex string that represents a map with a key of PublicKey and a value of Any
final String hexBytes = "04000000010000000000000005000000010d23984fefcce099679a24496f1d3072a540b95d321f8ba951" +
"df0cfe2c0691e5070280c6a47e8d030201000000013372bd275423a2191f3fc11e1bee0419fcb4890319873f455bb462e02b" +
"199457070280c6a47e8d03011213e00a3bd748278b38a00a4787a7143f28a9d564126566716a53daa9499852070380c6a47e" +
"8d03030100000001e45436d1609bd5c5ce13e8320a140421cf40a21089df1a08f7c58bcd06b6c9e4070380c6a47e8d030180" +
"b99ded1d271c61a26d1b18c289ab33fc64355fa90cda4ae18f91786aa6ba4b070580c6a47e8d030501000000018973a4ffc1" +
"7abab43f90bd229ef8a310236dd364ba0416d31612091d8cc17933070580c6a47e8d0301959d01aa68197e8cb91aa06bcc92" +
"0f8d4a245dff60ea726bb89255349107a565070180c6a47e8d03010100000001a1cce6ea8db0d11d95b83671cc69f726b36a" +
"afb46dbf808c608dbcd5d237b11c070180c6a47e8d0301fcf1392c59c7d89190bfcd1b00902cc0801700eab98034aa4e5681" +
"6d338f6c25070480c6a47e8d030401000000016997c57f973cd02df90941b7ace79d2b49e173f5f14a343cbf69a7a7ff8be3" +
"b5070480c6a47e8d03020000000000000005000000010d23984fefcce099679a24496f1d3072a540b95d321f8ba951df0cfe" +
"2c0691e5070280c6a47e8d030201000000013372bd275423a2191f3fc11e1bee0419fcb4890319873f455bb462e02b199457" +
"070280c6a47e8d03011213e00a3bd748278b38a00a4787a7143f28a9d564126566716a53daa9499852070380c6a47e8d0303" +
"0100000001e45436d1609bd5c5ce13e8320a140421cf40a21089df1a08f7c58bcd06b6c9e4070380c6a47e8d030180b99ded" +
"1d271c61a26d1b18c289ab33fc64355fa90cda4ae18f91786aa6ba4b070580c6a47e8d030501000000018973a4ffc17abab4" +
"3f90bd229ef8a310236dd364ba0416d31612091d8cc17933070580c6a47e8d0301959d01aa68197e8cb91aa06bcc920f8d4a" +
"245dff60ea726bb89255349107a565070180c6a47e8d03010100000001a1cce6ea8db0d11d95b83671cc69f726b36aafb46d" +
"bf808c608dbcd5d237b11c070180c6a47e8d0301fcf1392c59c7d89190bfcd1b00902cc0801700eab98034aa4e56816d338f" +
"6c25070480c6a47e8d030401000000016997c57f973cd02df90941b7ace79d2b49e173f5f14a343cbf69a7a7ff8be3b50704" +
"80c6a47e8d03030000000000000005000000010d23984fefcce099679a24496f1d3072a540b95d321f8ba951df0cfe2c0691" +
"e5070280c6a47e8d030201000000013372bd275423a2191f3fc11e1bee0419fcb4890319873f455bb462e02b199457070280" +
"c6a47e8d03011213e00a3bd748278b38a00a4787a7143f28a9d564126566716a53daa9499852070380c6a47e8d0303010000" +
"0001e45436d1609bd5c5ce13e8320a140421cf40a21089df1a08f7c58bcd06b6c9e4070380c6a47e8d030180b99ded1d271c" +
"61a26d1b18c289ab33fc64355fa90cda4ae18f91786aa6ba4b070580c6a47e8d030501000000018973a4ffc17abab43f90bd" +
"229ef8a310236dd364ba0416d31612091d8cc17933070580c6a47e8d0301959d01aa68197e8cb91aa06bcc920f8d4a245dff" +
"60ea726bb89255349107a565070180c6a47e8d03010100000001a1cce6ea8db0d11d95b83671cc69f726b36aafb46dbf808c" +
"608dbcd5d237b11c070180c6a47e8d0301fcf1392c59c7d89190bfcd1b00902cc0801700eab98034aa4e56816d338f6c2507" +
"0480c6a47e8d030401000000016997c57f973cd02df90941b7ace79d2b49e173f5f14a343cbf69a7a7ff8be3b5070480c6a4" +
"7e8d03040000000000000005000000010d23984fefcce099679a24496f1d3072a540b95d321f8ba951df0cfe2c0691e50702" +
"80c6a47e8d030201000000013372bd275423a2191f3fc11e1bee0419fcb4890319873f455bb462e02b199457070280c6a47e" +
"8d03011213e00a3bd748278b38a00a4787a7143f28a9d564126566716a53daa9499852070380c6a47e8d03030100000001e4" +
"5436d1609bd5c5ce13e8320a140421cf40a21089df1a08f7c58bcd06b6c9e4070380c6a47e8d030180b99ded1d271c61a26d" +
"1b18c289ab33fc64355fa90cda4ae18f91786aa6ba4b070580c6a47e8d030501000000018973a4ffc17abab43f90bd229ef8" +
"a310236dd364ba0416d31612091d8cc17933070580c6a47e8d0301959d01aa68197e8cb91aa06bcc920f8d4a245dff60ea72" +
"6bb89255349107a565070180c6a47e8d03010100000001a1cce6ea8db0d11d95b83671cc69f726b36aafb46dbf808c608dbc" +
"d5d237b11c070180c6a47e8d0301fcf1392c59c7d89190bfcd1b00902cc0801700eab98034aa4e56816d338f6c25070480c6" +
"a47e8d030401000000016997c57f973cd02df90941b7ace79d2b49e173f5f14a343cbf69a7a7ff8be3b5070480c6a47e8d03";

final String json = " {\n" +
" \"cl_type\": {\n" +
" \"Map\": {\n" +
" \"key\": \"PublicKey\",\n" +
" \"value\": \"Any\"\n" +
" }\n" +
" },\n" +
" \"bytes\": \"" + hexBytes + "\",\n" +
" \"parsed\": null\n" +
"}";

final CLValueMap clValueMap = (CLValueMap) new ObjectMapper().readValue(json, AbstractCLValue.class);

assertThat(clValueMap, is(notNullValue()));
assertThat(clValueMap.getClType().isDeserializable(), is(false));
assertThat(clValueMap.getBytes(), is(hexBytes));
}

@Test
public void nestedEmptyMapiWithoutAny() throws Exception {

final String json = " {\n" +
" \"cl_type\": {\n" +
" \"Map\": {\n" +
" \"key\": \"PublicKey\",\n" +
" \"value\": \"U256\"\n" +
" }\n" +
" },\n" +
" \"bytes\": \"00000000\",\n" +
" \"parsed\": null\n" +
"}";

final CLValueMap clValueMap = (CLValueMap) new ObjectMapper().readValue(json, AbstractCLValue.class);
assertThat(clValueMap, is(notNullValue()));
assertThat(clValueMap.getClType().isDeserializable(), is(true));
assertThat(clValueMap.getBytes(), is("00000000"));
}

@Test
void nestedListWithAny() throws Exception {

final String json = " {\n" +
" \"cl_type\": {\n" +
" \"List\": \"Any\"\n" +
" },\n" +
" \"bytes\": \"00000000\",\n" +
" \"parsed\": null\n" +
"}";

final CLValueList clValueList = (CLValueList) new ObjectMapper().readValue(json, AbstractCLValue.class);
assertThat(clValueList, is(notNullValue()));
assertThat(clValueList.getClType().isDeserializable(), is(false));
assertThat(clValueList.getBytes(), is("00000000"));
}

@Test
void nestedListWithoutAny() throws Exception {

final String json = " {\n" +
" \"cl_type\": {\n" +
" \"List\": \"U256\"\n" +
" },\n" +
" \"bytes\": \"00000000\",\n" +
" \"parsed\": null\n" +
"}";

final CLValueList clValueList = (CLValueList) new ObjectMapper().readValue(json, AbstractCLValue.class);
assertThat(clValueList, is(notNullValue()));
assertThat(clValueList.getClType().isDeserializable(), is(true));
assertThat(clValueList.getBytes(), is("00000000"));
}
}
5 changes: 5 additions & 0 deletions src/test/resources/event-samples/step-with-any-event.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
data:{"Step":{"era_id":0,"execution_effect":{"operations":[],"transforms":[{"key":"uref-cadd90e11751095414f0f48b7e428d4fc735c3a62f5a2dcd100db0314a7b5059-000","transform":{"WriteCLValue":{"cl_type":{"Map":{"key":"PublicKey","value":"Any"}}},"bytes":"010d23984fefcce099679a24496f1d3072a540b95d321f8ba951df0cfe2c0691e0070180c6a47e8d0301fcf1392c59c7d89190bfcd1b00902cc0801700eab98034aa4e56816d338f6c25070480c6a47e8d030401000000016997c57f973cd02df90941b7ace79d2b49e173f5f14a343cbf69a7a7ff8be3b5070480c6a47e8d0301483aba14ddd179941f24251dcb13e2fd017aeb58a5b184e215363482a107878c080180c6a47e8d0301fcf1392c59c7d89190bfcd1b00902cc0801700eab98034aa4e56816d338f6c25070480c6a47e8d030401000000016997c57f973cd02df90941b7ace79d2b49e173f5f14a343cbf69a7a7ff8be3b5070480c6a47e8d03"}}]}}}
id:0


{"era_id":0,"execution_effect":{"operations":[],"transforms":[{"key":"uref-cadd90e11751095414f0f48b7e428d4fc735c3a62f5a2dcd100db0314a7b5059-000","transform":"cl_type":{"Map":{"key":"PublicKey","value":"Any"}}},"bytes":"010d23984fefcce099679a24496f1d3072a540b95d321f8ba951df0cfe2c0691e0070180c6a47e8d0301fcf1392c59c7d89190bfcd1b00902cc0801700eab98034aa4e56816d338f6c25070480c6a47e8d030401000000016997c57f973cd02df90941b7ace79d2b49e173f5f14a343cbf69a7a7ff8be3b5070480c6a47e8d0301483aba14ddd179941f24251dcb13e2fd017aeb58a5b184e215363482a107878c080180c6a47e8d0301fcf1392c59c7d89190bfcd1b00902cc0801700eab98034aa4e56816d338f6c25070480c6a47e8d030401000000016997c57f973cd02df90941b7ace79d2b49e173f5f14a343cbf69a7a7ff8be3b5070480c6a47e8d03"}}]}

0 comments on commit c6f2ad5

Please sign in to comment.