Browse Source

增加合约返回值功能

tags/1.0.0
shaozhuguang 6 years ago
parent
commit
3e5cdcd534
21 changed files with 181 additions and 39 deletions
  1. +4
    -0
      source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java
  2. +3
    -0
      source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContract.java
  3. +14
    -2
      source/contract/contract-samples/src/main/java/com/jd/blockchain/contract/ReadContractImpl.java
  4. +1
    -1
      source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java
  5. +6
    -3
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java
  6. +10
    -6
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java
  7. +4
    -4
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionalEditor.java
  8. +16
    -14
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java
  9. +2
    -2
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerEditerTest.java
  10. +2
    -2
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerManagerTest.java
  11. +1
    -1
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/LedgerTransactionDataTest.java
  12. +1
    -1
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/TransactionSetTest.java
  13. +17
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessage.java
  14. +41
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/ContractReturnMessageData.java
  15. +7
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Transaction.java
  16. +17
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessage.java
  17. +26
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/TransactionReturnMessageData.java
  18. +7
    -1
      source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/IntegrationBase.java
  19. BIN
      source/test/test-integration/src/test/resources/contract-read.jar
  20. +1
    -1
      source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java
  21. +1
    -1
      source/tools/tools-mocker/src/main/java/com/jd/blockchain/mocker/MockerLedgerInitializer.java

+ 4
- 0
source/base/src/main/java/com/jd/blockchain/consts/DataCodes.java View File

@@ -30,6 +30,8 @@ public interface DataCodes {


public static final int TX_CONTENT_BODY = 0x220; 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 = 0x300;


public static final int TX_OP_LEDGER_INIT = 0x301; 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_BIZ_CONTENT = 0xA20;
public static final int CONTRACT_ARGS = 0xA21; 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 = 0xB00;


public static final int HASH_OBJECT = 0xB10; public static final int HASH_OBJECT = 0xB10;


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

@@ -6,5 +6,8 @@ public interface ReadContract {


@ContractEvent(name = "read-key") @ContractEvent(name = "read-key")
String read(String address, String key); String read(String address, String key);

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



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

@@ -8,9 +8,12 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract {


private ContractEventContext eventContext; private ContractEventContext eventContext;


private HashDigest ledgerHash;

@Override @Override
public void beforeEvent(ContractEventContext eventContext) { public void beforeEvent(ContractEventContext eventContext) {
this.eventContext = eventContext; this.eventContext = eventContext;
this.ledgerHash = eventContext.getCurrentLedgerHash();
} }


@Override @Override
@@ -31,8 +34,6 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract {
@Override @Override
@ContractEvent(name = "read-key") @ContractEvent(name = "read-key")
public String read(String address, String key) { public String read(String address, String key) {
HashDigest ledgerHash = eventContext.getCurrentLedgerHash();

KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key); KVDataEntry[] kvDataEntries = eventContext.getLedger().getDataEntries(ledgerHash, address, key);


if (kvDataEntries != null && kvDataEntries.length == 1) { if (kvDataEntries != null && kvDataEntries.length == 1) {
@@ -40,4 +41,15 @@ public class ReadContractImpl implements EventProcessingAwire, ReadContract {
} }
return null; 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;
}
} }

+ 1
- 1
source/gateway/src/main/java/com/jd/blockchain/gateway/web/BlockBrowserController.java View File

@@ -55,7 +55,7 @@ public class BlockBrowserController implements BlockchainExtendQueryService {


// @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/participants") // @RequestMapping(method = RequestMethod.GET, path = "ledgers/{ledgerHash}/participants")
@Override @Override
public ParticipantNode[] getConsensusParticipants(@PathVariable(name = "ledgerHash") HashDigest ledgerHash) {
public ParticipantNode[] getConsensusParticipants(HashDigest ledgerHash) {
return peerService.getQueryService().getConsensusParticipants(ledgerHash); return peerService.getQueryService().getConsensusParticipants(ledgerHash);
} }




+ 6
- 3
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerTransactionContext.java View File

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


import com.jd.blockchain.ledger.TransactionReturnMessage;
import com.jd.blockchain.ledger.TransactionState; import com.jd.blockchain.ledger.TransactionState;
import com.jd.blockchain.ledger.LedgerTransaction; import com.jd.blockchain.ledger.LedgerTransaction;
import com.jd.blockchain.ledger.TransactionRequest; import com.jd.blockchain.ledger.TransactionRequest;
@@ -30,19 +31,21 @@ public interface LedgerTransactionContext {
* 提交对账本数据的修改,以指定的交易状态提交交易; * 提交对账本数据的修改,以指定的交易状态提交交易;
* *
* @param txResult * @param txResult
* @param returnMessage
*
* @return * @return
*/ */
LedgerTransaction commit(TransactionState txResult);
LedgerTransaction commit(TransactionState txResult, TransactionReturnMessage returnMessage);


/** /**
* 抛弃对账本数据的修改,以指定的交易状态提交交易;<br> * 抛弃对账本数据的修改,以指定的交易状态提交交易;<br>
* *
* 通常来说,当在开启事务之后,修改账本或者尝试提交交易({@link #commit(TransactionState)})时发生错误,都应该抛弃数据,通过此方法记录一个表示错误状态的交易;
* 通常来说,当在开启事务之后,修改账本或者尝试提交交易({@link #commit(TransactionState, TransactionReturnMessage)})时发生错误,都应该抛弃数据,通过此方法记录一个表示错误状态的交易;
* *
* @param txResult * @param txResult
* @return * @return
*/ */
LedgerTransaction discardAndCommit(TransactionState txResult);
LedgerTransaction discardAndCommit(TransactionState txResult, TransactionReturnMessage returnMessage);


/** /**
* 回滚事务,抛弃本次事务的所有数据更新; * 回滚事务,抛弃本次事务的所有数据更新;


+ 10
- 6
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/LedgerTransactionData.java View File

@@ -1,11 +1,7 @@
package com.jd.blockchain.ledger.core.impl; package com.jd.blockchain.ledger.core.impl;


import com.jd.blockchain.crypto.HashDigest; 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 { public class LedgerTransactionData implements LedgerTransaction {


@@ -23,6 +19,8 @@ public class LedgerTransactionData implements LedgerTransaction {


private long blockHeight; private long blockHeight;


private TransactionReturnMessage returnMessage;

// private HashDigest adminAccountHash; // private HashDigest adminAccountHash;
// //
// private HashDigest userAccountSetHash; // private HashDigest userAccountSetHash;
@@ -49,7 +47,7 @@ public class LedgerTransactionData implements LedgerTransaction {
* 交易级的系统快照; * 交易级的系统快照;
*/ */
public LedgerTransactionData(long blockHeight, TransactionRequest txReq, TransactionState execState, public LedgerTransactionData(long blockHeight, TransactionRequest txReq, TransactionState execState,
TransactionStagedSnapshot txSnapshot) {
TransactionStagedSnapshot txSnapshot, TransactionReturnMessage returnMessage) {
this.blockHeight = blockHeight; this.blockHeight = blockHeight;
// this.txSnapshot = txSnapshot == null ? new TransactionStagedSnapshot() : txSnapshot; // this.txSnapshot = txSnapshot == null ? new TransactionStagedSnapshot() : txSnapshot;
this.txSnapshot = txSnapshot; this.txSnapshot = txSnapshot;
@@ -57,6 +55,7 @@ public class LedgerTransactionData implements LedgerTransaction {
this.endpointSignatures = txReq.getEndpointSignatures(); this.endpointSignatures = txReq.getEndpointSignatures();
this.nodeSignatures = txReq.getNodeSignatures(); this.nodeSignatures = txReq.getNodeSignatures();
this.executionState = execState; this.executionState = execState;
this.returnMessage = returnMessage;
} }


@Override @Override
@@ -74,6 +73,11 @@ public class LedgerTransactionData implements LedgerTransaction {
return executionState; return executionState;
} }


@Override
public TransactionReturnMessage getReturnMessage() {
return returnMessage;
}

@Override @Override
public TransactionContent getTransactionContent() { public TransactionContent getTransactionContent() {
return this.transactionContent; return this.transactionContent;


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

@@ -350,7 +350,7 @@ public class LedgerTransactionalEditor implements LedgerEditor {
} }


@Override @Override
public LedgerTransaction commit(TransactionState txResult) {
public LedgerTransaction commit(TransactionState txResult, TransactionReturnMessage returnMessage) {
checkTxState(); checkTxState();


// capture snapshot // capture snapshot
@@ -359,7 +359,7 @@ public class LedgerTransactionalEditor implements LedgerEditor {


// LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, // LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest,
// txResult, txDataSnapshot); // 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.add(tx);
// this.txset.commit(); // this.txset.commit();


@@ -376,7 +376,7 @@ public class LedgerTransactionalEditor implements LedgerEditor {
} }


@Override @Override
public LedgerTransaction discardAndCommit(TransactionState txResult) {
public LedgerTransaction discardAndCommit(TransactionState txResult, TransactionReturnMessage returnMessage) {
checkTxState(); checkTxState();


// 未处理 // 未处理
@@ -385,7 +385,7 @@ public class LedgerTransactionalEditor implements LedgerEditor {
// TransactionStagedSnapshot txDataSnapshot = takeSnapshot(); // TransactionStagedSnapshot txDataSnapshot = takeSnapshot();
// LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest, // LedgerTransactionData tx = new LedgerTransactionData(blockHeight, txRequest,
// txResult, txDataSnapshot); // 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.add(tx);
// this.txset.commit(); // this.txset.commit();




+ 16
- 14
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/TransactionBatchProcessor.java View File

@@ -5,16 +5,12 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;


import com.jd.blockchain.ledger.*;
import com.jd.blockchain.ledger.core.impl.handles.ContractEventSendOperationHandle; import com.jd.blockchain.ledger.core.impl.handles.ContractEventSendOperationHandle;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;


import com.jd.blockchain.crypto.HashDigest; 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.LedgerDataSet;
import com.jd.blockchain.ledger.core.LedgerEditor; import com.jd.blockchain.ledger.core.LedgerEditor;
import com.jd.blockchain.ledger.core.LedgerException; import com.jd.blockchain.ledger.core.LedgerException;
@@ -76,7 +72,8 @@ public class TransactionBatchProcessor implements TransactionBatchProcess {
// 此调用将会验证交易签名,验签失败将会抛出异常,同时,不记录签名错误的交易到链上; // 此调用将会验证交易签名,验签失败将会抛出异常,同时,不记录签名错误的交易到链上;
LedgerTransactionContext txCtx = newBlockEditor.newTransaction(request); LedgerTransactionContext txCtx = newBlockEditor.newTransaction(request);
TransactionState result; TransactionState result;
List<CompletableFuture<String>> contractReturn = new ArrayList<>();
TransactionReturnMessageData returnMessageData = new TransactionReturnMessageData();

try { try {
LedgerDataSet dataset = txCtx.getDataSet(); LedgerDataSet dataset = txCtx.getDataSet();
TransactionRequestContext reqCtx = new TransactionRequestContextImpl(request); TransactionRequestContext reqCtx = new TransactionRequestContextImpl(request);
@@ -103,12 +100,14 @@ public class TransactionBatchProcessor implements TransactionBatchProcess {
} }
}; };
OperationHandle opHandle; OperationHandle opHandle;
int contractOpIndex = 0;
for (Operation op : ops) { for (Operation op : ops) {
opHandle = opHandles.getHandle(op.getClass()); opHandle = opHandles.getHandle(op.getClass());
// 合约执行需要填充执行结果 // 合约执行需要填充执行结果
if (opHandle instanceof ContractEventSendOperationHandle) { if (opHandle instanceof ContractEventSendOperationHandle) {
CompletableFuture<String> currContractReturn = new CompletableFuture<>(); CompletableFuture<String> 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); ((ContractEventSendOperationHandle) opHandle).process(op, dataset, reqCtx, previousBlockDataset, handleContext, ledgerService, currContractReturn);
} else { } else {
opHandle.process(op, dataset, reqCtx, previousBlockDataset, handleContext, ledgerService); opHandle.process(op, dataset, reqCtx, previousBlockDataset, handleContext, ledgerService);
@@ -117,27 +116,30 @@ public class TransactionBatchProcessor implements TransactionBatchProcess {


// 提交交易(事务); // 提交交易(事务);
result = TransactionState.SUCCESS; result = TransactionState.SUCCESS;
txCtx.commit(result);
txCtx.commit(result, returnMessageData);
} catch (LedgerException e) { } catch (LedgerException e) {
// TODO: 识别更详细的异常类型以及执行对应的处理; // TODO: 识别更详细的异常类型以及执行对应的处理;
result = TransactionState.LEDGER_ERROR; 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", LOGGER.warn(String.format("Transaction rollback caused by the ledger exception! --[TxHash=%s] --%s",
request.getHash().toBase58(), e.getMessage()), e); request.getHash().toBase58(), e.getMessage()), e);
} catch (Exception e) { } catch (Exception e) {
result = TransactionState.SYSTEM_ERROR; 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", LOGGER.warn(String.format("Transaction rollback caused by the system exception! --[TxHash=%s] --%s",
request.getHash().toBase58(), e.getMessage()), e); request.getHash().toBase58(), e.getMessage()), e);
} }
TxResponseHandle resp = new TxResponseHandle(request, result); 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 { 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); resp.setContractReturn(returnValue);
} catch (Exception e) { } catch (Exception e) {


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

@@ -76,7 +76,7 @@ public class LedgerEditerTest {


dataAccount.setBytes(Bytes.fromString("A"), "abc".getBytes(), -1); 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(); LedgerBlock block = ldgEdt.prepare();
// 提交数据,写入存储; // 提交数据,写入存储;
ldgEdt.commit(); ldgEdt.commit();
@@ -96,7 +96,7 @@ public class LedgerEditerTest {
userAccount.setProperty("Name", "孙悟空", -1); userAccount.setProperty("Name", "孙悟空", -1);
userAccount.setProperty("Age", "10000", -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(genesisTxReq.getTransactionContent().getHash(), tx.getTransactionContent().getHash());
assertEquals(0, tx.getBlockHeight()); assertEquals(0, tx.getBlockHeight());


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

@@ -97,7 +97,7 @@ public class LedgerManagerTest {
System.out.println("UserAddress=" + userAccount.getAddress()); 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(genesisTxReq.getTransactionContent().getHash(), tx.getTransactionContent().getHash());
assertEquals(0, tx.getBlockHeight()); assertEquals(0, tx.getBlockHeight());
@@ -137,7 +137,7 @@ public class LedgerManagerTest {


LedgerTransactionContext txCtx1 = editor1.newTransaction(txRequest); LedgerTransactionContext txCtx1 = editor1.newTransaction(txRequest);
txCtx1.getDataSet().getDataAccountSet().register(dataKey.getAddress(), dataKey.getPubKey(), null); txCtx1.getDataSet().getDataAccountSet().register(dataKey.getAddress(), dataKey.getPubKey(), null);
txCtx1.commit(TransactionState.SUCCESS);
txCtx1.commit(TransactionState.SUCCESS, null);


LedgerBlock block1 = editor1.prepare(); LedgerBlock block1 = editor1.prepare();
editor1.commit(); editor1.commit();


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

@@ -68,7 +68,7 @@ public class LedgerTransactionDataTest {


long blockHeight = 9986L; long blockHeight = 9986L;
data = new LedgerTransactionData(blockHeight, txRequestMessage, TransactionState.SUCCESS, data = new LedgerTransactionData(blockHeight, txRequestMessage, TransactionState.SUCCESS,
initTransactionStagedSnapshot());
initTransactionStagedSnapshot(), null);


HashDigest hash = new HashDigest(ClassicAlgorithm.SHA256, "zhangsan".getBytes()); HashDigest hash = new HashDigest(ClassicAlgorithm.SHA256, "zhangsan".getBytes());
HashDigest adminAccountHash = new HashDigest(ClassicAlgorithm.SHA256, "lisi".getBytes()); HashDigest adminAccountHash = new HashDigest(ClassicAlgorithm.SHA256, "lisi".getBytes());


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

@@ -98,7 +98,7 @@ public class TransactionSetTest {
txSnapshot.setContractAccountSetHash(contractAccountSetHash); txSnapshot.setContractAccountSetHash(contractAccountSetHash);


long blockHeight = 8922L; 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); txset.add(tx);


assertTrue(txset.isUpdated()); assertTrue(txset.isUpdated());


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

@@ -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();

}

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

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

import java.util.concurrent.CompletableFuture;

public class ContractReturnMessageData implements ContractReturnMessage {

private int operationIndex;

private CompletableFuture<String> returnMsgFuture;

public ContractReturnMessageData() {
}

public ContractReturnMessageData(int operationIndex, CompletableFuture<String> returnMsgFuture) {
this.operationIndex = operationIndex;
this.returnMsgFuture = returnMsgFuture;
}

public void setOperationIndex(int operationIndex) {
this.operationIndex = operationIndex;
}

public void setReturnMsgFuture(CompletableFuture<String> 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);
}
}
}

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

@@ -45,4 +45,11 @@ public interface Transaction extends NodeRequest, HashObject {
@DataField(order=3, refEnum=true) @DataField(order=3, refEnum=true)
TransactionState getExecutionState(); TransactionState getExecutionState();
/**
* 交易的返回结果
*
* @return
*/
@DataField(order=4, refContract=true)
TransactionReturnMessage getReturnMessage();
} }

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

@@ -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();
}

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

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

import java.util.ArrayList;
import java.util.List;

public class TransactionReturnMessageData implements TransactionReturnMessage {

private List<ContractReturnMessage> 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);
}
}

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

@@ -577,6 +577,9 @@ public class IntegrationBase {
ReadContract readContract2 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class); ReadContract readContract2 = txContract.contract(contractDeployKey.getAddress(), ReadContract.class);
readContract2.read(newDataAccount.getAddress().toBase58(), key2); readContract2.read(newDataAccount.getAddress().toBase58(), key2);


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

// 签名; // 签名;
PreparedTransaction contractPtx = txContract.prepare(); PreparedTransaction contractPtx = txContract.prepare();
contractPtx.sign(adminKey); contractPtx.sign(adminKey);
@@ -593,13 +596,16 @@ public class IntegrationBase {


// 验证结果 // 验证结果
assertNotNull(contractReturn); assertNotNull(contractReturn);
assertEquals(contractReturn.length, 2);
assertEquals(contractReturn.length, 3);


String returnVal1 = contractReturn[0]; String returnVal1 = contractReturn[0];
assertEquals(value1, returnVal1); assertEquals(value1, returnVal1);


String returnVal2 = contractReturn[1]; String returnVal2 = contractReturn[1];
assertEquals(value2, returnVal2); assertEquals(value2, returnVal2);

String returnVal3 = contractReturn[2];
assertEquals("0", returnVal3);
} }


/** /**


BIN
source/test/test-integration/src/test/resources/contract-read.jar View File


+ 1
- 1
source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/web/LedgerInitializeWebController.java View File

@@ -425,7 +425,7 @@ public class LedgerInitializeWebController implements LedgerInitProcess, LedgerI
userRegOP.getUserID().getPubKey()); userRegOP.getUserID().getPubKey());
} }


txCtx.commit(TransactionState.SUCCESS);
txCtx.commit(TransactionState.SUCCESS, null);


return ledgerEditor.prepare(); return ledgerEditor.prepare();
} }


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

@@ -293,7 +293,7 @@ public class MockerLedgerInitializer implements LedgerInitProcess, LedgerInitCon
userRegOP.getUserID().getPubKey()); userRegOP.getUserID().getPubKey());
} }


txCtx.commit(TransactionState.SUCCESS);
txCtx.commit(TransactionState.SUCCESS, null);


return ledgerEditor.prepare(); return ledgerEditor.prepare();
} }


Loading…
Cancel
Save