From c3021e072836f93d5288f3ce8384e1116aac2331 Mon Sep 17 00:00:00 2001 From: Kirill Fomichev Date: Mon, 17 Jun 2024 18:48:54 -0400 Subject: [PATCH] init `mod decode` --- Cargo.lock | 6 ++ old-faithful-proto/Cargo.toml | 7 ++ old-faithful-proto/src/lib.rs | 118 ++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index aa7fea01..d33f3d94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3139,8 +3139,14 @@ name = "old-faithful-proto" version = "0.1.0" dependencies = [ "anyhow", + "bincode", + "prost 0.11.9", "prost 0.12.6", "protobuf-src", + "serde", + "solana-sdk", + "solana-storage-proto", + "solana-transaction-status", "tonic 0.11.0", "tonic-build 0.11.0", ] diff --git a/old-faithful-proto/Cargo.toml b/old-faithful-proto/Cargo.toml index 07605d72..5239723c 100644 --- a/old-faithful-proto/Cargo.toml +++ b/old-faithful-proto/Cargo.toml @@ -5,7 +5,14 @@ edition = "2021" publish = false [dependencies] +anyhow = { workspace = true } +bincode = { workspace = true } prost = { workspace = true } +prost_011 = { workspace = true } +serde = { workspace = true } +solana-sdk = { workspace = true } +solana-storage-proto = { workspace = true } +solana-transaction-status = { workspace = true } tonic = { workspace = true } [build-dependencies] diff --git a/old-faithful-proto/src/lib.rs b/old-faithful-proto/src/lib.rs index 3c095021..24183b4a 100644 --- a/old-faithful-proto/src/lib.rs +++ b/old-faithful-proto/src/lib.rs @@ -3,3 +3,121 @@ pub use {prost, tonic}; pub mod proto { tonic::include_proto!("old_faithful"); } + +pub mod decode { + use { + super::{proto, solana::StoredConfirmedBlockTransaction}, + anyhow::Context, + prost_011::Message, + solana_storage_proto::convert::generated, + solana_transaction_status::{ + ConfirmedBlock, ConfirmedTransactionWithStatusMeta, TransactionWithStatusMeta, + }, + }; + + pub fn confirmed_block(block: proto::BlockResponse) -> anyhow::Result { + todo!() + } + + pub fn confirmed_transaction( + tx: proto::TransactionResponse, + ) -> anyhow::Result { + versioned_transaction( + tx.transaction + .ok_or_else(|| anyhow::anyhow!("failed to get Transaction"))?, + ) + .map(|tx_with_meta| ConfirmedTransactionWithStatusMeta { + slot: tx.slot, + tx_with_meta, + block_time: Some(tx.block_time), + }) + } + + pub fn versioned_transaction( + tx: proto::Transaction, + ) -> anyhow::Result { + Ok( + match generated::ConfirmedTransaction::decode(tx.meta.as_ref()) { + Ok(meta) => meta + .try_into() + .context("failed to decode protobuf struct to solana")?, + Err(_error) => bincode::deserialize::(&tx.meta) + .context("failed to decode with bincode")? + .into(), + }, + ) + } +} + +mod solana { + use { + serde::{Deserialize, Serialize}, + solana_sdk::{ + message::v0::LoadedAddresses, + transaction::{TransactionError, VersionedTransaction}, + }, + solana_transaction_status::{ + TransactionStatusMeta, TransactionWithStatusMeta, VersionedTransactionWithStatusMeta, + }, + }; + + #[derive(Serialize, Deserialize)] + pub struct StoredConfirmedBlockTransaction { + transaction: VersionedTransaction, + meta: Option, + } + + impl From for TransactionWithStatusMeta { + fn from(tx_with_meta: StoredConfirmedBlockTransaction) -> Self { + let StoredConfirmedBlockTransaction { transaction, meta } = tx_with_meta; + match meta { + None => Self::MissingMetadata( + transaction + .into_legacy_transaction() + .expect("versioned transactions always have meta"), + ), + Some(meta) => Self::Complete(VersionedTransactionWithStatusMeta { + transaction, + meta: meta.into(), + }), + } + } + } + + #[derive(Serialize, Deserialize)] + struct StoredConfirmedBlockTransactionStatusMeta { + err: Option, + fee: u64, + pre_balances: Vec, + post_balances: Vec, + } + + impl From for TransactionStatusMeta { + fn from(value: StoredConfirmedBlockTransactionStatusMeta) -> Self { + let StoredConfirmedBlockTransactionStatusMeta { + err, + fee, + pre_balances, + post_balances, + } = value; + let status = match &err { + None => Ok(()), + Some(err) => Err(err.clone()), + }; + Self { + status, + fee, + pre_balances, + post_balances, + inner_instructions: None, + log_messages: None, + pre_token_balances: None, + post_token_balances: None, + rewards: None, + loaded_addresses: LoadedAddresses::default(), + return_data: None, + compute_units_consumed: None, + } + } + } +}