Skip to content

Commit

Permalink
<fix>(model): fix receipt hash calculate bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
kyonRay committed Mar 25, 2024
1 parent d0b8ff0 commit 3685137
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 107 deletions.
8 changes: 4 additions & 4 deletions .ci/ci_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,8 @@ check_standard_node()
prepare_environment "${2}"
## run integration test
bash gradlew clean integrationTest --info
# if $? is not 0, then exit
if [ ${?} -ne 0 ]; then
cat log/*.log
fi
# if hs_err log exist, print it
(cat hs_err_pid*.log) || true
## clean
clean_node "${1}"
}
Expand All @@ -153,6 +151,8 @@ check_wasm_node()
prepare_wasm_environment
## run integration test
bash gradlew clean integrationWasmTest --info
(cat hs_err_pid*.log) || true

## clean
clean_node "${1}"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,77 @@
package org.fisco.bcos.sdk.v3.test.transaction.decoder;

import org.fisco.bcos.sdk.jni.utilities.tx.TransactionVersion;
import org.fisco.bcos.sdk.v3.BcosSDK;
import org.fisco.bcos.sdk.v3.client.Client;
import org.fisco.bcos.sdk.v3.client.protocol.model.JsonTransactionResponse;
import org.fisco.bcos.sdk.v3.client.protocol.response.BcosBlock;
import org.fisco.bcos.sdk.v3.client.protocol.response.BcosBlockHeader;
import org.fisco.bcos.sdk.v3.client.protocol.response.BlockNumber;
import org.fisco.bcos.sdk.v3.crypto.hash.Keccak256;
import org.fisco.bcos.sdk.v3.crypto.hash.SM3Hash;
import org.fisco.bcos.sdk.v3.model.ConstantConfig;
import org.fisco.bcos.sdk.v3.model.CryptoType;
import org.fisco.bcos.sdk.v3.model.EnumNodeVersion;
import org.fisco.bcos.sdk.v3.model.TransactionReceipt;
import org.fisco.bcos.sdk.v3.test.contract.solidity.EventSubDemo;
import org.fisco.bcos.sdk.v3.test.contract.solidity.Incremental;
import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException;
import org.fisco.bcos.sdk.v3.utils.Hex;
import org.fisco.bcos.sdk.v3.utils.MerkleProofUtility;
import org.fisco.bcos.sdk.v3.utils.ObjectMapperFactory;
import org.junit.Assert;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.UUID;

import static org.fisco.bcos.sdk.v3.utils.Numeric.toBytesPadded;

public class HashCalculatorTest {
private static final String CONFIG_FILE =
"src/integration-test/resources/" + ConstantConfig.CONFIG_FILE_NAME;
private final Client client;
private final BcosBlock.Block block;
private BcosBlock.Block block;
private JsonTransactionResponse transactionResponse = null;
private JsonTransactionResponse transactionResponseV1 = null;
private JsonTransactionResponse transactionResponseV2 = null;

private TransactionReceipt transactionReceipt = null;
private TransactionReceipt transactionReceiptV1 = null;
private TransactionReceipt transactionReceiptV2 = null;

public HashCalculatorTest() {
public HashCalculatorTest() throws ContractException {
BcosSDK sdk = BcosSDK.build(CONFIG_FILE);
client = sdk.getClient("group0");
BlockNumber blockNumber = client.getBlockNumber();
block = client.getBlockByNumber(blockNumber.getBlockNumber(), false, false).getBlock();
if (!block.getTransactions().isEmpty()) {
BcosBlock.TransactionObject transactionObject =
(BcosBlock.TransactionObject) block.getTransactions().get(0);
JsonTransactionResponse transactionResponse1 = transactionObject.get();
transactionResponse =
client.getTransaction(transactionResponse1.getHash(), true)
.getTransaction()
.get();
transactionReceipt =
client.getTransactionReceipt(transactionResponse1.getHash(), true)
.getTransactionReceipt();
if (client.isSupportTransactionV1()) {
Incremental incremental =
Incremental.deploy(client, client.getCryptoSuite().getCryptoKeyPair());
String nonce = UUID.randomUUID().toString().replace("-", "");
transactionReceiptV1 = incremental.buildMethodInc(nonce).setNonce(nonce).send();
transactionResponseV1 =
client.getTransaction(transactionReceiptV1.getTransactionHash(), true)
.getResult();
}

if (client.isSupportTransactionV2()) {
Incremental incremental =
Incremental.deploy(client, client.getCryptoSuite().getCryptoKeyPair());
String nonce = UUID.randomUUID().toString().replace("-", "");
transactionReceiptV2 =
incremental
.buildMethodInc(nonce)
.setNonce(nonce)
.setExtension(nonce.getBytes())
.send();
transactionResponseV2 =
client.getTransaction(transactionReceiptV2.getTransactionHash(), true)
.getResult();
}

EventSubDemo eventSubDemo =
EventSubDemo.deploy(client, client.getCryptoSuite().getCryptoKeyPair());
transactionReceipt = eventSubDemo.echo(BigInteger.TEN, BigInteger.valueOf(1000), "Hello");
transactionResponse =
client.getTransaction(transactionReceipt.getTransactionHash(), true).getResult();
}

@Override
Expand All @@ -66,28 +87,13 @@ protected void finalize() {

@Test
public void testTxHashCalculate() throws IOException {
if (transactionResponse == null && block.getNumber() == 0) {
if (transactionResponse == null) {
return;
}
String chainId = transactionResponse.getChainID();
String groupId = transactionResponse.getGroupID();
long blockLimit = transactionResponse.getBlockLimit();
String nonce = transactionResponse.getNonce();
String contractAddress = transactionResponse.getTo();
String encodedAbi = transactionResponse.getInput();
String abi = transactionResponse.getAbi();
block =
client.getBlockByNumber(transactionReceipt.getBlockNumber(), false, false)
.getBlock();

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// version
byteArrayOutputStream.write(
toBytesPadded(BigInteger.valueOf(transactionResponse.getVersion()), 4));
// chainId
byteArrayOutputStream.write(chainId.getBytes());
// groupId
byteArrayOutputStream.write(groupId.getBytes());
// blockLimit
byteArrayOutputStream.write(toBytesPadded(BigInteger.valueOf(blockLimit), 8));
// nonce
String version =
client.getGroupInfo()
.getResult()
Expand All @@ -101,58 +107,141 @@ public void testTxHashCalculate() throws IOException {
.compareTo(EnumNodeVersion.BCOS_3_3_0.toVersionObj())
>= 0) {
System.out.println("use hex decode nonce");
byteArrayOutputStream.write(Hex.decode(nonce));
String calculateTxHashInNative =
transactionResponse.calculateTxHashInNative(client.getCryptoSuite().hashImpl);
Assert.assertEquals(calculateTxHashInNative, transactionResponse.getHash());
String hash1 =
transactionResponse.calculateHash(client.getCryptoSuite().cryptoTypeConfig);
Assert.assertEquals(hash1, transactionResponse.getHash());
} else {
System.out.println("use string nonce");
byteArrayOutputStream.write(nonce.getBytes());
String jniHash = transactionResponse.calculateHash(client.getCryptoSuite());
Assert.assertEquals(jniHash, transactionResponse.getHash());
}
// to
byteArrayOutputStream.write(contractAddress.getBytes());
// input
byteArrayOutputStream.write(Hex.decode(encodedAbi));
// abi
byteArrayOutputStream.write(abi.getBytes());

if (transactionResponse.getVersion() >= TransactionVersion.V1.getValue()) {
byteArrayOutputStream.write(transactionResponse.getValue().getBytes());
byteArrayOutputStream.write(transactionResponse.getGasPrice().getBytes());
byteArrayOutputStream.write(
toBytesPadded(BigInteger.valueOf(transactionResponse.getGasLimit()), 8));
byteArrayOutputStream.write(transactionResponse.getMaxFeePerGas().getBytes());
byteArrayOutputStream.write(transactionResponse.getMaxPriorityFeePerGas().getBytes());
if (client.getChainCompatibilityVersion()
.compareTo(EnumNodeVersion.BCOS_3_2_0.toVersionObj())
< 0) {
return;
}
if (client.getCryptoSuite().cryptoTypeConfig == CryptoType.ECDSA_TYPE) {
boolean verifyMerkle =
MerkleProofUtility.verifyMerkle(
block.getTransactionsRoot(),
transactionResponse.getTxProof(),
transactionResponse.getHash(),
new Keccak256());
Assert.assertTrue(verifyMerkle);
}
if (client.getCryptoSuite().cryptoTypeConfig == CryptoType.SM_TYPE) {
boolean verifyMerkle =
MerkleProofUtility.verifyMerkle(
block.getTransactionsRoot(),
transactionResponse.getTxProof(),
transactionResponse.getHash(),
new SM3Hash());
Assert.assertTrue(verifyMerkle);
}
}

if(transactionResponse.getVersion() == TransactionVersion.V2.getValue()){
byteArrayOutputStream.write(transactionResponse.getExtension());
@Test
public void testTxV1HashCalculate() throws IOException {
if (transactionResponseV1 == null) {
return;
}
block =
client.getBlockByNumber(transactionReceiptV1.getBlockNumber(), false, false)
.getBlock();
String version =
client.getGroupInfo()
.getResult()
.getNodeList()
.get(0)
.getIniConfig()
.getBinaryInfo()
.getVersion();
System.out.println("node bin version: " + version);

String jniHash =
transactionResponseV1.calculateHash(client.getCryptoSuite().cryptoTypeConfig);
Assert.assertEquals(jniHash, transactionResponseV1.getHash());
String nativeHash =
transactionResponseV1.calculateTxHashInNative(client.getCryptoSuite().hashImpl);
Assert.assertEquals(nativeHash, transactionResponseV1.getHash());

String hash = "";
if (client.getCryptoSuite().cryptoTypeConfig == CryptoType.ECDSA_TYPE) {
hash = Keccak256.calculateHash(byteArrayOutputStream.toByteArray());
boolean verifyMerkle =
MerkleProofUtility.verifyMerkle(
block.getTransactionsRoot(),
transactionResponseV1.getTxProof(),
transactionResponseV1.getHash(),
new Keccak256());
Assert.assertTrue(verifyMerkle);
}
if (client.getCryptoSuite().cryptoTypeConfig == CryptoType.SM_TYPE) {
hash = SM3Hash.calculateHash((byteArrayOutputStream.toByteArray()));
boolean verifyMerkle =
MerkleProofUtility.verifyMerkle(
block.getTransactionsRoot(),
transactionResponseV1.getTxProof(),
transactionResponseV1.getHash(),
new SM3Hash());
Assert.assertTrue(verifyMerkle);
}
hash = Hex.addPrefix(hash);
Assert.assertEquals(hash, transactionResponse.getHash());
if (EnumNodeVersion.getClassVersion(version)
.compareTo(EnumNodeVersion.BCOS_3_3_0.toVersionObj())
< 0) {
String jniHash = transactionResponse.calculateHash(client.getCryptoSuite());
Assert.assertEquals(jniHash, transactionResponse.getHash());
} else {
String hash1 =
transactionResponse.calculateHash(client.getCryptoSuite().cryptoTypeConfig);
Assert.assertEquals(hash1, transactionResponse.getHash());
}

@Test
public void testTxV2HashCalculate() throws IOException {
if (transactionResponseV2 == null) {
return;
}
block =
client.getBlockByNumber(transactionReceiptV2.getBlockNumber(), false, false)
.getBlock();
String version =
client.getGroupInfo()
.getResult()
.getNodeList()
.get(0)
.getIniConfig()
.getBinaryInfo()
.getVersion();
System.out.println("node bin version: " + version);
String jniHash =
transactionResponseV2.calculateHash(client.getCryptoSuite().cryptoTypeConfig);
Assert.assertEquals(jniHash, transactionResponseV2.getHash());
String nativeHash =
transactionResponseV2.calculateTxHashInNative(client.getCryptoSuite().hashImpl);
Assert.assertEquals(nativeHash, transactionResponseV2.getHash());

if (client.getCryptoSuite().cryptoTypeConfig == CryptoType.ECDSA_TYPE) {
boolean verifyMerkle =
MerkleProofUtility.verifyMerkle(
block.getTransactionsRoot(),
transactionResponseV2.getTxProof(),
transactionResponseV2.getHash(),
new Keccak256());
Assert.assertTrue(verifyMerkle);
}
if (client.getCryptoSuite().cryptoTypeConfig == CryptoType.SM_TYPE) {
boolean verifyMerkle =
MerkleProofUtility.verifyMerkle(
block.getTransactionsRoot(),
transactionResponseV2.getTxProof(),
transactionResponseV2.getHash(),
new SM3Hash());
Assert.assertTrue(verifyMerkle);
}
}

@Test
public void testBlock() throws IOException {

if (block == null) {
block =
client.getBlockByNumber(transactionReceipt.getBlockNumber(), false, false)
.getBlock();
}

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

// version
Expand Down Expand Up @@ -203,45 +292,30 @@ public void testBlock() throws IOException {
}

@Test
public void testTxProof() {
if (transactionResponse == null && block.getNumber() == 0) {
return;
}
if (client.getChainCompatibilityVersion()
.compareTo(EnumNodeVersion.BCOS_3_2_0.toVersionObj())
< 0) {
return;
}
if (client.getCryptoSuite().cryptoTypeConfig == CryptoType.ECDSA_TYPE) {
boolean verifyMerkle =
MerkleProofUtility.verifyMerkle(
block.getTransactionsRoot(),
transactionResponse.getTxProof(),
transactionResponse.getHash(),
new Keccak256());
Assert.assertTrue(verifyMerkle);
}
if (client.getCryptoSuite().cryptoTypeConfig == CryptoType.SM_TYPE) {
boolean verifyMerkle =
MerkleProofUtility.verifyMerkle(
block.getTransactionsRoot(),
transactionResponse.getTxProof(),
transactionResponse.getHash(),
new SM3Hash());
Assert.assertTrue(verifyMerkle);
}
public void testTransactionReceipt() throws IOException {
checkTransactionReceipt(transactionReceipt);
}

// @Test
// FIXME: need to fix in new tx
public void testTransactionReceipt() throws IOException {
if (transactionReceipt == null && block.getNumber() == 0) {
@Test
public void testTransactionReceiptV1() throws IOException {
checkTransactionReceipt(transactionReceiptV1);
}

@Test
public void testTransactionReceiptV2() throws IOException {
checkTransactionReceipt(transactionReceiptV2);
}

private void checkTransactionReceipt(TransactionReceipt transactionReceipt) throws IOException {
if (transactionReceipt == null) {
return;
}
block =
client.getBlockByNumber(transactionReceipt.getBlockNumber(), false, false)
.getBlock();
String hash =
transactionReceipt.calculateReceiptHashInNative(client.getCryptoSuite().hashImpl);
Assert.assertEquals(hash, transactionReceipt.getReceiptHash());

if (client.getChainCompatibilityVersion()
.compareTo(EnumNodeVersion.BCOS_3_2_0.toVersionObj())
< 0) {
Expand Down
Loading

0 comments on commit 3685137

Please sign in to comment.