Skip to content

Commit

Permalink
fix(calc): remove wasm-pack from node, and add it to calc library (#1360
Browse files Browse the repository at this point in the history
)

* fix(calc): remove wasm-pack from node, and add it to calc library

* Update calc/build.sh

Co-authored-by: Dominique <dominique@imodworks.io>

---------

Co-authored-by: Dominique <dominique@imodworks.io>
  • Loading branch information
TarikGul and Imod7 committed Nov 22, 2023
1 parent 9cc8c82 commit 87d2092
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 138 deletions.
5 changes: 5 additions & 0 deletions calc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ Example usage for the package can be found in Sidecar's
[staking payout service](https://github.com/paritytech/substrate-api-sidecar/blob/master/src/services/accounts/AccountsStakingPayoutsService.ts)
and Sidecar's [block service](https://github.com/paritytech/substrate-api-sidecar/blob/master/src/services/blocks/BlocksService.ts).

## Build

In order to build the rust source code with `wasm-pack`, please run `sh build.sh`.
This will require `wasm-pack` being installed globally. The script will install it for you, but before it does it will ask you whether you want it installed or not.

### calc_partial_fee
Tool to calculate an extrinsics' `partial_fee` (i.e. the total fee minus any tip).
It uses the following formula:
Expand Down
37 changes: 35 additions & 2 deletions calc/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,44 @@

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

install_wasm_pack() {
WASM_PACK_VERSION=0.12.1
WASM_PACK="wasm-pack"

uname_out="$(uname -s)"
case "${uname_out}" in
Linux*) machine=Linux;;
Darwin*) machine=Darwin;;
esac

if [ $(cargo install --list | grep -q "wasm-pack v${WASM_PACK_VERSION}"; echo $?) != 0 ]; then
echo "$WASM_PACK v${WASM_PACK_VERSION} is not installed, and is required to build calc, would you like to install it now? (Y/N)";
read response
if [ "$response" == "y" ] || [ "$response" == "Y" ]; then
## Check if system is linux or mac for sudo or not.
if [[ $machine = "Darwin" ]]
then
cargo install "$WASM_PACK" --vers 0.12.1;
elif [[ $machine = "Linux" ]]
then
sudo cargo install "$WASM_PACK" --vers 0.12.1;
fi
else
echo "Skipping the installation of $WASM_PACK...";
echo "Please note that this Conky configuration will not work without the $WASM_PACK package.";
fi
else
echo "The $WASM_PACK package has already been installed.";
fi
}

install_wasm_pack

if [ -z ${CALC_DEBUG} ]; then
yarn wasm-pack build --target nodejs --scope substrate "$SCRIPT_DIR"
wasm-pack build --target nodejs --scope substrate "$SCRIPT_DIR"
else
echo "Fee debugging enabled"
yarn wasm-pack build --debug --target nodejs --scope substrate "$SCRIPT_DIR" -- --features debug
wasm-pack build --debug --target nodejs --scope substrate "$SCRIPT_DIR" -- --features debug
fi
# append a newline to pkg/package.json if it isn't there
if [ "$(tail -c1 "$SCRIPT_DIR/pkg/package.json"; echo x)" != $'\nx' ]; then
Expand Down
80 changes: 78 additions & 2 deletions calc/pkg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,84 @@ standalone through the npm registry.

## Usage

Example usage for the package can be found in Sidecar's [staking payout service](https://github.com/paritytech/substrate-api-sidecar/blob/master/src/services/accounts/AccountsStakingPayoutsService.ts) and Sidecar's [block service](https://github.com/paritytech/substrate-api-sidecar/blob/master/src/services/blocks/BlocksService.ts).
Example usage for the package can be found in Sidecar's
[staking payout service](https://github.com/paritytech/substrate-api-sidecar/blob/master/src/services/accounts/AccountsStakingPayoutsService.ts)
and Sidecar's [block service](https://github.com/paritytech/substrate-api-sidecar/blob/master/src/services/blocks/BlocksService.ts).

### calc_partial_fee
Tool to calculate an extrinsics' `partial_fee` (i.e. the total fee minus any tip).
It uses the following formula:

```
partial_fee = base_fee + len_fee + ((adjusted_weight_fee/estimated_weight)*actual_weight)
```

Where:
- `base_fee` is a fixed base fee to include some transaction in a block. It accounts
for the work needed to verify the signature and the computing work common to any tx.
It is constant for any tx.
- `len_fee` is a fee paid based on the size (length in bytes) of the transaction.
Longer transactions require more storage, and therefore are more expensive.
- `adjusted_weight_fee` is a fee that is itself `estimated_weight * targeted_fee_adjustment`:
- `targeted_fee_adjustment` is some adjustment made based on the network load and
other circumstantial factors, and is an opaque internal value we have no access to.
- `estimated_weight` is the "pre-dispatch" weight of the transaction. It's set
based on the cost of processing the transaction on reference hardware.
- `actual_weight` is the weight that is found in the `ExtrinsicSuccess` event for
the extrinsic in a block (it's just called `weight` in the event), and it's
value is often close to `estimated_weight`, but the node has the opportunity
to change it depending on the actual computing work necessary to process the tx.

The RPC endpoint `payment_queryFeeDetails` returns `base_fee`, `len_fee` and
`adjusted_weight_fee`. The RPC endpoint `payment_queryInfo` returns `estimated_weight`
(called `weight` in the response), and a `partialFee` value, which is our best
guess at the inclusion fee for the tx without actually submitting it and seeing
whether the node changes the weight or decides not to take a fee at all.

To get the correct values for some extrinsic from both endpoints, provide the
extrinsic bytes, and the number of the block **before the block it is included in**
(e.g. if the extrinsic was in block 100, you'd use block 99 as an argument). This
is very important.

Once you've called these endpoints, access the `ExtrinsicSuccess` event to find
the `actual_weight`, but also a `paysFee` value which signals whether the extrinsic
actually incurred a fee at all or not (a node has the opportunity to refund the
fee entirely).

With all of those values at hand, the equation above calculates the correct Fee.
Why? Well, the basic way to calculate a pre-dispatch fee is:

```
partial_fee = base_fee + len_fee + adjusted_weight_fee
```

We can do this from just the RPC methods. But then once it's in a block, we need
to swap out the weight used to calculate that `adjusted_weight_fee` with the
actual weight that was used from the `ExtrinsicSuccess` event. In the end, the
calculation itself is simple, but gathering the details needed is the main difficulty.
We do this all in Rust simply to limit any precision loss.

### calc_payout

This is a tool to calculate the payout of a staking era, either for a validator
or a nominator. This is not a predictive estimation, instead it intakes data
from a concluded [era](https://wiki.polkadot.network/docs/kusama-parameters#periods-of-common-actions-and-attributes)
to arrive to the final amount. For this it takes the following parameters:
- `total_reward_points` are the total [era points](https://wiki.polkadot.network/docs/maintain-guides-validator-payout#era-points)
for a determined [era](https://wiki.polkadot.network/docs/kusama-parameters#periods-of-common-actions-and-attributes).
- `era_payout` is the [payout](https://wiki.polkadot.network/docs/maintain-guides-validator-payout#payout-scheme)
for a determined [era](https://wiki.polkadot.network/docs/kusama-parameters#periods-of-common-actions-and-attributes).
- `validator_reward_points` are the [era points](https://wiki.polkadot.network/docs/maintain-guides-validator-payout#era-points)
earned by the validator in a determined [era](https://wiki.polkadot.network/docs/kusama-parameters#periods-of-common-actions-and-attributes).
- `validator_commission` is the commission that the validator takes of its assigned
payout before distribituing the remainder between itself and it's nominators.
- `nominator_exposure` is the amount staked by the nominator or validator,
depending on who we are inquiring about.
- `total_exposure` the total amount staked.
- `is_validator` is a `bool` that states whether the inquired account is a validator.


## Contributing

We welcome [contributions for documentation and code](https://github.com/paritytech/substrate-api-sidecar/pulls). If you have any questions you can reach the maintainers by [filing an issue on github.](https://github.com/paritytech/substrate-api-sidecar/issues)
We welcome [contributions for documentation and code](https://github.com/paritytech/substrate-api-sidecar/pulls).
If you have any questions you can reach the maintainers by [filing an issue on github.](https://github.com/paritytech/substrate-api-sidecar/issues)
45 changes: 0 additions & 45 deletions calc/pkg/calc.d.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,6 @@
/* tslint:disable */
/* eslint-disable */
/**
* Uses the following formula to calculate an extrinsics `partial_fee` (ie the total fee
* minus any tip).
*
* ```
* partial_fee = base_fee + len_fee + ((adjusted_weight_fee/estimated_weight)*actual_weight)
* ```
*
* Where:
* - `base_fee` is a fixed base fee to include some transaction in a block. It accounts
* for the work needed to verify the signature and such and is constant for any tx.
* - `len_fee` is a fee paid based on the size (length in bytes) of the transaction. Longer
* transactions require more storage.
* - `adjusted_weight_fee` is a fee that is itself `estimated_weight * targeted_fee_adjustment`.
* `targeted_fee_adjustment` is some adjustment made based on the network load and such, and is
* an opaque internal value we have no access to.
* - `estimated_weight` is the "pre-dispatch" weight of the transaction. It's set based on the cost
* of processing the transaction on reference hardware.
* - `actual_weight` is the weight that is found in the `ExtrinsicSuccess` event for the extrinsic in
* a block (it's just called `weight` in the event), and is often the same as `estimated_weight`,
* but the node has the opportunity to change it to whatever it likes, I think.
*
* The RPC endpoint `payment_queryFeeDetails` returns `base_fee`, `len_fee` and `adjusted_weight_fee`/
* The RPC endpoint `payment_queryInfo` returns `estimated_weight` (called `weight` in the response), and
* a `partialFee` value, which is our best guess at the inclusion fee for the tx without actually submitting
* it and seeing whether the node changes the weight/decides not to take a fee at all.
*
* To get the correct values for some extrinsic from both endpoints, provide the extrinsic bytes, and the
* block number **one before the block it made it into** (eg if the extrinsic was in block 100, you'd use
* block 99 as an argument). This is very important.
*
* Once you've called these endpoints, access the `ExtrinsicSuccess` event to find the `actual_weight`, but
* also a `paysFee` value which signals whether the extrinsic actually incurred a fee at all or not (a node
* has the opportunity to refund the fee entirely if it likes by setting this).
*
* With all of those values to hand, the equation above calculates the correct Fee. Why? Well, the basic
* way to calculate a pre-dispatch fee is:
*
* ```
* partial_fee = base_fee + len_fee + adjusted_weight_fee
* ```
*
* We can do this from just the RPC methods. But then once it's in a block, we need to swap out the weight used
* to calculate that `adjusted_weight_fee` with the actual weight that was used from the `ExtrinsicSuccess` event.
* In the end, the maths is simple and gathering the details needed is the main difficulty. We do this all in
* Rust simply to limit any precision loss.
* @param {string} base_fee
* @param {string} len_fee
* @param {string} adjusted_weight_fee
Expand Down
45 changes: 0 additions & 45 deletions calc/pkg/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,51 +113,6 @@ function takeObject(idx) {
return ret;
}
/**
* Uses the following formula to calculate an extrinsics `partial_fee` (ie the total fee
* minus any tip).
*
* ```
* partial_fee = base_fee + len_fee + ((adjusted_weight_fee/estimated_weight)*actual_weight)
* ```
*
* Where:
* - `base_fee` is a fixed base fee to include some transaction in a block. It accounts
* for the work needed to verify the signature and such and is constant for any tx.
* - `len_fee` is a fee paid based on the size (length in bytes) of the transaction. Longer
* transactions require more storage.
* - `adjusted_weight_fee` is a fee that is itself `estimated_weight * targeted_fee_adjustment`.
* `targeted_fee_adjustment` is some adjustment made based on the network load and such, and is
* an opaque internal value we have no access to.
* - `estimated_weight` is the "pre-dispatch" weight of the transaction. It's set based on the cost
* of processing the transaction on reference hardware.
* - `actual_weight` is the weight that is found in the `ExtrinsicSuccess` event for the extrinsic in
* a block (it's just called `weight` in the event), and is often the same as `estimated_weight`,
* but the node has the opportunity to change it to whatever it likes, I think.
*
* The RPC endpoint `payment_queryFeeDetails` returns `base_fee`, `len_fee` and `adjusted_weight_fee`/
* The RPC endpoint `payment_queryInfo` returns `estimated_weight` (called `weight` in the response), and
* a `partialFee` value, which is our best guess at the inclusion fee for the tx without actually submitting
* it and seeing whether the node changes the weight/decides not to take a fee at all.
*
* To get the correct values for some extrinsic from both endpoints, provide the extrinsic bytes, and the
* block number **one before the block it made it into** (eg if the extrinsic was in block 100, you'd use
* block 99 as an argument). This is very important.
*
* Once you've called these endpoints, access the `ExtrinsicSuccess` event to find the `actual_weight`, but
* also a `paysFee` value which signals whether the extrinsic actually incurred a fee at all or not (a node
* has the opportunity to refund the fee entirely if it likes by setting this).
*
* With all of those values to hand, the equation above calculates the correct Fee. Why? Well, the basic
* way to calculate a pre-dispatch fee is:
*
* ```
* partial_fee = base_fee + len_fee + adjusted_weight_fee
* ```
*
* We can do this from just the RPC methods. But then once it's in a block, we need to swap out the weight used
* to calculate that `adjusted_weight_fee` with the actual weight that was used from the `ExtrinsicSuccess` event.
* In the end, the maths is simple and gathering the details needed is the main difficulty. We do this all in
* Rust simply to limit any precision loss.
* @param {string} base_fee
* @param {string} len_fee
* @param {string} adjusted_weight_fee
Expand Down
Binary file modified calc/pkg/calc_bg.wasm
Binary file not shown.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@
"@types/lru-cache": "^7.10.10",
"@types/morgan": "1.9.3",
"@types/triple-beam": "^1.3.2",
"ts-node-dev": "^2.0.0",
"wasm-pack": "^0.12.1"
"ts-node-dev": "^2.0.0"
},
"keywords": [
"substrate",
Expand Down
42 changes: 0 additions & 42 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,6 @@ __metadata:
prom-client: "npm:^14.2.0"
rxjs: "npm:^7.5.6"
ts-node-dev: "npm:^2.0.0"
wasm-pack: "npm:^0.12.1"
winston: "npm:^3.8.1"
bin:
substrate-api-sidecar: ./build/src/main.js
Expand Down Expand Up @@ -2133,15 +2132,6 @@ __metadata:
languageName: node
linkType: hard

"axios@npm:^0.26.1":
version: 0.26.1
resolution: "axios@npm:0.26.1"
dependencies:
follow-redirects: "npm:^1.14.8"
checksum: 02863f4a4fd4e43ad6e0c8bc9d1359a0863c43cc57bda42ea21dfce34681e3211df193b2bf2e8ee10b2c3870ab8d6bed38a3cf80cd6e8ee17749b7d73ccd4752
languageName: node
linkType: hard

"babel-jest@npm:^29.7.0":
version: 29.7.0
resolution: "babel-jest@npm:29.7.0"
Expand Down Expand Up @@ -2239,17 +2229,6 @@ __metadata:
languageName: node
linkType: hard

"binary-install@npm:^1.0.1":
version: 1.1.0
resolution: "binary-install@npm:1.1.0"
dependencies:
axios: "npm:^0.26.1"
rimraf: "npm:^3.0.2"
tar: "npm:^6.1.11"
checksum: 78121e9c32981c101cc090f1564fbd0453d976a1b40c599a5ca623184d739b0a7c49f5ba5f91c05142eb6ff9b2816959bb9e09a3aecd12e4e3e82398bed9b8f0
languageName: node
linkType: hard

"bintrees@npm:1.0.2":
version: 1.0.2
resolution: "bintrees@npm:1.0.2"
Expand Down Expand Up @@ -3428,16 +3407,6 @@ __metadata:
languageName: node
linkType: hard

"follow-redirects@npm:^1.14.8":
version: 1.15.3
resolution: "follow-redirects@npm:1.15.3"
peerDependenciesMeta:
debug:
optional: true
checksum: 60d98693f4976892f8c654b16ef6d1803887a951898857ab0cdc009570b1c06314ad499505b7a040ac5b98144939f8597766e5e6a6859c0945d157b473aa6f5f
languageName: node
linkType: hard

"foreground-child@npm:^3.1.0":
version: 3.1.1
resolution: "foreground-child@npm:3.1.1"
Expand Down Expand Up @@ -6478,17 +6447,6 @@ __metadata:
languageName: node
linkType: hard

"wasm-pack@npm:^0.12.1":
version: 0.12.1
resolution: "wasm-pack@npm:0.12.1"
dependencies:
binary-install: "npm:^1.0.1"
bin:
wasm-pack: run.js
checksum: c16b9cf690a2414aa94b72fdc142a72813fccf1c4259499ad6a50a4560f943719234f8336e4e02d5c8cb6fb1b5128dd2870671c19dd01df3f6c9157600dd30d4
languageName: node
linkType: hard

"web-streams-polyfill@npm:^3.0.3":
version: 3.2.1
resolution: "web-streams-polyfill@npm:3.2.1"
Expand Down

0 comments on commit 87d2092

Please sign in to comment.