Skip to content

Commit

Permalink
add support for Soroban Preview 11.
Browse files Browse the repository at this point in the history
  • Loading branch information
overcat committed Sep 16, 2023
1 parent 4cc0c3d commit 2c768c3
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 229 deletions.
33 changes: 16 additions & 17 deletions src/main/java/org/stellar/sdk/InvokeHostFunctionOperation.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
import org.stellar.sdk.xdr.Hash;
import org.stellar.sdk.xdr.HostFunction;
import org.stellar.sdk.xdr.HostFunctionType;
import org.stellar.sdk.xdr.InvokeContractArgs;
import org.stellar.sdk.xdr.InvokeHostFunctionOp;
import org.stellar.sdk.xdr.OperationType;
import org.stellar.sdk.xdr.SCSymbol;
import org.stellar.sdk.xdr.SCVal;
import org.stellar.sdk.xdr.SCValType;
import org.stellar.sdk.xdr.SCVec;
import org.stellar.sdk.xdr.SorobanAuthorizationEntry;
import org.stellar.sdk.xdr.Uint256;
import org.stellar.sdk.xdr.XdrString;
Expand Down Expand Up @@ -226,32 +225,25 @@ public static InvokeHostFunctionOperation fromXdr(InvokeHostFunctionOp op) {
* parameter preset, so that you can conveniently build an {@link InvokeHostFunctionOperation} to
* invoke a contract function.
*
* @see org.stellar.sdk.scval.Scv
* @see <a
* href="https://soroban.stellar.org/docs/fundamentals-and-concepts/interacting-with-contracts"
* target="_blank">Interacting with Contracts</a>
* @param contractId The ID of the contract to invoke.
* @param functionName The name of the function to invoke.
* @param parameters The parameters to pass to the method.
* @return {@link InvokeHostFunctionOperationBuilder}
* @see org.stellar.sdk.scval.Scv
* @see <a
* href="https://soroban.stellar.org/docs/fundamentals-and-concepts/interacting-with-contracts"
* target="_blank">Interacting with Contracts</a>
*/
public static InvokeHostFunctionOperationBuilder<?, ?> invokeContractFunctionOperationBuilder(
String contractId, String functionName, @Nullable Collection<SCVal> parameters) {
Address address = new Address(contractId);
if (address.getAddressType() != Address.AddressType.CONTRACT) {
throw new IllegalArgumentException("\"contractId\" must be a contract address");
}
SCVal contractIdScVal = address.toSCVal();
SCVal functionNameScVal =
new SCVal.Builder()
.discriminant(SCValType.SCV_SYMBOL)
.sym(new SCSymbol(new XdrString(functionName)))
.build();

SCSymbol functionNameSCSymbol = new SCSymbol(new XdrString(functionName));
List<SCVal> invokeContractParams =
new ArrayList<>(2 + (parameters != null ? parameters.size() : 0));
invokeContractParams.add(contractIdScVal);
invokeContractParams.add(functionNameScVal);
new ArrayList<>((parameters != null ? parameters.size() : 0));

if (parameters != null) {
for (SCVal parameter : parameters) {
if (parameter == null) {
Expand All @@ -261,10 +253,17 @@ public static InvokeHostFunctionOperation fromXdr(InvokeHostFunctionOp op) {
}
}

InvokeContractArgs invokeContractArgs =
new InvokeContractArgs.Builder()
.contractAddress(address.toSCAddress())
.functionName(functionNameSCSymbol)
.args(invokeContractParams.toArray(new SCVal[0]))
.build();

HostFunction hostFunction =
new HostFunction.Builder()
.discriminant(HostFunctionType.HOST_FUNCTION_TYPE_INVOKE_CONTRACT)
.invokeContract(new SCVec(invokeContractParams.toArray(new SCVal[0])))
.invokeContract(invokeContractArgs)
.build();
return builder().hostFunction(hostFunction);
}
Expand Down
6 changes: 0 additions & 6 deletions src/main/java/org/stellar/sdk/SorobanDataBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public SorobanDataBuilder() {
.instructions(new Uint32(new XdrUnsignedInteger(0)))
.readBytes(new Uint32(new XdrUnsignedInteger(0)))
.writeBytes(new Uint32(new XdrUnsignedInteger(0)))
.extendedMetaDataSizeBytes(new Uint32(new XdrUnsignedInteger(0)))
.build())
.refundableFee(new Int64(0L))
.ext(new ExtensionPoint.Builder().discriminant(0).build())
Expand Down Expand Up @@ -99,9 +98,6 @@ public SorobanDataBuilder setResources(Resources resources) {
data.getResources().setReadBytes(new Uint32(new XdrUnsignedInteger(resources.getReadBytes())));
data.getResources()
.setWriteBytes(new Uint32(new XdrUnsignedInteger(resources.getWriteBytes())));
data.getResources()
.setExtendedMetaDataSizeBytes(
new Uint32(new XdrUnsignedInteger(resources.getMetadataBytes())));
return this;
}

Expand Down Expand Up @@ -160,7 +156,5 @@ public static class Resources {
@NonNull Long readBytes;
// number of bytes being written (uint32)
@NonNull Long writeBytes;
// number of extended metadata bytes (uint32)
@NonNull Long metadataBytes;
}
}
20 changes: 9 additions & 11 deletions src/main/java/org/stellar/sdk/SorobanServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import org.stellar.sdk.responses.sorobanrpc.SimulateTransactionResponse;
import org.stellar.sdk.responses.sorobanrpc.SorobanRpcResponse;
import org.stellar.sdk.xdr.ContractDataDurability;
import org.stellar.sdk.xdr.ContractEntryBodyType;
import org.stellar.sdk.xdr.LedgerEntry;
import org.stellar.sdk.xdr.LedgerEntryType;
import org.stellar.sdk.xdr.LedgerKey;
Expand Down Expand Up @@ -179,7 +178,6 @@ public Optional<GetLedgerEntriesResponse.LedgerEntryResult> getContractData(
.contract(address.toSCAddress())
.key(key)
.durability(contractDataDurability)
.bodyType(ContractEntryBodyType.DATA_ENTRY)
.build();
LedgerKey ledgerKey =
new LedgerKey.Builder()
Expand Down Expand Up @@ -376,12 +374,6 @@ public Transaction prepareTransaction(Transaction transaction)
"simulation transaction failed, the response contains error information.",
simulateTransactionResponse);
}
if (simulateTransactionResponse.getResults() == null
|| simulateTransactionResponse.getResults().size() != 1) {
throw new PrepareTransactionException(
"simulation transaction failed, the \"results\" field contains multiple records, but it should only contain one.",
simulateTransactionResponse);
}
return assembleTransaction(transaction, simulateTransactionResponse);
}

Expand Down Expand Up @@ -416,9 +408,6 @@ private Transaction assembleTransaction(
"unsupported transaction: must contain exactly one InvokeHostFunctionOperation, BumpSequenceOperation, or RestoreFootprintOperation");
}

SimulateTransactionResponse.SimulateHostFunctionResult simulateHostFunctionResult =
simulateTransactionResponse.getResults().get(0);

long classicFeeNum = transaction.getFee();
long minResourceFeeNum =
Optional.ofNullable(simulateTransactionResponse.getMinResourceFee()).orElse(0L);
Expand All @@ -428,6 +417,15 @@ private Transaction assembleTransaction(
if (operation instanceof InvokeHostFunctionOperation) {
// If the operation is an InvokeHostFunctionOperation, we need to update the auth entries if
// existing entries are empty and the simulation result contains auth entries.
if (simulateTransactionResponse.getResults() == null
|| simulateTransactionResponse.getResults().size() != 1) {
throw new IllegalArgumentException(
"invalid simulateTransactionResponse: results must contain exactly one element if present");
}

SimulateTransactionResponse.SimulateHostFunctionResult simulateHostFunctionResult =
simulateTransactionResponse.getResults().get(0);

Collection<SorobanAuthorizationEntry> existingEntries =
((InvokeHostFunctionOperation) operation).getAuth();
if (existingEntries.isEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@ public class SimulateTransactionResponse {

Long minResourceFee;

// An array of the individual host function call results.
// This will only contain a single element if present, because only a single
// invokeHostFunctionOperation
// is supported per transaction.
ImmutableList<SimulateHostFunctionResult> results;

SimulateTransactionCost cost;

RestorePreamble restorePreamble;

Long latestLedger;

@AllArgsConstructor
Expand All @@ -46,4 +52,12 @@ public static class SimulateTransactionCost {
@SerializedName("memBytes")
BigInteger memoryBytes;
}

@AllArgsConstructor
@Value
public static class RestorePreamble {
String transactionData;

Long minResourceFee;
}
}
5 changes: 1 addition & 4 deletions src/main/java/org/stellar/sdk/scval/ScvError.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ class ScvError {
private static final SCValType TYPE = SCValType.SCV_ERROR;

static SCVal toSCVal(SCError value) {
return new SCVal.Builder()
.discriminant(TYPE)
.error(new SCError.Builder().code(value.getCode()).type(value.getType()).build())
.build();
return new SCVal.Builder().discriminant(TYPE).error(value).build();
}

static SCError fromSCVal(SCVal scVal) {
Expand Down
27 changes: 13 additions & 14 deletions src/test/java/org/stellar/sdk/InvokeHostFunctionOperationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
Expand All @@ -19,10 +18,10 @@
import org.stellar.sdk.xdr.HostFunction;
import org.stellar.sdk.xdr.HostFunctionType;
import org.stellar.sdk.xdr.Int64;
import org.stellar.sdk.xdr.InvokeContractArgs;
import org.stellar.sdk.xdr.SCAddress;
import org.stellar.sdk.xdr.SCSymbol;
import org.stellar.sdk.xdr.SCVal;
import org.stellar.sdk.xdr.SCValType;
import org.stellar.sdk.xdr.SCVec;
import org.stellar.sdk.xdr.SorobanAddressCredentials;
import org.stellar.sdk.xdr.SorobanAuthorizationEntry;
import org.stellar.sdk.xdr.SorobanAuthorizedFunction;
Expand Down Expand Up @@ -218,7 +217,6 @@ public void testNotEqualsAuth() {
.toSCAddress())
.nonce(new Int64(123123432L))
.signatureExpirationLedger(new Uint32(new XdrUnsignedInteger(10)))
.signatureArgs(new SCVec(new SCVal[] {}))
.build())
.build())
.rootInvocation(
Expand Down Expand Up @@ -486,26 +484,27 @@ public void invokeContractFunctionOperationBuilder() {
contractId, funcName, parameters)
.build();

SCVal contractIdScVal = new Address(contractId).toSCVal();
SCVal functionNameScVal =
new SCVal.Builder()
.discriminant(SCValType.SCV_SYMBOL)
.sym(new SCSymbol(new XdrString(funcName)))
.build();
SCAddress contractIdScAddress = new Address(contractId).toSCAddress();
SCSymbol functionNameSCSymbol = new SCSymbol(new XdrString(funcName));
SCVal paramScVal = parameters.get(0);
List<SCVal> invokeContractParams =
Arrays.asList(contractIdScVal, functionNameScVal, paramScVal);

InvokeContractArgs invokeContractArgs =
new InvokeContractArgs.Builder()
.contractAddress(contractIdScAddress)
.functionName(functionNameSCSymbol)
.args(new SCVal[] {paramScVal})
.build();
HostFunction expectedFunction =
new HostFunction.Builder()
.discriminant(HostFunctionType.HOST_FUNCTION_TYPE_INVOKE_CONTRACT)
.invokeContract(new SCVec(invokeContractParams.toArray(new SCVal[0])))
.invokeContract(invokeContractArgs)
.build();

assertEquals(operation.getHostFunction(), expectedFunction);
assertTrue(operation.getAuth().isEmpty());
assertNull(operation.getSourceAccount());
String expectedXdr =
"AAAAAAAAABgAAAAAAAAAAwAAABIAAAABPww0v5OtDZlx0EzMkPcFURyDiq2XNKSi+w16A/x/6JoAAAAPAAAABWhlbGxvAAAAAAAADwAAAAV3b3JsZAAAAAAAAAA=";
"AAAAAAAAABgAAAAAAAAAAT8MNL+TrQ2ZcdBMzJD3BVEcg4qtlzSkovsNegP8f+iaAAAABWhlbGxvAAAAAAAAAQAAAA8AAAAFd29ybGQAAAAAAAAA";
assertEquals(expectedXdr, operation.toXdrBase64());
}
}
3 changes: 0 additions & 3 deletions src/test/java/org/stellar/sdk/SorobanDataBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public class SorobanDataBuilderTest {
.instructions(new Uint32(new XdrUnsignedInteger(0)))
.readBytes(new Uint32(new XdrUnsignedInteger(0)))
.writeBytes(new Uint32(new XdrUnsignedInteger(0)))
.extendedMetaDataSizeBytes(new Uint32(new XdrUnsignedInteger(0)))
.build())
.refundableFee(new Int64(0L))
.ext(new ExtensionPoint.Builder().discriminant(0).build())
Expand All @@ -72,7 +71,6 @@ public class SorobanDataBuilderTest {
.instructions(new Uint32(new XdrUnsignedInteger(1)))
.readBytes(new Uint32(new XdrUnsignedInteger(2)))
.writeBytes(new Uint32(new XdrUnsignedInteger(3)))
.extendedMetaDataSizeBytes(new Uint32(new XdrUnsignedInteger(4)))
.build())
.refundableFee(new Int64(5L))
.ext(new ExtensionPoint.Builder().discriminant(0).build())
Expand Down Expand Up @@ -109,7 +107,6 @@ public void testSetProperties() {
.cpuInstructions(1L)
.readBytes(2L)
.writeBytes(3L)
.metadataBytes(4L)
.build())
.build();
assertEquals(presetSorobanData, actualData);
Expand Down
Loading

0 comments on commit 2c768c3

Please sign in to comment.