From 6229e75f4e0373eb96993ab6fc5b714afe85531e Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Fri, 9 Oct 2020 17:34:44 -0500 Subject: [PATCH 01/17] Add support for send_transaction and make it the default. --- .gitignore | 1 + build.gradle | 4 +- .../error/EosioJavaRpcErrorConstants.java | 5 + .../EosioJavaRpcProviderImpl.java | 36 ++++--- .../IEosioJavaRpcProviderApi.java | 21 ++-- .../RpcProviderUnitTest.java | 97 ++++++++++++++++--- 6 files changed, 121 insertions(+), 43 deletions(-) diff --git a/.gitignore b/.gitignore index 32f7257..7da23ea 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,4 @@ lint/tmp/ gradle.properties +.DS_Store diff --git a/build.gradle b/build.gradle index 469ed10..5b1ec95 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'one.block:eosiojava:0.1.2' + implementation 'one.block:eosiojava:0.1.3-eosio2.1' implementation 'org.jetbrains:annotations:17.0.0' implementation (group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1') { @@ -59,7 +59,7 @@ test { def libraryGroupId = 'one.block' def libraryArtifactId = 'eosio-java-rpc-provider' -def libraryVersion = '0.1.1' +def libraryVersion = '0.1.3-eosio2.1' task sourcesJar(type: Jar, dependsOn: classes){ classifier = 'sources' diff --git a/src/main/java/one/block/eosiojavarpcprovider/error/EosioJavaRpcErrorConstants.java b/src/main/java/one/block/eosiojavarpcprovider/error/EosioJavaRpcErrorConstants.java index 263dfcd..c3a2ed6 100644 --- a/src/main/java/one/block/eosiojavarpcprovider/error/EosioJavaRpcErrorConstants.java +++ b/src/main/java/one/block/eosiojavarpcprovider/error/EosioJavaRpcErrorConstants.java @@ -48,6 +48,11 @@ public class EosioJavaRpcErrorConstants { */ public static final String RPC_PROVIDER_ERROR_PUSHING_TRANSACTION = "Error pushing transaction."; + /** + * Error message gets thrown if {@link EosioJavaRpcProviderImpl#sendTransaction(SendTransactionRequest)} returns error. + */ + public static final String RPC_PROVIDER_ERROR_SENDING_TRANSACTION = "Error sending transaction."; + /** * Error message gets thrown if {@link EosioJavaRpcProviderImpl#pushTransactions(RequestBody)} returns error. */ diff --git a/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java b/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java index f5617a5..c4269c4 100644 --- a/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java +++ b/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java @@ -2,6 +2,9 @@ import com.google.gson.Gson; +import one.block.eosiojava.error.rpcProvider.*; +import one.block.eosiojava.models.rpcProvider.request.*; +import one.block.eosiojava.models.rpcProvider.response.*; import org.jetbrains.annotations.NotNull; import java.util.Locale; @@ -11,23 +14,7 @@ import okhttp3.ResponseBody; import okhttp3.logging.HttpLoggingInterceptor; import okhttp3.logging.HttpLoggingInterceptor.Level; -import one.block.eosiojava.error.rpcProvider.GetBlockRpcError; -import one.block.eosiojava.error.rpcProvider.GetInfoRpcError; -import one.block.eosiojava.error.rpcProvider.GetRawAbiRpcError; -import one.block.eosiojava.error.rpcProvider.GetRequiredKeysRpcError; -import one.block.eosiojava.error.rpcProvider.PushTransactionRpcError; -import one.block.eosiojava.error.rpcProvider.RpcProviderError; import one.block.eosiojava.interfaces.IRPCProvider; -import one.block.eosiojava.models.rpcProvider.request.GetBlockRequest; -import one.block.eosiojava.models.rpcProvider.request.GetRawAbiRequest; -import one.block.eosiojava.models.rpcProvider.request.GetRequiredKeysRequest; -import one.block.eosiojava.models.rpcProvider.request.PushTransactionRequest; -import one.block.eosiojava.models.rpcProvider.response.GetBlockResponse; -import one.block.eosiojava.models.rpcProvider.response.GetInfoResponse; -import one.block.eosiojava.models.rpcProvider.response.GetRawAbiResponse; -import one.block.eosiojava.models.rpcProvider.response.GetRequiredKeysResponse; -import one.block.eosiojava.models.rpcProvider.response.PushTransactionResponse; -import one.block.eosiojava.models.rpcProvider.response.RPCResponseError; //import one.block.eosiojavarpcprovider.BuildConfig; import one.block.eosiojavarpcprovider.error.EosioJavaRpcErrorConstants; import one.block.eosiojavarpcprovider.error.EosioJavaRpcProviderCallError; @@ -218,6 +205,23 @@ private O processCall(Call call) throws Exception { } } + /** + * Send a given transaction to the blockchain and process the response. + * @param sendTransactionRequest the transaction to send with signatures. + * @return SendTransactionResponse on successful return. + * @throws SendTransactionRpcError Thrown if any errors occur calling or processing the request. + */ + public @NotNull SendTransactionResponse sendTransaction( + SendTransactionRequest sendTransactionRequest) throws SendTransactionRpcError { + try { + Call syncCall = this.rpcProviderApi.sendTransaction(sendTransactionRequest); + return processCall(syncCall); + } catch (Exception ex) { + throw new SendTransactionRpcError(EosioJavaRpcErrorConstants.RPC_PROVIDER_ERROR_SENDING_TRANSACTION, + ex); + } + } + /** * Issue a get_account call to the blockchain and process the response. * @param requestBody request body of get_account API diff --git a/src/main/java/one/block/eosiojavarpcprovider/implementations/IEosioJavaRpcProviderApi.java b/src/main/java/one/block/eosiojavarpcprovider/implementations/IEosioJavaRpcProviderApi.java index 7429af2..7f8c606 100644 --- a/src/main/java/one/block/eosiojavarpcprovider/implementations/IEosioJavaRpcProviderApi.java +++ b/src/main/java/one/block/eosiojavarpcprovider/implementations/IEosioJavaRpcProviderApi.java @@ -5,15 +5,8 @@ import okhttp3.RequestBody; import okhttp3.ResponseBody; -import one.block.eosiojava.models.rpcProvider.request.GetBlockRequest; -import one.block.eosiojava.models.rpcProvider.request.GetRawAbiRequest; -import one.block.eosiojava.models.rpcProvider.request.GetRequiredKeysRequest; -import one.block.eosiojava.models.rpcProvider.request.PushTransactionRequest; -import one.block.eosiojava.models.rpcProvider.response.GetBlockResponse; -import one.block.eosiojava.models.rpcProvider.response.GetInfoResponse; -import one.block.eosiojava.models.rpcProvider.response.GetRawAbiResponse; -import one.block.eosiojava.models.rpcProvider.response.GetRequiredKeysResponse; -import one.block.eosiojava.models.rpcProvider.response.PushTransactionResponse; +import one.block.eosiojava.models.rpcProvider.request.*; +import one.block.eosiojava.models.rpcProvider.response.*; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.POST; @@ -73,6 +66,16 @@ public interface IEosioJavaRpcProviderApi { */ @POST("v1/chain/push_transaction") Call pushTransaction(@Body PushTransactionRequest pushTransactionRequest); + + /** + * Retrofit POST call to "chain/send_transaction" to an EOSIO blockchain. + * This method gets called from {@link EosioJavaRpcProviderImpl#sendTransaction(SendTransactionRequest)} to Send transaction RPC call to broadcast a transaction to backend + * + * @param sendTransactionRequest the transaction to push with signatures. + * @return Executable {@link Call} to return {@link PushTransactionResponse} has the send transaction response + */ + @POST("v1/chain/send_transaction") + Call sendTransaction(@Body SendTransactionRequest sendTransactionRequest); //endregion diff --git a/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java b/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java index 7997fd8..a08b032 100644 --- a/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java +++ b/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java @@ -1,5 +1,7 @@ package one.block.eosiojavarpcprovider; +import one.block.eosiojava.models.rpcProvider.request.*; +import one.block.eosiojava.models.rpcProvider.response.*; import org.json.simple.*; import org.json.simple.parser.JSONParser; import org.junit.Before; @@ -22,17 +24,6 @@ import one.block.eosiojava.models.rpcProvider.Action; import one.block.eosiojava.models.rpcProvider.Authorization; import one.block.eosiojava.models.rpcProvider.Transaction; -import one.block.eosiojava.models.rpcProvider.request.GetBlockRequest; -import one.block.eosiojava.models.rpcProvider.request.GetRawAbiRequest; -import one.block.eosiojava.models.rpcProvider.request.GetRequiredKeysRequest; -import one.block.eosiojava.models.rpcProvider.request.PushTransactionRequest; -import one.block.eosiojava.models.rpcProvider.response.GetBlockResponse; -import one.block.eosiojava.models.rpcProvider.response.GetInfoResponse; -import one.block.eosiojava.models.rpcProvider.response.GetRawAbiResponse; -import one.block.eosiojava.models.rpcProvider.response.GetRequiredKeysResponse; -import one.block.eosiojava.models.rpcProvider.response.PushTransactionResponse; -import one.block.eosiojava.models.rpcProvider.response.RPCResponseError; -import one.block.eosiojava.models.rpcProvider.response.RpcError; import one.block.eosiojavarpcprovider.error.EosioJavaRpcProviderCallError; import one.block.eosiojavarpcprovider.implementations.EosioJavaRpcProviderImpl; @@ -40,11 +31,6 @@ import static org.junit.Assert.*; -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ public class RpcProviderUnitTest { private JSONParser parser; @@ -261,6 +247,85 @@ public void pushTransactionErrorTest() { } + @Test + public void sendTransactionTest() { + + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setResponseCode(200).setBody(PUSH_TRANSACTION_RESPONSE)); + + try { + server.start(); + String baseUrl = server.url("/").toString(); + + EosioJavaRpcProviderImpl rpcProvider = new EosioJavaRpcProviderImpl( + baseUrl); + + List signatures = new ArrayList<>(); + signatures.add("SIG_K1_JzFA9ffefWfrTBvpwMwZi81kR6tvHF4mfsRekVXrBjLWWikg9g1FrS9WupYuoGaRew5mJhr4d39tHUjHiNCkxamtEfxi68"); + SendTransactionRequest request = new SendTransactionRequest(signatures, + 0, + "", + "C62A4F5C1CEF3D6D71BD000000000290AFC2D800EA3055000000405DA7ADBA0072CBDD956F52ACD910C3C958136D72F8560D1846BC7CF3157F5FBFB72D3001DE4597F4A1FDBECDA6D59C96A43009FC5E5D7B8F639B1269C77CEC718460DCC19CB30100A6823403EA3055000000572D3CCDCD0143864D5AF0FE294D44D19C612036CBE8C098414C4A12A5A7BB0BFE7DB155624800A6823403EA3055000000572D3CCDCD0100AEAA4AC15CFD4500000000A8ED32323B00AEAA4AC15CFD4500000060D234CD3DA06806000000000004454F53000000001A746865206772617373686F70706572206C69657320686561767900"); + SendTransactionResponse response = rpcProvider.sendTransaction(request); + assertNotNull(response); + assertEquals("ae735820e26a7b771e1b522186294d7cbba035d0c31ca88237559d6c0a3bf00a", + response.getTransactionId()); + } catch (Exception ex) { + fail("Should not get exception when calling pushTransaction(): " + ex.getLocalizedMessage() + + "\n" + getStackTraceString(ex)); + } finally { + try { + server.shutdown(); + } catch (Exception ex) { + // No need for anything here. + } + } + + } + + @Test + public void sendTransactionErrorTest() { + + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setResponseCode(500).setBody(PUSH_TRANSACTION_ERROR_RESPONSE)); + + try { + server.start(); + String baseUrl = server.url("/").toString(); + + EosioJavaRpcProviderImpl rpcProvider = new EosioJavaRpcProviderImpl( + baseUrl); + + List signatures = new ArrayList<>(); + signatures.add("SIG_K1_JzFA9ffefWfrTBvpwMwZi81kR6tvHF4mfsRekVXrBjLWWikg9g1FrS9WupYuoGaRew5mJhr4d39tHUjHiNCkxamtEfxi68"); + SendTransactionRequest request = new SendTransactionRequest(signatures, + 0, + "", + "C62A4F5C1CEF3D6D71BD000000000290AFC2D800EA3055000000405DA7ADBA0072CBDD956F52ACD910C3C958136D72F8560D1846BC7CF3157F5FBFB72D3001DE4597F4A1FDBECDA6D59C96A43009FC5E5D7B8F639B1269C77CEC718460DCC19CB30100A6823403EA3055000000572D3CCDCD0143864D5AF0FE294D44D19C612036CBE8C098414C4A12A5A7BB0BFE7DB155624800A6823403EA3055000000572D3CCDCD0100AEAA4AC15CFD4500000000A8ED32323B00AEAA4AC15CFD4500000060D234CD3DA06806000000000004454F53000000001A746865206772617373686F70706572206C69657320686561767900"); + SendTransactionResponse response = rpcProvider.sendTransaction(request); + fail("Push transaction should not succeed."); + } catch (Exception ex) { + assertEquals("Error sending transaction.", ex.getLocalizedMessage()); + assertNotNull(ex.getCause()); + assertEquals("Bad status code: 500 (Server Error), returned from server. Additional error information: See further error information in RPCProviderError.", ex.getCause().getMessage()); + RPCResponseError rpcResponseError = ((EosioJavaRpcProviderCallError)ex.getCause()).getRpcResponseError(); + assertNotNull(rpcResponseError); + assertEquals(new BigInteger("500"), rpcResponseError.getCode()); + assertEquals("Internal Service Error", rpcResponseError.getMessage()); + RpcError rpcError = rpcResponseError.getError(); + assertNotNull(rpcError); + assertEquals(new BigInteger("3040005"), rpcError.getCode()); + assertEquals("Expired Transaction", rpcError.getWhat()); + } finally { + try { + server.shutdown(); + } catch (Exception ex) { + // No need for anything here. + } + } + + } + @Test public void getInfoTimeoutTest() { From 6132df01f99e034bbd5a715167d4b0ee65dfbece Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Fri, 9 Oct 2020 17:40:31 -0500 Subject: [PATCH 02/17] Update README to include send transaction. --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 01bd53e..19d0911 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ Java RPC Provider is intended to be used in conjunction with [EOSIO SDK for Java To use Java RPC Provider with EOSIO SDK for Java in your app, add the following modules to your `build.gradle`: ```groovy -implementation 'one.block:eosiojava:0.1.2' -implementation 'one.block:eosio-java-rpc-provider:0.1.1' +implementation 'one.block:eosiojava:0.1.3' +implementation 'one.block:eosio-java-rpc-provider:0.1.3' ``` The `build.gradle` files for the project currently include configurations for publishing the project to Artifactory. These should be removed if you are not planning to use Artifactory or you will encounter build errors. To do so, make the changes marked by comments throughout the files. @@ -67,6 +67,7 @@ Please note that only the following five RPC endpoints have proper response mars Call getRawAbi(@Body GetRawAbiRequest getRawAbiRequest); Call getRequiredKeys(@Body GetRequiredKeysRequest getRequiredKeysRequest); Call pushTransaction(@Body PushTransactionRequest pushTransactionRequest); + Call sendTransaction(@Body SendTransactionRequest sendTransactionRequest); ``` The remaining endpoints accept a `RequestBody` as the request object and return a raw JSON string as the response. We aim to continue improving response marshalling for all endpoints, and we invite you to [help us improve](https://github.com/EOSIO/eosio-java-android-rpc-provider/issues/22) responses too. Check [EosioJavaRpcProviderImpl](https://github.com/EOSIO/eosio-java-android-rpc-provider/blob/master/eosiojavarpcprovider/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java) for more details. @@ -91,6 +92,7 @@ String balance = jsonArray.getString(0); 10/09/20 Version 0.1.1 The version consumes the eosio-java library version 0.1.2 and provides functionality equal to the older eosio-java-android-rpc-provider 0.1.1 release. +Version 0.1.3 The version consumes the eosio-java library version 0.1.3 and adds support for the send_transaction endpoint, return values and kv tables. ## Want to help? From 99246bb7d96006d907526349b3d8b5061998f30f Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 22 Oct 2020 15:45:26 -0500 Subject: [PATCH 03/17] Add support for get_kv_table_rows and get_block_info. --- build.gradle | 4 +- .../error/EosioJavaRpcErrorConstants.java | 5 ++ .../EosioJavaRpcProviderImpl.java | 36 +++++++++- .../IEosioJavaRpcProviderApi.java | 20 ++++++ .../RpcProviderUnitTest.java | 67 +++++++++++++++++++ .../RpcTestConstants.java | 32 +++++++++ 6 files changed, 161 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 5b1ec95..aa3fb24 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'one.block:eosiojava:0.1.3-eosio2.1' + implementation 'one.block:eosiojava:0.1.5-eosio2.1' implementation 'org.jetbrains:annotations:17.0.0' implementation (group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1') { @@ -59,7 +59,7 @@ test { def libraryGroupId = 'one.block' def libraryArtifactId = 'eosio-java-rpc-provider' -def libraryVersion = '0.1.3-eosio2.1' +def libraryVersion = '0.1.4-eosio2.1' task sourcesJar(type: Jar, dependsOn: classes){ classifier = 'sources' diff --git a/src/main/java/one/block/eosiojavarpcprovider/error/EosioJavaRpcErrorConstants.java b/src/main/java/one/block/eosiojavarpcprovider/error/EosioJavaRpcErrorConstants.java index c3a2ed6..47abbb4 100644 --- a/src/main/java/one/block/eosiojavarpcprovider/error/EosioJavaRpcErrorConstants.java +++ b/src/main/java/one/block/eosiojavarpcprovider/error/EosioJavaRpcErrorConstants.java @@ -103,6 +103,11 @@ public class EosioJavaRpcErrorConstants { */ public static final String RPC_PROVIDER_ERROR_GET_TABLE_ROWS = "Error get table rows."; + /** + * Error message gets thrown if {@link EosioJavaRpcProviderImpl#getKvTableRows(RequestBody)} returns error. + */ + public static final String RPC_PROVIDER_ERROR_GET_KV_TABLE_ROWS = "Error get kv table rows."; + /** * Error message gets thrown if {@link EosioJavaRpcProviderImpl#getCode(RequestBody)} returns error. */ diff --git a/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java b/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java index c4269c4..d413679 100644 --- a/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java +++ b/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java @@ -139,7 +139,6 @@ private O processCall(Call call) throws Exception { * @return GetBlockRsponse on successful return. * @throws GetBlockRpcError Thrown if any errors occur calling or processing the request. */ - @Override public @NotNull GetBlockResponse getBlock(GetBlockRequest getBlockRequest) throws GetBlockRpcError { try { @@ -151,6 +150,24 @@ private O processCall(Call call) throws Exception { } } + /** + * Issue a getBlockInfo() call to the blockchain and process the response. + * @param getBlockInfoRequest Info about a specific block. + * @return GetBlockInfoResponse on successful return. + * @throws GetBlockInfoRpcError Thrown if any errors occur calling or processing the request. + */ + @Override + public @NotNull GetBlockInfoResponse getBlockInfo(GetBlockInfoRequest getBlockInfoRequest) + throws GetBlockInfoRpcError { + try { + Call syncCall = this.rpcProviderApi.getBlockInfo(getBlockInfoRequest); + return processCall(syncCall); + } catch (Exception ex) { + throw new GetBlockInfoRpcError(EosioJavaRpcErrorConstants.RPC_PROVIDER_ERROR_GETTING_BLOCK_INFO, + ex); + } + } + /** * Issue a getRawAbi() request to the blockchain and process the response. * @param getRawAbiRequest Info about a specific smart contract. @@ -392,6 +409,23 @@ private O processCall(Call call) throws Exception { } } + /** + * Issue a getKvTableRows() call to the blockchain and process the response. + * @param requestBody request body of get_kv_table_rows API + * @return String content of ResponseBody on successful return. + * @throws RpcProviderError Thrown if any errors occur calling or processing the request. + */ + public @NotNull String getKvTableRows(RequestBody requestBody) throws RpcProviderError { + try { + Call syncCall = this.rpcProviderApi.getKvTableRows(requestBody); + try(ResponseBody responseBody = processCall(syncCall)) { + return responseBody.string(); + } + } catch (Exception ex) { + throw new RpcProviderError(EosioJavaRpcErrorConstants.RPC_PROVIDER_ERROR_GET_KV_TABLE_ROWS, ex); + } + } + /** * Issue a getCode() call to the blockchain and process the response. * @param requestBody request body of get_code API diff --git a/src/main/java/one/block/eosiojavarpcprovider/implementations/IEosioJavaRpcProviderApi.java b/src/main/java/one/block/eosiojavarpcprovider/implementations/IEosioJavaRpcProviderApi.java index 7f8c606..388b64a 100644 --- a/src/main/java/one/block/eosiojavarpcprovider/implementations/IEosioJavaRpcProviderApi.java +++ b/src/main/java/one/block/eosiojavarpcprovider/implementations/IEosioJavaRpcProviderApi.java @@ -37,6 +37,16 @@ public interface IEosioJavaRpcProviderApi { @POST("v1/chain/get_block") Call getBlock(@Body GetBlockRequest getBlockRequest); + /** + * Retrofit POST call to "chain/get_block_info" to an EOSIO blockchain. + * This method gets called from {@link EosioJavaRpcProviderImpl#getBlockInfo(GetBlockInfoRequest)} to get info/status of a specific block in the request. + * + * @param getBlockInfoRequest of a specific block. + * @return Executable {@link Call} to return {@link GetBlockResponse} has the info/status of a specific block in the request. + */ + @POST("v1/chain/get_block_info") + Call getBlockInfo(@Body GetBlockInfoRequest getBlockInfoRequest); + /** * Retrofit POST call to "chain/get_raw_abi" to an EOSIO blockchain. * This method gets called from {@link EosioJavaRpcProviderImpl#getRawAbi(GetRawAbiRequest)} to get serialized ABI of a smart contract in the request. @@ -181,6 +191,16 @@ public interface IEosioJavaRpcProviderApi { @POST("v1/chain/get_table_rows") Call getTableRows(@Body RequestBody requestBody); + /** + * Retrofit POST call to "chain/get_kv_table_rows" to an EOSIO blockchain. + * This method gets called from {@link EosioJavaRpcProviderImpl#getKvTableRows(RequestBody)} + * + * @param requestBody the request body to call 'get_kv_table_rows' API + * @return Executable {@link Call} to return {@link ResponseBody} of 'get_table_rows' API + */ + @POST("v1/chain/get_kv_table_rows") + Call getKvTableRows(@Body RequestBody requestBody); + /** * Retrofit POST call to "chain/get_code" to an EOSIO blockchain. * This method gets called from {@link EosioJavaRpcProviderImpl#getCode(RequestBody)} diff --git a/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java b/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java index a08b032..958817f 100644 --- a/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java +++ b/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java @@ -103,6 +103,39 @@ public void getBlockTest() { } + @Test + public void getBlockInfoTest() { + + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setResponseCode(200).setBody(GET_BLOCK_INFO_RESPONSE)); + + try { + server.start(); + String baseUrl = server.url("/").toString(); + + EosioJavaRpcProviderImpl rpcProvider = new EosioJavaRpcProviderImpl( + baseUrl); + GetBlockInfoRequest request = new GetBlockInfoRequest(new BigInteger("25260032")); + GetBlockInfoResponse response = rpcProvider.getBlockInfo(request); + assertNotNull(response); + assertEquals("0181700002e623f2bf291b86a10a5cec4caab4954d4231f31f050f4f86f26116", + response.getId()); + assertEquals(new BigInteger("2249927103"), response.getRefBlockPrefix()); + assertEquals("de5493939e3abdca80deeab2fc9389cc43dc1982708653cfe6b225eb788d6659", + response.getActionMroot()); + } catch (Exception ex) { + fail("Should not get exception when calling getBlockInfo(): " + ex.getLocalizedMessage() + + "\n" + getStackTraceString(ex)); + } finally { + try { + server.shutdown(); + } catch (Exception ex) { + // No need for anything here. + } + } + + } + @Test public void getRawAbiTest() { @@ -748,6 +781,40 @@ public void testGetTableRowsRpcCall() { } } + @Test + public void testGetKvTableRowsRpcCall() { + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setResponseCode(200).setBody(GET_KV_TABLE_ROWS_RESPONSE)); + + try { + server.start(); + String baseUrl = server.url("/").toString(); + + EosioJavaRpcProviderImpl rpcProvider = new EosioJavaRpcProviderImpl( + baseUrl); + + RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), GET_KV_TABLE_ROWS_REQUEST); + String response = rpcProvider.getKvTableRows(requestBody); + assertNotNull(response); + + JSONObject jsonObject = (JSONObject)parser.parse(response); + JSONArray jsonArray = (JSONArray)jsonObject.get("rows"); + assertEquals(1, jsonArray.size()); + String firstSerializedResult = (String)jsonArray.get(0); + assertEquals("002462663538316265652d396632632d343437622d393461642d3738653439383462366635312462663538316265652d396632632d343437622d393461642d37386534393834623666353100000000004013cd2462663538316265652d396632632d343437622d393461642d3738653439383462366635311a57726974652048656c6c6f20576f726c6420436f6e74726163742462663538316265652d396632632d343437622d393461642d373865343938346236663531002462663538316265652d396632632d343437622d393461642d37386534393834623666353194398a5f", + firstSerializedResult); + } catch (Exception ex) { + fail("Should not get exception when calling getKvTableRows(): " + ex.getLocalizedMessage() + + "\n" + getStackTraceString(ex)); + } finally { + try { + server.shutdown(); + } catch (Exception ex) { + // No need for anything here. + } + } + } + @Test public void testGetCodeRpcCall() { MockWebServer server = new MockWebServer(); diff --git a/src/test/java/one/block/eosiojavarpcprovider/RpcTestConstants.java b/src/test/java/one/block/eosiojavarpcprovider/RpcTestConstants.java index ac3fd14..bb747c0 100644 --- a/src/test/java/one/block/eosiojavarpcprovider/RpcTestConstants.java +++ b/src/test/java/one/block/eosiojavarpcprovider/RpcTestConstants.java @@ -36,6 +36,20 @@ public class RpcTestConstants { + " \"ref_block_prefix\": 2249927103\n" + "}"; + public static final String GET_BLOCK_INFO_RESPONSE = "{\n" + + " \"timestamp\": \"2019-02-21T18:31:40.000\",\n" + + " \"producer\": \"blkproducer2\",\n" + + " \"confirmed\": 0,\n" + + " \"previous\": \"01816fffa4548475add3c45d0e0620f59468a6817426137b37851c23ccafa9cc\",\n" + + " \"transaction_mroot\": \"0000000000000000000000000000000000000000000000000000000000000000\",\n" + + " \"action_mroot\": \"de5493939e3abdca80deeab2fc9389cc43dc1982708653cfe6b225eb788d6659\",\n" + + " \"schedule_version\": 3,\n" + + " \"producer_signature\": \"SIG_K1_KZ3ptku7orAgcyMzd9FKW4jPC9PvjW9BGadFoyxdJFWM44VZdjW28DJgDe6wkNHAxnpqCWSzaBHB1AfbXBUn3HDzetemoA\",\n" + + " \"id\": \"0181700002e623f2bf291b86a10a5cec4caab4954d4231f31f050f4f86f26116\",\n" + + " \"block_num\": 25260032,\n" + + " \"ref_block_prefix\": 2249927103\n" + + "}"; + public static final String GET_RAW_EOSIO_TOKEN_ABI_RESPONSE = "{\n" + " \"account_name\": \"eosio.token\",\n" + " \"code_hash\": \"3e0cf4172ab025f9fff5f1db11ee8a34d44779492e1d668ae1dc2d129e865348\",\n" @@ -679,6 +693,24 @@ public class RpcTestConstants { " \"more\": false\n" + "}"; + public static final String GET_KV_TABLE_ROWS_REQUEST = "{\n" + + " \"json\" : false\n" + + " \"code\" : \"todo\"\n" + + " \"table\" : \"todo\"\n" + + " \"encode_type\" : \"string\"\n" + + " \"index_name\" : \"uuid\"\n" + + " \"index_value\" : \"bf581bee-9f2c-447b-94ad-78e4984b6f51\"\n" + + " \"reverse\" : false\n" + + " \"show_payer\" : false\n" + + "}"; + public static final String GET_KV_TABLE_ROWS_RESPONSE = "{\n" + + " \"rows\": [\n" + + " \"002462663538316265652d396632632d343437622d393461642d3738653439383462366635312462663538316265652d396632632d343437622d393461642d37386534393834623666353100000000004013cd2462663538316265652d396632632d343437622d393461642d3738653439383462366635311a57726974652048656c6c6f20576f726c6420436f6e74726163742462663538316265652d396632632d343437622d393461642d373865343938346236663531002462663538316265652d396632632d343437622d393461642d37386534393834623666353194398a5f\"\n" + + " ],\n" + + " \"more\": false,\n" + + " \"next_key\": \"\"\n" + + "}"; + public static final String GET_TABLE_BY_SCOPE_REQUEST = "{\n" + "\t\"code\" : \"eosio.token\"\n" + "\t\"table\" : \"accounts\"\n" + From 280d3718eac87214dea148e6abcafebda63a05ac Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 22 Oct 2020 16:00:03 -0500 Subject: [PATCH 04/17] Update README file. --- README.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 19d0911..41d6dd4 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ Java RPC Provider is intended to be used in conjunction with [EOSIO SDK for Java To use Java RPC Provider with EOSIO SDK for Java in your app, add the following modules to your `build.gradle`: ```groovy -implementation 'one.block:eosiojava:0.1.3' -implementation 'one.block:eosio-java-rpc-provider:0.1.3' +implementation 'one.block:eosiojava:0.1.5' +implementation 'one.block:eosio-java-rpc-provider:0.1.4' ``` The `build.gradle` files for the project currently include configurations for publishing the project to Artifactory. These should be removed if you are not planning to use Artifactory or you will encounter build errors. To do so, make the changes marked by comments throughout the files. @@ -63,10 +63,9 @@ Please note that only the following five RPC endpoints have proper response mars ```java Call getInfo(); - Call getBlock(@Body GetBlockRequest getBlockRequest); + Call getBlockInfo(@Body GetBlockInfoRequest getBlockInfoRequest); Call getRawAbi(@Body GetRawAbiRequest getRawAbiRequest); Call getRequiredKeys(@Body GetRequiredKeysRequest getRequiredKeysRequest); - Call pushTransaction(@Body PushTransactionRequest pushTransactionRequest); Call sendTransaction(@Body SendTransactionRequest sendTransactionRequest); ``` @@ -89,10 +88,19 @@ String balance = jsonArray.getString(0); ## Releases -10/09/20 +10/01/20 +Version 0.1.1 +This version consumes the eosio-java library version 0.1.2 and provides functionality equal to the older eosio-java-android-rpc-provider 0.1.1 release. -Version 0.1.1 The version consumes the eosio-java library version 0.1.2 and provides functionality equal to the older eosio-java-android-rpc-provider 0.1.1 release. -Version 0.1.3 The version consumes the eosio-java library version 0.1.3 and adds support for the send_transaction endpoint, return values and kv tables. +10/09/20 +Version 0.1.3 +This version consumes the eosio-java library version 0.1.3 and adds support for the send_transaction endpoint, and return values. + +10/22/20 +Version 0.1.4 +This version consumes the eosio-java library version 0.1.5 and adds support for the get_block_info, and get_kv_table_rows endpoints. +GetBlockInfo has replaced GetBlock in the IRPCProvider interface since it is the preferred method for getting the information required to calculate TAPOS. GetBlock is still available. +PushTransaction has been removed from IRPCProvider in favor of SendTransaction. PushTransaction is still available. ## Want to help? From 089a913d214f6ab00efd3ff60d53bb07f7c4f88c Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 29 Oct 2020 17:39:50 -0500 Subject: [PATCH 05/17] Update eosio-java dependency to 0.1.6-eosio2.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index aa3fb24..f1b1355 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'one.block:eosiojava:0.1.5-eosio2.1' + implementation 'one.block:eosiojava:0.1.6-eosio2.1' implementation 'org.jetbrains:annotations:17.0.0' implementation (group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1') { From 07378505244c7f49d065fd3d5586f74c9e67b38e Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Fri, 30 Oct 2020 10:39:05 -0500 Subject: [PATCH 06/17] Remove override from pushTransaction. --- .../implementations/EosioJavaRpcProviderImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java b/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java index d413679..046b0ab 100644 --- a/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java +++ b/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java @@ -210,7 +210,6 @@ private O processCall(Call call) throws Exception { * @return PushTransactionResponse on successful return. * @throws PushTransactionRpcError Thrown if any errors occur calling or processing the request. */ - @Override public @NotNull PushTransactionResponse pushTransaction( PushTransactionRequest pushTransactionRequest) throws PushTransactionRpcError { try { From 2b94b34f2f44b9fca9555d5c14f777205d7efd58 Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Wed, 4 Nov 2020 10:37:13 -0600 Subject: [PATCH 07/17] Add EXAMPLES.md file for advanced snippets. --- EXAMPLES.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 EXAMPLES.md diff --git a/EXAMPLES.md b/EXAMPLES.md new file mode 100644 index 0000000..d0742e2 --- /dev/null +++ b/EXAMPLES.md @@ -0,0 +1,101 @@ +# EOSIO SDK for Java: RPC Provider Examples + +EOSIO SDK for Java: RPC Provider contains an extensive set of functionality beyond the basics required for transactions. The code snippets below show how to use some of this extended functionality. It is important to note that these are simply example snippets and may not work the way you expect if you just copy and paste them into a method. + +Note: For clarity, some of these examples may use the soft key signature provider which is NOT recommended for production use! + +## Extended RPC Provider Examples + +### Get Account Information +This snippet retrieves information for an account on the blockchain. There are several layers of response to unpack if all information is desired. Some portions of the response are not fully unmarshalled, either due to size or because the responses can vary in structure. These are returned as general `Map` objects. The [NODEOS Reference](https://developers.eos.io/eosio-nodeos/reference) is helpful for decoding the parts of responses that are not fully unmarshalled. + +```java +try { + EosioJavaRpcProviderImpl rpcProvider = new EosioJavaRpcProviderImpl( + "https://my.test.blockchain"); + String testAccount = "test_account"; + + RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), "{\"name\":\""+testAccount+"\"}"); + String response = rpcProvider.getAccount(requestBody); + + JSONObject jsonObject = (JSONObject)parser.parse(response); + + String account_name = (String) jsonObject.get("account_name"); + BigInteger ramQuota = (BigInteger) jsonObject.get("ram_quota"); + JSONArray permissions = (JSONArray) jsonObject.get("permissions"); + JSONObject permission = (JSONObject) permissions.get(0); + String permissionName = (String) permission.get("perm_name"); + // Keep going for more information... +} catch (Exception ex) { + println("Exception when calling getAccount(): " + ex.getLocalizedMessage() + + "\n" + getStackTraceString(ex)); +} +``` + +### Getting Transaction Information From the History Plugin + +This snippet returns information on a transaction from the History API plugin. Only a few fields are shown in the decoding example below. The [NODEOS Reference](https://developers.eos.io/eosio-nodeos/reference) is helpful for decoding the parts of responses that are not fully unmarshalled. + +```java +try { + EosioJavaRpcProviderImpl rpcProvider = new EosioJavaRpcProviderImpl( + "https://my.test.blockchain"); + + String getTransactionRequest = "{\n" + + "\t\"id\": \"transaction id\",\n" + + "\t\t\"block_num_hint\": 49420058\n" + + "}"; + + RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), getTransactionRequest); + String response = rpcProvider.getTransaction(requestBody); + + JSONObject jsonObject = (JSONObject)parser.parse(response); + String transactionId = (String) jsonObject.get("id"); + Long blockNum = (Long) jsonObject.get("block_num"); +} catch (Exception ex) { + println("Exception when calling getTransaction(): " + ex.getLocalizedMessage() + + "\n" + getStackTraceString(ex)); +} +``` + +### Retrieving Values From KV Tables + +This snippet retrieves values from a KV table defined by a contract on the server. The example below is requesting the values from the contract "todo" in the table named "todo". It is querying the index named "uuid" for the value "bf581bee-9f2c-447b-94ad-78e4984b6f51". The encoding type of the indexValue being supplied is "string". Other valid values include: "bytes", "dec", "hex" and "name", depending on the index type. + +```java +// Creating RPC Provider +IRPCProvider rpcProvider; +try { + rpcProvider = new EosioJavaRpcProviderImpl("https://my.test.blockchain", ENABLE_NETWORK_LOG); +} catch (EosioJavaRpcProviderInitializerError eosioJavaRpcProviderInitializerError) { + eosioJavaRpcProviderInitializerError.printStackTrace(); + println(Boolean.toString(false), eosioJavaRpcProviderInitializerError.getMessage()); + return null; +} + +String getKvTablesRequestJson = "{\n" + + " \"json\" : false\n" + + " \"code\" : \"todo\"\n" + + " \"table\" : \"todo\"\n" + + " \"encode_type\" : \"string\"\n" + + " \"index_name\" : \"uuid\"\n" + + " \"index_value\" : \"bf581bee-9f2c-447b-94ad-78e4984b6f51\"\n" + + " \"reverse\" : false\n" + + "}"; + + // If the RPC Provider was declared as the IRPCProvider interface type you have to cast it. + EosioJavaRpcProviderImpl fullRpcProvider = (EosioJavaRpcProviderImpl)rpcProvider; + + RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), getKvTablesRequestJson); + try { + println("Requesting KV table rows..."); + String response = fullRpcProvider.getKvTableRows(requestBody); + JSONParser parser = new JSONParser(); + JSONObject jsonObject = (JSONObject)parser.parse(response); + JSONArray jsonArray = (JSONArray)jsonObject.get("rows"); + String serializedResult = (String)jsonArray.get(0); + println("Your row result (serialized) is: " + serializedResult); + } catch (Exception getKvTableRowError) { + this.publishProgress(Boolean.toString(false), "Error getting table rows: " + getKvTableRowError.getLocalizedMessage()); + } +``` \ No newline at end of file From 159db10e5db8ff0f307e5e353f7b49b3d418c3c3 Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 5 Nov 2020 11:36:21 -0600 Subject: [PATCH 08/17] Set version numbers to 1.0.0 for merge to develop and release. Update README to reflect new version numbers. --- README.md | 8 ++++++-- build.gradle | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 41d6dd4..c7f6de1 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ Java RPC Provider is intended to be used in conjunction with [EOSIO SDK for Java To use Java RPC Provider with EOSIO SDK for Java in your app, add the following modules to your `build.gradle`: ```groovy -implementation 'one.block:eosiojava:0.1.5' -implementation 'one.block:eosio-java-rpc-provider:0.1.4' +implementation 'one.block:eosiojava:1.0.0' +implementation 'one.block:eosio-java-rpc-provider:1.0.0' ``` The `build.gradle` files for the project currently include configurations for publishing the project to Artifactory. These should be removed if you are not planning to use Artifactory or you will encounter build errors. To do so, make the changes marked by comments throughout the files. @@ -102,6 +102,10 @@ This version consumes the eosio-java library version 0.1.5 and adds support for GetBlockInfo has replaced GetBlock in the IRPCProvider interface since it is the preferred method for getting the information required to calculate TAPOS. GetBlock is still available. PushTransaction has been removed from IRPCProvider in favor of SendTransaction. PushTransaction is still available. +11/05/2020 +Version 1.0.0 +Support for EOSIO 3.0 functionality, including action return values and KV tables. Project jar implemenation that works on both Android and server side Java. + ## Want to help? Interested in contributing? That's awesome! Here are some [Contribution Guidelines](./CONTRIBUTING.md) and the [Code of Conduct](./CONTRIBUTING.md#conduct). diff --git a/build.gradle b/build.gradle index f1b1355..0794c3b 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'one.block:eosiojava:0.1.6-eosio2.1' + implementation 'one.block:eosiojava:1.0.0' implementation 'org.jetbrains:annotations:17.0.0' implementation (group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1') { @@ -59,7 +59,7 @@ test { def libraryGroupId = 'one.block' def libraryArtifactId = 'eosio-java-rpc-provider' -def libraryVersion = '0.1.4-eosio2.1' +def libraryVersion = '1.0.0' task sourcesJar(type: Jar, dependsOn: classes){ classifier = 'sources' From 04711e792e82ab424b25656849a8d96981d3ad94 Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 5 Nov 2020 16:37:58 -0600 Subject: [PATCH 09/17] Fix cast issue in EXAMPLES snippet. --- EXAMPLES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index d0742e2..944975c 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -21,7 +21,7 @@ try { JSONObject jsonObject = (JSONObject)parser.parse(response); String account_name = (String) jsonObject.get("account_name"); - BigInteger ramQuota = (BigInteger) jsonObject.get("ram_quota"); + Double ramQuota = (Double) jsonObject.get("ram_quota"); JSONArray permissions = (JSONArray) jsonObject.get("permissions"); JSONObject permission = (JSONObject) permissions.get(0); String permissionName = (String) permission.get("perm_name"); From d1dc818a3d0d6bc5238677cc7631756002667029 Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Fri, 6 Nov 2020 16:44:59 -0600 Subject: [PATCH 10/17] Create LiveServerUnitTest to run against an actual blockchain instance for testing. Ignored by default. --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 0794c3b..3ebfddd 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,9 @@ dependencies { testImplementation 'com.squareup.retrofit2:converter-gson:2.5.0' testImplementation 'com.squareup.okhttp3:logging-interceptor:3.12.1' testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.1' + // Uncomment if running LiveServerUnitTest + testImplementation 'one.block:eosiojavasoftkeysignatureprovider:1.0.0' + testImplementation 'one.block:eosio-java-abieos-serialization-provider:1.0.0' } test { From 5e260c30f4b3984ccee83901232e95858eb7325c Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Fri, 6 Nov 2020 16:49:03 -0600 Subject: [PATCH 11/17] Add new unit test file. Not sure why commit -a did not... --- .../LiveServerUnitTest.java | 265 ++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java diff --git a/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java b/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java new file mode 100644 index 0000000..5c7d68e --- /dev/null +++ b/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java @@ -0,0 +1,265 @@ +package one.block.eosiojavarpcprovider; + +import okhttp3.RequestBody; +import one.block.eosiojava.error.EosioError; +import one.block.eosiojava.error.serializationProvider.SerializationProviderError; +import one.block.eosiojava.error.session.TransactionPrepareError; +import one.block.eosiojava.error.session.TransactionSignAndBroadCastError; +import one.block.eosiojava.implementations.ABIProviderImpl; +import one.block.eosiojava.interfaces.IABIProvider; +import one.block.eosiojava.interfaces.IRPCProvider; +import one.block.eosiojava.interfaces.ISerializationProvider; +import one.block.eosiojava.interfaces.ISignatureProvider; +import one.block.eosiojava.models.rpcProvider.Action; +import one.block.eosiojava.models.rpcProvider.Authorization; +import one.block.eosiojava.models.rpcProvider.response.Detail; +import one.block.eosiojava.models.rpcProvider.response.RPCResponseError; +import one.block.eosiojava.models.rpcProvider.response.SendTransactionResponse; +import one.block.eosiojava.session.TransactionProcessor; +import one.block.eosiojava.session.TransactionSession; +import one.block.eosiojavaabieosserializationprovider.AbiEosSerializationProviderImpl; +import one.block.eosiojavarpcprovider.error.EosioJavaRpcProviderCallError; +import one.block.eosiojavarpcprovider.error.EosioJavaRpcProviderInitializerError; +import one.block.eosiojavarpcprovider.implementations.EosioJavaRpcProviderImpl; +import one.block.eosiosoftkeysignatureprovider.SoftKeySignatureProviderImpl; +import one.block.eosiosoftkeysignatureprovider.error.ImportKeyError; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.Collections; + +import static junit.framework.TestCase.fail; +import static org.junit.Assert.*; + +// Remove this annotation to run the tests. +@Ignore +public class LiveServerUnitTest { + private JSONParser parser; + private ISerializationProvider serializationProvider; + private IRPCProvider rpcProvider; + private IABIProvider abiProvider; + private ISignatureProvider signatureProvider; + private TransactionSession session; + private TransactionProcessor processor; + + private static final String nodeUrl = "https://my.test.blockchain"; + private static final boolean ENABLE_NETWORK_LOG = true; + private static final String privateKey = "MyTestPrivateKey"; + + @Before + public void setup() { + this.parser = new JSONParser(); + + try { + serializationProvider = new AbiEosSerializationProviderImpl(); + } catch (SerializationProviderError serializationProviderError) { + fail(serializationProviderError.getMessage()); + serializationProviderError.printStackTrace(); + return; + } + + try { + rpcProvider = new EosioJavaRpcProviderImpl(nodeUrl, ENABLE_NETWORK_LOG); + } catch (EosioJavaRpcProviderInitializerError eosioJavaRpcProviderInitializerError) { + eosioJavaRpcProviderInitializerError.printStackTrace(); + fail(eosioJavaRpcProviderInitializerError.getMessage()); + return; + } + + abiProvider = new ABIProviderImpl(rpcProvider, serializationProvider); + signatureProvider = new SoftKeySignatureProviderImpl(); + + try { + ((SoftKeySignatureProviderImpl) signatureProvider).importKey(privateKey); + } catch (ImportKeyError importKeyError) { + importKeyError.printStackTrace(); + fail(importKeyError.getMessage()); + return; + } + + // Creating TransactionProcess + session = new TransactionSession(serializationProvider, rpcProvider, abiProvider, signatureProvider); + processor = session.getTransactionProcessor(); + } + + @After + public void cleanup() { + // Must destroy the abieos serialization provider context between tests or we will leak memory. + AbiEosSerializationProviderImpl serializationProviderImpl = (AbiEosSerializationProviderImpl)serializationProvider; + serializationProviderImpl.destroyContext(); + } + + @Test + public void tokenTransferTest() { + String jsonData = "{\n" + + "\"from\": \"" + "bob" + "\",\n" + + "\"to\": \"" + "alice" + "\",\n" + + "\"quantity\": \"" + "1.1234 SYS" + "\",\n" + + "\"memo\" : \"" + "hello" + "\"\n" + + "}"; + + Action action = new Action("eosio.token", "transfer", Collections.singletonList(new Authorization("bob", "active")), jsonData); + int index = 0; + try { + processor.prepare(Collections.singletonList(action)); + SendTransactionResponse response = processor.signAndBroadcast(); + assertNotNull("Transaction Id should not be null.", response.getTransactionId() ); + System.out.println("Finished! Your transaction id is: " + response.getTransactionId()); + } catch (TransactionPrepareError transactionPrepareError) { + transactionPrepareError.printStackTrace(); + fail(transactionPrepareError.getLocalizedMessage()); + } catch (TransactionSignAndBroadCastError transactionSignAndBroadCastError) { + transactionSignAndBroadCastError.printStackTrace(); + + RPCResponseError rpcResponseError = ErrorUtils.getBackendError(transactionSignAndBroadCastError); + if (rpcResponseError != null) { + String backendErrorMessage = ErrorUtils.getBackendErrorMessageFromResponse(rpcResponseError); + fail(backendErrorMessage); + } + fail(transactionSignAndBroadCastError.getMessage()); + } + } + + @Test + public void actionReturnTest() { + String jsonData = "{}"; + + Action action = new Action("returnvalue", "actionresret", Collections.singletonList(new Authorization("bob", "active")), jsonData); + int index = 0; + try { + processor.prepare(Collections.singletonList(action)); + SendTransactionResponse response = processor.signAndBroadcast(); + Double actionReturnValue = response.getActionValueAtIndex(index, Double.class); + assertNotNull("Transaction Id should not be null.", response.getTransactionId()); + System.out.println("Your transaction id is: " + response.getTransactionId()); + assertEquals(new Double(10.0), actionReturnValue); + System.out.println("Finished! Your action return value is: " + actionReturnValue.toString()); + } catch (TransactionPrepareError transactionPrepareError) { + transactionPrepareError.printStackTrace(); + fail(transactionPrepareError.getLocalizedMessage()); + } catch (TransactionSignAndBroadCastError transactionSignAndBroadCastError) { + transactionSignAndBroadCastError.printStackTrace(); + + RPCResponseError rpcResponseError = ErrorUtils.getBackendError(transactionSignAndBroadCastError); + if (rpcResponseError != null) { + String backendErrorMessage = ErrorUtils.getBackendErrorMessageFromResponse(rpcResponseError); + fail(backendErrorMessage); + } + + fail(transactionSignAndBroadCastError.getMessage()); + } catch (IndexOutOfBoundsException outOfBoundsError) { + fail("No action value at index: " + index); + } catch (ClassCastException castError) { + fail("Cannot cast action value to requested class"); + } + } + + @Test + public void getKvTableRowsTest() { + String getKvTablesRequestJson = "{\n" + + " \"json\" : true\n" + + " \"code\" : \"kvaddrbook\"\n" + + " \"table\" : \"kvaddrbook\"\n" + + " \"encode_type\" : \"name\"\n" + + " \"index_name\" : \"accname\"\n" + + " \"lower_bound\" : \"jane\"\n" + + " \"reverse\" : false\n" + + "}"; + + + EosioJavaRpcProviderImpl fullRpcProvider = (EosioJavaRpcProviderImpl)rpcProvider; + + RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), getKvTablesRequestJson); + try { + String response = fullRpcProvider.getKvTableRows(requestBody); + JSONParser parser = new JSONParser(); + JSONObject jsonObject = (JSONObject)parser.parse(response); + JSONArray jsonArray = (JSONArray)jsonObject.get("rows"); + // Right now we can only get back the serialized form of the rows so we're only checking that. + String jsonArrayStr = jsonArray.toString(); + assertTrue(jsonArrayStr.contains("\"0000000000a0a679044a616e6503446f650d31323334204d79\"")); + assertTrue(jsonArrayStr.contains("\"0000000000301b7d044a6f686e05536d6974680c313233204d\"")); + assertTrue(jsonArrayStr.contains("\"0000000000801d8d044c6f6973044c616e650d35343332204d\"")); + assertTrue(jsonArrayStr.contains("\"0000000000b555c6055374657665054a6f6e65730c33323120\"")); + System.out.println("Finished! Got back rows:" + jsonArrayStr); + } catch (Exception getKvTableRowError) { + fail("Error getting kv table rows: " + getKvTableRowError.getLocalizedMessage()); + } + } + + static class ErrorUtils { + + /** + * Recursively look for a specific error inside causes loop of an EosioError + * + * @param errorClass - the error class to find + * @param error - the error object to search + * @param - the generic class which extends from EosioError + * @return the error which class is specified by input. Return null if could not find the specific class. + */ + public static T getErrorObject(Class errorClass, Exception error) { + if (error.getClass() == errorClass) { + return (T) error; + } + + if (error.getCause() == null) { + return null; + } + + // Recursively look deeper + return getErrorObject(errorClass, (Exception) error.getCause()); + } + + /** + * Recursively look for the error message of a specific error inside causes loop of an EosioError + * + * @param errorClass - the error class to get the message + * @param error - the error object to search + * @return the error message which class is specified by input. Return the root cause message if could not find the specific class. + */ + public static String getError(Class errorClass, EosioError error) { + if (error.getClass() == errorClass || error.getCause() == null) { + return error.getMessage(); + } + + return getError(errorClass, (EosioError) error.getCause()); + } + + /** + * Get backend error class {@link RPCResponseError} if an backend error is available + * + * @param error the error class to get the backend error + * @return {@link RPCResponseError} object. Return null if input error does not contain any backend error. + */ + public static RPCResponseError getBackendError(EosioError error) { + EosioJavaRpcProviderCallError rpcError = ErrorUtils.getErrorObject(EosioJavaRpcProviderCallError.class, error); + if (rpcError != null) { + return rpcError.getRpcResponseError(); + } + + return null; + } + + /** + * Format and return a back end error message from a {@link RPCResponseError} object + * + * @param error the backend error + * @return Formatted backend error message from input + */ + public static String getBackendErrorMessageFromResponse(RPCResponseError error) { + StringBuilder detail = new StringBuilder(); + if (!error.getError().getDetails().isEmpty()) { + for (Detail errorDetail : error.getError().getDetails()) { + detail.append(errorDetail.getMessage()).append(" - "); + } + } + + return error.getMessage() + " - Code: " + error.getError().getCode() + " - What " + error.getError().getCode() + " - detail: " + detail.toString(); + } + } +} From c497fe56920198d006e89e108f3b33b31fc85c6d Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Mon, 9 Nov 2020 13:24:51 -0600 Subject: [PATCH 12/17] Update get_kv_table_rows tests with json results. --- .../eosiojavarpcprovider/LiveServerUnitTest.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java b/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java index 5c7d68e..a29b5a3 100644 --- a/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java +++ b/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java @@ -36,7 +36,7 @@ import static junit.framework.TestCase.fail; import static org.junit.Assert.*; -// Remove this annotation to run the tests. +// Comment this annotation to run the tests. @Ignore public class LiveServerUnitTest { private JSONParser parser; @@ -47,9 +47,9 @@ public class LiveServerUnitTest { private TransactionSession session; private TransactionProcessor processor; - private static final String nodeUrl = "https://my.test.blockchain"; + private static final String nodeUrl = "http://my.test.blockchain"; private static final boolean ENABLE_NETWORK_LOG = true; - private static final String privateKey = "MyTestPrivateKey"; + private static final String privateKey = "MyTestKey"; @Before public void setup() { @@ -182,10 +182,11 @@ public void getKvTableRowsTest() { JSONArray jsonArray = (JSONArray)jsonObject.get("rows"); // Right now we can only get back the serialized form of the rows so we're only checking that. String jsonArrayStr = jsonArray.toString(); - assertTrue(jsonArrayStr.contains("\"0000000000a0a679044a616e6503446f650d31323334204d79\"")); - assertTrue(jsonArrayStr.contains("\"0000000000301b7d044a6f686e05536d6974680c313233204d\"")); - assertTrue(jsonArrayStr.contains("\"0000000000801d8d044c6f6973044c616e650d35343332204d\"")); - assertTrue(jsonArrayStr.contains("\"0000000000b555c6055374657665054a6f6e65730c33323120\"")); + assertTrue(jsonArray.size() == 4); + JSONObject entry1 = (JSONObject)jsonArray.get(0); + assertEquals("jane", (String) entry1.get("account_name")); + assertEquals("Jane", (String) entry1.get("first_name")); + assertEquals("Doe", (String) entry1.get("last_name")); System.out.println("Finished! Got back rows:" + jsonArrayStr); } catch (Exception getKvTableRowError) { fail("Error getting kv table rows: " + getKvTableRowError.getLocalizedMessage()); From a70e23ec1bdd8c65bfa5a27a225de430277d9944 Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Wed, 18 Nov 2020 20:29:58 -0600 Subject: [PATCH 13/17] Address feedback from PR review. --- .../EosioJavaRpcProviderImpl.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java b/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java index 046b0ab..b5b3341 100644 --- a/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java +++ b/src/main/java/one/block/eosiojavarpcprovider/implementations/EosioJavaRpcProviderImpl.java @@ -2,9 +2,28 @@ import com.google.gson.Gson; -import one.block.eosiojava.error.rpcProvider.*; -import one.block.eosiojava.models.rpcProvider.request.*; -import one.block.eosiojava.models.rpcProvider.response.*; +import one.block.eosiojava.error.rpcProvider.GetBlockInfoRpcError; +import one.block.eosiojava.error.rpcProvider.GetBlockRpcError; +import one.block.eosiojava.error.rpcProvider.GetInfoRpcError; +import one.block.eosiojava.error.rpcProvider.GetRawAbiRpcError; +import one.block.eosiojava.error.rpcProvider.GetRequiredKeysRpcError; +import one.block.eosiojava.error.rpcProvider.PushTransactionRpcError; +import one.block.eosiojava.error.rpcProvider.RpcProviderError; +import one.block.eosiojava.error.rpcProvider.SendTransactionRpcError; +import one.block.eosiojava.models.rpcProvider.request.GetBlockInfoRequest; +import one.block.eosiojava.models.rpcProvider.request.GetBlockRequest; +import one.block.eosiojava.models.rpcProvider.request.GetRawAbiRequest; +import one.block.eosiojava.models.rpcProvider.request.GetRequiredKeysRequest; +import one.block.eosiojava.models.rpcProvider.request.PushTransactionRequest; +import one.block.eosiojava.models.rpcProvider.request.SendTransactionRequest; +import one.block.eosiojava.models.rpcProvider.response.GetBlockInfoResponse; +import one.block.eosiojava.models.rpcProvider.response.GetBlockResponse; +import one.block.eosiojava.models.rpcProvider.response.GetInfoResponse; +import one.block.eosiojava.models.rpcProvider.response.GetRawAbiResponse; +import one.block.eosiojava.models.rpcProvider.response.GetRequiredKeysResponse; +import one.block.eosiojava.models.rpcProvider.response.PushTransactionResponse; +import one.block.eosiojava.models.rpcProvider.response.RPCResponseError; +import one.block.eosiojava.models.rpcProvider.response.SendTransactionResponse; import org.jetbrains.annotations.NotNull; import java.util.Locale; @@ -15,7 +34,6 @@ import okhttp3.logging.HttpLoggingInterceptor; import okhttp3.logging.HttpLoggingInterceptor.Level; import one.block.eosiojava.interfaces.IRPCProvider; -//import one.block.eosiojavarpcprovider.BuildConfig; import one.block.eosiojavarpcprovider.error.EosioJavaRpcErrorConstants; import one.block.eosiojavarpcprovider.error.EosioJavaRpcProviderCallError; import one.block.eosiojavarpcprovider.error.EosioJavaRpcProviderInitializerError; From c45e775c3dcdd2fd0994fbafcc8b4406c13c48a9 Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 19 Nov 2020 08:44:37 -0600 Subject: [PATCH 14/17] Update from PR feedback on unit test assert. --- .../java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java b/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java index a29b5a3..3d1ab52 100644 --- a/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java +++ b/src/test/java/one/block/eosiojavarpcprovider/LiveServerUnitTest.java @@ -182,7 +182,7 @@ public void getKvTableRowsTest() { JSONArray jsonArray = (JSONArray)jsonObject.get("rows"); // Right now we can only get back the serialized form of the rows so we're only checking that. String jsonArrayStr = jsonArray.toString(); - assertTrue(jsonArray.size() == 4); + assertEquals(4, jsonArray.size()); JSONObject entry1 = (JSONObject)jsonArray.get(0); assertEquals("jane", (String) entry1.get("account_name")); assertEquals("Jane", (String) entry1.get("first_name")); From 51125f5a7c714321ff584201668f716f88e627cb Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 19 Nov 2020 10:41:41 -0600 Subject: [PATCH 15/17] Exclude junit from json-simple. Comment testImplementation dependencies for LiveServerUnitTest. --- build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3ebfddd..f95be87 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,7 @@ dependencies { implementation 'org.jetbrains:annotations:17.0.0' implementation (group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1') { exclude group: 'org.hamcrest', module: 'hamcrest-core' + exclude group: 'junit', module: 'junit' } api 'com.squareup.retrofit2:retrofit:2.5.0' api 'com.squareup.retrofit2:converter-gson:2.5.0' @@ -50,8 +51,8 @@ dependencies { testImplementation 'com.squareup.okhttp3:logging-interceptor:3.12.1' testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.1' // Uncomment if running LiveServerUnitTest - testImplementation 'one.block:eosiojavasoftkeysignatureprovider:1.0.0' - testImplementation 'one.block:eosio-java-abieos-serialization-provider:1.0.0' + // testImplementation 'one.block:eosiojavasoftkeysignatureprovider:1.0.0' + // testImplementation 'one.block:eosio-java-abieos-serialization-provider:1.0.0' } test { From 7ffbf70bc859357d12e19b2d06812c0fde379410 Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 19 Nov 2020 10:44:49 -0600 Subject: [PATCH 16/17] Put back testImplementation dependencies for LiveServerUnitTest. Even ignored it still has to compile. --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index f95be87..7040d58 100644 --- a/build.gradle +++ b/build.gradle @@ -50,9 +50,9 @@ dependencies { testImplementation 'com.squareup.retrofit2:converter-gson:2.5.0' testImplementation 'com.squareup.okhttp3:logging-interceptor:3.12.1' testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.1' - // Uncomment if running LiveServerUnitTest - // testImplementation 'one.block:eosiojavasoftkeysignatureprovider:1.0.0' - // testImplementation 'one.block:eosio-java-abieos-serialization-provider:1.0.0' + // These are for LiveServerUnitTest. + testImplementation 'one.block:eosiojavasoftkeysignatureprovider:1.0.0' + testImplementation 'one.block:eosio-java-abieos-serialization-provider:1.0.0' } test { From 1dda011244fd8997ab18aa6add22dda6a4607707 Mon Sep 17 00:00:00 2001 From: Steve McCoole Date: Thu, 19 Nov 2020 11:07:10 -0600 Subject: [PATCH 17/17] Update unit tests based on feedback to add specific catches in tests for errors. --- .../RpcProviderUnitTest.java | 147 ++++++++---------- 1 file changed, 61 insertions(+), 86 deletions(-) diff --git a/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java b/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java index 958817f..c90c77e 100644 --- a/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java +++ b/src/test/java/one/block/eosiojavarpcprovider/RpcProviderUnitTest.java @@ -1,26 +1,41 @@ package one.block.eosiojavarpcprovider; -import one.block.eosiojava.models.rpcProvider.request.*; -import one.block.eosiojava.models.rpcProvider.response.*; -import org.json.simple.*; +import one.block.eosiojava.error.rpcProvider.PushTransactionRpcError; +import one.block.eosiojava.error.rpcProvider.SendTransactionRpcError; +import one.block.eosiojava.models.rpcProvider.request.GetBlockInfoRequest; +import one.block.eosiojava.models.rpcProvider.request.GetBlockRequest; +import one.block.eosiojava.models.rpcProvider.request.GetRawAbiRequest; +import one.block.eosiojava.models.rpcProvider.request.GetRequiredKeysRequest; +import one.block.eosiojava.models.rpcProvider.request.PushTransactionRequest; +import one.block.eosiojava.models.rpcProvider.request.SendTransactionRequest; +import one.block.eosiojava.models.rpcProvider.response.GetBlockInfoResponse; +import one.block.eosiojava.models.rpcProvider.response.GetBlockResponse; +import one.block.eosiojava.models.rpcProvider.response.GetInfoResponse; +import one.block.eosiojava.models.rpcProvider.response.GetRawAbiResponse; +import one.block.eosiojava.models.rpcProvider.response.GetRequiredKeysResponse; +import one.block.eosiojava.models.rpcProvider.response.PushTransactionResponse; +import one.block.eosiojava.models.rpcProvider.response.RPCResponseError; +import one.block.eosiojava.models.rpcProvider.response.RpcError; +import one.block.eosiojava.models.rpcProvider.response.SendTransactionResponse; +import one.block.eosiojavarpcprovider.error.EosioJavaRpcProviderInitializerError; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.junit.Before; import org.junit.Test; +import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.math.BigInteger; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import okhttp3.RequestBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.SocketPolicy; -import one.block.eosiojava.error.rpcProvider.GetBlockRpcError; import one.block.eosiojava.models.rpcProvider.Action; import one.block.eosiojava.models.rpcProvider.Authorization; import one.block.eosiojava.models.rpcProvider.Transaction; @@ -224,9 +239,15 @@ public void pushTransactionTest() { assertNotNull(response); assertEquals("ae735820e26a7b771e1b522186294d7cbba035d0c31ca88237559d6c0a3bf00a", response.getTransactionId()); - } catch (Exception ex) { - fail("Should not get exception when calling pushTransaction(): " + ex.getLocalizedMessage() - + "\n" + getStackTraceString(ex)); + } catch (EosioJavaRpcProviderInitializerError eosioJavaRpcProviderInitializerError) { + fail("Should not get exception when initializing rpcProvider: " + eosioJavaRpcProviderInitializerError.getLocalizedMessage() + + "\n" + getStackTraceString(eosioJavaRpcProviderInitializerError)); + } catch (PushTransactionRpcError pushTransactionRpcError) { + fail("Should not get exception when pushing transaction: " + pushTransactionRpcError.getLocalizedMessage() + + "\n" + getStackTraceString(pushTransactionRpcError)); + } catch (IOException e) { + fail("Should not get exception starting mock webserver: " + e.getLocalizedMessage() + + "\n" + getStackTraceString(e)); } finally { try { server.shutdown(); @@ -258,11 +279,11 @@ public void pushTransactionErrorTest() { "C62A4F5C1CEF3D6D71BD000000000290AFC2D800EA3055000000405DA7ADBA0072CBDD956F52ACD910C3C958136D72F8560D1846BC7CF3157F5FBFB72D3001DE4597F4A1FDBECDA6D59C96A43009FC5E5D7B8F639B1269C77CEC718460DCC19CB30100A6823403EA3055000000572D3CCDCD0143864D5AF0FE294D44D19C612036CBE8C098414C4A12A5A7BB0BFE7DB155624800A6823403EA3055000000572D3CCDCD0100AEAA4AC15CFD4500000000A8ED32323B00AEAA4AC15CFD4500000060D234CD3DA06806000000000004454F53000000001A746865206772617373686F70706572206C69657320686561767900"); PushTransactionResponse response = rpcProvider.pushTransaction(request); fail("Push transaction should not succeed."); - } catch (Exception ex) { - assertEquals("Error pushing transaction.", ex.getLocalizedMessage()); - assertNotNull(ex.getCause()); - assertEquals("Bad status code: 500 (Server Error), returned from server. Additional error information: See further error information in RPCProviderError.", ex.getCause().getMessage()); - RPCResponseError rpcResponseError = ((EosioJavaRpcProviderCallError)ex.getCause()).getRpcResponseError(); + } catch (PushTransactionRpcError pushTransactionRpcError) { + assertEquals("Error pushing transaction.", pushTransactionRpcError.getLocalizedMessage()); + assertNotNull(pushTransactionRpcError.getCause()); + assertEquals("Bad status code: 500 (Server Error), returned from server. Additional error information: See further error information in RPCProviderError.", pushTransactionRpcError.getCause().getMessage()); + RPCResponseError rpcResponseError = ((EosioJavaRpcProviderCallError)pushTransactionRpcError.getCause()).getRpcResponseError(); assertNotNull(rpcResponseError); assertEquals(new BigInteger("500"), rpcResponseError.getCode()); assertEquals("Internal Service Error", rpcResponseError.getMessage()); @@ -270,6 +291,12 @@ public void pushTransactionErrorTest() { assertNotNull(rpcError); assertEquals(new BigInteger("3040005"), rpcError.getCode()); assertEquals("Expired Transaction", rpcError.getWhat()); + } catch (EosioJavaRpcProviderInitializerError eosioJavaRpcProviderInitializerError) { + fail("Should not get exception when initializing rpcProvider: " + eosioJavaRpcProviderInitializerError.getLocalizedMessage() + + "\n" + getStackTraceString(eosioJavaRpcProviderInitializerError)); + } catch (IOException e) { + fail("Should not get exception starting mock webserver: " + e.getLocalizedMessage() + + "\n" + getStackTraceString(e)); } finally { try { server.shutdown(); @@ -303,9 +330,15 @@ public void sendTransactionTest() { assertNotNull(response); assertEquals("ae735820e26a7b771e1b522186294d7cbba035d0c31ca88237559d6c0a3bf00a", response.getTransactionId()); - } catch (Exception ex) { - fail("Should not get exception when calling pushTransaction(): " + ex.getLocalizedMessage() - + "\n" + getStackTraceString(ex)); + } catch (EosioJavaRpcProviderInitializerError eosioJavaRpcProviderInitializerError) { + fail("Should not get exception when initializing rpcProvider: " + eosioJavaRpcProviderInitializerError.getLocalizedMessage() + + "\n" + getStackTraceString(eosioJavaRpcProviderInitializerError)); + } catch (SendTransactionRpcError sendTransactionRpcError) { + fail("Should not get exception when sending transaction: " + sendTransactionRpcError.getLocalizedMessage() + + "\n" + getStackTraceString(sendTransactionRpcError)); + } catch (IOException e) { + fail("Should not get exception starting mock webserver: " + e.getLocalizedMessage() + + "\n" + getStackTraceString(e)); } finally { try { server.shutdown(); @@ -337,11 +370,11 @@ public void sendTransactionErrorTest() { "C62A4F5C1CEF3D6D71BD000000000290AFC2D800EA3055000000405DA7ADBA0072CBDD956F52ACD910C3C958136D72F8560D1846BC7CF3157F5FBFB72D3001DE4597F4A1FDBECDA6D59C96A43009FC5E5D7B8F639B1269C77CEC718460DCC19CB30100A6823403EA3055000000572D3CCDCD0143864D5AF0FE294D44D19C612036CBE8C098414C4A12A5A7BB0BFE7DB155624800A6823403EA3055000000572D3CCDCD0100AEAA4AC15CFD4500000000A8ED32323B00AEAA4AC15CFD4500000060D234CD3DA06806000000000004454F53000000001A746865206772617373686F70706572206C69657320686561767900"); SendTransactionResponse response = rpcProvider.sendTransaction(request); fail("Push transaction should not succeed."); - } catch (Exception ex) { - assertEquals("Error sending transaction.", ex.getLocalizedMessage()); - assertNotNull(ex.getCause()); - assertEquals("Bad status code: 500 (Server Error), returned from server. Additional error information: See further error information in RPCProviderError.", ex.getCause().getMessage()); - RPCResponseError rpcResponseError = ((EosioJavaRpcProviderCallError)ex.getCause()).getRpcResponseError(); + } catch (SendTransactionRpcError sendTransactionRpcError) { + assertEquals("Error sending transaction.", sendTransactionRpcError.getLocalizedMessage()); + assertNotNull(sendTransactionRpcError.getCause()); + assertEquals("Bad status code: 500 (Server Error), returned from server. Additional error information: See further error information in RPCProviderError.", sendTransactionRpcError.getCause().getMessage()); + RPCResponseError rpcResponseError = ((EosioJavaRpcProviderCallError)sendTransactionRpcError.getCause()).getRpcResponseError(); assertNotNull(rpcResponseError); assertEquals(new BigInteger("500"), rpcResponseError.getCode()); assertEquals("Internal Service Error", rpcResponseError.getMessage()); @@ -349,6 +382,12 @@ public void sendTransactionErrorTest() { assertNotNull(rpcError); assertEquals(new BigInteger("3040005"), rpcError.getCode()); assertEquals("Expired Transaction", rpcError.getWhat()); + } catch (EosioJavaRpcProviderInitializerError eosioJavaRpcProviderInitializerError) { + fail("Should not get exception when initializing rpcProvider: " + eosioJavaRpcProviderInitializerError.getLocalizedMessage() + + "\n" + getStackTraceString(eosioJavaRpcProviderInitializerError)); + } catch (IOException e) { + fail("Should not get exception starting mock webserver: " + e.getLocalizedMessage() + + "\n" + getStackTraceString(e)); } finally { try { server.shutdown(); @@ -391,70 +430,6 @@ public void getInfoTimeoutTest() { } - // Is this test necessary? -// @Test -// public void getBlockAsyncTest() { -// -// // This test shows how an RPC provider call might be made asynchronously. -// -// final CountDownLatch testLock = new CountDownLatch(1); -// -// MockWebServer server = new MockWebServer(); -// server.enqueue(new MockResponse().setResponseCode(200).setBody(GET_BLOCK_RESPONSE)); -// -// try { -// server.start(); -// String baseUrl = server.url("/").toString(); -// -// final EosioJavaRpcProviderImpl rpcProvider = new EosioJavaRpcProviderImpl( -// baseUrl); -// GetBlockRequest[] request = { new GetBlockRequest("25260032") }; -// -// AsyncTask asyncTask = new AsyncTask() { -// GetBlockRpcError getBlockError = null; -// @Override -// protected GetBlockResponse doInBackground(GetBlockRequest... getBlockRequests) { -// // Here we are on a background thread. -// GetBlockResponse response = null; -// try { -// response = rpcProvider.getBlock(getBlockRequests[0]); -// } catch (GetBlockRpcError err) { -// getBlockError = err; -// } -// return response; -// } -// -// protected void onPostExecute(GetBlockResponse response) { -// // Here we are back on the main thread and could update the UI. -// assertNotNull(response); -// assertEquals("0181700002e623f2bf291b86a10a5cec4caab4954d4231f31f050f4f86f26116", -// response.getId()); -// assertEquals(new BigInteger("2249927103"), response.getRefBlockPrefix()); -// assertEquals("de5493939e3abdca80deeab2fc9389cc43dc1982708653cfe6b225eb788d6659", -// response.getActionMroot()); -// testLock.countDown(); -// } -// }.execute(request); -// -// try { -// testLock.await(5000, TimeUnit.MILLISECONDS); -// } catch (InterruptedException interruptedException) { -// fail("Interrupted waiting for getBlock() to complete: " + -// interruptedException.getLocalizedMessage()); -// } -// -// } catch (Exception ex) { -// fail("Should not get exception when calling getBlock(): " + ex.getLocalizedMessage()); -// } finally { -// try { -// server.shutdown(); -// } catch (Exception ex) { -// // No need for anything here. -// } -// } -// -// } - @Test public void testGetAccountRpcCall() { MockWebServer server = new MockWebServer();