From 3e5cdcd5349f602039cf044b3a83ad384598c5b4 Mon Sep 17 00:00:00 2001 From: shaozhuguang Date: Tue, 11 Jun 2019 10:57:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=88=E7=BA=A6=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E5=80=BC=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jd/blockchain/consts/DataCodes.java | 4 ++ .../jd/blockchain/contract/ReadContract.java | 3 ++ .../blockchain/contract/ReadContractImpl.java | 16 ++++++- .../gateway/web/BlockBrowserController.java | 2 +- .../ledger/core/LedgerTransactionContext.java | 9 ++-- .../core/impl/LedgerTransactionData.java | 16 ++++--- .../core/impl/LedgerTransactionalEditor.java | 8 ++-- .../core/impl/TransactionBatchProcessor.java | 30 +++++++------ .../blockchain/ledger/LedgerEditerTest.java | 4 +- .../blockchain/ledger/LedgerManagerTest.java | 4 +- .../ledger/LedgerTransactionDataTest.java | 2 +- .../blockchain/ledger/TransactionSetTest.java | 2 +- .../ledger/ContractReturnMessage.java | 17 ++++++++ .../ledger/ContractReturnMessageData.java | 41 ++++++++++++++++++ .../com/jd/blockchain/ledger/Transaction.java | 7 +++ .../ledger/TransactionReturnMessage.java | 17 ++++++++ .../ledger/TransactionReturnMessageData.java | 26 +++++++++++ .../jd/blockchain/intgr/IntegrationBase.java | 8 +++- .../src/test/resources/contract-read.jar | Bin 3924 -> 4077 bytes .../web/LedgerInitializeWebController.java | 2 +- .../mocker/MockerLedgerInitializer.java | 2 +- 21 files changed, 181 insertions(+), 39 deletions(-) create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessage.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessageData.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessage.java create mode 100644 source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessageData.java diff --git a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java index 48cffbc7..577dd433 100644 --- a/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java +++ b/source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java @@ -30,6 +30,8 @@ public interface DataCodes { public static final int TX_CONTENT_BODY = 0x220; + public static final int TX_RETURN_MESSAGE = 0x230; + public static final int TX_OP = 0x300; public static final int TX_OP_LEDGER_INIT = 0x301; @@ -92,6 +94,8 @@ public interface DataCodes { public static final int CONTRACT_BIZ_CONTENT = 0xA20; public static final int CONTRACT_ARGS = 0xA21; + public static final int CONTRACT_RETURN = 0xA22; + public static final int HASH = 0xB00; public static final int HASH_OBJECT = 0xB10; diff --git a/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContract.java b/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContract.java index 1f82491f..8f97fb10 100644 --- a/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContract.java +++ b/source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContract.java @@ -6,5 +6,8 @@ public interface ReadContract { @ContractEvent(name = "read-key") String read(String address, String key); + + @ContractEvent(name = "version-key") + Long readVersion(String address, String key); } 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 65310b6e..b32e8d37 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 @@ -8,9 +8,12 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract { private ContractEventContext eventContext; + private HashDigest ledgerHash; + @Override public void beforeEvent(ContractEventContext eventContext) { this.eventContext = eventContext; + this.ledgerHash = eventContext.getCurrentLedgerHash(); } @Override @@ -31,8 +34,6 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract { @Override @ContractEvent(name = "read-key") public String read(String address, String key) { - HashDigest ledgerHash = eventContext.getCurrentLedgerHash(); - KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); if (kvDataEntries != null && kvDataEntries.length == 1) { @@ -40,4 +41,15 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract { } return null; } + + @Override + @ContractEvent(name = "version-key") + public Long readVersion(String address, String key) { + KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); + + if (kvDataEntries != null && kvDataEntries.length == 1) { + return kvDataEntries[0].getVersion(); + } + return -1L; + } } diff --git a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java index 66f94b97..9b41bcc0 100644 --- a/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java +++ b/source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java @@ -55,7 +55,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService { // @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/participants") @Override - public ParticipantNode[] getConsensusParticipants(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) { + public ParticipantNode[] getConsensusParticipants(HashDigest ledgerHash) { return peerService.getQueryService().getConsensusParticipants(ledgerHash); } diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java index 9b653ce8..c7be08e5 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java @@ -1,5 +1,6 @@ package com.jd.blockchain.ledger.core; +import com.jd.blockchain.ledger.TransactionReturnMessage; import com.jd.blockchain.ledger.TransactionState; import com.jd.blockchain.ledger.LedgerTransaction; import com.jd.blockchain.ledger.TransactionRequest; @@ -30,19 +31,21 @@ public interface LedgerTransactionContext { * 提交对账本数据的修改,以指定的交易状态提交交易; * * @param txResult + * @param returnMessage + * * @return */ - LedgerTransaction commit(TransactionState txResult); + LedgerTransaction commit(TransactionState txResult, TransactionReturnMessage returnMessage); /** * 抛弃对账本数据的修改,以指定的交易状态提交交易;
* - * 通常来说,当在开启事务之后,修改账本或者尝试提交交易({@link #commit(TransactionState)})时发生错误,都应该抛弃数据,通过此方法记录一个表示错误状态的交易; + * 通常来说,当在开启事务之后,修改账本或者尝试提交交易({@link #commit(TransactionState, TransactionReturnMessage)})时发生错误,都应该抛弃数据,通过此方法记录一个表示错误状态的交易; * * @param txResult * @return */ - LedgerTransaction discardAndCommit(TransactionState txResult); + LedgerTransaction discardAndCommit(TransactionState txResult, TransactionReturnMessage returnMessage); /** * 回滚事务,抛弃本次事务的所有数据更新; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java index 349e3040..a7c3d480 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java @@ -1,11 +1,7 @@ package com.jd.blockchain.ledger.core.impl; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.DigitalSignature; -import com.jd.blockchain.ledger.LedgerTransaction; -import com.jd.blockchain.ledger.TransactionContent; -import com.jd.blockchain.ledger.TransactionRequest; -import com.jd.blockchain.ledger.TransactionState; +import com.jd.blockchain.ledger.*; public class LedgerTransactionData implements LedgerTransaction { @@ -23,6 +19,8 @@ public class LedgerTransactionData implements LedgerTransaction { private long blockHeight; + private TransactionReturnMessage returnMessage; + // private HashDigest adminAccountHash; // // private HashDigest userAccountSetHash; @@ -49,7 +47,7 @@ public class LedgerTransactionData implements LedgerTransaction { * 交易级的系统快照; */ public LedgerTransactionData(long blockHeight, TransactionRequest txReq, TransactionState execState, - TransactionStagedSnapshot txSnapshot) { + TransactionStagedSnapshot txSnapshot, TransactionReturnMessage returnMessage) { this.blockHeight = blockHeight; // this.txSnapshot = txSnapshot == null ? new TransactionStagedSnapshot() : txSnapshot; this.txSnapshot = txSnapshot; @@ -57,6 +55,7 @@ public class LedgerTransactionData implements LedgerTransaction { this.endpointSignatures = txReq.getEndpointSignatures(); this.nodeSignatures = txReq.getNodeSignatures(); this.executionState = execState; + this.returnMessage = returnMessage; } @Override @@ -74,6 +73,11 @@ public class LedgerTransactionData implements LedgerTransaction { return executionState; } + @Override + public TransactionReturnMessage getReturnMessage() { + return returnMessage; + } + @Override public TransactionContent getTransactionContent() { return this.transactionContent; diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java index 5bb29512..deec6200 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java @@ -350,7 +350,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { } @Override - public LedgerTransaction commit(TransactionState txResult) { + public LedgerTransaction commit(TransactionState txResult, TransactionReturnMessage returnMessage) { checkTxState(); // capture snapshot @@ -359,7 +359,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { // LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, // txResult, txDataSnapshot); - LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, txResult, null); + LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, txResult, null, returnMessage); this.txset.add(tx); // this.txset.commit(); @@ -376,7 +376,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { } @Override - public LedgerTransaction discardAndCommit(TransactionState txResult) { + public LedgerTransaction discardAndCommit(TransactionState txResult, TransactionReturnMessage returnMessage) { checkTxState(); // 未处理 @@ -385,7 +385,7 @@ public class LedgerTransactionalEditor implements LedgerEditor { // TransactionStagedSnapshot txDataSnapshot = takeSnapshot(); // LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, // txResult, txDataSnapshot); - LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, txResult, null); + LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, txResult, null, returnMessage); this.txset.add(tx); // this.txset.commit(); diff --git a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java index 0e58fba7..ce2af7df 100644 --- a/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java +++ b/source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java @@ -5,16 +5,12 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.CompletableFuture; +import com.jd.blockchain.ledger.*; import com.jd.blockchain.ledger.core.impl.handles.ContractEventSendOperationHandle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.ledger.LedgerBlock; -import com.jd.blockchain.ledger.Operation; -import com.jd.blockchain.ledger.TransactionRequest; -import com.jd.blockchain.ledger.TransactionResponse; -import com.jd.blockchain.ledger.TransactionState; import com.jd.blockchain.ledger.core.LedgerDataSet; import com.jd.blockchain.ledger.core.LedgerEditor; import com.jd.blockchain.ledger.core.LedgerException; @@ -76,7 +72,8 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { // 此调用将会验证交易签名,验签失败将会抛出异常,同时,不记录签名错误的交易到链上; LedgerTransactionContext txCtx = newBlockEditor.newTransaction(request); TransactionState result; - List> contractReturn = new ArrayList<>(); + TransactionReturnMessageData returnMessageData = new TransactionReturnMessageData(); + try { LedgerDataSet dataset = txCtx.getDataSet(); TransactionRequestContext reqCtx = new TransactionRequestContextImpl(request); @@ -103,12 +100,14 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { } }; OperationHandle opHandle; + int contractOpIndex = 0; for (Operation op : ops) { opHandle = opHandles.getHandle(op.getClass()); // 合约执行需要填充执行结果 if (opHandle instanceof ContractEventSendOperationHandle) { CompletableFuture currContractReturn = new CompletableFuture<>(); - contractReturn.add(currContractReturn); + ContractReturnMessageData crmd = new ContractReturnMessageData(contractOpIndex++, currContractReturn); + returnMessageData.addContractReturnMessage(crmd); ((ContractEventSendOperationHandle) opHandle).process(op, dataset, reqCtx, previousBlockDataset, handleContext, ledgerService, currContractReturn); } else { opHandle.process(op, dataset, reqCtx, previousBlockDataset, handleContext, ledgerService); @@ -117,27 +116,30 @@ public class TransactionBatchProcessor implements TransactionBatchProcess { // 提交交易(事务); result = TransactionState.SUCCESS; - txCtx.commit(result); + txCtx.commit(result, returnMessageData); } catch (LedgerException e) { // TODO: 识别更详细的异常类型以及执行对应的处理; result = TransactionState.LEDGER_ERROR; - txCtx.discardAndCommit(TransactionState.LEDGER_ERROR); + txCtx.discardAndCommit(TransactionState.LEDGER_ERROR, returnMessageData); LOGGER.warn(String.format("Transaction rollback caused by the ledger exception! --[TxHash=%s] --%s", request.getHash().toBase58(), e.getMessage()), e); } catch (Exception e) { result = TransactionState.SYSTEM_ERROR; - txCtx.discardAndCommit(TransactionState.SYSTEM_ERROR); + txCtx.discardAndCommit(TransactionState.SYSTEM_ERROR, returnMessageData); LOGGER.warn(String.format("Transaction rollback caused by the system exception! --[TxHash=%s] --%s", request.getHash().toBase58(), e.getMessage()), e); } TxResponseHandle resp = new TxResponseHandle(request, result); - if (!contractReturn.isEmpty()) { + if (!returnMessageData.isContractReturnEmpty()) { + + ContractReturnMessage[] contractReturnMessages = returnMessageData.getContractReturn(); + // 获取结果中的字符串 - String[] returnValue = new String[contractReturn.size()]; + String[] returnValue = new String[contractReturnMessages.length]; try { - for (int i = 0; i < contractReturn.size(); i++) { - returnValue[i] = contractReturn.get(i).get(); + for (int i = 0; i < contractReturnMessages.length; i++) { + returnValue[i] = contractReturnMessages[i].getReturnMessage(); } resp.setContractReturn(returnValue); } catch (Exception e) { diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java index 3ae78c32..08f6d134 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java @@ -76,7 +76,7 @@ public class LedgerEditerTest { dataAccount.setBytes(Bytes.fromString("A"), "abc".getBytes(), -1); - LedgerTransaction tx = txCtx.commit(TransactionState.SUCCESS); + LedgerTransaction tx = txCtx.commit(TransactionState.SUCCESS, null); LedgerBlock block = ldgEdt.prepare(); // 提交数据,写入存储; ldgEdt.commit(); @@ -96,7 +96,7 @@ public class LedgerEditerTest { userAccount.setProperty("Name", "孙悟空", -1); userAccount.setProperty("Age", "10000", -1); - LedgerTransaction tx = txCtx.commit(TransactionState.SUCCESS); + LedgerTransaction tx = txCtx.commit(TransactionState.SUCCESS, null); assertEquals(genesisTxReq.getTransactionContent().getHash(), tx.getTransactionContent().getHash()); assertEquals(0, tx.getBlockHeight()); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java index cdbece82..f8297824 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java @@ -97,7 +97,7 @@ public class LedgerManagerTest { System.out.println("UserAddress=" + userAccount.getAddress()); // 提交交易结果; - LedgerTransaction tx = txCtx.commit(TransactionState.SUCCESS); + LedgerTransaction tx = txCtx.commit(TransactionState.SUCCESS, null); assertEquals(genesisTxReq.getTransactionContent().getHash(), tx.getTransactionContent().getHash()); assertEquals(0, tx.getBlockHeight()); @@ -137,7 +137,7 @@ public class LedgerManagerTest { LedgerTransactionContext txCtx1 = editor1.newTransaction(txRequest); txCtx1.getDataSet().getDataAccountSet().register(dataKey.getAddress(), dataKey.getPubKey(), null); - txCtx1.commit(TransactionState.SUCCESS); + txCtx1.commit(TransactionState.SUCCESS, null); LedgerBlock block1 = editor1.prepare(); editor1.commit(); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java index ba533a4a..e64a26a1 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java @@ -68,7 +68,7 @@ public class LedgerTransactionDataTest { long blockHeight = 9986L; data = new LedgerTransactionData(blockHeight, txRequestMessage, TransactionState.SUCCESS, - initTransactionStagedSnapshot()); + initTransactionStagedSnapshot(), null); HashDigest hash = new HashDigest(ClassicAlgorithm.SHA256, "zhangsan".getBytes()); HashDigest adminAccountHash = new HashDigest(ClassicAlgorithm.SHA256, "lisi".getBytes()); diff --git a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java index 41a9d3b5..85c5f277 100644 --- a/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java +++ b/source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java @@ -98,7 +98,7 @@ public class TransactionSetTest { txSnapshot.setContractAccountSetHash(contractAccountSetHash); long blockHeight = 8922L; - LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txReq, TransactionState.SUCCESS, txSnapshot); + LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txReq, TransactionState.SUCCESS, txSnapshot, null); txset.add(tx); assertTrue(txset.isUpdated()); diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessage.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessage.java new file mode 100644 index 00000000..3556c95c --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessage.java @@ -0,0 +1,17 @@ +package com.jd.blockchain.ledger; + +import com.jd.blockchain.binaryproto.DataContract; +import com.jd.blockchain.binaryproto.DataField; +import com.jd.blockchain.binaryproto.PrimitiveType; +import com.jd.blockchain.consts.DataCodes; + +@DataContract(code= DataCodes.CONTRACT_RETURN) +public interface ContractReturnMessage { + + @DataField(order=1, primitiveType = PrimitiveType.INT32) + int getOperationIndex(); + + @DataField(order=2, primitiveType = PrimitiveType.TEXT) + String getReturnMessage(); + +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessageData.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessageData.java new file mode 100644 index 00000000..70282725 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessageData.java @@ -0,0 +1,41 @@ +package com.jd.blockchain.ledger; + +import java.util.concurrent.CompletableFuture; + +public class ContractReturnMessageData implements ContractReturnMessage { + + private int operationIndex; + + private CompletableFuture returnMsgFuture; + + public ContractReturnMessageData() { + } + + public ContractReturnMessageData(int operationIndex, CompletableFuture returnMsgFuture) { + this.operationIndex = operationIndex; + this.returnMsgFuture = returnMsgFuture; + } + + public void setOperationIndex(int operationIndex) { + this.operationIndex = operationIndex; + } + + public void setReturnMsgFuture(CompletableFuture returnMsgFuture) { + this.returnMsgFuture = returnMsgFuture; + } + + @Override + public int getOperationIndex() { + return operationIndex; + } + + @Override + public String getReturnMessage() { + try { + return returnMsgFuture.get(); + } catch (Exception e) { + e.printStackTrace(); + throw new IllegalStateException(e); + } + } +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Transaction.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Transaction.java index a2442521..402024e2 100644 --- a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Transaction.java +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Transaction.java @@ -45,4 +45,11 @@ public interface Transaction extends NodeRequest, HashObject { @DataField(order=3, refEnum=true) TransactionState getExecutionState(); + /** + * 交易的返回结果 + * + * @return + */ + @DataField(order=4, refContract=true) + TransactionReturnMessage getReturnMessage(); } diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessage.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessage.java new file mode 100644 index 00000000..2d2fbfc7 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessage.java @@ -0,0 +1,17 @@ +package com.jd.blockchain.ledger; + +import com.jd.blockchain.binaryproto.DataContract; +import com.jd.blockchain.binaryproto.DataField; +import com.jd.blockchain.consts.DataCodes; + +@DataContract(code= DataCodes.TX_RETURN_MESSAGE) +public interface TransactionReturnMessage { + + /** + * 合约返回值列表 + * + * @return + */ + @DataField(order=1, list = true, refContract=true) + ContractReturnMessage[] getContractReturn(); +} diff --git a/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessageData.java b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessageData.java new file mode 100644 index 00000000..646b7090 --- /dev/null +++ b/source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessageData.java @@ -0,0 +1,26 @@ +package com.jd.blockchain.ledger; + +import java.util.ArrayList; +import java.util.List; + +public class TransactionReturnMessageData implements TransactionReturnMessage { + + private List contractReturnMessages = new ArrayList<>(); + + public void addContractReturnMessage(ContractReturnMessage contractReturnMessage) { + contractReturnMessages.add(contractReturnMessage); + } + + public boolean isContractReturnEmpty() { + return contractReturnMessages.isEmpty(); + } + + @Override + public ContractReturnMessage[] getContractReturn() { + if (isContractReturnEmpty()) { + return null; + } + ContractReturnMessage[] crms = new ContractReturnMessage[contractReturnMessages.size()]; + return contractReturnMessages.toArray(crms); + } +} 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 a06cc1e5..ba027f3d 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 @@ -577,6 +577,9 @@ public class IntegrationBase { ReadContract readContract2 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class); readContract2.read(newDataAccount.getAddress().toBase58(), key2); + ReadContract readContract3 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class); + readContract3.readVersion(newDataAccount.getAddress().toBase58(), key2); + // 签名; PreparedTransaction contractPtx = txContract.prepare(); contractPtx.sign(adminKey); @@ -593,13 +596,16 @@ public class IntegrationBase { // 验证结果 assertNotNull(contractReturn); - assertEquals(contractReturn.length, 2); + assertEquals(contractReturn.length, 3); String returnVal1 = contractReturn[0]; assertEquals(value1, returnVal1); String returnVal2 = contractReturn[1]; assertEquals(value2, returnVal2); + + String returnVal3 = contractReturn[2]; + assertEquals("0", returnVal3); } /** diff --git a/source/test/test-integration/src/test/resources/contract-read.jar b/source/test/test-integration/src/test/resources/contract-read.jar index 38f81951da1fa98c3b3fe1a08f47642ea9afc7cb..ddf9c66802c4fa96d6bad111a772ab2165168bfb 100644 GIT binary patch delta 1637 zcmYM#eKga190%|{cqrSvFmUhQF1k3PbR=XhE2 z8hSgIe!wH;h9u8{DHt{?xM*BO4E%8_qqWAR^-E5O=b)Y>jXO!xG_=ymZoZXWJ-V@_ zX}>piT86HixqrWHD-|7HQH<8svJIncEOav{j3_8&DC2`L6t^n|Mtib~_T!C)l&n~7 zOiYMS)>inZiojmsEp!J}d6lAU-ef%#0?~y*AYkd&Kvu2HmFo4uU04Nl=5dLu+UaNX zqF3}`vX3)$bE;TcYZDPv`=a>1!p6V0K12LLyws??x53scvWxJvztIr8lRmmd z>*={yvVBwO43DW`R;0A4)p6Ok{T2!LB*Ac)n9?j6iv65BF{`QC!Z{n&-=A`RU&Y>~ z8x420OG^7n$|o}O7t=U6?rwH8$G>#w^li&U?OZnWl{>0qXIgW;--u5z`Q(5(Y7FOM z&fi4zI9b-LU8L9|4=7K(D)D^~!=WEWJ<{5zWt@K2G5%Jo_sD+ z8T}2@QrEJ;sviwo@7g3SUME@a++Rli;wiY9=(;d=KC?tGDgsq&d#G5;Y`Vs~8!CJNt1>lT-j{Fcj z-EQtbLTd<>+^3J%)rEX&1>*ey$Tli_L`K(D;tx&#u*C1$-NUMOJ+S|;Y+c@Jwf8N zw3_P{fq)}!e9I&1yXH->yrz@u;60M#6;h^Hyg=oH~?UG<$96mirlGWk7WA+Q%ZZb#uL`u^KbkX^kkwz@ajS1xvl}xd@8F z_ZV~^BQp6_=-~D#IccN;y*=PV7h!7jkJU5S_~5U)q5ITXM{^wU(FTQ{7k7$TGkHmC z1I_qOxs{if;d2xIVl+^aauw@M{E^W^w2SK_B#G*^sHr%D+=k>)f0~Pnvp#P!-4SHA z*U&?yXUR?Mg?UCQrzQVP%gBh`c$}E8K7XeNi+Ay}7~nnJzDvpar&hz_!A=gwB~Rw> znmJYo2)16Fa^2#RJXHLN?z>sPF6#f~zwEBR_ujm*tVXy&bs8?+5B3iJvL_U)0D(lR zR6kbkfq^|YOJx9N2XMm>mMe{$dmZ5fhBAaX2o`Ap;(>Gk0g&z>y+}I{Rg@1%5Q?En z0iMu)btP^W%10lJemw?(5dZxj{@aR^N8#KI*kkqbU8{r~C zgt7}ogeWEqx474m>sNpDzUO^E=REIo&U?=D$9Gk1OcZHKfU{baf4BM-)X%gPiEb78^)+LQEagyx<#nglc)k>qkya9y{GWvm?tND)uj%DM6SW9=D;lw0AhoLNEvf%vJydKir4o z*@WUK_bz)`Oz8_~dm&^fhRh(DD{tX80qoG*num=7~*u|hUfrOwuqg@d0jYBmq3 zkhQ0Z^m;|ytmk_}ulDeDvTzfDZf1G9>C11|2AAupBW`YVXPtEIcudkb=hGh)j;ru#+qg@Z5j3J0 z%%?N|r6!p%%kjixtZ`nE#T|zpCj*0JLR{=5s>o;=PCE(z=5gwbJGl#sYn2uzN)&85=FWxk5&xbwYpoF(pDu$39ZOkT zs|o0uNNkXUQJT31&5epHyluV4JnY*UxU;4536 zqT^vlNRG