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

serde: implementation for proven transaction #337

Merged
merged 2 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions objects/src/accounts/account_id.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use miden_crypto::utils::{ByteReader, Deserializable, Serializable};
use vm_processor::DeserializationError;

use super::{
get_account_seed, Account, AccountError, Digest, Felt, FieldElement, Hasher, StarkField,
ToString, Vec, Word,
Expand Down Expand Up @@ -278,6 +281,21 @@ impl Ord for AccountId {
}
}

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

impl Serializable for AccountId {
fn write_into<W: miden_crypto::utils::ByteWriter>(&self, target: &mut W) {
self.0.write_into(target);
}
}

impl Deserializable for AccountId {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
Ok(AccountId(Felt::read_from(source)?))
}
}

// HELPER FUNCTIONS
// ================================================================================================
fn parse_felt(bytes: &[u8]) -> Result<Felt, AccountError> {
Expand Down
43 changes: 43 additions & 0 deletions objects/src/assets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ mod fungible;
pub use fungible::FungibleAsset;

mod nonfungible;
use miden_crypto::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
pub use nonfungible::{NonFungibleAsset, NonFungibleAssetDetails};

mod token_symbol;
pub use token_symbol::TokenSymbol;
use vm_processor::DeserializationError;

// ASSET
// ================================================================================================
Expand Down Expand Up @@ -112,6 +114,12 @@ impl From<Asset> for Word {
}
}

impl From<&Asset> for Word {
fn from(value: &Asset) -> Self {
(*value).into()
}
}

impl From<Asset> for [u8; 32] {
fn from(asset: Asset) -> Self {
use Asset::*;
Expand All @@ -122,6 +130,12 @@ impl From<Asset> for [u8; 32] {
}
}

impl From<&Asset> for [u8; 32] {
fn from(value: &Asset) -> Self {
(*value).into()
}
}

impl TryFrom<Word> for Asset {
type Error = AssetError;

Expand All @@ -148,6 +162,35 @@ impl TryFrom<[u8; 32]> for Asset {
}
}

impl TryFrom<&[u8; 32]> for Asset {
type Error = AssetError;

fn try_from(value: &[u8; 32]) -> Result<Self, Self::Error> {
(*value).try_into()
}
}

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

impl Serializable for Asset {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
let data: [u8; 32] = self.into();
target.write_bytes(&data);
}
}

impl Deserializable for Asset {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let data_vec = source.read_vec(32)?;
let data_array: [u8; 32] = data_vec.try_into().expect("Vec must be of size 32");

let asset = Asset::try_from(&data_array)
.map_err(|v| DeserializationError::InvalidValue(format!("{v:?}")))?;
Ok(asset)
}
}

// HELPER FUNCTIONS
// ================================================================================================

Expand Down
24 changes: 24 additions & 0 deletions objects/src/notes/envelope.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use super::{Digest, Felt, Note, NoteMetadata, Vec, Word};
use miden_crypto::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
use vm_core::StarkField;
use vm_processor::DeserializationError;

// NOTE ENVELOPE
// ================================================================================================
Expand Down Expand Up @@ -103,3 +105,25 @@ impl From<&Note> for NoteEnvelope {
}
}
}

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

impl Serializable for NoteEnvelope {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.note_hash.write_into(target);
self.note_metadata.write_into(target);
}
}

impl Deserializable for NoteEnvelope {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let note_hash = Digest::read_from(source)?;
let note_metadata = NoteMetadata::read_from(source)?;

Ok(Self {
note_hash,
note_metadata,
})
}
}
22 changes: 22 additions & 0 deletions objects/src/notes/inputs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use miden_crypto::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
use vm_processor::DeserializationError;

use super::{Digest, Felt, Hasher, NoteError, Vec, ZERO};

/// Holds the inputs which are placed onto the stack before a note's script is executed.
Expand Down Expand Up @@ -61,6 +64,25 @@ impl NoteInputs {
}
}

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

impl Serializable for NoteInputs {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.inputs.write_into(target);
}
}

impl Deserializable for NoteInputs {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let inputs = <[Felt; 16]>::read_from(source)?;
Self::new(&inputs).map_err(|v| DeserializationError::InvalidValue(format!("{v}")))
}
}

// TESTS
// ================================================================================================

#[test]
fn test_input_ordering() {
use super::Vec;
Expand Down
28 changes: 28 additions & 0 deletions objects/src/notes/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use miden_crypto::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
use vm_processor::DeserializationError;

use super::{AccountId, Felt, NoteError, Word};

/// Represents metadata associated with a note. This includes the sender, tag, and number of assets.
Expand Down Expand Up @@ -67,3 +70,28 @@ impl TryFrom<Word> for NoteMetadata {
})
}
}

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

impl Serializable for NoteMetadata {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.sender.write_into(target);
self.tag.write_into(target);
self.num_assets.write_into(target);
}
}

impl Deserializable for NoteMetadata {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let sender = AccountId::read_from(source)?;
let tag = Felt::read_from(source)?;
let num_assets = Felt::read_from(source)?;
bobbinth marked this conversation as resolved.
Show resolved Hide resolved

Ok(Self {
sender,
tag,
num_assets,
})
}
}
73 changes: 73 additions & 0 deletions objects/src/notes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod metadata;
pub use metadata::NoteMetadata;

mod origin;
use miden_crypto::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
pub use origin::{NoteInclusionProof, NoteOrigin};

mod script;
Expand All @@ -26,6 +27,7 @@ pub use stub::NoteStub;

mod vault;
pub use vault::NoteVault;
use vm_processor::DeserializationError;

// CONSTANTS
// ================================================================================================
Expand Down Expand Up @@ -59,6 +61,7 @@ pub const NOTE_LEAF_DEPTH: u8 = NOTE_TREE_DEPTH + 1;
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Note {
#[cfg_attr(feature = "serde", serde(with = "serialization"))]
script: NoteScript,
inputs: NoteInputs,
vault: NoteVault,
Expand Down Expand Up @@ -230,3 +233,73 @@ impl RecordedNote {
self.proof.origin()
}
}

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

impl Serializable for Note {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.script.write_into(target);
self.inputs.write_into(target);
self.vault.write_into(target);
self.serial_num.write_into(target);
self.metadata.write_into(target);
}
}

impl Deserializable for Note {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let script = NoteScript::read_from(source)?;
let inputs = NoteInputs::read_from(source)?;
let vault = NoteVault::read_from(source)?;
let serial_num = Word::read_from(source)?;
let metadata = NoteMetadata::read_from(source)?;

Ok(Self {
script,
inputs,
vault,
serial_num,
metadata,
})
}
}

impl Serializable for RecordedNote {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.note.write_into(target);
self.proof.write_into(target);
}
}

impl Deserializable for RecordedNote {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let note = Note::read_from(source)?;
let proof = NoteInclusionProof::read_from(source)?;

Ok(Self { note, proof })
}
}

#[cfg(feature = "serde")]
mod serialization {
use super::NoteScript;
use crate::utils::serde::{Deserializable, Serializable};

pub fn serialize<S>(code: &NoteScript, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let bytes = code.to_bytes();
serializer.serialize_bytes(&bytes)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<NoteScript, D::Error>
where
D: serde::Deserializer<'de>,
{
let bytes: Vec<u8> = <Vec<u8> as serde::Deserialize>::deserialize(deserializer)?;

NoteScript::read_from_bytes(&bytes).map_err(serde::de::Error::custom)
}
}
50 changes: 50 additions & 0 deletions objects/src/notes/origin.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use miden_crypto::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
use vm_processor::DeserializationError;

use super::{Digest, Felt, NoteError, ToString, NOTE_TREE_DEPTH};
use crate::crypto::merkle::{MerklePath, NodeIndex};

Expand Down Expand Up @@ -73,3 +76,50 @@ impl NoteInclusionProof {
&self.note_path
}
}

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

impl Serializable for NoteOrigin {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.block_num.write_into(target);
self.node_index.write_into(target);
}
}

impl Deserializable for NoteOrigin {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let block_num = Felt::read_from(source)?;
let node_index = NodeIndex::read_from(source)?;

Ok(Self {
block_num,
node_index,
})
}
}

impl Serializable for NoteInclusionProof {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
self.origin.write_into(target);
self.sub_hash.write_into(target);
self.note_root.write_into(target);
self.note_path.write_into(target);
}
}

impl Deserializable for NoteInclusionProof {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let origin = NoteOrigin::read_from(source)?;
let sub_hash = Digest::read_from(source)?;
let note_root = Digest::read_from(source)?;
let note_path = MerklePath::read_from(source)?;

Ok(Self {
origin,
sub_hash,
note_root,
note_path,
})
}
}
Loading
Loading