Search in sources :

Example 21 with KVEntry

use of com.jd.blockchain.ledger.merkletree.KVEntry 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 22 with KVEntry

use of com.jd.blockchain.ledger.merkletree.KVEntry in project jdchain-core by blockchain-jd-com.

the class MerkleHashTrieTest method testMerkleTreeDiffNewLeafType.

@Test
public void testMerkleTreeDiffNewLeafType() {
    CryptoSetting cryptoSetting = createCryptoSetting();
    MemoryKVStorage storage = new MemoryKVStorage();
    List<String> newdataListString = new ArrayList<String>();
    List<String> dataListString = new ArrayList<String>();
    List<VersioningKVData<String, byte[]>> dataList = new ArrayList<VersioningKVData<String, byte[]>>();
    List<VersioningKVData<String, byte[]>> newdataList = new ArrayList<VersioningKVData<String, byte[]>>();
    int count = 1;
    int newAddCount = 1;
    VersioningKVData<String, byte[]> orginData0 = new VersioningKVData<String, byte[]>("KEY-0", 0L, BytesUtils.concat(BytesUtils.toBytes(0), BytesUtils.toBytes("VALUE")));
    dataList.add(orginData0);
    dataListString.add(orginData0.getKey());
    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);
    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 = 0;
    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 23 with KVEntry

use of com.jd.blockchain.ledger.merkletree.KVEntry in project jdchain-core by blockchain-jd-com.

the class MerkleHashDataset method getDataEntries.

@Override
public DataEntry<Bytes, byte[]>[] getDataEntries(long fromIndex, int count) {
    if (count > LedgerConsts.MAX_LIST_COUNT) {
        throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!");
    }
    if (fromIndex < 0 || (fromIndex + count) > merkleTree.getTotalKeys()) {
        throw new IllegalArgumentException("Index out of bound!");
    }
    if (count == 0) {
        return EMPTY_ENTRIES;
    }
    @SuppressWarnings("unchecked") DataEntry<Bytes, byte[]>[] values = new DataEntry[count];
    byte[] bytesValue;
    SkippingIterator<KVEntry> iterator = merkleTree.iterator();
    iterator.skip(fromIndex);
    for (int i = 0; i < count && iterator.hasNext(); i++) {
        KVEntry dataNode = iterator.next();
        Bytes dataKey = encodeDataKey(dataNode.getKey());
        bytesValue = valueStorage.get(dataKey, dataNode.getVersion());
        values[i] = new VersioningKVData<Bytes, byte[]>(dataNode.getKey(), dataNode.getVersion(), bytesValue);
    }
    return values;
}
Also used : DataEntry(utils.DataEntry) Bytes(utils.Bytes) KVEntry(com.jd.blockchain.ledger.merkletree.KVEntry)

Example 24 with KVEntry

use of com.jd.blockchain.ledger.merkletree.KVEntry in project jdchain-core by blockchain-jd-com.

the class MerkleHashDataset method getDataEntryAt.

public DataEntry<Bytes, byte[]> getDataEntryAt(long index) {
    if (index < 0 || index + 1 > merkleTree.getTotalKeys()) {
        throw new IllegalArgumentException("Index out of bound!");
    }
    byte[] bytesValue;
    SkippingIterator<KVEntry> iterator = merkleTree.iterator();
    iterator.skip(index);
    if (iterator.hasNext()) {
        KVEntry dataNode = iterator.next();
        Bytes dataKey = encodeDataKey(dataNode.getKey());
        bytesValue = valueStorage.get(dataKey, dataNode.getVersion());
        DataEntry<Bytes, byte[]> entry = new VersioningKVData<Bytes, byte[]>(dataNode.getKey(), dataNode.getVersion(), bytesValue);
        return entry;
    }
    return null;
}
Also used : Bytes(utils.Bytes) KVEntry(com.jd.blockchain.ledger.merkletree.KVEntry) VersioningKVData(com.jd.blockchain.storage.service.utils.VersioningKVData)

Example 25 with KVEntry

use of com.jd.blockchain.ledger.merkletree.KVEntry in project jdchain-core by blockchain-jd-com.

the class MerkleHashDataset method getValues.

public byte[][] getValues(long fromIndex, int count) {
    if (count > LedgerConsts.MAX_LIST_COUNT) {
        throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!");
    }
    if (fromIndex < 0 || (fromIndex + count) > merkleTree.getTotalKeys()) {
        throw new IllegalArgumentException("The specified from-index and count are out of bound!");
    }
    byte[][] values = new byte[count][];
    SkippingIterator<KVEntry> iterator = merkleTree.iterator();
    iterator.skip(fromIndex);
    for (int i = 0; i < count && iterator.hasNext(); i++) {
        KVEntry dataNode = iterator.next();
        Bytes dataKey = encodeDataKey(dataNode.getKey());
        values[i] = valueStorage.get(dataKey, dataNode.getVersion());
    }
    return values;
}
Also used : Bytes(utils.Bytes) KVEntry(com.jd.blockchain.ledger.merkletree.KVEntry)

Aggregations

KVEntry (com.jd.blockchain.ledger.merkletree.KVEntry)31 HashDigest (com.jd.blockchain.crypto.HashDigest)20 VersioningKVData (com.jd.blockchain.storage.service.utils.VersioningKVData)20 Test (org.junit.Test)20 MemoryKVStorage (com.jd.blockchain.storage.service.utils.MemoryKVStorage)17 MerkleHashTrie (com.jd.blockchain.ledger.proof.MerkleHashTrie)11 CryptoSetting (com.jd.blockchain.ledger.CryptoSetting)10 MerkleHashSortTree (com.jd.blockchain.ledger.merkletree.MerkleHashSortTree)9 ArrayList (java.util.ArrayList)8 TreeOptions (com.jd.blockchain.ledger.merkletree.TreeOptions)7 Bytes (utils.Bytes)5 HashMap (java.util.HashMap)3 MerkleTree (com.jd.blockchain.ledger.merkletree.MerkleTree)2 SecureRandom (java.security.SecureRandom)1 HashSet (java.util.HashSet)1 Random (java.util.Random)1 DataEntry (utils.DataEntry)1