Browse Source

Refactored the processing of bytes values of ContractEventSendOperation;

tags/1.0.0
huanghaiquan 5 years ago
parent
commit
683b9d3ac0
14 changed files with 247 additions and 508 deletions
  1. +0
    -17
      source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java
  2. +2
    -0
      source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/BinaryProtocol.java
  3. +11
    -19
      source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java
  4. +165
    -165
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java
  5. +0
    -195
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils2.java
  6. +3
    -3
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractType.java
  7. +0
    -13
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_BYTES.java
  8. +0
    -13
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_INT.java
  9. +0
    -13
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_LONG.java
  10. +0
    -13
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_SHORT.java
  11. +0
    -13
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_STRING.java
  12. +60
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java
  13. +2
    -6
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocation.java
  14. +4
    -38
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationHandler.java

+ 0
- 17
source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java View File

@@ -85,26 +85,9 @@ public interface DataCodes {

//contract related;
public static final int CONTRACT = 0xA00;
public static final int CONTRACT_BYTE = 0xA01;

public static final int CONTRACT_SHORT = 0xA02;

public static final int CONTRACT_INT = 0xA03;

public static final int CONTRACT_LONG = 0xA04;

public static final int CONTRACT_STRING = 0xA05;

public static final int CONTRACT_BYTES = 0xA06;

public static final int CONTRACT_BIG_INT = 0xA07;
//...0xA19
public static final int CONTRACT_BIZ_CONTENT = 0xA20;

public static final int CONTRACT_ARGS = 0xA21;

public static final int CONTRACT_RETURN = 0xA22;

public static final int HASH = 0xB00;

public static final int HASH_OBJECT = 0xB10;


+ 2
- 0
source/binary-proto/src/main/java/com/jd/blockchain/binaryproto/BinaryProtocol.java View File

@@ -57,5 +57,7 @@ public class BinaryProtocol {
}

}

+ 11
- 19
source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/AbstractContractCode.java View File

@@ -11,6 +11,8 @@ import com.jd.blockchain.contract.ContractException;
import com.jd.blockchain.contract.EventProcessingAware;
import com.jd.blockchain.contract.engine.ContractCode;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.BytesValueEncoding;
import com.jd.blockchain.ledger.BytesValueList;
import com.jd.blockchain.utils.Bytes;

/**
@@ -29,7 +31,7 @@ public abstract class AbstractContractCode implements ContractCode {
this.version = version;
this.contractDefinition = contractDefinition;
}
public ContractDefinition getContractDefinition() {
return contractDefinition;
}
@@ -48,6 +50,7 @@ public abstract class AbstractContractCode implements ContractCode {
public BytesValue processEvent(ContractEventContext eventContext) {
EventProcessingAware evtProcAwire = null;
Object retn = null;
Method handleMethod = null;
Exception error = null;
try {
// 执行预处理;
@@ -61,17 +64,19 @@ public abstract class AbstractContractCode implements ContractCode {
}

// 反序列化参数;
Method handleMethod = contractDefinition.getType().getHandleMethod(eventContext.getEvent());
handleMethod = contractDefinition.getType().getHandleMethod(eventContext.getEvent());

if (handleMethod == null) {
throw new ContractException(
String.format("Contract[%s:%s] has no handle method to handle event[%s]!", address.toString(),
contractDefinition.getType().getDeclaredClass().toString(), eventContext.getEvent()));
}

Object[] args = resolveArgs();
BytesValueList bytesValues = eventContext.getArgs();
Object[] args = BytesValueEncoding.decode(bytesValues, handleMethod.getParameterTypes());
retn = ReflectionUtils.invokeMethod(handleMethod, contractInstance, args);

} catch (Exception e) {
error = e;
}
@@ -91,23 +96,10 @@ public abstract class AbstractContractCode implements ContractCode {
eventContext.getEvent(), address.toString(), error.getMessage()), error);
}

BytesValue retnBytes = resolveResult(retn);
BytesValue retnBytes = BytesValueEncoding.encode(retn, handleMethod.getReturnType());
return retnBytes;
}

protected abstract Object getContractInstance();

private BytesValue resolveResult(Object retn) {
if (retn == null) {
return null;
}
// TODO: resolve result in bytes;
throw new IllegalStateException("Not implemented!");
}

private Object[] resolveArgs() {
// TODO Auto-generated method stub
throw new IllegalStateException("Not implemented!");
}

}

+ 165
- 165
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java View File

@@ -1,165 +1,165 @@
package com.jd.blockchain.contract;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.contract.param.WRAP_BYTES;
import com.jd.blockchain.contract.param.WRAP_INT;
import com.jd.blockchain.contract.param.WRAP_LONG;
import com.jd.blockchain.contract.param.WRAP_SHORT;
import com.jd.blockchain.contract.param.WRAP_STRING;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.BytesValueList;
import com.jd.blockchain.utils.io.BytesUtils;
public class ContractSerializeUtils {
final static int INT_LENGTH = 4;
static Map<Class<?>, Class<?>> MAP = new HashMap<>();
static {
MAP.put(byte[].class, WRAP_BYTES.class);
MAP.put(Short.class, WRAP_SHORT.class);
MAP.put(short.class, WRAP_SHORT.class);
MAP.put(Integer.class, WRAP_INT.class);
MAP.put(int.class, WRAP_INT.class);
MAP.put(Long.class, WRAP_LONG.class);
MAP.put(long.class, WRAP_LONG.class);
MAP.put(String.class, WRAP_STRING.class);
DataContractRegistry.register(WRAP_BYTES.class);
DataContractRegistry.register(WRAP_SHORT.class);
DataContractRegistry.register(WRAP_INT.class);
DataContractRegistry.register(WRAP_LONG.class);
DataContractRegistry.register(WRAP_STRING.class);
}
public static boolean support(Class<?> clazz) {
if (clazz.isAnnotationPresent(DataContract.class) || MAP.containsKey(clazz)) {
return true;
}
return false;
}
public static BytesValue serialize(Object data) {
if (data == null) {
return null;
}
Class<?> clazz = data.getClass();
Class<?> serialClass;
Object wrapData = data;
if (clazz.isAnnotationPresent(DataContract.class)) {
serialClass = clazz;
} else {
// 判断类型是否可以序列化
Class<?> wrapClass = MAP.get(clazz);
if (wrapClass == null) {
throw new IllegalArgumentException("There are Un-Support Type !!!");
}
serialClass = wrapClass;
if (wrapClass.equals(WRAP_BYTES.class)) {
wrapData = (WRAP_BYTES) () -> (byte[]) data;
} else if (wrapClass.equals(WRAP_INT.class)) {
wrapData = (WRAP_INT) () -> (int) data;
} else if (wrapClass.equals(WRAP_LONG.class)) {
wrapData = (WRAP_LONG) () -> (long) data;
} else if (wrapClass.equals(WRAP_SHORT.class)) {
wrapData = (WRAP_SHORT) () -> (short) data;
} else if (wrapClass.equals(WRAP_STRING.class)) {
wrapData = (WRAP_STRING) () -> (String) data;
}
}
// 按照对应接口进行序列化
// 生成该接口对应的对象
return BinaryProtocol.encode(wrapData, serialClass);
}
public static BytesValueList serializeArray(Object[] datas) {
if (datas == null || datas.length == 0) {
return null;
}
int contentBytesSize = 0;
byte[] header = new byte[(datas.length + 1) * 4];
System.arraycopy(BytesUtils.toBytes(datas.length), 0, header, 0, INT_LENGTH);
int offset = INT_LENGTH;
List<byte[]> serialBytesList = new ArrayList<>();
for (Object data : datas) {
// 按照对应接口进行序列化
byte[] currBytes = serialize(data);
// 长度写入
System.arraycopy(BytesUtils.toBytes(currBytes.length), 0, header, offset, INT_LENGTH);
serialBytesList.add(currBytes);
contentBytesSize += currBytes.length;
offset += INT_LENGTH;
}
// 填充content
byte[] content = new byte[contentBytesSize];
offset = 0;
for (byte[] bytes : serialBytesList) {
System.arraycopy(bytes, 0, content, offset, bytes.length);
offset += bytes.length;
}
// 将header和content组装
return BytesUtils.concat(header, content);
}
public static Object[] resolveArray(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
byte[] lengthBytes = new byte[INT_LENGTH];
System.arraycopy(bytes, 0, lengthBytes, 0, INT_LENGTH);
int length = BytesUtils.toInt(lengthBytes);
Object[] datas = new Object[length];
int headerOffset = INT_LENGTH;
int contentStart = (length + 1) * INT_LENGTH;
for (int i = 0; i < length; i++) {
byte[] currDataLengthBytes = new byte[INT_LENGTH];
System.arraycopy(bytes, headerOffset, currDataLengthBytes, 0, INT_LENGTH);
int currDataLength = BytesUtils.toInt(currDataLengthBytes);
// 读取
byte[] dataBytes = new byte[currDataLength];
System.arraycopy(bytes, contentStart, dataBytes, 0, currDataLength);
datas[i] = resolve(dataBytes);
contentStart += currDataLength;
headerOffset += INT_LENGTH;
}
return datas;
}
public static Object resolve(BytesValue bytes) {
// 反序列化该接口
Object currData = BinaryProtocol.decode(bytes);
// 代理对象类型不能使用class判断,只能使用instanceof
if (currData instanceof WRAP_STRING) {
return ((WRAP_STRING) currData).getValue();
} else if (currData instanceof WRAP_INT) {
return ((WRAP_INT) currData).getValue();
} else if (currData instanceof WRAP_LONG) {
return ((WRAP_LONG) currData).getValue();
} else if (currData instanceof WRAP_BYTES) {
return ((WRAP_BYTES) currData).getValue();
} else if (currData instanceof WRAP_SHORT) {
return ((WRAP_SHORT) currData).getValue();
} else {
return currData;
}
}
}
//package com.jd.blockchain.contract;
//
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
//import com.jd.blockchain.binaryproto.BinaryProtocol;
//import com.jd.blockchain.binaryproto.DataContract;
//import com.jd.blockchain.binaryproto.DataContractRegistry;
//import com.jd.blockchain.contract.param.WRAP_BYTES;
//import com.jd.blockchain.contract.param.WRAP_INT;
//import com.jd.blockchain.contract.param.WRAP_LONG;
//import com.jd.blockchain.contract.param.WRAP_SHORT;
//import com.jd.blockchain.contract.param.WRAP_STRING;
//import com.jd.blockchain.ledger.BytesValue;
//import com.jd.blockchain.ledger.BytesValueList;
//import com.jd.blockchain.utils.io.BytesUtils;
//
//public class ContractSerializeUtils {
//
// final static int INT_LENGTH = 4;
//
// static Map<Class<?>, Class<?>> MAP = new HashMap<>();
//
// static {
// MAP.put(byte[].class, WRAP_BYTES.class);
// MAP.put(Short.class, WRAP_SHORT.class);
// MAP.put(short.class, WRAP_SHORT.class);
// MAP.put(Integer.class, WRAP_INT.class);
// MAP.put(int.class, WRAP_INT.class);
// MAP.put(Long.class, WRAP_LONG.class);
// MAP.put(long.class, WRAP_LONG.class);
// MAP.put(String.class, WRAP_STRING.class);
//
// DataContractRegistry.register(WRAP_BYTES.class);
// DataContractRegistry.register(WRAP_SHORT.class);
// DataContractRegistry.register(WRAP_INT.class);
// DataContractRegistry.register(WRAP_LONG.class);
// DataContractRegistry.register(WRAP_STRING.class);
// }
//
// public static boolean support(Class<?> clazz) {
// if (clazz.isAnnotationPresent(DataContract.class) || MAP.containsKey(clazz)) {
// return true;
// }
// return false;
// }
//
// public static BytesValue serialize(Object data) {
//
// if (data == null) {
// return null;
// }
//
// Class<?> clazz = data.getClass();
// Class<?> serialClass;
// Object wrapData = data;
// if (clazz.isAnnotationPresent(DataContract.class)) {
// serialClass = clazz;
// } else {
// // 判断类型是否可以序列化
// Class<?> wrapClass = MAP.get(clazz);
// if (wrapClass == null) {
// throw new IllegalArgumentException("There are Un-Support Type !!!");
// }
// serialClass = wrapClass;
//
// if (wrapClass.equals(WRAP_BYTES.class)) {
// wrapData = (WRAP_BYTES) () -> (byte[]) data;
// } else if (wrapClass.equals(WRAP_INT.class)) {
// wrapData = (WRAP_INT) () -> (int) data;
// } else if (wrapClass.equals(WRAP_LONG.class)) {
// wrapData = (WRAP_LONG) () -> (long) data;
// } else if (wrapClass.equals(WRAP_SHORT.class)) {
// wrapData = (WRAP_SHORT) () -> (short) data;
// } else if (wrapClass.equals(WRAP_STRING.class)) {
// wrapData = (WRAP_STRING) () -> (String) data;
// }
// }
// // 按照对应接口进行序列化
// // 生成该接口对应的对象
// return BinaryProtocol.encode(wrapData, serialClass);
// }
//
// public static BytesValueList serializeArray(Object[] datas) {
// if (datas == null || datas.length == 0) {
// return null;
// }
// int contentBytesSize = 0;
// byte[] header = new byte[(datas.length + 1) * 4];
// System.arraycopy(BytesUtils.toBytes(datas.length), 0, header, 0, INT_LENGTH);
// int offset = INT_LENGTH;
//
// List<byte[]> serialBytesList = new ArrayList<>();
// for (Object data : datas) {
// // 按照对应接口进行序列化
// byte[] currBytes = serialize(data);
// // 长度写入
// System.arraycopy(BytesUtils.toBytes(currBytes.length), 0, header, offset, INT_LENGTH);
// serialBytesList.add(currBytes);
// contentBytesSize += currBytes.length;
// offset += INT_LENGTH;
// }
//
// // 填充content
// byte[] content = new byte[contentBytesSize];
// offset = 0;
// for (byte[] bytes : serialBytesList) {
// System.arraycopy(bytes, 0, content, offset, bytes.length);
// offset += bytes.length;
// }
// // 将header和content组装
// return BytesUtils.concat(header, content);
// }
//
// public static Object[] resolveArray(byte[] bytes) {
// if (bytes == null || bytes.length == 0) {
// return null;
// }
// byte[] lengthBytes = new byte[INT_LENGTH];
// System.arraycopy(bytes, 0, lengthBytes, 0, INT_LENGTH);
// int length = BytesUtils.toInt(lengthBytes);
// Object[] datas = new Object[length];
//
// int headerOffset = INT_LENGTH;
// int contentStart = (length + 1) * INT_LENGTH;
//
// for (int i = 0; i < length; i++) {
// byte[] currDataLengthBytes = new byte[INT_LENGTH];
// System.arraycopy(bytes, headerOffset, currDataLengthBytes, 0, INT_LENGTH);
// int currDataLength = BytesUtils.toInt(currDataLengthBytes);
// // 读取
// byte[] dataBytes = new byte[currDataLength];
// System.arraycopy(bytes, contentStart, dataBytes, 0, currDataLength);
//
// datas[i] = resolve(dataBytes);
//
// contentStart += currDataLength;
// headerOffset += INT_LENGTH;
// }
//
// return datas;
// }
//
// public static Object resolve(BytesValue bytes) {
// // 反序列化该接口
// Object currData = BinaryProtocol.decode(bytes);
//
// // 代理对象类型不能使用class判断,只能使用instanceof
// if (currData instanceof WRAP_STRING) {
// return ((WRAP_STRING) currData).getValue();
// } else if (currData instanceof WRAP_INT) {
// return ((WRAP_INT) currData).getValue();
// } else if (currData instanceof WRAP_LONG) {
// return ((WRAP_LONG) currData).getValue();
// } else if (currData instanceof WRAP_BYTES) {
// return ((WRAP_BYTES) currData).getValue();
// } else if (currData instanceof WRAP_SHORT) {
// return ((WRAP_SHORT) currData).getValue();
// } else {
// return currData;
// }
// }
//}

+ 0
- 195
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils2.java View File

@@ -1,195 +0,0 @@
//package com.jd.blockchain.contract;
//
//import com.jd.blockchain.binaryproto.BinaryProtocol;
//import com.jd.blockchain.binaryproto.DataContract;
//import com.jd.blockchain.consts.DataCodes;
//import com.jd.blockchain.ledger.*;
//import com.jd.blockchain.utils.Bytes;
//import com.jd.blockchain.utils.IllegalDataException;
//import org.springframework.util.ReflectionUtils;
//
//import java.nio.ByteBuffer;
//import java.util.Arrays;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
///**
// * @author zhaogw
// * date 2019/5/16 18:05
// */
//public class ContractSerializeUtils {
// public static Map<Integer, Class<?>> DATA_CONTRACT_MAP = new HashMap<>();
// public static final Integer[] PRIMITIVE_DATA_CODES = {DataCodes.CONTRACT_INT8, DataCodes.CONTRACT_INT16, DataCodes.CONTRACT_INT32,
// DataCodes.CONTRACT_INT64, DataCodes.CONTRACT_BIG_INT,DataCodes.CONTRACT_TEXT, DataCodes.CONTRACT_BINARY };
//
// /**
// * serialize the Object[] by List<DataContract> list;
// * @param objArr
// * @param dataContractList
// * @return
// */
// public static byte[] serializeMethodParam(Object[] objArr,List<DataContract> dataContractList) {
// byte[][] result = new byte[objArr.length][];
// //将method中形参转换为实体对象,每个形参都必须为@DataContract类型;每个形参使用系统的BinaryProtocol来进行序列化,如果有5个参数,则使用5次序列化;
// int sum = 0;
//
// for(int i=0;i<objArr.length;i++){
// DataContract dataContract = dataContractList.get(i);
// objArr[i] = regenObj(dataContract,objArr[i]);
// //get data interface;
// result[i] = BinaryProtocol.encode(objArr[i],getDataIntf().get(dataContract.code()));
// sum += result[i].length;
// }
// /**
// * return byte[] format:
// return is byte[], but now is byte[][], so we should reduct dimension by adding the header info to the rtnBytes[];
// rtnBytes[]=classTypes.length/first length/second length/third length/result[0]/result[1]/result[2];
// rtnBytes[0]: 4 bytes(classTypes.length);
// rtnBytes[1]: 4 bytes(1 param's length);
// rtnBytes[2]: 4 bytes(2 param's length);
// rtnBytes[3]: 4 bytes(3 param's length);
// rtnBytes[...]: result[0][] bytes(1 param's length);
// rtnBytes[...]: result[1][] bytes(2 param's length);
// rtnBytes[...]: result[2][] bytes(3 param's length);
// */
// int bodyFirstPosition = 4 + 4 * (objArr.length);
// ByteBuffer byteBuffer = ByteBuffer.allocate(bodyFirstPosition + sum);
// byteBuffer.putInt(objArr.length);
// for(int j=0; j<result.length; j++) {
// byte[] curResult = result[j];
// byteBuffer.putInt(curResult.length);
// }
// for(int k=0; k<result.length; k++){
// byteBuffer.put(result[k]);
// }
// return byteBuffer.array();
// }
//
// /**
// * deserialize the params bytes[];
// * params format: nums|first length| second length| third length| ... |bytes[0]| byte[1] | bytes[2]| ...
// * @param params
// * @param dataContractList
// * @return
// */
// public static Object[] deserializeMethodParam(byte[] params, List<DataContract> dataContractList) {
// Object result[] = new Object[dataContractList.size()];
// ByteBuffer byteBuffer = ByteBuffer.allocate(params.length);
// byteBuffer.put(params);
// int paramNums = byteBuffer.getInt(0);
//
// if(paramNums != dataContractList.size()){
// throw new IllegalArgumentException("deserialize Method param. params'length in byte[] != method's param length");
// }
//
// int offsetPosition = (1 + dataContractList.size())*4; //start position of real data;
// for(int i=0; i<dataContractList.size(); i++){
// DataContract dataContract = dataContractList.get(i);
// int curParamLength = byteBuffer.getInt((i+1)*4);
// ByteBuffer byteBuffer1 = ByteBuffer.allocate(curParamLength);
// byteBuffer1.put(params,offsetPosition,curParamLength);
// offsetPosition += curParamLength;
// //if dataContract=primitive type(byte/short/int/long/String),only use its getValues();
// Object object = BinaryProtocol.decodeAs(byteBuffer1.array(),
// getDataIntf().get(dataContract.code()));
// if(isPrimitiveType(dataContract.code())){
// Class<?> classObj = getDataIntf().get(dataContract.code());
// try {
// result[i] = ReflectionUtils.invokeMethod(classObj.getMethod("getValue"),object);
// } catch (NoSuchMethodException e) {
// throw new IllegalStateException("no getValue(). detail="+e.getMessage());
// }
// }else {
// result[i] = object;
// }
// byteBuffer1.clear();
// }
//
// return result;
// }
//
//
// /**
// * the param types that we can support;
// * @param <T>
// * @return
// */
// public static <T> Map<Integer, Class<?> > getDataIntf(){
// DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_INT8, CONTRACT_INT8.class);
// DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_INT16, CONTRACT_INT16.class);
// DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_INT32, CONTRACT_INT32.class);
// DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_INT64, CONTRACT_INT64.class);
// DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_TEXT, CONTRACT_TEXT.class);
// DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_BINARY, CONTRACT_BINARY.class);
// DATA_CONTRACT_MAP.put(DataCodes.CONTRACT_BIZ_CONTENT, ContractBizContent.class);
// return DATA_CONTRACT_MAP;
// }
//
// public static boolean isPrimitiveType(int dataContractCode){
// return Arrays.asList(PRIMITIVE_DATA_CODES).contains(dataContractCode);
// }
//
// private static Object regenObj(DataContract dataContract, Object object){
// if(getDataIntf().get(dataContract.code()).equals(CONTRACT_INT8.class)){
//
// return (CONTRACT_INT8) () -> Byte.parseByte(object.toString());
// }else if(getDataIntf().get(dataContract.code()).equals(CONTRACT_INT16.class)){
// return (CONTRACT_INT16) () -> Short.parseShort(object.toString());
// }else if(getDataIntf().get(dataContract.code()).equals(CONTRACT_INT32.class)){
// return (CONTRACT_INT32) () -> Integer.parseInt(object.toString());
// }else if(getDataIntf().get(dataContract.code()).equals(CONTRACT_INT64.class)){
// return (CONTRACT_INT64) () -> Long.parseLong(object.toString());
// }else if(getDataIntf().get(dataContract.code()).equals(CONTRACT_TEXT.class)){
// return (CONTRACT_TEXT) () -> object.toString();
// }else if(getDataIntf().get(dataContract.code()).equals(CONTRACT_BINARY.class)){
// return (CONTRACT_BINARY) () -> (Bytes) object;
// }else if(getDataIntf().get(dataContract.code()).equals(ContractBizContent.class)){
// ContractBizContent contractBizContent = (ContractBizContent)object;
// return contractBizContent;
// }else {
// throw new IllegalDataException("cann't get new Object by dataContract and object.");
// }
// }
//
// /**
// * get contractType(contain @DataContract) by primitive class type;
// * some class type can be supported default (byte/char/int/long/String/Bytes, and so on).
// * in other words, need not contain the @DataContract in its class for contract param's serialization or deserialization.
// * @param classType
// * @return
// */
// private static Class<?> getContractTypeByPrimitiveType(Class<?> classType) {
// if(classType.equals(byte.class) || classType.equals(Byte.class)){
// return CONTRACT_INT8.class;
// }else if(classType.equals(char.class) || classType.equals(Character.class)){
// return CONTRACT_INT16.class;
// }else if(classType.equals(int.class) || classType.equals(Integer.class)){
// return CONTRACT_INT32.class;
// }else if(classType.equals(long.class) || classType.equals(Long.class)){
// return CONTRACT_INT64.class;
// }else if(classType.equals(String.class)){
// return CONTRACT_TEXT.class;
// }else if(classType.equals(Bytes.class)){
// return CONTRACT_BINARY.class;
// }else {
// throw new IllegalDataException(String.format("no support the classType=%s, please check @DataContract.",classType.toString()));
// }
// }
//
// public static DataContract parseDataContract(Class<?> classType){
// DataContract dataContract = classType.getAnnotation(DataContract.class);
// //if the param's class Type don't contain @DataContract, then check parameterAnnotations of this method.
// if(dataContract == null){
// boolean canPass = false;
// //if parameterAnnotations don't contain @DataContract, is it primitive type?
// Class<?> contractType = getContractTypeByPrimitiveType(classType);
// dataContract = contractType.getAnnotation(DataContract.class);
// }
// if(!getDataIntf().containsKey(dataContract.code())){
// throw new IllegalArgumentException(String.format(
// "for now, this @dataContract(code=%s) is forbidden in the param list.",dataContract.code()));
// }
// return dataContract;
// }
//}

+ 3
- 3
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractType.java View File

@@ -5,7 +5,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.jd.blockchain.contract.ContractSerializeUtils;
import com.jd.blockchain.ledger.BytesValueEncoding;
import com.jd.blockchain.utils.IllegalDataException;

public class ContractType {
@@ -113,7 +113,7 @@ public class ContractType {
// check param's type is fit for need.
Class<?>[] paramTypes = method.getParameterTypes();
for (Class<?> currParamType : paramTypes) {
if (!ContractSerializeUtils.support(currParamType)) {
if (!BytesValueEncoding.supportType(currParamType)) {
throw new IllegalStateException(
String.format("Param Type = %s can not support !!!", currParamType.getName()));
}
@@ -121,7 +121,7 @@ public class ContractType {

// 判断返回值是否可序列化
Class<?> returnType = method.getReturnType();
if (!ContractSerializeUtils.support(returnType)) {
if (!BytesValueEncoding.supportType(returnType)) {
throw new IllegalStateException(
String.format("Return Type = %s can not support !!!", returnType.getName()));
}


+ 0
- 13
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_BYTES.java View File

@@ -1,13 +0,0 @@
package com.jd.blockchain.contract.param;

import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;

@DataContract(code = DataCodes.CONTRACT_BYTES)
public interface WRAP_BYTES {

@DataField(order = 1, primitiveType = PrimitiveType.BYTES)
byte[] getValue();
}

+ 0
- 13
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_INT.java View File

@@ -1,13 +0,0 @@
package com.jd.blockchain.contract.param;

import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;

@DataContract(code = DataCodes.CONTRACT_INT)
public interface WRAP_INT {

@DataField(order = 1, primitiveType = PrimitiveType.INT32)
int getValue();
}

+ 0
- 13
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_LONG.java View File

@@ -1,13 +0,0 @@
package com.jd.blockchain.contract.param;

import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;

@DataContract(code = DataCodes.CONTRACT_LONG)
public interface WRAP_LONG {

@DataField(order = 1, primitiveType = PrimitiveType.INT64)
long getValue();
}

+ 0
- 13
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_SHORT.java View File

@@ -1,13 +0,0 @@
package com.jd.blockchain.contract.param;

import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;

@DataContract(code = DataCodes.CONTRACT_SHORT)
public interface WRAP_SHORT {

@DataField(order = 1, primitiveType = PrimitiveType.INT16)
short getValue();
}

+ 0
- 13
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/param/WRAP_STRING.java View File

@@ -1,13 +0,0 @@
package com.jd.blockchain.contract.param;

import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.DataField;
import com.jd.blockchain.binaryproto.PrimitiveType;
import com.jd.blockchain.consts.DataCodes;

@DataContract(code = DataCodes.CONTRACT_STRING)
public interface WRAP_STRING {

@DataField(order = 1, primitiveType = PrimitiveType.TEXT)
String getValue();
}

+ 60
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/BytesValueEncoding.java View File

@@ -0,0 +1,60 @@
package com.jd.blockchain.ledger;

public class BytesValueEncoding {
public static BytesValue encode(Object value, Class<?> type) {
}
public static BytesValueList encode(Object[] values, Class<?>[] types) {
}
public static Object decode(BytesValue value, Class<?> type) {
}
public static Object[] decode(BytesValueList values, Class<?>[] types) {
}
public static Object getDefaultValue(Class<?> type) {
if (type == void.class || type == Void.class) {
return null;
}

if (!type.isPrimitive()) {
// 非基本类型
return null;
} else {
// 基本类型需要处理返回值,目前采用枚举遍历方式
// 八种基本类型:int, double, float, long, short, boolean, byte, char, void
if (type.equals(int.class)) {
return 0;
} else if (type.equals(double.class)) {
return 0.0D;
} else if (type.equals(float.class)) {
return 0F;
} else if (type.equals(long.class)) {
return 0L;
} else if (type.equals(short.class)) {
return (short) 0;
} else if (type.equals(boolean.class)) {
return Boolean.FALSE;
} else if (type.equals(byte.class)) {
return (byte) 0;
} else if (type.equals(char.class)) {
return (char) 0;
}
return null;
}
}

public static boolean supportType(Class<?> currParamType) {
// TODO Auto-generated method stub
return false;
}
}

+ 2
- 6
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocation.java View File

@@ -6,6 +6,7 @@ import java.util.concurrent.Future;

import com.jd.blockchain.contract.ContractType;
import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.ledger.BytesValueEncoding;

/**
* ContractInvocation 包装了客户端发起的一次合约方法调用的相关信息,用于在客户端交易处理上下文进行共享处理状态;
@@ -53,14 +54,9 @@ class ContractInvocation implements OperationReturnValueHandler {
@Override
public Object setReturnValue(BytesValue bytesValue) {
// Resolve BytesValue to an value object with the return type;
Object returnValue = resolveValue(bytesValue, method.getReturnType());
Object returnValue = BytesValueEncoding.decode(bytesValue, method.getReturnType());
returnValueFuture.complete(returnValue);
return returnValue;
}

private Object resolveValue(BytesValue bytesValue, Class<?> returnType) {
// TODO: Resolve BytesValue to an value object with the return type;
throw new IllegalStateException("Not implemented!");
}

}

+ 4
- 38
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationHandler.java View File

@@ -5,8 +5,8 @@ import java.lang.reflect.Method;
import java.util.Arrays;

import com.jd.blockchain.contract.ContractException;
import com.jd.blockchain.contract.ContractSerializeUtils;
import com.jd.blockchain.contract.ContractType;
import com.jd.blockchain.ledger.BytesValueEncoding;
import com.jd.blockchain.ledger.BytesValueList;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.IllegalDataException;
@@ -52,7 +52,8 @@ public class ContractInvocationHandler implements InvocationHandler {
method.toString()));
}
// 序列化调用参数;
BytesValueList argBytes = serializeArgs(args);
Class<?>[] argTypes = method.getParameterTypes();
BytesValueList argBytes = BytesValueEncoding.encode(args, argTypes);

// 定义合约调用操作;
ContractEventSendOpTemplate opTemplate = (ContractEventSendOpTemplate) sendOpBuilder.send(contractAddress,
@@ -68,42 +69,7 @@ public class ContractInvocationHandler implements InvocationHandler {
ContractInvocationStub.set(invocation);

// 返回类型的默认值
return getDefaultValue(method.getReturnType());
return BytesValueEncoding.getDefaultValue(method.getReturnType());
}

private BytesValueList serializeArgs(Object[] args) {
return ContractSerializeUtils.serializeArray(args);
}

private Object getDefaultValue(Class<?> returnType) {
if (returnType == void.class || returnType == Void.class) {
return null;
}

if (!returnType.isPrimitive()) {
// 非基本类型
return null;
} else {
// 基本类型需要处理返回值,目前采用枚举遍历方式
// 八种基本类型:int, double, float, long, short, boolean, byte, char, void
if (returnType.equals(int.class)) {
return 0;
} else if (returnType.equals(double.class)) {
return 0.0D;
} else if (returnType.equals(float.class)) {
return 0F;
} else if (returnType.equals(long.class)) {
return 0L;
} else if (returnType.equals(short.class)) {
return (short) 0;
} else if (returnType.equals(boolean.class)) {
return Boolean.FALSE;
} else if (returnType.equals(byte.class)) {
return (byte) 0;
} else if (returnType.equals(char.class)) {
return (char) 0;
}
return null;
}
}
}

Loading…
Cancel
Save