Skip to content

fees: add max skipped blocks constant to pallet #209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 26, 2024
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion sugondat/chain/pallets/length-fee-adjustment/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ polkadot-primitives = { workspace = true }
[dev-dependencies]
sp-io = { workspace = true }
sp-core = { workspace = true }
sugondat-primitives = { workspace = true, features = ["std"] }

[features]
default = [ "std" ]
Expand All @@ -53,4 +54,4 @@ runtime-benchmarks = [
"sp-runtime/runtime-benchmarks",
"dep:sp-io"
]
try-runtime = [ "frame-support/try-runtime" ]
try-runtime = [ "frame-support/try-runtime" ]
18 changes: 12 additions & 6 deletions sugondat/chain/pallets/length-fee-adjustment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,18 @@ pub mod pallet {
///
/// Here, m represents the number of terms needed to be below the error.
/// The smallest value of m that satisfies the inequality should be used as the value for this parameter.
///
/// The maximum number of skipped blocks is used to ensure that only the right amount of terms is used,
/// and no terms are wasted. If n is exceeded, the approximation could diverge significantly from the actual value of e^x.
/// This means that producing a block at most every n skipped blocks should be enforced to avoid falling into this error.
#[pallet::constant]
type SkippedBlocksNumberTerms: Get<u32>;

/// The maximum number of skipped blocks is used to ensure that only the right amount of terms is used
/// and no terms are wasted. If n is exceeded, the approximation could diverge significantly from the actual value of e^x.
/// If the number of skipped blocks exceeds this value, it will be bounded to this value.
/// However, this limitation comes at the cost of losing the real fee adjustment update.
/// Therefore, producing a block at most every n skipped blocks should be enforced to avoid falling into this circumstance.
#[pallet::constant]
type MaximumSkippedBlocks: Get<u32>;

/// A source to provide the relay-parent number of the previous block.
type LastRelayBlockNumberProvider: LastRelayBlockNumberProvider;
}

Expand Down Expand Up @@ -243,10 +248,11 @@ pub mod pallet {
// However, saturating it to zero will prevent the multiplier from changing
let relay_parent_distance = relay_block_number.saturating_sub(prev_relay_block_number);

// TODO: update with `n_skipped_blocks = relay_parent_distance.saturating_sub(1)`
// TODO: update with `relay_parent_distance.saturating_sub(1)`
// when updating to asynchronous backing
// https://github.com/thrumdev/blobs/issues/166
let n_skipped_blocks = relay_parent_distance.saturating_sub(2) / 2;
let n_skipped_blocks =
(relay_parent_distance.saturating_sub(2) / 2).min(T::MaximumSkippedBlocks::get());

let n_skipped_blocks = Multiplier::saturating_from_integer(n_skipped_blocks);
let target_block_size = Multiplier::from(TargetBlockSize::<T>::get());
Expand Down
2 changes: 2 additions & 0 deletions sugondat/chain/pallets/length-fee-adjustment/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ parameter_types! {
// https://github.com/thrumdev/blobs/issues/166
// Accepted error is less than 10^(-2)
pub SkippedBlocksNumberTerms: u32 = 3;
pub MaximumSkippedBlocks: u32 = sugondat_primitives::MAX_SKIPPED_BLOCKS;

pub static WeightToFee: u64 = 1;
pub static OperationalFeeMultiplier: u8 = 5;
Expand Down Expand Up @@ -130,5 +131,6 @@ impl pallet_sugondat_length_fee_adjustment::Config for Test {
type MinimumMultiplierBlockSize = MinimumMultiplierBlockSize;
type MaximumMultiplierBlockSize = MaximumMultiplierBlockSize;
type SkippedBlocksNumberTerms = SkippedBlocksNumberTerms;
type MaximumSkippedBlocks = MaximumSkippedBlocks;
type LastRelayBlockNumberProvider = MockLastRelayBlockNumberProvider;
}
40 changes: 35 additions & 5 deletions sugondat/chain/pallets/length-fee-adjustment/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,9 @@ fn test_no_update_when_prev_is_zero() {

#[test]
fn test_skipped_block_multiplier_update() {
// TODO: change max_skipped_blocks to 7200
// when updating to asynchronous backing
// https://github.com/thrumdev/blobs/issues/166
new_test_ext().execute_with(|| {
let max_skipped_blocks = 3600;
for d in (0..max_skipped_blocks).step_by(max_skipped_blocks as usize / 1000) {
let max_skipped_blocks = <Test as Config>::MaximumSkippedBlocks::get();
for d in (0..max_skipped_blocks).step_by(max_skipped_blocks as usize / 100) {
// using Multiplier::one() only e^(-vnt) is tested
NextLengthMultiplier::<Test>::put(Multiplier::one());
mock::set_last_relay_block_number(1);
Expand Down Expand Up @@ -124,6 +121,39 @@ fn test_skipped_block_multiplier_update() {
});
}

#[test]
fn test_max_skipped_block_exceeded() {
new_test_ext().execute_with(|| {
NextLengthMultiplier::<Test>::put(Multiplier::one());
mock::set_last_relay_block_number(1);

let max_skipped_blocks = <Test as Config>::MaximumSkippedBlocks::get();
let relay_data = PersistedValidationData {
parent_head: HeadData(vec![]),
// The previous relay parent was 10 times greater than the expected MaximumSkippedBlocks.
// If the multiplier is updated with that number of skipped blocks
// there's should be a significant divergence in the final result.
// However, we expect it to be bounded by max_skipped_blocks.
relay_parent_number: 1 + 2 + ((max_skipped_blocks * 10) * 2),
relay_parent_storage_root: sp_core::H256::zero(),
max_pov_size: 0,
};

LengthFeeAdjustment::on_validation_data(&relay_data);

let mul = NextLengthMultiplier::<Test>::get();

// calculate expected result using f64::exp and assert on the error rate
let target = Multiplier::from(TargetBlockSize::<Test>::get()).to_float();
let v = <Test as Config>::AdjustmentVariableBlockSize::get().to_float();
let expected_mul =
Multiplier::from_float((-1.0 * target * v * max_skipped_blocks as f64).exp());

//Accepted error is less than 10^(-2)
assert_eq_error_rate!(mul, expected_mul, Multiplier::from_inner(10000000000000000));
});
}

#[test]
fn test_skipped_block_no_prev_data() {
new_test_ext().execute_with(|| {
Expand Down
4 changes: 4 additions & 0 deletions sugondat/chain/runtimes/sugondat-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ parameter_types! {
// The accepted error is less than 10^(-2) for an expected
// maximum of 3600 skipped blocks (half a day)
pub SkippedBlocksNumberTerms: u32 = 3;

// Maximum acceptable number of skipped parachain blocks.
pub MaximumSkippedBlocks: u32 = sugondat_primitives::MAX_SKIPPED_BLOCKS;
}

impl pallet_sugondat_length_fee_adjustment::Config for Runtime {
Expand All @@ -312,6 +315,7 @@ impl pallet_sugondat_length_fee_adjustment::Config for Runtime {
type MaximumMultiplierBlockSize = MaximumMultiplierBlockSize;
type MinimumMultiplierBlockSize = MinimumMultiplierBlockSize;
type SkippedBlocksNumberTerms = SkippedBlocksNumberTerms;
type MaximumSkippedBlocks = MaximumSkippedBlocks;
type LastRelayBlockNumberProvider = Runtime;
}

Expand Down
4 changes: 4 additions & 0 deletions sugondat/chain/runtimes/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,9 @@ parameter_types! {
// The accepted error is less than 10^(-2) for an expected
// maximum of 3600 skipped blocks (half a day)
pub SkippedBlocksNumberTerms: u32 = 3;

// Maximum acceptable number of skipped parachain blocks.
pub MaximumSkippedBlocks: u32 = sugondat_primitives::MAX_SKIPPED_BLOCKS;
}

impl pallet_sugondat_length_fee_adjustment::Config for Runtime {
Expand All @@ -379,6 +382,7 @@ impl pallet_sugondat_length_fee_adjustment::Config for Runtime {
type MaximumMultiplierBlockSize = MaximumMultiplierBlockSize;
type MinimumMultiplierBlockSize = MinimumMultiplierBlockSize;
type SkippedBlocksNumberTerms = SkippedBlocksNumberTerms;
type MaximumSkippedBlocks = MaximumSkippedBlocks;
type LastRelayBlockNumberProvider = Runtime;
}

Expand Down