Skip to content
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

allow zero as gas prices #416

Merged
merged 14 commits into from
Nov 5, 2024
Merged

allow zero as gas prices #416

merged 14 commits into from
Nov 5, 2024

Conversation

ftheirs
Copy link
Collaborator

@ftheirs ftheirs commented Oct 29, 2024

Problem: Gas prices can potentially be zero under certain conditions. See detailed explanation here.

Solution: Since the GasPrice struct uses NonZeroU128 types for its inner elements, we need to use a default fallback value in these cases, similar to the approach taken in Papyrus.

This can be reproduced on Sepolia for blocks 0~5 but the Starknet version from those blocks (0.12.x) is not supported by SNOS yet.

Issue Number: #405
Closes #405

Type

  • feature
  • bugfix
  • dev (no functional changes, no API changes)
  • fmt (formatting, renaming)
  • build
  • docs
  • testing

Description

Breaking changes?

  • yes
  • no

@ftheirs ftheirs marked this pull request as ready for review October 29, 2024 17:40
Comment on lines 33 to 40
eth_l1_gas_price: felt_to_u128(&block.l1_gas_price.price_in_wei).try_into().unwrap_or(NonZeroU128::MIN),
strk_l1_gas_price: felt_to_u128(&block.l1_gas_price.price_in_fri).try_into().unwrap_or(NonZeroU128::MIN),
eth_l1_data_gas_price: felt_to_u128(&block.l1_data_gas_price.price_in_wei)
.try_into()
.unwrap_or(NonZeroU128::MIN),
strk_l1_data_gas_price: felt_to_u128(&block.l1_data_gas_price.price_in_fri)
.try_into()
.unwrap_or(NonZeroU128::MIN),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be more careful with these checks because there are two cases that we are treating the same when we use try_into().unwrap_or(NonZeroU128::MIN):

  1. the intended case: try_into() errors because of the value 1
  2. the unintended case: try_into() errors because the felt overflows (is > u128::MAX)

The latter case should be handled more gracefully.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch 😉 I'll fix it asap

Copy link
Collaborator

@HermanObst HermanObst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Left some request for changes

}

// If felt_to_u128 conversion is ok, it won't fail cause we're catching the zero above
Ok(NonZeroU128::new(felt_to_u128(price)?).unwrap())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't handle the error gracefully?

Comment on lines +66 to +107
Ok(BlockContext::new(block_info, chain_info, versioned_constants.clone(), bouncer_config))
}

#[cfg(test)]
mod tests {

use starknet::core::types::{Felt, ResourcePrice};
use starknet_api::core::ChainId;

use super::*;

#[test]
fn test_build_block_context_with_zero_gas_prices() {
let chain_id = ChainId::Mainnet;
// We don't really care about most of the fields.
// What's important here is to set to zero different gas prices
let block = BlockWithTxs {
status: starknet::core::types::BlockStatus::AcceptedOnL1,
block_hash: Felt::ZERO,
parent_hash: Felt::ZERO,
block_number: 1,
new_root: Felt::ZERO,
timestamp: 0,
sequencer_address: Felt::ZERO,
l1_gas_price: ResourcePrice { price_in_wei: Felt::ZERO, price_in_fri: Felt::ZERO },
l1_data_gas_price: ResourcePrice { price_in_wei: Felt::ZERO, price_in_fri: Felt::ZERO },
l1_da_mode: L1DataAvailabilityMode::Blob,
starknet_version: String::from("0.13.2.1"),
transactions: vec![],
};

let starknet_version = blockifier::versioned_constants::StarknetVersion::Latest;

// Call this function must not fail
let block_context = build_block_context(chain_id, &block, starknet_version).unwrap();

// Verify that gas prices were set to NonZeroU128::MIN
assert_eq!(block_context.block_info().gas_prices.eth_l1_gas_price, NonZeroU128::MIN);
assert_eq!(block_context.block_info().gas_prices.strk_l1_gas_price, NonZeroU128::MIN);
assert_eq!(block_context.block_info().gas_prices.eth_l1_data_gas_price, NonZeroU128::MIN);
assert_eq!(block_context.block_info().gas_prices.strk_l1_data_gas_price, NonZeroU128::MIN);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! Could we add a test that checks that, if we have correct values, the block context is updated accordingly?

@@ -28,7 +28,7 @@ async fn test_replay_block() {
let state_reader = AsyncRpcStateReader::new(rpc_client.clone(), previous_block_id);
let mut state = CachedState::from(state_reader);

let block_context = build_block_context(ChainId::Sepolia, &block_with_txs, StarknetVersion::V0_13_1);
let block_context = build_block_context(ChainId::Sepolia, &block_with_txs, StarknetVersion::V0_13_1).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle error

Copy link
Collaborator

@notlesh notlesh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems good for now, but the rules around zero gas are not that clear to me. If gas can actually be zero and we need to support that, then it seems the upstream GasPrices struct should be changed to reflect this.

@HermanObst HermanObst merged commit b147c82 into main Nov 5, 2024
6 checks passed
@HermanObst HermanObst deleted the ft/allow_zero_gas_prices branch November 5, 2024 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: enable 0 gas price blocks
3 participants