Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/relay/src/lib/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ export class EthImpl implements Eth {
* @rpcParamValidationRules Applies JSON-RPC parameter validation according to the API specification
*
* @param {string} address - The account address for which to retrieve the transaction count.
* @param {string | null} blockNumOrTag - Possible values are 'earliest', 'pending', 'latest', or a block hash in hexadecimal format.
* @param {string} blockNumOrTag - Possible values are 'earliest', 'pending', 'latest', or a block hash in hexadecimal format.
* @param {RequestDetails} requestDetails - The details of the request for logging and tracking.
* @returns {Promise<string | JsonRpcError>} A promise that resolves to the transaction count in hexadecimal format or a JsonRpcError.
*/
Expand All @@ -921,7 +921,7 @@ export class EthImpl implements Eth {
})
async getTransactionCount(
address: string,
blockNumOrTag: string | null,
blockNumOrTag: string,
requestDetails: RequestDetails,
): Promise<string | JsonRpcError> {
return this.accountService.getTransactionCount(address, blockNumOrTag, requestDetails);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,12 @@ export class AccountService implements IAccountService {
* Queries mirror node for best effort and falls back to consensus node for contracts until HIP 729 is implemented.
*
* @param {string} address The account address
* @param {string | null} blockNumOrTag Possible values are earliest/pending/latest or hex
* @param {string} blockNumOrTag Possible values are earliest/pending/latest or hex
* @param {RequestDetails} requestDetails The request details for logging and tracking
*/
public async getTransactionCount(
address: string,
blockNumOrTag: string | null,
blockNumOrTag: string,
requestDetails: RequestDetails,
): Promise<string | JsonRpcError> {
const requestIdPrefix = requestDetails.formattedRequestId;
Expand All @@ -320,26 +320,21 @@ export class AccountService implements IAccountService {
}

const blockNum = Number(blockNumOrTag);
if (blockNumOrTag) {
if (blockNum === 0 || blockNum === 1) {
// previewnet and testnet bug have a genesis blockNumber of 1 but non system account were yet to be created
return constants.ZERO_HEX;
} else if (this.common.blockTagIsLatestOrPending(blockNumOrTag)) {
// if latest or pending, get latest ethereumNonce from mirror node account API
nonceCount = await this.getAccountLatestEthereumNonce(address, requestDetails);
} else if (blockNumOrTag === constants.BLOCK_EARLIEST) {
nonceCount = await this.getAccountNonceForEarliestBlock(requestDetails);
} else if (!isNaN(blockNum) && blockNumOrTag.length != constants.BLOCK_HASH_LENGTH && blockNum > 0) {
nonceCount = await this.getAccountNonceForHistoricBlock(address, blockNum, requestDetails);
} else if (blockNumOrTag.length == constants.BLOCK_HASH_LENGTH && blockNumOrTag.startsWith(constants.EMPTY_HEX)) {
nonceCount = await this.getAccountNonceForHistoricBlock(address, blockNumOrTag, requestDetails);
} else {
// return a '-39001: Unknown block' error per api-spec
throw predefined.UNKNOWN_BLOCK();
}
} else {
// if no block consideration, get latest ethereumNonce from mirror node if account or from consensus node is contract until HIP 729 is implemented
if (blockNum === 0 || blockNum === 1) {
// previewnet and testnet bug have a genesis blockNumber of 1 but non system account were yet to be created
return constants.ZERO_HEX;
} else if (this.common.blockTagIsLatestOrPending(blockNumOrTag)) {
// if latest or pending, get latest ethereumNonce from mirror node account API
nonceCount = await this.getAccountLatestEthereumNonce(address, requestDetails);
} else if (blockNumOrTag === constants.BLOCK_EARLIEST) {
nonceCount = await this.getAccountNonceForEarliestBlock(requestDetails);
} else if (!isNaN(blockNum) && blockNumOrTag.length != constants.BLOCK_HASH_LENGTH && blockNum > 0) {
nonceCount = await this.getAccountNonceForHistoricBlock(address, blockNum, requestDetails);
} else if (blockNumOrTag.length == constants.BLOCK_HASH_LENGTH && blockNumOrTag.startsWith(constants.EMPTY_HEX)) {
nonceCount = await this.getAccountNonceForHistoricBlock(address, blockNumOrTag, requestDetails);
} else {
// return a '-39001: Unknown block' error per api-spec
throw predefined.UNKNOWN_BLOCK();
}

const cacheTtl =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { RequestDetails } from '../../../types';
export interface IAccountService {
getTransactionCount: (
address: string,
blockNumOrTag: string | null,
blockNumOrTag: string,
requestDetails: RequestDetails,
) => Promise<string | JsonRpcError>;

Expand Down
10 changes: 4 additions & 6 deletions packages/relay/tests/lib/eth/eth_getTransactionCount.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,18 @@ describe('@ethGetTransactionCount eth_getTransactionCount spec', async function
getSdkClientStub = sinon.stub(hapiServiceInstance, 'getSDKClient').returns(sdkClientStub);
});

it('should return 0x0 nonce for no block consideration with not found acoount', async () => {
it('should return 0x0 nonce for latest block with not found account', async () => {
restMock.onGet(contractPath).reply(404, JSON.stringify(mockData.notFound));
restMock.onGet(accountPath).reply(404, JSON.stringify(mockData.notFound));
// @ts-ignore
const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null, requestDetails);
const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, 'latest', requestDetails);
expect(nonce).to.exist;
expect(nonce).to.equal(constants.ZERO_HEX);
});

it('should return latest nonce for no block consideration but valid account', async () => {
it('should return latest nonce for latest block but valid account', async () => {
restMock.onGet(contractPath).reply(404, JSON.stringify(mockData.notFound));
restMock.onGet(accountPath).reply(200, JSON.stringify(mockData.account));
// @ts-ignore
const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, null, requestDetails);
const nonce = await ethImpl.getTransactionCount(MOCK_ACCOUNT_ADDR, 'latest', requestDetails);
expect(nonce).to.exist;
expect(nonce).to.equal(numberTo0x(mockData.account.ethereum_nonce));
});
Expand Down
Loading