From 64cea29f146147e3c7c7c2a93019145bfe384b0e Mon Sep 17 00:00:00 2001 From: zhangshuang Date: Wed, 27 May 2020 10:54:37 +0800 Subject: [PATCH] fix contract execute bug --- .../contract/jvm/AbstractContractCode.java | 12 +++++++--- .../core/TransactionBatchProcessor.java | 14 ++++-------- .../ledger/ContractExecuteException.java | 22 +++++++++++++++++++ .../blockchain/ledger/TransactionState.java | 5 +++++ 4 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractExecuteException.java diff --git a/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java b/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java index 2aee31f8..f5b866c8 100644 --- a/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java +++ b/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java @@ -2,6 +2,7 @@ package com.jd.blockchain.contract.jvm; import java.lang.reflect.Method; +import com.jd.blockchain.ledger.ContractExecuteException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.ReflectionUtils; @@ -74,9 +75,14 @@ public abstract class AbstractContractCode implements ContractCode { BytesValueList bytesValues = eventContext.getArgs(); Object[] args = BytesValueEncoding.decode(bytesValues, handleMethod.getParameterTypes()); - - retn = ReflectionUtils.invokeMethod(handleMethod, contractInstance, args); - + + try { + retn = ReflectionUtils.invokeMethod(handleMethod, contractInstance, args); + } catch (Throwable e) { + throw new ContractExecuteException(String.format("Contract[%s:%s] has no handle method to handle event[%s]!", address.toString(), + contractDefinition.getType().getName(), eventContext.getEvent())); + } + } catch (Exception e) { error = e; } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionBatchProcessor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionBatchProcessor.java index 72408446..ce28ee95 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionBatchProcessor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/TransactionBatchProcessor.java @@ -157,7 +157,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), e.getMessage()), e); throw e; - } catch (Exception e) { + } catch (Throwable e) { // 抛弃发生处理异常的交易请求; resp = discard(request, TransactionState.SYSTEM_ERROR); LOGGER.error(String.format( @@ -165,14 +165,6 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), e.getMessage()), e); - } catch (Error e) { - // 抛弃发生系统错误的交易请求; - resp = discard(request, TransactionState.SYSTEM_ERROR); - LOGGER.error(String.format( - "Ignore transaction caused by the transaction op error! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", - newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), - e.getMessage()), e); - } finally { // 清空交易的用户安全策略; @@ -315,6 +307,8 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { result = TransactionState.USER_DOES_NOT_EXIST; } else if (e instanceof ContractDoesNotExistException) { result = TransactionState.CONTRACT_DOES_NOT_EXIST; + } else if (e instanceof ContractExecuteException) { + result = TransactionState.CONTRACT_EXECUTE_ERROR; } else if (e instanceof ParticipantDoesNotExistException) { result = TransactionState.PARTICIPANT_DOES_NOT_EXIST; } else if (e instanceof DataVersionConflictException) { @@ -333,7 +327,7 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { "Due to ledger security exception, the data changes resulting from transaction execution will be rolled back and the results of the transaction will be committed! --[BlockHeight=%s][RequestHash=%s][TxHash=%s] --%s", newBlockEditor.getBlockHeight(), request.getHash(), request.getTransactionContent().getHash(), e.getMessage()), e); - } catch (Exception e) { + } catch (Throwable e) { result = TransactionState.SYSTEM_ERROR; txCtx.discardAndCommit(TransactionState.SYSTEM_ERROR, operationResults); LOGGER.error(String.format( diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractExecuteException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractExecuteException.java new file mode 100644 index 00000000..bf294e64 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractExecuteException.java @@ -0,0 +1,22 @@ +package com.jd.blockchain.ledger; + +import com.jd.blockchain.crypto.HashDigest; + +/** + * @Author: zhangshuang + * @Date: 2020/5/27 10:34 AM + * Version 1.0 + */ +public class ContractExecuteException extends LedgerException { + + private static final long serialVersionUID = 8685914012112243776L; + + public ContractExecuteException(String message) { + super(message); + } + + public ContractExecuteException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionState.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionState.java index 57ddde05..04a8d89e 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionState.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionState.java @@ -49,6 +49,11 @@ public enum TransactionState { */ PARTICIPANT_DOES_NOT_EXIST((byte) 0x06), + /** + * 合约执行错误; + */ + CONTRACT_EXECUTE_ERROR((byte) 0x07), + /** * 被安全策略拒绝; */