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);
}
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);
}
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);
}
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())));
// }
}
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());
}
Aggregations