| @@ -1,117 +0,0 @@ | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>jdchain-core</artifactId> | |||
| <version>1.2.0-SNAPSHOT</version> | |||
| <relativePath>../core</relativePath> | |||
| </parent> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>test</artifactId> | |||
| <version>1.2.0-SNAPSHOT</version> | |||
| <packaging>pom</packaging> | |||
| <properties> | |||
| <core.version>1.2.0-SNAPSHOT</core.version> | |||
| </properties> | |||
| <modules> | |||
| <module>../core</module> | |||
| <module>test-consensus-client</module> | |||
| <module>test-consensus-node</module> | |||
| <module>test-ledger</module> | |||
| <module>test-contract</module> | |||
| <module>test-integration</module> | |||
| </modules> | |||
| <dependencyManagement> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>consensus-bftsmart</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>consensus-mq</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>contract-jvm</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>contract-maven-plugin</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>crypto-adv</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>crypto-pki</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>gateway</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>peer</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>ledger-database</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>runtime-context</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>runtime-modular</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>runtime-modular-booter</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>storage-redis</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>storage-rocksdb</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| </dependencies> | |||
| </dependencyManagement> | |||
| </project> | |||
| @@ -1 +0,0 @@ | |||
| /.apt_generated_tests/ | |||
| @@ -1,54 +0,0 @@ | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>test</artifactId> | |||
| <version>1.2.0-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>test-consensus-client</artifactId> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-web</artifactId> | |||
| <exclusions> | |||
| <exclusion> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-logging</artifactId> | |||
| </exclusion> | |||
| </exclusions> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-log4j2</artifactId> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>consensus-bftsmart</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <!-- <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>utils-http</artifactId> | |||
| <version>${framework.version}</version> | |||
| </dependency> --> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-configuration-processor</artifactId> | |||
| <optional>true</optional> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-maven-plugin</artifactId> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </project> | |||
| @@ -1,20 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.client; | |||
| import com.jd.blockchain.utils.http.HttpAction; | |||
| import com.jd.blockchain.utils.http.HttpMethod; | |||
| import com.jd.blockchain.utils.http.HttpService; | |||
| /** | |||
| * Created by zhangshuang3 on 2018/9/11. | |||
| */ | |||
| @HttpService | |||
| public interface ConsensusSettingService { | |||
| @HttpAction(path = "/node/settings", method = HttpMethod.GET) | |||
| public String getConsensusSettingsHex(); | |||
| @HttpAction(path = "/node/topology", method = HttpMethod.GET) | |||
| public String getConsensusTopologyHex(); | |||
| } | |||
| @@ -1,142 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.client; | |||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import com.jd.blockchain.utils.io.ByteArray; | |||
| /** | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| @Configuration | |||
| @ConfigurationProperties(prefix = "client") | |||
| public class Settings { | |||
| private String name; | |||
| private ConsensusSetting consensus; | |||
| public ByteArray getLedgerHash() { | |||
| return ledgerHash; | |||
| } | |||
| public void setLedgerHash(ByteArray ledgerHash) { | |||
| this.ledgerHash = ledgerHash; | |||
| } | |||
| private ByteArray ledgerHash; | |||
| public ConsensusSetting getConsensus() { | |||
| return consensus; | |||
| } | |||
| public void setConsensus(ConsensusSetting consensus) { | |||
| this.consensus = consensus; | |||
| } | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| public void setName(String name) { | |||
| this.name = name; | |||
| } | |||
| // =================================================================================================== | |||
| /** | |||
| * 共识相关的参数设置; | |||
| * | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| public static class ConsensusSetting { | |||
| /** | |||
| * 本机用于共识的IP地址; | |||
| */ | |||
| private String ip; | |||
| /** | |||
| * 本机用于共识的端口; | |||
| */ | |||
| private int port; | |||
| public ConsensusSetting() { | |||
| } | |||
| public ConsensusSetting(String ip, int port) { | |||
| this.ip = ip; | |||
| this.port = port; | |||
| } | |||
| private BftsmartSetting bftsmartConfig = new BftsmartSetting("config/system.config", "config/hosts.config"); | |||
| public String getIp() { | |||
| return ip; | |||
| } | |||
| public void setIp(String ip) { | |||
| this.ip = ip; | |||
| } | |||
| public int getPort() { | |||
| return port; | |||
| } | |||
| public void setPort(int port) { | |||
| this.port = port; | |||
| } | |||
| public BftsmartSetting getBftsmartConfig() { | |||
| return bftsmartConfig; | |||
| } | |||
| public void setBftsmartConfig(BftsmartSetting bftsmartConfig) { | |||
| this.bftsmartConfig = bftsmartConfig; | |||
| } | |||
| } | |||
| public static class BftsmartSetting { | |||
| private String hosts; | |||
| private String system; | |||
| private String home; | |||
| public BftsmartSetting() { | |||
| } | |||
| public BftsmartSetting(String systemConfig, String hostsConfig) { | |||
| this.system = systemConfig; | |||
| this.hosts = hostsConfig; | |||
| } | |||
| public String getHosts() { | |||
| return hosts; | |||
| } | |||
| public void setHosts(String hosts) { | |||
| this.hosts = hosts; | |||
| } | |||
| public String getSystem() { | |||
| return system; | |||
| } | |||
| public void setSystem(String system) { | |||
| this.system = system; | |||
| } | |||
| public String getHome() { | |||
| return home; | |||
| } | |||
| public void setHome(String home) { | |||
| this.home = home; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,17 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.client; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||
| @SpringBootApplication | |||
| @EnableAutoConfiguration | |||
| @EnableConfigurationProperties | |||
| public class WebBooter { | |||
| public static void main(String[] args) { | |||
| SpringApplication.run(WebBooter.class, args); | |||
| } | |||
| } | |||
| @@ -1,110 +0,0 @@ | |||
| //package test.perf.com.jd.blockchain.consensus.client; | |||
| // | |||
| //import java.util.Random; | |||
| // | |||
| //import com.jd.blockchain.consensus.bftsmart.BftsmartConsensusSettings; | |||
| //import com.jd.blockchain.consensus.bftsmart.BftsmartTopology; | |||
| //import com.jd.blockchain.consensus.bftsmart.client.BftsmartClientConfig; | |||
| //import com.jd.blockchain.consensus.bftsmart.client.BftsmartClientSettings; | |||
| //import com.jd.blockchain.consensus.bftsmart.client.BftsmartConsensusClient; | |||
| //import com.jd.blockchain.crypto.asymmetric.PubKey; | |||
| //import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| //import my.utils.http.agent.HttpServiceAgent; | |||
| //import my.utils.http.agent.ServiceEndpoint; | |||
| //import my.utils.serialize.binary.BinarySerializeUtils; | |||
| //import org.springframework.beans.factory.annotation.Autowired; | |||
| //import org.springframework.web.bind.annotation.PathVariable; | |||
| //import org.springframework.web.bind.annotation.RequestMapping; | |||
| //import org.springframework.web.bind.annotation.RequestMethod; | |||
| //import org.springframework.web.bind.annotation.RestController; | |||
| // | |||
| // | |||
| //import my.utils.codec.HexUtils; | |||
| // | |||
| //@RestController | |||
| //@RequestMapping(path="bft") | |||
| //public class WebClient { | |||
| // | |||
| // @Autowired | |||
| // private Settings settings; | |||
| // | |||
| // private Random random=new Random(); | |||
| // | |||
| // private volatile byte[] msgBytes; | |||
| // | |||
| // private BftsmartConsensusClient client; | |||
| // | |||
| // private BftsmartConsensusSettings setting; | |||
| // | |||
| // private BftsmartTopology topology; | |||
| // | |||
| // public WebClient() { | |||
| // random = new Random(); | |||
| // updateMessage(32); | |||
| // } | |||
| // | |||
| // private void init() { | |||
| // } | |||
| // | |||
| // @RequestMapping(path="/message", method=RequestMethod.GET) | |||
| // public String getMessage() { | |||
| // return String.format("[size=%s]--[%s]", msgBytes.length, HexUtils.encode(msgBytes)); | |||
| // } | |||
| // | |||
| // private void updateMessage(int size) { | |||
| // msgBytes = new byte[size]; | |||
| // random.nextBytes(msgBytes); | |||
| // } | |||
| // | |||
| // @RequestMapping(path="/message/set/{size}", method=RequestMethod.GET) | |||
| // public String setMessage(@PathVariable("size") int size) { | |||
| // if (size < 1 || size > 1024*1024*200) { | |||
| // return "Size cann't be less than 1 byte or great than 200 MB! "; | |||
| // } | |||
| // updateMessage(size); | |||
| // return getMessage(); | |||
| // } | |||
| // | |||
| // @RequestMapping(path="/test/ordered", method=RequestMethod.GET) | |||
| // public String testOrdered() { | |||
| // if (client == null) { | |||
| // throw new IllegalStateException("client not exist"); | |||
| // } | |||
| // | |||
| // //CallerInfo info = Profiler.registerInfo("jd-chain-bftsmart-performence-client-proxy", false, true); | |||
| // byte[] retn = client.getMessageService().sendOrdered(msgBytes).get(); | |||
| // if(retn.length == 1 && retn[0] == 1){ | |||
| // //Profiler.registerInfoEnd(info); | |||
| // return "OK"; | |||
| // } | |||
| // //Profiler.functionError(info); | |||
| // return "FAIL"; | |||
| // } | |||
| // | |||
| // | |||
| // @RequestMapping(path="/connect/{from}/{port}", method=RequestMethod.GET) | |||
| // public String connect(@PathVariable("from") String from, @PathVariable("port") int port){ | |||
| // if (client != null) { | |||
| // throw new IllegalStateException("Has been connected to nodes!"); | |||
| // } | |||
| // ServiceEndpoint endpoint = new ServiceEndpoint(from, port, false); | |||
| // ConsensusSettingService settingService = HttpServiceAgent.createService(ConsensusSettingService.class, endpoint); | |||
| // String hexSetting = settingService.getConsensusSettingsHex(); | |||
| // String hexTopology = settingService.getConsensusTopologyHex(); | |||
| // setting = BinarySerializeUtils.deserialize(HexUtils.decode(hexSetting)); | |||
| // topology = BinarySerializeUtils.deserialize(HexUtils.decode(hexTopology)); | |||
| // | |||
| // // 0.8.0 version | |||
| //// client = new BftsmartConsensusClient(0, setting, topology); | |||
| // | |||
| // // 0.8.1 version | |||
| // PubKey clientPubKey= BlockchainKeyGenerator.getInstance().generate().getPubKey(); | |||
| // | |||
| // BftsmartClientSettings clientSettings = new BftsmartClientConfig(0, clientPubKey,setting, topology); | |||
| // | |||
| // BftsmartConsensusClient client = new BftsmartConsensusClient(clientSettings); | |||
| // | |||
| // return "OK"; | |||
| // } | |||
| // | |||
| //} | |||
| @@ -1,11 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.client; | |||
| import org.springframework.context.annotation.ComponentScan; | |||
| import org.springframework.context.annotation.Configuration; | |||
| @Configuration | |||
| @ComponentScan | |||
| public class WebConfiguration { | |||
| } | |||
| @@ -1,28 +0,0 @@ | |||
| server.port=10010 | |||
| #server.ssl.key-store=classpath:mykeys.jks | |||
| #server.ssl.key-store-password=abc123 | |||
| #server.ssl.key-password=abc123 | |||
| server.tomcat.accesslog.enabled=false | |||
| debug=false | |||
| #logging.file=logs/peer.log | |||
| logging.level.com.jd.blockchain.peer=DEBUG | |||
| logging.level.org.org.springframework=DEBUG | |||
| spring.mvc.favicon.enabled=false | |||
| client.name=peer[0] | |||
| client.consensus.ip=127.0.0.1 | |||
| client.consensus.port=10000 | |||
| client.consensus.bftsmart-config.home=config | |||
| client.consensus.bftsmart-config.system=config/system.config | |||
| client.consensus.bftsmart-config.hosts=config/hosts.config | |||
| @@ -1 +0,0 @@ | |||
| /.apt_generated_tests/ | |||
| @@ -1,121 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,36 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| # This file defines the replicas ids, IPs and ports. | |||
| # It is used by the replicas and clients to find connection info | |||
| # to the initial replicas. | |||
| # The ports defined here are the ports used by clients to communicate | |||
| # with the replicas. Additional connections are opened by replicas to | |||
| # communicate with each other. This additional connection is opened in the | |||
| # next port defined here. For an example, consider the line "0 127.0.0.1 11000". | |||
| # That means that clients will open a communication channel to replica 0 in | |||
| # IP 127.0.0.1 and port 11000. On startup, replicas with id different than 0 | |||
| # will open a communication channel to replica 0 in port 11001. | |||
| # The same holds for replicas 1, 2, 3 ... N. | |||
| #server id, address and port (the ids from 0 to n-1 are the service replicas) | |||
| 0 127.0.0.1 11000 | |||
| 1 127.0.0.1 11010 | |||
| 2 127.0.0.1 11020 | |||
| 3 127.0.0.1 11030 | |||
| #4 192.168.151.33 11040 | |||
| #5 192.168.151.38 11050 | |||
| #6 127.0.0.1 11060 | |||
| #7 127.0.0.1 11070 | |||
| 7001 127.0.0.1 11100 | |||
| @@ -1,121 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,53 +0,0 @@ | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>test</artifactId> | |||
| <version>1.2.0-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>test-consensus-node</artifactId> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-web</artifactId> | |||
| <exclusions> | |||
| <exclusion> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-logging</artifactId> | |||
| </exclusion> | |||
| </exclusions> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-log4j2</artifactId> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>peer</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>consensus-bftsmart</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-configuration-processor</artifactId> | |||
| <optional>true</optional> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-maven-plugin</artifactId> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </project> | |||
| @@ -1,546 +0,0 @@ | |||
| //package test.perf.com.jd.blockchain.consensus.node; | |||
| // | |||
| //import java.io.IOException; | |||
| //import java.io.InputStream; | |||
| //import java.util.Collections; | |||
| //import java.util.LinkedList; | |||
| //import java.util.List; | |||
| //import java.util.Properties; | |||
| //import java.util.concurrent.CountDownLatch; | |||
| //import java.util.concurrent.CyclicBarrier; | |||
| //import java.util.concurrent.atomic.AtomicInteger; | |||
| // | |||
| //import com.jd.blockchain.consensus.*; | |||
| //import com.jd.blockchain.consensus.bftsmart.*; | |||
| //import com.jd.blockchain.consensus.bftsmart.client.BftsmartClientSettings; | |||
| //import com.jd.blockchain.consensus.bftsmart.service.BftsmartServerSettingConfig; | |||
| //import com.jd.blockchain.consensus.service.MessageHandle; | |||
| //import com.jd.blockchain.consensus.service.ServerSettings; | |||
| //import com.jd.blockchain.consensus.service.StateMachineReplicate; | |||
| //import com.jd.blockchain.crypto.asymmetric.PubKey; | |||
| //import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| //import com.jd.blockchain.peer.consensus.ConsensusMessageDispatcher; | |||
| //import com.jd.blockchain.peer.consensus.LedgerStateManager; | |||
| //import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
| //import my.utils.PropertiesUtils; | |||
| //import my.utils.Property; | |||
| //import my.utils.net.NetworkAddress; | |||
| //import org.springframework.core.io.ClassPathResource; | |||
| // | |||
| //import bftsmart.reconfiguration.util.HostsConfig; | |||
| //import my.utils.ConsoleUtils; | |||
| //import my.utils.concurrent.AsyncFuture; | |||
| //import my.utils.concurrent.ThreadInvoker; | |||
| //import my.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| //import my.utils.concurrent.ThreadUtils; | |||
| //import my.utils.io.BytesUtils; | |||
| //import my.utils.io.FileUtils; | |||
| // | |||
| //public class ConsensusTester { | |||
| // | |||
| // public static final String PASSWORD = "abc"; | |||
| // | |||
| // public static final String[] PUB_KEYS = { "endPsK36imXrY66pru6ttZ8dZ3TynWekmdqoM1K7ZRRoRBBiYVzM", | |||
| // "endPsK36jQE1uYpdVRSnwQXVYhgAMWTaMJiAqii7URiULoBDLUUN", | |||
| // "endPsK36fc7FSecKAJCJdFhTejbPHMLaGcihJVQCv95czCq4tW5n", | |||
| // "endPsK36m1grx8mkTMgh8XQHiiaNzajdC5hkuqP6pAuLmMbYkzd4" }; | |||
| // | |||
| // public static final String[] PRIV_KEYS = { | |||
| // "177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X", | |||
| // "177gjwQwTdXthkutDKVgKwiq6wWfLWYuxhji1U2N1C5MzqLRWCLZXo3i2g4vpfcEAQUPG8H", | |||
| // "177gjvLHUjxvAWsqVcGgV8eHgVNBvJZYDfpP9FLjTouR1gEJNiamYu1qjTNDh18XWyLg8or", | |||
| // "177gk2VtYeGbK5TS2xWhbSZA4BsT9Xj5Fb8hqCzxzgbojVVcqaDSFFrFPsLbZBx7rszyCNy" }; | |||
| // | |||
| // public static volatile boolean debug = false; | |||
| // | |||
| // public static MessageHandle consensusMessageHandler = new ConsensusMessageDispatcher(); | |||
| // public static StateMachineReplicate consensusStateManager = new LedgerStateManager(); | |||
| // | |||
| // public static void main(String[] args) { | |||
| // // DataContractRegistry.register(ActionResponse.class); | |||
| // try { | |||
| // HostsConfig hosts = new HostsConfig(); | |||
| // hosts.add(0, "127.0.0.1", 10000); | |||
| // hosts.add(1, "127.0.0.1", 10010); | |||
| // hosts.add(2, "127.0.0.1", 10020); | |||
| // hosts.add(3, "127.0.0.1", 10030); | |||
| // | |||
| // TestServceHandle handle0 = new TestServceHandle(0); | |||
| // AsyncCallback<BftsmartConsensusServlet> call0 = startReplica(0, hosts, handle0); | |||
| // TestServceHandle handle1 = new TestServceHandle(1); | |||
| // AsyncCallback<BftsmartConsensusServlet> call1 = startReplica(1, hosts, handle1); | |||
| // TestServceHandle handle2 = new TestServceHandle(2); | |||
| // AsyncCallback<BftsmartConsensusServlet> call2 = startReplica(2, hosts, handle2); | |||
| // TestServceHandle handle3 = new TestServceHandle(3); | |||
| // AsyncCallback<BftsmartConsensusServlet> call3 = startReplica(3, hosts, handle3); | |||
| // | |||
| // BftsmartConsensusServlet replica0 = call0.waitReturn(); | |||
| // BftsmartConsensusServlet replica1 = call1.waitReturn(); | |||
| // BftsmartConsensusServlet replica2 = call2.waitReturn(); | |||
| // BftsmartConsensusServlet replica3 = call3.waitReturn(); | |||
| // | |||
| // ConsoleUtils.info("All replicas have started!"); | |||
| // | |||
| // Topology tp = replica0.getTopology().copyOf(); | |||
| // | |||
| // { | |||
| // // 单步测试; | |||
| // // TestServce clientService = createClientService(0, hosts, tp); | |||
| // // debug = true; | |||
| // // ConsoleUtils.info("First message..."); | |||
| // // String resp = clientService.hello("AAAA"); | |||
| // //// String resp = clientService.hello("[SLEEP] AAAA"); | |||
| // // ConsoleUtils.info("response:[%s]", resp); | |||
| // | |||
| // // ConsoleUtils.info("Second message..."); | |||
| // // resp = clientService.hello("[SLEEP] BBBB"); | |||
| // // ConsoleUtils.info("response:[%s]", resp); | |||
| // } | |||
| // { | |||
| // // 异步调用; | |||
| // // TestServce clientService = createClientService(0, hosts, tp); | |||
| // // clientService = AsyncInvoker.asynchorize(TestServce.class, clientService); | |||
| // // debug = true; | |||
| // // long startTs = System.currentTimeMillis(); | |||
| // // ConsoleUtils.info("[%s] Async send first message...", startTs); | |||
| // // AsyncResult<String> ayncResult = | |||
| // // AsyncInvoker.call(clientService.hello("AAAA")); | |||
| // // ayncResult.addListener(new my.utils.concurrent.AsyncCallback<String>() { | |||
| // // @Override | |||
| // // public void complete(String replyMessage, Throwable error) { | |||
| // // if (error != null) { | |||
| // // long endTs = System.currentTimeMillis(); | |||
| // // ConsoleUtils.error("[%s][spanTS=%s] Async response error!!! --%s", endTs, | |||
| // // endTs - startTs, | |||
| // // error.getMessage()); | |||
| // // error.printStackTrace(); | |||
| // // return; | |||
| // // } | |||
| // // | |||
| // // ConsoleUtils.info("Async response:[%s]", replyMessage); | |||
| // // } | |||
| // // }); | |||
| // | |||
| // } | |||
| // | |||
| // { | |||
| // // 单客户端并发消息发送测试; | |||
| // // TestServce clientService = createClientService(0, hosts, tp); | |||
| // // testConcurrentMessageSending(clientService, 100); | |||
| // } | |||
| // | |||
| // { | |||
| // // 多客户端并发消息发送测试; | |||
| // int msgCount = 60000; | |||
| // | |||
| // AtomicInteger receiveCount = new AtomicInteger(0); | |||
| // | |||
| // // my.utils.concurrent.AsyncCallback<String> callback = new | |||
| // // my.utils.concurrent.AsyncCallback<String>() { | |||
| // // @Override | |||
| // // public void complete(String replyMessage, Throwable error) { | |||
| // // if (error != null) { | |||
| // // long endTs = System.currentTimeMillis(); | |||
| // // ConsoleUtils.error("[%s][spanTS=%s] Async response error!!! --%s", endTs, | |||
| // // endTs - startTs, | |||
| // // error.getMessage()); | |||
| // // error.printStackTrace(); | |||
| // // return; | |||
| // // } | |||
| // // int c = receiveCount.incrementAndGet(); | |||
| // // if (c >= msgCount) { | |||
| // // long endTs = System.currentTimeMillis(); | |||
| // // ConsoleUtils.info("\r\n============== All message has been received response! | |||
| // // [耗时:%s millis][TPS=%.2f] =====\r\n", (endTs - startTs), msgCount * 1000.0D | |||
| // // /(endTs - startTs)); | |||
| // // } | |||
| // // } | |||
| // // }; | |||
| // | |||
| // TestServce[] sessions = createSessions(10, hosts, tp); | |||
| // | |||
| // long startTs = System.currentTimeMillis(); | |||
| // ConsoleUtils.info("[%s] Async send first message...", startTs); | |||
| // AtomicInteger arrivedCounter = new AtomicInteger(0); | |||
| // my.utils.concurrent.AsyncHandle<String> allArrivedCallback = new my.utils.concurrent.AsyncHandle<String>() { | |||
| // | |||
| // @Override | |||
| // public void complete(String returnValue, Throwable error) { | |||
| // int c = arrivedCounter.incrementAndGet(); | |||
| // if (c >= 3) { | |||
| // long endTs = System.currentTimeMillis(); | |||
| // ConsoleUtils.info( | |||
| // "\r\n============== All message has been received by most nodes! [耗时:%s millis][TPS=%.2f] =====\r\n", | |||
| // (endTs - startTs), msgCount * 1000.0D / (endTs - startTs)); | |||
| // | |||
| // } | |||
| // if (c >= 4) { | |||
| // ConsoleUtils.info("Verify consistence of all replicas after all message received!"); | |||
| // verifyConsistence(msgCount, handle0, handle1, handle2, handle3); | |||
| // } | |||
| // } | |||
| // }; | |||
| // | |||
| // handle0.setThreshold(msgCount, allArrivedCallback); | |||
| // handle1.setThreshold(msgCount, allArrivedCallback); | |||
| // handle2.setThreshold(msgCount, allArrivedCallback); | |||
| // handle3.setThreshold(msgCount, allArrivedCallback); | |||
| // | |||
| // testConcurrentClient(sessions, msgCount, null); | |||
| // ConsoleUtils.info("Complete client sending."); | |||
| // | |||
| // boolean consistent; | |||
| // int tryTimes = 0; | |||
| // do { | |||
| // ConsoleUtils.info("Verify consistence of all replicas...[%s]", tryTimes); | |||
| // consistent = verifyConsistence(msgCount, handle0, handle1, handle2, handle3); | |||
| // if (consistent) { | |||
| // break; | |||
| // } | |||
| // tryTimes++; | |||
| // ThreadUtils.sleepUninterrupted(1000); | |||
| // } while (tryTimes < 5); | |||
| // } | |||
| // ConsoleUtils.info("----- Test finish! -----"); | |||
| // } catch (Exception e) { | |||
| // e.printStackTrace(); | |||
| // } | |||
| // } | |||
| // | |||
| // public static boolean verifyConsistence(int expectedMessageCount, TestServceHandle... handles) { | |||
| // try { | |||
| // for (int i = 0; i < handles.length; i++) { | |||
| // assertEquals(expectedMessageCount, handles[i].getMessageCount(), "replica[" + i + "] message count"); | |||
| // } | |||
| // | |||
| // for (int i = 0; i < expectedMessageCount; i++) { | |||
| // String msg0 = handles[0].getMessage(i); | |||
| // assertNotNULL(msg0, "replica[" + i + "]"); | |||
| // for (int j = 1; j < handles.length; j++) { | |||
| // String msg1 = handles[j].getMessage(i); | |||
| // assertEquals(msg0, msg1, "message comparison between replica[0] and replica[" + j + "]"); | |||
| // } | |||
| // } | |||
| // | |||
| // ConsoleUtils.info("========== states of all replicas are consistence! ======="); | |||
| // return true; | |||
| // } catch (Exception e) { | |||
| // e.printStackTrace(); | |||
| // return false; | |||
| // } | |||
| // } | |||
| // | |||
| // public static void assertNotNULL(Object actual, String note) { | |||
| // if (actual == null) { | |||
| // throw new IllegalStateException(String.format("%s (expected NULL, but actual[%s])", note, actual)); | |||
| // } | |||
| // } | |||
| // | |||
| // public static void assertEquals(Object expected, Object actual, String note) { | |||
| // if (expected == null && actual == null) { | |||
| // return; | |||
| // } | |||
| // if (expected == null) { | |||
| // throw new IllegalStateException(String.format("%s (expected[%s], but actual[%s])", note, expected, actual)); | |||
| // } | |||
| // if (!expected.equals(actual)) { | |||
| // throw new IllegalStateException(String.format("%s (expected[%s], but actual[%s])", note, expected, actual)); | |||
| // } | |||
| // } | |||
| // | |||
| // private static TestServce[] createSessions(int sessionCount, HostsConfig hosts, Topology tp) { | |||
| // TestServce[] clients = new TestServce[sessionCount]; | |||
| // for (int i = 0; i < clients.length; i++) { | |||
| // PubKey clientPubKey= BlockchainKeyGenerator.getInstance().generate().getPubKey(); | |||
| // TestServce clientService = createClientService(i, clientPubKey, hosts, tp.copyOf()); | |||
| // clients[i] = AsyncInvoker.asynchorize(TestServce.class, clientService); | |||
| // } | |||
| // return clients; | |||
| // } | |||
| // | |||
| // public static void testConcurrentClient(TestServce[] clients, int count, | |||
| // my.utils.concurrent.AsyncHandle<String> callback) { | |||
| // // TestServce[] clients = createSessions(id, hosts, tp); | |||
| // | |||
| // ConsoleUtils.info("All clients has conected to replicas..."); | |||
| // | |||
| // MessageSendingTask[] tasks = new MessageSendingTask[count]; | |||
| // | |||
| // int sessionCount = clients.length; | |||
| // CyclicBarrier barrier = new CyclicBarrier(sessionCount); | |||
| // AtomicInteger counter = new AtomicInteger(0); | |||
| // for (int i = 0; i < sessionCount; i++) { | |||
| // tasks[i] = new MessageSendingTask(count, counter, clients[i], barrier, null, callback); | |||
| // Thread thrd = new Thread(tasks[i]); | |||
| // | |||
| // thrd.start(); | |||
| // } | |||
| // | |||
| // } | |||
| // | |||
| // public static void testConcurrentMessageSending(TestServce clientService, int count) { | |||
| // | |||
| // CyclicBarrier barrier = new CyclicBarrier(count); | |||
| // for (int i = 0; i < count; i++) { | |||
| // | |||
| // Thread thrd = new Thread(new Runnable() { | |||
| // | |||
| // @Override | |||
| // public void run() { | |||
| // try { | |||
| // barrier.await(); | |||
| // clientService.hello("AAAA-" + count); | |||
| // } catch (Exception e) { | |||
| // ConsoleUtils.error("Error occurred on sending message! --%s", e.getMessage()); | |||
| // e.printStackTrace(); | |||
| // } | |||
| // } | |||
| // }); | |||
| // | |||
| // thrd.start(); | |||
| // } | |||
| // } | |||
| // | |||
| // public static TestServce createClientService(int id, PubKey clientPubKey, HostsConfig hosts, Topology tp) { | |||
| // Properties systemConfig = loadConsensusSetting(); | |||
| // | |||
| // BftsmartTopology topology = (BftsmartTopology)tp.copyOf(); | |||
| // Property[] bftsmartSystemConfigs = PropertiesUtils.getOrderedValues(systemConfig); | |||
| // | |||
| // BftsmartNodeSettings[] nodesSettings = new BftsmartNodeSettings[hosts.getNum()]; | |||
| // | |||
| // for (int i = 0; i < hosts.getNum(); i++) { | |||
| // PubKey pubKey = KeyGenCommand.decodePubKey(PUB_KEYS[i]); | |||
| // BftsmartNodeConfig nodeConfig = new BftsmartNodeConfig(pubKey, i, | |||
| // new NetworkAddress(hosts.getHost(i), hosts.getPort(i), false)); | |||
| // nodesSettings[i] = nodeConfig; | |||
| // } | |||
| // | |||
| // ConsensusSettings consensusSettings = new BftsmartConsensusConfig(nodesSettings, null, | |||
| // bftsmartSystemConfigs); | |||
| // | |||
| // BftsmartClientSettings clientSettings = new BftsmartClientSettings(id, clientPubKey, consensusSettings, topology); | |||
| // BftsmartConsensusProxyFactory serviceFactory = BftsmartConsensusProxyFactory.connect(clientSettings); | |||
| // | |||
| // // BftsmartConsensusSetting consensusSetting = new BftsmartConsensusSetting(id, | |||
| // // systemConfig, hosts); | |||
| // // BftsmartConsensusServiceFactory serviceFactory = | |||
| // // BftsmartConsensusServiceFactory.connect(0, consensusSetting, | |||
| // // (BftsmartTopology) tp); | |||
| // | |||
| // return serviceFactory.getService(TestServce.class); | |||
| // } | |||
| // | |||
| // public static AsyncCallback<BftsmartConsensusServlet> startReplica(int id, HostsConfig hosts, | |||
| // TestServce serviceHandle) { | |||
| // Properties systemConfig = loadConsensusSetting(); | |||
| // | |||
| // Property[] bftsmartSystemConfigs = PropertiesUtils.getOrderedValues(systemConfig); | |||
| // | |||
| // BftsmartNodeSettings currNodeSettings = null; | |||
| // | |||
| // for (int i = 0; i < hosts.getNum(); i++) { | |||
| // PubKey pubKey = KeyGenCommand.decodePubKey(PUB_KEYS[i]); | |||
| // BftsmartNodeConfig nodeConfig = new BftsmartNodeConfig(pubKey, i, | |||
| // new NetworkAddress(hosts.getHost(i), hosts.getPort(i), false)); | |||
| // | |||
| // if (i == id) { | |||
| // currNodeSettings = nodeConfig; | |||
| // } | |||
| // } | |||
| // | |||
| // ServerSettings serverSettings = new BftsmartServerSettingConfig(); | |||
| // ((BftsmartServerSettingConfig) serverSettings).setRealmName(null); | |||
| // ((BftsmartServerSettingConfig) serverSettings).setReplicaSettings(currNodeSettings); | |||
| // | |||
| // // BftsmartConsensusServlet servlet = new BftsmartConsensusServlet(id, | |||
| // // systemConfig, hosts); | |||
| // BftsmartConsensusServlet servlet = new BftsmartConsensusServlet(serverSettings, consensusMessageHandler, | |||
| // consensusStateManager); | |||
| //// servlet.addServiceHandler(TestServce.class, serviceHandle); | |||
| // | |||
| // ThreadInvoker<BftsmartConsensusServlet> invoker = new ThreadInvoker<BftsmartConsensusServlet>() { | |||
| // @Override | |||
| // protected BftsmartConsensusServlet invoke() throws Exception { | |||
| // try { | |||
| // servlet.start(); | |||
| // ConsoleUtils.info("Replica[%s] start success.", id); | |||
| // return servlet; | |||
| // } catch (Exception e) { | |||
| // ConsoleUtils.info("Replica[%s] start failed!", id); | |||
| // e.printStackTrace(); | |||
| // throw e; | |||
| // } | |||
| // } | |||
| // }; | |||
| // | |||
| // return invoker.start(); | |||
| // } | |||
| // | |||
| // public static Properties loadConsensusSetting() { | |||
| // ClassPathResource ledgerInitSettingResource = new ClassPathResource("system.config"); | |||
| // try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| // return FileUtils.readProperties(in); | |||
| // } catch (IOException e) { | |||
| // throw new IllegalStateException(e.getMessage(), e); | |||
| // } | |||
| // } | |||
| // | |||
| // public static class TextMessageConverter implements BinaryMessageConverter { | |||
| // | |||
| // @Override | |||
| // public byte[] encode(Object message) { | |||
| // return BytesUtils.toBytes((String) message); | |||
| // } | |||
| // | |||
| // @Override | |||
| // public Object decode(byte[] messageBytes) { | |||
| // return BytesUtils.toString(messageBytes); | |||
| // } | |||
| // | |||
| // } | |||
| // | |||
| // public static class DefaultGroupIndexer implements GroupIndexer { | |||
| // | |||
| // private byte[] groupId = { (byte) 0 }; | |||
| // | |||
| // @Override | |||
| // public byte[] getGroupId(Object[] messageObjects) { | |||
| // return groupId; | |||
| // } | |||
| // | |||
| // } | |||
| // | |||
| // // =================================================== | |||
| // | |||
| // public static interface TestServce { | |||
| // @OrderedAction(groupIndexer = DefaultGroupIndexer.class, responseConverter = TextMessageConverter.class) | |||
| // String hello(@ActionMessage(converter = TextMessageConverter.class) String msg); | |||
| // } | |||
| // | |||
| // private static class TestServceHandle implements TestServce, StateHandle { | |||
| // | |||
| // private int id; | |||
| // | |||
| // private List<String> msgs = Collections.synchronizedList(new LinkedList<>()); | |||
| // | |||
| // private AtomicInteger counter = new AtomicInteger(0); | |||
| // private int threshold; | |||
| // private my.utils.concurrent.AsyncHandle<String> callback; | |||
| // | |||
| // public void setThreshold(int threshold, my.utils.concurrent.AsyncHandle<String> callback) { | |||
| // this.counter.set(0); | |||
| // this.threshold = threshold; | |||
| // this.callback = callback; | |||
| // } | |||
| // | |||
| // public int getMessageCount() { | |||
| // return msgs.size(); | |||
| // } | |||
| // | |||
| // public String getMessage(int index) { | |||
| // return msgs.get(index); | |||
| // } | |||
| // | |||
| // public void clear() { | |||
| // msgs.clear(); | |||
| // } | |||
| // | |||
| // public TestServceHandle(int id) { | |||
| // this.id = id; | |||
| // } | |||
| // | |||
| // @Override | |||
| // public String hello(String msg) { | |||
| // if (debug) { | |||
| // ConsoleUtils.info("Handle message in replica[%s]. --MSG:%s", id, msg); | |||
| // } | |||
| // msgs.add(msg); | |||
| // int c = counter.incrementAndGet(); | |||
| // if (c == threshold && callback != null) { | |||
| // callback.complete("OK", null); | |||
| // } | |||
| // if (msg != null && msg.startsWith("[SLEEP]")) { | |||
| // try { | |||
| // Thread.sleep(600000); | |||
| // } catch (InterruptedException e) { | |||
| // } | |||
| // } | |||
| // return "OK"; | |||
| // } | |||
| // | |||
| // @Override | |||
| // public byte[] takeSnapshot() { | |||
| // int msgCount = getMessageCount(); | |||
| // ConsoleUtils.info("Take snapshot...[replica.id=%s][message.count=%s]", id, msgCount); | |||
| // return BytesUtils.toBytes(msgCount); | |||
| // } | |||
| // | |||
| // @Override | |||
| // public void installSnapshot(byte[] snapshot) { | |||
| // int msgCount = getMessageCount(); | |||
| // ConsoleUtils.info("Intall snapshot...[replica.id=%s][message.count=%s][snapshot.size=%s]", id, msgCount, | |||
| // snapshot == null ? 0 : snapshot.length); | |||
| // } | |||
| // | |||
| // } | |||
| // | |||
| // private static class MessageSendingTask implements Runnable { | |||
| // | |||
| // public static final String MESSAGE = "_ABCDEF"; | |||
| // | |||
| // private CyclicBarrier barrier; | |||
| // | |||
| // private CountDownLatch latch; | |||
| // | |||
| // private TestServce client; | |||
| // | |||
| // private int totalCount; | |||
| // private AtomicInteger counter; | |||
| // | |||
| // private my.utils.concurrent.AsyncHandle<String> callback; | |||
| // | |||
| // // public MessageSendingTask(int taskId, TestServce client) { | |||
| // // this(taskId, client, null, null, null); | |||
| // // } | |||
| // | |||
| // public MessageSendingTask(int totalCount, AtomicInteger counter, TestServce client, CyclicBarrier barrier, | |||
| // CountDownLatch latch, my.utils.concurrent.AsyncHandle<String> callback) { | |||
| // this.totalCount = totalCount; | |||
| // this.counter = counter; | |||
| // this.barrier = barrier; | |||
| // this.latch = latch; | |||
| // this.client = client; | |||
| // this.callback = callback; | |||
| // } | |||
| // | |||
| // @Override | |||
| // public void run() { | |||
| // try { | |||
| // if (barrier != null) { | |||
| // barrier.await(); | |||
| // } | |||
| // while (true) { | |||
| // int taskId = counter.incrementAndGet(); | |||
| // if (taskId > totalCount) { | |||
| // return; | |||
| // } | |||
| // AsyncFuture<String> result = AsyncInvoker.call(client.hello(taskId + MESSAGE)); | |||
| // if (callback != null) { | |||
| // result.whenCompleteAsync(callback); | |||
| // } | |||
| // } | |||
| // | |||
| // } catch (Exception e) { | |||
| // ConsoleUtils.error("Error occurred on sending message! --%s", e.getMessage()); | |||
| // e.printStackTrace(); | |||
| // } finally { | |||
| // if (latch != null) { | |||
| // latch.countDown(); | |||
| // } | |||
| // } | |||
| // } | |||
| // | |||
| // } | |||
| // | |||
| //} | |||
| @@ -1,57 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.node; | |||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||
| import org.springframework.context.annotation.Configuration; | |||
| /** | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| @Configuration | |||
| @ConfigurationProperties(prefix = "bft") | |||
| public class Settings { | |||
| private String name; | |||
| private String systemConfig = "config/system.config"; | |||
| private String nodesConfig = "config/hosts.config"; | |||
| // private String runtimeHome = "./runtime"; | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| public void setName(String name) { | |||
| this.name = name; | |||
| } | |||
| // =================================================================================================== | |||
| public String getSystemConfig() { | |||
| return systemConfig; | |||
| } | |||
| public void setSystemConfig(String systemConfig) { | |||
| this.systemConfig = systemConfig; | |||
| } | |||
| public String getNodesConfig() { | |||
| return nodesConfig; | |||
| } | |||
| public void setNodesConfig(String nodesConfig) { | |||
| this.nodesConfig = nodesConfig; | |||
| } | |||
| // public String getRuntimeHome() { | |||
| // return runtimeHome; | |||
| // } | |||
| // | |||
| // public void setRuntimeHome(String runtimeHome) { | |||
| // this.runtimeHome = runtimeHome; | |||
| // } | |||
| } | |||
| @@ -1,55 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.node; | |||
| import java.util.Properties; | |||
| import bftsmart.reconfiguration.util.HostsConfig; | |||
| import com.jd.blockchain.consensus.AsyncActionResponse; | |||
| import com.jd.blockchain.consensus.action.ActionRequest; | |||
| import com.jd.blockchain.consensus.bftsmart.service.BftsmartNodeServer; | |||
| import com.jd.blockchain.consensus.bftsmart.service.BftsmartServerSettingConfig; | |||
| import com.jd.blockchain.consensus.bftsmart.service.BftsmartServerSettings; | |||
| import com.jd.blockchain.consensus.service.MessageHandle; | |||
| import com.jd.blockchain.peer.consensus.ConsensusMessageDispatcher; | |||
| import com.jd.blockchain.utils.ConsoleUtils; | |||
| public class TestReplica extends BftsmartNodeServer { | |||
| private byte[] retnOK = {1}; | |||
| public TestReplica(int id, Properties systemsConfig, HostsConfig hostConfig) { | |||
| super(new BftsmartServerSettingConfig(), new ConsensusMessageDispatcher(), null); | |||
| } | |||
| // @Override | |||
| // protected AsyncActionResponse execute(ActionRequest request) { | |||
| // ConsoleUtils.info("Receive request ..."); | |||
| // return new SimpleResponse(retnOK); | |||
| // } | |||
| private static class SimpleResponse implements AsyncActionResponse{ | |||
| private byte[] data; | |||
| public SimpleResponse(byte[] data) { | |||
| this.data = data; | |||
| } | |||
| @Override | |||
| public byte[] process() { | |||
| return data; | |||
| } | |||
| } | |||
| @Override | |||
| public void installSnapshot(byte[] state) { | |||
| // TODO Auto-generated method stub | |||
| } | |||
| @Override | |||
| public byte[] getSnapshot() { | |||
| // TODO Auto-generated method stub | |||
| return null; | |||
| } | |||
| } | |||
| @@ -1,138 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.node; | |||
| import java.util.Properties; | |||
| import java.util.TreeSet; | |||
| import javax.annotation.PostConstruct; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.consensus.Topology; | |||
| import com.jd.blockchain.utils.codec.HexUtils; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.serialize.binary.BinarySerializeUtils; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.PathVariable; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.RequestMethod; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import bftsmart.reconfiguration.util.HostsConfig; | |||
| @RestController | |||
| public class TestWebController { | |||
| @Autowired | |||
| private Settings settings; | |||
| private Properties systemProperties; | |||
| private HostsConfig nodesConfig; | |||
| private TestReplica replica; | |||
| public TestWebController() { | |||
| } | |||
| @PostConstruct | |||
| private void init() { | |||
| nodesConfig = new HostsConfig(settings.getNodesConfig()); | |||
| systemProperties = FileUtils.readProperties(settings.getSystemConfig()); | |||
| } | |||
| @RequestMapping(path = "/configs/consensus", method = RequestMethod.GET) | |||
| public String getSystemProperties() { | |||
| TreeSet<String> names = new TreeSet<>(systemProperties.stringPropertyNames()); | |||
| StringBuilder content = new StringBuilder(); | |||
| for (String n : names) { | |||
| content.append(String.format("%s=%s<br>\r\n", n, systemProperties.getProperty(n))); | |||
| } | |||
| return content.toString(); | |||
| } | |||
| @RequestMapping(path = "/configs/consensus/set/{key}/{value}", method = RequestMethod.GET) | |||
| public String setSystemProperty(@PathVariable("key") String key, @PathVariable("value") String value) { | |||
| systemProperties.setProperty(key, value); | |||
| return getSystemProperties(); | |||
| } | |||
| @RequestMapping(path = "/configs/consensus/set/default", method = RequestMethod.GET) | |||
| public String setSystemDefaultProperty() { | |||
| systemProperties = FileUtils.readProperties(settings.getSystemConfig()); | |||
| return getSystemProperties(); | |||
| } | |||
| @RequestMapping(path = "/configs/nodes", method = RequestMethod.GET) | |||
| public String getNodes() { | |||
| StringBuilder content = new StringBuilder(); | |||
| int[] ids = nodesConfig.getHostsIds(); | |||
| for (int id : ids) { | |||
| content.append(String.format("%s - %s:%s [%s] <br>\r\n", id, nodesConfig.getHost(id), nodesConfig.getPort(id), | |||
| nodesConfig.getServerToServerPort(id))); | |||
| } | |||
| return content.toString(); | |||
| } | |||
| @RequestMapping(path = "/configs/nodes/set/{id}/{host}/{port}", method = RequestMethod.GET) | |||
| public String setNode(@PathVariable("id") int id, @PathVariable("host") String host, | |||
| @PathVariable("port") int port) { | |||
| nodesConfig.add(id, host, port); | |||
| return getNodes(); | |||
| } | |||
| @RequestMapping(path = "/node/id", method = RequestMethod.GET) | |||
| public String getNodeID() { | |||
| return "Node.ID=" + (replica == null ? 0 : replica.getId()); | |||
| } | |||
| @RequestMapping(path = "/node/status", method = RequestMethod.GET) | |||
| public String getStatus() { | |||
| return replica == null ? "STOPPED" : "RUNNING"; | |||
| } | |||
| @RequestMapping(path = "/node/start/{id}", method = RequestMethod.GET) | |||
| public String start(@PathVariable("id")int id) { | |||
| if (replica != null ) { | |||
| return "Already started!"; | |||
| } | |||
| TestReplica replica = new TestReplica(id, systemProperties, nodesConfig); | |||
| //after new TestConsensusReplica systemProperties field will be removed | |||
| replica.start(); | |||
| this.replica = replica; | |||
| return "success!"; | |||
| } | |||
| @RequestMapping(path = "/node/stop", method = RequestMethod.GET) | |||
| public String stop() { | |||
| if (replica == null ) { | |||
| return "Already stopped!"; | |||
| } | |||
| TestReplica replica = this.replica; | |||
| this.replica = null; | |||
| replica.stop(); | |||
| return "stopped!"; | |||
| } | |||
| @RequestMapping(path = "/node/topology", method = RequestMethod.GET) | |||
| public String getNodesTopology(){ | |||
| if (replica == null ) { | |||
| throw new IllegalStateException("Replica not start"); | |||
| } | |||
| Topology tp = replica.getTopology().copyOf(); | |||
| byte[] bytesTP = BinarySerializeUtils.serialize(tp); | |||
| return HexUtils.encode(bytesTP); | |||
| } | |||
| @RequestMapping(path = "/node/settings", method = RequestMethod.GET) | |||
| public String getNodesSettings(){ | |||
| if (replica == null ) { | |||
| throw new IllegalStateException("Replica not start"); | |||
| } | |||
| ConsensusSettings settings = replica.getConsensusSetting(); | |||
| byte[] bytesSettings = BinarySerializeUtils.serialize(settings); | |||
| return HexUtils.encode(bytesSettings); | |||
| } | |||
| } | |||
| @@ -1,17 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.node; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||
| @SpringBootApplication | |||
| @EnableAutoConfiguration | |||
| @EnableConfigurationProperties | |||
| public class WebBooter { | |||
| public static void main(String[] args) { | |||
| SpringApplication.run(WebBooter.class, args); | |||
| } | |||
| } | |||
| @@ -1,11 +0,0 @@ | |||
| package test.perf.com.jd.blockchain.consensus.node; | |||
| import org.springframework.context.annotation.ComponentScan; | |||
| import org.springframework.context.annotation.Configuration; | |||
| @Configuration | |||
| @ComponentScan | |||
| public class WebConfiguration { | |||
| } | |||
| @@ -1,19 +0,0 @@ | |||
| server.port=9000 | |||
| #server.ssl.key-store=classpath:mykeys.jks | |||
| #server.ssl.key-store-password=abc123 | |||
| #server.ssl.key-password=abc123 | |||
| server.tomcat.accesslog.enabled=false | |||
| debug=false | |||
| #logging.file=logs/peer.log | |||
| logging.level.com.jd.blockchain.peer=DEBUG | |||
| logging.level.org.org.springframework=DEBUG | |||
| spring.mvc.favicon.enabled=false | |||
| bft.name=node-0 | |||
| bft.nodes-config=config/hosts.config | |||
| bft.system-config=config/system.config | |||
| bft.runtime-home=config | |||
| @@ -1,121 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 800 | |||
| system.totalordermulticast.global_checkpoint_period = 5000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,34 +0,0 @@ | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>test</artifactId> | |||
| <version>1.2.0-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>test-contract</artifactId> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>contract-jvm</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>ledger-database</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>storage-rocksdb</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <!-- <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>crypto-classic</artifactId> | |||
| <version>${framework.version}</version> | |||
| </dependency> --> | |||
| </dependencies> | |||
| </project> | |||
| @@ -1,14 +0,0 @@ | |||
| package test.com.jd.blockchain.contract; | |||
| import static org.junit.Assert.*; | |||
| import org.junit.Test; | |||
| public class ContractTransactionRollbackTest { | |||
| @Test | |||
| public void test() { | |||
| } | |||
| } | |||
| @@ -1,76 +0,0 @@ | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>test</artifactId> | |||
| <version>1.2.0-SNAPSHOT</version> | |||
| </parent> | |||
| <artifactId>test-integration</artifactId> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>org.mockito</groupId> | |||
| <artifactId>mockito-core</artifactId> | |||
| <scope>compile</scope> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>peer</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>storage-rocksdb</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>storage-redis</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>gateway</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>tools-initializer</artifactId> | |||
| <version>${core.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>sdk-client</artifactId> | |||
| <version>${framework.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.jd.blockchain</groupId> | |||
| <artifactId>crypto-classic</artifactId> | |||
| <version>${framework.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>io.nats</groupId> | |||
| <artifactId>jnats</artifactId> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>org.mockito</groupId> | |||
| <artifactId>mockito-core</artifactId> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-maven-plugin</artifactId> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </project> | |||
| @@ -1,76 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import com.jd.blockchain.gateway.GatewayServerBooter; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import org.springframework.util.CollectionUtils; | |||
| import java.util.Map; | |||
| public class GatewayTestRunner { | |||
| private NetworkAddress serviceAddress; | |||
| private GatewayServerBooter gatewayServer; | |||
| public GatewayTestRunner(String host, int port, KeyPairConfig gatewayDefaultKey, NetworkAddress masterPeerAddres) { | |||
| this(host, port, gatewayDefaultKey, masterPeerAddres, null,null); | |||
| } | |||
| public GatewayTestRunner(String host, int port, KeyPairConfig gatewayDefaultKey, NetworkAddress masterPeerAddres, String[] providers, | |||
| Map<String,Object> otherMap) { | |||
| this.serviceAddress = new NetworkAddress(host, port); | |||
| GatewayConfigProperties config = new GatewayConfigProperties(); | |||
| config.http().setHost(host); | |||
| config.http().setPort(port); | |||
| if (providers != null) { | |||
| for (String provider : providers) { | |||
| config.providerConfig().add(provider); | |||
| } | |||
| } | |||
| config.setMasterPeerAddress(masterPeerAddres); | |||
| config.keys().getDefault().setPubKeyValue(gatewayDefaultKey.getPubKeyValue()); | |||
| config.keys().getDefault().setPrivKeyValue(gatewayDefaultKey.getPrivKeyValue()); | |||
| config.keys().getDefault().setPrivKeyPassword(gatewayDefaultKey.getPrivKeyPassword()); | |||
| if(!CollectionUtils.isEmpty(otherMap)){ | |||
| config.setDataRetrievalUrl(otherMap.get("DATA_RETRIEVAL_URL").toString()); | |||
| } | |||
| //get the springConfigLocation; | |||
| ClassPathResource configResource = new ClassPathResource("application-gw.properties"); | |||
| String springConfigLocation = "classPath:"+configResource.getPath(); | |||
| this.gatewayServer = new GatewayServerBooter(config,springConfigLocation); | |||
| } | |||
| public AsyncCallback<Object> start() { | |||
| ThreadInvoker<Object> invoker = new ThreadInvoker<Object>() { | |||
| @Override | |||
| protected Object invoke() throws Exception { | |||
| gatewayServer.start(); | |||
| return null; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public void stop() { | |||
| gatewayServer.close(); | |||
| } | |||
| public NetworkAddress getServiceAddress() { | |||
| return serviceAddress; | |||
| } | |||
| } | |||
| @@ -1,113 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import java.util.Arrays; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| public class IntegratedContext { | |||
| private HashDigest ledgerHash; | |||
| private Map<Integer, Node> nodes = new HashMap<>(); | |||
| public int[] getNodeIds() { | |||
| int[] ids = new int[nodes.size()]; | |||
| int i = 0; | |||
| for (Integer id : nodes.keySet()) { | |||
| ids[i] = id.intValue(); | |||
| i++; | |||
| } | |||
| Arrays.sort(ids); | |||
| return ids; | |||
| } | |||
| public HashDigest getLedgerHash() { | |||
| return ledgerHash; | |||
| } | |||
| public void setLedgerHash(HashDigest ledgerHash) { | |||
| this.ledgerHash = ledgerHash; | |||
| } | |||
| public Node getNode(int id) { | |||
| return nodes.get(id); | |||
| } | |||
| public void addNode(Node node) { | |||
| nodes.put(node.getId(), node); | |||
| } | |||
| public static class Node { | |||
| private int id; | |||
| private AsymmetricKeypair partiKeyPair; | |||
| // private NetworkAddress consensusAddress; | |||
| private ConsensusSettings consensusSettings; | |||
| private LedgerManager ledgerManager; | |||
| private DbConnectionFactory storageDB; | |||
| private LedgerBindingConfig bindingConfig; | |||
| public Node(int id) { | |||
| this.id = id; | |||
| } | |||
| public ConsensusSettings getConsensusAddress() { | |||
| return consensusSettings; | |||
| } | |||
| public LedgerManager getLedgerManager() { | |||
| return ledgerManager; | |||
| } | |||
| public DbConnectionFactory getStorageDB() { | |||
| return storageDB; | |||
| } | |||
| public AsymmetricKeypair getPartiKeyPair() { | |||
| return partiKeyPair; | |||
| } | |||
| public void setPartiKeyPair(AsymmetricKeypair partiKeyPair) { | |||
| this.partiKeyPair = partiKeyPair; | |||
| } | |||
| public int getId() { | |||
| return id; | |||
| } | |||
| public void setConsensusSettings(ConsensusSettings consensusSettings) { | |||
| this.consensusSettings = consensusSettings; | |||
| } | |||
| public void setLedgerManager(LedgerManager ledgerManager) { | |||
| this.ledgerManager = ledgerManager; | |||
| } | |||
| public void setStorageDB(DbConnectionFactory storageDB) { | |||
| this.storageDB = storageDB; | |||
| } | |||
| public LedgerBindingConfig getBindingConfig() { | |||
| return bindingConfig; | |||
| } | |||
| public void setBindingConfig(LedgerBindingConfig bindingConfig) { | |||
| this.bindingConfig = bindingConfig; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,704 +0,0 @@ | |||
| //package test.com.jd.blockchain.intgr; | |||
| // | |||
| //import java.io.File; | |||
| //import java.io.FileInputStream; | |||
| //import java.io.IOException; | |||
| //import java.io.InputStream; | |||
| //import java.util.Properties; | |||
| //import java.util.Random; | |||
| //import java.util.concurrent.CountDownLatch; | |||
| // | |||
| //import org.mockito.Mockito; | |||
| //import org.springframework.core.io.ClassPathResource; | |||
| // | |||
| //import com.jd.blockchain.consensus.ConsensusProvider; | |||
| //import com.jd.blockchain.consensus.ConsensusProviders; | |||
| //import com.jd.blockchain.consensus.ConsensusSettings; | |||
| //import com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider; | |||
| //import com.jd.blockchain.consensus.service.NodeServerFactory; | |||
| //import com.jd.blockchain.crypto.AddressEncoding; | |||
| //import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| //import com.jd.blockchain.crypto.Crypto; | |||
| //import com.jd.blockchain.crypto.HashDigest; | |||
| //import com.jd.blockchain.crypto.KeyGenUtils; | |||
| //import com.jd.blockchain.crypto.PrivKey; | |||
| //import com.jd.blockchain.crypto.PubKey; | |||
| //import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| //import com.jd.blockchain.ledger.BlockchainIdentity; | |||
| //import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| //import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| //import com.jd.blockchain.ledger.BytesValue; | |||
| //import com.jd.blockchain.ledger.DataAccountKVSetOperation; | |||
| //import com.jd.blockchain.ledger.LedgerBlock; | |||
| //import com.jd.blockchain.ledger.LedgerInfo; | |||
| //import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| //import com.jd.blockchain.ledger.ParticipantNode; | |||
| //import com.jd.blockchain.ledger.PreparedTransaction; | |||
| //import com.jd.blockchain.ledger.TransactionResponse; | |||
| //import com.jd.blockchain.ledger.TransactionTemplate; | |||
| //import com.jd.blockchain.ledger.TypedKVEntry; | |||
| //import com.jd.blockchain.ledger.UserInfo; | |||
| //import com.jd.blockchain.ledger.core.DataAccountQuery; | |||
| //import com.jd.blockchain.ledger.core.LedgerManage; | |||
| //import com.jd.blockchain.ledger.core.LedgerManager; | |||
| //import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| //import com.jd.blockchain.sdk.BlockchainService; | |||
| //import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| //import com.jd.blockchain.storage.service.KVStorageService; | |||
| //import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| //import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| //import com.jd.blockchain.tools.initializer.Prompter; | |||
| //import com.jd.blockchain.utils.Bytes; | |||
| //import com.jd.blockchain.utils.codec.HexUtils; | |||
| //import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| //import com.jd.blockchain.utils.net.NetworkAddress; | |||
| // | |||
| //import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| //import test.com.jd.blockchain.intgr.perf.LedgerInitializeWebTest; | |||
| //import test.com.jd.blockchain.intgr.perf.Utils; | |||
| // | |||
| //public class IntegrationTest { | |||
| // // 合约测试使用的初始化数据; | |||
| // BlockchainKeypair contractDataKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| // BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| // private String contractZipName = "AssetContract1.contract"; | |||
| // private String eventName = "issue-asset"; | |||
| // HashDigest txContentHash; | |||
| // // String userPubKeyVal = "this is user's pubKey"; | |||
| // // 保存资产总数的键; | |||
| // private static final String KEY_TOTAL = "TOTAL"; | |||
| // // 第二个参数; | |||
| // private static final String KEY_ABC = "abc"; | |||
| // | |||
| // private static final String MQ_SERVER = "nats://127.0.0.1:4222"; | |||
| // | |||
| // private static final String MQ_TOPIC = "subject"; | |||
| // | |||
| // private static String memDbConnString = LedgerInitConsensusConfig.memConnectionStrings[0]; | |||
| // | |||
| // // private static final MQConnectionConfig mqConnConfig = new | |||
| // // MQConnectionConfig(); | |||
| // // static { | |||
| // // mqConnConfig.setServer(MQ_SERVER); | |||
| // // mqConnConfig.setTopic(MQ_TOPIC); | |||
| // // } | |||
| // | |||
| // public static void main_(String[] args) { | |||
| // // init ledgers of all nodes ; | |||
| // IntegratedContext context = initLedgers(); | |||
| // Node node0 = context.getNode(0); | |||
| // Node node1 = context.getNode(1); | |||
| // Node node2 = context.getNode(2); | |||
| // Node node3 = context.getNode(3); | |||
| // | |||
| // BftsmartConsensusProvider csProvider0 = new BftsmartConsensusProvider(); | |||
| // NodeServerFactory mockedNodeServerFactory0 = Mockito.spy(csProvider0.getServerFactory()); | |||
| // | |||
| // NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 10200); | |||
| // PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, node0.getBindingConfig(), node0.getStorageDB()); | |||
| // | |||
| // NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 10210); | |||
| // PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, node1.getBindingConfig(), node1.getStorageDB()); | |||
| // | |||
| // NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 10220); | |||
| // PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, node2.getBindingConfig(), node2.getStorageDB()); | |||
| // | |||
| // NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 10230); | |||
| // PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, node3.getBindingConfig(), node3.getStorageDB()); | |||
| // | |||
| // AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
| // AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
| // AsyncCallback<Object> peerStarting2 = peer2.start(); | |||
| // AsyncCallback<Object> peerStarting3 = peer3.start(); | |||
| // | |||
| // peerStarting0.waitReturn(); | |||
| // peerStarting1.waitReturn(); | |||
| // peerStarting2.waitReturn(); | |||
| // peerStarting3.waitReturn(); | |||
| // | |||
| // String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWebTest.PASSWORD); | |||
| // | |||
| // KeyPairConfig gwkey0 = new KeyPairConfig(); | |||
| // gwkey0.setPubKeyValue(LedgerInitializeWebTest.PUB_KEYS[0]); | |||
| // gwkey0.setPrivKeyValue(LedgerInitializeWebTest.PRIV_KEYS[0]); | |||
| // gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| // // GatewayTestRunner gateway0 = new GatewayTestRunner("127.0.0.1", 10300, | |||
| // // gwkey0, peerSrvAddr0); | |||
| // GatewayTestRunner gateway0 = new GatewayTestRunner("127.0.0.1", 10300, gwkey0, peerSrvAddr0); | |||
| // | |||
| // // KeyPairConfig gwkey1 = new KeyPairConfig(); | |||
| // // gwkey1.setPubKeyValue(LedgerInitializeWebTest.PUB_KEYS[1]); | |||
| // // gwkey1.setPrivKeyValue(LedgerInitializeWebTest.PRIV_KEYS[1]); | |||
| // // gwkey1.setPrivKeyPassword(encodedBase58Pwd); | |||
| // // GatewayTestRunner gateway1 = new GatewayTestRunner("127.0.0.1", 10310, | |||
| // // gwkey1, peerSrvAddr1); | |||
| // | |||
| // AsyncCallback<Object> gwStarting0 = gateway0.start(); | |||
| // // AsyncCallback<Object> gwStarting1 = gateway1.start(); | |||
| // | |||
| // gwStarting0.waitReturn(); | |||
| // // gwStarting1.waitReturn(); | |||
| // | |||
| // // 执行测试用例之前,校验每个节点的一致性; | |||
| // // testConsistencyAmongNodes(context); | |||
| // | |||
| // testSDK(gateway0, context); | |||
| // | |||
| // // 执行测试用例之后,校验每个节点的一致性; | |||
| // // testConsistencyAmongNodes(context); | |||
| // } | |||
| // | |||
| // /** | |||
| // * 检查所有节点之间的账本是否一致; | |||
| // * | |||
| // * @param context | |||
| // */ | |||
| // private void testConsistencyAmongNodes(IntegratedContext context) { | |||
| // int[] ids = context.getNodeIds(); | |||
| // Node[] nodes = new Node[ids.length]; | |||
| // LedgerQuery[] ledgers = new LedgerQuery[ids.length]; | |||
| // for (int i = 0; i < nodes.length; i++) { | |||
| // nodes[i] = context.getNode(ids[i]); | |||
| // HashDigest ledgerHash = nodes[i].getLedgerManager().getLedgerHashs()[0]; | |||
| // ledgers[i] = nodes[i].getLedgerManager().getLedger(ledgerHash); | |||
| // } | |||
| // LedgerQuery ledger0 = ledgers[0]; | |||
| // LedgerBlock latestBlock0 = ledger0.retrieveLatestBlock(); | |||
| // for (int i = 1; i < ledgers.length; i++) { | |||
| // LedgerQuery otherLedger = ledgers[i]; | |||
| // LedgerBlock otherLatestBlock = otherLedger.retrieveLatestBlock(); | |||
| // } | |||
| // } | |||
| // | |||
| // private static void testSDK(GatewayTestRunner gateway, IntegratedContext context) { | |||
| // // 连接网关; | |||
| // GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| // BlockchainService bcsrv = gwsrvFact.getBlockchainService(); | |||
| // | |||
| // HashDigest[] ledgerHashs = bcsrv.getLedgerHashs(); | |||
| // | |||
| // AsymmetricKeypair adminKey = context.getNode(0).getPartiKeyPair(); | |||
| // | |||
| // BlockchainKeypair newUserAcount = testSDK_RegisterUser(adminKey, ledgerHashs[0], bcsrv, context); | |||
| // | |||
| // // BlockchainKeyPair newDataAccount = testSDK_RegisterDataAccount(adminKey, | |||
| // // ledgerHashs[0], bcsrv, context); | |||
| // // | |||
| // // testSDK_InsertData(adminKey, ledgerHashs[0], bcsrv, | |||
| // // newDataAccount.getAddress(), context); | |||
| // // | |||
| // // LedgerBlock latestBlock = testSDK_Contract(adminKey, ledgerHashs[0], bcsrv, | |||
| // // context); | |||
| // | |||
| // } | |||
| // | |||
| // private void testSDK_InsertData(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService, | |||
| // String dataAccountAddress, IntegratedContext context) { | |||
| // | |||
| // // 在本地定义注册账号的 TX; | |||
| // TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash); | |||
| // | |||
| // // -------------------------------------- | |||
| // // 将商品信息写入到指定的账户中; | |||
| // // 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; | |||
| // String dataAccount = dataAccountAddress; | |||
| // | |||
| // String dataKey = "jingdong" + new Random().nextInt(100000); | |||
| // String dataVal = "www.jd.com"; | |||
| // | |||
| // txTemp.dataAccount(dataAccount).setText(dataKey, dataVal, -1); | |||
| // | |||
| // // TX 准备就绪; | |||
| // PreparedTransaction prepTx = txTemp.prepare(); | |||
| // | |||
| // // 使用私钥进行签名; | |||
| // prepTx.sign(adminKey); | |||
| // | |||
| // // 提交交易; | |||
| // TransactionResponse txResp = prepTx.commit(); | |||
| // | |||
| // Node node0 = context.getNode(0); | |||
| // LedgerQuery ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); | |||
| // ledgerOfNode0.retrieveLatestBlock(); // 更新内存 | |||
| // | |||
| // // 先验证应答 | |||
| // TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, dataAccountAddress, dataKey); | |||
| // for (TypedKVEntry kvDataEntry : kvDataEntries) { | |||
| // String valHexText = (String) kvDataEntry.getValue(); | |||
| // byte[] valBytes = HexUtils.decode(valHexText); | |||
| // String valText = new String(valBytes); | |||
| // System.out.println(valText); | |||
| // } | |||
| // } | |||
| // | |||
| // private static BlockchainKeypair testSDK_RegisterUser(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| // BlockchainService blockchainService, IntegratedContext context) { | |||
| // // 注册用户,并验证最终写入; | |||
| // BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); | |||
| // | |||
| // // 定义交易; | |||
| // TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| // txTpl.users().register(user.getIdentity()); | |||
| // | |||
| // // 签名; | |||
| // PreparedTransaction ptx = txTpl.prepare(); | |||
| // | |||
| // HashDigest transactionHash = ptx.getHash(); | |||
| // | |||
| // ptx.sign(adminKey); | |||
| // | |||
| // // 提交并等待共识返回; | |||
| // TransactionResponse txResp = ptx.commit(); | |||
| // | |||
| // // 验证结果; | |||
| // Node node0 = context.getNode(0); | |||
| // LedgerManage ledgerManager = new LedgerManager(); | |||
| // | |||
| // KVStorageService storageService = node0.getStorageDB().connect(memDbConnString).getStorageService(); | |||
| // | |||
| // LedgerQuery ledgerOfNode0 = ledgerManager.register(ledgerHash, storageService); | |||
| // | |||
| // return user; | |||
| // } | |||
| // | |||
| // private BlockchainKeypair testSDK_RegisterDataAccount(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| // BlockchainService blockchainService, IntegratedContext context) { | |||
| // // 注册数据账户,并验证最终写入; | |||
| // BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); | |||
| // | |||
| // // 定义交易; | |||
| // TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| // txTpl.dataAccounts().register(dataAccount.getIdentity()); | |||
| // | |||
| // // 签名; | |||
| // PreparedTransaction ptx = txTpl.prepare(); | |||
| // | |||
| // HashDigest transactionHash = ptx.getHash(); | |||
| // | |||
| // ptx.sign(adminKey); | |||
| // | |||
| // // 提交并等待共识返回; | |||
| // TransactionResponse txResp = ptx.commit(); | |||
| // | |||
| // // 验证结果; | |||
| // Node node0 = context.getNode(0); | |||
| // // LedgerRepository ledgerOfNode0 = | |||
| // // node0.getLedgerManager().getLedger(ledgerHash); | |||
| // LedgerManage ledgerManager = new LedgerManager(); | |||
| // | |||
| // KVStorageService storageService = node0.getStorageDB().connect(memDbConnString).getStorageService(); | |||
| // | |||
| // LedgerQuery ledgerOfNode0 = ledgerManager.register(ledgerHash, storageService); | |||
| // long latestBlockHeight = ledgerOfNode0.retrieveLatestBlockHeight(); | |||
| // | |||
| // return dataAccount; | |||
| // } | |||
| // | |||
| // private void testSDK_Query(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService, | |||
| // IntegratedContext context, BlockchainKeypair newUserAcount, BlockchainKeypair newDataAcount) { | |||
| // | |||
| // Bytes userAddress = newUserAcount.getAddress(); | |||
| // Bytes dataAddress = newDataAcount.getAddress(); | |||
| // | |||
| // Node node0 = context.getNode(0); | |||
| // // LedgerRepository ledgerOfNode0 = | |||
| // // node0.getLedgerManager().getLedger(ledgerHash); | |||
| // LedgerManage ledgerManager = new LedgerManager(); | |||
| // | |||
| // KVStorageService storageService = node0.getStorageDB().connect(memDbConnString).getStorageService(); | |||
| // | |||
| // LedgerQuery ledgerOfNode0 = ledgerManager.register(ledgerHash, storageService); | |||
| // | |||
| // // getLedgerHashs | |||
| // HashDigest[] ledgerHashs = blockchainService.getLedgerHashs(); | |||
| // for (HashDigest hashDigest : ledgerHashs) { | |||
| // if (hashDigest.equals(ledgerHash)) { | |||
| // break; | |||
| // } | |||
| // System.out.println("Query getLedgerHashs error! ledgerHash not exist!"); | |||
| // } | |||
| // | |||
| // // getLedger | |||
| // LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||
| // long ledgerHeight = ledgerInfo.getLatestBlockHeight(); | |||
| // | |||
| // // getConsensusParticipants | |||
| // ParticipantNode[] consensusParticipants = blockchainService.getConsensusParticipants(ledgerHash); | |||
| // for (int i = 0; i < 4; i++) { | |||
| // } | |||
| // | |||
| // // getBlock | |||
| // for (int i = 0; i < ledgerHeight + 1; i++) { | |||
| // LedgerBlock expectBlock = ledgerOfNode0.getBlock(i); | |||
| // } | |||
| // | |||
| // // getTransactionCount according to blockhash | |||
| // for (int i = 0; i < ledgerHeight + 1; i++) { | |||
| // LedgerBlock expectBlock = ledgerOfNode0.getBlock(i); | |||
| // long expectTransactionCount = ledgerOfNode0.getTransactionSet(expectBlock).getTotalCount(); | |||
| // long actualTransactionCount = blockchainService.getTransactionCount(ledgerHash, expectBlock.getHash()); | |||
| // } | |||
| // | |||
| // // getDataAccountCount according to blockhash | |||
| // for (int i = 0; i < ledgerHeight + 1; i++) { | |||
| // LedgerBlock expectBlock = ledgerOfNode0.getBlock(i); | |||
| // long expectDataCount = ledgerOfNode0.getDataAccountSet(expectBlock).getTotal(); | |||
| // long actualDataCount = blockchainService.getDataAccountCount(ledgerHash, expectBlock.getHash()); | |||
| // } | |||
| // | |||
| // // getUserCount according to blockhash | |||
| // for (int i = 0; i < ledgerHeight + 1; i++) { | |||
| // LedgerBlock expectBlock = ledgerOfNode0.getBlock(i); | |||
| // long expectUserCount = ledgerOfNode0.getUserAccountSet(expectBlock).getTotal(); | |||
| // long actualUserCount = blockchainService.getUserCount(ledgerHash, expectBlock.getHash()); | |||
| // } | |||
| // | |||
| // // getContractCount according to blockhash | |||
| // for (int i = 0; i < ledgerHeight + 1; i++) { | |||
| // LedgerBlock expectBlock = ledgerOfNode0.getBlock(i); | |||
| // long expectContractCount = ledgerOfNode0.getContractAccountSet(expectBlock).getTotal(); | |||
| // long actualContractCount = blockchainService.getContractCount(ledgerHash, expectBlock.getHash()); | |||
| // } | |||
| // | |||
| // // getTransactionCount according to height | |||
| // // getDataAccountCount according to height | |||
| // // getUserCount according to height | |||
| // // getContractCount according to height | |||
| // long expectTransactionTotal = 0; | |||
| // long expectUserTotal = 0; | |||
| // long expectDataTotal = 0; | |||
| // long expectContractTotal = 0; | |||
| // for (int i = 0; i < ledgerHeight + 1; i++) { | |||
| // // actual block acount total | |||
| // long transactionCount = blockchainService.getTransactionCount(ledgerHash, i); | |||
| // long userCount = blockchainService.getUserCount(ledgerHash, i); | |||
| // long dataCount = blockchainService.getDataAccountCount(ledgerHash, i); | |||
| // long contractCount = blockchainService.getContractCount(ledgerHash, i); | |||
| // | |||
| // // expect block acount total | |||
| // LedgerBlock ledgerBlock = ledgerOfNode0.getBlock(i); | |||
| // expectTransactionTotal = ledgerOfNode0.getTransactionSet(ledgerBlock).getTotalCount(); | |||
| // expectUserTotal = ledgerOfNode0.getUserAccountSet(ledgerBlock).getTotal(); | |||
| // expectDataTotal = ledgerOfNode0.getDataAccountSet(ledgerBlock).getTotal(); | |||
| // expectContractTotal = ledgerOfNode0.getContractAccountSet(ledgerBlock).getTotal(); | |||
| // } | |||
| // | |||
| // // getTransactionTotalCount | |||
| // long actualTransactionTotal = blockchainService.getTransactionTotalCount(ledgerHash); | |||
| // | |||
| // // getUserTotalCount | |||
| // long actualUserTotal = blockchainService.getUserTotalCount(ledgerHash); | |||
| // | |||
| // // getDataAccountTotalCount | |||
| // long actualDataAccountTotal = blockchainService.getDataAccountTotalCount(ledgerHash); | |||
| // | |||
| // // getContractTotalCount | |||
| // long actualContractAccountTotal = blockchainService.getContractTotalCount(ledgerHash); | |||
| // | |||
| // // getTransactions | |||
| // // getTransactionByContentHash | |||
| // // getTransactionStateByContentHash | |||
| // // ledger-core not implement | |||
| // // for (int i = 0; i < ledgerHeight + 1; i++) { | |||
| // // LedgerBlock ledgerBlock = ledgerOfNode0.getBlock(i); | |||
| // // HashDigest blockHash = ledgerBlock.getHash(); | |||
| // // long expectCount = | |||
| // // ledgerOfNode0.getTransactionSet(ledgerBlock).getTotalCount(); | |||
| // // long actualCount = blockchainService.getTransactionCount(ledgerHash, i); | |||
| // // LedgerTransaction[] ledgerTransactions1 = | |||
| // // blockchainService.getTransactions(ledgerHash, i, 0, (int)(actualCount - 1)); | |||
| // // LedgerTransaction[] ledgerTransactions2 = | |||
| // // blockchainService.getTransactions(ledgerHash, blockHash, 0, (int)(expectCount | |||
| // // - 1)); | |||
| // // assertEquals(ledgerTransactions1.length, ledgerTransactions2.length); | |||
| // // assertArrayEquals(ledgerTransactions1, ledgerTransactions2); | |||
| // // | |||
| // // for (LedgerTransaction ledgerTransaction : ledgerTransactions1) { | |||
| // // assertEquals(ledgerTransaction, | |||
| // // blockchainService.getTransactionByContentHash(ledgerHash, | |||
| // // ledgerTransaction.getTransactionContent().getHash())); | |||
| // // assertEquals(TransactionState.SUCCESS, | |||
| // // blockchainService.getTransactionStateByContentHash(ledgerHash, | |||
| // // ledgerTransaction.getTransactionContent().getHash())); | |||
| // // } | |||
| // // } | |||
| // // getUser | |||
| // UserInfo userInfo = blockchainService.getUser(ledgerHash, userAddress.toString()); | |||
| // | |||
| // // getDataAccount | |||
| // BlockchainIdentity accountHeader = blockchainService.getDataAccount(ledgerHash, dataAddress.toString()); | |||
| // | |||
| // // getDataEntries | |||
| // | |||
| // return; | |||
| // } | |||
| // | |||
| // public static ConsensusProvider getConsensusProvider() { | |||
| // return ConsensusProviders.getProvider("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"); | |||
| // } | |||
| // | |||
| // private static IntegratedContext initLedgers() { | |||
| // Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| // LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| // Properties props = LedgerInitializeWebTest.loadConsensusSetting(); | |||
| // ConsensusProvider csProvider = getConsensusProvider(); | |||
| // ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| // .getConsensusSettingsBuilder() | |||
| // .createSettings(props, Utils.loadParticipantNodes()); | |||
| // | |||
| // // 启动服务器; | |||
| // NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| // LedgerInitializeWebTest.NodeWebContext nodeCtx0 = new LedgerInitializeWebTest.NodeWebContext(0, initAddr0); | |||
| // | |||
| // NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| // LedgerInitializeWebTest.NodeWebContext nodeCtx1 = new LedgerInitializeWebTest.NodeWebContext(1, initAddr1); | |||
| // | |||
| // NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| // LedgerInitializeWebTest.NodeWebContext nodeCtx2 = new LedgerInitializeWebTest.NodeWebContext(2, initAddr2); | |||
| // | |||
| // NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| // LedgerInitializeWebTest.NodeWebContext nodeCtx3 = new LedgerInitializeWebTest.NodeWebContext(3, initAddr3); | |||
| // PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWebTest.PRIV_KEYS[0], | |||
| // LedgerInitializeWebTest.PASSWORD); | |||
| // PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWebTest.PRIV_KEYS[1], | |||
| // LedgerInitializeWebTest.PASSWORD); | |||
| // PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWebTest.PRIV_KEYS[2], | |||
| // LedgerInitializeWebTest.PASSWORD); | |||
| // PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWebTest.PRIV_KEYS[3], | |||
| // LedgerInitializeWebTest.PASSWORD); | |||
| // | |||
| // String encodedPassword = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWebTest.PASSWORD); | |||
| // | |||
| // CountDownLatch quitLatch = new CountDownLatch(4); | |||
| // | |||
| // DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| // testDb0.setConnectionUri("memory://local/0"); | |||
| // LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
| // AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, | |||
| // csProvider, testDb0, consolePrompter, bindingConfig0, quitLatch); | |||
| // | |||
| // DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| // testDb1.setConnectionUri("memory://local/1"); | |||
| // LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); | |||
| // AsyncCallback<HashDigest> callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, csProps, | |||
| // csProvider, testDb1, consolePrompter, bindingConfig1, quitLatch); | |||
| // | |||
| // DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| // testDb2.setConnectionUri("memory://local/2"); | |||
| // LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); | |||
| // AsyncCallback<HashDigest> callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, csProps, | |||
| // csProvider, testDb2, consolePrompter, bindingConfig2, quitLatch); | |||
| // | |||
| // DBConnectionConfig testDb3 = new DBConnectionConfig(); | |||
| // testDb3.setConnectionUri("memory://local/3"); | |||
| // LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); | |||
| // AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps, | |||
| // csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); | |||
| // | |||
| // HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| // HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| // HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| // HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| // | |||
| // LedgerQuery ledger0 = nodeCtx0.registLedger(ledgerHash0); | |||
| // LedgerQuery ledger1 = nodeCtx1.registLedger(ledgerHash1); | |||
| // LedgerQuery ledger2 = nodeCtx2.registLedger(ledgerHash2); | |||
| // LedgerQuery ledger3 = nodeCtx3.registLedger(ledgerHash3); | |||
| // | |||
| // IntegratedContext context = new IntegratedContext(); | |||
| // | |||
| // Node node0 = new Node(0); | |||
| // node0.setConsensusSettings(csProps); | |||
| // node0.setLedgerManager(nodeCtx0.getLedgerManager()); | |||
| // node0.setStorageDB(nodeCtx0.getStorageDB()); | |||
| // node0.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(0).getPubKey(), privkey0)); | |||
| // node0.setBindingConfig(bindingConfig0); | |||
| // context.addNode(node0); | |||
| // | |||
| // Node node1 = new Node(1); | |||
| // node1.setConsensusSettings(csProps); | |||
| // node1.setLedgerManager(nodeCtx1.getLedgerManager()); | |||
| // node1.setStorageDB(nodeCtx1.getStorageDB()); | |||
| // node1.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(1).getPubKey(), privkey1)); | |||
| // node1.setBindingConfig(bindingConfig1); | |||
| // context.addNode(node1); | |||
| // | |||
| // Node node2 = new Node(2); | |||
| // node2.setConsensusSettings(csProps); | |||
| // node2.setLedgerManager(nodeCtx2.getLedgerManager()); | |||
| // node2.setStorageDB(nodeCtx2.getStorageDB()); | |||
| // node2.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(2).getPubKey(), privkey2)); | |||
| // node2.setBindingConfig(bindingConfig2); | |||
| // context.addNode(node2); | |||
| // | |||
| // Node node3 = new Node(3); | |||
| // node3.setConsensusSettings(csProps); | |||
| // node3.setLedgerManager(nodeCtx3.getLedgerManager()); | |||
| // node3.setStorageDB(nodeCtx3.getStorageDB()); | |||
| // node3.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(3).getPubKey(), privkey3)); | |||
| // node3.setBindingConfig(bindingConfig3); | |||
| // context.addNode(node3); | |||
| // | |||
| // nodeCtx0.closeServer(); | |||
| // nodeCtx1.closeServer(); | |||
| // nodeCtx2.closeServer(); | |||
| // nodeCtx3.closeServer(); | |||
| // | |||
| // return context; | |||
| // } | |||
| // | |||
| // public static LedgerInitProperties loadInitSetting_integration() { | |||
| // ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_integration.init"); | |||
| // try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| // LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| // return setting; | |||
| // } catch (IOException e) { | |||
| // throw new IllegalStateException(e.getMessage(), e); | |||
| // } | |||
| // } | |||
| // | |||
| // private LedgerBlock testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| // BlockchainService blockchainService, IntegratedContext context) { | |||
| // // valid the basic data in contract; | |||
| // prepareContractData(adminKey, ledgerHash, blockchainService, context); | |||
| // | |||
| // BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| // | |||
| // // 定义交易; | |||
| // TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| // byte[] contractCode = getChainCodeBytes(); | |||
| // | |||
| // txTpl.users().register(userKey.getIdentity()); | |||
| // | |||
| // txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); | |||
| // | |||
| // // 签名; | |||
| // PreparedTransaction ptx = txTpl.prepare(); | |||
| // ptx.sign(adminKey); | |||
| // | |||
| // // 提交并等待共识返回; | |||
| // TransactionResponse txResp = ptx.commit(); | |||
| // | |||
| // // 验证结果; | |||
| // txResp.getContentHash(); | |||
| // | |||
| // Node node0 = context.getNode(0); | |||
| // LedgerQuery ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); | |||
| // LedgerBlock block = ledgerOfNode0.getBlock(txResp.getBlockHeight()); | |||
| // byte[] contractCodeInDb = ledgerOfNode0.getContractAccountSet(block).getAccount(contractDeployKey.getAddress()) | |||
| // .getChainCode(); | |||
| // txContentHash = ptx.getHash(); | |||
| // | |||
| // // execute the contract; | |||
| // testContractExe(adminKey, ledgerHash, userKey, blockchainService, context); | |||
| // | |||
| // return block; | |||
| // } | |||
| // | |||
| // private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, | |||
| // BlockchainService blockchainService, IntegratedContext context) { | |||
| // LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||
| // LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); | |||
| // | |||
| // // 定义交易; | |||
| // TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| // | |||
| //// txTpl.contractEvents().send(contractDeployKey.getAddress(), eventName, | |||
| //// ("888##abc##" + contractDataKey.getAddress() + "##" + previousBlock.getHash().toBase58() + "##" | |||
| //// + userKey.getAddress() + "##" + contractDeployKey.getAddress() + "##" + txContentHash.toBase58() | |||
| //// + "##SOME-VALUE").getBytes()); | |||
| // | |||
| // // 签名; | |||
| // PreparedTransaction ptx = txTpl.prepare(); | |||
| // ptx.sign(adminKey); | |||
| // | |||
| // // 提交并等待共识返回; | |||
| // TransactionResponse txResp = ptx.commit(); | |||
| // | |||
| // // 验证结果; | |||
| // txResp.getContentHash(); | |||
| // | |||
| // LedgerInfo latestLedgerInfo = blockchainService.getLedger(ledgerHash); | |||
| // | |||
| // Node node0 = context.getNode(0); | |||
| // LedgerQuery ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); | |||
| // LedgerBlock backgroundLedgerBlock = ledgerOfNode0.retrieveLatestBlock(); | |||
| // | |||
| // // 验证合约中的赋值,外部可以获得; | |||
| // DataAccountQuery dataAccountSet = ledgerOfNode0.getDataAccountSet(backgroundLedgerBlock); | |||
| // AsymmetricKeypair key = Crypto.getSignatureFunction("ED25519").generateKeypair(); | |||
| // PubKey pubKey = key.getPubKey(); | |||
| // Bytes dataAddress = AddressEncoding.generateAddress(pubKey); | |||
| // | |||
| // // 验证userAccount,从合约内部赋值,然后外部验证;由于目前不允许输入重复的key,所以在内部合约中构建的key,不便于在外展示,屏蔽之; | |||
| // // UserAccountSet userAccountSet = | |||
| // // ledgerOfNode0.getUserAccountSet(backgroundLedgerBlock); | |||
| // // PubKey userPubKey = new PubKey(CryptoAlgorithm.ED25519, | |||
| // // userPubKeyVal.getBytes()); | |||
| // // String userAddress = AddressEncoding.generateAddress(userPubKey); | |||
| // // assertEquals(userAddress, userAccountSet.getUser(userAddress).getAddress()); | |||
| // } | |||
| // | |||
| // private void prepareContractData(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService, | |||
| // IntegratedContext context) { | |||
| // | |||
| // // 定义交易; | |||
| // TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| // // 注册数据账户,并验证最终写入; | |||
| // txTpl.dataAccounts().register(contractDataKey.getIdentity()); | |||
| // DataAccountKVSetOperation kvsetOP = txTpl.dataAccount(contractDataKey.getAddress()) | |||
| // .setText("A", "Value_A_0", -1).setText("B", "Value_B_0", -1) | |||
| // .setText(KEY_TOTAL, "total value,dataAccount", -1) | |||
| // .setText(KEY_ABC, "abc value,dataAccount", -1) | |||
| // // 所有的模拟数据都在这个dataAccount中填充; | |||
| // .setBytes("ledgerHash", ledgerHash.getRawDigest(), -1).getOperation(); | |||
| // | |||
| // // 签名; | |||
| // PreparedTransaction ptx = txTpl.prepare(); | |||
| // ptx.sign(adminKey); | |||
| // | |||
| // // 提交并等待共识返回; | |||
| // TransactionResponse txResp = ptx.commit(); | |||
| // | |||
| // // 验证结果; | |||
| // Node node0 = context.getNode(0); | |||
| // | |||
| // LedgerQuery ledgerOfNode0 = node0.getLedgerManager().getLedger(ledgerHash); | |||
| // LedgerBlock block = ledgerOfNode0.getBlock(txResp.getBlockHeight()); | |||
| // BytesValue val1InDb = ledgerOfNode0.getDataAccountSet(block).getAccount(contractDataKey.getAddress()) | |||
| // .getDataset().getValue("A"); | |||
| // BytesValue val2InDb = ledgerOfNode0.getDataAccountSet(block).getAccount(contractDataKey.getAddress()) | |||
| // .getDataset().getValue(KEY_TOTAL); | |||
| // } | |||
| // | |||
| // /** | |||
| // * 根据合约构建字节数组; | |||
| // * | |||
| // * @return | |||
| // */ | |||
| // private byte[] getChainCodeBytes() { | |||
| // // 构建合约的字节数组; | |||
| // byte[] contractCode = null; | |||
| // File file = null; | |||
| // InputStream input = null; | |||
| // try { | |||
| // ClassPathResource contractPath = new ClassPathResource(contractZipName); | |||
| // file = new File(contractPath.getURI()); | |||
| // input = new FileInputStream(file); | |||
| // // 这种暴力的读取压缩包,在class解析时有问题,所有需要改进; | |||
| // contractCode = new byte[input.available()]; | |||
| // input.read(contractCode); | |||
| // } catch (IOException e) { | |||
| // e.printStackTrace(); | |||
| // } finally { | |||
| // try { | |||
| // if (input != null) { | |||
| // input.close(); | |||
| // } | |||
| // } catch (IOException e) { | |||
| // e.printStackTrace(); | |||
| // } | |||
| // } | |||
| // return contractCode; | |||
| // } | |||
| //} | |||
| @@ -1,97 +0,0 @@ | |||
| /** | |||
| * Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
| * FileName: test.com.jd.blockchain.intgr.LedgerInitConsensusConfig | |||
| * Author: shaozhuguang | |||
| * Department: 区块链研发部 | |||
| * Date: 2018/12/21 下午5:52 | |||
| * Description: | |||
| */ | |||
| package test.com.jd.blockchain.intgr; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import test.com.jd.blockchain.intgr.perf.LedgerPerformanceTest; | |||
| import java.io.File; | |||
| /** | |||
| * | |||
| * @author shaozhuguang | |||
| * @create 2018/12/21 | |||
| * @since 1.0.0 | |||
| */ | |||
| public class LedgerInitConsensusConfig { | |||
| public static ConsensusConfig mqConfig = new ConsensusConfig(); | |||
| public static ConsensusConfig bftsmartConfig = new ConsensusConfig(); | |||
| public static String[] redisConnectionStrings = new String[4]; | |||
| public static String[] memConnectionStrings = new String[4]; | |||
| public static String[] rocksdbConnectionStrings = new String[4]; | |||
| public static String[] rocksdbDirStrings = new String[4]; | |||
| public static String[] mqProvider = new String[1]; | |||
| public static String[] bftsmartProvider = new String[1]; | |||
| public static String[] mqAndbftsmartProvider = new String[2]; | |||
| static { | |||
| mqConfig.provider = "com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider"; | |||
| mqConfig.configPath = "mq.config"; | |||
| bftsmartConfig.provider = "com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"; | |||
| bftsmartConfig.configPath = "bftsmart.config"; | |||
| // for (int i = 0; i < redisConnectionStrings.length; i++) { | |||
| // redisConnectionStrings[i] = "redis://127.0.0.1:6379/" + i; | |||
| // } | |||
| redisConnectionStrings[0] = "redis://192.168.54.112:6379"; | |||
| redisConnectionStrings[1] = "redis://192.168.54.112:6379/1"; | |||
| redisConnectionStrings[2] = "redis://192.168.54.112:6379/2"; | |||
| redisConnectionStrings[3] = "redis://192.168.54.112:6379/3"; | |||
| for (int i = 0; i < memConnectionStrings.length; i++) { | |||
| memConnectionStrings[i] = "memory://local/" + i; | |||
| } | |||
| mqProvider[0] = mqConfig.provider; | |||
| bftsmartProvider[0] = bftsmartConfig.provider; | |||
| mqAndbftsmartProvider[0] = mqConfig.provider; | |||
| mqAndbftsmartProvider[1] = bftsmartConfig.provider; | |||
| for (int i = 0; i < rocksdbConnectionStrings.length; i++) { | |||
| String currDir = FileUtils.getCurrentDir() + File.separator + "rocks.db"; | |||
| String dbDir = new File(currDir, "rocksdb" + i + ".db").getAbsolutePath(); | |||
| rocksdbDirStrings[i] = dbDir; | |||
| rocksdbConnectionStrings[i] = "rocksdb://" + dbDir; | |||
| } | |||
| } | |||
| public static ConsensusProvider getConsensusProvider(String providerName) { | |||
| return ConsensusProviders.getProvider(providerName); | |||
| } | |||
| public static class ConsensusConfig { | |||
| String provider; | |||
| String configPath; | |||
| public String getProvider() { | |||
| return provider; | |||
| } | |||
| public String getConfigPath() { | |||
| return configPath; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,63 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.peer.PeerServerBooter; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| public class PeerTestRunner { | |||
| private NetworkAddress serviceAddress; | |||
| private volatile PeerServerBooter peerServer; | |||
| private LedgerBindingConfig ledgerBindingConfig; | |||
| public DbConnectionFactory getDBConnectionFactory() { | |||
| return peerServer.getDBConnectionFactory(); | |||
| } | |||
| public NetworkAddress getServiceAddress() { | |||
| return serviceAddress; | |||
| } | |||
| public LedgerBindingConfig getLedgerBindingConfig() { | |||
| return ledgerBindingConfig; | |||
| } | |||
| public PeerTestRunner(NetworkAddress serviceAddress, LedgerBindingConfig ledgerBindingConfig) { | |||
| this(serviceAddress, ledgerBindingConfig, null, null); | |||
| } | |||
| public PeerTestRunner(NetworkAddress serviceAddress, LedgerBindingConfig ledgerBindingConfig, | |||
| DbConnectionFactory dbConnectionFactory, LedgerManager ledgerManager) { | |||
| this.serviceAddress = serviceAddress; | |||
| this.ledgerBindingConfig = ledgerBindingConfig; | |||
| if (dbConnectionFactory == null) { | |||
| this.peerServer = new PeerServerBooter(ledgerBindingConfig, serviceAddress.getHost(), serviceAddress.getPort(),null); | |||
| }else { | |||
| this.peerServer = new PeerServerBooter(ledgerBindingConfig, serviceAddress.getHost(), serviceAddress.getPort(),null, | |||
| dbConnectionFactory, ledgerManager); | |||
| } | |||
| } | |||
| public AsyncCallback<Object> start() { | |||
| ThreadInvoker<Object> invoker = new ThreadInvoker<Object>() { | |||
| @Override | |||
| protected Object invoke() throws Exception { | |||
| peerServer.start(); | |||
| return null; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public void stop() { | |||
| peerServer.close(); | |||
| } | |||
| } | |||
| @@ -1,33 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import java.util.Properties; | |||
| import com.jd.blockchain.tools.initializer.ConsolePrompter; | |||
| public class PresetAnswerPrompter extends ConsolePrompter { | |||
| private Properties answers = new Properties(); | |||
| private String defaultAnswer; | |||
| public PresetAnswerPrompter(String defaultAnswer) { | |||
| this.defaultAnswer = defaultAnswer; | |||
| } | |||
| public void setAnswer(String tag, String answer) { | |||
| answers.setProperty(tag, answer); | |||
| } | |||
| public void setDefaultAnswer(String defaultAnswer) { | |||
| this.defaultAnswer = defaultAnswer; | |||
| } | |||
| @Override | |||
| public String confirm(String tag, String format, Object... args) { | |||
| System.out.print(String.format(format, args)); | |||
| String answer = answers.getProperty(tag, defaultAnswer); | |||
| System.out.println(String.format("\r\n [Mocked answer:%s]", answer)); | |||
| return answer; | |||
| } | |||
| } | |||
| @@ -1,463 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.consensus; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.CyclicBarrier; | |||
| import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.context.ConfigurableApplicationContext; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.SignatureDigest; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.PreparedTransaction; | |||
| import com.jd.blockchain.ledger.TransactionContent; | |||
| import com.jd.blockchain.ledger.TransactionTemplate; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| //import com.jd.blockchain.storage.service.utils.MemoryBasedDb; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitCommand; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.ConsoleUtils; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.GatewayTestRunner; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.PeerTestRunner; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| import test.com.jd.blockchain.intgr.perf.LedgerInitTestConfiguration; | |||
| import test.com.jd.blockchain.intgr.perf.TransactionCommitter; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class ConsensusTest { | |||
| public static final int CONCURRENT_USER_COUNT = 2; | |||
| public static final int USER_TX_COUNT = 1; | |||
| public static void main_(String[] args) { | |||
| // init ledgers of all nodes ; | |||
| IntegratedContext context = initLedgers(); | |||
| Node node0 = context.getNode(0); | |||
| Node node1 = context.getNode(1); | |||
| Node node2 = context.getNode(2); | |||
| Node node3 = context.getNode(3); | |||
| NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 10200); | |||
| PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, node0.getBindingConfig(), node0.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 10210); | |||
| PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, node1.getBindingConfig(), node1.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 10220); | |||
| PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, node2.getBindingConfig(), node2.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 10230); | |||
| PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, node3.getBindingConfig(), node3.getStorageDB(), null); | |||
| AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
| AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
| AsyncCallback<Object> peerStarting2 = peer2.start(); | |||
| AsyncCallback<Object> peerStarting3 = peer3.start(); | |||
| peerStarting0.waitReturn(); | |||
| peerStarting1.waitReturn(); | |||
| peerStarting2.waitReturn(); | |||
| peerStarting3.waitReturn(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(Utils.PASSWORD); | |||
| KeyPairConfig gwkey0 = new KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(Utils.PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(Utils.PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway0 = new GatewayTestRunner("127.0.0.1", 10300, gwkey0, peerSrvAddr0); | |||
| KeyPairConfig gwkey1 = new KeyPairConfig(); | |||
| gwkey1.setPubKeyValue(Utils.PUB_KEYS[1]); | |||
| gwkey1.setPrivKeyValue(Utils.PRIV_KEYS[1]); | |||
| gwkey1.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway1 = new GatewayTestRunner("127.0.0.1", 10310, gwkey1, peerSrvAddr1); | |||
| AsyncCallback<Object> gwStarting0 = gateway0.start(); | |||
| AsyncCallback<Object> gwStarting1 = gateway1.start(); | |||
| gwStarting0.waitReturn(); | |||
| gwStarting1.waitReturn(); | |||
| // 连接网关; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway0.getServiceAddress()); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| int batchSize = CONCURRENT_USER_COUNT * USER_TX_COUNT; | |||
| BlockchainKeypair[] keys = generateKeys(batchSize); | |||
| HashDigest ledgerHash = node0.getLedgerManager().getLedgerHashs()[0]; | |||
| LedgerQuery ledger = node0.getLedgerManager().getLedger(ledgerHash); | |||
| PreparedTransaction[] ptxs = prepareTransactions_RegisterDataAcount(keys, node0.getPartiKeyPair(), ledgerHash, | |||
| blockchainService); | |||
| LedgerBlock latestBlock = ledger.getLatestBlock(); | |||
| ConsoleUtils.info("\r\n-----------------------------------------------"); | |||
| ConsoleUtils.info("------ 开始执行交易 [当前区块高度=%s] ------", latestBlock.getHeight()); | |||
| ConsoleUtils.info("-----------------------------------------------\r\n"); | |||
| long startTs = System.currentTimeMillis(); | |||
| // for (PreparedTransaction ptx : ptxs) { | |||
| // ptx.commit(); | |||
| // } | |||
| CyclicBarrier barrier = new CyclicBarrier(CONCURRENT_USER_COUNT); | |||
| CountDownLatch latch = new CountDownLatch(CONCURRENT_USER_COUNT); | |||
| for (int i = 0; i < CONCURRENT_USER_COUNT; i++) { | |||
| TransactionCommitter committer = new TransactionCommitter(ptxs, i * USER_TX_COUNT, USER_TX_COUNT); | |||
| committer.start(barrier, latch); | |||
| } | |||
| try { | |||
| latch.await(); | |||
| } catch (InterruptedException e) { | |||
| ConsoleUtils.error("Error occurred on waiting accomplishing all tx committing. --%s", e.getMessage()); | |||
| } | |||
| long elapsedTs = System.currentTimeMillis() - startTs; | |||
| latestBlock = ledger.retrieveLatestBlock(); | |||
| ConsoleUtils.info("全部交易执行完成! -- 当前区块高度=%s; 交易数=%s; 总耗时= %s ms; TPS=%.2f", latestBlock.getHeight(), batchSize, | |||
| elapsedTs, (batchSize * 1000.00D / elapsedTs)); | |||
| } | |||
| private static BlockchainKeypair[] generateKeys(int count) { | |||
| BlockchainKeypair[] keys = new BlockchainKeypair[count]; | |||
| for (int i = 0; i < count; i++) { | |||
| keys[i] = BlockchainKeyGenerator.getInstance().generate(); | |||
| } | |||
| return keys; | |||
| } | |||
| private static PreparedTransaction[] prepareTransactions_RegisterDataAcount(BlockchainKeypair[] userKeys, | |||
| AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService) { | |||
| PreparedTransaction[] ptxs = new PreparedTransaction[userKeys.length]; | |||
| for (int i = 0; i < ptxs.length; i++) { | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.users().register(userKeys[i].getIdentity()); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| ptxs[i] = ptx; | |||
| } | |||
| return ptxs; | |||
| } | |||
| public static ConsensusProvider getConsensusProvider() { | |||
| return ConsensusProviders.getProvider("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"); | |||
| } | |||
| private static IntegratedContext initLedgers() { | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = Utils.loadConsensusSetting(); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeInitContext nodeCtx0 = new NodeInitContext(0, initAddr0); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeInitContext nodeCtx1 = new NodeInitContext(1, initAddr1); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeInitContext nodeCtx2 = new NodeInitContext(2, initAddr2); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeInitContext nodeCtx3 = new NodeInitContext(3, initAddr3); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[0], Utils.PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[1], Utils.PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[2], Utils.PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[3], Utils.PASSWORD); | |||
| String encodedPassword = KeyGenUtils.encodePasswordAsBase58(Utils.PASSWORD); | |||
| CountDownLatch quitLatch = new CountDownLatch(4); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri("memory://local/0"); | |||
| LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, | |||
| csProvider, testDb0, consolePrompter, bindingConfig0, quitLatch); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri("memory://local/1"); | |||
| LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, csProps, | |||
| csProvider, testDb1, consolePrompter, bindingConfig1, quitLatch); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri("memory://local/2"); | |||
| LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, csProps, | |||
| csProvider, testDb2, consolePrompter, bindingConfig2, quitLatch); | |||
| DBConnectionConfig testDb3 = new DBConnectionConfig(); | |||
| testDb3.setConnectionUri("memory://local/3"); | |||
| LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps, | |||
| csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| nodeCtx0.registLedger(ledgerHash0); | |||
| nodeCtx1.registLedger(ledgerHash1); | |||
| nodeCtx2.registLedger(ledgerHash2); | |||
| nodeCtx3.registLedger(ledgerHash3); | |||
| IntegratedContext context = new IntegratedContext(); | |||
| Node node0 = new Node(0); | |||
| node0.setConsensusSettings(csProps); | |||
| node0.setLedgerManager(nodeCtx0.getLedgerManager()); | |||
| node0.setStorageDB(nodeCtx0.getStorageDB()); | |||
| node0.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(0).getPubKey(), privkey0)); | |||
| node0.setBindingConfig(bindingConfig0); | |||
| context.addNode(node0); | |||
| Node node1 = new Node(1); | |||
| node1.setConsensusSettings(csProps); | |||
| node1.setLedgerManager(nodeCtx1.getLedgerManager()); | |||
| node1.setStorageDB(nodeCtx1.getStorageDB()); | |||
| node1.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(1).getPubKey(), privkey1)); | |||
| node1.setBindingConfig(bindingConfig1); | |||
| context.addNode(node1); | |||
| Node node2 = new Node(2); | |||
| node2.setConsensusSettings(csProps); | |||
| node2.setLedgerManager(nodeCtx2.getLedgerManager()); | |||
| node2.setStorageDB(nodeCtx2.getStorageDB()); | |||
| node2.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(2).getPubKey(), privkey2)); | |||
| node2.setBindingConfig(bindingConfig2); | |||
| context.addNode(node2); | |||
| Node node3 = new Node(3); | |||
| node3.setConsensusSettings(csProps); | |||
| node3.setLedgerManager(nodeCtx3.getLedgerManager()); | |||
| node3.setStorageDB(nodeCtx3.getStorageDB()); | |||
| node3.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(3).getPubKey(), privkey3)); | |||
| node3.setBindingConfig(bindingConfig3); | |||
| context.addNode(node3); | |||
| nodeCtx0.closeServer(); | |||
| nodeCtx1.closeServer(); | |||
| nodeCtx2.closeServer(); | |||
| nodeCtx3.closeServer(); | |||
| return context; | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_integration() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_integration.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| private static class NodeInitContext { | |||
| private NetworkAddress serverAddress; | |||
| private DBConnectionConfig dbConnConfig; | |||
| private volatile ConfigurableApplicationContext ctx; | |||
| private volatile LedgerInitProcess initProcess; | |||
| private volatile LedgerInitializeWebController controller; | |||
| private volatile LedgerManager ledgerManager; | |||
| private volatile CompositeConnectionFactory db; | |||
| private int id; | |||
| public int getId() { | |||
| return controller.getId(); | |||
| } | |||
| public TransactionContent getInitTxContent() { | |||
| return controller.getInitTxContent(); | |||
| } | |||
| public LedgerInitProposal getLocalPermission() { | |||
| return controller.getLocalPermission(); | |||
| } | |||
| public LedgerInitDecision getLocalDecision() { | |||
| return controller.getLocalDecision(); | |||
| } | |||
| public NodeInitContext(int id, NetworkAddress serverAddress) { | |||
| this.id = id; | |||
| this.serverAddress = serverAddress; | |||
| } | |||
| public LedgerQuery registLedger(HashDigest ledgerHash) { | |||
| // LedgerManage ledgerManager = ctx.getBean(LedgerManage.class); | |||
| // | |||
| // DbConnectionFactory dbConnFactory = ctx.getBean(DbConnectionFactory.class); | |||
| // DbConnection conn = dbConnFactory.connect(dbConnConfig.getUri(), | |||
| // dbConnConfig.getPassword()); | |||
| DbConnection conn = db.connect(dbConnConfig.getUri(), dbConnConfig.getPassword()); | |||
| LedgerQuery ledgerRepo = ledgerManager.register(ledgerHash, conn.getStorageService()); | |||
| return ledgerRepo; | |||
| } | |||
| public SignatureDigest createPermissionRequestSignature(int requesterId, PrivKey privKey) { | |||
| return controller.signPermissionRequest(requesterId, privKey); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
| Prompter prompter, CountDownLatch quitLatch) { | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| doStartServer(); | |||
| // NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| NodeInitContext.this.dbConnConfig = dbConnConfig; | |||
| HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, | |||
| dbConnConfig, prompter); | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public AsyncCallback<HashDigest> startInitCommand(PrivKey privKey, String base58Pwd, | |||
| LedgerInitProperties ledgerSetting, ConsensusSettings csProps, ConsensusProvider csProvider, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, LedgerBindingConfig conf, | |||
| CountDownLatch quitLatch) { | |||
| this.db = new CompositeConnectionFactory(); | |||
| this.dbConnConfig = dbConnConfig; | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| LedgerInitCommand initCmd = new LedgerInitCommand(); | |||
| HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, prompter, conf, db); | |||
| NodeInitContext.this.ledgerManager = initCmd.getLedgerManager(); | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitProperties initProps) { | |||
| return controller.prepareLocalPermission(id, privKey, initProps); | |||
| } | |||
| public boolean consensusPermission(PrivKey privKey) { | |||
| return controller.consensusPermisions(privKey); | |||
| } | |||
| public LedgerInitDecision prepareLedger(DBConnectionConfig dbConnConfig, PrivKey privKey) { | |||
| controller.connectDb(dbConnConfig); | |||
| return controller.makeLocalDecision(privKey); | |||
| } | |||
| public void startServer() { | |||
| ThreadInvoker<Object> invoker = new ThreadInvoker<Object>() { | |||
| @Override | |||
| protected Object invoke() throws Exception { | |||
| doStartServer(); | |||
| return null; | |||
| } | |||
| }; | |||
| invoker.startAndWait(); | |||
| } | |||
| public void setPrompter(Prompter prompter) { | |||
| controller.setPrompter(prompter); | |||
| } | |||
| public void doStartServer() { | |||
| String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); | |||
| String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); | |||
| String nodebug = "--debug=false"; | |||
| String[] innerArgs = { argServerAddress, argServerPort, nodebug }; | |||
| ctx = SpringApplication.run(LedgerInitTestConfiguration.class, innerArgs); | |||
| ctx.setId("Node-" + id); | |||
| controller = ctx.getBean(LedgerInitializeWebController.class); | |||
| ledgerManager = ctx.getBean(LedgerManager.class); | |||
| db = ctx.getBean(CompositeConnectionFactory.class); | |||
| initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| } | |||
| public void closeServer() { | |||
| if (this.ctx != null) { | |||
| this.ctx.close(); | |||
| this.ctx = null; | |||
| } | |||
| } | |||
| public LedgerManager getLedgerManager() { | |||
| return ledgerManager; | |||
| // return ctx.getBean(LedgerManager.class); | |||
| } | |||
| public CompositeConnectionFactory getStorageDB() { | |||
| return db; | |||
| // return ctx.getBean(MemoryBasedDb.class); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,11 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| public enum DBType { | |||
| DEFAULT, | |||
| REDIS, | |||
| ROCKSDB | |||
| } | |||
| @@ -1,475 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.CyclicBarrier; | |||
| import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.context.ConfigurableApplicationContext; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.SignatureDigest; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.PreparedTransaction; | |||
| import com.jd.blockchain.ledger.TransactionContent; | |||
| import com.jd.blockchain.ledger.TransactionTemplate; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitCommand; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.ConsoleUtils; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.GatewayTestRunner; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.PeerTestRunner; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| public class GlobalPerformanceTest { | |||
| public static final int CONCURRENT_USER_COUNT = 1; | |||
| public static final int USER_TX_COUNT = 1; | |||
| public static void test(String[] args) { | |||
| // init ledgers of all nodes ; | |||
| IntegratedContext context = initLedgers(); | |||
| Node node0 = context.getNode(0); | |||
| Node node1 = context.getNode(1); | |||
| Node node2 = context.getNode(2); | |||
| Node node3 = context.getNode(3); | |||
| NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 10200); | |||
| PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, node0.getBindingConfig(), node0.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 10210); | |||
| PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, node1.getBindingConfig(), node1.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 10220); | |||
| PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, node2.getBindingConfig(), node2.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 10230); | |||
| PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, node3.getBindingConfig(), node3.getStorageDB(), null); | |||
| AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
| AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
| AsyncCallback<Object> peerStarting2 = peer2.start(); | |||
| AsyncCallback<Object> peerStarting3 = peer3.start(); | |||
| peerStarting0.waitReturn(); | |||
| peerStarting1.waitReturn(); | |||
| peerStarting2.waitReturn(); | |||
| peerStarting3.waitReturn(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(Utils.PASSWORD); | |||
| KeyPairConfig gwkey0 = new KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(Utils.PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(Utils.PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway0 = new GatewayTestRunner("127.0.0.1", 10300, gwkey0, peerSrvAddr0); | |||
| KeyPairConfig gwkey1 = new KeyPairConfig(); | |||
| gwkey1.setPubKeyValue(Utils.PUB_KEYS[1]); | |||
| gwkey1.setPrivKeyValue(Utils.PRIV_KEYS[1]); | |||
| gwkey1.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway1 = new GatewayTestRunner("127.0.0.1", 10310, gwkey1, peerSrvAddr1); | |||
| AsyncCallback<Object> gwStarting0 = gateway0.start(); | |||
| AsyncCallback<Object> gwStarting1 = gateway1.start(); | |||
| gwStarting0.waitReturn(); | |||
| gwStarting1.waitReturn(); | |||
| // 连接网关; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway0.getServiceAddress()); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| int batchSize = CONCURRENT_USER_COUNT * USER_TX_COUNT; | |||
| BlockchainKeypair[] keys = generateKeys(batchSize); | |||
| HashDigest ledgerHash = node0.getLedgerManager().getLedgerHashs()[0]; | |||
| LedgerQuery ledger = node0.getLedgerManager().getLedger(ledgerHash); | |||
| PreparedTransaction[] ptxs = prepareTransactions_RegisterDataAcount(keys, node0.getPartiKeyPair(), ledgerHash, | |||
| blockchainService); | |||
| LedgerBlock latestBlock = ledger.getLatestBlock(); | |||
| ConsoleUtils.info("\r\n-----------------------------------------------"); | |||
| ConsoleUtils.info("------ 开始执行交易 [当前区块高度=%s] ------", latestBlock.getHeight()); | |||
| ConsoleUtils.info("-----------------------------------------------\r\n"); | |||
| long startTs = System.currentTimeMillis(); | |||
| // for (PreparedTransaction ptx : ptxs) { | |||
| // ptx.commit(); | |||
| // } | |||
| CyclicBarrier barrier = new CyclicBarrier(CONCURRENT_USER_COUNT); | |||
| CountDownLatch latch = new CountDownLatch(CONCURRENT_USER_COUNT); | |||
| for (int i = 0; i < CONCURRENT_USER_COUNT; i++) { | |||
| TransactionCommitter committer = new TransactionCommitter(ptxs, i * USER_TX_COUNT, USER_TX_COUNT); | |||
| committer.start(barrier, latch); | |||
| } | |||
| try { | |||
| latch.await(); | |||
| } catch (InterruptedException e) { | |||
| ConsoleUtils.error("Error occurred on waiting accomplishing all tx committing. --%s", e.getMessage()); | |||
| } | |||
| long elapsedTs = System.currentTimeMillis() - startTs; | |||
| latestBlock = ledger.retrieveLatestBlock(); | |||
| ConsoleUtils.info("全部交易执行完成! -- 当前区块高度=%s; 交易数=%s; 总耗时= %s ms; TPS=%.2f", latestBlock.getHeight(), batchSize, | |||
| elapsedTs, (batchSize * 1000.00D / elapsedTs)); | |||
| } | |||
| private static BlockchainKeypair[] generateKeys(int count) { | |||
| BlockchainKeypair[] keys = new BlockchainKeypair[count]; | |||
| for (int i = 0; i < count; i++) { | |||
| keys[i] = BlockchainKeyGenerator.getInstance().generate(); | |||
| } | |||
| return keys; | |||
| } | |||
| private static PreparedTransaction[] prepareTransactions_RegisterDataAcount(BlockchainKeypair[] userKeys, | |||
| AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService) { | |||
| PreparedTransaction[] ptxs = new PreparedTransaction[userKeys.length]; | |||
| for (int i = 0; i < ptxs.length; i++) { | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.users().register(userKeys[i].getIdentity()); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| ptxs[i] = ptx; | |||
| } | |||
| return ptxs; | |||
| } | |||
| public static ConsensusProvider getConsensusProvider() { | |||
| return ConsensusProviders.getProvider("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"); | |||
| } | |||
| private static IntegratedContext initLedgers() { | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = Utils.loadConsensusSetting(); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props, | |||
| Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeInitContext nodeCtx0 = new NodeInitContext(0, initAddr0); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeInitContext nodeCtx1 = new NodeInitContext(1, initAddr1); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeInitContext nodeCtx2 = new NodeInitContext(2, initAddr2); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeInitContext nodeCtx3 = new NodeInitContext(3, initAddr3); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[0], Utils.PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[1], Utils.PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[2], Utils.PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[3], Utils.PASSWORD); | |||
| String encodedPassword = KeyGenUtils.encodePasswordAsBase58(Utils.PASSWORD); | |||
| CountDownLatch quitLatch = new CountDownLatch(4); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri("memory://local/0"); | |||
| LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, | |||
| csProvider, testDb0, consolePrompter, bindingConfig0, quitLatch); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri("memory://local/1"); | |||
| LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, csProps, | |||
| csProvider, testDb1, consolePrompter, bindingConfig1, quitLatch); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri("memory://local/2"); | |||
| LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, csProps, | |||
| csProvider, testDb2, consolePrompter, bindingConfig2, quitLatch); | |||
| DBConnectionConfig testDb3 = new DBConnectionConfig(); | |||
| testDb3.setConnectionUri("memory://local/3"); | |||
| LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps, | |||
| csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| nodeCtx0.registLedger(ledgerHash0); | |||
| nodeCtx1.registLedger(ledgerHash1); | |||
| nodeCtx2.registLedger(ledgerHash2); | |||
| nodeCtx3.registLedger(ledgerHash3); | |||
| IntegratedContext context = new IntegratedContext(); | |||
| Node node0 = new Node(0); | |||
| node0.setConsensusSettings(csProps); | |||
| node0.setLedgerManager(nodeCtx0.getLedgerManager()); | |||
| node0.setStorageDB(nodeCtx0.getStorageDB()); | |||
| node0.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(0).getPubKey(), privkey0)); | |||
| node0.setBindingConfig(bindingConfig0); | |||
| context.addNode(node0); | |||
| Node node1 = new Node(1); | |||
| node1.setConsensusSettings(csProps); | |||
| node1.setLedgerManager(nodeCtx1.getLedgerManager()); | |||
| node1.setStorageDB(nodeCtx1.getStorageDB()); | |||
| node1.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(1).getPubKey(), privkey1)); | |||
| node1.setBindingConfig(bindingConfig1); | |||
| context.addNode(node1); | |||
| Node node2 = new Node(2); | |||
| node2.setConsensusSettings(csProps); | |||
| node2.setLedgerManager(nodeCtx2.getLedgerManager()); | |||
| node2.setStorageDB(nodeCtx2.getStorageDB()); | |||
| node2.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(2).getPubKey(), privkey2)); | |||
| node2.setBindingConfig(bindingConfig2); | |||
| context.addNode(node2); | |||
| Node node3 = new Node(3); | |||
| node3.setConsensusSettings(csProps); | |||
| node3.setLedgerManager(nodeCtx3.getLedgerManager()); | |||
| node3.setStorageDB(nodeCtx3.getStorageDB()); | |||
| node3.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(3).getPubKey(), privkey3)); | |||
| node3.setBindingConfig(bindingConfig3); | |||
| context.addNode(node3); | |||
| nodeCtx0.closeServer(); | |||
| nodeCtx1.closeServer(); | |||
| nodeCtx2.closeServer(); | |||
| nodeCtx3.closeServer(); | |||
| return context; | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_integration() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_integration.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| private static class NodeInitContext { | |||
| private NetworkAddress serverAddress; | |||
| private DBConnectionConfig dbConnConfig; | |||
| private volatile ConfigurableApplicationContext ctx; | |||
| private volatile LedgerInitProcess initProcess; | |||
| private volatile LedgerInitializeWebController controller; | |||
| private volatile LedgerManager ledgerManager; | |||
| private volatile CompositeConnectionFactory db; | |||
| private List<DbConnection> conns = new ArrayList<>(); | |||
| private int id; | |||
| public int getId() { | |||
| return controller.getId(); | |||
| } | |||
| public TransactionContent getInitTxContent() { | |||
| return controller.getInitTxContent(); | |||
| } | |||
| public LedgerInitProposal getLocalPermission() { | |||
| return controller.getLocalPermission(); | |||
| } | |||
| public LedgerInitDecision getLocalDecision() { | |||
| return controller.getLocalDecision(); | |||
| } | |||
| public NodeInitContext(int id, NetworkAddress serverAddress) { | |||
| this.id = id; | |||
| this.serverAddress = serverAddress; | |||
| } | |||
| public LedgerQuery registLedger(HashDigest ledgerHash) { | |||
| // LedgerManage ledgerManager = ctx.getBean(LedgerManage.class); | |||
| // | |||
| // DbConnectionFactory dbConnFactory = ctx.getBean(DbConnectionFactory.class); | |||
| // DbConnection conn = dbConnFactory.connect(dbConnConfig.getUri(), | |||
| // dbConnConfig.getPassword()); | |||
| DbConnection conn = db.connect(dbConnConfig.getUri(), dbConnConfig.getPassword()); | |||
| conns.add(conn); | |||
| LedgerQuery ledgerRepo = ledgerManager.register(ledgerHash, conn.getStorageService()); | |||
| return ledgerRepo; | |||
| } | |||
| public SignatureDigest createPermissionRequestSignature(int requesterId, PrivKey privKey) { | |||
| return controller.signPermissionRequest(requesterId, privKey); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
| Prompter prompter, CountDownLatch quitLatch) { | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| doStartServer(); | |||
| // NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| NodeInitContext.this.dbConnConfig = dbConnConfig; | |||
| HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, | |||
| dbConnConfig, prompter); | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public AsyncCallback<HashDigest> startInitCommand(PrivKey privKey, String base58Pwd, | |||
| LedgerInitProperties ledgerSetting, ConsensusSettings csProps, ConsensusProvider csProvider, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, LedgerBindingConfig conf, | |||
| CountDownLatch quitLatch) { | |||
| this.db = new CompositeConnectionFactory(); | |||
| this.dbConnConfig = dbConnConfig; | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| LedgerInitCommand initCmd = new LedgerInitCommand(); | |||
| HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, | |||
| prompter, conf, db); | |||
| NodeInitContext.this.ledgerManager = initCmd.getLedgerManager(); | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitProperties initProps) { | |||
| return controller.prepareLocalPermission(id, privKey, initProps); | |||
| } | |||
| public boolean consensusPermission(PrivKey privKey) { | |||
| return controller.consensusPermisions(privKey); | |||
| } | |||
| public LedgerInitDecision prepareLedger(DBConnectionConfig dbConnConfig, PrivKey privKey) { | |||
| controller.connectDb(dbConnConfig); | |||
| return controller.makeLocalDecision(privKey); | |||
| } | |||
| public void startServer() { | |||
| ThreadInvoker<Object> invoker = new ThreadInvoker<Object>() { | |||
| @Override | |||
| protected Object invoke() throws Exception { | |||
| doStartServer(); | |||
| return null; | |||
| } | |||
| }; | |||
| invoker.startAndWait(); | |||
| } | |||
| public void setPrompter(Prompter prompter) { | |||
| controller.setPrompter(prompter); | |||
| } | |||
| public void doStartServer() { | |||
| String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); | |||
| String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); | |||
| String nodebug = "--debug=false"; | |||
| String[] innerArgs = { argServerAddress, argServerPort, nodebug }; | |||
| ctx = SpringApplication.run(LedgerInitTestConfiguration.class, innerArgs); | |||
| ctx.setId("Node-" + id); | |||
| controller = ctx.getBean(LedgerInitializeWebController.class); | |||
| ledgerManager = ctx.getBean(LedgerManager.class); | |||
| db = ctx.getBean(CompositeConnectionFactory.class); | |||
| initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| } | |||
| public void closeServer() { | |||
| try { | |||
| if (this.ctx != null) { | |||
| this.ctx.close(); | |||
| this.ctx = null; | |||
| } | |||
| } catch (Exception e1) { | |||
| // Ignore; | |||
| } | |||
| for (DbConnection conn : conns) { | |||
| try { | |||
| conn.close(); | |||
| } catch (Exception e) { | |||
| // Ignore; | |||
| } | |||
| } | |||
| } | |||
| public LedgerManager getLedgerManager() { | |||
| return ledgerManager; | |||
| // return ctx.getBean(LedgerManager.class); | |||
| } | |||
| public CompositeConnectionFactory getStorageDB() { | |||
| return db; | |||
| // return ctx.getBean(MemoryBasedDb.class); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,30 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; | |||
| import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.Import; | |||
| //import com.jd.blockchain.storage.service.utils.MemoryBasedDb; | |||
| import com.jd.blockchain.tools.initializer.web.InitWebSecurityConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.InitWebServerConfiguration; | |||
| @SpringBootApplication | |||
| @EnableAutoConfiguration | |||
| @EnableConfigurationProperties | |||
| @Import(value = { InitWebServerConfiguration.class, InitWebSecurityConfiguration.class }) | |||
| public class LedgerInitTestConfiguration { | |||
| @Bean | |||
| public MemoryDBConnFactory getStorageDB() { | |||
| return new MemoryDBConnFactory(); | |||
| } | |||
| // @Bean | |||
| // public LedgerManager getLedgerManager() { | |||
| // return new LedgerManager(); | |||
| // } | |||
| } | |||
| @@ -1,29 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| //import com.jd.blockchain.storage.service.utils.MemoryBasedDb; | |||
| import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; | |||
| import com.jd.blockchain.tools.initializer.web.InitWebSecurityConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.InitWebServerConfiguration; | |||
| import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.Import; | |||
| @SpringBootApplication | |||
| @EnableAutoConfiguration | |||
| @EnableConfigurationProperties | |||
| @Import(value = { InitWebServerConfiguration.class, InitWebSecurityConfiguration.class }) | |||
| public class LedgerInitWebTestConfiguration { | |||
| @Bean | |||
| public MemoryDBConnFactory getStorageDB() { | |||
| return new MemoryDBConnFactory(); | |||
| } | |||
| // @Bean | |||
| // public LedgerManager getLedgerManager() { | |||
| // return new LedgerManager(); | |||
| // } | |||
| } | |||
| @@ -1,277 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Map; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.crypto.SignatureDigest; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.ledger.core.UserAccount; | |||
| import com.jd.blockchain.ledger.core.UserAccountQuery; | |||
| import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; | |||
| //import com.jd.blockchain.storage.service.utils.MemoryBasedDb; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.InitConsensusServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| public class LedgerInitializeTest { | |||
| public static final String PASSWORD = "abc"; | |||
| public static final String[] PUB_KEYS = { "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9", | |||
| "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX", | |||
| "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x", | |||
| "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" }; | |||
| public static final String[] PRIV_KEYS = { | |||
| "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x", | |||
| "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT", | |||
| "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF", | |||
| "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" }; | |||
| private Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap = new ConcurrentHashMap<>(); | |||
| public static ConsensusProvider getConsensusProvider() { | |||
| return ConsensusProviders.getProvider("com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider"); | |||
| } | |||
| public void testInitWith4Nodes() { | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting(); | |||
| NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node1 = new NodeContext(initSetting.getConsensusParticipant(1).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node2 = new NodeContext(initSetting.getConsensusParticipant(2).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node3 = new NodeContext(initSetting.getConsensusParticipant(3).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| String[] memoryConnString = new String[] { "memory://local/0", "memory://local/1", "memory://local/2", | |||
| "memory://local/3" }; | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri(memoryConnString[0]); | |||
| AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri(memoryConnString[1]); | |||
| AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri(memoryConnString[2]); | |||
| AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
| DBConnectionConfig testDb03 = new DBConnectionConfig(); | |||
| testDb03.setConnectionUri(memoryConnString[3]); | |||
| AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| LedgerQuery ledger0 = node0.registLedger(ledgerHash0, memoryConnString[0]); | |||
| LedgerQuery ledger1 = node1.registLedger(ledgerHash1, memoryConnString[1]); | |||
| LedgerQuery ledger2 = node2.registLedger(ledgerHash2, memoryConnString[2]); | |||
| LedgerQuery ledger3 = node3.registLedger(ledgerHash3, memoryConnString[3]); | |||
| LedgerBlock genesisBlock = ledger0.getLatestBlock(); | |||
| UserAccountQuery userset0 = ledger0.getUserAccountSet(genesisBlock); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(PUB_KEYS[0]); | |||
| Bytes address0 = AddressEncoding.generateAddress(pubKey0); | |||
| UserAccount user0_0 = userset0.getAccount(address0); | |||
| PubKey pubKey1 = KeyGenUtils.decodePubKey(PUB_KEYS[1]); | |||
| Bytes address1 = AddressEncoding.generateAddress(pubKey1); | |||
| UserAccount user1_0 = userset0.getAccount(address1); | |||
| PubKey pubKey2 = KeyGenUtils.decodePubKey(PUB_KEYS[2]); | |||
| Bytes address2 = AddressEncoding.generateAddress(pubKey2); | |||
| UserAccount user2_0 = userset0.getAccount(address2); | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| Bytes address3 = AddressEncoding.generateAddress(pubKey3); | |||
| UserAccount user3_0 = userset0.getAccount(address3); | |||
| } | |||
| public static LedgerInitProperties loadInitSetting() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_web2.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static Properties loadConsensusSetting() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("bftsmart.config"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| return FileUtils.readProperties(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static class NodeContext { | |||
| private LedgerManager ledgerManager = new LedgerManager(); | |||
| private MemoryDBConnFactory memoryDBConnFactory = new MemoryDBConnFactory(); | |||
| // private MemoryBasedDb storageDb = new MemoryBasedDb(); | |||
| private InitConsensusServiceFactory initCsServiceFactory; | |||
| private LedgerInitProcess initProcess; | |||
| private AsymmetricKeypair partiKey; | |||
| public AsymmetricKeypair getPartiKey() { | |||
| return partiKey; | |||
| } | |||
| public LedgerManager getLedgerManager() { | |||
| return ledgerManager; | |||
| } | |||
| public MemoryDBConnFactory getMemoryDBConnFactory() { | |||
| return memoryDBConnFactory; | |||
| } | |||
| // public MemoryBasedDb () { | |||
| // return storageDb; | |||
| // } | |||
| public NodeContext(NetworkAddress address, Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap) { | |||
| this.initCsServiceFactory = new MultiThreadInterInvokerFactory(serviceRegisterMap); | |||
| LedgerInitializeWebController initController = new LedgerInitializeWebController(memoryDBConnFactory, | |||
| initCsServiceFactory); | |||
| serviceRegisterMap.put(address, initController); | |||
| this.initProcess = initController; | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter) { | |||
| partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties initProps, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, boolean autoVerifyHash) { | |||
| initProps.getCryptoProperties().setVerifyHash(autoVerifyHash); | |||
| initProps.getCryptoProperties().setHashAlgorithm("SHA256"); | |||
| partiKey = new AsymmetricKeypair(initProps.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, initProps, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public LedgerQuery registLedger(HashDigest ledgerHash, String connString) { | |||
| return ledgerManager.register(ledgerHash, memoryDBConnFactory.connect(connString).getStorageService()); | |||
| } | |||
| } | |||
| private static class MultiThreadInterInvokerFactory implements InitConsensusServiceFactory { | |||
| private Map<NetworkAddress, LedgerInitConsensusService> nodeConsesusServices; | |||
| public MultiThreadInterInvokerFactory(Map<NetworkAddress, LedgerInitConsensusService> nodeConsesusServices) { | |||
| this.nodeConsesusServices = nodeConsesusServices; | |||
| } | |||
| @Override | |||
| public LedgerInitConsensusService connect(NetworkAddress endpointAddress) { | |||
| return new InitConsensusServiceProxy(nodeConsesusServices.get(endpointAddress)); | |||
| } | |||
| } | |||
| private static class InitConsensusServiceProxy implements LedgerInitConsensusService { | |||
| private LedgerInitConsensusService initCsService; | |||
| public InitConsensusServiceProxy(LedgerInitConsensusService initCsService) { | |||
| this.initCsService = initCsService; | |||
| } | |||
| @Override | |||
| public LedgerInitProposal requestPermission(int requesterId, SignatureDigest signature) { | |||
| ThreadInvoker<LedgerInitProposal> invoker = new ThreadInvoker<LedgerInitProposal>() { | |||
| @Override | |||
| protected LedgerInitProposal invoke() { | |||
| return initCsService.requestPermission(requesterId, signature); | |||
| } | |||
| }; | |||
| return invoker.startAndWait(); | |||
| } | |||
| @Override | |||
| public LedgerInitDecision synchronizeDecision(LedgerInitDecision initDecision) { | |||
| ThreadInvoker<LedgerInitDecision> invoker = new ThreadInvoker<LedgerInitDecision>() { | |||
| @Override | |||
| protected LedgerInitDecision invoke() { | |||
| return initCsService.synchronizeDecision(initDecision); | |||
| } | |||
| }; | |||
| return invoker.startAndWait(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,528 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import com.jd.blockchain.ledger.core.*; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import org.mockito.Mockito; | |||
| import org.mockito.invocation.InvocationOnMock; | |||
| import org.mockito.stubbing.Answer; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.context.ConfigurableApplicationContext; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.crypto.SignatureDigest; | |||
| import com.jd.blockchain.crypto.SignatureFunction; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.Operation; | |||
| import com.jd.blockchain.ledger.TransactionContent; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory; | |||
| //import com.jd.blockchain.storage.service.utils.MemoryBasedDb; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitCommand; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.HttpInitConsensServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.BytesUtils; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.LedgerInitConsensusConfig; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| public class LedgerInitializeWebTest { | |||
| public static final String PASSWORD = LedgerInitializeTest.PASSWORD; | |||
| public static final String[] PUB_KEYS = LedgerInitializeTest.PUB_KEYS; | |||
| public static final String[] PRIV_KEYS = LedgerInitializeTest.PRIV_KEYS; | |||
| /** | |||
| * 测试一个节点向多个节点请求新建许可的过程; | |||
| */ | |||
| public void testWithSingleSteps() { | |||
| Prompter prompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| HttpInitConsensServiceFactory httpCsSrvFactory = new HttpInitConsensServiceFactory(); | |||
| // 加载初始化配置; | |||
| LedgerInitProperties initSetting = loadInitSetting_1(); | |||
| // 加载共识配置; | |||
| Properties props = loadConsensusSetting(LedgerInitConsensusConfig.bftsmartConfig.getConfigPath()); | |||
| // ConsensusProperties csProps = new ConsensusProperties(props); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeWebContext node0 = new NodeWebContext(0, initAddr0); | |||
| node0.startServer(); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeWebContext node1 = new NodeWebContext(1, initAddr1); | |||
| node1.startServer(); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeWebContext node2 = new NodeWebContext(2, initAddr2); | |||
| node2.startServer(); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeWebContext node3 = new NodeWebContext(3, initAddr3); | |||
| node3.startServer(); | |||
| node0.setPrompter(prompter); | |||
| node1.setPrompter(prompter); | |||
| node2.setPrompter(prompter); | |||
| node3.setPrompter(prompter); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(PUB_KEYS[0]); | |||
| PubKey pubKey1 = KeyGenUtils.decodePubKey(PUB_KEYS[1]); | |||
| PubKey pubKey2 = KeyGenUtils.decodePubKey(PUB_KEYS[2]); | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| // 测试生成“账本初始化许可”; | |||
| LedgerInitConfiguration initConfig = LedgerInitConfiguration.create(initSetting); | |||
| initConfig.setConsensusSettings(csProvider, csProps); | |||
| LedgerInitProposal permission0 = testPreparePermisssion(node0, privkey0, initConfig); | |||
| LedgerInitProposal permission1 = testPreparePermisssion(node1, privkey1, initConfig); | |||
| LedgerInitProposal permission2 = testPreparePermisssion(node2, privkey2, initConfig); | |||
| LedgerInitProposal permission3 = testPreparePermisssion(node3, privkey3, initConfig); | |||
| TransactionContent initTxContent0 = node0.getInitTxContent(); | |||
| TransactionContent initTxContent1 = node1.getInitTxContent(); | |||
| TransactionContent initTxContent2 = node2.getInitTxContent(); | |||
| TransactionContent initTxContent3 = node3.getInitTxContent(); | |||
| if (!initTxContent0.getHash().equals(initTxContent1.getHash())) { | |||
| Operation[] oplist0 = initTxContent0.getOperations(); | |||
| Operation[] oplist1 = initTxContent1.getOperations(); | |||
| LedgerInitOperation initOp0 = (LedgerInitOperation) oplist0[0]; | |||
| LedgerInitOperation initOp1 = (LedgerInitOperation) oplist1[0]; | |||
| byte[] initOpBytes0 = BinaryProtocol.encode(initOp0, LedgerInitOperation.class); | |||
| byte[] initOpBytes1 = BinaryProtocol.encode(initOp1, LedgerInitOperation.class); | |||
| UserRegisterOperation regOp00 = (UserRegisterOperation) oplist0[1]; | |||
| UserRegisterOperation regOp10 = (UserRegisterOperation) oplist1[1]; | |||
| byte[] regOpBytes00 = BinaryProtocol.encode(regOp00, UserRegisterOperation.class); | |||
| byte[] regOpBytes10 = BinaryProtocol.encode(regOp10, UserRegisterOperation.class); | |||
| UserRegisterOperation regOp01 = (UserRegisterOperation) oplist0[2]; | |||
| UserRegisterOperation regOp11 = (UserRegisterOperation) oplist1[2]; | |||
| byte[] regOpBytes01 = BinaryProtocol.encode(regOp01, UserRegisterOperation.class); | |||
| byte[] regOpBytes11 = BinaryProtocol.encode(regOp11, UserRegisterOperation.class); | |||
| UserRegisterOperation regOp02 = (UserRegisterOperation) oplist0[3]; | |||
| UserRegisterOperation regOp12 = (UserRegisterOperation) oplist1[3]; | |||
| byte[] regOpBytes02 = BinaryProtocol.encode(regOp02, UserRegisterOperation.class); | |||
| byte[] regOpBytes12 = BinaryProtocol.encode(regOp12, UserRegisterOperation.class); | |||
| UserRegisterOperation regOp03 = (UserRegisterOperation) oplist0[4]; | |||
| UserRegisterOperation regOp13 = (UserRegisterOperation) oplist1[4]; | |||
| byte[] regOpBytes03 = BinaryProtocol.encode(regOp03, UserRegisterOperation.class); | |||
| byte[] regOpBytes13 = BinaryProtocol.encode(regOp13, UserRegisterOperation.class); | |||
| } | |||
| // 测试请求“账本初始化许可”; | |||
| // test request permission, and verify the response; | |||
| LedgerInitConsensusService initCsService0 = httpCsSrvFactory.connect(initAddr0); | |||
| LedgerInitConsensusService initCsService1 = httpCsSrvFactory.connect(initAddr1); | |||
| LedgerInitConsensusService initCsService2 = httpCsSrvFactory.connect(initAddr2); | |||
| LedgerInitConsensusService initCsService3 = httpCsSrvFactory.connect(initAddr3); | |||
| testRequestPermission(node0, privkey0, node1, initCsService1); | |||
| testRequestPermission(node0, privkey0, node2, initCsService2); | |||
| testRequestPermission(node0, privkey0, node3, initCsService3); | |||
| testRequestPermission(node1, privkey1, node0, initCsService0); | |||
| testRequestPermission(node1, privkey1, node2, initCsService2); | |||
| testRequestPermission(node1, privkey1, node3, initCsService3); | |||
| testRequestPermission(node2, privkey2, node0, initCsService0); | |||
| testRequestPermission(node2, privkey2, node1, initCsService1); | |||
| testRequestPermission(node2, privkey2, node3, initCsService3); | |||
| testRequestPermission(node3, privkey3, node0, initCsService0); | |||
| testRequestPermission(node3, privkey3, node1, initCsService1); | |||
| testRequestPermission(node3, privkey3, node2, initCsService2); | |||
| // 测试在节点之间共识彼此的“账本初始化许可” | |||
| boolean allPermitted0 = node0.consensusPermission(privkey0); | |||
| boolean allPermitted1 = node1.consensusPermission(privkey1); | |||
| boolean allPermitted2 = node2.consensusPermission(privkey2); | |||
| boolean allPermitted3 = node3.consensusPermission(privkey3); | |||
| // 测试生成账本,并创建“账本初始化决议”; | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig("memory://local/0"); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig("memory://local/1"); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig("memory://local/2"); | |||
| DBConnectionConfig testDb3 = new DBConnectionConfig("memory://local/3"); | |||
| LedgerInitDecision dec0 = node0.prepareLedger(testDb0, privkey0); | |||
| LedgerInitDecision dec1 = node1.prepareLedger(testDb1, privkey1); | |||
| LedgerInitDecision dec2 = node2.prepareLedger(testDb2, privkey2); | |||
| LedgerInitDecision dec3 = node3.prepareLedger(testDb3, privkey3); | |||
| testRequestDecision(node0, node1, initCsService1); | |||
| testRequestDecision(node0, node2, initCsService2); | |||
| testRequestDecision(node0, node3, initCsService3); | |||
| testRequestDecision(node1, node0, initCsService0); | |||
| testRequestDecision(node1, node2, initCsService2); | |||
| testRequestDecision(node1, node3, initCsService3); | |||
| testRequestDecision(node2, node0, initCsService0); | |||
| testRequestDecision(node2, node1, initCsService1); | |||
| testRequestDecision(node2, node3, initCsService3); | |||
| testRequestDecision(node3, node0, initCsService0); | |||
| testRequestDecision(node3, node1, initCsService1); | |||
| testRequestDecision(node3, node2, initCsService2); | |||
| } | |||
| private LedgerInitProposal testPreparePermisssion(NodeWebContext node, PrivKey privKey, | |||
| LedgerInitConfiguration setting) { | |||
| LedgerInitProposal permission = node.preparePermision(privKey, setting); | |||
| return permission; | |||
| } | |||
| private void testRequestPermission(NodeWebContext fromNode, PrivKey fromPrivkey, NodeWebContext targetNode, | |||
| LedgerInitConsensusService targetNodeService) { | |||
| SignatureDigest reqSignature = fromNode.createPermissionRequestSignature(fromNode.getId(), fromPrivkey); | |||
| LedgerInitProposal targetPermission = targetNodeService.requestPermission(fromNode.getId(), reqSignature); | |||
| } | |||
| private void testRequestDecision(NodeWebContext fromNode, NodeWebContext targetNode, | |||
| LedgerInitConsensusService targetNodeService) { | |||
| LedgerInitDecision targetDecision = targetNodeService.synchronizeDecision(fromNode.getLocalDecision()); | |||
| } | |||
| public SignatureDigest signPermissionRequest(int requesterId, PrivKey privKey, LedgerInitProperties initSetting) { | |||
| byte[] reqAuthBytes = BytesUtils.concat(BytesUtils.toBytes(requesterId), initSetting.getLedgerSeed()); | |||
| SignatureFunction signFunc = Crypto.getSignatureFunction("ED25519"); | |||
| SignatureDigest reqAuthSign = signFunc.sign(privKey, reqAuthBytes); | |||
| return reqAuthSign; | |||
| } | |||
| private static ConsensusProvider getConsensusProvider() { | |||
| return ConsensusProviders.getProvider("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"); | |||
| } | |||
| public void testInitWith4Nodes() { | |||
| System.out.println("----------- is daemon=" + Thread.currentThread().isDaemon()); | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting_2(); | |||
| Properties props = loadConsensusSetting(LedgerInitConsensusConfig.bftsmartConfig.getConfigPath()); | |||
| // ConsensusProperties csProps = new ConsensusProperties(props); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeWebContext node0 = new NodeWebContext(0, initAddr0); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeWebContext node1 = new NodeWebContext(1, initAddr1); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeWebContext node2 = new NodeWebContext(2, initAddr2); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeWebContext node3 = new NodeWebContext(3, initAddr3); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
| CountDownLatch quitLatch = new CountDownLatch(4); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri("memory://local/0"); | |||
| AsyncCallback<HashDigest> callback0 = node0.startInit(privkey0, initSetting, testDb0, consolePrompter, | |||
| quitLatch); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri("memory://local/1"); | |||
| AsyncCallback<HashDigest> callback1 = node1.startInit(privkey1, initSetting, testDb1, consolePrompter, | |||
| quitLatch); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri("memory://local/2"); | |||
| AsyncCallback<HashDigest> callback2 = node2.startInit(privkey2, initSetting, testDb2, consolePrompter, | |||
| quitLatch); | |||
| DBConnectionConfig testDb03 = new DBConnectionConfig(); | |||
| testDb03.setConnectionUri("memory://local/3"); | |||
| AsyncCallback<HashDigest> callback3 = node3.startInit(privkey3, initSetting, testDb03, consolePrompter, | |||
| quitLatch); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| LedgerQuery ledger0 = node0.registLedger(ledgerHash0); | |||
| LedgerQuery ledger1 = node1.registLedger(ledgerHash1); | |||
| LedgerQuery ledger2 = node2.registLedger(ledgerHash2); | |||
| LedgerQuery ledger3 = node3.registLedger(ledgerHash3); | |||
| LedgerBlock genesisBlock = ledger0.getLatestBlock(); | |||
| UserAccountQuery userset0 = ledger0.getUserAccountSet(genesisBlock); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(PUB_KEYS[0]); | |||
| Bytes address0 = AddressEncoding.generateAddress(pubKey0); | |||
| UserAccount user0_0 = userset0.getAccount(address0); | |||
| PubKey pubKey1 = KeyGenUtils.decodePubKey(PUB_KEYS[1]); | |||
| Bytes address1 = AddressEncoding.generateAddress(pubKey1); | |||
| UserAccount user1_0 = userset0.getAccount(address1); | |||
| PubKey pubKey2 = KeyGenUtils.decodePubKey(PUB_KEYS[2]); | |||
| Bytes address2 = AddressEncoding.generateAddress(pubKey2); | |||
| UserAccount user2_0 = userset0.getAccount(address2); | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| Bytes address3 = AddressEncoding.generateAddress(pubKey3); | |||
| UserAccount user3_0 = userset0.getAccount(address3); | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_1() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_web1.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_2() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_web2.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static Properties loadConsensusSetting(String configPath) { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource(configPath); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| return FileUtils.readProperties(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static class NodeWebContext { | |||
| private NetworkAddress serverAddress; | |||
| private DBConnectionConfig dbConnConfig; | |||
| // private MQConnectionConfig mqConnConfig; | |||
| private volatile ConfigurableApplicationContext ctx; | |||
| private volatile LedgerInitProcess initProcess; | |||
| private volatile LedgerInitializeWebController controller; | |||
| private volatile LedgerManager ledgerManager; | |||
| private volatile DbConnectionFactory db; | |||
| private int id; | |||
| public int getId() { | |||
| return controller.getId(); | |||
| } | |||
| public TransactionContent getInitTxContent() { | |||
| return controller.getInitTxContent(); | |||
| } | |||
| public LedgerInitProposal getLocalPermission() { | |||
| return controller.getLocalPermission(); | |||
| } | |||
| public LedgerInitDecision getLocalDecision() { | |||
| return controller.getLocalDecision(); | |||
| } | |||
| public NodeWebContext(int id, NetworkAddress serverAddress) { | |||
| this.id = id; | |||
| this.serverAddress = serverAddress; | |||
| } | |||
| public LedgerQuery registLedger(HashDigest ledgerHash) { | |||
| // LedgerManage ledgerManager = ctx.getBean(LedgerManage.class); | |||
| // | |||
| // DbConnectionFactory dbConnFactory = ctx.getBean(DbConnectionFactory.class); | |||
| // DbConnection conn = dbConnFactory.connect(dbConnConfig.getUri(), | |||
| // dbConnConfig.getPassword()); | |||
| // DbConnection conn = db.connect(dbConnConfig.getUri(), | |||
| // dbConnConfig.getPassword()); | |||
| DbConnection conn = db.connect(dbConnConfig.getUri()); | |||
| LedgerQuery ledgerRepo = ledgerManager.register(ledgerHash, conn.getStorageService()); | |||
| return ledgerRepo; | |||
| } | |||
| public LedgerRepository ledgerRepository(HashDigest ledgerHash) { | |||
| return ledgerManager.getLedger(ledgerHash); | |||
| } | |||
| public SignatureDigest createPermissionRequestSignature(int requesterId, PrivKey privKey) { | |||
| return controller.signPermissionRequest(requesterId, privKey); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| doStartServer(); | |||
| // NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| NodeWebContext.this.dbConnConfig = dbConnConfig; | |||
| HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, | |||
| dbConnConfig, prompter); | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public AsyncCallback<HashDigest> startInitCommand(PrivKey privKey, String base58Pwd, | |||
| LedgerInitProperties ledgerSetting, ConsensusSettings csProps, ConsensusProvider csProvider, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, LedgerBindingConfig conf, | |||
| CountDownLatch quitLatch, DbConnectionFactory db) { | |||
| this.dbConnConfig = dbConnConfig; | |||
| // this.mqConnConfig = mqConnConfig; | |||
| this.db = db; | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| LedgerInitCommand initCmd = new LedgerInitCommand(); | |||
| HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, | |||
| prompter, conf, db); | |||
| LedgerManager lm = initCmd.getLedgerManager(); | |||
| NodeWebContext.this.ledgerManager = lm; | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitConfiguration initConfig) { | |||
| return controller.prepareLocalPermission(id, privKey, initConfig); | |||
| } | |||
| public boolean consensusPermission(PrivKey privKey) { | |||
| return controller.consensusPermisions(privKey); | |||
| } | |||
| public LedgerInitDecision prepareLedger(DBConnectionConfig dbConnConfig, PrivKey privKey) { | |||
| controller.connectDb(dbConnConfig); | |||
| return controller.makeLocalDecision(privKey); | |||
| } | |||
| public void startServer() { | |||
| ThreadInvoker<Object> invoker = new ThreadInvoker<Object>() { | |||
| @Override | |||
| protected Object invoke() throws Exception { | |||
| doStartServer(); | |||
| return null; | |||
| } | |||
| }; | |||
| invoker.startAndWait(); | |||
| } | |||
| public void setPrompter(Prompter prompter) { | |||
| controller.setPrompter(prompter); | |||
| } | |||
| public void doStartServer() { | |||
| String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); | |||
| String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); | |||
| String nodebug = "--debug=false"; | |||
| String[] innerArgs = { argServerAddress, argServerPort, nodebug }; | |||
| ctx = SpringApplication.run(LedgerInitWebTestConfiguration.class, innerArgs); | |||
| ctx.setId("Node-" + id); | |||
| controller = ctx.getBean(LedgerInitializeWebController.class); | |||
| ledgerManager = ctx.getBean(LedgerManager.class); | |||
| db = ctx.getBean(CompositeConnectionFactory.class); | |||
| initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| } | |||
| public void closeServer() { | |||
| if (this.ctx != null) { | |||
| this.ctx.close(); | |||
| this.ctx = null; | |||
| } | |||
| } | |||
| public LedgerManager getLedgerManager() { | |||
| return ledgerManager; | |||
| // return ctx.getBean(LedgerManager.class); | |||
| } | |||
| public DbConnectionFactory getStorageDB() { | |||
| return db; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,727 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.Properties; | |||
| import java.util.Set; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| import java.util.stream.DoubleStream; | |||
| import com.jd.blockchain.ledger.*; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.LedgerPermission; | |||
| import com.jd.blockchain.ledger.LedgerSecurityException; | |||
| import com.jd.blockchain.ledger.TransactionPermission; | |||
| import com.jd.blockchain.ledger.core.DefaultOperationHandleRegisteration; | |||
| import com.jd.blockchain.ledger.core.LedgerDataQuery; | |||
| import com.jd.blockchain.ledger.core.LedgerEditor; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerRepository; | |||
| import com.jd.blockchain.ledger.core.LedgerSecurityManager; | |||
| import com.jd.blockchain.ledger.core.MultiIDsPolicy; | |||
| import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
| import com.jd.blockchain.ledger.core.TransactionBatchProcessor; | |||
| import com.jd.blockchain.service.TransactionBatchResultHandle; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.storage.service.impl.redis.JedisConnection; | |||
| import com.jd.blockchain.storage.service.impl.redis.RedisConnectionFactory; | |||
| import com.jd.blockchain.storage.service.impl.redis.RedisStorageService; | |||
| import com.jd.blockchain.storage.service.impl.rocksdb.RocksDBConnectionFactory; | |||
| import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.transaction.TxBuilder; | |||
| import com.jd.blockchain.utils.ArgumentSet; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.ConsoleUtils; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| import test.com.jd.blockchain.intgr.perf.Utils.NodeContext; | |||
| //import com.jd.blockchain.storage.service.utils.MemoryBasedDb; | |||
| /** | |||
| * 账本性能测试; <br> | |||
| * | |||
| * 可用的参数:<br> | |||
| * -o: 优化模式执行;此时merkle树在加载时不做检查; | |||
| * <p> | |||
| * | |||
| * -redis: 基于 redis 数据库进行测试;需要预先启动redis数据库,4个节点分别连接到本机 redis://127.0.0.1 的端口为 | |||
| * 6079、6179、6279、6379 的 4 个数据库实例; | |||
| * <p> | |||
| * | |||
| * -rocksdb: 基于 rocksDB 进行测试;不需要预先配置数据库,4个节点连接到当前路径下的4个RocksDB数据库目录: | |||
| * rocksdb0.db、rocksdb1.db、rocksdb2.db、rocksdb3.db; | |||
| * <p> | |||
| * | |||
| * -silent: 采用静默模式启动测试用例;否则会在准备就绪后等待输入任意键才正式开始测试,并在完成测试后等待输入任意键才退出; | |||
| * | |||
| * | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| public class LedgerPerformanceTest { | |||
| static { | |||
| DataContractRegistry.register(LedgerInitOperation.class); | |||
| DataContractRegistry.register(UserRegisterOperation.class); | |||
| DataContractRegistry.register(DataAccountRegisterOperation.class); | |||
| DataContractRegistry.register(DataAccountKVSetOperation.class); | |||
| DataContractRegistry.register(ParticipantRegisterOperation.class); | |||
| DataContractRegistry.register(ParticipantStateUpdateOperation.class); | |||
| } | |||
| public static final LedgerSecurityManager DEFAULT_SECURITY_MANAGER = new FreedomLedgerSecurityManager(); | |||
| public static void test(String[] args) { | |||
| NodeContext[] nodes = null; | |||
| try { | |||
| boolean usertest = ArgumentSet.hasOption(args, "-usertest"); | |||
| boolean optimized = ArgumentSet.hasOption(args, "-o"); | |||
| boolean useRedis = ArgumentSet.hasOption(args, "-redis"); | |||
| boolean useRocksDB = ArgumentSet.hasOption(args, "-rocksdb"); | |||
| boolean silent = ArgumentSet.hasOption(args, "-silent"); | |||
| boolean contract = ArgumentSet.hasOption(args, "-contract"); | |||
| boolean mqConsensus = ArgumentSet.hasOption(args, "-mq"); | |||
| DBType dbType = DBType.DEFAULT; | |||
| if (useRedis) { | |||
| dbType = DBType.REDIS; | |||
| } | |||
| if (useRocksDB) { | |||
| dbType = DBType.ROCKSDB; | |||
| } | |||
| CryptoAlgorithm hashAlg = ArgumentSet.hasOption(args, "-160") ? Crypto.getAlgorithm("RIPEMD160") | |||
| : Crypto.getAlgorithm("SHA256"); | |||
| System.out.println( | |||
| String.format("----- LedgerPerformanceTest [HashAlgorithm=%s][DBType=%s] ----", hashAlg, dbType)); | |||
| // 初始化,并获取其中一个节点的账本,单独进行性能测试; | |||
| String provider = "com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"; | |||
| String config = "bftsmart.config"; | |||
| if (mqConsensus) { | |||
| provider = "com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider"; | |||
| config = "mq.config"; | |||
| } | |||
| nodes = initLedgers(optimized, hashAlg, dbType, provider, config); | |||
| NodeContext testNode = nodes[0]; | |||
| LedgerManager ledgerManager = testNode.getLedgerManager(); | |||
| HashDigest ledgerHash = ledgerManager.getLedgerHashs()[0]; | |||
| DefaultOperationHandleRegisteration opHandler = new DefaultOperationHandleRegisteration(); | |||
| System.out.println("Ledger is ready!"); | |||
| int batchSize = 1000; | |||
| int batchCount = 30; | |||
| if (args.length > 0) { | |||
| if (!args[0].startsWith("-")) { | |||
| batchSize = Integer.parseInt(args[0]); | |||
| } | |||
| } | |||
| if (args.length > 1) { | |||
| if (!args[1].startsWith("-")) { | |||
| batchCount = Integer.parseInt(args[1]); | |||
| } | |||
| } | |||
| if (contract) { | |||
| testContract(ledgerHash, testNode.getPartiKey(), ledgerManager, opHandler, batchSize, batchCount, | |||
| silent); | |||
| } | |||
| if (usertest) { | |||
| testUserRegistering(ledgerHash, testNode.getPartiKey(), ledgerManager, opHandler, batchSize, batchCount, | |||
| silent); | |||
| } else { | |||
| testKVWrite(ledgerHash, testNode.getPartiKey(), ledgerManager, opHandler, batchSize, batchCount, | |||
| silent); | |||
| } | |||
| } catch (Exception e) { | |||
| System.out.println("----------- error [" + e.getMessage() + "]-----------"); | |||
| e.printStackTrace(); | |||
| } finally { | |||
| if (nodes != null) { | |||
| for (NodeContext node : nodes) { | |||
| node.getStorageDb().close(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * 执行针对“注册用户”的性能测试; | |||
| * | |||
| * @param ledgerHash | |||
| * @param adminKey | |||
| * @param ledgerManager | |||
| * @param opHandler | |||
| * @param batchSize | |||
| * @param batchCount | |||
| * @param silent | |||
| */ | |||
| private static void testUserRegistering(HashDigest ledgerHash, AsymmetricKeypair adminKey, | |||
| LedgerManager ledgerManager, DefaultOperationHandleRegisteration opHandler, int batchSize, int batchCount, | |||
| boolean silent) { | |||
| LedgerRepository ledger = ledgerManager.getLedger(ledgerHash); | |||
| ConsoleUtils.info("\r\n\r\n================= 准备测试交易 [注册用户] ================="); | |||
| int totalCount = batchSize * batchCount; | |||
| List<TransactionRequest> txList = prepareUserRegisterRequests(ledgerHash, totalCount, adminKey); | |||
| // 预热; | |||
| ConsoleUtils.info("preheat......"); | |||
| int preheatTxBatch = 10; | |||
| int preheatTxBatchSize = 10; | |||
| int preheatTotalTx = preheatTxBatch * preheatTxBatchSize; | |||
| List<TransactionRequest> preheatTxList = prepareUserRegisterRequests(ledgerHash, preheatTotalTx, adminKey); | |||
| execPerformanceTest(preheatTxBatch, preheatTxBatchSize, preheatTxList, ledger, ledgerManager, opHandler, false); | |||
| preheatTxList.clear(); | |||
| preheatTxList = null; | |||
| if (!silent) { | |||
| ConsoleUtils.confirm("\r\nTest is ready! Any key to continue..."); | |||
| } | |||
| execPerformanceTest(batchCount, batchSize, txList, ledger, ledgerManager, opHandler, true); | |||
| if (!silent) { | |||
| ConsoleUtils.confirm("\r\nTest completed! Any key to quit..."); | |||
| } | |||
| } | |||
| /** | |||
| * 执行针对“写入数据”的性能测试; | |||
| * | |||
| * @param ledgerHash | |||
| * @param adminKey | |||
| * @param ledgerManager | |||
| * @param opHandler | |||
| * @param batchSize | |||
| * @param batchCount | |||
| * @param silent | |||
| */ | |||
| private static void testKVWrite(HashDigest ledgerHash, AsymmetricKeypair adminKey, LedgerManager ledgerManager, | |||
| DefaultOperationHandleRegisteration opHandler, int batchSize, int batchCount, boolean silent) { | |||
| LedgerRepository ledger = ledgerManager.getLedger(ledgerHash); | |||
| ConsoleUtils.info("\r\n\r\n================= 准备测试交易 [写入数据] ================="); | |||
| // 创建数据账户; | |||
| BlockchainIdentity[] dataAccounts = new BlockchainIdentity[10]; | |||
| List<TransactionRequest> dataAccountRegTxList = prepareDataAccountRegisterRequests(ledgerHash, dataAccounts, | |||
| adminKey, false); | |||
| execPerformanceTest(1, dataAccounts.length, dataAccountRegTxList, ledger, ledgerManager, opHandler, false); | |||
| // 预热; | |||
| ConsoleUtils.info("preheat......"); | |||
| int preheatTxBatch = 10; | |||
| int preheatTxBatchSize = 10; | |||
| int preheatTotalTx = preheatTxBatch * preheatTxBatchSize; | |||
| List<TransactionRequest> preheatTxList = prepareDataWriteRequests(ledgerHash, dataAccounts, preheatTotalTx, | |||
| adminKey, false); | |||
| execPerformanceTest(preheatTxBatch, preheatTxBatchSize, preheatTxList, ledger, ledgerManager, opHandler, false); | |||
| preheatTxList.clear(); | |||
| preheatTxList = null; | |||
| // 准备正式数据; | |||
| int totalCount = batchSize * batchCount; | |||
| List<TransactionRequest> txList = prepareDataWriteRequests(ledgerHash, dataAccounts, totalCount, adminKey, | |||
| false); | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); | |||
| if (!silent) { | |||
| // ConsoleUtils.confirm("\r\nTest is ready! Any key to continue..."); | |||
| consolePrompter.confirm("testKVWrite", "Test is ready! Any key to continue..."); | |||
| } | |||
| execPerformanceTest(batchCount, batchSize, txList, ledger, ledgerManager, opHandler, true); | |||
| if (!silent) { | |||
| // ConsoleUtils.confirm("\r\nTest completed! Any key to quit..."); | |||
| consolePrompter.confirm("testKVWrite", "Test completed! Any key to quit..."); | |||
| } | |||
| } | |||
| /** | |||
| * 执行针对“执行合约”的性能测试; | |||
| * | |||
| * @param ledgerHash | |||
| * @param adminKey | |||
| * @param ledgerManager | |||
| * @param opHandler | |||
| * @param batchSize | |||
| * @param batchCount | |||
| * @param silent | |||
| */ | |||
| private static void testContract(HashDigest ledgerHash, AsymmetricKeypair adminKey, LedgerManager ledgerManager, | |||
| DefaultOperationHandleRegisteration opHandler, int batchSize, int batchCount, boolean silent) { | |||
| LedgerRepository ledger = ledgerManager.getLedger(ledgerHash); | |||
| ConsoleUtils.info("\r\n\r\n================= 准备测试交易 [执行合约] ================="); | |||
| LedgerBlock latestBlock = ledger.getLatestBlock(); | |||
| LedgerDataQuery previousDataSet = ledger.getLedgerData(latestBlock); | |||
| LedgerEditor newEditor = ledger.createNextBlock(); | |||
| TransactionBatchProcessor txProc = new TransactionBatchProcessor(DEFAULT_SECURITY_MANAGER, newEditor, | |||
| ledger, opHandler); | |||
| // 准备请求 | |||
| int totalCount = batchSize * batchCount; | |||
| List<TransactionRequest> contractTxList = prepareContractRequests(ledgerHash, adminKey, totalCount, false, | |||
| txProc); | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); | |||
| if (!silent) { | |||
| // ConsoleUtils.confirm("\r\nTest is ready! Any key to continue..."); | |||
| consolePrompter.confirm("testContract", "Test is ready! Any key to continue..."); | |||
| } | |||
| execPerformanceTest(batchCount, batchSize, contractTxList, ledger, ledgerManager, opHandler, true); | |||
| if (!silent) { | |||
| // ConsoleUtils.confirm("\r\nTest completed! Any key to quit..."); | |||
| consolePrompter.confirm("testContract", "Test completed! Any key to quit..."); | |||
| } | |||
| } | |||
| private static void execPerformanceTest(int batchCount, int batchSize, List<TransactionRequest> txList, | |||
| LedgerRepository ledger, LedgerManager ledgerManager, DefaultOperationHandleRegisteration opHandler, | |||
| boolean statistic) { | |||
| double[] tpss = new double[batchCount]; | |||
| long batchStartTs = System.currentTimeMillis(); | |||
| for (int i = 0; i < batchCount; i++) { | |||
| LedgerBlock latestBlock = ledger.getLatestBlock(); | |||
| LedgerDataQuery previousDataSet = ledger.getLedgerData(latestBlock); | |||
| if (statistic) { | |||
| ConsoleUtils.info("------ 开始执行交易, 即将生成区块[高度:%s] ------", (latestBlock.getHeight() + 1)); | |||
| } | |||
| long startTs = System.currentTimeMillis(); | |||
| LedgerEditor newEditor = ledger.createNextBlock(); | |||
| TransactionBatchProcessor txProc = new TransactionBatchProcessor(DEFAULT_SECURITY_MANAGER, newEditor, | |||
| ledger, opHandler); | |||
| testTxExec(txList, i * batchSize, batchSize, txProc); | |||
| if (statistic) { | |||
| long elapsedTs = System.currentTimeMillis() - startTs; | |||
| tpss[i] = batchSize * 1000.00D / elapsedTs; | |||
| ConsoleUtils.info("新区块已生成! 交易数=%s; 总耗时= %s ms; TPS=%.2f", batchSize, elapsedTs, tpss[i]); | |||
| } | |||
| } | |||
| if (!statistic) { | |||
| return; | |||
| } | |||
| long batchElapsedTs = System.currentTimeMillis() - batchStartTs; | |||
| double globalTPS = batchSize * batchCount * 1000.00D / batchElapsedTs; | |||
| double avgTPS = DoubleStream.of(tpss).average().getAsDouble(); | |||
| double maxTPS = DoubleStream.of(tpss).max().getAsDouble(); | |||
| double variance = DoubleStream.of(tpss).reduce(0, (r, i) -> r + Math.pow(i - avgTPS, 2)) / tpss.length; | |||
| double stdDeviation = Math.sqrt(variance); | |||
| ConsoleUtils.info("\r\n**********************************************"); | |||
| ConsoleUtils.info("区块数:%s; 交易总数:%s; 总体TPS:%.2f;\r\n单区块TPS均值:%.2f;单区块TPS峰值:%.2f;单区块TPS波动(标准差):%.2f", batchCount, | |||
| batchSize * batchCount, globalTPS, avgTPS, maxTPS, stdDeviation); | |||
| ConsoleUtils.info("**********************************************\r\n"); | |||
| } | |||
| private static void testTxExec(List<TransactionRequest> txList, int from, int count, | |||
| TransactionBatchProcessor txProc) { | |||
| for (int i = 0; i < count; i++) { | |||
| txProc.schedule(txList.get(from + i)); | |||
| } | |||
| TransactionBatchResultHandle handle = txProc.prepare(); | |||
| handle.commit(); | |||
| } | |||
| public static List<TransactionRequest> prepareUserRegisterRequests(HashDigest ledgerHash, int count, | |||
| AsymmetricKeypair adminKey) { | |||
| long startTs = System.currentTimeMillis(); | |||
| List<TransactionRequest> txList = new ArrayList<>(); | |||
| for (int i = 0; i < count; i++) { | |||
| TxBuilder txbuilder = new TxBuilder(ledgerHash); | |||
| BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| txbuilder.users().register(userKey.getIdentity()); | |||
| TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); | |||
| reqBuilder.signAsEndpoint(adminKey); | |||
| txList.add(reqBuilder.buildRequest()); | |||
| } | |||
| long elapsedTs = System.currentTimeMillis() - startTs; | |||
| ConsoleUtils.info( | |||
| "============ Performance of Preparing user registering tx requests... TOTAL=%s; TPS=%.2f; TIME=%s millis ============", | |||
| count, (count * 1000.0 / elapsedTs), elapsedTs); | |||
| ConsoleUtils.info("====================================================="); | |||
| return txList; | |||
| } | |||
| public static List<TransactionRequest> prepareDataAccountRegisterRequests(HashDigest ledgerHash, | |||
| BlockchainIdentity[] dataAccounts, AsymmetricKeypair adminKey, boolean statistic) { | |||
| int count = dataAccounts.length; | |||
| long startTs = System.currentTimeMillis(); | |||
| List<TransactionRequest> txList = new ArrayList<>(); | |||
| for (int i = 0; i < count; i++) { | |||
| TxBuilder txbuilder = new TxBuilder(ledgerHash); | |||
| BlockchainKeypair dataAccountKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| dataAccounts[i] = dataAccountKey.getIdentity(); | |||
| txbuilder.dataAccounts().register(dataAccounts[i]); | |||
| TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); | |||
| reqBuilder.signAsEndpoint(adminKey); | |||
| txList.add(reqBuilder.buildRequest()); | |||
| } | |||
| if (statistic) { | |||
| long elapsedTs = System.currentTimeMillis() - startTs; | |||
| ConsoleUtils.info( | |||
| "============ Performance of Preparing data account registering tx requests... TOTAL=%s; TPS=%.2f; TIME=%s millis ============", | |||
| count, (count * 1000.0 / elapsedTs), elapsedTs); | |||
| ConsoleUtils.info("====================================================="); | |||
| } | |||
| return txList; | |||
| } | |||
| public static List<TransactionRequest> prepareDataWriteRequests(HashDigest ledgerHash, | |||
| BlockchainIdentity[] dataAccounts, int count, AsymmetricKeypair adminKey, boolean statistic) { | |||
| long startTs = System.currentTimeMillis(); | |||
| List<TransactionRequest> txList = new ArrayList<>(); | |||
| for (int i = 0; i < count; i++) { | |||
| TxBuilder txbuilder = new TxBuilder(ledgerHash); | |||
| // BlockchainKeyPair dataAccountKey = | |||
| // BlockchainKeyGenerator.getInstance().generate(); | |||
| BlockchainIdentity targetAccount = dataAccounts[count % dataAccounts.length]; | |||
| txbuilder.dataAccount(targetAccount.getAddress()).setText("key-" + startTs + "-" + i, "value-" + i, -1L); | |||
| TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); | |||
| reqBuilder.signAsEndpoint(adminKey); | |||
| txList.add(reqBuilder.buildRequest()); | |||
| } | |||
| if (statistic) { | |||
| long elapsedTs = System.currentTimeMillis() - startTs; | |||
| ConsoleUtils.info( | |||
| "============ Performance of Preparing data account registering tx requests... TOTAL=%s; TPS=%.2f; TIME=%s millis ============", | |||
| count, (count * 1000.0 / elapsedTs), elapsedTs); | |||
| ConsoleUtils.info("====================================================="); | |||
| } | |||
| return txList; | |||
| } | |||
| public static ConsensusProvider getConsensusProvider(String provider) { | |||
| return ConsensusProviders.getProvider(provider); | |||
| } | |||
| public static List<TransactionRequest> prepareContractRequests(HashDigest ledgerHash, AsymmetricKeypair adminKey, | |||
| int count, boolean statistic, TransactionBatchProcessor txProc) { | |||
| // deploy contract | |||
| byte[] chainCode; | |||
| try { | |||
| // InputStream input = LedgerPerformanceTest.class.getClassLoader().getResourceAsStream("Setkv.contract"); | |||
| InputStream input = LedgerPerformanceTest.class.getClassLoader().getResourceAsStream("example1.jar"); | |||
| chainCode = new byte[input.available()]; | |||
| input.read(chainCode); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| return null; | |||
| } | |||
| TxBuilder txbuilder = new TxBuilder(ledgerHash); | |||
| BlockchainKeypair contractAccountKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| BlockchainIdentity contractIdentity = contractAccountKey.getIdentity(); | |||
| txbuilder.contracts().deploy(contractIdentity, chainCode); | |||
| // create data account | |||
| BlockchainKeypair dataAccountKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| BlockchainIdentity dataIdentity = dataAccountKey.getIdentity(); | |||
| txbuilder.dataAccounts().register(dataIdentity); | |||
| TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); | |||
| reqBuilder.signAsEndpoint(adminKey); | |||
| TransactionResponse resp = txProc.schedule(reqBuilder.buildRequest()); | |||
| System.out.println(resp.isSuccess()); | |||
| TransactionBatchResultHandle handle = txProc.prepare(); | |||
| handle.commit(); | |||
| try { | |||
| Thread.sleep(1000); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| long startTs = System.currentTimeMillis(); | |||
| List<TransactionRequest> txList = new ArrayList<>(); | |||
| for (int i = 0; i < count; i++) { | |||
| txbuilder = new TxBuilder(ledgerHash); | |||
| String args = dataIdentity.getAddress().toString() + "##" + Integer.toString(i) + "##" | |||
| + Integer.toString(i); | |||
| txbuilder.contractEvents().send(contractIdentity.getAddress(), "print", BytesDataList.singleText("hello")); | |||
| // txbuilder.contractEvents().send(contractIdentity.getAddress(), "print", args.getBytes()); | |||
| reqBuilder = txbuilder.prepareRequest(); | |||
| reqBuilder.signAsEndpoint(adminKey); | |||
| txList.add(reqBuilder.buildRequest()); | |||
| } | |||
| if (statistic) { | |||
| long elapsedTs = System.currentTimeMillis() - startTs; | |||
| ConsoleUtils.info( | |||
| "============ Performance of Preparing contract execute tx requests... TOTAL=%s; TPS=%.2f; TIME=%s millis ============", | |||
| count, (count * 1000.0 / elapsedTs), elapsedTs); | |||
| ConsoleUtils.info("====================================================="); | |||
| } | |||
| return txList; | |||
| } | |||
| public static NodeContext[] initLedgers(boolean optimized, CryptoAlgorithm hashAlg, DBType dbType, String provider, | |||
| String config) { | |||
| Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap = new ConcurrentHashMap<>(); | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting(); | |||
| Properties props = loadConsensusSetting(config); | |||
| ConsensusProvider csProvider = getConsensusProvider(provider); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props, | |||
| Utils.loadParticipantNodes()); | |||
| DBSetting dbsetting0; | |||
| DBSetting dbsetting1; | |||
| DBSetting dbsetting2; | |||
| DBSetting dbsetting3; | |||
| if (dbType == DBType.REDIS) { | |||
| dbsetting0 = DBSetting.createRedisDBSetting("redis://127.0.0.1:6079"); | |||
| dbsetting1 = DBSetting.createRedisDBSetting("redis://127.0.0.1:6179"); | |||
| dbsetting2 = DBSetting.createRedisDBSetting("redis://127.0.0.1:6279"); | |||
| dbsetting3 = DBSetting.createRedisDBSetting("redis://127.0.0.1:6379"); | |||
| cleanRedisDB(dbsetting0); | |||
| cleanRedisDB(dbsetting1); | |||
| cleanRedisDB(dbsetting2); | |||
| cleanRedisDB(dbsetting3); | |||
| } else if (dbType == DBType.ROCKSDB) { | |||
| String currDir = FileUtils.getCurrentDir() + File.separator + "rocks.db"; | |||
| String dbDir0 = new File(currDir, "rocksdb0.db").getAbsolutePath(); | |||
| String dbDir1 = new File(currDir, "rocksdb1.db").getAbsolutePath(); | |||
| String dbDir2 = new File(currDir, "rocksdb2.db").getAbsolutePath(); | |||
| String dbDir3 = new File(currDir, "rocksdb3.db").getAbsolutePath(); | |||
| // clean db first; | |||
| FileUtils.deleteFile(dbDir0); | |||
| FileUtils.deleteFile(dbDir1); | |||
| FileUtils.deleteFile(dbDir2); | |||
| FileUtils.deleteFile(dbDir3); | |||
| dbsetting0 = DBSetting.createRocksDBSetting("rocksdb://" + dbDir0); | |||
| dbsetting1 = DBSetting.createRocksDBSetting("rocksdb://" + dbDir1); | |||
| dbsetting2 = DBSetting.createRocksDBSetting("rocksdb://" + dbDir2); | |||
| dbsetting3 = DBSetting.createRocksDBSetting("rocksdb://" + dbDir3); | |||
| } else { | |||
| dbsetting0 = DBSetting.createMemoryDBSetting("memory://local/0"); | |||
| dbsetting1 = DBSetting.createMemoryDBSetting("memory://local/1"); | |||
| dbsetting2 = DBSetting.createMemoryDBSetting("memory://local/2"); | |||
| dbsetting3 = DBSetting.createMemoryDBSetting("memory://local/3"); | |||
| } | |||
| NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), | |||
| serviceRegisterMap, dbsetting0.connectionFactory); | |||
| NodeContext node1 = new NodeContext(initSetting.getConsensusParticipant(1).getInitializerAddress(), | |||
| serviceRegisterMap, dbsetting1.connectionFactory); | |||
| NodeContext node2 = new NodeContext(initSetting.getConsensusParticipant(2).getInitializerAddress(), | |||
| serviceRegisterMap, dbsetting2.connectionFactory); | |||
| NodeContext node3 = new NodeContext(initSetting.getConsensusParticipant(3).getInitializerAddress(), | |||
| serviceRegisterMap, dbsetting3.connectionFactory); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[0], Utils.PASSWORD); | |||
| AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, csProps, csProvider, | |||
| dbsetting0.connectionConfig, consolePrompter, !optimized, hashAlg); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[1], Utils.PASSWORD); | |||
| AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, csProps, csProvider, | |||
| dbsetting1.connectionConfig, consolePrompter, !optimized, hashAlg); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[2], Utils.PASSWORD); | |||
| AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, csProps, csProvider, | |||
| dbsetting2.connectionConfig, consolePrompter, !optimized, hashAlg); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(Utils.PRIV_KEYS[3], Utils.PASSWORD); | |||
| AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, csProps, csProvider, | |||
| dbsetting3.connectionConfig, consolePrompter, !optimized, hashAlg); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| node0.registLedger(ledgerHash0, dbsetting0.connectionConfig); | |||
| node1.registLedger(ledgerHash1, dbsetting1.connectionConfig); | |||
| node2.registLedger(ledgerHash2, dbsetting2.connectionConfig); | |||
| node3.registLedger(ledgerHash3, dbsetting3.connectionConfig); | |||
| return new NodeContext[] { node0, node1, node2, node3 }; | |||
| } | |||
| private static void cleanRedisDB(DBSetting dbsetting) { | |||
| RedisConnectionFactory redisConnFactory = (RedisConnectionFactory) dbsetting.connectionFactory; | |||
| JedisConnection dbConn = (JedisConnection) redisConnFactory.connect(dbsetting.connectionConfig.getUri()); | |||
| RedisStorageService redisStorage = (RedisStorageService) dbConn.getStorageService(); | |||
| redisStorage.clearDB(); | |||
| dbConn.close(); | |||
| } | |||
| public static LedgerInitProperties loadInitSetting() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_web2.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static Properties loadConsensusSetting(String config) { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource(config); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| return FileUtils.readProperties(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static class DBSetting { | |||
| private DBConnectionConfig connectionConfig; | |||
| private DbConnectionFactory connectionFactory; | |||
| public static DBSetting createMemoryDBSetting(String uri) { | |||
| DBSetting setting = new DBSetting(); | |||
| setting.connectionConfig = new DBConnectionConfig(uri); | |||
| setting.connectionFactory = new MemoryDBConnFactory(); | |||
| return setting; | |||
| } | |||
| public static DBSetting createRedisDBSetting(String uri) { | |||
| DBSetting setting = new DBSetting(); | |||
| setting.connectionConfig = new DBConnectionConfig(uri); | |||
| setting.connectionFactory = new RedisConnectionFactory(); | |||
| return setting; | |||
| } | |||
| public static DBSetting createRocksDBSetting(String uri) { | |||
| DBSetting setting = new DBSetting(); | |||
| setting.connectionConfig = new DBConnectionConfig(uri); | |||
| setting.connectionFactory = new RocksDBConnectionFactory(); | |||
| return setting; | |||
| } | |||
| } | |||
| private static class FreedomLedgerSecurityManager implements LedgerSecurityManager { | |||
| public static final FreedomLedgerSecurityManager INSTANCE = new FreedomLedgerSecurityManager(); | |||
| @Override | |||
| public SecurityPolicy createSecurityPolicy(Set<Bytes> endpoints, Set<Bytes> nodes) { | |||
| return new FreedomSecurityPolicy(endpoints, nodes); | |||
| } | |||
| } | |||
| private static class FreedomSecurityPolicy implements SecurityPolicy { | |||
| private Set<Bytes> endpoints; | |||
| private Set<Bytes> nodes; | |||
| public FreedomSecurityPolicy(Set<Bytes> endpoints, Set<Bytes> nodes) { | |||
| this.endpoints = endpoints; | |||
| this.nodes = nodes; | |||
| } | |||
| @Override | |||
| public Set<Bytes> getEndpoints() { | |||
| return endpoints; | |||
| } | |||
| @Override | |||
| public Set<Bytes> getNodes() { | |||
| return nodes; | |||
| } | |||
| @Override | |||
| public boolean isEndpointEnable(LedgerPermission permission, MultiIDsPolicy midPolicy) { | |||
| return true; | |||
| } | |||
| @Override | |||
| public boolean isEndpointEnable(TransactionPermission permission, MultiIDsPolicy midPolicy) { | |||
| return true; | |||
| } | |||
| @Override | |||
| public boolean isNodeEnable(LedgerPermission permission, MultiIDsPolicy midPolicy) { | |||
| return true; | |||
| } | |||
| @Override | |||
| public boolean isNodeEnable(TransactionPermission permission, MultiIDsPolicy midPolicy) { | |||
| return true; | |||
| } | |||
| @Override | |||
| public void checkEndpointPermission(LedgerPermission permission, MultiIDsPolicy midPolicy) | |||
| throws LedgerSecurityException { | |||
| } | |||
| @Override | |||
| public void checkEndpointPermission(TransactionPermission permission, MultiIDsPolicy midPolicy) | |||
| throws LedgerSecurityException { | |||
| } | |||
| @Override | |||
| public void checkNodePermission(LedgerPermission permission, MultiIDsPolicy midPolicy) throws LedgerSecurityException { | |||
| } | |||
| @Override | |||
| public void checkNodePermission(TransactionPermission permission, MultiIDsPolicy midPolicy) | |||
| throws LedgerSecurityException { | |||
| } | |||
| @Override | |||
| public boolean isEndpointValid(MultiIDsPolicy midPolicy) { | |||
| return true; | |||
| } | |||
| @Override | |||
| public boolean isNodeValid(MultiIDsPolicy midPolicy) { | |||
| return true; | |||
| } | |||
| @Override | |||
| public void checkEndpointValidity(MultiIDsPolicy midPolicy) throws LedgerSecurityException { | |||
| } | |||
| @Override | |||
| public void checkNodeValidity(MultiIDsPolicy midPolicy) throws LedgerSecurityException { | |||
| } | |||
| } | |||
| } | |||
| @@ -1,135 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| import com.jd.blockchain.storage.service.KVStorageService; | |||
| import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
| import com.jd.blockchain.storage.service.impl.redis.RedisConnectionFactory; | |||
| import com.jd.blockchain.utils.ArgumentSet; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.ConsoleUtils; | |||
| import com.jd.blockchain.utils.codec.Base58Utils; | |||
| import com.jd.blockchain.utils.io.BytesUtils; | |||
| import com.jd.blockchain.utils.security.ShaUtils; | |||
| import java.io.IOException; | |||
| import java.util.Random; | |||
| import java.util.concurrent.ForkJoinPool; | |||
| import java.util.concurrent.ForkJoinTask; | |||
| import java.util.concurrent.RecursiveAction; | |||
| public class PerformanceTest { | |||
| public static void main(String[] args) { | |||
| try { | |||
| boolean testLedger = !ArgumentSet.hasOption(args, "-test=storage"); | |||
| if (testLedger) { | |||
| // LedgerPerformanceTest.test(new String[]{"-silent", "-usertest", "-o"}); | |||
| LedgerPerformanceTest.test(new String[]{"-silent", "-o", "-rocksdb"}); | |||
| return; | |||
| } | |||
| // GlobalPerformanceTest.test(args); | |||
| // testRedisWriting(args); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| }finally { | |||
| ForkJoinPool.commonPool().shutdown(); | |||
| } | |||
| } | |||
| private static void testRedisWriting(String[] args) { | |||
| ConsoleUtils.info("-------------------- start redis test --------------------"); | |||
| RedisConnectionFactory redisConnFactory = new RedisConnectionFactory(); | |||
| DbConnection conn = redisConnFactory.connect("redis://127.0.0.1:6079"); | |||
| KVStorageService storage = conn.getStorageService(); | |||
| VersioningKVStorage vs = storage.getVersioningKVStorage(); | |||
| byte[] data = BytesUtils.toBytes("TestDATA"); | |||
| int count = 100000; | |||
| if (args.length > 0) { | |||
| count = Integer.parseInt(args[0]); | |||
| } | |||
| if (args.length > 0) { | |||
| for (String arg : args) { | |||
| if (arg.startsWith("-threshold=")) { | |||
| int threshold = Integer.parseInt(arg.substring("-threshold=".length())); | |||
| if (threshold > 0) { | |||
| RedisWriteTestTask.THRESHOLD = threshold; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| Random rand = new Random(); | |||
| byte[] nameBytes = new byte[16]; | |||
| rand.nextBytes(nameBytes); | |||
| String name = Base58Utils.encode(ShaUtils.hash_256(nameBytes)); | |||
| rand.nextBytes(nameBytes); | |||
| name = name + "/" + Base58Utils.encode(ShaUtils.hash_256(nameBytes)); | |||
| rand.nextBytes(nameBytes); | |||
| name = name + "/" + Base58Utils.encode(ShaUtils.hash_256(nameBytes)); | |||
| long startTS = System.currentTimeMillis(); | |||
| RedisWriteTestTask task = new RedisWriteTestTask(name, 0, count, data, vs); | |||
| ForkJoinPool.commonPool().invoke(task); | |||
| long elapsedTS = System.currentTimeMillis() - startTS; | |||
| double globalTPS = count * 1000.00D / elapsedTS; | |||
| ConsoleUtils.info("\r\n**********************************************"); | |||
| ConsoleUtils.info("写入KEY总数:%s; 总体TPS:%.2f;", count, globalTPS); | |||
| ConsoleUtils.info("**********************************************\r\n"); | |||
| try { | |||
| conn.close(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| public static class RedisWriteTestTask extends RecursiveAction { | |||
| private static final long serialVersionUID = -8415596564326385834L; | |||
| public static int THRESHOLD = 800; | |||
| private int offset; | |||
| private int count; | |||
| private byte[] data; | |||
| private String name; | |||
| private VersioningKVStorage vs; | |||
| public RedisWriteTestTask(String name, int offset, int count, byte[] data, VersioningKVStorage vs) { | |||
| this.name = name; | |||
| this.offset = offset; | |||
| this.count = count; | |||
| this.data = data; | |||
| this.vs = vs; | |||
| } | |||
| @Override | |||
| protected void compute() { | |||
| if (count > THRESHOLD) { | |||
| int count1 = count / 2; | |||
| RedisWriteTestTask task1 = new RedisWriteTestTask(name, offset, count1, data, vs); | |||
| RedisWriteTestTask task2 = new RedisWriteTestTask(name, offset + count1, count - count1, data, vs); | |||
| ForkJoinTask.invokeAll(task1, task2); | |||
| } else { | |||
| for (int i = 0; i < count; i++) { | |||
| String key = String.format("[%s][%s]-TEST-KEY-%s", name, offset, i); | |||
| vs.set(Bytes.fromString(key), data, -1); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,46 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.CyclicBarrier; | |||
| import com.jd.blockchain.ledger.PreparedTransaction; | |||
| import com.jd.blockchain.utils.ConsoleUtils; | |||
| public class TransactionCommitter { | |||
| private PreparedTransaction[] ptxs; | |||
| private int startIndex; | |||
| private int count; | |||
| public TransactionCommitter(PreparedTransaction[] ptxs, int startIndex, int count) { | |||
| this.ptxs = ptxs; | |||
| this.startIndex = startIndex; | |||
| this.count = count; | |||
| } | |||
| public void start(CyclicBarrier barrier, CountDownLatch latch) { | |||
| Thread thrd = new Thread(new Runnable() { | |||
| @Override | |||
| public void run() { | |||
| try { | |||
| barrier.await(); | |||
| } catch (Exception e) { | |||
| System.out.println(" Barrier await error! --" + e.getMessage()); | |||
| e.printStackTrace(); | |||
| } | |||
| ConsoleUtils.info("Start committing... [%s]", startIndex); | |||
| try { | |||
| for (int i = 0; i < count; i++) { | |||
| ptxs[startIndex + i].commit(); | |||
| } | |||
| } catch (Exception e) { | |||
| System.out.println("Error occured on committing! --" + e.getMessage()); | |||
| e.printStackTrace(); | |||
| } | |||
| latch.countDown(); | |||
| } | |||
| }); | |||
| thrd.start(); | |||
| } | |||
| } | |||
| @@ -1,294 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.perf; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Map; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| import com.jd.blockchain.ledger.ParticipantNodeState; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
| import com.jd.blockchain.crypto.CryptoProvider; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.crypto.SignatureDigest; | |||
| import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
| import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
| import com.jd.blockchain.ledger.CryptoSetting; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.LedgerConfiguration; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.InitConsensusServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| public class Utils { | |||
| public static final String PASSWORD = "abc"; | |||
| public static final String[] PUB_KEYS = { "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9", | |||
| "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX", | |||
| "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x", | |||
| "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" }; | |||
| public static final String[] PRIV_KEYS = { | |||
| "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x", | |||
| "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT", | |||
| "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF", | |||
| "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" }; | |||
| private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
| SMCryptoService.class.getName() }; | |||
| private Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap = new ConcurrentHashMap<>(); | |||
| public static LedgerInitProperties loadInitSetting() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_web2.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static Properties loadConsensusSetting() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("bftsmart.config"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| return FileUtils.readProperties(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static ParticipantNode[] loadParticipantNodes() { | |||
| ParticipantNode[] participantNodes = new ParticipantNode[PUB_KEYS.length]; | |||
| for (int i = 0; i < PUB_KEYS.length; i++) { | |||
| participantNodes[i] = new PartNode(i, KeyGenUtils.decodePubKey(PUB_KEYS[i]), ParticipantNodeState.ACTIVED); | |||
| } | |||
| return participantNodes; | |||
| } | |||
| public static class NodeContext { | |||
| private LedgerManager ledgerManager = new LedgerManager(); | |||
| private DbConnectionFactory dbConnFactory; | |||
| private InitConsensusServiceFactory initCsServiceFactory; | |||
| private LedgerInitProcess initProcess; | |||
| private AsymmetricKeypair partiKey; | |||
| public AsymmetricKeypair getPartiKey() { | |||
| return partiKey; | |||
| } | |||
| public LedgerManager getLedgerManager() { | |||
| return ledgerManager; | |||
| } | |||
| public DbConnectionFactory getStorageDb() { | |||
| return dbConnFactory; | |||
| } | |||
| public NodeContext(NetworkAddress address, Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap, | |||
| DbConnectionFactory dbConnFactory) { | |||
| this.dbConnFactory = dbConnFactory; | |||
| this.initCsServiceFactory = new MultiThreadInterInvokerFactory(serviceRegisterMap); | |||
| LedgerInitializeWebController initController = new LedgerInitializeWebController(dbConnFactory, | |||
| initCsServiceFactory); | |||
| serviceRegisterMap.put(address, initController); | |||
| this.initProcess = initController; | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter) { | |||
| partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig, | |||
| Prompter prompter, boolean autoVerifyHash) { | |||
| CryptoAlgorithm algorithm = Crypto.getAlgorithm("SHA256"); | |||
| return startInit(currentId, privKey, setting, csProps, consensusProvider, dbConnConfig, prompter, | |||
| autoVerifyHash, algorithm); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig, | |||
| Prompter prompter, boolean autoVerifyHash, CryptoAlgorithm hashAlg) { | |||
| CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
| for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
| supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
| } | |||
| CryptoConfig cryptoSetting = new CryptoConfig(); | |||
| cryptoSetting.setSupportedProviders(supportedProviders); | |||
| cryptoSetting.setSupportedProviders(supportedProviders); | |||
| cryptoSetting.setAutoVerifyHash(autoVerifyHash); | |||
| cryptoSetting.setHashAlgorithm(hashAlg); | |||
| return startInit(currentId, privKey, setting, csProps, consensusProvider, dbConnConfig, prompter, | |||
| cryptoSetting); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
| ConsensusSettings csProps, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig, | |||
| Prompter prompter, CryptoSetting cryptoSetting) { | |||
| LedgerInitConfiguration ledgerInitConfig = LedgerInitConfiguration.create(setting); | |||
| ledgerInitConfig.getLedgerSettings().setCryptoSetting(cryptoSetting); | |||
| partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public LedgerQuery registLedger(HashDigest ledgerHash, DBConnectionConfig dbConnConf) { | |||
| return ledgerManager.register(ledgerHash, dbConnFactory.connect(dbConnConf.getUri()).getStorageService()); | |||
| } | |||
| } | |||
| private static class MultiThreadInterInvokerFactory implements InitConsensusServiceFactory { | |||
| private Map<NetworkAddress, LedgerInitConsensusService> nodeConsesusServices; | |||
| public MultiThreadInterInvokerFactory(Map<NetworkAddress, LedgerInitConsensusService> nodeConsesusServices) { | |||
| this.nodeConsesusServices = nodeConsesusServices; | |||
| } | |||
| @Override | |||
| public LedgerInitConsensusService connect(NetworkAddress endpointAddress) { | |||
| return new InitConsensusServiceProxy(nodeConsesusServices.get(endpointAddress)); | |||
| } | |||
| } | |||
| private static class InitConsensusServiceProxy implements LedgerInitConsensusService { | |||
| private LedgerInitConsensusService initCsService; | |||
| public InitConsensusServiceProxy(LedgerInitConsensusService initCsService) { | |||
| this.initCsService = initCsService; | |||
| } | |||
| @Override | |||
| public LedgerInitProposal requestPermission(int requesterId, SignatureDigest signature) { | |||
| ThreadInvoker<LedgerInitProposal> invoker = new ThreadInvoker<LedgerInitProposal>() { | |||
| @Override | |||
| protected LedgerInitProposal invoke() { | |||
| return initCsService.requestPermission(requesterId, signature); | |||
| } | |||
| }; | |||
| return invoker.startAndWait(); | |||
| } | |||
| @Override | |||
| public LedgerInitDecision synchronizeDecision(LedgerInitDecision initDecision) { | |||
| ThreadInvoker<LedgerInitDecision> invoker = new ThreadInvoker<LedgerInitDecision>() { | |||
| @Override | |||
| protected LedgerInitDecision invoke() { | |||
| return initCsService.synchronizeDecision(initDecision); | |||
| } | |||
| }; | |||
| return invoker.startAndWait(); | |||
| } | |||
| } | |||
| private static class PartNode implements ParticipantNode { | |||
| private int id; | |||
| private Bytes address; | |||
| private String name; | |||
| private PubKey pubKey; | |||
| private ParticipantNodeState participantNodeState; | |||
| public PartNode(int id, PubKey pubKey, ParticipantNodeState participantNodeState) { | |||
| this(id, id + "", pubKey, participantNodeState); | |||
| } | |||
| public PartNode(int id, String name, PubKey pubKey, ParticipantNodeState participantNodeState) { | |||
| this.id = id; | |||
| this.name = name; | |||
| this.pubKey = pubKey; | |||
| this.address = AddressEncoding.generateAddress(pubKey); | |||
| this.participantNodeState = participantNodeState; | |||
| } | |||
| @Override | |||
| public int getId() { | |||
| return id; | |||
| } | |||
| @Override | |||
| public Bytes getAddress() { | |||
| return address; | |||
| } | |||
| @Override | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| @Override | |||
| public PubKey getPubKey() { | |||
| return pubKey; | |||
| } | |||
| @Override | |||
| public ParticipantNodeState getParticipantNodeState() { | |||
| return participantNodeState; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,155 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ###### Consensus Participant0 ###### | |||
| ############################################ | |||
| system.server.0.network.host=127.0.0.1 | |||
| system.server.0.network.port=8910 | |||
| system.server.0.network.secure=false | |||
| ############################################ | |||
| ###### #Consensus Participant1 ###### | |||
| ############################################ | |||
| system.server.1.network.host=127.0.0.1 | |||
| system.server.1.network.port=8920 | |||
| system.server.1.network.secure=false | |||
| ############################################ | |||
| ###### #Consensus Participant2 ###### | |||
| ############################################ | |||
| system.server.2.network.host=127.0.0.1 | |||
| system.server.2.network.port=8930 | |||
| system.server.2.network.secure=false | |||
| ############################################ | |||
| ###### Consensus Participant3 ###### | |||
| ############################################ | |||
| system.server.3.network.host=127.0.0.1 | |||
| system.server.3.network.port=8940 | |||
| system.server.3.network.secure=false | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| #system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 5000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| #system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,85 +0,0 @@ | |||
| #账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
| ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
| #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
| ledger.name= | |||
| #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
| cons_parti.count=4 | |||
| #第0个参与方的名称; | |||
| cons_parti.0.name=jd.com | |||
| #第0个参与方的公钥文件路径; | |||
| cons_parti.0.pubkey-path=keys/jd-com.pub | |||
| #第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.0.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
| #第0个参与方的共识服务的主机地址; | |||
| cons_parti.0.consensus.host=127.0.0.1 | |||
| #第0个参与方的共识服务的端口; | |||
| cons_parti.0.consensus.port=8900 | |||
| #第0个参与方的共识服务是否开启安全连接; | |||
| cons_parti.0.consensus.secure=false | |||
| #第0个参与方的账本初始服务的主机; | |||
| cons_parti.0.initializer.host=127.0.0.1 | |||
| #第0个参与方的账本初始服务的端口; | |||
| cons_parti.0.initializer.port=8800 | |||
| #第0个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.0.initializer.secure=false | |||
| #第1个参与方的名称; | |||
| cons_parti.1.name=at.com | |||
| #第1个参与方的公钥文件路径; | |||
| cons_parti.1.pubkey-path=keys/at-com.pub | |||
| #第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.1.pubkey=endPsK36sC5JdPCDPDAXUwZtS3sxEmqEhFcC4whayAsTTh8Z6eoZ | |||
| #第1个参与方的共识服务的主机地址; | |||
| cons_parti.1.consensus.host=127.0.0.1 | |||
| #第1个参与方的共识服务的端口; | |||
| cons_parti.1.consensus.port=8910 | |||
| #第1个参与方的共识服务是否开启安全连接; | |||
| cons_parti.1.consensus.secure=false | |||
| #第1个参与方的账本初始服务的主机; | |||
| cons_parti.1.initializer.host=127.0.0.1 | |||
| #第1个参与方的账本初始服务的端口; | |||
| cons_parti.1.initializer.port=8810 | |||
| #第1个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.1.initializer.secure=false | |||
| #第2个参与方的名称; | |||
| cons_parti.2.name=bt.com | |||
| #第2个参与方的公钥文件路径; | |||
| cons_parti.2.pubkey-path=keys/bt-com.pub | |||
| #第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.2.pubkey=endPsK36jEG281HMHeh6oSqzqLkT95DTnCM6REDURjdb2c67uR3R | |||
| #第2个参与方的共识服务的主机地址; | |||
| cons_parti.2.consensus.host=127.0.0.1 | |||
| #第2个参与方的共识服务的端口; | |||
| cons_parti.2.consensus.port=8920 | |||
| #第2个参与方的共识服务是否开启安全连接; | |||
| cons_parti.2.consensus.secure=false | |||
| #第2个参与方的账本初始服务的主机; | |||
| cons_parti.2.initializer.host=127.0.0.1 | |||
| #第2个参与方的账本初始服务的端口; | |||
| cons_parti.2.initializer.port=8820 | |||
| #第2个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.2.initializer.secure=false | |||
| #第3个参与方的名称; | |||
| cons_parti.3.name=xt.com | |||
| #第3个参与方的公钥文件路径; | |||
| cons_parti.3.pubkey-path=keys/xt-com.pub | |||
| #第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.3.pubkey=endPsK36nse1dck4uF19zPvAMijCV336Y3zWdgb4rQG8QoRj5ktR | |||
| #第3个参与方的共识服务的主机地址; | |||
| cons_parti.3.consensus.host=127.0.0.1 | |||
| #第3个参与方的共识服务的端口; | |||
| cons_parti.3.consensus.port=8930 | |||
| #第3个参与方的共识服务是否开启安全连接; | |||
| cons_parti.3.consensus.secure=false | |||
| #第3个参与方的账本初始服务的主机; | |||
| cons_parti.3.initializer.host=127.0.0.1 | |||
| #第3个参与方的账本初始服务的端口; | |||
| cons_parti.3.initializer.port=8830 | |||
| #第3个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.3.initializer.secure=false | |||
| @@ -1,85 +0,0 @@ | |||
| #账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
| ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
| #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
| ledger.name= | |||
| #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
| cons_parti.count=4 | |||
| #第0个参与方的名称; | |||
| cons_parti.0.name=jd.com | |||
| #第0个参与方的公钥文件路径; | |||
| cons_parti.0.pubkey-path=keys/jd-com.pub | |||
| #第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.0.pubkey=3snPdw7i7PapsDoW185c3kfK6p8s6SwiJAdEUzgnfeuUox12nxgzXu | |||
| #第0个参与方的共识服务的主机地址; | |||
| cons_parti.0.consensus.host=127.0.0.1 | |||
| #第0个参与方的共识服务的端口; | |||
| cons_parti.0.consensus.port=8900 | |||
| #第0个参与方的共识服务是否开启安全连接; | |||
| cons_parti.0.consensus.secure=true | |||
| #第0个参与方的账本初始服务的主机; | |||
| cons_parti.0.initializer.host=127.0.0.1 | |||
| #第0个参与方的账本初始服务的端口; | |||
| cons_parti.0.initializer.port=8800 | |||
| #第0个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.0.initializer.secure=true | |||
| #第1个参与方的名称; | |||
| cons_parti.1.name=at.com | |||
| #第1个参与方的公钥文件路径; | |||
| cons_parti.1.pubkey-path=keys/at-com.pub | |||
| #第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.1.pubkey=3snPdw7i7Ph1SYLQt9uqVEqiuvNXjxCdGvEdN6otJsg5rbr7Aze7kf | |||
| #第1个参与方的共识服务的主机地址; | |||
| cons_parti.1.consensus.host=127.0.0.1 | |||
| #第1个参与方的共识服务的端口; | |||
| cons_parti.1.consensus.port=8910 | |||
| #第1个参与方的共识服务是否开启安全连接; | |||
| cons_parti.1.consensus.secure=false | |||
| #第1个参与方的账本初始服务的主机; | |||
| cons_parti.1.initializer.host=127.0.0.1 | |||
| #第1个参与方的账本初始服务的端口; | |||
| cons_parti.1.initializer.port=8810 | |||
| #第1个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.1.initializer.secure=false | |||
| #第2个参与方的名称; | |||
| cons_parti.2.name=bt.com | |||
| #第2个参与方的公钥文件路径; | |||
| cons_parti.2.pubkey-path=keys/bt-com.pub | |||
| #第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.2.pubkey=3snPdw7i7PezptA6dNBkotPjmKEbTkY8fmusLBnfj8Cf7eFwhWDwKr | |||
| #第2个参与方的共识服务的主机地址; | |||
| cons_parti.2.consensus.host=127.0.0.1 | |||
| #第2个参与方的共识服务的端口; | |||
| cons_parti.2.consensus.port=8920 | |||
| #第2个参与方的共识服务是否开启安全连接; | |||
| cons_parti.2.consensus.secure=false | |||
| #第2个参与方的账本初始服务的主机; | |||
| cons_parti.2.initializer.host=127.0.0.1 | |||
| #第2个参与方的账本初始服务的端口; | |||
| cons_parti.2.initializer.port=8820 | |||
| #第2个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.2.initializer.secure=true | |||
| #第3个参与方的名称; | |||
| cons_parti.3.name=xt.com | |||
| #第3个参与方的公钥文件路径; | |||
| cons_parti.3.pubkey-path=keys/xt-com.pub | |||
| #第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.3.pubkey=3snPdw7i7PerZYfRzEB61SAN9tFK4yHm9wUSRtkLSSGXHkQRbB5PkS | |||
| #第3个参与方的共识服务的主机地址; | |||
| cons_parti.3.consensus.host=127.0.0.1 | |||
| #第3个参与方的共识服务的端口; | |||
| cons_parti.3.consensus.port=8930 | |||
| #第3个参与方的共识服务是否开启安全连接; | |||
| cons_parti.3.consensus.secure=false | |||
| #第3个参与方的账本初始服务的主机; | |||
| cons_parti.3.initializer.host=127.0.0.1 | |||
| #第3个参与方的账本初始服务的端口; | |||
| cons_parti.3.initializer.port=8830 | |||
| #第3个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.3.initializer.secure=false | |||
| @@ -1,74 +0,0 @@ | |||
| #账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
| ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
| #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
| ledger.name==myledger | |||
| #声明的账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区 | |||
| created-time=2019-08-01 14:26:58.069+0800 | |||
| #共识服务提供者;必须; | |||
| consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
| #共识服务的参数配置;必须; | |||
| consensus.conf=classpath:bftsmart.config | |||
| #密码服务提供者列表,以英文逗点“,”分隔;必须; | |||
| crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ | |||
| com.jd.blockchain.crypto.service.sm.SMCryptoService | |||
| #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
| cons_parti.count=4 | |||
| #第0个参与方的名称; | |||
| cons_parti.0.name=jd.com | |||
| #第0个参与方的公钥文件路径; | |||
| cons_parti.0.pubkey-path=keys/jd-com.pub | |||
| #第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 | |||
| #第0个参与方的账本初始服务的主机; | |||
| cons_parti.0.initializer.host=127.0.0.1 | |||
| #第0个参与方的账本初始服务的端口; | |||
| cons_parti.0.initializer.port=9800 | |||
| #第0个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.0.initializer.secure=false | |||
| #第1个参与方的名称; | |||
| cons_parti.1.name=at.com | |||
| #第1个参与方的公钥文件路径; | |||
| cons_parti.1.pubkey-path=keys/at-com.pub | |||
| #第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX | |||
| #第1个参与方的账本初始服务的主机; | |||
| cons_parti.1.initializer.host=127.0.0.1 | |||
| #第1个参与方的账本初始服务的端口; | |||
| cons_parti.1.initializer.port=9810 | |||
| #第1个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.1.initializer.secure=false | |||
| #第2个参与方的名称; | |||
| cons_parti.2.name=bt.com | |||
| #第2个参与方的公钥文件路径; | |||
| cons_parti.2.pubkey-path=keys/bt-com.pub | |||
| #第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.2.pubkey=3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x | |||
| #第2个参与方的账本初始服务的主机; | |||
| cons_parti.2.initializer.host=127.0.0.1 | |||
| #第2个参与方的账本初始服务的端口; | |||
| cons_parti.2.initializer.port=9820 | |||
| #第2个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.2.initializer.secure=false | |||
| #第3个参与方的名称; | |||
| cons_parti.3.name=xt.com | |||
| #第3个参与方的公钥文件路径; | |||
| cons_parti.3.pubkey-path=keys/xt-com.pub | |||
| #第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk | |||
| #第3个参与方的账本初始服务的主机; | |||
| cons_parti.3.initializer.host=127.0.0.1 | |||
| #第3个参与方的账本初始服务的端口; | |||
| cons_parti.3.initializer.port=9830 | |||
| #第3个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.3.initializer.secure=false | |||
| @@ -1,12 +0,0 @@ | |||
| system.msg.queue.server=nats://127.0.0.1:4222 | |||
| system.msg.queue.topic.tx=tx-topic | |||
| system.msg.queue.topic.bl=bl-topic | |||
| system.msg.queue.topic.msg=msg-topic | |||
| system.msg.queue.block.txsize=1000 | |||
| system.msg.queue.block.maxdelay=2000 | |||
| system.servers.num=4 | |||
| system.server.0.pubkey=endPsK36koyFr1D245Sa9j83vt6pZUdFBJoJRB3xAsWM6cwhRbna | |||
| system.server.1.pubkey=endPsK36sC5JdPCDPDAXUwZtS3sxEmqEhFcC4whayAsTTh8Z6eoZ | |||
| system.server.2.pubkey=endPsK36jEG281HMHeh6oSqzqLkT95DTnCM6REDURjdb2c67uR3R | |||
| system.server.3.pubkey=endPsK36nse1dck4uF19zPvAMijCV336Y3zWdgb4rQG8QoRj5ktR | |||
| @@ -1,121 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 4000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 10000 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 1 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 4000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = false | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,743 +0,0 @@ | |||
| /** | |||
| * Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
| * FileName: test.com.jd.blockchain.intgr.perf.IntegrationBase | |||
| * Author: shaozhuguang | |||
| * Department: 区块链研发部 | |||
| * Date: 2018/12/25 下午3:40 | |||
| * Description: | |||
| */ | |||
| package test.com.jd.blockchain.intgr; | |||
| import static com.jd.blockchain.transaction.ContractReturnValue.decode; | |||
| import static org.junit.Assert.assertArrayEquals; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNotNull; | |||
| import static org.junit.Assert.assertTrue; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.net.URL; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.Random; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.atomic.AtomicLong; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.*; | |||
| import org.apache.commons.io.FileUtils; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
| //import com.jd.blockchain.contract.ReadContract; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.transaction.GenericValueHolder; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| /** | |||
| * | |||
| * @author shaozhuguang | |||
| * @create 2018/12/25 | |||
| * @since 1.0.0 | |||
| */ | |||
| public class IntegrationBase { | |||
| public static String KEY_TOTAL = "total"; | |||
| static { | |||
| DataContractRegistry.register(LedgerInitOperation.class); | |||
| DataContractRegistry.register(UserRegisterOperation.class); | |||
| } | |||
| public static final String PASSWORD = "abc"; | |||
| public static final String[] PUB_KEYS = { | |||
| "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9", | |||
| "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX", | |||
| "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x", | |||
| "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" }; | |||
| public static final String[] PRIV_KEYS = { | |||
| "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x", | |||
| "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT", | |||
| "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF", | |||
| "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" }; | |||
| public static final AtomicLong validLong = new AtomicLong(); | |||
| public static KeyPairResponse testSDK_RegisterUser(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService) { | |||
| // 注册用户,并验证最终写入; | |||
| BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.users().register(user.getIdentity()); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| HashDigest transactionHash = ptx.getHash(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| KeyPairResponse keyPairResponse = new KeyPairResponse(); | |||
| keyPairResponse.keyPair = user; | |||
| keyPairResponse.txResp = txResp; | |||
| keyPairResponse.txHash = transactionHash; | |||
| return keyPairResponse; | |||
| } | |||
| public static KeyPairResponse testSDK_BlockFullRollBack(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService) { | |||
| BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| //Register user account | |||
| txTpl.users().register(user.getIdentity()); | |||
| PreparedTransaction prepTx = txTpl.prepare(); | |||
| HashDigest transactionHash = prepTx.getHash(); | |||
| prepTx.sign(adminKey); | |||
| //Commit transaction | |||
| TransactionResponse transactionResponse = prepTx.commit(); | |||
| //The whole block will rollback, due to storage error | |||
| assertEquals(transactionResponse.getExecutionState().CODE, TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK.CODE); | |||
| KeyPairResponse keyPairResponse = new KeyPairResponse(); | |||
| keyPairResponse.keyPair = user; | |||
| keyPairResponse.txResp = transactionResponse; | |||
| keyPairResponse.txHash = transactionHash; | |||
| return keyPairResponse; | |||
| } | |||
| public static KeyPairResponse testSDK_RegisterDataAccount(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService) { | |||
| // 注册数据账户,并验证最终写入; | |||
| BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.dataAccounts().register(dataAccount.getIdentity()); | |||
| // txTpl.dataAccount(dataAccount.getAddress()).setInt64("total", 200, -1); | |||
| // txTpl.dataAccount(dataAccount.getAddress()).set("param1", "v", -1); | |||
| // txTpl.dataAccount(dataAccount.getAddress()).set("param2", 200, -1); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| HashDigest transactionHash = ptx.getHash(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| KeyPairResponse keyPairResponse = new KeyPairResponse(); | |||
| keyPairResponse.keyPair = dataAccount; | |||
| keyPairResponse.txResp = txResp; | |||
| keyPairResponse.txHash = transactionHash; | |||
| return keyPairResponse; | |||
| } | |||
| public static KvResponse testSDK_InsertData(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService, Bytes dataAccount) { | |||
| // 在本地定义注册账号的 TX; | |||
| TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash); | |||
| // -------------------------------------- | |||
| // 将商品信息写入到指定的账户中; | |||
| // 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; | |||
| String dataKey = "jingdong" + System.currentTimeMillis() + new Random().nextInt(100000); | |||
| String dataVal = "www.jd.com"; | |||
| txTemp.dataAccount(dataAccount).setText(dataKey, dataVal, -1); | |||
| // TX 准备就绪; | |||
| PreparedTransaction prepTx = txTemp.prepare(); | |||
| HashDigest transactionHash = prepTx.getHash(); | |||
| // 使用私钥进行签名; | |||
| prepTx.sign(adminKey); | |||
| // 提交交易; | |||
| TransactionResponse txResp = prepTx.commit(); | |||
| KvResponse kvResponse = new KvResponse(); | |||
| kvResponse.ledgerHash = ledgerHash; | |||
| kvResponse.dataAccount = dataAccount; | |||
| kvResponse.txResp = txResp; | |||
| kvResponse.txHash = transactionHash; | |||
| kvResponse.key = dataKey; | |||
| kvResponse.value = dataVal; | |||
| return kvResponse; | |||
| } | |||
| public static KeyPairResponse testSDK_RegisterParticipant(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService) { | |||
| // 注册参与方,并验证最终写入; | |||
| BlockchainKeypair participant = BlockchainKeyGenerator.getInstance().generate(); | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.participants().register("peer4", new BlockchainIdentityData(participant.getPubKey()), new NetworkAddress("127.0.0.1", 20000)); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| HashDigest transactionHash = ptx.getHash(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| KeyPairResponse keyPairResponse = new KeyPairResponse(); | |||
| keyPairResponse.keyPair = participant; | |||
| keyPairResponse.txResp = txResp; | |||
| keyPairResponse.txHash = transactionHash; | |||
| return keyPairResponse; | |||
| } | |||
| public static KeyPairResponse testSDK_UpdateParticipantState(AsymmetricKeypair adminKey, BlockchainKeypair participantKeyPair, HashDigest ledgerHash, | |||
| BlockchainService blockchainService) { | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| ParticipantInfoData participantInfoData = new ParticipantInfoData("peer4", participantKeyPair.getPubKey(), new NetworkAddress("127.0.0.1", 20000)); | |||
| txTpl.states().update(new BlockchainIdentityData(participantInfoData.getPubKey()), participantInfoData.getNetworkAddress(), ParticipantNodeState.ACTIVED); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| HashDigest transactionHash = ptx.getHash(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| KeyPairResponse keyPairResponse = new KeyPairResponse(); | |||
| keyPairResponse.keyPair = participantKeyPair; | |||
| keyPairResponse.txResp = txResp; | |||
| keyPairResponse.txHash = transactionHash; | |||
| return keyPairResponse; | |||
| } | |||
| public static void validKeyPair(IntegrationBase.KeyPairResponse keyPairResponse, LedgerQuery ledgerRepository, | |||
| KeyPairType keyPairType) { | |||
| TransactionResponse txResp = keyPairResponse.txResp; | |||
| HashDigest transactionHash = keyPairResponse.txHash; | |||
| BlockchainKeypair keyPair = keyPairResponse.keyPair; | |||
| long index = validLong.incrementAndGet(); | |||
| System.out.printf("validKeyPair start %s \r\n", index); | |||
| ledgerRepository.retrieveLatestBlock(); | |||
| assertEquals(txResp.getExecutionState(), TransactionState.SUCCESS); | |||
| assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); | |||
| assertEquals(txResp.getContentHash(), transactionHash); | |||
| assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); | |||
| if (keyPairType == KeyPairType.USER) { | |||
| assertTrue(ledgerRepository.getUserAccountSet(ledgerRepository.getLatestBlock()) | |||
| .contains(keyPair.getAddress())); | |||
| } | |||
| if (keyPairType == KeyPairType.DATAACCOUNT) { | |||
| assertNotNull(ledgerRepository.getDataAccountSet(ledgerRepository.getLatestBlock()) | |||
| .getAccount(keyPair.getAddress())); | |||
| } | |||
| System.out.printf("validKeyPair end %s \r\n", index); | |||
| } | |||
| public static void validKeyPair(IntegrationBase.KeyPairResponse keyPairResponse, LedgerQuery ledgerRepository, | |||
| KeyPairType keyPairType, CountDownLatch countDownLatch) { | |||
| TransactionResponse txResp = keyPairResponse.txResp; | |||
| HashDigest transactionHash = keyPairResponse.txHash; | |||
| BlockchainKeypair keyPair = keyPairResponse.keyPair; | |||
| ledgerRepository.retrieveLatestBlock(); | |||
| assertEquals(txResp.getExecutionState(), TransactionState.SUCCESS); | |||
| assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); | |||
| assertEquals(txResp.getContentHash(), transactionHash); | |||
| assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); | |||
| if (keyPairType == KeyPairType.USER) { | |||
| assertTrue(ledgerRepository.getUserAccountSet(ledgerRepository.getLatestBlock()) | |||
| .contains(keyPair.getAddress())); | |||
| } | |||
| if (keyPairType == KeyPairType.DATAACCOUNT) { | |||
| assertNotNull(ledgerRepository.getDataAccountSet(ledgerRepository.getLatestBlock()) | |||
| .getAccount(keyPair.getAddress())); | |||
| } | |||
| countDownLatch.countDown(); | |||
| } | |||
| public static void validKvWrite(IntegrationBase.KvResponse kvResponse, LedgerQuery ledgerRepository, | |||
| BlockchainService blockchainService) { | |||
| // 先验证应答 | |||
| TransactionResponse txResp = kvResponse.getTxResp(); | |||
| HashDigest transactionHash = kvResponse.getTxHash(); | |||
| HashDigest ledgerHash = kvResponse.getLedgerHash(); | |||
| String daAddress = kvResponse.getDataAccount().toBase58(); | |||
| String dataKey = kvResponse.getKey(); | |||
| String dataVal = kvResponse.getValue(); | |||
| ledgerRepository.retrieveLatestBlock(); | |||
| assertEquals(TransactionState.SUCCESS, txResp.getExecutionState()); | |||
| assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); | |||
| assertEquals(txResp.getContentHash(), transactionHash); | |||
| assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); | |||
| TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, daAddress, dataKey); | |||
| for (TypedKVEntry kvDataEntry : kvDataEntries) { | |||
| assertEquals(dataKey, kvDataEntry.getKey()); | |||
| String valHexText = (String) kvDataEntry.getValue(); | |||
| assertEquals(dataVal, valHexText); | |||
| } | |||
| } | |||
| public static LedgerQuery[] buildLedgers(LedgerBindingConfig[] bindingConfigs, | |||
| DbConnectionFactory[] dbConnectionFactories) { | |||
| int[] ids = { 0, 1, 2, 3 }; | |||
| LedgerQuery[] ledgers = new LedgerQuery[ids.length]; | |||
| LedgerManager[] ledgerManagers = new LedgerManager[ids.length]; | |||
| for (int i = 0; i < ids.length; i++) { | |||
| ledgerManagers[i] = new LedgerManager(); | |||
| HashDigest ledgerHash = bindingConfigs[0].getLedgerHashs()[0]; | |||
| DbConnection conn = dbConnectionFactories[i] | |||
| .connect(bindingConfigs[i].getLedger(ledgerHash).getDbConnection().getUri()); | |||
| ledgers[i] = ledgerManagers[i].register(ledgerHash, conn.getStorageService()); | |||
| } | |||
| return ledgers; | |||
| } | |||
| public static void testConsistencyAmongNodes(LedgerQuery[] ledgers) { | |||
| LedgerQuery ledger0 = ledgers[0]; | |||
| LedgerBlock latestBlock0 = ledger0.retrieveLatestBlock(); | |||
| for (int i = 1; i < ledgers.length; i++) { | |||
| LedgerQuery otherLedger = ledgers[i]; | |||
| LedgerBlock otherLatestBlock = otherLedger.retrieveLatestBlock(); | |||
| assertEquals(ledger0.getHash(), otherLedger.getHash()); | |||
| assertEquals(ledger0.getLatestBlockHeight(), otherLedger.getLatestBlockHeight()); | |||
| assertEquals(ledger0.getLatestBlockHash(), otherLedger.getLatestBlockHash()); | |||
| assertEquals(latestBlock0.getHeight(), otherLatestBlock.getHeight()); | |||
| assertEquals(latestBlock0.getHash(), otherLatestBlock.getHash()); | |||
| assertEquals(latestBlock0.getAdminAccountHash(), otherLatestBlock.getAdminAccountHash()); | |||
| assertEquals(latestBlock0.getTransactionSetHash(), otherLatestBlock.getTransactionSetHash()); | |||
| assertEquals(latestBlock0.getUserAccountSetHash(), otherLatestBlock.getUserAccountSetHash()); | |||
| assertEquals(latestBlock0.getDataAccountSetHash(), otherLatestBlock.getDataAccountSetHash()); | |||
| assertEquals(latestBlock0.getContractAccountSetHash(), otherLatestBlock.getContractAccountSetHash()); | |||
| assertEquals(latestBlock0.getPreviousHash(), otherLatestBlock.getPreviousHash()); | |||
| } | |||
| } | |||
| public static PeerTestRunner[] peerNodeStart(HashDigest ledgerHash, String dbType) { | |||
| NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 12000); | |||
| LedgerBindingConfig bindingConfig0 = loadBindingConfig(0, ledgerHash, dbType); | |||
| PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, bindingConfig0); | |||
| NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 12010); | |||
| LedgerBindingConfig bindingConfig1 = loadBindingConfig(1, ledgerHash, dbType); | |||
| PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, bindingConfig1); | |||
| NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 12020); | |||
| LedgerBindingConfig bindingConfig2 = loadBindingConfig(2, ledgerHash, dbType); | |||
| PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, bindingConfig2); | |||
| NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 12030); | |||
| LedgerBindingConfig bindingConfig3 = loadBindingConfig(3, ledgerHash, dbType); | |||
| PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, bindingConfig3); | |||
| ThreadInvoker.AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
| ThreadInvoker.AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
| ThreadInvoker.AsyncCallback<Object> peerStarting2 = peer2.start(); | |||
| ThreadInvoker.AsyncCallback<Object> peerStarting3 = peer3.start(); | |||
| peerStarting0.waitReturn(); | |||
| peerStarting1.waitReturn(); | |||
| peerStarting2.waitReturn(); | |||
| peerStarting3.waitReturn(); | |||
| return new PeerTestRunner[] { peer0, peer1, peer2, peer3 }; | |||
| } | |||
| public static LedgerBindingConfig loadBindingConfig(int id, HashDigest ledgerHash, String dbType) { | |||
| LedgerBindingConfig ledgerBindingConfig; | |||
| String newLedger = ledgerHash.toBase58(); | |||
| String resourceClassPath = "ledger-binding-" + dbType + "-" + id + ".conf"; | |||
| String ledgerBindingUrl = IntegrationBase.class.getResource("/") + resourceClassPath; | |||
| try { | |||
| URL url = new URL(ledgerBindingUrl); | |||
| File ledgerBindingConf = new File(url.getPath()); | |||
| System.out.printf("URL-ledgerBindingConf = %s \r\n", url.getPath()); | |||
| if (ledgerBindingConf.exists()) { | |||
| List<String> readLines = FileUtils.readLines(ledgerBindingConf); | |||
| List<String> writeLines = new ArrayList<>(); | |||
| if (readLines != null && !readLines.isEmpty()) { | |||
| String oldLedgerLine = null; | |||
| for (String readLine : readLines) { | |||
| if (readLine.startsWith("ledger")) { | |||
| oldLedgerLine = readLine; | |||
| break; | |||
| } | |||
| } | |||
| String[] oldLedgerArray = oldLedgerLine.split("="); | |||
| String oldLedger = oldLedgerArray[1]; | |||
| if (!oldLedger.equalsIgnoreCase(newLedger)) { | |||
| for (String readLine : readLines) { | |||
| String newLine = readLine.replace(oldLedger, newLedger); | |||
| if (dbType.equalsIgnoreCase("rocksdb")) { | |||
| if (newLine.contains("db.uri")) { | |||
| String[] propArray = newLine.split("="); | |||
| String dbKey = propArray[0]; | |||
| String dbValue = LedgerInitConsensusConfig.rocksdbConnectionStrings[id]; | |||
| newLine = dbKey + "=" + dbValue; | |||
| } | |||
| } | |||
| writeLines.add(newLine); | |||
| } | |||
| } else if (dbType.equalsIgnoreCase("rocksdb")) { | |||
| for (String readLine : readLines) { | |||
| String newLine = readLine; | |||
| if (readLine.contains("db.uri")) { | |||
| String[] propArray = readLine.split("="); | |||
| String dbKey = propArray[0]; | |||
| String dbValue = LedgerInitConsensusConfig.rocksdbConnectionStrings[id]; | |||
| newLine = dbKey + "=" + dbValue; | |||
| } | |||
| writeLines.add(newLine); | |||
| } | |||
| } | |||
| if (!writeLines.isEmpty()) { | |||
| FileUtils.writeLines(ledgerBindingConf, writeLines); | |||
| } | |||
| } | |||
| } | |||
| } catch (Exception e) { | |||
| } | |||
| ClassPathResource res = new ClassPathResource(resourceClassPath); | |||
| try (InputStream in = res.getInputStream()) { | |||
| ledgerBindingConfig = LedgerBindingConfig.resolve(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| return ledgerBindingConfig; | |||
| } | |||
| public static class KeyPairResponse { | |||
| HashDigest txHash; | |||
| BlockchainKeypair keyPair; | |||
| TransactionResponse txResp; | |||
| public BlockchainKeypair getKeyPair() { | |||
| return keyPair; | |||
| } | |||
| public TransactionResponse getTxResp() { | |||
| return txResp; | |||
| } | |||
| public HashDigest getTxHash() { | |||
| return txHash; | |||
| } | |||
| } | |||
| public static class KvResponse { | |||
| Bytes dataAccount; | |||
| HashDigest ledgerHash; | |||
| HashDigest txHash; | |||
| TransactionResponse txResp; | |||
| String key; | |||
| String value; | |||
| public HashDigest getTxHash() { | |||
| return txHash; | |||
| } | |||
| public TransactionResponse getTxResp() { | |||
| return txResp; | |||
| } | |||
| public String getKey() { | |||
| return key; | |||
| } | |||
| public String getValue() { | |||
| return value; | |||
| } | |||
| public HashDigest getLedgerHash() { | |||
| return ledgerHash; | |||
| } | |||
| public Bytes getDataAccount() { | |||
| return dataAccount; | |||
| } | |||
| } | |||
| public enum KeyPairType { | |||
| USER, DATAACCOUNT | |||
| } | |||
| // 合约测试使用的初始化数据; | |||
| static BlockchainKeypair contractDataKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| static BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| // 保存资产总数的键; | |||
| // 第二个参数; | |||
| private static String contractZipName = "contract-read.jar"; | |||
| static HashDigest txContentHash; | |||
| public static LedgerBlock testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService, LedgerQuery ledgerRepository) { | |||
| KeyPairResponse keyPairResponse = testSDK_RegisterDataAccount(adminKey,ledgerHash,blockchainService); | |||
| System.out.println("adminKey=" + AddressEncoding.generateAddress(adminKey.getPubKey())); | |||
| BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| System.out.println("userKey=" + userKey.getAddress()); | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.users().register(userKey.getIdentity()); | |||
| // 定义交易; | |||
| byte[] contractCode = getChainCodeBytes(); | |||
| txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| assertTrue(txResp.isSuccess()); | |||
| // 验证结果; | |||
| assertEquals(ptx.getHash(),txResp.getContentHash()); | |||
| LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight()); | |||
| byte[] contractCodeInDb = ledgerRepository.getContractAccountSet(block) | |||
| .getAccount(contractDeployKey.getAddress()).getChainCode(); | |||
| assertArrayEquals(contractCode, contractCodeInDb); | |||
| // execute the contract; | |||
| // testContractExe(adminKey, ledgerHash, keyPairResponse.keyPair, blockchainService, ledgerRepository); | |||
| // testContractExe1(adminKey, ledgerHash, keyPairResponse.keyPair, blockchainService, ledgerRepository); | |||
| testExeReadContract(adminKey, ledgerHash, blockchainService); | |||
| return block; | |||
| } | |||
| // private static <T> void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair dataKey, | |||
| // BlockchainService blockchainService, LedgerRepository ledgerRepository) { | |||
| // LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||
| // LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); | |||
| // | |||
| // // 定义交易; | |||
| // TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| // | |||
| // Byte byteObj = Byte.parseByte("123"); | |||
| //// txTpl.contract(contractDeployKey.getAddress(),AssetContract2.class).issue(byteObj, | |||
| //// contractDeployKey.getAddress().toBase58(),321123); | |||
| // txTpl.contract(contractDeployKey.getAddress(),AssetContract2.class).issue(byteObj, | |||
| // dataKey.getAddress().toBase58(),Bytes.fromString("123321")); | |||
| // | |||
| // // 签名; | |||
| // PreparedTransaction ptx = txTpl.prepare(); | |||
| // ptx.sign(adminKey); | |||
| // | |||
| // // 提交并等待共识返回; | |||
| // TransactionResponse txResp = ptx.commit(); | |||
| // | |||
| // // 验证结果; | |||
| // Assert.assertTrue(txResp.isSuccess()); | |||
| // assertEquals(ptx.getHash(),txResp.getContentHash()); | |||
| // LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight()); | |||
| // KVDataEntry[] kvDataEntries = ledgerRepository.getDataAccountSet(block).getDataAccount(dataKey.getAddress()).getDataEntries(0,1); | |||
| // assertEquals("100",kvDataEntries[0].getValue().toString()); | |||
| // } | |||
| // private static <T> void testContractExe1(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair dataKey, | |||
| // BlockchainService blockchainService,LedgerRepository ledgerRepository) { | |||
| // LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||
| // LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); | |||
| // | |||
| // // 定义交易; | |||
| // TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| // | |||
| // AssetContract2 assetContract = txTpl.contract(contractDeployKey.getAddress(), AssetContract2.class); | |||
| // ContractBizContent contractBizContent = () -> new String[]{"param1","param2"}; | |||
| // assetContract.issue(contractBizContent,dataKey.getAddress().toBase58(),123456); | |||
| // | |||
| // // 签名; | |||
| // PreparedTransaction ptx = txTpl.prepare(); | |||
| // ptx.sign(adminKey); | |||
| // | |||
| // // 提交并等待共识返回; | |||
| // TransactionResponse txResp = ptx.commit(); | |||
| // | |||
| // // 验证结果; | |||
| // Assert.assertTrue(txResp.isSuccess()); | |||
| // assertEquals(ptx.getHash(),txResp.getContentHash()); | |||
| // LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight()); | |||
| // KVDataEntry[] kvDataEntries = ledgerRepository.getDataAccountSet(block).getDataAccount(dataKey.getAddress()).getDataEntries(1,2); | |||
| // assertEquals("value1",kvDataEntries[0].getValue().toString()); | |||
| // assertEquals(888L,kvDataEntries[1].getValue()); | |||
| // } | |||
| private static void testExeReadContract(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainService blockchainService) { | |||
| // 首先注册一个数据账户 | |||
| BlockchainKeypair newDataAccount = BlockchainKeyGenerator.getInstance().generate(); | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.dataAccounts().register(newDataAccount.getIdentity()); | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| ptx.commit(); | |||
| // 再提交一个KV写入 | |||
| String key1 = "JingDong", value1 = "www.jd.com"; | |||
| String key2 = "JD", value2 = "JingDong"; | |||
| String key3 = "Test", value3 = "OK"; | |||
| TransactionTemplate txKv = blockchainService.newTransaction(ledgerHash); | |||
| txKv.dataAccount(newDataAccount.getAddress()) | |||
| .setText(key1, value1, -1) | |||
| .setBytes(key2, Bytes.fromString(value2), -1) | |||
| .setBytes(key3, Bytes.fromString(value3).toBytes(), -1); | |||
| PreparedTransaction kvPtx = txKv.prepare(); | |||
| kvPtx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| kvPtx.commit(); | |||
| // 下面才是执行Read交易 | |||
| // 定义交易; | |||
| TransactionTemplate txContract = blockchainService.newTransaction(ledgerHash); | |||
| ReadContract readContract1 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class); | |||
| GenericValueHolder<String> result1 = decode(readContract1.read(newDataAccount.getAddress().toBase58(), key1)); | |||
| ReadContract readContract2 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class); | |||
| readContract2.read(newDataAccount.getAddress().toBase58(), key2); | |||
| ReadContract readContract3 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class); | |||
| GenericValueHolder<Long> result3 = decode(readContract3.readVersion(newDataAccount.getAddress().toBase58(), key2)); | |||
| // 签名; | |||
| PreparedTransaction contractPtx = txContract.prepare(); | |||
| contractPtx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse readTxResp = contractPtx.commit(); | |||
| OperationResult[] operationResults = readTxResp.getOperationResults(); | |||
| // 通过EventResult获取结果 | |||
| System.out.printf("readContract1.result = %s \r\n", result1.get()); | |||
| System.out.printf("readContract3.result = %s \r\n", result3.get()); | |||
| for (int i = 0; i < operationResults.length; i++) { | |||
| OperationResult opResult = operationResults[i]; | |||
| System.out.printf("Operation[%s].result = %s \r\n", opResult.getIndex(), BytesValueEncoding.decode(opResult.getResult())); | |||
| } | |||
| // // 打印结果 | |||
| // for (OperationResult or : operationResults) { | |||
| // System.out.printf("操作[%s].Result = %s \r\n", or.getIndex(), ContractSerializeUtils.resolve(or.getResult())); | |||
| // } | |||
| // | |||
| // // 验证结果 | |||
| // assertNotNull(contractReturn); | |||
| // assertEquals(contractReturn.length, 3); | |||
| // | |||
| // String returnVal1 = contractReturn[0]; | |||
| // assertEquals(value1, returnVal1); | |||
| // | |||
| // String returnVal2 = contractReturn[1]; | |||
| // assertEquals(value2, returnVal2); | |||
| // | |||
| // String returnVal3 = contractReturn[2]; | |||
| // assertEquals("0", returnVal3); | |||
| } | |||
| /** | |||
| * 根据合约构建字节数组; | |||
| * | |||
| * @return | |||
| */ | |||
| private static byte[] getChainCodeBytes() { | |||
| // 构建合约的字节数组; | |||
| byte[] contractCode = null; | |||
| File file = null; | |||
| InputStream input = null; | |||
| try { | |||
| ClassPathResource contractPath = new ClassPathResource(contractZipName); | |||
| file = new File(contractPath.getURI()); | |||
| assertTrue("contract zip file is not exist.", file.exists() == true); | |||
| input = new FileInputStream(file); | |||
| // 这种暴力的读取压缩包,在class解析时有问题,所有需要改进; | |||
| contractCode = new byte[input.available()]; | |||
| input.read(contractCode); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } finally { | |||
| try { | |||
| if (input != null) { | |||
| input.close(); | |||
| } | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| return contractCode; | |||
| } | |||
| } | |||
| @@ -1,251 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNotNull; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class IntegrationBaseTest { | |||
| LedgerInitConsensusConfig.ConsensusConfig bftsmartConfig = LedgerInitConsensusConfig.bftsmartConfig; | |||
| public IntegratedContext context = initLedgers(bftsmartConfig.getConfigPath(), bftsmartConfig.getProvider()); | |||
| public GatewayTestRunner gateway0; | |||
| public GatewayTestRunner gateway1; | |||
| public void startPeer() { | |||
| // init ledgers of all nodes ; | |||
| Node node0 = context.getNode(0); | |||
| Node node1 = context.getNode(1); | |||
| Node node2 = context.getNode(2); | |||
| Node node3 = context.getNode(3); | |||
| NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 13200); | |||
| PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, node0.getBindingConfig(), node0.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 13210); | |||
| PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, node1.getBindingConfig(), node1.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 13220); | |||
| PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, node2.getBindingConfig(), node2.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 13230); | |||
| PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, node3.getBindingConfig(), node3.getStorageDB(), null); | |||
| AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
| AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
| AsyncCallback<Object> peerStarting2 = peer2.start(); | |||
| AsyncCallback<Object> peerStarting3 = peer3.start(); | |||
| peerStarting0.waitReturn(); | |||
| peerStarting1.waitReturn(); | |||
| peerStarting2.waitReturn(); | |||
| peerStarting3.waitReturn(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| KeyPairConfig gwkey0 = new KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(LedgerInitializeWeb4SingleStepsTest.PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| gateway0 = new GatewayTestRunner("127.0.0.1", 13300, gwkey0, peerSrvAddr0); | |||
| KeyPairConfig gwkey1 = new KeyPairConfig(); | |||
| gwkey1.setPubKeyValue(LedgerInitializeWeb4SingleStepsTest.PUB_KEYS[1]); | |||
| gwkey1.setPrivKeyValue(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[1]); | |||
| gwkey1.setPrivKeyPassword(encodedBase58Pwd); | |||
| gateway1 = new GatewayTestRunner("127.0.0.1", 13310, gwkey1, peerSrvAddr1); | |||
| AsyncCallback<Object> gwStarting0 = gateway0.start(); | |||
| AsyncCallback<Object> gwStarting1 = gateway1.start(); | |||
| gwStarting0.waitReturn(); | |||
| gwStarting1.waitReturn(); | |||
| } | |||
| public void testConsistencyAmongNodes(IntegratedContext context) { | |||
| int[] ids = context.getNodeIds(); | |||
| Node[] nodes = new Node[ids.length]; | |||
| LedgerQuery[] ledgers = new LedgerQuery[ids.length]; | |||
| for (int i = 0; i < nodes.length; i++) { | |||
| nodes[i] = context.getNode(ids[i]); | |||
| HashDigest ledgerHash = nodes[i].getLedgerManager().getLedgerHashs()[0]; | |||
| ledgers[i] = nodes[i].getLedgerManager().getLedger(ledgerHash); | |||
| } | |||
| LedgerQuery ledger0 = ledgers[0]; | |||
| LedgerBlock latestBlock0 = ledger0.retrieveLatestBlock(); | |||
| for (int i = 1; i < ledgers.length; i++) { | |||
| LedgerQuery otherLedger = ledgers[i]; | |||
| LedgerBlock otherLatestBlock = otherLedger.retrieveLatestBlock(); | |||
| assertEquals(ledger0.getHash(), otherLedger.getHash()); | |||
| assertEquals(ledger0.getLatestBlockHeight(), otherLedger.getLatestBlockHeight()); | |||
| assertEquals(ledger0.getLatestBlockHash(), otherLedger.getLatestBlockHash()); | |||
| assertEquals(latestBlock0.getHeight(), otherLatestBlock.getHeight()); | |||
| assertEquals(latestBlock0.getHash(), otherLatestBlock.getHash()); | |||
| assertEquals(latestBlock0.getAdminAccountHash(), otherLatestBlock.getAdminAccountHash()); | |||
| assertEquals(latestBlock0.getTransactionSetHash(), otherLatestBlock.getTransactionSetHash()); | |||
| assertEquals(latestBlock0.getUserAccountSetHash(), otherLatestBlock.getUserAccountSetHash()); | |||
| assertEquals(latestBlock0.getDataAccountSetHash(), otherLatestBlock.getDataAccountSetHash()); | |||
| assertEquals(latestBlock0.getContractAccountSetHash(), otherLatestBlock.getContractAccountSetHash()); | |||
| assertEquals(latestBlock0.getPreviousHash(), otherLatestBlock.getPreviousHash()); | |||
| } | |||
| } | |||
| private IntegratedContext initLedgers(String configPath, String providerName) { | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = LedgerInitializeWeb4SingleStepsTest.loadConsensusSetting(configPath); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(providerName); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeWebContext nodeCtx0 = new NodeWebContext(0, initAddr0); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeWebContext nodeCtx1 = new NodeWebContext(1, initAddr1); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeWebContext nodeCtx2 = new NodeWebContext(2, initAddr2); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeWebContext nodeCtx3 = new NodeWebContext(3, initAddr3); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[0], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[1], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[2], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[3], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| String encodedPassword = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| CountDownLatch quitLatch = new CountDownLatch(4); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[0]); | |||
| LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, testDb0, | |||
| consolePrompter, bindingConfig0, quitLatch); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[1]); | |||
| LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, testDb1, | |||
| consolePrompter, bindingConfig1, quitLatch); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[2]); | |||
| LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, testDb2, | |||
| consolePrompter, bindingConfig2, quitLatch); | |||
| DBConnectionConfig testDb3 = new DBConnectionConfig(); | |||
| testDb3.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[3]); | |||
| LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, | |||
| consolePrompter, bindingConfig3, quitLatch); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| assertNotNull(ledgerHash0); | |||
| assertEquals(ledgerHash0, ledgerHash1); | |||
| assertEquals(ledgerHash0, ledgerHash2); | |||
| assertEquals(ledgerHash0, ledgerHash3); | |||
| LedgerQuery ledger0 = nodeCtx0.registLedger(ledgerHash0); | |||
| LedgerQuery ledger1 = nodeCtx1.registLedger(ledgerHash1); | |||
| LedgerQuery ledger2 = nodeCtx2.registLedger(ledgerHash2); | |||
| LedgerQuery ledger3 = nodeCtx3.registLedger(ledgerHash3); | |||
| assertNotNull(ledger0); | |||
| assertNotNull(ledger1); | |||
| assertNotNull(ledger2); | |||
| assertNotNull(ledger3); | |||
| IntegratedContext context = new IntegratedContext(); | |||
| Node node0 = new Node(0); | |||
| node0.setConsensusSettings(csProps); | |||
| node0.setLedgerManager(nodeCtx0.getLedgerManager()); | |||
| node0.setStorageDB(nodeCtx0.getStorageDB()); | |||
| node0.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(0).getPubKey(), privkey0)); | |||
| node0.setBindingConfig(bindingConfig0); | |||
| context.addNode(node0); | |||
| Node node1 = new Node(1); | |||
| node1.setConsensusSettings(csProps); | |||
| node1.setLedgerManager(nodeCtx1.getLedgerManager()); | |||
| node1.setStorageDB(nodeCtx1.getStorageDB()); | |||
| node1.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(1).getPubKey(), privkey1)); | |||
| node1.setBindingConfig(bindingConfig1); | |||
| context.addNode(node1); | |||
| Node node2 = new Node(2); | |||
| node2.setConsensusSettings(csProps); | |||
| node2.setLedgerManager(nodeCtx2.getLedgerManager()); | |||
| node2.setStorageDB(nodeCtx2.getStorageDB()); | |||
| node2.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(2).getPubKey(), privkey2)); | |||
| node2.setBindingConfig(bindingConfig2); | |||
| context.addNode(node2); | |||
| Node node3 = new Node(3); | |||
| node3.setConsensusSettings(csProps); | |||
| node3.setLedgerManager(nodeCtx3.getLedgerManager()); | |||
| node3.setStorageDB(nodeCtx3.getStorageDB()); | |||
| node3.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(3).getPubKey(), privkey3)); | |||
| node3.setBindingConfig(bindingConfig3); | |||
| context.addNode(node3); | |||
| nodeCtx0.closeServer(); | |||
| nodeCtx1.closeServer(); | |||
| nodeCtx2.closeServer(); | |||
| nodeCtx3.closeServer(); | |||
| return context; | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_integration() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_integration.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,362 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNotNull; | |||
| import static org.junit.Assert.assertTrue; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInfo; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.PreparedTransaction; | |||
| import com.jd.blockchain.ledger.TransactionResponse; | |||
| import com.jd.blockchain.ledger.TransactionTemplate; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.contract.AssetContract; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| /** | |||
| * 测试合约,提交后不立即进行验证,因为此时可能还没有完成正式结块; | |||
| */ | |||
| public class IntegrationTest2 { | |||
| // 合约测试使用的初始化数据; | |||
| BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| private String contractZipName = "contract.jar"; | |||
| private String eventName = "issue-asset"; | |||
| @Test | |||
| public void test() { | |||
| // init ledgers of all nodes ; | |||
| IntegratedContext context = initLedgers(LedgerInitConsensusConfig.mqConfig, | |||
| LedgerInitConsensusConfig.memConnectionStrings); | |||
| Node node0 = context.getNode(0); | |||
| Node node1 = context.getNode(1); | |||
| Node node2 = context.getNode(2); | |||
| Node node3 = context.getNode(3); | |||
| NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 13200); | |||
| PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, node0.getBindingConfig(), node0.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 13210); | |||
| PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, node1.getBindingConfig(), node1.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 13220); | |||
| PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, node2.getBindingConfig(), node2.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 13230); | |||
| PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, node3.getBindingConfig(), node3.getStorageDB(), null); | |||
| AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
| AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
| AsyncCallback<Object> peerStarting2 = peer2.start(); | |||
| AsyncCallback<Object> peerStarting3 = peer3.start(); | |||
| peerStarting0.waitReturn(); | |||
| peerStarting1.waitReturn(); | |||
| peerStarting2.waitReturn(); | |||
| peerStarting3.waitReturn(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| KeyPairConfig gwkey0 = new KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(LedgerInitializeWeb4SingleStepsTest.PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway0 = new GatewayTestRunner("127.0.0.1", 13300, gwkey0, peerSrvAddr0); | |||
| KeyPairConfig gwkey1 = new KeyPairConfig(); | |||
| gwkey1.setPubKeyValue(LedgerInitializeWeb4SingleStepsTest.PUB_KEYS[1]); | |||
| gwkey1.setPrivKeyValue(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[1]); | |||
| gwkey1.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway1 = new GatewayTestRunner("127.0.0.1", 13310, gwkey1, peerSrvAddr1); | |||
| AsyncCallback<Object> gwStarting0 = gateway0.start(); | |||
| AsyncCallback<Object> gwStarting1 = gateway1.start(); | |||
| gwStarting0.waitReturn(); | |||
| gwStarting1.waitReturn(); | |||
| // 执行测试用例之前,校验每个节点的一致性; | |||
| testConsistencyAmongNodes(context); | |||
| testSDK(gateway0, context); | |||
| // 执行测试用例之后,校验每个节点的一致性; | |||
| testConsistencyAmongNodes(context); | |||
| } | |||
| private void testConsistencyAmongNodes(IntegratedContext context) { | |||
| int[] ids = context.getNodeIds(); | |||
| Node[] nodes = new Node[ids.length]; | |||
| LedgerQuery[] ledgers = new LedgerQuery[ids.length]; | |||
| for (int i = 0; i < nodes.length; i++) { | |||
| nodes[i] = context.getNode(ids[i]); | |||
| HashDigest ledgerHash = nodes[i].getLedgerManager().getLedgerHashs()[0]; | |||
| ledgers[i] = nodes[i].getLedgerManager().getLedger(ledgerHash); | |||
| } | |||
| LedgerQuery ledger0 = ledgers[0]; | |||
| LedgerBlock latestBlock0 = ledger0.retrieveLatestBlock(); | |||
| for (int i = 1; i < ledgers.length; i++) { | |||
| LedgerQuery otherLedger = ledgers[i]; | |||
| LedgerBlock otherLatestBlock = otherLedger.retrieveLatestBlock(); | |||
| assertEquals(ledger0.getHash(), otherLedger.getHash()); | |||
| assertEquals(ledger0.getLatestBlockHeight(), otherLedger.getLatestBlockHeight()); | |||
| assertEquals(ledger0.getLatestBlockHash(), otherLedger.getLatestBlockHash()); | |||
| assertEquals(latestBlock0.getHeight(), otherLatestBlock.getHeight()); | |||
| assertEquals(latestBlock0.getHash(), otherLatestBlock.getHash()); | |||
| assertEquals(latestBlock0.getAdminAccountHash(), otherLatestBlock.getAdminAccountHash()); | |||
| assertEquals(latestBlock0.getTransactionSetHash(), otherLatestBlock.getTransactionSetHash()); | |||
| assertEquals(latestBlock0.getUserAccountSetHash(), otherLatestBlock.getUserAccountSetHash()); | |||
| assertEquals(latestBlock0.getDataAccountSetHash(), otherLatestBlock.getDataAccountSetHash()); | |||
| assertEquals(latestBlock0.getContractAccountSetHash(), otherLatestBlock.getContractAccountSetHash()); | |||
| assertEquals(latestBlock0.getPreviousHash(), otherLatestBlock.getPreviousHash()); | |||
| } | |||
| } | |||
| private void testSDK(GatewayTestRunner gateway, IntegratedContext context) { | |||
| // 连接网关; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| BlockchainService bcsrv = gwsrvFact.getBlockchainService(); | |||
| HashDigest[] ledgerHashs = bcsrv.getLedgerHashs(); | |||
| AsymmetricKeypair adminKey = context.getNode(0).getPartiKeyPair(); | |||
| testSDK_Contract(adminKey, ledgerHashs[0], bcsrv, context); | |||
| } | |||
| private IntegratedContext initLedgers(LedgerInitConsensusConfig.ConsensusConfig config, String[] dbConns) { | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = LedgerInitializeWeb4SingleStepsTest.loadConsensusSetting(config.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeWebContext nodeCtx0 = new NodeWebContext(0, initAddr0); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeWebContext nodeCtx1 = new NodeWebContext(1, initAddr1); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeWebContext nodeCtx2 = new NodeWebContext(2, initAddr2); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeWebContext nodeCtx3 = new NodeWebContext(3, initAddr3); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[0], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[1], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[2], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[3], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| String encodedPassword = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| CountDownLatch quitLatch = new CountDownLatch(4); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri(dbConns[0]); | |||
| LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, testDb0, | |||
| consolePrompter, bindingConfig0, quitLatch); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri(dbConns[1]); | |||
| LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, testDb1, | |||
| consolePrompter, bindingConfig1, quitLatch); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri(dbConns[2]); | |||
| LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, testDb2, | |||
| consolePrompter, bindingConfig2, quitLatch); | |||
| DBConnectionConfig testDb3 = new DBConnectionConfig(); | |||
| testDb3.setConnectionUri(dbConns[3]); | |||
| LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, | |||
| consolePrompter, bindingConfig3, quitLatch); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| assertNotNull(ledgerHash0); | |||
| assertEquals(ledgerHash0, ledgerHash1); | |||
| assertEquals(ledgerHash0, ledgerHash2); | |||
| assertEquals(ledgerHash0, ledgerHash3); | |||
| LedgerQuery ledger0 = nodeCtx0.registLedger(ledgerHash0); | |||
| LedgerQuery ledger1 = nodeCtx1.registLedger(ledgerHash1); | |||
| LedgerQuery ledger2 = nodeCtx2.registLedger(ledgerHash2); | |||
| LedgerQuery ledger3 = nodeCtx3.registLedger(ledgerHash3); | |||
| assertNotNull(ledger0); | |||
| assertNotNull(ledger1); | |||
| assertNotNull(ledger2); | |||
| assertNotNull(ledger3); | |||
| IntegratedContext context = new IntegratedContext(); | |||
| Node node0 = new Node(0); | |||
| node0.setConsensusSettings(csProps); | |||
| node0.setLedgerManager(nodeCtx0.getLedgerManager()); | |||
| node0.setStorageDB(nodeCtx0.getStorageDB()); | |||
| node0.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(0).getPubKey(), privkey0)); | |||
| node0.setBindingConfig(bindingConfig0); | |||
| context.addNode(node0); | |||
| Node node1 = new Node(1); | |||
| node1.setConsensusSettings(csProps); | |||
| node1.setLedgerManager(nodeCtx1.getLedgerManager()); | |||
| node1.setStorageDB(nodeCtx1.getStorageDB()); | |||
| node1.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(1).getPubKey(), privkey1)); | |||
| node1.setBindingConfig(bindingConfig1); | |||
| context.addNode(node1); | |||
| Node node2 = new Node(2); | |||
| node2.setConsensusSettings(csProps); | |||
| node2.setLedgerManager(nodeCtx2.getLedgerManager()); | |||
| node2.setStorageDB(nodeCtx2.getStorageDB()); | |||
| node2.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(2).getPubKey(), privkey2)); | |||
| node2.setBindingConfig(bindingConfig2); | |||
| context.addNode(node2); | |||
| Node node3 = new Node(3); | |||
| node3.setConsensusSettings(csProps); | |||
| node3.setLedgerManager(nodeCtx3.getLedgerManager()); | |||
| node3.setStorageDB(nodeCtx3.getStorageDB()); | |||
| node3.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(3).getPubKey(), privkey3)); | |||
| node3.setBindingConfig(bindingConfig3); | |||
| context.addNode(node3); | |||
| nodeCtx0.closeServer(); | |||
| nodeCtx1.closeServer(); | |||
| nodeCtx2.closeServer(); | |||
| nodeCtx3.closeServer(); | |||
| return context; | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_integration() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_integration.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| private void testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService, IntegratedContext context) { | |||
| BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| byte[] contractCode = getChainCodeBytes(); | |||
| txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| assertTrue(txResp.isSuccess()); | |||
| // execute the contract; | |||
| testContractExe(adminKey, ledgerHash, userKey, blockchainService, context); | |||
| } | |||
| private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, | |||
| BlockchainService blockchainService, IntegratedContext context) { | |||
| LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||
| LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.contract(contractDeployKey.getAddress(), AssetContract.class).issue(10,"abc"); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| assertTrue(txResp.isSuccess()); | |||
| } | |||
| /** | |||
| * 根据合约构建字节数组; | |||
| * | |||
| * @return | |||
| */ | |||
| private byte[] getChainCodeBytes() { | |||
| // 构建合约的字节数组; | |||
| byte[] contractCode = null; | |||
| File file = null; | |||
| InputStream input = null; | |||
| try { | |||
| ClassPathResource contractPath = new ClassPathResource(contractZipName); | |||
| file = new File(contractPath.getURI()); | |||
| assertTrue("contract zip file is not exist.", file.exists() == true); | |||
| input = new FileInputStream(file); | |||
| // 这种暴力的读取压缩包,在class解析时有问题,所有需要改进; | |||
| contractCode = new byte[input.available()]; | |||
| input.read(contractCode); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } finally { | |||
| try { | |||
| if (input != null) { | |||
| input.close(); | |||
| } | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| return contractCode; | |||
| } | |||
| } | |||
| @@ -1,204 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.bftsmart.BftsmartConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.ParticipantNodeState; | |||
| import com.jd.blockchain.ledger.ParticipantStateUpdateInfo; | |||
| import com.jd.blockchain.ledger.ParticipantStateUpdateInfoData; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import org.junit.Test; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4Nodes; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.ExecutorService; | |||
| import java.util.concurrent.Executors; | |||
| import static test.com.jd.blockchain.intgr.IntegrationBase.*; | |||
| public class IntegrationTest4Bftsmart { | |||
| private static final boolean isRegisterUser = true; | |||
| private static final boolean isRegisterDataAccount = true; | |||
| private static final boolean isRegisterParticipant = true; | |||
| private static final boolean isParticipantStateUpdate = true; | |||
| private static final boolean isWriteKv = true; | |||
| private static final String DB_TYPE_MEM = "mem"; | |||
| private static final String DB_TYPE_REDIS = "redis"; | |||
| private static final String DB_TYPE_ROCKSDB = "rocksdb"; | |||
| public static final String BFTSMART_PROVIDER = "com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"; | |||
| @Test | |||
| public void test4Memory() { | |||
| test(LedgerInitConsensusConfig.bftsmartProvider, DB_TYPE_MEM, LedgerInitConsensusConfig.memConnectionStrings); | |||
| } | |||
| @Test | |||
| public void test4Redis() { | |||
| // test(LedgerInitConsensusConfig.bftsmartProvider, DB_TYPE_REDIS, LedgerInitConsensusConfig.redisConnectionStrings); | |||
| } | |||
| public void test(String[] providers, String dbType, String[] dbConnections) { | |||
| final ExecutorService sendReqExecutors = Executors.newFixedThreadPool(20); | |||
| // 内存账本初始化 | |||
| HashDigest ledgerHash = initLedger(dbConnections); | |||
| // 启动Peer节点 | |||
| PeerTestRunner[] peerNodes = peerNodeStart(ledgerHash, dbType); | |||
| DbConnectionFactory dbConnectionFactory0 = peerNodes[0].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory1 = peerNodes[1].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory2 = peerNodes[2].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory3 = peerNodes[3].getDBConnectionFactory(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeTest.PASSWORD); | |||
| GatewayConfigProperties.KeyPairConfig gwkey0 = new GatewayConfigProperties.KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(IntegrationBase.PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(IntegrationBase.PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway = new GatewayTestRunner("127.0.0.1", 11000, gwkey0, | |||
| peerNodes[0].getServiceAddress(), providers,null); | |||
| ThreadInvoker.AsyncCallback<Object> gwStarting = gateway.start(); | |||
| gwStarting.waitReturn(); | |||
| // 执行测试用例之前,校验每个节点的一致性; | |||
| LedgerQuery[] ledgers = buildLedgers(new LedgerBindingConfig[]{ | |||
| peerNodes[0].getLedgerBindingConfig(), | |||
| peerNodes[1].getLedgerBindingConfig(), | |||
| peerNodes[2].getLedgerBindingConfig(), | |||
| peerNodes[3].getLedgerBindingConfig(), | |||
| }, | |||
| new DbConnectionFactory[]{ | |||
| dbConnectionFactory0, | |||
| dbConnectionFactory1, | |||
| dbConnectionFactory2, | |||
| dbConnectionFactory3}); | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| LedgerQuery ledgerRepository = ledgers[0]; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(IntegrationBase.PRIV_KEYS[0], IntegrationBase.PASSWORD); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(IntegrationBase.PUB_KEYS[0]); | |||
| AsymmetricKeypair adminKey = new AsymmetricKeypair(pubKey0, privkey0); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| int size = 15; | |||
| CountDownLatch countDownLatch = new CountDownLatch(size); | |||
| if (isRegisterUser) { | |||
| for (int i = 0; i < size; i++) { | |||
| sendReqExecutors.execute(() -> { | |||
| System.out.printf(" sdk execute time = %s threadId = %s \r\n", System.currentTimeMillis(), Thread.currentThread().getId()); | |||
| IntegrationBase.KeyPairResponse userResponse = IntegrationBase.testSDK_RegisterUser(adminKey, ledgerHash, blockchainService); | |||
| // validKeyPair(userResponse, ledgerRepository, IntegrationBase.KeyPairType.USER); | |||
| countDownLatch.countDown(); | |||
| }); | |||
| } | |||
| } | |||
| try { | |||
| countDownLatch.await(); | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| if (isRegisterDataAccount) { | |||
| IntegrationBase.KeyPairResponse dataAccountResponse = IntegrationBase.testSDK_RegisterDataAccount(adminKey, ledgerHash, blockchainService); | |||
| validKeyPair(dataAccountResponse, ledgerRepository, IntegrationBase.KeyPairType.DATAACCOUNT); | |||
| if (isWriteKv) { | |||
| for (int m = 0; m < 13; m++) { | |||
| BlockchainKeypair da = dataAccountResponse.keyPair; | |||
| IntegrationBase.KvResponse kvResponse = IntegrationBase.testSDK_InsertData(adminKey, ledgerHash, blockchainService, da.getAddress()); | |||
| validKvWrite(kvResponse, ledgerRepository, blockchainService); | |||
| } | |||
| } | |||
| } | |||
| long participantCount = ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| long userCount = ledgerRepository.getUserAccountSet(ledgerRepository.retrieveLatestBlock()).getTotal(); | |||
| System.out.printf("before add participant: participantCount = %d, userCount = %d\r\n", (int)participantCount, (int)userCount); | |||
| IntegrationBase.KeyPairResponse participantResponse; | |||
| if (isRegisterParticipant) { | |||
| participantResponse = IntegrationBase.testSDK_RegisterParticipant(adminKey, ledgerHash, blockchainService); | |||
| } | |||
| participantCount = ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| userCount = ledgerRepository.getUserAccountSet(ledgerRepository.retrieveLatestBlock()).getTotal(); | |||
| System.out.printf("after add participant: participantCount = %d, userCount = %d\r\n", (int)participantCount, (int)userCount); | |||
| BftsmartConsensusSettings consensusSettings = (BftsmartConsensusSettings) ConsensusProviders.getProvider(BFTSMART_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminInfo().getSettings().getConsensusSetting().toBytes()); | |||
| System.out.printf("update participant state before ,old consensus env node num = %d\r\n", consensusSettings.getNodes().length); | |||
| for (int i = 0; i < participantCount; i++) { | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| } | |||
| if (isParticipantStateUpdate) { | |||
| IntegrationBase.testSDK_UpdateParticipantState(adminKey, new BlockchainKeypair(participantResponse.getKeyPair().getPubKey(), participantResponse.getKeyPair().getPrivKey()), ledgerHash, blockchainService); | |||
| } | |||
| BftsmartConsensusSettings consensusSettingsNew = (BftsmartConsensusSettings) ConsensusProviders.getProvider(BFTSMART_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getSettings().getConsensusSetting().toBytes()); | |||
| System.out.printf("update participant state after ,new consensus env node num = %d\r\n", consensusSettingsNew.getNodes().length); | |||
| for (int i = 0; i < participantCount; i++) { | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| } | |||
| try { | |||
| System.out.println("----------------- Init Completed -----------------"); | |||
| Thread.sleep(Integer.MAX_VALUE); | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| } | |||
| private HashDigest initLedger(String[] dbConnections) { | |||
| LedgerInitializeWeb4Nodes ledgerInit = new LedgerInitializeWeb4Nodes(); | |||
| HashDigest ledgerHash = ledgerInit.testInitWith4Nodes(LedgerInitConsensusConfig.bftsmartConfig, dbConnections); | |||
| System.out.printf("LedgerHash = %s \r\n", ledgerHash.toBase58()); | |||
| return ledgerHash; | |||
| } | |||
| } | |||
| @@ -1,122 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4Nodes; | |||
| import java.io.File; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.ExecutorService; | |||
| import java.util.concurrent.Executors; | |||
| import static test.com.jd.blockchain.intgr.IntegrationBase.*; | |||
| public class IntegrationTest4Contract { | |||
| private static final boolean isContractDeployAndExe = true; | |||
| private static final String DB_TYPE_MEM = "mem"; | |||
| @Test | |||
| public void test4Memory() { | |||
| test(LedgerInitConsensusConfig.bftsmartProvider, DB_TYPE_MEM, LedgerInitConsensusConfig.memConnectionStrings); | |||
| } | |||
| public void test(String[] providers, String dbType, String[] dbConnections) { | |||
| final ExecutorService sendReqExecutors = Executors.newFixedThreadPool(10); | |||
| // 内存账本初始化 | |||
| HashDigest ledgerHash = initLedger(dbConnections); | |||
| // 启动Peer节点 | |||
| PeerTestRunner[] peerNodes = peerNodeStart(ledgerHash, dbType); | |||
| DbConnectionFactory dbConnectionFactory0 = peerNodes[0].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory1 = peerNodes[1].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory2 = peerNodes[2].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory3 = peerNodes[3].getDBConnectionFactory(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeTest.PASSWORD); | |||
| GatewayConfigProperties.KeyPairConfig gwkey0 = new GatewayConfigProperties.KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(IntegrationBase.PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(IntegrationBase.PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway = new GatewayTestRunner("127.0.0.1", 11000, gwkey0, | |||
| peerNodes[0].getServiceAddress(), providers,null); | |||
| ThreadInvoker.AsyncCallback<Object> gwStarting = gateway.start(); | |||
| gwStarting.waitReturn(); | |||
| // 执行测试用例之前,校验每个节点的一致性; | |||
| LedgerQuery[] ledgers = buildLedgers(new LedgerBindingConfig[]{ | |||
| peerNodes[0].getLedgerBindingConfig(), | |||
| peerNodes[1].getLedgerBindingConfig(), | |||
| peerNodes[2].getLedgerBindingConfig(), | |||
| peerNodes[3].getLedgerBindingConfig(), | |||
| }, | |||
| new DbConnectionFactory[]{ | |||
| dbConnectionFactory0, | |||
| dbConnectionFactory1, | |||
| dbConnectionFactory2, | |||
| dbConnectionFactory3}); | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| LedgerQuery ledgerRepository = ledgers[0]; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(IntegrationBase.PRIV_KEYS[0], IntegrationBase.PASSWORD); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(IntegrationBase.PUB_KEYS[0]); | |||
| AsymmetricKeypair adminKey = new AsymmetricKeypair(pubKey0, privkey0); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| if(isContractDeployAndExe){ | |||
| // 合约测试需要runtime路径 | |||
| try { | |||
| ClassPathResource contractPath = new ClassPathResource(""); | |||
| File file = new File(contractPath.getURI()); | |||
| String runTimePath = file.getParentFile().getParent() + File.separator + "runtime"; | |||
| File runTime = new File(runTimePath); | |||
| if (!runTime.exists()) { | |||
| runTime.mkdir(); | |||
| } | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| IntegrationBase.testSDK_Contract(adminKey,ledgerHash,blockchainService,ledgerRepository); | |||
| } | |||
| try { | |||
| System.out.println("----------------- Init Completed -----------------"); | |||
| Thread.sleep(Integer.MAX_VALUE); | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| } | |||
| private HashDigest initLedger(String[] dbConnections) { | |||
| LedgerInitializeWeb4Nodes ledgerInit = new LedgerInitializeWeb4Nodes(); | |||
| HashDigest ledgerHash = ledgerInit.testInitWith4Nodes(LedgerInitConsensusConfig.bftsmartConfig, dbConnections); | |||
| System.out.printf("LedgerHash = %s \r\n", ledgerHash.toBase58()); | |||
| return ledgerHash; | |||
| } | |||
| } | |||
| @@ -1,213 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.bftsmart.BftsmartConsensusSettings; | |||
| import com.jd.blockchain.consensus.mq.settings.MsgQueueConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| import com.jd.blockchain.ledger.*; | |||
| import com.jd.blockchain.ledger.core.*; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import org.junit.Test; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4Nodes; | |||
| import java.util.HashMap; | |||
| import java.util.Map; | |||
| import static test.com.jd.blockchain.intgr.IntegrationBase.*; | |||
| public class IntegrationTest4MQ { | |||
| private static final boolean isRegisterUser = true; | |||
| private static final boolean isRegisterDataAccount = true; | |||
| private static final boolean isRegisterParticipant = true; | |||
| private static final boolean isParticipantStateUpdate = true; | |||
| private static final boolean isWriteKv = true; | |||
| private static final boolean isContract = false; | |||
| private static final boolean isOnline = true; | |||
| private static final int online_time = 60000*60; | |||
| private static final String DB_TYPE_MEM = "mem"; | |||
| private static final String DB_TYPE_REDIS = "redis"; | |||
| private static final String DB_TYPE_ROCKSDB = "rocksdb"; | |||
| private static final String DATA_RETRIEVAL_URL= "http://192.168.151.39:10001"; | |||
| public static final String MQ_PROVIDER = "com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider"; | |||
| @Test | |||
| public void test4Memory() { | |||
| test(LedgerInitConsensusConfig.mqProvider, DB_TYPE_MEM, LedgerInitConsensusConfig.memConnectionStrings); | |||
| } | |||
| @Test | |||
| public void test4Redis() { | |||
| // test(LedgerInitConsensusConfig.mqProvider, DB_TYPE_REDIS, LedgerInitConsensusConfig.redisConnectionStrings); | |||
| } | |||
| @Test | |||
| public void test4Rocksdb() { | |||
| test(LedgerInitConsensusConfig.mqProvider, DB_TYPE_ROCKSDB, LedgerInitConsensusConfig.rocksdbConnectionStrings); | |||
| } | |||
| public void test(String[] providers, String dbType, String[] dbConnections) { | |||
| // 内存账本初始化 | |||
| HashDigest ledgerHash = initLedger(dbType, dbConnections); | |||
| // 启动Peer节点 | |||
| PeerTestRunner[] peerNodes = peerNodeStart(ledgerHash, dbType); | |||
| DbConnectionFactory dbConnectionFactory0 = peerNodes[0].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory1 = peerNodes[1].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory2 = peerNodes[2].getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory3 = peerNodes[3].getDBConnectionFactory(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeTest.PASSWORD); | |||
| KeyPairConfig gwkey0 = new KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(IntegrationBase.PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(IntegrationBase.PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| Map<String,Object> otherMap = new HashMap<String,Object>(); | |||
| otherMap.put("DATA_RETRIEVAL_URL",DATA_RETRIEVAL_URL); | |||
| GatewayTestRunner gateway = new GatewayTestRunner("127.0.0.1", 11000, gwkey0, | |||
| peerNodes[0].getServiceAddress(), providers, otherMap); | |||
| AsyncCallback<Object> gwStarting = gateway.start(); | |||
| gwStarting.waitReturn(); | |||
| // 执行测试用例之前,校验每个节点的一致性; | |||
| LedgerQuery[] ledgers = buildLedgers(new LedgerBindingConfig[]{ | |||
| peerNodes[0].getLedgerBindingConfig(), | |||
| peerNodes[1].getLedgerBindingConfig(), | |||
| peerNodes[2].getLedgerBindingConfig(), | |||
| peerNodes[3].getLedgerBindingConfig(), | |||
| }, | |||
| new DbConnectionFactory[]{ | |||
| dbConnectionFactory0, | |||
| dbConnectionFactory1, | |||
| dbConnectionFactory2, | |||
| dbConnectionFactory3}); | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| LedgerQuery ledgerRepository = ledgers[0]; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(IntegrationBase.PRIV_KEYS[0], IntegrationBase.PASSWORD); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(IntegrationBase.PUB_KEYS[0]); | |||
| AsymmetricKeypair adminKey = new AsymmetricKeypair(pubKey0, privkey0); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| if (isRegisterUser) { | |||
| IntegrationBase.KeyPairResponse userResponse = IntegrationBase.testSDK_RegisterUser(adminKey, ledgerHash, blockchainService); | |||
| validKeyPair(userResponse, ledgerRepository, IntegrationBase.KeyPairType.USER); | |||
| } | |||
| if (isRegisterDataAccount) { | |||
| IntegrationBase.KeyPairResponse dataAccountResponse = IntegrationBase.testSDK_RegisterDataAccount(adminKey, ledgerHash, blockchainService); | |||
| validKeyPair(dataAccountResponse, ledgerRepository, IntegrationBase.KeyPairType.DATAACCOUNT); | |||
| if (isWriteKv) { | |||
| BlockchainKeypair da = dataAccountResponse.keyPair; | |||
| IntegrationBase.KvResponse kvResponse = IntegrationBase.testSDK_InsertData(adminKey, ledgerHash, blockchainService, da.getAddress()); | |||
| validKvWrite(kvResponse, ledgerRepository, blockchainService); | |||
| } | |||
| } | |||
| if(isContract){ | |||
| IntegrationBase integrationBase = new IntegrationBase(); | |||
| integrationBase.testSDK_Contract(adminKey, ledgerHash, blockchainService,ledgerRepository); | |||
| } | |||
| long participantCount = ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| long userCount = ledgerRepository.getUserAccountSet(ledgerRepository.retrieveLatestBlock()).getTotal(); | |||
| System.out.printf("before add participant: participantCount = %d, userCount = %d\r\n", (int)participantCount, (int)userCount); | |||
| IntegrationBase.KeyPairResponse participantResponse; | |||
| if (isRegisterParticipant) { | |||
| participantResponse = IntegrationBase.testSDK_RegisterParticipant(adminKey, ledgerHash, blockchainService); | |||
| } | |||
| participantCount = ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipantCount(); | |||
| userCount = ledgerRepository.getUserAccountSet(ledgerRepository.retrieveLatestBlock()).getTotal(); | |||
| System.out.printf("after add participant: participantCount = %d, userCount = %d\r\n", (int)participantCount, (int)userCount); | |||
| MsgQueueConsensusSettings consensusSettings = (MsgQueueConsensusSettings) ConsensusProviders.getProvider(MQ_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminInfo().getSettings().getConsensusSetting().toBytes()); | |||
| System.out.printf("update participant state before ,old consensus env node num = %d\r\n", consensusSettings.getNodes().length); | |||
| for (int i = 0; i < participantCount; i++) { | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| } | |||
| if (isParticipantStateUpdate) { | |||
| IntegrationBase.testSDK_UpdateParticipantState(adminKey, new BlockchainKeypair(participantResponse.getKeyPair().getPubKey(), participantResponse.getKeyPair().getPrivKey()), ledgerHash, blockchainService); | |||
| } | |||
| BftsmartConsensusSettings consensusSettingsNew = (BftsmartConsensusSettings) ConsensusProviders.getProvider(MQ_PROVIDER).getSettingsFactory().getConsensusSettingsEncoder().decode(ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getSettings().getConsensusSetting().toBytes()); | |||
| System.out.printf("update participant state after ,new consensus env node num = %d\r\n", consensusSettingsNew.getNodes().length); | |||
| for (int i = 0; i < participantCount; i++) { | |||
| System.out.printf("part%d state = %d\r\n",i, ledgerRepository.getAdminInfo(ledgerRepository.retrieveLatestBlock()).getParticipants()[i].getParticipantNodeState().CODE); | |||
| } | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| if(isOnline){ | |||
| try { | |||
| Thread.sleep(online_time); | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| private HashDigest initLedger(String dbType, String[] dbConnections) { | |||
| if (dbType.equalsIgnoreCase(DB_TYPE_ROCKSDB)) { | |||
| // rocksdb 需要先删除文件 | |||
| for (String dbDir : LedgerInitConsensusConfig.rocksdbDirStrings) { | |||
| try { | |||
| FileUtils.deleteFile(dbDir); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| LedgerInitializeWeb4Nodes ledgerInit = new LedgerInitializeWeb4Nodes(); | |||
| HashDigest ledgerHash = ledgerInit.testInitWith4Nodes(LedgerInitConsensusConfig.mqConfig, dbConnections); | |||
| System.out.printf("LedgerHash = %s \r\n", ledgerHash.toBase58()); | |||
| return ledgerHash; | |||
| } | |||
| } | |||
| @@ -1,542 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import static org.junit.Assert.assertArrayEquals; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNotNull; | |||
| import static org.junit.Assert.assertTrue; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Random; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.BytesValue; | |||
| import com.jd.blockchain.ledger.DataAccountKVSetOperation; | |||
| import com.jd.blockchain.ledger.TypedKVEntry; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInfo; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.PreparedTransaction; | |||
| import com.jd.blockchain.ledger.TransactionResponse; | |||
| import com.jd.blockchain.ledger.TransactionState; | |||
| import com.jd.blockchain.ledger.TransactionTemplate; | |||
| import com.jd.blockchain.ledger.core.DataAccount; | |||
| import com.jd.blockchain.ledger.core.DataAccountQuery; | |||
| import com.jd.blockchain.ledger.core.LedgerManage; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.codec.HexUtils; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.contract.AssetContract; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; | |||
| public class IntegrationTestAll4Redis { | |||
| public static final String PASSWORD = "abc"; | |||
| public static final String[] PUB_KEYS = { "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9", | |||
| "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX", | |||
| "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x", | |||
| "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" }; | |||
| public static final String[] PRIV_KEYS = { | |||
| "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x", | |||
| "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT", | |||
| "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF", | |||
| "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" }; | |||
| // batch transactions keys | |||
| BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| BlockchainKeypair dataKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| // 合约测试使用的初始化数据; | |||
| BlockchainKeypair contractDataKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| BlockchainKeypair contractDeployKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| private String contractZipName = "AssetContract1.contract"; | |||
| private String eventName = "issue-asset"; | |||
| HashDigest txContentHash; | |||
| String pubKeyVal = "jd.com" + System.currentTimeMillis(); | |||
| // String userPubKeyVal = "this is user's pubKey"; | |||
| // 保存资产总数的键; | |||
| private static final String KEY_TOTAL = "TOTAL"; | |||
| // 第二个参数; | |||
| private static final String KEY_ABC = "abc"; | |||
| @Test | |||
| public void test() { | |||
| NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 10200); | |||
| LedgerBindingConfig bindingConfig0 = loadBindingConfig(0); | |||
| PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, bindingConfig0); | |||
| NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 10210); | |||
| LedgerBindingConfig bindingConfig1 = loadBindingConfig(1); | |||
| PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, bindingConfig1); | |||
| NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 10220); | |||
| LedgerBindingConfig bindingConfig2 = loadBindingConfig(2); | |||
| PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, bindingConfig2); | |||
| NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 10230); | |||
| LedgerBindingConfig bindingConfig3 = loadBindingConfig(3); | |||
| PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, bindingConfig3); | |||
| AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
| AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
| AsyncCallback<Object> peerStarting2 = peer2.start(); | |||
| AsyncCallback<Object> peerStarting3 = peer3.start(); | |||
| peerStarting0.waitReturn(); | |||
| peerStarting1.waitReturn(); | |||
| peerStarting2.waitReturn(); | |||
| peerStarting3.waitReturn(); | |||
| DbConnectionFactory dbConnectionFactory0 = peer0.getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory1 = peer1.getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory2 = peer2.getDBConnectionFactory(); | |||
| DbConnectionFactory dbConnectionFactory3 = peer3.getDBConnectionFactory(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| KeyPairConfig gwkey0 = new KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway0 = new GatewayTestRunner("127.0.0.1", 11000, gwkey0, peerSrvAddr0); | |||
| AsyncCallback<Object> gwStarting0 = gateway0.start(); | |||
| gwStarting0.waitReturn(); | |||
| // 执行测试用例之前,校验每个节点的一致性; | |||
| LedgerQuery[] ledgers = buildLedgers( | |||
| new LedgerBindingConfig[] { bindingConfig0, bindingConfig1, bindingConfig2, bindingConfig3 }, | |||
| new DbConnectionFactory[] { dbConnectionFactory0, dbConnectionFactory1, dbConnectionFactory2, | |||
| dbConnectionFactory3 }); | |||
| testConsistencyAmongNodes(ledgers); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(PUB_KEYS[0]); | |||
| PubKey pubKey1 = KeyGenUtils.decodePubKey(PUB_KEYS[1]); | |||
| PubKey pubKey2 = KeyGenUtils.decodePubKey(PUB_KEYS[2]); | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| AsymmetricKeypair adminKey = new AsymmetricKeypair(pubKey0, privkey0); | |||
| testWriteBatchTransactions(gateway0, adminKey, ledgers[0]); | |||
| testSDK(gateway0, adminKey, ledgers[0]); | |||
| // 执行测试用例之后,校验每个节点的一致性; | |||
| testConsistencyAmongNodes(ledgers); | |||
| } | |||
| private LedgerBindingConfig loadBindingConfig(int id) { | |||
| ClassPathResource res = new ClassPathResource("ledger-binding-redis-" + id + ".conf"); | |||
| try (InputStream in = res.getInputStream()) { | |||
| return LedgerBindingConfig.resolve(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| private LedgerQuery[] buildLedgers(LedgerBindingConfig[] bindingConfigs, | |||
| DbConnectionFactory[] dbConnectionFactories) { | |||
| int[] ids = { 0, 1, 2, 3 }; | |||
| LedgerQuery[] ledgers = new LedgerQuery[ids.length]; | |||
| LedgerManager[] ledgerManagers = new LedgerManager[ids.length]; | |||
| for (int i = 0; i < ids.length; i++) { | |||
| ledgerManagers[i] = new LedgerManager(); | |||
| HashDigest ledgerHash = bindingConfigs[0].getLedgerHashs()[0]; | |||
| DbConnection conn = dbConnectionFactories[i].connect( | |||
| bindingConfigs[i].getLedger(ledgerHash).getDbConnection().getUri(), | |||
| bindingConfigs[i].getLedger(ledgerHash).getDbConnection().getPassword()); | |||
| ledgers[i] = ledgerManagers[i].register(ledgerHash, conn.getStorageService()); | |||
| } | |||
| return ledgers; | |||
| } | |||
| private void testConsistencyAmongNodes(LedgerQuery[] ledgers) { | |||
| LedgerQuery ledger0 = ledgers[0]; | |||
| LedgerBlock latestBlock0 = ledger0.retrieveLatestBlock(); | |||
| for (int i = 1; i < ledgers.length; i++) { | |||
| LedgerQuery otherLedger = ledgers[i]; | |||
| LedgerBlock otherLatestBlock = otherLedger.retrieveLatestBlock(); | |||
| assertEquals(ledger0.getHash(), otherLedger.getHash()); | |||
| assertEquals(ledger0.getLatestBlockHeight(), otherLedger.getLatestBlockHeight()); | |||
| assertEquals(latestBlock0.getHeight(), otherLatestBlock.getHeight()); | |||
| assertEquals(latestBlock0.getAdminAccountHash(), otherLatestBlock.getAdminAccountHash()); | |||
| assertEquals(latestBlock0.getUserAccountSetHash(), otherLatestBlock.getUserAccountSetHash()); | |||
| assertEquals(latestBlock0.getDataAccountSetHash(), otherLatestBlock.getDataAccountSetHash()); | |||
| assertEquals(latestBlock0.getContractAccountSetHash(), otherLatestBlock.getContractAccountSetHash()); | |||
| assertEquals(latestBlock0.getPreviousHash(), otherLatestBlock.getPreviousHash()); | |||
| assertEquals(latestBlock0.getTransactionSetHash(), otherLatestBlock.getTransactionSetHash()); | |||
| assertEquals(ledger0.getLatestBlockHash(), otherLedger.getLatestBlockHash()); | |||
| assertEquals(latestBlock0.getHash(), otherLatestBlock.getHash()); | |||
| } | |||
| } | |||
| // 测试一个区块包含多个交易的写入情况,并验证写入结果; | |||
| private void testWriteBatchTransactions(GatewayTestRunner gateway, AsymmetricKeypair adminKey, | |||
| LedgerQuery ledgerRepository) { | |||
| // 连接网关; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| HashDigest[] ledgerHashs = blockchainService.getLedgerHashs(); | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHashs[0]); | |||
| // regist user account | |||
| txTpl.users().register(userKey.getIdentity()); | |||
| // regist data account | |||
| txTpl.dataAccounts().register(dataKey.getIdentity()); | |||
| // add kv ops for data account | |||
| DataAccountKVSetOperation dataKvsetOP = txTpl.dataAccount(dataKey.getAddress()).setText("A", "Value_A_0", -1) | |||
| .setText("B", "Value_B_0", -1).setText("C", "Value_C_0", -1).setText("D", "Value_D_0", -1) | |||
| .getOperation(); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| assertTrue(txResp.isSuccess()); | |||
| assertEquals(ledgerRepository.retrieveLatestBlockHeight(), txResp.getBlockHeight()); | |||
| assertEquals("Value_A_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) | |||
| .getAccount(dataKey.getAddress()).getDataset().getValue("A").getBytes().toUTF8String()); | |||
| assertEquals("Value_B_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) | |||
| .getAccount(dataKey.getAddress()).getDataset().getValue("B").getBytes().toUTF8String()); | |||
| assertEquals("Value_C_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) | |||
| .getAccount(dataKey.getAddress()).getDataset().getValue("C").getBytes().toUTF8String()); | |||
| assertEquals("Value_D_0", ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) | |||
| .getAccount(dataKey.getAddress()).getDataset().getValue("D").getBytes().toUTF8String()); | |||
| assertEquals(0, ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) | |||
| .getAccount(dataKey.getAddress()).getDataset().getVersion("A")); | |||
| assertEquals(0, ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) | |||
| .getAccount(dataKey.getAddress()).getDataset().getVersion("B")); | |||
| assertEquals(0, ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) | |||
| .getAccount(dataKey.getAddress()).getDataset().getVersion("C")); | |||
| assertEquals(0, ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()) | |||
| .getAccount(dataKey.getAddress()).getDataset().getVersion("D")); | |||
| return; | |||
| } | |||
| private void testSDK(GatewayTestRunner gateway, AsymmetricKeypair adminKey, LedgerQuery ledgerRepository) { | |||
| // 连接网关; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| BlockchainService bcsrv = gwsrvFact.getBlockchainService(); | |||
| HashDigest[] ledgerHashs = bcsrv.getLedgerHashs(); | |||
| BlockchainKeypair newUserAcount = testSDK_RegisterUser(adminKey, ledgerHashs[0], bcsrv, ledgerRepository); | |||
| BlockchainKeypair newDataAccount = testSDK_RegisterDataAccount(adminKey, ledgerHashs[0], bcsrv, | |||
| ledgerRepository); | |||
| testSDK_InsertData(adminKey, ledgerHashs[0], bcsrv, newDataAccount.getAddress(), ledgerRepository); | |||
| LedgerBlock latestBlock = testSDK_Contract(adminKey, ledgerHashs[0], bcsrv, ledgerRepository); | |||
| } | |||
| private void testSDK_InsertData(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService, Bytes dataAccountAddress, LedgerQuery ledgerRepository) { | |||
| // 在本地定义注册账号的 TX; | |||
| TransactionTemplate txTemp = blockchainService.newTransaction(ledgerHash); | |||
| // -------------------------------------- | |||
| // 将商品信息写入到指定的账户中; | |||
| // 对象将被序列化为 JSON 形式存储,并基于 JSON 结构建立查询索引; | |||
| Bytes dataAccount = dataAccountAddress; | |||
| String dataKey = "jingdong" + new Random().nextInt(100000); | |||
| String dataVal = "www.jd.com"; | |||
| txTemp.dataAccount(dataAccount).setText(dataKey, dataVal, -1); | |||
| // TX 准备就绪; | |||
| PreparedTransaction prepTx = txTemp.prepare(); | |||
| // 使用私钥进行签名; | |||
| prepTx.sign(adminKey); | |||
| // 提交交易; | |||
| TransactionResponse txResp = prepTx.commit(); | |||
| ledgerRepository.retrieveLatestBlock(); // 更新内存 | |||
| // 先验证应答 | |||
| assertEquals(TransactionState.SUCCESS, txResp.getExecutionState()); | |||
| assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); | |||
| assertEquals(txResp.getContentHash(), prepTx.getHash()); | |||
| assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); | |||
| TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHash, dataAccountAddress.toString(), | |||
| dataKey); | |||
| for (TypedKVEntry kvDataEntry : kvDataEntries) { | |||
| assertEquals(dataKey, kvDataEntry.getKey()); | |||
| String valHexText = (String) kvDataEntry.getValue(); | |||
| byte[] valBytes = HexUtils.decode(valHexText); | |||
| String valText = new String(valBytes); | |||
| System.out.println(valText); | |||
| } | |||
| } | |||
| private BlockchainKeypair testSDK_RegisterDataAccount(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService, LedgerQuery ledgerRepository) { | |||
| // 注册数据账户,并验证最终写入; | |||
| BlockchainKeypair dataAccount = BlockchainKeyGenerator.getInstance().generate(); | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.dataAccounts().register(dataAccount.getIdentity()); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| HashDigest transactionHash = ptx.getHash(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| // 验证结果; | |||
| // LedgerRepository ledgerOfNode0 = | |||
| // node0.getLedgerManager().getLedger(ledgerHash); | |||
| LedgerManage ledgerManager = new LedgerManager(); | |||
| long latestBlockHeight = ledgerRepository.retrieveLatestBlockHeight(); | |||
| assertEquals(txResp.getExecutionState(), TransactionState.SUCCESS); | |||
| assertEquals(txResp.getBlockHeight(), latestBlockHeight); | |||
| assertEquals(txResp.getContentHash(), transactionHash); | |||
| assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); | |||
| assertNotNull(ledgerRepository.getDataAccountSet(ledgerRepository.getLatestBlock()) | |||
| .getAccount(dataAccount.getAddress())); | |||
| return dataAccount; | |||
| } | |||
| private BlockchainKeypair testSDK_RegisterUser(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService, LedgerQuery ledgerRepository) { | |||
| // 注册用户,并验证最终写入; | |||
| BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.users().register(user.getIdentity()); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| HashDigest transactionHash = ptx.getHash(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| // 验证结果; | |||
| LedgerManage ledgerManager = new LedgerManager(); | |||
| assertEquals(txResp.getExecutionState(), TransactionState.SUCCESS); | |||
| assertEquals(txResp.getBlockHeight(), ledgerRepository.getLatestBlockHeight()); | |||
| assertEquals(txResp.getContentHash(), transactionHash); | |||
| assertEquals(txResp.getBlockHash(), ledgerRepository.getLatestBlockHash()); | |||
| assertTrue(ledgerRepository.getUserAccountSet(ledgerRepository.getLatestBlock()).contains(user.getAddress())); | |||
| return user; | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_integration() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_integration.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| private LedgerBlock testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService, LedgerQuery ledgerRepository) { | |||
| System.out.println("adminKey=" + AddressEncoding.generateAddress(adminKey.getPubKey())); | |||
| BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| System.out.println("userKey=" + userKey.getAddress()); | |||
| // valid the basic data in contract; | |||
| // prepareContractData(adminKey, ledgerHash, | |||
| // blockchainService,ledgerRepository); | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.users().register(userKey.getIdentity()); | |||
| // 定义交易; | |||
| // 注册数据账户,并验证最终写入; | |||
| txTpl.dataAccounts().register(contractDataKey.getIdentity()); | |||
| // dataAccountSet.getDataAccount(dataAddress) | |||
| DataAccount dataAccount = ledgerRepository.getDataAccountSet(ledgerRepository.getLatestBlock()) | |||
| .getAccount(contractDataKey.getAddress()); | |||
| DataAccountKVSetOperation kvsetOP = txTpl.dataAccount(contractDataKey.getAddress()) | |||
| .setText("A", "Value_A_0", -1).setText("B", "Value_B_0", -1) | |||
| .setText(KEY_TOTAL, "total value,dataAccount", -1).setText(KEY_ABC, "abc value,dataAccount", -1) | |||
| // 所有的模拟数据都在这个dataAccount中填充; | |||
| .setBytes("ledgerHash", ledgerHash.getRawDigest(), -1).getOperation(); | |||
| byte[] contractCode = getChainCodeBytes(); | |||
| txTpl.contracts().deploy(contractDeployKey.getIdentity(), contractCode); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| assertTrue(txResp.isSuccess()); | |||
| // 验证结果; | |||
| txResp.getContentHash(); | |||
| LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight()); | |||
| byte[] contractCodeInDb = ledgerRepository.getContractAccountSet(block) | |||
| .getAccount(contractDeployKey.getAddress()).getChainCode(); | |||
| assertArrayEquals(contractCode, contractCodeInDb); | |||
| txContentHash = ptx.getHash(); | |||
| // execute the contract; | |||
| testContractExe(adminKey, ledgerHash, userKey, blockchainService, ledgerRepository); | |||
| return block; | |||
| } | |||
| private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, | |||
| BlockchainService blockchainService, LedgerQuery ledgerRepository) { | |||
| LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||
| LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| txTpl.contract(contractDeployKey.getAddress(), AssetContract.class).issue(10,"abc"); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| // 验证结果; | |||
| txResp.getContentHash(); | |||
| LedgerInfo latestLedgerInfo = blockchainService.getLedger(ledgerHash); | |||
| assertEquals(ledgerInfo.getLatestBlockHeight() + 1, latestLedgerInfo.getLatestBlockHeight()); | |||
| assertEquals(txResp.getBlockHeight(), latestLedgerInfo.getLatestBlockHeight()); | |||
| LedgerBlock backgroundLedgerBlock = ledgerRepository.retrieveLatestBlock(); | |||
| assertEquals(txResp.getBlockHeight(), backgroundLedgerBlock.getHeight()); | |||
| // 验证合约中的赋值,外部可以获得; | |||
| DataAccountQuery dataAccountSet = ledgerRepository.getDataAccountSet(backgroundLedgerBlock); | |||
| AsymmetricKeypair key = Crypto.getSignatureFunction("ED25519").generateKeypair(); | |||
| PubKey pubKey = key.getPubKey(); | |||
| Bytes dataAddress = AddressEncoding.generateAddress(pubKey); | |||
| assertEquals(dataAddress, dataAccountSet.getAccount(dataAddress).getID().getAddress()); | |||
| assertEquals("hello", | |||
| dataAccountSet.getAccount(dataAddress).getDataset().getValue(KEY_TOTAL, -1).getBytes().toUTF8String()); | |||
| // 验证userAccount,从合约内部赋值,然后外部验证;内部定义动态key,外部不便于得到,临时屏蔽; | |||
| // UserAccountSet userAccountSet = | |||
| // ledgerRepository.getUserAccountSet(backgroundLedgerBlock); | |||
| // PubKey userPubKey = new PubKey(CryptoAlgorithm.ED25519, | |||
| // userPubKeyVal.getBytes()); | |||
| // String userAddress = AddressEncoding.generateAddress(userPubKey); | |||
| // assertEquals(userAddress, userAccountSet.getUser(userAddress).getAddress()); | |||
| } | |||
| private void prepareContractData(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
| BlockchainService blockchainService, LedgerQuery ledgerRepository) { | |||
| // 定义交易; | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| assertTrue(txResp.isSuccess()); | |||
| // 验证结果; | |||
| LedgerBlock block = ledgerRepository.getBlock(txResp.getBlockHeight()); | |||
| BytesValue val1InDb = ledgerRepository.getDataAccountSet(block).getAccount(contractDataKey.getAddress()) | |||
| .getDataset().getValue("A"); | |||
| BytesValue val2InDb = ledgerRepository.getDataAccountSet(block).getAccount(contractDataKey.getAddress()) | |||
| .getDataset().getValue(KEY_TOTAL); | |||
| assertEquals("Value_A_0", val1InDb.getBytes().toUTF8String()); | |||
| assertEquals("total value,dataAccount", val2InDb.getBytes().toUTF8String()); | |||
| } | |||
| /** | |||
| * 根据合约构建字节数组; | |||
| * | |||
| * @return | |||
| */ | |||
| private byte[] getChainCodeBytes() { | |||
| // 构建合约的字节数组; | |||
| byte[] contractCode = null; | |||
| File file = null; | |||
| InputStream input = null; | |||
| try { | |||
| ClassPathResource contractPath = new ClassPathResource(contractZipName); | |||
| file = new File(contractPath.getURI()); | |||
| assertTrue("contract zip file is not exist.", file.exists() == true); | |||
| input = new FileInputStream(file); | |||
| // 这种暴力的读取压缩包,在class解析时有问题,所有需要改进; | |||
| contractCode = new byte[input.available()]; | |||
| input.read(contractCode); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } finally { | |||
| try { | |||
| if (input != null) { | |||
| input.close(); | |||
| } | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| return contractCode; | |||
| } | |||
| } | |||
| @@ -1,386 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNotNull; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
| import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.DataAccountKVSetOperation; | |||
| import com.jd.blockchain.ledger.TypedKVEntry; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.PreparedTransaction; | |||
| import com.jd.blockchain.ledger.TransactionResponse; | |||
| import com.jd.blockchain.ledger.TransactionTemplate; | |||
| import com.jd.blockchain.ledger.core.DataAccountQuery; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.BytesUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.IntegratedContext.Node; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class IntegrationTestDataAccount { | |||
| LedgerInitConsensusConfig.ConsensusConfig config = LedgerInitConsensusConfig.mqConfig; | |||
| public IntegratedContext context = initLedgers(config, LedgerInitConsensusConfig.memConnectionStrings); | |||
| public GatewayTestRunner gateway0; | |||
| public GatewayTestRunner gateway1; | |||
| private class JsonTest { | |||
| String name; | |||
| public JsonTest(String name) { | |||
| this.name = name; | |||
| } | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| } | |||
| @Test | |||
| public void startPeer() { | |||
| // init ledgers of all nodes ; | |||
| Node node0 = context.getNode(0); | |||
| Node node1 = context.getNode(1); | |||
| Node node2 = context.getNode(2); | |||
| Node node3 = context.getNode(3); | |||
| NetworkAddress peerSrvAddr0 = new NetworkAddress("127.0.0.1", 14200); | |||
| PeerTestRunner peer0 = new PeerTestRunner(peerSrvAddr0, node0.getBindingConfig(), node0.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr1 = new NetworkAddress("127.0.0.1", 14210); | |||
| PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, node1.getBindingConfig(), node1.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 14220); | |||
| PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, node2.getBindingConfig(), node2.getStorageDB(), null); | |||
| NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 14230); | |||
| PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, node3.getBindingConfig(), node3.getStorageDB(), null); | |||
| AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
| AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
| AsyncCallback<Object> peerStarting2 = peer2.start(); | |||
| AsyncCallback<Object> peerStarting3 = peer3.start(); | |||
| peerStarting0.waitReturn(); | |||
| peerStarting1.waitReturn(); | |||
| peerStarting2.waitReturn(); | |||
| peerStarting3.waitReturn(); | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| KeyPairConfig gwkey0 = new KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(LedgerInitializeWeb4SingleStepsTest.PUB_KEYS[0]); | |||
| gwkey0.setPrivKeyValue(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| gateway0 = new GatewayTestRunner("127.0.0.1", 13300, gwkey0, peerSrvAddr0); | |||
| KeyPairConfig gwkey1 = new KeyPairConfig(); | |||
| gwkey1.setPubKeyValue(LedgerInitializeWeb4SingleStepsTest.PUB_KEYS[1]); | |||
| gwkey1.setPrivKeyValue(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[1]); | |||
| gwkey1.setPrivKeyPassword(encodedBase58Pwd); | |||
| gateway1 = new GatewayTestRunner("127.0.0.1", 13310, gwkey1, peerSrvAddr1); | |||
| AsyncCallback<Object> gwStarting0 = gateway0.start(); | |||
| AsyncCallback<Object> gwStarting1 = gateway1.start(); | |||
| gwStarting0.waitReturn(); | |||
| gwStarting1.waitReturn(); | |||
| // 执行测试用例之前,校验每个节点的一致性; | |||
| testConsistencyAmongNodes(context); | |||
| // temp test add | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[0], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(LedgerInitializeWeb4SingleStepsTest.PUB_KEYS[0]); | |||
| AsymmetricKeypair adminKey = new AsymmetricKeypair(pubKey0, privkey0); | |||
| // regist data account | |||
| Bytes dataAddr = registDataAccount(gateway0, adminKey, context); | |||
| // add kv ops to data account | |||
| testAddKvOpToDataAccount(gateway0, adminKey, context, dataAddr); | |||
| // 执行测试用例之后,校验每个节点的一致性; | |||
| testConsistencyAmongNodes(context); | |||
| } | |||
| private Bytes registDataAccount(GatewayTestRunner gateway, AsymmetricKeypair adminKey, IntegratedContext context) { | |||
| // 连接网关; | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| HashDigest[] ledgerHashs = blockchainService.getLedgerHashs(); | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHashs[0]); | |||
| // BlockchainKeyPair user = BlockchainKeyGenerator.getInstance().generate(); | |||
| BlockchainKeypair data = BlockchainKeyGenerator.getInstance().generate(); | |||
| // regist user account | |||
| // txTpl.users().register(user.getIdentity()); | |||
| // //regist data account | |||
| txTpl.dataAccounts().register(data.getIdentity()); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| try { | |||
| Thread.sleep(6000); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return data.getAddress(); | |||
| } | |||
| // 通过调用SDK->GATEWAY,测试一个区块包含多个交易时的写入情况,并验证写入结果; | |||
| private void testAddKvOpToDataAccount(GatewayTestRunner gateway, AsymmetricKeypair adminKey, | |||
| IntegratedContext context, Bytes dataAddr) { | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| HashDigest[] ledgerHashs = blockchainService.getLedgerHashs(); | |||
| LedgerManager ledgerManager = context.getNode(0).getLedgerManager(); | |||
| DbConnection memoryBasedDb = context.getNode(0).getStorageDB() | |||
| .connect(LedgerInitConsensusConfig.memConnectionStrings[0]); | |||
| LedgerQuery ledgerRepository = ledgerManager.register(ledgerHashs[0], memoryBasedDb.getStorageService()); | |||
| DataAccountQuery dataAccountSet = ledgerRepository.getDataAccountSet(ledgerRepository.retrieveLatestBlock()); | |||
| TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHashs[0]); | |||
| long currentTime = System.currentTimeMillis(); | |||
| byte[] time = BytesUtils.toBytes(currentTime); | |||
| JsonTest jsonTest = new JsonTest("Jack"); | |||
| // | |||
| // //add kv ops for data account: Bytes, string, long, json string | |||
| DataAccountKVSetOperation dataKvsetOP = txTpl.dataAccount(dataAddr).setText("A", "Value_A_0", -1) | |||
| .setText("B", "Value_B_0", -1).setInt64("C", currentTime, -1).setText("D", JSON.toJSONString(jsonTest), -1) | |||
| .getOperation(); | |||
| // 签名; | |||
| PreparedTransaction ptx = txTpl.prepare(); | |||
| ptx.sign(adminKey); | |||
| // 提交并等待共识返回; | |||
| TransactionResponse txResp = ptx.commit(); | |||
| try { | |||
| Thread.sleep(6000); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| TypedKVEntry[] kvDataEntries = blockchainService.getDataEntries(ledgerHashs[0], dataAddr.toBase58(), "A", "B", | |||
| "C", "D"); | |||
| for (int i = 0; i < kvDataEntries.length; i++) { | |||
| Object result = kvDataEntries[i].getValue(); | |||
| System.out.println("result = " + result); | |||
| } | |||
| return; | |||
| } | |||
| public void testConsistencyAmongNodes(IntegratedContext context) { | |||
| int[] ids = context.getNodeIds(); | |||
| Node[] nodes = new Node[ids.length]; | |||
| LedgerQuery[] ledgers = new LedgerQuery[ids.length]; | |||
| for (int i = 0; i < nodes.length; i++) { | |||
| nodes[i] = context.getNode(ids[i]); | |||
| HashDigest ledgerHash = nodes[i].getLedgerManager().getLedgerHashs()[0]; | |||
| ledgers[i] = nodes[i].getLedgerManager().getLedger(ledgerHash); | |||
| } | |||
| LedgerQuery ledger0 = ledgers[0]; | |||
| LedgerBlock latestBlock0 = ledger0.retrieveLatestBlock(); | |||
| for (int i = 1; i < ledgers.length; i++) { | |||
| LedgerQuery otherLedger = ledgers[i]; | |||
| LedgerBlock otherLatestBlock = otherLedger.retrieveLatestBlock(); | |||
| assertEquals(ledger0.getHash(), otherLedger.getHash()); | |||
| assertEquals(ledger0.getLatestBlockHeight(), otherLedger.getLatestBlockHeight()); | |||
| assertEquals(ledger0.getLatestBlockHash(), otherLedger.getLatestBlockHash()); | |||
| assertEquals(latestBlock0.getHeight(), otherLatestBlock.getHeight()); | |||
| assertEquals(latestBlock0.getHash(), otherLatestBlock.getHash()); | |||
| assertEquals(latestBlock0.getAdminAccountHash(), otherLatestBlock.getAdminAccountHash()); | |||
| assertEquals(latestBlock0.getTransactionSetHash(), otherLatestBlock.getTransactionSetHash()); | |||
| assertEquals(latestBlock0.getUserAccountSetHash(), otherLatestBlock.getUserAccountSetHash()); | |||
| assertEquals(latestBlock0.getDataAccountSetHash(), otherLatestBlock.getDataAccountSetHash()); | |||
| assertEquals(latestBlock0.getContractAccountSetHash(), otherLatestBlock.getContractAccountSetHash()); | |||
| assertEquals(latestBlock0.getPreviousHash(), otherLatestBlock.getPreviousHash()); | |||
| } | |||
| } | |||
| private IntegratedContext initLedgers(LedgerInitConsensusConfig.ConsensusConfig config, String[] dbConns) { | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting_integration(); | |||
| Properties props = LedgerInitializeWeb4SingleStepsTest.loadConsensusSetting(config.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeWebContext nodeCtx0 = new NodeWebContext(0, initAddr0); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeWebContext nodeCtx1 = new NodeWebContext(1, initAddr1); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeWebContext nodeCtx2 = new NodeWebContext(2, initAddr2); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeWebContext nodeCtx3 = new NodeWebContext(3, initAddr3); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[0], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[1], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[2], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeWeb4SingleStepsTest.PRIV_KEYS[3], | |||
| LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| String encodedPassword = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeWeb4SingleStepsTest.PASSWORD); | |||
| CountDownLatch quitLatch = new CountDownLatch(4); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri(dbConns[0]); | |||
| LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, testDb0, | |||
| consolePrompter, bindingConfig0, quitLatch); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri(dbConns[1]); | |||
| LedgerBindingConfig bindingConfig1 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback1 = nodeCtx1.startInitCommand(privkey1, encodedPassword, initSetting, testDb1, | |||
| consolePrompter, bindingConfig1, quitLatch); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri(dbConns[2]); | |||
| LedgerBindingConfig bindingConfig2 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback2 = nodeCtx2.startInitCommand(privkey2, encodedPassword, initSetting, testDb2, | |||
| consolePrompter, bindingConfig2, quitLatch); | |||
| DBConnectionConfig testDb3 = new DBConnectionConfig(); | |||
| testDb3.setConnectionUri(dbConns[3]); | |||
| LedgerBindingConfig bindingConfig3 = new LedgerBindingConfig(); | |||
| AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, | |||
| consolePrompter, bindingConfig3, quitLatch); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| assertNotNull(ledgerHash0); | |||
| assertEquals(ledgerHash0, ledgerHash1); | |||
| assertEquals(ledgerHash0, ledgerHash2); | |||
| assertEquals(ledgerHash0, ledgerHash3); | |||
| LedgerQuery ledger0 = nodeCtx0.registLedger(ledgerHash0); | |||
| LedgerQuery ledger1 = nodeCtx1.registLedger(ledgerHash1); | |||
| LedgerQuery ledger2 = nodeCtx2.registLedger(ledgerHash2); | |||
| LedgerQuery ledger3 = nodeCtx3.registLedger(ledgerHash3); | |||
| assertNotNull(ledger0); | |||
| assertNotNull(ledger1); | |||
| assertNotNull(ledger2); | |||
| assertNotNull(ledger3); | |||
| IntegratedContext context = new IntegratedContext(); | |||
| Node node0 = new Node(0); | |||
| node0.setConsensusSettings(csProps); | |||
| node0.setLedgerManager(nodeCtx0.getLedgerManager()); | |||
| node0.setStorageDB(nodeCtx0.getStorageDB()); | |||
| node0.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(0).getPubKey(), privkey0)); | |||
| node0.setBindingConfig(bindingConfig0); | |||
| context.addNode(node0); | |||
| Node node1 = new Node(1); | |||
| node1.setConsensusSettings(csProps); | |||
| node1.setLedgerManager(nodeCtx1.getLedgerManager()); | |||
| node1.setStorageDB(nodeCtx1.getStorageDB()); | |||
| node1.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(1).getPubKey(), privkey1)); | |||
| node1.setBindingConfig(bindingConfig1); | |||
| context.addNode(node1); | |||
| Node node2 = new Node(2); | |||
| node2.setConsensusSettings(csProps); | |||
| node2.setLedgerManager(nodeCtx2.getLedgerManager()); | |||
| node2.setStorageDB(nodeCtx2.getStorageDB()); | |||
| node2.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(2).getPubKey(), privkey2)); | |||
| node2.setBindingConfig(bindingConfig2); | |||
| context.addNode(node2); | |||
| Node node3 = new Node(3); | |||
| node3.setConsensusSettings(csProps); | |||
| node3.setLedgerManager(nodeCtx3.getLedgerManager()); | |||
| node3.setStorageDB(nodeCtx3.getStorageDB()); | |||
| node3.setPartiKeyPair(new AsymmetricKeypair(initSetting.getConsensusParticipant(3).getPubKey(), privkey3)); | |||
| node3.setBindingConfig(bindingConfig3); | |||
| context.addNode(node3); | |||
| nodeCtx0.closeServer(); | |||
| nodeCtx1.closeServer(); | |||
| nodeCtx2.closeServer(); | |||
| nodeCtx3.closeServer(); | |||
| return context; | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_integration() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_integration.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,17 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import com.jd.blockchain.contract.Contract; | |||
| import com.jd.blockchain.contract.ContractEvent; | |||
| @Contract | |||
| public interface ReadContract { | |||
| @ContractEvent(name = "read-key") | |||
| String read(String address, String key); | |||
| @ContractEvent(name = "version-key") | |||
| Long readVersion(String address, String key); | |||
| int test(); | |||
| } | |||
| @@ -1,54 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr; | |||
| import com.jd.blockchain.contract.Contract; | |||
| import com.jd.blockchain.contract.ContractEvent; | |||
| import com.jd.blockchain.contract.ContractEventContext; | |||
| import com.jd.blockchain.contract.EventProcessingAware; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.ledger.TypedKVEntry; | |||
| @Contract | |||
| public class ReadContractImpl implements EventProcessingAware, ReadContract { | |||
| private ContractEventContext eventContext; | |||
| private HashDigest ledgerHash; | |||
| @Override | |||
| public void beforeEvent(ContractEventContext eventContext) { | |||
| this.eventContext = eventContext; | |||
| this.ledgerHash = eventContext.getCurrentLedgerHash(); | |||
| } | |||
| @Override | |||
| public void postEvent(ContractEventContext eventContext, Exception error) { | |||
| } | |||
| @Override | |||
| @ContractEvent(name = "read-key") | |||
| public String read(String address, String key) { | |||
| TypedKVEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); | |||
| if (kvDataEntries != null && kvDataEntries.length == 1) { | |||
| return kvDataEntries[0].getValue().toString(); | |||
| } | |||
| return null; | |||
| } | |||
| @Override | |||
| @ContractEvent(name = "version-key") | |||
| public Long readVersion(String address, String key) { | |||
| TypedKVEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); | |||
| if (kvDataEntries != null && kvDataEntries.length == 1) { | |||
| return kvDataEntries[0].getVersion(); | |||
| } | |||
| return -1L; | |||
| } | |||
| @Override | |||
| public int test() { | |||
| return 0; | |||
| } | |||
| } | |||
| @@ -1,225 +0,0 @@ | |||
| /** | |||
| * Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
| * FileName: BftsmartConfig | |||
| * Author: shaozhuguang | |||
| * Department: 区块链研发部 | |||
| * Date: 2019/1/10 下午3:43 | |||
| * Description: | |||
| */ | |||
| package test.com.jd.blockchain.intgr.batch.bftsmart; | |||
| import com.jd.blockchain.utils.codec.Base58Utils; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.security.ShaUtils; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.Properties; | |||
| /** | |||
| * | |||
| * @author shaozhuguang | |||
| * @create 2019/1/10 | |||
| * @since 1.0.0 | |||
| */ | |||
| public class BftsmartConfig { | |||
| public static final String BFTSMART_DIR = "bftsmart" + File.separator; | |||
| public static final String[] PUB_KEY = new String[64]; | |||
| public static final String[] PRIV_KEY = new String[64]; | |||
| public static final String PWD = Base58Utils.encode(ShaUtils.hash_256("abc".getBytes()));; | |||
| public static final int startBftsmartPort = 26000; | |||
| public static final int startInitPort = 15000; | |||
| static { | |||
| load(); | |||
| } | |||
| @Test | |||
| public void test4ConfigLoad() { | |||
| bftsmartConfigInit(4); | |||
| bftsmartLedgerInit(4); | |||
| } | |||
| @Test | |||
| public void test8ConfigLoad() { | |||
| bftsmartConfigInit(8); | |||
| bftsmartLedgerInit(8); | |||
| } | |||
| @Test | |||
| public void test16ConfigLoad() { | |||
| bftsmartConfigInit(16); | |||
| bftsmartLedgerInit(16); | |||
| } | |||
| @Test | |||
| public void test32ConfigLoad() { | |||
| bftsmartConfigInit(32); | |||
| bftsmartLedgerInit(32); | |||
| } | |||
| @Test | |||
| public void test64ConfigLoad() { | |||
| bftsmartConfigInit(64); | |||
| bftsmartLedgerInit(64); | |||
| } | |||
| public void bftsmartLedgerInit(int size) { | |||
| String file = BFTSMART_DIR + "ledger_init_bftsmart-" + size + ".init"; | |||
| ClassPathResource res = new ClassPathResource(file); | |||
| try { | |||
| File resFile = res.getFile(); | |||
| List<String> fileContent = org.apache.commons.io.FileUtils.readLines(resFile); | |||
| // 处理新内容 | |||
| List<String> newFileContent = handleInitContent(fileContent, size); | |||
| org.apache.commons.io.FileUtils.writeLines(resFile, newFileContent); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| private List<String> handleInitContent(List<String> fileContent, int size) { | |||
| List<String> newFileContent = new ArrayList<>(); | |||
| for (String srcLine : fileContent) { | |||
| String dstLine = srcLine; | |||
| if (srcLine.startsWith("cons_parti.count")) { | |||
| dstLine = "cons_parti.count=" + size; | |||
| } else if (srcLine.startsWith("###############cons_parti_configs###############")) { | |||
| List<String> parts = initParts(size); | |||
| newFileContent.addAll(parts); | |||
| dstLine = null; | |||
| } | |||
| if (dstLine != null) { | |||
| newFileContent.add(dstLine); | |||
| } | |||
| } | |||
| return newFileContent; | |||
| } | |||
| private List<String> initParts(int size) { | |||
| List<String> parts = new ArrayList<>(); | |||
| for (int i = 0; i < size; i++) { | |||
| parts.add(""); | |||
| parts.add("#第" + i + "个参与方的名称"); | |||
| parts.add("cons_parti." + i + ".name=xx-" + i + ".com"); | |||
| parts.add("#第" + i + "个参与方的公钥文件路径"); | |||
| parts.add("cons_parti." + i + ".pubkey-path="); | |||
| parts.add("#第" + i + "个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数"); | |||
| parts.add("cons_parti." + i + ".pubkey=" + PUB_KEY[i]); | |||
| parts.add("#第" + i + "个参与方的账本初始服务的主机"); | |||
| parts.add("cons_parti." + i + ".initializer.host=127.0.0.1"); | |||
| parts.add("#第" + i + "个参与方的账本初始服务的端口"); | |||
| int portVal = startInitPort + i * 15; | |||
| parts.add("cons_parti." + i + ".initializer.port=" + portVal); | |||
| parts.add("#第" + i + "个参与方的账本初始服务是否开启安全连接"); | |||
| parts.add("cons_parti." + i + ".initializer.secure=false"); | |||
| parts.add(""); | |||
| } | |||
| return parts; | |||
| } | |||
| public void bftsmartConfigInit(int size) { | |||
| String file = BFTSMART_DIR + "bftsmart-" + size + ".config"; | |||
| ClassPathResource res = new ClassPathResource(file); | |||
| try { | |||
| File resFile = res.getFile(); | |||
| List<String> fileContent = org.apache.commons.io.FileUtils.readLines(resFile); | |||
| // 处理新内容 | |||
| List<String> newFileContent = handleContent(fileContent, size); | |||
| org.apache.commons.io.FileUtils.writeLines(resFile, newFileContent); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| public List<String> handleContent(List<String> fileContent, int size) { | |||
| List<String> newFileContent = new ArrayList<>(); | |||
| for (String srcLine : fileContent) { | |||
| String dstLine = srcLine; | |||
| if (srcLine.startsWith("system.initial.view")) { | |||
| dstLine = "system.initial.view = " + initViews(size); | |||
| } else if (srcLine.startsWith("system.servers.num")) { | |||
| dstLine = "system.servers.num = " + size; | |||
| } else if (srcLine.startsWith("system.servers.f")) { | |||
| dstLine = "system.servers.f = " + initFsize(size); | |||
| } else if (srcLine.startsWith("###############system.server###############")) { | |||
| List<String> servers = initServers(size); | |||
| newFileContent.addAll(servers); | |||
| dstLine = null; | |||
| } | |||
| if (dstLine != null) { | |||
| newFileContent.add(dstLine); | |||
| } | |||
| } | |||
| return newFileContent; | |||
| } | |||
| private List<String> initServers(int size) { | |||
| List<String> servers = new ArrayList<>(); | |||
| for (int i = 0; i < size; i++) { | |||
| String pubKey = "system.server." + i + ".pubkey=" + PUB_KEY[i]; | |||
| String host = "system.server." + i + ".network.host=127.0.0.1"; | |||
| int portVal = startBftsmartPort + i * 10; | |||
| String port = "system.server." + i + ".network.port=" + portVal; | |||
| String secure = "system.server." + i+ ".network.secure=false"; | |||
| servers.add("############################################"); | |||
| servers.add("###### #Consensus Participant" + i + " ######"); | |||
| servers.add("############################################"); | |||
| servers.add(""); | |||
| servers.add(pubKey); | |||
| servers.add(host); | |||
| servers.add(port); | |||
| servers.add(secure); | |||
| servers.add(""); | |||
| } | |||
| return servers; | |||
| } | |||
| private int initFsize(int size) { | |||
| return (size - 1) / 3; | |||
| } | |||
| private String initViews(int size) { | |||
| StringBuilder stringBuilder = new StringBuilder(); | |||
| for (int i = 0; i < size; i++) { | |||
| if (stringBuilder.length() > 0) { | |||
| stringBuilder.append(","); | |||
| } | |||
| stringBuilder.append(i); | |||
| } | |||
| return stringBuilder.toString(); | |||
| } | |||
| public static void load() { | |||
| ClassPathResource res = new ClassPathResource(BFTSMART_DIR + "bftsmart-users.conf"); | |||
| try(InputStream in = res.getInputStream()){ | |||
| loadUsers(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static void loadUsers(InputStream in) { | |||
| Properties props = FileUtils.readProperties(in, "UTF-8"); | |||
| for (int i = 0; i < PUB_KEY.length; i++) { | |||
| String currUserPubKey = "user[" + i + "]pubKeyBase58"; | |||
| String currUserPrivKey = "user[" + i + "]privKeyBase58"; | |||
| PUB_KEY[i] = props.getProperty(currUserPubKey).trim(); | |||
| PRIV_KEY[i] = props.getProperty(currUserPrivKey).trim(); | |||
| System.out.printf("user[%s] pubKey=%s \r\n", i, PUB_KEY[i]); | |||
| System.out.printf("user[%s] privKey=%s \r\n", i, PRIV_KEY[i]); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,393 +0,0 @@ | |||
| /** | |||
| * Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
| * FileName: BftsmartLedgerInit | |||
| * Author: shaozhuguang | |||
| * Department: 区块链研发部 | |||
| * Date: 2019/1/10 下午5:03 | |||
| * Description: | |||
| */ | |||
| package test.com.jd.blockchain.intgr.batch.bftsmart; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.gateway.GatewayConfigProperties; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.peer.PeerServerBooter; | |||
| import com.jd.blockchain.sdk.BlockchainService; | |||
| import com.jd.blockchain.sdk.client.GatewayServiceFactory; | |||
| import com.jd.blockchain.storage.service.DbConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitCommand; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import org.junit.Before; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import test.com.jd.blockchain.intgr.GatewayTestRunner; | |||
| import test.com.jd.blockchain.intgr.IntegrationBase; | |||
| import test.com.jd.blockchain.intgr.LedgerInitConsensusConfig; | |||
| import test.com.jd.blockchain.intgr.PeerTestRunner; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeTest; | |||
| import java.io.File; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import java.util.concurrent.ExecutorService; | |||
| import java.util.concurrent.Executors; | |||
| import java.util.concurrent.atomic.AtomicLong; | |||
| import static test.com.jd.blockchain.intgr.IntegrationBase.buildLedgers; | |||
| import static test.com.jd.blockchain.intgr.IntegrationBase.validKeyPair; | |||
| import static test.com.jd.blockchain.intgr.IntegrationBase.validKvWrite; | |||
| /** | |||
| * | |||
| * @author shaozhuguang | |||
| * @create 2019/1/10 | |||
| * @since 1.0.0 | |||
| */ | |||
| public class BftsmartLedgerInit { | |||
| // private final ExecutorService ledgerInitPools = Executors.newFixedThreadPool(64); | |||
| private final ExecutorService nodeStartPools = Executors.newCachedThreadPool(); | |||
| private final ExecutorService txSendPools = Executors.newFixedThreadPool(20); | |||
| private static String localPath = FileUtils.getCurrentDir() + File.separator + "bftsmart-rocks.db"; | |||
| private BftsmartConfig bftsmartConfig = new BftsmartConfig(); | |||
| private static final int peerStartPort = 20000; | |||
| private static final int registerUserSize = 500; | |||
| private static final int kvStorageSize = 1000; | |||
| private static final boolean isBrowser = true; | |||
| @Before | |||
| public void before() { | |||
| File localDir = new File(localPath); | |||
| if (!localDir.exists()) { | |||
| localDir.mkdir(); | |||
| } | |||
| } | |||
| @Test | |||
| public void localConf4NodesLoad() { | |||
| bftsmartConfig.test4ConfigLoad(); | |||
| localConfLoad(4); | |||
| ledgerInitNodes(4); | |||
| } | |||
| @Test | |||
| public void start4Nodes() { | |||
| localConf4NodesLoad(); | |||
| PeerTestRunner[] peerNodes = startNodes(4); | |||
| // 检查账本一致性 | |||
| LedgerQuery[] ledgers = checkNodes(peerNodes); | |||
| txRequestTest(peerNodes, ledgers); | |||
| } | |||
| @Test | |||
| public void localConf8NodesLoad() { | |||
| bftsmartConfig.test8ConfigLoad(); | |||
| localConfLoad(8); | |||
| ledgerInitNodes(8); | |||
| } | |||
| @Test | |||
| public void start8Nodes() { | |||
| localConf8NodesLoad(); | |||
| PeerTestRunner[] peerNodes = startNodes(8); | |||
| // 检查账本一致性 | |||
| LedgerQuery[] ledgers = checkNodes(peerNodes); | |||
| txRequestTest(peerNodes, ledgers); | |||
| } | |||
| @Test | |||
| public void localConf16NodesLoad() { | |||
| bftsmartConfig.test16ConfigLoad(); | |||
| localConfLoad(16); | |||
| ledgerInitNodes(16); | |||
| } | |||
| @Test | |||
| public void start16Nodes() { | |||
| localConf16NodesLoad(); | |||
| PeerTestRunner[] peerNodes = startNodes(16); | |||
| // 检查账本一致性 | |||
| LedgerQuery[] ledgers = checkNodes(peerNodes); | |||
| txRequestTest(peerNodes, ledgers); | |||
| } | |||
| @Test | |||
| public void localConf32NodesLoad() { | |||
| bftsmartConfig.test32ConfigLoad(); | |||
| localConfLoad(32); | |||
| ledgerInitNodes(32); | |||
| } | |||
| @Test | |||
| public void start32Nodes() { | |||
| localConf32NodesLoad(); | |||
| // ledgerInitPools.shutdown(); | |||
| PeerTestRunner[] peerNodes = startNodes(32); | |||
| // 检查账本一致性 | |||
| LedgerQuery[] ledgers = checkNodes(peerNodes); | |||
| txRequestTest(peerNodes, ledgers); | |||
| } | |||
| @Test | |||
| public void localConf64NodesLoad() { | |||
| bftsmartConfig.test64ConfigLoad(); | |||
| localConfLoad(64); | |||
| ledgerInitNodes(64); | |||
| } | |||
| @Test | |||
| public void start64Nodes() { | |||
| localConf64NodesLoad(); | |||
| PeerTestRunner[] peerNodes = startNodes(64); | |||
| // 检查账本一致性 | |||
| LedgerQuery[] ledgers = checkNodes(peerNodes); | |||
| txRequestTest(peerNodes, ledgers); | |||
| } | |||
| public void txRequestTest(PeerTestRunner[] peerNodes, LedgerQuery[] ledgers) { | |||
| // 测试K-V | |||
| GatewayTestRunner gateway = initGateWay(peerNodes[0]); | |||
| LedgerQuery ledgerRepository = ledgers[0]; | |||
| HashDigest ledgerHash = ledgerRepository.getHash(); | |||
| GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(BftsmartConfig.PRIV_KEY[0], IntegrationBase.PASSWORD); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(BftsmartConfig.PUB_KEY[0]); | |||
| AsymmetricKeypair adminKey = new AsymmetricKeypair(pubKey0, privkey0); | |||
| BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
| CountDownLatch cdlUser = new CountDownLatch(registerUserSize); | |||
| System.out.println("--------- Register Users Start ---------"); | |||
| for (int i = 0; i < registerUserSize; i++) { | |||
| txSendPools.execute(() -> { | |||
| IntegrationBase.KeyPairResponse userResponse = IntegrationBase.testSDK_RegisterUser(adminKey, ledgerHash, blockchainService); | |||
| // validKeyPair(userResponse, ledgerRepository, IntegrationBase.KeyPairType.USER); | |||
| cdlUser.countDown(); | |||
| }); | |||
| } | |||
| IntegrationBase.KeyPairResponse dataAccountResponse = null; | |||
| try { | |||
| System.out.println("--------- Register Users Waiting ---------"); | |||
| cdlUser.await(); | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| System.out.println("--------- Register Users Success ---------"); | |||
| System.out.println("--------- Register DataAccount Start ---------"); | |||
| dataAccountResponse = IntegrationBase.testSDK_RegisterDataAccount(adminKey, ledgerHash, blockchainService); | |||
| validKeyPair(dataAccountResponse, ledgerRepository, IntegrationBase.KeyPairType.DATAACCOUNT); | |||
| System.out.println("--------- Register DataAccount Success ---------"); | |||
| Thread.sleep(5000); | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| // CountDownLatch cdlKv = new CountDownLatch(kvStorageSize); | |||
| // BlockchainKeyPair da = dataAccountResponse.getKeyPair(); | |||
| // for (int i = 0; i < kvStorageSize; i++) { | |||
| // txSendPools.execute(() -> { | |||
| // IntegrationBase.testSDK_InsertData(adminKey, ledgerHash, blockchainService, da.getAddress()); | |||
| // cdlKv.countDown(); | |||
| // }); | |||
| // } | |||
| try { | |||
| // cdlKv.await(); | |||
| Thread.sleep(2000); | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| System.out.println("--------- TestConsistencyAmongNodes Success ---------"); | |||
| if (isBrowser) { | |||
| Thread.sleep(Integer.MAX_VALUE); | |||
| } | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| public GatewayTestRunner initGateWay(PeerTestRunner peerNode) { | |||
| String encodedBase58Pwd = KeyGenUtils.encodePasswordAsBase58(LedgerInitializeTest.PASSWORD); | |||
| GatewayConfigProperties.KeyPairConfig gwkey0 = new GatewayConfigProperties.KeyPairConfig(); | |||
| gwkey0.setPubKeyValue(BftsmartConfig.PUB_KEY[0]); | |||
| gwkey0.setPrivKeyValue(BftsmartConfig.PRIV_KEY[0]); | |||
| gwkey0.setPrivKeyPassword(encodedBase58Pwd); | |||
| GatewayTestRunner gateway = new GatewayTestRunner("127.0.0.1", 11000, gwkey0, | |||
| peerNode.getServiceAddress(), LedgerInitConsensusConfig.bftsmartProvider,null); | |||
| ThreadInvoker.AsyncCallback<Object> gwStarting = gateway.start(); | |||
| gwStarting.waitReturn(); | |||
| return gateway; | |||
| } | |||
| public LedgerQuery[] checkNodes(PeerTestRunner[] peerNodes) { | |||
| int size = peerNodes.length; | |||
| LedgerBindingConfig[] ledgerBindingConfigs = new LedgerBindingConfig[size]; | |||
| DbConnectionFactory[] connectionFactories = new DbConnectionFactory[size]; | |||
| for (int i = 0; i < size; i++) { | |||
| ledgerBindingConfigs[i] = peerNodes[i].getLedgerBindingConfig(); | |||
| connectionFactories[i] = peerNodes[i].getDBConnectionFactory(); | |||
| } | |||
| // 执行测试用例之前,校验每个节点的一致性; | |||
| LedgerQuery[] ledgers = buildLedgers(ledgerBindingConfigs, connectionFactories); | |||
| IntegrationBase.testConsistencyAmongNodes(ledgers); | |||
| return ledgers; | |||
| } | |||
| public PeerTestRunner[] startNodes(int size) { | |||
| PeerTestRunner[] peerNodes = new PeerTestRunner[size]; | |||
| CountDownLatch countDownLatch = new CountDownLatch(size); | |||
| try { | |||
| for (int i = 0; i < size; i++) { | |||
| final int index = i; | |||
| nodeStartPools.execute(() -> { | |||
| try { | |||
| NetworkAddress peerSrvAddr = new NetworkAddress("127.0.0.1", peerStartPort + index * 10); | |||
| String ledgerBindingConf = BftsmartConfig.BFTSMART_DIR + "conf" + File.separator + index + File.separator + "ledger-binding.conf"; | |||
| ClassPathResource ledgerBindingConfRes = new ClassPathResource(ledgerBindingConf); | |||
| LedgerBindingConfig bindingConfig = LedgerBindingConfig.resolve(ledgerBindingConfRes.getInputStream()); | |||
| PeerTestRunner peer = new PeerTestRunner(peerSrvAddr, bindingConfig); | |||
| ThreadInvoker.AsyncCallback<Object> peerStarting = peer.start(); | |||
| peerStarting.waitReturn(); | |||
| peerNodes[index] = peer; | |||
| countDownLatch.countDown(); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| }); | |||
| } | |||
| countDownLatch.await(); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return peerNodes; | |||
| } | |||
| public void ledgerInitNodes(int size) { | |||
| try { | |||
| CountDownLatch countDownLatch = new CountDownLatch(size); | |||
| for (int i = 0; i < size; i++) { | |||
| final int index = i; | |||
| nodeStartPools.execute((() -> { | |||
| try { | |||
| // 启动tool-booter | |||
| String[] args = new String[4]; | |||
| args[0] = "-l"; | |||
| String localConf = BftsmartConfig.BFTSMART_DIR + "conf" + File.separator + index + File.separator + "local-bftsmart-" + index + ".conf"; | |||
| ClassPathResource localConfRes = new ClassPathResource(localConf); | |||
| args[1] = localConfRes.getFile().getAbsolutePath(); | |||
| args[2] = "-i"; | |||
| String ledgerInit = BftsmartConfig.BFTSMART_DIR + "ledger_init_bftsmart-" + size + ".init"; | |||
| ClassPathResource ledgerInitRes = new ClassPathResource(ledgerInit); | |||
| args[3] = ledgerInitRes.getFile().getAbsolutePath(); | |||
| LedgerInitCommand.main(args); | |||
| countDownLatch.countDown(); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| })); | |||
| } | |||
| countDownLatch.await(); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| public void localConfLoad(int size) { | |||
| for (int i = 0; i < size; i++) { | |||
| localConfAllLoad(i, size); | |||
| } | |||
| } | |||
| public void localConfAllLoad(int index, int size) { | |||
| String file = BftsmartConfig.BFTSMART_DIR + "conf" + File.separator + index + File.separator + "local-bftsmart-" + index + ".conf"; | |||
| ClassPathResource res = new ClassPathResource(file); | |||
| try { | |||
| File resFile = res.getFile(); | |||
| // 处理新内容 | |||
| List<String> newFileContent = handleLocalConfContent(index, size); | |||
| org.apache.commons.io.FileUtils.writeLines(resFile, newFileContent); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| public List<String> handleLocalConfContent(int index, int size) throws Exception { | |||
| List<String> newFileContent = new ArrayList<>(); | |||
| newFileContent.add("#当前参与方的 id"); | |||
| newFileContent.add("local.parti.id=" + index); | |||
| newFileContent.add(""); | |||
| newFileContent.add("#当前参与方的公钥"); | |||
| newFileContent.add("local.parti.pubkey=" + BftsmartConfig.PUB_KEY[index]); | |||
| newFileContent.add(""); | |||
| newFileContent.add("#当前参与方的私钥(密文编码)"); | |||
| newFileContent.add("local.parti.privkey=" + BftsmartConfig.PRIV_KEY[index]); | |||
| newFileContent.add(""); | |||
| newFileContent.add("#当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入"); | |||
| newFileContent.add("local.parti.pwd=" + BftsmartConfig.PWD); | |||
| newFileContent.add(""); | |||
| String outDir = BftsmartConfig.BFTSMART_DIR + "conf" + File.separator + index + File.separator; | |||
| ClassPathResource outDirRes = new ClassPathResource(outDir); | |||
| newFileContent.add("#账本初始化完成后生成的\"账本绑定配置文件\"的输出目录"); | |||
| newFileContent.add("ledger.binding.out=" + outDirRes.getFile().getAbsolutePath()); | |||
| newFileContent.add(""); | |||
| String dbDir = new File(localPath, "rocksdb" + index + ".db").getAbsolutePath(); | |||
| FileUtils.deleteFile(dbDir); | |||
| newFileContent.add("#账本数据库的连接字符"); | |||
| newFileContent.add("ledger.db.uri=rocksdb://" + dbDir); | |||
| newFileContent.add(""); | |||
| newFileContent.add("#账本数据库的连接口令"); | |||
| newFileContent.add("ledger.db.pwd="); | |||
| newFileContent.add(""); | |||
| String consensusDir = BftsmartConfig.BFTSMART_DIR + "bftsmart-" + size + ".config"; | |||
| ClassPathResource consensusDirRes = new ClassPathResource(consensusDir); | |||
| newFileContent.add("#共识配置文件路径"); | |||
| newFileContent.add("consensus.conf=" + consensusDirRes.getFile().getAbsolutePath()); | |||
| newFileContent.add(""); | |||
| newFileContent.add("#共识Providers配置"); | |||
| newFileContent.add("consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"); | |||
| return newFileContent; | |||
| } | |||
| } | |||
| @@ -1,53 +0,0 @@ | |||
| /** | |||
| * Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
| * FileName: BftsmartTestBase | |||
| * Author: shaozhuguang | |||
| * Department: 区块链研发部 | |||
| * Date: 2019/1/10 下午3:32 | |||
| * Description: | |||
| */ | |||
| package test.com.jd.blockchain.intgr.batch.bftsmart; | |||
| import static com.jd.blockchain.crypto.KeyGenUtils.encodePrivKey; | |||
| import static com.jd.blockchain.crypto.KeyGenUtils.encodePubKey; | |||
| import org.junit.Test; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| import com.jd.blockchain.crypto.SignatureFunction; | |||
| import com.jd.blockchain.utils.codec.Base58Utils; | |||
| import com.jd.blockchain.utils.security.ShaUtils; | |||
| /** | |||
| * | |||
| * @author shaozhuguang | |||
| * @create 2019/1/10 | |||
| * @since 1.0.0 | |||
| */ | |||
| public class BftsmartTestBase { | |||
| private final int userSize = 64; | |||
| private final byte[] pwdBytes= ShaUtils.hash_256("abc".getBytes()); | |||
| private final String base58Pwd = Base58Utils.encode(pwdBytes); | |||
| @Test | |||
| public void newUsers() { | |||
| SignatureFunction signFunc = Crypto.getSignatureFunction("ED25519"); | |||
| for (int i = 0; i < userSize; i++) { | |||
| AsymmetricKeypair kp = signFunc.generateKeypair(); | |||
| String base58PubKey = encodePubKey(kp.getPubKey()); | |||
| String base58PrivKey = encodePrivKey(kp.getPrivKey(), pwdBytes); | |||
| System.out.printf("user[%s] privKeyBase58 = %s \r\n", i, base58PrivKey); | |||
| System.out.printf("user[%s] pubKeyBase58 = %s \r\n", i, base58PubKey); | |||
| System.out.println("------------------------------------------------------"); | |||
| } | |||
| System.out.printf("pwdBase58 = %s \r\n", base58Pwd); | |||
| } | |||
| } | |||
| @@ -1,65 +0,0 @@ | |||
| /** | |||
| * Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
| * FileName: test.com.jd.blockchain.intgr.perf.LedgerPerfCapabilityTest | |||
| * Author: shaozhuguang | |||
| * Department: 区块链研发部 | |||
| * Date: 2018/12/6 上午11:15 | |||
| * Description: | |||
| */ | |||
| package test.com.jd.blockchain.intgr.capability; | |||
| import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import org.junit.Test; | |||
| import test.com.jd.blockchain.intgr.perf.LedgerPerformanceTest; | |||
| /** | |||
| * | |||
| * @author shaozhuguang | |||
| * @create 2018/12/6 | |||
| * @since 1.0.0 | |||
| */ | |||
| public class LedgerPerfCapabilityTest { | |||
| private final String CONSENSUS = "-mq"; | |||
| private final String SILENT = "-silent"; | |||
| private final String ROCKSDB = "-rocksdb"; | |||
| private final String USERTEST = "-usertest"; | |||
| static { | |||
| DataContractRegistry.register(LedgerInitOperation.class); | |||
| DataContractRegistry.register(UserRegisterOperation.class); | |||
| } | |||
| @Test | |||
| public void testKvStorage4Memory() { | |||
| LedgerPerformanceTest.test(new String[]{SILENT}); | |||
| } | |||
| @Test | |||
| public void testUserRegister4Memory() { | |||
| LedgerPerformanceTest.test(new String[]{USERTEST, SILENT}); | |||
| } | |||
| @Test | |||
| public void testKvStorage4Rocksdb() { | |||
| LedgerPerformanceTest.test(new String[]{ROCKSDB, SILENT}); | |||
| } | |||
| @Test | |||
| public void testUserRegister4Rocksdb() { | |||
| LedgerPerformanceTest.test(new String[]{USERTEST, ROCKSDB, SILENT}); | |||
| } | |||
| public void testUserRegister4Redis() { | |||
| //test example not verify redis | |||
| LedgerPerformanceTest.test(new String[]{"-redis", "-usertest"}); | |||
| } | |||
| public void testContract(){LedgerPerformanceTest.test(new String[]{"-contract", "-silent"});} | |||
| } | |||
| @@ -1,39 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.contract; | |||
| import com.jd.blockchain.contract.Contract; | |||
| import com.jd.blockchain.contract.ContractEvent; | |||
| /** | |||
| * 示例:一个“资产管理”智能合约; | |||
| * | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| @Contract | |||
| public interface AssetContract { | |||
| /** | |||
| * 发行资产; | |||
| * | |||
| * @param amount | |||
| * 新发行的资产数量; | |||
| * @param assetHolderAddress | |||
| * 新发行的资产的持有账户; | |||
| */ | |||
| @ContractEvent(name = "issue-asset") | |||
| void issue(long amount, String assetHolderAddress); | |||
| /** | |||
| * 转移资产 | |||
| * | |||
| * @param fromAddress | |||
| * 转出账户; | |||
| * @param toAddress | |||
| * 转入账户; | |||
| * @param amount | |||
| * 转移的资产数额; | |||
| */ | |||
| @ContractEvent(name = "transfer-asset") | |||
| void transfer(String fromAddress, String toAddress, long amount); | |||
| } | |||
| @@ -1,5 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.contract; | |||
| public class AssetContractImpl { | |||
| } | |||
| @@ -1,14 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.contract; | |||
| import static org.junit.Assert.*; | |||
| import org.junit.Test; | |||
| public class ContractInvocationTest { | |||
| @Test | |||
| public void test() { | |||
| } | |||
| } | |||
| @@ -1,30 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.initializer; | |||
| import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory; | |||
| import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import org.springframework.context.annotation.Import; | |||
| import com.jd.blockchain.tools.initializer.web.InitWebSecurityConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.InitWebServerConfiguration; | |||
| @SpringBootApplication | |||
| @Configuration | |||
| @EnableConfigurationProperties | |||
| @Import(value = { InitWebServerConfiguration.class, InitWebSecurityConfiguration.class }) | |||
| public class LedgerInitWebTestConfiguration { | |||
| @Bean | |||
| public CompositeConnectionFactory getCompositeConnectionFactory() { | |||
| return new CompositeConnectionFactory(); | |||
| } | |||
| // @Bean | |||
| // public LedgerManager getLedgerManager() { | |||
| // return new LedgerManager(); | |||
| // } | |||
| } | |||
| @@ -1,332 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.initializer; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNotNull; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Map; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.Crypto; | |||
| import com.jd.blockchain.crypto.CryptoProvider; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.crypto.SignatureDigest; | |||
| import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
| import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.RolesConfigureOperation; | |||
| import com.jd.blockchain.ledger.UserAuthorizeOperation; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.ledger.core.UserAccount; | |||
| import com.jd.blockchain.ledger.core.UserAccountQuery; | |||
| import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.InitConsensusServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.IntegrationBase; | |||
| import test.com.jd.blockchain.intgr.LedgerInitConsensusConfig; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| public class LedgerInitializeTest { | |||
| static { | |||
| DataContractRegistry.register(LedgerInitOperation.class); | |||
| DataContractRegistry.register(UserRegisterOperation.class); | |||
| DataContractRegistry.register(RolesConfigureOperation.class); | |||
| DataContractRegistry.register(UserAuthorizeOperation.class); | |||
| } | |||
| private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
| SMCryptoService.class.getName() }; | |||
| public static final String PASSWORD = IntegrationBase.PASSWORD; | |||
| public static final String[] PUB_KEYS = IntegrationBase.PUB_KEYS; | |||
| public static final String[] PRIV_KEYS = IntegrationBase.PRIV_KEYS; | |||
| private Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap = new ConcurrentHashMap<>(); | |||
| public void testMQInitByMemWith4Nodes() { | |||
| testInitWith4Nodes(LedgerInitConsensusConfig.mqConfig, LedgerInitConsensusConfig.memConnectionStrings); | |||
| } | |||
| public void testMQInitByRedisWith4Nodes() { | |||
| testInitWith4Nodes(LedgerInitConsensusConfig.mqConfig, LedgerInitConsensusConfig.redisConnectionStrings); | |||
| } | |||
| @Test | |||
| public void testBftsmartInitWith4Nodes() { | |||
| testInitWith4Nodes(LedgerInitConsensusConfig.bftsmartConfig, LedgerInitConsensusConfig.memConnectionStrings); | |||
| } | |||
| public void testInitWith4Nodes(LedgerInitConsensusConfig.ConsensusConfig config, String[] dbConnections) { | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting(); | |||
| Properties props = loadConsensusSetting(config.getConfigPath()); | |||
| // ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); | |||
| // ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
| NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node1 = new NodeContext(initSetting.getConsensusParticipant(1).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node2 = new NodeContext(initSetting.getConsensusParticipant(2).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node3 = new NodeContext(initSetting.getConsensusParticipant(3).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri(dbConnections[0]); | |||
| AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri(dbConnections[1]); | |||
| AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri(dbConnections[2]); | |||
| AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
| DBConnectionConfig testDb03 = new DBConnectionConfig(); | |||
| testDb03.setConnectionUri(dbConnections[3]); | |||
| AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| assertNotNull(ledgerHash0); | |||
| assertEquals(ledgerHash0, ledgerHash1); | |||
| assertEquals(ledgerHash0, ledgerHash2); | |||
| assertEquals(ledgerHash0, ledgerHash3); | |||
| LedgerQuery ledger0 = node0.registLedger(ledgerHash0, dbConnections[0]); | |||
| LedgerQuery ledger1 = node1.registLedger(ledgerHash1, dbConnections[1]); | |||
| LedgerQuery ledger2 = node2.registLedger(ledgerHash2, dbConnections[2]); | |||
| LedgerQuery ledger3 = node3.registLedger(ledgerHash3, dbConnections[3]); | |||
| assertNotNull(ledger0); | |||
| assertNotNull(ledger1); | |||
| assertNotNull(ledger2); | |||
| assertNotNull(ledger3); | |||
| LedgerBlock genesisBlock = ledger0.getLatestBlock(); | |||
| assertEquals(0, genesisBlock.getHeight()); | |||
| assertEquals(ledgerHash0, genesisBlock.getHash()); | |||
| UserAccountQuery userset0 = ledger0.getUserAccountSet(genesisBlock); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(PUB_KEYS[0]); | |||
| Bytes address0 = AddressEncoding.generateAddress(pubKey0); | |||
| UserAccount user0_0 = userset0.getAccount(address0); | |||
| assertNotNull(user0_0); | |||
| PubKey pubKey1 = KeyGenUtils.decodePubKey(PUB_KEYS[1]); | |||
| Bytes address1 = AddressEncoding.generateAddress(pubKey1); | |||
| UserAccount user1_0 = userset0.getAccount(address1); | |||
| assertNotNull(user1_0); | |||
| PubKey pubKey2 = KeyGenUtils.decodePubKey(PUB_KEYS[2]); | |||
| Bytes address2 = AddressEncoding.generateAddress(pubKey2); | |||
| UserAccount user2_0 = userset0.getAccount(address2); | |||
| assertNotNull(user2_0); | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| Bytes address3 = AddressEncoding.generateAddress(pubKey3); | |||
| UserAccount user3_0 = userset0.getAccount(address3); | |||
| assertNotNull(user3_0); | |||
| } | |||
| public static LedgerInitProperties loadInitSetting() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static Properties loadConsensusSetting(String configPath) { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource(configPath); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| return FileUtils.readProperties(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| private static class ConsensusConfig { | |||
| String provider; | |||
| String configPath; | |||
| public String getProvider() { | |||
| return provider; | |||
| } | |||
| public String getConfigPath() { | |||
| return configPath; | |||
| } | |||
| } | |||
| public static class NodeContext { | |||
| private LedgerManager ledgerManager = new LedgerManager(); | |||
| private MemoryDBConnFactory storageDb = new MemoryDBConnFactory(); | |||
| private InitConsensusServiceFactory initCsServiceFactory; | |||
| private LedgerInitProcess initProcess; | |||
| private AsymmetricKeypair partiKey; | |||
| public AsymmetricKeypair getPartiKey() { | |||
| return partiKey; | |||
| } | |||
| public LedgerManager getLedgerManager() { | |||
| return ledgerManager; | |||
| } | |||
| public MemoryDBConnFactory getStorageDb() { | |||
| return storageDb; | |||
| } | |||
| public NodeContext(NetworkAddress address, Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap) { | |||
| this.initCsServiceFactory = new MultiThreadInterInvokerFactory(serviceRegisterMap); | |||
| LedgerInitializeWebController initController = new LedgerInitializeWebController(storageDb, | |||
| initCsServiceFactory); | |||
| serviceRegisterMap.put(address, initController); | |||
| this.initProcess = initController; | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter) { | |||
| partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, boolean autoVerifyHash) { | |||
| CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
| for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
| supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
| } | |||
| CryptoConfig cryptoSetting = new CryptoConfig(); | |||
| cryptoSetting.setSupportedProviders(supportedProviders); | |||
| cryptoSetting.setAutoVerifyHash(autoVerifyHash); | |||
| cryptoSetting.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); | |||
| setting.getCryptoProperties().setHashAlgorithm("SHA256"); | |||
| setting.getCryptoProperties().setVerifyHash(autoVerifyHash); | |||
| partiKey = new AsymmetricKeypair(setting.getConsensusParticipant(0).getPubKey(), privKey); | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public LedgerQuery registLedger(HashDigest ledgerHash, String memConn) { | |||
| return ledgerManager.register(ledgerHash, storageDb.connect(memConn).getStorageService()); | |||
| } | |||
| } | |||
| private static class MultiThreadInterInvokerFactory implements InitConsensusServiceFactory { | |||
| private Map<NetworkAddress, LedgerInitConsensusService> nodeConsesusServices; | |||
| public MultiThreadInterInvokerFactory(Map<NetworkAddress, LedgerInitConsensusService> nodeConsesusServices) { | |||
| this.nodeConsesusServices = nodeConsesusServices; | |||
| } | |||
| @Override | |||
| public LedgerInitConsensusService connect(NetworkAddress endpointAddress) { | |||
| return new InitConsensusServiceProxy(nodeConsesusServices.get(endpointAddress)); | |||
| } | |||
| } | |||
| private static class InitConsensusServiceProxy implements LedgerInitConsensusService { | |||
| private LedgerInitConsensusService initCsService; | |||
| public InitConsensusServiceProxy(LedgerInitConsensusService initCsService) { | |||
| this.initCsService = initCsService; | |||
| } | |||
| @Override | |||
| public LedgerInitProposal requestPermission(int requesterId, SignatureDigest signature) { | |||
| ThreadInvoker<LedgerInitProposal> invoker = new ThreadInvoker<LedgerInitProposal>() { | |||
| @Override | |||
| protected LedgerInitProposal invoke() { | |||
| return initCsService.requestPermission(requesterId, signature); | |||
| } | |||
| }; | |||
| return invoker.startAndWait(); | |||
| } | |||
| @Override | |||
| public LedgerInitDecision synchronizeDecision(LedgerInitDecision initDecision) { | |||
| ThreadInvoker<LedgerInitDecision> invoker = new ThreadInvoker<LedgerInitDecision>() { | |||
| @Override | |||
| protected LedgerInitDecision invoke() { | |||
| return initCsService.synchronizeDecision(initDecision); | |||
| } | |||
| }; | |||
| return invoker.startAndWait(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,287 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.initializer; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.*; | |||
| import com.jd.blockchain.ledger.core.*; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.*; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import org.junit.Test; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.context.ConfigurableApplicationContext; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import test.com.jd.blockchain.intgr.IntegrationBase; | |||
| import test.com.jd.blockchain.intgr.LedgerInitConsensusConfig; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import static org.junit.Assert.*; | |||
| public class LedgerInitializeWeb4Nodes { | |||
| public static final String PASSWORD = IntegrationBase.PASSWORD; | |||
| public static final String[] PUB_KEYS = IntegrationBase.PUB_KEYS; | |||
| public static final String[] PRIV_KEYS = IntegrationBase.PRIV_KEYS; | |||
| static { | |||
| try { | |||
| // 首先获取当前Resource路径 | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource(""); | |||
| String path = ledgerInitSettingResource.getURL().getPath(); | |||
| System.out.println("-----" + path + "-----"); | |||
| // 将参数注册进去 | |||
| System.setProperty("peer.log", path); | |||
| System.setProperty("init.log", path); | |||
| System.setProperty("gateway.log", path); | |||
| System.setProperty("jdchain.log", path); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| @Test | |||
| public void testMQInitByMemWith4Nodes() { | |||
| testInitWith4Nodes(LedgerInitConsensusConfig.mqConfig, LedgerInitConsensusConfig.memConnectionStrings); | |||
| } | |||
| @Test | |||
| public void testMQInitByRedisWith4Nodes() { | |||
| testInitWith4Nodes(LedgerInitConsensusConfig.mqConfig, LedgerInitConsensusConfig.redisConnectionStrings); | |||
| } | |||
| @Test | |||
| public void testBftsmartLedgerInitByMemWith4Nodes() { | |||
| testInitWith4Nodes(LedgerInitConsensusConfig.bftsmartConfig, LedgerInitConsensusConfig.memConnectionStrings); | |||
| } | |||
| @Test | |||
| public void testBftsmartLedgerInitByRedisWith4Nodes() { | |||
| testInitWith4Nodes(LedgerInitConsensusConfig.bftsmartConfig, LedgerInitConsensusConfig.redisConnectionStrings); | |||
| } | |||
| public HashDigest testInitWith4Nodes(LedgerInitConsensusConfig.ConsensusConfig config, String[] dbConns) { | |||
| System.out.println("----------- is daemon=" + Thread.currentThread().isDaemon()); | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting_2(); | |||
| Properties props = loadConsensusSetting(config.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory() | |||
| .getConsensusSettingsBuilder() | |||
| .createSettings(props, Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeWebContext node0 = new NodeWebContext(0, initAddr0); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeWebContext node1 = new NodeWebContext(1, initAddr1); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeWebContext node2 = new NodeWebContext(2, initAddr2); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeWebContext node3 = new NodeWebContext(3, initAddr3); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
| CountDownLatch quitLatch = new CountDownLatch(4); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri(dbConns[0]); | |||
| AsyncCallback<HashDigest> callback0 = node0.startInit(privkey0, initSetting, testDb0, consolePrompter, | |||
| quitLatch); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri(dbConns[1]); | |||
| AsyncCallback<HashDigest> callback1 = node1.startInit(privkey1, initSetting, testDb1, consolePrompter, | |||
| quitLatch); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri(dbConns[2]); | |||
| AsyncCallback<HashDigest> callback2 = node2.startInit(privkey2, initSetting, testDb2, consolePrompter, | |||
| quitLatch); | |||
| DBConnectionConfig testDb03 = new DBConnectionConfig(); | |||
| testDb03.setConnectionUri(dbConns[3]); | |||
| AsyncCallback<HashDigest> callback3 = node3.startInit(privkey3, initSetting, testDb03, consolePrompter, | |||
| quitLatch); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| assertNotNull(ledgerHash0); | |||
| assertEquals(ledgerHash0, ledgerHash1); | |||
| assertEquals(ledgerHash0, ledgerHash2); | |||
| assertEquals(ledgerHash0, ledgerHash3); | |||
| LedgerQuery ledger0 = node0.registLedger(ledgerHash0); | |||
| LedgerQuery ledger1 = node1.registLedger(ledgerHash1); | |||
| LedgerQuery ledger2 = node2.registLedger(ledgerHash2); | |||
| LedgerQuery ledger3 = node3.registLedger(ledgerHash3); | |||
| assertNotNull(ledger0); | |||
| assertNotNull(ledger1); | |||
| assertNotNull(ledger2); | |||
| assertNotNull(ledger3); | |||
| LedgerBlock genesisBlock = ledger0.getLatestBlock(); | |||
| assertEquals(0, genesisBlock.getHeight()); | |||
| assertEquals(ledgerHash0, genesisBlock.getHash()); | |||
| UserAccountQuery userset0 = ledger0.getUserAccountSet(genesisBlock); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(PUB_KEYS[0]); | |||
| Bytes address0 = AddressEncoding.generateAddress(pubKey0); | |||
| System.out.printf("localNodeAddress0 = %s \r\n", address0.toBase58()); | |||
| UserAccount user0_0 = userset0.getAccount(address0); | |||
| assertNotNull(user0_0); | |||
| PubKey pubKey1 = KeyGenUtils.decodePubKey(PUB_KEYS[1]); | |||
| Bytes address1 = AddressEncoding.generateAddress(pubKey1); | |||
| UserAccount user1_0 = userset0.getAccount(address1); | |||
| assertNotNull(user1_0); | |||
| System.out.printf("localNodeAddress1 = %s \r\n", address1.toBase58()); | |||
| PubKey pubKey2 = KeyGenUtils.decodePubKey(PUB_KEYS[2]); | |||
| Bytes address2 = AddressEncoding.generateAddress(pubKey2); | |||
| UserAccount user2_0 = userset0.getAccount(address2); | |||
| assertNotNull(user2_0); | |||
| System.out.printf("localNodeAddress2 = %s \r\n", address2.toBase58()); | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| Bytes address3 = AddressEncoding.generateAddress(pubKey3); | |||
| UserAccount user3_0 = userset0.getAccount(address3); | |||
| assertNotNull(user3_0); | |||
| System.out.printf("localNodeAddress3 = %s \r\n", address3.toBase58()); | |||
| return ledgerHash0; | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_2() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_web2.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static Properties loadConsensusSetting(String configPath) { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource(configPath); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| return FileUtils.readProperties(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static class NodeWebContext { | |||
| private NetworkAddress serverAddress; | |||
| private DBConnectionConfig dbConnConfig; | |||
| private volatile ConfigurableApplicationContext ctx; | |||
| private volatile LedgerInitProcess initProcess; | |||
| private volatile LedgerInitializeWebController controller; | |||
| private volatile LedgerManager ledgerManager; | |||
| private volatile CompositeConnectionFactory db; | |||
| private int id; | |||
| public int getId() { | |||
| return controller.getId(); | |||
| } | |||
| public TransactionContent getInitTxContent() { | |||
| return controller.getInitTxContent(); | |||
| } | |||
| public LedgerInitProposal getLocalPermission() { | |||
| return controller.getLocalPermission(); | |||
| } | |||
| public LedgerInitDecision getLocalDecision() { | |||
| return controller.getLocalDecision(); | |||
| } | |||
| public NodeWebContext(int id, NetworkAddress serverAddress) { | |||
| this.id = id; | |||
| this.serverAddress = serverAddress; | |||
| } | |||
| public LedgerQuery registLedger(HashDigest ledgerHash) { | |||
| DbConnection conn = db.connect(dbConnConfig.getUri()); | |||
| LedgerQuery ledgerRepo = ledgerManager.register(ledgerHash, conn.getStorageService()); | |||
| return ledgerRepo; | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| doStartServer(); | |||
| NodeWebContext.this.dbConnConfig = dbConnConfig; | |||
| HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, | |||
| dbConnConfig, prompter); | |||
| System.out.printf("ledgerHash = %s \r\n", ledgerHash.toBase58()); | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public void doStartServer() { | |||
| String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); | |||
| String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); | |||
| String nodebug = "--debug=false"; | |||
| String[] innerArgs = { argServerAddress, argServerPort, nodebug }; | |||
| ctx = SpringApplication.run(LedgerInitWebTestConfiguration.class, innerArgs); | |||
| ctx.setId("Node-" + id); | |||
| controller = ctx.getBean(LedgerInitializeWebController.class); | |||
| ledgerManager = ctx.getBean(LedgerManager.class); | |||
| db = ctx.getBean(CompositeConnectionFactory.class); | |||
| initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,466 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.initializer; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNotNull; | |||
| import static org.junit.Assert.assertNull; | |||
| import static org.junit.Assert.assertTrue; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.CountDownLatch; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.context.ConfigurableApplicationContext; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.crypto.SignatureDigest; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.Operation; | |||
| import com.jd.blockchain.ledger.TransactionContent; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
| import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerQuery; | |||
| import com.jd.blockchain.storage.service.DbConnection; | |||
| import com.jd.blockchain.storage.service.impl.composite.CompositeConnectionFactory; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitCommand; | |||
| import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.HttpInitConsensServiceFactory; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConfiguration; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
| import com.jd.blockchain.transaction.SignatureUtils; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.BytesUtils; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.LedgerInitConsensusConfig; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class LedgerInitializeWeb4SingleStepsTest { | |||
| public static final String PASSWORD = LedgerInitializeTest.PASSWORD; | |||
| public static final String[] PUB_KEYS = LedgerInitializeTest.PUB_KEYS; | |||
| public static final String[] PRIV_KEYS = LedgerInitializeTest.PRIV_KEYS; | |||
| /** | |||
| * 测试一个节点向多个节点请求新建许可的过程; | |||
| */ | |||
| public void testWithSingleSteps() { | |||
| } | |||
| public void testWithSingleSteps(LedgerInitConsensusConfig.ConsensusConfig consensusConfig, String[] dbConns) { | |||
| Prompter prompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| HttpInitConsensServiceFactory httpCsSrvFactory = new HttpInitConsensServiceFactory(); | |||
| // 加载初始化配置; | |||
| LedgerInitProperties initSetting = loadInitSetting_1(); | |||
| // 加载共识配置; | |||
| Properties props = loadConsensusSetting(consensusConfig.getConfigPath()); | |||
| ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(consensusConfig.getProvider()); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props, | |||
| Utils.loadParticipantNodes()); | |||
| // 启动服务器; | |||
| NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
| NodeWebContext node0 = new NodeWebContext(0, initAddr0); | |||
| node0.startServer(); | |||
| NetworkAddress initAddr1 = initSetting.getConsensusParticipant(1).getInitializerAddress(); | |||
| NodeWebContext node1 = new NodeWebContext(1, initAddr1); | |||
| node1.startServer(); | |||
| NetworkAddress initAddr2 = initSetting.getConsensusParticipant(2).getInitializerAddress(); | |||
| NodeWebContext node2 = new NodeWebContext(2, initAddr2); | |||
| node2.startServer(); | |||
| NetworkAddress initAddr3 = initSetting.getConsensusParticipant(3).getInitializerAddress(); | |||
| NodeWebContext node3 = new NodeWebContext(3, initAddr3); | |||
| node3.startServer(); | |||
| node0.setPrompter(prompter); | |||
| node1.setPrompter(prompter); | |||
| node2.setPrompter(prompter); | |||
| node3.setPrompter(prompter); | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
| PubKey pubKey0 = KeyGenUtils.decodePubKey(PUB_KEYS[0]); | |||
| PubKey pubKey1 = KeyGenUtils.decodePubKey(PUB_KEYS[1]); | |||
| PubKey pubKey2 = KeyGenUtils.decodePubKey(PUB_KEYS[2]); | |||
| PubKey pubKey3 = KeyGenUtils.decodePubKey(PUB_KEYS[3]); | |||
| // 测试生成“账本初始化许可”; | |||
| LedgerInitConfiguration initConfig = LedgerInitConfiguration.create(initSetting); | |||
| initConfig.setConsensusSettings(csProvider, csProps); | |||
| LedgerInitProposal permission0 = testPreparePermisssion(node0, privkey0, initConfig); | |||
| LedgerInitProposal permission1 = testPreparePermisssion(node1, privkey1, initConfig); | |||
| LedgerInitProposal permission2 = testPreparePermisssion(node2, privkey2, initConfig); | |||
| LedgerInitProposal permission3 = testPreparePermisssion(node3, privkey3, initConfig); | |||
| TransactionContent initTxContent0 = node0.getInitTxContent(); | |||
| TransactionContent initTxContent1 = node1.getInitTxContent(); | |||
| TransactionContent initTxContent2 = node2.getInitTxContent(); | |||
| TransactionContent initTxContent3 = node3.getInitTxContent(); | |||
| assertTrue(SignatureUtils.verifySignature(initTxContent0, permission0.getTransactionSignature(), pubKey0)); | |||
| assertTrue(SignatureUtils.verifySignature(initTxContent1, permission1.getTransactionSignature(), pubKey1)); | |||
| assertTrue(SignatureUtils.verifySignature(initTxContent2, permission2.getTransactionSignature(), pubKey2)); | |||
| assertTrue(SignatureUtils.verifySignature(initTxContent3, permission3.getTransactionSignature(), pubKey3)); | |||
| assertNotNull(initTxContent0.getHash()); | |||
| if (!initTxContent0.getHash().equals(initTxContent1.getHash())) { | |||
| assertNull(initTxContent0.getLedgerHash()); | |||
| assertNull(initTxContent1.getLedgerHash()); | |||
| Operation[] oplist0 = initTxContent0.getOperations(); | |||
| Operation[] oplist1 = initTxContent1.getOperations(); | |||
| assertEquals(oplist0.length, oplist1.length); | |||
| LedgerInitOperation initOp0 = (LedgerInitOperation) oplist0[0]; | |||
| LedgerInitOperation initOp1 = (LedgerInitOperation) oplist1[0]; | |||
| byte[] initOpBytes0 = BinaryProtocol.encode(initOp0, LedgerInitOperation.class); | |||
| byte[] initOpBytes1 = BinaryProtocol.encode(initOp1, LedgerInitOperation.class); | |||
| assertTrue(BytesUtils.equals(initOpBytes0, initOpBytes1)); | |||
| UserRegisterOperation regOp00 = (UserRegisterOperation) oplist0[1]; | |||
| UserRegisterOperation regOp10 = (UserRegisterOperation) oplist1[1]; | |||
| byte[] regOpBytes00 = BinaryProtocol.encode(regOp00, UserRegisterOperation.class); | |||
| byte[] regOpBytes10 = BinaryProtocol.encode(regOp10, UserRegisterOperation.class); | |||
| assertTrue(BytesUtils.equals(regOpBytes00, regOpBytes10)); | |||
| UserRegisterOperation regOp01 = (UserRegisterOperation) oplist0[2]; | |||
| UserRegisterOperation regOp11 = (UserRegisterOperation) oplist1[2]; | |||
| byte[] regOpBytes01 = BinaryProtocol.encode(regOp01, UserRegisterOperation.class); | |||
| byte[] regOpBytes11 = BinaryProtocol.encode(regOp11, UserRegisterOperation.class); | |||
| assertTrue(BytesUtils.equals(regOpBytes01, regOpBytes11)); | |||
| UserRegisterOperation regOp02 = (UserRegisterOperation) oplist0[3]; | |||
| UserRegisterOperation regOp12 = (UserRegisterOperation) oplist1[3]; | |||
| byte[] regOpBytes02 = BinaryProtocol.encode(regOp02, UserRegisterOperation.class); | |||
| byte[] regOpBytes12 = BinaryProtocol.encode(regOp12, UserRegisterOperation.class); | |||
| assertTrue(BytesUtils.equals(regOpBytes02, regOpBytes12)); | |||
| UserRegisterOperation regOp03 = (UserRegisterOperation) oplist0[4]; | |||
| UserRegisterOperation regOp13 = (UserRegisterOperation) oplist1[4]; | |||
| byte[] regOpBytes03 = BinaryProtocol.encode(regOp03, UserRegisterOperation.class); | |||
| byte[] regOpBytes13 = BinaryProtocol.encode(regOp13, UserRegisterOperation.class); | |||
| assertTrue(BytesUtils.equals(regOpBytes03, regOpBytes13)); | |||
| } | |||
| assertEquals(initTxContent0.getHash(), initTxContent1.getHash()); | |||
| assertEquals(initTxContent0.getHash(), initTxContent2.getHash()); | |||
| assertEquals(initTxContent0.getHash(), initTxContent3.getHash()); | |||
| assertNull(initTxContent0.getLedgerHash()); | |||
| assertNull(initTxContent1.getLedgerHash()); | |||
| assertNull(initTxContent2.getLedgerHash()); | |||
| assertNull(initTxContent3.getLedgerHash()); | |||
| // 测试请求“账本初始化许可”; | |||
| // test request permission, and verify the response; | |||
| LedgerInitConsensusService initCsService0 = httpCsSrvFactory.connect(initAddr0); | |||
| LedgerInitConsensusService initCsService1 = httpCsSrvFactory.connect(initAddr1); | |||
| LedgerInitConsensusService initCsService2 = httpCsSrvFactory.connect(initAddr2); | |||
| LedgerInitConsensusService initCsService3 = httpCsSrvFactory.connect(initAddr3); | |||
| testRequestPermission(node0, privkey0, node1, initCsService1); | |||
| testRequestPermission(node0, privkey0, node2, initCsService2); | |||
| testRequestPermission(node0, privkey0, node3, initCsService3); | |||
| testRequestPermission(node1, privkey1, node0, initCsService0); | |||
| testRequestPermission(node1, privkey1, node2, initCsService2); | |||
| testRequestPermission(node1, privkey1, node3, initCsService3); | |||
| testRequestPermission(node2, privkey2, node0, initCsService0); | |||
| testRequestPermission(node2, privkey2, node1, initCsService1); | |||
| testRequestPermission(node2, privkey2, node3, initCsService3); | |||
| testRequestPermission(node3, privkey3, node0, initCsService0); | |||
| testRequestPermission(node3, privkey3, node1, initCsService1); | |||
| testRequestPermission(node3, privkey3, node2, initCsService2); | |||
| // 测试在节点之间共识彼此的“账本初始化许可” | |||
| boolean allPermitted0 = node0.consensusPermission(privkey0); | |||
| boolean allPermitted1 = node1.consensusPermission(privkey1); | |||
| boolean allPermitted2 = node2.consensusPermission(privkey2); | |||
| boolean allPermitted3 = node3.consensusPermission(privkey3); | |||
| assertTrue(allPermitted0); | |||
| assertTrue(allPermitted1); | |||
| assertTrue(allPermitted2); | |||
| assertTrue(allPermitted3); | |||
| // 测试生成账本,并创建“账本初始化决议”; | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(dbConns[0]); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(dbConns[1]); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(dbConns[2]); | |||
| DBConnectionConfig testDb3 = new DBConnectionConfig(dbConns[3]); | |||
| LedgerInitDecision dec0 = node0.prepareLedger(testDb0, privkey0); | |||
| LedgerInitDecision dec1 = node1.prepareLedger(testDb1, privkey1); | |||
| LedgerInitDecision dec2 = node2.prepareLedger(testDb2, privkey2); | |||
| LedgerInitDecision dec3 = node3.prepareLedger(testDb3, privkey3); | |||
| assertEquals(dec0.getLedgerHash(), dec1.getLedgerHash()); | |||
| assertEquals(dec0.getLedgerHash(), dec2.getLedgerHash()); | |||
| assertEquals(dec0.getLedgerHash(), dec3.getLedgerHash()); | |||
| testRequestDecision(node0, node1, initCsService1); | |||
| testRequestDecision(node0, node2, initCsService2); | |||
| testRequestDecision(node0, node3, initCsService3); | |||
| testRequestDecision(node1, node0, initCsService0); | |||
| testRequestDecision(node1, node2, initCsService2); | |||
| testRequestDecision(node1, node3, initCsService3); | |||
| testRequestDecision(node2, node0, initCsService0); | |||
| testRequestDecision(node2, node1, initCsService1); | |||
| testRequestDecision(node2, node3, initCsService3); | |||
| testRequestDecision(node3, node0, initCsService0); | |||
| testRequestDecision(node3, node1, initCsService1); | |||
| testRequestDecision(node3, node2, initCsService2); | |||
| } | |||
| private LedgerInitProposal testPreparePermisssion(NodeWebContext node, PrivKey privKey, | |||
| LedgerInitConfiguration setting) { | |||
| LedgerInitProposal permission = node.preparePermision(privKey, setting); | |||
| assertEquals(node.getId(), permission.getParticipantId()); | |||
| assertNotNull(permission.getTransactionSignature()); | |||
| return permission; | |||
| } | |||
| private void testRequestPermission(NodeWebContext fromNode, PrivKey fromPrivkey, NodeWebContext targetNode, | |||
| LedgerInitConsensusService targetNodeService) { | |||
| SignatureDigest reqSignature = fromNode.createPermissionRequestSignature(fromNode.getId(), fromPrivkey); | |||
| LedgerInitProposal targetPermission = targetNodeService.requestPermission(fromNode.getId(), reqSignature); | |||
| assertEquals(targetNode.getId(), targetPermission.getParticipantId()); | |||
| assertEquals(targetNode.getLocalPermission().getTransactionSignature(), | |||
| targetPermission.getTransactionSignature()); | |||
| } | |||
| private void testRequestDecision(NodeWebContext fromNode, NodeWebContext targetNode, | |||
| LedgerInitConsensusService targetNodeService) { | |||
| LedgerInitDecision targetDecision = targetNodeService.synchronizeDecision(fromNode.getLocalDecision()); | |||
| assertEquals(targetNode.getId(), targetDecision.getParticipantId()); | |||
| assertEquals(targetNode.getLocalDecision().getLedgerHash(), targetDecision.getLedgerHash()); | |||
| assertEquals(targetNode.getLocalDecision().getSignature(), targetDecision.getSignature()); | |||
| } | |||
| public static LedgerInitProperties loadInitSetting_1() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_web1.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static Properties loadConsensusSetting(String configPath) { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource(configPath); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| return FileUtils.readProperties(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static class NodeWebContext { | |||
| private NetworkAddress serverAddress; | |||
| private DBConnectionConfig dbConnConfig; | |||
| private volatile ConfigurableApplicationContext ctx; | |||
| private volatile LedgerInitProcess initProcess; | |||
| private volatile LedgerInitializeWebController controller; | |||
| private volatile LedgerManager ledgerManager; | |||
| private volatile CompositeConnectionFactory db; | |||
| private int id; | |||
| public int getId() { | |||
| return controller.getId(); | |||
| } | |||
| public TransactionContent getInitTxContent() { | |||
| return controller.getInitTxContent(); | |||
| } | |||
| public LedgerInitProposal getLocalPermission() { | |||
| return controller.getLocalPermission(); | |||
| } | |||
| public LedgerInitDecision getLocalDecision() { | |||
| return controller.getLocalDecision(); | |||
| } | |||
| public NodeWebContext(int id, NetworkAddress serverAddress) { | |||
| this.id = id; | |||
| this.serverAddress = serverAddress; | |||
| } | |||
| public LedgerQuery registLedger(HashDigest ledgerHash) { | |||
| // LedgerManage ledgerManager = ctx.getBean(LedgerManage.class); | |||
| // | |||
| // DbConnectionFactory dbConnFactory = ctx.getBean(DbConnectionFactory.class); | |||
| // DbConnection conn = dbConnFactory.connect(dbConnConfig.getUri(), | |||
| // dbConnConfig.getPassword()); | |||
| // DbConnection conn = db.connect(dbConnConfig.getUri(), | |||
| // dbConnConfig.getPassword()); | |||
| DbConnection conn = db.connect(dbConnConfig.getUri()); | |||
| LedgerQuery ledgerRepo = ledgerManager.register(ledgerHash, conn.getStorageService()); | |||
| return ledgerRepo; | |||
| } | |||
| public SignatureDigest createPermissionRequestSignature(int requesterId, PrivKey privKey) { | |||
| return controller.signPermissionRequest(requesterId, privKey); | |||
| } | |||
| public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
| DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| doStartServer(); | |||
| // NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| NodeWebContext.this.dbConnConfig = dbConnConfig; | |||
| HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, | |||
| dbConnConfig, prompter); | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public AsyncCallback<HashDigest> startInitCommand(PrivKey privKey, String base58Pwd, | |||
| LedgerInitProperties ledgerSetting, DBConnectionConfig dbConnConfig, Prompter prompter, | |||
| LedgerBindingConfig conf, CountDownLatch quitLatch) { | |||
| this.db = new CompositeConnectionFactory(); | |||
| this.dbConnConfig = dbConnConfig; | |||
| ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
| @Override | |||
| protected HashDigest invoke() throws Exception { | |||
| LedgerInitCommand initCmd = new LedgerInitCommand(); | |||
| HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, | |||
| prompter, conf, db); | |||
| NodeWebContext.this.ledgerManager = initCmd.getLedgerManager(); | |||
| quitLatch.countDown(); | |||
| return ledgerHash; | |||
| } | |||
| }; | |||
| return invoker.start(); | |||
| } | |||
| public LedgerInitProposal preparePermision(PrivKey privKey, LedgerInitConfiguration setting) { | |||
| return controller.prepareLocalPermission(id, privKey, setting); | |||
| } | |||
| public boolean consensusPermission(PrivKey privKey) { | |||
| return controller.consensusPermisions(privKey); | |||
| } | |||
| public LedgerInitDecision prepareLedger(DBConnectionConfig dbConnConfig, PrivKey privKey) { | |||
| controller.connectDb(dbConnConfig); | |||
| return controller.makeLocalDecision(privKey); | |||
| } | |||
| public void startServer() { | |||
| ThreadInvoker<Object> invoker = new ThreadInvoker<Object>() { | |||
| @Override | |||
| protected Object invoke() throws Exception { | |||
| doStartServer(); | |||
| return null; | |||
| } | |||
| }; | |||
| invoker.startAndWait(); | |||
| } | |||
| public void setPrompter(Prompter prompter) { | |||
| controller.setPrompter(prompter); | |||
| } | |||
| public void doStartServer() { | |||
| String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); | |||
| String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); | |||
| String nodebug = "--debug=false"; | |||
| String[] innerArgs = { argServerAddress, argServerPort, nodebug }; | |||
| ctx = SpringApplication.run(LedgerInitWebTestConfiguration.class, innerArgs); | |||
| ctx.setId("Node-" + id); | |||
| controller = ctx.getBean(LedgerInitializeWebController.class); | |||
| ledgerManager = ctx.getBean(LedgerManager.class); | |||
| db = ctx.getBean(CompositeConnectionFactory.class); | |||
| initProcess = ctx.getBean(LedgerInitProcess.class); | |||
| } | |||
| public void closeServer() { | |||
| if (this.ctx != null) { | |||
| this.ctx.close(); | |||
| this.ctx = null; | |||
| } | |||
| } | |||
| public LedgerManager getLedgerManager() { | |||
| return ledgerManager; | |||
| // return ctx.getBean(LedgerManager.class); | |||
| } | |||
| public CompositeConnectionFactory getStorageDB() { | |||
| return db; | |||
| // return ctx.getBean(MemoryBasedDb.class); | |||
| } | |||
| } | |||
| private static class ConsensusConfig { | |||
| String provider; | |||
| String configPath; | |||
| public String getProvider() { | |||
| return provider; | |||
| } | |||
| public String getConfigPath() { | |||
| return configPath; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,207 +0,0 @@ | |||
| package test.com.jd.blockchain.intgr.ledger; | |||
| import static org.junit.Assert.assertEquals; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.Properties; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.consensus.ConsensusProvider; | |||
| import com.jd.blockchain.consensus.ConsensusProviders; | |||
| import com.jd.blockchain.consensus.ConsensusSettings; | |||
| import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
| import com.jd.blockchain.crypto.HashDigest; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PrivKey; | |||
| import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||
| import com.jd.blockchain.ledger.LedgerBlock; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.TransactionRequest; | |||
| import com.jd.blockchain.ledger.TransactionRequestBuilder; | |||
| import com.jd.blockchain.ledger.core.DefaultOperationHandleRegisteration; | |||
| import com.jd.blockchain.ledger.core.LedgerDataQuery; | |||
| import com.jd.blockchain.ledger.core.LedgerEditor; | |||
| import com.jd.blockchain.ledger.core.LedgerManager; | |||
| import com.jd.blockchain.ledger.core.LedgerRepository; | |||
| import com.jd.blockchain.ledger.core.TransactionBatchProcessor; | |||
| import com.jd.blockchain.service.TransactionBatchResultHandle; | |||
| import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
| import com.jd.blockchain.tools.initializer.Prompter; | |||
| import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
| import com.jd.blockchain.transaction.TxBuilder; | |||
| import com.jd.blockchain.utils.ConsoleUtils; | |||
| import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
| import com.jd.blockchain.utils.io.FileUtils; | |||
| import com.jd.blockchain.utils.net.NetworkAddress; | |||
| import test.com.jd.blockchain.intgr.PresetAnswerPrompter; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeTest; | |||
| import test.com.jd.blockchain.intgr.initializer.LedgerInitializeTest.NodeContext; | |||
| import test.com.jd.blockchain.intgr.perf.LedgerPerformanceTest; | |||
| import test.com.jd.blockchain.intgr.perf.Utils; | |||
| public class LedgerBlockGeneratingTest { | |||
| @Test | |||
| public void testBlocksGenerating() { | |||
| // 初始化,并获取其中一个节点的账本,单独进行性能测试; | |||
| NodeContext node = initLedgers(false)[0]; | |||
| LedgerManager ledgerManager = node.getLedgerManager(); | |||
| HashDigest ledgerHash = ledgerManager.getLedgerHashs()[0]; | |||
| DefaultOperationHandleRegisteration opHandler = new DefaultOperationHandleRegisteration(); | |||
| test(ledgerHash, node.getPartiKey(), ledgerManager, opHandler, 1000, 5); | |||
| } | |||
| private static void test(HashDigest ledgerHash, AsymmetricKeypair adminKey, LedgerManager ledgerManager, | |||
| DefaultOperationHandleRegisteration opHandler, int batchSize, int batchCount) { | |||
| LedgerRepository ledger = ledgerManager.getLedger(ledgerHash); | |||
| long height = ledger.getLatestBlockHeight(); | |||
| assertEquals(0L, height); | |||
| ConsoleUtils.info("\r\n\r\n================= 准备测试交易 [注册用户] ================="); | |||
| int totalCount = batchSize * batchCount; | |||
| List<TransactionRequest> txList = prepareUserRegisterRequests(ledgerHash, totalCount, adminKey); | |||
| for (int i = 0; i < batchCount; i++) { | |||
| LedgerBlock latestBlock = ledger.getLatestBlock(); | |||
| assertEquals(height + i, latestBlock.getHeight()); | |||
| LedgerDataQuery previousDataSet = ledger.getLedgerData(latestBlock); | |||
| ConsoleUtils.info("------ 开始执行交易, 即将生成区块[%s] ------", (latestBlock.getHeight() + 1)); | |||
| long startTs = System.currentTimeMillis(); | |||
| LedgerEditor newEditor = ledger.createNextBlock(); | |||
| TransactionBatchProcessor txProc = new TransactionBatchProcessor( | |||
| LedgerPerformanceTest.DEFAULT_SECURITY_MANAGER, newEditor, ledger, opHandler); | |||
| testTxExec(txList, i * batchSize, batchSize, txProc); | |||
| long elapsedTs = System.currentTimeMillis() - startTs; | |||
| ConsoleUtils.info("新区块已生成! 交易数=%s; 总耗时= %s ms; TPS=%.2f", batchSize, elapsedTs, | |||
| (batchSize * 1000.00D / elapsedTs)); | |||
| } | |||
| } | |||
| private static void testTxExec(List<TransactionRequest> txList, int from, int count, | |||
| TransactionBatchProcessor txProc) { | |||
| for (int i = 0; i < count; i++) { | |||
| txProc.schedule(txList.get(from + i)); | |||
| } | |||
| TransactionBatchResultHandle handle = txProc.prepare(); | |||
| handle.commit(); | |||
| } | |||
| private static List<TransactionRequest> prepareUserRegisterRequests(HashDigest ledgerHash, int count, | |||
| AsymmetricKeypair adminKey) { | |||
| List<TransactionRequest> txList = new ArrayList<>(); | |||
| for (int i = 0; i < count; i++) { | |||
| TxBuilder txbuilder = new TxBuilder(ledgerHash); | |||
| BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||
| txbuilder.users().register(userKey.getIdentity()); | |||
| TransactionRequestBuilder reqBuilder = txbuilder.prepareRequest(); | |||
| reqBuilder.signAsEndpoint(adminKey); | |||
| txList.add(reqBuilder.buildRequest()); | |||
| } | |||
| return txList; | |||
| } | |||
| public static ConsensusProvider getConsensusProvider() { | |||
| return ConsensusProviders.getProvider("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider"); | |||
| } | |||
| public static NodeContext[] initLedgers(boolean optimized) { | |||
| Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap = new ConcurrentHashMap<>(); | |||
| Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
| LedgerInitProperties initSetting = loadInitSetting(); | |||
| Properties props = loadConsensusSetting(); | |||
| ConsensusProvider csProvider = getConsensusProvider(); | |||
| ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props, | |||
| Utils.loadParticipantNodes()); | |||
| NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node1 = new NodeContext(initSetting.getConsensusParticipant(1).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node2 = new NodeContext(initSetting.getConsensusParticipant(2).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| NodeContext node3 = new NodeContext(initSetting.getConsensusParticipant(3).getInitializerAddress(), | |||
| serviceRegisterMap); | |||
| String[] memConns = new String[] { "memory://local/0", "memory://local/1", "memory://local/2", | |||
| "memory://local/3" }; | |||
| PrivKey privkey0 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[0], | |||
| LedgerInitializeTest.PASSWORD); | |||
| DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
| testDb0.setConnectionUri(memConns[0]); | |||
| AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter, | |||
| !optimized); | |||
| PrivKey privkey1 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[1], | |||
| LedgerInitializeTest.PASSWORD); | |||
| DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
| testDb1.setConnectionUri(memConns[1]); | |||
| AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter, | |||
| !optimized); | |||
| PrivKey privkey2 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[2], | |||
| LedgerInitializeTest.PASSWORD); | |||
| DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
| testDb2.setConnectionUri(memConns[2]); | |||
| AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter, | |||
| !optimized); | |||
| PrivKey privkey3 = KeyGenUtils.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[3], | |||
| LedgerInitializeTest.PASSWORD); | |||
| DBConnectionConfig testDb03 = new DBConnectionConfig(); | |||
| testDb03.setConnectionUri(memConns[3]); | |||
| AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter, | |||
| !optimized); | |||
| HashDigest ledgerHash0 = callback0.waitReturn(); | |||
| HashDigest ledgerHash1 = callback1.waitReturn(); | |||
| HashDigest ledgerHash2 = callback2.waitReturn(); | |||
| HashDigest ledgerHash3 = callback3.waitReturn(); | |||
| node0.registLedger(ledgerHash0, memConns[0]); | |||
| node1.registLedger(ledgerHash1, memConns[1]); | |||
| node2.registLedger(ledgerHash2, memConns[2]); | |||
| node3.registLedger(ledgerHash3, memConns[3]); | |||
| return new NodeContext[] { node0, node1, node2, node3 }; | |||
| } | |||
| public static LedgerInitProperties loadInitSetting() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger_init_test_web2.init"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
| return setting; | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| public static Properties loadConsensusSetting() { | |||
| ClassPathResource ledgerInitSettingResource = new ClassPathResource("bftsmart.config"); | |||
| try (InputStream in = ledgerInitSettingResource.getInputStream()) { | |||
| return FileUtils.readProperties(in); | |||
| } catch (IOException e) { | |||
| throw new IllegalStateException(e.getMessage(), e); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,155 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ###### Consensus Participant0 ###### | |||
| ############################################ | |||
| system.server.0.network.host=127.0.0.1 | |||
| system.server.0.network.port=8910 | |||
| system.server.0.network.secure=false | |||
| ############################################ | |||
| ###### #Consensus Participant1 ###### | |||
| ############################################ | |||
| system.server.1.network.host=127.0.0.1 | |||
| system.server.1.network.port=8920 | |||
| system.server.1.network.secure=false | |||
| ############################################ | |||
| ###### #Consensus Participant2 ###### | |||
| ############################################ | |||
| system.server.2.network.host=127.0.0.1 | |||
| system.server.2.network.port=8930 | |||
| system.server.2.network.secure=false | |||
| ############################################ | |||
| ###### Consensus Participant3 ###### | |||
| ############################################ | |||
| system.server.3.network.host=127.0.0.1 | |||
| system.server.3.network.port=8940 | |||
| system.server.3.network.secure=false | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| #system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 5000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| #system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,136 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: transaction count ###### | |||
| ############################################ | |||
| system.block.txsize=15 | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: delay time ###### | |||
| ############################################ | |||
| system.block.maxdelay=500 | |||
| ###############system.server############### | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,136 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: transaction count ###### | |||
| ############################################ | |||
| system.block.txsize=15 | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: delay time ###### | |||
| ############################################ | |||
| system.block.maxdelay=500 | |||
| ###############system.server############### | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,136 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: transaction count ###### | |||
| ############################################ | |||
| system.block.txsize=15 | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: delay time ###### | |||
| ############################################ | |||
| system.block.maxdelay=500 | |||
| ###############system.server############### | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,136 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: transaction count ###### | |||
| ############################################ | |||
| system.block.txsize=15 | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: delay time ###### | |||
| ############################################ | |||
| system.block.maxdelay=500 | |||
| ###############system.server############### | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,136 +0,0 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # 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. | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: transaction count ###### | |||
| ############################################ | |||
| system.block.txsize=15 | |||
| ############################################ | |||
| ###### Consensus Commit Block Parameters: delay time ###### | |||
| ############################################ | |||
| system.block.maxdelay=500 | |||
| ###############system.server############### | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| @@ -1,128 +0,0 @@ | |||
| user[0]privKeyBase58=177gk1jTpc8qhaNtNn3Gku36zHL21WhQ7UjuCzVNBULuRgDeMrje9Av2SGgUmwgYbKNeguE | |||
| user[0]pubKeyBase58=endPsK36hceJEHbT876oATzGzkM2Wj1fpCzUgcbXWZ5iu1M3XTCf | |||
| user[1]privKeyBase58=177gjzU7GVC2kbhQ9fYTv1Zuz2bSBb4mcWdge6qEyvr6cTUuaqtXd9faYMeFYgW9YaBvkrk | |||
| user[1]pubKeyBase58=endPsK36cRmi1LhvTWNHjEJq3E5UQ2dBLvhpsABUPisE3zgqx2Z1 | |||
| user[2]privKeyBase58=177gjvto4zeC2MhYtK3hpvfxrhXhsRSt7q9WaKtZBLxXhWKLdH3YRYRfY8EazdWfgUhMdM8 | |||
| user[2]pubKeyBase58=endPsK36dDC65ACSFPmYtgHSQYqaTHWh5A6KWvNPYZwYDfKKsSYV | |||
| user[3]privKeyBase58=177gjweFgu9gzWJWXBgj18b8csnYQ77Ky7Gq1Adj92v9K6KywxbiizCejqkYm2oppYotznr | |||
| user[3]pubKeyBase58=endPsK36odY2z3kYTAbWnk6uySiyP3FTGY8f4TnNzD9VvDinZ47n | |||
| user[4]privKeyBase58=177gjxr5bPmfLZwaZ69i1ZexvpoLThdkahj8tVKNHtPtxqbCPkvhS9w2CEUcKE2YDmPWBt2 | |||
| user[4]pubKeyBase58=endPsK36g2yE2YJCZFEWfA2oDSyUZBPBvkRo3ANqgguVcyZrBBXK | |||
| user[5]privKeyBase58=177gjy6uro6c6QqcMFqu6cWg37r6vMqLwxvpotUK6vrfhSVLhsRDu5Mx7c4QyP9fMXa1BME | |||
| user[5]pubKeyBase58=endPsK36fMpdDaKWXiDo6jFjzGSsiEvC9URB8rUmNZo8sa1FHqNJ | |||
| user[6]privKeyBase58=177gjyinU15F85ERGxU9gaZBtrqy5enmwPJUZgxwu8gg6irVNZT6pEpw3W4hXwCyGVo1SPN | |||
| user[6]pubKeyBase58=endPsK36fDBPcSozjcZQyzUYL78cFQKZva3z3kknsCVcdoSg2p9i | |||
| user[7]privKeyBase58=177gk1VvWwysYDWKG1ndnzTuB2cpsztHdWHWurL72hSTGD1jcuU7KvV2WWdfnX2B2cTebRk | |||
| user[7]pubKeyBase58=endPsK36jbtQAgnEPEFofsjZV4LXRqcvoUs9zfzQ6j2php8aiX8q | |||
| user[8]privKeyBase58=177gk2KA4Yj2cTZqYwHfnB1CPAktzzPALdRiSUTezUZjFqVedmnQrZHYKcyK1crSNAevDh8 | |||
| user[8]pubKeyBase58=endPsK36ox5HmNDXBrHznL4BU7KVLBbAzDhRG2cbKc25m8wpnvKa | |||
| user[9]privKeyBase58=177gjyty49KxKiKGsz4pZF2ULrcVvKBErwfKwkk9b1ox8Tne9iVvtR45Sj7QsoRmQnJHPFf | |||
| user[9]pubKeyBase58=endPsK36n9w1ErHGnSqwRUQnJnyuBPQ5QmSCxGzB1k75X4NT4qBC | |||
| user[10]privKeyBase58=177gjv53KYZMqJVbfAwYtyPcajGmLjrau8Awf6unkbcNjxmHq7qRovMPrZc6ga21ue1Wa7d | |||
| user[10]pubKeyBase58=endPsK36q8B6kenwFiZvhKUThdJM4YFmBh1SoCz1tnF1j3Mcjau4 | |||
| user[11]privKeyBase58=177gjzMmTmPLTfeiXwv2k2jMn53svpEnKfUANwJXPmt3gcXnfWRdYVg61bpg98XZ66DW1S1 | |||
| user[11]pubKeyBase58=endPsK36kaUmnTESBpakavXpviV76hfGj78BJwSAfDhCaxs59QoZ | |||
| user[12]privKeyBase58=177gjwJjhm4eYRP9f2QHPewrM5dzoTojXFf1J8UhcNXT3VseVBknK9x6YickwYQkXKL6AGp | |||
| user[12]pubKeyBase58=endPsK36crfPSgzCjs6anNJ47AWdPYKS3bME3kkvAawaN1vqs8N1 | |||
| user[13]privKeyBase58=177gjzWtyyLdVtHK7GAQk54xUA9Y456KVCMD2SzWCxbd3d21Jzyxniq6xmYeff9oSVctHnB | |||
| user[13]pubKeyBase58=endPsK36j5KZYRhDhsgTsC5ZdKp1rcJX5K7nnmxeYwuRkDe7Rysp | |||
| user[14]privKeyBase58=177gjw7PK4xTAHgHdhuPWs6FUkTeeXax7U1Ccxp3XmogPsbAiEqo4wak7h2oXsJwJSRLLyE | |||
| user[14]pubKeyBase58=endPsK36gd4NXmvPkUWqJuMLg3a7ySGot26n4e53kSrxXsfXBjKG | |||
| user[15]privKeyBase58=177gjwBZXWsnyPKwaEF19h21W2ubcdyzuyUANHZcXqY8hfM7x1RYN38J2mWyZCyoNh7Pp1F | |||
| user[15]pubKeyBase58=endPsK36jNqThhuRtjiBBgrTRyGMzvQJh2CHRptd8SPzLxYwXcMR | |||
| user[16]privKeyBase58=177gjukkSbRFXy5x3NkBKopranzRE15Gmpny1M752dSqSjxi8FgdodVcydYTXyoFpcaJKT8 | |||
| user[16]pubKeyBase58=endPsK36ptiZM2QjMrNUwNgYj8xk1Rgj5Zf5sjSL7XAC7yn62puk | |||
| user[17]privKeyBase58=177gk1PxxA8hE4pBHJDo7ZsWUFNCQSKZBd57SwnfjgaWUD2pHBTADjxt6S2zSisoDL7gc9i | |||
| user[17]pubKeyBase58=endPsK36efCKq91s34hpf8Y2SBkrBr6xSJ14BNh58T5fzL2PFpND | |||
| user[18]privKeyBase58=177gjzzvgUt8Gpfw2fHhSe4Fcz7XWa7vzde43HW8RaECq1RrdiVkmJU9tBBYikmJMGjE2X1 | |||
| user[18]pubKeyBase58=endPsK36qwTfPUGx5o43K697bFGrex27z9hKyxs3rrfdu6S5LzLe | |||
| user[19]privKeyBase58=177gjsZV6iHWFPPRERKxWp7be2iKoNTH5uYjsEKvULTTRamKyhzM2FUJU6952skGx5D3WNs | |||
| user[19]pubKeyBase58=endPsK36drkcb7vVK9Gt8kYJQZpdxSmcRTBDZvShehy4Hcy3KCcK | |||
| user[20]privKeyBase58=177gk2Y7YjjwYcJ58BTRSpQvDcQcrNy4Kr7MC9vavgBbN3D789NaW5kF7kKTno32hoUQKcy | |||
| user[20]pubKeyBase58=endPsK36q9x98p2gKCd3yG9VEPtSU7bDMkYkiQYvBrsLWqUTmJMh | |||
| user[21]privKeyBase58=177gk1xuWkrnRogZVR6zZm88jfwY77DYLWqsw38ySAqB7P5gTMwVbacqBQ1WfRDE88ApfuH | |||
| user[21]pubKeyBase58=endPsK36kC2xs3j4iYFvroXqGEmRKwwncTQD79DX3NXzaUXeKaYZ | |||
| user[22]privKeyBase58=177gjtGutJvehWKacyPQxm1vFVWm8W23YNNydhMh6pkjzN3s894ga9fUe5LuoQCz6iBcHv6 | |||
| user[22]pubKeyBase58=endPsK36njitppxk4mSTFQZ8paMrFkCcxyiJmf4qtCFuurmuTcdB | |||
| user[23]privKeyBase58=177gjy13tQybqBwqqeer1L5MZ9rZQJ7zdhyJfHNmnx6t1ALqAAcWbmYpjswMCrwqiWXKc1w | |||
| user[23]pubKeyBase58=endPsK36n8niT9ZA8CFDfQgNSDekYQfVzqCSMu9uaVf2SSMz8hhJ | |||
| user[24]privKeyBase58=177gk2Xog1oV3udGppyb7pRbioBfXtr9CbYXdhn2h13tLAHfRnXdF2t3psjUHBQ9cR9DHvE | |||
| user[24]pubKeyBase58=endPsK36edG59E2cBMHZdGPeUaBMaT6jb9NAiR89DP7LUgT7rKCA | |||
| user[25]privKeyBase58=177gjuQRNBMaCsFvPF8vnNdjbvfcchVNgGvoJfoQdwJdypn8jYVm8ZXQy89J6Mi5cKFcJQ1 | |||
| user[25]pubKeyBase58=endPsK36g8mv52w79ABiDJ8FYoNEi2rFr9QqsHk2gUFCKJSeBnHp | |||
| user[26]privKeyBase58=177gjxFrM9exKoEC6LmFVRwW42V44Fbc3FX1PmVgwXB89MXdHz3ivbkHjK7sDxU8wbnWFeK | |||
| user[26]pubKeyBase58=endPsK36cLtDH1mKrfVfYhq8hgc5i2U5GjvsiGKJy4CjDuFsbgdw | |||
| user[27]privKeyBase58=177gjzjuMCRtGkWMcFTKR3ohYy6s5oGmHtpUwtX4joHJeBCMHhbRj2n3ZPVy5rPzeHr8YvS | |||
| user[27]pubKeyBase58=endPsK36qSTJh43PcmUZ3yJNJZo26KGff6gUPWG7CBjw2SDT6dNi | |||
| user[28]privKeyBase58=177gjxFUGbrTHdjA65sFWbAQnrsxXMuUA2UuXXnJ32wVVxeLuUpCswEpa2Z6LzeiR1DXvmn | |||
| user[28]pubKeyBase58=endPsK36guc4hCb7aiGC3RTrPd8s9czjnQmsXhvHSTp2CXUWnkhK | |||
| user[29]privKeyBase58=177gk1c7jZPrPx3r16oaUw15e94qKD6UYz72qDxyDCNHYHhKHmMp1dsWCora8knyRy3EYvC | |||
| user[29]pubKeyBase58=endPsK36icvZ2cvfXPoCyADDAgvFw2Hey9GstaFdBXYwfvU31viQ | |||
| user[30]privKeyBase58=177gju3UWrfHE1KHZkqLDB7t4bfFHgP92TGBc3C7rFSMTX9NBZX9ZhXk2EQnVyBvkRjHki1 | |||
| user[30]pubKeyBase58=endPsK36dtpxCZmyqoYqVcERoRLo4hC5VWo5LXg3dQx2uhPg5w4g | |||
| user[31]privKeyBase58=177gjsWzFrHvu5x6Pk353j2UdnTBffcq7TWWwZMX2VifrGDJT135ccuLWQL9PMD114LVzGZ | |||
| user[31]pubKeyBase58=endPsK36rf95mB5Vg5tsPxsoaYCBQEoAPEeFiRxZGcxmDUdyNhaf | |||
| user[32]privKeyBase58=177gjxVGMzaeT3Gc5iUu8YXgcsCFtX8zHGrxj4tSNduMnfKun6kC4RW56tnBJSBCnNnAdSD | |||
| user[32]pubKeyBase58=endPsK36pk5Gs4axsXRPecJAidcF9HeR3FM5tT1KyxRL91y7RAVa | |||
| user[33]privKeyBase58=177gk2FXVprLzfkZZUnNkuwr3TAPrEHm6Xj8dsc1uSq4pD5qfoRLFXbT861hDchYFU9XY8A | |||
| user[33]pubKeyBase58=endPsK36i76UE9Vg7uJRTtc7adLz5dxJ8VEiqirdRPhQY7QPGQZq | |||
| user[34]privKeyBase58=177gjzRCPGL9iSmSKLzUCrYwNtCS2mAzTyBdpRLLJbE25uPBsu68CCGvZp4ppkuora4c8Fe | |||
| user[34]pubKeyBase58=endPsK36oBLXYvPMBzm3itx6HnV6BKx1pd8PMXiK1kdhEh3FPs4M | |||
| user[35]privKeyBase58=177gjvNmrWKsh6nidSXbKMpPDUjA6azArLgwZ8DbPMeP2doXxgXyZSXuJcgAEEacF5fd32Q | |||
| user[35]pubKeyBase58=endPsK36k4npwVVZzeyWB3MRiKRprXQSDL4BMko6RGQfBiSbgGR7 | |||
| user[36]privKeyBase58=177gjzYa8Rp9HVE8cwPxTBRCvenWqkV5YWzPGcmRVJpUyd41PPstL2vMHj3G31HMCFngGf9 | |||
| user[36]pubKeyBase58=endPsK36jnVe7WNb5FJKuZ74RrQSyuf258Rb72LGWqfgs4EF7C61 | |||
| user[37]privKeyBase58=177gjz1YcRRb7KvA5vtJHis59tk5DH6R7k1gugxkVrwaUYsTsXhkjnqEXa2wSsUPyMGXsEX | |||
| user[37]pubKeyBase58=endPsK36pY59gVHWf2pHg5v69DPrbYGu4TUbjDHuUcivbEFfG2Bi | |||
| user[38]privKeyBase58=177gjvLDQxsVk4uNsZCSLX9k55Kmw2VgDPDv7cMjhJdorWdx8GkyfqtrnGw5SaPfLnRq76N | |||
| user[38]pubKeyBase58=endPsK36brD47DbWcpfbzVZ7mqcuLSBhqe6S4tWB5VHNeU3HrCGS | |||
| user[39]privKeyBase58=177gjy1mp1DBCDiSqEHRCVtZuP7dTrFSqvbpm4xUYHAVpqaLaxki9ajCJwHr47UMEgd6E7U | |||
| user[39]pubKeyBase58=endPsK36fZrfkLA16yAh3YfKn7sfjoCgNB6JML5DNCiWaj2Qjb5t | |||
| user[40]privKeyBase58=177gjtUDrLtvxCCKq7M8EMj7LkmbrfpA1gCc4YWzMF3BhnCuGnGzrJBByhfFnHScNWPg9k7 | |||
| user[40]pubKeyBase58=endPsK36pRBC9S2G9rh3BPs7SHgQtDLmQxSgFcE6JuLr6nMDJEKc | |||
| user[41]privKeyBase58=177gjxP1PK2XcBVZedJ1KfUQs9EViFVu3AgvqS1YHKYiKz2AtRAS4oLrhSFcL7cmfQTxepV | |||
| user[41]pubKeyBase58=endPsK36dez73AKqFPs4YsDNnXsCEV4ybGBdBe6wH1a2Xozc55F2 | |||
| user[42]privKeyBase58=177gjt2b87GPSS8eFctAkPELqWg6PhXkeBN1eeyDHtacC8YN9pQMB7X53PsnkQr6ZKdKBRR | |||
| user[42]pubKeyBase58=endPsK36qQjdrLEjkd3ukEBTJN6DAZQFxWhKH5iZuwAhAUgUK6bC | |||
| user[43]privKeyBase58=177gjwtLzpD6nPUzwr8V1L28sxPyBBScLoDdWhKSWeyfsyVqyuR31eroxjyjVcZpFFWMefa | |||
| user[43]pubKeyBase58=endPsK36cKze8GEMCQdMaHueetv3VMr6WRh3mTTeKN3TSkUitqTd | |||
| user[44]privKeyBase58=177gju6CW6A6WbTD9SDEXDgTAkdJQEh65qiULbvwJSoCNrcvaRqRebZ3AjdmaRqHWFQqHMN | |||
| user[44]pubKeyBase58=endPsK36r3jc7212WrVUAxkoz3DMVZSnhGSovT84EJESSo7sAGo5 | |||
| user[45]privKeyBase58=177gjuK9Dn1AYL9GzATY26xdKVcdNSiLNcb4h2He5QWebh3czW8Z2ZBPZDh6aJ1CvDHokPH | |||
| user[45]pubKeyBase58=endPsK36ihMZ4WDY3g7LN1N4MuAQYBiCZfiDYBVcsQNk3LQtyS3s | |||
| user[46]privKeyBase58=177gjzuuC7XSuFySNnuG4Vdxq9KiXKnEze6r3gS6142AtVdcLBcFGEiEKSoxN79LZioXxGP | |||
| user[46]pubKeyBase58=endPsK36jwD38VaqUEJX3BScdhTWz8t4JeRPAJvHmk8ohjNCY6a3 | |||
| user[47]privKeyBase58=177gjwK2m3Xut94h7apKB9wJJTL4VMogUhDM4L9A6iBpGhvQsNK2g2b2zakeuUhNRVbvVSN | |||
| user[47]pubKeyBase58=endPsK36mzgNV7LrB6uH3dwqsBp5V65YjimrFQNPNqHTWUbRuca9 | |||
| user[48]privKeyBase58=177gjxucknnafMMd7xQFGgTtVvgKLmRV5zCKj9uPPsiHhXVnb9WDemjmedf13rTsrwcXi5J | |||
| user[48]pubKeyBase58=endPsK36qEgVVZYjMzFRxKEaqmdfHDVrEfC6EaLQWDXJgpNjdRhr | |||
| user[49]privKeyBase58=177gjtE4XqdWT4duP34L8p1PpLfSumuPwWQnbYdzv8qwW2JJXYt9FpvedYgK7C8zvofM9Q8 | |||
| user[49]pubKeyBase58=endPsK36o9VZGMzJmgK8hFR3dFjE94QQNDRPVbsnugB46mhZ4nJQ | |||
| user[50]privKeyBase58=177gk2BLKbHnM6xjikbBa2i9uibkJP65Wd2hZQB69fChaxBNMo2GiZjqJbtaxCGwQsBEXUw | |||
| user[50]pubKeyBase58=endPsK36eV7Cm6Py8zRg8EfowKDf52mjCbAZdjgezim2Ubj6QVvE | |||
| user[51]privKeyBase58=177gjyiWv6wZ1GwMzHw94LJXZdMb7HHRV6XseQM4Be44ffaBVv6GuKpFQLRpQU35hBB4WcT | |||
| user[51]pubKeyBase58=endPsK36bkC8rzNy1kBgvv1x7yTHxARegtddrcBm4MRezJnTbzYf | |||
| user[52]privKeyBase58=177gjxhwn23LwwjN2Nu3pnN7R1skSukrGqyquDMf5LBxHJQ6RqJzscpXZNu2hTa8AHBaX29 | |||
| user[52]pubKeyBase58=endPsK36hAw55q6e3Fn1bkqQwYbW3goYUDs5HAXVM3PtNzxHoh1y | |||
| user[53]privKeyBase58=177gjwSd4r9pyJEazwM2ur1sBm3tkCEGifMFPjmPZqZcoTxyy711a2kvgrAiFFu9fMuphit | |||
| user[53]pubKeyBase58=endPsK36qkt9RiY2E6RCrwhDuGh5V6K3ZnvcspFuu7xLYvd9b3BS | |||
| user[54]privKeyBase58=177gjsD52ce6yn2oZWt21Q7Z6TGovc6eLSD415E99kk6gghAU2VwKH2L7E3gcQh31JHS2Ct | |||
| user[54]pubKeyBase58=endPsK36t48ddNpAjpez8b5TFocL4Qm16EyNyv3DqJAABcgJSuys | |||
| user[55]privKeyBase58=177gjwzeLxFNECpTsZgaHj7asXDw2tfA6ARDemXLuQJcEyPd24trrvbw59gWNqkRCZ9toqM | |||
| user[55]pubKeyBase58=endPsK36qfjKsFh1jsSfT2MKCMwrabYCpKmT3YBd7WbCkRdeLpcW | |||
| user[56]privKeyBase58=177gjsefMKGDuAGp29VFQk71yZNhR6zVDejV13R2tfNkhM7b3ftT8htfPdk8axdWBN96p5u | |||
| user[56]pubKeyBase58=endPsK36fbEiN5bZfdbiSYt56NvCwhhVHEBuzCHrdn3bUe3HBQp6 | |||
| user[57]privKeyBase58=177gjwQGxVjAdzb21Ktm6wNeyKskLppREjtwVxJpwgUYB5FQWJb96qyV9opBjdrs4DFhbHb | |||
| user[57]pubKeyBase58=endPsK36ePXN8pAmW7ZnXqu5eCuMa2Xnh9byXHGofpFVsSj1guCM | |||
| user[58]privKeyBase58=177gjxRcVAPULLEc6DNZzaimCKz1y6PcfotrKeH5TKpVK1trekX9xjbG3MG6aSgvgrmTGuc | |||
| user[58]pubKeyBase58=endPsK36oUSQMP6VTEJjv3bVgtF3mKstRiQFr9dtFx4RHfXaZUkQ | |||
| user[59]privKeyBase58=177gjtSeghrFfEeeicuoNFW4ciTJaBWRgdQ4Unp18uUA1uMwjptvjEWnyio2da5u611rRGH | |||
| user[59]pubKeyBase58=endPsK36ez3ihRJYW8m5rN4pi4f74cvJbwe8bZ4acNKZLvWX6UsN | |||
| user[60]privKeyBase58=177gjzuueMnccbKkoj6EnZxXZhtySEUqWe7Y9qdDPjEKTHEzJvZLWCmgDCADCbBSG7595qm | |||
| user[60]pubKeyBase58=endPsK36jmL17it2cqcjjqEuev4bKGBtKhqaRHgTiQHakytGDU3H | |||
| user[61]privKeyBase58=177gjuDD2rqj5kyXTJ4effaABK3FUDUNeRJXH4RFv7yQoQ7yqvVkFPUCiWoDAu1F3Rde4hq | |||
| user[61]pubKeyBase58=endPsK36rcaHXedAuHARU3Zy5E1UTKvE9Yr5yrp36DPP8Ge7VsCz | |||
| user[62]privKeyBase58=177gjuYzszWekfBatM3yg23fVDYHKkoTKTVP6PCQfFDQTfDZN7bTd7DKMr3fQvXrVC3d8Je | |||
| user[62]pubKeyBase58=endPsK36tQXnk4u9Tw9Gm4CDUTDPuag2qv6Yyn3RoBqPgD9zxjax | |||
| user[63]privKeyBase58=177gjzS5W8CZdhduphojGqeQgp3ZtwGkfRVwWQpTN6K5cUWRM2F4hwUrfURu4nrixf5V418 | |||
| user[63]pubKeyBase58=endPsK36q36veT5yUTKkBkhyDhXzWRRLNDjR9fEbWTiD5Eoy8ygN | |||
| @@ -1,26 +0,0 @@ | |||
| #当前参与方的 id | |||
| local.parti.id=0 | |||
| #当前参与方的公钥 | |||
| local.parti.pubkey=endPsK36hceJEHbT876oATzGzkM2Wj1fpCzUgcbXWZ5iu1M3XTCf | |||
| #当前参与方的私钥(密文编码) | |||
| local.parti.privkey=177gk1jTpc8qhaNtNn3Gku36zHL21WhQ7UjuCzVNBULuRgDeMrje9Av2SGgUmwgYbKNeguE | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入 | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录 | |||
| ledger.binding.out=/Users/shaozhuguang/Documents/ideaProjects/jdchain-release/source/test/test-integration/target/test-classes/bftsmart/conf/0 | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///Users/shaozhuguang/Documents/ideaProjects/jdchain-release/source/test/test-integration/bftsmart-rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令 | |||
| ledger.db.pwd= | |||
| #共识配置文件路径 | |||
| consensus.conf=/Users/shaozhuguang/Documents/ideaProjects/jdchain-release/source/test/test-integration/target/test-classes/bftsmart/bftsmart-4.config | |||
| #共识Providers配置 | |||
| consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||
| @@ -1,38 +0,0 @@ | |||
| #当前参与方的 id; | |||
| local.parti.id=0 | |||
| #当前参与方的私钥(密文编码); | |||
| local.parti.privkey=177gjsuHdbf3PU68Sm1ZU2aMcyB7sLWj94xwBUoUKvTgHq7qGUfg6ynDB62hocYYXSRXD4X | |||
| #当前参与方的私钥解密密钥(原始口令的一次哈希,Base58格式),如果不设置,则启动过程中需要从控制台输入; | |||
| local.parti.pwd=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY | |||
| #账本初始化完成后生成的"账本绑定配置文件"的输出目录; | |||
| ledger.binding.out=../conf/ | |||
| #账本数据库的连接字符 | |||
| ledger.db.uri=rocksdb:///export/App08/peer/rocks.db/rocksdb0.db | |||
| #账本数据库的连接口令; | |||
| ledger.db.pwd= | |||
| #共识系统的参数配置;可选参数; | |||
| consensus.conf=../conf/init/system.config | |||
| //ledger.base.server=nats://192.168.151.39:4222 | |||
| ledger.base.server=rabbit://192.168.151.39:5672 | |||
| #MQ订阅交易主题; | |||
| ledger.base.topic.tx=tx-topic | |||
| #MQ订阅交易结块主题; | |||
| ledger.base.topic.bl=bl-topic | |||
| #当前开启的共识算法;msg-queue/bft-smart | |||
| ledger.consensus.type=msg-queue | |||
| #发起结块的交易数间隔; | |||
| ledger.commit.interv.tx=10 | |||
| #发起结块的时间间隔,单位ms; | |||
| ledger.commit.interv.ts=5000 | |||