Search in sources :

Example 11 with MemoryKVStorage

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

the class AccountSetTest method test.

@Test
public void test() {
    OpeningAccessPolicy accessPolicy = new OpeningAccessPolicy();
    MemoryKVStorage storage = new MemoryKVStorage();
    CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length];
    for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) {
        supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]);
    }
    CryptoConfig cryptoConf = new CryptoConfig();
    cryptoConf.setSupportedProviders(supportedProviders);
    cryptoConf.setAutoVerifyHash(true);
    cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256);
    String keyPrefix = "";
    MerkleAccountSetEditor accset = new MerkleAccountSetEditor(cryptoConf, Bytes.fromString(keyPrefix), storage, storage, accessPolicy);
    BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate();
    accset.register(userKey.getAddress(), userKey.getPubKey());
    // 尚未提交之前,可以检索到账户的存在,但版本仍然标记为 -1;
    CompositeAccount userAcc = accset.getAccount(userKey.getAddress());
    assertNotNull(userAcc);
    assertTrue(accset.contains(userKey.getAddress()));
    accset.commit();
    HashDigest rootHash = accset.getRootHash();
    assertNotNull(rootHash);
    MerkleAccountSetEditor reloadAccSet = new MerkleAccountSetEditor(rootHash, cryptoConf, Bytes.fromString(keyPrefix), storage, storage, true, accessPolicy);
    CompositeAccount reloadUserAcc = reloadAccSet.getAccount(userKey.getAddress());
    assertNotNull(reloadUserAcc);
    assertTrue(reloadAccSet.contains(userKey.getAddress()));
    assertEquals(userAcc.getID().getAddress(), reloadUserAcc.getID().getAddress());
    assertEquals(userAcc.getID().getPubKey(), reloadUserAcc.getID().getPubKey());
}
Also used : HashDigest(com.jd.blockchain.crypto.HashDigest) MerkleAccountSetEditor(com.jd.blockchain.ledger.core.MerkleAccountSetEditor) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) BlockchainKeypair(com.jd.blockchain.ledger.BlockchainKeypair) CryptoProvider(com.jd.blockchain.crypto.CryptoProvider) OpeningAccessPolicy(com.jd.blockchain.ledger.core.OpeningAccessPolicy) CryptoConfig(com.jd.blockchain.ledger.core.CryptoConfig) CompositeAccount(com.jd.blockchain.ledger.core.CompositeAccount) Test(org.junit.Test)

Example 12 with MemoryKVStorage

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

the class BaseAccountTest method basicTest.

@Test
public void basicTest() {
    String keyPrefix = "";
    MemoryKVStorage testStorage = new MemoryKVStorage();
    CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length];
    for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) {
        supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]);
    }
    CryptoConfig cryptoConf = new CryptoConfig();
    cryptoConf.setSupportedProviders(supportedProviders);
    cryptoConf.setAutoVerifyHash(true);
    cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256);
    // OpeningAccessPolicy accPlc = new OpeningAccessPolicy();
    BlockchainKeypair bck = BlockchainKeyGenerator.getInstance().generate();
    // 新建账户;
    MerkleComplecatedAccount baseAccount = new MerkleComplecatedAccount(bck.getIdentity(), cryptoConf, Bytes.fromString(keyPrefix), testStorage, testStorage);
    // 初始化新账户时,先写入PubKey;
    assertTrue(baseAccount.isUpdated());
    assertFalse(baseAccount.isReadonly());
    // 在空白状态下写入数据;
    long v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A"), 0);
    // 预期失败;
    assertEquals(-1, v);
    v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A"), 1);
    // 预期失败;
    assertEquals(-1, v);
    v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A"), -1);
    // 预期成功;
    assertEquals(0, v);
    v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A-1"), -1);
    // 已经存在版本,指定版本号-1,预期导致失败;
    assertEquals(-1, v);
    baseAccount.commit();
    v = 0;
    for (int i = 0; i < 10; i++) {
        long s = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A_" + i), v);
        baseAccount.commit();
        // 预期成功;
        assertEquals(v + 1, s);
        v++;
    }
    v = baseAccount.getDataset().setValue("A", TypedValue.fromText("VALUE_A_" + v), v + 1);
    // 预期成功;
    assertEquals(-1, v);
    System.out.println("============== commit ==============");
    baseAccount.commit();
}
Also used : MerkleComplecatedAccount(com.jd.blockchain.ledger.core.MerkleComplecatedAccount) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) BlockchainKeypair(com.jd.blockchain.ledger.BlockchainKeypair) CryptoProvider(com.jd.blockchain.crypto.CryptoProvider) CryptoConfig(com.jd.blockchain.ledger.core.CryptoConfig) Test(org.junit.Test)

Example 13 with MemoryKVStorage

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

the class MerkleHashTrieTest method testMerkleTreeDiffPathsType.

@Test
public void testMerkleTreeDiffPathsType() {
    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 = 2;
    int newAddCount = 5;
    VersioningKVData<String, byte[]> orginData0 = new VersioningKVData<String, byte[]>("KEY-19745261600024463", 0L, BytesUtils.concat(BytesUtils.toBytes(0), BytesUtils.toBytes("VALUE")));
    dataList.add(orginData0);
    dataListString.add(orginData0.getKey());
    VersioningKVData<String, byte[]> orginData1 = new VersioningKVData<String, byte[]>("KEY-155749221633494971", 0L, BytesUtils.concat(BytesUtils.toBytes(0), BytesUtils.toBytes("VALUE")));
    dataList.add(orginData1);
    dataListString.add(orginData1.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);
    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 14 with MemoryKVStorage

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

the class MerkleSortTreeTest method testIterator.

@Test
public void testIterator() {
    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 count1 = 10;
    byte[][] datas1 = generateRandomData(count1);
    long[] ids1 = generateSeqenceIDs(0, count1);
    HashMap<Long, byte[]> dataMap = new HashMap<Long, byte[]>();
    mapIdValues(ids1, datas1, dataMap);
    addDatasAndCommit(ids1, datas1, mst);
    iter = mst.iterator();
    assertIteratorSortedAndEquals(iter, count1, ids1, dataMap);
    // 随机加入;验证迭代器返回有序的序列;
    Set<Long> excludingIDs = createIdSet(ids1);
    int count2 = (int) power(4, 8) + 1;
    byte[][] datas2 = generateRandomData(count2);
    long[] ids2 = generateRandomIDs(count2, excludingIDs, true);
    mapIdValues(ids2, datas2, dataMap);
    addDatasAndCommit(ids2, datas2, mst);
    long[] totalIds = ArrayUtils.concat(ids1, ids2);
    Arrays.sort(totalIds);
    long totalCount = count1 + count2;
    iter = mst.iterator();
    assertIteratorSortedAndEquals(iter, totalCount, totalIds, dataMap);
    // 验证有跳跃的情形;
    iter = mst.iterator();
    assertEquals(-1, iter.getCursor());
    int index = -1;
    long skipped = 1;
    iter.skip(skipped);
    index += skipped;
    assertEquals(index, iter.getCursor());
    MerkleValue<byte[]> merkleData = iter.next();
    index++;
    assertEquals(index, iter.getCursor());
    assertNotNull(merkleData);
    assertEquals(totalIds[index], merkleData.getId());
    skipped = 2;
    iter.skip(skipped);
    index += skipped;
    assertEquals(index, iter.getCursor());
    merkleData = iter.next();
    index++;
    assertEquals(index, iter.getCursor());
    assertNotNull(merkleData);
    assertEquals(totalIds[index], merkleData.getId());
    skipped = 3;
    iter.skip(skipped);
    index += skipped;
    assertEquals(index, iter.getCursor());
    merkleData = iter.next();
    index++;
    assertEquals(index, iter.getCursor());
    assertNotNull(merkleData);
    assertEquals(totalIds[index], merkleData.getId());
    SecureRandom random = new SecureRandom();
    for (int j = 0; j < 100; j++) {
        skipped = random.nextInt(100);
        iter.skip(skipped);
        index += skipped;
        assertEquals(index, iter.getCursor());
        merkleData = iter.next();
        index++;
        assertEquals(index, iter.getCursor());
        assertNotNull(merkleData);
        assertEquals(totalIds[index], merkleData.getId());
    }
    // 验证直接跳跃到倒数第 1 条的情形;
    long left = iter.getCount();
    iter.skip(left - 1);
    assertTrue(iter.hasNext());
    assertEquals(1, iter.getCount());
    merkleData = iter.next();
    assertEquals(totalCount - 1, iter.getCursor());
    assertNotNull(merkleData);
    assertEquals(totalIds[(int) totalCount - 1], merkleData.getId());
    assertFalse(iter.hasNext());
    merkleData = iter.next();
    assertNull(merkleData);
    // 验证直接跳跃到末尾的情形;
    iter = mst.iterator();
    assertTrue(iter.hasNext());
    long c = iter.skip(totalCount);
    assertEquals(totalCount, c);
    assertFalse(iter.hasNext());
    merkleData = iter.next();
    assertNull(merkleData);
}
Also used : HashMap(java.util.HashMap) SecureRandom(java.security.SecureRandom) TreeOptions(com.jd.blockchain.ledger.merkletree.TreeOptions) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) MerkleValue(com.jd.blockchain.ledger.merkletree.MerkleValue) Test(org.junit.Test)

Example 15 with MemoryKVStorage

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

the class MerkleSortTreeTest method testMultiDataCountIterator.

/**
 * 测试包含数据策略中计数大于 1 的数据迭代;
 */
@Test
public void testMultiDataCountIterator() {
    TreeOptions options = createTreeOptions();
    MemoryKVStorage storage = new MemoryKVStorage();
    DataPolicy<byte[]> bytesDataPolicy = new DefaultDataPolicy<byte[]>() {

        @Override
        public byte[] updateData(long id, byte[] origData, byte[] newData) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            if (origData == null) {
                BytesUtils.writeInt(1, out);
            } else {
                int count = BytesUtils.toInt(origData) + 1;
                BytesUtils.writeInt(count, out);
                out.write(origData, 4, origData.length - 4);
            }
            BytesEncoding.writeInNormal(newData, out);
            return out.toByteArray();
        }

        @Override
        public long count(long id, byte[] data) {
            return BytesUtils.toInt(data);
        }

        @Override
        public SkippingIterator<MerkleValue<byte[]>> iterator(long id, byte[] bytesData, long count, BytesConverter<byte[]> converter) {
            byte[][] values = new byte[(int) count][];
            ByteArrayInputStream in = new ByteArrayInputStream(bytesData, 4, bytesData.length - 4);
            for (int i = 0; i < values.length; i++) {
                values[i] = BytesEncoding.readInNormal(in);
            }
            return new BytesEntriesIterator(id, values);
        }
    };
    MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage, bytesDataPolicy);
    int count = 16;
    byte[][] datas = generateRandomData(count);
    long[] ids = new long[count];
    int startIndex = 10;
    for (int i = 0; i < startIndex; i++) {
        ids[i] = i;
    }
    // 从 10 开始,连续3条不同的记录使用相同的 编码;
    int testId = startIndex + 2;
    ids[startIndex] = testId;
    ids[startIndex + 1] = testId;
    ids[startIndex + 2] = testId;
    for (int i = 0; i < ids.length - startIndex - 3; i++) {
        ids[startIndex + i + 3] = startIndex + i + 5;
    }
    addDatas(ids, datas, mst);
    mst.commit();
    // 验证所有的数据都能够正常检索;
    SkippingIterator<MerkleValue<byte[]>> iter = mst.iterator();
    assertEquals(count, iter.getTotalCount());
    assertIteratorEquals(count, datas, ids, 0, iter);
    // 验证略过中间数据也能够正常检索:跳跃到连续 id 的前一条;
    iter = mst.iterator();
    iter.skip(startIndex - 1);
    int i = startIndex - 1;
    assertIteratorEquals(count - (startIndex - 1), datas, ids, startIndex - 1, iter);
    // 验证略过中间数据也能够正常检索:跳跃到连续 id 的第1条;
    iter = mst.iterator();
    iter.skip(startIndex);
    i = startIndex;
    {
        MerkleValue<byte[]> v = iter.next();
        assertNotNull(v);
        assertEquals(testId, v.getId());
        assertArrayEquals(datas[i], v.getValue());
        v = iter.next();
        assertNotNull(v);
        assertEquals(testId, v.getId());
        assertArrayEquals(datas[i + 1], v.getValue());
        v = iter.next();
        assertNotNull(v);
        assertEquals(testId, v.getId());
        assertArrayEquals(datas[i + 2], v.getValue());
    }
    assertIteratorEquals(count - (i + 3), datas, ids, i + 3, iter);
    // 验证略过中间数据也能够正常检索:跳跃到连续 id 的第2条;
    iter = mst.iterator();
    iter.skip(startIndex + 1);
    i = startIndex;
    {
        MerkleValue<byte[]> v = iter.next();
        assertNotNull(v);
        assertEquals(testId, v.getId());
        assertArrayEquals(datas[i + 1], v.getValue());
        v = iter.next();
        assertNotNull(v);
        assertEquals(testId, v.getId());
        assertArrayEquals(datas[i + 2], v.getValue());
    }
    assertIteratorEquals(count - (i + 3), datas, ids, i + 3, iter);
    // 验证略过中间数据也能够正常检索:跳跃到连续 id 的第3条;
    iter = mst.iterator();
    iter.skip(startIndex + 2);
    i = startIndex;
    {
        MerkleValue<byte[]> v = iter.next();
        assertNotNull(v);
        assertEquals(testId, v.getId());
        assertArrayEquals(datas[i + 2], v.getValue());
    }
    assertIteratorEquals(count - (i + 3), datas, ids, i + 3, iter);
    // 验证略过中间数据也能够正常检索:跳跃到连续 id 第3条;
    iter = mst.iterator();
    iter.skip(startIndex + 3);
    assertIteratorEquals(count - (startIndex + 3), datas, ids, startIndex + 3, iter);
}
Also used : DefaultDataPolicy(com.jd.blockchain.ledger.merkletree.DefaultDataPolicy) ByteArrayOutputStream(java.io.ByteArrayOutputStream) TreeOptions(com.jd.blockchain.ledger.merkletree.TreeOptions) ByteArrayInputStream(java.io.ByteArrayInputStream) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) BytesConverter(com.jd.blockchain.ledger.merkletree.BytesConverter) MerkleValue(com.jd.blockchain.ledger.merkletree.MerkleValue) 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