use crate::Word;
use crate::account::{AccountCode, AccountId, PartialAccount, PartialStorage};
use crate::asset::PartialVault;
use crate::block::AccountWitness;
use crate::crypto::merkle::{SmtProof, SmtProofError};
use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AccountInputs {
partial_account: PartialAccount,
witness: AccountWitness,
}
impl AccountInputs {
pub fn new(partial_account: PartialAccount, witness: AccountWitness) -> AccountInputs {
AccountInputs { partial_account, witness }
}
pub fn id(&self) -> AccountId {
self.partial_account.id()
}
pub fn account(&self) -> &PartialAccount {
&self.partial_account
}
pub fn code(&self) -> &AccountCode {
self.partial_account.code()
}
pub fn storage(&self) -> &PartialStorage {
self.partial_account.storage()
}
pub fn vault(&self) -> &PartialVault {
self.partial_account.vault()
}
pub fn witness(&self) -> &AccountWitness {
&self.witness
}
pub fn into_parts(self) -> (PartialAccount, AccountWitness) {
(self.partial_account, self.witness)
}
pub fn compute_account_root(&self) -> Result<Word, SmtProofError> {
let smt_merkle_path = self.witness.path().clone();
let smt_leaf = self.witness.leaf();
let root = SmtProof::new(smt_merkle_path, smt_leaf)?.compute_root();
Ok(root)
}
}
impl Serializable for AccountInputs {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
target.write(&self.partial_account);
target.write(&self.witness);
}
}
impl Deserializable for AccountInputs {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let partial_account = source.read()?;
let witness = source.read()?;
Ok(AccountInputs { partial_account, witness })
}
}
#[cfg(test)]
mod tests {
use alloc::vec::Vec;
use miden_core::Felt;
use miden_core::utils::{Deserializable, Serializable};
use miden_crypto::merkle::SparseMerklePath;
use miden_processor::SMT_DEPTH;
use crate::account::{Account, AccountCode, AccountId, AccountStorage, PartialAccount};
use crate::asset::AssetVault;
use crate::block::AccountWitness;
use crate::testing::account_id::ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE;
use crate::transaction::AccountInputs;
#[test]
fn serde_roundtrip() {
let id = AccountId::try_from(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE).unwrap();
let code = AccountCode::mock();
let vault = AssetVault::new(&[]).unwrap();
let storage = AccountStorage::new(vec![]).unwrap();
let account = Account::new_existing(id, vault, storage, code, Felt::new(10));
let commitment = account.commitment();
let mut merkle_nodes = Vec::with_capacity(SMT_DEPTH as usize);
for _ in 0..(SMT_DEPTH as usize) {
merkle_nodes.push(commitment);
}
let merkle_path = SparseMerklePath::from_sized_iter(merkle_nodes)
.expect("The nodes given are of SMT_DEPTH count");
let fpi_inputs = AccountInputs::new(
PartialAccount::from(&account),
AccountWitness::new(id, commitment, merkle_path).unwrap(),
);
let serialized = fpi_inputs.to_bytes();
let deserialized = AccountInputs::read_from_bytes(&serialized).unwrap();
assert_eq!(deserialized, fpi_inputs);
}
}