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