Skip to content

Commit

Permalink
MAJOR: cut solana-rpc dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
grooviegermanikus committed Aug 8, 2024
1 parent ae5ab64 commit 5a92d1f
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 1,555 deletions.
1,611 changes: 69 additions & 1,542 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions connector/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "mango-feeds-connector"
version = "0.3.0"
authors = ["Christian Kamm <[email protected]>"]
version = "0.3.2"
authors = ["Christian Kamm <[email protected]>", "[email protected]"]
edition = "2021"
license = "AGPL-3.0-or-later"
description = "Listen to Solana account updates via geyser or websockets"
Expand All @@ -14,8 +14,12 @@ default = []
[dependencies]
jsonrpc-core = { workspace = true }
jsonrpc-core-client = { workspace = true }
jsonrpc-derive = "18.0.0"
jsonrpc-pubsub = "18.0.0"

solana-rpc = { workspace = true }
# note: avoid solana-rpc dependency
solana-rpc-client = "1.17"
solana-rpc-client-api = "1.17"
solana-client = { workspace = true }
solana-account-decoder = { workspace = true }
solana-sdk = { workspace = true }
Expand Down
32 changes: 32 additions & 0 deletions connector/examples/call_gpa_gma_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#![allow(unused_variables)]

use clap::Parser;

use mango_feeds_connector::snapshot::get_snapshot_gma;
use solana_sdk::pubkey::Pubkey;

#[derive(Parser, Debug, Clone)]
#[clap()]
struct Cli {
// e.g. https://mango.devnet.rpcpool.com
#[clap(short, long, env)]
rpc_url: String,

// e.g. 4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg
#[clap(short, long, env)]
program_account: Pubkey,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
solana_logger::setup_with_default("info");

let cli = Cli::parse_from(std::env::args_os());

let rpc_http_url = cli.rpc_url;
let program_id = cli.program_account;

get_snapshot_gma(rpc_http_url, vec![program_id.to_string()]).await?;

Ok(())
}
4 changes: 2 additions & 2 deletions connector/examples/snapshot_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use clap::Parser;

use jsonrpc_core_client::transports::http;
use mango_feeds_connector::GetProgramAccountsClient;
use mango_feeds_connector::solana_rpc_minimal::rpc_accounts_scan::RpcAccountsScanClient;
use solana_account_decoder::UiAccountEncoding;
use solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig};
use solana_client::rpc_response::OptionalContext;
Expand Down Expand Up @@ -31,7 +31,7 @@ async fn main() -> anyhow::Result<()> {
let rpc_http_url = cli.rpc_url;
let program_id = cli.program_account;

let rpc_client_scan = http::connect::<GetProgramAccountsClient>(&rpc_http_url)
let rpc_client_scan = http::connect::<RpcAccountsScanClient>(&rpc_http_url)
.await
.unwrap();

Expand Down
4 changes: 2 additions & 2 deletions connector/examples/websocket_example_consumer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ async fn main() -> anyhow::Result<()> {
grpc_sources: vec![],
// used for websocket+geyser
snapshot: SnapshotSourceConfig {
rpc_http_url: "http://127.0.0.1:8899".to_string(),
rpc_http_url: "http://localhost:18899/".to_string(),
},
// used only for websocket
rpc_ws_url: "ws://localhost:8900/".to_string(),
rpc_ws_url: "ws://localhost:18900/".to_string(),
};

let filter_config1 = FilterConfig {
Expand Down
3 changes: 1 addition & 2 deletions connector/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod chain_data;
pub mod grpc_plugin_source;
pub mod metrics;
pub mod snapshot;
pub mod solana_rpc_minimal;
pub mod websocket_source;

use itertools::Itertools;
Expand All @@ -12,8 +13,6 @@ use {
solana_sdk::{account::Account, pubkey::Pubkey},
};

pub use solana_rpc::rpc::rpc_accounts_scan::AccountsScanClient as GetProgramAccountsClient;

pub use solana_sdk;

trait AnyhowWrap {
Expand Down
6 changes: 3 additions & 3 deletions connector/src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use solana_client::{
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
rpc_response::{OptionalContext, RpcKeyedAccount},
};
use solana_rpc::rpc::rpc_accounts::AccountsDataClient;
use solana_sdk::{commitment_config::CommitmentConfig, slot_history::Slot};

use crate::solana_rpc_minimal::rpc_accounts_scan::RpcAccountsScanClient;
use crate::AnyhowWrap;

/// gPA snapshot struct
Expand All @@ -27,7 +27,7 @@ pub async fn get_snapshot_gpa(
rpc_http_url: String,
program_id: String,
) -> anyhow::Result<SnapshotProgramAccounts> {
let rpc_client = http::connect::<crate::GetProgramAccountsClient>(&rpc_http_url)
let rpc_client = http::connect::<RpcAccountsScanClient>(&rpc_http_url)
.await
.map_err_anyhow()?;

Expand Down Expand Up @@ -66,7 +66,7 @@ pub async fn get_snapshot_gma(
rpc_http_url: String,
ids: Vec<String>,
) -> anyhow::Result<SnapshotMultipleAccounts> {
let rpc_client = http::connect::<AccountsDataClient>(&rpc_http_url)
let rpc_client = http::connect::<RpcAccountsScanClient>(&rpc_http_url)
.await
.map_err_anyhow()?;

Expand Down
120 changes: 120 additions & 0 deletions connector/src/solana_rpc_minimal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
pub mod rpc_accounts_scan {
use jsonrpc_core::Result;
use jsonrpc_derive::rpc;
use solana_account_decoder::UiAccount;
use solana_rpc_client_api::config::{RpcAccountInfoConfig, RpcProgramAccountsConfig};
use solana_rpc_client_api::response::{
OptionalContext, Response as RpcResponse, RpcKeyedAccount,
};

/// this definition is derived from solana-rpc/rpc.rs
/// we want to avoid the heavy dependency to solana-rpc
/// the crate solana-rpc-client provides some client methods but do not expose the ```Context```we need
///
#[rpc]
pub trait RpcAccountsScan {
type Metadata;

#[rpc(meta, name = "getProgramAccounts")]
fn get_program_accounts(
&self,
meta: Self::Metadata,
program_id_str: String,
config: Option<RpcProgramAccountsConfig>,
) -> Result<OptionalContext<Vec<RpcKeyedAccount>>>;

#[rpc(meta, name = "getMultipleAccounts")]
fn get_multiple_accounts(
&self,
meta: Self::Metadata,
pubkey_strs: Vec<String>,
config: Option<RpcAccountInfoConfig>,
) -> Result<RpcResponse<Vec<Option<UiAccount>>>>;
}
}

pub mod rpc_pubsub {
use jsonrpc_core::Result;
use jsonrpc_derive::rpc;
use jsonrpc_pubsub::typed::Subscriber;
use jsonrpc_pubsub::SubscriptionId as PubSubSubscriptionId;
use solana_account_decoder::UiAccount;
use solana_rpc_client_api::config::{RpcAccountInfoConfig, RpcProgramAccountsConfig};
use solana_rpc_client_api::response::{Response as RpcResponse, RpcKeyedAccount, SlotUpdate};
use std::sync::Arc;

#[rpc]
pub trait RpcSolPubSub {
type Metadata;

#[pubsub(
subscription = "accountNotification",
subscribe,
name = "accountSubscribe"
)]
fn account_subscribe(
&self,
meta: Self::Metadata,
subscriber: Subscriber<RpcResponse<UiAccount>>,
pubkey_str: String,
config: Option<RpcAccountInfoConfig>,
);

#[pubsub(
subscription = "accountNotification",
unsubscribe,
name = "accountUnsubscribe"
)]
fn account_unsubscribe(
&self,
meta: Option<Self::Metadata>,
id: PubSubSubscriptionId,
) -> Result<bool>;

#[pubsub(
subscription = "programNotification",
subscribe,
name = "programSubscribe"
)]
fn program_subscribe(
&self,
meta: Self::Metadata,
subscriber: Subscriber<RpcResponse<RpcKeyedAccount>>,
pubkey_str: String,
config: Option<RpcProgramAccountsConfig>,
);

#[pubsub(
subscription = "programNotification",
unsubscribe,
name = "programUnsubscribe"
)]
fn program_unsubscribe(
&self,
meta: Option<Self::Metadata>,
id: PubSubSubscriptionId,
) -> Result<bool>;

#[pubsub(
subscription = "slotsUpdatesNotification",
subscribe,
name = "slotsUpdatesSubscribe"
)]
fn slots_updates_subscribe(
&self,
meta: Self::Metadata,
subscriber: Subscriber<Arc<SlotUpdate>>,
);

#[pubsub(
subscription = "slotsUpdatesNotification",
unsubscribe,
name = "slotsUpdatesUnsubscribe"
)]
fn slots_updates_unsubscribe(
&self,
meta: Option<Self::Metadata>,
id: PubSubSubscriptionId,
) -> Result<bool>;
}
}
2 changes: 1 addition & 1 deletion connector/src/websocket_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use solana_client::{
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
rpc_response::{Response, RpcKeyedAccount},
};
use solana_rpc::rpc_pubsub::RpcSolPubSubClient;
use solana_sdk::{
account::Account, commitment_config::CommitmentConfig, pubkey::Pubkey, slot_history::Slot,
};
Expand All @@ -24,6 +23,7 @@ use tokio::time::timeout;
use crate::snapshot::{
get_snapshot_gma, get_snapshot_gpa, SnapshotMultipleAccounts, SnapshotProgramAccounts,
};
use crate::solana_rpc_minimal::rpc_pubsub::RpcSolPubSubClient;
use crate::{
chain_data::SlotStatus, AccountWrite, AnyhowWrap, EntityFilter, FilterConfig, SlotUpdate,
SourceConfig,
Expand Down

0 comments on commit 5a92d1f

Please sign in to comment.