From 42c856bfe7c35acd60f9e867bf02485d81a3457e Mon Sep 17 00:00:00 2001 From: duanyytop Date: Mon, 29 Jun 2020 10:58:46 +0800 Subject: [PATCH 01/15] chore(deps): Upgrade gradle and shadow version --- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 0232abea4..37e11873f 100644 --- a/build.gradle +++ b/build.gradle @@ -17,12 +17,12 @@ buildscript { dependencies { classpath 'io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.21.2' - classpath 'com.github.jengelman.gradle.plugins:shadow:5.1.0' + classpath 'com.github.jengelman.gradle.plugins:shadow:6.0.0' } } plugins { - id 'com.github.johnrengelman.shadow' version '5.2.0' + id 'com.github.johnrengelman.shadow' version '6.0.0' id 'java' id 'com.github.sherter.google-java-format' version '0.8' id 'com.jfrog.bintray' version '1.8.5' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 44e7c4d1d..622ab64a3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From e5eef53b98f671620f5d8c05c0cc7b1e62f7674f Mon Sep 17 00:00:00 2001 From: duanyytop Date: Mon, 29 Jun 2020 14:42:10 +0800 Subject: [PATCH 02/15] feat: Add batch rpc request --- .../main/java/org/nervos/ckb/service/Api.java | 12 ++++++ .../org/nervos/ckb/service/RpcResponse.java | 14 +++++++ .../org/nervos/ckb/service/RpcService.java | 38 ++++++++++++------- ckb/src/test/java/service/ApiTest.java | 38 +++++++++++++++++++ 4 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 ckb/src/main/java/org/nervos/ckb/service/RpcResponse.java diff --git a/ckb/src/main/java/org/nervos/ckb/service/Api.java b/ckb/src/main/java/org/nervos/ckb/service/Api.java index fcd948304..f9028dc29 100644 --- a/ckb/src/main/java/org/nervos/ckb/service/Api.java +++ b/ckb/src/main/java/org/nervos/ckb/service/Api.java @@ -255,4 +255,16 @@ public LockHashCapacity getCapacityByLockHash(String lockHash) throws IOExceptio return rpcService.post( "get_capacity_by_lock_hash", Collections.singletonList(lockHash), LockHashCapacity.class); } + + /** + * Batch RPC request + * + * @param requests: A list of rpc method and parameters and the first element of each list must be + * rpc method. Example: [["get_block_hash", "0x200"],["get_block_by_number", "0x300"]] + * @return A list of rpc response + * @throws IOException Request or response error will throw exception + */ + public List batchRPC(List requests) throws IOException { + return rpcService.batchPost(requests); + } } diff --git a/ckb/src/main/java/org/nervos/ckb/service/RpcResponse.java b/ckb/src/main/java/org/nervos/ckb/service/RpcResponse.java new file mode 100644 index 000000000..2e205c9d8 --- /dev/null +++ b/ckb/src/main/java/org/nervos/ckb/service/RpcResponse.java @@ -0,0 +1,14 @@ +package org.nervos.ckb.service; + +/** Copyright © 2020 Nervos Foundation. All rights reserved. */ +public class RpcResponse { + public long id; + public String jsonrpc; + public T result; + public Error error; + + static class Error { + public int code; + public String message; + } +} diff --git a/ckb/src/main/java/org/nervos/ckb/service/RpcService.java b/ckb/src/main/java/org/nervos/ckb/service/RpcService.java index ce36aca49..7c412ae05 100644 --- a/ckb/src/main/java/org/nervos/ckb/service/RpcService.java +++ b/ckb/src/main/java/org/nervos/ckb/service/RpcService.java @@ -6,7 +6,9 @@ import com.google.gson.reflect.TypeToken; import java.io.IOException; import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.concurrent.atomic.AtomicLong; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; @@ -40,7 +42,7 @@ T post(@NotNull String method, List params, Type cls) throws IOException { Request request = new Request.Builder().url(url).post(body).build(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { - String responseBody = response.body().string(); + String responseBody = Objects.requireNonNull(response.body()).string(); RpcResponse rpcResponse = gson.fromJson(responseBody, new TypeToken() {}.getType()); @@ -78,7 +80,7 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { if (response.isSuccessful()) { - String responseBody = response.body().string(); + String responseBody = Objects.requireNonNull(response.body()).string(); RpcResponse rpcResponse = gson.fromJson(responseBody, new TypeToken>() {}.getType()); if (rpcResponse.error != null) { @@ -99,6 +101,26 @@ public void onResponse(@NotNull Call call, @NotNull Response response) }); } + List batchPost(List requests) throws IOException { + List paramsList = new ArrayList<>(); + for (List request : requests) { + if (request.size() == 0 || !(request.get(0) instanceof String)) { + throw new IOException("RPC method name must be a non-null string"); + } + paramsList.add( + new RequestParams(request.get(0).toString(), request.subList(1, request.size()))); + } + RequestBody body = RequestBody.create(gson.toJson(paramsList), JSON_MEDIA_TYPE); + Request request = new Request.Builder().url(url).post(body).build(); + Response response = client.newCall(request).execute(); + if (response.isSuccessful()) { + String responseBody = Objects.requireNonNull(response.body()).string(); + return gson.fromJson(responseBody, new TypeToken>() {}.getType()); + } else { + throw new IOException("RpcService error code " + response.code()); + } + } + static class RequestParams { String jsonrpc = "2.0"; String method; @@ -111,16 +133,4 @@ public RequestParams(String method, List params) { this.id = nextId.getAndIncrement(); } } - - static class RpcResponse { - long id; - String jsonrpc; - T result; - Error error; - - class Error { - public int code; - public String message; - } - } } diff --git a/ckb/src/test/java/service/ApiTest.java b/ckb/src/test/java/service/ApiTest.java index c537569c9..6e2e9a4d7 100644 --- a/ckb/src/test/java/service/ApiTest.java +++ b/ckb/src/test/java/service/ApiTest.java @@ -1,12 +1,15 @@ package service; +import com.google.gson.Gson; import java.io.IOException; import java.math.BigInteger; +import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.*; import org.junit.jupiter.api.function.Executable; import org.nervos.ckb.service.Api; +import org.nervos.ckb.service.RpcResponse; import org.nervos.ckb.type.*; import org.nervos.ckb.type.cell.CellOutputWithOutPoint; import org.nervos.ckb.type.cell.CellTransaction; @@ -343,4 +346,39 @@ public void testGetCapacityByLockHash() throws Exception { Assertions.assertNotNull(lockHashCapacity.capacity); Assertions.assertNotNull(lockHashCapacity.cellsCount); } + + @Test + public void testBatchRpc() throws IOException { + List rpcResponses = + api.batchRPC( + Arrays.asList( + Arrays.asList("get_block_hash", "0x200"), + Arrays.asList("get_block_by_number", "0x300"))); + Assertions.assertNotNull(rpcResponses); + Assertions.assertEquals(2, rpcResponses.size()); + Assertions.assertTrue(rpcResponses.get(0).result instanceof String); + Assertions.assertTrue( + new Gson().fromJson(rpcResponses.get(1).result.toString(), Block.class).transactions.size() + > 0); + + Assertions.assertThrows( + IOException.class, + new Executable() { + @Override + public void execute() throws Throwable { + api.batchRPC(Collections.singletonList(Arrays.asList(1, "0x300"))); + } + }, + "RPC method name must be a non-null string"); + + Assertions.assertThrows( + IOException.class, + new Executable() { + @Override + public void execute() throws Throwable { + api.batchRPC(Collections.singletonList(Collections.EMPTY_LIST)); + } + }, + "RPC method name must be a non-null string"); + } } From 870352625eb661d8f0095eedd1327db0fd5dd1eb Mon Sep 17 00:00:00 2001 From: duanyytop Date: Mon, 29 Jun 2020 17:09:30 +0800 Subject: [PATCH 03/15] chore: Support request parameters as integers --- .../main/java/org/nervos/ckb/service/RpcService.java | 6 ++++++ ckb/src/test/java/service/ApiTest.java | 7 +++++-- utils/src/main/java/org/nervos/ckb/utils/Numeric.java | 9 +++++++++ .../test/java/org/nervos/ckb/utils/NumericTest.java | 11 +++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ckb/src/main/java/org/nervos/ckb/service/RpcService.java b/ckb/src/main/java/org/nervos/ckb/service/RpcService.java index 7c412ae05..4e4b43259 100644 --- a/ckb/src/main/java/org/nervos/ckb/service/RpcService.java +++ b/ckb/src/main/java/org/nervos/ckb/service/RpcService.java @@ -13,6 +13,7 @@ import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; import org.jetbrains.annotations.NotNull; +import org.nervos.ckb.utils.Numeric; /** Copyright © 2019 Nervos Foundation. All rights reserved. */ class RpcService { @@ -107,6 +108,11 @@ List batchPost(List requests) throws IOException { if (request.size() == 0 || !(request.get(0) instanceof String)) { throw new IOException("RPC method name must be a non-null string"); } + for (int i = 1; i < request.size(); i++) { + if (Numeric.isIntegerValue(request.get(i).toString())) { + request.set(i, Numeric.toHexString(request.get(i).toString())); + } + } paramsList.add( new RequestParams(request.get(0).toString(), request.subList(1, request.size()))); } diff --git a/ckb/src/test/java/service/ApiTest.java b/ckb/src/test/java/service/ApiTest.java index 6e2e9a4d7..5311f13b5 100644 --- a/ckb/src/test/java/service/ApiTest.java +++ b/ckb/src/test/java/service/ApiTest.java @@ -353,13 +353,16 @@ public void testBatchRpc() throws IOException { api.batchRPC( Arrays.asList( Arrays.asList("get_block_hash", "0x200"), - Arrays.asList("get_block_by_number", "0x300"))); + Arrays.asList("get_block_by_number", "300"), + Arrays.asList("get_header_by_number", 100))); Assertions.assertNotNull(rpcResponses); - Assertions.assertEquals(2, rpcResponses.size()); + Assertions.assertEquals(3, rpcResponses.size()); Assertions.assertTrue(rpcResponses.get(0).result instanceof String); Assertions.assertTrue( new Gson().fromJson(rpcResponses.get(1).result.toString(), Block.class).transactions.size() > 0); + Assertions.assertNotNull( + new Gson().fromJson(rpcResponses.get(2).result.toString(), Header.class).compactTarget); Assertions.assertThrows( IOException.class, diff --git a/utils/src/main/java/org/nervos/ckb/utils/Numeric.java b/utils/src/main/java/org/nervos/ckb/utils/Numeric.java index 587725eea..775ca80cf 100644 --- a/utils/src/main/java/org/nervos/ckb/utils/Numeric.java +++ b/utils/src/main/java/org/nervos/ckb/utils/Numeric.java @@ -221,6 +221,15 @@ public static boolean isIntegerValue(BigDecimal value) { return value.signum() == 0 || value.scale() <= 0 || value.stripTrailingZeros().scale() <= 0; } + public static boolean isIntegerValue(String value) { + try { + Integer.parseInt(value); + } catch (NumberFormatException e) { + return false; + } + return true; + } + public static List intToBytes(int value) { return Bytes.asList(Numeric.hexStringToByteArray(Integer.toHexString(value))); } diff --git a/utils/src/test/java/org/nervos/ckb/utils/NumericTest.java b/utils/src/test/java/org/nervos/ckb/utils/NumericTest.java index 0aa54d793..f4dee491c 100644 --- a/utils/src/test/java/org/nervos/ckb/utils/NumericTest.java +++ b/utils/src/test/java/org/nervos/ckb/utils/NumericTest.java @@ -182,6 +182,17 @@ public void testIsIntegerValue() { Assertions.assertFalse(Numeric.isIntegerValue(BigDecimal.valueOf(-1.1))); } + @Test + public void testIsIntegerValue2() { + Assertions.assertTrue(Numeric.isIntegerValue("20")); + Assertions.assertTrue(Numeric.isIntegerValue("-20")); + Assertions.assertTrue(Numeric.isIntegerValue("0")); + + Assertions.assertFalse(Numeric.isIntegerValue("0x20")); + Assertions.assertFalse(Numeric.isIntegerValue("abc")); + Assertions.assertFalse(Numeric.isIntegerValue("#%34")); + } + @Test public void testLittleEndian() { String littleEndian = Numeric.littleEndian(71); From caa9654bc91a412453bbe6ac10d54ca004752eec Mon Sep 17 00:00:00 2001 From: duanyytop Date: Tue, 30 Jun 2020 16:43:01 +0800 Subject: [PATCH 04/15] refactor: Remove uesless code of utils --- .../main/java/org/nervos/ckb/utils/Bytes.java | 23 -------- .../java/org/nervos/ckb/utils/FileUtils.java | 45 ---------------- .../java/org/nervos/ckb/utils/HexUtil.java | 53 ------------------- .../java/org/nervos/ckb/utils/Strings.java | 27 ---------- 4 files changed, 148 deletions(-) delete mode 100644 utils/src/main/java/org/nervos/ckb/utils/Bytes.java delete mode 100644 utils/src/main/java/org/nervos/ckb/utils/FileUtils.java delete mode 100644 utils/src/main/java/org/nervos/ckb/utils/HexUtil.java diff --git a/utils/src/main/java/org/nervos/ckb/utils/Bytes.java b/utils/src/main/java/org/nervos/ckb/utils/Bytes.java deleted file mode 100644 index 257b27f88..000000000 --- a/utils/src/main/java/org/nervos/ckb/utils/Bytes.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.nervos.ckb.utils; - -import java.util.Arrays; - -/** Byte array utility functions. */ -public class Bytes { - - private Bytes() {} - - public static byte[] trimLeadingBytes(byte[] bytes, byte b) { - int offset = 0; - for (; offset < bytes.length - 1; offset++) { - if (bytes[offset] != b) { - break; - } - } - return Arrays.copyOfRange(bytes, offset, bytes.length); - } - - public static byte[] trimLeadingZeroes(byte[] bytes) { - return trimLeadingBytes(bytes, (byte) 0); - } -} diff --git a/utils/src/main/java/org/nervos/ckb/utils/FileUtils.java b/utils/src/main/java/org/nervos/ckb/utils/FileUtils.java deleted file mode 100644 index 961de0115..000000000 --- a/utils/src/main/java/org/nervos/ckb/utils/FileUtils.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.nervos.ckb.utils; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.nio.file.Files; - -/** Copyright © 2018 Nervos Foundation. All rights reserved. */ -public class FileUtils { - - public static String readFile(String path) { - BufferedReader in = null; - try { - in = new BufferedReader(new FileReader(path)); - StringBuilder strBuilder = new StringBuilder(); - String str; - while ((str = in.readLine()) != null) { - strBuilder.append(str).append("\n"); - } - return strBuilder.toString(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - if (in != null) { - in.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - return null; - } - - public static byte[] readFileForBytes(String path) { - File file = new File(path); - try { - return Files.readAllBytes(file.toPath()); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } -} diff --git a/utils/src/main/java/org/nervos/ckb/utils/HexUtil.java b/utils/src/main/java/org/nervos/ckb/utils/HexUtil.java deleted file mode 100644 index 47237ed5a..000000000 --- a/utils/src/main/java/org/nervos/ckb/utils/HexUtil.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.nervos.ckb.utils; - -public class HexUtil { - - public static byte[] hexToBytes(String inHex) { - int hexlen = inHex.length(); - byte[] result; - if (hexlen % 2 == 1) { - hexlen++; - result = new byte[(hexlen / 2)]; - inHex = "0" + inHex; - } else { - result = new byte[(hexlen / 2)]; - } - int j = 0; - for (int i = 0; i < hexlen; i += 2) { - result[j] = hexToByte(inHex.substring(i, i + 2)); - j++; - } - return result; - } - - public static byte hexToByte(String inHex) { - return (byte) Integer.parseInt(inHex, 16); - } - - public static String bytesToHex(byte[] in) { - final StringBuilder builder = new StringBuilder(); - for (byte b : in) { - int c = b; - c = c < 0 ? c + 256 : c; - String n = Integer.toHexString(c); - if (n.length() == 1) { - n = "0" + n; - } - builder.append(n); - } - return builder.toString(); - } - - public static void printBytes(byte[] bytes) { - for (byte b : bytes) { - int c = b; - c = c < 0 ? c + 256 : c; - String n = Integer.toHexString(c); - if (n.length() == 1) { - n = "0" + n; - } - System.out.print(n + ""); - } - System.out.println(" "); - } -} diff --git a/utils/src/main/java/org/nervos/ckb/utils/Strings.java b/utils/src/main/java/org/nervos/ckb/utils/Strings.java index 20ff57135..ea9d38225 100644 --- a/utils/src/main/java/org/nervos/ckb/utils/Strings.java +++ b/utils/src/main/java/org/nervos/ckb/utils/Strings.java @@ -1,7 +1,5 @@ package org.nervos.ckb.utils; -import java.util.Collections; - /** Copyright © 2018 Nervos Foundation. All rights reserved. */ public class Strings { public static String zeros(int n) { @@ -15,29 +13,4 @@ public static String repeat(char value, int n) { public static boolean isEmpty(String s) { return s == null || s.length() == 0; } - - public static byte[] asciiToHex(String asciiValue, int length) { - char[] chars = asciiValue.toCharArray(); - StringBuilder hex = new StringBuilder(); - for (int i = 0; i < chars.length; i++) { - hex.append(Integer.toHexString((int) chars[i])); - } - - String hexStr = - hex.toString() + "".join("", Collections.nCopies(length - (hex.length() / 2), "00")); - return Numeric.hexStringToByteArray(hexStr); - } - - public static String hexStringToAscii(String hexStr) { - assert (hexStr.length() % 2 == 0); - StringBuilder asciiStr = new StringBuilder(); - for (int i = 0; i < hexStr.length(); i += 2) { - String str = hexStr.substring(i, i + 2); - if (str.equals("00")) { - break; - } - asciiStr.append((char) Integer.parseInt(str, 16)); - } - return asciiStr.toString(); - } } From 1f09a405ab641bddbab792bf78333966c1b10e58 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2020 21:19:16 +0000 Subject: [PATCH 05/15] chore(deps): bump bcprov-jdk15on from 1.65.01 to 1.66 Bumps [bcprov-jdk15on](https://github.com/bcgit/bc-java) from 1.65.01 to 1.66. - [Release notes](https://github.com/bcgit/bc-java/releases) - [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) Signed-off-by: dependabot-preview[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 37e11873f..5bbd918a3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { - ext.bouncycastleVersion = '1.65.01' + ext.bouncycastleVersion = '1.66' ext.rxjavaVersion = '2.2.19' ext.gsonVersion = '2.8.6' ext.okhttpVersion = '4.7.2' From 1a790d7e04438f20360f2f6059a70eb77cacf602 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2020 21:24:24 +0000 Subject: [PATCH 06/15] chore(deps): bump logging-interceptor from 4.7.2 to 4.8.0 Bumps [logging-interceptor](https://github.com/square/okhttp) from 4.7.2 to 4.8.0. - [Release notes](https://github.com/square/okhttp/releases) - [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/okhttp/compare/parent-4.7.2...parent-4.8.0) Signed-off-by: dependabot-preview[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5bbd918a3..4942e9cd0 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { ext.rxjavaVersion = '2.2.19' ext.gsonVersion = '2.8.6' ext.okhttpVersion = '4.7.2' - ext.loggingOkhttpVersion = '4.7.2' + ext.loggingOkhttpVersion = '4.8.0' ext.slf4jVersion = '1.7.30' ext.guavaVersion = '29.0-jre' From 4efe1a88eac9a3ee0b9e44ee71075e0818e53a37 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2020 21:24:44 +0000 Subject: [PATCH 07/15] chore(deps): bump okhttp from 4.7.2 to 4.8.0 Bumps [okhttp](https://github.com/square/okhttp) from 4.7.2 to 4.8.0. - [Release notes](https://github.com/square/okhttp/releases) - [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/okhttp/compare/parent-4.7.2...parent-4.8.0) Signed-off-by: dependabot-preview[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5bbd918a3..b529857f4 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { ext.bouncycastleVersion = '1.66' ext.rxjavaVersion = '2.2.19' ext.gsonVersion = '2.8.6' - ext.okhttpVersion = '4.7.2' + ext.okhttpVersion = '4.8.0' ext.loggingOkhttpVersion = '4.7.2' ext.slf4jVersion = '1.7.30' ext.guavaVersion = '29.0-jre' From 1f0f8630c570fc754b39ea0258c30886ac271f15 Mon Sep 17 00:00:00 2001 From: duanyytop Date: Thu, 16 Jul 2020 15:38:20 +0800 Subject: [PATCH 08/15] fix: Check full address payload length --- .../nervos/ckb/utils/address/AddressParser.java | 3 +++ ckb/src/test/java/utils/AddressParserTest.java | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ckb/src/main/java/org/nervos/ckb/utils/address/AddressParser.java b/ckb/src/main/java/org/nervos/ckb/utils/address/AddressParser.java index ee9274774..98ff41553 100644 --- a/ckb/src/main/java/org/nervos/ckb/utils/address/AddressParser.java +++ b/ckb/src/main/java/org/nervos/ckb/utils/address/AddressParser.java @@ -46,6 +46,9 @@ public static AddressParseResult parse(String address) throws AddressFormatExcep } } + if (payload.length() < 66) { + throw new AddressFormatException("Invalid full address payload length"); + } String codeHash = Numeric.prependHexPrefix(payload.substring(2, 66)); String args = Numeric.prependHexPrefix(payload.substring(66)); if (TYPE_FULL_DATA.equals(type)) { diff --git a/ckb/src/test/java/utils/AddressParserTest.java b/ckb/src/test/java/utils/AddressParserTest.java index 48eeab106..5f3c5d05b 100644 --- a/ckb/src/test/java/utils/AddressParserTest.java +++ b/ckb/src/test/java/utils/AddressParserTest.java @@ -198,4 +198,19 @@ public void execute() throws Throwable { Assertions.assertTrue( exception.getMessage().contains("Short address args byte length must be equal to 20")); } + + @Test + void testAddressPayloadLengthException() { + String address = "ckt1qsvf96jqmq4483ncl7yrzfzshwchu9jd0glq4yy5r2jcsw04r0l5xl"; + AddressFormatException exception = + Assertions.assertThrows( + AddressFormatException.class, + new Executable() { + @Override + public void execute() throws Throwable { + AddressParser.parse(address); + } + }); + Assertions.assertTrue(exception.getMessage().contains("Invalid full address payload length")); + } } From 28fd144516b158f78fac20aeee2d814e31f41ec2 Mon Sep 17 00:00:00 2001 From: duanyytop Date: Tue, 21 Jul 2020 14:33:06 +0800 Subject: [PATCH 09/15] feat: Add clearTxPool rpc --- .gitignore | 1 + ckb/src/main/java/org/nervos/ckb/service/Api.java | 4 ++++ ckb/src/test/java/service/ApiTest.java | 8 +++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3857492fe..10432eef1 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ hs_err_pid* */out/ gradle.properties +local.properties # Ignore RPCTest because loachost can not visit RpcTest diff --git a/ckb/src/main/java/org/nervos/ckb/service/Api.java b/ckb/src/main/java/org/nervos/ckb/service/Api.java index f9028dc29..f6f879397 100644 --- a/ckb/src/main/java/org/nervos/ckb/service/Api.java +++ b/ckb/src/main/java/org/nervos/ckb/service/Api.java @@ -148,6 +148,10 @@ public TxPoolInfo txPoolInfo() throws IOException { return rpcService.post("tx_pool_info", Collections.emptyList(), TxPoolInfo.class); } + public String clearTxPool() throws IOException { + return rpcService.post("clear_tx_pool", Collections.emptyList(), String.class); + } + public String sendTransaction(Transaction transaction) throws IOException { return rpcService.post( "send_transaction", diff --git a/ckb/src/test/java/service/ApiTest.java b/ckb/src/test/java/service/ApiTest.java index 5311f13b5..368f359b3 100644 --- a/ckb/src/test/java/service/ApiTest.java +++ b/ckb/src/test/java/service/ApiTest.java @@ -135,12 +135,18 @@ public void testGetBannedAddress() throws IOException { } @Test - public void txPoolInfo() throws IOException { + public void testTxPoolInfo() throws IOException { TxPoolInfo txPoolInfo = api.txPoolInfo(); Assertions.assertNotNull(txPoolInfo); Assertions.assertNotNull(txPoolInfo.minFeeRate); } + @Test + public void testClearTxPool() throws IOException { + String txPoolInfo = api.clearTxPool(); + Assertions.assertNull(txPoolInfo); + } + @Test public void testGetBlockchainInfo() throws IOException { BlockchainInfo blockchainInfo = api.getBlockchainInfo(); From b5da012112958e39c28c6b12a470607790f02c05 Mon Sep 17 00:00:00 2001 From: duanyytop Date: Tue, 21 Jul 2020 14:36:54 +0800 Subject: [PATCH 10/15] feat: Set computeScriptHash and computeTransactionHash as deprecated rpc --- ckb/src/main/java/org/nervos/ckb/service/Api.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ckb/src/main/java/org/nervos/ckb/service/Api.java b/ckb/src/main/java/org/nervos/ckb/service/Api.java index f6f879397..7800aceaa 100644 --- a/ckb/src/main/java/org/nervos/ckb/service/Api.java +++ b/ckb/src/main/java/org/nervos/ckb/service/Api.java @@ -185,6 +185,7 @@ public Cycles dryRunTransaction(Transaction transaction) throws IOException { Cycles.class); } + @Deprecated public String computeTransactionHash(Transaction transaction) throws IOException { return rpcService.post( "_compute_transaction_hash", @@ -192,6 +193,7 @@ public String computeTransactionHash(Transaction transaction) throws IOException String.class); } + @Deprecated public String computeScriptHash(Script script) throws IOException { return rpcService.post("_compute_script_hash", Collections.singletonList(script), String.class); } From 07c366b2b366cd54072a0162e6d22557d85cd8c8 Mon Sep 17 00:00:00 2001 From: duanyytop Date: Tue, 21 Jul 2020 14:45:10 +0800 Subject: [PATCH 11/15] feat: Remove estimateFeeRate rpc --- ckb/src/main/java/org/nervos/ckb/service/Api.java | 7 ------- .../main/java/org/nervos/ckb/utils/Calculator.java | 14 -------------- ckb/src/test/java/service/ApiTest.java | 5 ----- .../org/nervos/ckb/MultiKeySingleSigTxExample.java | 1 - .../nervos/ckb/MultiSignTransactionExample.java | 1 - .../main/java/org/nervos/ckb/NervosDaoExample.java | 2 -- .../src/main/java/org/nervos/ckb/SUDTExample.java | 3 --- .../nervos/ckb/SendToMultiSigAddressTxExample.java | 1 - .../nervos/ckb/SingleKeySingleSigTxExample.java | 1 - .../nervos/ckb/SingleSigWithIndexerTxExample.java | 1 - 10 files changed, 36 deletions(-) diff --git a/ckb/src/main/java/org/nervos/ckb/service/Api.java b/ckb/src/main/java/org/nervos/ckb/service/Api.java index 7800aceaa..a736a2257 100644 --- a/ckb/src/main/java/org/nervos/ckb/service/Api.java +++ b/ckb/src/main/java/org/nervos/ckb/service/Api.java @@ -198,13 +198,6 @@ public String computeScriptHash(Script script) throws IOException { return rpcService.post("_compute_script_hash", Collections.singletonList(script), String.class); } - public FeeRate estimateFeeRate(String expectedConfirmBlocks) throws IOException { - return rpcService.post( - "estimate_fee_rate", - Collections.singletonList(Numeric.toHexString(expectedConfirmBlocks)), - FeeRate.class); - } - public String calculateDaoMaximumWithdraw(OutPoint outPoint, String withdrawBlockHash) throws IOException { return rpcService.post( diff --git a/ckb/src/main/java/org/nervos/ckb/utils/Calculator.java b/ckb/src/main/java/org/nervos/ckb/utils/Calculator.java index 53c760d02..6ff031fc6 100644 --- a/ckb/src/main/java/org/nervos/ckb/utils/Calculator.java +++ b/ckb/src/main/java/org/nervos/ckb/utils/Calculator.java @@ -1,8 +1,6 @@ package org.nervos.ckb.utils; -import java.io.IOException; import java.math.BigInteger; -import org.nervos.ckb.service.Api; import org.nervos.ckb.type.dynamic.Table; import org.nervos.ckb.type.transaction.Transaction; @@ -10,7 +8,6 @@ public class Calculator { // 4 bytes for the tx offset cost with molecule vector (transactions) private static final int SERIALIZED_TX_OFFSET_BYTE_SIZE = 4; - private static final int MIN_CONFIRM_BLOCKS = 3; public static int calculateTransactionSize(Transaction transaction) { Table serializedTx = Serializer.serializeTransaction(transaction); @@ -29,17 +26,6 @@ private static BigInteger calculateTransactionFee( return fee; } - public static BigInteger calculateTransactionFee( - Api api, Transaction transaction, long expectedConfirmBlocks) throws IOException { - if (expectedConfirmBlocks < MIN_CONFIRM_BLOCKS) { - throw new IOException("Confirm block must not be smaller than " + MIN_CONFIRM_BLOCKS); - } - BigInteger feeRate = - Numeric.toBigInt(api.estimateFeeRate(String.valueOf(expectedConfirmBlocks)).feeRate); - BigInteger txSize = BigInteger.valueOf(calculateTransactionSize(transaction)); - return calculateTransactionFee(txSize, feeRate); - } - public static BigInteger calculateTransactionFee(Transaction transaction, BigInteger feeRate) { BigInteger txSize = BigInteger.valueOf(calculateTransactionSize(transaction)); return calculateTransactionFee(txSize, feeRate); diff --git a/ckb/src/test/java/service/ApiTest.java b/ckb/src/test/java/service/ApiTest.java index 368f359b3..30548f6d2 100644 --- a/ckb/src/test/java/service/ApiTest.java +++ b/ckb/src/test/java/service/ApiTest.java @@ -286,11 +286,6 @@ public void testComputeTransactionHash() throws IOException { Assertions.assertNotNull(transactionHash); } - @Test - public void testEstimateFeeRate() { - Assertions.assertThrows(IOException.class, () -> api.estimateFeeRate("0xa")); - } - @Test public void testIndexLockHash() throws IOException { LockHashIndexState lockHashIndexState = diff --git a/example/src/main/java/org/nervos/ckb/MultiKeySingleSigTxExample.java b/example/src/main/java/org/nervos/ckb/MultiKeySingleSigTxExample.java index 0f405ffcc..0bca27222 100644 --- a/example/src/main/java/org/nervos/ckb/MultiKeySingleSigTxExample.java +++ b/example/src/main/java/org/nervos/ckb/MultiKeySingleSigTxExample.java @@ -151,7 +151,6 @@ private static Transaction generateTx( txBuilder.addOutputs(cellOutputs); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); // initial_length = 2 * secp256k1_signature_byte.length diff --git a/example/src/main/java/org/nervos/ckb/MultiSignTransactionExample.java b/example/src/main/java/org/nervos/ckb/MultiSignTransactionExample.java index 6d7d2e5e9..bfdef5b23 100644 --- a/example/src/main/java/org/nervos/ckb/MultiSignTransactionExample.java +++ b/example/src/main/java/org/nervos/ckb/MultiSignTransactionExample.java @@ -113,7 +113,6 @@ public static Transaction generateTx( txBuilder.addOutputs(cellOutputs); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); // initial_length = multi_sig_hash.length + 2 * secp256k1_signature_byte.length diff --git a/example/src/main/java/org/nervos/ckb/NervosDaoExample.java b/example/src/main/java/org/nervos/ckb/NervosDaoExample.java index 0ed2b7b25..6d23cb8a2 100644 --- a/example/src/main/java/org/nervos/ckb/NervosDaoExample.java +++ b/example/src/main/java/org/nervos/ckb/NervosDaoExample.java @@ -104,7 +104,6 @@ private static Transaction generateDepositingToDaoTx(BigInteger capacity) throws new CellDep(SystemContract.getSystemNervosDaoCell(api).outPoint, CellDep.CODE)); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); CollectUtils collectUtils = new CollectUtils(api); CollectResult collectResult = @@ -175,7 +174,6 @@ private static Transaction generateWithdrawingFromDaoTx(OutPoint depositOutPoint txBuilder.addInput(new CellInput(depositOutPoint, "0x0")); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); CollectUtils collectUtils = new CollectUtils(api); CollectResult collectResult = diff --git a/example/src/main/java/org/nervos/ckb/SUDTExample.java b/example/src/main/java/org/nervos/ckb/SUDTExample.java index aaa28bd18..fa432ef23 100644 --- a/example/src/main/java/org/nervos/ckb/SUDTExample.java +++ b/example/src/main/java/org/nervos/ckb/SUDTExample.java @@ -83,7 +83,6 @@ private static String issue(BigInteger udtAmount, Script udtType) throws IOExcep txBuilder.addCellDep(new CellDep(new OutPoint(SUDT_OUT_POINT_TX_HASH, "0x0"), CellDep.CODE)); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); // initial_length = 2 * secp256k1_signature_byte.length @@ -147,7 +146,6 @@ private static String transfer(BigInteger udtAmount, Script udtType) throws IOEx txBuilder.addCellDep(new CellDep(new OutPoint(SUDT_OUT_POINT_TX_HASH, "0x0"), CellDep.CODE)); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); // initial_length = 2 * secp256k1_signature_byte.length @@ -210,7 +208,6 @@ private static String burn(BigInteger udtAmount, Script udtType) throws IOExcept txBuilder.addCellDep(new CellDep(new OutPoint(SUDT_OUT_POINT_TX_HASH, "0x0"), CellDep.CODE)); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); // initial_length = 2 * secp256k1_signature_byte.length diff --git a/example/src/main/java/org/nervos/ckb/SendToMultiSigAddressTxExample.java b/example/src/main/java/org/nervos/ckb/SendToMultiSigAddressTxExample.java index 7e1348919..8bfd10296 100644 --- a/example/src/main/java/org/nervos/ckb/SendToMultiSigAddressTxExample.java +++ b/example/src/main/java/org/nervos/ckb/SendToMultiSigAddressTxExample.java @@ -75,7 +75,6 @@ private static String sendCapacity(List receivers, String changeAddres List scriptGroupWithPrivateKeysList = new ArrayList<>(); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); // initial_length = 2 * secp256k1_signature_byte.length diff --git a/example/src/main/java/org/nervos/ckb/SingleKeySingleSigTxExample.java b/example/src/main/java/org/nervos/ckb/SingleKeySingleSigTxExample.java index 365092df2..7209657ff 100644 --- a/example/src/main/java/org/nervos/ckb/SingleKeySingleSigTxExample.java +++ b/example/src/main/java/org/nervos/ckb/SingleKeySingleSigTxExample.java @@ -80,7 +80,6 @@ private static String sendCapacity(List receivers, String changeAddres txBuilder.addOutputs(cellOutputs); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); // initial_length = 2 * secp256k1_signature_byte.length diff --git a/example/src/main/java/org/nervos/ckb/SingleSigWithIndexerTxExample.java b/example/src/main/java/org/nervos/ckb/SingleSigWithIndexerTxExample.java index dcfc582a9..d74527085 100644 --- a/example/src/main/java/org/nervos/ckb/SingleSigWithIndexerTxExample.java +++ b/example/src/main/java/org/nervos/ckb/SingleSigWithIndexerTxExample.java @@ -92,7 +92,6 @@ private static String sendCapacity(List receivers, String changeAddres txBuilder.addOutputs(cellOutputs); // You can get fee rate by rpc or set a simple number - // BigInteger feeRate = Numeric.toBigInt(api.estimateFeeRate("5").feeRate); BigInteger feeRate = BigInteger.valueOf(1024); // initial_length = 2 * secp256k1_signature_byte.length From 989cb6c686817d55512e7464124436b79e4bcae4 Mon Sep 17 00:00:00 2001 From: duanyytop Date: Tue, 21 Jul 2020 14:54:05 +0800 Subject: [PATCH 12/15] doc: Update CHANGELOG --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 424354423..5ce08008f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [v0.34.0](https://github.com/nervosnetwork/ckb-sdk-java/compare/v0.33.0...v0.34.0) (2020-7-21) + +### Feature + + * Add batch rpc request ([e5eef53](https://github.com/nervosnetwork/ckb-sdk-java/commit/e5eef53b98f671620f5d8c05c0cc7b1e62f7674f)) + * Add `clearTxPool` rpc request([64819d9](https://github.com/nervosnetwork/ckb-sdk-java/commit/64819d9e6be352ae193c5ee4da1949868e96426a)) + * Remove `estimateFeeRate` rpc request ([054bd01](https://github.com/nervosnetwork/ckb-sdk-java/commit/054bd01e22b77591ec0d5735d23f679cc6712e4b)) + * Set `computeScriptHash` and `computeTransactionHash` as deprecated rpc request ([fec42ec](https://github.com/nervosnetwork/ckb-sdk-java/commit/fec42ec72248d49cb5c62f6933a3d54be35c13dd)) + +### BugFix + +* Check full address payload length ([02a425a](https://github.com/nervosnetwork/ckb-sdk-java/commit/02a425ae70110439e8118db8dc9fbbdcc829c05b)) + +### BreakingChanges + +* Remove `estimateFeeRate` rpc request ([054bd01](https://github.com/nervosnetwork/ckb-sdk-java/commit/054bd01e22b77591ec0d5735d23f679cc6712e4b)) + + # [v0.33.0](https://github.com/nervosnetwork/ckb-sdk-java/compare/v0.32.0...v0.33.0) (2020-6-22) Bump version to v0.33.0 From c19331e688e90312450dcd3da30e20ac4eef72e3 Mon Sep 17 00:00:00 2001 From: duanyytop Date: Tue, 21 Jul 2020 14:55:28 +0800 Subject: [PATCH 13/15] chore: Bump to version v0.34.0 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 37a69d03d..57ca917d4 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ allprojects { targetCompatibility = 1.8 group 'org.nervos.ckb' - version '0.33.0' + version '0.34.0' apply plugin: 'java' @@ -113,7 +113,7 @@ configure(subprojects.findAll { it.name != 'tests' }) { publications { mavenJava(MavenPublication) { groupId 'org.nervos.ckb' - version '0.33.0' + version '0.34.0' from components.java } } From cf3997b51baefd44a63d9c449b488c47c1373a74 Mon Sep 17 00:00:00 2001 From: duanyytop Date: Tue, 21 Jul 2020 15:08:46 +0800 Subject: [PATCH 14/15] fix: Fix address parse method bug --- .../main/java/org/nervos/ckb/address/AddressUtils.java | 5 +++-- .../src/test/java/org/nervos/ckb/address/AddressTest.java | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/utils/src/main/java/org/nervos/ckb/address/AddressUtils.java b/utils/src/main/java/org/nervos/ckb/address/AddressUtils.java index 4c7a3860a..ea917621a 100644 --- a/utils/src/main/java/org/nervos/ckb/address/AddressUtils.java +++ b/utils/src/main/java/org/nervos/ckb/address/AddressUtils.java @@ -71,10 +71,11 @@ public static CodeHashType parseAddressType(String address) throws AddressFormat public static String parse(String address) throws AddressFormatException { String payload = parsePrefix(address); String prefixCodeHash = payload.substring(TYPE.length()); + System.out.println(payload); if (prefixCodeHash.startsWith(CODE_HASH_IDX_BLAKE160)) { - return payload.replace(TYPE + CODE_HASH_IDX_BLAKE160, ""); + return payload.substring((TYPE + CODE_HASH_IDX_BLAKE160).length()); } - return payload.replace(TYPE + CODE_HASH_IDX_MULTISIG, ""); + return payload.substring((TYPE + CODE_HASH_IDX_MULTISIG).length()); } private String prefix() { diff --git a/utils/src/test/java/org/nervos/ckb/address/AddressTest.java b/utils/src/test/java/org/nervos/ckb/address/AddressTest.java index a61f6edb4..c5c7101c2 100644 --- a/utils/src/test/java/org/nervos/ckb/address/AddressTest.java +++ b/utils/src/test/java/org/nervos/ckb/address/AddressTest.java @@ -61,11 +61,17 @@ public void testPrivateKeyHashToAddressTestnet() { } @Test - public void testBlake160FromAddressTestnet() { + public void testBlake160FromAddressTestnet1() { String blake160 = AddressUtils.parse("ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83"); Assertions.assertEquals(blake160, "36c329ed630d6ce750712a477543672adab57f4c"); } + @Test + public void testBlake160FromAddressTestnet2() { + String blake160 = AddressUtils.parse("ckt1qyq2742g7yajdcahqsyn63spqrlspyy8g5pq7xg9tu"); + Assertions.assertEquals(blake160, "af5548f13b26e3b704093d460100ff0090874502"); + } + @Test public void testBlake160FromAddressMainnet() { String blake160 = AddressUtils.parse("ckb1qyqrdsefa43s6m882pcj53m4gdnj4k440axqdt9rtd"); From 61c234d324dc8e259b9f04d5d08b17b7ec3b50a6 Mon Sep 17 00:00:00 2001 From: duanyytop Date: Tue, 21 Jul 2020 15:10:09 +0800 Subject: [PATCH 15/15] doc: Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ce08008f..a25d4738a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ### BugFix * Check full address payload length ([02a425a](https://github.com/nervosnetwork/ckb-sdk-java/commit/02a425ae70110439e8118db8dc9fbbdcc829c05b)) +* Fix address parse method bug ([cf3997b](https://github.com/nervosnetwork/ckb-sdk-java/commit/cf3997b51baefd44a63d9c449b488c47c1373a74)) ### BreakingChanges