@@ -68,6 +68,8 @@ public interface DataCodes { | |||
// public static final int METADATA_PARTICIPANT_INFO = 0x640; | |||
public static final int METADATA_CRYPTO_SETTING = 0x642; | |||
public static final int METADATA_CRYPTO_SETTING_PROVIDER = 0x643; | |||
// public static final int ACCOUNT = 0x700; | |||
@@ -4,6 +4,7 @@ import java.security.AccessControlContext; | |||
import java.security.AccessController; | |||
import java.security.PrivilegedAction; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.LinkedHashMap; | |||
import java.util.Map; | |||
@@ -48,32 +49,45 @@ public final class ProviderManager { | |||
* @return | |||
*/ | |||
public <S> S getService(Class<S> serviceClazz, String providerName) { | |||
NamedProviders<S> providers = getServiceProvider(serviceClazz); | |||
NamedProviders<S> providers = getNamedProviders(serviceClazz); | |||
return providers.getService(providerName); | |||
} | |||
public <S> Provider<S> getProvider(Class<S> serviceClazz, String providerName) { | |||
@SuppressWarnings("unchecked") | |||
NamedProviders<S> providers = (NamedProviders<S>) serviceProviders.get(serviceClazz); | |||
if (providers == null) { | |||
return null; | |||
} | |||
return providers.getProvider(providerName); | |||
} | |||
public <S> Collection<Provider<S>> getAllProviders(Class<S> serviceClazz) { | |||
NamedProviders<S> providers = getServiceProvider(serviceClazz); | |||
@SuppressWarnings("unchecked") | |||
NamedProviders<S> providers = (NamedProviders<S>) serviceProviders.get(serviceClazz); | |||
if (providers == null) { | |||
return Collections.emptyList(); | |||
} | |||
return providers.getProviders(); | |||
} | |||
public <S> S installProvider(Class<S> serviceClazz, String providerFullName) { | |||
NamedProviders<S> providers = getServiceProvider(serviceClazz); | |||
NamedProviders<S> providers = getNamedProviders(serviceClazz); | |||
return providers.install(providerFullName); | |||
} | |||
public <S> S installProvider(Class<S> service, String providerFullName, ClassLoader classLoader) { | |||
NamedProviders<S> providers = getServiceProvider(service); | |||
NamedProviders<S> providers = getNamedProviders(service); | |||
return providers.install(providerFullName, classLoader); | |||
} | |||
public <S> void installAllProviders(Class<S> serviceClazz, ClassLoader classLoader) { | |||
NamedProviders<S> providers = getServiceProvider(serviceClazz); | |||
NamedProviders<S> providers = getNamedProviders(serviceClazz); | |||
providers.installAll(classLoader); | |||
} | |||
@SuppressWarnings("unchecked") | |||
private <S> NamedProviders<S> getServiceProvider(Class<S> serviceClazz) { | |||
private <S> NamedProviders<S> getNamedProviders(Class<S> serviceClazz) { | |||
NamedProviders<S> providers = (NamedProviders<S>) serviceProviders.get(serviceClazz); | |||
if (providers == null) { | |||
synchronized (mutex) { | |||
@@ -189,6 +203,11 @@ public final class ProviderManager { | |||
public Collection<Provider<S>> getProviders() { | |||
return namedProviders.values(); | |||
} | |||
public Provider<S> getProvider(String providerFullName) { | |||
return namedProviders.get(providerFullName); | |||
} | |||
public S getService(String name) { | |||
String fullName = shortNames.get(name); | |||
@@ -5,6 +5,7 @@ import com.jd.blockchain.crypto.PrivKey; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import com.jd.blockchain.utils.StringUtils; | |||
import com.jd.blockchain.utils.codec.Base58Utils; | |||
import com.jd.blockchain.utils.io.FileUtils; | |||
import org.apache.maven.plugin.AbstractMojo; | |||
@@ -1,10 +0,0 @@ | |||
package com.jd.blockchain; | |||
/** | |||
* @Author zhaogw | |||
* @Date 2018/11/26 20:46 | |||
*/ | |||
public abstract class StringUtils { | |||
public static boolean isEmpty(Object str) { | |||
return str == null || "".equals(str); | |||
} | |||
} |
@@ -1,9 +1,9 @@ | |||
#项目源文件存放的位置; | |||
#PROJECT_BASE_DIR | |||
PROJECT_BASE_DIR=E:\\gitCode\\block\\prototype\\ | |||
#合同使用的类库存放的位置,可能不在项目中,故采用全新的地址; | |||
#LEDGER_BASE_CLASS_PATH | |||
LEDGER_BASE_CLASS_PATH=E:\\gitCode\\block\\prototype\\libs\\ | |||
#为了测试,临时添加的变量; | |||
#deploy and execute the contract; | |||
cParam=com.jd.blockchain.contract.AssetContract3 | |||
sParam=E:\\gitCode\\block\\prototype\\source\\sdk\\contract-sample\\src\\main\\java\\ | |||
eParam=utf-8 | |||
@@ -1,80 +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>contract</artifactId> | |||
<version>0.9.0-SNAPSHOT</version> | |||
</parent> | |||
<artifactId>contract-tools</artifactId> | |||
<dependencies> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>contract-compiler</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>contract-jar</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>commons-io</groupId> | |||
<artifactId>commons-io</artifactId> | |||
<version>${commons-io.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.mockito</groupId> | |||
<artifactId>mockito-core</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.slf4j</groupId> | |||
<artifactId>slf4j-log4j12</artifactId> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-surefire-plugin</artifactId> | |||
<version>2.5</version> | |||
<configuration> | |||
<skipTests>true</skipTests> | |||
</configuration> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
<!--<build>--> | |||
<!--<plugins>--> | |||
<!--<plugin>--> | |||
<!--<groupId>org.apache.maven.plugins</groupId>--> | |||
<!--<artifactId>maven-compiler-plugin</artifactId>--> | |||
<!--<version>3.1</version>--> | |||
<!--<configuration>--> | |||
<!--<source>1.8</source>--> | |||
<!--<target>1.8</target>--> | |||
<!--<encoding>UTF-8</encoding>--> | |||
<!--<compilerArgs>--> | |||
<!--<!–<arg>-verbose</arg>–>--> | |||
<!--<!–<arg>-Xlint:unchecked</arg>–>--> | |||
<!--<!–<arg>-Xlint:deprecation</arg>–>--> | |||
<!--<!–<arg>-bootclasspath</arg>–>--> | |||
<!--<!–<arg>${env.JAVA_HOME}/jre/lib/rt.jar</arg>–>--> | |||
<!--<arg>-extdirs</arg>--> | |||
<!--<arg>${project.basedir}/../contract/contract-libs;$JAVA_HOME/jre/lib/ext</arg>--> | |||
<!--</compilerArgs>--> | |||
<!--</configuration>--> | |||
<!--</plugin>--> | |||
<!--</plugins>--> | |||
<!--</build>--> | |||
</project> |
@@ -106,6 +106,44 @@ public final class Crypto { | |||
private Crypto() { | |||
} | |||
public static CryptoProvider[] getProviders() { | |||
Collection<Provider<CryptoService>> providers = pm.getAllProviders(CryptoService.class); | |||
CryptoProvider[] infos = new CryptoProvider[providers.size()]; | |||
int i = 0; | |||
for (Provider<CryptoService> pd : providers) { | |||
CryptoProviderInfo info = getProviderInfo(pd); | |||
infos[i] = info; | |||
} | |||
return infos; | |||
} | |||
private static CryptoProviderInfo getProviderInfo(Provider<CryptoService> pd) { | |||
Collection<CryptoFunction> functions = pd.getService().getFunctions(); | |||
CryptoAlgorithm[] algorithms = new CryptoAlgorithm[functions.size()]; | |||
int i = 0; | |||
for (CryptoFunction function : functions) { | |||
algorithms[i] = function.getAlgorithm(); | |||
i++; | |||
} | |||
return new CryptoProviderInfo(pd.getFullName(), algorithms); | |||
} | |||
/** | |||
* 返回指定名称的密码服务提供者;如果不存在,则返回 null ; | |||
* | |||
* @param providerFullName | |||
* @return | |||
*/ | |||
public static CryptoProvider getProvider(String providerFullName) { | |||
Provider<CryptoService> pd = pm.getProvider(CryptoService.class, providerFullName); | |||
if (pd == null) { | |||
throw new CryptoException("Crypto service provider named [" + providerFullName + "] does not exist!"); | |||
} | |||
return getProviderInfo(pd); | |||
} | |||
public static Collection<CryptoAlgorithm> getAllAlgorithms() { | |||
return algorithms.values(); | |||
} | |||
@@ -9,7 +9,7 @@ import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.utils.io.BytesUtils; | |||
//@DataContract(code = DataCodes.CRYPTO_ALGORITHM) | |||
@DataContract(code = DataCodes.CRYPTO_ALGORITHM) | |||
public interface CryptoAlgorithm { | |||
/** | |||
@@ -63,7 +63,7 @@ public interface CryptoAlgorithm { | |||
* {@link #EXT_ALGORITHM}) 5 种); 接下来4位标识密钥类型(包括:{@link #SYMMETRIC_KEY}, | |||
* {@link #ASYMMETRIC_KEY}); 最后8位是算法唯一ID; | |||
*/ | |||
// @DataField(primitiveType = PrimitiveType.INT16, order = 0) | |||
@DataField(order = 0, primitiveType = PrimitiveType.INT16) | |||
short code(); | |||
/** | |||
@@ -75,7 +75,13 @@ public interface CryptoAlgorithm { | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 1, primitiveType = PrimitiveType.TEXT) | |||
String name(); | |||
public static String getString(CryptoAlgorithm algorithm) { | |||
return String.format("%s[%s]", algorithm.name(), (algorithm.code() & 0xFFFF)); | |||
} | |||
/** | |||
* | |||
@@ -23,16 +23,14 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { | |||
@Override | |||
public String toString() { | |||
return name + "[" + (code & 0xFFFF) + "]"; | |||
return CryptoAlgorithm.getString(this); | |||
} | |||
/** | |||
* 声明一项哈希算法; | |||
* | |||
* @param name | |||
* 算法名称; | |||
* @param uid | |||
* 算法ID;需要在同类算法中保持唯一性; | |||
* @param name 算法名称; | |||
* @param uid 算法ID;需要在同类算法中保持唯一性; | |||
* @return | |||
*/ | |||
public static CryptoAlgorithm defineHash(String name, byte uid) { | |||
@@ -43,10 +41,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { | |||
/** | |||
* 声明一项非对称密码算法; | |||
* | |||
* @param name | |||
* 算法名称; | |||
* @param uid | |||
* 算法ID;需要在同类算法中保持唯一性; | |||
* @param name 算法名称; | |||
* @param uid 算法ID;需要在同类算法中保持唯一性; | |||
* @return | |||
*/ | |||
public static CryptoAlgorithm defineSignature(String name, boolean encryptable, byte uid) { | |||
@@ -62,10 +58,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { | |||
/** | |||
* 声明一项非对称加密算法; | |||
* | |||
* @param name | |||
* 算法名称; | |||
* @param uid | |||
* 算法ID;需要在同类算法中保持唯一性; | |||
* @param name 算法名称; | |||
* @param uid 算法ID;需要在同类算法中保持唯一性; | |||
* @return | |||
*/ | |||
public static CryptoAlgorithm defineAsymmetricEncryption(String name, byte uid) { | |||
@@ -76,10 +70,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { | |||
/** | |||
* 声明一项对称密码算法; | |||
* | |||
* @param name | |||
* 算法名称; | |||
* @param uid | |||
* 算法ID;需要在同类算法中保持唯一性; | |||
* @param name 算法名称; | |||
* @param uid 算法ID;需要在同类算法中保持唯一性; | |||
* @return | |||
*/ | |||
public static CryptoAlgorithm defineSymmetricEncryption(String name, byte uid) { | |||
@@ -90,10 +82,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { | |||
/** | |||
* 声明一项随机数算法; | |||
* | |||
* @param name | |||
* 算法名称; | |||
* @param uid | |||
* 算法ID;需要在同类算法中保持唯一性; | |||
* @param name 算法名称; | |||
* @param uid 算法ID;需要在同类算法中保持唯一性; | |||
* @return | |||
*/ | |||
public static CryptoAlgorithm defineRandom(String name, byte uid) { | |||
@@ -104,10 +94,8 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { | |||
/** | |||
* 声明一项扩展的密码算法; | |||
* | |||
* @param name | |||
* 算法名称; | |||
* @param uid | |||
* 算法ID;需要在同类算法中保持唯一性; | |||
* @param name 算法名称; | |||
* @param uid 算法ID;需要在同类算法中保持唯一性; | |||
* @return | |||
*/ | |||
public static CryptoAlgorithm definExt(String name, byte uid) { | |||
@@ -0,0 +1,17 @@ | |||
package com.jd.blockchain.crypto; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
@DataContract(code = DataCodes.METADATA_CRYPTO_SETTING_PROVIDER) | |||
public interface CryptoProvider { | |||
@DataField(order = 0, primitiveType = PrimitiveType.TEXT) | |||
String getName(); | |||
@DataField(order = 1, list = true, refContract = true) | |||
CryptoAlgorithm[] getAlgorithms(); | |||
} |
@@ -0,0 +1,24 @@ | |||
package com.jd.blockchain.crypto; | |||
class CryptoProviderInfo implements CryptoProvider { | |||
private String name; | |||
private CryptoAlgorithm[] algorithms; | |||
public CryptoProviderInfo(String name, CryptoAlgorithm[] algorithms) { | |||
this.name = name; | |||
this.algorithms = algorithms; | |||
} | |||
@Override | |||
public String getName() { | |||
return name; | |||
} | |||
@Override | |||
public CryptoAlgorithm[] getAlgorithms() { | |||
return algorithms.clone(); | |||
} | |||
} |
@@ -1,67 +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= | |||
#第0个参与方的公钥文件路径 | |||
cons_parti.0.pubkey-path= | |||
#第0个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
cons_parti.0.pubkey= | |||
#第0个参与方的账本初始服务的主机 | |||
cons_parti.0.initializer.host=127.0.0.1 | |||
#第0个参与方的账本初始服务的端口 | |||
cons_parti.0.initializer.port=17000 | |||
#第0个参与方的账本初始服务是否开启安全连接 | |||
cons_parti.0.initializer.secure=false | |||
#第1个参与方的名称 | |||
cons_parti.1.name= | |||
#第1个参与方的公钥文件路径 | |||
cons_parti.1.pubkey-path= | |||
#第1个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
cons_parti.1.pubkey= | |||
#第1个参与方的账本初始服务的主机 | |||
cons_parti.1.initializer.host=127.0.0.1 | |||
#第1个参与方的账本初始服务的端口 | |||
cons_parti.1.initializer.port=17010 | |||
#第1个参与方的账本初始服务是否开启安全连接 | |||
cons_parti.1.initializer.secure=false | |||
#第2个参与方的名称 | |||
cons_parti.2.name= | |||
#第2个参与方的公钥文件路径 | |||
cons_parti.2.pubkey-path= | |||
#第2个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
cons_parti.2.pubkey= | |||
#第2个参与方的账本初始服务的主机 | |||
cons_parti.2.initializer.host=127.0.0.1 | |||
#第2个参与方的账本初始服务的端口 | |||
cons_parti.2.initializer.port=17020 | |||
#第2个参与方的账本初始服务是否开启安全连接 | |||
cons_parti.2.initializer.secure=false | |||
#第3个参与方的名称 | |||
cons_parti.3.name= | |||
#第3个参与方的公钥文件路径 | |||
cons_parti.3.pubkey-path= | |||
#第3个参与方的公钥内容(由keygen工具生成),此参数优先于 pubkey-path 参数 | |||
cons_parti.3.pubkey= | |||
#第3个参与方的账本初始服务的主机 | |||
cons_parti.3.initializer.host=127.0.0.1 | |||
#第3个参与方的账本初始服务的端口 | |||
cons_parti.3.initializer.port=17030 | |||
#第3个参与方的账本初始服务是否开启安全连接 | |||
cons_parti.3.initializer.secure=false | |||
@@ -0,0 +1,97 @@ | |||
#账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
ledger.name= | |||
#共识服务提供者;必须; | |||
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.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=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX | |||
#第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=classpath:keys/parti2.pub | |||
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.2.pubkey= | |||
#第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=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk | |||
#第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 |
@@ -22,11 +22,3 @@ ledger.db.uri= | |||
#账本数据库的连接口令 | |||
ledger.db.pwd= | |||
#共识配置文件路径 | |||
#推荐使用绝对路径,相对路径以当前文件(local.conf)所在目录为基准 | |||
consensus.conf=bftsmart.config | |||
#共识Providers配置 | |||
#BftSmart共识Provider:com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
#简单消息共识Provider:com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider | |||
consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider |
@@ -81,7 +81,7 @@ public class GatewayQueryServiceHandler implements GatewayQueryService { | |||
ledgerInitSettings.setSeed(initSeed(ledgerMetadata.getSeed())); | |||
// 设置共识协议 | |||
ledgerInitSettings.setConsensusProtocol(consensusProtocol(ledgerMetadata.getSetting().getConsensusProvider())); | |||
ledgerInitSettings.setConsensusProtocol(ledgerMetadata.getSetting().getConsensusProvider()); | |||
return ledgerInitSettings; | |||
} | |||
@@ -110,24 +110,6 @@ public class GatewayQueryServiceHandler implements GatewayQueryService { | |||
return seed.toString(); | |||
} | |||
/** | |||
* 生成共识协议 | |||
* | |||
* @param consensusProvider | |||
* 共识协议提提供者 | |||
* @return | |||
*/ | |||
private int consensusProtocol(String consensusProvider) { | |||
if (consensusProvider.equals(BftsmartConsensusProvider.NAME)) { | |||
return LedgerInitSettings.CONSENSUS_PROTOCOL.BFTSMART.code(); | |||
} else if (consensusProvider.equals(MsgQueueConsensusProvider.NAME)) { | |||
return LedgerInitSettings.CONSENSUS_PROTOCOL.MSGQUEUE.code(); | |||
} | |||
return LedgerInitSettings.CONSENSUS_PROTOCOL.UNKNOWN.code(); | |||
} | |||
/** | |||
* 初始化共识配置 | |||
* | |||
@@ -239,6 +239,13 @@ public class BlockBrowserController implements BlockchainExtendQueryService { | |||
return peerService.getQueryService().getDataEntries(ledgerHash, address, keys); | |||
} | |||
@RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/{address}/entries-version") | |||
public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, | |||
@PathVariable("address") String address, | |||
@RequestBody KVInfoVO kvInfoVO) { | |||
return peerService.getQueryService().getDataEntries(ledgerHash, address, kvInfoVO); | |||
} | |||
@RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") | |||
@Override | |||
public KVDataEntry[] getDataEntries(@PathVariable("ledgerHash") HashDigest ledgerHash, | |||
@@ -2,6 +2,13 @@ package com.jd.blockchain.gateway.web; | |||
import java.util.List; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.consensus.ClientIdentification; | |||
import com.jd.blockchain.consensus.ClientIdentifications; | |||
import com.jd.blockchain.consensus.action.ActionRequest; | |||
import com.jd.blockchain.consensus.action.ActionResponse; | |||
import com.jd.blockchain.consensus.bftsmart.BftsmartNodeSettings; | |||
import com.jd.blockchain.ledger.*; | |||
import com.jd.blockchain.web.serializes.ByteArrayObjectUtil; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.format.FormatterRegistry; | |||
@@ -27,6 +34,7 @@ public class GatewayWebServerConfigurer implements WebMvcConfigurer { | |||
static { | |||
JSONSerializeUtils.disableCircularReferenceDetect(); | |||
JSONSerializeUtils.configStringSerializer(ByteArray.class); | |||
DataContractRegistry.register(BftsmartNodeSettings.class); | |||
} | |||
@@ -21,10 +21,10 @@ peer.providers=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
data.retrieval.url=http://127.0.0.1:10001 | |||
#默认公钥的内容(Base58编码数据); | |||
keys.default.pubkey=3snPdw7i7PapsDoW185c3kfK6p8s6SwiJAdEUzgnfeuUox12nxgzXu | |||
keys.default.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 | |||
#默认私钥的路径;在 pk-path 和 pk 之间必须设置其一; | |||
keys.default.privkey-path= | |||
#默认私钥的内容(加密的Base58编码数据);在 pk-path 和 pk 之间必须设置其一; | |||
keys.default.privkey=177gjyoEUhdD1NkQSxBVvfSyovMd1ha5H46zsb9kyErLNBuQkLRAf2ea6CNjStjCFJQN8S1 | |||
keys.default.privkey=177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x | |||
#默认私钥的解码密码; | |||
keys.default.privkey-password=DYu3G8aGTMBW1WrTw76zxQJQU4DHLw9MLyy7peG4LKkY |
@@ -1,22 +1,37 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import java.util.HashMap; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
public class CryptoConfig implements CryptoSetting { | |||
private CryptoProvider[] cryptoProviders; | |||
private short hashAlgorithm; | |||
private boolean autoVerifyHash; | |||
HashMap<String, CryptoProvider> providers; | |||
HashMap<String, CryptoAlgorithm> nameAlgorithms; | |||
HashMap<Short, CryptoAlgorithm> codeAlgorithms; | |||
public CryptoConfig() { | |||
} | |||
public CryptoConfig(CryptoSetting setting) { | |||
this.hashAlgorithm = setting.getHashAlgorithm(); | |||
setSupportedProviders(setting.getSupportedProviders()); | |||
setHashAlgorithm(setting.getHashAlgorithm()); | |||
this.autoVerifyHash = setting.getAutoVerifyHash(); | |||
} | |||
@Override | |||
public CryptoProvider[] getSupportedProviders() { | |||
return cryptoProviders == null ? null : cryptoProviders.clone(); | |||
} | |||
@Override | |||
public short getHashAlgorithm() { | |||
return hashAlgorithm; | |||
@@ -27,11 +42,47 @@ public class CryptoConfig implements CryptoSetting { | |||
return autoVerifyHash; | |||
} | |||
public void setSupportedProviders(CryptoProvider[] supportedProviders) { | |||
HashMap<String, CryptoProvider> providers = new HashMap<String, CryptoProvider>(); | |||
HashMap<String, CryptoAlgorithm> nameAlgorithms = new HashMap<String, CryptoAlgorithm>(); | |||
HashMap<Short, CryptoAlgorithm> codeAlgorithms = new HashMap<Short, CryptoAlgorithm>(); | |||
if (supportedProviders != null) { | |||
// 检查是否存在重复的提供者以及算法; | |||
for (CryptoProvider cryptoProvider : supportedProviders) { | |||
if (providers.containsKey(cryptoProvider.getName())) { | |||
throw new LedgerException("Duplicate crypto providers [" + cryptoProvider.getName() + "]!"); | |||
} | |||
CryptoAlgorithm[] algorithms = cryptoProvider.getAlgorithms(); | |||
for (CryptoAlgorithm alg : algorithms) { | |||
if (nameAlgorithms.containsKey(alg.name())) { | |||
throw new LedgerException("Duplicate crypto algorithms [" + alg.toString() + "] from provider " | |||
+ cryptoProvider.getName() + "!"); | |||
} | |||
if (codeAlgorithms.containsKey(alg.code())) { | |||
throw new LedgerException("Duplicate crypto algorithms [" + alg.toString() + "] from provider" | |||
+ cryptoProvider.getName() + "!"); | |||
} | |||
nameAlgorithms.put(alg.name(), alg); | |||
codeAlgorithms.put(alg.code(), alg); | |||
} | |||
providers.put(cryptoProvider.getName(), cryptoProvider); | |||
} | |||
} | |||
this.providers = providers; | |||
this.nameAlgorithms = nameAlgorithms; | |||
this.codeAlgorithms = codeAlgorithms; | |||
this.cryptoProviders = supportedProviders; | |||
} | |||
public void setHashAlgorithm(CryptoAlgorithm hashAlgorithm) { | |||
this.hashAlgorithm = hashAlgorithm.code(); | |||
setHashAlgorithm(hashAlgorithm.code()); | |||
} | |||
public void setHashAlgorithm(short hashAlgorithm) { | |||
if (codeAlgorithms == null || !codeAlgorithms.containsKey(hashAlgorithm)) { | |||
throw new LedgerException("The specified algorithm[" + hashAlgorithm + "] has no provider!"); | |||
} | |||
this.hashAlgorithm = hashAlgorithm; | |||
} | |||
@@ -157,6 +157,9 @@ public class DataAccount implements AccountHeader, MerkleProvable { | |||
* @return return total count; | |||
*/ | |||
public long getDataEntriesTotalCount() { | |||
if(baseAccount == null){ | |||
return 0; | |||
} | |||
return baseAccount.dataset.getDataCount(); | |||
} | |||
@@ -3,10 +3,15 @@ package com.jd.blockchain.ledger.core.impl; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
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.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.LedgerInitSetting; | |||
import com.jd.blockchain.ledger.core.LedgerConsts; | |||
import com.jd.blockchain.ledger.core.LedgerEditor; | |||
import com.jd.blockchain.ledger.core.LedgerException; | |||
import com.jd.blockchain.ledger.core.LedgerManage; | |||
import com.jd.blockchain.ledger.core.LedgerRepository; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
@@ -57,26 +62,83 @@ public class LedgerManager implements LedgerManage { | |||
@Override | |||
public LedgerRepository register(HashDigest ledgerHash, KVStorageService storageService) { | |||
// 加载账本数据库; | |||
VersioningKVStorage ledgerVersioningStorage = storageService.getVersioningKVStorage(); | |||
ExPolicyKVStorage ledgerExPolicyStorage = storageService.getExPolicyKVStorage(); | |||
LedgerRepository ledgerRepo = new LedgerRepositoryImpl(ledgerHash, LEDGER_PREFIX, ledgerExPolicyStorage, | |||
ledgerVersioningStorage); | |||
LedgerRepositoryContext ledgerCtx = new LedgerRepositoryContext(); | |||
ledgerCtx.ledgerRepo = ledgerRepo; | |||
ledgerCtx.storageService = storageService; | |||
// 校验 crypto service provider ; | |||
CryptoSetting cryptoSetting = ledgerRepo.getAdminAccount().getSetting().getCryptoSetting(); | |||
checkCryptoSetting(cryptoSetting, ledgerHash); | |||
// 创建账本上下文; | |||
LedgerRepositoryContext ledgerCtx = new LedgerRepositoryContext(ledgerRepo, storageService); | |||
ledgers.put(ledgerHash, ledgerCtx); | |||
return ledgerRepo; | |||
} | |||
/** | |||
* 检查账本的密码参数设置与本地节点的运行时环境是否匹配; | |||
* | |||
* @param cryptoSetting | |||
* @param ledgerHash | |||
*/ | |||
private void checkCryptoSetting(CryptoSetting cryptoSetting, HashDigest ledgerHash) { | |||
CryptoProvider[] cryptoProviders = cryptoSetting.getSupportedProviders(); | |||
if (cryptoProviders == null || cryptoProviders.length == 0) { | |||
throw new LedgerException("No supported crypto service providers has been setted in the ledger[" | |||
+ ledgerHash.toBase58() + "]!"); | |||
} | |||
for (CryptoProvider cp : cryptoProviders) { | |||
CryptoProvider regCp = Crypto.getProvider(cp.getName()); | |||
checkCryptoProviderConsistency(regCp, cp); | |||
} | |||
} | |||
/** | |||
* 检查密码服务提供者的信息是否匹配; | |||
* | |||
* @param registeredProvider | |||
* @param settingProvider | |||
*/ | |||
private void checkCryptoProviderConsistency(CryptoProvider registeredProvider, CryptoProvider settingProvider) { | |||
if (registeredProvider == null) { | |||
throw new LedgerException("Crypto service provider[" + settingProvider.getName() | |||
+ "] has not registered in the runtime environment of current peer!"); | |||
} | |||
CryptoAlgorithm[] runtimeAlgothms = registeredProvider.getAlgorithms(); | |||
CryptoAlgorithm[] settingAlgothms = settingProvider.getAlgorithms(); | |||
if (runtimeAlgothms.length != settingAlgothms.length) { | |||
throw new LedgerException("Crypto service provider[" + settingProvider.getName() | |||
+ "] has not registered in runtime of current peer!"); | |||
} | |||
HashMap<Short, CryptoAlgorithm> runtimeAlgothmMap = new HashMap<Short, CryptoAlgorithm>(); | |||
for (CryptoAlgorithm alg : runtimeAlgothms) { | |||
runtimeAlgothmMap.put(alg.code(), alg); | |||
} | |||
for (CryptoAlgorithm alg : settingAlgothms) { | |||
CryptoAlgorithm regAlg = runtimeAlgothmMap.get(alg.code()); | |||
if (regAlg == null) { | |||
throw new LedgerException( | |||
String.format("Crypto algorithm[%s] is not defined by provider[%s] in runtime of current peer!", | |||
alg.toString(), registeredProvider.getName())); | |||
} | |||
if (!regAlg.name().equals(alg.name())) { | |||
throw new LedgerException(String.format( | |||
"Crypto algorithm[%s] do not match the same code algorithm[%s] defined by provider[%s] in runtime of current peer!", | |||
CryptoAlgorithm.getString(alg), CryptoAlgorithm.getString(regAlg), | |||
registeredProvider.getName())); | |||
} | |||
} | |||
} | |||
@Override | |||
public void unregister(HashDigest ledgerHash) { | |||
LedgerRepositoryContext ledgerCtx = ledgers.get(ledgerHash); | |||
LedgerRepositoryContext ledgerCtx = ledgers.remove(ledgerHash); | |||
if (ledgerCtx != null) { | |||
ledgerCtx.ledgerRepo.close(); | |||
ledgers.remove(ledgerHash); | |||
ledgerCtx.ledgerRepo = null; | |||
ledgerCtx.storageService = null; | |||
} | |||
} | |||
@@ -88,18 +150,6 @@ public class LedgerManager implements LedgerManage { | |||
*/ | |||
@Override | |||
public LedgerEditor newLedger(LedgerInitSetting initSetting, KVStorageService storageService) { | |||
// GenesisLedgerStorageProxy genesisStorageProxy = new | |||
// GenesisLedgerStorageProxy(); | |||
// BufferedKVStorage bufferedStorage = new | |||
// BufferedKVStorage(genesisStorageProxy, genesisStorageProxy, false); | |||
// LedgerEditor genesisBlockEditor = | |||
// LedgerTransactionalEditor.createEditor(initSetting, | |||
// bufferedStorage, bufferedStorage); | |||
// return new LedgerInitializer(genesisBlockEditor, bufferedStorage, | |||
// genesisStorageProxy, storageService, this); | |||
LedgerEditor genesisBlockEditor = LedgerTransactionalEditor.createEditor(initSetting, LEDGER_PREFIX, | |||
storageService.getExPolicyKVStorage(), storageService.getVersioningKVStorage()); | |||
return genesisBlockEditor; | |||
@@ -110,10 +160,16 @@ public class LedgerManager implements LedgerManage { | |||
return LEDGER_PREFIX + base58LedgerHash + LedgerConsts.KEY_SEPERATOR; | |||
} | |||
private static class LedgerRepositoryContext { | |||
private LedgerRepository ledgerRepo; | |||
public final LedgerRepository ledgerRepo; | |||
private KVStorageService storageService; | |||
public final KVStorageService storageService; | |||
public LedgerRepositoryContext(LedgerRepository ledgerRepo, KVStorageService storageService) { | |||
this.ledgerRepo = ledgerRepo; | |||
this.storageService = storageService; | |||
} | |||
} | |||
} |
@@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core.impl; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.contract.ContractException; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.*; | |||
import com.jd.blockchain.ledger.core.ContractAccountSet; | |||
@@ -15,6 +16,10 @@ import com.jd.blockchain.ledger.core.UserAccountSet; | |||
import com.jd.blockchain.transaction.BlockchainQueryService; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.QueryUtil; | |||
import com.jd.blockchain.utils.StringUtils; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
public class LedgerQueryService implements BlockchainQueryService { | |||
@@ -263,6 +268,9 @@ public class LedgerQueryService implements BlockchainQueryService { | |||
long ver; | |||
for (int i = 0; i < entries.length; i++) { | |||
ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); | |||
dataAccount.getBytes(Bytes.fromString(keys[i]),1); | |||
if (ver < 0) { | |||
entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); | |||
}else { | |||
@@ -275,6 +283,60 @@ public class LedgerQueryService implements BlockchainQueryService { | |||
return entries; | |||
} | |||
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { | |||
//parse kvInfoVO; | |||
List<String> keyList = new ArrayList<>(); | |||
List<Long> versionList = new ArrayList<>(); | |||
if(kvInfoVO != null){ | |||
for(KVDataVO kvDataVO : kvInfoVO.getData()){ | |||
for(Long version : kvDataVO.getVersion()){ | |||
keyList.add(kvDataVO.getKey()); | |||
versionList.add(version); | |||
} | |||
} | |||
} | |||
String[] keys = keyList.toArray(new String[keyList.size()]); | |||
Long[] versions = versionList.toArray(new Long[versionList.size()]); | |||
if (keys == null || keys.length == 0) { | |||
return null; | |||
} | |||
if (versions == null || versions.length == 0) { | |||
return null; | |||
} | |||
if(keys.length != versions.length){ | |||
throw new ContractException("keys.length!=versions.length!"); | |||
} | |||
LedgerRepository ledger = ledgerService.getLedger(ledgerHash); | |||
LedgerBlock block = ledger.getLatestBlock(); | |||
DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); | |||
DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); | |||
KVDataEntry[] entries = new KVDataEntry[keys.length]; | |||
long ver = -1; | |||
for (int i = 0; i < entries.length; i++) { | |||
// ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); | |||
// dataAccount.getBytes(Bytes.fromString(keys[i]),1); | |||
ver = versions[i]; | |||
if (ver < 0) { | |||
entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); | |||
}else { | |||
if(dataAccount.getDataEntriesTotalCount()==0 || | |||
dataAccount.getBytes(Bytes.fromString(keys[i]), ver) == null){ | |||
//is the address is not exist; the result is null; | |||
entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); | |||
} else { | |||
byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); | |||
BytesValue decodeData = BinaryProtocol.decode(value); | |||
entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); | |||
} | |||
} | |||
} | |||
return entries; | |||
} | |||
@Override | |||
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { | |||
@@ -156,6 +156,11 @@ public class ContractLedgerContext implements LedgerContext { | |||
return innerQueryService.getDataEntries(ledgerHash, address, keys); | |||
} | |||
@Override | |||
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { | |||
return innerQueryService.getDataEntries(ledgerHash, address, kvInfoVO); | |||
} | |||
@Override | |||
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { | |||
return innerQueryService.getDataEntries(ledgerHash, address, fromIndex, count); | |||
@@ -6,8 +6,12 @@ import static org.junit.Assert.assertTrue; | |||
import org.junit.Test; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.ledger.core.AccountSet; | |||
@@ -17,6 +21,11 @@ import com.jd.blockchain.ledger.core.impl.OpeningAccessPolicy; | |||
import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | |||
public class AccountSetTest { | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
@Test | |||
public void test() { | |||
@@ -24,7 +33,12 @@ public class AccountSetTest { | |||
MemoryKVStorage storage = new MemoryKVStorage(); | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConf = new CryptoConfig(); | |||
cryptoConf.setSupportedProviders(supportedProviders); | |||
cryptoConf.setAutoVerifyHash(true); | |||
cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
@@ -5,7 +5,11 @@ import static org.junit.Assert.assertFalse; | |||
import org.junit.Test; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.ledger.core.BaseAccount; | |||
@@ -22,12 +26,21 @@ import com.jd.blockchain.utils.io.BytesUtils; | |||
*/ | |||
public class BaseAccountTest { | |||
public static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
@Test | |||
public void basicTest() { | |||
String keyPrefix = ""; | |||
MemoryKVStorage testStorage = new MemoryKVStorage(); | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConf = new CryptoConfig(); | |||
cryptoConf.setSupportedProviders(supportedProviders); | |||
cryptoConf.setAutoVerifyHash(true); | |||
cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
@@ -13,8 +13,12 @@ import com.jd.blockchain.ledger.LedgerMetadata; | |||
import org.junit.Test; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
@@ -30,6 +34,9 @@ import com.jd.blockchain.utils.net.NetworkAddress; | |||
public class LedgerAdminAccountTest { | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
private Random rand = new Random(); | |||
@Test | |||
@@ -55,7 +62,13 @@ public class LedgerAdminAccountTest { | |||
initSetting.setConsensusSettings(new Bytes(csSysSettingBytes)); | |||
initSetting.setConsensusProvider("consensus-provider"); | |||
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(true); | |||
cryptoSetting.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
initSetting.setCryptoSetting(cryptoSetting); | |||
@@ -11,8 +11,11 @@ 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.SignatureFunction; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.ledger.LedgerBlock; | |||
import com.jd.blockchain.ledger.LedgerInitSetting; | |||
@@ -34,6 +37,10 @@ import com.jd.blockchain.utils.io.BytesUtils; | |||
import com.jd.blockchain.utils.net.NetworkAddress; | |||
public class LedgerEditerTest { | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
static { | |||
DataContractRegistry.register(com.jd.blockchain.ledger.TransactionContent.class); | |||
@@ -109,8 +116,14 @@ public class LedgerEditerTest { | |||
private LedgerInitSetting createLedgerInitSetting() { | |||
SignatureFunction signFunc = Crypto.getSignatureFunction("ED25519"); | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig defCryptoSetting = new CryptoConfig(); | |||
defCryptoSetting.setSupportedProviders(supportedProviders); | |||
defCryptoSetting.setAutoVerifyHash(true); | |||
defCryptoSetting.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
@@ -12,7 +12,11 @@ import org.junit.Test; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.ledger.LedgerInitOperation; | |||
@@ -27,6 +31,9 @@ import com.jd.blockchain.utils.net.NetworkAddress; | |||
public class LedgerInitOperationTest { | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
byte[] seed = null; | |||
byte[] csSysSettingBytes = null; | |||
LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData(); | |||
@@ -44,7 +51,12 @@ public class LedgerInitOperationTest { | |||
csSysSettingBytes = new byte[64]; | |||
rand.nextBytes(csSysSettingBytes); | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setSupportedProviders(supportedProviders); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
@@ -12,7 +12,11 @@ import org.junit.Test; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.ledger.LedgerInitSetting; | |||
@@ -24,12 +28,15 @@ import com.jd.blockchain.transaction.LedgerInitSettingData; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.net.NetworkAddress; | |||
public class LedgerInitSettingTest { | |||
public class LedgerInitSettingSerializeTest { | |||
byte[] seed = null; | |||
byte[] csSysSettingBytes = null; | |||
LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData(); | |||
LedgerInitOpTemplate template = new LedgerInitOpTemplate(); | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
@Before | |||
public void initCfg() { | |||
@@ -41,7 +48,13 @@ public class LedgerInitSettingTest { | |||
csSysSettingBytes = new byte[64]; | |||
rand.nextBytes(csSysSettingBytes); | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setSupportedProviders(supportedProviders); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
@@ -71,7 +84,7 @@ public class LedgerInitSettingTest { | |||
ConsensusParticipantData[] parties1 = Arrays.copyOf(parties, 4); | |||
ledgerInitSettingData.setConsensusParticipants(parties1); | |||
byte[] encode = BinaryProtocol.encode(ledgerInitSettingData, LedgerInitSetting.class); | |||
LedgerInitSetting decode = BinaryProtocol.decode(encode); |
@@ -13,9 +13,12 @@ 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.SignatureFunction; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockBody; | |||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
@@ -54,8 +57,12 @@ public class LedgerManagerTest { | |||
DataContractRegistry.register(UserRegisterOperation.class); | |||
DataContractRegistry.register(DataAccountRegisterOperation.class); | |||
DataContractRegistry.register(BlockBody.class); | |||
DataContractRegistry.register(CryptoProvider.class); | |||
} | |||
public static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
private SignatureFunction signatureFunction; | |||
@Before | |||
@@ -170,7 +177,16 @@ public class LedgerManagerTest { | |||
} | |||
private LedgerInitSetting createLedgerInitSetting() { | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig defCryptoSetting = new CryptoConfig(); | |||
defCryptoSetting.setSupportedProviders(supportedProviders); | |||
defCryptoSetting.setAutoVerifyHash(true); | |||
defCryptoSetting.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
@@ -15,9 +15,13 @@ import org.junit.Test; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
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.ParticipantNode; | |||
import com.jd.blockchain.ledger.core.CryptoConfig; | |||
@@ -30,6 +34,10 @@ import com.jd.blockchain.utils.Bytes; | |||
* Created by zhangshuang3 on 2018/8/31. | |||
*/ | |||
public class LedgerMetaDataTest { | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
byte[] seed = null; | |||
String consensusProvider = "test-provider"; | |||
byte[] consensusSettingBytes = null; | |||
@@ -56,7 +64,13 @@ public class LedgerMetaDataTest { | |||
// ConsensusConfig consensusConfig = new ConsensusConfig(); | |||
// consensusConfig.setValue(settingValue);ClassicCryptoService.ED25519_ALGORITHM | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setSupportedProviders(supportedProviders); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
@@ -93,7 +107,13 @@ public class LedgerMetaDataTest { | |||
// ConsensusConfig consensusConfig = new ConsensusConfig(); | |||
// consensusConfig.setValue(settingValue); | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setSupportedProviders(supportedProviders); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
@@ -133,7 +153,14 @@ public class LedgerMetaDataTest { | |||
@Test | |||
public void testSerialize_CryptoSetting() { | |||
// LedgerCodes.METADATA_LEDGER_SETTING_CRYPTO | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setSupportedProviders(supportedProviders); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
byte[] encodeBytes = BinaryProtocol.encode(cryptoConfig, CryptoSetting.class); | |||
@@ -4,10 +4,13 @@ import java.util.Random; | |||
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.PubKey; | |||
import com.jd.blockchain.crypto.SignatureFunction; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainIdentityData; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.PreparedTransaction; | |||
@@ -22,6 +25,9 @@ public class LedgerTestUtils { | |||
// private static ThreadLocalRandom rand = ThreadLocalRandom.current(); | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
private static Random rand = new Random(); | |||
public static TransactionRequest createTxRequest(HashDigest ledgerHash) { | |||
@@ -76,7 +82,14 @@ public class LedgerTestUtils { | |||
} | |||
public static CryptoSetting createDefaultCryptoSetting() { | |||
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(true); | |||
cryptoSetting.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
return cryptoSetting; | |||
@@ -14,8 +14,12 @@ import java.util.Set; | |||
import org.junit.Test; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.core.CryptoConfig; | |||
import com.jd.blockchain.ledger.core.MerkleDataSet; | |||
import com.jd.blockchain.ledger.core.MerkleProof; | |||
@@ -26,13 +30,23 @@ import com.jd.blockchain.utils.io.BytesUtils; | |||
public class MerkleDataSetTest { | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
/** | |||
* 测试存储的增长; | |||
*/ | |||
@Test | |||
public void testStorageIncreasement() { | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
String keyPrefix = ""; | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setSupportedProviders(supportedProviders); | |||
cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
@@ -116,7 +130,13 @@ public class MerkleDataSetTest { | |||
String keyPrefix = ""; | |||
Random rand = new Random(); | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setSupportedProviders(supportedProviders); | |||
cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
@@ -281,7 +301,13 @@ public class MerkleDataSetTest { | |||
String keyPrefix = ""; | |||
Random rand = new Random(); | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setSupportedProviders(supportedProviders); | |||
cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
@@ -1,26 +1,48 @@ | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.utils.Bytes; | |||
/** | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code= DataCodes.TX_OP_CONTRACT_EVENT_SEND) | |||
public interface ContractEventSendOperation extends Operation { | |||
@DataField(order=2, primitiveType=PrimitiveType.BYTES) | |||
Bytes getContractAddress(); | |||
@DataField(order=3, primitiveType=PrimitiveType.TEXT) | |||
String getEvent(); | |||
@DataField(order=4, primitiveType=PrimitiveType.BYTES) | |||
byte[] getArgs(); | |||
} | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.utils.Bytes; | |||
/** | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code = DataCodes.TX_OP_CONTRACT_EVENT_SEND) | |||
public interface ContractEventSendOperation extends Operation { | |||
/** | |||
* 响应事件的合约地址; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 2, primitiveType = PrimitiveType.BYTES) | |||
Bytes getContractAddress(); | |||
/** | |||
* 事件名; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 3, primitiveType = PrimitiveType.TEXT) | |||
String getEvent(); | |||
/** | |||
* 事件参数; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 4, primitiveType = PrimitiveType.BYTES) | |||
byte[] getArgs(); | |||
/** | |||
* 时间戳; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 5, primitiveType = PrimitiveType.INT64) | |||
long getTs(); | |||
} |
@@ -1,12 +0,0 @@ | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
public interface CryptoProviderInfo { | |||
String getName(); | |||
CryptoAlgorithm[] getAlgorithms(); | |||
} |
@@ -4,6 +4,7 @@ import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
/** | |||
* 默克尔树算法相关的配置; | |||
@@ -14,6 +15,16 @@ import com.jd.blockchain.consts.DataCodes; | |||
@DataContract(code = DataCodes.METADATA_CRYPTO_SETTING) | |||
public interface CryptoSetting { | |||
/** | |||
* 系统支持的密码服务提供者; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 0, refContract = true, list = true) | |||
public CryptoProvider[] getSupportedProviders(); | |||
/** | |||
* 系统中使用的 Hash 算法; <br> | |||
* | |||
@@ -27,7 +38,7 @@ public interface CryptoSetting { | |||
public short getHashAlgorithm(); | |||
/** | |||
* 当有完整性证明的数据被从持久化介质中加载时,是否对其进行完整性校验(重新计算 hash 比对是否一致); <br> | |||
* 当有加载附带哈希摘要的数据时,是否重新计算哈希摘要进行完整性校验; <br> | |||
* | |||
* 如果为 true ,则自动进行校验,如果校验失败,会引发异常; <br> | |||
* | |||
@@ -37,5 +48,6 @@ public interface CryptoSetting { | |||
*/ | |||
@DataField(order = 2, primitiveType = PrimitiveType.BOOLEAN) | |||
public boolean getAutoVerifyHash(); | |||
} |
@@ -0,0 +1,26 @@ | |||
package com.jd.blockchain.ledger; | |||
/** | |||
* @author zhaogw | |||
* date 2019/5/14 14:17 | |||
*/ | |||
public class KVDataVO { | |||
private String key; | |||
private long[] version; | |||
public String getKey() { | |||
return key; | |||
} | |||
public void setKey(String key) { | |||
this.key = key; | |||
} | |||
public long[] getVersion() { | |||
return version; | |||
} | |||
public void setVersion(long[] version) { | |||
this.version = version; | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
package com.jd.blockchain.ledger; | |||
/** | |||
* for BlockBrowserController.java, param is json ,then match it; | |||
* @author zhaogw | |||
* date 2019/5/14 14:19 | |||
*/ | |||
public class KVInfoVO { | |||
private KVDataVO[] data; | |||
public KVDataVO[] getData() { | |||
return data; | |||
} | |||
public void setData(KVDataVO[] data) { | |||
this.data = data; | |||
} | |||
} |
@@ -22,6 +22,7 @@ public interface ParticipantNode {// extends ConsensusNode, ParticipantInfo { | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 0, primitiveType = PrimitiveType.INT32) | |||
int getId(); | |||
/** | |||
@@ -1,21 +1,21 @@ | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
/** | |||
* 交易内容; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code= DataCodes.TX_CONTENT) | |||
public interface TransactionContent extends TransactionContentBody, HashObject { | |||
@Override | |||
@DataField(order=1, primitiveType = PrimitiveType.BYTES) | |||
HashDigest getHash(); | |||
} | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
/** | |||
* 交易内容; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code= DataCodes.TX_CONTENT) | |||
public interface TransactionContent extends TransactionContentBody, HashObject { | |||
@Override | |||
@DataField(order=1, primitiveType = PrimitiveType.BYTES) | |||
HashDigest getHash(); | |||
} |
@@ -1,36 +1,36 @@ | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
/** | |||
* 交易内容; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code = DataCodes.TX_CONTENT_BODY) | |||
public interface TransactionContentBody { | |||
/** | |||
* 执行交易的账本地址; | |||
* | |||
* 注:除了账本的创世交易之外,任何交易的账本地址都不允许为 null; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||
HashDigest getLedgerHash(); | |||
/** | |||
* 操作列表; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 2, list = true, refContract = true, genericContract = true) | |||
Operation[] getOperations(); | |||
} | |||
package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
/** | |||
* 交易内容; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code = DataCodes.TX_CONTENT_BODY) | |||
public interface TransactionContentBody { | |||
/** | |||
* 执行交易的账本地址; | |||
* | |||
* 注:除了账本的创世交易之外,任何交易的账本地址都不允许为 null; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||
HashDigest getLedgerHash(); | |||
/** | |||
* 操作列表; | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 2, list = true, refContract = true, genericContract = true) | |||
Operation[] getOperations(); | |||
} |
@@ -261,6 +261,8 @@ public interface BlockchainQueryService { | |||
*/ | |||
KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, String... keys); | |||
KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO); | |||
/** | |||
* 返回指定数据账户中KV数据的总数; <br> | |||
* | |||
@@ -1,40 +1,50 @@ | |||
package com.jd.blockchain.transaction; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.ledger.ContractEventSendOperation; | |||
import com.jd.blockchain.utils.Bytes; | |||
public class ContractEventSendOpTemplate implements ContractEventSendOperation { | |||
static { | |||
DataContractRegistry.register(ContractEventSendOperation.class); | |||
} | |||
private Bytes contractAddress; | |||
private byte[] args; | |||
private String event; | |||
public ContractEventSendOpTemplate() { | |||
} | |||
public ContractEventSendOpTemplate(Bytes contractAddress, String event, byte[] args) { | |||
this.contractAddress = contractAddress; | |||
this.event = event; | |||
this.args = args; | |||
} | |||
@Override | |||
public Bytes getContractAddress() { | |||
return contractAddress; | |||
} | |||
@Override | |||
public String getEvent() { | |||
return event; | |||
} | |||
@Override | |||
public byte[] getArgs() { | |||
return args; | |||
} | |||
} | |||
package com.jd.blockchain.transaction; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.ledger.ContractEventSendOperation; | |||
import com.jd.blockchain.utils.Bytes; | |||
public class ContractEventSendOpTemplate implements ContractEventSendOperation { | |||
static { | |||
DataContractRegistry.register(ContractEventSendOperation.class); | |||
} | |||
private Bytes contractAddress; | |||
private byte[] args; | |||
private String event; | |||
private long ts; | |||
public ContractEventSendOpTemplate() { | |||
} | |||
public ContractEventSendOpTemplate(Bytes contractAddress, String event, byte[] args) { | |||
this.contractAddress = contractAddress; | |||
this.event = event; | |||
this.args = args; | |||
} | |||
@Override | |||
public Bytes getContractAddress() { | |||
return contractAddress; | |||
} | |||
@Override | |||
public String getEvent() { | |||
return event; | |||
} | |||
@Override | |||
public byte[] getArgs() { | |||
return args; | |||
} | |||
@Override | |||
public long getTs() { | |||
return ts; | |||
} | |||
public void setTs(long ts) { | |||
this.ts = ts; | |||
} | |||
} |
@@ -4,18 +4,19 @@ import com.jd.blockchain.ledger.ContractEventSendOperation; | |||
import com.jd.blockchain.utils.Bytes; | |||
@Deprecated | |||
class ContractEventSendOperationBuilderImpl implements ContractEventSendOperationBuilder{ | |||
class ContractEventSendOperationBuilderImpl implements ContractEventSendOperationBuilder { | |||
@Override | |||
public ContractEventSendOperation send(String address, String event, byte[] args) { | |||
ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(Bytes.fromBase58(address), event, args); | |||
op.setTs(System.currentTimeMillis()); | |||
return op; | |||
} | |||
@Override | |||
public ContractEventSendOperation send(Bytes address, String event, byte[] args) { | |||
ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args); | |||
op.setTs(System.currentTimeMillis()); | |||
return op; | |||
} | |||
@@ -1,22 +1,53 @@ | |||
package com.jd.blockchain.transaction; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.serialize.binary.BinarySerializeUtils; | |||
import java.lang.reflect.InvocationHandler; | |||
import java.lang.reflect.Method; | |||
public class ContractInvocationProxy implements InvocationHandler { | |||
private String contractMessage; | |||
public class ContractInvocationProxy implements InvocationHandler { | |||
// private String contractMessage; | |||
private Bytes contractAddress; | |||
private ContractType contractType; | |||
private ContractEventSendOperationBuilder sendOpBuilder; | |||
public ContractInvocationProxy(Bytes contractAddress, ContractType contractType, | |||
ContractEventSendOperationBuilder sendOpBuilder) { | |||
this.contractAddress = contractAddress; | |||
this.contractType = contractType; | |||
this.sendOpBuilder = sendOpBuilder; | |||
} | |||
@Override | |||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { | |||
// TODO Auto-generated method stub | |||
if(contractType == null){ | |||
return "contractType == null, no invoke really."; | |||
} | |||
String event = contractType.getEvent(method); | |||
if (event == null) { | |||
// 适配 Object 对象的方法; | |||
// toString 方法; | |||
return String.format("[%s]-%s", contractAddress, contractType.toString()); | |||
// hashCode 方法; | |||
} | |||
// 合约方法; | |||
byte[] argBytes = serializeArgs(args); | |||
sendOpBuilder.send(contractAddress, event, argBytes); | |||
// TODO: 暂时未考虑有返回值的情况; | |||
return null; | |||
} | |||
private byte[] serializeArgs(Object[] args) { | |||
// TODO 根据方法参数的定义序列化参数; | |||
return BinarySerializeUtils.serialize(args); | |||
} | |||
} |
@@ -49,7 +49,7 @@ public class DataAccountKVSetOpTemplate implements DataAccountKVSetOperation { | |||
public void set(String key, BytesValue value, long expVersion) { | |||
if (kvset.containsKey(key)) { | |||
throw new IllegalArgumentException("Cann't set the same key repeatly!"); | |||
throw new IllegalArgumentException("Cann't set the same key repeatedly!"); | |||
} | |||
KVData kvdata = new KVData(key, value, expVersion); | |||
kvset.put(key, kvdata); | |||
@@ -57,7 +57,7 @@ public class DataAccountKVSetOpTemplate implements DataAccountKVSetOperation { | |||
public void set(KVData kvData) { | |||
if (kvset.containsKey(kvData.getKey())) { | |||
throw new IllegalArgumentException("Cann't set the same key repeatly!"); | |||
throw new IllegalArgumentException("Cann't set the same key repeatedly!"); | |||
} | |||
kvset.put(kvData.getKey(), kvData); | |||
} | |||
@@ -1,93 +1,93 @@ | |||
package com.jd.blockchain.transaction; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.TransactionBuilder; | |||
import com.jd.blockchain.ledger.TransactionContent; | |||
import com.jd.blockchain.ledger.TransactionContentBody; | |||
import com.jd.blockchain.ledger.TransactionRequestBuilder; | |||
import com.jd.blockchain.utils.Bytes; | |||
public class TxBuilder implements TransactionBuilder { | |||
static { | |||
DataContractRegistry.register(TransactionContentBody.class); | |||
} | |||
private BlockchainOperationFactory opFactory = new BlockchainOperationFactory(); | |||
private static final String DEFAULT_HASH_ALGORITHM = "SHA256"; | |||
private HashDigest ledgerHash; | |||
public TxBuilder(HashDigest ledgerHash) { | |||
this.ledgerHash = ledgerHash; | |||
} | |||
@Override | |||
public HashDigest getLedgerHash() { | |||
return ledgerHash; | |||
} | |||
@Override | |||
public TransactionRequestBuilder prepareRequest() { | |||
TransactionContent txContent = prepareContent(); | |||
return new TxRequestBuilder(txContent); | |||
} | |||
@Override | |||
public TransactionContent prepareContent() { | |||
TxContentBlob txContent = new TxContentBlob(ledgerHash); | |||
txContent.addOperations(opFactory.getOperations()); | |||
byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); | |||
HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); | |||
txContent.setHash(contentHash); | |||
return txContent; | |||
} | |||
@Override | |||
public LedgerInitOperationBuilder ledgers() { | |||
return opFactory.ledgers(); | |||
} | |||
@Override | |||
public UserRegisterOperationBuilder users() { | |||
return opFactory.users(); | |||
} | |||
@Override | |||
public DataAccountRegisterOperationBuilder dataAccounts() { | |||
return opFactory.dataAccounts(); | |||
} | |||
@Override | |||
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) { | |||
return opFactory.dataAccount(accountAddress); | |||
} | |||
@Override | |||
public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) { | |||
return opFactory.dataAccount(accountAddress); | |||
} | |||
@Override | |||
public ContractCodeDeployOperationBuilder contracts() { | |||
return opFactory.contracts(); | |||
} | |||
@Override | |||
public ContractEventSendOperationBuilder contractEvents() { | |||
return opFactory.contractEvents(); | |||
} | |||
@Override | |||
public <T> T contract(String address, Class<T> contractIntf) { | |||
// TODO Auto-generated method stub | |||
throw new IllegalStateException("Not implemented."); | |||
} | |||
} | |||
package com.jd.blockchain.transaction; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.TransactionBuilder; | |||
import com.jd.blockchain.ledger.TransactionContent; | |||
import com.jd.blockchain.ledger.TransactionContentBody; | |||
import com.jd.blockchain.ledger.TransactionRequestBuilder; | |||
import com.jd.blockchain.utils.Bytes; | |||
public class TxBuilder implements TransactionBuilder { | |||
static { | |||
DataContractRegistry.register(TransactionContentBody.class); | |||
} | |||
private BlockchainOperationFactory opFactory = new BlockchainOperationFactory(); | |||
private static final String DEFAULT_HASH_ALGORITHM = "SHA256"; | |||
private HashDigest ledgerHash; | |||
public TxBuilder(HashDigest ledgerHash) { | |||
this.ledgerHash = ledgerHash; | |||
} | |||
@Override | |||
public HashDigest getLedgerHash() { | |||
return ledgerHash; | |||
} | |||
@Override | |||
public TransactionRequestBuilder prepareRequest() { | |||
TransactionContent txContent = prepareContent(); | |||
return new TxRequestBuilder(txContent); | |||
} | |||
@Override | |||
public TransactionContent prepareContent() { | |||
TxContentBlob txContent = new TxContentBlob(ledgerHash); | |||
txContent.addOperations(opFactory.getOperations()); | |||
byte[] contentBodyBytes = BinaryProtocol.encode(txContent, TransactionContentBody.class); | |||
HashDigest contentHash = Crypto.getHashFunction(DEFAULT_HASH_ALGORITHM).hash(contentBodyBytes); | |||
txContent.setHash(contentHash); | |||
return txContent; | |||
} | |||
@Override | |||
public LedgerInitOperationBuilder ledgers() { | |||
return opFactory.ledgers(); | |||
} | |||
@Override | |||
public UserRegisterOperationBuilder users() { | |||
return opFactory.users(); | |||
} | |||
@Override | |||
public DataAccountRegisterOperationBuilder dataAccounts() { | |||
return opFactory.dataAccounts(); | |||
} | |||
@Override | |||
public DataAccountKVSetOperationBuilder dataAccount(String accountAddress) { | |||
return opFactory.dataAccount(accountAddress); | |||
} | |||
@Override | |||
public DataAccountKVSetOperationBuilder dataAccount(Bytes accountAddress) { | |||
return opFactory.dataAccount(accountAddress); | |||
} | |||
@Override | |||
public ContractCodeDeployOperationBuilder contracts() { | |||
return opFactory.contracts(); | |||
} | |||
@Override | |||
public ContractEventSendOperationBuilder contractEvents() { | |||
return opFactory.contractEvents(); | |||
} | |||
@Override | |||
public <T> T contract(String address, Class<T> contractIntf) { | |||
// TODO Auto-generated method stub | |||
throw new IllegalStateException("Not implemented."); | |||
} | |||
} |
@@ -1,91 +1,91 @@ | |||
package com.jd.blockchain.transaction; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.Operation; | |||
import com.jd.blockchain.ledger.TransactionContent; | |||
import com.jd.blockchain.utils.io.NumberMask; | |||
/** | |||
* 交易内容的数据块; | |||
* <p> | |||
* | |||
* 包含原始交易请求的数据块; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
public class TxContentBlob implements TransactionContent { | |||
/** | |||
* 操作数量的最大值; | |||
*/ | |||
public static final int MAX_OP_COUNT = NumberMask.SHORT.MAX_BOUNDARY_SIZE; | |||
private List<Operation> operationList = new ArrayList<Operation>(); | |||
private HashDigest hash; | |||
private HashDigest ledgerHash; | |||
public TxContentBlob(HashDigest ledgerHash) { | |||
this.ledgerHash = ledgerHash; | |||
} | |||
/** | |||
* 交易内容的哈希值; | |||
*/ | |||
@Override | |||
public HashDigest getHash() { | |||
return this.hash; | |||
} | |||
/** | |||
* 更新交易内容的哈希值; | |||
* <p> | |||
* 注:当前对象只充当值对象,不校验指定哈希值的完整性,调用者应该在外部实施完整性校验; | |||
* | |||
* @param hash | |||
*/ | |||
public void setHash(HashDigest hash) { | |||
this.hash = hash; | |||
} | |||
/** | |||
* 交易请求链的hash | |||
* | |||
* @return | |||
*/ | |||
@Override | |||
public HashDigest getLedgerHash() { | |||
return ledgerHash; | |||
} | |||
public void setLedgerHash(HashDigest ledgerHash) { | |||
this.ledgerHash = ledgerHash; | |||
} | |||
@Override | |||
public Operation[] getOperations() { | |||
return operationList.toArray(new Operation[operationList.size()]); | |||
} | |||
public void setOperations(Object[] operations) { | |||
// in array's case ,cast will failed! | |||
for (Object operation : operations) { | |||
Operation op = (Operation) operation; | |||
addOperation(op); | |||
} | |||
} | |||
public void addOperation(Operation operation) { | |||
operationList.add(operation); | |||
} | |||
public void addOperations(Collection<Operation> operations) { | |||
operationList.addAll(operations); | |||
} | |||
} | |||
package com.jd.blockchain.transaction; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.Operation; | |||
import com.jd.blockchain.ledger.TransactionContent; | |||
import com.jd.blockchain.utils.io.NumberMask; | |||
/** | |||
* 交易内容的数据块; | |||
* <p> | |||
* | |||
* 包含原始交易请求的数据块; | |||
* | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
public class TxContentBlob implements TransactionContent { | |||
/** | |||
* 操作数量的最大值; | |||
*/ | |||
public static final int MAX_OP_COUNT = NumberMask.SHORT.MAX_BOUNDARY_SIZE; | |||
private List<Operation> operationList = new ArrayList<Operation>(); | |||
private HashDigest hash; | |||
private HashDigest ledgerHash; | |||
public TxContentBlob(HashDigest ledgerHash) { | |||
this.ledgerHash = ledgerHash; | |||
} | |||
/** | |||
* 交易内容的哈希值; | |||
*/ | |||
@Override | |||
public HashDigest getHash() { | |||
return this.hash; | |||
} | |||
/** | |||
* 更新交易内容的哈希值; | |||
* <p> | |||
* 注:当前对象只充当值对象,不校验指定哈希值的完整性,调用者应该在外部实施完整性校验; | |||
* | |||
* @param hash | |||
*/ | |||
public void setHash(HashDigest hash) { | |||
this.hash = hash; | |||
} | |||
/** | |||
* 交易请求链的hash | |||
* | |||
* @return | |||
*/ | |||
@Override | |||
public HashDigest getLedgerHash() { | |||
return ledgerHash; | |||
} | |||
public void setLedgerHash(HashDigest ledgerHash) { | |||
this.ledgerHash = ledgerHash; | |||
} | |||
@Override | |||
public Operation[] getOperations() { | |||
return operationList.toArray(new Operation[operationList.size()]); | |||
} | |||
public void setOperations(Object[] operations) { | |||
// in array's case ,cast will failed! | |||
for (Object operation : operations) { | |||
Operation op = (Operation) operation; | |||
addOperation(op); | |||
} | |||
} | |||
public void addOperation(Operation operation) { | |||
operationList.add(operation); | |||
} | |||
public void addOperations(Collection<Operation> operations) { | |||
operationList.addAll(operations); | |||
} | |||
} |
@@ -20,11 +20,6 @@ | |||
<artifactId>consensus-framework</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>state-transfer</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>ledger-rpc</artifactId> | |||
@@ -4,8 +4,6 @@ import com.jd.blockchain.consensus.service.NodeServer; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
import java.util.List; | |||
public interface LedgerBindingConfigAware { | |||
void setConfig(LedgerBindingConfig config); | |||
@@ -1,21 +1,30 @@ | |||
package com.jd.blockchain.peer.web; | |||
import com.jd.blockchain.contract.ContractException; | |||
import com.jd.blockchain.ledger.*; | |||
import com.jd.blockchain.ledger.core.*; | |||
import com.jd.blockchain.utils.StringUtils; | |||
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.RequestParam; | |||
import org.springframework.web.bind.annotation.RestController; | |||
import org.springframework.web.bind.annotation.*; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.core.ContractAccountSet; | |||
import com.jd.blockchain.ledger.core.DataAccount; | |||
import com.jd.blockchain.ledger.core.DataAccountSet; | |||
import com.jd.blockchain.ledger.core.LedgerAdministration; | |||
import com.jd.blockchain.ledger.core.LedgerRepository; | |||
import com.jd.blockchain.ledger.core.LedgerService; | |||
import com.jd.blockchain.ledger.core.ParticipantCertData; | |||
import com.jd.blockchain.ledger.core.TransactionSet; | |||
import com.jd.blockchain.ledger.core.UserAccountSet; | |||
import com.jd.blockchain.transaction.BlockchainQueryService; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.QueryUtil; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
@RestController | |||
@RequestMapping(path = "/") | |||
public class LedgerQueryController implements BlockchainQueryService { | |||
@@ -342,6 +351,63 @@ public class LedgerQueryController implements BlockchainQueryService { | |||
return entries; | |||
} | |||
@RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/{address}/entries-version") | |||
@Override | |||
public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, | |||
@PathVariable(name = "address") String address, | |||
@RequestBody KVInfoVO kvInfoVO) { | |||
//parse kvInfoVO; | |||
List<String> keyList = new ArrayList<>(); | |||
List<Long> versionList = new ArrayList<>(); | |||
if(kvInfoVO != null){ | |||
for(KVDataVO kvDataVO : kvInfoVO.getData()){ | |||
for(Long version : kvDataVO.getVersion()){ | |||
keyList.add(kvDataVO.getKey()); | |||
versionList.add(version); | |||
} | |||
} | |||
} | |||
String[] keys = keyList.toArray(new String[keyList.size()]); | |||
Long[] versions = versionList.toArray(new Long[versionList.size()]); | |||
if (keys == null || keys.length == 0) { | |||
return null; | |||
} | |||
if (versions == null || versions.length == 0) { | |||
return null; | |||
} | |||
if(keys.length != versions.length){ | |||
throw new ContractException("keys.length!=versions.length!"); | |||
} | |||
LedgerRepository ledger = ledgerService.getLedger(ledgerHash); | |||
LedgerBlock block = ledger.getLatestBlock(); | |||
DataAccountSet dataAccountSet = ledger.getDataAccountSet(block); | |||
DataAccount dataAccount = dataAccountSet.getDataAccount(Bytes.fromBase58(address)); | |||
KVDataEntry[] entries = new KVDataEntry[keys.length]; | |||
long ver = -1; | |||
for (int i = 0; i < entries.length; i++) { | |||
// ver = dataAccount.getDataVersion(Bytes.fromString(keys[i])); | |||
ver = versions[i]; | |||
if (ver < 0) { | |||
entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); | |||
}else { | |||
if(dataAccount.getDataEntriesTotalCount()==0 || | |||
dataAccount.getBytes(Bytes.fromString(keys[i]), ver) == null){ | |||
//is the address is not exist; the result is null; | |||
entries[i] = new KVDataObject(keys[i], -1, PrimitiveType.NIL, null); | |||
} else { | |||
byte[] value = dataAccount.getBytes(Bytes.fromString(keys[i]), ver); | |||
BytesValue decodeData = BinaryProtocol.decode(value); | |||
entries[i] = new KVDataObject(keys[i], ver, PrimitiveType.valueOf(decodeData.getType().CODE), decodeData.getValue().toBytes()); | |||
} | |||
} | |||
} | |||
return entries; | |||
} | |||
@RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") | |||
@Override | |||
public KVDataEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, | |||
@@ -5,10 +5,6 @@ import java.util.List; | |||
import java.util.Map; | |||
import java.util.concurrent.ConcurrentHashMap; | |||
import javax.annotation.PostConstruct; | |||
import javax.annotation.PreDestroy; | |||
import com.jd.blockchain.ledger.*; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
@@ -35,6 +31,21 @@ import com.jd.blockchain.consensus.service.NodeServer; | |||
import com.jd.blockchain.consensus.service.ServerSettings; | |||
import com.jd.blockchain.consensus.service.StateMachineReplicate; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.ContractCodeDeployOperation; | |||
import com.jd.blockchain.ledger.ContractEventSendOperation; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.DataAccountKVSetOperation; | |||
import com.jd.blockchain.ledger.DataAccountRegisterOperation; | |||
import com.jd.blockchain.ledger.EndpointRequest; | |||
import com.jd.blockchain.ledger.LedgerBlock; | |||
import com.jd.blockchain.ledger.LedgerInitOperation; | |||
import com.jd.blockchain.ledger.NodeRequest; | |||
import com.jd.blockchain.ledger.Operation; | |||
import com.jd.blockchain.ledger.TransactionContent; | |||
import com.jd.blockchain.ledger.TransactionContentBody; | |||
import com.jd.blockchain.ledger.TransactionRequest; | |||
import com.jd.blockchain.ledger.TransactionResponse; | |||
import com.jd.blockchain.ledger.UserRegisterOperation; | |||
import com.jd.blockchain.ledger.core.LedgerAdminAccount; | |||
import com.jd.blockchain.ledger.core.LedgerManage; | |||
import com.jd.blockchain.ledger.core.LedgerRepository; | |||
@@ -68,35 +79,17 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag | |||
public static final int MIN_GATEWAY_ID = 10000; | |||
// @Autowired | |||
// private PeerSettings peerSetting; | |||
// @Autowired | |||
// private ConsensusTransactionService consensusService; | |||
// private ConsensusPeer consensusReplica; | |||
@Autowired | |||
private LedgerManage ledgerManager; | |||
@Autowired | |||
private DbConnectionFactory connFactory; | |||
// private Map<HashDigest, DbConnection> ledgerConns = new | |||
// ConcurrentHashMap<>(); | |||
private Map<HashDigest, MsgQueueMessageDispatcher> ledgerTxConverters = new ConcurrentHashMap<>(); | |||
private Map<HashDigest, NodeServer> ledgerPeers = new ConcurrentHashMap<>(); | |||
private Map<HashDigest, CryptoSetting> ledgerCryptoSettings = new ConcurrentHashMap<>(); | |||
// private Map<ConsensusNode, ConsensusRealm> nodeRealms = new | |||
// ConcurrentHashMap<>(); | |||
// private Map<HashDigest, ConsensusRealm> ledgerRealms = new | |||
// ConcurrentHashMap<>(); | |||
// private Map<HashDigest, ConsensusRealm> ledgerRealmsNoConflict = new | |||
// ConcurrentHashMap<>(); | |||
private LedgerBindingConfig config; | |||
@@ -106,9 +99,6 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag | |||
@Autowired | |||
private StateMachineReplicate consensusStateManager; | |||
// private static int step = 0; | |||
// private static int temp = 0; | |||
static { | |||
DataContractRegistry.register(LedgerInitOperation.class); | |||
DataContractRegistry.register(LedgerBlock.class); | |||
@@ -134,24 +124,6 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag | |||
} | |||
@PostConstruct | |||
private void init() { | |||
} | |||
@PreDestroy | |||
private void destroy() { | |||
// DbConnection[] conns = ledgerConns.values().toArray(new DbConnection[ledgerConns.size()]); | |||
// ledgerConns.clear(); | |||
// for (DbConnection conn : conns) { | |||
// try { | |||
// conn.close(); | |||
// } catch (Exception e) { | |||
// // Ignore; | |||
// } | |||
// } | |||
} | |||
/** | |||
* 接入认证; | |||
* | |||
@@ -234,42 +206,8 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag | |||
HashDigest[] ledgerHashs = config.getLedgerHashs(); | |||
for (HashDigest ledgerHash : ledgerHashs) { | |||
setConfig(config,ledgerHash); | |||
// LedgerBindingConfig.BindingConfig bindingConfig = config.getLedger(ledgerHash); | |||
// DbConnection dbConnNew = connFactory.connect(bindingConfig.getDbConnection().getUri(), | |||
// bindingConfig.getDbConnection().getPassword()); | |||
// LedgerRepository ledgerRepository = ledgerManager.register(ledgerHash, dbConnNew.getStorageService()); | |||
// | |||
// // load provider; | |||
// LedgerAdminAccount ledgerAdminAccount = ledgerRepository.getAdminAccount(); | |||
// String consensusProvider = ledgerAdminAccount.getSetting().getConsensusProvider(); | |||
// ConsensusProvider provider = ConsensusProviders.getProvider(consensusProvider); | |||
// // find current node; | |||
// Bytes csSettingBytes = ledgerAdminAccount.getSetting().getConsensusSetting(); | |||
// ConsensusSettings csSettings = provider.getSettingsFactory().getConsensusSettingsEncoder() | |||
// .decode(csSettingBytes.toBytes()); | |||
// NodeSettings currentNode = null; | |||
// for (NodeSettings nodeSettings : csSettings.getNodes()) { | |||
// if (nodeSettings.getAddress().equals(bindingConfig.getParticipant().getAddress())) { | |||
// currentNode = nodeSettings; | |||
// } | |||
// } | |||
// if (currentNode == null) { | |||
// throw new IllegalArgumentException( | |||
// "Current node is not found from the consensus settings of ledger[" + ledgerHash.toBase58() | |||
// + "]!"); | |||
// } | |||
// ServerSettings serverSettings = provider.getServerFactory().buildServerSettings(ledgerHash.toBase58(), csSettings, currentNode.getAddress()); | |||
// | |||
// NodeServer server = provider.getServerFactory().setupServer(serverSettings, consensusMessageHandler, | |||
// consensusStateManager); | |||
// ledgerPeers.put(ledgerHash, server); | |||
// ledgerCryptoSettings.put(ledgerHash, ledgerAdminAccount.getSetting().getCryptoSetting()); | |||
} | |||
// remove duplicate consensus realm,and establish consensus peer and consensus | |||
// realm corresponding relationship | |||
// initBindingConfig(config); | |||
this.config = config; | |||
} catch (Exception e) { | |||
@@ -314,46 +252,6 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag | |||
return server; | |||
} | |||
// private void initBindingConfig(LedgerBindingConfig config) { | |||
// boolean intersection = false; | |||
// // to remove intersection consensus realm | |||
// for (HashDigest hashDigest : ledgerRealms.keySet()) { | |||
// ConsensusRealm consensusRealm1i = ledgerRealms.get(hashDigest); | |||
// for (ConsensusRealm consensusRealm1j : ledgerRealms.values()) { | |||
// // avoid compare with myself | |||
// if (consensusRealm1i.equals(consensusRealm1j)) { | |||
// continue; | |||
// } | |||
// if (consensusRealm1i.hasIntersection(consensusRealm1j)) { | |||
// intersection = true; | |||
// break; | |||
// } | |||
// } | |||
// // prompt consensus realm conflict info | |||
// if (intersection == true) { | |||
// ConsoleUtils.info("\r\nconsensus realm intersection with other consensus | |||
// realm\r\n"); | |||
// continue; | |||
// } | |||
// if (intersection == false) { | |||
// // add consensus realm without conflict to ledgerRealmsNoConflict | |||
// ledgerRealmsNoConflict.put(hashDigest, consensusRealm1i); | |||
// | |||
// // String consensusSystemFile = | |||
// config.getLedger(hashDigest).getCsConfigFile(); | |||
// int currentId = config.getLedger(hashDigest).getParticipant().getId(); | |||
// // init consensusSystemConfig; | |||
// ConsensusProperties csProps = | |||
// ConsensusProperties.resolve(consensusRealm1i.getSetting()); | |||
// ConsensusPeer consensusPeer = new ConsensusPeer(consensusRealm1i, currentId, | |||
// consensusService, | |||
// csProps.getProperties()); | |||
// ledgerPeers.put(hashDigest, consensusPeer); | |||
// } | |||
// } // END OF FOR:get ledgerRealmsNoConflict and ledgerPeers | |||
// | |||
// } | |||
@Override | |||
public ConsensusRealm[] getRealms() { | |||
throw new IllegalStateException("Not implemented!"); | |||
@@ -364,45 +262,6 @@ public class ManagementController implements LedgerBindingConfigAware, PeerManag | |||
for (NodeServer peer : ledgerPeers.values()) { | |||
runRealm(peer); | |||
} | |||
// try { | |||
// | |||
// // for (ConsensusPeer peer : ledgerPeers.values()) { | |||
// for (Map.Entry<HashDigest, ConsensusPeer> entry : ledgerPeers.entrySet()) { | |||
// HashDigest ledgerHash = entry.getKey(); | |||
// ConsensusPeer peer = entry.getValue(); | |||
// // TODO: 多线程启动; | |||
// ConsensusNode[] nodes = peer.getConsensusRealm().getNodes(); | |||
// StringBuilder consensusInfo = new StringBuilder(); | |||
// for (ConsensusNode node : nodes) { | |||
// consensusInfo.append( | |||
// String.format("[%s]-%s; ", node.getAddress(), | |||
// node.getConsensusAddress().toString())); | |||
// } | |||
// LOGGER.debug(String.format("-------- start consensus peer[Id=%s] --Nodes=%s | |||
// -------------", | |||
// peer.getCurrentId(), consensusInfo.toString())); | |||
// peer.start(); | |||
// // 设置消息队列 | |||
// MsgQueueMessageDispatcher messageDispatcher = ledgerTxConverters.get(ledgerHash); | |||
// | |||
// if (messageDispatcher == null) { | |||
// LedgerBindingConfig.BindingConfig bindingConfig = | |||
// this.config.getLedger(ledgerHash); | |||
// MQConnectionConfig mqConnection = bindingConfig.getMqConnection(); | |||
// if (mqConnection != null && mqConnection.getServer() != null) { | |||
// MessageQueueConfig mqConfig = new | |||
// MessageQueueConfig(mqConnection.getServer(), | |||
// mqConnection.getTopic()); | |||
// messageDispatcher = MessageDispatcherFactory.newInstance(mqConfig, peer); | |||
// Executors.newSingleThreadExecutor().execute(messageDispatcher); // 启动监听 | |||
// } | |||
// } | |||
// } | |||
// } catch (Exception e) { | |||
// LOGGER.error("Error occurred on starting all consensus realms! --" + | |||
// e.getMessage(), e); | |||
// throw new IllegalStateException(e.getMessage(), e); | |||
// } | |||
} | |||
@Override | |||
@@ -15,11 +15,11 @@ import com.jd.blockchain.peer.ConsensusManage; | |||
import com.jd.blockchain.peer.LedgerBindingConfigAware; | |||
import com.jd.blockchain.peer.PeerServerBooter; | |||
import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
import com.jd.blockchain.utils.ArgumentSet; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.beans.BeansException; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.boot.CommandLineRunner; | |||
import org.springframework.context.ApplicationContext; | |||
import org.springframework.context.ApplicationContextAware; | |||
import org.springframework.core.io.ClassPathResource; | |||
@@ -38,9 +38,11 @@ import java.util.*; | |||
* @since 1.0.0 | |||
*/ | |||
@Component | |||
//@EnableScheduling | |||
@EnableScheduling | |||
public class PeerTimeTasks implements ApplicationContextAware { | |||
private static Logger LOGGER = LoggerFactory.getLogger(PeerTimeTasks.class); | |||
private ApplicationContext applicationContext; | |||
@Autowired | |||
@@ -51,7 +53,9 @@ public class PeerTimeTasks implements ApplicationContextAware { | |||
//每1分钟执行一次 | |||
@Scheduled(cron = "0 */5 * * * * ") | |||
public void updateLedger(){ | |||
System.out.println ("Update Ledger Tasks Start " + new Date()); | |||
LOGGER.debug("Time Task Update Ledger Tasks Start {}", new Date()); | |||
try { | |||
LedgerBindingConfig ledgerBindingConfig = loadLedgerBindingConfig(); | |||
@@ -78,7 +82,8 @@ public class PeerTimeTasks implements ApplicationContextAware { | |||
Map<String, LedgerBindingConfigAware> bindingConfigAwares = applicationContext.getBeansOfType(LedgerBindingConfigAware.class); | |||
List<NodeServer> nodeServers = new ArrayList<>(); | |||
for (HashDigest ledgerHash : newAddHashs) { | |||
System.out.printf("newLedger[%s] \r\n", ledgerHash.toBase58()); | |||
LOGGER.info("New Ledger [{}] Need To Be Init !!!", ledgerHash.toBase58()); | |||
for (LedgerBindingConfigAware aware : bindingConfigAwares.values()) { | |||
nodeServers.add(aware.setConfig(ledgerBindingConfig, ledgerHash)); | |||
} | |||
@@ -89,10 +94,10 @@ public class PeerTimeTasks implements ApplicationContextAware { | |||
consensusManage.runRealm(nodeServer); | |||
} | |||
} else { | |||
System.out.println("All Ledgers is newest!!!"); | |||
LOGGER.debug("All Ledgers is newest!!!"); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
LOGGER.error(e.getMessage()); | |||
} | |||
} | |||
@@ -104,7 +109,8 @@ public class PeerTimeTasks implements ApplicationContextAware { | |||
private LedgerBindingConfig loadLedgerBindingConfig() throws Exception { | |||
LedgerBindingConfig ledgerBindingConfig; | |||
ledgerBindConfigFile = PeerServerBooter.ledgerBindConfigFile; | |||
System.out.printf("load ledgerBindConfigFile = %s \r\n", ledgerBindConfigFile); | |||
LOGGER.debug("Load LedgerBindConfigFile path = {}", | |||
ledgerBindConfigFile == null ? "Default" : ledgerBindConfigFile); | |||
if (ledgerBindConfigFile == null) { | |||
ClassPathResource configResource = new ClassPathResource("ledger-binding.conf"); | |||
InputStream in = configResource.getInputStream(); | |||
@@ -34,7 +34,7 @@ public class LedgerInitSettings { | |||
/** | |||
* 共识协议 | |||
*/ | |||
private int consensusProtocol; | |||
private String consensusProtocol; | |||
/** | |||
* 共识配置 | |||
@@ -70,11 +70,11 @@ public class LedgerInitSettings { | |||
this.cryptoSetting = cryptoSetting; | |||
} | |||
public int getConsensusProtocol() { | |||
public String getConsensusProtocol() { | |||
return consensusProtocol; | |||
} | |||
public void setConsensusProtocol(int consensusProtocol) { | |||
public void setConsensusProtocol(String consensusProtocol) { | |||
this.consensusProtocol = consensusProtocol; | |||
} | |||
@@ -93,21 +93,4 @@ public class LedgerInitSettings { | |||
public void setParticipantNodes(ParticipantNode[] participantNodes) { | |||
this.participantNodes = participantNodes; | |||
} | |||
public enum CONSENSUS_PROTOCOL { | |||
UNKNOWN(0), | |||
BFTSMART(1), | |||
MSGQUEUE(2), | |||
; | |||
private int code; | |||
CONSENSUS_PROTOCOL(int code) { | |||
this.code = code; | |||
} | |||
public int code() { | |||
return code; | |||
} | |||
} | |||
} |
@@ -147,6 +147,11 @@ public abstract class BlockchainServiceProxy implements BlockchainService { | |||
return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, keys); | |||
} | |||
@Override | |||
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, KVInfoVO kvInfoVO) { | |||
return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, kvInfoVO); | |||
} | |||
@Override | |||
public KVDataEntry[] getDataEntries(HashDigest ledgerHash, String address, int fromIndex, int count) { | |||
return getQueryService(ledgerHash).getDataEntries(ledgerHash, address, fromIndex, count); | |||
@@ -496,7 +496,11 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService | |||
@PathParam(name="address") String address, | |||
@RequestParam(name="keys", array = true) String... keys); | |||
@HttpAction(method = HttpMethod.POST, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") | |||
@HttpAction(method=HttpMethod.POST, path="ledgers/{ledgerHash}/accounts/{address}/entries-version") | |||
@Override | |||
KVDataEntry[] getDataEntries(@PathParam(name="ledgerHash", converter=HashDigestToStringConverter.class) HashDigest ledgerHash, | |||
@PathParam(name="address") String address, | |||
@RequestBody KVInfoVO kvInfoVO); | |||
/** | |||
* 返回数据账户中指定序号的最新值; | |||
@@ -513,6 +517,7 @@ public interface HttpBlockchainQueryService extends BlockchainExtendQueryService | |||
* 如果参数值为 -1,则返回全部的记录;<br> | |||
* @return | |||
*/ | |||
@HttpAction(method = HttpMethod.POST, path = "ledgers/{ledgerHash}/accounts/address/{address}/entries") | |||
@Override | |||
KVDataEntry[] getDataEntries(@PathParam(name = "ledgerHash") HashDigest ledgerHash, | |||
@PathParam(name = "address") String address, | |||
@@ -15,7 +15,6 @@ | |||
<module>test-consensus-node</module> | |||
<module>test-ledger-core</module> | |||
<module>test-integration</module> | |||
<module>test-stp-community</module> | |||
</modules> | |||
<build> | |||
@@ -7,13 +7,13 @@ 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); | |||
} | |||
@@ -21,7 +21,7 @@ public class PresetAnswerPrompter extends ConsolePrompter { | |||
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)); | |||
@@ -29,7 +29,5 @@ public class PresetAnswerPrompter extends ConsolePrompter { | |||
System.out.println(String.format("\r\n [Mocked answer:%s]", answer)); | |||
return answer; | |||
} | |||
} |
@@ -215,26 +215,26 @@ public class ConsensusTest { | |||
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); | |||
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); | |||
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); | |||
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); | |||
AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, csProps, | |||
csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -354,8 +354,8 @@ public class ConsensusTest { | |||
} | |||
public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, Prompter prompter, | |||
CountDownLatch quitLatch) { | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter, CountDownLatch quitLatch) { | |||
ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
@Override | |||
@@ -364,7 +364,7 @@ public class ConsensusTest { | |||
// NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); | |||
NodeInitContext.this.dbConnConfig = dbConnConfig; | |||
HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, csProps, csProvider, | |||
HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, | |||
dbConnConfig, prompter); | |||
quitLatch.countDown(); | |||
@@ -386,8 +386,7 @@ public class ConsensusTest { | |||
@Override | |||
protected HashDigest invoke() throws Exception { | |||
LedgerInitCommand initCmd = new LedgerInitCommand(); | |||
HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, csProps, | |||
csProvider, dbConnConfig, prompter, conf, db); | |||
HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, prompter, conf, db); | |||
NodeInitContext.this.ledgerManager = initCmd.getLedgerManager(); | |||
quitLatch.countDown(); | |||
return ledgerHash; | |||
@@ -187,7 +187,7 @@ public class GlobalPerformanceTest { | |||
Properties props = Utils.loadConsensusSetting(); | |||
ConsensusProvider csProvider = getConsensusProvider(); | |||
ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
// 启动服务器; | |||
NetworkAddress initAddr0 = initSetting.getConsensusParticipant(0).getInitializerAddress(); | |||
NodeInitContext nodeCtx0 = new NodeInitContext(0, initAddr0); | |||
@@ -365,8 +365,8 @@ public class GlobalPerformanceTest { | |||
// NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); | |||
NodeInitContext.this.dbConnConfig = dbConnConfig; | |||
HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, csProps, | |||
csProvider, dbConnConfig, prompter); | |||
HashDigest ledgerHash = NodeInitContext.this.initProcess.initialize(id, privKey, setting, | |||
dbConnConfig, prompter); | |||
quitLatch.countDown(); | |||
return ledgerHash; | |||
@@ -387,8 +387,8 @@ public class GlobalPerformanceTest { | |||
@Override | |||
protected HashDigest invoke() throws Exception { | |||
LedgerInitCommand initCmd = new LedgerInitCommand(); | |||
HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, csProps, | |||
csProvider, dbConnConfig, prompter, conf, db); | |||
HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, | |||
prompter, conf, db); | |||
NodeInitContext.this.ledgerManager = initCmd.getLedgerManager(); | |||
quitLatch.countDown(); | |||
return ledgerHash; | |||
@@ -68,9 +68,6 @@ public class LedgerInitializeTest { | |||
public void testInitWith4Nodes() { | |||
Prompter consolePrompter = new PresetAnswerPrompter("N"); // new ConsolePrompter(); | |||
LedgerInitProperties initSetting = loadInitSetting(); | |||
Properties props = loadConsensusSetting(); | |||
ConsensusProvider csProvider = getConsensusProvider(); | |||
ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), | |||
serviceRegisterMap); | |||
@@ -81,31 +78,28 @@ public class LedgerInitializeTest { | |||
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"}; | |||
String[] memoryConnString = new String[] { "memory://local/0", "memory://local/1", "memory://local/2", | |||
"memory://local/3" }; | |||
PrivKey privkey0 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
testDb0.setConnectionUri(memoryConnString[0]); | |||
AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, csProps, csProvider, testDb0, | |||
consolePrompter); | |||
AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter); | |||
PrivKey privkey1 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
testDb1.setConnectionUri(memoryConnString[1]); | |||
AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, csProps, csProvider, testDb1, | |||
consolePrompter); | |||
AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter); | |||
PrivKey privkey2 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
testDb2.setConnectionUri(memoryConnString[2]); | |||
AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, csProps, csProvider, testDb2, | |||
consolePrompter); | |||
AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter); | |||
PrivKey privkey3 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
DBConnectionConfig testDb03 = new DBConnectionConfig(); | |||
testDb03.setConnectionUri(memoryConnString[3]); | |||
AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, csProps, csProvider, testDb03, | |||
consolePrompter); | |||
AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -188,23 +182,21 @@ public class LedgerInitializeTest { | |||
public NodeContext(NetworkAddress address, Map<NetworkAddress, LedgerInitConsensusService> serviceRegisterMap) { | |||
this.initCsServiceFactory = new MultiThreadInterInvokerFactory(serviceRegisterMap); | |||
LedgerInitializeWebController initController = new LedgerInitializeWebController(ledgerManager, memoryDBConnFactory, | |||
initCsServiceFactory); | |||
LedgerInitializeWebController initController = new LedgerInitializeWebController(ledgerManager, | |||
memoryDBConnFactory, initCsServiceFactory); | |||
serviceRegisterMap.put(address, initController); | |||
this.initProcess = initController; | |||
} | |||
public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter) { | |||
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, csProps, csProvider, dbConnConfig, | |||
prompter); | |||
return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
} | |||
}; | |||
@@ -212,8 +204,7 @@ public class LedgerInitializeTest { | |||
} | |||
public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter, boolean autoVerifyHash) { | |||
DBConnectionConfig dbConnConfig, Prompter prompter, boolean autoVerifyHash) { | |||
CryptoConfig cryptoSetting = new CryptoConfig(); | |||
cryptoSetting.setAutoVerifyHash(autoVerifyHash); | |||
@@ -224,8 +215,7 @@ public class LedgerInitializeTest { | |||
ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
@Override | |||
protected HashDigest invoke() throws Exception { | |||
return initProcess.initialize(currentId, privKey, setting, csProps, csProvider, dbConnConfig, | |||
prompter, cryptoSetting); | |||
return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); | |||
} | |||
}; | |||
@@ -264,23 +264,23 @@ public class LedgerInitializeWebTest { | |||
DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
testDb0.setConnectionUri("memory://local/0"); | |||
AsyncCallback<HashDigest> callback0 = node0.startInit(privkey0, initSetting, csProps, csProvider, testDb0, | |||
consolePrompter, quitLatch); | |||
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, csProps, csProvider, testDb1, | |||
consolePrompter, quitLatch); | |||
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, csProps, csProvider, testDb2, | |||
consolePrompter, quitLatch); | |||
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, csProps, csProvider, testDb03, | |||
consolePrompter, quitLatch); | |||
AsyncCallback<HashDigest> callback3 = node3.startInit(privkey3, initSetting, testDb03, consolePrompter, | |||
quitLatch); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -402,8 +402,7 @@ public class LedgerInitializeWebTest { | |||
} | |||
public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter, CountDownLatch quitLatch) { | |||
DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { | |||
ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
@Override | |||
@@ -412,8 +411,8 @@ public class LedgerInitializeWebTest { | |||
// NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); | |||
NodeWebContext.this.dbConnConfig = dbConnConfig; | |||
HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, csProps, | |||
csProvider, dbConnConfig, prompter); | |||
HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, | |||
dbConnConfig, prompter); | |||
quitLatch.countDown(); | |||
return ledgerHash; | |||
@@ -443,8 +442,8 @@ public class LedgerInitializeWebTest { | |||
@Override | |||
protected HashDigest invoke() throws Exception { | |||
LedgerInitCommand initCmd = new LedgerInitCommand(); | |||
HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, csProps, | |||
csProvider, dbConnConfig, prompter, conf, db); | |||
HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, | |||
prompter, conf, db); | |||
NodeWebContext.this.ledgerManager = initCmd.getLedgerManager(); | |||
quitLatch.countDown(); | |||
return ledgerHash; | |||
@@ -106,16 +106,14 @@ public class Utils { | |||
} | |||
public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider consensusProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter) { | |||
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, csProps, consensusProvider, dbConnConfig, | |||
prompter); | |||
return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
} | |||
}; | |||
@@ -150,8 +148,7 @@ public class Utils { | |||
ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
@Override | |||
protected HashDigest invoke() throws Exception { | |||
return initProcess.initialize(currentId, privKey, setting, csProps, consensusProvider, dbConnConfig, | |||
prompter, cryptoSetting); | |||
return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); | |||
} | |||
}; | |||
@@ -1,7 +1,16 @@ | |||
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.ConsensusProviders; | |||
import com.jd.blockchain.consensus.ConsensusSettings; | |||
import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
@@ -9,27 +18,21 @@ import com.jd.blockchain.crypto.PrivKey; | |||
import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; | |||
import com.jd.blockchain.ledger.LedgerBlock; | |||
import com.jd.blockchain.ledger.core.LedgerRepository; | |||
import com.jd.blockchain.tools.initializer.*; | |||
import com.jd.blockchain.tools.initializer.DBConnectionConfig; | |||
import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
import com.jd.blockchain.tools.initializer.LedgerInitProperties; | |||
import com.jd.blockchain.tools.initializer.Prompter; | |||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
import com.jd.blockchain.utils.net.NetworkAddress; | |||
import org.springframework.core.io.ClassPathResource; | |||
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 java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.Properties; | |||
import java.util.concurrent.CountDownLatch; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
public class IntegrationBaseTest { | |||
LedgerInitConsensusConfig.ConsensusConfig bftsmartConfig = LedgerInitConsensusConfig.bftsmartConfig; | |||
LedgerInitConsensusConfig.ConsensusConfig bftsmartConfig = LedgerInitConsensusConfig.bftsmartConfig; | |||
public IntegratedContext context = initLedgers(bftsmartConfig.getConfigPath(), bftsmartConfig.getProvider()); | |||
public GatewayTestRunner gateway0; | |||
@@ -150,26 +153,26 @@ public class IntegrationBaseTest { | |||
DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
testDb0.setConnectionUri(LedgerInitConsensusConfig.memConnectionStrings[0]); | |||
LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, | |||
csProvider, testDb0, consolePrompter, bindingConfig0, quitLatch); | |||
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, csProps, | |||
csProvider, testDb1, consolePrompter, bindingConfig1, quitLatch); | |||
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, csProps, | |||
csProvider, testDb2, consolePrompter, bindingConfig2, quitLatch); | |||
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, csProps, | |||
csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); | |||
AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, | |||
consolePrompter, bindingConfig3, quitLatch); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -57,7 +57,7 @@ public class IntegrationTest2 { | |||
public void test() { | |||
// init ledgers of all nodes ; | |||
IntegratedContext context = initLedgers(LedgerInitConsensusConfig.mqConfig, | |||
LedgerInitConsensusConfig.memConnectionStrings); | |||
LedgerInitConsensusConfig.memConnectionStrings); | |||
Node node0 = context.getNode(0); | |||
Node node1 = context.getNode(1); | |||
Node node2 = context.getNode(2); | |||
@@ -70,10 +70,10 @@ public class IntegrationTest2 { | |||
PeerTestRunner peer1 = new PeerTestRunner(peerSrvAddr1, node1.getBindingConfig(), node1.getStorageDB()); | |||
NetworkAddress peerSrvAddr2 = new NetworkAddress("127.0.0.1", 13220); | |||
PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2,node2.getBindingConfig(), node2.getStorageDB()); | |||
PeerTestRunner peer2 = new PeerTestRunner(peerSrvAddr2, node2.getBindingConfig(), node2.getStorageDB()); | |||
NetworkAddress peerSrvAddr3 = new NetworkAddress("127.0.0.1", 13230); | |||
PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3,node3.getBindingConfig(), node3.getStorageDB()); | |||
PeerTestRunner peer3 = new PeerTestRunner(peerSrvAddr3, node3.getBindingConfig(), node3.getStorageDB()); | |||
AsyncCallback<Object> peerStarting0 = peer0.start(); | |||
AsyncCallback<Object> peerStarting1 = peer1.start(); | |||
@@ -192,26 +192,26 @@ public class IntegrationTest2 { | |||
DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
testDb0.setConnectionUri(dbConns[0]); | |||
LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, csProvider, | |||
testDb0, consolePrompter, bindingConfig0, quitLatch); | |||
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, csProps,csProvider, | |||
testDb1, consolePrompter, bindingConfig1, quitLatch); | |||
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, csProps,csProvider, | |||
testDb2, consolePrompter, bindingConfig2, quitLatch); | |||
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, csProps,csProvider, | |||
testDb3, consolePrompter, bindingConfig3, quitLatch); | |||
AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, | |||
consolePrompter, bindingConfig3, quitLatch); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -286,7 +286,7 @@ public class IntegrationTest2 { | |||
} | |||
private void testSDK_Contract(AsymmetricKeypair adminKey, HashDigest ledgerHash, | |||
BlockchainService blockchainService, IntegratedContext context) { | |||
BlockchainService blockchainService, IntegratedContext context) { | |||
BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | |||
// 定义交易; | |||
@@ -304,19 +304,18 @@ public class IntegrationTest2 { | |||
assertTrue(txResp.isSuccess()); | |||
// execute the contract; | |||
testContractExe(adminKey, ledgerHash, userKey, blockchainService, context); | |||
testContractExe(adminKey, ledgerHash, userKey, blockchainService, context); | |||
} | |||
private void testContractExe(AsymmetricKeypair adminKey, HashDigest ledgerHash, BlockchainKeypair userKey, | |||
BlockchainService blockchainService, IntegratedContext context) { | |||
BlockchainService blockchainService, IntegratedContext context) { | |||
LedgerInfo ledgerInfo = blockchainService.getLedger(ledgerHash); | |||
LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight()-1); | |||
LedgerBlock previousBlock = blockchainService.getBlock(ledgerHash, ledgerInfo.getLatestBlockHeight() - 1); | |||
// 定义交易; | |||
TransactionTemplate txTpl = blockchainService.newTransaction(ledgerHash); | |||
txTpl.contractEvents().send(contractDeployKey.getAddress(), eventName, | |||
("888##999##abc").getBytes()); | |||
txTpl.contractEvents().send(contractDeployKey.getAddress(), eventName, ("888##999##abc").getBytes()); | |||
// 签名; | |||
PreparedTransaction ptx = txTpl.prepare(); | |||
@@ -327,7 +326,6 @@ public class IntegrationTest2 { | |||
assertTrue(txResp.isSuccess()); | |||
} | |||
/** | |||
* 根据合约构建字节数组; | |||
* | |||
@@ -8,13 +8,11 @@ import java.io.InputStream; | |||
import java.util.Properties; | |||
import java.util.concurrent.CountDownLatch; | |||
import com.jd.blockchain.storage.service.DbConnection; | |||
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.ConsensusProviders; | |||
import com.jd.blockchain.consensus.ConsensusSettings; | |||
import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
@@ -34,6 +32,7 @@ import com.jd.blockchain.ledger.core.LedgerRepository; | |||
import com.jd.blockchain.ledger.core.impl.LedgerManager; | |||
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.LedgerInitProperties; | |||
@@ -50,7 +49,7 @@ import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsT | |||
public class IntegrationTestDataAccount { | |||
LedgerInitConsensusConfig.ConsensusConfig config = LedgerInitConsensusConfig.mqConfig; | |||
LedgerInitConsensusConfig.ConsensusConfig config = LedgerInitConsensusConfig.mqConfig; | |||
public IntegratedContext context = initLedgers(config, LedgerInitConsensusConfig.memConnectionStrings); | |||
public GatewayTestRunner gateway0; | |||
@@ -173,8 +172,8 @@ public class IntegrationTestDataAccount { | |||
} | |||
// 通过调用SDK->GATEWAY,测试一个区块包含多个交易时的写入情况,并验证写入结果; | |||
private void testAddKvOpToDataAccount(GatewayTestRunner gateway, AsymmetricKeypair adminKey, IntegratedContext context, | |||
Bytes dataAddr) { | |||
private void testAddKvOpToDataAccount(GatewayTestRunner gateway, AsymmetricKeypair adminKey, | |||
IntegratedContext context, Bytes dataAddr) { | |||
GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(gateway.getServiceAddress()); | |||
BlockchainService blockchainService = gwsrvFact.getBlockchainService(); | |||
@@ -182,7 +181,8 @@ public class IntegrationTestDataAccount { | |||
LedgerManager ledgerManager = context.getNode(0).getLedgerManager(); | |||
DbConnection memoryBasedDb = context.getNode(0).getStorageDB().connect(LedgerInitConsensusConfig.memConnectionStrings[0]); | |||
DbConnection memoryBasedDb = context.getNode(0).getStorageDB() | |||
.connect(LedgerInitConsensusConfig.memConnectionStrings[0]); | |||
LedgerRepository ledgerRepository = ledgerManager.register(ledgerHashs[0], memoryBasedDb.getStorageService()); | |||
@@ -288,26 +288,26 @@ public class IntegrationTestDataAccount { | |||
DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
testDb0.setConnectionUri(dbConns[0]); | |||
LedgerBindingConfig bindingConfig0 = new LedgerBindingConfig(); | |||
AsyncCallback<HashDigest> callback0 = nodeCtx0.startInitCommand(privkey0, encodedPassword, initSetting, csProps, | |||
csProvider, testDb0, consolePrompter, bindingConfig0, quitLatch); | |||
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, csProps, | |||
csProvider, testDb1, consolePrompter, bindingConfig1, quitLatch); | |||
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, csProps, | |||
csProvider, testDb2, consolePrompter, bindingConfig2, quitLatch); | |||
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, csProps, | |||
csProvider, testDb3, consolePrompter, bindingConfig3, quitLatch); | |||
AsyncCallback<HashDigest> callback3 = nodeCtx3.startInitCommand(privkey3, encodedPassword, initSetting, testDb3, | |||
consolePrompter, bindingConfig3, quitLatch); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -16,39 +16,44 @@ import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import com.jd.blockchain.utils.codec.HexUtils; | |||
import test.com.jd.blockchain.intgr.IntegrationBase; | |||
public class LedgerInitSettingTest { | |||
public class LedgerInitPropertiesTest { | |||
@Test | |||
public void test() throws IOException { | |||
ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger.init"); | |||
InputStream in = ledgerInitSettingResource.getInputStream(); | |||
try { | |||
LedgerInitProperties setting = LedgerInitProperties.resolve(in); | |||
assertEquals(4, setting.getConsensusParticipantCount()); | |||
String expectedLedgerSeed = "932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe".replace("-", ""); | |||
String actualLedgerSeed = HexUtils.encode(setting.getLedgerSeed()); | |||
LedgerInitProperties initProps = LedgerInitProperties.resolve(in); | |||
assertEquals(4, initProps.getConsensusParticipantCount()); | |||
String expectedLedgerSeed = "932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe" | |||
.replace("-", ""); | |||
String actualLedgerSeed = HexUtils.encode(initProps.getLedgerSeed()); | |||
assertEquals(expectedLedgerSeed, actualLedgerSeed); | |||
ConsensusParticipantConfig part0 = setting.getConsensusParticipant(0); | |||
assertEquals("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider", | |||
initProps.getConsensusProvider()); | |||
String[] cryptoProviders = initProps.getCryptoProviders(); | |||
assertEquals(2, cryptoProviders.length); | |||
assertEquals("com.jd.blockchain.crypto.service.classic.ClassicCryptoService", cryptoProviders[0]); | |||
assertEquals("com.jd.blockchain.crypto.service.sm.SMCryptoService", cryptoProviders[1]); | |||
ConsensusParticipantConfig part0 = initProps.getConsensusParticipant(0); | |||
assertEquals("jd.com", part0.getName()); | |||
assertEquals("keys/jd-com.pub", part0.getPubKeyPath()); | |||
PubKey pubKey0 = KeyGenCommand.decodePubKey("3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9"); | |||
assertEquals(pubKey0, part0.getPubKey()); | |||
// assertEquals("127.0.0.1", part0.getConsensusAddress().getHost()); | |||
// assertEquals(8900, part0.getConsensusAddress().getPort()); | |||
// assertEquals(true, part0.getConsensusAddress().isSecure()); | |||
assertEquals("127.0.0.1", part0.getInitializerAddress().getHost()); | |||
assertEquals(8800, part0.getInitializerAddress().getPort()); | |||
assertEquals(true, part0.getInitializerAddress().isSecure()); | |||
ConsensusParticipantConfig part1 = setting.getConsensusParticipant(1); | |||
ConsensusParticipantConfig part1 = initProps.getConsensusParticipant(1); | |||
assertEquals(false, part1.getInitializerAddress().isSecure()); | |||
PubKey pubKey1 = KeyGenCommand.decodePubKey("3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX"); | |||
assertEquals(pubKey1, part1.getPubKey()); | |||
ConsensusParticipantConfig part2 = setting.getConsensusParticipant(2); | |||
assertEquals(null, part2.getPubKey()); | |||
ConsensusParticipantConfig part2 = initProps.getConsensusParticipant(2); | |||
assertEquals("7VeRAr3dSbi1xatq11ZcF7sEPkaMmtZhV9shonGJWk9T4pLe", part2.getPubKey().toBase58()); | |||
} finally { | |||
in.close(); | |||
} |
@@ -9,22 +9,22 @@ import java.util.Map; | |||
import java.util.Properties; | |||
import java.util.concurrent.ConcurrentHashMap; | |||
import com.jd.blockchain.storage.service.utils.MemoryDBConnFactory; | |||
import org.junit.Test; | |||
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.AddressEncoding; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
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.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.UserRegisterOperation; | |||
@@ -35,6 +35,7 @@ import com.jd.blockchain.ledger.core.LedgerRepository; | |||
import com.jd.blockchain.ledger.core.UserAccount; | |||
import com.jd.blockchain.ledger.core.UserAccountSet; | |||
import com.jd.blockchain.ledger.core.impl.LedgerManager; | |||
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.LedgerInitProperties; | |||
@@ -60,6 +61,9 @@ public class LedgerInitializeTest { | |||
DataContractRegistry.register(UserRegisterOperation.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; | |||
@@ -85,8 +89,8 @@ public class LedgerInitializeTest { | |||
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); | |||
// ConsensusProvider csProvider = LedgerInitConsensusConfig.getConsensusProvider(config.getProvider()); | |||
// ConsensusSettings csProps = csProvider.getSettingsFactory().getConsensusSettingsBuilder().createSettings(props); | |||
NodeContext node0 = new NodeContext(initSetting.getConsensusParticipant(0).getInitializerAddress(), | |||
serviceRegisterMap); | |||
@@ -100,26 +104,22 @@ public class LedgerInitializeTest { | |||
PrivKey privkey0 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[0], PASSWORD); | |||
DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
testDb0.setConnectionUri(dbConnections[0]); | |||
AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, csProps, csProvider, testDb0, | |||
consolePrompter); | |||
AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter); | |||
PrivKey privkey1 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[1], PASSWORD); | |||
DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
testDb1.setConnectionUri(dbConnections[1]); | |||
AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, csProps, csProvider, testDb1, | |||
consolePrompter); | |||
AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter); | |||
PrivKey privkey2 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[2], PASSWORD); | |||
DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
testDb2.setConnectionUri(dbConnections[2]); | |||
AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, csProps, csProvider, testDb2, | |||
consolePrompter); | |||
AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter); | |||
PrivKey privkey3 = KeyGenCommand.decodePrivKeyWithRawPassword(PRIV_KEYS[3], PASSWORD); | |||
DBConnectionConfig testDb03 = new DBConnectionConfig(); | |||
testDb03.setConnectionUri(dbConnections[3]); | |||
AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, csProps, csProvider, testDb03, | |||
consolePrompter); | |||
AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -234,16 +234,14 @@ public class LedgerInitializeTest { | |||
} | |||
public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter) { | |||
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, csProps, csProvider, dbConnConfig, | |||
prompter); | |||
return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter); | |||
} | |||
}; | |||
@@ -251,10 +249,14 @@ public class LedgerInitializeTest { | |||
} | |||
public AsyncCallback<HashDigest> startInit(int currentId, PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter, boolean autoVerifyHash) { | |||
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")); | |||
@@ -263,8 +265,7 @@ public class LedgerInitializeTest { | |||
ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
@Override | |||
protected HashDigest invoke() throws Exception { | |||
return initProcess.initialize(currentId, privKey, setting, csProps, csProvider, dbConnConfig, | |||
prompter, cryptoSetting); | |||
return initProcess.initialize(currentId, privKey, setting, dbConnConfig, prompter, cryptoSetting); | |||
} | |||
}; | |||
@@ -94,23 +94,23 @@ public class LedgerInitializeWeb4Nodes { | |||
DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
testDb0.setConnectionUri(dbConns[0]); | |||
AsyncCallback<HashDigest> callback0 = node0.startInit(privkey0, initSetting, csProps, csProvider, testDb0, | |||
consolePrompter, quitLatch); | |||
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, csProps, csProvider, testDb1, | |||
consolePrompter, quitLatch); | |||
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, csProps, csProvider, testDb2, | |||
consolePrompter, quitLatch); | |||
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, csProps, csProvider, testDb03, | |||
consolePrompter, quitLatch); | |||
AsyncCallback<HashDigest> callback3 = node3.startInit(privkey3, initSetting, testDb03, consolePrompter, | |||
quitLatch); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -230,8 +230,7 @@ public class LedgerInitializeWeb4Nodes { | |||
} | |||
public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter, CountDownLatch quitLatch) { | |||
DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { | |||
ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
@Override | |||
@@ -239,8 +238,8 @@ public class LedgerInitializeWeb4Nodes { | |||
doStartServer(); | |||
NodeWebContext.this.dbConnConfig = dbConnConfig; | |||
HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, csProps, | |||
csProvider, dbConnConfig, prompter); | |||
HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, | |||
dbConnConfig, prompter); | |||
System.out.printf("ledgerHash = %s \r\n", ledgerHash.toBase58()); | |||
@@ -252,7 +251,6 @@ public class LedgerInitializeWeb4Nodes { | |||
return invoker.start(); | |||
} | |||
public void doStartServer() { | |||
String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); | |||
String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); | |||
@@ -340,8 +340,7 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
} | |||
public AsyncCallback<HashDigest> startInit(PrivKey privKey, LedgerInitProperties setting, | |||
ConsensusSettings csProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter, CountDownLatch quitLatch) { | |||
DBConnectionConfig dbConnConfig, Prompter prompter, CountDownLatch quitLatch) { | |||
ThreadInvoker<HashDigest> invoker = new ThreadInvoker<HashDigest>() { | |||
@Override | |||
@@ -350,8 +349,8 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
// NodeWebContext.this.initProcess = ctx.getBean(LedgerInitProcess.class); | |||
NodeWebContext.this.dbConnConfig = dbConnConfig; | |||
HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, csProps, | |||
csProvider, dbConnConfig, prompter); | |||
HashDigest ledgerHash = NodeWebContext.this.initProcess.initialize(id, privKey, setting, | |||
dbConnConfig, prompter); | |||
quitLatch.countDown(); | |||
return ledgerHash; | |||
@@ -362,9 +361,8 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
} | |||
public AsyncCallback<HashDigest> startInitCommand(PrivKey privKey, String base58Pwd, | |||
LedgerInitProperties ledgerSetting, ConsensusSettings csProps, ConsensusProvider csProvider, | |||
DBConnectionConfig dbConnConfig, Prompter prompter, LedgerBindingConfig conf, | |||
CountDownLatch quitLatch) { | |||
LedgerInitProperties ledgerSetting, DBConnectionConfig dbConnConfig, Prompter prompter, | |||
LedgerBindingConfig conf, CountDownLatch quitLatch) { | |||
this.db = new CompositeConnectionFactory(); | |||
this.dbConnConfig = dbConnConfig; | |||
@@ -372,8 +370,8 @@ public class LedgerInitializeWeb4SingleStepsTest { | |||
@Override | |||
protected HashDigest invoke() throws Exception { | |||
LedgerInitCommand initCmd = new LedgerInitCommand(); | |||
HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, csProps, | |||
csProvider, dbConnConfig, prompter, conf, db); | |||
HashDigest ledgerHash = initCmd.startInit(id, privKey, base58Pwd, ledgerSetting, dbConnConfig, | |||
prompter, conf, db); | |||
NodeWebContext.this.ledgerManager = initCmd.getLedgerManager(); | |||
quitLatch.countDown(); | |||
return ledgerHash; | |||
@@ -141,41 +141,36 @@ public class LedgerBlockGeneratingTest { | |||
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" | |||
}; | |||
String[] memConns = new String[] { "memory://local/0", "memory://local/1", "memory://local/2", | |||
"memory://local/3" }; | |||
PrivKey privkey0 = KeyGenCommand.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[0], | |||
LedgerInitializeTest.PASSWORD); | |||
DBConnectionConfig testDb0 = new DBConnectionConfig(); | |||
testDb0.setConnectionUri(memConns[0]); | |||
AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, csProps, csProvider, testDb0, | |||
consolePrompter, !optimized); | |||
AsyncCallback<HashDigest> callback0 = node0.startInit(0, privkey0, initSetting, testDb0, consolePrompter, | |||
!optimized); | |||
PrivKey privkey1 = KeyGenCommand.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[1], | |||
LedgerInitializeTest.PASSWORD); | |||
DBConnectionConfig testDb1 = new DBConnectionConfig(); | |||
testDb1.setConnectionUri(memConns[1]); | |||
AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, csProps, csProvider, testDb1, | |||
consolePrompter, !optimized); | |||
AsyncCallback<HashDigest> callback1 = node1.startInit(1, privkey1, initSetting, testDb1, consolePrompter, | |||
!optimized); | |||
PrivKey privkey2 = KeyGenCommand.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[2], | |||
LedgerInitializeTest.PASSWORD); | |||
DBConnectionConfig testDb2 = new DBConnectionConfig(); | |||
testDb2.setConnectionUri(memConns[2]); | |||
AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, csProps, csProvider, testDb2, | |||
consolePrompter, !optimized); | |||
AsyncCallback<HashDigest> callback2 = node2.startInit(2, privkey2, initSetting, testDb2, consolePrompter, | |||
!optimized); | |||
PrivKey privkey3 = KeyGenCommand.decodePrivKeyWithRawPassword(LedgerInitializeTest.PRIV_KEYS[3], | |||
LedgerInitializeTest.PASSWORD); | |||
DBConnectionConfig testDb03 = new DBConnectionConfig(); | |||
testDb03.setConnectionUri(memConns[3]); | |||
AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, csProps, csProvider, testDb03, | |||
consolePrompter, !optimized); | |||
AsyncCallback<HashDigest> callback3 = node3.startInit(3, privkey3, initSetting, testDb03, consolePrompter, | |||
!optimized); | |||
HashDigest ledgerHash0 = callback0.waitReturn(); | |||
HashDigest ledgerHash1 = callback1.waitReturn(); | |||
@@ -0,0 +1 @@ | |||
3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x |
@@ -5,6 +5,18 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 | |||
#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
ledger.name= | |||
#共识服务提供者;必须; | |||
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 | |||
@@ -49,7 +61,7 @@ cons_parti.1.initializer.secure=false | |||
#第2个参与方的名称; | |||
cons_parti.2.name=bt.com | |||
#第2个参与方的公钥文件路径; | |||
cons_parti.2.pubkey-path=keys/bt-com.pub | |||
cons_parti.2.pubkey-path=classpath:keys/parti2.pub | |||
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.2.pubkey= | |||
#第2个参与方的共识服务的主机地址; | |||
@@ -5,6 +5,16 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 | |||
#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
ledger.name= | |||
#共识服务提供者;必须; | |||
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 | |||
@@ -5,6 +5,17 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323 | |||
#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
#ledger.name= | |||
#共识服务提供者;必须; | |||
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 | |||
@@ -1,36 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<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"> | |||
<parent> | |||
<artifactId>test</artifactId> | |||
<groupId>com.jd.blockchain</groupId> | |||
<version>0.9.0-SNAPSHOT</version> | |||
</parent> | |||
<modelVersion>4.0.0</modelVersion> | |||
<artifactId>test-stp-community</artifactId> | |||
<name>test-stp-community</name> | |||
<properties> | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
<maven.compiler.source>1.8</maven.compiler.source> | |||
<maven.compiler.target>1.8</maven.compiler.target> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>stp-communication</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
</project> |
@@ -1,37 +0,0 @@ | |||
/** | |||
* Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
* FileName: com.jd.blockchain.stp.commucation.MyMessageExecutor | |||
* Author: shaozhuguang | |||
* Department: Y事业部 | |||
* Date: 2019/4/17 下午3:38 | |||
* Description: | |||
*/ | |||
package com.jd.blockchain.stp.commucation; | |||
import com.jd.blockchain.stp.communication.MessageExecutor; | |||
import com.jd.blockchain.stp.communication.RemoteSession; | |||
import java.nio.charset.Charset; | |||
/** | |||
* | |||
* @author shaozhuguang | |||
* @create 2019/4/17 | |||
* @since 1.0.0 | |||
*/ | |||
public class MyMessageExecutor implements MessageExecutor { | |||
@Override | |||
public byte[] receive(String key, byte[] data, RemoteSession session) { | |||
String receiveMsg = new String(data, Charset.defaultCharset()); | |||
System.out.printf("receive client {%s} request {%s} \r\n", session.remoteNode().toString(), receiveMsg); | |||
String msg = session.localId() + " -> received !!!"; | |||
return msg.getBytes(Charset.defaultCharset()); | |||
} | |||
@Override | |||
public REPLY replyType() { | |||
return REPLY.AUTO; | |||
} | |||
} |
@@ -1,75 +0,0 @@ | |||
/** | |||
* Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
* FileName: com.jd.blockchain.StpReceiversBoot | |||
* Author: shaozhuguang | |||
* Department: Y事业部 | |||
* Date: 2019/4/18 下午3:44 | |||
* Description: | |||
*/ | |||
package com.jd.blockchain.stp.commucation; | |||
import com.jd.blockchain.stp.communication.MessageExecutor; | |||
import com.jd.blockchain.stp.communication.manager.RemoteSessionManager; | |||
import com.jd.blockchain.stp.communication.node.LocalNode; | |||
import java.util.concurrent.CountDownLatch; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
/** | |||
* | |||
* @author shaozhuguang | |||
* @create 2019/4/18 | |||
* @since 1.0.0 | |||
*/ | |||
public class StpReceiversBoot { | |||
private int[] listenPorts; | |||
private final String remoteHost = "127.0.0.1"; | |||
private ExecutorService threadPool; | |||
public StpReceiversBoot(int... ports) { | |||
listenPorts = ports; | |||
threadPool = Executors.newFixedThreadPool(ports.length + 2); | |||
} | |||
public RemoteSessionManager[] start(MessageExecutor messageExecutor) { | |||
final int totalSessionSize = listenPorts.length; | |||
CountDownLatch countDownLatch = new CountDownLatch(totalSessionSize); | |||
RemoteSessionManager[] sessionManagers = new RemoteSessionManager[totalSessionSize]; | |||
for (int i = 0; i < totalSessionSize; i++) { | |||
final int port = listenPorts[i], index = i; | |||
threadPool.execute(() -> { | |||
// 创建本地节点 | |||
final LocalNode localNode = new LocalNode(remoteHost, port, messageExecutor); | |||
try { | |||
// 启动当前节点 | |||
RemoteSessionManager sessionManager = new RemoteSessionManager(localNode); | |||
sessionManagers[index] = sessionManager; | |||
System.out.printf("Current Node {%s} start success !!! \r\n", localNode.toString()); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
countDownLatch.countDown(); | |||
} | |||
}); | |||
} | |||
// 等待所有节点启动完成 | |||
try { | |||
countDownLatch.await(); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
return sessionManagers; | |||
} | |||
} |
@@ -1,43 +0,0 @@ | |||
/** | |||
* Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
* FileName: com.jd.blockchain.StpReceiversBootTest | |||
* Author: shaozhuguang | |||
* Department: Y事业部 | |||
* Date: 2019/4/18 下午3:53 | |||
* Description: | |||
*/ | |||
package com.jd.blockchain; | |||
import com.jd.blockchain.stp.commucation.MyMessageExecutor; | |||
import com.jd.blockchain.stp.commucation.StpReceiversBoot; | |||
import com.jd.blockchain.stp.communication.manager.RemoteSessionManager; | |||
import org.junit.Test; | |||
/** | |||
* | |||
* @author shaozhuguang | |||
* @create 2019/4/18 | |||
* @since 1.0.0 | |||
*/ | |||
public class StpReceiversBootTest { | |||
public static final int[] localPorts = new int[]{9900, 9901}; | |||
@Test | |||
public void test() { | |||
StpReceiversBoot stpReceiversBoot = new StpReceiversBoot(9900, 9901); | |||
RemoteSessionManager[] sessionManagers = stpReceiversBoot.start(new MyMessageExecutor()); | |||
try { | |||
Thread.sleep(10000); | |||
// 关闭所有的监听器 | |||
for (RemoteSessionManager sessionManager : sessionManagers) { | |||
sessionManager.connectionManager().closeReceiver(); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
} |
@@ -1,96 +0,0 @@ | |||
/** | |||
* Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
* FileName: com.jd.blockchain.StpSenderTest | |||
* Author: shaozhuguang | |||
* Department: Y事业部 | |||
* Date: 2019/4/18 下午3:56 | |||
* Description: | |||
*/ | |||
package com.jd.blockchain; | |||
import com.jd.blockchain.stp.commucation.MyMessageExecutor; | |||
import com.jd.blockchain.stp.commucation.StpReceiversBoot; | |||
import com.jd.blockchain.stp.communication.RemoteSession; | |||
import com.jd.blockchain.stp.communication.callback.CallBackBarrier; | |||
import com.jd.blockchain.stp.communication.callback.CallBackDataListener; | |||
import com.jd.blockchain.stp.communication.manager.RemoteSessionManager; | |||
import com.jd.blockchain.stp.communication.message.LoadMessage; | |||
import com.jd.blockchain.stp.communication.node.RemoteNode; | |||
import org.junit.Test; | |||
import java.util.Iterator; | |||
import java.util.LinkedList; | |||
/** | |||
* | |||
* @author shaozhuguang | |||
* @create 2019/4/18 | |||
* @since 1.0.0 | |||
*/ | |||
public class StpSenderTest { | |||
// 本地的端口 | |||
private static final int localPort = 9800; | |||
// 连接的远端端口集合 | |||
private static final int[] remotePorts = StpReceiversBootTest.localPorts; | |||
// 本地节点信息 | |||
private static final String localHost = "127.0.0.1"; | |||
@Test | |||
public void test() { | |||
// 首先启动本地节点 | |||
StpReceiversBoot stpReceiversBoot = new StpReceiversBoot(localPort); | |||
RemoteSessionManager[] sessionManagers = stpReceiversBoot.start(new MyMessageExecutor()); | |||
// 本地节点启动完成后 | |||
if (sessionManagers != null && sessionManagers.length > 0) { | |||
RemoteSessionManager localSessionManager = sessionManagers[0]; | |||
// 连接远端的两个节点 | |||
RemoteNode[] remoteNodes = new RemoteNode[]{ | |||
new RemoteNode(localHost, remotePorts[0]), | |||
new RemoteNode(localHost, remotePorts[1]) | |||
}; | |||
RemoteSession[] remoteSessions = localSessionManager.newSessions(remoteNodes); | |||
// 生成请求对象 | |||
LoadMessage loadMessage = new StpTest.StpLoadMessage(localHost + ":" + localPort); | |||
// 异步发送处理过程 | |||
CallBackBarrier callBackBarrier = CallBackBarrier.newCallBackBarrier(remoteSessions.length, 10000); | |||
// 发送请求至remotes | |||
LinkedList<CallBackDataListener> responses = new LinkedList<>(); | |||
for (RemoteSession remoteSession : remoteSessions) { | |||
CallBackDataListener response = remoteSession.asyncRequest(loadMessage, callBackBarrier); | |||
responses.addLast(response); | |||
} | |||
// 超时判断 | |||
try { | |||
if (callBackBarrier.tryCall()) { | |||
// 说明结果已经全部返回 | |||
// 打印出所有的结果 | |||
// 通过迭代器遍历链表 | |||
Iterator<CallBackDataListener> iterator = responses.iterator(); | |||
while (iterator.hasNext()) { | |||
CallBackDataListener response = iterator.next(); | |||
// 判断是否已完成,对于没有完成的直接放弃(因为已经超时) | |||
if (response.isDone()) { | |||
System.out.printf("Receive Response {%s} {%s} \r\n", | |||
response.remoteNode().toString(), new String(response.getCallBackData())); | |||
} | |||
} | |||
} | |||
Thread.sleep(Integer.MAX_VALUE); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
} | |||
} |
@@ -1,206 +0,0 @@ | |||
/** | |||
* Copyright: Copyright 2016-2020 JD.COM All Right Reserved | |||
* FileName: com.jd.blockchain.StpTest | |||
* Author: shaozhuguang | |||
* Department: Y事业部 | |||
* Date: 2019/4/11 下午3:31 | |||
* Description: | |||
*/ | |||
package com.jd.blockchain; | |||
import com.jd.blockchain.stp.commucation.MyMessageExecutor; | |||
import com.jd.blockchain.stp.communication.RemoteSession; | |||
import com.jd.blockchain.stp.communication.callback.CallBackBarrier; | |||
import com.jd.blockchain.stp.communication.callback.CallBackDataListener; | |||
import com.jd.blockchain.stp.communication.manager.RemoteSessionManager; | |||
import com.jd.blockchain.stp.communication.message.LoadMessage; | |||
import com.jd.blockchain.stp.communication.node.LocalNode; | |||
import com.jd.blockchain.stp.communication.node.RemoteNode; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import java.nio.charset.Charset; | |||
import java.util.Iterator; | |||
import java.util.LinkedList; | |||
import java.util.concurrent.CountDownLatch; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
import static org.junit.Assert.assertNull; | |||
/** | |||
* | |||
* @author shaozhuguang | |||
* @create 2019/4/11 | |||
* @since 1.0.0 | |||
*/ | |||
public class StpTest { | |||
private int maxWaitTime = 2000; | |||
private final String remoteHost = "127.0.0.1"; | |||
private final int localPort = 9001; | |||
private final int[] listenPorts = new int[]{9001, 9002, 9003, 9004}; | |||
private final RemoteSessionManager[] sessionManagers = new RemoteSessionManager[listenPorts.length]; | |||
private final ExecutorService threadPool = Executors.newFixedThreadPool(6); | |||
private RemoteSession[] remoteSessions; | |||
@Before | |||
public void init() { | |||
System.out.println("---------- listenStart -----------"); | |||
listenStart(); | |||
System.out.println("---------- listenComplete -----------"); | |||
System.out.println("---------- ConnectionStart ----------"); | |||
connectOneOther(); | |||
System.out.println("---------- ConnectionComplete ----------"); | |||
} | |||
private void listenStart() { | |||
CountDownLatch countDownLatch = new CountDownLatch(listenPorts.length); | |||
for (int i = 0; i < listenPorts.length; i++) { | |||
final int port = listenPorts[i], index = i; | |||
threadPool.execute(() -> { | |||
// 创建本地节点 | |||
final LocalNode localNode = new LocalNode(remoteHost, port, new MyMessageExecutor()); | |||
try { | |||
// 启动当前节点 | |||
RemoteSessionManager sessionManager = new RemoteSessionManager(localNode); | |||
sessionManagers[index] = sessionManager; | |||
System.out.printf("Current Node {%s} start success !!! \r\n", localNode.toString()); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} finally { | |||
countDownLatch.countDown(); | |||
} | |||
}); | |||
} | |||
// 等待所有节点启动完成 | |||
try { | |||
countDownLatch.await(); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
private void connectAllOthers() { | |||
// 所有节点完成之后,需要启动 | |||
// 启动一个节点 | |||
RemoteSessionManager starter = sessionManagers[0]; | |||
// 当前节点需要连接到其他3个节点 | |||
RemoteNode[] remoteNodes = new RemoteNode[listenPorts.length - 1]; | |||
int index = 0; | |||
for (int port : listenPorts) { | |||
if (port != localPort) { | |||
remoteNodes[index++] = new RemoteNode(remoteHost, port); | |||
} | |||
} | |||
remoteSessions = starter.newSessions(remoteNodes); | |||
} | |||
private void connectOneOther() { | |||
// 所有节点完成之后,需要启动 | |||
// 启动一个节点 | |||
RemoteSessionManager starter = sessionManagers[0]; | |||
// 当前节点需要连接到其他3个节点 | |||
RemoteNode[] remoteNodes = new RemoteNode[1]; | |||
int index = 0; | |||
for (int port : listenPorts) { | |||
if (port != localPort && index < 1) { | |||
remoteNodes[index++] = new RemoteNode(remoteHost, port); | |||
} | |||
} | |||
remoteSessions = starter.newSessions(remoteNodes); | |||
} | |||
private void connectOneErrorNode() { | |||
// 所有节点完成之后,需要启动 | |||
// 启动一个节点 | |||
RemoteSessionManager starter = sessionManagers[0]; | |||
// 当前节点需要连接到其他3个节点 | |||
RemoteNode[] remoteNodes = new RemoteNode[1]; | |||
remoteNodes[0] = new RemoteNode(remoteHost, 10001); | |||
remoteSessions = starter.newSessions(remoteNodes); | |||
assertNull(remoteSessions); | |||
} | |||
@Test | |||
public void test() { | |||
try { | |||
Thread.sleep(3000); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
// 生成请求对象 | |||
LoadMessage loadMessage = new StpLoadMessage(remoteHost + ":" + localPort); | |||
// 异步发送处理过程 | |||
CallBackBarrier callBackBarrier = CallBackBarrier.newCallBackBarrier(remoteSessions.length, 10000); | |||
// 发送请求至remotes | |||
LinkedList<CallBackDataListener> responses = new LinkedList<>(); | |||
for (RemoteSession remoteSession : remoteSessions) { | |||
CallBackDataListener response = remoteSession.asyncRequest(loadMessage, callBackBarrier); | |||
responses.addLast(response); | |||
} | |||
// 超时判断 | |||
try { | |||
if (callBackBarrier.tryCall()) { | |||
// 说明结果已经全部返回 | |||
// 打印出所有的结果 | |||
// 通过迭代器遍历链表 | |||
Iterator<CallBackDataListener> iterator = responses.iterator(); | |||
while (iterator.hasNext()) { | |||
CallBackDataListener response = iterator.next(); | |||
// 判断是否已完成,对于没有完成的直接放弃(因为已经超时) | |||
if (response.isDone()) { | |||
System.out.printf("Receive Response {%s} {%s} \r\n", | |||
response.remoteNode().toString(), new String(response.getCallBackData())); | |||
} | |||
} | |||
} | |||
Thread.sleep(Integer.MAX_VALUE); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
public static class StpLoadMessage implements LoadMessage { | |||
private String localInfo; | |||
public StpLoadMessage(String localInfo) { | |||
this.localInfo = localInfo; | |||
} | |||
@Override | |||
public byte[] toBytes() { | |||
String msg = localInfo + " -> Send !!!"; | |||
return msg.getBytes(Charset.defaultCharset()); | |||
} | |||
} | |||
} |
@@ -1,7 +1,6 @@ | |||
package com.jd.blockchain.tools.initializer; | |||
import java.io.File; | |||
import java.util.Properties; | |||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; | |||
import org.springframework.boot.SpringApplication; | |||
@@ -11,9 +10,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties | |||
import org.springframework.context.ApplicationContextInitializer; | |||
import org.springframework.context.ConfigurableApplicationContext; | |||
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.HashDigest; | |||
import com.jd.blockchain.crypto.PrivKey; | |||
@@ -23,7 +19,6 @@ import com.jd.blockchain.tools.initializer.LedgerBindingConfig.BindingConfig; | |||
import com.jd.blockchain.tools.initializer.LedgerInitProperties.ConsensusParticipantConfig; | |||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import com.jd.blockchain.utils.ArgumentSet; | |||
import com.jd.blockchain.utils.ConsoleUtils; | |||
import com.jd.blockchain.utils.ArgumentSet.ArgEntry; | |||
import com.jd.blockchain.utils.ArgumentSet.Setting; | |||
import com.jd.blockchain.utils.io.FileUtils; | |||
@@ -51,72 +46,68 @@ public class LedgerInitCommand { | |||
// 是否输出调试信息; | |||
private static final String DEBUG_OPT = "-debug"; | |||
private static final Prompter DEFAULT_PROMPTER = new ConsolePrompter(); | |||
/** | |||
* 入口; | |||
* | |||
* @param args | |||
*/ | |||
public static void main(String[] args) { | |||
Prompter prompter = DEFAULT_PROMPTER; | |||
Setting argSetting = ArgumentSet.setting().prefix(LOCAL_ARG, INI_ARG).option(DEBUG_OPT); | |||
ArgumentSet argset = ArgumentSet.resolve(args, argSetting); | |||
try { | |||
ArgEntry localArg = argset.getArg(LOCAL_ARG); | |||
if (localArg == null) { | |||
ConsoleUtils.info("Miss local config file which can be specified with arg [%s]!!!", LOCAL_ARG); | |||
prompter.info("Miss local config file which can be specified with arg [%s]!!!", LOCAL_ARG); | |||
} | |||
LocalConfig localConf = LocalConfig.resolve(localArg.getValue()); | |||
ArgEntry iniArg = argset.getArg(INI_ARG); | |||
if (iniArg == null) { | |||
ConsoleUtils.info("Miss ledger initializing config file which can be specified with arg [%s]!!!", | |||
INI_ARG); | |||
prompter.info("Miss ledger initializing config file which can be specified with arg [%s]!!!", INI_ARG); | |||
return; | |||
} | |||
// // load ledger init setting; | |||
LedgerInitProperties ledgerInitSetting = LedgerInitProperties.resolve(iniArg.getValue()); | |||
// load ledger init setting; | |||
LedgerInitProperties ledgerInitProperties = LedgerInitProperties.resolve(iniArg.getValue()); | |||
String localNodePubKeyString = localConf.getLocal().getPubKeyString(); | |||
PubKey localNodePubKey = KeyGenCommand.decodePubKey(localNodePubKeyString); | |||
// 地址根据公钥生成 | |||
String localNodeAddress = AddressEncoding.generateAddress(localNodePubKey).toBase58(); | |||
// load all pub keys; | |||
// 加载全部公钥; | |||
int currId = -1; | |||
for (int i = 0; i < ledgerInitSetting.getConsensusParticipantCount(); i++) { | |||
ConsensusParticipantConfig pconf = ledgerInitSetting.getConsensusParticipant(i); | |||
String currPartAddress = pconf.getAddress(); | |||
if (currPartAddress == null) { | |||
if (pconf.getPubKeyPath() != null) { | |||
PubKey pubKey = KeyGenCommand.readPubKey(pconf.getPubKeyPath()); | |||
pconf.setPubKey(pubKey); | |||
currPartAddress = pconf.getAddress(); | |||
} | |||
} | |||
if (localNodeAddress.equals(currPartAddress)) { | |||
for (int i = 0; i < ledgerInitProperties.getConsensusParticipantCount(); i++) { | |||
ConsensusParticipantConfig partiConf = ledgerInitProperties.getConsensusParticipant(i); | |||
// String partiAddress = partiConf.getAddress(); | |||
// if (partiAddress == null) { | |||
// if (partiConf.getPubKeyPath() != null) { | |||
// PubKey pubKey = KeyGenCommand.readPubKey(partiConf.getPubKeyPath()); | |||
// partiConf.setPubKey(pubKey); | |||
// partiAddress = partiConf.getAddress(); | |||
// } | |||
// } | |||
if (localNodeAddress.equals(partiConf.getAddress())) { | |||
currId = i; | |||
} | |||
} | |||
if (currId == -1) { | |||
throw new IllegalStateException("The current node specified in local.conf is not found in ledger.init!"); | |||
throw new IllegalStateException( | |||
"The current node specified in local.conf is not found in ledger.init!"); | |||
} | |||
// 加载当前节点的私钥; | |||
String base58Pwd = localConf.getLocal().getPassword(); | |||
if (base58Pwd == null) { | |||
base58Pwd = KeyGenCommand.readPasswordString(); | |||
} | |||
PrivKey privKey = KeyGenCommand.decodePrivKey(localConf.getLocal().getPrivKeyString(), base58Pwd); | |||
// Load consensus properties; | |||
Properties props = FileUtils.readProperties(localConf.getConsensusConfig()); | |||
ConsensusProvider csProvider = ConsensusProviders.getProvider(localConf.getConsensusProvider()); | |||
ConsensusSettings csSettings = csProvider.getSettingsFactory().getConsensusSettingsBuilder() | |||
.createSettings(props); | |||
// ConsensusProperties csProps = new ConsensusProperties(props); | |||
// Output ledger binding config of peer; | |||
if (!FileUtils.existDirectory(localConf.getBindingOutDir())) { | |||
FileUtils.makeDirectory(localConf.getBindingOutDir()); | |||
@@ -131,27 +122,26 @@ public class LedgerInitCommand { | |||
// 启动初始化; | |||
LedgerInitCommand initCommand = new LedgerInitCommand(); | |||
HashDigest newLedgerHash = initCommand.startInit(currId, privKey, base58Pwd, ledgerInitSetting, csSettings, csProvider, | |||
localConf.getStoragedDb(), new ConsolePrompter(), conf); | |||
HashDigest newLedgerHash = initCommand.startInit(currId, privKey, base58Pwd, ledgerInitProperties, | |||
localConf.getStoragedDb(), prompter, conf); | |||
if (newLedgerHash != null) { | |||
// success; | |||
// so save ledger binding config to file system; | |||
conf.store(ledgerBindingFile); | |||
ConsoleUtils.info("\r\n------ Update Ledger binding configuration success! ------[%s]", | |||
prompter.info("\r\n------ Update Ledger binding configuration success! ------[%s]", | |||
ledgerBindingFile.getAbsolutePath()); | |||
} | |||
// ConsoleUtils.confirm("\r\n\r\n Press any key to quit. :>"); | |||
} catch (Exception e) { | |||
ConsoleUtils.error("\r\nError!! -- %s\r\n", e.getMessage()); | |||
prompter.error("\r\nError!! -- %s\r\n", e.getMessage()); | |||
if (argset.hasOption(DEBUG_OPT)) { | |||
e.printStackTrace(); | |||
} | |||
ConsoleUtils.error("\r\n Ledger init process has been broken by error!"); | |||
prompter.error("\r\n Ledger init process has been broken by error!"); | |||
} | |||
prompter.confirm(InitializingStep.LEDGER_INIT_COMPLETED.toString(), "\r\n\r\n Press any key to quit. :>"); | |||
} | |||
@@ -164,20 +154,19 @@ public class LedgerInitCommand { | |||
public LedgerInitCommand() { | |||
} | |||
public HashDigest startInit(int currId, PrivKey privKey, String base58Pwd, LedgerInitProperties ledgerSetting, | |||
ConsensusSettings csSettings, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter, LedgerBindingConfig conf, Object... extBeans) { | |||
if (currId < 0 || currId >= ledgerSetting.getConsensusParticipantCount()) { | |||
ConsoleUtils.info( | |||
public HashDigest startInit(int currId, PrivKey privKey, String base58Pwd, | |||
LedgerInitProperties ledgerInitProperties, DBConnectionConfig dbConnConfig, Prompter prompter, | |||
LedgerBindingConfig conf, Object... extBeans) { | |||
if (currId < 0 || currId >= ledgerInitProperties.getConsensusParticipantCount()) { | |||
prompter.info( | |||
"Your participant id is illegal which is less than 1 or great than the total participants count[%s]!!!", | |||
ledgerSetting.getConsensusParticipantCount()); | |||
ledgerInitProperties.getConsensusParticipantCount()); | |||
return null; | |||
} | |||
// generate binding config; | |||
BindingConfig bindingConf = new BindingConfig(); | |||
// bindingConf.setCsConfigFile(localConf.getConsensusConfig()); | |||
bindingConf.getParticipant().setAddress(ledgerSetting.getConsensusParticipant(currId).getAddress()); | |||
bindingConf.getParticipant().setAddress(ledgerInitProperties.getConsensusParticipant(currId).getAddress()); | |||
String encodedPrivKey = KeyGenCommand.encodePrivKey(privKey, base58Pwd); | |||
bindingConf.getParticipant().setPk(encodedPrivKey); | |||
bindingConf.getParticipant().setPassword(base58Pwd); | |||
@@ -185,16 +174,13 @@ public class LedgerInitCommand { | |||
bindingConf.getDbConnection().setConnectionUri(dbConnConfig.getUri()); | |||
bindingConf.getDbConnection().setPassword(dbConnConfig.getPassword()); | |||
// bindingConf.getMqConnection().setServer(mqConnConfig.getServer()); | |||
// bindingConf.getMqConnection().setTopic(mqConnConfig.getTopic()); | |||
// confirm continue; | |||
prompter.info("\r\n\r\n This is participant [%s], the ledger initialization is ready to start!\r\n", currId); | |||
// ConsoleUtils.confirm("Press any key to continue... "); | |||
// prompter.confirm("Press any key to continue... "); | |||
// ConsoleUtils.confirm("Press any key to continue... "); | |||
// prompter.confirm("Press any key to continue... "); | |||
// start web listener; | |||
NetworkAddress serverAddress = ledgerSetting.getConsensusParticipant(currId).getInitializerAddress(); | |||
// start the web controller of Ledger Initializer; | |||
NetworkAddress serverAddress = ledgerInitProperties.getConsensusParticipant(currId).getInitializerAddress(); | |||
String argServerAddress = String.format("--server.address=%s", serverAddress.getHost()); | |||
String argServerPort = String.format("--server.port=%s", serverAddress.getPort()); | |||
String[] innerArgs = { argServerAddress, argServerPort }; | |||
@@ -211,21 +197,21 @@ public class LedgerInitCommand { | |||
ConfigurableApplicationContext ctx = app.run(innerArgs); | |||
this.ledgerManager = ctx.getBean(LedgerManager.class); | |||
prompter.info("\r\n------ Web listener[%s:%s] was started. ------\r\n", serverAddress.getHost(), | |||
serverAddress.getPort()); | |||
prompter.info("\r\n------ Web controller of Ledger Initializer[%s:%s] was started. ------\r\n", | |||
serverAddress.getHost(), serverAddress.getPort()); | |||
try { | |||
LedgerInitProcess initProc = ctx.getBean(LedgerInitProcess.class); | |||
HashDigest ledgerHash = initProc.initialize(currId, privKey, ledgerSetting, csSettings, csProvider, | |||
HashDigest ledgerHash = initProc.initialize(currId, privKey, ledgerInitProperties, | |||
bindingConf.getDbConnection(), prompter); | |||
if (ledgerHash == null) { | |||
// ledger init fail; | |||
ConsoleUtils.error("\r\n------ Ledger initialize fail! ------\r\n"); | |||
prompter.error("\r\n------ Ledger initialize fail! ------\r\n"); | |||
return null; | |||
} else { | |||
ConsoleUtils.info("\r\n------ Ledger initialize success! ------"); | |||
ConsoleUtils.info("New Ledger Hash is :[%s]", ledgerHash.toBase58()); | |||
prompter.info("\r\n------ Ledger initialize success! ------"); | |||
prompter.info("New Ledger Hash is :[%s]", ledgerHash.toBase58()); | |||
if (conf == null) { | |||
conf = new LedgerBindingConfig(); | |||
@@ -237,7 +223,7 @@ public class LedgerInitCommand { | |||
} | |||
} finally { | |||
ctx.close(); | |||
ConsoleUtils.info("\r\n------ Web listener[%s:%s] was closed. ------\r\n", serverAddress.getHost(), | |||
prompter.info("\r\n------ Web listener[%s:%s] was closed. ------\r\n", serverAddress.getHost(), | |||
serverAddress.getPort()); | |||
} | |||
} | |||
@@ -17,44 +17,26 @@ public interface LedgerInitProcess { | |||
/** | |||
* Init a new ledger; | |||
* | |||
* @param currentId | |||
* @param privKey | |||
* @param ledgerInitProps | |||
* 账本初始化配置属性; | |||
* @param consensusSettings | |||
* 共识配置属性; | |||
* @param consensusServiceProvider | |||
* @param prompter | |||
* @return 返回新账本的 hash;如果未初始化成功,则返回 null; | |||
*/ | |||
/** | |||
* Init a new ledger; | |||
* @param currentId Id of current participant; | |||
* @param privKey Private key of current participant; | |||
* @param ledgerInitProps The settings about this initialization; | |||
* @param consensusSettings The consensus settings | |||
* @param consensusProvider | |||
* @param dbConnConfig | |||
* @param prompter | |||
* @param currentId Id of current participant. | |||
* @param privKey Private key of current participant. | |||
* @param ledgerInitProps The settings about this initialization. | |||
* @param dbConnConfig The configuration of DB Connection. | |||
* @param prompter Prompter for interaction. | |||
* @return | |||
*/ | |||
HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
ConsensusSettings consensusSettings, ConsensusProvider consensusProvider, | |||
DBConnectionConfig dbConnConfig, Prompter prompter); | |||
/** | |||
* @param currentId | |||
* @param privKey | |||
* @param ledgerInitProps | |||
* @param consensusSettings | |||
* @param consensusProvider | |||
* @param dbConnConfig | |||
* @param prompter | |||
* @param cryptoSetting | |||
* @return | |||
*/ | |||
HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
ConsensusSettings consensusSettings, ConsensusProvider consensusProvider, | |||
DBConnectionConfig dbConnConfig, Prompter prompter, CryptoSetting cryptoSetting); | |||
} |
@@ -1,23 +1,23 @@ | |||
package com.jd.blockchain.tools.initializer; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Properties; | |||
import org.springframework.util.ResourceUtils; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import com.jd.blockchain.utils.PropertiesUtils; | |||
import com.jd.blockchain.utils.codec.HexUtils; | |||
import com.jd.blockchain.utils.io.FileUtils; | |||
import com.jd.blockchain.utils.net.NetworkAddress; | |||
import org.springframework.core.io.ClassPathResource; | |||
public class LedgerInitProperties { | |||
// 账本种子; | |||
@@ -32,12 +32,7 @@ public class LedgerInitProperties { | |||
public static final String PART_PUBKEY_PATH = "pubkey-path"; | |||
// 参与方的公钥文件路径; | |||
public static final String PART_PUBKEY = "pubkey"; | |||
// //共识参与方的共识服务的主机地址; | |||
// public static final String PART_CONSENSUS_HOST = "consensus.host"; | |||
// // 共识参与方的共识服务的端口; | |||
// public static final String PART_CONSENSUS_PORT = "consensus.port"; | |||
// // 共识参与方的共识服务是否开启安全连接; | |||
// public static final String PART_CONSENSUS_SECURE = "consensus.secure"; | |||
// 共识参与方的账本初始服务的主机; | |||
public static final String PART_INITIALIZER_HOST = "initializer.host"; | |||
// 共识参与方的账本初始服务的端口; | |||
@@ -45,70 +40,37 @@ public class LedgerInitProperties { | |||
// 共识参与方的账本初始服务是否开启安全连接; | |||
public static final String PART_INITIALIZER_SECURE = "initializer.secure"; | |||
// 共识服务的参数配置;必须; | |||
public static final String CONSENSUS_CONFIG = "consensus.conf"; | |||
// 共识服务提供者;必须; | |||
public static final String CONSENSUS_SERVICE_PROVIDER = "consensus.service-provider"; | |||
// 密码服务提供者列表,以英文逗点“,”分隔;必须; | |||
public static final String CRYPTO_SERVICE_PROVIDERS = "crypto.service-providers"; | |||
public static final String CRYPTO_SERVICE_PROVIDERS_SPLITTER = ","; | |||
private byte[] ledgerSeed; | |||
private List<ConsensusParticipantConfig> consensusParticipants = new ArrayList<>(); | |||
private String consensusProvider; | |||
private Properties consensusConfig; | |||
private String[] cryptoProviders; | |||
public byte[] getLedgerSeed() { | |||
return ledgerSeed; | |||
return ledgerSeed.clone(); | |||
} | |||
public static byte[] getHostSettingValue() throws Exception { | |||
ClassPathResource hostConfigResource = new ClassPathResource("hosts.config"); | |||
InputStream fis = hostConfigResource.getInputStream(); | |||
ByteArrayOutputStream bos = null; | |||
byte[] buffer = null; | |||
try { | |||
bos = new ByteArrayOutputStream(1000); | |||
byte[] b = new byte[1000]; | |||
int n; | |||
while ((n = fis.read(b)) != -1) { | |||
bos.write(b, 0, n); | |||
} | |||
// host file to bytes | |||
buffer = bos.toByteArray(); | |||
} catch (FileNotFoundException e) { | |||
throw new Exception(e.getMessage(), e); | |||
} catch (IOException e) { | |||
throw new Exception(e.getMessage(), e); | |||
} finally { | |||
if (fis != null) { | |||
fis.close(); | |||
} | |||
if (bos != null) { | |||
bos.close(); | |||
} | |||
} | |||
return buffer; | |||
public Properties getConsensusConfig() { | |||
return consensusConfig; | |||
} | |||
public static byte[] getSystemSettingValue() throws Exception { | |||
ClassPathResource systemConfigResource = new ClassPathResource("bftsmart.config"); | |||
InputStream fis = systemConfigResource.getInputStream(); | |||
ByteArrayOutputStream bos = null; | |||
byte[] buffer = null; | |||
try { | |||
bos = new ByteArrayOutputStream(1000); | |||
byte[] b = new byte[1000]; | |||
int n; | |||
while ((n = fis.read(b)) != -1) { | |||
bos.write(b, 0, n); | |||
} | |||
// file to bytes | |||
buffer = bos.toByteArray(); | |||
} catch (FileNotFoundException e) { | |||
throw new Exception(e.getMessage(), e); | |||
} catch (IOException e) { | |||
throw new Exception(e.getMessage(), e); | |||
} finally { | |||
if (fis != null) { | |||
fis.close(); | |||
} | |||
if (bos != null) { | |||
bos.close(); | |||
} | |||
} | |||
return buffer; | |||
public String getConsensusProvider() { | |||
return consensusProvider; | |||
} | |||
public int getConsensusParticipantCount() { | |||
@@ -118,21 +80,24 @@ public class LedgerInitProperties { | |||
public List<ConsensusParticipantConfig> getConsensusParticipants() { | |||
return consensusParticipants; | |||
} | |||
public ConsensusParticipantConfig[] getConsensusParticipantArray() { | |||
return consensusParticipants.toArray(new ConsensusParticipantConfig[consensusParticipants.size()]); | |||
public String[] getCryptoProviders() { | |||
return cryptoProviders.clone(); | |||
} | |||
public void setCryptoProviders(String[] cryptoProviders) { | |||
this.cryptoProviders = cryptoProviders; | |||
} | |||
/** | |||
* 返回参与者; | |||
* | |||
* @param address | |||
* 从 1 开始; 小于等于 {@link #getConsensusParticipantCount()}; | |||
* @param address 从 1 开始; 小于等于 {@link #getConsensusParticipantCount()}; | |||
* @return | |||
*/ | |||
public ConsensusParticipantConfig getConsensusParticipant(int id) { | |||
for (ConsensusParticipantConfig p : consensusParticipants) { | |||
if (p.getId()== id) { | |||
if (p.getId() == id) { | |||
return p; | |||
} | |||
} | |||
@@ -163,11 +128,31 @@ public class LedgerInitProperties { | |||
} | |||
private static LedgerInitProperties resolve(Properties props) { | |||
String hexLedgerSeed = getProperty(props, LEDGER_SEED).replace("-", ""); | |||
String hexLedgerSeed = PropertiesUtils.getRequiredProperty(props, LEDGER_SEED).replace("-", ""); | |||
byte[] ledgerSeed = HexUtils.decode(hexLedgerSeed); | |||
LedgerInitProperties setting = new LedgerInitProperties(ledgerSeed); | |||
LedgerInitProperties initProps = new LedgerInitProperties(ledgerSeed); | |||
// 解析共识相关的属性; | |||
initProps.consensusProvider = PropertiesUtils.getRequiredProperty(props, CONSENSUS_SERVICE_PROVIDER); | |||
String consensusConfigFilePath = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONFIG); | |||
try { | |||
File consensusConfigFile = ResourceUtils.getFile(consensusConfigFilePath); | |||
initProps.consensusConfig = FileUtils.readProperties(consensusConfigFile); | |||
} catch (FileNotFoundException e) { | |||
throw new IllegalArgumentException( | |||
String.format("Consensus config file[%s] doesn't exist! ", consensusConfigFilePath), e); | |||
} | |||
int partCount = getInt(getProperty(props, PART_COUNT)); | |||
// 解析密码提供者列表; | |||
String cryptoProviderNames = PropertiesUtils.getProperty(props, CRYPTO_SERVICE_PROVIDERS, true); | |||
String[] cryptoProviders = cryptoProviderNames.split(CRYPTO_SERVICE_PROVIDERS_SPLITTER); | |||
for (int i = 0; i < cryptoProviders.length; i++) { | |||
cryptoProviders[i] = cryptoProviders[i].trim(); | |||
} | |||
initProps.cryptoProviders = cryptoProviders; | |||
// 解析参与方节点列表; | |||
int partCount = getInt(PropertiesUtils.getRequiredProperty(props, PART_COUNT)); | |||
if (partCount < 0) { | |||
throw new IllegalArgumentException(String.format("Property[%s] is negative!", PART_COUNT)); | |||
} | |||
@@ -180,62 +165,40 @@ public class LedgerInitProperties { | |||
parti.setId(i); | |||
String nameKey = getKeyOfCsParti(i, PART_NAME); | |||
parti.setName(getProperty(props, nameKey)); | |||
parti.setName(PropertiesUtils.getRequiredProperty(props, nameKey)); | |||
String pubkeyPathKey = getKeyOfCsParti(i, PART_PUBKEY_PATH); | |||
parti.setPubKeyPath(getProperty(props, pubkeyPathKey)); | |||
String pubkeyPath = PropertiesUtils.getProperty(props, pubkeyPathKey, false); | |||
String pubkeyKey = getKeyOfCsParti(i, PART_PUBKEY); | |||
String base58PubKey = getProperty(props, pubkeyKey); | |||
String base58PubKey = PropertiesUtils.getProperty(props, pubkeyKey, false); | |||
if (base58PubKey != null) { | |||
PubKey pubKey = KeyGenCommand.decodePubKey(base58PubKey); | |||
parti.setPubKey(pubKey); | |||
} else if (pubkeyPath != null) { | |||
PubKey pubKey = KeyGenCommand.readPubKey(pubkeyPath); | |||
parti.setPubKey(pubKey); | |||
} else { | |||
throw new IllegalArgumentException( | |||
String.format("Property[%s] and property[%s] are all empty!", pubkeyKey, pubkeyPathKey)); | |||
} | |||
// String consensusHostKey = getKeyOfCsParti(i, PART_CONSENSUS_HOST); | |||
// String consensusHost = getProperty(props, consensusHostKey); | |||
// | |||
// String consensusPortKey = getKeyOfCsParti(i, PART_CONSENSUS_PORT); | |||
// int consensusPort = getInt(getProperty(props, consensusPortKey)); | |||
// | |||
// String consensusSecureKey = getKeyOfCsParti(i, PART_CONSENSUS_SECURE); | |||
// boolean consensusSecure = Boolean.parseBoolean(getProperty(props, | |||
// consensusSecureKey)); | |||
// NetworkAddress consensusAddress = new NetworkAddress(consensusHost, | |||
// consensusPort, consensusSecure); | |||
// parti.setConsensusAddress(consensusAddress); | |||
String initializerHostKey = getKeyOfCsParti(i, PART_INITIALIZER_HOST); | |||
String initializerHost = getProperty(props, initializerHostKey); | |||
String initializerHost = PropertiesUtils.getRequiredProperty(props, initializerHostKey); | |||
String initializerPortKey = getKeyOfCsParti(i, PART_INITIALIZER_PORT); | |||
int initializerPort = getInt(getProperty(props, initializerPortKey)); | |||
int initializerPort = getInt(PropertiesUtils.getRequiredProperty(props, initializerPortKey)); | |||
String initializerSecureKey = getKeyOfCsParti(i, PART_INITIALIZER_SECURE); | |||
boolean initializerSecure = Boolean.parseBoolean(getProperty(props, initializerSecureKey)); | |||
boolean initializerSecure = Boolean | |||
.parseBoolean(PropertiesUtils.getRequiredProperty(props, initializerSecureKey)); | |||
NetworkAddress initializerAddress = new NetworkAddress(initializerHost, initializerPort, initializerSecure); | |||
parti.setInitializerAddress(initializerAddress); | |||
setting.addConsensusParticipant(parti); | |||
initProps.addConsensusParticipant(parti); | |||
} | |||
return setting; | |||
} | |||
private static String getProperty(Properties props, String key) { | |||
return getProperty(props, key, true); | |||
} | |||
private static String getProperty(Properties props, String key, boolean required) { | |||
String value = props.getProperty(key); | |||
if (value == null) { | |||
if (required) { | |||
throw new IllegalArgumentException("Miss property[" + key + "]!"); | |||
} | |||
return null; | |||
} | |||
value = value.trim(); | |||
return value.length() == 0 ? null : value; | |||
return initProps; | |||
} | |||
private static int getInt(String strInt) { | |||
@@ -249,14 +212,14 @@ public class LedgerInitProperties { | |||
* | |||
*/ | |||
public static class ConsensusParticipantConfig implements ParticipantNode { | |||
private int id; | |||
private String address; | |||
private String name; | |||
private String pubKeyPath; | |||
// private String pubKeyPath; | |||
private PubKey pubKey; | |||
@@ -271,7 +234,7 @@ public class LedgerInitProperties { | |||
public void setId(int id) { | |||
this.id = id; | |||
} | |||
@Override | |||
public String getAddress() { | |||
return address; | |||
@@ -285,13 +248,13 @@ public class LedgerInitProperties { | |||
this.name = name; | |||
} | |||
public String getPubKeyPath() { | |||
return pubKeyPath; | |||
} | |||
public void setPubKeyPath(String pubKeyPath) { | |||
this.pubKeyPath = pubKeyPath; | |||
} | |||
// public String getPubKeyPath() { | |||
// return pubKeyPath; | |||
// } | |||
// | |||
// public void setPubKeyPath(String pubKeyPath) { | |||
// this.pubKeyPath = pubKeyPath; | |||
// } | |||
public NetworkAddress getInitializerAddress() { | |||
return initializerAddress; | |||
@@ -2,8 +2,6 @@ package com.jd.blockchain.tools.initializer; | |||
import java.io.File; | |||
import java.io.InputStream; | |||
import java.net.URI; | |||
import java.nio.file.Path; | |||
import java.util.Properties; | |||
import com.jd.blockchain.utils.PathUtils; | |||
@@ -30,17 +28,11 @@ public class LocalConfig { | |||
// 账本数据库的连接口令; | |||
public static final String LEDGER_DB_PWD = "ledger.db.pwd"; | |||
// 账本消息队列的地址 | |||
// public static final String LEDGER_MQ_SERVER = "ledger.mq.server"; | |||
// | |||
// // 账本消息队列的主题 | |||
// public static final String LEDGER_MQ_TOPIC = "ledger.mq.topic"; | |||
// 共识系统的参数配置;必须参数; | |||
public static final String CONSENSUS_CONF = "consensus.conf"; | |||
// 共识系统的参数配置;必须参数; | |||
public static final String CONSENSUS_SERVICE_PROVIDER = "consensus.service-provider"; | |||
// // 共识系统的参数配置;必须参数; | |||
// public static final String CONSENSUS_CONF = "consensus.conf"; | |||
// | |||
// // 共识系统的参数配置;必须参数; | |||
// public static final String CONSENSUS_SERVICE_PROVIDER = "consensus.service-provider"; | |||
private LocalParticipantConfig local = new LocalParticipantConfig(); | |||
@@ -48,10 +40,9 @@ public class LocalConfig { | |||
private DBConnectionConfig storagedDb = new DBConnectionConfig(); | |||
// private MQConnectionConfig handleMq = new MQConnectionConfig(); | |||
private String consensusConfig; | |||
private String consensusProvider; | |||
// private String consensusConfig; | |||
// private String consensusProvider; | |||
public LocalParticipantConfig getLocal() { | |||
return local; | |||
@@ -77,22 +68,6 @@ public class LocalConfig { | |||
this.storagedDb = storagedDb; | |||
} | |||
// public MQConnectionConfig getHandleMq() { | |||
// return handleMq; | |||
// } | |||
// | |||
// public void setHandleMq(MQConnectionConfig handleMq) { | |||
// this.handleMq = handleMq; | |||
// } | |||
public String getConsensusConfig() { | |||
return consensusConfig; | |||
} | |||
public void setConsensusConfig(String consensusConfig) { | |||
this.consensusConfig = consensusConfig; | |||
} | |||
public static LocalConfig resolve(String initSettingFile) { | |||
Properties props = FileUtils.readProperties(initSettingFile, "UTF-8"); | |||
return resolve(props, initSettingFile); | |||
@@ -118,17 +93,12 @@ public class LocalConfig { | |||
if (initSettingFile == null) { | |||
conf.bindingOutDir = PropertiesUtils.getRequiredProperty(props, LEDGER_BINDING_OUT); | |||
conf.consensusConfig = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONF); | |||
} else { | |||
String bindingOutDir = PropertiesUtils.getRequiredProperty(props, LEDGER_BINDING_OUT); | |||
String consensusConfig = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONF); | |||
String initSettingDir = PathUtils.concatPaths(initSettingFile, "../"); | |||
conf.bindingOutDir = absolutePath(initSettingDir, bindingOutDir); | |||
conf.consensusConfig = absolutePath(initSettingDir, consensusConfig); | |||
} | |||
conf.consensusProvider = PropertiesUtils.getRequiredProperty(props, CONSENSUS_SERVICE_PROVIDER); | |||
return conf; | |||
} | |||
@@ -141,18 +111,6 @@ public class LocalConfig { | |||
return absolutePath; | |||
} | |||
private static int getInt(String strInt) { | |||
return Integer.parseInt(strInt.trim()); | |||
} | |||
public String getConsensusProvider() { | |||
return consensusProvider; | |||
} | |||
public void setConsensusProvider(String consensusProvider) { | |||
this.consensusProvider = consensusProvider; | |||
} | |||
/** | |||
* 当前参与方的本地配置信息; | |||
* | |||
@@ -192,12 +150,4 @@ public class LocalConfig { | |||
} | |||
public static void main(String[] args) { | |||
String currPath = "/Users/zhanglin33/Ddisk/20mintest/0/config/init/local.conf"; | |||
// String settingPath = "../"; | |||
String settingPath = "bftsmart.config"; | |||
String path = absolutePath(PathUtils.concatPaths(currPath, "../"), settingPath); | |||
System.out.println(path); | |||
} | |||
} |
@@ -2,6 +2,28 @@ package com.jd.blockchain.tools.initializer; | |||
public interface Prompter { | |||
//定义一些常用的问答常量; | |||
/** | |||
* 询问是或否; | |||
*/ | |||
public static final String QUESTION_YESNO = "YES/NO"; | |||
/** | |||
* 提示按任意键继续; | |||
*/ | |||
public static final String PROMPT_ANYKEY_TO_CONTINUE = "ANYKEY"; | |||
/** | |||
* | |||
*/ | |||
public static final String ANSWER_YES = "Y"; | |||
public static final String ANSWER_NO = "N"; | |||
void info(String format, Object... args); | |||
void error(String format, Object... args); | |||
@@ -5,6 +5,7 @@ import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Comparator; | |||
import java.util.List; | |||
import java.util.Properties; | |||
import java.util.Random; | |||
import java.util.concurrent.CountDownLatch; | |||
import java.util.concurrent.TimeUnit; | |||
@@ -18,14 +19,17 @@ import org.springframework.web.bind.annotation.RestController; | |||
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.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
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.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainIdentity; | |||
import com.jd.blockchain.ledger.BlockchainIdentityData; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
@@ -53,11 +57,11 @@ import com.jd.blockchain.tools.initializer.LedgerInitException; | |||
import com.jd.blockchain.tools.initializer.LedgerInitProcess; | |||
import com.jd.blockchain.tools.initializer.LedgerInitProperties; | |||
import com.jd.blockchain.tools.initializer.LedgerInitProperties.ConsensusParticipantConfig; | |||
import com.jd.blockchain.tools.initializer.Prompter; | |||
import com.jd.blockchain.transaction.DigitalSignatureBlob; | |||
import com.jd.blockchain.transaction.LedgerInitSettingData; | |||
import com.jd.blockchain.transaction.TxBuilder; | |||
import com.jd.blockchain.transaction.TxRequestBuilder; | |||
import com.jd.blockchain.tools.initializer.Prompter; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.concurrent.InvocationResult; | |||
import com.jd.blockchain.utils.io.BytesUtils; | |||
@@ -76,8 +80,11 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
DataContractRegistry.register(TransactionRequest.class); | |||
} | |||
private static final String[] SUPPORTED_PROVIDERS = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
private static final String DEFAULT_SIGN_ALGORITHM = "ED25519"; | |||
private final SignatureFunction SIGN_FUNC; | |||
private volatile LedgerInitPermission localPermission; | |||
@@ -122,7 +129,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
public LedgerInitializeWebController(LedgerManage ledgerManager, DbConnectionFactory dbConnFactory, | |||
InitConsensusServiceFactory initCsServiceFactory) { | |||
this.SIGN_FUNC = Crypto.getSignatureFunction(DEFAULT_SIGN_ALGORITHM); | |||
this.ledgerManager = ledgerManager; | |||
this.dbConnFactory = dbConnFactory; | |||
this.initCsServiceFactory = initCsServiceFactory; | |||
@@ -148,36 +155,39 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
this.prompter = prompter; | |||
} | |||
public ConsensusProvider getConsensusProvider() { | |||
return consensusProvider; | |||
} | |||
// private ConsensusProvider getConsensusProvider() { | |||
// return consensusProvider; | |||
// } | |||
public void setConsensusProvider(ConsensusProvider consensusProvider) { | |||
private void setConsensusProvider(ConsensusProvider consensusProvider) { | |||
this.consensusProvider = consensusProvider; | |||
} | |||
@Override | |||
public HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
ConsensusSettings csSettings, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter) { | |||
return initialize(currentId, privKey, ledgerInitProps, csSettings, csProvider, dbConnConfig, prompter, | |||
createDefaultCryptoSetting()); | |||
DBConnectionConfig dbConnConfig, Prompter prompter) { | |||
return initialize(currentId, privKey, ledgerInitProps, dbConnConfig, prompter, createDefaultCryptoSetting()); | |||
} | |||
@Override | |||
public HashDigest initialize(int currentId, PrivKey privKey, LedgerInitProperties ledgerInitProps, | |||
ConsensusSettings consensusProps, ConsensusProvider csProvider, DBConnectionConfig dbConnConfig, | |||
Prompter prompter, CryptoSetting cryptoSetting) { | |||
DBConnectionConfig dbConnConfig, Prompter prompter, CryptoSetting cryptoSetting) { | |||
if (this.ledgerInitSetting != null) { | |||
throw new IllegalStateException("ledger init process has already started."); | |||
} | |||
setPrompter(prompter); | |||
Properties csProps = ledgerInitProps.getConsensusConfig(); | |||
ConsensusProvider csProvider = ConsensusProviders.getProvider(ledgerInitProps.getConsensusProvider()); | |||
ConsensusSettings csSettings = csProvider.getSettingsFactory().getConsensusSettingsBuilder() | |||
.createSettings(csProps); | |||
setConsensusProvider(csProvider); | |||
prompter.info("Init settings and sign permision..."); | |||
prepareLocalPermission(currentId, privKey, ledgerInitProps, consensusProps, cryptoSetting); | |||
prepareLocalPermission(currentId, privKey, ledgerInitProps, csSettings, cryptoSetting); | |||
prompter.confirm(InitializingStep.PERMISSION_READY.toString(), | |||
"Ledger init permission has already prepared! Any key to continue..."); | |||
@@ -230,7 +240,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
this.decisions[i] = new DecisionResultHandle(i); | |||
} | |||
// 预置当前参与方的“决定”到列表,避免向自己发起请求; | |||
this.decisions[currentId].setResult(localDecision); | |||
this.decisions[currentId].setValue(localDecision); | |||
return localDecision; | |||
} | |||
@@ -299,7 +309,12 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
} | |||
public CryptoSetting createDefaultCryptoSetting() { | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig defCryptoSetting = new CryptoConfig(); | |||
defCryptoSetting.setSupportedProviders(supportedProviders); | |||
defCryptoSetting.setAutoVerifyHash(true); | |||
defCryptoSetting.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); | |||
@@ -318,7 +333,9 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
LedgerInitSettingData initSetting = new LedgerInitSettingData(); | |||
initSetting.setLedgerSeed(ledgerProps.getLedgerSeed()); | |||
initSetting.setCryptoSetting(cryptoSetting); | |||
ConsensusParticipantConfig[] parties = ledgerProps.getConsensusParticipantArray(); | |||
List<ConsensusParticipantConfig> partiList = ledgerProps.getConsensusParticipants(); | |||
ConsensusParticipantConfig[] parties = partiList.toArray(new ConsensusParticipantConfig[partiList.size()]); | |||
ConsensusParticipantConfig[] orderedParties = sortAndVerify(parties); | |||
initSetting.setConsensusParticipants(orderedParties); | |||
@@ -447,7 +464,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
List<String> waitingIds = new ArrayList<>(); | |||
for (int i = 0; i < results.length; i++) { | |||
if (results[i] != null) { | |||
if (results[i].getResult() == null) { | |||
if (results[i].getValue() == null) { | |||
waitingIds.add("" + (i + 1)); | |||
} | |||
} | |||
@@ -474,7 +491,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
continue; | |||
} | |||
PubKey pubKey = participants[i].getPubKey(); | |||
LedgerInitPermission permission = (LedgerInitPermission) results[i].getResult(); | |||
LedgerInitPermission permission = (LedgerInitPermission) results[i].getValue(); | |||
if (permission.getParticipantId() != participants[i].getId()) { | |||
prompter.error("\r\nThe id of received permission isn't equal to it's participant ! --[Id=%s][name=%s]", | |||
participants[i].getAddress(), participants[i].getName()); | |||
@@ -525,7 +542,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
public void run() { | |||
try { | |||
LedgerInitPermission permission = initConsensus.requestPermission(currentId, reqAuthSign); | |||
result.setResult(permission); | |||
result.setValue(permission); | |||
} catch (Exception e) { | |||
result.setError(e); | |||
} finally { | |||
@@ -595,7 +612,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
while (!allDecided) { | |||
allDecided = true; | |||
for (int i = 0; i < randDecHdls.length; i++) { | |||
if (randDecHdls[i].getResult() != null) { | |||
if (randDecHdls[i].getValue() != null) { | |||
// 忽略当前参与方自己(在初始化“决定”时已经置为非空),以及已经收到主动提交“决定”的参与方; | |||
continue; | |||
} | |||
@@ -636,10 +653,11 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
try { | |||
targetDecision = initConsensus.synchronizeDecision(localDecision); | |||
} catch (Exception e1) { | |||
prompter.info("Error occurred on synchronizing decision . --%s", e1.getMessage()); | |||
prompter.info("Error occurred on synchronizing decision . --[%s] %s", e1.getClass().getName(), | |||
e1.getMessage()); | |||
} | |||
if (targetDecision == null) { | |||
if (resultHandle.getResult() != null) { | |||
if (resultHandle.getValue() != null) { | |||
// 已经验证过; | |||
return true; | |||
} | |||
@@ -666,7 +684,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
} | |||
} while (targetDecision == null); | |||
if (targetDecision.getParticipantId() != targetId && resultHandle.getResult() == null) { | |||
if (targetDecision.getParticipantId() != targetId && resultHandle.getValue() == null) { | |||
prompter.error( | |||
"The received id of participant isn't equal to id of request target participant! --[Id=%s]", | |||
targetId); | |||
@@ -684,7 +702,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
/** | |||
* 校验并记录指定的参与方做出的决定; | |||
* <p> | |||
* 注:对 {@link DecisionResultHandle#setResult(LedgerInitDecision)} | |||
* 注:对 {@link DecisionResultHandle#setValue(LedgerInitDecision)} | |||
* 方法的调用不是线程安全的,但由于是在满足有效性校验之后才调用,具有幂等性,所以不必对该方法的多处调用进行同步; | |||
* | |||
* @param targetDecision | |||
@@ -695,7 +713,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
private synchronized boolean validateAndRecordDecision(LedgerInitDecision targetDecision, | |||
DecisionResultHandle resultHandle) { | |||
if ((!localDecision.getLedgerHash().equals(targetDecision.getLedgerHash())) | |||
&& resultHandle.getResult() == null) { | |||
&& resultHandle.getValue() == null) { | |||
// 如果结果已经被 | |||
prompter.error( | |||
"The received ledger hash of participant isn't equal to ledger hash of current participant! --[Id=%s]", | |||
@@ -708,13 +726,13 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
.getPubKey(); | |||
byte[] deciBytes = getDecisionBytes(targetDecision.getParticipantId(), targetDecision.getLedgerHash()); | |||
if ((!SIGN_FUNC.verify(targetDecision.getSignature(), targetPubKey, deciBytes)) | |||
&& resultHandle.getResult() == null) { | |||
&& resultHandle.getValue() == null) { | |||
prompter.error("The signature of received decision is invalid! --[Id=%s]", | |||
targetDecision.getParticipantId()); | |||
return false; | |||
} | |||
resultHandle.setResult(targetDecision); | |||
resultHandle.setValue(targetDecision); | |||
return true; | |||
} | |||
@@ -723,20 +741,38 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI | |||
public LedgerInitDecision synchronizeDecision(@RequestBody LedgerInitDecision initDecision) { | |||
int remoteId = initDecision.getParticipantId(); | |||
if (remoteId == currentId) { | |||
prompter.error("Reject decision because of self-synchronization! --[Id=%s]", remoteId); | |||
throw new LedgerInitException( | |||
String.format("Reject decision because of self-synchronization! --[Id=%s]", remoteId)); | |||
} | |||
if (this.genesisBlock == null) { | |||
// 当前参与者尚未准备就绪,返回 null; | |||
prompter.info("Not ready for genesis block! --[RemoteId=%s][CurrentId=%s]", remoteId, currentId); | |||
return null; | |||
} | |||
DecisionResultHandle resultHandle = this.decisions[remoteId]; | |||
if (!validateAndRecordDecision(initDecision, resultHandle)) { | |||
// 签名无效; | |||
prompter.info("Received request of synchronizing decision! --[RemoteId=%s][CurrentId=%s]", remoteId, currentId); | |||
try { | |||
DecisionResultHandle resultHandle = this.decisions[remoteId]; | |||
if (!validateAndRecordDecision(initDecision, resultHandle)) { | |||
// 签名无效; | |||
prompter.error("Reject decision because of invalid signature! --[RemoteId=%s][CurrentId=%s]", remoteId, | |||
currentId); | |||
throw new LedgerInitException( | |||
String.format("Reject decision because of invalid signature! --[RemoteId=%s][CurrentId=%s]", | |||
remoteId, currentId)); | |||
} | |||
return localDecision; | |||
} catch (Exception e) { | |||
prompter.error(e, | |||
"Error occurred while receiving the request of synchronizing decision! --[RemoteId=%s][CurrentId=%s] %s", | |||
remoteId, currentId, e.getMessage()); | |||
throw new LedgerInitException( | |||
String.format("Reject decision because of invalid signature! --[Id=%s]", remoteId)); | |||
"Error occurred while receiving the request of synchronizing decision! --" + e.getMessage(), e); | |||
} | |||
return localDecision; | |||
} | |||
/** | |||
@@ -16,10 +16,3 @@ ledger.db.uri=redis://127.0.0.1/0 | |||
#账本数据库的连接口令; | |||
ledger.db.pwd= | |||
#共识协议的参数配置;必须参数; | |||
consensus.conf=mq.config | |||
#共识协议的实现类型;必须参数; | |||
consensus.service-provider=com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider | |||
@@ -1,14 +1,7 @@ | |||
package com.jd.blockchain.utils; | |||
import java.lang.reflect.Array; | |||
import java.util.Collections; | |||
import java.util.HashSet; | |||
import java.util.Iterator; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import java.util.Set; | |||
import java.util.SortedSet; | |||
import java.util.TreeSet; | |||
import java.util.*; | |||
/** | |||
* @author haiq | |||
@@ -83,5 +76,4 @@ public abstract class ArrayUtils { | |||
} | |||
return new ReadonlyArrayListWrapper<T>(array, fromIndex, toIndex); | |||
} | |||
} |
@@ -37,9 +37,10 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 创建配置对象的实例,并且从指定的属性表中初始化对应的实例字段; | |||
* | |||
* @param configClass configClass | |||
* @param properties properties | |||
* @param <T> T | |||
* @param properties properties | |||
* @param <T> T | |||
* @return T | |||
*/ | |||
@SuppressWarnings("unchecked") | |||
@@ -56,13 +57,10 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 创建配置对象的实例,并且从指定的属性表中初始化对应的实例字段; | |||
* | |||
* @param configClass | |||
* 配置对象的类型; | |||
* @param properties | |||
* 属性表; | |||
* @param propsPrefix | |||
* 在属性表中与配置对象相关的属性的key的前缀; | |||
* @param <T> T | |||
* @param configClass 配置对象的类型; | |||
* @param properties 属性表; | |||
* @param propsPrefix 在属性表中与配置对象相关的属性的key的前缀; | |||
* @param <T> T | |||
* @return T | |||
*/ | |||
public static <T> T createInstance(Class<T> configClass, Properties properties, String propsPrefix) { | |||
@@ -77,12 +75,9 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 设置配置值; | |||
* | |||
* @param obj | |||
* 配置对象;配置值将设置到此对象匹配的属性; | |||
* @param configValues | |||
* 配置值; | |||
* @param propPrefix | |||
* 自动加入的属性前缀; | |||
* @param obj 配置对象;配置值将设置到此对象匹配的属性; | |||
* @param configValues 配置值; | |||
* @param propPrefix 自动加入的属性前缀; | |||
*/ | |||
public static void setValues(Object obj, Properties configValues, String propPrefix) { | |||
Properties values = new Properties(); | |||
@@ -93,10 +88,8 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 设置配置值; | |||
* | |||
* @param obj | |||
* 配置对象;配置值将设置到此对象匹配的属性; | |||
* @param configValues | |||
* 配置值; | |||
* @param obj 配置对象;配置值将设置到此对象匹配的属性; | |||
* @param configValues 配置值; | |||
*/ | |||
public static void setValues(Object obj, Properties configValues) { | |||
BeanWrapper confBean = new BeanWrapperImpl(obj); | |||
@@ -109,13 +102,10 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 从指定的路径加载配置; | |||
* | |||
* @param configClass | |||
* 配置对象的类型; | |||
* @param configFilePathPattern | |||
* properties配置文件的路径;可以指定 spring 资源路径表达式; | |||
* @param charset | |||
* 字符集; | |||
* @param <T> class | |||
* @param configClass 配置对象的类型; | |||
* @param configFilePathPattern properties配置文件的路径;可以指定 spring 资源路径表达式; | |||
* @param charset 字符集; | |||
* @param <T> class | |||
* @return T | |||
* @throws IOException exception | |||
*/ | |||
@@ -127,12 +117,9 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 从指定的路径加载配置; | |||
* | |||
* @param obj | |||
* 配置对象;配置文件的值将设置到此对象匹配的属性; | |||
* @param configFilePathPattern | |||
* properties配置文件的路径;可以指定 spring 资源路径表达式; | |||
* @param charset | |||
* 字符集; | |||
* @param obj 配置对象;配置文件的值将设置到此对象匹配的属性; | |||
* @param configFilePathPattern properties配置文件的路径;可以指定 spring 资源路径表达式; | |||
* @param charset 字符集; | |||
* @throws IOException exception | |||
*/ | |||
public static void load(Object obj, String configFilePathPattern, String charset) throws IOException { | |||
@@ -180,10 +167,8 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 合并两个 properties ; | |||
* | |||
* @param props | |||
* 要将其它值合并进来的属性集合;操作将对其产生修改; | |||
* @param from | |||
* 属性值将要合并进入其它属性集合;操作不对其产生修改; | |||
* @param props 要将其它值合并进来的属性集合;操作将对其产生修改; | |||
* @param from 属性值将要合并进入其它属性集合;操作不对其产生修改; | |||
*/ | |||
public static void mergeFrom(Properties props, Properties from) { | |||
mergeFrom(props, from, null); | |||
@@ -192,12 +177,9 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 合并两个 properties ; | |||
* | |||
* @param props | |||
* 要将其它值合并进来的属性集合;操作将对其产生修改; | |||
* @param from | |||
* 属性值将要合并进入其它属性集合;操作不对其产生修改; | |||
* @param propertyNamePrefix | |||
* 属性名称前缀; | |||
* @param props 要将其它值合并进来的属性集合;操作将对其产生修改; | |||
* @param from 属性值将要合并进入其它属性集合;操作不对其产生修改; | |||
* @param propertyNamePrefix 属性名称前缀; | |||
*/ | |||
public static void mergeFrom(Properties props, Properties from, String propertyNamePrefix) { | |||
if (propertyNamePrefix == null || propertyNamePrefix.length() == 0) { | |||
@@ -214,12 +196,9 @@ public abstract class PropertiesUtils { | |||
/** | |||
* 获取指定 properties 中以指定的前缀开头的子集; | |||
* | |||
* @param props | |||
* 要抽取的属性集合; | |||
* @param propertyNamePrefix | |||
* 属性名称前缀; | |||
* @param trimPrefix | |||
* 是否在复制的新的属性集合去掉指定的前缀; | |||
* @param props 要抽取的属性集合; | |||
* @param propertyNamePrefix 属性名称前缀; | |||
* @param trimPrefix 是否在复制的新的属性集合去掉指定的前缀; | |||
* @return properties | |||
*/ | |||
public static Properties subset(Properties props, String propertyNamePrefix, boolean trimPrefix) { | |||
@@ -278,13 +257,22 @@ public abstract class PropertiesUtils { | |||
* 如果不存在,或者返回值为空(null 或 空白字符),则抛出 {@link IllegalArgumentException} 异常; | |||
* | |||
* @param props props | |||
* @param key key | |||
* @param key key | |||
* @return String | |||
*/ | |||
public static String getRequiredProperty(Properties props, String key) { | |||
return getProperty(props, key, true); | |||
} | |||
/** | |||
* 返回指定的属性; <br> | |||
* | |||
* @param props 属性表; | |||
* @param key 要查找的 key; | |||
* @param required 值为 false 时,如果不存在则返回 null;值为 true 时,如果不存在,或者返回值为空(null 或 | |||
* 空白字符),则抛出 {@link IllegalArgumentException} 异常; | |||
* @return | |||
*/ | |||
public static String getProperty(Properties props, String key, boolean required) { | |||
String value = props.getProperty(key); | |||
if (value == null) { | |||
@@ -319,7 +307,7 @@ public abstract class PropertiesUtils { | |||
setValues(props, propValues); | |||
return props; | |||
} | |||
public static Properties setValues(Properties props, Property[] propValues) { | |||
for (Property p : propValues) { | |||
props.setProperty(p.getName(), p.getValue()); | |||
@@ -0,0 +1,24 @@ | |||
package com.jd.blockchain.utils; | |||
import java.util.regex.Pattern; | |||
/** | |||
* @Author zhaogw | |||
* date 2018/11/26 20:46 | |||
*/ | |||
public class StringUtils { | |||
public static boolean isEmpty(Object str) { | |||
return str == null || "".equals(str); | |||
} | |||
/* | |||
* 判断是否为整数 | |||
* @param str 传入的字符串 | |||
* @return 是整数返回true,否则返回false | |||
*/ | |||
public static boolean isNumber(String str) { | |||
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); | |||
return pattern.matcher(str).matches(); | |||
} | |||
} |
@@ -2,16 +2,16 @@ package com.jd.blockchain.utils.concurrent; | |||
public class InvocationResult<T> { | |||
private volatile T result; | |||
private volatile T value; | |||
private volatile Exception error; | |||
public T getResult() { | |||
return result; | |||
public T getValue() { | |||
return value; | |||
} | |||
public void setResult(T result) { | |||
this.result = result; | |||
public void setValue(T value) { | |||
this.value = value; | |||
} | |||
public Exception getError() { | |||
@@ -1,9 +1,23 @@ | |||
package com.jd.blockchain.utils.io; | |||
import java.io.*; | |||
import java.io.BufferedOutputStream; | |||
import java.io.BufferedReader; | |||
import java.io.BufferedWriter; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.FileNotFoundException; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.InputStreamReader; | |||
import java.io.OutputStream; | |||
import java.io.OutputStreamWriter; | |||
import java.io.Reader; | |||
import java.util.ArrayList; | |||
import java.util.Properties; | |||
import org.springframework.util.ResourceUtils; | |||
/** | |||
* @author haiq | |||
* | |||
@@ -41,7 +55,7 @@ public class FileUtils { | |||
throw new IllegalStateException(e.getMessage(), e); | |||
} | |||
} | |||
/** | |||
* 返回父目录的路径; | |||
* | |||
@@ -67,9 +81,8 @@ public class FileUtils { | |||
/** | |||
* 读取指定文件的首行; | |||
* | |||
* @param file file | |||
* @param charset | |||
* 字符集; | |||
* @param file file | |||
* @param charset 字符集; | |||
* @return 返回首行非空行;返回结果不会自动截取两头的空字符串; | |||
* @throws IOException exception | |||
*/ | |||
@@ -90,9 +103,8 @@ public class FileUtils { | |||
/** | |||
* 返回指定文件的所有行; | |||
* | |||
* @param file file | |||
* @param charset | |||
* 字符集; | |||
* @param file file | |||
* @param charset 字符集; | |||
* @return 返回首行非空行;返回结果不会自动截取两头的空字符串; | |||
*/ | |||
public static String[] readLines(File file, String charset) { | |||
@@ -155,10 +167,8 @@ public class FileUtils { | |||
/** | |||
* 以默认字符集(UTF-8)将指定的文本保存到指定的文件中; | |||
* | |||
* @param file | |||
* 要保存的文件; | |||
* @param text | |||
* 文本内容; | |||
* @param file 要保存的文件; | |||
* @param text 文本内容; | |||
*/ | |||
public static void writeText(String text, File file) { | |||
writeText(text, file, DEFAULT_CHARSET); | |||
@@ -166,12 +176,10 @@ public class FileUtils { | |||
/** | |||
* 将指定的文本保存到指定的文件中; | |||
* @param text | |||
* 文本内容; | |||
* @param file | |||
* 要保存的文件; | |||
* @param charset | |||
* 字符集; | |||
* | |||
* @param text 文本内容; | |||
* @param file 要保存的文件; | |||
* @param charset 字符集; | |||
*/ | |||
public static void writeText(String text, File file, String charset) { | |||
try (FileOutputStream out = new FileOutputStream(file, false)) { | |||
@@ -181,7 +189,7 @@ public class FileUtils { | |||
throw new RuntimeIOException(e.getMessage(), e); | |||
} | |||
} | |||
public static void writeBytes(byte[] content, File file) { | |||
try (FileOutputStream out = new FileOutputStream(file, false)) { | |||
out.write(content); | |||
@@ -190,7 +198,7 @@ public class FileUtils { | |||
throw new RuntimeIOException(e.getMessage(), e); | |||
} | |||
} | |||
public static void appendBytes(byte[] content, File file) { | |||
try (FileOutputStream out = new FileOutputStream(file, true)) { | |||
out.write(content); | |||
@@ -224,16 +232,23 @@ public class FileUtils { | |||
/** | |||
* 以默认字符集(UTF-8)从文件读取文本; | |||
* | |||
* @param file file | |||
* @return String | |||
*/ | |||
public static String readText(String file) { | |||
return readText(new File(file), DEFAULT_CHARSET); | |||
public static String readText(String filePath) { | |||
try { | |||
File file = ResourceUtils.getFile(filePath); | |||
return readText(file, DEFAULT_CHARSET); | |||
} catch (FileNotFoundException e) { | |||
throw new RuntimeIOException(e.getMessage(), e); | |||
} | |||
} | |||
/** | |||
* 从文件读取文本; | |||
* @param file file | |||
* | |||
* @param file file | |||
* @param charset charset | |||
* @return String | |||
*/ | |||
@@ -254,7 +269,7 @@ public class FileUtils { | |||
/** | |||
* 从文件读取文本; | |||
* | |||
* @param file file | |||
* @param file file | |||
* @param charset charset | |||
* @return String | |||
*/ | |||
@@ -278,7 +293,7 @@ public class FileUtils { | |||
/** | |||
* 从流读取文本; | |||
* | |||
* @param in in | |||
* @param in in | |||
* @param charset charset | |||
* @return String | |||
* @throws IOException exception | |||
@@ -310,7 +325,7 @@ public class FileUtils { | |||
throw new RuntimeIOException(e.getMessage(), e); | |||
} | |||
} | |||
public static byte[] readBytes(File file) { | |||
try { | |||
FileInputStream in = new FileInputStream(file); | |||
@@ -324,8 +339,12 @@ public class FileUtils { | |||
} | |||
} | |||
public static Properties readProperties(String systemConfig) { | |||
return readProperties(systemConfig, DEFAULT_CHARSET); | |||
public static Properties readProperties(String file) { | |||
return readProperties(file, DEFAULT_CHARSET); | |||
} | |||
public static Properties readProperties(File file) { | |||
return readProperties(file, DEFAULT_CHARSET); | |||
} | |||
public static Properties readProperties(String file, String charset) { | |||
@@ -417,11 +436,11 @@ public class FileUtils { | |||
throw new IllegalStateException(e.getMessage(), e); | |||
} | |||
} | |||
public static void deleteFile(String dir) { | |||
deleteFile(dir, false); | |||
} | |||
public static void deleteFile(File file) { | |||
deleteFile(file, false); | |||
} | |||
@@ -435,8 +454,7 @@ public class FileUtils { | |||
* 删除文件; | |||
* | |||
* @param file | |||
* @param silent | |||
* 是否静默删除;如果为 true ,则吞噬删除过程中的异常,意味着方法即便正常返回时也有可能删除不完全; | |||
* @param silent 是否静默删除;如果为 true ,则吞噬删除过程中的异常,意味着方法即便正常返回时也有可能删除不完全; | |||
*/ | |||
public static void deleteFile(File file, boolean silent) { | |||
if (file.isFile()) { | |||