Skip to content
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

feat: add conversion from Account to AccountDelta #983

Merged
merged 9 commits into from
Dec 2, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- [BREAKING] Add error messages to errors and implement `core::error::Error` (#974).
- Implemented new `digest_from_hex!` macro (#984).
- Added Format Guidebook to the `miden-lib` crate (#987).
- Added conversion from `Account` to `AccountDelta` for initial account state representation as delta (#983).

## 0.6.2 (2024-11-20)

Expand Down
12 changes: 12 additions & 0 deletions objects/src/accounts/delta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,18 @@ impl AccountUpdateDetails {
}
}

/// Converts an [Account] into an [AccountDelta] for initial delta construction.
impl From<Account> for AccountDelta {
fn from(account: Account) -> Self {
let (_id, vault, storage, _code, nonce) = account.into_parts();
AccountDelta {
storage: storage.into(),
vault: (&vault).into(),
nonce: Some(nonce),
}
}
}

// SERIALIZATION
// ================================================================================================

Expand Down
50 changes: 47 additions & 3 deletions objects/src/accounts/delta/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ use alloc::{
vec::Vec,
};

use miden_crypto::EMPTY_WORD;
use miden_crypto::{merkle::SmtLeaf, EMPTY_WORD};

use super::{
AccountDeltaError, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
Word,
};
use crate::Digest;

use crate::{
accounts::{AccountStorage, StorageMap, StorageSlot},
Digest,
};
// ACCOUNT STORAGE DELTA
// ================================================================================================

Expand Down Expand Up @@ -127,6 +129,27 @@ impl AccountStorageDelta {
}
}

/// Converts an [AccountStorage] into an [AccountStorageDelta] for initial delta construction.
impl From<AccountStorage> for AccountStorageDelta {
fn from(storage: AccountStorage) -> Self {
let mut values = BTreeMap::new();
let mut maps = BTreeMap::new();
for (slot_idx, slot) in storage.into_iter().enumerate() {
let slot_idx: u8 = slot_idx.try_into().expect("slot index must fit into `u8`");
match slot {
StorageSlot::Value(value) => {
values.insert(slot_idx, value);
},
StorageSlot::Map(map) => {
maps.insert(slot_idx, map.into());
},
}
}

Self { values, maps }
}
}

impl Serializable for AccountStorageDelta {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
let cleared: Vec<u8> = self.cleared_slots().collect();
Expand Down Expand Up @@ -251,6 +274,27 @@ impl StorageMapDelta {
}
}

/// Converts a [StorageMap] into a [StorageMapDelta] for initial delta construction.
impl From<StorageMap> for StorageMapDelta {
fn from(map: StorageMap) -> Self {
// TODO: implement `IntoIterator` for `Smt` and get rid of copying keys/values:
let mut delta = StorageMapDelta::new(BTreeMap::default());
for (_, leaf) in map.leaves() {
match leaf {
SmtLeaf::Empty(_) => continue,
SmtLeaf::Single((key, value)) => {
delta.insert(*key, *value);
},
SmtLeaf::Multiple(vec) => {
vec.iter().for_each(|(key, value)| delta.insert(*key, *value));
},
}
}

delta
}
}

impl Serializable for StorageMapDelta {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
let cleared: Vec<&Digest> = self.cleared_keys().collect();
Expand Down
32 changes: 30 additions & 2 deletions objects/src/accounts/delta/vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ use super::{
};
use crate::{
accounts::{AccountId, AccountType},
assets::{Asset, FungibleAsset, NonFungibleAsset},
assets::{Asset, AssetVault, FungibleAsset, NonFungibleAsset},
};

// ACCOUNT VAULT DELTA
// ================================================================================================

Expand Down Expand Up @@ -148,6 +147,35 @@ impl AccountVaultDelta {
}
}

impl From<&AssetVault> for AccountVaultDelta {
fn from(vault: &AssetVault) -> Self {
let mut fungible = BTreeMap::new();
let mut non_fungible = BTreeMap::new();

for asset in vault.assets() {
match asset {
Asset::Fungible(asset) => {
fungible.insert(
asset.faucet_id(),
asset
.amount()
.try_into()
.expect("asset amount should be at most i64::MAX by construction"),
);
},
Asset::NonFungible(asset) => {
non_fungible.insert(asset, NonFungibleDeltaAction::Add);
},
}
}

Self {
fungible: FungibleAssetDelta(fungible),
non_fungible: NonFungibleAssetDelta::new(non_fungible),
}
}
}

impl Serializable for AccountVaultDelta {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
target.write(&self.fungible);
Expand Down
5 changes: 5 additions & 0 deletions objects/src/accounts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ impl Account {
self.nonce == ZERO
}

/// Decomposes account details into underlying components.
pub fn into_parts(self) -> (AccountId, AssetVault, AccountStorage, AccountCode, Felt) {
polydez marked this conversation as resolved.
Show resolved Hide resolved
(self.id, self.vault, self.storage, self.code, self.nonce)
}

// DATA MUTATORS
// --------------------------------------------------------------------------------------------

Expand Down
12 changes: 12 additions & 0 deletions objects/src/accounts/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,18 @@ impl AccountStorage {
}
}

// ITERATORS
// ================================================================================================

impl IntoIterator for AccountStorage {
type Item = StorageSlot;
type IntoIter = alloc::vec::IntoIter<StorageSlot>;

fn into_iter(self) -> Self::IntoIter {
self.slots.into_iter()
}
}

// HELPER FUNCTIONS
// ------------------------------------------------------------------------------------------------

Expand Down
Loading