Skip to content

Commit

Permalink
Merge pull request #337 from 0xPolygonMiden/hacka-serde-prove-transac…
Browse files Browse the repository at this point in the history
…tion

serde: implementation for proven transaction
  • Loading branch information
bobbinth authored Dec 7, 2023
2 parents fa63b26 + 8db6ca2 commit a95cdb8
Show file tree
Hide file tree
Showing 11 changed files with 406 additions and 27 deletions.
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)?;

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

0 comments on commit a95cdb8

Please sign in to comment.