Browse Source

Modify the way of Contract's return Result !

tags/1.0.0
shaozhuguang 5 years ago
parent
commit
713f847165
21 changed files with 313 additions and 85 deletions
  1. +2
    -0
      source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContract.java
  2. +5
    -0
      source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java
  3. +10
    -2
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractSerializeUtils.java
  4. +39
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventResult.java
  5. +0
    -1
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractEventSendOperation.java
  6. +0
    -2
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/OperationResult.java
  7. +0
    -10
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/OperationResultData.java
  8. +22
    -7
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java
  9. +6
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventExecutor.java
  10. +40
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOpTemplate.java
  11. +13
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilder.java
  12. +21
    -21
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilderImpl.java
  13. +38
    -12
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxy.java
  14. +26
    -16
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxyBuilder.java
  15. +7
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java
  16. +8
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/EventOperator.java
  17. +19
    -5
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PreparedTx.java
  18. +11
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java
  19. +18
    -2
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxTemplate.java
  20. +26
    -6
      source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java
  21. +2
    -1
      source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/proxy/ContractProxy.java

+ 2
- 0
source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContract.java View File

@@ -9,5 +9,7 @@ public interface ReadContract {

@ContractEvent(name = "version-key")
Long readVersion(String address, String key);

int test();
}


+ 5
- 0
source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java View File

@@ -42,4 +42,9 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract {
}
return -1L;
}

@Override
public int test() {
return 0;
}
}

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

@@ -1,7 +1,6 @@
package com.jd.blockchain.contract;

import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.binaryproto.*;
import com.jd.blockchain.contract.param.*;
import com.jd.blockchain.utils.io.BytesUtils;

@@ -19,9 +18,18 @@ public class ContractSerializeUtils {
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) {


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

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

import com.jd.blockchain.utils.IllegalDataException;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class EventResult<T> {

private static final long MAX_SECONDS = 30;

private CompletableFuture<T> data = new CompletableFuture<>();

private int opIndex;

public EventResult() {
}

public EventResult(int opIndex) {
this.opIndex = opIndex;
}

public void done(T value) {
data.complete(value);
}

public int opIndex() {
return this.opIndex;
}

public T get() {
try {
// 防止长时间阻塞
return data.get(MAX_SECONDS, TimeUnit.SECONDS);
} catch (Exception e) {
throw new IllegalDataException(e.getMessage());
}
}
}

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

@@ -44,5 +44,4 @@ public interface ContractEventSendOperation extends Operation {
*/
@DataField(order = 5, primitiveType = PrimitiveType.INT64)
long getTxOpTime();

}

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

@@ -13,6 +13,4 @@ public interface OperationResult {

@DataField(order=2, primitiveType = PrimitiveType.BYTES)
byte[] getResult();

<T> T getResultData();
}

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

@@ -1,6 +1,5 @@
package com.jd.blockchain.ledger;

import com.jd.blockchain.contract.ContractSerializeUtils;

public class OperationResultData implements OperationResult {

@@ -11,10 +10,6 @@ public class OperationResultData implements OperationResult {
public OperationResultData() {
}

public OperationResultData(OperationResult operationResult) {
this(operationResult.getIndex(), operationResult.getResult());
}

public OperationResultData(int index, byte[] result) {
this.index = index;
this.result = result;
@@ -30,11 +25,6 @@ public class OperationResultData implements OperationResult {
return result;
}

@Override
public <T> T getResultData() {
return (T) ContractSerializeUtils.resolve(result);
}

public void setIndex(int index) {
this.index = index;
}


+ 22
- 7
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java View File

@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.ContractCodeDeployOperation;
import com.jd.blockchain.ledger.ContractEventSendOperation;
@@ -29,7 +30,7 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe
private static final ContractCodeDeployOperationBuilderImpl CONTRACT_CODE_DEPLOY_OP_BUILDER = new ContractCodeDeployOperationBuilderImpl();
private static final ContractEventSendOperationBuilderImpl CONTRACT_EVENT_SEND_OP_BUILDER = new ContractEventSendOperationBuilderImpl();
// private static final ContractEventSendOperationBuilderImpl CONTRACT_EVENT_SEND_OP_BUILDER = new ContractEventSendOperationBuilderImpl();
private LedgerInitOperationBuilder ledgerInitOpBuilder = new LedgerInitOperationBuilderFilter();
@@ -89,6 +90,11 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe
return contractInvoProxyBuilder.create(address, contractIntf, contractEventSendOpBuilder);
}
@Override
public <T> EventResult<T> result(ContractEventExecutor execute) {
return contractInvoProxyBuilder.execute(execute);
}
public Collection<Operation> getOperations() {
// TODO: 合并操作列表中可能的重复操作;
return operationList;
@@ -130,7 +136,6 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe
operationList.add(op);
return op;
}
}
private class DataAccountKVSetOperationBuilderFilter implements DataAccountKVSetOperationBuilder {
@@ -235,25 +240,35 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe
operationList.add(op);
return op;
}
}
private class ContractEventSendOperationBuilderFilter implements ContractEventSendOperationBuilder {
@Override
public ContractEventSendOperation send(String address, String event, byte[] args) {
ContractEventSendOperation op = CONTRACT_EVENT_SEND_OP_BUILDER.send(address, event, args);
operationList.add(op);
return op;
return send(Bytes.fromBase58(address), event, args);
}
@Override
public ContractEventSendOperation send(Bytes address, String event, byte[] args) {
ContractEventSendOperation op = CONTRACT_EVENT_SEND_OP_BUILDER.send(address, event, args);
int opIndex = operationList.size();
ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args, opIndex);
operationList.add(op);
return op;
}
@Override
public ContractEventSendOperation send(String address) {
return send(Bytes.fromBase58(address));
}
@Override
public ContractEventSendOperation send(Bytes address) {
int opIndex = operationList.size();
ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, opIndex);
operationList.add(op);
return op;
}
}
}

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

@@ -0,0 +1,6 @@
package com.jd.blockchain.transaction;

public interface ContractEventExecutor<T> {

T execute();
}

+ 40
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOpTemplate.java View File

@@ -5,6 +5,7 @@ import com.jd.blockchain.ledger.ContractEventSendOperation;
import com.jd.blockchain.utils.Bytes;

public class ContractEventSendOpTemplate implements ContractEventSendOperation {

static {
DataContractRegistry.register(ContractEventSendOperation.class);
}
@@ -14,17 +15,47 @@ public class ContractEventSendOpTemplate implements ContractEventSendOperation {
private String event;
//交易操作时间;
private long txOpTime;
// 所属操作Index
private int opIndex;

public ContractEventSendOpTemplate() {
}

public ContractEventSendOpTemplate(Bytes contractAddress) {
this(contractAddress, -1);
}

public ContractEventSendOpTemplate(Bytes contractAddress, int opIndex) {
this.contractAddress = contractAddress;
this.opIndex = opIndex;
this.txOpTime = System.currentTimeMillis();
}

public ContractEventSendOpTemplate(Bytes contractAddress, String event, byte[] args) {
this(contractAddress, event, args, -1);
}

public ContractEventSendOpTemplate(Bytes contractAddress, String event, byte[] args, int opIndex) {
this.contractAddress = contractAddress;
this.event = event;
this.args = args;
this.opIndex = opIndex;
this.txOpTime = System.currentTimeMillis();
}

public void setArgs(byte[] args) {
this.args = args;
}

public void setEvent(String event) {
this.event = event;
}

public void setEventAndArgs(String event, byte[] args) {
this.event = event;
this.args = args;
}

@Override
public Bytes getContractAddress() {
return contractAddress;
@@ -44,4 +75,13 @@ public class ContractEventSendOpTemplate implements ContractEventSendOperation {
public long getTxOpTime() {
return txOpTime;
}

/**
* 获取所属交易中的序号,该值不需要序列化
*
* @return
*/
public int getOpIndex() {
return opIndex;
}
}

+ 13
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilder.java View File

@@ -23,4 +23,17 @@ public interface ContractEventSendOperationBuilder {
@Deprecated
ContractEventSendOperation send(Bytes address, String event, byte[] args);
/**
*
* @param address
* @return
*/
ContractEventSendOperation send(String address);
/**
*
* @param address
* @return
*/
ContractEventSendOperation send(Bytes address);
}

+ 21
- 21
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractEventSendOperationBuilderImpl.java View File

@@ -1,21 +1,21 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.ledger.ContractEventSendOperation;
import com.jd.blockchain.utils.Bytes;
@Deprecated
class ContractEventSendOperationBuilderImpl implements ContractEventSendOperationBuilder {
@Override
public ContractEventSendOperation send(String address, String event, byte[] args) {
ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(Bytes.fromBase58(address), event, args);
return op;
}
@Override
public ContractEventSendOperation send(Bytes address, String event, byte[] args) {
ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args);
return op;
}
}
//package com.jd.blockchain.transaction;
//
//import com.jd.blockchain.ledger.ContractEventSendOperation;
//import com.jd.blockchain.utils.Bytes;
//
//@Deprecated
//class ContractEventSendOperationBuilderImpl implements ContractEventSendOperationBuilder {
//
// @Override
// public ContractEventSendOperation send(String address, String event, byte[] args) {
// ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(Bytes.fromBase58(address), event, args);
// return op;
// }
//
// @Override
// public ContractEventSendOperation send(Bytes address, String event, byte[] args) {
// ContractEventSendOpTemplate op = new ContractEventSendOpTemplate(address, event, args);
// return op;
// }
//
//}

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

@@ -4,6 +4,7 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import com.jd.blockchain.contract.ContractSerializeUtils;
import com.jd.blockchain.ledger.ContractEventSendOperation;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.IllegalDataException;

@@ -11,41 +12,66 @@ public class ContractInvocationProxy implements InvocationHandler {

// private String contractMessage;

private Bytes contractAddress;
// private Bytes contractAddress;

private ContractType contractType;

private ContractEventSendOperationBuilder sendOpBuilder;
// private ContractEventSendOperationBuilder sendOpBuilder;

private ContractEventSendOperation sendOperation;

public ContractInvocationProxy(Bytes contractAddress, ContractType contractType,
ContractEventSendOperationBuilder sendOpBuilder) {
this.contractAddress = contractAddress;
// this.contractAddress = contractAddress;
if(contractType == null){
throw new IllegalDataException("contractType == null, no invoke really.");
}
this.contractType = contractType;
this.sendOpBuilder = sendOpBuilder;
// this.sendOpBuilder = sendOpBuilder;
// Send一个地址,但不涉及Event
this.sendOperation = sendOpBuilder.send(contractAddress);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// 判断是否是常规方法调用
if (method.getName().equals("hashCode")) {
// 该处需要使用当前代理类的HashCode
return this.hashCode();
}
if (method.getName().equals("toString")) {
// 该处使用当前代理类的toString
return this.toString();
}

if (sendOperation.getEvent() != null) {
throw new IllegalStateException("Contract Object can only execute method one time !!!");
}

String event = contractType.getEvent(method);
if (event == null) {
// 适配 Object 对象的方法;
// toString 方法;
return String.format("[%s]-%s", contractAddress, contractType.toString());

// hashCode 方法;
// 该方法不是合约可执行的方法
throw new IllegalAccessException(String.format("This Method [%s] is not Contract Event Method !!!",
method.getName()));
}
// 合约方法;
byte[] argBytes = serializeArgs(args);
sendOpBuilder.send(contractAddress, event, argBytes);

// TODO: 暂时未考虑有返回值的情况;
if (sendOperation instanceof ContractEventSendOpTemplate) {
((ContractEventSendOpTemplate) sendOperation).setEventAndArgs(event, argBytes);
}
// 代理操作,返回值类型无法创建
return null;
}

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

public int opIndex() {
if (sendOperation instanceof ContractEventSendOpTemplate) {
return ((ContractEventSendOpTemplate) sendOperation).getOpIndex();
}
return -1;
}
}

+ 26
- 16
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractInvocationProxyBuilder.java View File

@@ -1,17 +1,19 @@
package com.jd.blockchain.transaction;
import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.jd.blockchain.contract.Contract;
import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.IllegalDataException;
public class ContractInvocationProxyBuilder {
private Map<Class<?>, ContractType> contractTypes = new ConcurrentHashMap<>();
private Map<Object, Integer> contractOperations = new ConcurrentHashMap<>();
public <T> T create(String address, Class<T> contractIntf, ContractEventSendOperationBuilder contractEventBuilder) {
return create(Bytes.fromBase58(address), contractIntf, contractEventBuilder);
}
@@ -22,10 +24,31 @@ public class ContractInvocationProxyBuilder {
ContractInvocationProxy proxyHandler = new ContractInvocationProxy(address, contractType,
contractEventBuilder);
T proxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class<?>[] { contractIntf }, proxyHandler);
// 创建关联关系
contractOperations.put(proxy, proxyHandler.opIndex());
return proxy;
}
public <T> EventResult<T> execute(ContractEventExecutor execute) {
Object contractProxy = execute.execute();
if (contractProxy == null) {
// 该方法执行必须要有返回值
throw new IllegalStateException(
String.format("ContractEventExecutor [%s] 's return must be not empty !!!", execute.toString()));
}
if (!(contractProxy instanceof Proxy)) {
throw new IllegalDataException(
String.format("ContractEventExecutor [%s] 's return must from TxTemplate.contract()'s result !!!", execute.toString()));
}
return (T) proxy;
Integer opIndex = contractOperations.get(contractProxy);
if (opIndex != null && opIndex > -1) {
return new EventResult<>(opIndex);
}
return null;
}
private ContractType resolveContractType(Class<?> contractIntf) {
@@ -33,21 +56,8 @@ public class ContractInvocationProxyBuilder {
if (contractType != null) {
return contractType;
}
// TODO 检查返回值类型;
ContractType ct = ContractType.resolve(contractIntf);
contractTypes.put(contractIntf, ct);
return ct;
}
/**
* is contractType really? identified by @Contract;
* @param contractIntf
* @return
*/
private boolean isContractType(Class<?> contractIntf) {
Annotation annotation = contractIntf.getDeclaredAnnotation(Contract.class);
return annotation != null ? true : false;
}
}

+ 7
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/ContractType.java View File

@@ -91,6 +91,13 @@ public class ContractType {
throw new IllegalStateException(String.format("Param Type = %s can not support !!!", currParamType.getName()));
}
}

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

contractType.events.put(eventName, method);
contractType.handleMethods.put(method, eventName);
}


+ 8
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/EventOperator.java View File

@@ -1,5 +1,6 @@
package com.jd.blockchain.transaction;

import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.utils.Bytes;

public interface EventOperator {
@@ -30,4 +31,11 @@ public interface EventOperator {
*/
<T> T contract(Bytes address, Class<T> contractIntf);

/**
* 执行合约异步等待应答结果
*
* @param execute
* @return
*/
<T> EventResult<T> result(ContractEventExecutor execute);
}

+ 19
- 5
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/PreparedTx.java View File

@@ -1,6 +1,8 @@
package com.jd.blockchain.transaction;

import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.contract.ContractSerializeUtils;
import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.HashDigest;
@@ -9,15 +11,24 @@ import com.jd.blockchain.crypto.SignatureDigest;
import com.jd.blockchain.crypto.SignatureFunction;
import com.jd.blockchain.ledger.*;

import java.util.Map;

public class PreparedTx implements PreparedTransaction {

private TransactionRequestBuilder txReqBuilder;

private TransactionService txProcessor;

private Map<Integer, EventResult> eventResults;

public PreparedTx(TransactionRequestBuilder txReqBuilder, TransactionService txProcessor) {
this(txReqBuilder, txProcessor, null);
}

public PreparedTx(TransactionRequestBuilder txReqBuilder, TransactionService txProcessor, Map<Integer, EventResult> eventResults) {
this.txReqBuilder = txReqBuilder;
this.txProcessor = txProcessor;
this.eventResults = eventResults;
}

@Override
@@ -53,12 +64,15 @@ public class PreparedTx implements PreparedTransaction {
TransactionResponse txResponse = txProcessor.process(txReq);
// 重新包装操作集合
OperationResult[] operationResults = txResponse.getOperationResults();
if (operationResults != null && operationResults.length > 0) {
OperationResult[] wrapOpResults = new OperationResult[operationResults.length];
for (int i = 0; i < operationResults.length; i++) {
wrapOpResults[i] = new OperationResultData(operationResults[i]);
if (operationResults != null && operationResults.length > 0 &&
eventResults != null && !eventResults.isEmpty()) {
for (OperationResult operationResult : operationResults) {
int opIndex = operationResult.getIndex();
EventResult eventResult = eventResults.get(opIndex);
if (eventResult != null) {
eventResult.done(ContractSerializeUtils.resolve(operationResult.getResult()));
}
}
return new TxResponseMessage(txResponse, wrapOpResults);
}
return txResponse;
}


+ 11
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/TxBuilder.java View File

@@ -2,6 +2,7 @@ package com.jd.blockchain.transaction;

import com.jd.blockchain.binaryproto.BinaryProtocol;
import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.crypto.Crypto;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.TransactionBuilder;
@@ -10,6 +11,9 @@ import com.jd.blockchain.ledger.TransactionContentBody;
import com.jd.blockchain.ledger.TransactionRequestBuilder;
import com.jd.blockchain.utils.Bytes;

import java.util.HashMap;
import java.util.Map;

public class TxBuilder implements TransactionBuilder {

static {
@@ -18,6 +22,8 @@ public class TxBuilder implements TransactionBuilder {

private BlockchainOperationFactory opFactory = new BlockchainOperationFactory();

private Map<Object, Integer> contractProxyMap = new HashMap<>();

private static final String DEFAULT_HASH_ALGORITHM = "SHA256";

private HashDigest ledgerHash;
@@ -88,6 +94,11 @@ public class TxBuilder implements TransactionBuilder {
return opFactory.contract(address, contractIntf);
}

@Override
public <T> EventResult<T> result(ContractEventExecutor execute) {
return opFactory.result(execute);
}

@Override
public <T> T contract(String address, Class<T> contractIntf) {
return opFactory.contract(address, contractIntf);


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

@@ -1,20 +1,27 @@
package com.jd.blockchain.transaction;
import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionRequestBuilder;
import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.utils.Bytes;
import java.util.HashMap;
import java.util.Map;
public class TxTemplate implements TransactionTemplate {
private TxBuilder txBuilder;
private TransactionService txService;
private Map<Integer, EventResult> eventResults;
public TxTemplate(HashDigest ledgerHash, TransactionService txService) {
this.txBuilder = new TxBuilder(ledgerHash);
this.txService = txService;
this.eventResults = new HashMap<>();
}
@Override
@@ -25,7 +32,7 @@ public class TxTemplate implements TransactionTemplate {
@Override
public PreparedTransaction prepare() {
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest();
return new PreparedTx(txReqBuilder, txService);
return new PreparedTx(txReqBuilder, txService, eventResults);
}
@Override
@@ -62,7 +69,16 @@ public class TxTemplate implements TransactionTemplate {
public <T> T contract(Bytes address, Class<T> contractIntf) {
return txBuilder.contract(address, contractIntf);
}
@Override
public <T> EventResult<T> result(ContractEventExecutor execute) {
EventResult<T> eventResult = txBuilder.result(execute);
if (eventResult != null) {
eventResults.put(eventResult.opIndex(), eventResult);
}
return eventResult;
}
@Override
public <T> T contract(String address, Class<T> contractIntf) {
return txBuilder.contract(address, contractIntf);


+ 26
- 6
source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java View File

@@ -24,8 +24,10 @@ import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;

import com.jd.blockchain.contract.EventResult;
import com.jd.blockchain.contract.ReadContract;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.transaction.ContractEventExecutor;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;

@@ -568,13 +570,25 @@ public class IntegrationBase {
TransactionTemplate txContract = blockchainService.newTransaction(ledgerHash);

ReadContract readContract1 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);
readContract1.read(newDataAccount.getAddress().toBase58(), key1);

EventResult<String> read1 = txContract.result((ContractEventExecutor<ReadContract>) () -> {
readContract1.read(newDataAccount.getAddress().toBase58(), key1);
return readContract1;
});

ReadContract readContract2 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);
readContract2.read(newDataAccount.getAddress().toBase58(), key2);

EventResult<String> read2 = txContract.result((ContractEventExecutor<ReadContract>) () -> {
readContract2.read(newDataAccount.getAddress().toBase58(), key2);
return readContract2;
});

ReadContract readContract3 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);
readContract3.readVersion(newDataAccount.getAddress().toBase58(), key2);

EventResult<Long> read3 = txContract.result((ContractEventExecutor<ReadContract>) () -> {
readContract3.readVersion(newDataAccount.getAddress().toBase58(), key2);
return readContract3;
});

// 签名;
PreparedTransaction contractPtx = txContract.prepare();
@@ -585,10 +599,16 @@ public class IntegrationBase {

OperationResult[] operationResults = readTxResp.getOperationResults();

// 通过EventResult获取结果
System.out.printf("readContract1.result = %s \r\n", read1.get());
System.out.printf("readContract2.result = %s \r\n", read2.get());
System.out.printf("readContract3.result = %s \r\n", read3.get());


// 打印结果
for (OperationResult or : operationResults) {
System.out.printf("操作[%s].Result = %s \r\n", or.getIndex(), or.getResultData());
}
// for (OperationResult or : operationResults) {
// System.out.printf("操作[%s].Result = %s \r\n", or.getIndex(), or.getResult());
// }
//
// // 验证结果
// assertNotNull(contractReturn);


+ 2
- 1
source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/proxy/ContractProxy.java View File

@@ -2,6 +2,7 @@ package com.jd.blockchain.mocker.proxy;

import com.jd.blockchain.contract.Contract;
import com.jd.blockchain.contract.ContractEvent;
import com.jd.blockchain.contract.ContractSerializeUtils;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainIdentity;
import com.jd.blockchain.ledger.OperationResult;
@@ -77,7 +78,7 @@ public class ContractProxy<T> implements InvocationHandler {
OperationResult opResult = operationResults[0];

// 处理返回值
return new OperationResultData(opResult).getResultData();
return ContractSerializeUtils.resolve(opResult.getResult());
}

private boolean isExecuteContractMethod(Method method) {


Loading…
Cancel
Save