use of com.jd.blockchain.ledger.merkletree.MerkleHashSortTree in project jdchain-core by blockchain-jd-com.
the class MerkleHashSortTreeTest method testReadUncommitting.
/**
* 验证 HashSortingMerkleTree 在未提交之前的总数和根哈希维持不变的特性,新增的数据记录可读,但是具有临时性,一旦回滚则被清除;
*/
@Test
public void testReadUncommitting() {
// 数据集合长度为 1024 时也能正常生成;
int count = 100;
List<VersioningKVData<String, byte[]>> dataList = generateDatas(count);
VersioningKVData<String, byte[]>[] datas = toArray(dataList);
TreeOptions treeOption = createTreeOptions();
MemoryKVStorage storage = new MemoryKVStorage();
MerkleHashSortTree merkleTree = new MerkleHashSortTree(treeOption, KEY_PREFIX, storage);
setDatas(merkleTree, datas);
assertDataExist(merkleTree, datas);
// 未提交之前查不到信息;
assertNull(merkleTree.getRootHash());
assertEquals(0, merkleTree.getTotalKeys());
KVEntry dt = merkleTree.getData("KEY-69");
assertNotNull(dt);
assertEquals(0, dt.getVersion());
dt = merkleTree.getData("KEY-69", 0);
assertNotNull(dt);
assertEquals(0, dt.getVersion());
dt = merkleTree.getData("KEY-69", 1);
assertNull(dt);
// 提交;
merkleTree.commit();
// 重新加载;
HashDigest rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
merkleTree = new MerkleHashSortTree(rootHash, treeOption, KEY_PREFIX, storage);
// 测试写入数据的多版本;
VersioningKVData<String, byte[]> data69 = new VersioningKVData<String, byte[]>("KEY-69", 1, BytesUtils.toBytes("NEW-VALUE-VERSION-1"));
merkleTree.setData(data69.getKey(), data69.getVersion(), data69.getValue());
dt = merkleTree.getData("KEY-69", 1);
assertNotNull(dt);
assertEquals(1, dt.getVersion());
merkleTree.commit();
rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
// 预期键的总数不变;
assertEquals(count, merkleTree.getTotalKeys());
dt = merkleTree.getData("KEY-69");
assertNotNull(dt);
assertEquals(1, dt.getVersion());
dt = merkleTree.getData("KEY-69", 0);
assertNotNull(dt);
assertEquals(0, dt.getVersion());
dt = merkleTree.getData("KEY-69", 1);
assertNotNull(dt);
assertEquals(1, dt.getVersion());
// 整体地验证数据的存在性;
datas[69] = data69;
assertDataExist(merkleTree, datas);
}
use of com.jd.blockchain.ledger.merkletree.MerkleHashSortTree in project jdchain-core by blockchain-jd-com.
the class MerkleHashSortTreeTest method testCreation.
/**
* 测试树的创建的正确性;
*/
@Test
public void testCreation() {
// 数据集合长度为 0 时也能正常生成;
List<VersioningKVData<String, byte[]>> dataList = generateDatas(0);
VersioningKVData<String, byte[]>[] datas = toArray(dataList);
MerkleHashSortTree merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(0, merkleTree.getTotalKeys());
// TODO: 暂时注释掉默克尔证明相关的内容;
// MerkleProof proof = merkleTree.getProof("KEY_NOT_EXIST");
// assertNull(proof);
// 数据集合长度为 1 时也能正常生成;
dataList = generateDatas(1);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(1, merkleTree.getTotalKeys());
// TODO: 暂时注释掉默克尔证明相关的内容;
// 默克尔证明路径的长度至少为 4 ——包括:根节点/叶子节点/数据节点/值哈希;
// assertMerkleProofAndProofLength(datas[0], merkleTree, 4);
// 数据集合长度为 2 时也能正常生成;
dataList = generateDatas(2);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(2, merkleTree.getTotalKeys());
// TODO: 暂时注释掉默克尔证明相关的内容;
// assertMerkleProofAndProofLength(datas[0], merkleTree, 4);
// assertMerkleProofAndProofLength(datas[1], merkleTree, 4);
// 数据集合长度为 100 时也能正常生成;
dataList = generateDatas(100);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(100, merkleTree.getTotalKeys());
// 数据集合长度为 1024 时也能正常生成;
int count = 1024;
dataList = generateDatas(count);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(count, merkleTree.getTotalKeys());
// TODO: 暂时注释掉默克尔证明相关的内容;
// merkleTree.print();
// for (VersioningKVData<String, byte[]> data : datas) {
// assertMerkleProof(data, merkleTree);
// }
// testMerkleProof1024(datas, merkleTree);
// 数据集合长度为 20000 时也能正常生成;
count = 20000;
dataList = generateDatas(count);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(count, merkleTree.getTotalKeys());
// TODO: 暂时注释掉默克尔证明相关的内容;
// merkleTree.print();
// for (VersioningKVData<String, byte[]> data : datas) {
// assertMerkleProof(data, merkleTree);
// }
}
use of com.jd.blockchain.ledger.merkletree.MerkleHashSortTree in project jdchain-core by blockchain-jd-com.
the class MerkleHashSortTreeTest method testMerkleProofCorrectness.
/**
* 测试 Merkle 证明的正确性;
*/
// TODO: 暂时注释掉默克尔证明相关的内容;
// @Test
public void testMerkleProofCorrectness() {
// 长度为 0 的情况;
int count = 0;
// System.out.printf("\r\n\r\n================= %s 个节点 =================\r\n\r\n", count);
List<VersioningKVData<String, byte[]>> dataList = generateDatas(count);
VersioningKVData<String, byte[]>[] datas = toArray(dataList);
MerkleHashSortTree merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash0 = merkleTree.getRootHash();
assertNotNull(rootHash0);
// 预期空的默克尔树中查询任何数据的证明都获得 null 返回;
MerkleProof proof = merkleTree.getProof("KEY-0");
assertNull(proof);
// 长度为 1 的情况;
count = 1;
// System.out.printf("\r\n\r\n================= %s 个节点 =================\r\n\r\n", count);
dataList = generateDatas(count);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash1 = merkleTree.getRootHash();
assertNotNull(rootHash1);
// 预期在只有 1 条数据的情况下可以正常得到该数据的默克尔证明;
MerkleProof proof1_0 = merkleTree.getProof("KEY-0");
assertNotNull(proof1_0);
// 依照设计,预期任何默克尔证明都至少有 4 条路径;
assertMerkleProofPath(proof1_0, merkleTree.getRootHash(), merkleTree.getData("KEY-0"));
// 长度为 2 的情况;
count = 2;
// System.out.printf("\r\n\r\n================= %s 个节点 =================\r\n\r\n", count);
dataList = generateDatas(count);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash2 = merkleTree.getRootHash();
assertNotNull(rootHash2);
MerkleProof proof2_0 = merkleTree.getProof("KEY-0");
assertNotNull(proof2_0);
// 依照设计,预期任何默克尔证明都至少有 4 条路径;
assertMerkleProofPath(proof2_0, merkleTree.getRootHash(), merkleTree.getData("KEY-0"));
// 长度为 16 的情况;
count = 16;
// System.out.printf("\r\n\r\n================= %s 个节点 =================\r\n\r\n", count);
dataList = generateDatas(count);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash16 = merkleTree.getRootHash();
assertNotNull(rootHash16);
MerkleProof proof16_0 = merkleTree.getProof("KEY-0");
assertNotNull(proof16_0);
// 依照设计,预期任何默克尔证明都至少有 4 条路径;
assertMerkleProofPath(proof16_0, merkleTree.getRootHash(), merkleTree.getData("KEY-0"));
// 长度为 32 的情况;
count = 32;
// System.out.printf("\r\n\r\n================= %s 个节点 =================\r\n\r\n", count);
dataList = generateDatas(count);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash32 = merkleTree.getRootHash();
assertNotNull(rootHash32);
MerkleProof proof32_0 = merkleTree.getProof("KEY-0");
assertNotNull(proof32_0);
// 依照设计,预期任何默克尔证明都至少有 4 条路径;
assertMerkleProofPath(proof32_0, merkleTree.getRootHash(), merkleTree.getData("KEY-0"));
// 长度为 1025 的情况;
count = 1025;
// System.out.printf("\r\n\r\n================= %s 个节点 =================\r\n\r\n", count);
dataList = generateDatas(count);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash1025 = merkleTree.getRootHash();
assertNotNull(rootHash1025);
MerkleProof proof1025 = merkleTree.getProof("KEY-0");
assertNotNull(proof1025);
// 依照设计,预期任何默克尔证明都至少有 4 条路径;
assertMerkleProofPath(proof1025, merkleTree.getRootHash(), merkleTree.getData("KEY-0"));
}
use of com.jd.blockchain.ledger.merkletree.MerkleHashSortTree in project jdchain-core by blockchain-jd-com.
the class MerkleHashSortTreePerformanceTest method testPerformace1.
private static void testPerformace1(int round, int count) {
System.out.printf("------------- Performance test: MerkleHashSortTree --------------\r\n", round, count);
TreeOptions setting = TreeOptions.build().setDefaultHashAlgorithm(ClassicAlgorithm.SHA256.code());
Bytes prefix = Bytes.fromString(LedgerTestUtils.LEDGER_KEY_PREFIX);
MemoryKVStorage storage = new MemoryKVStorage();
Random rand = new Random();
byte[] value = new byte[128];
rand.nextBytes(value);
long startTs = System.currentTimeMillis();
MerkleHashSortTree merkleTree = new MerkleHashSortTree(setting, prefix, storage);
String key;
for (int r = 0; r < round; r++) {
for (int i = 0; i < count; i++) {
key = "KEY-" + r + "-" + i;
merkleTree.setData(key, 0, value);
}
merkleTree.commit();
}
long elapsedTs = System.currentTimeMillis() - startTs;
long totalCount = count * round;
double tps = round * 1000.0D / elapsedTs;
double kps = round * count * 1000.0D / elapsedTs;
System.out.printf("--[Performance]:: TotalKeys=%s; Round=%s; Count=%s; Times=%sms; TPS=%.2f; KPS=%.2f\r\n\r\n", totalCount, round, count, elapsedTs, tps, kps);
}
Aggregations