From a8fdd86149c790afa0a77fa2e7b44106b0ae99e0 Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Thu, 5 Dec 2024 14:25:02 +0200 Subject: [PATCH 01/11] chore: add precheck for receivers account in sendRawTransactionCheck Signed-off-by: Nadezhda Popova --- packages/relay/src/lib/precheck.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index 98e247456d..196829d13f 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -20,7 +20,6 @@ import { ethers, Transaction } from 'ethers'; import { Logger } from 'pino'; - import { prepend0x } from '../formatters'; import { MirrorNodeClient } from './clients'; import constants from './constants'; @@ -85,6 +84,9 @@ export class Precheck { this.value(parsedTx); this.gasPrice(parsedTx, networkGasPriceInWeiBars, requestDetails); this.balance(parsedTx, mirrorAccountInfo, requestDetails); + if (parsedTx.to) { + await this.receiverAccount(parsedTx, requestDetails); + } } /** @@ -376,4 +378,17 @@ export class Precheck { throw predefined.UNSUPPORTED_TRANSACTION_TYPE; } } + + /** + * Checks if the receiver account exists. + * @param {Transaction} tx - The transaction. + * @param {RequestDetails} requestDetails - The request details for logging and tracking. + */ + async receiverAccount(tx: Transaction, requestDetails: RequestDetails) { + const verifyAccount = await this.mirrorNodeClient.getAccount(tx.to!, requestDetails); + + if (verifyAccount !== null && verifyAccount.receiver_sig_required === true) { + throw predefined.INTERNAL_ERROR("Receiver's signature is required."); + } + } } From a8922478a10e93308f6942c5c87f984e61b23116 Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Thu, 5 Dec 2024 16:55:06 +0200 Subject: [PATCH 02/11] fixup! chore: add precheck for receivers account in sendRawTransactionCheck Signed-off-by: Nadezhda Popova --- .../relay/tests/lib/eth/eth_sendRawTransaction.spec.ts | 9 +++++++++ packages/relay/tests/lib/openrpc.spec.ts | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts index 7f87e73576..dad1335b35 100644 --- a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts +++ b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts @@ -99,6 +99,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () let clock: any; const accountAddress = '0x9eaee9E66efdb91bfDcF516b034e001cc535EB57'; const accountEndpoint = `accounts/${accountAddress}${NO_TRANSACTIONS}`; + const receiverAccountEndpoint = `accounts/${ACCOUNT_ADDRESS_1}${NO_TRANSACTIONS}`; const gasPrice = '0xad78ebc5ac620000'; const transactionIdServicesFormat = '0.0.902@1684375868.230217103'; const transactionId = '0.0.902-1684375868-230217103'; @@ -127,6 +128,13 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () balance: Hbar.from(100_000_000_000, HbarUnit.Hbar).to(HbarUnit.Tinybar), }, }; + const RECEIVER_ACCOUNT_RES = { + account: ACCOUNT_ADDRESS_1, + balance: { + balance: Hbar.from(100_000_000_000, HbarUnit.Hbar).to(HbarUnit.Tinybar), + }, + receiver_sig_required: false, + }; const useAsyncTxProcessing = ConfigService.get('USE_ASYNC_TX_PROCESSING') as boolean; beforeEach(() => { @@ -135,6 +143,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () sdkClientStub = sinon.createStubInstance(SDKClient); sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub); restMock.onGet(accountEndpoint).reply(200, ACCOUNT_RES); + restMock.onGet(receiverAccountEndpoint).reply(200, RECEIVER_ACCOUNT_RES); restMock.onGet(networkExchangeRateEndpoint).reply(200, mockedExchangeRate); }); diff --git a/packages/relay/tests/lib/openrpc.spec.ts b/packages/relay/tests/lib/openrpc.spec.ts index fd832c48d3..3c1a1b3ae2 100644 --- a/packages/relay/tests/lib/openrpc.spec.ts +++ b/packages/relay/tests/lib/openrpc.spec.ts @@ -75,7 +75,7 @@ import { overrideEnvsInMochaDescribe, signedTransactionHash, } from '../helpers'; -import { NOT_FOUND_RES } from './eth/eth-config'; +import { CONTRACT_RESULT_MOCK, NOT_FOUND_RES } from './eth/eth-config'; const logger = pino(); const registry = new Registry(); @@ -229,6 +229,7 @@ describe('Open RPC Specification', function () { mock.onGet(`accounts/${defaultContractResults.results[1].from}?transactions=false`).reply(200); mock.onGet(`accounts/${defaultContractResults.results[0].to}?transactions=false`).reply(200); mock.onGet(`accounts/${defaultContractResults.results[1].to}?transactions=false`).reply(200); + mock.onGet(`accounts/${CONTRACT_RESULT_MOCK.from}?transactions=false`).reply(200, CONTRACT_RESULT_MOCK); mock.onGet(`contracts/${defaultContractResults.results[0].from}`).reply(404, NOT_FOUND_RES); mock.onGet(`contracts/${defaultContractResults.results[1].from}`).reply(404, NOT_FOUND_RES); mock.onGet(`contracts/${defaultContractResults.results[0].to}`).reply(200); From 4604f1fca271b0ec3d6670ea61f98dc0ada3bc13 Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Wed, 11 Dec 2024 16:31:37 +0200 Subject: [PATCH 03/11] fixup! fixup! chore: add precheck for receivers account in sendRawTransactionCheck Signed-off-by: Nadezhda Popova --- packages/relay/src/lib/precheck.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index 196829d13f..a8acf1273b 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -84,9 +84,7 @@ export class Precheck { this.value(parsedTx); this.gasPrice(parsedTx, networkGasPriceInWeiBars, requestDetails); this.balance(parsedTx, mirrorAccountInfo, requestDetails); - if (parsedTx.to) { - await this.receiverAccount(parsedTx, requestDetails); - } + await this.receiverAccount(parsedTx, requestDetails); } /** @@ -380,15 +378,18 @@ export class Precheck { } /** - * Checks if the receiver account exists. + * Checks if the receiver account exists and has receiver_sig_required set to true. * @param {Transaction} tx - The transaction. * @param {RequestDetails} requestDetails - The request details for logging and tracking. */ async receiverAccount(tx: Transaction, requestDetails: RequestDetails) { - const verifyAccount = await this.mirrorNodeClient.getAccount(tx.to!, requestDetails); + if (tx.to) { + const verifyAccount = await this.mirrorNodeClient.getAccount(tx.to!, requestDetails); - if (verifyAccount !== null && verifyAccount.receiver_sig_required === true) { - throw predefined.INTERNAL_ERROR("Receiver's signature is required."); + // When `receiver_sig_required` is set to true, the receiver's account must sign all incoming transactions. + if (verifyAccount !== null && verifyAccount.receiver_sig_required === true) { + throw predefined.RECEIVER_SIGNATURE_REQUIRED; + } } } } From 3b85b1a63218fd1ca6ae3324df442d6f3fa6702d Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Wed, 11 Dec 2024 16:33:14 +0200 Subject: [PATCH 04/11] test: add test for receivers account precheck Signed-off-by: Nadezhda Popova --- packages/relay/src/lib/errors/JsonRpcError.ts | 4 ++ .../tests/acceptance/rpc_batch1.spec.ts | 49 ++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/relay/src/lib/errors/JsonRpcError.ts b/packages/relay/src/lib/errors/JsonRpcError.ts index bd559a86f5..d500a6c844 100644 --- a/packages/relay/src/lib/errors/JsonRpcError.ts +++ b/packages/relay/src/lib/errors/JsonRpcError.ts @@ -238,6 +238,10 @@ export const predefined = { code: -39013, message: 'Invalid block range', }), + RECEIVER_SIGNATURE_REQUIRED: new JsonRpcError({ + code: -32000, + message: "Receiver's signature is required.", + }), FILTER_NOT_FOUND: new JsonRpcError({ code: -32001, message: 'Filter not found', diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 7fd20a5c19..354eb8402d 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -26,7 +26,14 @@ import Constants from '@hashgraph/json-rpc-relay/dist/lib/constants'; // Errors and constants from local resources import { predefined } from '@hashgraph/json-rpc-relay/dist/lib/errors/JsonRpcError'; import { RequestDetails } from '@hashgraph/json-rpc-relay/dist/lib/types'; -import { FileInfo, FileInfoQuery, Hbar, TransferTransaction } from '@hashgraph/sdk'; +import { + AccountCreateTransaction, + FileInfo, + FileInfoQuery, + Hbar, + PrivateKey, + TransferTransaction, +} from '@hashgraph/sdk'; import { expect } from 'chai'; import { ethers } from 'ethers'; @@ -1586,6 +1593,46 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const error = predefined.NONCE_TOO_LOW(nonce, nonce + 1); await Assertions.assertPredefinedRpcError(error, sendRawTransaction, true, relay, [signedTx, requestDetails]); }); + + it('should fail "eth_sendRawTransaction" if receiver\'s account has receiver_sig_required enabled', async function () { + const newPrivateKey = PrivateKey.generateED25519(); + const newAccount = await new AccountCreateTransaction() + .setKey(newPrivateKey.publicKey) + .setInitialBalance(100) + .setReceiverSignatureRequired(true) + .freezeWith(servicesNode.client) + .sign(newPrivateKey); + + const transaction = await newAccount.execute(servicesNode.client); + const receipt = await transaction.getReceipt(servicesNode.client); + + if (!receipt.accountId) { + throw new Error('Failed to create new account - accountId is null'); + } + + const toAddress = Utils.idToEvmAddress(receipt.accountId.toString()); + const tx = { + nonce: await accounts[0].wallet.getNonce(), + chainId: CHAIN_ID, + to: toAddress, + from: accounts[0].address, + value: '0x2E90EDD000', + gasLimit: defaultGasLimit, + accessList: [], + maxPriorityFeePerGas: defaultGasPrice, + maxFeePerGas: defaultGasPrice, + }; + + const signedTx = await accounts[0].wallet.signTransaction(tx); + await new Promise((r) => setTimeout(r, 3000)); + + const error = predefined.RECEIVER_SIGNATURE_REQUIRED; + + await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [ + signedTx, + requestDetails, + ]); + }); }); it('@release should execute "eth_getTransactionByHash" for existing transaction', async function () { From 62b7885bd3aa476e48f6ecacc4ba9b5b9e151e9f Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Thu, 12 Dec 2024 19:16:47 +0200 Subject: [PATCH 05/11] fixup! test: add test for receivers account precheck Signed-off-by: Nadezhda Popova --- packages/relay/src/lib/precheck.ts | 3 +- .../tests/acceptance/rpc_batch1.spec.ts | 41 ++++++++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index a8acf1273b..d4e7701dcc 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -20,6 +20,7 @@ import { ethers, Transaction } from 'ethers'; import { Logger } from 'pino'; + import { prepend0x } from '../formatters'; import { MirrorNodeClient } from './clients'; import constants from './constants'; @@ -384,7 +385,7 @@ export class Precheck { */ async receiverAccount(tx: Transaction, requestDetails: RequestDetails) { if (tx.to) { - const verifyAccount = await this.mirrorNodeClient.getAccount(tx.to!, requestDetails); + const verifyAccount = await this.mirrorNodeClient.getAccount(tx.to, requestDetails); // When `receiver_sig_required` is set to true, the receiver's account must sign all incoming transactions. if (verifyAccount !== null && verifyAccount.receiver_sig_required === true) { diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 354eb8402d..0309aa1fc7 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -1612,15 +1612,11 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const toAddress = Utils.idToEvmAddress(receipt.accountId.toString()); const tx = { + ...defaultLegacyTransactionData, + chainId: Number(CHAIN_ID), nonce: await accounts[0].wallet.getNonce(), - chainId: CHAIN_ID, to: toAddress, from: accounts[0].address, - value: '0x2E90EDD000', - gasLimit: defaultGasLimit, - accessList: [], - maxPriorityFeePerGas: defaultGasPrice, - maxFeePerGas: defaultGasPrice, }; const signedTx = await accounts[0].wallet.signTransaction(tx); @@ -1633,6 +1629,39 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { requestDetails, ]); }); + + it('should execute "eth_sendRawTransaction" if receiver\'s account has receiver_sig_required disabled', async function () { + const newPrivateKey = PrivateKey.generateED25519(); + const newAccount = await new AccountCreateTransaction() + .setKey(newPrivateKey.publicKey) + .setInitialBalance(100) + .setReceiverSignatureRequired(false) + .freezeWith(servicesNode.client) + .sign(newPrivateKey); + + const transaction = await newAccount.execute(servicesNode.client); + const receipt = await transaction.getReceipt(servicesNode.client); + + if (!receipt.accountId) { + throw new Error('Failed to create new account - accountId is null'); + } + + const toAddress = Utils.idToEvmAddress(receipt.accountId.toString()); + const tx = { + ...defaultLegacyTransactionData, + chainId: Number(CHAIN_ID), + nonce: await accounts[0].wallet.getNonce(), + to: toAddress, + from: accounts[0].address, + }; + + const signedTx = await accounts[0].wallet.signTransaction(tx); + const transactionHash = await relay.sendRawTransaction(signedTx, requestId); + const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId); + + expect(info).to.exist; + expect(info.result).to.equal('SUCCESS'); + }); }); it('@release should execute "eth_getTransactionByHash" for existing transaction', async function () { From 12cdbe76b484b00dd82aeaea00ffb9ec179a1d8e Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Thu, 12 Dec 2024 20:30:14 +0200 Subject: [PATCH 06/11] fixup! fixup! test: add test for receivers account precheck Signed-off-by: Nadezhda Popova --- packages/relay/tests/lib/precheck.spec.ts | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/relay/tests/lib/precheck.spec.ts b/packages/relay/tests/lib/precheck.spec.ts index c793c3911a..5a4a3cf169 100644 --- a/packages/relay/tests/lib/precheck.spec.ts +++ b/packages/relay/tests/lib/precheck.spec.ts @@ -654,4 +654,50 @@ describe('Precheck', async function () { expect(error.code).to.equal(predefined.UNSUPPORTED_TRANSACTION_TYPE.code); }); }); + + describe('receiverAccount', async function () { + let parsedTx: Transaction; + let mirrorAccountTo: any; + const defaultNonce: number = 4; + const toAddress = ethers.Wallet.createRandom().address; + + before(async () => { + const wallet = ethers.Wallet.createRandom(); + const signed = await wallet.signTransaction({ + ...defaultTx, + from: wallet.address, + to: toAddress, + nonce: defaultNonce, + }); + + parsedTx = ethers.Transaction.from(signed); + }); + + it('should fail with signature required error', async function () { + mirrorAccountTo = { + receiver_sig_required: true, + }; + + mock.onGet(`accounts/${parsedTx.to}${transactionsPostFix}`).reply(200, mirrorAccountTo); + + try { + await precheck.receiverAccount(parsedTx, requestDetails); + expectedError(); + } catch (e: any) { + expect(e).to.exist; + expect(e.code).to.eq(-32000); + expect(e).to.eql(predefined.RECEIVER_SIGNATURE_REQUIRED); + } + }); + + it('should accept check if signature required is set to false', async function () { + mirrorAccountTo = { + receiver_sig_required: false, + }; + + mock.onGet(`accounts/${parsedTx.to}${transactionsPostFix}`).reply(200, mirrorAccountTo); + + expect(async () => await precheck.receiverAccount(parsedTx, requestDetails)).not.to.throw; + }); + }); }); From 41102a08080a6c92f08d50d765f97919cbd91292 Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Thu, 12 Dec 2024 21:27:42 +0200 Subject: [PATCH 07/11] fixup! fixup! fixup! test: add test for receivers account precheck Signed-off-by: Nadezhda Popova --- packages/relay/src/lib/errors/JsonRpcError.ts | 4 ++-- packages/relay/src/lib/precheck.ts | 2 +- packages/relay/tests/lib/precheck.spec.ts | 2 +- packages/server/tests/acceptance/rpc_batch1.spec.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/relay/src/lib/errors/JsonRpcError.ts b/packages/relay/src/lib/errors/JsonRpcError.ts index d500a6c844..7e17207b5b 100644 --- a/packages/relay/src/lib/errors/JsonRpcError.ts +++ b/packages/relay/src/lib/errors/JsonRpcError.ts @@ -238,9 +238,9 @@ export const predefined = { code: -39013, message: 'Invalid block range', }), - RECEIVER_SIGNATURE_REQUIRED: new JsonRpcError({ + RECEIVER_SIGNATURE_ENABLED: new JsonRpcError({ code: -32000, - message: "Receiver's signature is required.", + message: "Receiver's signature is enabled.", }), FILTER_NOT_FOUND: new JsonRpcError({ code: -32001, diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index d4e7701dcc..f0c313b15e 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -389,7 +389,7 @@ export class Precheck { // When `receiver_sig_required` is set to true, the receiver's account must sign all incoming transactions. if (verifyAccount !== null && verifyAccount.receiver_sig_required === true) { - throw predefined.RECEIVER_SIGNATURE_REQUIRED; + throw predefined.RECEIVER_SIGNATURE_ENABLED; } } } diff --git a/packages/relay/tests/lib/precheck.spec.ts b/packages/relay/tests/lib/precheck.spec.ts index 5a4a3cf169..46a70bc3a3 100644 --- a/packages/relay/tests/lib/precheck.spec.ts +++ b/packages/relay/tests/lib/precheck.spec.ts @@ -686,7 +686,7 @@ describe('Precheck', async function () { } catch (e: any) { expect(e).to.exist; expect(e.code).to.eq(-32000); - expect(e).to.eql(predefined.RECEIVER_SIGNATURE_REQUIRED); + expect(e).to.eql(predefined.RECEIVER_SIGNATURE_ENABLED); } }); diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 0309aa1fc7..7ae01cbe53 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -1622,7 +1622,7 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const signedTx = await accounts[0].wallet.signTransaction(tx); await new Promise((r) => setTimeout(r, 3000)); - const error = predefined.RECEIVER_SIGNATURE_REQUIRED; + const error = predefined.RECEIVER_SIGNATURE_ENABLED; await Assertions.assertPredefinedRpcError(error, sendRawTransaction, false, relay, [ signedTx, From 5850f89d8aeee847400919b3f8040897cb8d21f3 Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Fri, 13 Dec 2024 10:22:40 +0200 Subject: [PATCH 08/11] fixup! fixup! fixup! fixup! test: add test for receivers account precheck Signed-off-by: Nadezhda Popova --- packages/server/tests/acceptance/rpc_batch1.spec.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 7ae01cbe53..8e262c40bf 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -1611,6 +1611,10 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { } const toAddress = Utils.idToEvmAddress(receipt.accountId.toString()); + const verifyAccount = await mirrorNode.get(`/accounts/${toAddress}`, requestId); + + expect(verifyAccount.receiver_sig_required).to.be.true; + const tx = { ...defaultLegacyTransactionData, chainId: Number(CHAIN_ID), @@ -1620,7 +1624,6 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { }; const signedTx = await accounts[0].wallet.signTransaction(tx); - await new Promise((r) => setTimeout(r, 3000)); const error = predefined.RECEIVER_SIGNATURE_ENABLED; @@ -1647,6 +1650,10 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { } const toAddress = Utils.idToEvmAddress(receipt.accountId.toString()); + const verifyAccount = await mirrorNode.get(`/accounts/${toAddress}`, requestId); + + expect(verifyAccount.receiver_sig_required).to.be.false; + const tx = { ...defaultLegacyTransactionData, chainId: Number(CHAIN_ID), From f43a76e26b305897a5d3dfe3e14de1bb8119a645 Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Fri, 13 Dec 2024 13:53:17 +0200 Subject: [PATCH 09/11] fixup! fixup! fixup! fixup! fixup! test: add test for receivers account precheck Signed-off-by: Nadezhda Popova --- packages/relay/src/lib/precheck.ts | 2 +- packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/relay/src/lib/precheck.ts b/packages/relay/src/lib/precheck.ts index f0c313b15e..27a0e8ac54 100644 --- a/packages/relay/src/lib/precheck.ts +++ b/packages/relay/src/lib/precheck.ts @@ -388,7 +388,7 @@ export class Precheck { const verifyAccount = await this.mirrorNodeClient.getAccount(tx.to, requestDetails); // When `receiver_sig_required` is set to true, the receiver's account must sign all incoming transactions. - if (verifyAccount !== null && verifyAccount.receiver_sig_required === true) { + if (verifyAccount && verifyAccount.receiver_sig_required) { throw predefined.RECEIVER_SIGNATURE_ENABLED; } } diff --git a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts index dad1335b35..28970ef870 100644 --- a/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts +++ b/packages/relay/tests/lib/eth/eth_sendRawTransaction.spec.ts @@ -131,7 +131,7 @@ describe('@ethSendRawTransaction eth_sendRawTransaction spec', async function () const RECEIVER_ACCOUNT_RES = { account: ACCOUNT_ADDRESS_1, balance: { - balance: Hbar.from(100_000_000_000, HbarUnit.Hbar).to(HbarUnit.Tinybar), + balance: Hbar.from(1, HbarUnit.Hbar).to(HbarUnit.Tinybar), }, receiver_sig_required: false, }; From 2dc942a6fe34783d760bcb3368004775cc5af42e Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Fri, 13 Dec 2024 17:56:00 +0200 Subject: [PATCH 10/11] fixup! fixup! fixup! fixup! fixup! fixup! test: add test for receivers account precheck Signed-off-by: Nadezhda Popova --- packages/relay/src/lib/errors/JsonRpcError.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/relay/src/lib/errors/JsonRpcError.ts b/packages/relay/src/lib/errors/JsonRpcError.ts index 7e17207b5b..89fd1680b4 100644 --- a/packages/relay/src/lib/errors/JsonRpcError.ts +++ b/packages/relay/src/lib/errors/JsonRpcError.ts @@ -240,7 +240,7 @@ export const predefined = { }), RECEIVER_SIGNATURE_ENABLED: new JsonRpcError({ code: -32000, - message: "Receiver's signature is enabled.", + message: "Operation is not supported when receiver's signature is enabled.", }), FILTER_NOT_FOUND: new JsonRpcError({ code: -32001, From 2ccf78d3f884c030dc10cb6e92579ba575fbc410 Mon Sep 17 00:00:00 2001 From: Nadezhda Popova Date: Mon, 16 Dec 2024 18:08:48 +0200 Subject: [PATCH 11/11] fixup! fixup! fixup! fixup! fixup! fixup! fixup! test: add test for receivers account precheck Signed-off-by: Nadezhda Popova --- packages/server/tests/acceptance/rpc_batch1.spec.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/server/tests/acceptance/rpc_batch1.spec.ts b/packages/server/tests/acceptance/rpc_batch1.spec.ts index 8e262c40bf..0c41b43478 100644 --- a/packages/server/tests/acceptance/rpc_batch1.spec.ts +++ b/packages/server/tests/acceptance/rpc_batch1.spec.ts @@ -1613,6 +1613,10 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const toAddress = Utils.idToEvmAddress(receipt.accountId.toString()); const verifyAccount = await mirrorNode.get(`/accounts/${toAddress}`, requestId); + if (verifyAccount && !verifyAccount.account) { + verifyAccount == (await mirrorNode.get(`/accounts/${toAddress}`, requestId)); + } + expect(verifyAccount.receiver_sig_required).to.be.true; const tx = { @@ -1652,6 +1656,10 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () { const toAddress = Utils.idToEvmAddress(receipt.accountId.toString()); const verifyAccount = await mirrorNode.get(`/accounts/${toAddress}`, requestId); + if (verifyAccount && !verifyAccount.account) { + verifyAccount == (await mirrorNode.get(`/accounts/${toAddress}`, requestId)); + } + expect(verifyAccount.receiver_sig_required).to.be.false; const tx = {