-
Notifications
You must be signed in to change notification settings - Fork 28
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
chore(blockifier): change deserialization of versioned_constants #2818
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -403,6 +403,162 @@ impl VersionedConstants { | |
} | ||
} | ||
|
||
|
||
impl<'de> Deserialize<'de> for VersionedConstants { | ||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
where | ||
D: Deserializer<'de>, | ||
{ | ||
#[derive(Clone, Debug, Default, Deserialize)] | ||
#[serde(deny_unknown_fields)] | ||
pub struct TmpVersionedConstants { | ||
// Limits. | ||
pub tx_event_limits: EventLimits, | ||
pub invoke_tx_max_n_steps: u32, | ||
pub execute_max_sierra_gas: GasAmount, | ||
pub deprecated_l2_resource_gas_costs: ArchivalDataGasCosts, | ||
pub archival_data_gas_costs: ArchivalDataGasCosts, | ||
pub max_recursion_depth: usize, | ||
pub validate_max_n_steps: u32, | ||
pub validate_max_sierra_gas: GasAmount, | ||
pub min_compiler_version_for_sierra_gas: CompilerVersion, | ||
// BACKWARD COMPATIBILITY: If true, the segment_arena builtin instance counter will be | ||
// multiplied by 3. This offsets a bug in the old vm where the counter counted the number of | ||
// cells used by instances of the builtin, instead of the number of instances. | ||
pub segment_arena_cells: bool, | ||
|
||
// Transactions settings. | ||
pub disable_cairo0_redeclaration: bool, | ||
pub enable_stateful_compression: bool, | ||
pub comprehensive_state_diff: bool, | ||
pub ignore_inner_event_resources: bool, | ||
|
||
// Compiler settings. | ||
pub enable_reverts: bool, | ||
|
||
// Cairo OS constants. | ||
// Note: if loaded from a json file, there are some assumptions made on its structure. | ||
// See the struct's docstring for more details. | ||
pub tmp_os_constants: Arc<TmpOsConstants>, | ||
|
||
// Fee related. | ||
pub(crate) vm_resource_fee_cost: Arc<VmResourceCosts>, | ||
// Cost of allocating a storage cell. | ||
pub allocation_cost: AllocationCost, | ||
|
||
// Resources. | ||
os_resources: Arc<OsResources>, | ||
|
||
// Just to make sure the value exists, but don't use the actual values. | ||
#[allow(dead_code)] | ||
gateway: serde::de::IgnoredAny, | ||
} | ||
|
||
impl TmpVersionedConstants { | ||
/// Calculates the syscall gas cost from the OS resources. | ||
pub fn get_syscall_gas_cost(&self, syscall_selector: &SyscallSelector) -> u64 { | ||
let gas_costs = &self.os_constants.gas_costs; | ||
let execution_resources = &self | ||
.os_resources | ||
.execute_syscalls | ||
.get(syscall_selector) | ||
.expect("Fetching the execution resources of a syscall should not fail."); | ||
let n_steps = u64_from_usize(execution_resources.n_steps); | ||
let n_memory_holes = u64_from_usize(execution_resources.n_memory_holes); | ||
let total_builtin_gas_cost: u64 = execution_resources | ||
.builtin_instance_counter | ||
.iter() | ||
.map(|(builtin, amount)| { | ||
let builtin_cost = gas_costs | ||
.builtins | ||
.get_builtin_gas_cost(builtin) | ||
.unwrap_or_else(|err| panic!("Failed to get gas cost: {}", err)); | ||
builtin_cost * u64_from_usize(*amount) | ||
}) | ||
.sum(); | ||
// The minimum total cost is `syscall_base_gas_cost`, which is pre-charged by the compiler. | ||
std::cmp::max( | ||
n_steps * gas_costs.base.step_gas_cost | ||
+ n_memory_holes * gas_costs.base.memory_hole_gas_cost | ||
+ total_builtin_gas_cost, | ||
gas_costs.base.syscall_base_gas_cost, | ||
) | ||
} | ||
} | ||
|
||
let tmp_versioned_constants = TmpVersionedConstants::deserialize(deserializer)?; | ||
if (*(tmp_versioned_constants.tmp_os_constants).is_syscall_gas_costs_none()) { | ||
let syscall_gas_costs = SyscallGasCosts::default(); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::CallContract, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::CallContract)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Deploy, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Deploy)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::EmitEvent, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::EmitEvent)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::GetBlockHash, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::GetBlockHash)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::GetExecutionInfo, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::GetExecutionInfo)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Keccak, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Keccak)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::LibraryCall, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::LibraryCall)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Sha256ProcessBlock, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Sha256ProcessBlock)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::ReplaceClass, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::ReplaceClass)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256k1Add, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256k1Add)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256k1GetPointFromX, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256k1GetPointFromX)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256k1GetXy, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256k1GetXy)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256k1Mul, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256k1Mul)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256k1New, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256k1New)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256r1Add, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256r1Add)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256r1GetPointFromX, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256r1GetPointFromX)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256r1GetXy, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256r1GetXy)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256r1Mul, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256r1Mul)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::Secp256r1New, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::Secp256r1New)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::SendMessageToL1, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::SendMessageToL1)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::StorageRead, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::StorageRead)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::StorageWrite, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::StorageWrite)); | ||
syscall_gas_costs.set_syscall_price(&SyscallSelector::GetClassHashAt, tmp_versioned_constants.get_syscall_gas_cost(&SyscallSelector::GetClassHashAt)); | ||
|
||
let gas_costs: GasCosts = GasCosts { | ||
base: tmp_versioned_constants.tmp_os_constants.gas_costs.base, | ||
builtins: tmp_versioned_constants.tmp_os_constants.gas_costs.builtins, | ||
syscalls: syscall_gas_costs, | ||
}; | ||
let constants = Arc::new(OsConstants { | ||
gas_costs, | ||
validate_rounding_consts: tmp_versioned_constants.tmp_os_constants.validate_rounding_consts, | ||
os_contract_addresses: tmp_versioned_constants.tmp_os_constants.os_contract_addresses, | ||
}); | ||
|
||
} else { | ||
let constants = Arc::new(OsConstants { | ||
gas_costs: tmp_versioned_constants.tmp_os_constants.gas_costs, | ||
validate_rounding_consts: tmp_versioned_constants.tmp_os_constants.validate_rounding_consts, | ||
os_contract_addresses: tmp_versioned_constants.tmp_os_constants.os_contract_addresses, | ||
}); | ||
} | ||
|
||
Ok(VersionedConstants { | ||
tx_event_limits: tmp_versioned_constants.tx_event_limits, | ||
invoke_tx_max_n_steps: tmp_versioned_constants.invoke_tx_max_n_steps, | ||
execute_max_sierra_gas: tmp_versioned_constants.execute_max_sierra_gas, | ||
deprecated_l2_resource_gas_costs: tmp_versioned_constants.deprecated_l2_resource_gas_costs, | ||
archival_data_gas_costs: tmp_versioned_constants.archival_data_gas_costs, | ||
max_recursion_depth: tmp_versioned_constants.max_recursion_depth, | ||
validate_max_n_steps: tmp_versioned_constants.validate_max_n_steps, | ||
validate_max_sierra_gas: tmp_versioned_constants.validate_max_sierra_gas, | ||
min_compiler_version_for_sierra_gas: tmp_versioned_constants.min_compiler_version_for_sierra_gas, | ||
segment_arena_cells: tmp_versioned_constants.segment_arena_cells, | ||
disable_cairo0_redeclaration: tmp_versioned_constants.disable_cairo0_redeclaration, | ||
enable_stateful_compression: tmp_versioned_constants.enable_stateful_compression, | ||
comprehensive_state_diff: tmp_versioned_constants.comprehensive_state_diff, | ||
ignore_inner_event_resources: tmp_versioned_constants.ignore_inner_event_resources, | ||
enable_reverts: tmp_versioned_constants.enable_reverts, | ||
os_constants: constants, | ||
vm_resource_fee_cost: tmp_versioned_constants.vm_resource_fee_cost, | ||
allocation_cost: tmp_versioned_constants.allocation_cost, | ||
os_resources: tmp_versioned_constants.os_resources, | ||
gateway: tmp_versioned_constants.gateway, | ||
}) | ||
} | ||
} | ||
|
||
|
||
|
||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] | ||
pub struct ArchivalDataGasCosts { | ||
// TODO(barak, 18/03/2024): Once we start charging per byte change to milligas_per_data_byte, | ||
|
@@ -614,8 +770,8 @@ pub struct SyscallGasCosts { | |
pub sha256_process_block: u64, | ||
} | ||
|
||
impl SyscallGasCosts { | ||
pub fn get_syscall_gas_cost(&self, selector: &SyscallSelector) -> Result<u64, GasCostsError> { | ||
impl SyscallGasCosts { | ||
pub fn get_syscall_gas_cost(&self, selector: &SyscallSelector) -> Result<u64, TmpGasCostsError> { | ||
let gas_cost = match *selector { | ||
SyscallSelector::CallContract => self.call_contract, | ||
SyscallSelector::Deploy => self.deploy, | ||
|
@@ -656,8 +812,48 @@ impl SyscallGasCosts { | |
|
||
Ok(gas_cost) | ||
} | ||
} | ||
|
||
fn set_syscall_price(&self, selector: &SyscallSelector, amount: u64) { | ||
match *selector { | ||
SyscallSelector::CallContract => self.call_contract = amount, | ||
SyscallSelector::Deploy => self.deploy = amount, | ||
SyscallSelector::EmitEvent => self.emit_event = amount, | ||
SyscallSelector::GetBlockHash => self.get_block_hash = amount, | ||
SyscallSelector::GetExecutionInfo => self.get_execution_info = amount, | ||
SyscallSelector::GetClassHashAt => self.get_class_hash_at = amount, | ||
SyscallSelector::Keccak => {self.keccak = amount; | ||
self.keccak_round_cost = 180000}, | ||
SyscallSelector::Sha256ProcessBlock => self.sha256_process_block = amount, | ||
SyscallSelector::LibraryCall => self.library_call = amount, | ||
SyscallSelector::ReplaceClass => self.replace_class = amount, | ||
SyscallSelector::Secp256k1Add => self.secp256k1_add = amount, | ||
SyscallSelector::Secp256k1GetPointFromX => self.secp256k1_get_point_from_x = amount, | ||
SyscallSelector::Secp256k1GetXy => self.secp256k1_get_xy = amount, | ||
SyscallSelector::Secp256k1Mul => self.secp256k1_mul = amount, | ||
SyscallSelector::Secp256k1New => self.secp256k1_new = amount, | ||
SyscallSelector::Secp256r1Add => self.secp256r1_add = amount, | ||
SyscallSelector::Secp256r1GetPointFromX => self.secp256r1_get_point_from_x = amount, | ||
SyscallSelector::Secp256r1GetXy => self.secp256r1_get_xy = amount, | ||
SyscallSelector::Secp256r1Mul => self.secp256r1_mul = amount, | ||
SyscallSelector::Secp256r1New => self.secp256r1_new = amount, | ||
SyscallSelector::SendMessageToL1 => self.send_message_to_l1 = amount, | ||
SyscallSelector::StorageRead => self.storage_read = amount, | ||
SyscallSelector::StorageWrite => self.storage_write = amount, | ||
SyscallSelector::DelegateCall | ||
| SyscallSelector::DelegateL1Handler | ||
| SyscallSelector::GetBlockNumber | ||
| SyscallSelector::GetBlockTimestamp | ||
| SyscallSelector::GetCallerAddress | ||
| SyscallSelector::GetContractAddress | ||
| SyscallSelector::GetTxInfo | ||
| SyscallSelector::GetSequencerAddress | ||
| SyscallSelector::GetTxSignature | ||
| SyscallSelector::LibraryCallL1Handler => { | ||
return Err(GasCostsError::DeprecatedSyscall { selector: *selector }); | ||
} | ||
} | ||
} | ||
Comment on lines
+816
to
+855
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function signature Spotted by Graphite Reviewer
Comment on lines
+816
to
+855
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function signature needs to be modified to: fn set_syscall_price(&mut self, selector: &SyscallSelector, amount: u64) -> Result<(), GasCostsError> Two changes are required:
Additionally, add Spotted by Graphite Reviewer |
||
} | ||
#[derive(Debug, Default, Deserialize)] | ||
pub struct BaseGasCosts { | ||
pub step_gas_cost: u64, | ||
|
@@ -686,8 +882,9 @@ pub struct BuiltinGasCosts { | |
pub ecdsa: u64, | ||
} | ||
|
||
|
||
impl BuiltinGasCosts { | ||
pub fn get_builtin_gas_cost(&self, builtin: &BuiltinName) -> Result<u64, GasCostsError> { | ||
pub fn get_builtin_gas_cost(&self, builtin: &BuiltinName) -> Result<u64, TmpGasCostsError> { | ||
let gas_cost = match *builtin { | ||
BuiltinName::range_check => self.range_check, | ||
BuiltinName::pedersen => self.pedersen, | ||
|
@@ -709,13 +906,27 @@ impl BuiltinGasCosts { | |
} | ||
} | ||
|
||
/// Gas cost constants. For more documentation see in core/os/constants.cairo. | ||
#[derive(Debug, Default, Deserialize)] | ||
pub struct TmpGasCosts { | ||
pub base: BaseGasCosts, | ||
pub builtins: BuiltinGasCosts, | ||
pub syscalls: Option<SyscallGasCosts>, | ||
} | ||
|
||
/// Gas cost constants. For more documentation see in core/os/constants.cairo. | ||
#[derive(Debug, Default, Deserialize)] | ||
pub struct GasCosts { | ||
pub base: BaseGasCosts, | ||
pub builtins: BuiltinGasCosts, | ||
pub syscalls: SyscallGasCosts, | ||
} | ||
#[derive(Debug, Default)] | ||
pub struct OsConstants { | ||
pub gas_costs: GasCosts, | ||
pub validate_rounding_consts: ValidateRoundingConsts, | ||
pub os_contract_addresses: OsContractAddresses, | ||
} | ||
|
||
// Below, serde first deserializes the json into a regular IndexMap wrapped by the newtype | ||
// `OsConstantsRawJson`, then calls the `try_from` of the newtype, which handles the | ||
|
@@ -724,13 +935,13 @@ pub struct GasCosts { | |
// in the `try_from`. | ||
#[derive(Debug, Default, Deserialize)] | ||
#[serde(try_from = "OsConstantsRawJson")] | ||
pub struct OsConstants { | ||
pub gas_costs: GasCosts, | ||
pub struct TmpOsConstants { | ||
pub gas_costs: TmpGasCosts, | ||
pub validate_rounding_consts: ValidateRoundingConsts, | ||
pub os_contract_addresses: OsContractAddresses, | ||
} | ||
|
||
impl OsConstants { | ||
impl TmpOsConstants { | ||
// List of os constants to be ignored | ||
// during the creation of the struct containing the base gas costs. | ||
|
||
|
@@ -766,28 +977,36 @@ impl OsConstants { | |
"validate_rounding_consts", | ||
"validated", | ||
]; | ||
|
||
fn is_syscall_gas_costs_none (&self) ->bool { | ||
self.gas_costs.is_none() | ||
} | ||
Comment on lines
+981
to
+983
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Spotted by Graphite Reviewer
Comment on lines
+981
to
+983
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The method is checking the wrong field - it should be checking Spotted by Graphite Reviewer |
||
} | ||
|
||
impl TryFrom<&OsConstantsRawJson> for GasCosts { | ||
impl TryFrom<&OsConstantsRawJson> for TmpGasCosts { | ||
type Error = OsConstantsSerdeError; | ||
|
||
fn try_from(raw_json_data: &OsConstantsRawJson) -> Result<Self, Self::Error> { | ||
let base_value: Value = serde_json::to_value(&raw_json_data.parse_base()?)?; | ||
let base: BaseGasCosts = serde_json::from_value(base_value)?; | ||
let builtins_value: Value = serde_json::to_value(&raw_json_data.parse_builtin()?)?; | ||
let builtins: BuiltinGasCosts = serde_json::from_value(builtins_value)?; | ||
let syscalls_value: Value = | ||
if (&raw_json_data.raw_json_file_as_dict.contains_key("syscalls_gas_costs")) { | ||
let syscalls_value: Value = | ||
serde_json::to_value(&raw_json_data.parse_syscalls(&base, &builtins)?)?; | ||
let syscalls: SyscallGasCosts = serde_json::from_value(syscalls_value)?; | ||
Ok(GasCosts { base, builtins, syscalls }) | ||
let syscalls: SyscallGasCosts = serde_json::from_value(syscalls_value)?; | ||
Ok(TmpGasCosts { base, builtins, syscalls }) | ||
} else { | ||
Ok(TmpGasCosts { base, builtins, None}) | ||
} | ||
} | ||
} | ||
|
||
impl TryFrom<OsConstantsRawJson> for OsConstants { | ||
impl TryFrom<OsConstantsRawJson> for TmpOsConstants { | ||
type Error = OsConstantsSerdeError; | ||
|
||
fn try_from(raw_json_data: OsConstantsRawJson) -> Result<Self, Self::Error> { | ||
let gas_costs = GasCosts::try_from(&raw_json_data)?; | ||
let gas_costs = TmpGasCosts::try_from(&raw_json_data)?; | ||
let validate_rounding_consts = raw_json_data.validate_rounding_consts; | ||
let os_contract_addresses = raw_json_data.os_contract_addresses; | ||
let os_constants = | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
constants
variable is created but not used in the finalVersionedConstants
struct construction. Please assignconstants
to theos_constants
field in theOk(VersionedConstants { ... })
return value.Spotted by Graphite Reviewer
Is this helpful? React 👍 or 👎 to let us know.