diff --git a/.github/workflows/ci_check.yml b/.github/workflows/ci_check.yml index 6bfae39..f940d5a 100644 --- a/.github/workflows/ci_check.yml +++ b/.github/workflows/ci_check.yml @@ -6,8 +6,8 @@ name: actions check on: pull_request jobs: - ubuntu1804jdk8: - runs-on: ubuntu-18.04 + ubuntujdk8: + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Set up JDK 1.8 @@ -19,8 +19,8 @@ jobs: - name: upload coverage run: bash <(curl -s https://codecov.io/bash) - ubuntu1804jdk11: - runs-on: ubuntu-18.04 + ubuntujdk11: + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Set up JDK 11 diff --git a/build.gradle b/build.gradle index 1798e16..2b7d4ce 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'com.github.sherter.google-java-format' version '0.8' - id 'com.github.johnrengelman.shadow' version '5.2.0' + id 'com.github.johnrengelman.shadow' version '6.1.0' id 'org.ajoberstar.grgit' version '4.0.1' id 'maven-publish' } @@ -14,7 +14,7 @@ apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'com.github.johnrengelman.shadow' group 'com.webank.wecross' -version '1.3.0' +version '1.4.0' sourceCompatibility = 1.8 @@ -60,19 +60,24 @@ dependencies { } implementation 'com.google.code.gson:gson:2.8.9' implementation 'org.slf4j:slf4j-api:1.7.36' - implementation 'com.google.guava:guava:30.1-jre' + implementation 'com.google.guava:guava:32.0.1-jre' implementation 'org.yaml:snakeyaml:2.0' // Fabric implementation 'javassist:javassist:3.12.1.GA' implementation ("org.hyperledger.fabric-sdk-java:fabric-sdk-java:1.4.4") { exclude group: 'io.netty' + exclude group: 'com.google.protobuf', module: 'protobuf-java' + exclude group: 'org.apache.logging.log4j' + exclude group: 'log4j' } + implementation "com.google.protobuf:protobuf-java:3.25.3" + implementation 'org.apache.commons:commons-compress:1.26.0' // implementation 'io.netty:netty-tcnative-boringssl-static:2.0.27.Final' // WeCross - implementation ('com.webank:wecross-java-stub:1.3.0') { + implementation ('com.webank:wecross-java-stub:1.4.0-SNAPSHOT') { exclude group: 'org.fisco-bcos', module: 'tcnative' } configurations.compile.exclude(group: 'ch.qos.logback') diff --git a/release_note.txt b/release_note.txt index 18fa8e7..0d0c52f 100644 --- a/release_note.txt +++ b/release_note.txt @@ -1 +1 @@ -v1.3.0 +v1.4.0 diff --git a/src/main/java/com/webank/wecross/stub/fabric/FabricBlock.java b/src/main/java/com/webank/wecross/stub/fabric/FabricBlock.java index 9b5117a..762d320 100644 --- a/src/main/java/com/webank/wecross/stub/fabric/FabricBlock.java +++ b/src/main/java/com/webank/wecross/stub/fabric/FabricBlock.java @@ -72,6 +72,15 @@ public BlockHeader dumpWeCrossHeader() { blockHeader.setHash(this.getHash()); blockHeader.setPrevHash(header.getPrevHash()); blockHeader.setTransactionRoot(header.getDataHash()); + try { + Common.Envelope envelope = Common.Envelope.parseFrom(blockData.blockData.getData(0)); + Common.Payload payload = Common.Payload.parseFrom(envelope.getPayload()); + Common.ChannelHeader channelHeader = + Common.ChannelHeader.parseFrom(payload.getHeader().getChannelHeader()); + blockHeader.setTimestamp(channelHeader.getTimestamp().getSeconds()); + } catch (Exception ignored) { + blockHeader.setTimestamp(0); + } return blockHeader; } diff --git a/src/main/java/com/webank/wecross/stub/fabric/FabricDriver.java b/src/main/java/com/webank/wecross/stub/fabric/FabricDriver.java index c269e36..aa5ae3b 100644 --- a/src/main/java/com/webank/wecross/stub/fabric/FabricDriver.java +++ b/src/main/java/com/webank/wecross/stub/fabric/FabricDriver.java @@ -4,10 +4,25 @@ import static com.webank.wecross.utils.FabricUtils.longToBytes; import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; import com.webank.wecross.account.FabricAccount; import com.webank.wecross.account.FabricAccountFactory; import com.webank.wecross.common.FabricType; -import com.webank.wecross.stub.*; +import com.webank.wecross.stub.Account; +import com.webank.wecross.stub.Block; +import com.webank.wecross.stub.BlockManager; +import com.webank.wecross.stub.Connection; +import com.webank.wecross.stub.Driver; +import com.webank.wecross.stub.Path; +import com.webank.wecross.stub.Request; +import com.webank.wecross.stub.ResourceInfo; +import com.webank.wecross.stub.Response; +import com.webank.wecross.stub.StubConstant; +import com.webank.wecross.stub.Transaction; +import com.webank.wecross.stub.TransactionContext; +import com.webank.wecross.stub.TransactionException; +import com.webank.wecross.stub.TransactionRequest; +import com.webank.wecross.stub.TransactionResponse; import com.webank.wecross.stub.fabric.FabricCustomCommand.InstallChaincodeRequest; import com.webank.wecross.stub.fabric.FabricCustomCommand.InstallCommand; import com.webank.wecross.stub.fabric.FabricCustomCommand.InstantiateChaincodeRequest; @@ -21,7 +36,9 @@ import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.hyperledger.fabric.protos.common.Common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -396,7 +413,6 @@ public void asyncGetBlock( block.setRawBytes(response.getData()); FabricBlock fabricBlock = null; - List transactionsHashes = new ArrayList<>(); try { fabricBlock = FabricBlock.encode(response.getData()); if (blockVerifierString != null) { @@ -425,11 +441,48 @@ public void asyncGetBlock( } if (!onlyHeader) { - transactionsHashes = new ArrayList<>(fabricBlock.getValidTxs()); + Common.Block b = Common.Block.parseFrom(response.getData()); + List dataList = b.getData().getDataList(); + for (ByteString data : dataList) { + try { + Common.Envelope envelope = Common.Envelope.parseFrom(data); + String payload = envelope.toString(); + int from = payload.indexOf("-----BEGIN CERTIFICATE-----"); + int end = payload.indexOf("-----END CERTIFICATE-----"); + String identity = + payload.substring(from, end) + + "-----END CERTIFICATE-----\n"; + FabricTransaction fabricTransaction = + FabricTransaction.buildFromEnvelopeBytes( + envelope.toByteArray()); + if (StringUtils.isBlank(fabricTransaction.getTxID())) { + continue; + } + Transaction transaction = + parseFabricTransaction(fabricTransaction); + transaction + .getTransactionResponse() + .setErrorCode( + FabricType.TransactionResponseStatus + .SUCCESS); + transaction.setAccountIdentity(identity); + transaction + .getTransactionResponse() + .setHash(fabricTransaction.getTxID()); + transaction.setTxBytes(data.toByteArray()); + transaction + .getTransactionResponse() + .setBlockNumber(blockNumber); + block.getTransactionsWithDetail().add(transaction); + } catch (InvalidProtocolBufferException e) { + logger.warn( + "Invalid fabric block transactions,blockNumber: {},e: {}", + blockNumber, + e.getMessage()); + } + } } block.setBlockHeader(fabricBlock.dumpWeCrossHeader()); - block.setTransactionsHashes(transactionsHashes); - callback.onResponse(null, block); } catch (Exception e) { String errorMsg = @@ -498,7 +551,7 @@ public void asyncGetTransaction( blockNumber, blockManager, hasOnChain -> { - if (!hasOnChain.booleanValue()) { + if (!hasOnChain) { callback.onResponse( new Exception( "Transaction proof verify failed. Tx(" @@ -597,15 +650,17 @@ private void asyncSendTransactionHandleOrdererResponse( + txBlockNumber + ")"); } else { + FabricTransaction fabricTransaction = + FabricTransaction.buildFromPayloadBytes( + ordererPayloadToSign); response = decodeTransactionResponse( - FabricTransaction.buildFromPayloadBytes( - ordererPayloadToSign) - .getOutputBytes()); + fabricTransaction.getOutputBytes()); response.setHash(txID); response.setBlockNumber(txBlockNumber); response.setErrorCode( FabricType.TransactionResponseStatus.SUCCESS); + response.setTimestamp(fabricTransaction.getTimestamp()); response.setMessage("Success"); transactionException = TransactionException.Builder.newSuccessException(); @@ -1195,6 +1250,7 @@ private Transaction parseFabricTransaction(FabricTransaction fabricTransaction) ByteString payload = ByteString.copyFrom(outputBytes); String[] output = new String[] {payload.toStringUtf8()}; transaction.getTransactionResponse().setResult(output); + transaction.getTransactionResponse().setTimestamp(fabricTransaction.getTimestamp()); /** xa */ transaction.setTransactionByProxy(byProxy); diff --git a/src/main/java/com/webank/wecross/stub/fabric/FabricTransaction.java b/src/main/java/com/webank/wecross/stub/fabric/FabricTransaction.java index b150af5..cd6b8f0 100644 --- a/src/main/java/com/webank/wecross/stub/fabric/FabricTransaction.java +++ b/src/main/java/com/webank/wecross/stub/fabric/FabricTransaction.java @@ -1,6 +1,7 @@ package com.webank.wecross.stub.fabric; import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.LinkedList; @@ -17,14 +18,20 @@ public class FabricTransaction { private List transactionActionList = new ArrayList<>(); private String txID; + private long timestamp = 0; + FabricTransaction(byte[] payloadBytes) throws Exception { Common.Payload transactionPayload = Common.Payload.parseFrom(payloadBytes); this.header = transactionPayload.getHeader(); - this.txID = Common.ChannelHeader.parseFrom(header.getChannelHeader()).getTxId(); + Common.ChannelHeader channelHeader = + Common.ChannelHeader.parseFrom(header.getChannelHeader()); + this.txID = channelHeader.getTxId(); this.transaction = org.hyperledger.fabric.protos.peer.FabricTransaction.Transaction.parseFrom( transactionPayload.getData()); + Timestamp ts = channelHeader.getTimestamp(); + this.timestamp = ts.getSeconds(); for (org.hyperledger.fabric.protos.peer.FabricTransaction.TransactionAction action : transaction.getActionsList()) { transactionActionList.add(new TransactionAction(action)); @@ -74,6 +81,10 @@ public byte[] getOutputBytes() { .getOutputBytes(); } + public long getTimestamp() { + return timestamp; + } + public static class TransactionAction { private org.hyperledger.fabric.protos.peer.FabricTransaction.TransactionAction transactionAction; diff --git a/src/main/java/com/webank/wecross/utils/TarUtils.java b/src/main/java/com/webank/wecross/utils/TarUtils.java index ab23eb9..9ec37fe 100644 --- a/src/main/java/com/webank/wecross/utils/TarUtils.java +++ b/src/main/java/com/webank/wecross/utils/TarUtils.java @@ -61,7 +61,7 @@ private static byte[] generateTarGzInputStreamBytes(File src, String pathPrefix) archiveEntry = new TarArchiveEntry(childFile, relativePath); try (FileInputStream fileInputStream = new FileInputStream(childFile)) { - archiveOutputStream.putArchiveEntry(archiveEntry); + archiveOutputStream.putArchiveEntry((TarArchiveEntry) archiveEntry); try { IOUtils.copy(fileInputStream, archiveOutputStream); diff --git a/src/main/resources/chaincode/WeCrossHub/hub.go b/src/main/resources/chaincode/WeCrossHub/hub.go index a25cb67..4f6754b 100644 --- a/src/main/resources/chaincode/WeCrossHub/hub.go +++ b/src/main/resources/chaincode/WeCrossHub/hub.go @@ -20,6 +20,7 @@ const ( NilFlag = "null" CallTypeQuery = "0" CallTypeInvoke = "1" + CallTypeGetBlock = "2" ChannelKey = "channel" CurrentIndexKey = "current_index" @@ -77,6 +78,8 @@ func (h *Hub) Invoke(stub shim.ChaincodeStubInterface) (res peer.Response) { res = h.interchainInvoke(stub, args) case "interchainQuery": res = h.interchainQuery(stub, args) + case "interchainGetBlock": + res = h.interchainGetBlock(stub, args) case "registerCallbackResult": res = h.registerCallbackResult(stub, args) case "selectCallbackResult": @@ -124,6 +127,16 @@ func (h *Hub) interchainQuery(stub shim.ChaincodeStubInterface, args []string) p return shim.Success(uint64ToBytes(uid)) } +func (h *Hub) interchainGetBlock(stub shim.ChaincodeStubInterface, args []string) peer.Response { + if len(args) != 5 { + return shim.Error("incorrect number of arguments, expecting 5") + } + + uid := handleRequest(stub, CallTypeGetBlock, args[0], args[1], args[2], args[3], args[4]) + + return shim.Success(uint64ToBytes(uid)) +} + func handleRequest(stub shim.ChaincodeStubInterface, callType, path, method, args, callbackPath, callbackMethod string) uint64 { increment, err := stub.GetState(IncrementKey) checkError(err)