forked from Qortal/qortal
Fixed deserialization issues with CreationRequest, added validation, and made small code tweaks for consistency with other endpoints.
This commit is contained in:
parent
b051f9be89
commit
3fbcc50503
102
src/main/java/org/qortal/api/model/AtCreationRequest.java
Normal file
102
src/main/java/org/qortal/api/model/AtCreationRequest.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package org.qortal.api.model;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
|
|
||||||
|
import org.bouncycastle.util.encoders.Base64;
|
||||||
|
import org.bouncycastle.util.encoders.DecoderException;
|
||||||
|
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class AtCreationRequest {
|
||||||
|
|
||||||
|
@Schema(description = "CIYAM AT version", example = "2")
|
||||||
|
private short ciyamAtVersion;
|
||||||
|
|
||||||
|
@Schema(description = "base64-encoded code bytes", example = "")
|
||||||
|
private String codeBytesBase64;
|
||||||
|
|
||||||
|
@Schema(description = "base64-encoded data bytes", example = "")
|
||||||
|
private String dataBytesBase64;
|
||||||
|
|
||||||
|
private short numCallStackPages;
|
||||||
|
private short numUserStackPages;
|
||||||
|
private long minActivationAmount;
|
||||||
|
|
||||||
|
// Default constructor for JSON deserialization
|
||||||
|
public AtCreationRequest() {}
|
||||||
|
|
||||||
|
// Getters and setters
|
||||||
|
public short getCiyamAtVersion() {
|
||||||
|
return ciyamAtVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCiyamAtVersion(short ciyamAtVersion) {
|
||||||
|
this.ciyamAtVersion = ciyamAtVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getCodeBytesBase64() {
|
||||||
|
return this.codeBytesBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlTransient
|
||||||
|
@Schema(hidden = true)
|
||||||
|
public byte[] getCodeBytes() {
|
||||||
|
if (this.codeBytesBase64 != null) {
|
||||||
|
try {
|
||||||
|
return Base64.decode(this.codeBytesBase64);
|
||||||
|
}
|
||||||
|
catch (DecoderException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getDataBytesBase64() {
|
||||||
|
return this.dataBytesBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlTransient
|
||||||
|
@Schema(hidden = true)
|
||||||
|
public byte[] getDataBytes() {
|
||||||
|
if (this.dataBytesBase64 != null) {
|
||||||
|
try {
|
||||||
|
return Base64.decode(this.dataBytesBase64);
|
||||||
|
}
|
||||||
|
catch (DecoderException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public short getNumCallStackPages() {
|
||||||
|
return numCallStackPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumCallStackPages(short numCallStackPages) {
|
||||||
|
this.numCallStackPages = numCallStackPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getNumUserStackPages() {
|
||||||
|
return numUserStackPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumUserStackPages(short numUserStackPages) {
|
||||||
|
this.numUserStackPages = numUserStackPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMinActivationAmount() {
|
||||||
|
return minActivationAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinActivationAmount(long minActivationAmount) {
|
||||||
|
this.minActivationAmount = minActivationAmount;
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
|||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@ -28,7 +27,7 @@ import org.qortal.api.ApiException;
|
|||||||
import org.qortal.api.ApiExceptionFactory;
|
import org.qortal.api.ApiExceptionFactory;
|
||||||
import org.qortal.data.at.ATData;
|
import org.qortal.data.at.ATData;
|
||||||
import org.qortal.data.at.ATStateData;
|
import org.qortal.data.at.ATStateData;
|
||||||
import org.qortal.data.transaction.CreationRequest;
|
import org.qortal.api.model.AtCreationRequest;
|
||||||
import org.qortal.data.transaction.DeployAtTransactionData;
|
import org.qortal.data.transaction.DeployAtTransactionData;
|
||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
import org.qortal.repository.Repository;
|
import org.qortal.repository.Repository;
|
||||||
@ -39,10 +38,11 @@ import org.qortal.transaction.Transaction.ValidationResult;
|
|||||||
import org.qortal.transform.TransformationException;
|
import org.qortal.transform.TransformationException;
|
||||||
import org.qortal.transform.transaction.DeployAtTransactionTransformer;
|
import org.qortal.transform.transaction.DeployAtTransactionTransformer;
|
||||||
import org.qortal.utils.Base58;
|
import org.qortal.utils.Base58;
|
||||||
import java.util.Base64;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
@Path("/at")
|
@Path("/at")
|
||||||
@Tag(name = "Automated Transactions")
|
@Tag(name = "Automated Transactions")
|
||||||
public class AtResource {
|
public class AtResource {
|
||||||
@ -163,21 +163,21 @@ public class AtResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/createMachineState")
|
@Path("/create")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Create MachineState bytes from the provided parameters",
|
summary = "Create base58-encoded AT creation bytes from the provided parameters",
|
||||||
requestBody = @RequestBody(
|
requestBody = @RequestBody(
|
||||||
required = true,
|
required = true,
|
||||||
content = @Content(
|
content = @Content(
|
||||||
mediaType = MediaType.APPLICATION_JSON,
|
mediaType = MediaType.APPLICATION_JSON,
|
||||||
schema = @Schema(
|
schema = @Schema(
|
||||||
implementation = CreationRequest.class
|
implementation = AtCreationRequest.class
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "MachineState bytes",
|
description = "AT creation bytes suitable for use in a DEPLOY_AT transaction",
|
||||||
content = @Content(
|
content = @Content(
|
||||||
mediaType = MediaType.TEXT_PLAIN,
|
mediaType = MediaType.TEXT_PLAIN,
|
||||||
schema = @Schema(
|
schema = @Schema(
|
||||||
@ -187,27 +187,26 @@ public class AtResource {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
public String createMachineState(String jsonBody) throws IOException {
|
public String create(AtCreationRequest atCreationRequest) {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
if (atCreationRequest.getCiyamAtVersion() < 2) {
|
||||||
CreationRequest request = objectMapper.readValue(jsonBody, CreationRequest.class);
|
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, "ciyamAtVersion must be at least 2");
|
||||||
|
}
|
||||||
|
if (atCreationRequest.getCodeBytes() == null) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, "Valid codeBytesBase64 must be supplied");
|
||||||
|
}
|
||||||
|
if (atCreationRequest.getDataBytes() == null) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, "Valid dataBytesBase64 must be supplied");
|
||||||
|
}
|
||||||
|
|
||||||
logger.info("ciyamAtVersion: {}", request.getCiyamAtVersion());
|
|
||||||
logger.info("codeBytes: {}", request.getCodeBytes());
|
|
||||||
logger.info("codeBytes: {}", request.getNumUserStackPages());
|
|
||||||
logger.info("codeBytes: {}", request.getDataBytes());
|
|
||||||
logger.info("codeBytes: {}", request.getNumCallStackPages());
|
|
||||||
logger.info("codeBytes: {}", request.getMinActivationAmount());
|
|
||||||
byte[] creationBytes = MachineState.toCreationBytes(
|
byte[] creationBytes = MachineState.toCreationBytes(
|
||||||
request.getCiyamAtVersion(),
|
atCreationRequest.getCiyamAtVersion(),
|
||||||
request.getCodeBytes(),
|
atCreationRequest.getCodeBytes(),
|
||||||
request.getDataBytes(),
|
atCreationRequest.getDataBytes(),
|
||||||
request.getNumCallStackPages(),
|
atCreationRequest.getNumCallStackPages(),
|
||||||
request.getNumUserStackPages(),
|
atCreationRequest.getNumUserStackPages(),
|
||||||
request.getMinActivationAmount()
|
atCreationRequest.getMinActivationAmount()
|
||||||
);
|
);
|
||||||
return Base58.encode(creationBytes);
|
return Base58.encode(creationBytes);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@POST
|
@POST
|
||||||
@Operation(
|
@Operation(
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
package org.qortal.data.transaction;
|
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
public class CreationRequest {
|
|
||||||
|
|
||||||
private short ciyamAtVersion;
|
|
||||||
@JsonProperty("codeBytesBase64")
|
|
||||||
private String codeBytesBase64;
|
|
||||||
private String dataBytesBase64;
|
|
||||||
private short numCallStackPages;
|
|
||||||
private short numUserStackPages;
|
|
||||||
private long minActivationAmount;
|
|
||||||
|
|
||||||
// Default constructor for JSON deserialization
|
|
||||||
public CreationRequest() {}
|
|
||||||
|
|
||||||
// Getters and setters
|
|
||||||
public short getCiyamAtVersion() {
|
|
||||||
return ciyamAtVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCiyamAtVersion(short ciyamAtVersion) {
|
|
||||||
this.ciyamAtVersion = ciyamAtVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getCodeBytes() {
|
|
||||||
if (this.codeBytesBase64 != null) {
|
|
||||||
return Base64.getDecoder().decode(this.codeBytesBase64);
|
|
||||||
}
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCodeBytesBase64(String codeBytesBase64) {
|
|
||||||
this.codeBytesBase64 = codeBytesBase64;
|
|
||||||
}
|
|
||||||
public String getCodeBytes2() {
|
|
||||||
return codeBytesBase64;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public byte[] getDataBytes() {
|
|
||||||
if (this.dataBytesBase64 != null) {
|
|
||||||
return Base64.getDecoder().decode(this.dataBytesBase64);
|
|
||||||
}
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDataBytesBase64(String dataBytesBase64) {
|
|
||||||
this.dataBytesBase64 = dataBytesBase64;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getNumCallStackPages() {
|
|
||||||
return numCallStackPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNumCallStackPages(short numCallStackPages) {
|
|
||||||
this.numCallStackPages = numCallStackPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getNumUserStackPages() {
|
|
||||||
return numUserStackPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNumUserStackPages(short numUserStackPages) {
|
|
||||||
this.numUserStackPages = numUserStackPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getMinActivationAmount() {
|
|
||||||
return minActivationAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinActivationAmount(long minActivationAmount) {
|
|
||||||
this.minActivationAmount = minActivationAmount;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user