use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class TransactionSetTest method testTransactionSequence.
@Test
public void testTransactionSequence() {
CryptoSetting cryptoSetting = LedgerTestUtils.createDefaultCryptoSetting();
MemoryKVStorage testStorage = new MemoryKVStorage();
// Create a new TransactionSet;
TransactionSetEditor txset = new TransactionSetEditor(cryptoSetting, keyPrefix, testStorage, testStorage, LedgerDataStructure.MERKLE_TREE);
HashDigest ledgerHash = LedgerTestUtils.generateRandomHash();
long blockHeight = 8922L;
// 生成指定数量的测试数据:交易请求和交易执行结果;
int txCount0 = 10;
TransactionRequest[] txRequests_0 = new TransactionRequest[txCount0];
TransactionResult[] txResults_0 = new TransactionResult[txCount0];
buildRequestAndResult(ledgerHash, blockHeight, cryptoSetting, txCount0, txRequests_0, txResults_0);
// add tx to trasaction set;
for (int i = 0; i < txCount0; i++) {
txset.addTransaction(txRequests_0[i], txResults_0[i]);
}
txset.commit();
// 验证交易集合中记录的交易顺序;
assertEquals(txCount0, txset.getTotalCount());
TransactionResult[] actualTxResults = txset.getTransactionResults(0, txCount0);
assertEquals(txCount0, actualTxResults.length);
for (int i = 0; i < txCount0; i++) {
assertTransactionEquals(txResults_0[i], actualTxResults[i]);
}
// 重新加载交易集合;
HashDigest txsetRootHash = txset.getRootHash();
TransactionSetEditor reloadTxset = new TransactionSetEditor(-1, txsetRootHash, cryptoSetting, keyPrefix, testStorage, testStorage, LedgerDataStructure.MERKLE_TREE, true);
// 验证重新加载之后的交易集合中记录的交易顺序;
assertEquals(txCount0, reloadTxset.getTotalCount());
TransactionResult[] actualTxResults_reload = reloadTxset.getTransactionResults(0, txCount0);
assertEquals(txCount0, actualTxResults_reload.length);
for (int i = 0; i < txCount0; i++) {
assertTransactionEquals(txResults_0[i], actualTxResults_reload[i]);
}
// 生成指定数量的测试数据:交易请求和交易执行结果;
int txCount1 = new Random().nextInt(200) + 1;
TransactionRequest[] txRequests_1 = new TransactionRequest[txCount1];
TransactionResult[] txResults_1 = new TransactionResult[txCount1];
buildRequestAndResult(ledgerHash, blockHeight, cryptoSetting, txCount1, txRequests_1, txResults_1);
// add tx to trasaction set;
TransactionSetEditor newTxset = new TransactionSetEditor(-1, txsetRootHash, cryptoSetting, keyPrefix, testStorage, testStorage, LedgerDataStructure.MERKLE_TREE, false);
for (int i = 0; i < txCount1; i++) {
newTxset.addTransaction(txRequests_1[i], txResults_1[i]);
}
newTxset.commit();
// 验证交易集合中记录的交易顺序;
int totalCount = txCount0 + txCount1;
assertEquals(totalCount, newTxset.getTotalCount());
TransactionResult[] actualTxResults_reload_2 = newTxset.getTransactionResults(0, totalCount);
assertEquals(totalCount, actualTxResults_reload_2.length);
TransactionRequest[] txRequests = ArrayUtils.concat(txRequests_0, txRequests_1, TransactionRequest.class);
TransactionResult[] txResults = ArrayUtils.concat(txResults_0, txResults_1, TransactionResult.class);
for (int i = 0; i < totalCount; i++) {
assertTransactionEquals(txResults[i], actualTxResults_reload_2[i]);
}
}
use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class TransactionSetTest method testSpecialCase_1.
/**
* 根据实际运行中一个随机出现的错误中提取到的数据来建立的测试用例,可以更简化地验证正确性;
*
* <p>
*
* 注:重构了 {@link LedgerTransaction} 和 {@link TransactionContent}
* 等交易结构相关的类型之后,此用例已经失效; by huanghaiquan on 2020-09-16;
*/
// @Test
public void testSpecialCase_1() {
CryptoSetting defCryptoSetting = LedgerTestUtils.createDefaultCryptoSetting();
MemoryKVStorage testStorage = new MemoryKVStorage();
BufferedKVStorage bufferStorage = new BufferedKVStorage(null, testStorage, testStorage, false);
// Create a new TransactionSet, it's empty;
TransactionSetEditor txset = new TransactionSetEditor(defCryptoSetting, keyPrefix, bufferStorage, bufferStorage, LedgerDataStructure.MERKLE_TREE);
assertTrue(txset.isUpdated());
assertFalse(txset.isReadonly());
assertNull(txset.getRootHash());
HashDigest ledgerHash = Crypto.resolveAsHashDigest(Base58Utils.decode("j5iF5xJ7KN4kjRrhD3EUKVSPmHz2bExxp3h9avqxcnnzch"));
assertEquals("j5iF5xJ7KN4kjRrhD3EUKVSPmHz2bExxp3h9avqxcnnzch", ledgerHash.toBase58());
BlockchainKeypair parti0 = LedgerTestUtils.createKeyPair("7VeRLBwqTAz8oRazEazeaEfqei46sk2FzvBgyHMUBJvrUEGT", "7VeRUm27GbrsX9HbQSZguChLp24HZYub6s5FJ7FjBht8BmbA");
BlockchainKeypair userKeypair1 = LedgerTestUtils.createKeyPair("7VeRKf3GFLFcBfzvtzmtyMXEoX2HYGEJ4j7CmHcnRV99W5Dp", "7VeRYQjeAaQY5Po8MMtmGNHA2SniqLXmJaZwBS5K8zTtMAU1");
TransactionRequest transactionRequest1 = LedgerTestUtils.createTxRequest_UserReg_SHA256(userKeypair1, ledgerHash, 1580315317127L, parti0, parti0);
// TransactionRequest transactionRequest1 = LedgerTestUtils.createTxRequest_UserReg(userKeypair1, ledgerHash, 202001202020L,
// parti0, parti0);
System.out.printf("\r\n ===||=== transactionRequest1.getTransactionHash()=[%s]\r\n", transactionRequest1.getTransactionHash().toBase58());
// assertEquals("j5sXmpcomtM2QMUNWeQWsF8bNFFnyeXoCjVAekEeLSscgY", transactionRequest1.getTransactionHash().toBase58());
assertEquals("j5wPGKT5CUzwi8j6VfCWaP2p9YZ6WVWtMANp9HbHWzvhgG", transactionRequest1.getTransactionHash().toBase58());
TransactionStagedSnapshot txSnapshot = new TransactionStagedSnapshot();
txSnapshot.setAdminAccountHash(Crypto.resolveAsHashDigest(Base58Utils.decode("j5taeK6cpmJGcn8QbEYCqadna6s7NDSheDTK6NJdU4mFhh")));
txSnapshot.setUserAccountSetHash(Crypto.resolveAsHashDigest(Base58Utils.decode("j5oQDSob92mCoGSHtrXa9soqgAtMyjwfRMt2kj7igXXJrP")));
TransactionResult tx = new TransactionResultData(transactionRequest1.getTransactionHash(), 1, TransactionState.SUCCESS, txSnapshot);
txset.addTransaction(transactionRequest1, tx);
LedgerTransaction tx_query = txset.getTransaction(transactionRequest1.getTransactionHash());
assertNotNull(tx_query);
txset.commit();
bufferStorage.commit();
tx_query = txset.getTransaction(transactionRequest1.getTransactionHash());
TransactionState tx_state = txset.getState(transactionRequest1.getTransactionHash());
assertNotNull(tx_query);
assertEquals(0, tx_state.CODE);
HashDigest txsetRootHash = txset.getRootHash();
txset = new TransactionSetEditor(-1, txsetRootHash, defCryptoSetting, keyPrefix, testStorage, testStorage, LedgerDataStructure.MERKLE_TREE, false);
tx_query = txset.getTransaction(transactionRequest1.getTransactionHash());
tx_state = txset.getState(transactionRequest1.getTransactionHash());
assertNotNull(tx_query);
assertEquals(0, tx_state.CODE);
}
use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class UserRoleDatasetTest method testAddUserRoles.
@Test
public void testAddUserRoles() {
CryptoConfig cryptoConfig = new CryptoConfig();
cryptoConfig.setAutoVerifyHash(true);
cryptoConfig.setSupportedProviders(SUPPORTED_PROVIDERS);
cryptoConfig.setHashAlgorithm(HASH_ALGORITHM);
MemoryKVStorage testStorage = new MemoryKVStorage();
String prefix = "user-roles/";
UserRoleDatasetEditor userRolesDataset = new UserRoleDatasetEditor(cryptoConfig, prefix, testStorage, testStorage, LedgerDataStructure.MERKLE_TREE);
BlockchainKeypair bckp = BlockchainKeyGenerator.getInstance().generate();
String[] authRoles = { "DEFAULT", "MANAGER" };
userRolesDataset.addUserRoles(bckp.getAddress(), RolesPolicy.UNION, authRoles);
userRolesDataset.commit();
assertEquals(1, userRolesDataset.getUserCount());
UserRoles userRoles = userRolesDataset.getUserRoles(bckp.getAddress());
assertNotNull(userRoles);
String[] roles = userRoles.getRoles();
assertEquals(2, roles.length);
assertArrayEquals(authRoles, roles);
assertEquals(RolesPolicy.UNION, userRoles.getPolicy());
}
use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class MerkleHashSortTreePerformanceTest method testPerformace1.
private static void testPerformace1(int round, int count) {
System.out.printf("------------- Performance test: MerkleHashSortTree --------------\r\n", round, count);
TreeOptions setting = 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();
MerkleHashSortTree merkleTree = new MerkleHashSortTree(setting, prefix, storage);
String key;
for (int r = 0; r < round; r++) {
for (int i = 0; i < count; i++) {
key = "KEY-" + r + "-" + i;
merkleTree.setData(key, 0, 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);
}
use of com.jd.blockchain.storage.service.utils.MemoryKVStorage in project jdchain-core by blockchain-jd-com.
the class MerkleSortTreeTest method testCommitAndCancel.
@Test
public void testCommitAndCancel() {
int count1 = 48;
byte[][] datas1 = generateRandomData(count1);
long[] ids1 = generateRandomIDs(count1);
Set<Long> excludingIds = createIdSet(ids1);
int count2 = 32;
byte[][] datas2 = generateRandomData(count2);
long[] ids2 = generateRandomIDs(count2, excludingIds, true);
TreeOptions options = createTreeOptions();
MemoryKVStorage storage = new MemoryKVStorage();
MerkleSortTree<byte[]> mst = MerkleSortTree.createBytesTree(options, DEFAULT_MKL_KEY_PREFIX, storage);
long expectedMaxId1 = Arrays.stream(ids1).max().getAsLong();
assertEquals(0, mst.getCount());
assertNull(mst.getRootHash());
assertEquals(-1L, mst.getMaxId());
addDatas(ids1, datas1, mst);
// 未提交之前总数不会发生变化;
assertEquals(0, mst.getCount());
assertNull(mst.getRootHash());
// “最大编码”会实时更新;
assertNotNull(mst.getMaxId());
assertEquals(expectedMaxId1, mst.getMaxId());
// 迭代器不包含未提交的数据;预期迭代器为空;
SkippingIterator<MerkleValue<byte[]>> iter = mst.bytesIterator();
assertEquals(0, iter.getTotalCount());
// 提交之后才更新属性;
mst.commit();
assertEquals(count1, mst.getCount());
assertNotNull(mst.getRootHash());
assertNotNull(mst.getMaxId());
assertEquals(expectedMaxId1, mst.getMaxId());
assertDataEquals(mst, ids1, datas1);
// 预期提交后,迭代器反映出最新提交的数据;
Map<Long, byte[]> dataMap = new HashMap<Long, byte[]>();
mapIdValues(ids1, datas1, dataMap);
iter = mst.iterator();
long[] sortedIds1 = ids1;
Arrays.sort(sortedIds1);
assertIteratorSortedAndEquals(iter, count1, sortedIds1, dataMap);
// 测试写入数据后回滚操作是否符合预期;
long expectedMaxId2 = Arrays.stream(ids2).max().getAsLong();
expectedMaxId2 = Math.max(expectedMaxId1, expectedMaxId2);
HashDigest rootHash1 = mst.getRootHash();
// 写入数据,但并不提交;
addDatas(ids2, datas2, mst);
// 预期未提交之前,根哈希不会变化;
assertEquals(rootHash1, mst.getRootHash());
// 预期未提交之前,总数不会变化;
assertEquals(count1, mst.getCount());
// 预期“最大编码”属性是实时变化的;
assertEquals(expectedMaxId2, mst.getMaxId());
// 预期未提交之前,预期迭代器不会变化;
iter = mst.iterator();
assertIteratorSortedAndEquals(iter, count1, sortedIds1, dataMap);
// 回滚之后,预期所有的属性恢复到上一次提交的结果;
mst.cancel();
// 预期“根哈希”维持上次提交之后的结果;
assertEquals(rootHash1, mst.getRootHash());
// 预期“总数”维持上次提交之后的结果;
assertEquals(count1, mst.getCount());
// 预期“最大编码”属性恢复到上次提交之后的结果;
assertEquals(expectedMaxId1, mst.getMaxId());
// 预期迭代器不会变化,维持上次提交之后的结果;
iter = mst.iterator();
assertIteratorSortedAndEquals(iter, count1, sortedIds1, dataMap);
}
Aggregations