Struct AccountDelta

Source
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

Source

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.
Source

pub fn merge(&mut self, other: Self) -> Result<(), AccountDeltaError>

Merge another AccountDelta into this one.

Source

pub fn is_empty(&self) -> bool

Returns true if this account delta does not contain any vault, storage or nonce updates.

Source

pub fn storage(&self) -> &AccountStorageDelta

Returns storage updates for this account delta.

Source

pub fn vault(&self) -> &AccountVaultDelta

Returns vault updates for this account delta.

Source

pub fn nonce_delta(&self) -> Felt

Returns the amount by which the nonce was incremented.

Source

pub fn id(&self) -> AccountId

Returns the account ID to which this delta applies.

Source

pub fn into_parts(self) -> (AccountStorageDelta, AccountVaultDelta, Felt)

Converts this storage delta into individual delta components.

Source

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).
  • 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 since faucet_id_prefix is 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.
  • 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.
    • 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 [[domain = 3, slot_idx, num_changed_entries, 0], 0, 0, 0, 0], except if num_changed_entries is 0, where slot_idx is the index of the slot and num_changed_entries is the number of changed key-value pairs in the map.
§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

Source§

fn clone(&self) -> AccountDelta

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AccountDelta

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deserializable for AccountDelta

Source§

fn read_from<R: ByteReader>( source: &mut R, ) -> Result<Self, DeserializationError>

Reads a sequence of bytes from the provided source, attempts to deserialize these bytes into Self, and returns the result. Read more
Source§

fn read_from_bytes(bytes: &[u8]) -> Result<Self, DeserializationError>

Attempts to deserialize the provided bytes into Self and returns the result. Read more
Source§

impl PartialEq for AccountDelta

Source§

fn eq(&self, other: &AccountDelta) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serializable for AccountDelta

Source§

fn write_into<W: ByteWriter>(&self, target: &mut W)

Serializes self into bytes and writes these bytes into the target.
Source§

fn get_size_hint(&self) -> usize

Returns an estimate of how many bytes are needed to represent self. Read more
Source§

fn to_bytes(&self) -> Vec<u8>

Serializes self into a vector of bytes.
Source§

impl Eq for AccountDelta

Source§

impl StructuralPartialEq for AccountDelta

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<D> OwoColorize for D

Source§

fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>
where C: Color,

Set the foreground color generically Read more
Source§

fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>
where C: Color,

Set the background color generically. Read more
Source§

fn black(&self) -> FgColorDisplay<'_, Black, Self>

Change the foreground color to black
Source§

fn on_black(&self) -> BgColorDisplay<'_, Black, Self>

Change the background color to black
Source§

fn red(&self) -> FgColorDisplay<'_, Red, Self>

Change the foreground color to red
Source§

fn on_red(&self) -> BgColorDisplay<'_, Red, Self>

Change the background color to red
Source§

fn green(&self) -> FgColorDisplay<'_, Green, Self>

Change the foreground color to green
Source§

fn on_green(&self) -> BgColorDisplay<'_, Green, Self>

Change the background color to green
Source§

fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>

Change the foreground color to yellow
Source§

fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>

Change the background color to yellow
Source§

fn blue(&self) -> FgColorDisplay<'_, Blue, Self>

Change the foreground color to blue
Source§

fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>

Change the background color to blue
Source§

fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to magenta
Source§

fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to magenta
Source§

fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to purple
Source§

fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to purple
Source§

fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>

Change the foreground color to cyan
Source§

fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>

Change the background color to cyan
Source§

fn white(&self) -> FgColorDisplay<'_, White, Self>

Change the foreground color to white
Source§

fn on_white(&self) -> BgColorDisplay<'_, White, Self>

Change the background color to white
Source§

fn default_color(&self) -> FgColorDisplay<'_, Default, Self>

Change the foreground color to the terminal default
Source§

fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>

Change the background color to the terminal default
Source§

fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>

Change the foreground color to bright black
Source§

fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>

Change the background color to bright black
Source§

fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>

Change the foreground color to bright red
Source§

fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>

Change the background color to bright red
Source§

fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>

Change the foreground color to bright green
Source§

fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>

Change the background color to bright green
Source§

fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>

Change the foreground color to bright yellow
Source§

fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>

Change the background color to bright yellow
Source§

fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>

Change the foreground color to bright blue
Source§

fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>

Change the background color to bright blue
Source§

fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright magenta
Source§

fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright magenta
Source§

fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright purple
Source§

fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright purple
Source§

fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>

Change the foreground color to bright cyan
Source§

fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>

Change the background color to bright cyan
Source§

fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>

Change the foreground color to bright white
Source§

fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>

Change the background color to bright white
Source§

fn bold(&self) -> BoldDisplay<'_, Self>

Make the text bold
Source§

fn dimmed(&self) -> DimDisplay<'_, Self>

Make the text dim
Source§

fn italic(&self) -> ItalicDisplay<'_, Self>

Make the text italicized
Source§

fn underline(&self) -> UnderlineDisplay<'_, Self>

Make the text underlined
Make the text blink
Make the text blink (but fast!)
Source§

fn reversed(&self) -> ReversedDisplay<'_, Self>

Swap the foreground and background colors
Source§

fn hidden(&self) -> HiddenDisplay<'_, Self>

Hide the text
Source§

fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>

Cross out the text
Source§

fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the foreground color at runtime. Only use if you do not know which color will be used at compile-time. If the color is constant, use either OwoColorize::fg or a color-specific method, such as OwoColorize::green, Read more
Source§

fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the background color at runtime. Only use if you do not know what color to use at compile-time. If the color is constant, use either OwoColorize::bg or a color-specific method, such as OwoColorize::on_yellow, Read more
Source§

fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the foreground color to a specific RGB value.
Source§

fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the background color to a specific RGB value.
Source§

fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>

Sets the foreground color to an RGB value.
Source§

fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>

Sets the background color to an RGB value.
Source§

fn style(&self, style: Style) -> Styled<&Self>

Apply a runtime-determined style
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more