Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tars sdk impl #818

Merged
merged 15 commits into from
Aug 28, 2023
6 changes: 4 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ext {
slf4jApiVerison = '1.7.36'
mockitoVersion = '4.8.0'
gsonVersion = '2.10.1'
tarsSDKVersion = '3.5.0-SNAPSHOT'
}

// check.dependsOn integrationTest
Expand Down Expand Up @@ -59,8 +60,8 @@ 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 {
Expand Down Expand Up @@ -124,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"
Expand Down Expand Up @@ -181,6 +183,7 @@ javadoc {
task sourcesJar(type: Jar) {
from sourceSets.main.allJava
archiveClassifier = 'sources'
duplicatesStrategy = 'warn'
}

task javadocJar(type: Jar) {
Expand All @@ -207,7 +210,6 @@ tasks.withType(Test) {
publishing {
publications {
mavenJava(MavenPublication) {

artifactId "fisco-bcos-" + project.name
groupId project.group
version project.version
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/fisco/bcos/sdk/v3/BcosSDK.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
*
Expand Down
178 changes: 178 additions & 0 deletions src/main/java/org/fisco/bcos/sdk/v3/client/TarsClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package org.fisco.bcos.sdk.v3.client;

import java.math.BigInteger;
import java.net.URL;
import java.util.Objects;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
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;
static final int queueSize = 10 * 10000;
static final String libFileName = System.mapLibraryName("bcos_swig_java");

protected TarsClient(String groupID, ConfigOption configOption, long nativePointer) {
super(groupID, configOption, nativePointer);
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(configOption.getNetworkConfig().getTimeout() * 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<Runnable>(queueSize));
}

public static void loadLibrary() {
URL configUrl = TarsClient.class.getClassLoader().getResource(libFileName);
System.load(configUrl.getPath());
}

public static void loadLibrary(String libPath) {
System.load(libPath);
}

public static TarsClient build(String groupId, ConfigOption configOption, long nativePointer) {
logger.info(
"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) {
if (withProof) {
super.sendTransactionAsync(node, signedTransactionData, withProof, callback);
return;
}
node = Objects.isNull(node) ? "" : node;
Transaction transaction = toTransaction(signedTransactionData);
SendTransaction sendTransaction = new SendTransaction(tarsRPCClient);

sendTransaction.setCallback(
new Callback() {
public void onMessage() {

Check notice

Code scanning / CodeQL

Missing Override annotation Note

This method overrides
Callback.onMessage
; it is advisable to add an Override annotation.
asyncThreadPool.submit(
() -> {
TransactionReceipt receipt = sendTransaction.get();
callback.onResponse(
toJSONTransactionReceipt(receipt, transaction));
});
}
});
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class NetworkConfig {
private static final Logger logger = LoggerFactory.getLogger(NetworkConfig.class);

private List<String> peers;
private List<String> tarsPeers;
private int timeout = -1;
private String defaultGroup;
private boolean sendRpcRequestToHighestBlockNode = true;
Expand All @@ -37,6 +38,7 @@ public NetworkConfig(ConfigProperty configProperty) {
Map<String, Object> networkProperty = configProperty.getNetwork();
if (networkProperty != null) {
peers = (List<String>) networkProperty.get("peers");
tarsPeers = (List<String>) networkProperty.get("tarsPeers");
defaultGroup = (String) networkProperty.get("defaultGroup");
Object value = networkProperty.get("messageTimeout");
if (Objects.nonNull(value)) {
Expand All @@ -63,6 +65,14 @@ public void setPeers(List<String> peers) {
this.peers = peers;
}

public List<String> getTarsPeers() {
return tarsPeers;
}

public void setTarsPeers(List<String> tarsPeers) {
this.tarsPeers = tarsPeers;
}

public String getDefaultGroup() {
return defaultGroup;
}
Expand Down Expand Up @@ -92,6 +102,8 @@ public String toString() {
return "NetworkConfig{"
+ "peers="
+ peers
+ ", tarsPeers="
+ tarsPeers
+ ", timeout="
+ timeout
+ ", defaultGroup='"
Expand Down
Loading