@@ -23,9 +23,9 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { | |||
@Override | |||
public String toString() { | |||
return name + "[" + code + "]"; | |||
return name + "[" + (code & 0xFFFF) + "]"; | |||
} | |||
/** | |||
* 声明一项哈希算法; | |||
* | |||
@@ -100,7 +100,7 @@ public final class CryptoAlgorithmDefinition implements CryptoAlgorithm { | |||
short code = (short) (RANDOM_ALGORITHM | (uid & 0x00FF)); | |||
return new CryptoAlgorithmDefinition(name, code); | |||
} | |||
/** | |||
* 声明一项扩展的密码算法; | |||
* | |||
@@ -26,6 +26,17 @@ | |||
<artifactId>consensus-mq</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>crypto-classic</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>crypto-sm</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
@@ -15,16 +15,6 @@ | |||
<artifactId>consensus-framework</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>consensus-mq</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>consensus-bftsmart</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>ledger-rpc</artifactId> | |||
@@ -53,6 +43,13 @@ | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>crypto-classic</artifactId> | |||
<version>${project.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>commons-io</groupId> | |||
<artifactId>commons-io</artifactId> | |||
@@ -84,8 +81,11 @@ | |||
<artifactId>spring-boot-configuration-processor</artifactId> | |||
<optional>true</optional> | |||
</dependency> | |||
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> | |||
<optional>true</optional> </dependency> --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-devtools</artifactId> | |||
<optional>true</optional> | |||
</dependency> | |||
</dependencies> | |||
@@ -5,21 +5,20 @@ import com.jd.blockchain.ledger.CryptoSetting; | |||
public class CryptoConfig implements CryptoSetting { | |||
private CryptoAlgorithm hashAlgorithm; | |||
private short hashAlgorithm; | |||
private boolean autoVerifyHash; | |||
public CryptoConfig() { | |||
} | |||
public CryptoConfig(CryptoSetting setting) { | |||
this.hashAlgorithm = setting.getHashAlgorithm(); | |||
this.autoVerifyHash = setting.getAutoVerifyHash(); | |||
} | |||
@Override | |||
public CryptoAlgorithm getHashAlgorithm() { | |||
public short getHashAlgorithm() { | |||
return hashAlgorithm; | |||
} | |||
@@ -29,6 +28,10 @@ public class CryptoConfig implements CryptoSetting { | |||
} | |||
public void setHashAlgorithm(CryptoAlgorithm hashAlgorithm) { | |||
this.hashAlgorithm = hashAlgorithm.code(); | |||
} | |||
public void setHashAlgorithm(short hashAlgorithm) { | |||
this.hashAlgorithm = hashAlgorithm; | |||
} | |||
@@ -36,5 +39,4 @@ public class CryptoConfig implements CryptoSetting { | |||
this.autoVerifyHash = autoVerifyHash; | |||
} | |||
} |
@@ -593,6 +593,7 @@ public class MerkleTree implements Transactional { | |||
* 用于记录已更新节点的列表; | |||
* @return | |||
*/ | |||
@SuppressWarnings("unused") | |||
private int rehash(PathNode pathNode, List<AbstractMerkleNode> updatedNodes) { | |||
// int newDataCount = 0; | |||
boolean updated = false; | |||
@@ -1248,7 +1249,12 @@ public class MerkleTree implements Transactional { | |||
return (int) ((offset - offset % s) / s); | |||
} | |||
@SuppressWarnings("unused") | |||
private PathNode newEmptyChild(CryptoAlgorithm hashAlgorithm, int index) { | |||
return newEmptyChild(hashAlgorithm.code(), index); | |||
} | |||
private PathNode newEmptyChild(short hashAlgorithm, int index) { | |||
long newStartingSN = startingSN + subinterval * index; | |||
PathNode child = new PathNode(hashAlgorithm, newStartingSN, (byte) (level - 1), 0); | |||
attachChildNode(child, index); | |||
@@ -1437,8 +1443,13 @@ public class MerkleTree implements Transactional { | |||
this.dataNodeBytes = dataBytes; | |||
} | |||
@SuppressWarnings("unused") | |||
private static DataNode newDataNode(CryptoAlgorithm hashAlgorithm, long sn, Bytes key, long version, | |||
byte[] hashedData) { | |||
return newDataNode(hashAlgorithm.code(), sn, key, version, hashedData); | |||
} | |||
private static DataNode newDataNode(short hashAlgorithm, long sn, Bytes key, long version, byte[] hashedData) { | |||
// byte[] keyStrBytes = BytesUtils.toBytes(key); | |||
// int maskSize = NumberMask.SHORT.getMaskLength(keyStrBytes.length); | |||
int keySize = key.size(); | |||
@@ -34,7 +34,7 @@ public class MerkleTreeTest { | |||
Random rand = new Random(); | |||
CryptoSetting setting = Mockito.mock(CryptoSetting.class); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256.code()); | |||
when(setting.getAutoVerifyHash()).thenReturn(true); | |||
// 测试从空的树开始,顺序增加数据节点; | |||
@@ -85,7 +85,7 @@ public class MerkleTreeTest { | |||
@Test | |||
public void testSequenceInsert_OneCommit() { | |||
CryptoSetting setting = Mockito.mock(CryptoSetting.class); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256.code()); | |||
when(setting.getAutoVerifyHash()).thenReturn(true); | |||
// 测试从空的树开始,顺序增加数据节点; | |||
@@ -139,7 +139,7 @@ public class MerkleTreeTest { | |||
@Test | |||
public void testSequenceInsert_MultiCommit() { | |||
CryptoSetting setting = Mockito.mock(CryptoSetting.class); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256.code()); | |||
when(setting.getAutoVerifyHash()).thenReturn(true); | |||
// 测试从空的树开始,顺序增加数据节点; | |||
@@ -319,7 +319,7 @@ public class MerkleTreeTest { | |||
@Test | |||
public void testRandomInsert_MultiCommit() { | |||
CryptoSetting setting = Mockito.mock(CryptoSetting.class); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256.code()); | |||
when(setting.getAutoVerifyHash()).thenReturn(true); | |||
// 保存所有写入的数据节点的 SN-Hash 映射表; | |||
@@ -409,7 +409,7 @@ public class MerkleTreeTest { | |||
@Test | |||
public void testDataModify() { | |||
CryptoSetting setting = Mockito.mock(CryptoSetting.class); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256.code()); | |||
when(setting.getAutoVerifyHash()).thenReturn(true); | |||
// 保存所有写入的数据节点的 SN-Hash 映射表; | |||
@@ -492,7 +492,7 @@ public class MerkleTreeTest { | |||
@Test | |||
public void testDataVersionModify() { | |||
CryptoSetting setting = Mockito.mock(CryptoSetting.class); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256.code()); | |||
when(setting.getAutoVerifyHash()).thenReturn(true); | |||
// 保存所有写入的数据节点的 SN-Hash 映射表; | |||
@@ -559,7 +559,7 @@ public class MerkleTreeTest { | |||
@Test | |||
public void testMerkleReload() { | |||
CryptoSetting setting = Mockito.mock(CryptoSetting.class); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256); | |||
when(setting.getHashAlgorithm()).thenReturn(ClassicAlgorithm.SHA256.code()); | |||
when(setting.getAutoVerifyHash()).thenReturn(true); | |||
// 保存所有写入的数据节点的 SN-Hash 映射表; | |||
@@ -3,7 +3,6 @@ package com.jd.blockchain.ledger; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.consts.TypeCodes; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.utils.ValueType; | |||
/** | |||
@@ -12,7 +11,7 @@ import com.jd.blockchain.utils.ValueType; | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code= TypeCodes.METADATA_CRYPTO_SETTING) | |||
@DataContract(code = TypeCodes.METADATA_CRYPTO_SETTING) | |||
public interface CryptoSetting { | |||
/** | |||
@@ -24,9 +23,9 @@ public interface CryptoSetting { | |||
* | |||
* @return | |||
*/ | |||
@DataField(order=1, refEnum=true) | |||
public CryptoAlgorithm getHashAlgorithm(); | |||
@DataField(order = 1, primitiveType = ValueType.INT16) | |||
public short getHashAlgorithm(); | |||
/** | |||
* 当有完整性证明的数据被从持久化介质中加载时,是否对其进行完整性校验(重新计算 hash 比对是否一致); <br> | |||
* | |||
@@ -36,7 +35,7 @@ public interface CryptoSetting { | |||
* | |||
* @return | |||
*/ | |||
@DataField(order=2, primitiveType= ValueType.BOOLEAN) | |||
@DataField(order = 2, primitiveType = ValueType.BOOLEAN) | |||
public boolean getAutoVerifyHash(); | |||
} |
@@ -4,7 +4,6 @@ import com.jd.blockchain.binaryproto.BinaryEncodingUtils; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
import com.jd.blockchain.consensus.MessageService; | |||
import com.jd.blockchain.consensus.client.ConsensusClient; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
import com.jd.blockchain.crypto.CryptoServiceProviders; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
@@ -39,9 +38,9 @@ public class NodeSigningAppender implements TransactionService { | |||
private AsymmetricKeypair nodeKeyPair; | |||
private CryptoAlgorithm hashAlgorithm; | |||
private short hashAlgorithm; | |||
public NodeSigningAppender(CryptoAlgorithm hashAlgorithm, AsymmetricKeypair nodeKeyPair, ConsensusClient consensusClient) { | |||
public NodeSigningAppender(short hashAlgorithm, AsymmetricKeypair nodeKeyPair, ConsensusClient consensusClient) { | |||
this.hashAlgorithm = hashAlgorithm; | |||
this.nodeKeyPair = nodeKeyPair; | |||
this.consensusClient = consensusClient; | |||
@@ -20,6 +20,16 @@ | |||
<artifactId>crypto-framework</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>crypto-classic</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>crypto-sm</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>ledger-core</artifactId> | |||
@@ -47,11 +57,8 @@ | |||
<version>${project.version}</version> | |||
</dependency> | |||
<!-- <dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>consensus</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> --> | |||
<!-- <dependency> <groupId>com.jd.blockchain</groupId> <artifactId>consensus</artifactId> | |||
<version>${project.version}</version> </dependency> --> | |||
<dependency> | |||
<groupId>com.jd.blockchain</groupId> | |||
<artifactId>tools-keygen</artifactId> | |||
@@ -7,13 +7,18 @@ import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.UUID; | |||
import java.util.zip.ZipEntry; | |||
import java.util.zip.ZipOutputStream; | |||
import org.junit.Test; | |||
import org.springframework.core.io.ClassPathResource; | |||
import com.jd.blockchain.crypto.CryptoServiceProviders; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.HashFunction; | |||
import com.jd.blockchain.crypto.RandomFunction; | |||
import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||
import com.jd.blockchain.tools.initializer.LedgerBindingConfig; | |||
import com.jd.blockchain.tools.initializer.LedgerBindingConfig.BindingConfig; | |||
import com.jd.blockchain.utils.codec.Base58Utils; | |||
@@ -21,6 +26,15 @@ import com.jd.blockchain.utils.io.BytesUtils; | |||
public class LedgerBindingConfigTest { | |||
public static void main(String[] args) { | |||
//生成测试 | |||
HashFunction hashFunc = CryptoServiceProviders.getHashFunction(ClassicAlgorithm.SHA256); | |||
HashDigest hash1 = hashFunc.hash(UUID.randomUUID().toString().getBytes()); | |||
HashDigest hash2 = hashFunc.hash(UUID.randomUUID().toString().getBytes()); | |||
System.out.println("Hash1=[" + hash1.toBase58() + "]"); | |||
System.out.println("Hash1=[" + hash2.toBase58() + "]"); | |||
} | |||
@Test | |||
public void testResolveAndStore() throws IOException { | |||
ClassPathResource ledgerBindingConfigFile = new ClassPathResource("ledger-binding.conf"); | |||
@@ -32,10 +46,10 @@ public class LedgerBindingConfigTest { | |||
conf.store(System.out); | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
conf.store(out); | |||
ByteArrayInputStream newIn = new ByteArrayInputStream(out.toByteArray()); | |||
LedgerBindingConfig newConf = LedgerBindingConfig.resolve(newIn); | |||
assertLedgerBindingConfig(newConf); | |||
} finally { | |||
in.close(); | |||
@@ -49,8 +63,8 @@ public class LedgerBindingConfigTest { | |||
* @param conf | |||
*/ | |||
private void assertLedgerBindingConfig(LedgerBindingConfig conf) { | |||
String[] expectedHashs = { "6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K", | |||
"64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty" }; | |||
String[] expectedHashs = { "j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk", | |||
"j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf" }; | |||
HashDigest[] hashs = conf.getLedgerHashs(); | |||
for (int i = 0; i < hashs.length; i++) { | |||
assertEquals(expectedHashs[i], hashs[i].toBase58()); | |||
@@ -1,34 +1,34 @@ | |||
#绑定的账本的hash列表;以逗号分隔; | |||
ledger.bindings=6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K, \ | |||
64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty | |||
ledger.bindings=j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk, \ | |||
j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf | |||
#第1个账本[6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K]的配置; | |||
#第1个账本[j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk]的配置; | |||
#账本的当前共识参与方的ID; | |||
binding.6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K.parti.address=1 | |||
binding.j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk.parti.address=1 | |||
#账本的当前共识参与方的私钥文件的保存路径; | |||
binding.6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K.parti.pk-path=keys/jd-com.priv | |||
binding.j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk.parti.pk-path=keys/jd-com.priv | |||
#账本的当前共识参与方的私钥内容(Base58编码);如果指定了,优先选用此属性,其次是 pk-path 属性; | |||
binding.6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K.parti.pk=AdSXsf5QJpy | |||
binding.j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk.parti.pk=AdSXsf5QJpy | |||
#账本的当前共识参与方的私钥文件的读取口令;可为空;如果为空时,节点的启动过程中需要手动从控制台输入; | |||
binding.6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K.parti.pwd= | |||
binding.j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk.parti.pwd= | |||
#账本的存储数据库的连接字符串; | |||
binding.6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K.db.uri=redis://ip:port/1 | |||
binding.j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk.db.uri=redis://ip:port/1 | |||
#账本的存储数据库的连接口令; | |||
binding.6HaDnSu4kY6vNAdSXsf5QJpyYxrtxxoH1tn8dDRvbRD8K.db.pwd=kksfweffj | |||
binding.j5ptBmn67B2p3yki3ji1j2ZMjnJhrUvP4kFpGmcXgvrhmk.db.pwd=kksfweffj | |||
#第2个账本[64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty]的配置; | |||
#第2个账本[j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf]的配置; | |||
#账本的当前共识参与方的ID; | |||
binding.64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty.parti.address=2 | |||
binding.j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf.parti.address=2 | |||
#账本的当前共识参与方的私钥文件的保存路径; | |||
binding.64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty.parti.pk-path=keys/jd-com-1.priv | |||
binding.j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf.parti.pk-path=keys/jd-com-1.priv | |||
#账本的当前共识参与方的私钥内容(Base58编码);如果指定了,优先选用此属性,其次是 pk-path 属性; | |||
binding.64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty.parti.pk= | |||
binding.j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf.parti.pk= | |||
#账本的当前共识参与方的私钥文件的读取口令;可为空;如果为空时,节点的启动过程中需要手动从控制台输入; | |||
binding.64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty.parti.pwd=kksafe | |||
binding.j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf.parti.pwd=kksafe | |||
#账本的存储数据库的连接字符串; | |||
binding.64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty.db.uri=redis://ip:port/2 | |||
binding.j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf.db.uri=redis://ip:port/2 | |||
#账本的存储数据库的连接口令; | |||
binding.64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty.db.pwd= | |||
binding.j5kLUENMvcUooZjKfz2bEYU6zoK9DAqbdDDU8aZEZFR4qf.db.pwd= |