From 7a073f64f150a1f4c712de50ea2a8393ff82f3d0 Mon Sep 17 00:00:00 2001 From: zhaoguangwei Date: Mon, 27 May 2019 15:05:55 +0800 Subject: [PATCH] According to Haiquan's suggestion to modify the codes for improving the performance. must admit: these proposals are very valuable. --- .../contract/ContractSerializeUtils.java | 1 - .../transaction/ContractInvocationProxy.java | 10 +++--- .../ContractInvocationProxyBuilder.java | 35 ++++++++++--------- .../blockchain/transaction/ContractType.java | 16 ++++----- .../sdk/test/SDK_Contract_Test.java | 2 +- .../com/jd/blockchain/utils/BaseConstant.java | 2 +- 6 files changed, 32 insertions(+), 34 deletions(-) diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java index 0e650415..474a1838 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java @@ -42,7 +42,6 @@ public class ContractSerializeUtils { } Class[] classTypes = method.getParameterTypes(); - Annotation [][] annotations = method.getParameterAnnotations(); byte[][] result = new byte[classTypes.length][]; //将method中形参转换为实体对象,每个形参都必须为@DataContract类型;每个形参使用系统的BinaryProtocol来进行序列化,如果有5个参数,则使用5次序列化; int sum = 0; diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java index 542e31f5..a5a3fd09 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java @@ -2,6 +2,8 @@ package com.jd.blockchain.transaction; import com.jd.blockchain.contract.ContractSerializeUtils; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.IllegalDataException; + import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @@ -18,17 +20,15 @@ public class ContractInvocationProxy implements InvocationHandler { public ContractInvocationProxy(Bytes contractAddress, ContractType contractType, ContractEventSendOperationBuilder sendOpBuilder) { this.contractAddress = contractAddress; + if(contractType == null){ + throw new IllegalDataException("contractType == null, no invoke really."); + } this.contractType = contractType; this.sendOpBuilder = sendOpBuilder; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - - if(contractType == null){ - return "contractType == null, no invoke really."; - } - String event = contractType.getEvent(method); if (event == null) { // 适配 Object 对象的方法; diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxyBuilder.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxyBuilder.java index 90032a9f..4bf825b7 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxyBuilder.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxyBuilder.java @@ -4,16 +4,18 @@ import com.jd.blockchain.contract.Contract; import com.jd.blockchain.contract.ContractEvent; import com.jd.blockchain.utils.BaseConstant; import com.jd.blockchain.utils.Bytes; +import com.jd.blockchain.utils.IllegalDataException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; public class ContractInvocationProxyBuilder { - private Map, ContractType> contractTypes = new HashMap, ContractType>(); + private Map, ContractType> contractTypes = new ConcurrentHashMap<>(); public T create(String address, Class contractIntf, ContractEventSendOperationBuilder contractEventBuilder) { return create(Bytes.fromBase58(address), contractIntf, contractEventBuilder); @@ -39,12 +41,12 @@ public class ContractInvocationProxyBuilder { // 判断是否是标注了合约的接口类型; if (!isContractType(contractIntf)){ - return null; + throw new IllegalDataException("is not Contract Type, becaust there is not @Contract."); } // 解析合约事件处理方法,检查是否有重名; if(!isUniqueEvent(contractIntf)){ - return null; + throw new IllegalDataException("there is repeat definition of contractEvent to @ContractEvent."); } // TODO 检查是否不支持的参数类型; @@ -63,22 +65,21 @@ public class ContractInvocationProxyBuilder { Map methodAnnoMap = new HashMap(); Map annoMethodMap = new HashMap(); for (int i = 0; i < classMethods.length; i++) { - Annotation[] a = classMethods[i].getDeclaredAnnotations(); - methodAnnoMap.put(classMethods[i], a); + Annotation[] annotations = classMethods[i].getDeclaredAnnotations(); + methodAnnoMap.put(classMethods[i], annotations); // if current method contains @ContractEvent,then put it in this map; - for (Annotation annotation_ : a) { - if (classMethods[i].isAnnotationPresent(ContractEvent.class)) { - Object obj = classMethods[i].getAnnotation(ContractEvent.class); - String annoAllName = obj.toString(); - // format:@com.jd.blockchain.contract.model.ContractEvent(name=transfer-asset) - String eventName_ = obj.toString().substring(BaseConstant.CONTRACT_EVENT_PREFIX.length(), - annoAllName.length() - 1); - //if annoMethodMap has contained the eventName, too many same eventNames exists probably, say NO! - if(annoMethodMap.containsKey(eventName_)){ - isUnique = false; - } - annoMethodMap.put(eventName_, classMethods[i]); + Method curMethod = classMethods[i]; + ContractEvent contractEvent = curMethod.getAnnotation(ContractEvent.class); + if (contractEvent != null) { + Object obj = classMethods[i].getAnnotation(ContractEvent.class); + String annoAllName = obj.toString(); + // format:@com.jd.blockchain.contract.model.ContractEvent(name=transfer-asset) + String eventName_ = contractEvent.name(); + //if annoMethodMap has contained the eventName, too many same eventNames exists probably, say NO! + if(annoMethodMap.containsKey(eventName_)){ + isUnique = false; } + annoMethodMap.put(eventName_, classMethods[i]); } } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java index 1bb3e7c8..97424e48 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java @@ -2,16 +2,17 @@ package com.jd.blockchain.transaction; import com.jd.blockchain.contract.ContractEvent; import com.jd.blockchain.contract.ContractException; -import com.jd.blockchain.utils.BaseConstant; import java.lang.reflect.Method; -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; public class ContractType { private String name; - private SortedMap events = Collections.synchronizedSortedMap(new TreeMap<>()); + private Map events = new HashMap<>(); private Map handleMethods = new HashMap<>();; @@ -57,12 +58,9 @@ public class ContractType { Method[] classMethods = contractIntf.getDeclaredMethods(); for (Method method : classMethods) { // if current method contains @ContractEvent,then put it in this map; - if (method.isAnnotationPresent(ContractEvent.class)) { - Object obj = method.getAnnotation(ContractEvent.class); - String annoAllName = obj.toString(); - // format:@com.jd.blockchain.contract.model.ContractEvent(name=transfer-asset) - String eventName_ = obj.toString().substring(BaseConstant.CONTRACT_EVENT_PREFIX.length(), - annoAllName.length() - 1); + ContractEvent contractEvent = method.getAnnotation(ContractEvent.class); + if (contractEvent != null) { + String eventName_ = contractEvent.name(); //if annoMethodMap has contained the eventName, too many same eventNames exists probably, say NO! if(contractType.events.containsKey(eventName_)){ throw new ContractException("too many same eventNames exists in the contract, check it."); diff --git a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java index cc160bf3..b2aa577d 100644 --- a/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java +++ b/source/sdk/sdk-samples/src/test/java/test/com/jd/blockchain/sdk/test/SDK_Contract_Test.java @@ -68,7 +68,7 @@ public class SDK_Contract_Test { public void demoContract1() { // 发起交易; TransactionTemplate txTemp = bcsrv.newTransaction(ledgerHash); - String contractAddress = "LdeNmSdtUqVfURfcVxmJda252HC4FYHYfGTQv"; + String contractAddress = "LdeNw7PsVrXTrffQMfYLTvqscDyQ8QCUPruTS"; AssetContract2 assetContract = txTemp.contract(contractAddress, AssetContract2.class); TransactionContentBody transactionContentBody = new TransactionContentBody() { @Override diff --git a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/BaseConstant.java b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/BaseConstant.java index 6e3aeb8c..4548dbad 100644 --- a/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/BaseConstant.java +++ b/source/utils/utils-common/src/main/java/com/jd/blockchain/utils/BaseConstant.java @@ -22,7 +22,7 @@ public class BaseConstant { public static final String SYS_CONTRACT_PROPS_NAME = "sys-contract.properties"; public static final String CONTRACT_MAIN_CLASS_KEY = "contract"; - public static final String CONTRACT_EVENT_PREFIX="@com.jd.blockchain.contract.ContractEvent(name="; +// public static final String CONTRACT_EVENT_PREFIX="@com.jd.blockchain.contract.ContractEvent(name="; // 编译时引用包黑名单 public static final String PACKAGE_BLACKLIST = "BLACKLIST";