From e30949e144242462977825d8c53e860780d4be64 Mon Sep 17 00:00:00 2001 From: octopus <912554887@qq.com> Date: Wed, 8 Jun 2022 19:02:54 +0800 Subject: [PATCH 1/4] modify transaction receipt merkle proof --- .../bcos/channel/client/ReceiptEncoder.java | 14 +- .../channel/client/TransactionResource.java | 140 ------------------ .../methods/response/TransactionReceipt.java | 25 ++++ .../bcos/web3j/tx/MerkleProofUtility.java | 39 ++++- 4 files changed, 71 insertions(+), 147 deletions(-) delete mode 100644 src/main/java/org/fisco/bcos/channel/client/TransactionResource.java diff --git a/src/main/java/org/fisco/bcos/channel/client/ReceiptEncoder.java b/src/main/java/org/fisco/bcos/channel/client/ReceiptEncoder.java index e589f2a94..d618fd1fb 100644 --- a/src/main/java/org/fisco/bcos/channel/client/ReceiptEncoder.java +++ b/src/main/java/org/fisco/bcos/channel/client/ReceiptEncoder.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import org.fisco.bcos.fisco.EnumNodeVersion; import org.fisco.bcos.web3j.protocol.core.methods.response.Log; import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt; import org.fisco.bcos.web3j.rlp.RlpEncoder; @@ -12,14 +13,16 @@ // encode transaction receipt by Rlp into hex string public class ReceiptEncoder { - public static String encode(TransactionReceipt transactionReceipt) { - List values = asRlpValues(transactionReceipt); + public static String encode( + TransactionReceipt transactionReceipt, EnumNodeVersion.Version version) { + List values = asRlpValues(transactionReceipt, version); RlpList rlpList = new RlpList(values); byte[] rlpBytes = RlpEncoder.encode(rlpList); return Numeric.toHexString(rlpBytes); } - private static List asRlpValues(TransactionReceipt transactionReceipt) { + private static List asRlpValues( + TransactionReceipt transactionReceipt, EnumNodeVersion.Version version) { List result = new ArrayList<>(); // bytes result.add(RlpString.create(Numeric.hexStringToByteArray(transactionReceipt.getRoot()))); @@ -38,6 +41,11 @@ private static List asRlpValues(TransactionReceipt transactionReceipt) result.add(RlpString.create(Numeric.hexStringToByteArray(transactionReceipt.getOutput()))); + // gas used + if (version != null && version.getMinor() >= 9) { + result.add(RlpString.create(Numeric.toBigInt(transactionReceipt.getRemainGasRaw()))); + } + // List List logs = transactionReceipt.getLogs(); List logList = new ArrayList<>(); diff --git a/src/main/java/org/fisco/bcos/channel/client/TransactionResource.java b/src/main/java/org/fisco/bcos/channel/client/TransactionResource.java deleted file mode 100644 index f924eb0ab..000000000 --- a/src/main/java/org/fisco/bcos/channel/client/TransactionResource.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.fisco.bcos.channel.client; - -import java.io.IOException; -import java.math.BigInteger; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.fisco.bcos.web3j.crypto.Hash; -import org.fisco.bcos.web3j.protocol.Web3j; -import org.fisco.bcos.web3j.protocol.core.methods.response.Transaction; -import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt; -import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceiptWithProof; -import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionWithProof; -import org.fisco.bcos.web3j.rlp.RlpEncoder; -import org.fisco.bcos.web3j.rlp.RlpString; -import org.fisco.bcos.web3j.utils.Numeric; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TransactionResource { - private static final Logger logger = LoggerFactory.getLogger(TransactionResource.class); - - private Web3j web3j; - - public TransactionResource(Web3j web3j) { - this.web3j = web3j; - } - - public TransactionWithProof getTransactionWithProof(String transactionHash, String rootHash) - throws IOException { - TransactionWithProof transactionWithProof = - web3j.getTransactionByHashWithProof(transactionHash).send(); - if (transactionWithProof.getTransactionWithProof() == null) { - return null; - } - - Transaction transaction = transactionWithProof.getTransactionWithProof().getTransaction(); - logger.debug("Transaction:{}", transaction); - - // transaction index - String index = transaction.getTransactionIndexRaw(); - BigInteger indexValue = Numeric.toBigInt(index); - byte[] byteIndex = RlpEncoder.encode(RlpString.create(indexValue)); - String input = Numeric.toHexString(byteIndex) + transactionHash.substring(2); - logger.info("TransWithIndex:{}", input); - - String proof = - Merkle.calculateMerkleRoot( - transactionWithProof.getTransactionWithProof().getTxProof(), input); - // System.out.println("MerkleRoot: " + proof); - - if (!proof.equals(rootHash)) { - logger.debug("MerkleRoot:{}", proof); - logger.debug("TransRoot :{}", rootHash); - return null; - } - return transactionWithProof; - } - - public TransactionReceiptWithProof getTransactionReceiptWithProof( - String transactionHash, String rootHash) throws IOException { - TransactionReceiptWithProof transactionReceiptWithProof = - web3j.getTransactionReceiptByHashWithProof(transactionHash).send(); - - if (transactionReceiptWithProof.getTransactionReceiptWithProof() == null) { - return null; - } - TransactionReceipt transactionReceipt = - transactionReceiptWithProof - .getTransactionReceiptWithProof() - .getTransactionReceipt(); - logger.debug("Receipt {}", transactionReceipt.toString()); - - // transaction index - String index = transactionReceipt.getTransactionIndexRaw(); - BigInteger indexValue = Numeric.toBigInt(index); - byte[] byteIndex = RlpEncoder.encode(RlpString.create(indexValue)); - - String receiptRlp = ReceiptEncoder.encode(transactionReceipt); - logger.debug("ReceiptRlp:{}", receiptRlp); - - String rlpHash = Hash.sha3(receiptRlp); - logger.debug("ReceiptRlpHash:{}", rlpHash); - - String input = Numeric.toHexString(byteIndex) + rlpHash.substring(2); - logger.info("ReceiptWithIndex:{}", input); - - String proof = - Merkle.calculateMerkleRoot( - transactionReceiptWithProof - .getTransactionReceiptWithProof() - .getReceiptProof(), - input); - - // System.out.println("MerkleRoot: " + proof); - if (!proof.equals(rootHash)) { - logger.debug("MerkleRoot:{}", proof); - logger.debug("TransRoot :{}", rootHash); - return null; - } - return transactionReceiptWithProof; - } - - public ImmutablePair - getTransactionAndReceiptWithProof( - String transactionHash, String transactionsRoot, String receiptsRoot) - throws IOException { - TransactionWithProof transactionWithProof = - getTransactionWithProof(transactionHash, transactionsRoot); - if (transactionWithProof == null) { - return null; - } - - TransactionReceiptWithProof transactionReceiptWithProof = - getTransactionReceiptWithProof(transactionHash, receiptsRoot); - if (transactionReceiptWithProof == null) { - return null; - } - - String indexFromTransaction = - transactionWithProof - .getTransactionWithProof() - .getTransaction() - .getTransactionIndexRaw(); - - String indexFromReceipt = - transactionReceiptWithProof - .getTransactionReceiptWithProof() - .getTransactionReceipt() - .getTransactionIndexRaw(); - - logger.debug( - "indexFromTransaction:{}, indexFromReceipt:{}", - indexFromTransaction, - indexFromReceipt); - if (!indexFromTransaction.equals(indexFromReceipt)) { - return null; - } - - return new ImmutablePair<>(transactionWithProof, transactionReceiptWithProof); - } -} diff --git a/src/main/java/org/fisco/bcos/web3j/protocol/core/methods/response/TransactionReceipt.java b/src/main/java/org/fisco/bcos/web3j/protocol/core/methods/response/TransactionReceipt.java index 3e352880b..dca57c656 100644 --- a/src/main/java/org/fisco/bcos/web3j/protocol/core/methods/response/TransactionReceipt.java +++ b/src/main/java/org/fisco/bcos/web3j/protocol/core/methods/response/TransactionReceipt.java @@ -12,6 +12,7 @@ public class TransactionReceipt { private String blockHash; private String blockNumber; private String gasUsed; + private String remainGas; private String contractAddress; private String root; // status is only present on Byzantium transactions onwards @@ -34,6 +35,7 @@ public TransactionReceipt( String transactionIndex, String blockHash, String blockNumber, + String remainGas, String gasUsed, String contractAddress, String root, @@ -49,6 +51,7 @@ public TransactionReceipt( this.transactionIndex = transactionIndex; this.blockHash = blockHash; this.blockNumber = blockNumber; + this.remainGas = remainGas; this.gasUsed = gasUsed; this.contractAddress = contractAddress; this.root = root; @@ -120,6 +123,19 @@ public void setBlockNumber(String blockNumber) { this.blockNumber = blockNumber; } + @JsonIgnore + public String getRemainGasRaw() { + return remainGas; + } + + public BigInteger getRemainGas() { + return Numeric.decodeQuantity(remainGas); + } + + public void setRemainGas(String remainGas) { + this.remainGas = remainGas; + } + public BigInteger getGasUsed() { return Numeric.decodeQuantity(gasUsed); } @@ -261,6 +277,11 @@ public boolean equals(Object o) { if (gasUsed != null ? !gasUsed.equals(that.gasUsed) : that.gasUsed != null) { return false; } + + if (remainGas != null ? !remainGas.equals(that.remainGas) : that.remainGas != null) { + return false; + } + if (getContractAddress() != null ? !getContractAddress().equals(that.getContractAddress()) : that.getContractAddress() != null) { @@ -303,6 +324,7 @@ public int hashCode() { result = 31 * result + (getBlockHash() != null ? getBlockHash().hashCode() : 0); result = 31 * result + (blockNumber != null ? blockNumber.hashCode() : 0); result = 31 * result + (gasUsed != null ? gasUsed.hashCode() : 0); + result = 31 * result + (remainGas != null ? remainGas.hashCode() : 0); result = 31 * result + (getContractAddress() != null ? getContractAddress().hashCode() : 0); result = 31 * result + (getRoot() != null ? getRoot().hashCode() : 0); result = 31 * result + (getStatus() != null ? getStatus().hashCode() : 0); @@ -333,6 +355,9 @@ public String toString() { + ", gasUsed='" + gasUsed + '\'' + + ", remainGas='" + + remainGas + + '\'' + ", contractAddress='" + contractAddress + '\'' diff --git a/src/main/java/org/fisco/bcos/web3j/tx/MerkleProofUtility.java b/src/main/java/org/fisco/bcos/web3j/tx/MerkleProofUtility.java index b69c6f5d0..b0634d0b4 100644 --- a/src/main/java/org/fisco/bcos/web3j/tx/MerkleProofUtility.java +++ b/src/main/java/org/fisco/bcos/web3j/tx/MerkleProofUtility.java @@ -4,6 +4,8 @@ import java.util.List; import org.fisco.bcos.channel.client.Merkle; import org.fisco.bcos.channel.client.ReceiptEncoder; +import org.fisco.bcos.channel.protocol.ChannelPrococolExceiption; +import org.fisco.bcos.fisco.EnumNodeVersion; import org.fisco.bcos.web3j.crypto.Hash; import org.fisco.bcos.web3j.protocol.core.methods.response.MerkleProofUnit; import org.fisco.bcos.web3j.protocol.core.methods.response.Transaction; @@ -55,7 +57,15 @@ public static boolean verifyTransaction( * @return */ public static boolean verifyTransactionReceipt( - String receiptRoot, TransactionReceiptWithProof.ReceiptAndProof receiptAndProof) { + String receiptRoot, + TransactionReceiptWithProof.ReceiptAndProof receiptAndProof, + String supportedVersion) { + + EnumNodeVersion.Version classVersion = null; + try { + classVersion = EnumNodeVersion.getClassVersion(supportedVersion); + } catch (ChannelPrococolExceiption e) { + } TransactionReceipt transactionReceipt = receiptAndProof.getTransactionReceipt(); @@ -67,7 +77,14 @@ public static boolean verifyTransactionReceipt( transactionReceipt.setGasUsed("0x" + transactionReceipt.getGasUsed().toString(16)); } - String receiptRlp = ReceiptEncoder.encode(transactionReceipt); + if (classVersion != null && classVersion.getMinor() >= 9) { + if (!transactionReceipt.getRemainGasRaw().startsWith("0x")) { + transactionReceipt.setRemainGas( + "0x" + transactionReceipt.getRemainGas().toString(16)); + } + } + + String receiptRlp = ReceiptEncoder.encode(transactionReceipt, classVersion); String rlpHash = Hash.sha3(receiptRlp); String input = Numeric.toHexString(byteIndex) + rlpHash.substring(2); @@ -125,17 +142,31 @@ public static boolean verifyTransaction( public static boolean verifyTransactionReceipt( String receiptRoot, TransactionReceipt transactionReceipt, - List receiptProof) { + List receiptProof, + String supportedVersion) { if (!transactionReceipt.getGasUsedRaw().startsWith("0x")) { transactionReceipt.setGasUsed("0x" + transactionReceipt.getGasUsed().toString(16)); } + EnumNodeVersion.Version classVersion = null; + try { + classVersion = EnumNodeVersion.getClassVersion(supportedVersion); + } catch (ChannelPrococolExceiption e) { + } + + if (classVersion != null && classVersion.getMinor() >= 9) { + if (!transactionReceipt.getRemainGasRaw().startsWith("0x")) { + transactionReceipt.setRemainGas( + "0x" + transactionReceipt.getRemainGas().toString(16)); + } + } + // transaction index byte[] byteIndex = RlpEncoder.encode(RlpString.create(transactionReceipt.getTransactionIndex())); - String receiptRlp = ReceiptEncoder.encode(transactionReceipt); + String receiptRlp = ReceiptEncoder.encode(transactionReceipt, classVersion); String rlpHash = Hash.sha3(receiptRlp); String input = Numeric.toHexString(byteIndex) + rlpHash.substring(2); From 95efa06ac975b71d32ed611f3250a23f6e0fdb43 Mon Sep 17 00:00:00 2001 From: octopus <912554887@qq.com> Date: Wed, 8 Jun 2022 19:16:42 +0800 Subject: [PATCH 2/4] update web3sdk version --- publish.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/publish.gradle b/publish.gradle index 8d741de4d..6bc219f0c 100644 --- a/publish.gradle +++ b/publish.gradle @@ -90,7 +90,7 @@ dependencies { archivesBaseName = 'web3sdk' group = 'org.fisco-bcos' -version = '2.6.4' +version = '2.6.5' // Additional attribute definition From fbea665e8146a2ac420a17b5eb73c6b0eceb68e5 Mon Sep 17 00:00:00 2001 From: octopus <912554887@qq.com> Date: Tue, 11 Jul 2023 16:09:49 +0800 Subject: [PATCH 3/4] update netty version to 4.1.94 --- build.gradle | 3 +- publish.gradle | 6 +- .../client/TransactionResourceTest.java | 149 ------------------ 3 files changed, 4 insertions(+), 154 deletions(-) delete mode 100644 src/test/java/org/fisco/bcos/channel/client/TransactionResourceTest.java diff --git a/build.gradle b/build.gradle index b23e246ee..c85574e77 100644 --- a/build.gradle +++ b/build.gradle @@ -68,12 +68,11 @@ dependencies { // compile 'io.netty:netty-tcnative:2.0.25.Final' // compile 'io.netty:netty-tcnative-boringssl-static:2.0.27.Final' // compile 'org.fisco-bcos:netty-sm-ssl-context:1.0.0-SNAPSHOT' - compile ('org.fisco-bcos:netty-sm-ssl-context:1.2.0') { + compile ('org.fisco-bcos:netty-sm-ssl-context:1.5.2') { exclude module:"log4j" } // compile 'org.ethereum:solcJ-all:0.4.25' - compile 'io.netty:netty-all:4.1.53.Final' compile 'com.google.guava:guava:29.0-jre' compile 'commons-configuration:commons-configuration:1.10' compile 'org.apache.httpcomponents:httpclient:4.5.5' diff --git a/publish.gradle b/publish.gradle index 6bc219f0c..6c63f59f5 100644 --- a/publish.gradle +++ b/publish.gradle @@ -59,12 +59,12 @@ dependencies { // compile 'io.netty:netty-tcnative:2.0.25.Final' // compile 'io.netty:netty-tcnative-boringssl-static:2.0.27.Final' - compile ('org.fisco-bcos:netty-sm-ssl-context:1.2.0') { + compile ('org.fisco-bcos:netty-sm-ssl-context:1.5.2') { exclude module:"log4j" } // compile 'org.ethereum:solcJ-all:0.4.25' - compile 'io.netty:netty-all:4.1.53.Final' +// compile 'io.netty:netty-all:4.1.53.Final' compile 'com.google.guava:guava:29.0-jre' compile 'commons-configuration:commons-configuration:1.10' compile 'org.apache.httpcomponents:httpclient:4.5.5' @@ -90,7 +90,7 @@ dependencies { archivesBaseName = 'web3sdk' group = 'org.fisco-bcos' -version = '2.6.5' +version = '2.6.6-SNAPSHOT' // Additional attribute definition diff --git a/src/test/java/org/fisco/bcos/channel/client/TransactionResourceTest.java b/src/test/java/org/fisco/bcos/channel/client/TransactionResourceTest.java deleted file mode 100644 index 0b701d8e9..000000000 --- a/src/test/java/org/fisco/bcos/channel/client/TransactionResourceTest.java +++ /dev/null @@ -1,149 +0,0 @@ -package org.fisco.bcos.channel.client; - -import java.math.BigInteger; -import java.util.List; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.fisco.bcos.web3j.crypto.Credentials; -import org.fisco.bcos.web3j.crypto.ECKeyPair; -import org.fisco.bcos.web3j.crypto.Keys; -import org.fisco.bcos.web3j.protocol.Web3j; -import org.fisco.bcos.web3j.protocol.channel.ChannelEthereumService; -import org.fisco.bcos.web3j.protocol.core.DefaultBlockParameter; -import org.fisco.bcos.web3j.protocol.core.methods.response.BcosBlock; -import org.fisco.bcos.web3j.protocol.core.methods.response.BcosTransaction; -import org.fisco.bcos.web3j.protocol.core.methods.response.MerkleProofUnit; -import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceiptWithProof; -import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionWithProof; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; - -public class TransactionResourceTest { - static Logger logger = LoggerFactory.getLogger(TransactionResourceTest.class); - public static Web3j web3j; - - public static ECKeyPair keyPair; - public static Credentials credentials; - - public static void main(String[] args) throws Exception { - - // init the Service - ApplicationContext context = - new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); - Service service = context.getBean(Service.class); - service.setGroupId(Integer.parseInt(args[0])); - service.run(); // run the daemon service - // init the client keys - keyPair = Keys.createEcKeyPair(); - credentials = Credentials.create(keyPair); - - logger.info("-----> start TransactionResourceTest !"); - ChannelEthereumService channelEthereumService = new ChannelEthereumService(); - channelEthereumService.setChannelService(service); - try { - web3j = Web3j.build(channelEthereumService, Integer.parseInt(args[0])); - } catch (Exception e) { - System.out.println("Please provide groupID in the first paramters"); - System.exit(1); - } - - try { - if (args.length == 4) { - BigInteger blockNumber = new BigInteger(args[2]); - BigInteger transactionIndex = new BigInteger(args[3]); - DefaultBlockParameter defaultBlockParameter = - DefaultBlockParameter.valueOf(blockNumber); - - BcosTransaction bcosTransaction = - web3j.getTransactionByBlockNumberAndIndex( - defaultBlockParameter, transactionIndex) - .send(); - String transactionHash = bcosTransaction.getTransaction().get().getHash(); - - BcosBlock block = web3j.getBlockByNumber(defaultBlockParameter, true).send(); - String transactionsRootHash = block.getBlock().getTransactionsRoot(); - System.out.println("transactionsRoot: " + transactionsRootHash); - String receiptRootHash = block.getBlock().getReceiptsRoot(); - System.out.println("receiptRootHash : " + receiptRootHash); - - TransactionResource transactionResource = new TransactionResource(web3j); - - if ("getTrans".equals(args[1])) { - TransactionWithProof transactionWithProof = - web3j.getTransactionByHashWithProof(transactionHash).send(); - if (transactionWithProof == null) { - System.out.println("transactionWithProof == null"); - System.exit(1); - } - - System.out.println("***********Test getTransactionByHashWithProof************"); - List transactionProof = - transactionWithProof.getTransactionWithProof().getTxProof(); - System.out.println("transactionProof:" + transactionProof); - - TransactionWithProof newTransactionWithProof = - transactionResource.getTransactionWithProof( - transactionHash, transactionsRootHash); - if (newTransactionWithProof == null) { - System.out.println("Test getTransactionByHashWithProof failed!"); - - } else { - System.out.println( - newTransactionWithProof.getTransactionWithProof().toString()); - System.out.println("Test getTransactionByHashWithProof successfully!"); - } - - } else if ("getReceipt".equals(args[1])) { - TransactionReceiptWithProof transactionReceiptWithProof = - web3j.getTransactionReceiptByHashWithProof(transactionHash).send(); - if (transactionReceiptWithProof == null) { - System.out.println("transactionReceiptWithProof == null"); - System.exit(1); - } - - List transactionReceiptProof = - transactionReceiptWithProof - .getTransactionReceiptWithProof() - .getReceiptProof(); - System.out.println("receiptProof:" + transactionReceiptProof); - - System.out.println("***********Test getReceiptByHashWithProof************"); - TransactionReceiptWithProof newTransactionReceiptWithProof = - transactionResource.getTransactionReceiptWithProof( - transactionHash, receiptRootHash); - if (newTransactionReceiptWithProof == null) { - System.out.println("Test getReceiptByHashWithProof failed!"); - - } else { - System.out.println( - newTransactionReceiptWithProof - .getTransactionReceiptWithProof() - .toString()); - System.out.println("Test getReceiptByHashWithProof successfully!"); - } - } else if ("getAll".equals(args[1])) { - System.out.println( - "***********Test getTransactionAndReceiptWithProof************"); - ImmutablePair pair = - transactionResource.getTransactionAndReceiptWithProof( - transactionHash, transactionsRootHash, receiptRootHash); - if (pair == null) { - System.out.println("Test getAll failed!"); - } else { - System.out.println("Test getAll successful!"); - } - } else { - System.out.println("Command not found!"); - } - } else { - System.out.println("Please choose follow commands:\n getTrans or getReceipt!"); - } - } catch (Exception e) { - System.out.println(e.getLocalizedMessage()); - System.exit(1); - } - - System.exit(0); - } -} From 79b5e96913595160742416b8323368ca61c05857 Mon Sep 17 00:00:00 2001 From: octopus <912554887@qq.com> Date: Thu, 13 Jul 2023 17:18:32 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E4=B8=BA2.6.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/publish.gradle b/publish.gradle index 6c63f59f5..3c0c825c7 100644 --- a/publish.gradle +++ b/publish.gradle @@ -90,7 +90,7 @@ dependencies { archivesBaseName = 'web3sdk' group = 'org.fisco-bcos' -version = '2.6.6-SNAPSHOT' +version = '2.6.6' // Additional attribute definition