//! Conversions between indexer_service_protocol types and nssa/nssa_core types use crate::*; // ============================================================================ // Account-related conversions // ============================================================================ impl From for AccountId { fn from(value: nssa_core::account::AccountId) -> Self { Self { value: value.into_value(), } } } impl From for nssa_core::account::AccountId { fn from(value: AccountId) -> Self { let AccountId { value } = value; nssa_core::account::AccountId::new(value) } } impl From for Account { fn from(value: nssa_core::account::Account) -> Self { let nssa_core::account::Account { program_owner, balance, data, nonce, } = value; Self { program_owner, balance, data: data.into(), nonce, } } } impl TryFrom for nssa_core::account::Account { type Error = nssa_core::account::data::DataTooBigError; fn try_from(value: Account) -> Result { let Account { program_owner, balance, data, nonce, } = value; Ok(nssa_core::account::Account { program_owner, balance, data: data.try_into()?, nonce, }) } } impl From for Data { fn from(value: nssa_core::account::Data) -> Self { Self(value.into_inner()) } } impl TryFrom for nssa_core::account::Data { type Error = nssa_core::account::data::DataTooBigError; fn try_from(value: Data) -> Result { nssa_core::account::Data::try_from(value.0) } } // ============================================================================ // Commitment and Nullifier conversions // ============================================================================ impl From for Commitment { fn from(value: nssa_core::Commitment) -> Self { Self(value.to_byte_array()) } } impl From for nssa_core::Commitment { fn from(value: Commitment) -> Self { nssa_core::Commitment::from_byte_array(value.0) } } impl From for Nullifier { fn from(value: nssa_core::Nullifier) -> Self { Self(value.to_byte_array()) } } impl From for nssa_core::Nullifier { fn from(value: Nullifier) -> Self { nssa_core::Nullifier::from_byte_array(value.0) } } impl From for CommitmentSetDigest { fn from(value: nssa_core::CommitmentSetDigest) -> Self { Self(value) } } impl From for nssa_core::CommitmentSetDigest { fn from(value: CommitmentSetDigest) -> Self { value.0 } } // ============================================================================ // Encryption-related conversions // ============================================================================ impl From for Ciphertext { fn from(value: nssa_core::encryption::Ciphertext) -> Self { Self(value.into_inner()) } } impl From for nssa_core::encryption::Ciphertext { fn from(value: Ciphertext) -> Self { nssa_core::encryption::Ciphertext::from_inner(value.0) } } impl From for EphemeralPublicKey { fn from(value: nssa_core::encryption::EphemeralPublicKey) -> Self { Self(value.0) } } impl From for nssa_core::encryption::EphemeralPublicKey { fn from(value: EphemeralPublicKey) -> Self { nssa_core::encryption::shared_key_derivation::Secp256k1Point(value.0) } } // ============================================================================ // Signature and PublicKey conversions // ============================================================================ impl From for Signature { fn from(value: nssa::Signature) -> Self { let nssa::Signature { value } = value; Self(value) } } impl From for nssa::Signature { fn from(value: Signature) -> Self { let Signature(sig_value) = value; nssa::Signature { value: sig_value } } } impl From for PublicKey { fn from(value: nssa::PublicKey) -> Self { Self(*value.value()) } } impl TryFrom for nssa::PublicKey { type Error = nssa::error::NssaError; fn try_from(value: PublicKey) -> Result { nssa::PublicKey::try_new(value.0) } } // ============================================================================ // Proof conversions // ============================================================================ impl From for Proof { fn from(value: nssa::privacy_preserving_transaction::circuit::Proof) -> Self { Self(value.into_inner()) } } impl From for nssa::privacy_preserving_transaction::circuit::Proof { fn from(value: Proof) -> Self { nssa::privacy_preserving_transaction::circuit::Proof::from_inner(value.0) } } // ============================================================================ // EncryptedAccountData conversions // ============================================================================ impl From for EncryptedAccountData { fn from(value: nssa::privacy_preserving_transaction::message::EncryptedAccountData) -> Self { Self { ciphertext: value.ciphertext.into(), epk: value.epk.into(), view_tag: value.view_tag, } } } impl From for nssa::privacy_preserving_transaction::message::EncryptedAccountData { fn from(value: EncryptedAccountData) -> Self { Self { ciphertext: value.ciphertext.into(), epk: value.epk.into(), view_tag: value.view_tag, } } } // ============================================================================ // Transaction Message conversions // ============================================================================ impl From for PublicMessage { fn from(value: nssa::public_transaction::Message) -> Self { let nssa::public_transaction::Message { program_id, account_ids, nonces, instruction_data, } = value; Self { program_id, account_ids: account_ids.into_iter().map(Into::into).collect(), nonces, instruction_data, } } } impl From for nssa::public_transaction::Message { fn from(value: PublicMessage) -> Self { let PublicMessage { program_id, account_ids, nonces, instruction_data, } = value; Self::new_preserialized( program_id, account_ids.into_iter().map(Into::into).collect(), nonces, instruction_data, ) } } impl From for PrivacyPreservingMessage { fn from(value: nssa::privacy_preserving_transaction::message::Message) -> Self { let nssa::privacy_preserving_transaction::message::Message { public_account_ids, nonces, public_post_states, encrypted_private_post_states, new_commitments, new_nullifiers, } = value; Self { public_account_ids: public_account_ids.into_iter().map(Into::into).collect(), nonces, public_post_states: public_post_states.into_iter().map(Into::into).collect(), encrypted_private_post_states: encrypted_private_post_states .into_iter() .map(Into::into) .collect(), new_commitments: new_commitments.into_iter().map(Into::into).collect(), new_nullifiers: new_nullifiers .into_iter() .map(|(n, d)| (n.into(), d.into())) .collect(), } } } impl TryFrom for nssa::privacy_preserving_transaction::message::Message { type Error = nssa_core::account::data::DataTooBigError; fn try_from(value: PrivacyPreservingMessage) -> Result { let PrivacyPreservingMessage { public_account_ids, nonces, public_post_states, encrypted_private_post_states, new_commitments, new_nullifiers, } = value; Ok(Self { public_account_ids: public_account_ids.into_iter().map(Into::into).collect(), nonces, public_post_states: public_post_states .into_iter() .map(TryInto::try_into) .collect::, _>>()?, encrypted_private_post_states: encrypted_private_post_states .into_iter() .map(Into::into) .collect(), new_commitments: new_commitments.into_iter().map(Into::into).collect(), new_nullifiers: new_nullifiers .into_iter() .map(|(n, d)| (n.into(), d.into())) .collect(), }) } } impl From for ProgramDeploymentMessage { fn from(value: nssa::program_deployment_transaction::Message) -> Self { Self { bytecode: value.into_bytecode(), } } } impl From for nssa::program_deployment_transaction::Message { fn from(value: ProgramDeploymentMessage) -> Self { let ProgramDeploymentMessage { bytecode } = value; Self::new(bytecode) } } // ============================================================================ // WitnessSet conversions // ============================================================================ impl TryFrom for WitnessSet { type Error = (); fn try_from(_value: nssa::public_transaction::WitnessSet) -> Result { // Public transaction witness sets don't have proofs, so we can't convert them directly Err(()) } } impl From for WitnessSet { fn from(value: nssa::privacy_preserving_transaction::witness_set::WitnessSet) -> Self { let (sigs_and_pks, proof) = value.into_raw_parts(); Self { signatures_and_public_keys: sigs_and_pks .into_iter() .map(|(sig, pk)| (sig.into(), pk.into())) .collect(), proof: proof.into(), } } } impl TryFrom for nssa::privacy_preserving_transaction::witness_set::WitnessSet { type Error = nssa::error::NssaError; fn try_from(value: WitnessSet) -> Result { let WitnessSet { signatures_and_public_keys, proof, } = value; let signatures_and_public_keys = signatures_and_public_keys .into_iter() .map(|(sig, pk)| Ok((sig.into(), pk.try_into()?))) .collect::, Self::Error>>()?; Ok(Self::from_raw_parts( signatures_and_public_keys, proof.into(), )) } } // ============================================================================ // Transaction conversions // ============================================================================ impl From for PublicTransaction { fn from(value: nssa::PublicTransaction) -> Self { let hash = Hash(value.hash()); let nssa::PublicTransaction { message, witness_set, } = value; Self { hash, message: message.into(), witness_set: WitnessSet { signatures_and_public_keys: witness_set .signatures_and_public_keys() .iter() .map(|(sig, pk)| (sig.clone().into(), pk.clone().into())) .collect(), proof: Proof(vec![]), // Public transactions don't have proofs }, } } } impl TryFrom for nssa::PublicTransaction { type Error = nssa::error::NssaError; fn try_from(value: PublicTransaction) -> Result { let PublicTransaction { hash: _, message, witness_set, } = value; let WitnessSet { signatures_and_public_keys, proof: _, } = witness_set; Ok(Self::new( message.into(), nssa::public_transaction::WitnessSet::from_raw_parts( signatures_and_public_keys .into_iter() .map(|(sig, pk)| Ok((sig.into(), pk.try_into()?))) .collect::, Self::Error>>()?, ), )) } } impl From for PrivacyPreservingTransaction { fn from(value: nssa::PrivacyPreservingTransaction) -> Self { let hash = Hash(value.hash()); let nssa::PrivacyPreservingTransaction { message, witness_set, } = value; Self { hash, message: message.into(), witness_set: witness_set.into(), } } } impl TryFrom for nssa::PrivacyPreservingTransaction { type Error = nssa::error::NssaError; fn try_from(value: PrivacyPreservingTransaction) -> Result { let PrivacyPreservingTransaction { hash: _, message, witness_set, } = value; Ok(Self::new( message .try_into() .map_err(|err: nssa_core::account::data::DataTooBigError| { nssa::error::NssaError::InvalidInput(err.to_string()) })?, witness_set.try_into()?, )) } } impl From for ProgramDeploymentTransaction { fn from(value: nssa::ProgramDeploymentTransaction) -> Self { let hash = Hash(value.hash()); let nssa::ProgramDeploymentTransaction { message } = value; Self { hash, message: message.into(), } } } impl From for nssa::ProgramDeploymentTransaction { fn from(value: ProgramDeploymentTransaction) -> Self { let ProgramDeploymentTransaction { hash: _, message } = value; Self::new(message.into()) } } impl From for Transaction { fn from(value: common::transaction::NSSATransaction) -> Self { match value { common::transaction::NSSATransaction::Public(tx) => Transaction::Public(tx.into()), common::transaction::NSSATransaction::PrivacyPreserving(tx) => { Transaction::PrivacyPreserving(tx.into()) } common::transaction::NSSATransaction::ProgramDeployment(tx) => { Transaction::ProgramDeployment(tx.into()) } } } } impl TryFrom for common::transaction::NSSATransaction { type Error = nssa::error::NssaError; fn try_from(value: Transaction) -> Result { match value { Transaction::Public(tx) => { Ok(common::transaction::NSSATransaction::Public(tx.try_into()?)) } Transaction::PrivacyPreserving(tx) => Ok( common::transaction::NSSATransaction::PrivacyPreserving(tx.try_into()?), ), Transaction::ProgramDeployment(tx) => Ok( common::transaction::NSSATransaction::ProgramDeployment(tx.into()), ), } } } // ============================================================================ // Block conversions // ============================================================================ impl From for BlockHeader { fn from(value: common::block::BlockHeader) -> Self { let common::block::BlockHeader { block_id, prev_block_hash, hash, timestamp, signature, } = value; Self { block_id, prev_block_hash: Hash(prev_block_hash), hash: Hash(hash), timestamp, signature: signature.into(), } } } impl TryFrom for common::block::BlockHeader { type Error = nssa::error::NssaError; fn try_from(value: BlockHeader) -> Result { let BlockHeader { block_id, prev_block_hash, hash, timestamp, signature, } = value; Ok(Self { block_id, prev_block_hash: prev_block_hash.0, hash: hash.0, timestamp, signature: signature.into(), }) } } impl TryFrom for BlockBody { type Error = std::io::Error; fn try_from(value: common::block::BlockBody) -> Result { // Note: EncodedTransaction doesn't have a direct conversion to NSSATransaction // This conversion will decode and re-encode the transactions use borsh::BorshDeserialize as _; let common::block::BlockBody { transactions } = value; let transactions = transactions .into_iter() .map(|encoded_tx| match encoded_tx.tx_kind { common::transaction::TxKind::Public => { nssa::PublicTransaction::try_from_slice(&encoded_tx.encoded_transaction_data) .map(|tx| Transaction::Public(tx.into())) } common::transaction::TxKind::PrivacyPreserving => { nssa::PrivacyPreservingTransaction::try_from_slice( &encoded_tx.encoded_transaction_data, ) .map(|tx| Transaction::PrivacyPreserving(tx.into())) } common::transaction::TxKind::ProgramDeployment => { nssa::ProgramDeploymentTransaction::try_from_slice( &encoded_tx.encoded_transaction_data, ) .map(|tx| Transaction::ProgramDeployment(tx.into())) } }) .collect::, _>>()?; Ok(Self { transactions }) } } impl TryFrom for common::block::BlockBody { type Error = nssa::error::NssaError; fn try_from(value: BlockBody) -> Result { let BlockBody { transactions } = value; let transactions = transactions .into_iter() .map(|tx| { let nssa_tx: common::transaction::NSSATransaction = tx.try_into()?; Ok::<_, nssa::error::NssaError>(nssa_tx.into()) }) .collect::, _>>()?; Ok(Self { transactions }) } } impl TryFrom for Block { type Error = std::io::Error; fn try_from(value: common::block::Block) -> Result { let common::block::Block { header, body, bedrock_status, bedrock_parent_id, } = value; Ok(Self { header: header.into(), body: body.try_into()?, bedrock_status: bedrock_status.into(), bedrock_parent_id: MantleMsgId(bedrock_parent_id), }) } } impl TryFrom for common::block::Block { type Error = nssa::error::NssaError; fn try_from(value: Block) -> Result { let Block { header, body, bedrock_status, bedrock_parent_id, } = value; Ok(Self { header: header.try_into()?, body: body.try_into()?, bedrock_status: bedrock_status.into(), bedrock_parent_id: bedrock_parent_id.0, }) } } impl From for BedrockStatus { fn from(value: common::block::BedrockStatus) -> Self { match value { common::block::BedrockStatus::Pending => Self::Pending, common::block::BedrockStatus::Safe => Self::Safe, common::block::BedrockStatus::Finalized => Self::Finalized, } } } impl From for common::block::BedrockStatus { fn from(value: BedrockStatus) -> Self { match value { BedrockStatus::Pending => Self::Pending, BedrockStatus::Safe => Self::Safe, BedrockStatus::Finalized => Self::Finalized, } } }