use of com.jd.blockchain.ledger.proof.MerkleHashTrie in project jdchain-core by blockchain-jd-com.
the class MerkleHashTrieTest method testDataIterator.
/**
* 测试浏览默克尔树的所有数据节点;
*/
@Test
public void testDataIterator() {
int count = 1024;
List<VersioningKVData<String, byte[]>> dataList = generateDatas(count);
VersioningKVData<String, byte[]>[] datas = toArray(dataList);
MerkleHashTrie merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(count, merkleTree.getTotalKeys());
assertEquals(count, merkleTree.getTotalRecords());
Map<String, VersioningKVData<String, byte[]>> dataMap = new HashMap<String, VersioningKVData<String, byte[]>>();
for (VersioningKVData<String, byte[]> data : datas) {
dataMap.put(data.getKey(), data);
}
Iterator<KVEntry> dataIterator = merkleTree.iterator();
String[] dataKeys = new String[count];
int index = 0;
while (dataIterator.hasNext()) {
KVEntry data = dataIterator.next();
assertNotNull(data);
String key = data.getKey().toUTF8String();
assertTrue(dataMap.containsKey(key));
dataMap.remove(key);
dataKeys[index] = key;
index++;
}
assertEquals(0, dataMap.size());
assertEquals(count, index);
SkippingIterator<KVEntry> skippingIterator = merkleTree.iterator();
testDataIteratorSkipping(dataKeys, skippingIterator, 0);
skippingIterator = merkleTree.iterator();
testDataIteratorSkipping(dataKeys, skippingIterator, 1);
skippingIterator = merkleTree.iterator();
testDataIteratorSkipping(dataKeys, skippingIterator, 2);
skippingIterator = merkleTree.iterator();
testDataIteratorSkipping(dataKeys, skippingIterator, 16);
skippingIterator = merkleTree.iterator();
testDataIteratorSkipping(dataKeys, skippingIterator, 128);
skippingIterator = merkleTree.iterator();
testDataIteratorSkipping(dataKeys, skippingIterator, 1023);
skippingIterator = merkleTree.iterator();
testDataIteratorSkipping(dataKeys, skippingIterator, 1024);
}
use of com.jd.blockchain.ledger.proof.MerkleHashTrie in project jdchain-core by blockchain-jd-com.
the class MerkleHashTrieTest method testCreation.
/**
* 测试树的创建的正确性;
*/
@Test
public void testCreation() {
// 数据集合长度为 0 时也能正常生成;
List<VersioningKVData<String, byte[]>> dataList = generateDatas(0);
VersioningKVData<String, byte[]>[] datas = toArray(dataList);
MerkleHashTrie merkleTree = newMerkleTree_with_committed(datas);
HashDigest rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(0, merkleTree.getTotalKeys());
assertEquals(0, merkleTree.getTotalRecords());
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());
assertEquals(1, merkleTree.getTotalRecords());
// 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());
assertEquals(2, merkleTree.getTotalRecords());
// 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());
assertEquals(100, merkleTree.getTotalRecords());
// 数据集合长度为 1024 时也能正常生成;
int count = 1024;
dataList = generateDatas(count);
datas = toArray(dataList);
merkleTree = newMerkleTree_with_committed(datas);
rootHash = merkleTree.getRootHash();
assertNotNull(rootHash);
assertEquals(count, merkleTree.getTotalKeys());
assertEquals(count, merkleTree.getTotalRecords());
// merkleTree.print();
// TODO: 暂时忽略默克尔证明的测试;
// 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());
assertEquals(count, merkleTree.getTotalRecords());
// merkleTree.print();
// TODO: 暂时忽略默克尔证明的测试;
// for (VersioningKVData<String, byte[]> data : datas) {
// assertMerkleProof(data, merkleTree);
// }
}
use of com.jd.blockchain.ledger.proof.MerkleHashTrie in project jdchain-core by blockchain-jd-com.
the class MerkleHashTrieTest method testSpecialUseCase_1.
@Test
public void testSpecialUseCase_1() {
CryptoSetting cryptoSetting = createCryptoSetting();
MemoryKVStorage storage = new MemoryKVStorage();
MerkleHashTrie merkleTree = new MerkleHashTrie(cryptoSetting, KEY_PREFIX, storage);
byte[] key = Base58Utils.decode("j5sXmpcomtM2QMUNWeQWsF8bNFFnyeXoCjVAekEeLSscgY");
byte[] value = BytesUtils.toBytes("Special Use-Case VALUE");
long version = 0;
merkleTree.setData(key, version, value);
KVEntry mkdata = merkleTree.getData(key);
assertNotNull(mkdata);
merkleTree.commit();
mkdata = merkleTree.getData(key);
assertNotNull(mkdata);
MerkleTree merkleTreeReload = new MerkleHashTrie(merkleTree.getRootHash(), cryptoSetting, KEY_PREFIX, storage, false);
mkdata = merkleTreeReload.getData(key);
assertNotNull(mkdata);
}
use of com.jd.blockchain.ledger.proof.MerkleHashTrie 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())));
// }
}
use of com.jd.blockchain.ledger.proof.MerkleHashTrie 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())));
// }
}
Aggregations