Search in sources :

Example 1 with MerkleHashDataset

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

the class MerkleHashDataSetTest method testKeyIndex.

/**
 * 测试存储的增长;
 */
@Test
public void testKeyIndex() {
    CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length];
    for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) {
        supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]);
    }
    String keyPrefix = "";
    CryptoConfig cryptoConfig = new CryptoConfig();
    cryptoConfig.setSupportedProviders(supportedProviders);
    cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256);
    cryptoConfig.setAutoVerifyHash(true);
    MemoryKVStorage storage = new MemoryKVStorage();
    MerkleHashDataset mds = new MerkleHashDataset(cryptoConfig, keyPrefix, storage, storage);
    Bytes keyA = Bytes.fromString("A");
    Bytes keyB = Bytes.fromString("B");
    Bytes keyC = Bytes.fromString("C");
    long v;
    v = mds.setValue(keyA, "A".getBytes(), -1);
    assertEquals(0, v);
    v = mds.setValue(keyB, "B".getBytes(), -1);
    assertEquals(0, v);
    v = mds.setValue(keyC, "C".getBytes(), -1);
    assertEquals(0, v);
    mds.commit();
    // 校验读最新值的正确性;
    assertEquals("A", new String(mds.getValue(keyA)));
    assertEquals("B", new String(mds.getValue(keyB)));
    assertEquals("C", new String(mds.getValue(keyC)));
    // 验证读最新数据项的正确性;
    DataEntry<Bytes, byte[]> data;
    data = mds.getDataEntry(keyA);
    assertEquals("A", new String(data.getValue()));
    assertEquals(0, data.getVersion());
    data = mds.getDataEntry(keyB);
    assertEquals("B", new String(data.getValue()));
    assertEquals(0, data.getVersion());
    data = mds.getDataEntry(keyC);
    assertEquals("C", new String(data.getValue()));
    assertEquals(0, data.getVersion());
    // 写入数据,验证版本号增加的正确性;
    v = mds.setValue(keyB, "B1".getBytes(), 0);
    assertEquals(1, v);
    v = mds.setValue(keyC, "C1".getBytes(), 0);
    assertEquals(1, v);
    mds.commit();
    // 校验读最新值的正确性;
    assertEquals("A", new String(mds.getValue(keyA, 0)));
    assertEquals("B1", new String(mds.getValue(keyB, 1)));
    assertEquals("C1", new String(mds.getValue(keyC, 1)));
    // 验证读最新数据项的正确性;
    data = mds.getDataEntry(keyA);
    assertEquals("A", new String(data.getValue()));
    assertEquals(0, data.getVersion());
    data = mds.getDataEntry(keyB);
    assertEquals("B1", new String(data.getValue()));
    assertEquals(1, data.getVersion());
    data = mds.getDataEntry(keyC);
    assertEquals("C1", new String(data.getValue()));
    assertEquals(1, data.getVersion());
}
Also used : Bytes(utils.Bytes) MerkleHashDataset(com.jd.blockchain.ledger.core.MerkleHashDataset) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) CryptoProvider(com.jd.blockchain.crypto.CryptoProvider) CryptoConfig(com.jd.blockchain.ledger.core.CryptoConfig) Test(org.junit.Test)

Example 2 with MerkleHashDataset

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

the class MerkleHashDataSetTest method testInsertSameData.

@Test
public void testInsertSameData() {
    String keyPrefix = "";
    Random rand = new Random();
    CryptoSetting cryptoSetting = createCryptoSetting();
    MemoryKVStorage storage = new MemoryKVStorage();
    MerkleHashDataset mds = new MerkleHashDataset(cryptoSetting, keyPrefix, storage, storage);
    Dataset<String, byte[]> ds = DatasetHelper.map(mds);
    // 初始的时候没有任何数据,总是返回 null;
    DataEntry verKVEntry = ds.getDataEntry("NULL_KEY");
    byte[] vbytes = ds.getValue("NULL_KEY");
    assertNull(verKVEntry);
    assertNull(vbytes);
    Map<String, Long> dataVersions = new HashMap<>();
    // Map<String, byte[]> dataValues = new HashMap<>();
    Map<HashDigest, Map<String, KeySnapshot>> history = new LinkedHashMap<>();
    HashDigest rootHash;
    // generate base data sample;
    // + rand.nextInt(1024);
    int count = 1024;
    String key;
    byte[] data = new byte[64];
    rand.nextBytes(data);
    long v;
    MerkleProof proof;
    for (int i = 0; i < count; i++) {
        key = "data" + i;
        v = ds.setValue(key, data, -1);
        dataVersions.put(key, v);
        // dataValues.put(key + "_" + v, data);
        assertEquals(v, 0);
    }
    mds.commit();
    // Take snapshot;
    {
        rootHash = mds.getRootHash();
        Map<String, KeySnapshot> snapshot = new HashMap<>();
        for (int i = 0; i < count; i++) {
            key = "data" + i;
            // TODO: 暂时注释掉默克尔证明相关的内容;
            // proof = mds.getProof(key);
            // assertNotNull(proof);
            // assertEquals(rootHash, proof.getRootHash());
            KeySnapshot ks = new KeySnapshot();
            ks.rootHash = mds.getRootHash();
            ks.maxVersion = ds.getVersion(key);
            snapshot.put(key, ks);
        }
        history.put(rootHash, snapshot);
    }
    // verify;
    {
        MerkleHashDataset mdsReload = new MerkleHashDataset(rootHash, cryptoSetting, keyPrefix, storage, storage, true);
        Dataset<String, byte[]> dsReload = DatasetHelper.map(mdsReload);
        // verify every keys;
        Map<String, KeySnapshot> snapshot = history.get(rootHash);
        MerkleProof expProof;
        for (int i = 0; i < count; i++) {
            key = "data" + i;
            // TODO: 暂时注释掉默克尔证明相关的内容;
            // proof = mdsReload.getProof(key);
            // assertNotNull(proof);
            // assertEquals(rootHash, proof.getRootHash());
            // expProof = snapshot.get(key).rootHash;
            // assertEquals(expProof.toString(), proof.toString());
            byte[] value = dsReload.getValue(key);
            assertTrue(BytesUtils.equals(data, value));
        }
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) MerkleHashDataset(com.jd.blockchain.ledger.core.MerkleHashDataset) Dataset(utils.Dataset) MerkleHashDataset(com.jd.blockchain.ledger.core.MerkleHashDataset) MerkleProof(com.jd.blockchain.ledger.MerkleProof) LinkedHashMap(java.util.LinkedHashMap) DataEntry(utils.DataEntry) CryptoSetting(com.jd.blockchain.ledger.CryptoSetting) Random(java.util.Random) HashDigest(com.jd.blockchain.crypto.HashDigest) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) Test(org.junit.Test)

Example 3 with MerkleHashDataset

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

the class MerkleHashDataSetTest method testSpecialCase_1.

@Test
public void testSpecialCase_1() {
    CryptoSetting cryptoSetting = createCryptoSetting();
    MemoryKVStorage storage = new MemoryKVStorage();
    MerkleHashDataset mds = new MerkleHashDataset(cryptoSetting, KEY_PREFIX, storage, storage);
    Bytes key = Bytes.fromBase58("j5sXmpcomtM2QMUNWeQWsF8bNFFnyeXoCjVAekEeLSscgY");
    byte[] value = BytesUtils.toBytes("Special Use-Case VALUE");
    mds.setValue(key, value, -1);
    byte[] data = mds.getValue(key);
    assertNotNull(data);
    mds.commit();
    data = mds.getValue(key);
    assertNotNull(data);
    MerkleHashDataset mds_reload = new MerkleHashDataset(mds.getRootHash(), cryptoSetting, KEY_PREFIX, storage, storage, false);
    data = mds_reload.getValue(key);
    assertNotNull(data);
}
Also used : Bytes(utils.Bytes) CryptoSetting(com.jd.blockchain.ledger.CryptoSetting) MerkleHashDataset(com.jd.blockchain.ledger.core.MerkleHashDataset) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) Test(org.junit.Test)

Example 4 with MerkleHashDataset

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

the class MerkleHashDataSetTest method testDataReload.

@Test
public void testDataReload() {
    String keyPrefix = "";
    Random rand = new Random();
    CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length];
    for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) {
        supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]);
    }
    CryptoConfig cryptoConfig = new CryptoConfig();
    cryptoConfig.setSupportedProviders(supportedProviders);
    cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256);
    cryptoConfig.setAutoVerifyHash(true);
    MemoryKVStorage storage = new MemoryKVStorage();
    MerkleHashDataset mds = new MerkleHashDataset(cryptoConfig, keyPrefix, storage, storage);
    Dataset<String, byte[]> ds = DatasetHelper.map(mds);
    // 初始的时候没有任何数据,总是返回 null;
    DataEntry verKVEntry = ds.getDataEntry("NULL_KEY");
    byte[] vbytes = ds.getValue("NULL_KEY");
    assertNull(verKVEntry);
    assertNull(vbytes);
    Map<String, Long> dataVersions = new HashMap<>();
    Map<String, byte[]> dataValues = new HashMap<>();
    Map<HashDigest, Map<String, KeySnapshot>> history = new LinkedHashMap<>();
    HashDigest rootHash;
    // generate base data sample;
    // + rand.nextInt(1024);
    int count = 1024;
    String key;
    byte[] data = new byte[64];
    long v;
    MerkleProof proof;
    for (int i = 0; i < count; i++) {
        key = "data" + i;
        rand.nextBytes(data);
        v = ds.setValue(key, data, -1);
        dataVersions.put(key, v);
        dataValues.put(key + "_" + v, data);
        assertEquals(v, 0);
    }
    mds.commit();
    // Take snapshot;
    {
        rootHash = mds.getRootHash();
        Map<String, KeySnapshot> snapshot = new HashMap<>();
        for (int i = 0; i < count; i++) {
            key = "data" + i;
            // TODO: 暂时注释掉默克尔证明相关的内容;
            // proof = mds.getProof(key);
            // assertNotNull(proof);
            // assertEquals(rootHash, proof.getRootHash());
            KeySnapshot ks = new KeySnapshot();
            // ks.proof = proof;
            ks.rootHash = mds.getRootHash();
            ks.maxVersion = ds.getVersion(key);
            snapshot.put(key, ks);
        }
        history.put(rootHash, snapshot);
    }
    // verify;
    {
    // TODO: 暂时注释掉默克尔证明相关的内容;
    // MerkleHashDataset mdsReload = new MerkleHashDataset(rootHash, cryptoConfig, keyPrefix, storage, storage, true);
    // // verify every keys;
    // Map<String, KeySnapshot> snapshots = history.get(rootHash);
    // MerkleProof expProof;
    // for (int i = 0; i < count; i++) {
    // key = "data" + i;
    // proof = mdsReload.getProof(key);
    // assertNotNull(proof);
    // assertEquals(rootHash, proof.getRootHash());
    // expProof = snapshots.get(key).rootHash;
    // assertEquals(expProof.toString(), proof.toString());
    // }
    }
    // generate multi-version data sample;
    long expVer;
    long maxVer = 0;
    long minIdx = count;
    long maxIdx = 0;
    for (int t = 0; t < 100; t++) {
        int bound = rand.nextInt(500) + 1;
        for (int i = rand.nextInt(count); i < count; i = i + rand.nextInt(bound) + 1) {
            key = "data" + i;
            rand.nextBytes(data);
            expVer = dataVersions.get(key);
            v = ds.setValue(key, data, expVer);
            assertEquals(v, expVer + 1);
            dataVersions.put(key, v);
            dataValues.put(key + "_" + v, data);
            maxVer = v > maxVer ? v : maxVer;
            minIdx = i < minIdx ? i : minIdx;
            maxIdx = i > maxIdx ? i : maxIdx;
        }
        mds.commit();
        assertNotEquals(rootHash, mds.getRootHash());
        // Take snapshot;
        {
            // TODO: 暂时注释掉默克尔证明相关的内容;
            rootHash = mds.getRootHash();
            Map<String, KeySnapshot> snapshot = new HashMap<>();
            for (int i = 0; i < count; i++) {
                key = "data" + i;
                // TODO: 暂时注释掉默克尔证明相关的内容;
                // proof = mds.getProof(key);
                // assertNotNull(proof);
                // assertEquals(rootHash, proof.getRootHash());
                KeySnapshot ks = new KeySnapshot();
                ks.rootHash = rootHash;
                ks.maxVersion = ds.getVersion(key);
                snapshot.put(key, ks);
            }
            history.put(rootHash, snapshot);
        }
    }
    System.out.println(String.format("total count=%s; from %s to %s,  max version=%s;", count, minIdx, maxIdx, maxVer));
    {
        for (HashDigest hisRootHash : history.keySet()) {
            Map<String, KeySnapshot> snapshot = history.get(hisRootHash);
            MerkleHashDataset mdsReload = new MerkleHashDataset(hisRootHash, cryptoConfig, keyPrefix, storage, storage, true);
            Dataset<String, byte[]> dsReload = DatasetHelper.map(mdsReload);
            assertEquals(hisRootHash, mdsReload.getRootHash());
            // verify every keys;
            for (int i = 0; i < count; i++) {
                key = "data" + i;
                // 最新版本一致;
                long expLatestVersion = snapshot.get(key).maxVersion;
                long actualLatestVersion = dsReload.getVersion(key);
                assertEquals(expLatestVersion, actualLatestVersion);
                // TODO: 暂时注释掉默克尔证明相关的内容;
                // 数据证明一致;
                // proof = mdsReload.getProof(key);
                // assertNotNull(proof);
                // 
                // MerkleProof expProof = snapshot.get(key).rootHash;
                // assertEquals(expProof, proof);
                maxVer = dataVersions.get(key);
                assertTrue(actualLatestVersion > -1);
                assertTrue(actualLatestVersion <= maxVer);
                for (long j = 0; j < actualLatestVersion; j++) {
                    String keyver = key + "_" + j;
                    byte[] expValue = dataValues.get(keyver);
                    byte[] actualValue = dsReload.getValue(key, j);
                    assertTrue(BytesUtils.equals(expValue, actualValue));
                }
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) MerkleHashDataset(com.jd.blockchain.ledger.core.MerkleHashDataset) Dataset(utils.Dataset) MerkleHashDataset(com.jd.blockchain.ledger.core.MerkleHashDataset) CryptoProvider(com.jd.blockchain.crypto.CryptoProvider) MerkleProof(com.jd.blockchain.ledger.MerkleProof) LinkedHashMap(java.util.LinkedHashMap) DataEntry(utils.DataEntry) Random(java.util.Random) HashDigest(com.jd.blockchain.crypto.HashDigest) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) CryptoConfig(com.jd.blockchain.ledger.core.CryptoConfig) Test(org.junit.Test)

Example 5 with MerkleHashDataset

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

the class MerkleHashDataSetTest method testStorageIncreasement.

/**
 * TODO:测试存储的增长;
 */
// @Test
public void testStorageIncreasement() {
    CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length];
    for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) {
        supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]);
    }
    String keyPrefix = "";
    CryptoConfig cryptoConfig = new CryptoConfig();
    cryptoConfig.setSupportedProviders(supportedProviders);
    cryptoConfig.setHashAlgorithm(ClassicAlgorithm.SHA256);
    cryptoConfig.setAutoVerifyHash(true);
    MemoryKVStorage storage = new MemoryKVStorage();
    MerkleHashDataset mds = new MerkleHashDataset(cryptoConfig, keyPrefix, storage, storage);
    Dataset<String, byte[]> ds = DatasetHelper.map(mds);
    long v;
    v = ds.setValue("A", "A".getBytes(), -1);
    assertEquals(0, v);
    v = ds.setValue("B", "B".getBytes(), -1);
    assertEquals(0, v);
    v = ds.setValue("C", "C".getBytes(), -1);
    assertEquals(0, v);
    mds.commit();
    byte[] va = ds.getValue("A");
    assertNotNull(va);
    assertEquals("A", new String(va));
    byte[] vc = ds.getValue("C");
    DataEntry<String, byte[]> ventry = ds.getDataEntry("C");
    assertNotNull(vc);
    assertNotNull(ventry);
    assertEquals("C", new String(vc));
    assertEquals("C", ventry.getKey());
    HashDigest root1 = mds.getRootHash();
    // 1个KV项的存储KEY的数量= 1 + Merkle节点数量;
    // 所以:3 项;
    // so the expected item count in storage is 10;
    // int expStorageCount = 10; // 3 数据项, 7 个 Merkle 节点(1 个根节点,3 个叶子节点,3 个数据节点);
    // assertEquals(expStorageCount, storage.getStorageCount());
    ds.setValue("B", "B".getBytes(), 0);
    ds.setValue("C", "C".getBytes(), 0);
    mds.commit();
    HashDigest root2 = mds.getRootHash();
    assertNotEquals(root1, root2);
    // Version changed only;仅仅增加 merkle 节点,此时 Merkle 树只有 1 层路径节点,因此只更新2个数据节点和 1
    // 个路径节点;(注:版本值是在同一个 key 下按序列保存的);
    // expStorageCount = expStorageCount + 5; // 增加了
    // //		mds.print();
    // assertEquals(expStorageCount, storage.getStorageCount());
    ds.setValue("D", "DValue".getBytes(), -1);
    mds.commit();
    HashDigest root3 = mds.getRootHash();
    assertNotEquals(root2, root3);
    assertNotEquals(root1, root3);
    // New key added, include 1 versioning kv, 1 sn key, 2 merkle nodes;
    // String[] keys = StringUtils.toStringArray(storage.keySet());
    // Bytes[] keys = storage.keySet().toArray(new Bytes[0]);
    // expStorageCount = expStorageCount + 1 + 1 + 2;
    // assertEquals(expStorageCount, storage.getStorageCount());
    // Check rollback function: Add some keys, and then rollback;
    v = ds.setValue("E", "E-values".getBytes(), -1);
    assertEquals(v, 0);
    String expEValue = new String(ds.getValue("E"));
    assertEquals(expEValue, "E-values");
    v = ds.setValue("F", "F-values".getBytes(), -1);
    assertEquals(v, 0);
    String expFValue = new String(ds.getValue("F"));
    assertEquals(expFValue, "F-values");
    v = ds.setValue("E", "E-values-1".getBytes(), 0);
    assertEquals(v, 1);
    expEValue = new String(ds.getValue("E"));
    assertEquals(expEValue, "E-values-1");
    mds.cancel();
    byte[] bv = ds.getValue("E");
    assertNull(bv);
    bv = ds.getValue("F");
    assertNull(bv);
    v = ds.getVersion("E");
    assertEquals(-1, v);
    v = ds.getVersion("F");
    assertEquals(-1, v);
    // // Expect that states has been recover;
    // keys = storage.keySet().toArray(new Bytes[0]);
    // assertEquals(expStorageCount, storage.getStorageCount());
    // ------
    System.out.println("\r\n------------- storage keys --------------");
    Set<Bytes> storageKeys = storage.getStorageKeySet();
    int i = 0;
    for (Bytes k : storageKeys) {
        System.out.println(String.format("keys[%s]=%s", i, k));
        i++;
    }
}
Also used : MerkleHashDataset(com.jd.blockchain.ledger.core.MerkleHashDataset) CryptoProvider(com.jd.blockchain.crypto.CryptoProvider) Bytes(utils.Bytes) HashDigest(com.jd.blockchain.crypto.HashDigest) MemoryKVStorage(com.jd.blockchain.storage.service.utils.MemoryKVStorage) CryptoConfig(com.jd.blockchain.ledger.core.CryptoConfig)

Aggregations

MerkleHashDataset (com.jd.blockchain.ledger.core.MerkleHashDataset)5 MemoryKVStorage (com.jd.blockchain.storage.service.utils.MemoryKVStorage)5 Test (org.junit.Test)4 CryptoProvider (com.jd.blockchain.crypto.CryptoProvider)3 HashDigest (com.jd.blockchain.crypto.HashDigest)3 CryptoConfig (com.jd.blockchain.ledger.core.CryptoConfig)3 Bytes (utils.Bytes)3 CryptoSetting (com.jd.blockchain.ledger.CryptoSetting)2 MerkleProof (com.jd.blockchain.ledger.MerkleProof)2 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 Random (java.util.Random)2 DataEntry (utils.DataEntry)2 Dataset (utils.Dataset)2