|
21 | 21 | }, |
22 | 22 | tokio::{fs, sync::Mutex}, |
23 | 23 | tonic::transport::{channel::ClientTlsConfig, Certificate}, |
24 | | - yellowstone_grpc_client::{GeyserGrpcClient, GeyserGrpcClientError, Interceptor}, |
| 24 | + yellowstone_grpc_client::{ |
| 25 | + GeyserGrpcBuilder, GeyserGrpcClient, GeyserGrpcClientError, Interceptor, |
| 26 | + }, |
25 | 27 | yellowstone_grpc_geyser::plugin::{convert_from, filter::message::FilteredUpdate}, |
26 | 28 | yellowstone_grpc_proto::{ |
27 | 29 | geyser::SlotStatus, |
@@ -89,6 +91,10 @@ struct Args { |
89 | 91 | #[clap(long)] |
90 | 92 | connect_timeout_ms: Option<u64>, |
91 | 93 |
|
| 94 | + /// Connect via Unix Domain Socket at this path instead of TCP |
| 95 | + #[clap(long)] |
| 96 | + uds: Option<PathBuf>, |
| 97 | + |
92 | 98 | /// Sets the tower service default internal buffer size, default is 1024 |
93 | 99 | #[clap(long)] |
94 | 100 | buffer_size: Option<usize>, |
@@ -150,7 +156,7 @@ impl Args { |
150 | 156 | Some(self.commitment.unwrap_or_default().into()) |
151 | 157 | } |
152 | 158 |
|
153 | | - async fn connect(&self) -> anyhow::Result<GeyserGrpcClient<impl Interceptor + Clone>> { |
| 159 | + async fn build(&self) -> anyhow::Result<GeyserGrpcBuilder> { |
154 | 160 | let mut tls_config = ClientTlsConfig::new().with_native_roots(); |
155 | 161 | if let Some(path) = &self.ca_certificate { |
156 | 162 | let bytes = fs::read(path).await?; |
@@ -206,7 +212,7 @@ impl Args { |
206 | 212 | builder = builder.timeout(Duration::from_millis(duration)); |
207 | 213 | } |
208 | 214 |
|
209 | | - builder.connect().await.map_err(Into::into) |
| 215 | + Ok(builder) |
210 | 216 | } |
211 | 217 | } |
212 | 218 |
|
@@ -652,6 +658,71 @@ impl Action { |
652 | 658 | } |
653 | 659 | } |
654 | 660 |
|
| 661 | +async fn run_action( |
| 662 | + mut client: GeyserGrpcClient<impl Interceptor>, |
| 663 | + action: &Action, |
| 664 | + commitment: Option<CommitmentLevel>, |
| 665 | +) -> anyhow::Result<()> { |
| 666 | + match action { |
| 667 | + Action::HealthCheck => client |
| 668 | + .health_check() |
| 669 | + .await |
| 670 | + .map_err(anyhow::Error::new) |
| 671 | + .map(|response| info!("response: {response:?}")), |
| 672 | + Action::HealthWatch => geyser_health_watch(client).await, |
| 673 | + Action::Subscribe(_) => { |
| 674 | + let (request, resub, stats, verify_encoding) = action |
| 675 | + .get_subscribe_request(commitment) |
| 676 | + .await? |
| 677 | + .ok_or_else(|| anyhow::anyhow!("expect subscribe action"))?; |
| 678 | + |
| 679 | + geyser_subscribe(client, request, resub, stats, verify_encoding).await |
| 680 | + } |
| 681 | + Action::SubscribeDeshred(_) => { |
| 682 | + let (request, stats) = action |
| 683 | + .get_subscribe_deshred_request() |
| 684 | + .ok_or_else(|| anyhow::anyhow!("expect subscribe deshred action"))?; |
| 685 | + |
| 686 | + geyser_subscribe_deshred(client, request, stats).await |
| 687 | + } |
| 688 | + Action::SubscribeReplayInfo => client |
| 689 | + .subscribe_replay_info() |
| 690 | + .await |
| 691 | + .map_err(anyhow::Error::new) |
| 692 | + .map(|response| info!("response: {response:?}")), |
| 693 | + Action::Ping { count } => client |
| 694 | + .ping(*count) |
| 695 | + .await |
| 696 | + .map_err(anyhow::Error::new) |
| 697 | + .map(|response| info!("response: {response:?}")), |
| 698 | + Action::GetLatestBlockhash => client |
| 699 | + .get_latest_blockhash(commitment) |
| 700 | + .await |
| 701 | + .map_err(anyhow::Error::new) |
| 702 | + .map(|response| info!("response: {response:?}")), |
| 703 | + Action::GetBlockHeight => client |
| 704 | + .get_block_height(commitment) |
| 705 | + .await |
| 706 | + .map_err(anyhow::Error::new) |
| 707 | + .map(|response| info!("response: {response:?}")), |
| 708 | + Action::GetSlot => client |
| 709 | + .get_slot(commitment) |
| 710 | + .await |
| 711 | + .map_err(anyhow::Error::new) |
| 712 | + .map(|response| info!("response: {response:?}")), |
| 713 | + Action::IsBlockhashValid { blockhash } => client |
| 714 | + .is_blockhash_valid(blockhash.clone(), commitment) |
| 715 | + .await |
| 716 | + .map_err(anyhow::Error::new) |
| 717 | + .map(|response| info!("response: {response:?}")), |
| 718 | + Action::GetVersion => client |
| 719 | + .get_version() |
| 720 | + .await |
| 721 | + .map_err(anyhow::Error::new) |
| 722 | + .map(|response| info!("response: {response:?}")), |
| 723 | + } |
| 724 | +} |
| 725 | + |
655 | 726 | #[tokio::main] |
656 | 727 | async fn main() -> anyhow::Result<()> { |
657 | 728 | env::set_var( |
@@ -680,74 +751,29 @@ async fn main() -> anyhow::Result<()> { |
680 | 751 | drop(zero_attempts); |
681 | 752 |
|
682 | 753 | let commitment = args.get_commitment(); |
683 | | - let mut client = args.connect().await.map_err(backoff::Error::transient)?; |
684 | | - info!("Connected"); |
| 754 | + let builder = args.build().await.map_err(backoff::Error::transient)?; |
685 | 755 |
|
686 | | - match &args.action { |
687 | | - Action::HealthCheck => client |
688 | | - .health_check() |
689 | | - .await |
690 | | - .map_err(anyhow::Error::new) |
691 | | - .map(|response| info!("response: {response:?}")), |
692 | | - Action::HealthWatch => geyser_health_watch(client).await, |
693 | | - Action::Subscribe(_) => { |
694 | | - let (request, resub, stats, verify_encoding) = args |
695 | | - .action |
696 | | - .get_subscribe_request(commitment) |
697 | | - .await |
698 | | - .map_err(backoff::Error::Permanent)? |
699 | | - .ok_or(backoff::Error::Permanent(anyhow::anyhow!( |
700 | | - "expect subscribe action" |
701 | | - )))?; |
702 | | - |
703 | | - geyser_subscribe(client, request, resub, stats, verify_encoding).await |
704 | | - } |
705 | | - Action::SubscribeDeshred(_) => { |
706 | | - let (request, stats) = args.action.get_subscribe_deshred_request().ok_or( |
707 | | - backoff::Error::Permanent(anyhow::anyhow!( |
708 | | - "expect subscribe deshred action" |
709 | | - )), |
710 | | - )?; |
711 | | - |
712 | | - geyser_subscribe_deshred(client, request, stats).await |
713 | | - } |
714 | | - Action::SubscribeReplayInfo => client |
715 | | - .subscribe_replay_info() |
716 | | - .await |
717 | | - .map_err(anyhow::Error::new) |
718 | | - .map(|response| info!("response: {response:?}")), |
719 | | - Action::Ping { count } => client |
720 | | - .ping(*count) |
721 | | - .await |
722 | | - .map_err(anyhow::Error::new) |
723 | | - .map(|response| info!("response: {response:?}")), |
724 | | - Action::GetLatestBlockhash => client |
725 | | - .get_latest_blockhash(commitment) |
726 | | - .await |
727 | | - .map_err(anyhow::Error::new) |
728 | | - .map(|response| info!("response: {response:?}")), |
729 | | - Action::GetBlockHeight => client |
730 | | - .get_block_height(commitment) |
| 756 | + if let Some(uds_path) = &args.uds { |
| 757 | + let client = builder |
| 758 | + .connect_uds(uds_path) |
731 | 759 | .await |
732 | 760 | .map_err(anyhow::Error::new) |
733 | | - .map(|response| info!("response: {response:?}")), |
734 | | - Action::GetSlot => client |
735 | | - .get_slot(commitment) |
| 761 | + .map_err(backoff::Error::transient)?; |
| 762 | + info!("Connected"); |
| 763 | + run_action(client, &args.action, commitment) |
736 | 764 | .await |
737 | | - .map_err(anyhow::Error::new) |
738 | | - .map(|response| info!("response: {response:?}")), |
739 | | - Action::IsBlockhashValid { blockhash } => client |
740 | | - .is_blockhash_valid(blockhash.clone(), commitment) |
| 765 | + .map_err(backoff::Error::transient)?; |
| 766 | + } else { |
| 767 | + let client = builder |
| 768 | + .connect() |
741 | 769 | .await |
742 | 770 | .map_err(anyhow::Error::new) |
743 | | - .map(|response| info!("response: {response:?}")), |
744 | | - Action::GetVersion => client |
745 | | - .get_version() |
| 771 | + .map_err(backoff::Error::transient)?; |
| 772 | + info!("Connected"); |
| 773 | + run_action(client, &args.action, commitment) |
746 | 774 | .await |
747 | | - .map_err(anyhow::Error::new) |
748 | | - .map(|response| info!("response: {response:?}")), |
| 775 | + .map_err(backoff::Error::transient)?; |
749 | 776 | } |
750 | | - .map_err(backoff::Error::transient)?; |
751 | 777 |
|
752 | 778 | Ok::<(), backoff::Error<anyhow::Error>>(()) |
753 | 779 | } |
|
0 commit comments