2026-01-26 23:31:28 +03:00

649 lines
20 KiB
Rust

//! Conversions between indexer_service_protocol types and nssa/nssa_core types
use crate::*;
// ============================================================================
// Account-related conversions
// ============================================================================
impl From<nssa_core::account::AccountId> for AccountId {
fn from(value: nssa_core::account::AccountId) -> Self {
Self {
value: value.into_value(),
}
}
}
impl From<AccountId> for nssa_core::account::AccountId {
fn from(value: AccountId) -> Self {
let AccountId { value } = value;
nssa_core::account::AccountId::new(value)
}
}
impl From<nssa_core::account::Account> 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<Account> for nssa_core::account::Account {
type Error = nssa_core::account::data::DataTooBigError;
fn try_from(value: Account) -> Result<Self, Self::Error> {
let Account {
program_owner,
balance,
data,
nonce,
} = value;
Ok(nssa_core::account::Account {
program_owner,
balance,
data: data.try_into()?,
nonce,
})
}
}
impl From<nssa_core::account::Data> for Data {
fn from(value: nssa_core::account::Data) -> Self {
Self(value.into_inner())
}
}
impl TryFrom<Data> for nssa_core::account::Data {
type Error = nssa_core::account::data::DataTooBigError;
fn try_from(value: Data) -> Result<Self, Self::Error> {
nssa_core::account::Data::try_from(value.0)
}
}
// ============================================================================
// Commitment and Nullifier conversions
// ============================================================================
impl From<nssa_core::Commitment> for Commitment {
fn from(value: nssa_core::Commitment) -> Self {
Self(value.to_byte_array())
}
}
impl From<Commitment> for nssa_core::Commitment {
fn from(value: Commitment) -> Self {
nssa_core::Commitment::from_byte_array(value.0)
}
}
impl From<nssa_core::Nullifier> for Nullifier {
fn from(value: nssa_core::Nullifier) -> Self {
Self(value.to_byte_array())
}
}
impl From<Nullifier> for nssa_core::Nullifier {
fn from(value: Nullifier) -> Self {
nssa_core::Nullifier::from_byte_array(value.0)
}
}
impl From<nssa_core::CommitmentSetDigest> for CommitmentSetDigest {
fn from(value: nssa_core::CommitmentSetDigest) -> Self {
Self(value)
}
}
impl From<CommitmentSetDigest> for nssa_core::CommitmentSetDigest {
fn from(value: CommitmentSetDigest) -> Self {
value.0
}
}
// ============================================================================
// Encryption-related conversions
// ============================================================================
impl From<nssa_core::encryption::Ciphertext> for Ciphertext {
fn from(value: nssa_core::encryption::Ciphertext) -> Self {
Self(value.into_inner())
}
}
impl From<Ciphertext> for nssa_core::encryption::Ciphertext {
fn from(value: Ciphertext) -> Self {
nssa_core::encryption::Ciphertext::from_inner(value.0)
}
}
impl From<nssa_core::encryption::EphemeralPublicKey> for EphemeralPublicKey {
fn from(value: nssa_core::encryption::EphemeralPublicKey) -> Self {
Self(value.0)
}
}
impl From<EphemeralPublicKey> 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<nssa::Signature> for Signature {
fn from(value: nssa::Signature) -> Self {
let nssa::Signature { value } = value;
Self(value)
}
}
impl From<Signature> for nssa::Signature {
fn from(value: Signature) -> Self {
let Signature(sig_value) = value;
nssa::Signature { value: sig_value }
}
}
impl From<nssa::PublicKey> for PublicKey {
fn from(value: nssa::PublicKey) -> Self {
Self(*value.value())
}
}
impl TryFrom<PublicKey> for nssa::PublicKey {
type Error = nssa::error::NssaError;
fn try_from(value: PublicKey) -> Result<Self, Self::Error> {
nssa::PublicKey::try_new(value.0)
}
}
// ============================================================================
// Proof conversions
// ============================================================================
impl From<nssa::privacy_preserving_transaction::circuit::Proof> for Proof {
fn from(value: nssa::privacy_preserving_transaction::circuit::Proof) -> Self {
Self(value.into_inner())
}
}
impl From<Proof> 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<nssa::privacy_preserving_transaction::message::EncryptedAccountData>
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<EncryptedAccountData>
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<nssa::public_transaction::Message> 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<PublicMessage> 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<nssa::privacy_preserving_transaction::message::Message> 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<PrivacyPreservingMessage> for nssa::privacy_preserving_transaction::message::Message {
type Error = nssa_core::account::data::DataTooBigError;
fn try_from(value: PrivacyPreservingMessage) -> Result<Self, Self::Error> {
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::<Result<Vec<_>, _>>()?,
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<nssa::program_deployment_transaction::Message> for ProgramDeploymentMessage {
fn from(value: nssa::program_deployment_transaction::Message) -> Self {
Self {
bytecode: value.into_bytecode(),
}
}
}
impl From<ProgramDeploymentMessage> for nssa::program_deployment_transaction::Message {
fn from(value: ProgramDeploymentMessage) -> Self {
let ProgramDeploymentMessage { bytecode } = value;
Self::new(bytecode)
}
}
// ============================================================================
// WitnessSet conversions
// ============================================================================
impl TryFrom<nssa::public_transaction::WitnessSet> for WitnessSet {
type Error = ();
fn try_from(_value: nssa::public_transaction::WitnessSet) -> Result<Self, Self::Error> {
// Public transaction witness sets don't have proofs, so we can't convert them directly
Err(())
}
}
impl From<nssa::privacy_preserving_transaction::witness_set::WitnessSet> 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<WitnessSet> for nssa::privacy_preserving_transaction::witness_set::WitnessSet {
type Error = nssa::error::NssaError;
fn try_from(value: WitnessSet) -> Result<Self, Self::Error> {
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::<Result<Vec<_>, Self::Error>>()?;
Ok(Self::from_raw_parts(
signatures_and_public_keys,
proof.into(),
))
}
}
// ============================================================================
// Transaction conversions
// ============================================================================
impl From<nssa::PublicTransaction> for PublicTransaction {
fn from(value: nssa::PublicTransaction) -> Self {
Self {
message: value.message().clone().into(),
witness_set: WitnessSet {
signatures_and_public_keys: value
.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<PublicTransaction> for nssa::PublicTransaction {
type Error = nssa::error::NssaError;
fn try_from(value: PublicTransaction) -> Result<Self, Self::Error> {
let PublicTransaction {
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::<Result<Vec<_>, Self::Error>>()?,
),
))
}
}
impl From<nssa::PrivacyPreservingTransaction> for PrivacyPreservingTransaction {
fn from(value: nssa::PrivacyPreservingTransaction) -> Self {
Self {
message: value.message().clone().into(),
witness_set: value.witness_set().clone().into(),
}
}
}
impl TryFrom<PrivacyPreservingTransaction> for nssa::PrivacyPreservingTransaction {
type Error = nssa::error::NssaError;
fn try_from(value: PrivacyPreservingTransaction) -> Result<Self, Self::Error> {
let PrivacyPreservingTransaction {
message,
witness_set,
} = value;
Ok(Self::new(
message.try_into().map_err(|_| {
nssa::error::NssaError::InvalidInput("Data too big error".to_string())
})?,
witness_set.try_into()?,
))
}
}
impl From<nssa::ProgramDeploymentTransaction> for ProgramDeploymentTransaction {
fn from(value: nssa::ProgramDeploymentTransaction) -> Self {
Self {
message: value.into_message().into(),
}
}
}
impl From<ProgramDeploymentTransaction> for nssa::ProgramDeploymentTransaction {
fn from(value: ProgramDeploymentTransaction) -> Self {
let ProgramDeploymentTransaction { message } = value;
Self::new(message.into())
}
}
impl From<common::transaction::NSSATransaction> 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<Transaction> for common::transaction::NSSATransaction {
type Error = nssa::error::NssaError;
fn try_from(value: Transaction) -> Result<Self, Self::Error> {
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<common::block::BlockHeader> 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<BlockHeader> for common::block::BlockHeader {
type Error = nssa::error::NssaError;
fn try_from(value: BlockHeader) -> Result<Self, Self::Error> {
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<common::block::BlockBody> for BlockBody {
type Error = std::io::Error;
fn try_from(value: common::block::BlockBody) -> Result<Self, Self::Error> {
// 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::<Result<Vec<_>, _>>()?;
Ok(Self { transactions })
}
}
impl TryFrom<BlockBody> for common::block::BlockBody {
type Error = nssa::error::NssaError;
fn try_from(value: BlockBody) -> Result<Self, Self::Error> {
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::<Result<Vec<_>, _>>()?;
Ok(Self { transactions })
}
}
impl TryFrom<common::block::Block> for Block {
type Error = std::io::Error;
fn try_from(value: common::block::Block) -> Result<Self, Self::Error> {
let common::block::Block {
header,
body,
bedrock_status,
} = value;
Ok(Self {
header: header.into(),
body: body.try_into()?,
bedrock_status: bedrock_status.into(),
})
}
}
impl TryFrom<Block> for common::block::Block {
type Error = nssa::error::NssaError;
fn try_from(value: Block) -> Result<Self, Self::Error> {
let Block {
header,
body,
bedrock_status,
} = value;
Ok(Self {
header: header.try_into()?,
body: body.try_into()?,
bedrock_status: bedrock_status.into(),
})
}
}
impl From<common::block::BedrockStatus> 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<BedrockStatus> for common::block::BedrockStatus {
fn from(value: BedrockStatus) -> Self {
match value {
BedrockStatus::Pending => Self::Pending,
BedrockStatus::Safe => Self::Safe,
BedrockStatus::Finalized => Self::Finalized,
}
}
}