Skip to content

Commit

Permalink
[JSS-101] Estimate smart-contract update energy costs
Browse files Browse the repository at this point in the history
Added new method getContractUpdateEnergyCost
Get contract update energy cost
Estimated by calculateEnergyCost, where transactionSpecificCost received from invokeContract used energy

Updated README.md for node-sdk examples
  • Loading branch information
Ivan-Mahda committed May 22, 2024
1 parent b54ea78 commit 441d2f9
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ npm_config_target_arch=x64 yarn

### Building for a release

Note: you need rustup in order to build rust-bindings (can be installed from [rust-lang.org](https://www.rust-lang.org/tools/install))

To build the project run

```shell
Expand Down
4 changes: 4 additions & 0 deletions examples/nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,7 @@ yarn run-example /path/to/example.ts [opts]
```

Where opts are any arguments that the example script takes.

Default endpoint for node is 'localhost:20000',
but instead of installing local node,
can be used testnet node https://node.testnet.concordium.com:20000
6 changes: 6 additions & 0 deletions packages/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 7.4.1

### Added

- Method (`getContractUpdateEnergyCost`) for estimating energy usage of contract update.

## 7.4.0

### Added
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@concordium/web-sdk",
"version": "7.4.0",
"version": "7.4.1",
"license": "Apache-2.0",
"engines": {
"node": ">=16"
Expand Down
13 changes: 13 additions & 0 deletions packages/sdk/src/contractHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,16 @@ export function getNamesFromReceive(receiveName: string): {
entrypointName: receiveName.substring(splitPoint + 1),
};
}

/**
* Get contract update payload size by adding reserved offsets to parameter size and receive name size
* Amount (8 bytes), Contract address (16 bytes), Receive name size (2 bytes), Parameter size (2 bytes)
*/
export function getUpdatePayloadSize(
parameterSize: number,
receiveNameLength: number
) {
return (
8n + 16n + 2n + BigInt(parameterSize) + 2n + BigInt(receiveNameLength)
);
}
44 changes: 44 additions & 0 deletions packages/sdk/src/energyCost.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ConcordiumGRPCClient } from './grpc/GRPCClient.js';
import { getAccountTransactionHandler } from './accountTransactions.js';
import { collapseRatio, multiplyRatio } from './ratioHelpers.js';
import {
Expand All @@ -8,6 +9,13 @@ import {
} from './types.js';
import * as Energy from './types/Energy.js';
import * as CcdAmount from './types/CcdAmount.js';
import {
AccountAddress,
ContractAddress,
Parameter,
ReceiveName,
} from './pub/types.js';
import { getUpdatePayloadSize } from './contractHelpers.js';

/**
* These constants must be consistent with constA and constB in:
Expand Down Expand Up @@ -60,6 +68,42 @@ export function getEnergyCost(
);
}

/**
* Get contract update energy cost
* Estimated by calculateEnergyCost, where transactionSpecificCost received from invokeContract used energy
* @param {ConcordiumGRPCClient} grpcClient - The client to be used for the query
* @param {ContractAddress.Type} contractAddress - The address of the contract to query
* @param {AccountAddress.Type} invoker - Representation of an account address
* @param {Parameter.Type} parameter - Input for contract function
* @param {ReceiveName.Type} method - Represents a receive-function in a smart contract module
* @param {bigint} signatureCount - Number of expected signatures
*/
export async function getContractUpdateEnergyCost(
grpcClient: ConcordiumGRPCClient,
contractAddress: ContractAddress.Type,
invoker: AccountAddress.Type,
parameter: Parameter.Type,
method: ReceiveName.Type,
signatureCount: bigint
): Promise<Energy.Type> {
const res = await grpcClient.invokeContract({
contract: contractAddress,
invoker,
parameter,
method,
});

if (!res || res.tag === 'failure') {
throw new Error(res?.reason?.tag || 'no response');
}

return calculateEnergyCost(
signatureCount,
getUpdatePayloadSize(parameter.buffer.length, method.toString().length),
res.usedEnergy.value
);
}

/**
* Given the current blockchain parameters, return the microCCD per NRG exchange rate of the chain.
* @returns the microCCD per NRG exchange rate as a ratio.
Expand Down

0 comments on commit 441d2f9

Please sign in to comment.