Developers Home»how to guides»Calculating Transaction Weights

Calculating Transaction Weights

Information

This guide shows a basic procedure for configuring weights. There are more advanced methods that suit different use cases. For simple functions with fixed amounts of storage reads, this method works well. For other use cases, see the section on weights.

Goal

Understand how to calculate transaction weights for a basic dispatch function.

Use Cases

  • Assign the correct weight before a function call to storage.
  • Calculate transaction fees.

Overview

Weights are an important part of Substrate development because they provide information about the maximum cost of a function in terms of the block size it will take up. This way, the weighting system checks what the cost will be before a function is executed. As runtime engineers, we care a lot about weights. Not only do they help add security checks around the functions we create, but they also force us to think about the computational ressources consumed by a transaction. From that, we can figure out what fees to charge users. This guide will cover how to calculate the maximum weight for a dispatch call; calculate the actual weight after execution; and reimburse the difference. Here's an overview of the traits we'll be implementing:

Steps

1. Import weight configuration tools

Make sure you have the right dependencies:

use frame_support::Parameter;
use frame_support::weights::{GetDispatchInfo, Pays};
use sp_runtime::traits::Dispatchable;
use frame_support::pallet_prelude::{DispatchResultWithPostInfo};
use frame_support::dispatch::DispatchResult;

2. Calculate maximum weight before a function

Using call.get_dispatch_info(), calculate the maximum possible weight before the function is declared:

#[weight = {
            let dispatch_info = call.get_dispatch_info();
            (dispatch_info.weight, dispatch_info.class, Pays::Yes)
            }]

      // Define a function header that returns DispatchResultWithPostInfo.
          fn do_three_reads(origin, call: Box<<T as Config>::Call>) -> DispatchResultWithPostInfo {
      // Function logic.
        }

GetDispatchInfo provides the get_dispatch_info() method we need to retrieve information about the function's weight.

3. Calculate the actual weight linked to function's logic

The actual weight of a function call depends on the logic of the extrinsic. After execution, we can give back fees once the actual weight has been calculated. Handle this using the Pays Enum and DbWeight.

For a function whose logic does three storage reads, calculate it using DbWeight and return it at the end of the function:

// Function returns a calculation corresponding to 3 DB reads
let check_logic_weight = T::DbWeight::get().reads(3);
return Ok(Some(check_logic_weight).into())

//Remove fee assoicated to weight
Ok(Pays::Yes.into())

Examples

Docs

Rust docs

Other

Last edit: on

Was This Guide Helpful?
Help us improve