Search in sources :

Example 11 with MerkleHashSortTree

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);
}
Also used : KVEntry(com.jd.blockchain.ledger.merkletree.KVEntry) TreeOptions(com.jd.blockchain.ledger.merkletree.TreeOptions) HashDigest(com.jd.blockchain.crypto.HashDigest) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) MerkleHashSortTree(com.jd.blockchain.ledger.merkletree.MerkleHashSortTree) VersioningKVData(com.jd.blockchain.storage.service.utils.VersioningKVData) Test(org.junit.Test)

Example 12 with MerkleHashSortTree

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);
// }
}
Also used : HashDigest(com.jd.blockchain.crypto.HashDigest) MerkleHashSortTree(com.jd.blockchain.ledger.merkletree.MerkleHashSortTree) VersioningKVData(com.jd.blockchain.storage.service.utils.VersioningKVData) Test(org.junit.Test)

Example 13 with MerkleHashSortTree

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"));
}
Also used : HashDigest(com.jd.blockchain.crypto.HashDigest) MerkleHashSortTree(com.jd.blockchain.ledger.merkletree.MerkleHashSortTree) MerkleProof(com.jd.blockchain.ledger.MerkleProof) VersioningKVData(com.jd.blockchain.storage.service.utils.VersioningKVData)

Example 14 with MerkleHashSortTree

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);
}
Also used : Bytes(utils.Bytes) TreeOptions(com.jd.blockchain.ledger.merkletree.TreeOptions) Random(java.util.Random) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) MerkleHashSortTree(com.jd.blockchain.ledger.merkletree.MerkleHashSortTree)

Aggregations

MerkleHashSortTree (com.jd.blockchain.ledger.merkletree.MerkleHashSortTree)14 HashDigest (com.jd.blockchain.crypto.HashDigest)11 VersioningKVData (com.jd.blockchain.storage.service.utils.VersioningKVData)11 Test (org.junit.Test)11 KVEntry (com.jd.blockchain.ledger.merkletree.KVEntry)9 TreeOptions (com.jd.blockchain.ledger.merkletree.TreeOptions)8 MemoryKVStorage (com.jd.blockchain.storage.service.utils.MemoryKVStorage)8 Random (java.util.Random)2 Bytes (utils.Bytes)2 MerkleProof (com.jd.blockchain.ledger.MerkleProof)1 MerkleTree (com.jd.blockchain.ledger.merkletree.MerkleTree)1 SecureRandom (java.security.SecureRandom)1 HashMap (java.util.HashMap)1