Skip to content

Commit

Permalink
release: v2.42.0 (#2177)
Browse files Browse the repository at this point in the history
* version

Signed-off-by: svetoslav-nikol0v <[email protected]>

* release notes

Signed-off-by: svetoslav-nikol0v <[email protected]>

* stringify the value

Signed-off-by: svetoslav-nikol0v <[email protected]>

* address books update

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: update version, changelog, address books

Signed-off-by: svetoslav-nikol0v <[email protected]>

* feature: handling and externalisation improvements for account nonce updates (#2176)

* chore: all necessary stuff for release

Signed-off-by: svetoslav-nikol0v <[email protected]>

* feature: add signerNonce field

Signed-off-by: svetoslav-nikol0v <[email protected]>

---------

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: remove .only

Signed-off-by: svetoslav-nikol0v <[email protected]>

* fix: release workflow

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: skip the test suit for ethereum transaction

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: add more details

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: typo

Signed-off-by: svetoslav-nikol0v <[email protected]>

---------

Signed-off-by: svetoslav-nikol0v <[email protected]>
  • Loading branch information
svetoslav-nikol0v authored Mar 12, 2024
1 parent 841655f commit 03d4fce
Show file tree
Hide file tree
Showing 11 changed files with 222 additions and 12 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/publish_release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
RELEASE_VERSION="$(semver get release "${REF_NAME}")"
PREREL_VERSION="$(semver get prerel "${REF_NAME}")"
PREREL_VERSION_LC="$(printf "%s" "${PREREL_VERSION}" | tr '[:upper:]' '[:lower:]')"
IS_PRERELEASE="false"
[[ -n "${PREREL_VERSION}" ]] && IS_PRERELEASE="true"
Expand Down Expand Up @@ -111,6 +111,11 @@ jobs:
exit 2
fi
if [[ "${{ steps.tag.outputs.type }}" != "production" && "${{ steps.tag.outputs.type }}" != "beta" ]]; then
echo "::error title=Unsupported PreRelease::The tag '${{ steps.tag.outputs.name }}' is an unsupported prerelease tag. Only 'beta' prereleases are supported."
exit 2
fi
run-safety-checks:
name: Safety Checks
runs-on: [self-hosted, Linux, medium, ephemeral]
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## v2.42.0

## What's Changed

* feature: handling and externalisation improvements for account nonce updates (HIP-844) by @svetoslav-nikol0v in https://github.com/hashgraph/hedera-sdk-js/pull/2176

## v2.42.0-beta.4

## What's Changed
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hashgraph/sdk",
"version": "2.42.0-beta.4",
"version": "2.42.0",
"description": "Hedera™ Hashgraph SDK",
"types": "./lib/index.d.ts",
"main": "./lib/index.cjs",
Expand Down Expand Up @@ -58,7 +58,7 @@
"@ethersproject/rlp": "^5.7.0",
"@grpc/grpc-js": "1.8.2",
"@hashgraph/cryptography": "1.4.8-beta.5",
"@hashgraph/proto": "2.14.0-beta.3",
"@hashgraph/proto": "2.14.0-beta.4",
"axios": "^1.6.4",
"bignumber.js": "^9.1.1",
"bn.js": "^5.1.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/proto/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hashgraph/proto",
"version": "2.14.0-beta.3",
"version": "2.14.0-beta.4",
"description": "Protobufs for the Hedera™ Hashgraph SDK",
"main": "lib/index.js",
"browser": "src/index.js",
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/client/addressbooks/mainnet.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/client/addressbooks/testnet.js

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions src/contract/ContractFunctionResult.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export default class ContractFunctionResult {
* @param {?AccountId} result.senderAccountId
* @param {ContractStateChange[]} result.stateChanges
* @param {ContractNonceInfo[]} result.contractNonces
* @param {Long | null} result.signerNonce
*/
constructor(result) {
/**
Expand Down Expand Up @@ -149,6 +150,12 @@ export default class ContractFunctionResult {
* This is always empty in a ContractCallLocalResponse#ContractFunctionResult message, since no internal creations can happen in a static EVM call.
*/
this.contractNonces = result.contractNonces;

/**
* If not null this field specifies what the value of the signer account nonce is post transaction execution.
* For transactions that don't update the signer nonce (like HAPI ContractCall and ContractCreate transactions) this field should be null.
*/
this.signerNonce = result.signerNonce;
}

/**
Expand Down Expand Up @@ -204,6 +211,12 @@ export default class ContractFunctionResult {
).map((contractNonce) =>
ContractNonceInfo._fromProtobuf(contractNonce),
),
signerNonce:
result.signerNonce != null
? result.signerNonce.value
? result.signerNonce.value
: null
: null,
});
}

Expand Down Expand Up @@ -1053,6 +1066,12 @@ export default class ContractFunctionResult {
contractNonces: this.contractNonces.map((contractNonce) =>
contractNonce._toProtobuf(),
),
signerNonce:
this.signerNonce != null
? {
value: this.signerNonce,
}
: null,
};
}
}
177 changes: 177 additions & 0 deletions test/integration/EthereumTransactionIntegrationTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import {
FileCreateTransaction,
ContractFunctionParameters,
ContractCreateTransaction,
EthereumTransaction,
PrivateKey,
TransferTransaction,
Hbar,
TransactionResponse,
TransactionReceipt,
FileId,
ContractId,
Status,
TransactionRecord,
} from "../../src/exports.js";
import { SMART_CONTRACT_BYTECODE } from "./contents.js";
import * as rlp from "@ethersproject/rlp";
import IntegrationTestEnv from "./client/NodeIntegrationTestEnv.js";
import * as hex from "../../src/encoding/hex.js";

/**
* @summary E2E-HIP-844
* @url https://hips.hedera.com/hip/hip-844
*
* @description
* At the moment the ethereum transaction behavior is not stable.
* Occasionally the test fails with the following error INVALID_ACCOUNT_ID.
* The test suite will be skipped until the problem is investigated and fixed.
*/

// eslint-disable-next-line mocha/no-skipped-tests
describe.skip("EthereumTransactionIntegrationTest", function () {
let env, operatorKey, wallet, contractAddress, operatorId;

before(async function () {
env = await IntegrationTestEnv.new();
wallet = env.wallet;
operatorKey = wallet.getAccountKey();
operatorId = wallet.getAccountId();
});

it("Signer nonce changed on Ethereum transaction", async function () {
this.timeout(120000);

try {
const fileResponse = await (
await (
await new FileCreateTransaction()
.setKeys([wallet.getAccountKey()])
.setContents(SMART_CONTRACT_BYTECODE)
.setMaxTransactionFee(new Hbar(2))
.freezeWithSigner(wallet)
).signWithSigner(wallet)
).executeWithSigner(wallet);
expect(fileResponse).to.be.instanceof(TransactionResponse);

const fileReceipt = await fileResponse.getReceiptWithSigner(wallet);
expect(fileReceipt).to.be.instanceof(TransactionReceipt);
expect(fileReceipt.status).to.be.equal(Status.Success);
const fileId = fileReceipt.fileId;
expect(fileId).to.be.instanceof(FileId);

const contractResponse = await (
await (
await new ContractCreateTransaction()
.setAdminKey(operatorKey)
.setGas(200000)
.setConstructorParameters(
new ContractFunctionParameters()
.addString("Hello from Hedera.")
._build(),
)
.setBytecodeFileId(fileId)
.setContractMemo("[e2e::ContractCreateTransaction]")
.freezeWithSigner(wallet)
).signWithSigner(wallet)
).executeWithSigner(wallet);
expect(contractResponse).to.be.instanceof(TransactionResponse);
const contractReceipt =
await contractResponse.getReceiptWithSigner(wallet);
expect(contractReceipt).to.be.instanceof(TransactionReceipt);
expect(contractReceipt.status).to.be.equal(Status.Success);
const contractId = contractReceipt.contractId;
expect(contractId).to.be.instanceof(ContractId);
contractAddress = contractId.toSolidityAddress();
} catch (error) {
console.error(error);
}

const type = "02";
const chainId = hex.decode("012a");
const nonce = new Uint8Array();
const maxPriorityGas = hex.decode("00");
const maxGas = hex.decode("d1385c7bf0");
const gasLimit = hex.decode("0249f0");
const value = new Uint8Array();
const to = hex.decode(contractAddress);
const callData = new ContractFunctionParameters()
.addString("new message")
._build("setMessage");
const accessList = [];

const encoded = rlp
.encode([
chainId,
nonce,
maxPriorityGas,
maxGas,
gasLimit,
to,
value,
callData,
accessList,
])
.substring(2);
expect(typeof encoded).to.equal("string");

const privateKey = PrivateKey.generateECDSA();
expect(privateKey).to.be.instanceof(PrivateKey);

const accountAlias = privateKey.publicKey.toEvmAddress();

const transfer = await new TransferTransaction()
.addHbarTransfer(operatorId, new Hbar(10).negated())
.addHbarTransfer(accountAlias, new Hbar(10))
.setMaxTransactionFee(new Hbar(1))
.freezeWithSigner(wallet);

const transferResponse = await transfer.executeWithSigner(wallet);
expect(transferResponse).to.be.instanceof(TransactionResponse);
const transferReceipt =
await transferResponse.getReceiptWithSigner(wallet);
expect(transferReceipt).to.be.instanceof(TransactionReceipt);
expect(transferReceipt.status).to.be.equal(Status.Success);

const signedBytes = privateKey.sign(hex.decode(type + encoded));
const middleOfSignedBytes = signedBytes.length / 2;
const r = signedBytes.slice(0, middleOfSignedBytes);
const s = signedBytes.slice(middleOfSignedBytes, signedBytes.length);
const v = hex.decode("01"); // recovery id

const data = rlp
.encode([
chainId,
nonce,
maxPriorityGas,
maxGas,
gasLimit,
to,
value,
callData,
accessList,
v,
r,
s,
])
.substring(2);
expect(typeof data).to.equal("string");
const ethereumData = hex.decode(type + data);
expect(ethereumData.length).to.be.gt(0);

const response = await (
await (
await new EthereumTransaction()
.setEthereumData(ethereumData)
.freezeWithSigner(wallet)
).signWithSigner(wallet)
).executeWithSigner(wallet);
const record = await response.getRecordWithSigner(wallet);
expect(record).to.be.instanceof(TransactionRecord);
expect(response).to.be.instanceof(TransactionResponse);

const receipt = await response.getReceiptWithSigner(wallet);
expect(receipt).to.be.instanceof(TransactionReceipt);
expect(receipt.status).to.be.equal(Status.Success);
});
});
4 changes: 2 additions & 2 deletions test/integration/client/BaseIntegrationTestEnv.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default class BaseIntegrationTestEnv {
options.env.OPERATOR_KEY != null
) {
const operatorId = AccountId.fromString(options.env.OPERATOR_ID);
const operatorKey = PrivateKey.fromString(options.env.OPERATOR_KEY);
const operatorKey = PrivateKey.fromStringDer(options.env.OPERATOR_KEY);

client.setOperator(operatorId, operatorKey);
}
Expand Down Expand Up @@ -122,7 +122,7 @@ export default class BaseIntegrationTestEnv {
}
client.setNetwork(network);

const newOperatorKey = PrivateKey.generateED25519();
const newOperatorKey = PrivateKey.generateECDSA();

const response = await new AccountCreateTransaction()
.setKey(newOperatorKey)
Expand Down
3 changes: 3 additions & 0 deletions test/integration/contents.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 03d4fce

Please sign in to comment.