diff --git a/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractCode.java b/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractCode.java index 94ded100..fc7bc64e 100644 --- a/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractCode.java +++ b/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractCode.java @@ -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 execReturn); + byte[] processEvent(ContractEventContext eventContext); } diff --git a/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java b/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java index 2e81c7f8..8567c13e 100644 --- a/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java +++ b/source/contract/contract-framework/src/main/java/com/jd/blockchain/contract/engine/ContractEngine.java @@ -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); } diff --git a/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JavaContractCode.java b/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JavaContractCode.java index a8036121..5686b6b9 100644 --- a/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JavaContractCode.java +++ b/source/contract/contract-jvm/src/main/java/com/jd/blockchain/contract/jvm/JavaContractCode.java @@ -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 execReturn) { - this.contractEventContext = eventContext; - codeModule.execute(new ContractExecution(execReturn)); - } - - private Object resolveArgs(byte[] args, List 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 { - private CompletableFuture contractReturn; + private ContractEventContext eventContext; - public ContractExecution(CompletableFuture 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!"); } } diff --git a/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java b/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java index b32e8d37..5bb18b36 100644 --- a/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java +++ b/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java @@ -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) { } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java index ec0504e4..a1742499 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/DefaultOperationHandleRegisteration.java @@ -21,18 +21,7 @@ import com.jd.blockchain.ledger.core.impl.handles.UserRegisterOperationHandle; public class DefaultOperationHandleRegisteration implements OperationHandleRegisteration { private List 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() + "]!"); } - - + } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java index 03342459..aab23e21 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractEventSendOperationHandle.java @@ -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 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); } } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java new file mode 100644 index 00000000..0f081af9 --- /dev/null +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingHandle.java @@ -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 contractInstances = new ConcurrentHashMap(); +// +// @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 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); +// } +// +//} diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java new file mode 100644 index 00000000..08d9f381 --- /dev/null +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/ContractInvokingTest.java @@ -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; + } +} diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java index 82369888..3a631ad3 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTestUtils.java @@ -96,6 +96,7 @@ public class LedgerTestUtils { if (gatewayKeypair != null) { txReqBuilder.signAsNode(gatewayKeypair); } + return txReqBuilder.buildRequest(); } diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TestContract.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TestContract.java new file mode 100644 index 00000000..ed56f49f --- /dev/null +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TestContract.java @@ -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); +} diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java index e18ca2a0..72c8a848 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionBatchProcessorTest.java @@ -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); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractException.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractException.java index 61ba347a..725d878a 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractException.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/ContractException.java @@ -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); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventProcessingAwire.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventProcessingAwire.java index 36080be1..e6e07ebb 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventProcessingAwire.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/contract/EventProcessingAwire.java @@ -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(); } diff --git a/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java b/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java index e2c064cd..885d9aac 100644 --- a/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java +++ b/source/runtime/runtime-context/src/main/java/com/jd/blockchain/runtime/Module.java @@ -10,7 +10,7 @@ public interface Module { String getName(); Class loadClass(String className); - + InputStream loadResourceAsStream(String name); String getMainClass(); diff --git a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java index 770f78c4..272a55a2 100644 --- a/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java +++ b/source/sdk/sdk-samples/src/main/java/com/jd/blockchain/contract/samples/AssetContractImpl.java @@ -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() { - - } } diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java index aaa67038..25360ebe 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java @@ -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 diff --git a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java index 1da5341b..f1f5288c 100644 --- a/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java +++ b/source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationTest2.java @@ -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.*; - /** * 测试合约,提交后不立即进行验证,因为此时可能还没有完成正式结块; */ diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java index 5813849b..421cc919 100644 --- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java +++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/AccountContractImpl.java @@ -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() { - - } } diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java index 48874420..3fdedc81 100644 --- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java +++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/contracts/WriteContractImpl.java @@ -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 -----"); - } } diff --git a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java index 23dbaa7a..0e9364fa 100644 --- a/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java +++ b/source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/handler/MockerContractExeHandle.java @@ -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); }