@@ -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 |