2024-01-22 09:26:26 -08:00
|
|
|
use crate::Message;
|
2024-01-26 10:25:39 -08:00
|
|
|
use crate::Message::GeyserSubscribeUpdate;
|
2023-12-13 06:57:50 -08:00
|
|
|
use async_stream::stream;
|
2023-12-22 08:05:48 -08:00
|
|
|
use futures::{Stream, StreamExt};
|
2023-12-19 05:19:27 -08:00
|
|
|
use log::{info, warn};
|
2023-12-15 03:01:29 -08:00
|
|
|
use merge_streams::MergeStreams;
|
2023-12-13 06:57:50 -08:00
|
|
|
use solana_sdk::clock::Slot;
|
2023-12-15 01:25:21 -08:00
|
|
|
use yellowstone_grpc_proto::geyser::SubscribeUpdate;
|
2023-12-14 03:58:47 -08:00
|
|
|
|
2023-12-19 02:27:42 -08:00
|
|
|
pub trait FromYellowstoneExtractor {
|
2023-12-14 04:09:43 -08:00
|
|
|
// Target is something like ProducedBlock
|
2023-12-14 03:58:47 -08:00
|
|
|
type Target;
|
2023-12-14 04:09:43 -08:00
|
|
|
fn map_yellowstone_update(&self, update: SubscribeUpdate) -> Option<(Slot, Self::Target)>;
|
2023-12-14 01:58:26 -08:00
|
|
|
}
|
|
|
|
|
2023-12-15 02:43:00 -08:00
|
|
|
/// use streams created by ``create_geyser_reconnecting_stream``
|
2023-12-19 02:57:23 -08:00
|
|
|
/// this is agnostic to the type of the stream
|
|
|
|
/// CAUTION: do not try to use with commitment level "processed" as this will form trees (forks) and not a sequence
|
2023-12-19 04:42:26 -08:00
|
|
|
pub fn create_multiplexed_stream<E>(
|
2023-12-15 03:12:06 -08:00
|
|
|
grpc_source_streams: Vec<impl Stream<Item = Message>>,
|
2023-12-19 02:57:23 -08:00
|
|
|
extractor: E,
|
|
|
|
) -> impl Stream<Item = E::Target>
|
2023-12-15 01:25:21 -08:00
|
|
|
where
|
2023-12-19 02:57:23 -08:00
|
|
|
E: FromYellowstoneExtractor,
|
2023-12-14 01:58:26 -08:00
|
|
|
{
|
2023-12-15 02:43:00 -08:00
|
|
|
if grpc_source_streams.is_empty() {
|
2023-12-19 02:57:23 -08:00
|
|
|
panic!("Must have at least one grpc source");
|
2023-12-13 06:57:50 -08:00
|
|
|
}
|
|
|
|
|
2023-12-19 05:19:27 -08:00
|
|
|
info!(
|
|
|
|
"Starting multiplexer with {} sources",
|
|
|
|
grpc_source_streams.len()
|
|
|
|
);
|
2023-12-14 01:58:26 -08:00
|
|
|
|
2023-12-15 03:01:29 -08:00
|
|
|
let mut streams = vec![];
|
2023-12-19 05:19:27 -08:00
|
|
|
for (idx, grpc_stream) in grpc_source_streams.into_iter().enumerate() {
|
2023-12-19 02:57:23 -08:00
|
|
|
let tagged = grpc_stream.map(move |msg| TaggedMessage {
|
2023-12-15 07:11:01 -08:00
|
|
|
stream_idx: idx,
|
|
|
|
payload: msg,
|
|
|
|
});
|
|
|
|
streams.push(Box::pin(tagged));
|
2023-12-14 01:58:26 -08:00
|
|
|
}
|
2023-12-13 06:57:50 -08:00
|
|
|
|
2023-12-15 03:01:29 -08:00
|
|
|
let merged_streams = streams.merge();
|
|
|
|
|
2023-12-19 02:27:42 -08:00
|
|
|
extract_payload_from_geyser_updates(merged_streams, extractor)
|
2023-12-14 01:58:26 -08:00
|
|
|
}
|
2023-12-13 06:57:50 -08:00
|
|
|
|
2023-12-19 04:42:26 -08:00
|
|
|
struct TaggedMessage {
|
|
|
|
pub stream_idx: usize,
|
|
|
|
pub payload: Message,
|
|
|
|
}
|
|
|
|
|
2023-12-19 05:19:27 -08:00
|
|
|
fn extract_payload_from_geyser_updates<E>(
|
|
|
|
merged_stream: impl Stream<Item = TaggedMessage>,
|
|
|
|
extractor: E,
|
|
|
|
) -> impl Stream<Item = E::Target>
|
2023-12-15 01:25:21 -08:00
|
|
|
where
|
2023-12-19 02:27:42 -08:00
|
|
|
E: FromYellowstoneExtractor,
|
2023-12-14 01:58:26 -08:00
|
|
|
{
|
2023-12-14 04:09:43 -08:00
|
|
|
let mut tip: Slot = 0;
|
2023-12-14 01:58:26 -08:00
|
|
|
stream! {
|
2023-12-19 02:57:23 -08:00
|
|
|
for await TaggedMessage {stream_idx, payload} in merged_stream {
|
2023-12-15 07:11:01 -08:00
|
|
|
match payload {
|
2023-12-15 03:12:06 -08:00
|
|
|
GeyserSubscribeUpdate(update) => {
|
2023-12-14 09:39:12 -08:00
|
|
|
// take only the update messages we want
|
2023-12-20 00:06:16 -08:00
|
|
|
if let Some((proposed_slot, block)) = extractor.map_yellowstone_update(*update) {
|
2023-12-14 09:39:12 -08:00
|
|
|
if proposed_slot > tip {
|
|
|
|
tip = proposed_slot;
|
|
|
|
yield block;
|
|
|
|
}
|
2023-12-14 04:09:43 -08:00
|
|
|
}
|
2023-12-13 06:57:50 -08:00
|
|
|
}
|
2023-12-15 08:02:42 -08:00
|
|
|
Message::Connecting(attempt) => {
|
|
|
|
if attempt > 1 {
|
|
|
|
warn!("Stream-{} performs reconnect attempt {}", stream_idx, attempt);
|
|
|
|
}
|
2023-12-14 09:39:12 -08:00
|
|
|
}
|
2023-12-13 06:57:50 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|