-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
[Gas Metering] Add storage_rebate
to Object
and introduce gas price
#1254
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 |
---|---|---|
|
@@ -118,32 +118,63 @@ impl<S> AuthorityTemporaryStore<S> { | |
/// the gas object hasn't been mutated yet. Passing in `gas_object_size` so that we can also charge | ||
/// for the gas object mutation in advance. | ||
pub fn charge_gas_for_storage_changes( | ||
&self, | ||
&mut self, | ||
gas_status: &mut SuiGasStatus, | ||
gas_object_size: usize, | ||
gas_object: &mut Object, | ||
) -> SuiResult { | ||
for (object_id, (_object_ref, object)) in &self.written { | ||
// Objects in written can be either mutation or creation. | ||
// We figure it out by looking them up in `self.objects`. | ||
let object_size = object.object_size_for_gas_metering(); | ||
let old_object_size = if let Some(old_obj) = self.objects.get(object_id) { | ||
old_obj.object_size_for_gas_metering() | ||
} else { | ||
0 | ||
}; | ||
gas_status.charge_storage_mutation(old_object_size, object_size)?; | ||
let mut objects_to_update = vec![]; | ||
// Also charge gas for mutating the gas object in advance. | ||
let gas_object_size = gas_object.object_size_for_gas_metering(); | ||
gas_object.storage_rebate = gas_status.charge_storage_mutation( | ||
gas_object_size, | ||
gas_object_size, | ||
gas_object.storage_rebate, | ||
)?; | ||
objects_to_update.push(gas_object.clone()); | ||
|
||
for (object_id, (_object_ref, object)) in &mut self.written { | ||
let (old_object_size, storage_rebate) = | ||
if let Some(old_object) = self.objects.get(object_id) { | ||
( | ||
old_object.object_size_for_gas_metering(), | ||
old_object.storage_rebate, | ||
) | ||
} else { | ||
(0, 0) | ||
}; | ||
let new_storage_rebate = gas_status.charge_storage_mutation( | ||
old_object_size, | ||
object.object_size_for_gas_metering(), | ||
storage_rebate, | ||
)?; | ||
if !object.is_read_only() { | ||
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. Is it safe to instead do
at the beginning of the loop, or even at the beginning of the function? At least based on the name, it sounds like 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. It's not. Newly published package will show up in |
||
// We don't need to set storage rebate for immutable objects, as they will | ||
// never be deleted. | ||
object.storage_rebate = new_storage_rebate; | ||
objects_to_update.push(object.clone()); | ||
} | ||
} | ||
|
||
for object_id in self.deleted.keys() { | ||
// If an object is in `self.deleted`, and also in `self.objects`, we give storage rebate. | ||
// Otherwise if an object is in `self.deleted` but not in `self.objects`, it means this | ||
// object was unwrapped and then deleted. The rebate would have been provided already when | ||
// mutating the object that wrapped this object. | ||
if let Some(old_obj) = self.objects.get(object_id) { | ||
gas_status.charge_storage_mutation(old_obj.object_size_for_gas_metering(), 0)?; | ||
if let Some(old_object) = self.objects.get(object_id) { | ||
gas_status.charge_storage_mutation( | ||
old_object.object_size_for_gas_metering(), | ||
0, | ||
old_object.storage_rebate, | ||
)?; | ||
} | ||
} | ||
// Also charge gas for mutating the gas object in advance. | ||
gas_status.charge_storage_mutation(gas_object_size, gas_object_size)?; | ||
|
||
// Write all objects at the end only if all previous gas charges succeeded. | ||
// This avoids polluting the temporary store state if this function failed. | ||
for object in objects_to_update { | ||
self.write_object(object); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
|
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.
Could take
Object
to avoid the clone at 133 i the caller happens to have ownership?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.
We cannot unfortunately. We still need to actually deduct gas from the gas_object after this function returns.