use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class ContractInvokingTest method buildBlock.
private LedgerBlock buildBlock(LedgerRepository ledgerRepo, LedgerService ledgerService, OperationHandleRegisteration opReg, TxDefinitor txDefinitor) {
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(ledgerRepo.getHash(), cryptoSetting.getHashAlgorithm());
txDefinitor.buildTx(txBuilder);
TransactionRequest txReq = buildAndSignRequest(txBuilder, parti0, parti0);
TransactionResponse resp = txbatchProcessor.schedule(txReq);
// 提交区块;
TransactionBatchResultHandle txResultHandle = txbatchProcessor.prepare();
txResultHandle.commit();
LedgerBlock latestBlock = ledgerRepo.getLatestBlock();
assertNotNull(resp.getBlockHash());
assertEquals(preBlock.getHeight() + 1, resp.getBlockHeight());
return latestBlock;
}
use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class ContractInvokingTest method testNormal.
@Ignore("合约需要更新")
@Test
public void testNormal() {
// 初始化账本到指定的存储库;
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();
TestContract contractInstance = Mockito.mock(TestContract.class);
final String asset = "AK";
final long issueAmount = new Random().nextLong();
when(contractInstance.issue(anyString(), anyLong())).thenReturn(issueAmount);
// 装载合约;
contractInvokingHandle.setup(contractAddress, TestContract.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();
LedgerSecurityManager securityManager = getSecurityManager();
TransactionBatchProcessor txbatchProcessor = new TransactionBatchProcessor(securityManager, newBlockEditor, ledgerRepo, opReg);
// 构建基于接口调用合约的交易请求,用于测试合约调用;
CryptoSetting cryptoSetting = ledgerRepo.getAdminInfo().getSettings().getCryptoSetting();
TxBuilder txBuilder = new TxBuilder(ledgerHash, cryptoSetting.getHashAlgorithm());
TestContract contractProxy = txBuilder.contract(contractAddress, TestContract.class);
// 构造调用合约的交易;
contractProxy.issue(asset, issueAmount);
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
txReqBuilder.signAsEndpoint(parti0);
txReqBuilder.signAsNode(parti0);
TransactionRequest txReq = txReqBuilder.buildRequest();
TransactionResponse resp = txbatchProcessor.schedule(txReq);
verify(contractInstance, times(1)).issue(asset, issueAmount);
OperationResult[] opResults = resp.getOperationResults();
assertEquals(1, opResults.length);
assertEquals(0, opResults[0].getIndex());
byte[] expectedRetnBytes = BinaryProtocol.encode(TypedValue.fromInt64(issueAmount), BytesValue.class);
byte[] reallyRetnBytes = BinaryProtocol.encode(opResults[0].getResult(), BytesValue.class);
assertArrayEquals(expectedRetnBytes, reallyRetnBytes);
// 提交区块;
TransactionBatchResultHandle txResultHandle = txbatchProcessor.prepare();
txResultHandle.commit();
LedgerBlock latestBlock = ledgerRepo.getLatestBlock();
assertEquals(preBlock.getHeight() + 1, latestBlock.getHeight());
assertEquals(resp.getBlockHeight(), latestBlock.getHeight());
assertEquals(resp.getBlockHash(), latestBlock.getHash());
// 再验证一次结果;
assertEquals(1, opResults.length);
assertEquals(0, opResults[0].getIndex());
reallyRetnBytes = BinaryProtocol.encode(opResults[0].getResult(), BytesValue.class);
assertArrayEquals(expectedRetnBytes, reallyRetnBytes);
}
use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class ManagementController method replayTransaction.
private boolean replayTransaction(LedgerRepository ledgerRepository, ParticipantNode node, ServiceEndpoint endpoint) {
long height = ledgerRepository.retrieveLatestBlock().getHeight();
HashDigest ledgerHash = ledgerRepository.retrieveLatestBlock().getLedgerHash();
TransactionBatchResultHandle handle = null;
OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration();
try (ServiceConnection httpConnection = ServiceConnectionManager.connect(endpoint)) {
HttpBlockchainBrowserService queryService = HttpServiceAgent.createService(HttpBlockchainBrowserService.class, httpConnection, null);
while (true) {
boolean getout = false;
TransactionBatchProcessor batchProcessor = new TransactionBatchProcessor(ledgerRepository, opReg);
try {
height++;
long remoteLatestBlockHeight = queryService.getLedger(ledgerHash).getLatestBlockHeight();
// fix endpoint write block to database slow bug, that lead to active node failed!
int count = 0;
while ((remoteLatestBlockHeight < height) && (count < 600)) {
Thread.sleep(1000);
remoteLatestBlockHeight = queryService.getLedger(ledgerHash).getLatestBlockHeight();
count++;
}
if (remoteLatestBlockHeight < height) {
throw new IllegalStateException("Remote endpoint block height exception!");
}
LedgerBlock block = queryService.getBlock(ledgerHash, height);
// 获取区块内的增量交易
List<LedgerTransaction> transactions = getAdditionalTransactions(queryService, ledgerHash, (int) height);
try {
for (LedgerTransaction ledgerTransaction : transactions) {
batchProcessor.schedule(ledgerTransaction.getRequest());
Operation[] operations = ledgerTransaction.getRequest().getTransactionContent().getOperations();
for (Operation op : operations) {
if (op instanceof ParticipantStateUpdateOperation) {
ParticipantStateUpdateOperation psop = (ParticipantStateUpdateOperation) op;
if (psop.getParticipantID().getPubKey().equals(node.getPubKey())) {
getout = true;
}
}
}
}
} catch (BlockRollbackException e) {
batchProcessor.cancel(LEDGER_ERROR);
continue;
}
LedgerEditor.TIMESTAMP_HOLDER.set(block.getTimestamp());
handle = batchProcessor.prepare();
if (!(handle.getBlock().getHash().toBase58().equals(block.getHash().toBase58()))) {
LOGGER.error("replayTransaction, transactions replay result is inconsistent at height {}", height);
throw new IllegalStateException("checkLedgerDiff, transactions replay, block hash result is inconsistent!");
}
handle.commit();
LOGGER.debug("replayTransaction, transactions replay result is consistent at height {}", height);
if (getout) {
return true;
}
} catch (Exception e) {
handle.cancel(LEDGER_ERROR);
throw new IllegalStateException("replayTransaction, transactions replay failed!", e);
}
}
}
}
use of com.jd.blockchain.service.TransactionBatchResultHandle in project jdchain-core by blockchain-jd-com.
the class ManagementController method cancelBlock.
private void cancelBlock(long blockGenerateTime, TransactionBatchProcessor txBatchProcessor) {
LedgerEditor.TIMESTAMP_HOLDER.set(blockGenerateTime);
TransactionBatchResultHandle handle = txBatchProcessor.prepare();
handle.cancel(LEDGER_ERROR);
}
Aggregations