Skip to content

Commit

Permalink
feat: solution to query the mirror node for the account balance, acco…
Browse files Browse the repository at this point in the history
…unt info, and contract info data (#2289)

* update: queries

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

* update: queries

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

* fix: adjustments and formatting

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

* update: increase timeout

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

* update: integration tests

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

* remove logs

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

* update: test

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

* fix: reorder tests in the suite

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

* fix: reliability issue

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

* fix: reliability issue

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

* fix: integration test

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

* update: reorder steps in the pipeline

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

* update: update build workflow

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

* update: reorder steps in build workflow

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

* chore: remove log

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

* chore: adjustment

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

* fix

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

* update: unit test

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

* fix: unit test

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

* update: unit tests

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

* update: revert workflow

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

* update workflow

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

* update: workflow

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

* update workflow

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

* update: workflow

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

* update: workflow

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

* add logs

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

* update

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

* ..

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

* workflow

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

* log

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

* update

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

* update: workflow

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

* update

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

* update: workflow

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

* chore: formatting

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

* update

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

* update: workflow

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

* add: tests

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

* chore: formatting

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

* deprecate symbol

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

* update: review changes

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

* update: added missing statuses

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

* chore: renaming

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

* chore: naming

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

* chore: formatting

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

* fix: typo

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

* update: add new response code

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

* update: build workflow

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

---------

Signed-off-by: svetoslav-nikol0v <[email protected]>
  • Loading branch information
svetoslav-nikol0v authored Jun 6, 2024
1 parent 14489c9 commit 70214b1
Show file tree
Hide file tree
Showing 52 changed files with 1,629 additions and 920 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,30 +164,30 @@ jobs:
if: ${{ steps.build-sdk.conclusion == 'success' && steps.start-local-node.conclusion == 'success' && !cancelled() && always() }}
run: ${{ env.CG_EXEC }} task test:integration:codecov

- name: Stop the local node
id: stop-local-node
if: ${{ steps.start-local-node.conclusion == 'success' && !cancelled() && always() }}
run: ${{ env.CG_EXEC }} npx @hashgraph/hedera-local stop

- name: Build @hashgraph/cryptography
working-directory: packages/cryptography
if: ${{ steps.build-sdk.conclusion == 'success' && steps.stop-local-node.conclusion == 'success' && !cancelled() && always() }}
if: ${{ steps.build-sdk.conclusion == 'success' && steps.start-local-node.conclusion == 'success' && !cancelled() && always() }}
run: ${{ env.CG_EXEC }} task build

- name: Unit Test @hashgraph/cryptography
working-directory: packages/cryptography
if: ${{ steps.build-sdk.conclusion == 'success' && steps.stop-local-node.conclusion == 'success' && !cancelled() && always() }}
if: ${{ steps.build-sdk.conclusion == 'success' && steps.start-local-node.conclusion == 'success' && !cancelled() && always() }}
run: ${{ env.CG_EXEC }} task test:unit

- name: Codecov @hashgraph/cryptography
working-directory: packages/cryptography
if: ${{ steps.build-sdk.conclusion == 'success' && steps.stop-local-node.conclusion == 'success' && !cancelled() && always() }}
if: ${{ steps.build-sdk.conclusion == 'success' && steps.start-local-node.conclusion == 'success' && !cancelled() && always() }}
run: ${{ env.CG_EXEC }} task test:unit:codecov

- name: Unit Test @hashgraph/sdk
if: ${{ steps.build-sdk.conclusion == 'success' && steps.stop-local-node.conclusion == 'success' && steps.playwright-deps.conclusion == 'success' && !cancelled() && always() }}
if: ${{ steps.build-sdk.conclusion == 'success' && steps.start-local-node.conclusion == 'success' && steps.playwright-deps.conclusion == 'success' && !cancelled() && always() }}
run: ${{ env.CG_EXEC }} task test:unit

- name: Codecov @hashgraph/sdk
if: ${{ steps.build-sdk.conclusion == 'success' && steps.stop-local-node.conclusion == 'success' && !cancelled() && always() }}
if: ${{ steps.build-sdk.conclusion == 'success' && steps.start-local-node.conclusion == 'success' && !cancelled() && always() }}
run: ${{ env.CG_EXEC }} task test:unit:codecov

- name: Stop the local node
id: stop-local-node
if: ${{ steps.start-local-node.conclusion == 'success' && !cancelled() && always() }}
run: ${{ env.CG_EXEC }} npx @hashgraph/hedera-local stop
23 changes: 23 additions & 0 deletions src/Executable.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import HttpError from "./http/HttpError.js";
* @typedef {import("./Signer.js").Signer} Signer
* @typedef {import("./PublicKey.js").default} PublicKey
* @typedef {import("./logger/Logger.js").default} Logger
* @typedef {import("./LedgerId.js").default} LedgerId
*/

/**
Expand Down Expand Up @@ -134,6 +135,20 @@ export default class Executable {
* @type {Logger | null}
*/
this._logger = null;

/**
* List of mirror network nodes with which execution will be attempted.
* @protected
* @type {string[]}
*/
this._mirrorNetworkNodes = [];

/**
* Current LedgerId of the network with which execution will be attempted.
* @protected
* @type {LedgerId | null}
*/
this._ledgerId = null;
}

/**
Expand Down Expand Up @@ -511,6 +526,14 @@ export default class Executable {
* @returns {Promise<OutputT>}
*/
async execute(client, requestTimeout) {
// Set list of mirror network nodes with
// which execution will be attempted
this._mirrorNetworkNodes = client.mirrorNetwork;

// Set current LedgerId of the network with
// which execution will be attempted
this._ledgerId = client.ledgerId;

// If the logger on the request is not set, use the logger in client
// (if set, otherwise do not use logger)
this._logger =
Expand Down
54 changes: 54 additions & 0 deletions src/Status.js
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,18 @@ export default class Status {
return "INVALID_GRPC_CERTIFICATE";
case Status.InvalidMaxAutoAssociations:
return "INVALID_MAX_AUTO_ASSOCIATIONS";
case Status.MaxNodesCreated:
return "MAX_NODES_CREATED";
case Status.IpFqdnCannotBeSetForSameEndpoint:
return "IP_FQDN_CANNOT_BE_SET_FOR_SAME_ENDPOINT";
case Status.GossipEndpointCannotHaveFqdn:
return "GOSSIP_ENDPOINT_CANNOT_HAVE_FQDN";
case Status.FqdnSizeTooLarge:
return "FQDN_SIZE_TOO_LARGE";
case Status.InvalidEndpoint:
return "INVALID_ENDPOINT";
case Status.GossipEndpointsExceededLimit:
return "GOSSIP_ENDPOINTS_EXCEEDED_LIMIT";
default:
return `UNKNOWN (${this._code})`;
}
Expand Down Expand Up @@ -1273,6 +1285,18 @@ export default class Status {
return Status.InvalidGrpcCertificate;
case 346:
return Status.InvalidMaxAutoAssociations;
case 347:
return Status.MaxNodesCreated;
case 348:
return Status.IpFqdnCannotBeSetForSameEndpoint;
case 349:
return Status.GossipEndpointCannotHaveFqdn;
case 350:
return Status.FqdnSizeTooLarge;
case 351:
return Status.InvalidEndpoint;
case 352:
return Status.GossipEndpointsExceededLimit;
default:
throw new Error(
`(BUG) Status.fromCode() does not handle code: ${code}`,
Expand Down Expand Up @@ -2855,3 +2879,33 @@ Status.InvalidGrpcCertificate = new Status(345);
* The most common cause for this error is a value less than `-1`.
*/
Status.InvalidMaxAutoAssociations = new Status(346);

/**
* The maximum number of nodes allowed in the address book have been created.
*/
Status.MaxNodesCreated = new Status(347);

/**
* In ServiceEndpoint, domain_name and ipAddressV4 are mutually exclusive
*/
Status.IpFqdnCannotBeSetForSameEndpoint = new Status(348);

/**
* Fully qualified domain name is not allowed in gossip_endpoint
*/
Status.GossipEndpointCannotHaveFqdn = new Status(349);

/**
* In ServiceEndpoint, domain_name size too large
*/
Status.FqdnSizeTooLarge = new Status(350);

/**
* ServiceEndpoint is invalid
*/
Status.InvalidEndpoint = new Status(351);

/**
* The number of gossip endpoints exceeds the limit
*/
Status.GossipEndpointsExceededLimit = new Status(352);
10 changes: 0 additions & 10 deletions src/account/AccountBalance.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,8 @@ export default class AccountBalance {
*/
this.hbars = props.hbars;

/**
* @deprecated - Use the mirror node API https://docs.hedera.com/guides/docs/mirror-node-api/rest-api#api-v1-accounts instead
* @readonly
*/
// eslint-disable-next-line deprecation/deprecation
this.tokens = props.tokens;

/**
* @deprecated - Use the mirror node API https://docs.hedera.com/guides/docs/mirror-node-api/rest-api#api-v1-accounts instead
* @readonly
*/
// eslint-disable-next-line deprecation/deprecation
this.tokenDecimals = props.tokenDecimals;

Object.freeze(this);
Expand Down
75 changes: 69 additions & 6 deletions src/account/AccountBalanceQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import Query, { QUERY_REGISTRY } from "../query/Query.js";
import AccountId from "./AccountId.js";
import ContractId from "../contract/ContractId.js";
import AccountBalance from "./AccountBalance.js";
import MirrorNodeService from "../network/MirrorNodeService.js";
import MirrorNodeGateway from "../network/MirrorNodeGateway.js";

/**
* @namespace proto
Expand All @@ -31,6 +33,7 @@ import AccountBalance from "./AccountBalance.js";
* @typedef {import("@hashgraph/proto").proto.IResponseHeader} HashgraphProto.proto.IResponseHeader
* @typedef {import("@hashgraph/proto").proto.ICryptoGetAccountBalanceQuery} HashgraphProto.proto.ICryptoGetAccountBalanceQuery
* @typedef {import("@hashgraph/proto").proto.ICryptoGetAccountBalanceResponse} HashgraphProto.proto.ICryptoGetAccountBalanceResponse
* @typedef {import("@hashgraph/proto").proto.ITokenBalance} HashgraphProto.proto.ITokenBalance
*/

/**
Expand Down Expand Up @@ -69,6 +72,13 @@ export default class AccountBalanceQuery extends Query {
*/
this._contractId = null;

/**
* @private
* @description Delay in ms if is necessary to wait for the mirror node to update the account balance
* @type {number}
*/
this._timeout = 0;

if (props.accountId != null) {
this.setAccountId(props.accountId);
}
Expand Down Expand Up @@ -149,6 +159,16 @@ export default class AccountBalanceQuery extends Query {
return this;
}

/**
*
* @param {number} timeout
* @returns {this}
*/
setTimeout(timeout) {
this._timeout = timeout;
return this;
}

/**
* @protected
* @override
Expand Down Expand Up @@ -210,13 +230,56 @@ export default class AccountBalanceQuery extends Query {
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_mapResponse(response, nodeAccountId, request) {
const cryptogetAccountBalance =
/** @type {HashgraphProto.proto.ICryptoGetAccountBalanceResponse} */ (
response.cryptogetAccountBalance
return new Promise((resolve, reject) => {
const mirrorNodeGateway = MirrorNodeGateway.forNetwork(
this._mirrorNetworkNodes,
this._ledgerId,
);
return Promise.resolve(
AccountBalance._fromProtobuf(cryptogetAccountBalance),
);
const mirrorNodeService = new MirrorNodeService(mirrorNodeGateway);

const cryptogetAccountBalanceFromConsensusNode =
/** @type {HashgraphProto.proto.ICryptoGetAccountBalanceResponse} */ (
response.cryptogetAccountBalance
);

if (cryptogetAccountBalanceFromConsensusNode.accountID) {
const accountIdFromConsensusNode = AccountId._fromProtobuf(
cryptogetAccountBalanceFromConsensusNode.accountID,
);

mirrorNodeService
.setTimeout(this._timeout)
.getTokenBalancesForAccount(
accountIdFromConsensusNode.num.toString(),
)
.then(
(
/** @type {HashgraphProto.proto.ITokenBalance[]} */ tokenBalances,
) => {
if (
cryptogetAccountBalanceFromConsensusNode?.tokenBalances &&
tokenBalances
) {
// Reset the array to avoid duplicates
cryptogetAccountBalanceFromConsensusNode.tokenBalances.length = 0;
// Add the token balances from the mirror node to the response from the consensus node
cryptogetAccountBalanceFromConsensusNode.tokenBalances.push(
...tokenBalances,
);

resolve(
AccountBalance._fromProtobuf(
cryptogetAccountBalanceFromConsensusNode,
),
);
}
},
)
.catch((error) => {
reject(error);
});
}
});
}

/**
Expand Down
Loading

0 comments on commit 70214b1

Please sign in to comment.