From 53bb8e6f08ee1e87b6098bb4c8d65a02a47bc3fa Mon Sep 17 00:00:00 2001 From: zhangshuang Date: Thu, 28 Nov 2019 14:51:10 +0800 Subject: [PATCH] solve block rollback exception --- .../bftsmart/service/BftsmartNodeServer.java | 105 ++++++------------ .../consensus/ConsensusMessageDispatcher.java | 5 + 2 files changed, 39 insertions(+), 71 deletions(-) diff --git a/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java b/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java index bbecdb5c..fcebcfa0 100644 --- a/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java +++ b/source/consensus/consensus-bftsmart/src/main/java/com/jd/blockchain/consensus/bftsmart/service/BftsmartNodeServer.java @@ -354,40 +354,6 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer // }); } - /** - * - * Used by consensus write phase, pre compute new block hash - * - */ -// public BatchAppResultImpl preComputeAppHash(byte[][] commands) { -// String batchId = messageHandle.beginBatch(realmName); -// List> asyncFutureLinkedList = new ArrayList<>(commands.length); -// List responseLinkedList = new ArrayList<>(); -// try { -// int msgId = 0; -// for (byte[] txContent : commands) { -// AsyncFuture asyncFuture = messageHandle.processOrdered(msgId++, txContent, realmName, batchId); -// asyncFutureLinkedList.add(asyncFuture); -// } -// StateSnapshot stateSnapshot = messageHandle.completeBatch(realmName, batchId); -// byte[] blockHashBytes = stateSnapshot.getSnapshot(); -// -// for (int i = 0; i< asyncFutureLinkedList.size(); i++) { -// responseLinkedList.add(asyncFutureLinkedList.get(i).get()); -// } -// -// -// return new BatchAppResultImpl(responseLinkedList, blockHashBytes, batchId); -// -// } catch (Exception e) { -// // todo 需要处理应答码 404 -// LOGGER.error("Error occurred while processing ordered messages! --" + e.getMessage(), e); -// messageHandle.rollbackBatch(realmName, batchId, TransactionState.IGNORED_BY_CONSENSUS_PHASE_PRECOMPUTE_ROLLBACK.CODE); -// } -// -// return null; -// } - /** * Used by consensus write phase, pre compute new block hash */ @@ -395,56 +361,53 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer String batchId = messageHandle.beginBatch(realmName); List> asyncFutureLinkedList = new ArrayList<>(commands.length); List responseLinkedList = new ArrayList<>(); + StateSnapshot stateSnapshot = null; BatchAppResultImpl result; - try { - int msgId = 0; - - boolean isOK = true; - TransactionState transactionState = TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK; + int msgId = 0; + boolean isOK = true; + TransactionState transactionState = TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK; - try { - for (int i = 0; i < commands.length; i++) { - byte[] txContent = commands[i]; - AsyncFuture asyncFuture = messageHandle.processOrdered(msgId++, txContent, realmName, batchId); - asyncFutureLinkedList.add(asyncFuture); - } - } catch (BlockRollbackException e) { - LOGGER.error("Error occurred while processing ordered messages! --" + e.getMessage(), e); - isOK = false; + try { + for (int i = 0; i < commands.length; i++) { + byte[] txContent = commands[i]; + AsyncFuture asyncFuture = messageHandle.processOrdered(msgId++, txContent, realmName, batchId); + asyncFutureLinkedList.add(asyncFuture); } + stateSnapshot = messageHandle.completeBatch(realmName, batchId); + } catch (Exception e) { + LOGGER.error("Error occurred while processing ordered messages or complete batch! --" + e.getMessage(), e); + messageHandle.rollbackBatch(realmName, batchId, TransactionState.IGNORED_BY_CONSENSUS_PHASE_PRECOMPUTE_ROLLBACK.CODE); + isOK = false; + } - if (isOK) { - StateSnapshot stateSnapshot = messageHandle.completeBatch(realmName, batchId); - byte[] blockHashBytes = stateSnapshot.getSnapshot(); + if (isOK) { - for (int i = 0; i < asyncFutureLinkedList.size(); i++) { - responseLinkedList.add(asyncFutureLinkedList.get(i).get()); - } + byte[] blockHashBytes = stateSnapshot.getSnapshot(); - result = new BatchAppResultImpl(responseLinkedList, blockHashBytes, batchId); - result.setErrorCode((byte) 0); + for (int i = 0; i < asyncFutureLinkedList.size(); i++) { + responseLinkedList.add(asyncFutureLinkedList.get(i).get()); + } - return result; - } else { + result = new BatchAppResultImpl(responseLinkedList, blockHashBytes, batchId); + result.setErrorCode((byte) 0); - for (int i = 0; i < commands.length; i++) { - responseLinkedList.add(createAppResponse(commands[i],transactionState)); - } + return result; + } else { - Random random = new Random(); - byte[] rand = new byte[4]; - random.nextBytes(rand); + for (int i = 0; i < commands.length; i++) { + responseLinkedList.add(createAppResponse(commands[i],transactionState)); + } - result = new BatchAppResultImpl(responseLinkedList, rand, batchId); - result.setErrorCode((byte) 1); + Random random = new Random(); + byte[] rand = new byte[4]; + random.nextBytes(rand); - return result; - } + result = new BatchAppResultImpl(responseLinkedList, rand, batchId); + result.setErrorCode((byte) 1); - } catch (Exception e) { - LOGGER.error("Error occurred while genearte batch app result! --" + e.getMessage(), e); - throw e; + return result; } + } // Block full rollback responses, generated in pre compute phase, due to tx fail diff --git a/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusMessageDispatcher.java b/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusMessageDispatcher.java index 7a3ba62f..ceb33490 100644 --- a/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusMessageDispatcher.java +++ b/source/peer/src/main/java/com/jd/blockchain/peer/consensus/ConsensusMessageDispatcher.java @@ -236,12 +236,17 @@ public class ConsensusMessageDispatcher implements MessageHandle { currBatchId = null; txResponseMap = null; txBatchProcess = null; + batchResultHandle =null; } finally { realmLock.unlock(); } } public void rollback(int reasonCode) { + + if (batchResultHandle == null) { + return; + } realmLock.lock(); try { batchResultHandle.cancel(TransactionState.valueOf((byte)reasonCode));