use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class ContractInvokingTest method testReadNewWritting.
// @Test
public void testReadNewWritting() {
// 初始化账本到指定的存储库;
HashDigest ledgerHash = initLedger(storage, parti0, parti1, parti2, parti3);
// 重新加载账本;
LedgerManager ledgerManager = new LedgerManager();
LedgerRepository ledgerRepo = ledgerManager.register(ledgerHash, storage, LedgerDataStructure.MERKLE_TREE);
// 创建合约处理器;
ContractInvokingHandle contractInvokingHandle = new ContractInvokingHandle();
// 创建和加载合约实例;
BlockchainKeypair contractKey = BlockchainKeyGenerator.getInstance().generate();
Bytes contractAddress = contractKey.getAddress();
TxTestContractImpl contractInstance = new TxTestContractImpl();
contractInvokingHandle.setup(contractAddress, TxTestContract.class, contractInstance);
// 注册合约处理器;
DefaultOperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration();
opReg.registerHandle(contractInvokingHandle);
// 发布指定地址合约
deploy(ledgerRepo, ledgerManager, opReg, ledgerHash, contractKey);
// 创建新区块的交易处理器;
LedgerBlock preBlock = ledgerRepo.getLatestBlock();
LedgerDataSet previousBlockDataset = ledgerRepo.getLedgerDataSet(preBlock);
// 加载合约
LedgerEditor newBlockEditor = ledgerRepo.createNextBlock();
TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(getSecurityManager(), newBlockEditor, ledgerRepo, opReg);
String key = TxTestContractImpl.KEY;
String value = "VAL";
CryptoSetting cryptoSetting = ledgerRepo.getAdminInfo().getSettings().getCryptoSetting();
TxBuilder txBuilder = new TxBuilder(ledgerHash, cryptoSetting.getHashAlgorithm());
BlockchainKeypair kpDataAccount = BlockchainKeyGenerator.getInstance().generate();
contractInstance.setDataAddress(kpDataAccount.getAddress());
txBuilder.dataAccounts().register(kpDataAccount.getIdentity());
TransactionRequestBuilder txReqBuilder1 = txBuilder.prepareRequest();
txReqBuilder1.signAsEndpoint(parti0);
txReqBuilder1.signAsNode(parti0);
TransactionRequest txReq1 = txReqBuilder1.buildRequest();
// 构建基于接口调用合约的交易请求,用于测试合约调用;
txBuilder = new TxBuilder(ledgerHash, cryptoSetting.getHashAlgorithm());
TxTestContract contractProxy = txBuilder.contract(contractAddress, TxTestContract.class);
BooleanValueHolder readableHolder = decode(contractProxy.testReadable());
TransactionRequestBuilder txReqBuilder2 = txBuilder.prepareRequest();
txReqBuilder2.signAsEndpoint(parti0);
txReqBuilder2.signAsNode(parti0);
TransactionRequest txReq2 = txReqBuilder2.buildRequest();
TransactionResponse resp1 = txbatchProcessor.schedule(txReq1);
TransactionResponse resp2 = txbatchProcessor.schedule(txReq2);
// 提交区块;
TransactionBatchResultHandle txResultHandle = txbatchProcessor.prepare();
txResultHandle.commit();
BytesValue latestValue = ledgerRepo.getDataAccountSet().getAccount(kpDataAccount.getAddress()).getDataset().getValue(key, -1);
System.out.printf("latest value=[%s] %s \r\n", latestValue.getType(), latestValue.getBytes().toUTF8String());
boolean readable = readableHolder.get();
assertTrue(readable);
LedgerBlock latestBlock = ledgerRepo.getLatestBlock();
assertEquals(preBlock.getHeight() + 1, latestBlock.getHeight());
assertEquals(resp1.getBlockHeight(), latestBlock.getHeight());
assertEquals(resp1.getBlockHash(), latestBlock.getHash());
}
use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class ContractInvokingTest method deploy.
private void deploy(LedgerRepository ledgerRepo, LedgerManager ledgerManager, DefaultOperationHandleRegisteration opReg, HashDigest ledgerHash, BlockchainKeypair contractKey) {
// 创建新区块的交易处理器;
LedgerBlock preBlock = ledgerRepo.getLatestBlock();
LedgerDataSet previousBlockDataset = ledgerRepo.getLedgerDataSet(preBlock);
// 加载合约
LedgerEditor newBlockEditor = ledgerRepo.createNextBlock();
LedgerSecurityManager securityManager = getSecurityManager();
TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(securityManager, newBlockEditor, ledgerRepo, opReg);
// 构建基于接口调用合约的交易请求,用于测试合约调用;
CryptoSetting cryptoSetting = ledgerRepo.getAdminInfo().getSettings().getCryptoSetting();
TxBuilder txBuilder = new TxBuilder(ledgerHash, cryptoSetting.getHashAlgorithm());
txBuilder.contracts().deploy(contractKey.getIdentity(), chainCode());
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
txReqBuilder.signAsEndpoint(parti0);
txReqBuilder.signAsNode(parti0);
TransactionRequest txReq = txReqBuilder.buildRequest();
TransactionResponse resp = txbatchProcessor.schedule(txReq);
OperationResult[] opResults = resp.getOperationResults();
assertNull(opResults);
// 提交区块;
TransactionBatchResultHandle txResultHandle = txbatchProcessor.prepare();
txResultHandle.commit();
}
use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class ContractInvokingTest method registerDataAccount.
private void registerDataAccount(LedgerRepository ledgerRepo, LedgerManager ledgerManager, DefaultOperationHandleRegisteration opReg, HashDigest ledgerHash, BlockchainKeypair kpDataAccount) {
LedgerBlock preBlock = ledgerRepo.getLatestBlock();
LedgerDataSet previousBlockDataset = ledgerRepo.getLedgerDataSet(preBlock);
// 加载合约
LedgerEditor newBlockEditor = ledgerRepo.createNextBlock();
TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(getSecurityManager(), newBlockEditor, ledgerRepo, opReg);
// 注册数据账户;
CryptoSetting cryptoSetting = ledgerRepo.getAdminInfo().getSettings().getCryptoSetting();
TxBuilder txBuilder = new TxBuilder(ledgerHash, cryptoSetting.getHashAlgorithm());
txBuilder.dataAccounts().register(kpDataAccount.getIdentity());
TransactionRequestBuilder txReqBuilder1 = txBuilder.prepareRequest();
txReqBuilder1.signAsEndpoint(parti0);
txReqBuilder1.signAsNode(parti0);
TransactionRequest txReq = txReqBuilder1.buildRequest();
TransactionResponse resp = txbatchProcessor.schedule(txReq);
TransactionBatchResultHandle txResultHandle = txbatchProcessor.prepare();
txResultHandle.commit();
assertNotNull(resp.getBlockHash());
assertEquals(TransactionState.SUCCESS, resp.getExecutionState());
assertEquals(preBlock.getHeight() + 1, resp.getBlockHeight());
}
use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class ManagementController method checkLedgerDiff.
private WebResponse checkLedgerDiff(HashDigest ledgerHash, LedgerRepository ledgerRepository, LedgerBlock ledgerLatestBlock, ServiceEndpoint endpoint) {
LOGGER.info("check ledger diff from {}:{}:{}", endpoint.getHost(), endpoint.getPort(), endpoint.isSecure());
long localLatestBlockHeight = ledgerLatestBlock.getHeight();
HashDigest localLatestBlockHash = ledgerLatestBlock.getHash();
TransactionBatchResultHandle handle = null;
try (ServiceConnection httpConnection = ServiceConnectionManager.connect(endpoint)) {
HttpBlockchainBrowserService queryService = HttpServiceAgent.createService(HttpBlockchainBrowserService.class, httpConnection, null);
// 激活新节点时,远端管理节点最新区块高度
long remoteLatestBlockHeight = queryService.getLedger(ledgerHash).getLatestBlockHeight();
if ((localLatestBlockHeight <= remoteLatestBlockHeight)) {
// 检查本节点与拉取节点相同高度的区块,哈希是否一致,不一致说明其中一个节点的数据库被污染了
HashDigest remoteBlockHash = queryService.getBlock(ledgerHash, localLatestBlockHeight).getHash();
if (!(localLatestBlockHash.toBase58().equals(remoteBlockHash.toBase58()))) {
throw new IllegalStateException("checkLedgerDiff, ledger database is inconsistent, please check ledger database!");
}
// 本节点与拉取节点高度一致,不需要进行交易重放
if (localLatestBlockHeight == remoteLatestBlockHeight) {
return WebResponse.createSuccessResult(null);
}
} else {
throw new IllegalStateException("checkLedgerDiff, local latest block height > remote node latest block height!");
}
OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration();
// 对差异进行交易重放
for (int height = (int) localLatestBlockHeight + 1; height <= remoteLatestBlockHeight; height++) {
TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(ledgerRepository, opReg);
// transactions replay
try {
HashDigest pullBlockHash = queryService.getBlock(ledgerHash, height).getHash();
long pullBlockTime = queryService.getBlock(ledgerHash, height).getTimestamp();
// 获取区块内的增量交易
List<LedgerTransaction> addition_transactions = getAdditionalTransactions(queryService, ledgerHash, height);
try {
for (LedgerTransaction ledgerTransaction : addition_transactions) {
txbatchProcessor.schedule(ledgerTransaction.getRequest());
}
} catch (BlockRollbackException e) {
txbatchProcessor.cancel(LEDGER_ERROR);
continue;
}
LedgerEditor.TIMESTAMP_HOLDER.set(pullBlockTime);
handle = txbatchProcessor.prepare();
if (!(handle.getBlock().getHash().toBase58().equals(pullBlockHash.toBase58()))) {
LOGGER.error("checkLedgerDiff, transactions replay result is inconsistent at height {}", height);
throw new IllegalStateException("checkLedgerDiff, transactions replay, block hash result is inconsistent!");
}
handle.commit();
} catch (Exception e) {
handle.cancel(LEDGER_ERROR);
throw new IllegalStateException("checkLedgerDiff, transactions replay failed!", e);
}
}
} catch (Exception e) {
LOGGER.error("checkLedgerDiff error!", e);
return WebResponse.createFailureResult(-1, "checkLedgerDiff error!" + e);
}
return WebResponse.createSuccessResult(null);
}
use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class BlockSyncService method sync.
private void sync(HttpBlockchainBrowserService queryService, HashDigest ledger, LedgerBlock block) {
if (block == null) {
throw new IllegalStateException("sync block is null");
}
OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration();
TransactionBatchProcessor batchProcessor = new TransactionBatchProcessor(repository, opReg);
List<LedgerTransaction> transactions = getAdditionalTransactions(queryService, ledger, block.getHeight());
try {
for (LedgerTransaction ledgerTransaction : transactions) {
batchProcessor.schedule(ledgerTransaction.getRequest());
}
} catch (BlockRollbackException e) {
batchProcessor.cancel(LEDGER_ERROR);
throw e;
}
LedgerEditor.TIMESTAMP_HOLDER.set(block.getTimestamp());
TransactionBatchResultHandle handle = batchProcessor.prepare();
try {
if (!(handle.getBlock().getHash().toBase58().equals(block.getHash().toBase58()))) {
throw new IllegalStateException("sync block hash result is inconsistent!");
}
if (handle.getBlock().getHeight() != block.getHeight()) {
throw new IllegalStateException("sync block height is inconsistent!");
}
handle.commit();
} catch (Exception e) {
handle.cancel(TransactionState.SYSTEM_ERROR);
throw e;
}
LOGGER.debug("sync block at height {}", block.getHeight());
}
Aggregations