use of com.jd.blockchain.storage.service.utils.VersioningKVData 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;
}
use of com.jd.blockchain.storage.service.utils.VersioningKVData in project jdchain-core by blockchain-jd-com.
the class MerkleHashDataset method getDataEntry.
@Override
public DataEntry<Bytes, byte[]> getDataEntry(Bytes key, long version) {
long latestVersion = getMerkleVersion(key);
if (latestVersion < 0 || version > latestVersion) {
// by the current merkletree;
return null;
}
version = version < 0 ? latestVersion : version;
Bytes dataKey = encodeDataKey(key);
byte[] value = valueStorage.get(dataKey, version);
if (value == null) {
throw new MerkleProofException("Expected value does not exist!");
}
return new VersioningKVData<Bytes, byte[]>(key, version, value);
}
use of com.jd.blockchain.storage.service.utils.VersioningKVData 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);
// }
}
use of com.jd.blockchain.storage.service.utils.VersioningKVData in project jdchain-core by blockchain-jd-com.
the class MerkleHashSortTreeTest method getRandomSortingCopy.
private VersioningKVData<String, byte[]>[] getRandomSortingCopy(VersioningKVData<String, byte[]>[] origDatas) {
VersioningKVData<String, byte[]>[] datas = Arrays.copyOf(origDatas, origDatas.length);
SecureRandom rand = new SecureRandom();
VersioningKVData<String, byte[]> t;
int c = datas.length * 2;
for (int i = 0; i < c; i++) {
int x = rand.nextInt(datas.length);
int y = rand.nextInt(datas.length);
t = datas[x];
datas[x] = datas[y];
datas[y] = t;
}
return datas;
}
use of com.jd.blockchain.storage.service.utils.VersioningKVData 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"));
}
Aggregations