From a0f1ba780ce31ac42c4e90ddb4dfcd39abed1405 Mon Sep 17 00:00:00 2001 From: XingQiang Bai Date: Fri, 14 Jul 2023 10:06:56 +0800 Subject: [PATCH 01/11] add paillier and modify generate of evidence and evidence (#169) * modify generateTx * use multi files * add simpleEvidence * add paillier --- .../demo/contract/PaillierPrecompiled.java | 132 ++++++++ .../demo/contract/SimpleEvidenceFactory.java | 155 ++++++++++ .../sdk/demo/contract/sol/SimpleEvidence.sol | 19 +- .../contract/sol/SimpleEvidenceFactory.sol | 16 + .../bcos/sdk/demo/perf/ParallelOkPerf.java | 5 +- .../sdk/demo/perf/PerformanceEvidence.java | 150 ++++++++- .../perf/PerformancePaillierPrecompiled.java | 178 +++++++++++ .../demo/perf/PerformanceSimpleEvidence.java | 284 ++++++++++++++++++ .../sdk/demo/perf/paillier/CommonUtils.java | 109 +++++++ .../demo/perf/paillier/PaillierCipher.java | 129 ++++++++ .../demo/perf/paillier/PaillierKeyPair.java | 118 ++++++++ .../demo/perf/parallel/ParallelOkDemo.java | 171 ++++++++--- 12 files changed, 1393 insertions(+), 73 deletions(-) create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/contract/PaillierPrecompiled.java create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/contract/SimpleEvidenceFactory.java create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/contract/sol/SimpleEvidenceFactory.sol create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceSimpleEvidence.java create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/CommonUtils.java create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/PaillierCipher.java create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/PaillierKeyPair.java diff --git a/src/main/java/org/fisco/bcos/sdk/demo/contract/PaillierPrecompiled.java b/src/main/java/org/fisco/bcos/sdk/demo/contract/PaillierPrecompiled.java new file mode 100644 index 0000000..bbbf9e3 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/contract/PaillierPrecompiled.java @@ -0,0 +1,132 @@ +package org.fisco.bcos.sdk.demo.contract; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.codec.datatypes.Function; +import org.fisco.bcos.sdk.v3.codec.datatypes.Type; +import org.fisco.bcos.sdk.v3.codec.datatypes.TypeReference; +import org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String; +import org.fisco.bcos.sdk.v3.codec.datatypes.generated.tuples.generated.Tuple1; +import org.fisco.bcos.sdk.v3.codec.datatypes.generated.tuples.generated.Tuple2; +import org.fisco.bcos.sdk.v3.contract.Contract; +import org.fisco.bcos.sdk.v3.crypto.CryptoSuite; +import org.fisco.bcos.sdk.v3.crypto.keypair.CryptoKeyPair; +import org.fisco.bcos.sdk.v3.model.CryptoType; +import org.fisco.bcos.sdk.v3.model.TransactionReceipt; +import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback; +import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; + +@SuppressWarnings("unchecked") +public class PaillierPrecompiled extends Contract { + public static final String[] BINARY_ARRAY = {}; + + public static final String BINARY = + org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", BINARY_ARRAY); + + public static final String[] SM_BINARY_ARRAY = {}; + + public static final String SM_BINARY = + org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", SM_BINARY_ARRAY); + + public static final String[] ABI_ARRAY = { + "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"cipher1\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"cipher2\",\"type\":\"string\"}],\"name\":\"paillierAdd\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"selector\":[2475587176,2331773994],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + }; + + public static final String ABI = org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", ABI_ARRAY); + + public static final String FUNC_PAILLIERADD = "paillierAdd"; + + protected PaillierPrecompiled(String contractAddress, Client client, CryptoKeyPair credential) { + super(getBinary(client.getCryptoSuite()), contractAddress, client, credential); + } + + public static String getBinary(CryptoSuite cryptoSuite) { + return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY); + } + + public static String getABI() { + return ABI; + } + + public TransactionReceipt paillierAdd(String cipher1, String cipher2) { + final Function function = + new Function( + FUNC_PAILLIERADD, + Arrays.asList( + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(cipher1), + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(cipher2)), + Collections.>emptyList(), + 0); + return executeTransaction(function); + } + + public String getSignedTransactionForPaillierAdd(String cipher1, String cipher2) { + final Function function = + new Function( + FUNC_PAILLIERADD, + Arrays.asList( + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(cipher1), + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(cipher2)), + Collections.>emptyList(), + 0); + return createSignedTransaction(function); + } + + public String paillierAdd(String cipher1, String cipher2, TransactionCallback callback) { + final Function function = + new Function( + FUNC_PAILLIERADD, + Arrays.asList( + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(cipher1), + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(cipher2)), + Collections.>emptyList(), + 0); + return asyncExecuteTransaction(function, callback); + } + + public Tuple2 getPaillierAddInput(TransactionReceipt transactionReceipt) { + String data = transactionReceipt.getInput().substring(10); + final Function function = + new Function( + FUNC_PAILLIERADD, + Arrays.asList(), + Arrays.>asList( + new TypeReference() {}, + new TypeReference() {})); + List results = + this.functionReturnDecoder.decode(data, function.getOutputParameters()); + return new Tuple2( + (String) results.get(0).getValue(), (String) results.get(1).getValue()); + } + + public Tuple1 getPaillierAddOutput(TransactionReceipt transactionReceipt) { + String data = transactionReceipt.getOutput(); + final Function function = + new Function( + FUNC_PAILLIERADD, + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + List results = + this.functionReturnDecoder.decode(data, function.getOutputParameters()); + return new Tuple1((String) results.get(0).getValue()); + } + + public static PaillierPrecompiled load( + String contractAddress, Client client, CryptoKeyPair credential) { + return new PaillierPrecompiled(contractAddress, client, credential); + } + + public static PaillierPrecompiled deploy(Client client, CryptoKeyPair credential) + throws ContractException { + return deploy( + PaillierPrecompiled.class, + client, + credential, + getBinary(client.getCryptoSuite()), + getABI(), + null, + null); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/demo/contract/SimpleEvidenceFactory.java b/src/main/java/org/fisco/bcos/sdk/demo/contract/SimpleEvidenceFactory.java new file mode 100644 index 0000000..f40f9da --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/contract/SimpleEvidenceFactory.java @@ -0,0 +1,155 @@ +package org.fisco.bcos.sdk.demo.contract; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.codec.datatypes.Address; +import org.fisco.bcos.sdk.v3.codec.datatypes.Event; +import org.fisco.bcos.sdk.v3.codec.datatypes.Function; +import org.fisco.bcos.sdk.v3.codec.datatypes.Type; +import org.fisco.bcos.sdk.v3.codec.datatypes.TypeReference; +import org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String; +import org.fisco.bcos.sdk.v3.codec.datatypes.generated.Int256; +import org.fisco.bcos.sdk.v3.codec.datatypes.generated.tuples.generated.Tuple2; +import org.fisco.bcos.sdk.v3.contract.Contract; +import org.fisco.bcos.sdk.v3.crypto.CryptoSuite; +import org.fisco.bcos.sdk.v3.crypto.keypair.CryptoKeyPair; +import org.fisco.bcos.sdk.v3.model.CryptoType; +import org.fisco.bcos.sdk.v3.model.TransactionReceipt; +import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback; +import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; + +@SuppressWarnings("unchecked") +public class SimpleEvidenceFactory extends Contract { + public static final String[] BINARY_ARRAY = { + "608060405234801561001057600080fd5b50610602806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80635bd8b3a214610030575b600080fd5b61004361003e3660046100e4565b610045565b005b60008282604051610055906100c1565b610060929190610199565b604051809103906000f08015801561007c573d6000803e3d6000fd5b506040516001600160a01b03821681529091507f8b94c7f6b3fadc764673ea85b4bfef3e17ce928d13e51b818ddfa891ad0f1fcc9060200160405180910390a1505050565b6103d6806101f783390190565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156100f757600080fd5b823567ffffffffffffffff8082111561010f57600080fd5b818501915085601f83011261012357600080fd5b813581811115610135576101356100ce565b604051601f8201601f19908116603f0116810190838211818310171561015d5761015d6100ce565b8160405282815288602084870101111561017657600080fd5b826020860160208301376000602093820184015298969091013596505050505050565b604081526000835180604084015260005b818110156101c757602081870181015160608684010152016101aa565b818111156101d9576000606083860101525b50602083019390935250601f91909101601f19160160600191905056fe608060405234801561001057600080fd5b506040516103d63803806103d683398101604081905261002f916100fb565b815161004290600090602085019061004c565b506001555061020e565b828054610058906101d3565b90600052602060002090601f01602090048101928261007a57600085556100c0565b82601f1061009357805160ff19168380011785556100c0565b828001600101855582156100c0579182015b828111156100c05782518255916020019190600101906100a5565b506100cc9291506100d0565b5090565b5b808211156100cc57600081556001016100d1565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561010e57600080fd5b82516001600160401b038082111561012557600080fd5b818501915085601f83011261013957600080fd5b81518181111561014b5761014b6100e5565b604051601f8201601f19908116603f01168101908382118183101715610173576101736100e5565b8160405282815260209350888484870101111561018f57600080fd5b600091505b828210156101b15784820184015181830185015290830190610194565b828211156101c25760008484830101525b969092015195979596505050505050565b600181811c908216806101e757607f821691505b6020821081141561020857634e487b7160e01b600052602260045260246000fd5b50919050565b6101b98061021d6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063596f21f814610030575b600080fd5b61003861004f565b6040516100469291906100eb565b60405180910390f35b606060008060015481805461006390610148565b80601f016020809104026020016040519081016040528092919081815260200182805461008f90610148565b80156100dc5780601f106100b1576101008083540402835291602001916100dc565b820191906000526020600020905b8154815290600101906020018083116100bf57829003601f168201915b50505050509150915091509091565b604081526000835180604084015260005b8181101561011957602081870181015160608684010152016100fc565b8181111561012b576000606083860101525b50602083019390935250601f91909101601f191601606001919050565b600181811c9082168061015c57607f821691505b6020821081141561017d57634e487b7160e01b600052602260045260246000fd5b5091905056fea2646970667358221220940d75243a70f881e10b5aa0645863ed642fd429cd7b15bffb944c5788175b7b64736f6c634300080b0033a2646970667358221220092d4a55b0166b3d68186328108e15dfeb0918abb5e763215144c935d18b264764736f6c634300080b0033" + }; + + public static final String BINARY = + org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", BINARY_ARRAY); + + public static final String[] SM_BINARY_ARRAY = { + "608060405234801561001057600080fd5b50610602806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806347ef631614610030575b600080fd5b61004361003e3660046100e4565b610045565b005b60008282604051610055906100c1565b610060929190610199565b604051809103906000f08015801561007c573d6000803e3d6000fd5b506040516001600160a01b03821681529091507ffce723060091dd1452a91ae12d05541e3141b37fa27968bc557add04601f74d09060200160405180910390a1505050565b6103d6806101f783390190565b63b95aa35560e01b600052604160045260246000fd5b600080604083850312156100f757600080fd5b823567ffffffffffffffff8082111561010f57600080fd5b818501915085601f83011261012357600080fd5b813581811115610135576101356100ce565b604051601f8201601f19908116603f0116810190838211818310171561015d5761015d6100ce565b8160405282815288602084870101111561017657600080fd5b826020860160208301376000602093820184015298969091013596505050505050565b604081526000835180604084015260005b818110156101c757602081870181015160608684010152016101aa565b818111156101d9576000606083860101525b50602083019390935250601f91909101601f19160160600191905056fe608060405234801561001057600080fd5b506040516103d63803806103d683398101604081905261002f916100fb565b815161004290600090602085019061004c565b506001555061020e565b828054610058906101d3565b90600052602060002090601f01602090048101928261007a57600085556100c0565b82601f1061009357805160ff19168380011785556100c0565b828001600101855582156100c0579182015b828111156100c05782518255916020019190600101906100a5565b506100cc9291506100d0565b5090565b5b808211156100cc57600081556001016100d1565b63b95aa35560e01b600052604160045260246000fd5b6000806040838503121561010e57600080fd5b82516001600160401b038082111561012557600080fd5b818501915085601f83011261013957600080fd5b81518181111561014b5761014b6100e5565b604051601f8201601f19908116603f01168101908382118183101715610173576101736100e5565b8160405282815260209350888484870101111561018f57600080fd5b600091505b828210156101b15784820184015181830185015290830190610194565b828211156101c25760008484830101525b969092015195979596505050505050565b600181811c908216806101e757607f821691505b602082108114156102085763b95aa35560e01b600052602260045260246000fd5b50919050565b6101b98061021d6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80634ae70cef14610030575b600080fd5b61003861004f565b6040516100469291906100eb565b60405180910390f35b606060008060015481805461006390610148565b80601f016020809104026020016040519081016040528092919081815260200182805461008f90610148565b80156100dc5780601f106100b1576101008083540402835291602001916100dc565b820191906000526020600020905b8154815290600101906020018083116100bf57829003601f168201915b50505050509150915091509091565b604081526000835180604084015260005b8181101561011957602081870181015160608684010152016100fc565b8181111561012b576000606083860101525b50602083019390935250601f91909101601f191601606001919050565b600181811c9082168061015c57607f821691505b6020821081141561017d5763b95aa35560e01b600052602260045260246000fd5b5091905056fea2646970667358221220efc061a98e40cc06a1de894dc8169b2538b84b632ac867f7ea55242c1244705764736f6c634300080b0033a2646970667358221220b4fd7c33feb3c173257d70fc38317f8b125e5a436800be57a09fb2d3120d867164736f6c634300080b0033" + }; + + public static final String SM_BINARY = + org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", SM_BINARY_ARRAY); + + public static final String[] ABI_ARRAY = { + "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"newEvidenceEvent\",\"type\":\"event\"},{\"conflictFields\":[{\"kind\":0}],\"inputs\":[{\"internalType\":\"string\",\"name\":\"evidence\",\"type\":\"string\"},{\"internalType\":\"int256\",\"name\":\"id\",\"type\":\"int256\"}],\"name\":\"newEvidence\",\"outputs\":[],\"selector\":[1540928418,1206870806],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + }; + + public static final String ABI = org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", ABI_ARRAY); + + public static final String FUNC_NEWEVIDENCE = "newEvidence"; + + public static final Event NEWEVIDENCEEVENT_EVENT = + new Event( + "newEvidenceEvent", + Arrays.>asList(new TypeReference
() {}));; + + protected SimpleEvidenceFactory( + String contractAddress, Client client, CryptoKeyPair credential) { + super(getBinary(client.getCryptoSuite()), contractAddress, client, credential); + } + + public static String getBinary(CryptoSuite cryptoSuite) { + return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY); + } + + public static String getABI() { + return ABI; + } + + public List getNewEvidenceEventEvents( + TransactionReceipt transactionReceipt) { + List valueList = + extractEventParametersWithLog(NEWEVIDENCEEVENT_EVENT, transactionReceipt); + ArrayList responses = + new ArrayList(valueList.size()); + for (Contract.EventValuesWithLog eventValues : valueList) { + NewEvidenceEventEventResponse typedResponse = new NewEvidenceEventEventResponse(); + typedResponse.log = eventValues.getLog(); + typedResponse.addr = (String) eventValues.getNonIndexedValues().get(0).getValue(); + responses.add(typedResponse); + } + return responses; + } + + public TransactionReceipt newEvidence(String evidence, BigInteger id) { + final Function function = + new Function( + FUNC_NEWEVIDENCE, + Arrays.asList( + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(evidence), + new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Int256(id)), + Collections.>emptyList(), + 0); + return executeTransaction(function); + } + + public String getSignedTransactionForNewEvidence(String evidence, BigInteger id) { + final Function function = + new Function( + FUNC_NEWEVIDENCE, + Arrays.asList( + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(evidence), + new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Int256(id)), + Collections.>emptyList(), + 0); + return createSignedTransaction(function); + } + + public String newEvidence(String evidence, BigInteger id, TransactionCallback callback) { + final Function function = + new Function( + FUNC_NEWEVIDENCE, + Arrays.asList( + new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(evidence), + new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Int256(id)), + Collections.>emptyList(), + 0); + return asyncExecuteTransaction(function, callback); + } + + public Tuple2 getNewEvidenceInput(TransactionReceipt transactionReceipt) { + String data = transactionReceipt.getInput().substring(10); + final Function function = + new Function( + FUNC_NEWEVIDENCE, + Arrays.asList(), + Arrays.>asList( + new TypeReference() {}, + new TypeReference() {})); + List results = + this.functionReturnDecoder.decode(data, function.getOutputParameters()); + return new Tuple2( + (String) results.get(0).getValue(), (BigInteger) results.get(1).getValue()); + } + + public static SimpleEvidenceFactory load( + String contractAddress, Client client, CryptoKeyPair credential) { + return new SimpleEvidenceFactory(contractAddress, client, credential); + } + + public static SimpleEvidenceFactory deploy(Client client, CryptoKeyPair credential) + throws ContractException { + return deploy( + SimpleEvidenceFactory.class, + client, + credential, + getBinary(client.getCryptoSuite()), + getABI(), + null, + null); + } + + public static class NewEvidenceEventEventResponse { + public TransactionReceipt.Logs log; + + public String addr; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/SimpleEvidence.sol b/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/SimpleEvidence.sol index 74baf7b..76299b7 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/SimpleEvidence.sol +++ b/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/SimpleEvidence.sol @@ -2,23 +2,16 @@ pragma solidity >=0.6.10 <0.8.20; pragma experimental ABIEncoderV2; contract SimpleEvidence{ string evidence; - string evidenceInfo; - string evidenceId; - event newEvidenceEvent(string evi, string info, string id); - constructor(string memory evi, string memory info, string memory id) public + int256 evidenceId; + // event newEvidenceEvent(string evi, int256 id); + constructor(string memory evi, int256 id) public { evidence = evi; - evidenceInfo = info; evidenceId = id; - emit newEvidenceEvent(evi,info,id); + // emit newEvidenceEvent(evi,id); } - function getEvidenceInfo() public view returns(string memory) - { - return evidenceInfo; - } - - function getEvidence() public view returns(string memory,string memory,string memory){ - return(evidence,evidenceInfo,evidenceId); + function getEvidence() public view returns(string memory,int256){ + return(evidence,evidenceId); } } diff --git a/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/SimpleEvidenceFactory.sol b/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/SimpleEvidenceFactory.sol new file mode 100644 index 0000000..e47c818 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/contract/sol/SimpleEvidenceFactory.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.6.10 <0.8.20; +pragma experimental ABIEncoderV2; +import "./SimpleEvidence.sol"; + +contract SimpleEvidenceFactory { + event newEvidenceEvent(address addr); + + function newEvidence( + string memory evidence, + int256 id + ) public { + SimpleEvidence evi = new SimpleEvidence(evidence, id); + emit newEvidenceEvent(address(evi)); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/ParallelOkPerf.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/ParallelOkPerf.java index 0b88ebb..ab7ae81 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/perf/ParallelOkPerf.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/ParallelOkPerf.java @@ -176,8 +176,9 @@ public static void parallelOkPerf( client.getCryptoSuite().getCryptoKeyPair()); parallelOkDemo = new ParallelOkDemo(parallelOk, dagUserInfo, threadPoolService); parallelOkDemo.generateTransferTxs( - BigInteger.valueOf(count), - "parallelOKTxs.txt", + client.getGroup(), + count, + "parallelOKTxs", BigInteger.valueOf(qps), BigInteger.valueOf(conflictPercent)); break; diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceEvidence.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceEvidence.java index 05aab9f..32d1407 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceEvidence.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceEvidence.java @@ -13,15 +13,22 @@ */ package org.fisco.bcos.sdk.demo.perf; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.RateLimiter; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.math.BigInteger; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.IntStream; import me.tongfei.progressbar.ProgressBar; import me.tongfei.progressbar.ProgressBarBuilder; @@ -29,11 +36,13 @@ import org.fisco.bcos.sdk.demo.contract.EvidenceSignersData; import org.fisco.bcos.sdk.v3.BcosSDK; import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.client.protocol.request.JsonRpcRequest; import org.fisco.bcos.sdk.v3.contract.precompiled.sharding.ShardingService; import org.fisco.bcos.sdk.v3.model.ConstantConfig; import org.fisco.bcos.sdk.v3.model.TransactionReceipt; import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback; import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; +import org.fisco.bcos.sdk.v3.utils.ObjectMapperFactory; public class PerformanceEvidence { private static Client client; @@ -42,11 +51,11 @@ public static void usage() { System.out.println(" Usage:"); System.out.println("===== PerformanceEvidence test==========="); System.out.println( - " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.PerformanceEvidence [groupId] [count] [qps] [evidenceLength] [shards]."); + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.PerformanceEvidence [new/generate] [groupId] [count] [qps] [evidenceLength] [shards]."); } public static void main(String[] args) - throws ContractException, IOException, InterruptedException { + throws ContractException, IOException, InterruptedException, ContractException { try { String configFileName = ConstantConfig.CONFIG_FILE_NAME; URL configUrl = ParallelOkPerf.class.getClassLoader().getResource(configFileName); @@ -60,21 +69,31 @@ public static void main(String[] args) return; } - String groupId = args[0]; - Integer count = Integer.valueOf(args[1]).intValue(); - Integer qps = Integer.valueOf(args[2]).intValue(); - Integer evidenceLength = Integer.valueOf(args[3]).intValue(); + String command = args[0]; + String groupId = args[1]; + Integer count = Integer.valueOf(args[2]).intValue(); + Integer qps = Integer.valueOf(args[3]).intValue(); + Integer evidenceLength = Integer.valueOf(args[4]).intValue(); Integer shards = 1; - if (args.length == 5) { - shards = Integer.valueOf(args[4]).intValue(); + if (args.length == 6) { + shards = Integer.valueOf(args[5]).intValue(); } String configFile = configUrl.getPath(); BcosSDK sdk = BcosSDK.build(configFile); client = sdk.getClient(groupId); - start(groupId, count, qps, evidenceLength, shards); - + switch (command) { + case "new": + newEvidence(groupId, count, qps, evidenceLength, shards); + break; + case "generate": + generate(count, qps, evidenceLength, shards); + break; + default: + System.out.println("valid command are new/generate, got : " + command); + break; + } System.exit(0); } catch (Exception e) { e.printStackTrace(); @@ -82,7 +101,8 @@ public static void main(String[] args) } } - public static void start(String groupId, int count, Integer qps, int evidenceLength, int shards) + public static void newEvidence( + String groupId, int count, Integer qps, int evidenceLength, int shards) throws IOException, InterruptedException, ContractException { System.out.println( "====== Start test, count: " @@ -173,4 +193,112 @@ public void onResponse(TransactionReceipt receipt) { collector.report(); System.out.println("Sending transactions finished!"); } + + public static void generate(int count, Integer qps, int evidenceLength, int shards) + throws IOException, InterruptedException, ContractException { + + // if txsPath not exist, create it + String txsPath = "newEvidenceTxs"; + File txsDir = new File(txsPath); + if (!txsDir.exists()) { + txsDir.mkdir(); + } + int threads = Runtime.getRuntime().availableProcessors(); + BufferedWriter[] bufferedWriters = new BufferedWriter[threads]; + Lock[] locks = new ReentrantLock[threads]; + for (int i = 0; i < threads; i++) { + String fileName = txsPath + "/" + i + ".txt"; + File file = new File(fileName); + if (!file.exists()) { + file.createNewFile(); + } + FileWriter fileWriter = new FileWriter(fileName, true); + bufferedWriters[i] = new BufferedWriter(fileWriter); + locks[i] = new ReentrantLock(); + } + + System.out.println( + "====== Generating, count: " + + count + + ", qps:" + + qps + + ", groupId: " + + client.getGroup() + + ", evidenceLength: " + + evidenceLength + + ", shards: " + + shards); + + ShardingService shardingService = + new ShardingService(client, client.getCryptoSuite().getCryptoKeyPair()); + List evidenceSigners = new ArrayList<>(); + evidenceSigners.add(client.getCryptoSuite().getCryptoKeyPair().getAddress()); + EvidenceSignersData[] contracts = new EvidenceSignersData[shards]; + for (int i = 0; i < shards; i++) { + contracts[i] = + EvidenceSignersData.deploy( + client, client.getCryptoSuite().getCryptoKeyPair(), evidenceSigners); + shardingService.linkShard("testShard" + i, contracts[i].getContractAddress()); + } + + final Random random = new Random(); + random.setSeed(System.currentTimeMillis()); + + ProgressBar sendedBar = + new ProgressBarBuilder() + .setTaskName("Generated :") + .setInitialMax(count) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + + CountDownLatch transactionLatch = new CountDownLatch(count); + AtomicLong totalCost = new AtomicLong(0); + Collector collector = new Collector(); + collector.setTotal(count); + + IntStream.range(0, count) + .parallel() + .forEach( + index -> { + byte[] data = new byte[32]; + random.nextBytes(data); + byte[] evidenceBuffer = new byte[evidenceLength]; + random.nextBytes(evidenceBuffer); + String evidence = new String(evidenceBuffer); + int contractIndex = index % shards; + long now = System.currentTimeMillis(); + // 生成长度为32的随机字符串 + String txData = + contracts[contractIndex].getSignedTransactionForNewEvidence( + evidence, + String.valueOf(index), + String.valueOf(index), + BigInteger.valueOf(1), + data, + data); + JsonRpcRequest request = + new JsonRpcRequest<>( + "sendTransaction", + Arrays.asList(client.getGroup(), "", txData, false)); + ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + int fileIndex = index % threads; + try { + locks[fileIndex].lock(); + bufferedWriters[fileIndex].write( + objectMapper.writeValueAsString(request)); + bufferedWriters[fileIndex].newLine(); + locks[fileIndex].unlock(); + } catch (IOException e) { + e.printStackTrace(); + } + sendedBar.step(); + transactionLatch.countDown(); + }); + transactionLatch.await(); + sendedBar.close(); + for (int i = 0; i < threads; i++) { + bufferedWriters[i].close(); + } + System.out.println("Generating transactions finished! Transactions saved in " + txsPath); + } } diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java new file mode 100644 index 0000000..1b765da --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java @@ -0,0 +1,178 @@ +/** + * Copyright 2014-2020 [fisco-dev] + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.fisco.bcos.sdk.demo.perf; + +import com.google.common.util.concurrent.RateLimiter; +import java.io.IOException; +import java.math.BigInteger; +import java.net.URL; +import java.security.KeyPair; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.IntStream; +import me.tongfei.progressbar.ProgressBar; +import me.tongfei.progressbar.ProgressBarBuilder; +import me.tongfei.progressbar.ProgressBarStyle; +import org.fisco.bcos.sdk.demo.contract.PaillierPrecompiled; +import org.fisco.bcos.sdk.demo.perf.paillier.PaillierCipher; +import org.fisco.bcos.sdk.demo.perf.paillier.PaillierKeyPair; +import org.fisco.bcos.sdk.v3.BcosSDK; +import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.model.ConstantConfig; +import org.fisco.bcos.sdk.v3.model.TransactionReceipt; +import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback; +import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; + +public class PerformancePaillierPrecompiled { + private static Client client; + private static final String PAILLIER_ADDR = "0x0000000000000000000000000000000000005003"; + + public static void usage() { + System.out.println(" Usage:"); + System.out.println("===== PerformancePaillierPrecompiled test==========="); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.PerformancePaillierPrecompiled [add] [groupId] [PrivateKeyLen(512/1024)] [count] [qps]."); + } + + public static void main(String[] args) + throws ContractException, IOException, InterruptedException, ContractException { + try { + String configFileName = ConstantConfig.CONFIG_FILE_NAME; + URL configUrl = ParallelOkPerf.class.getClassLoader().getResource(configFileName); + if (configUrl == null) { + System.out.println("The configFile " + configFileName + " doesn't exist!"); + return; + } + + if (args.length < 4) { + usage(); + return; + } + + String command = args[0]; + String groupId = args[1]; + Integer pkLen = Integer.valueOf(args[2]).intValue(); + if (pkLen != 512 && pkLen != 1024 && pkLen != 2048) { + System.out.println("valid pkLen are 512/1024/2048, got : " + pkLen); + return; + } + Integer count = Integer.valueOf(args[3]).intValue(); + Integer qps = Integer.valueOf(args[4]).intValue(); + + String configFile = configUrl.getPath(); + BcosSDK sdk = BcosSDK.build(configFile); + client = sdk.getClient(groupId); + + switch (command) { + case "add": + add(groupId, pkLen, count, qps); + break; + default: + System.out.println("valid command are add, got : " + command); + break; + } + System.exit(0); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + public static void add(String groupId, Integer pklen, int count, Integer qps) + throws IOException, InterruptedException, ContractException { + System.out.println( + "====== Start test, count: " + count + ", qps:" + qps + ", groupId: " + groupId); + + RateLimiter limiter = RateLimiter.create(qps.intValue()); + + PaillierPrecompiled paillierPrecompiled = + PaillierPrecompiled.load( + PAILLIER_ADDR, client, client.getCryptoSuite().getCryptoKeyPair()); + + final Random random = new Random(); + random.setSeed(System.currentTimeMillis()); + + System.out.println("Prepare parameters..."); + + int numbers = 10000; + String[] data = new String[numbers]; + BigInteger[] bigs = new BigInteger[numbers]; + KeyPair paillierKeyPair = PaillierKeyPair.generateKeyPair(pklen); + for (int i = 0; i < numbers; i++) { + bigs[i] = new BigInteger(256, random); + data[i] = PaillierCipher.encrypt(bigs[i], paillierKeyPair.getPublic()); + } + System.out.println("Sending transactions..."); + ProgressBar sendedBar = + new ProgressBarBuilder() + .setTaskName("Send :") + .setInitialMax(count) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + ProgressBar receivedBar = + new ProgressBarBuilder() + .setTaskName("Receive:") + .setInitialMax(count) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + CountDownLatch transactionLatch = new CountDownLatch(count); + AtomicLong totalCost = new AtomicLong(0); + Collector collector = new Collector(); + collector.setTotal(count); + + IntStream.range(0, count) + .parallel() + .forEach( + index -> { + limiter.acquire(); + long now = System.currentTimeMillis(); + int firstIndex = index % numbers; + int secondIndex = (index + numbers / 2) % numbers; + String first = data[firstIndex]; + String second = data[firstIndex]; + BigInteger result = bigs[firstIndex].add(bigs[secondIndex]); + paillierPrecompiled.paillierAdd( + first, + second, + new TransactionCallback() { + @Override + public void onResponse(TransactionReceipt receipt) { + long cost = System.currentTimeMillis() - now; + collector.onMessage(receipt, cost); + receivedBar.step(); + transactionLatch.countDown(); + totalCost.addAndGet(System.currentTimeMillis() - now); + String output = + paillierPrecompiled + .getPaillierAddOutput(receipt) + .getValue1(); + BigInteger ret = + PaillierCipher.decrypt( + output, paillierKeyPair.getPrivate()); + if (!ret.equals(result)) { + System.out.println("result not equal"); + } + } + }); + sendedBar.step(); + }); + transactionLatch.await(); + + sendedBar.close(); + receivedBar.close(); + collector.report(); + System.out.println("Sending transactions finished!"); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceSimpleEvidence.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceSimpleEvidence.java new file mode 100644 index 0000000..ac02fc4 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceSimpleEvidence.java @@ -0,0 +1,284 @@ +/** + * Copyright 2014-2020 [fisco-dev] + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.fisco.bcos.sdk.demo.perf; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.util.concurrent.RateLimiter; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.math.BigInteger; +import java.net.URL; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.IntStream; +import me.tongfei.progressbar.ProgressBar; +import me.tongfei.progressbar.ProgressBarBuilder; +import me.tongfei.progressbar.ProgressBarStyle; +import org.fisco.bcos.sdk.demo.contract.SimpleEvidenceFactory; +import org.fisco.bcos.sdk.v3.BcosSDK; +import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.client.protocol.request.JsonRpcRequest; +import org.fisco.bcos.sdk.v3.contract.precompiled.sharding.ShardingService; +import org.fisco.bcos.sdk.v3.model.ConstantConfig; +import org.fisco.bcos.sdk.v3.model.TransactionReceipt; +import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback; +import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; +import org.fisco.bcos.sdk.v3.utils.ObjectMapperFactory; + +public class PerformanceSimpleEvidence { + private static Client client; + + public static void usage() { + System.out.println(" Usage:"); + System.out.println("===== PerformanceSimpleEvidence test==========="); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.PerformanceSimpleEvidence [new/generate] [groupId] [count] [qps] [evidenceLength] [shards]."); + } + + public static void main(String[] args) + throws ContractException, IOException, InterruptedException, ContractException { + try { + String configFileName = ConstantConfig.CONFIG_FILE_NAME; + URL configUrl = ParallelOkPerf.class.getClassLoader().getResource(configFileName); + if (configUrl == null) { + System.out.println("The configFile " + configFileName + " doesn't exist!"); + return; + } + + if (args.length < 4) { + usage(); + return; + } + + String command = args[0]; + String groupId = args[1]; + Integer count = Integer.valueOf(args[2]).intValue(); + Integer qps = Integer.valueOf(args[3]).intValue(); + Integer evidenceLength = Integer.valueOf(args[4]).intValue(); + Integer shards = 1; + if (args.length == 6) { + shards = Integer.valueOf(args[5]).intValue(); + } + + String configFile = configUrl.getPath(); + BcosSDK sdk = BcosSDK.build(configFile); + client = sdk.getClient(groupId); + + switch (command) { + case "new": + newEvidence(groupId, count, qps, evidenceLength, shards); + break; + case "generate": + generate(count, qps, evidenceLength, shards); + break; + default: + System.out.println("valid command are new/generate, got : " + command); + break; + } + System.exit(0); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + public static void newEvidence( + String groupId, int count, Integer qps, int evidenceLength, int shards) + throws IOException, InterruptedException, ContractException { + System.out.println( + "====== Start test, count: " + + count + + ", qps:" + + qps + + ", groupId: " + + groupId + + ", evidenceLength: " + + evidenceLength + + ", shards: " + + shards); + + RateLimiter limiter = RateLimiter.create(qps.intValue()); + + ShardingService shardingService = + new ShardingService(client, client.getCryptoSuite().getCryptoKeyPair()); + SimpleEvidenceFactory[] contracts = new SimpleEvidenceFactory[shards]; + for (int i = 0; i < shards; i++) { + contracts[i] = + SimpleEvidenceFactory.deploy( + client, client.getCryptoSuite().getCryptoKeyPair()); + shardingService.linkShard("testShard" + i, contracts[i].getContractAddress()); + } + + final Random random = new Random(); + random.setSeed(System.currentTimeMillis()); + + System.out.println("Sending transactions..."); + ProgressBar sendedBar = + new ProgressBarBuilder() + .setTaskName("Send :") + .setInitialMax(count) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + ProgressBar receivedBar = + new ProgressBarBuilder() + .setTaskName("Receive:") + .setInitialMax(count) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + + CountDownLatch transactionLatch = new CountDownLatch(count); + AtomicLong totalCost = new AtomicLong(0); + Collector collector = new Collector(); + collector.setTotal(count); + + IntStream.range(0, count) + .parallel() + .forEach( + index -> { + limiter.acquire(); + byte[] evidenceBuffer = new byte[evidenceLength]; + random.nextBytes(evidenceBuffer); + String evidence = new String(evidenceBuffer); + int contractIndex = index % shards; + long now = System.currentTimeMillis(); + // 生成长度为32的随机字符串 + contracts[contractIndex].newEvidence( + evidence, + BigInteger.valueOf(1), + new TransactionCallback() { + @Override + public void onResponse(TransactionReceipt receipt) { + long cost = System.currentTimeMillis() - now; + collector.onMessage(receipt, cost); + + receivedBar.step(); + transactionLatch.countDown(); + totalCost.addAndGet(System.currentTimeMillis() - now); + } + }); + sendedBar.step(); + }); + transactionLatch.await(); + + sendedBar.close(); + receivedBar.close(); + collector.report(); + System.out.println("Sending transactions finished!"); + } + + public static void generate(int count, Integer qps, int evidenceLength, int shards) + throws IOException, InterruptedException, ContractException { + + // if txsPath not exist, create it + String txsPath = "newSimpleEvidenceTxs"; + File txsDir = new File(txsPath); + if (!txsDir.exists()) { + txsDir.mkdir(); + } + int threads = Runtime.getRuntime().availableProcessors(); + BufferedWriter[] bufferedWriters = new BufferedWriter[threads]; + Lock[] locks = new ReentrantLock[threads]; + for (int i = 0; i < threads; i++) { + String fileName = txsPath + "/" + i + ".txt"; + File file = new File(fileName); + if (!file.exists()) { + file.createNewFile(); + } + FileWriter fileWriter = new FileWriter(fileName, true); + bufferedWriters[i] = new BufferedWriter(fileWriter); + locks[i] = new ReentrantLock(); + } + + System.out.println( + "====== Generating, count: " + + count + + ", qps:" + + qps + + ", groupId: " + + client.getGroup() + + ", evidenceLength: " + + evidenceLength + + ", shards: " + + shards); + + ShardingService shardingService = + new ShardingService(client, client.getCryptoSuite().getCryptoKeyPair()); + SimpleEvidenceFactory[] contracts = new SimpleEvidenceFactory[shards]; + for (int i = 0; i < shards; i++) { + contracts[i] = + SimpleEvidenceFactory.deploy( + client, client.getCryptoSuite().getCryptoKeyPair()); + shardingService.linkShard("testShard" + i, contracts[i].getContractAddress()); + } + + final Random random = new Random(); + random.setSeed(System.currentTimeMillis()); + + ProgressBar sendedBar = + new ProgressBarBuilder() + .setTaskName("Generated :") + .setInitialMax(count) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + + CountDownLatch transactionLatch = new CountDownLatch(count); + AtomicLong totalCost = new AtomicLong(0); + Collector collector = new Collector(); + collector.setTotal(count); + + IntStream.range(0, count) + .parallel() + .forEach( + index -> { + byte[] evidenceBuffer = new byte[evidenceLength]; + random.nextBytes(evidenceBuffer); + String evidence = new String(evidenceBuffer); + int contractIndex = index % shards; + long now = System.currentTimeMillis(); + // 生成长度为32的随机字符串 + String txData = + contracts[contractIndex].getSignedTransactionForNewEvidence( + evidence, BigInteger.valueOf(1)); + JsonRpcRequest request = + new JsonRpcRequest<>( + "sendTransaction", + Arrays.asList(client.getGroup(), "", txData, false)); + ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + int fileIndex = index % threads; + try { + locks[fileIndex].lock(); + bufferedWriters[fileIndex].write( + objectMapper.writeValueAsString(request)); + bufferedWriters[fileIndex].newLine(); + locks[fileIndex].unlock(); + } catch (IOException e) { + e.printStackTrace(); + } + sendedBar.step(); + transactionLatch.countDown(); + }); + transactionLatch.await(); + sendedBar.close(); + for (int i = 0; i < threads; i++) { + bufferedWriters[i].close(); + } + System.out.println("Generating transactions finished! Transactions saved in " + txsPath); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/CommonUtils.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/CommonUtils.java new file mode 100644 index 0000000..cb89f9c --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/CommonUtils.java @@ -0,0 +1,109 @@ +package org.fisco.bcos.sdk.demo.perf.paillier; + +import java.math.BigInteger; + +public class CommonUtils { + public CommonUtils() {} + + public static byte[] intToByte4(int i) { + byte[] targets = new byte[4]; + targets[3] = (byte) (i & 0xFF); + targets[2] = (byte) (i >> 8 & 0xFF); + targets[1] = (byte) (i >> 16 & 0xFF); + targets[0] = (byte) (i >> 24 & 0xFF); + return targets; + } + + public static byte[] longToByte8(long lo) { + byte[] targets = new byte[8]; + for (int i = 0; i < 8; i++) { + int offset = (targets.length - 1 - i) * 8; + targets[i] = (byte) ((lo >>> offset) & 0xFF); + } + return targets; + } + + public static byte[] unsignedShortToByte2(int s) { + byte[] targets = new byte[2]; + targets[0] = (byte) (s >> 8 & 0xFF); + targets[1] = (byte) (s & 0xFF); + return targets; + } + + public static int byte2ToUnsignedShort(byte[] bytes) { + return byte2ToUnsignedShort(bytes, 0); + } + + public static int byte2ToUnsignedShort(byte[] bytes, int off) { + int high = bytes[off]; + int low = bytes[off + 1]; + return (high << 8 & 0xFF00) | (low & 0xFF); + } + + public static int byte4ToInt(byte[] bytes, int off) { + int b0 = bytes[off] & 0xFF; + int b1 = bytes[off + 1] & 0xFF; + int b2 = bytes[off + 2] & 0xFF; + int b3 = bytes[off + 3] & 0xFF; + return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; + } + + public static byte[] asUnsignedByteArray(BigInteger paramBigInteger) { + byte[] arrayOfByte1 = paramBigInteger.toByteArray(); + if (arrayOfByte1[0] == 0) { + byte[] arrayOfByte2 = new byte[arrayOfByte1.length - 1]; + System.arraycopy(arrayOfByte1, 1, arrayOfByte2, 0, arrayOfByte2.length); + return arrayOfByte2; + } + return arrayOfByte1; + } + + public static byte[] asUnsignedByteArray(BigInteger paramBigInteger, int byteLength) { + byte[] arrayOfByte1 = asUnsignedByteArray(paramBigInteger); + if (arrayOfByte1.length < byteLength) { + byte[] arrayOfByte2 = new byte[byteLength]; + int offset = byteLength - arrayOfByte1.length; + for (int i = 0; i < offset; i++) { + arrayOfByte2[i] = 0; + } + System.arraycopy(arrayOfByte1, 0, arrayOfByte2, offset, arrayOfByte1.length); + return arrayOfByte2; + } + return arrayOfByte1; + } + + public static BigInteger fromUnsignedByteArray(byte[] paramArrayOfByte) { + return new BigInteger(1, paramArrayOfByte); + } + + public static String byteToHexString(byte[] bt) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < bt.length; i++) { + String hex = Integer.toHexString(bt[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + sb.append(hex.toUpperCase()); + } + return sb.toString(); + } + + public static byte[] hexStringToBytes(String hexString) { + if (hexString == null || hexString.equals("")) { + return null; + } + hexString = hexString.toUpperCase(); + int length = hexString.length() / 2; + char[] hexChars = hexString.toCharArray(); + byte[] d = new byte[length]; + for (int i = 0; i < length; i++) { + int pos = i * 2; + d[i] = (byte) (charToByte(hexChars[pos]) << 4 | (charToByte(hexChars[pos + 1]) & 0xff)); + } + return d; + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/PaillierCipher.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/PaillierCipher.java new file mode 100644 index 0000000..76cf3ac --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/PaillierCipher.java @@ -0,0 +1,129 @@ +package org.fisco.bcos.sdk.demo.perf.paillier; + +import java.math.*; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPublicKey; +import java.util.*; + +public class PaillierCipher { + + public static String encrypt(BigInteger m, PublicKey publicKey) { + return CommonUtils.byteToHexString(encryptAsBytes(m, publicKey)); + } + + public static byte[] encryptAsBytes(BigInteger m, PublicKey publicKey) { + RSAPublicKey rsaPubKey = (RSAPublicKey) publicKey; + BigInteger n = rsaPubKey.getModulus(); + BigInteger g = n.add(BigInteger.ONE); + + BigInteger random; + do { + random = new BigInteger(n.bitLength(), new Random()); + } while (random.signum() != 1); + + if (m.signum() == -1) { + m = m.mod(n); + } + + BigInteger nsquare = n.multiply(n); + BigInteger ciphertext = + g.modPow(m, nsquare).multiply(random.modPow(n, nsquare)).mod(nsquare); + + byte[] nBytes = CommonUtils.asUnsignedByteArray(n); + byte[] nLenBytes = CommonUtils.unsignedShortToByte2(nBytes.length); + byte[] cipherBytes = CommonUtils.asUnsignedByteArray(ciphertext, n.bitLength() / 4); + byte[] data = new byte[nLenBytes.length + nBytes.length + cipherBytes.length]; + System.arraycopy(nLenBytes, 0, data, 0, nLenBytes.length); + System.arraycopy(nBytes, 0, data, nLenBytes.length, nBytes.length); + System.arraycopy( + cipherBytes, 0, data, nLenBytes.length + nBytes.length, cipherBytes.length); + return data; + } + + public static BigInteger decrypt(String ciphertext, PrivateKey privateKey) { + return decrypt(CommonUtils.hexStringToBytes(ciphertext), privateKey); + } + + public static BigInteger decrypt(byte[] ciphertext, PrivateKey privateKey) { + RSAPrivateCrtKey rsaPriKey = (RSAPrivateCrtKey) privateKey; + BigInteger n = rsaPriKey.getModulus(); + BigInteger lambda = + rsaPriKey + .getPrimeP() + .subtract(BigInteger.ONE) + .multiply(rsaPriKey.getPrimeQ().subtract(BigInteger.ONE)); + + int nLen = CommonUtils.byte2ToUnsignedShort(ciphertext); + byte[] nBytes = new byte[nLen]; + System.arraycopy(ciphertext, 2, nBytes, 0, nLen); + BigInteger n1 = CommonUtils.fromUnsignedByteArray(nBytes); + if (n1.compareTo(n) != 0) { + System.err.println("Invalid ciphertext, cannot match n parameter"); + return null; + } + + byte[] data = new byte[ciphertext.length - nLen - 2]; + System.arraycopy(ciphertext, 2 + nLen, data, 0, ciphertext.length - nLen - 2); + BigInteger intCiphertext = CommonUtils.fromUnsignedByteArray(data); + + BigInteger mu = lambda.modInverse(n); + BigInteger nsquare = n.multiply(n); + BigInteger message = + intCiphertext + .modPow(lambda, nsquare) + .subtract(BigInteger.ONE) + .divide(n) + .multiply(mu) + .mod(n); + BigInteger maxValue = BigInteger.ONE.shiftLeft(n.bitLength() / 2); + if (message.compareTo(maxValue) > 0) { + return message.subtract(n); + } else { + return message; + } + } + + public static String ciphertextAdd(String ciphertext1, String ciphertext2) { + return CommonUtils.byteToHexString( + ciphertextAdd( + CommonUtils.hexStringToBytes(ciphertext1), + CommonUtils.hexStringToBytes(ciphertext2))); + } + + public static byte[] ciphertextAdd(byte[] ciphertext1, byte[] ciphertext2) { + int nLen1 = CommonUtils.byte2ToUnsignedShort(ciphertext1); + byte[] nBytes1 = new byte[nLen1]; + System.arraycopy(ciphertext1, 2, nBytes1, 0, nLen1); + BigInteger n1 = CommonUtils.fromUnsignedByteArray(nBytes1); + byte[] data1 = new byte[ciphertext1.length - nLen1 - 2]; + System.arraycopy(ciphertext1, 2 + nLen1, data1, 0, ciphertext1.length - nLen1 - 2); + + int nLen2 = CommonUtils.byte2ToUnsignedShort(ciphertext2); + byte[] nBytes2 = new byte[nLen2]; + System.arraycopy(ciphertext2, 2, nBytes2, 0, nLen2); + BigInteger n2 = CommonUtils.fromUnsignedByteArray(nBytes2); + if (n2.compareTo(n1) != 0) { + System.err.println("ciphertext1 cannot match ciphertext2"); + return null; + } + + byte[] data2 = new byte[ciphertext2.length - nLen2 - 2]; + System.arraycopy(ciphertext2, 2 + nLen2, data2, 0, ciphertext2.length - nLen2 - 2); + + BigInteger ct1 = CommonUtils.fromUnsignedByteArray(data1); + BigInteger ct2 = CommonUtils.fromUnsignedByteArray(data2); + BigInteger nsquare = n1.multiply(n1); + BigInteger ct = ct1.multiply(ct2).mod(nsquare); + + byte[] nLenBytes = CommonUtils.unsignedShortToByte2(nBytes1.length); + byte[] cipherBytes = CommonUtils.asUnsignedByteArray(ct, n1.bitLength() / 4); + byte[] data = new byte[nLenBytes.length + nBytes1.length + cipherBytes.length]; + System.arraycopy(nLenBytes, 0, data, 0, nLenBytes.length); + System.arraycopy(nBytes1, 0, data, nLenBytes.length, nBytes1.length); + System.arraycopy( + cipherBytes, 0, data, nLenBytes.length + nBytes1.length, cipherBytes.length); + return data; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/PaillierKeyPair.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/PaillierKeyPair.java new file mode 100644 index 0000000..531c197 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/paillier/PaillierKeyPair.java @@ -0,0 +1,118 @@ +package org.fisco.bcos.sdk.demo.perf.paillier; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemObjectGenerator; +import org.bouncycastle.util.io.pem.PemReader; +import org.bouncycastle.util.io.pem.PemWriter; + +public class PaillierKeyPair { + + public static KeyPair generateGoodKeyPair() { + return generateKeyPair(2048); + } + + public static KeyPair generateStrongKeyPair() { + return generateKeyPair(4096); + } + + public static KeyPair generateKeyPair(int len) { + // if (len < 2048) { + // return null; + // } + + KeyPairGenerator generator; + try { + generator = KeyPairGenerator.getInstance("RSA"); + generator.initialize(len, new SecureRandom()); + return generator.generateKeyPair(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + public static String publicKeyToPem(PublicKey publicKey) { + StringWriter pemStrWriter = new StringWriter(); + PemWriter pemWriter = null; + try { + pemWriter = new PemWriter(pemStrWriter); + PemObject pemObject = new PemObject("PUBLIC KEY", publicKey.getEncoded()); + pemWriter.writeObject(pemObject); + pemWriter.flush(); + pemWriter.close(); + return pemStrWriter.toString(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static PublicKey pemToPublicKey(String publicKeyStr) { + try { + StringReader pemStrReader = new StringReader(publicKeyStr); + PemReader pemReader = new PemReader(pemStrReader); + byte[] pubKey = pemReader.readPemObject().getContent(); + pemReader.close(); + + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePublic(new X509EncodedKeySpec(pubKey)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + } + return null; + } + + public static String privateKeyToPem(PrivateKey privateKey) { + try { + StringWriter pemStrWriter = new StringWriter(); + PemWriter pemWriter = new PemWriter(pemStrWriter); + PemObjectGenerator pemObjectGenerator = + new PemObject("PRIVATE KEY", privateKey.getEncoded()); + pemWriter.writeObject(pemObjectGenerator); + pemWriter.flush(); + pemWriter.close(); + return pemStrWriter.toString(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static PrivateKey pemToPrivateKey(String privateKeyStr) { + try { + StringReader pemStrReader = new StringReader(privateKeyStr); + PemReader pemReader = new PemReader(pemStrReader); + byte[] priKey = pemReader.readPemObject().getContent(); + pemReader.close(); + + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePrivate(new PKCS8EncodedKeySpec(priKey)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/parallel/ParallelOkDemo.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/parallel/ParallelOkDemo.java index 76957cc..21d03a8 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/perf/parallel/ParallelOkDemo.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/parallel/ParallelOkDemo.java @@ -13,6 +13,7 @@ */ package org.fisco.bcos.sdk.demo.perf.parallel; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.RateLimiter; import java.io.BufferedWriter; import java.io.File; @@ -20,11 +21,14 @@ import java.io.IOException; import java.math.BigInteger; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.IntStream; import me.tongfei.progressbar.ProgressBar; import me.tongfei.progressbar.ProgressBarBuilder; @@ -35,9 +39,11 @@ import org.fisco.bcos.sdk.demo.perf.collector.PerformanceCollector; import org.fisco.bcos.sdk.demo.perf.model.DagTransferUser; import org.fisco.bcos.sdk.demo.perf.model.DagUserInfo; +import org.fisco.bcos.sdk.v3.client.protocol.request.JsonRpcRequest; import org.fisco.bcos.sdk.v3.model.TransactionReceipt; import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback; import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; +import org.fisco.bcos.sdk.v3.utils.ObjectMapperFactory; import org.fisco.bcos.sdk.v3.utils.ThreadPoolService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -231,68 +237,139 @@ public void run() { } public void generateTransferTxs( - BigInteger count, String txsFile, BigInteger qps, BigInteger conflictPercent) + String groupID, int count, String txsPath, BigInteger qps, BigInteger conflictPercent) throws InterruptedException, IOException { - File file = new File(txsFile); - if (!file.exists()) { - file.createNewFile(); + + // if txsPath not exist, create it + File txsDir = new File(txsPath); + if (!txsDir.exists()) { + txsDir.mkdir(); } System.out.println( "ParallelOkDemo: test generateTransferTxs, count: " + count - + ", txsFile: " - + txsFile); + + ", txsPath: " + + txsPath); System.out.println("==================================================================="); - queryAccount(qps); - FileWriter fileWriter = new FileWriter(file.getName(), true); - BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); + // queryAccount(qps); + int threads = Runtime.getRuntime().availableProcessors(); + BufferedWriter[] bufferedWriters = new BufferedWriter[threads]; + Lock[] locks = new ReentrantLock[threads]; + for (int i = 0; i < threads; i++) { + String fileName = txsPath + "/" + i + ".txt"; + File file = new File(fileName); + if (!file.exists()) { + file.createNewFile(); + } + FileWriter fileWriter = new FileWriter(fileName, true); + bufferedWriters[i] = new BufferedWriter(fileWriter); + locks[i] = new ReentrantLock(); + } System.out.println( "ParallelOkDemo: start generateTransferTxs, count: " + count - + ", txsFile: " - + txsFile); - AtomicInteger generated = new AtomicInteger(0); - Integer area = count.intValue() / 10; - for (Integer i = 0; i < count.intValue(); i++) { + + ", txsPath: " + + txsPath); + ProgressBar generatedBar = + new ProgressBarBuilder() + .setTaskName("Generated :") + .setInitialMax(count) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + CountDownLatch transactionLatch = new CountDownLatch(count); + for (Integer i = 0; i < count; i++) { final Integer index = i; + threadPoolService + .getThreadPool() + .execute( + new Runnable() { + @Override + public void run() { + DagTransferUser from = dagUserInfo.getFrom(index); + DagTransferUser to = dagUserInfo.getTo(index); + // if ((conflictPercent.intValue() > 0) + // && (index + // <= (conflictPercent.intValue() * count) + // / 100)) { + // to = dagUserInfo.getNext(index); + // } + Random random = new Random(); + int r = random.nextInt(100) + 1; + BigInteger amount = BigInteger.valueOf(r); + String txData = + parallelOk.getSignedTransactionForTransfer( + from.getUser(), to.getUser(), amount); + JsonRpcRequest request = + new JsonRpcRequest<>( + "sendTransaction", + Arrays.asList(groupID, "", txData, false)); + ObjectMapper objectMapper = + ObjectMapperFactory.getObjectMapper(); + int fileIndex = index % threads; + try { + locks[fileIndex].lock(); + bufferedWriters[fileIndex].write( + objectMapper.writeValueAsString(request)); + bufferedWriters[fileIndex].newLine(); + locks[fileIndex].unlock(); + } catch (IOException e) { + e.printStackTrace(); + } - DagTransferUser from = dagUserInfo.getFrom(index); - DagTransferUser to = dagUserInfo.getTo(index); - if ((conflictPercent.intValue() > 0) - && (index <= (conflictPercent.intValue() * count.intValue()) / 100)) { - to = dagUserInfo.getNext(index); - } - Random random = new Random(); - int r = random.nextInt(100) + 1; - BigInteger amount = BigInteger.valueOf(r); - String txData = - parallelOk.getSignedTransactionForTransfer( - from.getUser(), to.getUser(), amount); - try { - bufferedWriter.write(txData); - bufferedWriter.newLine(); - generated.incrementAndGet(); - if (generated.get() >= area && ((generated.get() % area) == 0)) { - System.out.println( - "Already generated: " - + generated.get() - + "/" - + count - + " transactions"); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - while (generated.intValue() < count.intValue()) { - Thread.sleep(2000); + generatedBar.step(); + transactionLatch.countDown(); + } + }); } + transactionLatch.await(); + generatedBar.close(); + // Integer area = count.intValue() / 10; + // for (Integer i = 0; i < count.intValue(); i++) { + // final Integer index = i; + + // DagTransferUser from = dagUserInfo.getFrom(index); + // DagTransferUser to = dagUserInfo.getTo(index); + // if ((conflictPercent.intValue() > 0) + // && (index <= (conflictPercent.intValue() * count.intValue()) / 100)) { + // to = dagUserInfo.getNext(index); + // } + // Random random = new Random(); + // int r = random.nextInt(100) + 1; + // BigInteger amount = BigInteger.valueOf(r); + // String txData = + // parallelOk.getSignedTransactionForTransfer( + // from.getUser(), to.getUser(), amount); + // JsonRpcRequest request = + // new JsonRpcRequest<>( + // "sendTransaction", Arrays.asList(groupID, "", txData, false)); + // ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + // try { + // bufferedWriter.write(objectMapper.writeValueAsString(request)); + // bufferedWriter.newLine(); + // generated.incrementAndGet(); + // if (generated.get() >= area && ((generated.get() % area) == 0)) { + // System.out.println( + // "Already generated: " + // + generated.get() + // + "/" + // + count + // + " transactions"); + // } + // } catch (IOException e) { + // e.printStackTrace(); + // } + // } + // while (generated.intValue() < count.intValue()) { + // Thread.sleep(2000); + // } System.out.println( "ParallelOkDemo: generateTransferTxs success ! count: " + count - + ", txsFile: " - + txsFile); - bufferedWriter.close(); + + ", txsPath: " + + txsPath); + for (int i = 0; i < threads; i++) { + bufferedWriters[i].close(); + } System.exit(0); } From 5f5704a968e33d25476cc24e0f577a89a79d04c9 Mon Sep 17 00:00:00 2001 From: XingQiang Bai Date: Fri, 14 Jul 2023 18:03:38 +0800 Subject: [PATCH 02/11] fix PerformancePaillier verify failed (#171) --- .../sdk/demo/perf/PerformancePaillierPrecompiled.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java index 1b765da..23b454a 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java @@ -141,7 +141,7 @@ public static void add(String groupId, Integer pklen, int count, Integer qps) int firstIndex = index % numbers; int secondIndex = (index + numbers / 2) % numbers; String first = data[firstIndex]; - String second = data[firstIndex]; + String second = data[secondIndex]; BigInteger result = bigs[firstIndex].add(bigs[secondIndex]); paillierPrecompiled.paillierAdd( first, @@ -162,7 +162,11 @@ public void onResponse(TransactionReceipt receipt) { PaillierCipher.decrypt( output, paillierKeyPair.getPrivate()); if (!ret.equals(result)) { - System.out.println("result not equal"); + System.out.println( + "result not equal, return: " + + ret + + " expect: " + + result); } } }); From eea5490735067fad9173ea22dc71385a0ee88f35 Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Fri, 21 Jul 2023 17:00:56 +0800 Subject: [PATCH 03/11] (test): add ChainContinuityTester. (#172) --- .../bcos/sdk/demo/ChainContinuityTester.java | 233 ++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java diff --git a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java new file mode 100644 index 0000000..ef71805 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java @@ -0,0 +1,233 @@ +package org.fisco.bcos.sdk.demo; + +import java.math.BigInteger; +import java.net.URL; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicLong; +import me.tongfei.progressbar.ProgressBar; +import me.tongfei.progressbar.ProgressBarBuilder; +import me.tongfei.progressbar.ProgressBarStyle; +import org.fisco.bcos.sdk.v3.BcosSDK; +import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.client.protocol.response.BcosBlock; +import org.fisco.bcos.sdk.v3.client.protocol.response.BlockNumber; +import org.fisco.bcos.sdk.v3.client.protocol.response.SealerList; +import org.fisco.bcos.sdk.v3.model.ConstantConfig; +import org.fisco.bcos.sdk.v3.model.Response; +import org.fisco.bcos.sdk.v3.model.callback.RespCallback; +import org.fisco.bcos.sdk.v3.utils.ThreadPoolService; + +public class ChainContinuityTester { + private static Client client; + private static BigInteger toBlock; + private static final ConcurrentHashMap> + nodeBlockMap = new ConcurrentHashMap<>(); + + public static void Usage() { + System.out.println(" Usage:"); + System.out.println("========== Chain Testers =========="); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.ChainContinuityTester [groupId] [fromBlock] [toBlock] [nodeId...]."); + } + + public static void main(String[] args) throws InterruptedException { + String configFileName = ConstantConfig.CONFIG_FILE_NAME; + URL configUrl = ChainContinuityTester.class.getClassLoader().getResource(configFileName); + if (configUrl == null) { + System.out.println("The configFile " + configFileName + " doesn't exist!"); + return; + } + if (args.length < 3) { + Usage(); + return; + } + String groupId = args[0]; + BigInteger fromBlock = new BigInteger(args[1]); + toBlock = new BigInteger(args[2]); + if (fromBlock.compareTo(BigInteger.ZERO) < 0) { + System.out.println("fromBlock must be greater than 0"); + return; + } + if (toBlock.compareTo(fromBlock) < 0 && !toBlock.equals(BigInteger.valueOf(-1))) { + System.out.println("toBlock must be greater than fromBlock"); + return; + } + List nodeIds = new ArrayList<>(); + if (args.length > 3) { + nodeIds.addAll(Arrays.asList(args).subList(3, args.length)); + } + String configFile = configUrl.getPath(); + BcosSDK sdk = BcosSDK.build(configFile); + client = sdk.getClient(groupId); + ThreadPoolService threadPoolService = + new ThreadPoolService( + "ChainContinuityTester", Runtime.getRuntime().availableProcessors()); + if (nodeIds.isEmpty()) { + SealerList sealerList = client.getSealerList(); + SealerList.Sealer sealer = + sealerList + .getSealerList() + .get(new Random().nextInt(sealerList.getSealerList().size())); + getNodeBlocks(sealer.getNodeID(), fromBlock, threadPoolService); + } else { + for (String nodeId : nodeIds) { + getNodeBlocks(nodeId, fromBlock, threadPoolService); + } + } + System.out.println("finish get node blocks, begin to check continuity..."); + for (Map.Entry> concurrentHashMapEntry : + nodeBlockMap.entrySet()) { + checkBlockContinuity(concurrentHashMapEntry); + } + if (nodeIds.isEmpty()) { + return; + } + List> values = + new ArrayList<>(nodeBlockMap.values()); + for (long i = fromBlock.longValue(); i < toBlock.longValue(); i++) { + BcosBlock.Block block = values.get(0).get(i); + if (block == null) { + break; + } + for (int j = 1; j < nodeBlockMap.size(); j++) { + BcosBlock.Block block1 = values.get(j).get(i); + if (block1 == null) { + break; + } + boolean equals = block1.equals(block); + equals = equals && (block1.getTimestamp() == block.getTimestamp()); + equals = + equals + && (Objects.equals( + block1.getReceiptsRoot(), block.getReceiptsRoot())); + equals = + equals + && (Objects.equals( + block1.getTransactionsRoot(), block.getTransactionsRoot())); + equals = equals && (Objects.equals(block.getStateRoot(), block1.getStateRoot())); + equals = equals && block1.getHash().equals(block.getHash()); + equals = equals && block1.getGasUsed().equals(block.getGasUsed()); + if (!equals) { + System.out.println("block continuity check failed, blockNumber:" + i); + } + } + } + } + + private static void checkBlockContinuity( + Map.Entry> concurrentHashMapEntry) { + String nodeId = concurrentHashMapEntry.getKey(); + ConcurrentHashMap blockConcurrentHashMap = + concurrentHashMapEntry.getValue(); + ConcurrentSkipListSet transactionHashes = new ConcurrentSkipListSet<>(); + final AtomicLong lastTimestamp = new AtomicLong(0); + ProgressBar checkBar = + new ProgressBarBuilder() + .setTaskName("Checking " + nodeId + " continuity: ") + .setInitialMax(blockConcurrentHashMap.size()) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + blockConcurrentHashMap.forEach( + (blockNumber, block) -> { + if (block.getTimestamp() <= lastTimestamp.get()) { + System.out.println( + "block continuity timestamp check failed, nodeId:" + + nodeId + + ", blockNumber:" + + blockNumber + + ", timestamp:" + + block.getTimestamp() + + ", lastTimestamp:" + + lastTimestamp); + } + lastTimestamp.set(block.getTimestamp()); + block.getTransactionHashes() + .forEach( + transactionHash -> { + if (!transactionHashes.add(transactionHash.get())) { + System.out.println( + "block continuity transactionHash check failed, nodeId:" + + nodeId + + ", blockNumber:" + + blockNumber + + ", transactionHash:" + + transactionHash.get()); + } + }); + checkBar.step(); + }); + checkBar.close(); + } + + public static void getNodeBlocks( + String nodeId, BigInteger fromBlk, ThreadPoolService threadPoolService) + throws InterruptedException { + BlockNumber blockNumber = client.getBlockNumber(nodeId); + if (toBlock.equals(BigInteger.valueOf(-1)) + || toBlock.compareTo(blockNumber.getBlockNumber()) > 0) { + toBlock = blockNumber.getBlockNumber(); + } + ConcurrentHashMap blockConcurrentHashMap = new ConcurrentHashMap<>(); + System.out.println( + "get node blocks..., nodeId:" + + nodeId + + ", blockNumber:" + + blockNumber.getBlockNumber().intValue() + + ", fromBlock:" + + fromBlk.intValue() + + ", toBlock:" + + toBlock.intValue()); + + CountDownLatch countDownLatch = new CountDownLatch(blockNumber.getBlockNumber().intValue()); + ProgressBar sentBar = + new ProgressBarBuilder() + .setTaskName("Send :") + .setInitialMax(blockNumber.getBlockNumber().intValue()) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + ProgressBar receivedBar = + new ProgressBarBuilder() + .setTaskName("Receive:") + .setInitialMax(blockNumber.getBlockNumber().intValue()) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); + for (long i = 0; i < blockNumber.getBlockNumber().intValue(); i++) { + long finalI = i; + threadPoolService + .getThreadPool() + .execute( + () -> { + client.getBlockByNumberAsync( + nodeId, + BigInteger.valueOf(finalI), + false, + false, + new RespCallback() { + @Override + public void onResponse(BcosBlock bcosBlock) { + blockConcurrentHashMap.put( + finalI, bcosBlock.getBlock()); + countDownLatch.countDown(); + receivedBar.step(); + } + + @Override + public void onError(Response errorResponse) { + blockConcurrentHashMap.put( + finalI, new BcosBlock.Block()); + countDownLatch.countDown(); + receivedBar.step(); + } + }); + sentBar.step(); + }); + } + countDownLatch.await(); + sentBar.close(); + receivedBar.close(); + nodeBlockMap.put(nodeId, blockConcurrentHashMap); + } +} From 0500b983e404d50fb1e62e02a769930066c9251a Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Fri, 21 Jul 2023 17:34:02 +0800 Subject: [PATCH 04/11] (test): fix ChainContinuityTester. (#173) --- .../bcos/sdk/demo/ChainContinuityTester.java | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java index ef71805..577130b 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java @@ -77,24 +77,37 @@ public static void main(String[] args) throws InterruptedException { getNodeBlocks(nodeId, fromBlock, threadPoolService); } } - System.out.println("finish get node blocks, begin to check continuity..."); + System.out.println("Finish get node blocks, begin to check continuity..."); + System.out.println("==================================================="); for (Map.Entry> concurrentHashMapEntry : nodeBlockMap.entrySet()) { checkBlockContinuity(concurrentHashMapEntry); } + System.out.println("Check continuity finished."); + System.out.println("==================================================="); if (nodeIds.isEmpty()) { - return; + System.exit(0); } + System.out.println("Begin to check block consistency..."); List> values = new ArrayList<>(nodeBlockMap.values()); + + ProgressBar checkBar = + new ProgressBarBuilder() + .setTaskName("Checking :") + .setInitialMax(toBlock.intValue()) + .setStyle(ProgressBarStyle.UNICODE_BLOCK) + .build(); for (long i = fromBlock.longValue(); i < toBlock.longValue(); i++) { BcosBlock.Block block = values.get(0).get(i); if (block == null) { + checkBar.close(); break; } for (int j = 1; j < nodeBlockMap.size(); j++) { BcosBlock.Block block1 = values.get(j).get(i); if (block1 == null) { + checkBar.step(); break; } boolean equals = block1.equals(block); @@ -111,10 +124,14 @@ public static void main(String[] args) throws InterruptedException { equals = equals && block1.getHash().equals(block.getHash()); equals = equals && block1.getGasUsed().equals(block.getGasUsed()); if (!equals) { - System.out.println("block continuity check failed, blockNumber:" + i); + System.out.println("ERROR: block continuity check failed, blockNumber:" + i); } + checkBar.step(); } + checkBar.close(); } + System.out.println("==================================================="); + System.exit(0); } private static void checkBlockContinuity( @@ -124,15 +141,10 @@ private static void checkBlockContinuity( concurrentHashMapEntry.getValue(); ConcurrentSkipListSet transactionHashes = new ConcurrentSkipListSet<>(); final AtomicLong lastTimestamp = new AtomicLong(0); - ProgressBar checkBar = - new ProgressBarBuilder() - .setTaskName("Checking " + nodeId + " continuity: ") - .setInitialMax(blockConcurrentHashMap.size()) - .setStyle(ProgressBarStyle.UNICODE_BLOCK) - .build(); + System.out.println("Checking " + nodeId.substring(0, 8) + "... continuity..."); blockConcurrentHashMap.forEach( (blockNumber, block) -> { - if (block.getTimestamp() <= lastTimestamp.get()) { + if (block.getTimestamp() < lastTimestamp.get()) { System.out.println( "block continuity timestamp check failed, nodeId:" + nodeId @@ -149,7 +161,7 @@ private static void checkBlockContinuity( transactionHash -> { if (!transactionHashes.add(transactionHash.get())) { System.out.println( - "block continuity transactionHash check failed, nodeId:" + "ERROR: block continuity transactionHash check failed, nodeId:" + nodeId + ", blockNumber:" + blockNumber @@ -157,9 +169,7 @@ private static void checkBlockContinuity( + transactionHash.get()); } }); - checkBar.step(); }); - checkBar.close(); } public static void getNodeBlocks( @@ -172,7 +182,7 @@ public static void getNodeBlocks( } ConcurrentHashMap blockConcurrentHashMap = new ConcurrentHashMap<>(); System.out.println( - "get node blocks..., nodeId:" + "Get node blocks..., nodeId:" + nodeId + ", blockNumber:" + blockNumber.getBlockNumber().intValue() @@ -181,20 +191,20 @@ public static void getNodeBlocks( + ", toBlock:" + toBlock.intValue()); - CountDownLatch countDownLatch = new CountDownLatch(blockNumber.getBlockNumber().intValue()); + CountDownLatch countDownLatch = new CountDownLatch(toBlock.intValue()); ProgressBar sentBar = new ProgressBarBuilder() .setTaskName("Send :") - .setInitialMax(blockNumber.getBlockNumber().intValue()) + .setInitialMax(toBlock.intValue()) .setStyle(ProgressBarStyle.UNICODE_BLOCK) .build(); ProgressBar receivedBar = new ProgressBarBuilder() .setTaskName("Receive:") - .setInitialMax(blockNumber.getBlockNumber().intValue()) + .setInitialMax(toBlock.intValue()) .setStyle(ProgressBarStyle.UNICODE_BLOCK) .build(); - for (long i = 0; i < blockNumber.getBlockNumber().intValue(); i++) { + for (long i = fromBlk.longValue(); i < toBlock.longValue(); i++) { long finalI = i; threadPoolService .getThreadPool() @@ -204,7 +214,7 @@ public static void getNodeBlocks( nodeId, BigInteger.valueOf(finalI), false, - false, + true, new RespCallback() { @Override public void onResponse(BcosBlock bcosBlock) { From 28adc2f79bc4df69c9e93f867195b63b27d4decb Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Tue, 25 Jul 2023 19:25:27 +0800 Subject: [PATCH 05/11] (perf): fix ChainContinuityTester. (#174) --- .../bcos/sdk/demo/ChainContinuityTester.java | 127 +++++++++++------- 1 file changed, 78 insertions(+), 49 deletions(-) diff --git a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java index 577130b..0612e30 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java @@ -7,6 +7,7 @@ import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicLong; + import me.tongfei.progressbar.ProgressBar; import me.tongfei.progressbar.ProgressBarBuilder; import me.tongfei.progressbar.ProgressBarStyle; @@ -81,7 +82,7 @@ public static void main(String[] args) throws InterruptedException { System.out.println("==================================================="); for (Map.Entry> concurrentHashMapEntry : nodeBlockMap.entrySet()) { - checkBlockContinuity(concurrentHashMapEntry); + checkBlockContinuity(concurrentHashMapEntry, threadPoolService); } System.out.println("Check continuity finished."); System.out.println("==================================================="); @@ -95,47 +96,68 @@ public static void main(String[] args) throws InterruptedException { ProgressBar checkBar = new ProgressBarBuilder() .setTaskName("Checking :") - .setInitialMax(toBlock.intValue()) + .setInitialMax(toBlock.intValue()- fromBlock.intValue()) .setStyle(ProgressBarStyle.UNICODE_BLOCK) .build(); for (long i = fromBlock.longValue(); i < toBlock.longValue(); i++) { - BcosBlock.Block block = values.get(0).get(i); - if (block == null) { - checkBar.close(); - break; - } - for (int j = 1; j < nodeBlockMap.size(); j++) { - BcosBlock.Block block1 = values.get(j).get(i); - if (block1 == null) { - checkBar.step(); - break; - } - boolean equals = block1.equals(block); - equals = equals && (block1.getTimestamp() == block.getTimestamp()); - equals = - equals - && (Objects.equals( - block1.getReceiptsRoot(), block.getReceiptsRoot())); - equals = - equals - && (Objects.equals( - block1.getTransactionsRoot(), block.getTransactionsRoot())); - equals = equals && (Objects.equals(block.getStateRoot(), block1.getStateRoot())); - equals = equals && block1.getHash().equals(block.getHash()); - equals = equals && block1.getGasUsed().equals(block.getGasUsed()); - if (!equals) { - System.out.println("ERROR: block continuity check failed, blockNumber:" + i); - } - checkBar.step(); - } - checkBar.close(); + long finalI = i; + threadPoolService + .getThreadPool() + .execute( + () -> { + BcosBlock.Block block = values.get(0).get(finalI); + if (block == null) { + checkBar.close(); + return; + } + for (int j = 1; j < nodeBlockMap.size(); j++) { + BcosBlock.Block block1 = values.get(j).get(finalI); + if (block1 == null) { + checkBar.step(); + break; + } + boolean equals = block1.equals(block); + equals = + equals + && (block1.getTimestamp() + == block.getTimestamp()); + equals = + equals + && (Objects.equals( + block1.getReceiptsRoot(), + block.getReceiptsRoot())); + equals = + equals + && (Objects.equals( + block1.getTransactionsRoot(), + block.getTransactionsRoot())); + equals = + equals + && (Objects.equals( + block.getStateRoot(), + block1.getStateRoot())); + equals = equals && block1.getHash().equals(block.getHash()); + equals = + equals + && block1.getGasUsed() + .equals(block.getGasUsed()); + if (!equals) { + System.out.println( + "ERROR: block continuity check failed, blockNumber:" + + finalI); + } + checkBar.step(); + } + }); } + checkBar.close(); System.out.println("==================================================="); System.exit(0); } private static void checkBlockContinuity( - Map.Entry> concurrentHashMapEntry) { + Map.Entry> concurrentHashMapEntry, + ThreadPoolService threadPoolService) { String nodeId = concurrentHashMapEntry.getKey(); ConcurrentHashMap blockConcurrentHashMap = concurrentHashMapEntry.getValue(); @@ -156,19 +178,26 @@ private static void checkBlockContinuity( + lastTimestamp); } lastTimestamp.set(block.getTimestamp()); - block.getTransactionHashes() - .forEach( - transactionHash -> { - if (!transactionHashes.add(transactionHash.get())) { - System.out.println( - "ERROR: block continuity transactionHash check failed, nodeId:" - + nodeId - + ", blockNumber:" - + blockNumber - + ", transactionHash:" - + transactionHash.get()); - } - }); + List transactionHashes1 = + block.getTransactionHashes(); + for (int i = 0; i < transactionHashes1.size(); i++) { + int finalI = i; + threadPoolService + .getThreadPool() + .execute( + () -> { + String txHash = transactionHashes1.get(finalI).get(); + if (!transactionHashes.add(txHash)) { + System.out.println( + "ERROR: block continuity transactionHash check failed, nodeId:" + + nodeId + + ", blockNumber:" + + blockNumber + + ", transactionHash:" + + txHash); + } + }); + } }); } @@ -191,17 +220,17 @@ public static void getNodeBlocks( + ", toBlock:" + toBlock.intValue()); - CountDownLatch countDownLatch = new CountDownLatch(toBlock.intValue()); + CountDownLatch countDownLatch = new CountDownLatch(toBlock.intValue() - fromBlk.intValue()); ProgressBar sentBar = new ProgressBarBuilder() .setTaskName("Send :") - .setInitialMax(toBlock.intValue()) + .setInitialMax(toBlock.intValue() - fromBlk.intValue()) .setStyle(ProgressBarStyle.UNICODE_BLOCK) .build(); ProgressBar receivedBar = new ProgressBarBuilder() .setTaskName("Receive:") - .setInitialMax(toBlock.intValue()) + .setInitialMax(toBlock.intValue() - fromBlk.intValue()) .setStyle(ProgressBarStyle.UNICODE_BLOCK) .build(); for (long i = fromBlk.longValue(); i < toBlock.longValue(); i++) { From 24c936669aa432f3c182ef3340387d0fe0cecc41 Mon Sep 17 00:00:00 2001 From: MO NAN <651932351@qq.com> Date: Mon, 28 Aug 2023 17:39:33 +0800 Subject: [PATCH 06/11] Add tars perfomrnace impl (#176) Add tars perfomrnace impl (#176) --- build.gradle | 27 ++- .../bcos/sdk/demo/ChainContinuityTester.java | 19 +- .../bcos/sdk/demo/perf/PerformanceBFS.java | 1 + .../sdk/demo/perf/TarsParallelOkPerf.java | 229 ++++++++++++++++++ 4 files changed, 255 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java diff --git a/build.gradle b/build.gradle index f28a5bd..7780bb7 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ println("Notice: current gradle version is " + gradle.gradleVersion) // Additional attribute definition ext { // jackson version - javaSDKVersion="3.4.0" + javaSDKVersion="3.5.0-SNAPSHOT" //solcJVersion = "0.4.25.1" //solcJVersion = "0.5.2.1" //solcJVersion = "0.6.10.1" @@ -21,6 +21,10 @@ ext { springVersion = '5.3.22' } +tasks.withType(JavaCompile) { + options.encoding = "UTF-8" +} + archivesBaseName = 'java-sdk-demo' version = '3.4.0' @@ -30,9 +34,10 @@ targetCompatibility = 1.8 // In this section you declare where to find the dependencies of your project repositories { mavenCentral() - maven { url "http://maven.aliyun.com/nexus/content/groups/public/" } - maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2"} + maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2"} + } sourceSets { @@ -95,17 +100,17 @@ googleJavaFormat { } dependencies { - compile ("org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:${javaSDKVersion}") - compile('org.fisco-bcos.code-generator:bcos-code-generator:1.0.0') { + api ("org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:${javaSDKVersion}") + api('org.fisco-bcos.code-generator:bcos-code-generator:1.0.0') { exclude group : "org.fisco-bcos.java-sdk" exclude group : "org.slf4j" } - compile ("org.fisco-bcos:solcJ:${solcJVersion}") - compile ("com.google.guava:guava:${guavaVersion}") - compile ("org.apache.commons:commons-collections4:${commonsCollections4Version}") - compile ("me.tongfei:progressbar:0.9.2") - compile spring - compile logger + api ("org.fisco-bcos:solcJ:${solcJVersion}") + api ("com.google.guava:guava:${guavaVersion}") + api ("org.apache.commons:commons-collections4:${commonsCollections4Version}") + api ("me.tongfei:progressbar:0.9.2") + api spring + api logger } configurations.all { diff --git a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java index 0612e30..67be837 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java @@ -7,7 +7,6 @@ import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicLong; - import me.tongfei.progressbar.ProgressBar; import me.tongfei.progressbar.ProgressBarBuilder; import me.tongfei.progressbar.ProgressBarStyle; @@ -96,7 +95,7 @@ public static void main(String[] args) throws InterruptedException { ProgressBar checkBar = new ProgressBarBuilder() .setTaskName("Checking :") - .setInitialMax(toBlock.intValue()- fromBlock.intValue()) + .setInitialMax(toBlock.intValue() - fromBlock.intValue()) .setStyle(ProgressBarStyle.UNICODE_BLOCK) .build(); for (long i = fromBlock.longValue(); i < toBlock.longValue(); i++) { @@ -120,27 +119,27 @@ public static void main(String[] args) throws InterruptedException { equals = equals && (block1.getTimestamp() - == block.getTimestamp()); + == block.getTimestamp()); equals = equals && (Objects.equals( - block1.getReceiptsRoot(), - block.getReceiptsRoot())); + block1.getReceiptsRoot(), + block.getReceiptsRoot())); equals = equals && (Objects.equals( - block1.getTransactionsRoot(), - block.getTransactionsRoot())); + block1.getTransactionsRoot(), + block.getTransactionsRoot())); equals = equals && (Objects.equals( - block.getStateRoot(), - block1.getStateRoot())); + block.getStateRoot(), + block1.getStateRoot())); equals = equals && block1.getHash().equals(block.getHash()); equals = equals && block1.getGasUsed() - .equals(block.getGasUsed()); + .equals(block.getGasUsed()); if (!equals) { System.out.println( "ERROR: block continuity check failed, blockNumber:" diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceBFS.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceBFS.java index c93df96..281263a 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceBFS.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformanceBFS.java @@ -90,6 +90,7 @@ public static void main(String[] args) { System.out.println("client is null"); return; } + version = client.getChainCompatibilityVersion(); HelloWorld helloWorld = diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java new file mode 100644 index 0000000..6001ec7 --- /dev/null +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java @@ -0,0 +1,229 @@ +/** + * Copyright 2014-2020 [fisco-dev] + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.fisco.bcos.sdk.demo.perf; + +import java.io.IOException; +import java.math.BigInteger; +import java.net.URL; +import org.fisco.bcos.sdk.demo.contract.ParallelOk; +import org.fisco.bcos.sdk.demo.perf.model.DagUserInfo; +import org.fisco.bcos.sdk.demo.perf.parallel.DagPrecompiledDemo; +import org.fisco.bcos.sdk.demo.perf.parallel.ParallelOkDemo; +import org.fisco.bcos.sdk.v3.BcosSDK; +import org.fisco.bcos.sdk.v3.client.Client; +import org.fisco.bcos.sdk.v3.client.TarsClient; +import org.fisco.bcos.sdk.v3.contract.precompiled.sharding.ShardingService; +import org.fisco.bcos.sdk.v3.model.ConstantConfig; +import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; +import org.fisco.bcos.sdk.v3.utils.ThreadPoolService; + +public class TarsParallelOkPerf { + private static Client client; + private static DagUserInfo dagUserInfo = new DagUserInfo(); + private static ShardingService shardingService; + + public static void Usage() { + System.out.println(" Usage:"); + System.out.println("===== ParallelOk test==========="); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.TarsParallelOkPerf [parallelok] [groupId] [add] [count] [tps] [file] [isParallel]."); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.TarsParallelOkPerf [parallelok] [groupId] [transfer] [count] [tps] [file] [isParallel]."); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.TarsParallelOkPerf [parallelok] [groupId] [generate] [count] [tps] [file] [isParallel]."); + + System.out.println("===== DagTransafer test==========="); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.TarsParallelOkPerf [precompiled] [groupId] [add] [count] [tps] [file]."); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.TarsParallelOkPerf [precompiled] [groupId] [transfer] [count] [tps] [file]."); + System.out.println( + " \t java -cp 'conf/:lib/*:apps/*' org.fisco.bcos.sdk.demo.perf.TarsParallelOkPerf [precompiled] [groupId] [generate] [count] [tps] [file]."); + } + + public static void main(String[] args) + throws ContractException, IOException, InterruptedException { + try { + String configFileName = ConstantConfig.CONFIG_FILE_NAME; + URL configUrl = TarsParallelOkPerf.class.getClassLoader().getResource(configFileName); + if (configUrl == null) { + System.out.println("The configFile " + configFileName + " doesn't exist!"); + return; + } + boolean isParallel = true; + if (args.length < 6) { + Usage(); + return; + } else if (args.length == 8) { + isParallel = Boolean.parseBoolean(args[7]); + } + String perfType = args[0]; + String groupId = args[1]; + String command = args[2]; + Integer count = Integer.valueOf(args[3]); + Integer qps = Integer.valueOf(args[4]); + String userFile = args[5]; + Integer conflictPercent = 0; + if (args.length == 7) { + conflictPercent = Integer.valueOf(args[6]); + } + + String configFile = configUrl.getPath(); + BcosSDK sdk = BcosSDK.build(configFile); + TarsClient.loadLibrary(); + client = sdk.getTarsClient(groupId); + + dagUserInfo.setFile(userFile); + ThreadPoolService threadPoolService = + new ThreadPoolService( + "ParallelOkPerf", Runtime.getRuntime().availableProcessors()); + + if (perfType.compareToIgnoreCase("parallelok") == 0) { + parallelOkPerf( + groupId, + command, + count, + qps, + conflictPercent, + threadPoolService, + isParallel); + } else if (perfType.compareToIgnoreCase("precompiled") == 0) { + dagTransferPerf(groupId, command, count, qps, conflictPercent, threadPoolService); + } else { + System.out.println( + "invalid perf option: " + + perfType + + ", only support parallelok/precompiled now"); + Usage(); + } + } catch (Exception e) { + System.out.println("ParallelOkPerf test failed, error info: " + e.getMessage()); + System.exit(0); + } + } + + public static void parallelOkPerf( + String groupId, + String command, + Integer count, + Integer qps, + Integer conflictPercent, + ThreadPoolService threadPoolService, + boolean isParallel) + throws IOException, InterruptedException, ContractException { + System.out.println( + "====== ParallelOk trans, count: " + + count + + ", qps:" + + qps + + ", groupId: " + + groupId + + ", conflictPercent: " + + conflictPercent + + ", isParallel: " + + isParallel); + ParallelOk parallelOk; + ParallelOkDemo parallelOkDemo; + switch (command) { + case "add": + // deploy ParallelOk + parallelOk = + ParallelOk.deploy( + client, client.getCryptoSuite().getCryptoKeyPair(), isParallel); + + parallelOkDemo = new ParallelOkDemo(parallelOk, dagUserInfo, threadPoolService); + parallelOkDemo.userAdd(BigInteger.valueOf(count), BigInteger.valueOf(qps)); + break; + case "transfer": + dagUserInfo.loadDagTransferUser(); + parallelOk = + ParallelOk.load( + dagUserInfo.getContractAddr(), + client, + client.getCryptoSuite().getCryptoKeyPair()); + System.out.println( + "====== ParallelOk trans, load success, address: " + + parallelOk.getContractAddress()); + + System.out.println("Start transfer..."); + parallelOkDemo = new ParallelOkDemo(parallelOk, dagUserInfo, threadPoolService); + parallelOkDemo.userTransfer(count, BigInteger.valueOf(qps)); + break; + case "generate": + dagUserInfo.loadDagTransferUser(); + parallelOk = + ParallelOk.load( + dagUserInfo.getContractAddr(), + client, + client.getCryptoSuite().getCryptoKeyPair()); + parallelOkDemo = new ParallelOkDemo(parallelOk, dagUserInfo, threadPoolService); + parallelOkDemo.generateTransferTxs( + client.getGroup(), + count, + "parallelOKTxs", + BigInteger.valueOf(qps), + BigInteger.valueOf(conflictPercent)); + break; + default: + System.out.println("invalid command: " + command); + Usage(); + break; + } + } + + public static void dagTransferPerf( + String groupId, + String command, + Integer count, + Integer qps, + Integer conflictPercent, + ThreadPoolService threadPoolService) + throws IOException, InterruptedException, ContractException { + System.out.println( + "====== DagTransfer trans, count: " + + count + + ", qps:" + + qps + + ", groupId: " + + groupId + + ", conflictPercent: " + + conflictPercent); + + DagPrecompiledDemo dagPrecompiledDemo; + switch (command) { + case "add": + dagPrecompiledDemo = new DagPrecompiledDemo(client, dagUserInfo, threadPoolService); + dagPrecompiledDemo.userAdd(BigInteger.valueOf(count), BigInteger.valueOf(qps)); + break; + case "transfer": + dagUserInfo.loadDagTransferUser(); + dagPrecompiledDemo = new DagPrecompiledDemo(client, dagUserInfo, threadPoolService); + dagPrecompiledDemo.userTransfer(BigInteger.valueOf(count), BigInteger.valueOf(qps)); + break; + case "generate": + dagUserInfo.loadDagTransferUser(); + dagPrecompiledDemo = new DagPrecompiledDemo(client, dagUserInfo, threadPoolService); + dagPrecompiledDemo.generateTransferTxs( + BigInteger.valueOf(count), + "dagTxs.txt", + BigInteger.valueOf(qps), + BigInteger.valueOf(conflictPercent)); + break; + default: + System.out.println("invalid command: " + command); + Usage(); + break; + } + } +} From 7979ad859955ac119a515669faf54bc89c05e024 Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:17:25 +0800 Subject: [PATCH 07/11] (demo): fix ChainContinuityTester timestamp check bug. (#177) --- build.gradle | 2 +- .../bcos/sdk/demo/ChainContinuityTester.java | 74 ++++++++++--------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/build.gradle b/build.gradle index 7780bb7..8ec7536 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ tasks.withType(JavaCompile) { } archivesBaseName = 'java-sdk-demo' -version = '3.4.0' +version = '3.5.0' sourceCompatibility = 1.8 targetCompatibility = 1.8 diff --git a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java index 67be837..c62f5d7 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/ChainContinuityTester.java @@ -23,6 +23,7 @@ public class ChainContinuityTester { private static Client client; private static BigInteger toBlock; + // nodeId -> blockNumber -> block private static final ConcurrentHashMap> nodeBlockMap = new ConcurrentHashMap<>(); @@ -81,7 +82,7 @@ public static void main(String[] args) throws InterruptedException { System.out.println("==================================================="); for (Map.Entry> concurrentHashMapEntry : nodeBlockMap.entrySet()) { - checkBlockContinuity(concurrentHashMapEntry, threadPoolService); + checkBlockContinuity(concurrentHashMapEntry, fromBlock, threadPoolService); } System.out.println("Check continuity finished."); System.out.println("==================================================="); @@ -156,6 +157,7 @@ public static void main(String[] args) throws InterruptedException { private static void checkBlockContinuity( Map.Entry> concurrentHashMapEntry, + BigInteger fromBlk, ThreadPoolService threadPoolService) { String nodeId = concurrentHashMapEntry.getKey(); ConcurrentHashMap blockConcurrentHashMap = @@ -163,41 +165,41 @@ private static void checkBlockContinuity( ConcurrentSkipListSet transactionHashes = new ConcurrentSkipListSet<>(); final AtomicLong lastTimestamp = new AtomicLong(0); System.out.println("Checking " + nodeId.substring(0, 8) + "... continuity..."); - blockConcurrentHashMap.forEach( - (blockNumber, block) -> { - if (block.getTimestamp() < lastTimestamp.get()) { - System.out.println( - "block continuity timestamp check failed, nodeId:" - + nodeId - + ", blockNumber:" - + blockNumber - + ", timestamp:" - + block.getTimestamp() - + ", lastTimestamp:" - + lastTimestamp); - } - lastTimestamp.set(block.getTimestamp()); - List transactionHashes1 = - block.getTransactionHashes(); - for (int i = 0; i < transactionHashes1.size(); i++) { - int finalI = i; - threadPoolService - .getThreadPool() - .execute( - () -> { - String txHash = transactionHashes1.get(finalI).get(); - if (!transactionHashes.add(txHash)) { - System.out.println( - "ERROR: block continuity transactionHash check failed, nodeId:" - + nodeId - + ", blockNumber:" - + blockNumber - + ", transactionHash:" - + txHash); - } - }); - } - }); + for (long i = fromBlk.longValue(); i < toBlock.longValue(); i++) { + BcosBlock.Block block = blockConcurrentHashMap.get(i); + if (block.getTimestamp() < lastTimestamp.get()) { + System.out.println( + "block continuity timestamp check failed, nodeId:" + + nodeId + + ", blockNumber:" + + i + + ", timestamp:" + + block.getTimestamp() + + ", lastTimestamp:" + + lastTimestamp); + } + lastTimestamp.set(block.getTimestamp()); + List transactionHashes1 = block.getTransactionHashes(); + for (int j = 0; j < transactionHashes1.size(); j++) { + int finalJ = j; + long finalI = i; + threadPoolService + .getThreadPool() + .execute( + () -> { + String txHash = transactionHashes1.get(finalJ).get(); + if (!transactionHashes.add(txHash)) { + System.out.println( + "ERROR: block continuity transactionHash check failed, nodeId:" + + nodeId + + ", blockNumber:" + + finalI + + ", transactionHash:" + + txHash); + } + }); + } + } } public static void getNodeBlocks( From 57aacf4d90a96d1bc9fdae6e6ed7f518b9a5dd5e Mon Sep 17 00:00:00 2001 From: MO NAN <651932351@qq.com> Date: Wed, 13 Sep 2023 12:55:38 +0800 Subject: [PATCH 08/11] Update tars perf (#178) * Add tars perfomrnace * Revert comments * Use tars transaction processor --- .../bcos/sdk/demo/perf/TarsParallelOkPerf.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java index 6001ec7..b416587 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java @@ -23,15 +23,15 @@ import org.fisco.bcos.sdk.v3.BcosSDK; import org.fisco.bcos.sdk.v3.client.Client; import org.fisco.bcos.sdk.v3.client.TarsClient; -import org.fisco.bcos.sdk.v3.contract.precompiled.sharding.ShardingService; import org.fisco.bcos.sdk.v3.model.ConstantConfig; +import org.fisco.bcos.sdk.v3.transaction.manager.TarsTransactionProcessor; import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; import org.fisco.bcos.sdk.v3.utils.ThreadPoolService; public class TarsParallelOkPerf { private static Client client; + private static TarsTransactionProcessor tarsTransactionProcessor; private static DagUserInfo dagUserInfo = new DagUserInfo(); - private static ShardingService shardingService; public static void Usage() { System.out.println(" Usage:"); @@ -83,6 +83,10 @@ public static void main(String[] args) BcosSDK sdk = BcosSDK.build(configFile); TarsClient.loadLibrary(); client = sdk.getTarsClient(groupId); + tarsTransactionProcessor = + new TarsTransactionProcessor( + client, client.getCryptoSuite().getCryptoKeyPair(), groupId, "chain0"); + dagUserInfo.setFile(userFile); ThreadPoolService threadPoolService = @@ -141,6 +145,8 @@ public static void parallelOkPerf( parallelOk = ParallelOk.deploy( client, client.getCryptoSuite().getCryptoKeyPair(), isParallel); + parallelOk.setTransactionProcessor(tarsTransactionProcessor); + parallelOkDemo = new ParallelOkDemo(parallelOk, dagUserInfo, threadPoolService); parallelOkDemo.userAdd(BigInteger.valueOf(count), BigInteger.valueOf(qps)); @@ -152,6 +158,8 @@ public static void parallelOkPerf( dagUserInfo.getContractAddr(), client, client.getCryptoSuite().getCryptoKeyPair()); + parallelOk.setTransactionProcessor(tarsTransactionProcessor); + System.out.println( "====== ParallelOk trans, load success, address: " + parallelOk.getContractAddress()); @@ -167,6 +175,8 @@ public static void parallelOkPerf( dagUserInfo.getContractAddr(), client, client.getCryptoSuite().getCryptoKeyPair()); + parallelOk.setTransactionProcessor(tarsTransactionProcessor); + parallelOkDemo = new ParallelOkDemo(parallelOk, dagUserInfo, threadPoolService); parallelOkDemo.generateTransferTxs( client.getGroup(), From 739956e5098cc5962acf39c125acc51d311c7e86 Mon Sep 17 00:00:00 2001 From: XingQiang Bai Date: Tue, 19 Sep 2023 14:53:40 +0800 Subject: [PATCH 09/11] fix paillier overflow (#179) --- .../bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java index 23b454a..7652685 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/PerformancePaillierPrecompiled.java @@ -111,7 +111,7 @@ public static void add(String groupId, Integer pklen, int count, Integer qps) BigInteger[] bigs = new BigInteger[numbers]; KeyPair paillierKeyPair = PaillierKeyPair.generateKeyPair(pklen); for (int i = 0; i < numbers; i++) { - bigs[i] = new BigInteger(256, random); + bigs[i] = new BigInteger(250, random); data[i] = PaillierCipher.encrypt(bigs[i], paillierKeyPair.getPublic()); } System.out.println("Sending transactions..."); From a2ed5ba1138b0644fe9406a245dfcee806b152e3 Mon Sep 17 00:00:00 2001 From: Kyon <32325790+kyonRay@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:58:33 +0800 Subject: [PATCH 10/11] (build): update guava to 32.0.1-jre, update spring to 5.3.30. (#180) --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 8ec7536..39330ea 100644 --- a/build.gradle +++ b/build.gradle @@ -16,9 +16,9 @@ ext { //solcJVersion = "0.5.2.1" //solcJVersion = "0.6.10.1" solcJVersion = "0.8.11.1" - guavaVersion = "30.1.1-jre" + guavaVersion = "32.0.1-jre" commonsCollections4Version = "4.4" - springVersion = '5.3.22' + springVersion = '5.3.30' } tasks.withType(JavaCompile) { From b624535f8d16b000da7629c11bafde4c1b22e196 Mon Sep 17 00:00:00 2001 From: MO NAN <651932351@qq.com> Date: Mon, 9 Oct 2023 19:07:43 +0800 Subject: [PATCH 11/11] Update tars usage (#181) --- .../java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java b/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java index b416587..fd97df9 100644 --- a/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java +++ b/src/main/java/org/fisco/bcos/sdk/demo/perf/TarsParallelOkPerf.java @@ -22,7 +22,6 @@ import org.fisco.bcos.sdk.demo.perf.parallel.ParallelOkDemo; import org.fisco.bcos.sdk.v3.BcosSDK; import org.fisco.bcos.sdk.v3.client.Client; -import org.fisco.bcos.sdk.v3.client.TarsClient; import org.fisco.bcos.sdk.v3.model.ConstantConfig; import org.fisco.bcos.sdk.v3.transaction.manager.TarsTransactionProcessor; import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException; @@ -81,13 +80,11 @@ public static void main(String[] args) String configFile = configUrl.getPath(); BcosSDK sdk = BcosSDK.build(configFile); - TarsClient.loadLibrary(); client = sdk.getTarsClient(groupId); tarsTransactionProcessor = new TarsTransactionProcessor( client, client.getCryptoSuite().getCryptoKeyPair(), groupId, "chain0"); - dagUserInfo.setFile(userFile); ThreadPoolService threadPoolService = new ThreadPoolService( @@ -147,7 +144,6 @@ public static void parallelOkPerf( client, client.getCryptoSuite().getCryptoKeyPair(), isParallel); parallelOk.setTransactionProcessor(tarsTransactionProcessor); - parallelOkDemo = new ParallelOkDemo(parallelOk, dagUserInfo, threadPoolService); parallelOkDemo.userAdd(BigInteger.valueOf(count), BigInteger.valueOf(qps)); break;