Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a7dd669
issues/373 - TransactionV1Payload WiP
meywood Dec 4, 2024
8b131ae
issues/373 - TransactionV1Payload implemented payload with session tr…
meywood Dec 18, 2024
1cb6ee9
issues/373 - TransactionV1Payload implemented payload with native tra…
meywood Dec 18, 2024
925f888
issues/373 - TransactionV1Payload implemented payload with stored tra…
meywood Dec 18, 2024
6b6670f
issues/373 - TransactionV1 implemented json serialization
meywood Dec 20, 2024
771a720
issues/373 - TransactionV1 test data correction for new transferred_v…
meywood Jan 6, 2025
5cba5ac
issues/373 - Fixed commented out lines
meywood Jan 8, 2025
624f6b8
issues/373 - Fix accountPutTransferV1, and tidy up bad formatting of …
meywood Jan 8, 2025
4f8e2cb
issues/373 - Fixed issue with list containing tuple with 'any' value …
meywood Jan 8, 2025
6a0b1a6
issues/373 - Fixed issue with message key JSON deserialization in exe…
meywood Jan 8, 2025
0e7a9d1
issues/373 - Fixed issue with missing message topic kind in execution…
meywood Jan 8, 2025
fce6a73
issues/373 - Fixed issue with missing message topic kind in execution…
meywood Jan 8, 2025
6e89f66
issues/373 - Fixed issue with missing contract wasm kind in execution…
meywood Jan 8, 2025
0e86ad0
issues/373 - Updated contract to user condor style entrt point classes.
meywood Jan 10, 2025
2c01b1f
issues/373 - Refactored Groups to match condor changes
meywood Jan 10, 2025
9425a26
issues/373 - Refactored Groups to match condor changes
meywood Jan 10, 2025
4b7cc5f
issues/373 - Updated tests to match code changes for execution effects
meywood Jan 10, 2025
c190d9f
issues/373 - Added method to obtain contract entry point by name
meywood Jan 10, 2025
c381d74
Merge remote-tracking branch 'origin/issues/373' into issues/373
meywood Jan 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions script/docker-run
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env bash
CONTAINER_NAME="cspr-cctl"
#CONTAINER_NAME="cspr-nctl-condor"
IMAGE_VERSION="feat-2.0"
IMAGE_VERSION="condor"
# run the cspr-nctl container in docker
#docker run --rm -it --name ${CONTAINER_NAME} -d -p 25101:25101 -p 11101:11101 -p 14101:14101 -p 18101:18101 casper-nctl:${IMAGE_VERSION}
docker run --rm -it --name ${CONTAINER_NAME} -d -p 25101:25101 -p 11101:11101 -p 14101:14101 -p 18101:18101 -p 21101:21101 stormeye2000/cspr-cctl:${IMAGE_VERSION}
docker run --rm -it --name ${CONTAINER_NAME} -d -p 25101:25101 -p 11101:11101 -p 14101:14101 -p 18101:18101 -p 21101:21101 stormeye2000/${CONTAINER_NAME}:${IMAGE_VERSION}
113 changes: 82 additions & 31 deletions src/main/java/com/casper/sdk/helper/TransactionHelper.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
package com.casper.sdk.helper;

import com.casper.sdk.model.clvalue.*;
import com.casper.sdk.model.common.Digest;
import com.casper.sdk.model.common.Ttl;
import com.casper.sdk.model.deploy.NamedArg;
import com.casper.sdk.model.key.PublicKey;
import com.casper.sdk.model.transaction.*;
import com.casper.sdk.model.transaction.entrypoint.TransactionEntryPoint;
import com.casper.sdk.model.transaction.entrypoint.TransferEntryPoint;
import com.casper.sdk.model.transaction.field.Fields;
import com.casper.sdk.model.transaction.pricing.FixedPricingMode;
import com.casper.sdk.model.transaction.pricing.PricingMode;
import com.casper.sdk.model.transaction.scheduling.Standard;
import com.casper.sdk.model.transaction.scheduling.TransactionScheduling;
import com.casper.sdk.model.transaction.target.TransactionTarget;
import com.casper.sdk.model.uref.URef;
import dev.oak3.sbs4j.exception.ValueSerializationException;

import java.util.Date;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
* Utility class to help with the building of transactions.
Expand All @@ -18,44 +29,84 @@
*/
public class TransactionHelper {

public static TransactionV1 buildTransaction(final InitiatorAddr<?> initiatorAddr,
final Ttl ttl,
final String chainName,
final PricingMode pricingMode,
final TransactionV1Body body) {
@SuppressWarnings({"unchecked", "rawtypes", "OptionalOfNullableMisuse"})
public static <TransferTarget> TransactionV1 newTransfer(final String chainName,
final BigInteger amount,
final URef maybeSource,
final TransferTarget target,
final Long maybeId) throws ValueSerializationException {
final List<NamedArg<?>> namedArgs = new ArrayList<>();
namedArgs.add(NamedArg.builder().type("amount").clValue((AbstractCLValue) new CLValueU512(amount)).build());
namedArgs.add(NamedArg.builder()
.type("source")
.clValue((AbstractCLValue) new CLValueOption(Optional.ofNullable(new CLValueURef(maybeSource))))
.build()
);

final AbstractCLValue clTarget;

if (target instanceof URef) {
clTarget = new CLValueURef((URef) target);
} else if (target instanceof PublicKey) {
clTarget = new CLValuePublicKey((PublicKey) target);
} else if (target instanceof Digest) {
clTarget = new CLValueByteArray(((Digest) target).getDigest());
} else {
throw new IllegalArgumentException("Invalid target type " + target);
}

namedArgs.add(NamedArg.builder().type("target").clValue(clTarget).build());

if (maybeId != null) {

namedArgs.add(new NamedArg<>("id", new CLValueOption(
Optional.ofNullable(maybeId != null ? new CLValueU64(BigInteger.valueOf(System.currentTimeMillis())) : null)
)));
}

return TransactionV1.builder()
.header(buildTransactionHeader(initiatorAddr, new Date(), ttl, chainName, pricingMode))
.body(body)
.payload(TransactionV1Payload.builder()
.chainName(chainName)
.fields(Fields.builder()
.args(new NamedArgs(namedArgs))
.scheduling(new Standard())
.target((TransactionTarget) target)
.entryPoint(new TransferEntryPoint())
.build()
)
.pricingMode(new FixedPricingMode(0, 1))
.build()
)
.build();
}

private static TransactionV1Body buildTransactionBody(final List<NamedArg<?>> args,
final TransactionTarget target,
final TransactionEntryPoint entryPoint,
final TransactionCategory category,
final TransactionScheduling scheduling) {
return TransactionV1Body.builder()
.args(args)
.target(target)
.entryPoint(entryPoint)
.transactionCategory(category)
.scheduling(scheduling)
public static TransactionV1 buildTransaction(final InitiatorAddr<?> initiatorAddr,
final Ttl ttl,
final String chainName,
final PricingMode pricingMode) {

return TransactionV1.builder()
.payload(TransactionV1Payload.builder()
.initiatorAddr(initiatorAddr)
.ttl(ttl)
.chainName(chainName)
.pricingMode(pricingMode)
.build())
.build();
}

private static TransactionV1Header buildTransactionHeader(@SuppressWarnings("rawtypes") final InitiatorAddr initiatorAddr,
final Date timestamp,
final Ttl ttl,
final String chainName,
final PricingMode pricingMode) {
return TransactionV1Header.builder()
.initiatorAddr(initiatorAddr)
.timestamp(timestamp)
.ttl(ttl)
.chainName(chainName)
.pricingMode(pricingMode)
private static TransactionV1Payload buildTransactionPayload(final List<NamedArg<?>> args,
final TransactionTarget target,
final TransactionEntryPoint entryPoint,
final TransactionCategory category,
final TransactionScheduling scheduling) {
return TransactionV1Payload.builder()
.fields(Fields.builder()
.args(new NamedArgs(args))
.entryPoint(entryPoint)
.scheduling(scheduling)
.target(target)
.build())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.casper.sdk.jackson.deserializer;

import com.casper.sdk.model.clvalue.cltype.AbstractCLType;
import com.casper.sdk.model.contract.EntryPointArg;
import com.casper.sdk.model.contract.EntryPointType;
import com.casper.sdk.model.contract.EntryPointV1;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;

import java.io.IOException;
import java.util.List;

/**
* Custom deserializer for {@link EntryPointV1} objects
*
* @author ian@meywood.com
*/
public class EntryPointV1Deserializer extends JsonDeserializer<EntryPointV1> {
@Override
public EntryPointV1 deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException {

final JsonNode mapNode = p.getCodec().readTree(p);
final JsonNode entryPointNode = mapNode.get("entry_point");

return EntryPointV1.builder()
.name(mapNode.get("name").asText())
.access(entryPointNode.get("access").asText())
.ret(getNestedObject(entryPointNode, ctxt, "ret", AbstractCLType.class))
.entryPointType(getNestedObject(entryPointNode, ctxt, "entry_point_type", EntryPointType.class))
.args(getNestedObject(entryPointNode, ctxt, "args", new TypeReference<List<EntryPointArg>>() {
}))
.build();
}


private <T> T getNestedObject(final JsonNode node,
final DeserializationContext ctx,
final String name,
final Class<T> type) throws IOException {
try (final JsonParser parser = node.get(name).traverse()) {
parser.setCodec(ctx.getParser().getCodec());
return parser.readValueAs(type);
}
}

private <T> T getNestedObject(final JsonNode node,
final DeserializationContext ctx,
final String name,
final TypeReference<T> type) throws IOException {
try (final JsonParser parser = node.get(name).traverse()) {
parser.setCodec(ctx.getParser().getCodec());
return parser.readValueAs(type);
}
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.casper.sdk.exception.DeserializationException;
import com.casper.sdk.exception.NoSuchTypeException;
import com.casper.sdk.model.common.Digest;
import com.casper.sdk.model.transaction.target.*;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
Expand Down Expand Up @@ -47,7 +48,9 @@ private Stored createStored(final JsonNode node, final DeserializationContext ct
try {
return new Stored(
createInvocationTarget(node, ctx),
TransactionRuntime.fromJson(node.get(RUNTIME).asText()));
TransactionRuntime.fromJson(node.get(RUNTIME).asText()),
node.has(TRANSFERRED_VALUE) ? node.get(TRANSFERRED_VALUE).asLong() : 0
);
} catch (NoSuchTypeException e) {
throw new DeserializationException("Unable to find 'runtime'", e);
}
Expand All @@ -62,9 +65,14 @@ private TransactionInvocationTarget createInvocationTarget(final JsonNode node,

private Session createSession(final JsonNode node) throws DeserializationException {
try {

// FIXME use annotation processor for JSON serialization
return new Session(
node.has(IS_INSTALL_UPGRADE) && node.get(IS_INSTALL_UPGRADE).asBoolean(),
TransactionRuntime.fromJson(node.get(RUNTIME).asText()),
Hex.decode(node.get(MODULE_BYTES).asText()),
TransactionRuntime.fromJson(node.get(RUNTIME).asText())
node.has(TRANSFERRED_VALUE) ? node.get(TRANSFERRED_VALUE).asLong() : 0,
node.has(SEED) && !node.get(SEED).isNull() && !"null".equals(node.get(SEED).asText()) ? new Digest(node.get(SEED).asText()) : null
);
} catch (NoSuchTypeException e) {
throw new DeserializationException("Unable to find required fields", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
public class TransactionTargetSerializer extends JsonSerializer<TransactionTarget> {



@Override
public void serialize(final TransactionTarget value, final JsonGenerator gen, final SerializerProvider serializers) throws IOException {

Expand All @@ -41,6 +43,7 @@ private static void serializeStored(final Stored value, final JsonGenerator gen)
gen.writeFieldName(RUNTIME);
gen.writeString(value.getRuntime().getJsonName());
}
gen.writeNumberField(TRANSFERRED_VALUE, value.getTransferredValue());
gen.writeEndObject();
gen.writeEndObject();
}
Expand All @@ -49,9 +52,13 @@ private static void serializeSession(final Session value, final JsonGenerator ge
gen.writeStartObject();
gen.writeFieldName(SESSION);
gen.writeStartObject();
gen.writeStringField(MODULE_BYTES, Hex.encode(value.getModuleBytes()));
gen.writeBooleanField(IS_INSTALL_UPGRADE, value.isInstallUpgrade());
gen.writeStringField(RUNTIME, TransactionRuntime.toJson(value.getRuntime()));
gen.writeStringField(MODULE_BYTES, Hex.encode(value.getModuleBytes()));
gen.writeNumberField(TRANSFERRED_VALUE, value.getTransferredValue());
gen.writeObjectField(SEED, value.getSeed());
gen.writeEndObject();

gen.writeEndObject();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,14 @@ public CLTypeData getChildClTypeData(final int index) throws NoSuchTypeException

@Override
public boolean isDeserializable() {
return getChildTypes().stream().allMatch(AbstractCLType::isDeserializable);
for (AbstractCLType childType : getChildTypes()) {
if (childType instanceof CLTypeAny) {
return false;
} else if (!childType.isDeserializable()) {
return false;
}
}
return true;
}

protected void loadCLTypes(final List<Object> childTypeObjects)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ protected List<Object> getChildTypeObjects() {
return super.getChildTypeObjects();
}


@Override
public void serializeChildTypes(final SerializerBuffer ser) throws NoSuchTypeException {

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/casper/sdk/model/contract/Contract.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class Contract {

/** entry_points(Array) - A list of entry points. */
@JsonProperty("entry_points")
private List<EntryPoint> entryPoints;
private List<EntryPointV1> entryPoints;

/** named_keys(Array) - A list of named keys. */
@JsonProperty("named_keys")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ public class ContractWasm {
/**
* ContractWasm(object/string) A contract's Wasm.
*/
@JsonProperty("ContractWasm")
@JsonProperty("bytes")
private String wasm;
}
21 changes: 21 additions & 0 deletions src/main/java/com/casper/sdk/model/contract/EntryPointArg.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.casper.sdk.model.contract;

import com.casper.sdk.model.clvalue.cltype.AbstractCLType;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

/**
* A named argument for an entry point.
*
* @author ian@meywood.com
*/
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
public class EntryPointArg {
private String name;
@JsonProperty("cl_type")
private AbstractCLType clType;
}
18 changes: 18 additions & 0 deletions src/main/java/com/casper/sdk/model/contract/EntryPointType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.casper.sdk.model.contract;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Context of method execution
*
* @author ian@meywood.com
*/
public enum EntryPointType {

@JsonProperty("Caller")
CALLER,
@JsonProperty("Called")
CALLED,
@JsonProperty("Factory")
FACTORY
}
33 changes: 33 additions & 0 deletions src/main/java/com/casper/sdk/model/contract/EntryPointV1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.casper.sdk.model.contract;

import com.casper.sdk.jackson.deserializer.EntryPointV1Deserializer;
import com.casper.sdk.model.clvalue.cltype.AbstractCLType;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.*;

import java.util.List;

/**
* Type signature of a method. Order of arguments matter since can be referenced by index as well as name.
*
* @author ian@meywood.com
*/
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
@JsonTypeName("entry_point")
@JsonDeserialize(using = EntryPointV1Deserializer.class)
public class EntryPointV1 {

private String name;
private String access;
private AbstractCLType ret;
@JsonProperty("entry_point_type")
private EntryPointType entryPointType;
@JsonProperty("args")
private List<EntryPointArg> args;
}
Loading