Search in sources :

Example 51 with MemoryKVStorage

use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.

the class MerkleSortTreeTest method testCounts.

@Test
public void testCounts() {
    TreeOptions options = createTreeOptions();
    MemoryKVStorage storage = new MemoryKVStorage();
    MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage);
    HashSet<Long> excludingIDs = new HashSet<Long>();
    int count1 = (int) power(MerkleSortTree.DEFAULT_DEGREE, 2);
    byte[][] datas1 = generateRandomData(count1);
    long[] ids1 = generateRandomIDs(count1, excludingIDs, true);
    addDatasAndCommit(ids1, datas1, mst);
    int count2 = (int) power(MerkleSortTree.DEFAULT_DEGREE, 3);
    byte[][] datas2 = generateRandomData(count2);
    long[] ids2 = generateRandomIDs(count2, excludingIDs, true);
    addDatasAndCommit(ids2, datas2, mst);
    // 合并前两次产生的数据,验证默克尔树中是否已经写入相同的数据;
    long[] ids = ArrayUtils.concat(ids1, ids2);
    byte[][] datas = ArrayUtils.concat(datas1, datas2, byte[].class);
    assertDataEquals(mst, ids, datas);
    // 从存储中重新加载默克尔树,验证默克尔树中是否已经写入相同的数据;
    HashDigest rootHash = mst.getRootHash();
    mst = MerkleSortTree.createBytesTree(rootHash, options, DEFAULT_MKL_KEY_PREFIX, storage);
    assertDataEquals(mst, ids, datas);
    // 对重新加载的默克尔树持续写入,验证重复加载后持续写入的正确性;
    int count3 = 1023;
    byte[][] datas3 = generateRandomData(count3);
    long[] ids3 = generateRandomIDs(count3, excludingIDs, true);
    addDatasAndCommit(ids3, datas3, mst);
    ids = ArrayUtils.concat(ids, ids3);
    datas = ArrayUtils.concat(datas, datas3, byte[].class);
    assertDataEquals(mst, ids, datas);
}
Also used : TreeOptions(com.jd.blockchain.ledger.merkletree.TreeOptions) HashDigest(com.jd.blockchain.crypto.HashDigest) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 52 with MemoryKVStorage

use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.

the class MerkleSortTreeTest method testIdConfliction.

/**
 * 测试插入同一个 ID 的冲突表现是否符合预期;
 */
@Test
public void testIdConfliction() {
    TreeOptions options = createTreeOptions();
    MemoryKVStorage storage = new MemoryKVStorage();
    MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage);
    // 验证空的迭代器;
    SkippingIterator<MerkleValue<byte[]>> iter = mst.bytesIterator();
    assertEquals(0, iter.getTotalCount());
    assertEquals(-1, iter.getCursor());
    assertFalse(iter.hasNext());
    assertNull(iter.next());
    // 加入数据,验证顺序数据插入的生成的迭代器;
    int count = 10;
    byte[][] datas = generateRandomData(count);
    long[] ids = generateSeqenceIDs(0, count);
    addDatasAndCommit(ids, datas, mst);
    ;
    // 预期默认的 MerkleSortedTree 实现下,写入相同 id 的数据会引发移除;
    MerkleTreeKeyExistException keyExistException = null;
    try {
        mst.set(8, datas[0]);
    } catch (MerkleTreeKeyExistException e) {
        keyExistException = e;
    }
    assertNotNull(keyExistException);
}
Also used : TreeOptions(com.jd.blockchain.ledger.merkletree.TreeOptions) MerkleTreeKeyExistException(com.jd.blockchain.ledger.merkletree.MerkleTreeKeyExistException) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) MerkleValue(com.jd.blockchain.ledger.merkletree.MerkleValue) Test(org.junit.Test)

Example 53 with MemoryKVStorage

use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.

the class MerkleSortTreeTest method testAddDuplicatedData.

@Test
public void testAddDuplicatedData() {
    Random random = new Random();
    byte[] data = new byte[32];
    random.nextBytes(data);
    MemoryKVStorage storage = new MemoryKVStorage();
    // 配置选项设置为”不报告重复数据项“;
    // 以不同的 id 重复设置两个相同的数据,预期不会报告异常;
    MerkleProofException ex = null;
    try {
        TreeOptions options = TreeOptions.build().setDefaultHashAlgorithm(HASH_ALGORITHM.code()).setReportKeyStorageConfliction(false);
        MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage);
        mst.set(1, data);
        mst.set(2, data);
        mst.commit();
    } catch (MerkleProofException e) {
        ex = e;
    }
    assertNull(ex);
    // 配置选项设置为”报告重复数据项“;
    // 以不同的 id 重复设置两个相同的数据,预期将报告异常;
    ex = null;
    try {
        TreeOptions options = TreeOptions.build().setDefaultHashAlgorithm(HASH_ALGORITHM.code()).setReportKeyStorageConfliction(true);
        MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage);
        mst.set(1, data);
        mst.set(2, data);
        mst.commit();
    } catch (MerkleProofException e) {
        ex = e;
    }
    assertNotNull(ex);
}
Also used : MerkleProofException(com.jd.blockchain.ledger.core.MerkleProofException) Random(java.util.Random) SecureRandom(java.security.SecureRandom) TreeOptions(com.jd.blockchain.ledger.merkletree.TreeOptions) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) Test(org.junit.Test)

Example 54 with MemoryKVStorage

use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.

the class MerkleHashTrieTest method testMerkleTreeDiffNewPathType.

@Test
public void testMerkleTreeDiffNewPathType() {
    CryptoSetting cryptoSetting = createCryptoSetting();
    MemoryKVStorage storage = new MemoryKVStorage();
    List<String> newdataListString = new ArrayList<String>();
    List<String> dataListString = new ArrayList<String>();
    List<VersioningKVData<String, byte[]>> newdataList = new ArrayList<VersioningKVData<String, byte[]>>();
    int count = 1;
    int newAddCount = 5;
    List<VersioningKVData<String, byte[]>> dataList = generateSpecKeyDatas(dataListString, count);
    VersioningKVData<String, byte[]>[] datas = toArray(dataList);
    MerkleHashTrie merkleTree = newMerkleTree_with_committed(datas, cryptoSetting, storage);
    HashDigest rootHash0 = merkleTree.getRootHash();
    assertNotNull(rootHash0);
    assertEquals(count, merkleTree.getTotalKeys());
    assertEquals(count, merkleTree.getTotalRecords());
    // reload and add random key data item;
    MerkleHashTrie merkleTree_reload = new MerkleHashTrie(rootHash0, cryptoSetting, KEY_PREFIX, storage, false);
    assertEquals(count, merkleTree_reload.getTotalKeys());
    assertEquals(count, merkleTree_reload.getTotalRecords());
    assertEquals(rootHash0, merkleTree_reload.getRootHash());
    VersioningKVData<String, byte[]> data0 = new VersioningKVData<String, byte[]>("KEY-1741789838495252", 0L, BytesUtils.concat(BytesUtils.toBytes(0), BytesUtils.toBytes("VALUE")));
    newdataList.add(data0);
    VersioningKVData<String, byte[]> data1 = new VersioningKVData<String, byte[]>("KEY-2741789838505562", 0L, BytesUtils.concat(BytesUtils.toBytes(0), BytesUtils.toBytes("VALUE")));
    newdataList.add(data1);
    VersioningKVData<String, byte[]> data2 = new VersioningKVData<String, byte[]>("KEY-0745023937104559", 0L, BytesUtils.concat(BytesUtils.toBytes(0), BytesUtils.toBytes("VALUE")));
    newdataList.add(data2);
    VersioningKVData<String, byte[]> data3 = new VersioningKVData<String, byte[]>("KEY-7745261599950097", 0L, BytesUtils.concat(BytesUtils.toBytes(0), BytesUtils.toBytes("VALUE")));
    newdataList.add(data3);
    VersioningKVData<String, byte[]> data4 = new VersioningKVData<String, byte[]>("KEY-9745261599963367", 0L, BytesUtils.concat(BytesUtils.toBytes(0), BytesUtils.toBytes("VALUE")));
    newdataList.add(data4);
    for (int i = 0; i < newdataList.size(); i++) {
        merkleTree_reload.setData(newdataList.get(i).getKey(), newdataList.get(i).getVersion(), newdataList.get(i).getValue());
        newdataListString.add(newdataList.get(i).getKey());
    }
    merkleTree_reload.commit();
    HashDigest rootHash1 = merkleTree_reload.getRootHash();
    assertNotNull(rootHash1);
    assertNotEquals(rootHash0, rootHash1);
    assertEquals(count + newAddCount, merkleTree_reload.getTotalKeys());
    assertEquals(count + newAddCount, merkleTree_reload.getTotalRecords());
    SkippingIterator<KVEntry> diffIterator = merkleTree_reload.getKeyDiffIterator(merkleTree);
    // max boundary skip test
    assertEquals(newAddCount, diffIterator.getTotalCount());
    assertEquals(-1, diffIterator.getCursor());
    assertTrue(diffIterator.hasNext());
    long skipped = diffIterator.skip(newAddCount);
    assertEquals(newAddCount, skipped);
    assertFalse(diffIterator.hasNext());
    // re-interator and random skip test
    int skipNum = 4;
    diffIterator = merkleTree_reload.getKeyDiffIterator(merkleTree);
    assertEquals(newAddCount, diffIterator.getTotalCount());
    assertEquals(-1, diffIterator.getCursor());
    assertTrue(diffIterator.hasNext());
    long skipped1 = diffIterator.skip(skipNum);
    assertEquals(skipNum, skipped1);
    int diffNum = 0;
    // TODO: 无效的验证逻辑; by huanghaiquan at 2020-07-15;
    // while (diffIterator.hasNext()) {
    // MerkleData data = diffIterator.next();
    // assertNotNull(data);
    // assertFalse(dataList.contains(new String(data.getKey())));
    // assertTrue(newdataListString.contains(new String(data.getKey())));
    // diffNum++;
    // }
    // assertEquals(diffNum, diffIterator.getCount() - skipNum);
    // re-interator and next test
    diffIterator = merkleTree_reload.getKeyDiffIterator(merkleTree);
    int diffNum1 = 0;
    assertEquals(newAddCount, diffIterator.getTotalCount());
    while (diffIterator.hasNext()) {
        KVEntry data = diffIterator.next();
        assertNotNull(data);
        diffNum1++;
    }
    assertFalse(diffIterator.hasNext());
    assertEquals(newAddCount - 1, diffIterator.getCursor());
    assertEquals(newAddCount, diffIterator.getTotalCount());
    assertEquals(diffNum1, diffIterator.getTotalCount());
    // re-interator and test next key consistency
    diffIterator = merkleTree_reload.getKeyDiffIterator(merkleTree);
// TODO: 无效的验证逻辑; by huanghaiquan at 2020-07-15;
// while (diffIterator.hasNext()) {
// MerkleData data = diffIterator.next();
// assertNotNull(data);
// assertFalse(dataList.contains(new String(data.getKey())));
// assertTrue(newdataListString.contains(new String(data.getKey())));
// }
}
Also used : ArrayList(java.util.ArrayList) VersioningKVData(com.jd.blockchain.storage.service.utils.VersioningKVData) CryptoSetting(com.jd.blockchain.ledger.CryptoSetting) KVEntry(com.jd.blockchain.ledger.merkletree.KVEntry) HashDigest(com.jd.blockchain.crypto.HashDigest) MerkleHashTrie(com.jd.blockchain.ledger.proof.MerkleHashTrie) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) Test(org.junit.Test)

Example 55 with MemoryKVStorage

use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.

the class MerkleHashTrieTest method testReloadTreeAddRandomNewDataNode.

/**
 * 对已存在的树进行重载,增加新的数据节点,通过重载树验证新节点是否添加成功,total keys 与total records
 * 是否符合预期,新添加的数据节点Key随机产生
 */
@Test
public void testReloadTreeAddRandomNewDataNode() {
    Random random = new Random();
    byte[] bytes = new byte[200];
    random.nextBytes(bytes);
    String newDataKey = Arrays.toString(bytes);
    CryptoSetting cryptoSetting = createCryptoSetting();
    MemoryKVStorage storage = new MemoryKVStorage();
    int count = 1024;
    List<VersioningKVData<String, byte[]>> dataList = generateDatas(count);
    VersioningKVData<String, byte[]>[] datas = toArray(dataList);
    MerkleHashTrie merkleTree = newMerkleTree_with_committed(datas, cryptoSetting, storage);
    HashDigest rootHash0 = merkleTree.getRootHash();
    assertNotNull(rootHash0);
    assertEquals(count, merkleTree.getTotalKeys());
    assertEquals(count, merkleTree.getTotalRecords());
    // reload and add one data item;
    MerkleHashTrie merkleTree_reload = new MerkleHashTrie(rootHash0, cryptoSetting, KEY_PREFIX, storage, false);
    assertEquals(count, merkleTree_reload.getTotalKeys());
    assertEquals(count, merkleTree_reload.getTotalRecords());
    assertEquals(rootHash0, merkleTree_reload.getRootHash());
    VersioningKVData<String, byte[]> data1025 = new VersioningKVData<String, byte[]>(newDataKey, 0, BytesUtils.toBytes("NEW-VALUE-1025-VERSION-0"));
    merkleTree_reload.setData(data1025.getKey(), data1025.getVersion(), data1025.getValue());
    merkleTree_reload.commit();
    HashDigest rootHash1 = merkleTree_reload.getRootHash();
    assertNotNull(rootHash1);
    assertNotEquals(rootHash0, rootHash1);
    MerkleTrieData data1025_reload_0 = merkleTree_reload.getData(data1025.getKey(), 0);
    assertNotNull(data1025_reload_0);
    assertNull(data1025_reload_0.getPreviousEntryHash());
    MerkleTrieData data0_reload_0 = merkleTree_reload.getData("KEY-0", 0);
    assertNotNull(data0_reload_0);
    assertNull(data0_reload_0.getPreviousEntryHash());
    System.out.println("mkl reload total keys = " + merkleTree_reload.getTotalKeys());
    assertEquals(count + 1, merkleTree_reload.getTotalKeys());
    MerkleHashTrie merkleTree_reload_1 = new MerkleHashTrie(rootHash1, cryptoSetting, KEY_PREFIX, storage, false);
    assertEquals(count + 1, merkleTree_reload_1.getTotalKeys());
    assertEquals(count + 1, merkleTree_reload_1.getTotalRecords());
    assertEquals(rootHash1, merkleTree_reload_1.getRootHash());
    HashDigest rootHash2 = merkleTree_reload_1.getRootHash();
    assertNotNull(rootHash2);
    assertNotEquals(rootHash0, rootHash2);
    MerkleTrieData data1025_reload_1 = merkleTree_reload_1.getData(data1025.getKey(), 0);
    assertNotNull(data1025_reload_1);
    assertNull(data1025_reload_1.getPreviousEntryHash());
    MerkleTrieData data0_reload_1 = merkleTree_reload_1.getData("KEY-0", 0);
    assertNotNull(data0_reload_1);
    assertNull(data0_reload_1.getPreviousEntryHash());
    System.out.println("mkl reload total keys = " + merkleTree_reload_1.getTotalKeys());
    assertEquals(count + 1, merkleTree_reload_1.getTotalKeys());
}
Also used : VersioningKVData(com.jd.blockchain.storage.service.utils.VersioningKVData) CryptoSetting(com.jd.blockchain.ledger.CryptoSetting) Random(java.util.Random) SecureRandom(java.security.SecureRandom) HashDigest(com.jd.blockchain.crypto.HashDigest) MerkleTrieData(com.jd.blockchain.ledger.proof.MerkleTrieData) MerkleHashTrie(com.jd.blockchain.ledger.proof.MerkleHashTrie) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) Test(org.junit.Test)

Aggregations

MemoryKVStorage (com.jd.blockchain.storage.service.utils.MemoryKVStorage)61 Test (org.junit.Test)50 HashDigest (com.jd.blockchain.crypto.HashDigest)39 CryptoSetting (com.jd.blockchain.ledger.CryptoSetting)23 TreeOptions (com.jd.blockchain.ledger.merkletree.TreeOptions)21 VersioningKVData (com.jd.blockchain.storage.service.utils.VersioningKVData)18 KVEntry (com.jd.blockchain.ledger.merkletree.KVEntry)17 MerkleHashTrie (com.jd.blockchain.ledger.proof.MerkleHashTrie)15 BlockchainKeypair (com.jd.blockchain.ledger.BlockchainKeypair)14 Bytes (utils.Bytes)13 TransactionRequest (com.jd.blockchain.ledger.TransactionRequest)9 CryptoConfig (com.jd.blockchain.ledger.core.CryptoConfig)9 Random (java.util.Random)9 LedgerEditor (com.jd.blockchain.ledger.core.LedgerEditor)8 LedgerManager (com.jd.blockchain.ledger.core.LedgerManager)8 LedgerRepository (com.jd.blockchain.ledger.core.LedgerRepository)8 ArrayList (java.util.ArrayList)8 LedgerBlock (com.jd.blockchain.ledger.LedgerBlock)7 MerkleHashSortTree (com.jd.blockchain.ledger.merkletree.MerkleHashSortTree)7 CryptoProvider (com.jd.blockchain.crypto.CryptoProvider)6