pub struct AccountDelta { /* private fields */ }Expand description
AccountDelta stores the differences between two account states.
The differences are represented as follows:
- storage: an AccountStorageDelta that contains the changes to the account storage.
- vault: an AccountVaultDelta object that contains the changes to the account vault.
- nonce: if the nonce of the account has changed, the delta of the nonce is stored, i.e. the value by which the nonce increased.
TODO: add ability to trace account code updates.
Implementations§
Source§impl AccountDelta
impl AccountDelta
Sourcepub fn new(
account_id: AccountId,
storage: AccountStorageDelta,
vault: AccountVaultDelta,
nonce_delta: Felt,
) -> Result<Self, AccountDeltaError>
pub fn new( account_id: AccountId, storage: AccountStorageDelta, vault: AccountVaultDelta, nonce_delta: Felt, ) -> Result<Self, AccountDeltaError>
Returns new AccountDelta instantiated from the provided components.
§Errors
- Returns an error if storage or vault were updated, but the nonce was either not updated or set to 0.
Sourcepub fn merge(&mut self, other: Self) -> Result<(), AccountDeltaError>
pub fn merge(&mut self, other: Self) -> Result<(), AccountDeltaError>
Merge another AccountDelta into this one.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if this account delta does not contain any vault, storage or nonce updates.
Sourcepub fn storage(&self) -> &AccountStorageDelta
pub fn storage(&self) -> &AccountStorageDelta
Returns storage updates for this account delta.
Sourcepub fn vault(&self) -> &AccountVaultDelta
pub fn vault(&self) -> &AccountVaultDelta
Returns vault updates for this account delta.
Sourcepub fn nonce_delta(&self) -> Felt
pub fn nonce_delta(&self) -> Felt
Returns the amount by which the nonce was incremented.
Sourcepub fn into_parts(self) -> (AccountStorageDelta, AccountVaultDelta, Felt)
pub fn into_parts(self) -> (AccountStorageDelta, AccountVaultDelta, Felt)
Converts this storage delta into individual delta components.
Sourcepub fn commitment(&self) -> Digest
pub fn commitment(&self) -> Digest
Computes the commitment to the account delta.
The delta is a sequential hash over a vector of field elements which starts out empty and is appended to in the following way. Whenever sorting is expected, it is that of a link map key. The WORD layout is in memory-order.
- Append
[[nonce_delta, 0, account_id_suffix, account_id_prefix], EMPTY_WORD], where account_id_{prefix,suffix} are the prefix and suffix felts of the native account id and nonce_delta is the value by which the nonce was incremented. - Fungible Asset Delta
- For each updated fungible asset, sorted by its vault key, whose amount delta is
non-zero:
- Append
[domain = 1, was_added, 0, 0]. - Append
[amount, 0, faucet_id_suffix, faucet_id_prefix]where amount is the delta by which the fungible asset’s amount has changed and was_added is a boolean flag indicating whether the amount was added (1) or subtracted (0).
- Append
- For each updated fungible asset, sorted by its vault key, whose amount delta is
non-zero:
- Non-Fungible Asset Delta
- For each updated non-fungible asset, sorted by its vault key:
- Append
[domain = 1, was_added, 0, 0]where was_added is a boolean flag indicating whether the asset was added (1) or removed (0). Note that the domain is the same for assets sincefaucet_id_prefixis at the same position in the layout for both assets, and, by design, it is never the same for fungible and non-fungible assets. - Append
[hash0, hash1, hash2, faucet_id_prefix], i.e. the non-fungible asset.
- Append
- For each updated non-fungible asset, sorted by its vault key:
- Storage Slots - for each slot whose value has changed, depending on the slot type:
- Value Slot
- Append
[[domain = 2, slot_idx, 0, 0], NEW_VALUE]where NEW_VALUE is the new value of the slot and slot_idx is the index of the slot.
- Append
- Map Slot
- For each key-value pair, sorted by key, whose new value is different from the previous
value in the map:
- Append
[KEY, NEW_VALUE].
- Append
- Append
[[domain = 3, slot_idx, num_changed_entries, 0], 0, 0, 0, 0], except ifnum_changed_entriesis 0, where slot_idx is the index of the slot andnum_changed_entriesis the number of changed key-value pairs in the map.
- For each key-value pair, sorted by key, whose new value is different from the previous
value in the map:
- Value Slot
§Rationale
The rationale for this layout is that hashing in the VM should be as efficient as possible and minimize the number of branches to be as efficient as possible. Every high-level section in this bullet point list should add an even number of words since the hasher operates on double words. In the VM, each permutation is done immediately, so adding an uneven number of words in a given step will result in more difficulty in the MASM implementation.
§Security
The general concern with the commitment is that two deltas must never has to the same commitment. E.g. a commitment of a delta that changes a key-value pair in a storage map slot should be different from a delta that adds a non-fungible asset to the vault. If not, a delta can be crafted in the VM that sets a map key but a malicious actor crafts a delta outside the VM that adds a non-fungible asset. To prevent that, a couple of measures are taken.
- Because multiple unrelated contexts (e.g. vaults and storage slots) are hashed in the same hasher, domain separators are used to disambiguate. For each changed asset and each changed slot in the delta, a domain separator is hashed into the delta. The domain separator is always at the same index in each layout so it cannot be maliciously crafted (see below for an example).
- Storage value slots:
- since only changed value slots are included in the delta, there is no ambiguity between a value slot being set to EMPTY_WORD and its value being unchanged.
- Storage map slots:
- Map slots append a header which summarizes the changes in the slot, in particular the slot index and number of changed entries. Since only changed slots are included, the number of changed entries is never zero.
- Two distinct storage map slots use the same domain but are disambiguated due to inclusion of the slot index.
Domain Separators
As an example for ambiguity, consider these two deltas:
[
ID_AND_NONCE, EMPTY_WORD,
[/* no fungible asset delta */],
[[domain = 1, was_added = 1, 0, 0], NON_FUNGIBLE_ASSET],
[/* no storage delta */]
][
ID_AND_NONCE, EMPTY_WORD,
[/* no fungible asset delta */],
[/* no non-fungible asset delta */],
[[domain = 2, slot_idx = 1, 0, 0], NEW_VALUE]
]NEW_VALUE is user-controllable so it can be crafted to match NON_FUNGIBLE_ASSET. The
domain separator is then the only value that differentiates these two deltas. This shows the
importance of placing the domain separators in the same index within each word’s layout
which makes it easy to see that this value cannot be crafted to be the same.
Number of Changed Entries
As an example for ambiguity, consider these two deltas:
[
EMPTY_WORD, ID_AND_NONCE,
[/* no fungible asset delta */],
[[domain = 1, was_added = 1, 0, 0], NON_FUNGIBLE_ASSET],
[/* no storage delta */],
][
ID_AND_NONCE, EMPTY_WORD,
[/* no fungible asset delta */],
[/* no non-fungible asset delta */],
[KEY0, VALUE0],
[KEY1, VALUE1],
[domain = 3, slot_idx = 0, num_changed_entries = 2, 0, 0, 0, 0, 0]
]The keys and values of map slots are user-controllable so KEY0 and VALUE0 can be crafted
to match NON_FUNGIBLE_ASSET and its metadata. Including the header of the map slot
additionally hashes the map domain into the delta, but if the header was included whenever
any value in the map has changed, it would cause ambiguity about whether KEY0/VALUE0
are in fact map keys or a non-fungible asset (or any asset or a value storage slot more
generally). Including num_changed_entries disambiguates this situation, by ensuring
that the delta commitment is different when, e.g. 1) a non-fungible asset and one key-value
pair have changed and 2) when two key-value pairs have changed.
Trait Implementations§
Source§impl Clone for AccountDelta
impl Clone for AccountDelta
Source§fn clone(&self) -> AccountDelta
fn clone(&self) -> AccountDelta
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for AccountDelta
impl Debug for AccountDelta
Source§impl Deserializable for AccountDelta
impl Deserializable for AccountDelta
Source§fn read_from<R: ByteReader>(
source: &mut R,
) -> Result<Self, DeserializationError>
fn read_from<R: ByteReader>( source: &mut R, ) -> Result<Self, DeserializationError>
source, attempts to deserialize these bytes
into Self, and returns the result. Read moreSource§fn read_from_bytes(bytes: &[u8]) -> Result<Self, DeserializationError>
fn read_from_bytes(bytes: &[u8]) -> Result<Self, DeserializationError>
Source§impl PartialEq for AccountDelta
impl PartialEq for AccountDelta
Source§impl Serializable for AccountDelta
impl Serializable for AccountDelta
Source§fn write_into<W: ByteWriter>(&self, target: &mut W)
fn write_into<W: ByteWriter>(&self, target: &mut W)
self into bytes and writes these bytes into the target.Source§fn get_size_hint(&self) -> usize
fn get_size_hint(&self) -> usize
impl Eq for AccountDelta
impl StructuralPartialEq for AccountDelta
Auto Trait Implementations§
impl Freeze for AccountDelta
impl RefUnwindSafe for AccountDelta
impl Send for AccountDelta
impl Sync for AccountDelta
impl Unpin for AccountDelta
impl UnwindSafe for AccountDelta
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more