From fe07802c1cc07e7ebe0c6196c0c240bc72e50c4b Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:32:32 +0800 Subject: [PATCH] (client,transaction): add get support configs interfaces, fix transaction builder set extension version bug. (#922) * (client): add get support configs interfaces. * (transaction,contract): fix transaction builder set extension version bug. --- build.gradle | 2 +- .../fisco/bcos/sdk/v3/test/BcosSDKTest.java | 12 ++ .../org/fisco/bcos/sdk/v3/client/Client.java | 24 +++ .../fisco/bcos/sdk/v3/client/ClientImpl.java | 154 ++++++++++++++++-- .../v3/client/exceptions/ClientException.java | 2 + .../protocol/response/BcosGroupNodeInfo.java | 12 +- .../sdk/v3/config/model/NetworkConfig.java | 2 +- .../v3/contract/auth/manager/AuthManager.java | 35 ++-- .../sysconfig/SystemConfigService.java | 6 + .../org/fisco/bcos/sdk/v3/model/Response.java | 4 + .../transactionv1/dto/BasicRequest.java | 4 + .../utils/TransactionRequestBuilder.java | 33 +++- .../model/dto/TransactionResponse.java | 2 +- 13 files changed, 256 insertions(+), 36 deletions(-) diff --git a/build.gradle b/build.gradle index 1d1cb98fe..fcdd0bf78 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ ext { // integrationTest.mustRunAfter test allprojects { group = 'org.fisco-bcos.java-sdk' - version = '3.7.0' + version = '3.8.0-SNAPSHOT' apply plugin: 'maven-publish' apply plugin: 'idea' 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 e3f4f713a..dd5619f86 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 @@ -21,6 +21,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -92,6 +94,16 @@ public void testClient() { System.out.println( "New block, group: " + groupId + ", blockNumber: " + blockNumber)); + Map> systemConfigList = client.getSystemConfigList(); + systemConfigList.forEach( + (key, value) -> + System.out.println( + key + + " : " + + (value.isPresent() + ? value.get().getSystemConfig() + : "null"))); + // test getBlockNumber BlockNumber blockNumber = client.getBlockNumber(); Assert.assertTrue(blockNumber.getBlockNumber().compareTo(BigInteger.ZERO) >= 0); 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 b33167847..51f212822 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 @@ -16,6 +16,9 @@ package org.fisco.bcos.sdk.v3.client; import java.math.BigInteger; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import org.fisco.bcos.sdk.jni.BcosSDKJniObj; import org.fisco.bcos.sdk.v3.client.protocol.request.Transaction; import org.fisco.bcos.sdk.v3.client.protocol.response.Abi; @@ -840,6 +843,13 @@ void getTransactionReceiptAsync( */ SystemConfig getSystemConfigByKey(String node, String key); + /** + * Peer operation: get system config list, witch will fetch all config + * + * @return all config value + */ + Map> getSystemConfigList(); + /** * Peer operation: async get system config * @@ -857,6 +867,20 @@ void getTransactionReceiptAsync( */ void getSystemConfigByKeyAsync(String node, String key, RespCallback callback); + /** + * async get all connect nodes support keys + * + * @param callback the callback instance + */ + void getSupportSysConfigKeysAsync(RespCallback> callback); + + /** + * Peer operation: async get system config list, witch will fetch all config + * + * @param callback the callback instance + */ + void getSystemConfigListAsync(RespCallback>> callback); + /** * Peer operation: get sync status * 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 cddf58a2c..0d7b14e81 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 @@ -21,9 +21,17 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; import org.fisco.bcos.sdk.jni.BcosSDKJniObj; import org.fisco.bcos.sdk.jni.rpc.RpcJniObj; import org.fisco.bcos.sdk.v3.client.exceptions.ClientException; @@ -58,6 +66,7 @@ import org.fisco.bcos.sdk.v3.client.protocol.response.SystemConfig; import org.fisco.bcos.sdk.v3.client.protocol.response.TotalTransactionCount; import org.fisco.bcos.sdk.v3.config.ConfigOption; +import org.fisco.bcos.sdk.v3.contract.precompiled.sysconfig.SystemConfigFeature; import org.fisco.bcos.sdk.v3.contract.precompiled.sysconfig.SystemConfigService; import org.fisco.bcos.sdk.v3.crypto.CryptoSuite; import org.fisco.bcos.sdk.v3.model.CryptoType; @@ -1008,6 +1017,32 @@ public SystemConfig getSystemConfigByKey(String node, String key) { SystemConfig.class); } + @Override + public Map> getSystemConfigList() { + CompletableFuture>> future = new CompletableFuture<>(); + this.getSystemConfigListAsync( + new RespCallback>>() { + @Override + public void onResponse(Map> configMap) { + future.complete(configMap); + } + + @Override + public void onError(Response errorResponse) { + future.completeExceptionally( + new ClientException( + "getSystemConfigList failed, error: " + + errorResponse.getErrorMessage())); + } + }); + try { + return future.get(configOption.getNetworkConfig().getTimeout(), TimeUnit.MILLISECONDS); + } catch (Exception e) { + logger.warn("getSystemConfigList failed, error: {}", e.getMessage(), e); + throw new ClientException("getSystemConfigList failed, error: " + e.getMessage(), e); + } + } + @Override public void getSystemConfigByKeyAsync(String key, RespCallback callback) { this.getSystemConfigByKeyAsync(nodeToSendRequest, key, callback); @@ -1026,6 +1061,89 @@ public void getSystemConfigByKeyAsync( callback); } + @Override + public void getSupportSysConfigKeysAsync(RespCallback> callback) { + this.getGroupInfoListAsync( + new RespCallback() { + @Override + public void onResponse(BcosGroupInfoList bcosGroupInfoList) { + Optional group = + bcosGroupInfoList.getResult().stream() + .filter(gInfo -> gInfo.getGroupID().equals(getGroup())) + .findFirst(); + Set keys = new TreeSet<>(); + keys.addAll( + Arrays.stream(SystemConfigFeature.Features.values()) + .map(SystemConfigFeature.Features::toString) + .collect(Collectors.toList())); + keys.addAll(SystemConfigService.getConfigKeys()); + if (group.isPresent() && !group.get().getNodeList().isEmpty()) { + group.get() + .getNodeList() + .forEach( + groupNodeInfo -> { + keys.addAll(groupNodeInfo.getFeatureKeys()); + keys.addAll(groupNodeInfo.getSupportConfigs()); + }); + } + callback.onResponse(keys); + } + + @Override + public void onError(Response errorResponse) { + callback.onError(errorResponse); + } + }); + } + + @Override + public void getSystemConfigListAsync( + RespCallback>> callback) { + + this.getSupportSysConfigKeysAsync( + new RespCallback>() { + @Override + public void onResponse(Set keys) { + Map> configMap = + new ConcurrentSkipListMap<>(); + if (keys.isEmpty()) { + callback.onResponse(configMap); + return; + } + keys.forEach( + key -> + getSystemConfigByKeyAsync( + key, + new RespCallback() { + @Override + public void onResponse( + SystemConfig systemConfig) { + configMap.put( + key, + Optional.ofNullable(systemConfig)); + if (configMap.size() == keys.size()) { + callback.onResponse(configMap); + } + } + + @Override + public void onError(Response errorResponse) { + // maybe not exist + configMap.put(key, Optional.empty()); + if (configMap.size() == keys.size()) { + callback.onResponse(configMap); + } + } + })); + } + + @Override + public void onError(Response errorResponse) { + callback.onError(errorResponse); + } + }); + } + @Override public SyncStatus getSyncStatus(String node) { node = Objects.isNull(node) ? "" : node; @@ -1130,7 +1248,8 @@ public BcosGroupInfo getGroupInfo() { future.complete(response); }); - Response response = future.get(); + Response response = + future.get(configOption.getNetworkConfig().getTimeout(), TimeUnit.MILLISECONDS); return ClientImpl.parseResponseIntoJsonRpcResponse( JsonRpcMethods.GET_GROUP_INFO, response, BcosGroupInfo.class); } catch (ClientException e) { @@ -1146,6 +1265,12 @@ public BcosGroupInfo getGroupInfo() { "getGroupInfo failed for decode the message exception, error message:" + e.getMessage(), e); + } catch (TimeoutException e) { + logger.error("e: ", e); + throw new ClientException( + "getGroupInfo failed for get group info timeout, error message:" + + e.getMessage(), + e); } } @@ -1604,41 +1729,44 @@ public static > T parseResponseIntoJsonRpcResponse( // parse the response into JsonRPCResponse T jsonRpcResponse = getObjectMapper().readValue(response.getContent(), responseType); - if (jsonRpcResponse.getError() != null) { - logger.error( - "parseResponseIntoJsonRpcResponse failed for non-empty error message, method: {}, retErrorMessage: {}, retErrorCode: {}", + // error code inside json rpc response + if (jsonRpcResponse.hasError()) { + logger.info( + "parseResponseIntoJsonRpcResponse failed for non-empty error message, method: {}, msg: {}, code: {}, rawRsp: {}", method, jsonRpcResponse.getError().getMessage(), - jsonRpcResponse.getError().getCode()); + jsonRpcResponse.getError().getCode(), + response.getContentString()); throw new ClientException( jsonRpcResponse.getError().getCode(), jsonRpcResponse.getError().getMessage(), - "ErrorMessage: " + jsonRpcResponse.getError().getMessage()); + "msg: " + jsonRpcResponse.getError().getMessage()); } return jsonRpcResponse; } else { - logger.error( - "parseResponseIntoJsonRpcResponse failed, method: {}, retErrorMessage: {}, retErrorCode: {}", + logger.info( + "parseResponseIntoJsonRpcResponse failed, method: {}, msg: {}, code: {}, rawRsp: {}", method, response.getErrorMessage(), - response.getErrorCode()); + response.getErrorCode(), + response.getContent()); throw new ClientException( response.getErrorCode(), response.getErrorMessage(), - "get response failed, errorCode: " + "get response failed, code: " + response.getErrorCode() - + ", error message: " + + ", msg: " + response.getErrorMessage()); } } catch (ClientException e) { - logger.error( + logger.info( "parseResponseIntoJsonRpcResponse failed for decode the message exception, response: {}, errorMessage: {}", response, e.getMessage(), e); throw e; } catch (Exception e) { - logger.error( + logger.info( "parseResponseIntoJsonRpcResponse failed for decode the message exception, response: {}, errorMessage: {}", response, e.getMessage(), diff --git a/src/main/java/org/fisco/bcos/sdk/v3/client/exceptions/ClientException.java b/src/main/java/org/fisco/bcos/sdk/v3/client/exceptions/ClientException.java index 1d0997bf6..f54adf5f3 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/client/exceptions/ClientException.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/client/exceptions/ClientException.java @@ -64,6 +64,8 @@ public String toString() { + ", errorMessage='" + errorMessage + '\'' + + ", msg=" + + getMessage() + '}'; } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/client/protocol/response/BcosGroupNodeInfo.java b/src/main/java/org/fisco/bcos/sdk/v3/client/protocol/response/BcosGroupNodeInfo.java index cf484812e..07aa85466 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/client/protocol/response/BcosGroupNodeInfo.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/client/protocol/response/BcosGroupNodeInfo.java @@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.util.Converter; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import org.fisco.bcos.sdk.v3.client.protocol.model.GroupNodeIniInfo; import org.fisco.bcos.sdk.v3.model.JsonRpcResponse; @@ -80,7 +81,8 @@ public static class GroupNodeInfo { private String name; private List serviceInfoList; private Protocol protocol; - private List featureKeys; + private List featureKeys = new ArrayList<>(); + private List supportConfigs = new ArrayList<>(); @Override public String toString() { @@ -150,6 +152,14 @@ public void setFeatureKeys(List featureKeys) { this.featureKeys = featureKeys; } + public List getSupportConfigs() { + return supportConfigs; + } + + public void setSupportConfigs(List supportConfigs) { + this.supportConfigs = supportConfigs; + } + static class ServiceInfo { private String serviceName; private int type; 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 828b25816..54945f33b 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 @@ -28,7 +28,7 @@ public class NetworkConfig { private List peers; private List tarsPeers; - private int timeout = -1; + private int timeout = 10000; // ms private String defaultGroup; private boolean sendRpcRequestToHighestBlockNode = true; diff --git a/src/main/java/org/fisco/bcos/sdk/v3/contract/auth/manager/AuthManager.java b/src/main/java/org/fisco/bcos/sdk/v3/contract/auth/manager/AuthManager.java index 6617119b8..faf1c8866 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/contract/auth/manager/AuthManager.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/contract/auth/manager/AuthManager.java @@ -898,20 +898,29 @@ private RetCode getRetCode( private void getExecEvent(TransactionReceipt tr, BigInteger proposalId) throws ContractException { - List execResultEvents = - committeeManager.getExecResultEvents(tr); - if (!execResultEvents.isEmpty()) { - BigInteger execResultParam0 = execResultEvents.get(0).execResultParam0; - if (!BigInteger.ZERO.equals(execResultParam0)) { - RetCode precompiledResponse = - PrecompiledRetCode.getPrecompiledResponse(execResultParam0.intValue(), ""); - throw new ContractException( - "Exec proposal finished with error occurs, proposalId: " - + proposalId - + ", exec error msg: " - + precompiledResponse.getMessage(), - precompiledResponse.getCode()); + try { + List execResultEvents = + committeeManager.getExecResultEvents(tr); + if (!execResultEvents.isEmpty()) { + BigInteger execResultParam0 = execResultEvents.get(0).execResultParam0; + if (!BigInteger.ZERO.equals(execResultParam0)) { + RetCode precompiledResponse = + PrecompiledRetCode.getPrecompiledResponse( + execResultParam0.intValue(), ""); + throw new ContractException( + "Exec proposal finished with error occurs, proposalId: " + + proposalId + + ", exec error msg: " + + precompiledResponse.getMessage(), + precompiledResponse.getCode()); + } } + } catch (Exception e) { + throw new ContractException( + "Exec proposal finished with exception, proposalId: " + + proposalId + + ", exception msg: " + + e.getMessage()); } } } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/contract/precompiled/sysconfig/SystemConfigService.java b/src/main/java/org/fisco/bcos/sdk/v3/contract/precompiled/sysconfig/SystemConfigService.java index 42c597b8f..eec128f30 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/contract/precompiled/sysconfig/SystemConfigService.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/contract/precompiled/sysconfig/SystemConfigService.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; import org.fisco.bcos.sdk.v3.client.Client; @@ -56,6 +57,7 @@ public class SystemConfigService { predicateMap.put( TX_GAS_LIMIT, value -> value.compareTo(BigInteger.valueOf(TX_GAS_LIMIT_MIN)) >= 0); predicateMap.put(TX_GAS_PRICE, value -> value.compareTo(BigInteger.ZERO) >= 0); + predicateMap.put(COMPATIBILITY_VERSION, value -> true); } public SystemConfigService(Client client, CryptoKeyPair credential) { @@ -150,6 +152,10 @@ public static boolean isCheckableInValueValidation(String key) { return predicateMap.containsKey(key); } + public static Set getConfigKeys() { + return predicateMap.keySet(); + } + public static boolean checkCompatibilityVersion(Client client, String version) { try { EnumNodeVersion.Version setVersion = EnumNodeVersion.getClassVersion(version); diff --git a/src/main/java/org/fisco/bcos/sdk/v3/model/Response.java b/src/main/java/org/fisco/bcos/sdk/v3/model/Response.java index 5211edbb1..0e98fabb5 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/model/Response.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/model/Response.java @@ -47,6 +47,10 @@ public byte[] getContent() { return content; } + public String getContentString() { + return new String(content); + } + public void setContent(byte[] content) { this.content = content; } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/transactionv1/dto/BasicRequest.java b/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/transactionv1/dto/BasicRequest.java index 6e9973dc0..ba99e67ba 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/transactionv1/dto/BasicRequest.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/transactionv1/dto/BasicRequest.java @@ -119,6 +119,10 @@ public TransactionVersion getVersion() { } public void setVersion(TransactionVersion version) { + if (this.version.getValue() < version.getValue()) this.version = version; + } + + public void setVersionForce(TransactionVersion version) { this.version = version; } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/transactionv1/utils/TransactionRequestBuilder.java b/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/transactionv1/utils/TransactionRequestBuilder.java index e9ac22aa6..82bfab0aa 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/transactionv1/utils/TransactionRequestBuilder.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/transaction/manager/transactionv1/utils/TransactionRequestBuilder.java @@ -39,6 +39,18 @@ public TransactionRequestBuilder(String abi, String bin) { this.bin = bin; } + public TransactionRequestBuilder setVersion(TransactionVersion version) { + if (this.version.getValue() < version.getValue()) { + this.version = version; + } + return this; + } + + public TransactionRequestBuilder setVersionForce(TransactionVersion version) { + this.version = version; + return this; + } + public TransactionRequestBuilder setMethod(String method) { this.method = method; return this; @@ -66,31 +78,41 @@ public TransactionRequestBuilder setNonce(String nonce) { public TransactionRequestBuilder setValue(BigInteger value) { this.value = value; - if (value != null) this.version = TransactionVersion.V1; + if (value != null) { + return setVersion(TransactionVersion.V1); + } return this; } public TransactionRequestBuilder setGasPrice(BigInteger gasPrice) { this.gasPrice = gasPrice; - if (gasPrice != null) this.version = TransactionVersion.V1; + if (gasPrice != null) { + return setVersion(TransactionVersion.V1); + } return this; } public TransactionRequestBuilder setGasLimit(BigInteger gasLimit) { this.gasLimit = gasLimit; - if (gasLimit != null) this.version = TransactionVersion.V1; + if (gasLimit != null) { + return setVersion(TransactionVersion.V1); + } return this; } public TransactionRequestBuilder setEIP1559Struct(EIP1559Struct eip1559Struct) { this.eip1559Struct = eip1559Struct; - if (eip1559Struct != null) this.version = TransactionVersion.V1; + if (eip1559Struct != null) { + setVersion(TransactionVersion.V1); + } return this; } public TransactionRequestBuilder setExtension(byte[] extension) { this.extension = extension; - if (extension != null && extension.length > 0) this.version = TransactionVersion.V2; + if (extension != null && extension.length > 0) { + setVersion(TransactionVersion.V2); + } return this; } @@ -116,7 +138,6 @@ public TransactionRequest buildRequest(List params) throws ContractExcep this.gasLimit, this.eip1559Struct, this.extension); - sendTransactionRequest.setVersion(version); sendTransactionRequest.setParams(params); return sendTransactionRequest; } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/transaction/model/dto/TransactionResponse.java b/src/main/java/org/fisco/bcos/sdk/v3/transaction/model/dto/TransactionResponse.java index 1afe41abb..737547baa 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/transaction/model/dto/TransactionResponse.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/transaction/model/dto/TransactionResponse.java @@ -32,7 +32,7 @@ public class TransactionResponse extends CommonResponse { private TransactionReceipt transactionReceipt; private String contractAddress; - private String values; + @Deprecated private String values; private String events; private String receiptMessages; private List returnObject;