use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class LedgerEditorTest method testRollback.
@Test
public void testRollback() {
BlockchainKeypair parti0 = LedgerTestUtils.createKeyPair("7VeRLBwqTAz8oRazEazeaEfqei46sk2FzvBgyHMUBJvrUEGT", "7VeRUm27GbrsX9HbQSZguChLp24HZYub6s5FJ7FjBht8BmbA");
BlockchainKeypair parti1 = LedgerTestUtils.createKeyPair("7VeRNJasZp76ThmUkoAajJEduotS4JC6T9wzhz9TDPvjLCRk", "7VeRcBcPkTZ4hFwfcKRgFJWdDesHyysQWkKYC6xfPApbfvwQ");
BlockchainKeypair parti2 = LedgerTestUtils.createKeyPair("7VeR7uSd7sqxkMp73936MoK7eUSmGPVrsmrwdekiR9fmvdYN", "7VeRUkgMXRegHHWhezv4LdJV6oQuSXo6Ezp2sjC2M5NTUWkz");
BlockchainKeypair parti3 = LedgerTestUtils.createKeyPair("7VeR8X8fa9th42XSXvnuBLfR4v3dxjXq6jPfvF7nDPB2MTo1", "7VeRdreAev1E8ySsLWX7rRMArh5wHBTmZXKwNUuoVo7cBn6o");
BlockchainKeypair[] participants = new BlockchainKeypair[] { parti0, parti1, parti2, parti3 };
final MemoryKVStorage STORAGE = new MemoryKVStorage();
// 初始化账本到指定的存储库;
HashDigest ledgerHash = LedgerTestUtils.initLedger(STORAGE, parti0, parti1, parti2, parti3);
System.out.printf("\r\n------------ LEDGER [%s] -----------\r\n", ledgerHash.toBase58());
// 验证重新加载的正确性;
LedgerManager manager = new LedgerManager();
LedgerRepository repo = manager.register(ledgerHash, STORAGE, LedgerDataStructure.MERKLE_TREE);
LedgerBlock block = repo.getBlock(ledgerHash);
assertNotNull(block);
assertNotNull(block.getHash());
assertEquals(0, block.getHeight());
// 创建交易连续交易,验证中间的交易回滚是否影响前后的交易;
BlockchainKeypair user1 = LedgerTestUtils.createKeyPair("7VeRKf3GFLFcBfzvtzmtyMXEoX2HYGEJ4j7CmHcnRV99W5Dp", "7VeRYQjeAaQY5Po8MMtmGNHA2SniqLXmJaZwBS5K8zTtMAU1");
TransactionRequest req1 = LedgerTestUtils.createTxRequest_UserReg_SHA256(user1, ledgerHash, 1580315317127L, parti0, parti0);
// 引发错误的参数:ts=1580315317127;
// txhash=j5wPGKT5CUzwi8j6VfCWaP2p9YZ6WVWtMANp9HbHWzvhgG
System.out.printf("\r\n ===||=== transactionRequest1.getTransactionContent().getHash()=[%s]\r\n", req1.getTransactionHash().toBase58());
BlockchainKeypair user2 = LedgerTestUtils.createKeyPair("7VeRKSnDFveTfLLMsLZDmmhGmgf7i142XHgBFjnrKuS95tY3", "7VeRTiJ2TpQD9aBi29ajnqdntgoVBANmC3oCbHThKb5tzfTJ");
TransactionRequest req2 = LedgerTestUtils.createTxRequest_MultiOPs_WithNotExistedDataAccount_SHA256(user2, ledgerHash, 202001202020L, parti0, parti0);
System.out.printf("\r\n ===||=== transactionRequest2.getTransactionContent().getHash()=[%s]\r\n", req2.getTransactionHash().toBase58());
BlockchainKeypair user3 = LedgerTestUtils.createKeyPair("7VeRDoaSexqLWKkaZyrQwdwSuE9n5nszduMrYBfYRfEkREQV", "7VeRdFtTuLfrzCYJzQ6enQUkGTc83ATgjr8WbmfjBQuTFpHt");
TransactionRequest req3 = LedgerTestUtils.createTxRequest_UserReg_SHA256(user3, ledgerHash, 202001202020L, parti0, parti0);
System.out.printf("\r\n ===||=== transactionRequest3.getTransactionContent().getHash()=[%s]\r\n", req3.getTransactionHash().toBase58());
System.out.println("\r\n--------------- Start new Block 1 --------------\r\n");
// 创建交易;
LedgerEditor editor = repo.createNextBlock();
System.out.println("\r\n--------------- Start new tx1 --------------\r\n");
LedgerTransactionContext txctx1 = editor.newTransaction(req1);
((UserAccountSetEditor) (txctx1.getDataset().getUserAccountSet())).register(user1.getAddress(), user1.getPubKey());
TransactionResult tx1 = txctx1.commit(TransactionState.SUCCESS);
HashDigest txHash1 = tx1.getTransactionHash();
System.out.println("\r\n--------------- Start new tx2 --------------\r\n");
LedgerTransactionContext txctx2 = editor.newTransaction(req2);
((UserAccountSetEditor) (txctx2.getDataset().getUserAccountSet())).register(user2.getAddress(), user2.getPubKey());
TransactionResult tx2 = txctx2.discardAndCommit(TransactionState.DATA_ACCOUNT_DOES_NOT_EXIST);
HashDigest txHash2 = tx2.getTransactionHash();
System.out.println("\r\n--------------- Start new tx3 --------------\r\n");
LedgerTransactionContext txctx3 = editor.newTransaction(req3);
((UserAccountSetEditor) (txctx3.getDataset().getUserAccountSet())).register(user3.getAddress(), user3.getPubKey());
TransactionResult tx3 = txctx3.commit(TransactionState.SUCCESS);
HashDigest txHash3 = tx3.getTransactionHash();
System.out.println("\r\n--------------- Start preparing new block 1 --------------\r\n");
LedgerBlock block1 = editor.prepare();
System.out.println("\r\n--------------- Start commiting new block 1 --------------\r\n");
editor.commit();
System.out.printf("\r\n--------------- End commiting new block 1 [Storage.Count=%s]--------------\r\n\r\n", STORAGE.getStorageCount());
assertEquals(1, block1.getHeight());
// 重新加载和验证;
manager = new LedgerManager();
repo = manager.register(ledgerHash, STORAGE, LedgerDataStructure.MERKLE_TREE);
LedgerTransaction act_tx1 = repo.getTransactionSet().getTransaction(txHash1);
LedgerTransaction act_tx2 = repo.getTransactionSet().getTransaction(txHash2);
LedgerTransaction act_tx3 = repo.getTransactionSet().getTransaction(txHash3);
assertNotNull(act_tx3);
assertNotNull(act_tx2);
assertNotNull(act_tx1);
}
use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class BlockFullRollBackTest method testBlockFullkRollBack.
@Test
public void testBlockFullkRollBack() {
final MemoryKVStorage STORAGE = new MemoryKVStorage();
final MemoryKVStorage STORAGE_Mock = Mockito.spy(STORAGE);
// 初始化账本到指定的存储库;
ledgerHash = initLedger(STORAGE_Mock, parti0, parti1, parti2, parti3);
System.out.println("---------- Ledger init OK !!! ----------");
// 加载账本;
LedgerManager ledgerManager = new LedgerManager();
LedgerRepository ledgerRepo = ledgerManager.register(ledgerHash, STORAGE_Mock, LedgerDataStructure.MERKLE_TREE);
// 构造存储错误,并产生区块回滚
doThrow(BlockRollbackException.class).when(STORAGE_Mock).set(any(), any(), anyLong());
LedgerEditor newBlockEditor = ledgerRepo.createNextBlock();
OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration();
LedgerSecurityManager securityManager = getSecurityManager();
TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(securityManager, newBlockEditor, ledgerRepo, opReg);
// 注册新用户;
BlockchainKeypair userKeypair = BlockchainKeyGenerator.getInstance().generate();
TransactionRequest transactionRequest = LedgerTestUtils.createTxRequest_UserReg(userKeypair, ledgerHash, parti0, parti0);
TransactionResponse txResp = txbatchProcessor.schedule(transactionRequest);
LedgerBlock newBlock = newBlockEditor.prepare();
try {
newBlockEditor.commit();
} catch (BlockRollbackException e) {
newBlockEditor.cancel();
}
// 验证正确性;
ledgerManager = new LedgerManager();
ledgerRepo = ledgerManager.register(ledgerHash, STORAGE_Mock, LedgerDataStructure.MERKLE_TREE);
LedgerBlock latestBlock = ledgerRepo.getLatestBlock();
assertEquals(ledgerRepo.getBlockHash(0), latestBlock.getHash());
assertEquals(0, latestBlock.getHeight());
LedgerDataSet ledgerDS = ledgerRepo.getLedgerDataSet(latestBlock);
boolean existUser = ledgerDS.getUserAccountSet().contains(userKeypair.getAddress());
assertFalse(existUser);
doCallRealMethod().when(STORAGE_Mock).set(any(), any(), anyLong());
// 区块正常提交
// 生成新区块;
LedgerEditor newBlockEditor1 = ledgerRepo.createNextBlock();
OperationHandleRegisteration opReg1 = new DefaultOperationHandleRegisteration();
LedgerSecurityManager securityManager1 = getSecurityManager();
TransactionBatchProcessor txbatchProcessor1 = new TransactionBatchProcessor(securityManager1, newBlockEditor1, ledgerRepo, opReg1);
// 注册新用户;
BlockchainKeypair userKeypair1 = BlockchainKeyGenerator.getInstance().generate();
TransactionRequest transactionRequest1 = LedgerTestUtils.createTxRequest_UserReg(userKeypair1, ledgerHash, parti0, parti0);
TransactionResponse txResp1 = txbatchProcessor1.schedule(transactionRequest1);
LedgerBlock newBlock1 = newBlockEditor1.prepare();
try {
newBlockEditor1.commit();
} catch (BlockRollbackException e) {
newBlockEditor1.cancel();
}
ledgerManager = new LedgerManager();
ledgerRepo = ledgerManager.register(ledgerHash, STORAGE_Mock, LedgerDataStructure.MERKLE_TREE);
LedgerBlock latestBlock1 = ledgerRepo.getLatestBlock();
assertEquals(newBlock1.getHash(), latestBlock1.getHash());
assertEquals(1, latestBlock1.getHeight());
LedgerDataSet ledgerDS1 = ledgerRepo.getLedgerDataSet(latestBlock1);
boolean existUser1 = ledgerDS1.getUserAccountSet().contains(userKeypair1.getAddress());
assertTrue(existUser1);
}
use of com.jd.blockchain.storage.service.utils.MemoryKVStorage 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++;
}
}
use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class MerkleHashSortTreeTest method newMerkleTree_with_committed.
private MerkleHashSortTree newMerkleTree_with_committed(VersioningKVData<String, byte[]>[] datas) {
TreeOptions treeOption = createTreeOptions();
MemoryKVStorage storage = new MemoryKVStorage();
return newMerkleTree(datas, treeOption, storage, true);
}
use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class MerkleSortTreePerformanceTest method testPerformace1.
private void testPerformace1(int round, int count) {
System.out.printf("------------- Performance test: MerkleSortTree --------------\r\n", round, count);
TreeOptions options = TreeOptions.build().setDefaultHashAlgorithm(ClassicAlgorithm.SHA256.code());
Bytes prefix = Bytes.fromString(LedgerTestUtils.LEDGER_KEY_PREFIX);
MemoryKVStorage storage = new MemoryKVStorage();
Random rand = new Random();
byte[] value = new byte[128];
rand.nextBytes(value);
long startTs = System.currentTimeMillis();
MerkleSortTree<byte[]> merkleTree = MerkleSortTree.createBytesTree(options, prefix, storage);
long key;
for (int r = 0; r < round; r++) {
for (int i = 0; i < count; i++) {
key = ((long) r << 32) | i;
merkleTree.set(key, value);
}
merkleTree.commit();
}
long elapsedTs = System.currentTimeMillis() - startTs;
long totalCount = count * round;
double tps = round * 1000.0D / elapsedTs;
double kps = round * count * 1000.0D / elapsedTs;
System.out.printf("--[Performance]:: TotalKeys=%s; Round=%s; Count=%s; Times=%sms; TPS=%.2f; KPS=%.2f\r\n\r\n", totalCount, round, count, elapsedTs, tps, kps);
}
Aggregations