Skip to main content

AccountDelta

Struct AccountDelta 

Source
pub struct AccountDelta { /* private fields */ }
Expand description

The AccountDelta stores the differences between two account states, which can result from one or more transaction.

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.
  • code: an AccountCode for new accounts and None for others.

The presence of the code in a delta signals if the delta is a full state or partial state delta. A full state delta must be converted into an Account object, while a partial state delta must be applied to an existing Account.

TODO(code_upgrades): The ability to track account code updates is an outstanding feature. For that reason, the account code is not considered as part of the “nonce must be incremented if state changed” check.

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_delta is 0.
Source

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

Merge another AccountDelta into this one.

Source

pub fn vault_mut(&mut self) -> &mut AccountVaultDelta

Returns a mutable reference to the account vault delta.

Source

pub fn with_code(self, code: Option<AccountCode>) -> Self

Sets the AccountCode of the delta.

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 is_full_state(&self) -> bool

Returns true if this delta is a “full state” delta, false otherwise, i.e. if it is a “partial state” delta.

See the type-level docs for more on this distinction.

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 code(&self) -> Option<&AccountCode>

Returns a reference to the account code of this delta, if present.

Source

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

Converts this storage delta into individual delta components.

Source

pub fn to_commitment(&self) -> Word

Computes the commitment to the account delta.

§Computation

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 LexicographicWord. 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 are sorted by slot ID and are iterated in this order. For each slot whose value has changed, depending on the slot type:
    • Value Slot
      • Append [[domain = 2, 0, slot_id_suffix, slot_id_prefix], NEW_VALUE] where NEW_VALUE is the new value of the slot and slot_id_{suffix, prefix} is the identifier 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, num_changed_entries, slot_id_suffix, slot_id_prefix], 0, 0, 0, 0], where slot_id_{suffix, prefix} are the slot identifiers and num_changed_entries is the number of changed key-value pairs in the map.
        • For partial state deltas, the map header must only be included if num_changed_entries is not zero.
        • For full state deltas, the map header must always be included.
§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.

§New Accounts

The delta for new accounts (a full state delta) must commit to all the storage slots of the account, even if the storage slots have a default value (e.g. the empty word for value slots or an empty storage map). This ensures the full state delta commits to the exact storage slots that are contained in the account.

§Security

The general concern with the commitment is that two distinct deltas must never hash 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 ID and number of changed entries.
    • Two distinct storage map slots use the same domain but are disambiguated due to inclusion of the slot ID.
§Domain Separators

As an example for ambiguity, consider these two deltas:

[
  ID_AND_NONCE, EMPTY_WORD,
  [/* no fungible asset delta */],
  [[domain = 1, was_added = 0, 0, 0], NON_FUNGIBLE_ASSET],
  [/* no storage delta */]
]
[
  ID_AND_NONCE, EMPTY_WORD,
  [/* no fungible asset delta */],
  [/* no non-fungible asset delta */],
  [[domain = 2, 0, slot_id_suffix = 0, slot_id_prefix = 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:

[
  ID_AND_NONCE, EMPTY_WORD,
  [/* no fungible asset delta */],
  [/* no non-fungible asset delta */],
  [domain = 3, num_changed_entries = 0, slot_id_suffix = 20, slot_id_prefix = 21, 0, 0, 0, 0]
  [domain = 3, num_changed_entries = 0, slot_id_suffix = 42, slot_id_prefix = 43, 0, 0, 0, 0]
]
[
  ID_AND_NONCE, EMPTY_WORD,
  [/* no fungible asset delta */],
  [/* no non-fungible asset delta */],
  [KEY0, VALUE0],
  [domain = 3, num_changed_entries = 1, slot_id_suffix = 42, slot_id_prefix = 43, 0, 0, 0, 0]
]

The keys and values of map slots are user-controllable so KEY0 and VALUE0 could be crafted to match the first map header in the first delta. So, without having num_changed_entries included in the commitment, these deltas would be ambiguous. A delta with two empty maps could have the same commitment as a delta with one map entry where one key-value pair has changed.

§New Accounts

The number of changed entries of a storage map can be validly zero when an empty storage map is added to a new account. In such cases, the number of changed key-value pairs is 0, but the map must still be committed to, in order to differentiate between a slot being an empty map or not being present at all.

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 SequentialCommit for AccountDelta

Source§

fn to_elements(&self) -> Vec<Felt>

Reduces the delta to a sequence of field elements.

See AccountDelta::to_commitment() for more details.

Source§

type Commitment = Word

A type of the commitment which must be derivable from Word.
Source§

fn to_commitment(&self) -> Self::Commitment

Computes the commitment to the object. Read more
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 TryFrom<&AccountDelta> for Account

Source§

fn try_from(delta: &AccountDelta) -> Result<Self, Self::Error>

Converts an AccountDelta into an Account.

Conceptually, this applies the delta onto an empty account.

§Errors

Returns an error if:

  • If the delta is not a full state delta. See AccountDelta for details.
  • If any vault delta operation removes an asset.
  • If any vault delta operation adds an asset that would overflow the maximum representable amount.
  • If any storage delta update violates account storage constraints.
Source§

type Error = AccountError

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

impl TryFrom<Account> for AccountDelta

Source§

fn try_from(account: Account) -> Result<Self, Self::Error>

Converts an Account into an AccountDelta.

§Errors

Returns an error if:

  • the account has a seed. Accounts with seeds have a nonce of 0. Representing such accounts as deltas is not possible because deltas with a non-empty state change need a nonce_delta greater than 0.
Source§

type Error = AccountError

The type returned in the event of a conversion error.
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<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<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
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> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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