Browse Source

Refactored the invoking process of contract code;

tags/1.0.0
huanghaiquan 5 years ago
parent
commit
00bb4e5e07
20 changed files with 395 additions and 214 deletions
  1. +1
    -4
      source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractCode.java
  2. +2
    -3
      source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java
  3. +64
    -70
      source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JavaContractCode.java
  4. +1
    -11
      source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java
  5. +19
    -26
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java
  6. +4
    -14
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java
  7. +82
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java
  8. +110
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java
  9. +1
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java
  10. +49
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TestContract.java
  11. +2
    -2
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java
  12. +2
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractException.java
  13. +1
    -14
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventProcessingAwire.java
  14. +1
    -1
      source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java
  15. +1
    -11
      source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java
  16. +29
    -24
      source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java
  17. +22
    -12
      source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java
  18. +1
    -10
      source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java
  19. +1
    -10
      source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java
  20. +2
    -2
      source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java

+ 1
- 4
source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractCode.java View File

@@ -3,14 +3,11 @@ package com.jd.blockchain.contract.engine;
import com.jd.blockchain.contract.ContractEventContext; import com.jd.blockchain.contract.ContractEventContext;
import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Bytes;


import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

public interface ContractCode { public interface ContractCode {


Bytes getAddress(); Bytes getAddress();
long getVersion(); long getVersion();


void processEvent(ContractEventContext eventContext, CompletableFuture<String> execReturn);
byte[] processEvent(ContractEventContext eventContext);
} }

+ 2
- 3
source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java View File

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


import com.jd.blockchain.ledger.BytesValue;
import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Bytes;


/** /**
@@ -27,9 +26,9 @@ public interface ContractEngine {
* 如果已经存在,则直接返回已有实例; * 如果已经存在,则直接返回已有实例;
* *
* @param address * @param address
* @param code
* @param codeBytes
* @return * @return
*/ */
ContractCode setupContract(Bytes address, long version, byte[] code);
ContractCode setupContract(Bytes address, long version, byte[] codeBytes);


} }

+ 64
- 70
source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JavaContractCode.java View File

@@ -1,21 +1,19 @@
package com.jd.blockchain.contract.jvm; package com.jd.blockchain.contract.jvm;


import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.Callable;


import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;


import com.jd.blockchain.binaryproto.DataContract;
import com.jd.blockchain.contract.ContractEventContext; import com.jd.blockchain.contract.ContractEventContext;
import com.jd.blockchain.contract.ContractException;
import com.jd.blockchain.contract.EventProcessingAwire;
import com.jd.blockchain.contract.engine.ContractCode; import com.jd.blockchain.contract.engine.ContractCode;
import com.jd.blockchain.runtime.Module; import com.jd.blockchain.runtime.Module;
import com.jd.blockchain.transaction.ContractType; import com.jd.blockchain.transaction.ContractType;
import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.IllegalDataException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;


/** /**
* contract code based jvm * contract code based jvm
@@ -27,14 +25,22 @@ public class JavaContractCode implements ContractCode {
private Module codeModule; private Module codeModule;
private Bytes address; private Bytes address;
private long version; private long version;
private ContractEventContext contractEventContext;


private Class<?> contractClass;
private ContractType contractType; private ContractType contractType;


public JavaContractCode(Bytes address, long version, Module codeModule) { public JavaContractCode(Bytes address, long version, Module codeModule) {
this.address = address; this.address = address;
this.version = version; this.version = version;
this.codeModule = codeModule; this.codeModule = codeModule;

init();
}

private void init() {
String contractClassName = codeModule.getMainClass();
this.contractClass = codeModule.loadClass(contractClassName);
this.contractType = ContractType.resolve(contractClass);
} }


@Override @Override
@@ -48,89 +54,77 @@ public class JavaContractCode implements ContractCode {
} }


@Override @Override
public void processEvent(ContractEventContext eventContext, CompletableFuture<String> execReturn) {
this.contractEventContext = eventContext;
codeModule.execute(new ContractExecution(execReturn));
}

private Object resolveArgs(byte[] args, List<DataContract> dataContractList) {
if(args == null || args.length == 0){
return null;
}
//TODO: Not implemented;
throw new IllegalStateException("Not implemented!");
// return ContractSerializeUtils.deserializeMethodParam(args,dataContractList);
public byte[] processEvent(ContractEventContext eventContext) {
return codeModule.call(new ContractExecution(eventContext));
} }


class ContractExecution implements Runnable {
private class ContractExecution implements Callable<byte[]> {


private CompletableFuture<String> contractReturn;
private ContractEventContext eventContext;


public ContractExecution(CompletableFuture<String> contractReturn) {
this.contractReturn = contractReturn;
public ContractExecution(ContractEventContext contractEventContext) {
this.eventContext = contractEventContext;
} }


public void run() {
LOGGER.info("ContractThread execute().");
@Override
public byte[] call() throws Exception {
EventProcessingAwire evtProcAwire = null;
Object retn = null;
Exception error = null;
try { try {
// 执行预处理; // 执行预处理;
long startTime = System.currentTimeMillis();

String contractClassName = codeModule.getMainClass();

Class myClass = codeModule.loadClass(contractClassName);

Object contractMainClassObj = myClass.newInstance();// 合约主类生成的类实例;

Method beforeMth_ = myClass.getMethod("beforeEvent",
codeModule.loadClass(ContractEventContext.class.getName()));

ReflectionUtils.invokeMethod(beforeMth_, contractMainClassObj, contractEventContext);

LOGGER.info("beforeEvent,耗时:" + (System.currentTimeMillis() - startTime));
Object contractInstance = contractClass.newInstance();// 合约主类生成的类实例;
if (contractInstance instanceof EventProcessingAwire) {
evtProcAwire = (EventProcessingAwire) contractInstance;
}


// Method eventMethod = this.getMethodByAnno(contractMainClassObj, contractEventContext.getEvent());
startTime = System.currentTimeMillis();
if (evtProcAwire != null) {
evtProcAwire.beforeEvent(eventContext);
}


// 反序列化参数; // 反序列化参数;
contractType = ContractType.resolve(myClass);

Method handleMethod = contractType.getHandleMethod(contractEventContext.getEvent());
Method handleMethod = contractType.getHandleMethod(eventContext.getEvent());


if (handleMethod == null){
throw new IllegalDataException("don't get this method by it's @ContractEvent.");
if (handleMethod == null) {
throw new ContractException(
String.format("Contract[%s:%s] has no handle method to handle event[%s]!",
address.toString(), contractClass.getName(), eventContext.getEvent()));
} }
//TODO: Not implemented;
// Object args = resolveArgs(contractEventContext.getArgs(),
// contractType.getDataContractMap().get(handleMethod));
//
// Object[] params = null;
// if(args.getClass().isArray()){
// params = (Object[])args;
// }
// ReflectionUtils.invokeMethod(handleMethod, contractMainClassObj, params);


LOGGER.info("合约执行,耗时:" + (System.currentTimeMillis() - startTime));
Object[] args = resolveArgs();
retn = ReflectionUtils.invokeMethod(handleMethod, contractInstance, args);


Method mth2 = myClass.getMethod("postEvent");
startTime = System.currentTimeMillis();
} catch (Exception e) {
error = e;
}


ReflectionUtils.invokeMethod(mth2, contractMainClassObj);
if (evtProcAwire != null) {
try {
evtProcAwire.postEvent(eventContext, error);
} catch (Exception e) {
LOGGER.error("Error occurred while posting contract event! --" + e.getMessage(), e);
}
}
if (error != null) {
// Rethrow error;
throw error;
}


LOGGER.info("postEvent,耗时:" + (System.currentTimeMillis() - startTime));
byte[] retnBytes = resolveResult(retn);
return retnBytes;
}


// 填充return结果
if (this.contractReturn != null) {
//TODO: Not implemented;
throw new IllegalStateException("Not implemented!");
// this.contractReturn.complete(contractReturn);
}
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(e.getMessage());
} catch (Exception e) {
throw new IllegalDataException(e.getMessage());
private byte[] resolveResult(Object retn) {
if (retn == null) {
return null;
} }
// TODO: resolve result in bytes;
return null;
}

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




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

@@ -17,17 +17,7 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract {
} }


@Override @Override
public void postEvent(ContractEventContext eventContext, ContractException error) {

}

@Override
public void postEvent(ContractException error) {

}

@Override
public void postEvent() {
public void postEvent(ContractEventContext eventContext, Exception error) {


} }




+ 19
- 26
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java View File

@@ -21,18 +21,7 @@ import com.jd.blockchain.ledger.core.impl.handles.UserRegisterOperationHandle;
public class DefaultOperationHandleRegisteration implements OperationHandleRegisteration { public class DefaultOperationHandleRegisteration implements OperationHandleRegisteration {


private List<OperationHandle> opHandles = new ArrayList<>(); private List<OperationHandle> opHandles = new ArrayList<>();
// private UserRegisterOperationHandle userRegHandle;
//
// private DataAccountRegisterOperationHandle dataAccRegHandle;
//
// private DataAccountKVSetOperationHandle dataAccKVSetHandle;
//
// private ContractCodeDeployOperationHandle contractDplHandle;
//
// private ContractEventSendOperationHandle contractEvtSendHandle;

public DefaultOperationHandleRegisteration() { public DefaultOperationHandleRegisteration() {
initDefaultHandles(); initDefaultHandles();
} }
@@ -40,25 +29,30 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis
/** /**
* 针对不采用bean依赖注入的方式来处理; * 针对不采用bean依赖注入的方式来处理;
*/ */
private void initDefaultHandles(){
private void initDefaultHandles() {
opHandles.add(new DataAccountKVSetOperationHandle()); opHandles.add(new DataAccountKVSetOperationHandle());
opHandles.add(new DataAccountRegisterOperationHandle()); opHandles.add(new DataAccountRegisterOperationHandle());
opHandles.add(new UserRegisterOperationHandle()); opHandles.add(new UserRegisterOperationHandle());
opHandles.add(new ContractCodeDeployOperationHandle()); opHandles.add(new ContractCodeDeployOperationHandle());
opHandles.add(new ContractEventSendOperationHandle()); opHandles.add(new ContractEventSendOperationHandle());
} }
// @PostConstruct
// private void init() {
// opHandles.add(dataAccKVSetHandle);
// opHandles.add(dataAccRegHandle);
// opHandles.add(userRegHandle);
// opHandles.add(contractDplHandle);
// opHandles.add(contractEvtSendHandle);
// }


/* (non-Javadoc)
* @see com.jd.blockchain.ledger.core.impl.OperationHandleRegisteration#getHandle(java.lang.Class)
/**
* 以最高优先级插入一个操作处理器;
*
* @param handle
*/
public void insertAsTopPriority(OperationHandle handle) {
opHandles.remove(handle);
opHandles.add(0, handle);
}

/*
* (non-Javadoc)
*
* @see
* com.jd.blockchain.ledger.core.impl.OperationHandleRegisteration#getHandle(
* java.lang.Class)
*/ */
@Override @Override
public OperationHandle getHandle(Class<?> operationType) { public OperationHandle getHandle(Class<?> operationType) {
@@ -69,6 +63,5 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis
} }
throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!");
} }

} }

+ 4
- 14
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java View File

@@ -31,24 +31,14 @@ public class ContractEventSendOperationHandle implements OperationHandle {
JVM_ENGINE = ContractServiceProviders.getProvider(CONTRACT_SERVICE_PROVIDER).getEngine(); JVM_ENGINE = ContractServiceProviders.getProvider(CONTRACT_SERVICE_PROVIDER).getEngine();
} }


@Override
public byte[] process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext,
LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService) {
process(op, dataset, requestContext, previousBlockDataset, opHandleContext, ledgerService, null);

// TODO: return value;
return null;
}

@Override @Override
public boolean support(Class<?> operationType) { public boolean support(Class<?> operationType) {
return ContractEventSendOperation.class.isAssignableFrom(operationType); return ContractEventSendOperation.class.isAssignableFrom(operationType);
} }


public void process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext,
LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService,
CompletableFuture<String> contractReturn) {

@Override
public byte[] process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext,
LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService) {
ContractEventSendOperation contractOP = (ContractEventSendOperation) op; ContractEventSendOperation contractOP = (ContractEventSendOperation) op;
// 先从账本校验合约的有效性; // 先从账本校验合约的有效性;
// 注意:必须在前一个区块的数据集中进行校验,因为那是经过共识的数据;从当前新区块链数据集校验则会带来攻击风险:未经共识的合约得到执行; // 注意:必须在前一个区块的数据集中进行校验,因为那是经过共识的数据;从当前新区块链数据集校验则会带来攻击风险:未经共识的合约得到执行;
@@ -83,7 +73,7 @@ public class ContractEventSendOperationHandle implements OperationHandle {
} }


// 处理合约事件; // 处理合约事件;
contractCode.processEvent(localContractEventContext, contractReturn);
return contractCode.processEvent(localContractEventContext);
} }


} }

+ 82
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java View File

@@ -0,0 +1,82 @@
//package test.com.jd.blockchain.ledger;
//
//import java.util.Map;
//import java.util.concurrent.CompletableFuture;
//import java.util.concurrent.ConcurrentHashMap;
//
//import com.jd.blockchain.contract.LocalContractEventContext;
//import com.jd.blockchain.contract.engine.ContractCode;
//import com.jd.blockchain.ledger.ContractEventSendOperation;
//import com.jd.blockchain.ledger.LedgerException;
//import com.jd.blockchain.ledger.Operation;
//import com.jd.blockchain.ledger.core.ContractAccount;
//import com.jd.blockchain.ledger.core.ContractAccountSet;
//import com.jd.blockchain.ledger.core.LedgerDataSet;
//import com.jd.blockchain.ledger.core.LedgerService;
//import com.jd.blockchain.ledger.core.OperationHandle;
//import com.jd.blockchain.ledger.core.TransactionRequestContext;
//import com.jd.blockchain.ledger.core.impl.LedgerQueryService;
//import com.jd.blockchain.ledger.core.impl.OperationHandleContext;
//import com.jd.blockchain.ledger.core.impl.handles.ContractLedgerContext;
//import com.jd.blockchain.utils.Bytes;
//
//public class ContractInvokingHandle implements OperationHandle {
//
// private Map<Bytes, Object> contractInstances = new ConcurrentHashMap<Bytes, Object>();
//
// @Override
// public byte[] process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext,
// LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService) {
// process(op, dataset, requestContext, previousBlockDataset, opHandleContext, ledgerService, null);
//
// // TODO: return value;
// return null;
// }
//
// @Override
// public boolean support(Class<?> operationType) {
// return ContractEventSendOperation.class.isAssignableFrom(operationType);
// }
//
// public void process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext,
// LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService,
// CompletableFuture<String> contractReturn) {
//
// ContractEventSendOperation contractOP = (ContractEventSendOperation) op;
// // 先从账本校验合约的有效性;
// // 注意:必须在前一个区块的数据集中进行校验,因为那是经过共识的数据;从当前新区块链数据集校验则会带来攻击风险:未经共识的合约得到执行;
// ContractAccountSet contractSet = previousBlockDataset.getContractAccountSet();
// if (!contractSet.contains(contractOP.getContractAddress())) {
// throw new LedgerException(String.format("Contract was not registered! --[ContractAddress=%s]",
// contractOP.getContractAddress()));
// }
//
// // 创建合约的账本上下文实例;
// LedgerQueryService queryService = new LedgerQueryService(ledgerService);
// ContractLedgerContext ledgerContext = new ContractLedgerContext(queryService, opHandleContext);
//
// // 先检查合约引擎是否已经加载合约;如果未加载,再从账本中读取合约代码并装载到引擎中执行;
// ContractAccount contract = contractSet.getContract(contractOP.getContractAddress());
// if (contract == null) {
// throw new LedgerException(String.format("Contract was not registered! --[ContractAddress=%s]",
// contractOP.getContractAddress()));
// }
//
// // 创建合约上下文;
// LocalContractEventContext localContractEventContext = new LocalContractEventContext(
// requestContext.getRequest().getTransactionContent().getLedgerHash(), contractOP.getEvent());
// localContractEventContext.setArgs(contractOP.getArgs()).setTransactionRequest(requestContext.getRequest())
// .setLedgerContext(ledgerContext);
//
// ContractCode contractCode = JVM_ENGINE.getContract(contract.getAddress(), contract.getChaincodeVersion());
// if (contractCode == null) {
// // 装载合约;
// contractCode = JVM_ENGINE.setupContract(contract.getAddress(), contract.getChaincodeVersion(),
// contract.getChainCode());
// }
//
// // 处理合约事件;
// contractCode.processEvent(localContractEventContext, contractReturn);
// }
//
//}

+ 110
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java View File

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

import static org.junit.Assert.*;

import org.junit.Test;

import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.EndpointRequest;
import com.jd.blockchain.ledger.LedgerBlock;
import com.jd.blockchain.ledger.LedgerInitSetting;
import com.jd.blockchain.ledger.LedgerTransaction;
import com.jd.blockchain.ledger.NodeRequest;
import com.jd.blockchain.ledger.TransactionContent;
import com.jd.blockchain.ledger.TransactionContentBody;
import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionState;
import com.jd.blockchain.ledger.UserRegisterOperation;
import com.jd.blockchain.ledger.core.LedgerDataSet;
import com.jd.blockchain.ledger.core.LedgerEditor;
import com.jd.blockchain.ledger.core.LedgerRepository;
import com.jd.blockchain.ledger.core.LedgerTransactionContext;
import com.jd.blockchain.ledger.core.UserAccount;
import com.jd.blockchain.ledger.core.impl.DefaultOperationHandleRegisteration;
import com.jd.blockchain.ledger.core.impl.LedgerManager;
import com.jd.blockchain.ledger.core.impl.LedgerTransactionalEditor;
import com.jd.blockchain.ledger.core.impl.OperationHandleRegisteration;
import com.jd.blockchain.storage.service.utils.MemoryKVStorage;
import com.jd.blockchain.transaction.TxBuilder;

public class ContractInvokingTest {
static {
DataContractRegistry.register(TransactionContent.class);
DataContractRegistry.register(TransactionContentBody.class);
DataContractRegistry.register(TransactionRequest.class);
DataContractRegistry.register(NodeRequest.class);
DataContractRegistry.register(EndpointRequest.class);
DataContractRegistry.register(TransactionResponse.class);
DataContractRegistry.register(UserRegisterOperation.class);
}

private static final String LEDGER_KEY_PREFIX = "LDG://";


private BlockchainKeypair parti0 = BlockchainKeyGenerator.getInstance().generate();
private BlockchainKeypair parti1 = BlockchainKeyGenerator.getInstance().generate();
private BlockchainKeypair parti2 = BlockchainKeyGenerator.getInstance().generate();
private BlockchainKeypair parti3 = BlockchainKeyGenerator.getInstance().generate();

// 采用基于内存的 Storage;
private MemoryKVStorage storage = new MemoryKVStorage();

@Test
public void test() {
// 初始化账本到指定的存储库;
HashDigest ledgerHash = initLedger(storage, parti0, parti1, parti2, parti3);

// 重新加载账本;
LedgerManager ledgerManager = new LedgerManager();
LedgerRepository ledgerRepo = ledgerManager.register(ledgerHash, storage);
OperationHandleRegisteration opReg = new DefaultOperationHandleRegisteration();
//构建基于接口调用合约的交易请求;
TxBuilder txBuilder = new TxBuilder(ledgerHash);
// txBuilder.contract(address, contractIntf)
}

private HashDigest initLedger(MemoryKVStorage storage, BlockchainKeypair... partiKeys) {
// 创建初始化配置;
LedgerInitSetting initSetting = LedgerTestUtils.createLedgerInitSetting(partiKeys);

// 创建账本;
LedgerEditor ldgEdt = LedgerTransactionalEditor.createEditor(initSetting, LEDGER_KEY_PREFIX, storage, storage);

TransactionRequest genesisTxReq = LedgerTestUtils.createTxRequest_UserReg(null);
LedgerTransactionContext genisisTxCtx = ldgEdt.newTransaction(genesisTxReq);
LedgerDataSet ldgDS = genisisTxCtx.getDataSet();

for (int i = 0; i < partiKeys.length; i++) {
UserAccount userAccount = ldgDS.getUserAccountSet().register(partiKeys[i].getAddress(),
partiKeys[i].getPubKey());
userAccount.setProperty("Name", "参与方-" + i, -1);
userAccount.setProperty("Share", "" + (10 + i), -1);
}

LedgerTransaction tx = genisisTxCtx.commit(TransactionState.SUCCESS);

assertEquals(genesisTxReq.getTransactionContent().getHash(), tx.getTransactionContent().getHash());
assertEquals(0, tx.getBlockHeight());

LedgerBlock block = ldgEdt.prepare();

assertEquals(0, block.getHeight());
assertNotNull(block.getHash());
assertNull(block.getPreviousHash());

assertEquals(block.getHash(), block.getLedgerHash());

// 提交数据,写入存储;
ldgEdt.commit();

HashDigest ledgerHash = block.getHash();
return ledgerHash;
}
}

+ 1
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java View File

@@ -96,6 +96,7 @@ public class LedgerTestUtils {
if (gatewayKeypair != null) { if (gatewayKeypair != null) {
txReqBuilder.signAsNode(gatewayKeypair); txReqBuilder.signAsNode(gatewayKeypair);
} }
return txReqBuilder.buildRequest(); return txReqBuilder.buildRequest();
} }




+ 49
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TestContract.java View File

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

public interface TestContract {

/**
* 发行资产;
*
* @param asset 资产代码;
* @param amount 本次发行的资产数量;
* @return 资产总量;
*/
long issue(String asset, long amount);

/**
* 获取资产总量;
*
* @param asset
* @return
*/
long getAmount(String asset);

/**
* 获取资产余额;
*
* @param address
* @param asset
* @return
*/
long getBalance(String address, String asset);
/**
* 向账户分配资产;
*
* @param address
* @param asset
* @param amount
*/
void assign(String address, String asset, int amount);

/**
* 转移资产;
*
* @param fromAddress
* @param toAddress
* @param asset
* @param amount
*/
void transfer(String fromAddress, String toAddress, String asset, long amount);
}

+ 2
- 2
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java View File

@@ -57,10 +57,10 @@ public class TransactionBatchProcessorTest {
private TransactionRequest transactionRequest; private TransactionRequest transactionRequest;


// 采用基于内存的 Storage; // 采用基于内存的 Storage;
MemoryKVStorage storage = new MemoryKVStorage();
private MemoryKVStorage storage = new MemoryKVStorage();


@Test @Test
public void testContractOperations() {
public void testTxReqProcess() {
// 初始化账本到指定的存储库; // 初始化账本到指定的存储库;
ledgerHash = initLedger(storage, parti0, parti1, parti2, parti3); ledgerHash = initLedger(storage, parti0, parti1, parti2, parti3);




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

@@ -2,6 +2,8 @@ package com.jd.blockchain.contract;


public class ContractException extends RuntimeException { public class ContractException extends RuntimeException {
private static final long serialVersionUID = 4338023105616639257L;

public ContractException(String message) { public ContractException(String message) {
super(message); super(message);
} }


+ 1
- 14
source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventProcessingAwire.java View File

@@ -21,19 +21,6 @@ public interface EventProcessingAwire extends ContractRuntimeAwire {
* @param error * @param error
* 错误;如果事件处理正常结束,则此参数为 null;如果事件处理发生了错误,此参数非空; * 错误;如果事件处理正常结束,则此参数为 null;如果事件处理发生了错误,此参数非空;
*/ */
void postEvent(ContractEventContext eventContext, ContractException error);
void postEvent(ContractEventContext eventContext, Exception error);



/**
* 在事件处理方法成功执行之后调用;
*
* @param error
* 错误;如果事件处理正常结束,则此参数为 null;如果事件处理发生了错误,此参数非空;
*/
void postEvent(ContractException error);

/**
* 在事件处理方法成功执行之后调用;
*/
void postEvent();
} }

+ 1
- 1
source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java View File

@@ -10,7 +10,7 @@ public interface Module {
String getName(); String getName();


Class<?> loadClass(String className); Class<?> loadClass(String className);
InputStream loadResourceAsStream(String name); InputStream loadResourceAsStream(String name);


String getMainClass(); String getMainClass();


+ 1
- 11
source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java View File

@@ -171,17 +171,7 @@ public class AssetContractImpl implements EventProcessingAwire, AssetContract {
* com.jd.blockchain.contract.model.ContractError) * com.jd.blockchain.contract.model.ContractError)
*/ */
@Override @Override
public void postEvent(ContractEventContext eventContext, ContractException error) {
public void postEvent(ContractEventContext eventContext, Exception error) {
this.eventContext = null; this.eventContext = null;
} }

@Override
public void postEvent(ContractException error) {

}

@Override
public void postEvent() {

}
} }

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

@@ -8,12 +8,39 @@
*/ */
package test.com.jd.blockchain.intgr; package test.com.jd.blockchain.intgr;


import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;

import com.jd.blockchain.binaryproto.DataContractRegistry; import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.crypto.AddressEncoding; import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.ledger.core.LedgerManage;
import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.KVDataEntry;
import com.jd.blockchain.ledger.LedgerBlock;
import com.jd.blockchain.ledger.LedgerInitOperation;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionState;
import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.ledger.UserRegisterOperation;
import com.jd.blockchain.ledger.core.LedgerRepository; import com.jd.blockchain.ledger.core.LedgerRepository;
import com.jd.blockchain.ledger.core.impl.LedgerManager; import com.jd.blockchain.ledger.core.impl.LedgerManager;
import com.jd.blockchain.sdk.BlockchainService; import com.jd.blockchain.sdk.BlockchainService;
@@ -21,31 +48,9 @@ import com.jd.blockchain.storage.service.DbConnection;
import com.jd.blockchain.storage.service.DbConnectionFactory; import com.jd.blockchain.storage.service.DbConnectionFactory;
import com.jd.blockchain.tools.initializer.LedgerBindingConfig; import com.jd.blockchain.tools.initializer.LedgerBindingConfig;
import com.jd.blockchain.utils.Bytes; import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.codec.HexUtils;
import com.jd.blockchain.utils.concurrent.ThreadInvoker; import com.jd.blockchain.utils.concurrent.ThreadInvoker;
import com.jd.blockchain.utils.net.NetworkAddress; import com.jd.blockchain.utils.net.NetworkAddress;


import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.springframework.core.io.ClassPathResource;
import test.com.jd.blockchain.intgr.contract.AssetContract;
import test.com.jd.blockchain.intgr.contract.AssetContract2;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;

import static org.junit.Assert.*;

/** /**
* *
* @author shaozhuguang * @author shaozhuguang


+ 22
- 12
source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java View File

@@ -1,12 +1,32 @@
package test.com.jd.blockchain.intgr; package test.com.jd.blockchain.intgr;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;

import org.junit.Test;
import org.springframework.core.io.ClassPathResource;

import com.jd.blockchain.consensus.ConsensusProvider; import com.jd.blockchain.consensus.ConsensusProvider;
import com.jd.blockchain.consensus.ConsensusSettings; import com.jd.blockchain.consensus.ConsensusSettings;
import com.jd.blockchain.crypto.AsymmetricKeypair; import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.HashDigest; import com.jd.blockchain.crypto.HashDigest;
import com.jd.blockchain.crypto.PrivKey; import com.jd.blockchain.crypto.PrivKey;
import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig; import com.jd.blockchain.gateway.GatewayConfigProperties.KeyPairConfig;
import com.jd.blockchain.ledger.*;
import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import com.jd.blockchain.ledger.BlockchainKeypair;
import com.jd.blockchain.ledger.LedgerBlock;
import com.jd.blockchain.ledger.LedgerInfo;
import com.jd.blockchain.ledger.PreparedTransaction;
import com.jd.blockchain.ledger.TransactionResponse;
import com.jd.blockchain.ledger.TransactionTemplate;
import com.jd.blockchain.ledger.core.LedgerRepository; import com.jd.blockchain.ledger.core.LedgerRepository;
import com.jd.blockchain.sdk.BlockchainService; import com.jd.blockchain.sdk.BlockchainService;
import com.jd.blockchain.sdk.client.GatewayServiceFactory; import com.jd.blockchain.sdk.client.GatewayServiceFactory;
@@ -17,22 +37,12 @@ import com.jd.blockchain.tools.initializer.Prompter;
import com.jd.blockchain.tools.keygen.KeyGenCommand; import com.jd.blockchain.tools.keygen.KeyGenCommand;
import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback;
import com.jd.blockchain.utils.net.NetworkAddress; import com.jd.blockchain.utils.net.NetworkAddress;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;

import test.com.jd.blockchain.intgr.IntegratedContext.Node; import test.com.jd.blockchain.intgr.IntegratedContext.Node;
import test.com.jd.blockchain.intgr.contract.AssetContract; import test.com.jd.blockchain.intgr.contract.AssetContract;
import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest;
import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext; import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest.NodeWebContext;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;

import static org.junit.Assert.*;

/** /**
* 测试合约,提交后不立即进行验证,因为此时可能还没有完成正式结块; * 测试合约,提交后不立即进行验证,因为此时可能还没有完成正式结块;
*/ */


+ 1
- 10
source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java View File

@@ -65,17 +65,8 @@ public class AccountContractImpl implements EventProcessingAwire, AccountContrac
} }


@Override @Override
public void postEvent(ContractEventContext eventContext, ContractException error) {
public void postEvent(ContractEventContext eventContext, Exception error) {


} }


@Override
public void postEvent(ContractException error) {

}

@Override
public void postEvent() {

}
} }

+ 1
- 10
source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java View File

@@ -25,17 +25,8 @@ public class WriteContractImpl implements EventProcessingAwire, WriteContract {
} }


@Override @Override
public void postEvent(ContractEventContext eventContext, ContractException error) {
public void postEvent(ContractEventContext eventContext, Exception error) {
System.out.println("----- postEvent1 -----"); System.out.println("----- postEvent1 -----");
} }


@Override
public void postEvent(ContractException error) {
System.out.println("----- postEvent2 -----");
}

@Override
public void postEvent() {
System.out.println("----- postEvent3 -----");
}
} }

+ 2
- 2
source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java View File

@@ -52,9 +52,9 @@ public class MockerContractExeHandle implements OperationHandle {
executorProxy.invoke(); executorProxy.invoke();


// After处理过程 // After处理过程
eventProcessingAwire.postEvent();
eventProcessingAwire.postEvent(contractEventContext, null);
} catch (Exception e) { } catch (Exception e) {
eventProcessingAwire.postEvent(new ContractException(e.getMessage()));
eventProcessingAwire.postEvent(contractEventContext, new ContractException(e.getMessage()));
} finally { } finally {
removeExecutorProxy(txHash); removeExecutorProxy(txHash);
} }


Loading…
Cancel
Save