pub struct AccountPatch { /* private fields */ }Expand description
An AccountPatch describes the new absolute state of an account after one or more
transactions, in contrast to an AccountDelta, which describes
the relative change.
For example, where a delta might say “remove 50 USDC from the vault”, a patch says “the new USDC balance is 100”. This means a patch can be applied to compute the new account state without loading the previous state and without invoking any custom asset compose logic (e.g. merge/split procedures defined by the issuing faucet).
§Full and Partial State Patches
The presence of the code in a patch signals if the patch is a full state or partial state
patch. A full state patch must be converted into an Account object, while a partial state
patch must be applied to an existing Account. Because a full state patch reconstructs the
account from empty storage, its storage patch may only create slots, never update or remove
them; AccountPatch::new enforces this. A full state patch can only be the base of a
merge, never the incoming patch (see its docs for the permutation
rules).
The patch represents updates to the account as follows:
- storage: an
AccountStoragePatchcontaining the new values of changed storage slots and map entries. Storage updates are already absolute per changed entry, so no dedicated patch type is required for storage. - vault: an
AccountVaultPatchcontaining the new values of changed vault entries. - nonce: the new (absolute) nonce of the account, in contrast to
AccountDelta::nonce_deltawhich stores the increment. - code: an
AccountCodefor new accounts andNonefor others, with the same semantics as inAccountDelta.
Implementations§
Source§impl AccountPatch
impl AccountPatch
Sourcepub fn new(
account_id: AccountId,
storage: AccountStoragePatch,
vault: AccountVaultPatch,
code: Option<AccountCode>,
final_nonce: Option<Felt>,
) -> Result<Self, AccountPatchError>
pub fn new( account_id: AccountId, storage: AccountStoragePatch, vault: AccountVaultPatch, code: Option<AccountCode>, final_nonce: Option<Felt>, ) -> Result<Self, AccountPatchError>
Returns a new AccountPatch instantiated from the provided components.
final_nonce must be Some(non_zero_nonce) if storage or vault contain any updates,
and can be None only for empty patches.
§Errors
Returns an error if:
final_nonceisSome(Felt::ZERO). The tx kernel guarantees that an updated nonce is at least one, so a zero nonce is never a valid post-tx-state. Empty patches must be constructed withNoneinstead.storageorvaultcontain updates or code is present butfinal_nonceisNone. The tx kernel mandates that the nonce is incremented whenever account state changes.final_nonceis 1 butcodeis notSome. Such a patch describes a new account and should be convertible into a fullAccount, so account code is required.
Sourcepub fn empty(account_id: AccountId) -> Self
pub fn empty(account_id: AccountId) -> Self
Returns an empty patch for the provided account ID.
Sourcepub fn merge(&mut self, other: Self) -> Result<(), AccountPatchError>
pub fn merge(&mut self, other: Self) -> Result<(), AccountPatchError>
Merges the other AccountPatch into this one with patch semantics: entries present in
other overwrite their counterparts in self, and other.final_nonce, if present,
becomes the new final nonce.
Both patches must apply to the same account, and other.final_nonce must be exactly one
greater than self.final_nonce whenever both are set. The exact +1 requirement reflects
the tx kernel invariants that (a) a state-changing transaction must increment the nonce,
and (b) the nonce can be incremented at most once per transaction. As a consequence
the patch of the next transaction always lands at self.final_nonce + 1. The same nonce in
both patches represents a fork and a nonce delta larger than 1 means a missed transaction.
§Full and Partial State
The patches’ full/partial state determines whether the merge is allowed. In short, the
incoming patch (other) must never be a full state patch. In more detail:
full_state + partial_state: allowed. The full state (account-creation) patch is the base and later partial patches layer on top of it.partial_state + partial_state: allowed. Both are incremental updates.partial_state + full_state: disallowed. A full state patch describes the account’s initial state, so it cannot follow an earlier (partial) patch.full_state + full_state: disallowed. An account is created once, so two creation patches cannot both apply.
Empty patches are neutral and handled before this rule: merging into an empty self adopts
other, and merging an empty other is a no-op.
§Errors
Returns an error if:
- the two patches apply to different accounts.
- both patches carry a final nonce and the nonce in
otheris not exactly one greater than the nonce inself. - the incoming patch (
other) is a full state patch (see permutations above). - a storage slot is used as different slot types in the two patches.
Sourcepub fn storage(&self) -> &AccountStoragePatch
pub fn storage(&self) -> &AccountStoragePatch
Returns the storage updates of this patch.
Sourcepub fn vault(&self) -> &AccountVaultPatch
pub fn vault(&self) -> &AccountVaultPatch
Returns the vault updates of this patch.
Sourcepub fn code(&self) -> Option<&AccountCode>
pub fn code(&self) -> Option<&AccountCode>
Returns a reference to the account code of this patch, if present.
Sourcepub fn final_nonce(&self) -> Option<Felt>
pub fn final_nonce(&self) -> Option<Felt>
Returns the new (absolute) nonce of the account after this patch is applied, or None if
the nonce wasn’t updated.
Sourcepub fn is_full_state(&self) -> bool
pub fn is_full_state(&self) -> bool
Returns true if this patch is a “full state” patch, false otherwise, i.e. if it is a
“partial state” patch.
See the type-level docs for more on this distinction.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if this account patch does not contain any vault or storage updates and the nonce wasn’t updated.
Sourcepub fn to_commitment(&self) -> Word
pub fn to_commitment(&self) -> Word
Computes the commitment to the account patch.
This is very similar to
AccountDelta::to_commitment. See its docs
for the rationale, security aspects, and other details. The only differences between
these are:
- the patch includes the new nonce rather than the nonce delta.
- The patch includes the new absolute asset values (
AccountVaultPatch) while the delta includes the relative asset changes (AccountVaultDelta).
§Computation
The patch commitment 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 Word.
- Append
[[domain = 2, final_nonce, account_id_suffix, account_id_prefix], EMPTY_WORD], whereaccount_id_{prefix,suffix}are the prefix and suffix felts of the native account id,final_nonceis the new nonce of the account, anddomain = 2identifies the header as the start of an account patch commitment (distinguishing it from a delta commitment, which usesdomain = 1). - Asset Patch
- For each asset whose value has changed compared to the initial state of the transaction,
including if it was removed, sorted by its asset ID:
- Append
[ASSET_ID, ASSET_VALUE_OR_EMPTY_WORD]which are the key and either the value of the asset (for updates) or the empty word (for removals). - Append
[[domain = 4, num_changed_assets, 0, 0], 0, 0, 0, 0], wherenum_changed_assetsis the number of assets that were appended. Note that this is a distinct domain from the delta asset domain (3), so an asset delta and an asset patch can never produce the same commitment.
- Append
- For each asset whose value has changed compared to the initial state of the transaction,
including if it was removed, sorted by its asset ID:
- Storage Slots are sorted by slot ID and are iterated in this order.
patch_opis theStoragePatchOperationof the slot patch andslot_id_{suffix, prefix}is the identifier of the slot. For each slot, depending on its slot type:- Value Slot
- Append
[[domain = 5, patch_op, slot_id_suffix, slot_id_prefix], NEW_VALUE]whereNEW_VALUEis the new value 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
- The map trailer is constructed as
[[domain = 6, patch_op, slot_id_suffix, slot_id_prefix], [num_changed_entries, 0, 0, 0]], wherenum_changed_entriesis the number of key-value pairs appended above. Whether the trailer is included depends onpatch_op:- For
StoragePatchOperation::Create, the trailer is always included, since the slot’s creation must be committed to even when the map is created empty (num_changed_entries == 0). - For
StoragePatchOperation::Update, the trailer is included only ifnum_changed_entries != 0. An update that changes no entries is a no-op and is omitted entirely. - For
StoragePatchOperation::Remove, the trailer is always included withnum_changed_entriesset to zero, since the number of removed entries is unknown.
- For
- For each key-value pair, sorted by key, whose new value is different from the previous
value in the map:
- Value Slot
Headers for storage map slots and asset patches are appended rather than prepended since the tx kernel cannot efficiently get the number of changed entries before the iteration.
Trait Implementations§
Source§impl Clone for AccountPatch
impl Clone for AccountPatch
Source§fn clone(&self) -> AccountPatch
fn clone(&self) -> AccountPatch
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for AccountPatch
impl Debug for AccountPatch
Source§impl Deserializable for AccountPatch
impl Deserializable for AccountPatch
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 min_serialized_size() -> usize
fn min_serialized_size() -> usize
Source§fn read_from_bytes(bytes: &[u8]) -> Result<Self, DeserializationError>
fn read_from_bytes(bytes: &[u8]) -> Result<Self, DeserializationError>
Source§fn read_from_bytes_with_budget(
bytes: &[u8],
budget: usize,
) -> Result<Self, DeserializationError>
fn read_from_bytes_with_budget( bytes: &[u8], budget: usize, ) -> Result<Self, DeserializationError>
Self from bytes with a byte budget limit. Read moreimpl Eq for AccountPatch
Source§impl PartialEq for AccountPatch
impl PartialEq for AccountPatch
Source§impl SequentialCommit for AccountPatch
impl SequentialCommit for AccountPatch
Source§fn to_elements(&self) -> Vec<Felt>
fn to_elements(&self) -> Vec<Felt>
Reduces the patch to a sequence of field elements.
See AccountPatch::to_commitment() for more details.
Source§type Commitment = Word
type Commitment = Word
Source§fn to_commitment(&self) -> Self::Commitment
fn to_commitment(&self) -> Self::Commitment
Source§impl Serializable for AccountPatch
impl Serializable for AccountPatch
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 StructuralPartialEq for AccountPatch
Source§impl TryFrom<&AccountPatch> for Account
impl TryFrom<&AccountPatch> for Account
Source§fn try_from(patch: &AccountPatch) -> Result<Self, Self::Error>
fn try_from(patch: &AccountPatch) -> Result<Self, Self::Error>
Converts an AccountPatch into an Account.
Conceptually, this applies the patch onto an empty account. Only patches that fully
describe an account (i.e. carry account code and a final nonce) can be converted; see
AccountPatch for details.
§Errors
Returns an error if:
- The patch does not carry account code or a final nonce.
- Applying the vault patch to an empty vault fails.
- Applying the storage patch to empty storage fails.
Source§type Error = AccountError
type Error = AccountError
Source§impl TryFrom<Account> for AccountPatch
impl TryFrom<Account> for AccountPatch
Source§fn try_from(account: Account) -> Result<Self, Self::Error>
fn try_from(account: Account) -> Result<Self, Self::Error>
Converts an Account into an AccountPatch.
§Errors
Returns an error if:
- the account has a seed. Accounts with seeds have a nonce of 0. Representing such accounts
as patches is not possible because patches with a non-empty state change need a
final_noncegreater than 0.
Source§type Error = AccountError
type Error = AccountError
Auto Trait Implementations§
impl Freeze for AccountPatch
impl RefUnwindSafe for AccountPatch
impl Send for AccountPatch
impl Sync for AccountPatch
impl Unpin for AccountPatch
impl UnsafeUnpin for AccountPatch
impl UnwindSafe for AccountPatch
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
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<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 moreSource§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