@@ -3,14 +3,11 @@ package com.jd.blockchain.contract.engine; | |||
import com.jd.blockchain.contract.ContractEventContext; | |||
import com.jd.blockchain.utils.Bytes; | |||
import java.util.concurrent.CompletableFuture; | |||
import java.util.concurrent.Future; | |||
public interface ContractCode { | |||
Bytes getAddress(); | |||
long getVersion(); | |||
void processEvent(ContractEventContext eventContext, CompletableFuture<String> execReturn); | |||
byte[] processEvent(ContractEventContext eventContext); | |||
} |
@@ -1,6 +1,5 @@ | |||
package com.jd.blockchain.contract.engine; | |||
import com.jd.blockchain.ledger.BytesValue; | |||
import com.jd.blockchain.utils.Bytes; | |||
/** | |||
@@ -27,9 +26,9 @@ public interface ContractEngine { | |||
* 如果已经存在,则直接返回已有实例; | |||
* | |||
* @param address | |||
* @param code | |||
* @param codeBytes | |||
* @return | |||
*/ | |||
ContractCode setupContract(Bytes address, long version, byte[] code); | |||
ContractCode setupContract(Bytes address, long version, byte[] codeBytes); | |||
} |
@@ -1,21 +1,19 @@ | |||
package com.jd.blockchain.contract.jvm; | |||
import java.lang.reflect.Method; | |||
import java.util.List; | |||
import java.util.concurrent.Callable; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.util.ReflectionUtils; | |||
import com.jd.blockchain.binaryproto.DataContract; | |||
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.runtime.Module; | |||
import com.jd.blockchain.transaction.ContractType; | |||
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 | |||
@@ -27,14 +25,22 @@ public class JavaContractCode implements ContractCode { | |||
private Module codeModule; | |||
private Bytes address; | |||
private long version; | |||
private ContractEventContext contractEventContext; | |||
private Class<?> contractClass; | |||
private ContractType contractType; | |||
public JavaContractCode(Bytes address, long version, Module codeModule) { | |||
this.address = address; | |||
this.version = version; | |||
this.codeModule = codeModule; | |||
init(); | |||
} | |||
private void init() { | |||
String contractClassName = codeModule.getMainClass(); | |||
this.contractClass = codeModule.loadClass(contractClassName); | |||
this.contractType = ContractType.resolve(contractClass); | |||
} | |||
@Override | |||
@@ -48,89 +54,77 @@ public class JavaContractCode implements ContractCode { | |||
} | |||
@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 { | |||
// 执行预处理; | |||
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!"); | |||
} | |||
} | |||
@@ -17,17 +17,7 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract { | |||
} | |||
@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) { | |||
} | |||
@@ -21,18 +21,7 @@ import com.jd.blockchain.ledger.core.impl.handles.UserRegisterOperationHandle; | |||
public class DefaultOperationHandleRegisteration implements OperationHandleRegisteration { | |||
private List<OperationHandle> opHandles = new ArrayList<>(); | |||
// private UserRegisterOperationHandle userRegHandle; | |||
// | |||
// private DataAccountRegisterOperationHandle dataAccRegHandle; | |||
// | |||
// private DataAccountKVSetOperationHandle dataAccKVSetHandle; | |||
// | |||
// private ContractCodeDeployOperationHandle contractDplHandle; | |||
// | |||
// private ContractEventSendOperationHandle contractEvtSendHandle; | |||
public DefaultOperationHandleRegisteration() { | |||
initDefaultHandles(); | |||
} | |||
@@ -40,25 +29,30 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis | |||
/** | |||
* 针对不采用bean依赖注入的方式来处理; | |||
*/ | |||
private void initDefaultHandles(){ | |||
private void initDefaultHandles() { | |||
opHandles.add(new DataAccountKVSetOperationHandle()); | |||
opHandles.add(new DataAccountRegisterOperationHandle()); | |||
opHandles.add(new UserRegisterOperationHandle()); | |||
opHandles.add(new ContractCodeDeployOperationHandle()); | |||
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 | |||
public OperationHandle getHandle(Class<?> operationType) { | |||
@@ -69,6 +63,5 @@ public class DefaultOperationHandleRegisteration implements OperationHandleRegis | |||
} | |||
throw new LedgerException("Unsupported operation type[" + operationType.getName() + "]!"); | |||
} | |||
} |
@@ -31,24 +31,14 @@ public class ContractEventSendOperationHandle implements OperationHandle { | |||
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 | |||
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) { | |||
@Override | |||
public byte[] process(Operation op, LedgerDataSet dataset, TransactionRequestContext requestContext, | |||
LedgerDataSet previousBlockDataset, OperationHandleContext opHandleContext, LedgerService ledgerService) { | |||
ContractEventSendOperation contractOP = (ContractEventSendOperation) op; | |||
// 先从账本校验合约的有效性; | |||
// 注意:必须在前一个区块的数据集中进行校验,因为那是经过共识的数据;从当前新区块链数据集校验则会带来攻击风险:未经共识的合约得到执行; | |||
@@ -83,7 +73,7 @@ public class ContractEventSendOperationHandle implements OperationHandle { | |||
} | |||
// 处理合约事件; | |||
contractCode.processEvent(localContractEventContext, contractReturn); | |||
return contractCode.processEvent(localContractEventContext); | |||
} | |||
} |
@@ -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); | |||
// } | |||
// | |||
//} |
@@ -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; | |||
} | |||
} |
@@ -96,6 +96,7 @@ public class LedgerTestUtils { | |||
if (gatewayKeypair != null) { | |||
txReqBuilder.signAsNode(gatewayKeypair); | |||
} | |||
return txReqBuilder.buildRequest(); | |||
} | |||
@@ -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); | |||
} |
@@ -57,10 +57,10 @@ public class TransactionBatchProcessorTest { | |||
private TransactionRequest transactionRequest; | |||
// 采用基于内存的 Storage; | |||
MemoryKVStorage storage = new MemoryKVStorage(); | |||
private MemoryKVStorage storage = new MemoryKVStorage(); | |||
@Test | |||
public void testContractOperations() { | |||
public void testTxReqProcess() { | |||
// 初始化账本到指定的存储库; | |||
ledgerHash = initLedger(storage, parti0, parti1, parti2, parti3); | |||
@@ -2,6 +2,8 @@ package com.jd.blockchain.contract; | |||
public class ContractException extends RuntimeException { | |||
private static final long serialVersionUID = 4338023105616639257L; | |||
public ContractException(String message) { | |||
super(message); | |||
} | |||
@@ -21,19 +21,6 @@ public interface EventProcessingAwire extends ContractRuntimeAwire { | |||
* @param error | |||
* 错误;如果事件处理正常结束,则此参数为 null;如果事件处理发生了错误,此参数非空; | |||
*/ | |||
void postEvent(ContractEventContext eventContext, ContractException error); | |||
void postEvent(ContractEventContext eventContext, Exception error); | |||
/** | |||
* 在事件处理方法成功执行之后调用; | |||
* | |||
* @param error | |||
* 错误;如果事件处理正常结束,则此参数为 null;如果事件处理发生了错误,此参数非空; | |||
*/ | |||
void postEvent(ContractException error); | |||
/** | |||
* 在事件处理方法成功执行之后调用; | |||
*/ | |||
void postEvent(); | |||
} |
@@ -10,7 +10,7 @@ public interface Module { | |||
String getName(); | |||
Class<?> loadClass(String className); | |||
InputStream loadResourceAsStream(String name); | |||
String getMainClass(); | |||
@@ -171,17 +171,7 @@ public class AssetContractImpl implements EventProcessingAwire, AssetContract { | |||
* com.jd.blockchain.contract.model.ContractError) | |||
*/ | |||
@Override | |||
public void postEvent(ContractEventContext eventContext, ContractException error) { | |||
public void postEvent(ContractEventContext eventContext, Exception error) { | |||
this.eventContext = null; | |||
} | |||
@Override | |||
public void postEvent(ContractException error) { | |||
} | |||
@Override | |||
public void postEvent() { | |||
} | |||
} |
@@ -8,12 +8,39 @@ | |||
*/ | |||
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.crypto.AddressEncoding; | |||
import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
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.impl.LedgerManager; | |||
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.tools.initializer.LedgerBindingConfig; | |||
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.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 | |||
@@ -1,12 +1,32 @@ | |||
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.ConsensusSettings; | |||
import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.PrivKey; | |||
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.sdk.BlockchainService; | |||
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.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
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.contract.AssetContract; | |||
import test.com.jd.blockchain.intgr.initializer.LedgerInitializeWeb4SingleStepsTest; | |||
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.*; | |||
/** | |||
* 测试合约,提交后不立即进行验证,因为此时可能还没有完成正式结块; | |||
*/ | |||
@@ -65,17 +65,8 @@ public class AccountContractImpl implements EventProcessingAwire, AccountContrac | |||
} | |||
@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() { | |||
} | |||
} |
@@ -25,17 +25,8 @@ public class WriteContractImpl implements EventProcessingAwire, WriteContract { | |||
} | |||
@Override | |||
public void postEvent(ContractEventContext eventContext, ContractException error) { | |||
public void postEvent(ContractEventContext eventContext, Exception error) { | |||
System.out.println("----- postEvent1 -----"); | |||
} | |||
@Override | |||
public void postEvent(ContractException error) { | |||
System.out.println("----- postEvent2 -----"); | |||
} | |||
@Override | |||
public void postEvent() { | |||
System.out.println("----- postEvent3 -----"); | |||
} | |||
} |
@@ -52,9 +52,9 @@ public class MockerContractExeHandle implements OperationHandle { | |||
executorProxy.invoke(); | |||
// After处理过程 | |||
eventProcessingAwire.postEvent(); | |||
eventProcessingAwire.postEvent(contractEventContext, null); | |||
} catch (Exception e) { | |||
eventProcessingAwire.postEvent(new ContractException(e.getMessage())); | |||
eventProcessingAwire.postEvent(contractEventContext, new ContractException(e.getMessage())); | |||
} finally { | |||
removeExecutorProxy(txHash); | |||
} | |||