diff --git a/.ci/ci_check.sh b/.ci/ci_check.sh index 2988743ba..0ccba269a 100755 --- a/.ci/ci_check.sh +++ b/.ci/ci_check.sh @@ -159,7 +159,6 @@ pwd ls -la export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8 download_tassl - LOG_INFO "------ download_binary: v3.0.0---------" download_build_chain "v3.0.0" download_binary "v3.0.0" @@ -184,6 +183,13 @@ rm -rf ./bin LOG_INFO "------ download_build_chain: v3.3.0---------" download_binary "v3.3.0" download_build_chain "v3.3.0" +LOG_INFO "------ check_standard_node---------" +check_standard_node "true" "sm" "-s" +rm -rf ./bin + +LOG_INFO "------ download_build_chain: v3.4.0---------" +download_binary "v3.4.0" +download_build_chain "v3.4.0" LOG_INFO "------ check_wasm_node---------" check_wasm_node "false" LOG_INFO "------ check_standard_node---------" diff --git a/.codecov.yml b/.codecov.yml index 5fab68d31..d45ac1032 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -7,7 +7,7 @@ coverage: status: project: default: - target: "30%" + target: "40%" threshold: "1%" if_not_found: success patch: diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 41230a32f..3503dc9ec 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -41,16 +41,17 @@ jobs: if: runner.os == 'macOS' run: | brew install openssl@1.1 ccache - - name: Set up JDK 1.8 + - name: Set up JDK 1.8.0.345 uses: actions/setup-java@v3 with: - distribution: 'zulu' - java-version: '8.0.345' + distribution: 'zulu' + java-version: '8.0.345' - name: run build test if: runner.os == 'Windows' run: ./gradlew.bat build - name: run integration testing - if: runner.os != 'Windows' + # FIXME: macOS WASM integration testing failed + if: runner.os != 'Windows' && runner.os != 'macOS' run: /bin/bash .ci/ci_check.sh build-centos: @@ -87,6 +88,11 @@ jobs: java-version: '8.0.345' - name: install CentOS dependencies run: yum install -y epel-release centos-release-scl wget which git openssl-devel openssl tree + - name: Set up JDK 1.8.0.345 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '8.0.345' - name: run build test run: /bin/bash gradlew build --info - name: run integration testing diff --git a/build.gradle b/build.gradle index 75b3da811..ccac2fb43 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ ext { if (!project.hasProperty("ossrhPassword")) { ossrhPassword = "xxx" } - jacksonVersion = '2.14.2' + jacksonVersion = '2.14.3' commonsIOVersion = '2.11.0' commonsLang3Version = '3.12.0' toml4jVersion = "0.7.2" @@ -24,18 +24,18 @@ ext { webankJavaCryptoVersion = "1.0.3" junitVersion = '4.13.2' commonsCollections4Version = "4.4" - guavaVersion = '31.1-jre' bcosSdkJniVersion = "3.4.0" slf4jApiVerison = '1.7.36' mockitoVersion = '4.8.0' gsonVersion = '2.10.1' + tarsSDKVersion = '3.5.0-SNAPSHOT' } // check.dependsOn integrationTest // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.java-sdk' - version = '3.4.0' + version = '3.5.0-SNAPSHOT' apply plugin: 'maven-publish' apply plugin: 'idea' @@ -60,15 +60,14 @@ allprojects { repositories { mavenCentral() maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } - maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2" } maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2" } } dependencies { api("org.slf4j:slf4j-api:${slf4jApiVerison}") testImplementation("junit:junit:${junitVersion}") testImplementation("org.apache.commons:commons-collections4:${commonsCollections4Version}") - testImplementation("com.google.guava:guava:${guavaVersion}") testImplementation("org.mockito:mockito-core:${mockitoVersion}") } @@ -126,6 +125,7 @@ googleJavaFormat { } dependencies { + api("org.fisco-bcos:fisco-bcos-tars-sdk" + ":${tarsSDKVersion}") api("org.fisco-bcos:bcos-sdk-jni:${bcosSdkJniVersion}") { exclude group : "org.slf4j" exclude group : "com.fasterxml.jackson.core" @@ -136,14 +136,10 @@ dependencies { api("org.apache.commons:commons-lang3:${commonsLang3Version}") api("com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}") api("commons-io:commons-io:${commonsIOVersion}") - // api("com.webank:key-mini-toolkit:${keyMiniToolkit}") api("com.webank:webank-blockchain-java-crypto:${webankJavaCryptoVersion}") api("com.moandjiezana.toml:toml4j:${toml4jVersion}") { exclude group: "com.google.code.gson" } -// api("org.apache.commons:commons-configuration2:${config2Version}"){ -// exclude group: "commons-logging" -// } integrationTestImplementation project integrationWasmTestImplementation project @@ -183,6 +179,7 @@ javadoc { task sourcesJar(type: Jar) { from sourceSets.main.allJava archiveClassifier = 'sources' + duplicatesStrategy = 'warn' } task javadocJar(type: Jar) { @@ -209,7 +206,6 @@ tasks.withType(Test) { publishing { publications { mavenJava(MavenPublication) { - artifactId "fisco-bcos-" + project.name groupId project.group version project.version @@ -262,7 +258,7 @@ publishing { jar { // destinationDir file('dist/apps') - archiveName "fisco-bcos-" + project.name + '-' + project.version + '.jar' + archiveFileName="fisco-bcos-" + project.name + '-' + project.version + '.jar' exclude '**/*.xml' exclude '**/*.properties' diff --git a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/BcosSDKTest.java b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/BcosSDKTest.java index 2638fe0d7..2af9521c6 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/BcosSDKTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/BcosSDKTest.java @@ -337,9 +337,13 @@ public void onError(Response errorResponse) { BcosTransaction transaction1 = client.getTransaction(txHash, false); BcosTransactionReceipt transactionReceipt = client.getTransactionReceipt(txHash, false); if (client.getChainCompatibilityVersion().compareTo(EnumNodeVersion.BCOS_3_2_0.toVersionObj()) >= 0) { + Assert.assertEquals(extraData, receipt.getExtraData()); Assert.assertEquals(extraData, transaction1.getResult().getExtraData()); Assert.assertEquals(extraData, transactionReceipt.getResult().getExtraData()); + Assert.assertFalse(receipt.getInput().isEmpty()); } + Assert.assertFalse(transactionReceipt.getResult().getInput().isEmpty()); + Assert.assertFalse(transaction1.getResult().getInput().isEmpty()); // get 2nd block block1 = diff --git a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/decoder/EventDecodeTest.java b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/decoder/EventDecodeTest.java index d1c67bd1e..91d8ca8f5 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/decoder/EventDecodeTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/decoder/EventDecodeTest.java @@ -14,7 +14,7 @@ */ package org.fisco.bcos.sdk.v3.test.transaction.decoder; -import com.google.common.collect.Lists; +import java.util.ArrayList; import java.util.List; import java.util.Map; import org.fisco.bcos.sdk.v3.BcosSDK; @@ -53,7 +53,7 @@ public void testDecode() throws Exception { client, client.getCryptoSuite().getCryptoKeyPair(), abiFile, binFile); ContractCodec contractCodec = new ContractCodec(client.getCryptoSuite(), client.isWASM()); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = manager.deployByContractLoader("ComplexSol", params); diff --git a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/decoder/TransactionDecoderServiceTest.java b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/decoder/TransactionDecoderServiceTest.java index 5d2298f06..ff5348a64 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/decoder/TransactionDecoderServiceTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/decoder/TransactionDecoderServiceTest.java @@ -14,11 +14,9 @@ */ package org.fisco.bcos.sdk.v3.test.transaction.decoder; -import com.google.common.collect.Lists; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; + import org.fisco.bcos.sdk.v3.BcosSDK; import org.fisco.bcos.sdk.v3.client.Client; import org.fisco.bcos.sdk.v3.model.ConstantConfig; @@ -57,7 +55,7 @@ public void testDecode() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( client, client.getCryptoSuite().getCryptoKeyPair(), abiFile, binFile); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = manager.deployByContractLoader(contractName, params); @@ -71,9 +69,10 @@ public void testDecode() throws Exception { contractName, contractAddress, "incrementUint256", - Lists.newArrayList(BigInteger.valueOf(1))); + Collections.singletonList(BigInteger.ONE)); TransactionResponse transactionResponseWithoutValues = decoder.decodeReceiptWithoutValues(abi, transactionReceipt); + Assert.assertEquals(0, transactionResponseWithoutValues.getReturnCode()); TransactionResponse transactionResponseWithValues = decoder.decodeReceiptWithValues(abi, "incrementUint256", transactionReceipt); Assert.assertEquals("Success", transactionResponseWithValues.getReceiptMessages()); @@ -83,8 +82,8 @@ public void testDecode() throws Exception { } // setBytesMapping { - List s = Lists.newArrayList("2".getBytes()); - List paramsSetBytes = new ArrayList(); + List s = Collections.singletonList("2".getBytes()); + List paramsSetBytes = new ArrayList<>(); paramsSetBytes.add(s); TransactionReceipt transactionReceipt2 = manager.sendTransactionAndGetReceiptByContractLoader( @@ -96,7 +95,7 @@ public void testDecode() throws Exception { Assert.assertEquals( transactionResponse2.getReceiptMessages(), "Bytes array is less than 2"); - List s2 = Lists.newArrayList("2".getBytes(), "3".getBytes()); + List s2 = Arrays.asList("2".getBytes(), "3".getBytes()); List paramsSetBytes2 = new ArrayList<>(); paramsSetBytes2.add(s2); TransactionReceipt transactionReceipt = diff --git a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/manager/AssembleTransactionProcessorTest.java b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/manager/AssembleTransactionProcessorTest.java index c1a3cff9d..f1b04eb74 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/manager/AssembleTransactionProcessorTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/manager/AssembleTransactionProcessorTest.java @@ -14,15 +14,8 @@ */ package org.fisco.bcos.sdk.v3.test.transaction.manager; -import com.google.common.collect.Lists; - import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.concurrent.CompletableFuture; import org.apache.commons.collections4.ListUtils; @@ -174,7 +167,7 @@ public void test11HelloWorldAsync() throws Exception { // send tx with callback String to = callbackMock.getResult().getContractAddress(); System.out.println("contract address is " + to); - List params = Lists.newArrayList("test"); + List params = Collections.singletonList("test"); transactionProcessor.sendTransactionAsync(to, abi, "set", params, callbackMock); Assert.assertEquals(0, callbackMock.getResult().getStatus()); @@ -205,7 +198,7 @@ public void test2ComplexDeploy() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = @@ -233,7 +226,7 @@ public void test3ComplexQuery() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = @@ -273,7 +266,7 @@ public void test4ComplexEmptyTx() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = @@ -293,7 +286,7 @@ public void test5ComplexIncrement() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = @@ -305,7 +298,7 @@ public void test5ComplexIncrement() throws Exception { contractAddress, this.ABI, "incrementUint256", - Lists.newArrayList(BigInteger.valueOf(10)), + Collections.singletonList(BigInteger.valueOf(10)), new TransactionCallback() { @Override public void onResponse(TransactionReceipt receipt) { @@ -320,7 +313,7 @@ public void onResponse(TransactionReceipt receipt) { contractAddress, AssembleTransactionProcessorTest.this.ABI, "getUint256", - Lists.newArrayList()); + new ArrayList<>()); System.out.println(JsonUtils.toJson(callResponse3)); Assert.assertEquals("Success", callResponse3.getReturnMessage()); } catch (TransactionBaseException | ContractCodecException e) { @@ -336,7 +329,7 @@ public void test6ComplexSetValues() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(-1); params.add("test2"); TransactionResponse response = @@ -344,7 +337,7 @@ public void test6ComplexSetValues() throws Exception { Assert.assertEquals(response.getTransactionReceipt().getStatus(), 0); String contractAddress = response.getContractAddress(); // set values - List paramsSetValues = Lists.newArrayList(-20); + List paramsSetValues = new ArrayList<>(Collections.singletonList(-20)); String[] o = {"0x1", "0x2", "0x3"}; List a = Arrays.asList(o); paramsSetValues.add(a); @@ -363,7 +356,7 @@ public void test6ComplexSetValues() throws Exception { contractAddress, ABI, "getValues", - Lists.newArrayList()); + new ArrayList<>()); Assert.assertEquals(0, callResponse4.getReturnCode()); Assert.assertEquals( callResponse4.getResults().get(0).getValue(), new Int256(-20).getValue()); @@ -376,7 +369,7 @@ public void test7ComplexSetBytes() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = @@ -385,7 +378,7 @@ public void test7ComplexSetBytes() throws Exception { String contractAddress = response.getContractAddress(); // setBytes { - List paramsSetBytes = Lists.newArrayList(new String("123".getBytes())); + List paramsSetBytes = Collections.singletonList(new String("123".getBytes())); TransactionResponse transactionResponse3 = transactionProcessor.sendTransactionWithStringParamsAndGetResponse( contractAddress, ABI, "setBytes", paramsSetBytes); @@ -402,7 +395,7 @@ public void test7ComplexSetBytes() throws Exception { contractAddress, ABI, "_bytesV", - Lists.newArrayList()); + new ArrayList<>()); Assert.assertEquals(0, callResponse4.getReturnCode()); Assert.assertEquals( Hex.toHexString((byte[]) callResponse4.getResults().get(0).getValue()), @@ -412,7 +405,7 @@ public void test7ComplexSetBytes() throws Exception { // setBytes { List paramsSetBytes2 = - Lists.newArrayList(new String("hex://0x1234".getBytes())); + Collections.singletonList(new String("hex://0x1234".getBytes())); TransactionResponse transactionResponse4 = transactionProcessor.sendTransactionWithStringParamsAndGetResponse( contractAddress, ABI, "setBytes", paramsSetBytes2); @@ -428,7 +421,7 @@ public void test7ComplexSetBytes() throws Exception { contractAddress, ABI, "_bytesV", - Lists.newArrayList()); + new ArrayList<>()); Assert.assertEquals(0, callResponse4.getReturnCode()); } } @@ -439,14 +432,14 @@ public void test8ComplexSetBytesFuture() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = transactionProcessor.deployByContractLoader("ComplexSol", params); Assert.assertEquals(response.getTransactionReceipt().getStatus(), 0); String contractAddress = response.getContractAddress(); - List paramsSetBytes = Lists.newArrayList("2".getBytes()); + List paramsSetBytes = Collections.singletonList("2".getBytes()); byte[] data = transactionProcessor.encodeFunction(ABI, "setBytes", paramsSetBytes); TxPair txPair = transactionProcessor.createSignedTransaction( @@ -454,9 +447,7 @@ public void test8ComplexSetBytesFuture() throws Exception { CompletableFuture future = transactionProcessor.sendTransactionAsync(txPair.getSignedTx()); future.thenAccept( - r -> { - Assert.assertEquals(0, response.getTransactionReceipt().getStatus()); - }); + r -> Assert.assertEquals(0, response.getTransactionReceipt().getStatus())); TxPair txPair0 = transactionProcessor.createSignedTransaction( @@ -475,7 +466,7 @@ public void test9ComplexSetStaticBytes() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); // deploy - List params = Lists.newArrayList(); + List params = new ArrayList<>(); params.add(1); params.add("test2"); TransactionResponse response = @@ -485,7 +476,7 @@ public void test9ComplexSetStaticBytes() throws Exception { // setStaticByte4 in hex { - List paramsSetBytes = Lists.newArrayList("hex://0x12345678"); + List paramsSetBytes = Collections.singletonList("hex://0x12345678"); TransactionResponse transactionResponse3 = transactionProcessor.sendTransactionWithStringParamsAndGetResponse( contractAddress, ABI, "setStaticByte4", paramsSetBytes); @@ -498,7 +489,7 @@ public void test9ComplexSetStaticBytes() throws Exception { contractAddress, ABI, "_bytes4V", - Lists.newArrayList()); + new ArrayList<>()); Assert.assertEquals(0, callResponse4.getReturnCode()); Assert.assertEquals( Hex.toHexString((byte[]) callResponse4.getResults().get(0).getValue()), @@ -514,7 +505,7 @@ public void test10EventDemo() throws Exception { String contractAddress = null; // deploy { - List params = Lists.newArrayList(); + List params = new ArrayList<>(); TransactionResponse response = transactionProcessor.deployByContractLoader("EventSubDemo", params); Assert.assertEquals(response.getTransactionReceipt().getStatus(), 0); @@ -561,13 +552,13 @@ public void test11CallWithSign() throws Exception { TransactionProcessorFactory.createAssembleTransactionProcessor( this.client, this.cryptoKeyPair, ABI_FILE, BIN_FILE); - if(client.getChainCompatibilityVersion().compareTo(EnumNodeVersion.BCOS_3_4_0.toVersionObj()) < 0){ + if (client.getChainCompatibilityVersion().compareTo(EnumNodeVersion.BCOS_3_4_0.toVersionObj()) < 0) { return; } String contractAddress = null; // deploy { - List params = Lists.newArrayList(); + List params = new ArrayList<>(); TransactionResponse response = transactionProcessor.deployByContractLoader("TestCallWithSign", params); Assert.assertEquals(response.getTransactionReceipt().getStatus(), 0); diff --git a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/manager/AssembleTransactionWithRemoteSignProcessorTest.java b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/manager/AssembleTransactionWithRemoteSignProcessorTest.java index e1b753721..5d745ce44 100644 --- a/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/manager/AssembleTransactionWithRemoteSignProcessorTest.java +++ b/src/integration-test/java/org/fisco/bcos/sdk/v3/test/transaction/manager/AssembleTransactionWithRemoteSignProcessorTest.java @@ -14,8 +14,8 @@ */ package org.fisco.bcos.sdk.v3.test.transaction.manager; -import com.google.common.collect.Lists; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; import org.apache.commons.lang3.StringUtils; @@ -48,7 +48,7 @@ public class AssembleTransactionWithRemoteSignProcessorTest { "src/integration-test/resources/" + ConstantConfig.CONFIG_FILE_NAME; private static final String abiFile = "src/integration-test/resources/abi/"; private static final String binFile = "src/integration-test/resources/bin/"; - private List params = Lists.newArrayList("test"); + private List params = new ArrayList<>(Collections.singletonList("test")); // prepare sdk, read from the config file private BcosSDK sdk = BcosSDK.build(configFile); // set the group number 1 diff --git a/src/main/java/org/fisco/bcos/sdk/v3/BcosSDK.java b/src/main/java/org/fisco/bcos/sdk/v3/BcosSDK.java index 2322b9c45..986e3de34 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/BcosSDK.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/BcosSDK.java @@ -17,6 +17,7 @@ import org.fisco.bcos.sdk.jni.BlockNotifier; import org.fisco.bcos.sdk.v3.amop.Amop; import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.client.TarsClient; import org.fisco.bcos.sdk.v3.config.Config; import org.fisco.bcos.sdk.v3.config.ConfigOption; import org.fisco.bcos.sdk.v3.config.exceptions.ConfigException; @@ -89,6 +90,15 @@ public Client getClient(String groupId) throws BcosSDKException { } } + public TarsClient getTarsClient(String groupID) { + try { + return TarsClient.build(groupID, config, bcosSDKJniObj.getNativePointer()); + } catch (Exception e) { + logger.warn("create client for failed, error: ", e); + throw new BcosSDKException("get Client failed, e: " + e.getMessage(), e); + } + } + /** * Get a Client instance of default group in config * diff --git a/src/main/java/org/fisco/bcos/sdk/v3/client/Client.java b/src/main/java/org/fisco/bcos/sdk/v3/client/Client.java index 668f027b9..db59d2c07 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/client/Client.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/client/Client.java @@ -752,6 +752,44 @@ void getTransactionReceiptAsync( */ void getSealerListAsync(String node, RespCallback callback); + /** + * get node list by type + * + * @param type type of node, now support consensus_sealer, consensus_observer and + * consensus_candidate_sealer + * @return node list + */ + SealerList getNodeListByType(String type); + + /** + * get node list by type + * + * @param node the node rpc request send to + * @param type type of node, now support consensus_sealer, consensus_observer and + * consensus_candidate_sealer + * @return node list + */ + SealerList getNodeListByType(String node, String type); + + /** + * async get node list by type + * + * @param type type of node, now support consensus_sealer, consensus_observer and + * consensus_candidate_sealer + * @param callback the callback + */ + void getNodeListByTypeAsync(String type, RespCallback callback); + + /** + * async get node list by type + * + * @param node the node rpc request send to + * @param type type of node, now support consensus_sealer, consensus_observer and + * consensus_candidate_sealer + * @param callback the callback + */ + void getNodeListByTypeAsync(String node, String type, RespCallback callback); + /** * Peer operation: get pbft view * @@ -925,14 +963,35 @@ void getTransactionReceiptAsync( @Deprecated EnumNodeVersion getChainVersion(); + /** + * get the chain compatibility version + * + * @return the chain compatibility version + */ EnumNodeVersion.Version getChainCompatibilityVersion(); /** * async get the chain compatibility version * - * @param versionRespCallback the callback instance + * @param versionRespCallback the callback that will be called when receive the response + */ + void getChainCompatibilityVersionAsync( + RespCallback versionRespCallback); + + /** + * Set node name to send rpc request directly, if not set, will use random node in the + * groupInfoList. Node name should choose from groupInfo. + * + * @param nodeToSendRequest the node name + */ + void setNodeToSendRequest(String nodeToSendRequest); + + /** + * get node name to send rpc request directly + * + * @return the node name */ - void getChainVersionAsync(RespCallback versionRespCallback); + String getNodeToSendRequest(); void start(); diff --git a/src/main/java/org/fisco/bcos/sdk/v3/client/ClientImpl.java b/src/main/java/org/fisco/bcos/sdk/v3/client/ClientImpl.java index 76df28326..dad9bf6ed 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/client/ClientImpl.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/client/ClientImpl.java @@ -86,6 +86,7 @@ public class ClientImpl implements Client { private long blockNumber = 0; + private String nodeToSendRequest = ""; private final ConfigOption configOption; private BcosGroupInfo.GroupInfo groupInfo; private GroupNodeIniConfig groupNodeIniConfig; @@ -253,7 +254,7 @@ public Boolean isSerialExecute() { @Override public BcosTransactionReceipt sendTransaction(String signedTransactionData, boolean withProof) { - return this.sendTransaction("", signedTransactionData, withProof); + return this.sendTransaction(nodeToSendRequest, signedTransactionData, withProof); } @Override @@ -272,7 +273,7 @@ public BcosTransactionReceipt sendTransaction( @Override public void sendTransactionAsync( String signedTransactionData, boolean withProof, TransactionCallback callback) { - this.sendTransactionAsync("", signedTransactionData, withProof, callback); + this.sendTransactionAsync(nodeToSendRequest, signedTransactionData, withProof, callback); } @Override @@ -305,7 +306,7 @@ public void onError(Response errorResponse) { @Override public Call call(Transaction transaction) { - return this.call("", transaction); + return this.call(nodeToSendRequest, transaction); } @Override @@ -329,7 +330,7 @@ public Call call(String node, Transaction transaction) { @Override public Call call(Transaction transaction, String sign) { - return call("", transaction, sign); + return call(nodeToSendRequest, transaction, sign); } @Override @@ -358,7 +359,7 @@ public Call call(String node, Transaction transaction, String sign) { @Override public void callAsync(Transaction transaction, RespCallback callback) { - this.callAsync("", transaction, callback); + this.callAsync(nodeToSendRequest, transaction, callback); } @Override @@ -380,7 +381,7 @@ public void callAsync(String node, Transaction transaction, RespCallback c @Override public void callAsync(Transaction transaction, String sign, RespCallback callback) { - this.callAsync("", transaction, sign, callback); + this.callAsync(nodeToSendRequest, transaction, sign, callback); } @Override @@ -404,7 +405,7 @@ public void callAsync( @Override public BlockNumber getBlockNumber() { - return this.getBlockNumber(""); + return this.getBlockNumber(nodeToSendRequest); } @Override @@ -421,7 +422,7 @@ public BlockNumber getBlockNumber(String node) { @Override public void getBlockNumberAsync(RespCallback callback) { - this.getBlockNumberAsync("", callback); + this.getBlockNumberAsync(nodeToSendRequest, callback); } @Override @@ -438,7 +439,7 @@ public void getBlockNumberAsync(String node, RespCallback callback) @Override public Code getCode(String address) { - return this.getCode("", address); + return this.getCode(nodeToSendRequest, address); } @Override @@ -456,7 +457,7 @@ public Code getCode(String node, String address) { @Override public void getCodeAsync(String address, RespCallback callback) { - this.getCodeAsync("", address, callback); + this.getCodeAsync(nodeToSendRequest, address, callback); } @Override @@ -474,7 +475,7 @@ public void getCodeAsync(String node, String address, RespCallback callbac @Override public Abi getABI(String address) { - return this.getABI("", address); + return this.getABI(nodeToSendRequest, address); } @Override @@ -492,7 +493,7 @@ public Abi getABI(String node, String address) { @Override public void getABIAsync(String address, RespCallback callback) { - this.getABIAsync("", address, callback); + this.getABIAsync(nodeToSendRequest, address, callback); } @Override @@ -510,7 +511,7 @@ public void getABIAsync(String node, String address, RespCallback callback) @Override public TotalTransactionCount getTotalTransactionCount() { - return this.getTotalTransactionCount(""); + return this.getTotalTransactionCount(nodeToSendRequest); } @Override @@ -528,7 +529,7 @@ public TotalTransactionCount getTotalTransactionCount(String node) { @Override public void getTotalTransactionCountAsync(RespCallback callback) { - this.getTotalTransactionCountAsync("", callback); + this.getTotalTransactionCountAsync(nodeToSendRequest, callback); } @Override @@ -547,7 +548,7 @@ public void getTotalTransactionCountAsync( @Override public BcosBlock getBlockByHash(String blockHash, boolean onlyHeader, boolean onlyTxHash) { - return this.getBlockByHash("", blockHash, onlyHeader, onlyTxHash); + return this.getBlockByHash(nodeToSendRequest, blockHash, onlyHeader, onlyTxHash); } @Override @@ -569,7 +570,7 @@ public void getBlockByHashAsync( boolean onlyHeader, boolean onlyTxHash, RespCallback callback) { - this.getBlockByHashAsync("", blockHash, onlyHeader, onlyTxHash, callback); + this.getBlockByHashAsync(nodeToSendRequest, blockHash, onlyHeader, onlyTxHash, callback); } @Override @@ -593,7 +594,7 @@ public void getBlockByHashAsync( @Override public BcosBlock getBlockByNumber( BigInteger blockNumber, boolean onlyHeader, boolean onlyTxHash) { - return this.getBlockByNumber("", blockNumber, onlyHeader, onlyTxHash); + return this.getBlockByNumber(nodeToSendRequest, blockNumber, onlyHeader, onlyTxHash); } @Override @@ -615,7 +616,8 @@ public void getBlockByNumberAsync( boolean onlyHeader, boolean onlyTxHash, RespCallback callback) { - this.getBlockByNumberAsync("", blockNumber, onlyHeader, onlyTxHash, callback); + this.getBlockByNumberAsync( + nodeToSendRequest, blockNumber, onlyHeader, onlyTxHash, callback); } @Override @@ -638,7 +640,7 @@ public void getBlockByNumberAsync( @Override public BlockHash getBlockHashByNumber(BigInteger blockNumber) { - return this.getBlockHashByNumber("", blockNumber); + return this.getBlockHashByNumber(nodeToSendRequest, blockNumber); } @Override @@ -656,7 +658,7 @@ public BlockHash getBlockHashByNumber(String node, BigInteger blockNumber) { @Override public void getBlockHashByNumberAsync( BigInteger blockNumber, RespCallback callback) { - this.getBlockHashByNumberAsync("", blockNumber, callback); + this.getBlockHashByNumberAsync(nodeToSendRequest, blockNumber, callback); } @Override @@ -675,7 +677,7 @@ public void getBlockHashByNumberAsync( @Override public BcosTransaction getTransaction(String transactionHash, Boolean withProof) { - return this.getTransaction("", transactionHash, withProof); + return this.getTransaction(nodeToSendRequest, transactionHash, withProof); } @Override @@ -693,7 +695,7 @@ public BcosTransaction getTransaction(String node, String transactionHash, Boole @Override public void getTransactionAsync( String transactionHash, Boolean withProof, RespCallback callback) { - this.getTransactionAsync("", transactionHash, withProof, callback); + this.getTransactionAsync(nodeToSendRequest, transactionHash, withProof, callback); } @Override @@ -715,7 +717,7 @@ public void getTransactionAsync( @Override public BcosTransactionReceipt getTransactionReceipt(String transactionHash, Boolean withProof) { - return this.getTransactionReceipt("", transactionHash, withProof); + return this.getTransactionReceipt(nodeToSendRequest, transactionHash, withProof); } @Override @@ -736,7 +738,7 @@ public void getTransactionReceiptAsync( String transactionHash, Boolean withProof, RespCallback callback) { - this.getTransactionReceiptAsync("", transactionHash, withProof, callback); + this.getTransactionReceiptAsync(nodeToSendRequest, transactionHash, withProof, callback); } @Override @@ -758,7 +760,7 @@ public void getTransactionReceiptAsync( @Override public PendingTxSize getPendingTxSize() { - return this.getPendingTxSize(""); + return this.getPendingTxSize(nodeToSendRequest); } @Override @@ -774,7 +776,7 @@ public PendingTxSize getPendingTxSize(String node) { @Override public void getPendingTxSizeAsync(RespCallback callback) { - this.getPendingTxSizeAsync("", callback); + this.getPendingTxSizeAsync(nodeToSendRequest, callback); } @Override @@ -807,7 +809,7 @@ public BigInteger getBlockLimit() { public GroupPeers getGroupPeers() { return this.callRemoteMethod( this.groupID, - "", + nodeToSendRequest, new JsonRpcRequest<>( JsonRpcMethods.GET_GROUP_PEERS, Arrays.asList(this.groupID, "")), GroupPeers.class); @@ -817,7 +819,7 @@ public GroupPeers getGroupPeers() { public void getGroupPeersAsync(RespCallback callback) { this.asyncCallRemoteMethod( this.groupID, - "", + nodeToSendRequest, new JsonRpcRequest<>( JsonRpcMethods.GET_GROUP_PEERS, Arrays.asList(this.groupID, "")), GroupPeers.class, @@ -828,7 +830,7 @@ public void getGroupPeersAsync(RespCallback callback) { public Peers getPeers() { return this.callRemoteMethod( "", - "", + nodeToSendRequest, new JsonRpcRequest<>(JsonRpcMethods.GET_PEERS, Collections.emptyList()), Peers.class); } @@ -837,7 +839,7 @@ public Peers getPeers() { public void getPeersAsync(RespCallback callback) { this.asyncCallRemoteMethod( "", - "", + nodeToSendRequest, new JsonRpcRequest<>(JsonRpcMethods.GET_PEERS, Collections.emptyList()), Peers.class, callback); @@ -845,7 +847,7 @@ public void getPeersAsync(RespCallback callback) { @Override public ObserverList getObserverList() { - return this.getObserverList(""); + return this.getObserverList(nodeToSendRequest); } @Override @@ -861,7 +863,7 @@ public ObserverList getObserverList(String node) { @Override public void getObserverList(RespCallback callback) { - this.getObserverList("", callback); + this.getObserverList(nodeToSendRequest, callback); } @Override @@ -878,7 +880,7 @@ public void getObserverList(String node, RespCallback callback) { @Override public SealerList getSealerList() { - return this.getSealerList(""); + return this.getSealerList(nodeToSendRequest); } @Override @@ -894,7 +896,7 @@ public SealerList getSealerList(String node) { @Override public void getSealerListAsync(RespCallback callback) { - this.getSealerListAsync("", callback); + this.getSealerListAsync(nodeToSendRequest, callback); } @Override @@ -909,6 +911,42 @@ public void getSealerListAsync(String node, RespCallback callback) { callback); } + @Override + public SealerList getNodeListByType(String type) { + return getNodeListByType(nodeToSendRequest, type); + } + + @Override + public SealerList getNodeListByType(String node, String type) { + node = Objects.isNull(node) ? "" : node; + return this.callRemoteMethod( + this.groupID, + node, + new JsonRpcRequest<>( + JsonRpcMethods.GET_NODE_LIST_BY_TYPE, + Arrays.asList(this.groupID, node, type)), + SealerList.class); + } + + @Override + public void getNodeListByTypeAsync(String type, RespCallback callback) { + this.getNodeListByTypeAsync(nodeToSendRequest, type, callback); + } + + @Override + public void getNodeListByTypeAsync( + String node, String type, RespCallback callback) { + node = Objects.isNull(node) ? "" : node; + this.asyncCallRemoteMethod( + this.groupID, + node, + new JsonRpcRequest<>( + JsonRpcMethods.GET_NODE_LIST_BY_TYPE, + Arrays.asList(this.groupID, node, type)), + SealerList.class, + callback); + } + @Override public PbftView getPbftView() { return this.getPbftView(""); @@ -916,7 +954,7 @@ public PbftView getPbftView() { @Override public void getPbftViewAsync(RespCallback callback) { - this.getPbftViewAsync("", callback); + this.getPbftViewAsync(nodeToSendRequest, callback); } @Override @@ -944,7 +982,7 @@ public void getPbftViewAsync(String node, RespCallback callback) { @Override public SystemConfig getSystemConfigByKey(String key) { - return this.getSystemConfigByKey("", key); + return this.getSystemConfigByKey(nodeToSendRequest, key); } @Override @@ -961,7 +999,7 @@ public SystemConfig getSystemConfigByKey(String node, String key) { @Override public void getSystemConfigByKeyAsync(String key, RespCallback callback) { - this.getSystemConfigByKeyAsync("", key, callback); + this.getSystemConfigByKeyAsync(nodeToSendRequest, key, callback); } @Override @@ -990,12 +1028,12 @@ public SyncStatus getSyncStatus(String node) { @Override public SyncStatus getSyncStatus() { - return getSyncStatus(""); + return getSyncStatus(nodeToSendRequest); } @Override public void getSyncStatusAsync(RespCallback callback) { - this.getSyncStatusAsync("", callback); + this.getSyncStatusAsync(nodeToSendRequest, callback); } @Override @@ -1024,7 +1062,7 @@ public void getConsensusStatusAsync(String node, RespCallback c @Override public void getConsensusStatusAsync(RespCallback callback) { - this.getConsensusStatusAsync("", callback); + this.getConsensusStatusAsync(nodeToSendRequest, callback); } @Override @@ -1040,14 +1078,14 @@ public ConsensusStatus getConsensusStatus(String node) { @Override public ConsensusStatus getConsensusStatus() { - return getConsensusStatus(""); + return getConsensusStatus(nodeToSendRequest); } @Override public BcosGroupList getGroupList() { return this.callRemoteMethod( "", - "", + nodeToSendRequest, new JsonRpcRequest<>(JsonRpcMethods.GET_GROUP_LIST, Collections.emptyList()), BcosGroupList.class); } @@ -1056,7 +1094,7 @@ public BcosGroupList getGroupList() { public void getGroupListAsync(RespCallback callback) { this.asyncCallRemoteMethod( "", - "", + nodeToSendRequest, new JsonRpcRequest<>(JsonRpcMethods.GET_GROUP_LIST, Collections.emptyList()), BcosGroupList.class, callback); @@ -1126,7 +1164,7 @@ public void getGroupInfoAsync(RespCallback callback) { public BcosGroupInfoList getGroupInfoList() { return this.callRemoteMethod( "", - "", + nodeToSendRequest, new JsonRpcRequest<>(JsonRpcMethods.GET_GROUP_INFO_LIST, Collections.emptyList()), BcosGroupInfoList.class); } @@ -1135,7 +1173,7 @@ public BcosGroupInfoList getGroupInfoList() { public void getGroupInfoListAsync(RespCallback callback) { this.asyncCallRemoteMethod( "", - "", + nodeToSendRequest, new JsonRpcRequest<>(JsonRpcMethods.GET_GROUP_INFO_LIST, Collections.emptyList()), BcosGroupInfoList.class, callback); @@ -1186,7 +1224,8 @@ public EnumNodeVersion.Version getChainCompatibilityVersion() { } @Override - public void getChainVersionAsync(RespCallback versionRespCallback) { + public void getChainCompatibilityVersionAsync( + RespCallback versionRespCallback) { getGroupInfoAsync( new RespCallback() { @Override @@ -1212,6 +1251,23 @@ public void onError(Response errorResponse) { }); } + @Override + public void setNodeToSendRequest(String nodeToSendRequest) { + if (null == nodeToSendRequest || nodeToSendRequest.isEmpty()) { + this.nodeToSendRequest = ""; + return; + } + List nodeList = getGroupInfo().getResult().getNodeList(); + if (nodeList.stream().anyMatch(node -> node.getName().equals(nodeToSendRequest))) { + this.nodeToSendRequest = nodeToSendRequest; + } + } + + @Override + public String getNodeToSendRequest() { + return this.nodeToSendRequest; + } + @Override public void start() { if (rpcJniObj != null) { diff --git a/src/main/java/org/fisco/bcos/sdk/v3/client/TarsClient.java b/src/main/java/org/fisco/bcos/sdk/v3/client/TarsClient.java new file mode 100644 index 000000000..5bb18a258 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/v3/client/TarsClient.java @@ -0,0 +1,285 @@ +package org.fisco.bcos.sdk.v3.client; + +import java.io.File; +import java.io.InputStream; +import java.math.BigInteger; +import java.nio.file.Files; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import org.fisco.bcos.sdk.tars.Callback; +import org.fisco.bcos.sdk.tars.Config; +import org.fisco.bcos.sdk.tars.CryptoSuite; +import org.fisco.bcos.sdk.tars.LogEntry; +import org.fisco.bcos.sdk.tars.RPCClient; +import org.fisco.bcos.sdk.tars.SWIGTYPE_p_bcos__bytesConstRef; +import org.fisco.bcos.sdk.tars.SWIGTYPE_p_bcos__h256; +import org.fisco.bcos.sdk.tars.SWIGTYPE_p_std__vectorT_unsigned_char_t; +import org.fisco.bcos.sdk.tars.SendTransaction; +import org.fisco.bcos.sdk.tars.StringVector; +import org.fisco.bcos.sdk.tars.Transaction; +import org.fisco.bcos.sdk.tars.TransactionFactoryImpl; +import org.fisco.bcos.sdk.tars.TransactionReceipt; +import org.fisco.bcos.sdk.tars.bcos; +import org.fisco.bcos.sdk.v3.client.protocol.response.BcosTransactionReceipt; +import org.fisco.bcos.sdk.v3.config.ConfigOption; +import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback; +import org.fisco.bcos.sdk.v3.utils.Hex; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TarsClient extends ClientImpl implements Client { + private static Logger logger = LoggerFactory.getLogger(TarsClient.class); + private RPCClient tarsRPCClient; + private TransactionFactoryImpl transactionFactory; + private ThreadPoolExecutor asyncThreadPool; + private Callback callback; + + private static final int queueSize = 10 * 10000; + private static final String libFileName = System.mapLibraryName("bcos_swig_java"); + + private static class Content { + private SendTransaction sendTransaction; + private Transaction transaction; + private TransactionCallback callback; + + public SendTransaction getSendTransaction() { + return sendTransaction; + } + + public void setSendTransaction(SendTransaction sendTransaction) { + this.sendTransaction = sendTransaction; + } + + public Transaction getTransaction() { + return transaction; + } + + public void setTransaction(Transaction transaction) { + this.transaction = transaction; + } + + public TransactionCallback getCallback() { + return callback; + } + + public void setCallback(TransactionCallback callback) { + this.callback = callback; + } + }; + + ConcurrentHashMap callbackMap = + new ConcurrentHashMap(); + AtomicInteger currentSeq = new AtomicInteger(); + + public RPCClient getTarsRPCClient() { + return tarsRPCClient; + } + + public void setTarsRPCClient(RPCClient tarsRPCClient) { + this.tarsRPCClient = tarsRPCClient; + } + + public TransactionFactoryImpl getTransactionFactory() { + return transactionFactory; + } + + public void setTransactionFactory(TransactionFactoryImpl transactionFactory) { + this.transactionFactory = transactionFactory; + } + + protected TarsClient(String groupID, ConfigOption configOption, long nativePointer) + throws Exception { + super(groupID, configOption, nativePointer); + + loadLibrary(); + String connectionString = + RPCClient.toConnectionString( + new StringVector(configOption.getNetworkConfig().getTarsPeers())); + + logger.info("Tars connection: {}", connectionString); + Config config = new Config(); + config.setConnectionString(connectionString); + config.setSendQueueSize(queueSize); + config.setTimeoutMs(60 * 1000); + tarsRPCClient = new RPCClient(config); + + CryptoSuite cryptoSuite = + bcos.newCryptoSuite(configOption.getCryptoMaterialConfig().getUseSmCrypto()); + transactionFactory = new TransactionFactoryImpl(cryptoSuite); + asyncThreadPool = + new ThreadPoolExecutor( + 1, + configOption.getThreadPoolConfig().getThreadPoolSize(), + 0, + TimeUnit.SECONDS, + new ArrayBlockingQueue(queueSize)); + callback = + new Callback() { + public void onMessage(int seq) { + asyncThreadPool.submit( + () -> { + logger.debug("Receive seq: {}", seq); + Content content = callbackMap.remove(seq); + if (content != null) { + TransactionReceipt receipt = + content.getSendTransaction().get(); + content.getCallback() + .onResponse( + toJSONTransactionReceipt( + receipt, content.getTransaction())); + } + }); + } + }; + } + + private static AtomicBoolean loaded = new AtomicBoolean(false); + + private static void loadLibrary() throws Exception { + boolean inited = loaded.getAndSet(true); + if (inited) { + return; + } + try { + File jniFile = File.createTempFile(libFileName, UUID.randomUUID().toString()); + String osName = System.getProperty("os.name"); + if (osName.contains("Linux")) osName = "linux"; + else if (osName.contains("Mac OS X")) osName = "darwin"; + else if (osName.contains("Windows")) osName = "windows"; + + String osArch = System.getProperty("os.arch"); + if (osArch.contains("amd64")) osArch = "x86_64"; + + InputStream jniStream = + TarsClient.class.getResourceAsStream( + "/" + osName + "-" + osArch + "/" + libFileName); + Files.copy( + jniStream, + jniFile.getAbsoluteFile().toPath(), + java.nio.file.StandardCopyOption.REPLACE_EXISTING); + System.load(jniFile.getAbsolutePath()); + jniFile.deleteOnExit(); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + public static TarsClient build(String groupId, ConfigOption configOption, long nativePointer) + throws Exception { + logger.info( + "TarsClient build, groupID: {}, configOption: {}, nativePointer: {}", + groupId, + configOption, + nativePointer); + return new TarsClient(groupId, configOption, nativePointer); + } + + @Override + public BcosTransactionReceipt sendTransaction( + String node, String signedTransactionData, boolean withProof) { + if (withProof) { + return super.sendTransaction(node, signedTransactionData, withProof); + } + node = Objects.isNull(node) ? "" : node; + + Transaction transaction = toTransaction(signedTransactionData); + TransactionReceipt receipt = new SendTransaction(tarsRPCClient).send(transaction).get(); + BcosTransactionReceipt bcosReceipt = new BcosTransactionReceipt(); + bcosReceipt.setResult(toJSONTransactionReceipt(receipt, transaction)); + + return bcosReceipt; + } + + @Override + public void sendTransactionAsync( + String node, + String signedTransactionData, + boolean withProof, + TransactionCallback callback) { + logger.debug("sendTransactionAsync... {} {}", node, withProof); + if (withProof) { + super.sendTransactionAsync(node, signedTransactionData, withProof, callback); + return; + } + node = Objects.isNull(node) ? "" : node; + Transaction transaction = toTransaction(signedTransactionData); + sendTransactionAsync(transaction, callback); + } + + public void sendTransactionAsync(Transaction transaction, TransactionCallback callback) { + int seq = currentSeq.addAndGet(1); + + SendTransaction sendTransaction = new SendTransaction(tarsRPCClient); + sendTransaction.setCallback(this.callback); + sendTransaction.setSeq(seq); + + Content content = new Content(); + content.setSendTransaction(sendTransaction); + content.setTransaction(transaction); + content.setCallback(callback); + callbackMap.put(seq, content); + + sendTransaction.send(transaction); + } + + private Transaction toTransaction(String signedTransactionData) { + byte[] transactionBytes = Hex.decode(signedTransactionData); + + SWIGTYPE_p_std__vectorT_unsigned_char_t vectorTransactionBytes = + bcos.toBytes(transactionBytes); + SWIGTYPE_p_bcos__bytesConstRef ref = bcos.toBytesConstRef(vectorTransactionBytes); + Transaction transaction = transactionFactory.createTransaction(ref, false, false); + return transaction; + } + + private org.fisco.bcos.sdk.v3.model.TransactionReceipt toJSONTransactionReceipt( + TransactionReceipt receipt, Transaction transaction) { + org.fisco.bcos.sdk.v3.model.TransactionReceipt jsonReceipt = + new org.fisco.bcos.sdk.v3.model.TransactionReceipt(); + jsonReceipt.setTransactionHash("0x" + bcos.toHex(transaction.hash())); + jsonReceipt.setVersion(receipt.version()); + jsonReceipt.setReceiptHash("0x" + bcos.toHex(receipt.hash())); + jsonReceipt.setBlockNumber(BigInteger.valueOf(receipt.blockNumber())); + jsonReceipt.setFrom(bcos.toString(transaction.sender())); + jsonReceipt.setTo(bcos.toString(transaction.to())); + jsonReceipt.setGasUsed(bcos.toString(receipt.gasUsed())); + jsonReceipt.setContractAddress(bcos.toString(receipt.contractAddress())); + jsonReceipt.setChecksumContractAddress(jsonReceipt.getContractAddress()); // FIXME: how to? + jsonReceipt.setLogEntries( + bcos.logEntrySpanToVector(receipt.logEntries()).stream() + .map( + (LogEntry logEntry) -> { + org.fisco.bcos.sdk.v3.model.TransactionReceipt.Logs + rawLogEntry = + new org.fisco.bcos.sdk.v3.model + .TransactionReceipt.Logs(); + rawLogEntry.setAddress(bcos.toString(logEntry.address())); + rawLogEntry.setBlockNumber( + String.valueOf(receipt.blockNumber())); + rawLogEntry.setData("0x" + bcos.toHex(logEntry.data())); + rawLogEntry.setTopics( + bcos.h256SpanToVector(logEntry.topics()).stream() + .map( + (SWIGTYPE_p_bcos__h256 hash) -> { + return "0x" + bcos.toHex(hash); + }) + .collect(Collectors.toList())); + return rawLogEntry; + }) + .collect(Collectors.toList())); + jsonReceipt.setStatus(receipt.status()); + jsonReceipt.setInput("0x" + bcos.toHex(transaction.input())); + jsonReceipt.setOutput("0x" + bcos.toHex(receipt.output())); + jsonReceipt.setExtraData(bcos.toString(transaction.extraData())); + + return jsonReceipt; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/v3/client/protocol/request/JsonRpcMethods.java b/src/main/java/org/fisco/bcos/sdk/v3/client/protocol/request/JsonRpcMethods.java index 8f8fb5efd..97d762f23 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/client/protocol/request/JsonRpcMethods.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/client/protocol/request/JsonRpcMethods.java @@ -20,6 +20,7 @@ public class JsonRpcMethods { public static final String GET_PBFT_VIEW = "getPbftView"; public static final String GET_CONSENSUS_STATUS = "getConsensusStatus"; public static final String GET_SEALER_LIST = "getSealerList"; + public static final String GET_NODE_LIST_BY_TYPE = "getNodeListByType"; public static final String GET_SYSTEM_CONFIG_BY_KEY = "getSystemConfigByKey"; public static final String GET_OBSERVER_LIST = "getObserverList"; public static final String GET_SYNC_STATUS = "getSyncStatus"; diff --git a/src/main/java/org/fisco/bcos/sdk/v3/codec/datatypes/IntType.java b/src/main/java/org/fisco/bcos/sdk/v3/codec/datatypes/IntType.java index 8006d8d3a..67785dfcc 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/codec/datatypes/IntType.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/codec/datatypes/IntType.java @@ -19,10 +19,14 @@ public IntType(String typePrefix, int bitSize, BigInteger value) { } boolean valid(int bitSize, BigInteger value) { - return isValidBitSize(bitSize); + return isValidBitSize(bitSize) && isValidBitCount(bitSize, value); } static boolean isValidBitSize(int bitSize) { return bitSize % 8 == 0 && bitSize > 0 && bitSize <= MAX_BIT_LENGTH; } + + private static boolean isValidBitCount(int bitSize, BigInteger value) { + return value.bitLength() <= bitSize; + } } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/config/model/NetworkConfig.java b/src/main/java/org/fisco/bcos/sdk/v3/config/model/NetworkConfig.java index 3c472b7c0..828b25816 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/config/model/NetworkConfig.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/config/model/NetworkConfig.java @@ -27,6 +27,7 @@ public class NetworkConfig { private static final Logger logger = LoggerFactory.getLogger(NetworkConfig.class); private List peers; + private List tarsPeers; private int timeout = -1; private String defaultGroup; private boolean sendRpcRequestToHighestBlockNode = true; @@ -37,6 +38,7 @@ public NetworkConfig(ConfigProperty configProperty) { Map networkProperty = configProperty.getNetwork(); if (networkProperty != null) { peers = (List) networkProperty.get("peers"); + tarsPeers = (List) networkProperty.get("tarsPeers"); defaultGroup = (String) networkProperty.get("defaultGroup"); Object value = networkProperty.get("messageTimeout"); if (Objects.nonNull(value)) { @@ -63,6 +65,14 @@ public void setPeers(List peers) { this.peers = peers; } + public List getTarsPeers() { + return tarsPeers; + } + + public void setTarsPeers(List tarsPeers) { + this.tarsPeers = tarsPeers; + } + public String getDefaultGroup() { return defaultGroup; } @@ -92,6 +102,8 @@ public String toString() { return "NetworkConfig{" + "peers=" + peers + + ", tarsPeers=" + + tarsPeers + ", timeout=" + timeout + ", defaultGroup='" diff --git a/src/main/java/org/fisco/bcos/sdk/v3/contract/precompiled/sysconfig/SystemConfigFeature.java b/src/main/java/org/fisco/bcos/sdk/v3/contract/precompiled/sysconfig/SystemConfigFeature.java new file mode 100644 index 000000000..c113f7e94 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/v3/contract/precompiled/sysconfig/SystemConfigFeature.java @@ -0,0 +1,52 @@ +package org.fisco.bcos.sdk.v3.contract.precompiled.sysconfig; + +import org.fisco.bcos.sdk.v3.model.EnumNodeVersion; + +public class SystemConfigFeature { + public enum Features { + BUGFIX_REVERT("bugfix_revert", EnumNodeVersion.BCOS_3_2_3.getVersion()), + FEATURE_SHARDING("feature_sharding", EnumNodeVersion.BCOS_3_5_0.getVersion()), + FEATURE_RPBFT("feature_rpbft", EnumNodeVersion.BCOS_3_5_0.getVersion()), + FEATURE_RPBFT_EPOCH_BLOCK_NUM( + "feature_rpbft_epoch_block_num", EnumNodeVersion.BCOS_3_5_0.getVersion()), + FEATURE_RPBFT_EPOCH_SEALER_NUM( + "feature_rpbft_epoch_sealer_num", EnumNodeVersion.BCOS_3_5_0.getVersion()), + FEATURE_PAILLIER("feature_paillier", EnumNodeVersion.BCOS_3_5_0.getVersion()); + + private final String featureName; + private final int enableVersion; + + Features(String name, int enableVersion) { + this.featureName = name; + this.enableVersion = enableVersion; + } + + @Override + public String toString() { + return featureName; + } + + public int enableVersion() { + return enableVersion; + } + } + + public static Features fromString(String name) { + switch (name) { + case "bugfix_revert": + return Features.BUGFIX_REVERT; + case "feature_sharding": + return Features.FEATURE_SHARDING; + case "feature_rpbft": + return Features.FEATURE_RPBFT; + case "feature_rpbft_epoch_block_num": + return Features.FEATURE_RPBFT_EPOCH_BLOCK_NUM; + case "feature_rpbft_epoch_sealer_num": + return Features.FEATURE_RPBFT_EPOCH_SEALER_NUM; + case "feature_paillier": + return Features.FEATURE_PAILLIER; + default: + return null; + } + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/v3/model/EnumNodeVersion.java b/src/main/java/org/fisco/bcos/sdk/v3/model/EnumNodeVersion.java index ea357c7c3..93a950bdb 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/model/EnumNodeVersion.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/model/EnumNodeVersion.java @@ -9,8 +9,10 @@ public enum EnumNodeVersion { BCOS_3_0_0(0x03000000), BCOS_3_1_0(0x03010000), BCOS_3_2_0(0x03020000), + BCOS_3_2_3(0x03020300), BCOS_3_3_0(0x03030000), - BCOS_3_4_0(0x03040000); + BCOS_3_4_0(0x03040000), + BCOS_3_5_0(0x03050000); private final Integer version; private static final Map versionLookupMap = new HashMap<>(); @@ -20,8 +22,10 @@ public enum EnumNodeVersion { versionLookupMap.put(0x03000000, BCOS_3_0_0); versionLookupMap.put(0x03010000, BCOS_3_1_0); versionLookupMap.put(0x03020000, BCOS_3_2_0); + versionLookupMap.put(0x03020300, BCOS_3_2_3); versionLookupMap.put(0x03030000, BCOS_3_3_0); versionLookupMap.put(0x03040000, BCOS_3_4_0); + versionLookupMap.put(0x03050000, BCOS_3_5_0); } EnumNodeVersion(Integer version) { @@ -46,6 +50,8 @@ public String getVersionString() { return "3.3.0"; case BCOS_3_4_0: return "3.4.0"; + case BCOS_3_5_0: + return "3.5.0"; case UNKNOWN: default: return "0.0.0"; diff --git a/src/main/java/org/fisco/bcos/sdk/v3/model/NodeType.java b/src/main/java/org/fisco/bcos/sdk/v3/model/NodeType.java new file mode 100644 index 000000000..0e88ae1b7 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/v3/model/NodeType.java @@ -0,0 +1,14 @@ +package org.fisco.bcos.sdk.v3.model; + +public enum NodeType { + CONSENSUS_SEALER("consensus_sealer"), + CONSENSUS_OBSERVER("consensus_observer"), + CONSENSUS_CANDIDATE_SEALER("consensus_candidate_sealer"), + UNKNOWN("unknown"); + + private final String type; + + NodeType(String t) { + type = t; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/AssembleTransactionProcessor.java b/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/AssembleTransactionProcessor.java index 0efb08a0b..9cfb54300 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/AssembleTransactionProcessor.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/AssembleTransactionProcessor.java @@ -883,35 +883,43 @@ public CallResponse callAndGetResponse( String from, String to, String abi, String functionName, byte[] data) throws ContractCodecException, TransactionBaseException { Call call = this.executeCall(from, to, data); + CallResponse callResponse = this.parseCallResponseStatus(call.getCallResult()); ABIObject decodedResult = this.contractCodec.decodeMethodAndGetOutputAbiObject( abi, functionName, call.getCallResult().getOutput()); - return getCallResponse(call, decodedResult); + Pair, List> outputObject = + ContractCodecTools.decodeJavaObjectAndGetOutputObject(decodedResult); + callResponse.setReturnObject(outputObject.getLeft()); + callResponse.setReturnABIObject(outputObject.getRight()); + try { + callResponse.setResults(ContractCodecTools.getABIObjectTypeListResult(decodedResult)); + } catch (Exception ignored) { + log.error("decode results failed, ignored. value: {}", decodedResult); + } + return callResponse; } public CallResponse callAndGetResponse( String from, String to, ABIDefinition abiDefinition, byte[] data) throws ContractCodecException, TransactionBaseException { Call call = this.executeCall(from, to, data); - ABIObject abiObject = - contractCodec.decodeMethodAndGetOutAbiObjectByABIDefinition( - abiDefinition, call.getCallResult().getOutput()); - return getCallResponse(call, abiObject); + return getCallResponse(call, abiDefinition); } public CallResponse callWithSignAndGetResponse( String from, String to, ABIDefinition abiDefinition, byte[] data) throws ContractCodecException, TransactionBaseException { Call call = this.executeCallWithSign(from, to, data); - ABIObject abiObject = - contractCodec.decodeMethodAndGetOutAbiObjectByABIDefinition( - abiDefinition, call.getCallResult().getOutput()); - return getCallResponse(call, abiObject); + + return getCallResponse(call, abiDefinition); } - public CallResponse getCallResponse(Call call, ABIObject decodedResult) - throws TransactionBaseException { + public CallResponse getCallResponse(Call call, ABIDefinition abiDefinition) + throws TransactionBaseException, ContractCodecException { CallResponse callResponse = this.parseCallResponseStatus(call.getCallResult()); + ABIObject decodedResult = + contractCodec.decodeMethodAndGetOutAbiObjectByABIDefinition( + abiDefinition, call.getCallResult().getOutput()); Pair, List> outputObject = ContractCodecTools.decodeJavaObjectAndGetOutputObject(decodedResult); callResponse.setReturnObject(outputObject.getLeft()); diff --git a/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/TarsTransactionProcessor.java b/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/TarsTransactionProcessor.java new file mode 100644 index 000000000..76be4d6b7 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/TarsTransactionProcessor.java @@ -0,0 +1,70 @@ +package org.fisco.bcos.sdk.v3.transaction.manager; + +import org.fisco.bcos.sdk.tars.KeyPairInterface; +import org.fisco.bcos.sdk.tars.SWIGTYPE_p_bcos__bytesConstRef; +import org.fisco.bcos.sdk.tars.SWIGTYPE_p_std__shared_ptrT_KeyInterface_t; +import org.fisco.bcos.sdk.tars.SWIGTYPE_p_std__unique_ptrT_bcos__crypto__KeyPairInterface_t; +import org.fisco.bcos.sdk.tars.SWIGTYPE_p_std__vectorT_unsigned_char_t; +import org.fisco.bcos.sdk.tars.Transaction; +import org.fisco.bcos.sdk.tars.bcos; +import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.client.TarsClient; +import org.fisco.bcos.sdk.v3.crypto.keypair.CryptoKeyPair; +import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TarsTransactionProcessor extends TransactionProcessor { + private TarsClient tarsClient; + private static final Logger logger = LoggerFactory.getLogger(TarsTransactionProcessor.class); + + public TarsTransactionProcessor( + Client client, CryptoKeyPair cryptoKeyPair, String groupId, String chainId) { + super(client, cryptoKeyPair, groupId, chainId); + tarsClient = (TarsClient) client; + } + + @Override + public String sendTransactionAsync( + String to, + byte[] data, + CryptoKeyPair cryptoKeyPair, + int txAttribute, + TransactionCallback callback) { + String extraData = client.getExtraData(); + + String hexPrivateKey = cryptoKeyPair.getHexPrivateKey(); + SWIGTYPE_p_std__vectorT_unsigned_char_t privateKey = bcos.fromHex(hexPrivateKey); + SWIGTYPE_p_bcos__bytesConstRef privateKeyRef = bcos.toBytesConstRef(privateKey); + SWIGTYPE_p_std__shared_ptrT_KeyInterface_t key = + tarsClient + .getTransactionFactory() + .cryptoSuite() + .keyFactory() + .createKey(privateKeyRef); + SWIGTYPE_p_std__unique_ptrT_bcos__crypto__KeyPairInterface_t sharedKeyPair = + tarsClient.getTransactionFactory().cryptoSuite().signatureImpl().createKeyPair(key); + KeyPairInterface keyPair = bcos.pointerToReference(sharedKeyPair); + SWIGTYPE_p_std__vectorT_unsigned_char_t input = bcos.toBytes(data); + + Transaction transaction = + tarsClient + .getTransactionFactory() + .createTransaction( + 0, + to, + input, + tarsClient.getTarsRPCClient().generateNonce(), + client.getBlockLimit().longValue(), + client.getChainId(), + client.getGroup(), + 0, + keyPair, + ""); + transaction.setExtraData(extraData); + transaction.setAttribute(txAttribute); + tarsClient.sendTransactionAsync(transaction, callback); + + return bcos.toHex(transaction.hash()); + } +}