yellowstone-block-machine 0.9.0-rc2

State machine for reconstructing Solana blocks from Geyser events
Documentation
use {
    crate::event::{
        BlockMetaView, EntryView, GeyserEventView, GeyserEventViewer, SlotStatusKind,
        SlotUpdateView,
    },
    yellowstone_grpc_proto::geyser::{
        SlotStatus, SubscribeUpdate, subscribe_update::UpdateOneof,
    },
};

impl From<SlotStatus> for SlotStatusKind {
    fn from(value: SlotStatus) -> Self {
        match value {
            SlotStatus::SlotFirstShredReceived => SlotStatusKind::FirstShredReceived,
            SlotStatus::SlotCompleted => SlotStatusKind::Completed,
            SlotStatus::SlotCreatedBank => SlotStatusKind::CreatedBank,
            SlotStatus::SlotDead => SlotStatusKind::Dead,
            SlotStatus::SlotProcessed => SlotStatusKind::Processed,
            SlotStatus::SlotConfirmed => SlotStatusKind::Confirmed,
            SlotStatus::SlotFinalized => SlotStatusKind::Finalized,
        }
    }
}

impl GeyserEventViewer for SubscribeUpdate {
    type GeyserEventT = SubscribeUpdate;

    fn view(event: &SubscribeUpdate) -> GeyserEventView<'_> {
        let Some(update_oneof) = event.update_oneof.as_ref() else {
            return GeyserEventView::Other;
        };
        match update_oneof {
            UpdateOneof::Slot(slot_update) => GeyserEventView::Slot(SlotUpdateView {
                slot: slot_update.slot,
                parent: slot_update.parent,
                status: slot_update.status().into(),
                dead_error: slot_update.dead_error.is_some(),
            }),
            UpdateOneof::BlockMeta(block_meta) => GeyserEventView::BlockMeta(BlockMetaView {
                slot: block_meta.slot,
                parent_slot: block_meta.parent_slot,
                entries_count: block_meta.entries_count,
                executed_transaction_count: block_meta.executed_transaction_count,
                blockhash: block_meta.blockhash.as_str(),
            }),
            UpdateOneof::Entry(entry) => GeyserEventView::Entry(EntryView {
                slot: entry.slot,
                index: entry.index,
                starting_transaction_index: entry.starting_transaction_index,
                executed_transaction_count: entry.executed_transaction_count,
                hash: entry.hash.as_slice(),
                filters: event.filters.as_slice(),
            }),
            UpdateOneof::Transaction(tx) => GeyserEventView::Transaction { slot: tx.slot },
            UpdateOneof::Account(account) => GeyserEventView::Account { slot: account.slot },
            UpdateOneof::TransactionStatus(tx) => {
                GeyserEventView::TransactionStatus { slot: tx.slot }
            }
            _ => GeyserEventView::Other,
        }
    }
}