@@ -400,19 +400,20 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer | |||
int msgId = 0; | |||
boolean isOK = true; | |||
TransactionState transactionState = TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK; | |||
for (int i = 0; i < commands.length; i++) { | |||
byte[] txContent = commands[i]; | |||
try { | |||
AsyncFuture<byte[]> 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; | |||
// TODO: handle the BlockRollbackException in detail; | |||
if (e instanceof DataVersionConflictException) { | |||
transactionState = TransactionState.DATA_VERSION_CONFLICT; | |||
} | |||
break; | |||
} | |||
} | |||
@@ -432,7 +433,7 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer | |||
} else { | |||
for (int i = 0; i < commands.length; i++) { | |||
responseLinkedList.add(createAppResponse(commands[i])); | |||
responseLinkedList.add(createAppResponse(commands[i],transactionState)); | |||
} | |||
Random random = new Random(); | |||
@@ -451,11 +452,12 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer | |||
} | |||
} | |||
public byte[] createAppResponse(byte[] command) { | |||
public byte[] createAppResponse(byte[] command, TransactionState transactionState) { | |||
TransactionRequest txRequest = BinaryProtocol.decode(command); | |||
TxResponseMessage resp = new TxResponseMessage(txRequest.getTransactionContent().getHash()); | |||
resp.setExecutionState(TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK); | |||
// resp.setExecutionState(TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK); | |||
resp.setExecutionState(transactionState); | |||
return BinaryProtocol.encode(resp, TransactionResponse.class); | |||
} | |||
@@ -42,7 +42,7 @@ public class GatewayInterceptServiceHandler implements GatewayInterceptService { | |||
private void contractCheck(final ContractCodeDeployOperation contractOP) { | |||
// 校验chainCode | |||
ContractJarUtils.verify(contractOP.getChainCode()); | |||
ContractJarUtils.verify(contractsPath, contractOP.getChainCode()); | |||
} | |||
private static String jarRootDir() { | |||
@@ -597,7 +597,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { | |||
public BlockchainIdentity[] getUsers(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, | |||
@RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, | |||
@RequestParam(name = "count", required = false, defaultValue = "-1") int count) { | |||
return peerService.getQueryService().getUsers(ledgerHash, fromIndex, count); | |||
return revertAccountHeader(peerService.getQueryService().getUsers(ledgerHash, fromIndex, count)); | |||
} | |||
@RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/accounts") | |||
@@ -605,7 +605,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { | |||
public BlockchainIdentity[] getDataAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, | |||
@RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, | |||
@RequestParam(name = "count", required = false, defaultValue = "-1") int count) { | |||
return peerService.getQueryService().getDataAccounts(ledgerHash, fromIndex, count); | |||
return revertAccountHeader(peerService.getQueryService().getDataAccounts(ledgerHash, fromIndex, count)); | |||
} | |||
@RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/contracts") | |||
@@ -613,6 +613,20 @@ public class BlockBrowserController implements BlockchainExtendQueryService { | |||
public BlockchainIdentity[] getContractAccounts(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, | |||
@RequestParam(name = "fromIndex", required = false, defaultValue = "0") int fromIndex, | |||
@RequestParam(name = "count", required = false, defaultValue = "-1") int count) { | |||
return peerService.getQueryService().getContractAccounts(ledgerHash, fromIndex, count); | |||
return revertAccountHeader(peerService.getQueryService().getContractAccounts(ledgerHash, fromIndex, count)); | |||
} | |||
/** | |||
* reverse the AccountHeader[] content; the latest record show first; | |||
* @return | |||
*/ | |||
private AccountHeader[] revertAccountHeader(AccountHeader[] accountHeaders){ | |||
AccountHeader[] accounts = new AccountHeader[accountHeaders.length]; | |||
if(accountHeaders!=null && accountHeaders.length>0){ | |||
for (int i = 0; i < accountHeaders.length; i++) { | |||
accounts[accountHeaders.length-1-i] = accountHeaders[i]; | |||
} | |||
} | |||
return accounts; | |||
} | |||
} |
@@ -405,7 +405,7 @@ public class LedgerQueryService implements BlockchainQueryService { | |||
checkLedgerHash(ledgerHash); | |||
LedgerBlock block = ledger.getLatestBlock(); | |||
UserAccountQuery userAccountSet = ledger.getUserAccountSet(block); | |||
int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) userAccountSet.getTotal()); | |||
int pages[] = QueryUtil.calFromIndexAndCountDescend(fromIndex, count, (int) userAccountSet.getTotal()); | |||
return userAccountSet.getHeaders(pages[0], pages[1]); | |||
} | |||
@@ -414,7 +414,7 @@ public class LedgerQueryService implements BlockchainQueryService { | |||
checkLedgerHash(ledgerHash); | |||
LedgerBlock block = ledger.getLatestBlock(); | |||
DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); | |||
int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccountSet.getTotal()); | |||
int pages[] = QueryUtil.calFromIndexAndCountDescend(fromIndex, count, (int) dataAccountSet.getTotal()); | |||
return dataAccountSet.getHeaders(pages[0], pages[1]); | |||
} | |||
@@ -423,7 +423,7 @@ public class LedgerQueryService implements BlockchainQueryService { | |||
checkLedgerHash(ledgerHash); | |||
LedgerBlock block = ledger.getLatestBlock(); | |||
ContractAccountQuery contractAccountSet = ledger.getContractAccountSet(block); | |||
int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) contractAccountSet.getTotal()); | |||
int pages[] = QueryUtil.calFromIndexAndCountDescend(fromIndex, count, (int) contractAccountSet.getTotal()); | |||
return contractAccountSet.getHeaders(pages[0], pages[1]); | |||
} | |||
@@ -5,29 +5,11 @@ import java.util.Collection; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import com.jd.blockchain.ledger.*; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.BlockRollbackException; | |||
import com.jd.blockchain.ledger.BytesValue; | |||
import com.jd.blockchain.ledger.ContractDoesNotExistException; | |||
import com.jd.blockchain.ledger.DataAccountDoesNotExistException; | |||
import com.jd.blockchain.ledger.IllegalTransactionException; | |||
import com.jd.blockchain.ledger.LedgerBlock; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
import com.jd.blockchain.ledger.LedgerPermission; | |||
import com.jd.blockchain.ledger.LedgerSecurityException; | |||
import com.jd.blockchain.ledger.Operation; | |||
import com.jd.blockchain.ledger.OperationResult; | |||
import com.jd.blockchain.ledger.OperationResultData; | |||
import com.jd.blockchain.ledger.ParticipantDoesNotExistException; | |||
import com.jd.blockchain.ledger.TransactionContent; | |||
import com.jd.blockchain.ledger.TransactionRequest; | |||
import com.jd.blockchain.ledger.TransactionResponse; | |||
import com.jd.blockchain.ledger.TransactionRollbackException; | |||
import com.jd.blockchain.ledger.TransactionState; | |||
import com.jd.blockchain.ledger.UserDoesNotExistException; | |||
import com.jd.blockchain.ledger.core.TransactionRequestExtension.Credential; | |||
import com.jd.blockchain.service.TransactionBatchProcess; | |||
import com.jd.blockchain.service.TransactionBatchResult; | |||
@@ -63,7 +45,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { | |||
/** | |||
* @param newBlockEditor 新区块的数据编辑器; | |||
* @param ledgerQueryer 账本查询器,只包含新区块的前一个区块的数据集;即未提交新区块之前的经过共识的账本最新数据集; | |||
* @param newBlockEditor 账本查询器,只包含新区块的前一个区块的数据集;即未提交新区块之前的经过共识的账本最新数据集; | |||
* @param opHandles 操作处理对象注册表; | |||
*/ | |||
public TransactionBatchProcessor(LedgerSecurityManager securityManager, LedgerEditor newBlockEditor, | |||
@@ -153,6 +135,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { | |||
} catch (BlockRollbackException e) { | |||
// 发生区块级别的处理异常,向上重新抛出异常进行处理,整个区块可能被丢弃; | |||
resp = discard(request, e.getState()); | |||
LOGGER.error(String.format( | |||
"Ignore transaction caused by BlockRollbackException! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", | |||
newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), | |||
@@ -287,8 +270,12 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { | |||
newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), | |||
e.getMessage()), e); | |||
} catch (BlockRollbackException e) { | |||
// 回滚整个区块; | |||
// rollback all the block; | |||
// TODO: handle the BlockRollbackException in detail; | |||
result = TransactionState.IGNORED_BY_BLOCK_FULL_ROLLBACK; | |||
if (e instanceof DataVersionConflictException) { | |||
result = TransactionState.DATA_VERSION_CONFLICT; | |||
} | |||
txCtx.rollback(); | |||
LOGGER.error( | |||
String.format("Transaction was rolled back! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", | |||
@@ -498,7 +498,7 @@ public class LedgerQueryController implements BlockchainQueryService { | |||
LedgerQuery ledger = ledgerService.getLedger(ledgerHash); | |||
LedgerBlock block = ledger.getLatestBlock(); | |||
UserAccountQuery userAccountSet = ledger.getUserAccountSet(block); | |||
int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) userAccountSet.getTotal()); | |||
int pages[] = QueryUtil.calFromIndexAndCountDescend(fromIndex, count, (int) userAccountSet.getTotal()); | |||
return userAccountSet.getHeaders(pages[0], pages[1]); | |||
} | |||
@@ -518,7 +518,7 @@ public class LedgerQueryController implements BlockchainQueryService { | |||
LedgerQuery ledger = ledgerService.getLedger(ledgerHash); | |||
LedgerBlock block = ledger.getLatestBlock(); | |||
DataAccountQuery dataAccountSet = ledger.getDataAccountSet(block); | |||
int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) dataAccountSet.getTotal()); | |||
int pages[] = QueryUtil.calFromIndexAndCountDescend(fromIndex, count, (int) dataAccountSet.getTotal()); | |||
return dataAccountSet.getHeaders(pages[0], pages[1]); | |||
} | |||
@@ -530,7 +530,7 @@ public class LedgerQueryController implements BlockchainQueryService { | |||
LedgerQuery ledger = ledgerService.getLedger(ledgerHash); | |||
LedgerBlock block = ledger.getLatestBlock(); | |||
ContractAccountQuery contractAccountSet = ledger.getContractAccountSet(block); | |||
int pages[] = QueryUtil.calFromIndexAndCount(fromIndex, count, (int) contractAccountSet.getTotal()); | |||
int pages[] = QueryUtil.calFromIndexAndCountDescend(fromIndex, count, (int) contractAccountSet.getTotal()); | |||
return contractAccountSet.getHeaders(pages[0], pages[1]); | |||
} | |||
@@ -35,7 +35,7 @@ | |||
</modules> | |||
<properties> | |||
<bft-smart.version>0.2.0.RELEASE</bft-smart.version> | |||
<bft-smart.version>0.3.0-SNAPSHOT</bft-smart.version> | |||
<data-explorer.version>1.1.0.RELEASE</data-explorer.version> | |||
<manager-explorer.version>1.1.0.RELEASE</manager-explorer.version> | |||
<commons-io.version>2.4</commons-io.version> | |||
@@ -240,7 +240,7 @@ public abstract class RuntimeContext { | |||
private static void initBlacks() { | |||
try { | |||
InputStream inputStream = ContractURLClassLoader.class.getResourceAsStream(File.separator + BLACK_CONFIG); | |||
InputStream inputStream = ContractURLClassLoader.class.getResourceAsStream("/"+ BLACK_CONFIG); | |||
String text = FileUtils.readText(inputStream); | |||
String[] textArray = text.split("\n"); | |||
for (String setting : textArray) { | |||
@@ -47,4 +47,21 @@ public class QueryUtil { | |||
rtn[1] = count; | |||
return rtn; | |||
} | |||
/** | |||
* cal the data by descend; | |||
* @param fromIndex | |||
* @param count | |||
* @param maxNum | |||
* @return | |||
*/ | |||
public static int[] calFromIndexAndCountDescend(int fromIndex, int count, int maxNum){ | |||
int rtn[] = new int[2]; | |||
int results[] = calFromIndexAndCount(fromIndex,count,maxNum); | |||
//now use descend; first show the latest record; | |||
rtn[0] = maxNum - results[0] - results[1]; | |||
rtn[1] = results[1]; | |||
return rtn; | |||
} | |||
} |