diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index 2cccfd247..94cfe0b2c 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -28,9 +28,9 @@ jobs: ENABLE_LOGS: true NETWORK: local ENABLE_SOROBAN_RPC: true - PROTOCOL_VERSION: 24 + PROTOCOL_VERSION: 25 options: >- - --health-cmd "curl --no-progress-meter --fail-with-body -X POST \"http://localhost:8000/soroban/rpc\" -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":8675309,\"method\":\"getNetwork\"}' && curl --no-progress-meter \"http://localhost:8000/friendbot\" | grep '\"invalid_field\": \"addr\"'" + --health-cmd "curl --no-progress-meter --fail-with-body -X POST \"http://localhost:8000/rpc\" -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":8675309,\"method\":\"getNetwork\"}' && curl --no-progress-meter \"http://localhost:8000/friendbot\" | grep '\"invalid_field\": \"addr\"'" --health-interval 10s --health-timeout 5s --health-retries 50 diff --git a/CHANGELOG.md b/CHANGELOG.md index ae5edaa6b..37635c126 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Pending +- refactor!: remove `InvokeHostFunctionOperation.createStellarAssetContractOperationBuilder(Address, byte[])`, use `InvokeHostFunctionOperation.createContractOperationBuilder` instead. ## 2.2.2 diff --git a/src/main/java/org/stellar/sdk/operations/InvokeHostFunctionOperation.java b/src/main/java/org/stellar/sdk/operations/InvokeHostFunctionOperation.java index 332c57d48..ac60b9db8 100644 --- a/src/main/java/org/stellar/sdk/operations/InvokeHostFunctionOperation.java +++ b/src/main/java/org/stellar/sdk/operations/InvokeHostFunctionOperation.java @@ -191,49 +191,6 @@ public static InvokeHostFunctionOperation fromXdr(InvokeHostFunctionOp op) { return builder().hostFunction(hostFunction); } - /** - * This function will create an {@link InvokeHostFunctionOperationBuilder} with the "hostFunction" - * parameter preset, so that you can conveniently build an {@link InvokeHostFunctionOperation} to - * create a token contract wrapping a classic asset. - * - * @param address The address to use to derive the contract ID. - * @param salt The 32-byte salt to use to derive the contract ID, if null, a random salt will be - * generated. - * @return {@link InvokeHostFunctionOperationBuilder} - */ - public static InvokeHostFunctionOperationBuilder createStellarAssetContractOperationBuilder( - Address address, @Nullable byte[] salt) { - if (salt == null) { - salt = new byte[32]; - new SecureRandom().nextBytes(salt); - } else if (salt.length != 32) { - throw new IllegalArgumentException("\"salt\" must be 32 bytes long"); - } - - CreateContractArgs createContractArgs = - CreateContractArgs.builder() - .contractIDPreimage( - ContractIDPreimage.builder() - .discriminant(ContractIDPreimageType.CONTRACT_ID_PREIMAGE_FROM_ADDRESS) - .fromAddress( - ContractIDPreimage.ContractIDPreimageFromAddress.builder() - .address(address.toSCAddress()) - .salt(new Uint256(salt)) - .build()) - .build()) - .executable( - ContractExecutable.builder() - .discriminant(ContractExecutableType.CONTRACT_EXECUTABLE_STELLAR_ASSET) - .build()) - .build(); - HostFunction hostFunction = - HostFunction.builder() - .discriminant(HostFunctionType.HOST_FUNCTION_TYPE_CREATE_CONTRACT) - .createContract(createContractArgs) - .build(); - return builder().hostFunction(hostFunction); - } - /** * This function will create an {@link InvokeHostFunctionOperationBuilder} with the "hostFunction" * parameter preset, so that you can conveniently build an {@link InvokeHostFunctionOperation} to diff --git a/src/test/java/org/stellar/sdk/IntegrationUtils.java b/src/test/java/org/stellar/sdk/IntegrationUtils.java index 44cc61f6e..2c8fc3c46 100644 --- a/src/test/java/org/stellar/sdk/IntegrationUtils.java +++ b/src/test/java/org/stellar/sdk/IntegrationUtils.java @@ -1,6 +1,8 @@ package org.stellar.sdk; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; import java.math.BigInteger; import java.net.HttpURLConnection; @@ -17,7 +19,7 @@ import org.stellar.sdk.xdr.SCVal; public class IntegrationUtils { - public static final String RPC_URL = "http://127.0.0.1:8000/soroban/rpc"; + public static final String RPC_URL = "http://127.0.0.1:8000/rpc"; public static final String HORIZON_URL = "http://127.0.0.1:8000"; public static final String FRIEND_BOT_URL = "http://127.0.0.1:8000/friendbot"; public static final Network NETWORK = Network.STANDALONE; @@ -57,12 +59,52 @@ public static void createAssetContract(Asset asset, KeyPair source) { } } + public static byte[] uploadWasm(byte[] contractWasm, KeyPair source) { + try (SorobanServer server = new SorobanServer(RPC_URL)) { + TransactionBuilderAccount account = server.getAccount(source.getAccountId()); + InvokeHostFunctionOperation op = + InvokeHostFunctionOperation.uploadContractWasmOperationBuilder(contractWasm).build(); + TransactionBuilder transactionBuilder = + new TransactionBuilder(account, NETWORK).setBaseFee(100).addOperation(op).setTimeout(300); + AssembledTransaction assembledTransaction = + new AssembledTransaction<>(transactionBuilder, server, source, Scv::fromBytes, 300); + AssembledTransaction simulated = assembledTransaction.simulate(false); + if (simulated.isReadCall()) { + return simulated.result(); + } else { + return simulated.signAndSubmit(source, false); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public static String getRandomContractId(KeyPair source) { + byte[] wasm; + try (InputStream is = + IntegrationUtils.class.getResourceAsStream( + "/wasm_files/soroban_hello_world_contract.wasm")) { + if (is == null) { + throw new RuntimeException("soroban_hello_world_contract.wasm not found"); + } + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + byte[] data = new byte[1024]; + int bytesRead; + while ((bytesRead = is.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, bytesRead); + } + wasm = buffer.toByteArray(); + } catch (IOException e) { + throw new RuntimeException(e); + } + + byte[] wasmId = uploadWasm(wasm, source); + try (SorobanServer server = new SorobanServer(RPC_URL)) { TransactionBuilderAccount account = server.getAccount(source.getAccountId()); InvokeHostFunctionOperation op = - InvokeHostFunctionOperation.createStellarAssetContractOperationBuilder( - new Address(source.getAccountId()), null) + InvokeHostFunctionOperation.createContractOperationBuilder( + wasmId, new Address(source.getAccountId()), null, null) .build(); TransactionBuilder transactionBuilder = new TransactionBuilder(account, NETWORK).setBaseFee(100).addOperation(op).setTimeout(300); diff --git a/src/test/java/org/stellar/sdk/operations/InvokeHostFunctionOperationTest.java b/src/test/java/org/stellar/sdk/operations/InvokeHostFunctionOperationTest.java index 5da854ec3..6ae33dbde 100644 --- a/src/test/java/org/stellar/sdk/operations/InvokeHostFunctionOperationTest.java +++ b/src/test/java/org/stellar/sdk/operations/InvokeHostFunctionOperationTest.java @@ -469,48 +469,6 @@ public void createContractOperationBuilderWithConstructorArgs() { assertEquals(expectedXdr, operation.toXdrBase64()); } - @Test - public void createStellarAssetContractOperationBuilderWithAddress() { - Address address = new Address("GAHJJJKMOKYE4RVPZEWZTKH5FVI4PA3VL7GK2LFNUBSGBV6OJP7TQSLX"); - byte[] salt = - new byte[] { - 0x11, 0x33, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, - 0x1e, 0x1f - }; - InvokeHostFunctionOperation operation = - InvokeHostFunctionOperation.createStellarAssetContractOperationBuilder(address, salt) - .build(); - CreateContractArgs createContractArgs = - CreateContractArgs.builder() - .contractIDPreimage( - ContractIDPreimage.builder() - .discriminant(ContractIDPreimageType.CONTRACT_ID_PREIMAGE_FROM_ADDRESS) - .fromAddress( - ContractIDPreimage.ContractIDPreimageFromAddress.builder() - .address(address.toSCAddress()) - .salt(new Uint256(salt)) - .build()) - .build()) - .executable( - ContractExecutable.builder() - .discriminant(ContractExecutableType.CONTRACT_EXECUTABLE_STELLAR_ASSET) - .build()) - .build(); - HostFunction expectedFunction = - HostFunction.builder() - .discriminant(HostFunctionType.HOST_FUNCTION_TYPE_CREATE_CONTRACT) - .createContract(createContractArgs) - .build(); - - assertEquals(operation.getHostFunction(), expectedFunction); - assertTrue(operation.getAuth().isEmpty()); - assertNull(operation.getSourceAccount()); - String expectedXdr = - "AAAAAAAAABgAAAABAAAAAAAAAAAAAAAADpSlTHKwTkavyS2ZqP0tUceDdV/MrSytoGRg185L/zgRMwIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHwAAAAEAAAAA"; - assertEquals(expectedXdr, operation.toXdrBase64()); - } - @Test public void createStellarAssetContractOperationBuilderWithAsset() { Asset asset = diff --git a/src/test/resources/wasm_files/soroban_hello_world_contract.wasm b/src/test/resources/wasm_files/soroban_hello_world_contract.wasm new file mode 100644 index 000000000..464064fd2 Binary files /dev/null and b/src/test/resources/wasm_files/soroban_hello_world_contract.wasm differ