@ -3,12 +3,9 @@
|
|||||||
use crate::rpc_subscriptions::{Confirmations, RpcSubscriptions, SlotInfo};
|
use crate::rpc_subscriptions::{Confirmations, RpcSubscriptions, SlotInfo};
|
||||||
use jsonrpc_core::{Error, ErrorCode, Result};
|
use jsonrpc_core::{Error, ErrorCode, Result};
|
||||||
use jsonrpc_derive::rpc;
|
use jsonrpc_derive::rpc;
|
||||||
use jsonrpc_pubsub::typed::Subscriber;
|
use jsonrpc_pubsub::{typed::Subscriber, Session, SubscriptionId};
|
||||||
use jsonrpc_pubsub::{Session, SubscriptionId};
|
use solana_client::rpc_response::RpcKeyedAccount;
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::{account::Account, pubkey::Pubkey, signature::Signature, transaction};
|
||||||
use solana_sdk::pubkey::Pubkey;
|
|
||||||
use solana_sdk::signature::Signature;
|
|
||||||
use solana_sdk::transaction;
|
|
||||||
use std::sync::{atomic, Arc};
|
use std::sync::{atomic, Arc};
|
||||||
|
|
||||||
// Suppress needless_return due to
|
// Suppress needless_return due to
|
||||||
@ -28,10 +25,10 @@ pub trait RpcSolPubSub {
|
|||||||
)]
|
)]
|
||||||
fn account_subscribe(
|
fn account_subscribe(
|
||||||
&self,
|
&self,
|
||||||
_: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
_: Subscriber<Account>,
|
subscriber: Subscriber<Account>,
|
||||||
_: String,
|
pubkey_str: String,
|
||||||
_: Option<Confirmations>,
|
confirmations: Option<Confirmations>,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Unsubscribe from account notification subscription.
|
// Unsubscribe from account notification subscription.
|
||||||
@ -40,7 +37,8 @@ pub trait RpcSolPubSub {
|
|||||||
unsubscribe,
|
unsubscribe,
|
||||||
name = "accountUnsubscribe"
|
name = "accountUnsubscribe"
|
||||||
)]
|
)]
|
||||||
fn account_unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool>;
|
fn account_unsubscribe(&self, meta: Option<Self::Metadata>, id: SubscriptionId)
|
||||||
|
-> Result<bool>;
|
||||||
|
|
||||||
// Get notification every time account data owned by a particular program is changed
|
// Get notification every time account data owned by a particular program is changed
|
||||||
// Accepts pubkey parameter as base-58 encoded string
|
// Accepts pubkey parameter as base-58 encoded string
|
||||||
@ -51,10 +49,10 @@ pub trait RpcSolPubSub {
|
|||||||
)]
|
)]
|
||||||
fn program_subscribe(
|
fn program_subscribe(
|
||||||
&self,
|
&self,
|
||||||
_: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
_: Subscriber<(String, Account)>,
|
subscriber: Subscriber<RpcKeyedAccount>,
|
||||||
_: String,
|
pubkey_str: String,
|
||||||
_: Option<Confirmations>,
|
confirmations: Option<Confirmations>,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Unsubscribe from account notification subscription.
|
// Unsubscribe from account notification subscription.
|
||||||
@ -63,7 +61,8 @@ pub trait RpcSolPubSub {
|
|||||||
unsubscribe,
|
unsubscribe,
|
||||||
name = "programUnsubscribe"
|
name = "programUnsubscribe"
|
||||||
)]
|
)]
|
||||||
fn program_unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool>;
|
fn program_unsubscribe(&self, meta: Option<Self::Metadata>, id: SubscriptionId)
|
||||||
|
-> Result<bool>;
|
||||||
|
|
||||||
// Get notification when signature is verified
|
// Get notification when signature is verified
|
||||||
// Accepts signature parameter as base-58 encoded string
|
// Accepts signature parameter as base-58 encoded string
|
||||||
@ -74,10 +73,10 @@ pub trait RpcSolPubSub {
|
|||||||
)]
|
)]
|
||||||
fn signature_subscribe(
|
fn signature_subscribe(
|
||||||
&self,
|
&self,
|
||||||
_: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
_: Subscriber<transaction::Result<()>>,
|
subscriber: Subscriber<transaction::Result<()>>,
|
||||||
_: String,
|
signature_str: String,
|
||||||
_: Option<Confirmations>,
|
confirmations: Option<Confirmations>,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Unsubscribe from signature notification subscription.
|
// Unsubscribe from signature notification subscription.
|
||||||
@ -86,11 +85,15 @@ pub trait RpcSolPubSub {
|
|||||||
unsubscribe,
|
unsubscribe,
|
||||||
name = "signatureUnsubscribe"
|
name = "signatureUnsubscribe"
|
||||||
)]
|
)]
|
||||||
fn signature_unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool>;
|
fn signature_unsubscribe(
|
||||||
|
&self,
|
||||||
|
meta: Option<Self::Metadata>,
|
||||||
|
id: SubscriptionId,
|
||||||
|
) -> Result<bool>;
|
||||||
|
|
||||||
// Get notification when slot is encountered
|
// Get notification when slot is encountered
|
||||||
#[pubsub(subscription = "slotNotification", subscribe, name = "slotSubscribe")]
|
#[pubsub(subscription = "slotNotification", subscribe, name = "slotSubscribe")]
|
||||||
fn slot_subscribe(&self, _: Self::Metadata, _: Subscriber<SlotInfo>);
|
fn slot_subscribe(&self, meta: Self::Metadata, subscriber: Subscriber<SlotInfo>);
|
||||||
|
|
||||||
// Unsubscribe from slot notification subscription.
|
// Unsubscribe from slot notification subscription.
|
||||||
#[pubsub(
|
#[pubsub(
|
||||||
@ -98,7 +101,7 @@ pub trait RpcSolPubSub {
|
|||||||
unsubscribe,
|
unsubscribe,
|
||||||
name = "slotUnsubscribe"
|
name = "slotUnsubscribe"
|
||||||
)]
|
)]
|
||||||
fn slot_unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool>;
|
fn slot_unsubscribe(&self, meta: Option<Self::Metadata>, id: SubscriptionId) -> Result<bool>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -168,7 +171,7 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
|
|||||||
fn program_subscribe(
|
fn program_subscribe(
|
||||||
&self,
|
&self,
|
||||||
_meta: Self::Metadata,
|
_meta: Self::Metadata,
|
||||||
subscriber: Subscriber<(String, Account)>,
|
subscriber: Subscriber<RpcKeyedAccount>,
|
||||||
pubkey_str: String,
|
pubkey_str: String,
|
||||||
confirmations: Option<Confirmations>,
|
confirmations: Option<Confirmations>,
|
||||||
) {
|
) {
|
||||||
@ -277,21 +280,18 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::genesis_utils::{create_genesis_config, GenesisConfigInfo};
|
use crate::genesis_utils::{create_genesis_config, GenesisConfigInfo};
|
||||||
use jsonrpc_core::futures::sync::mpsc;
|
use jsonrpc_core::{futures::sync::mpsc, Response};
|
||||||
use jsonrpc_core::Response;
|
|
||||||
use jsonrpc_pubsub::{PubSubHandler, Session};
|
use jsonrpc_pubsub::{PubSubHandler, Session};
|
||||||
use solana_budget_program;
|
use solana_budget_program::{self, budget_instruction};
|
||||||
use solana_budget_program::budget_instruction;
|
|
||||||
use solana_ledger::bank_forks::BankForks;
|
use solana_ledger::bank_forks::BankForks;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::{
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
pubkey::Pubkey,
|
||||||
use solana_sdk::system_program;
|
signature::{Keypair, KeypairUtil},
|
||||||
use solana_sdk::system_transaction;
|
system_program, system_transaction,
|
||||||
use solana_sdk::transaction::{self, Transaction};
|
transaction::{self, Transaction},
|
||||||
use std::sync::RwLock;
|
};
|
||||||
use std::thread::sleep;
|
use std::{sync::RwLock, thread::sleep, time::Duration};
|
||||||
use std::time::Duration;
|
|
||||||
use tokio::prelude::{Async, Stream};
|
use tokio::prelude::{Async, Stream};
|
||||||
|
|
||||||
fn process_transaction_and_notify(
|
fn process_transaction_and_notify(
|
||||||
|
@ -4,14 +4,17 @@ use core::hash::Hash;
|
|||||||
use jsonrpc_core::futures::Future;
|
use jsonrpc_core::futures::Future;
|
||||||
use jsonrpc_pubsub::{typed::Sink, SubscriptionId};
|
use jsonrpc_pubsub::{typed::Sink, SubscriptionId};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use solana_client::rpc_response::RpcKeyedAccount;
|
||||||
use solana_ledger::bank_forks::BankForks;
|
use solana_ledger::bank_forks::BankForks;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account, clock::Slot, pubkey::Pubkey, signature::Signature, transaction,
|
account::Account, clock::Slot, pubkey::Pubkey, signature::Signature, transaction,
|
||||||
};
|
};
|
||||||
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
use std::sync::{Arc, RwLock};
|
collections::HashMap,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
pub type Confirmations = usize;
|
pub type Confirmations = usize;
|
||||||
|
|
||||||
@ -25,7 +28,7 @@ pub struct SlotInfo {
|
|||||||
type RpcAccountSubscriptions =
|
type RpcAccountSubscriptions =
|
||||||
RwLock<HashMap<Pubkey, HashMap<SubscriptionId, (Sink<Account>, Confirmations)>>>;
|
RwLock<HashMap<Pubkey, HashMap<SubscriptionId, (Sink<Account>, Confirmations)>>>;
|
||||||
type RpcProgramSubscriptions =
|
type RpcProgramSubscriptions =
|
||||||
RwLock<HashMap<Pubkey, HashMap<SubscriptionId, (Sink<(String, Account)>, Confirmations)>>>;
|
RwLock<HashMap<Pubkey, HashMap<SubscriptionId, (Sink<RpcKeyedAccount>, Confirmations)>>>;
|
||||||
type RpcSignatureSubscriptions = RwLock<
|
type RpcSignatureSubscriptions = RwLock<
|
||||||
HashMap<Signature, HashMap<SubscriptionId, (Sink<transaction::Result<()>>, Confirmations)>>,
|
HashMap<Signature, HashMap<SubscriptionId, (Sink<transaction::Result<()>>, Confirmations)>>,
|
||||||
>;
|
>;
|
||||||
@ -147,9 +150,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn notify_program(accounts: Vec<(Pubkey, Account)>, sink: &Sink<(String, Account)>, _root: Slot) {
|
fn notify_program(accounts: Vec<(Pubkey, Account)>, sink: &Sink<RpcKeyedAccount>, _root: Slot) {
|
||||||
for (pubkey, account) in accounts.iter() {
|
for (pubkey, account) in accounts.iter() {
|
||||||
sink.notify(Ok((pubkey.to_string(), account.clone())))
|
sink.notify(Ok(RpcKeyedAccount {
|
||||||
|
pubkey: pubkey.to_string(),
|
||||||
|
account: account.clone(),
|
||||||
|
}))
|
||||||
.wait()
|
.wait()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -247,7 +253,7 @@ impl RpcSubscriptions {
|
|||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
confirmations: Option<Confirmations>,
|
confirmations: Option<Confirmations>,
|
||||||
sub_id: &SubscriptionId,
|
sub_id: &SubscriptionId,
|
||||||
sink: &Sink<(String, Account)>,
|
sink: &Sink<RpcKeyedAccount>,
|
||||||
) {
|
) {
|
||||||
let mut subscriptions = self.program_subscriptions.write().unwrap();
|
let mut subscriptions = self.program_subscriptions.write().unwrap();
|
||||||
add_subscription(&mut subscriptions, program_id, confirmations, sub_id, sink);
|
add_subscription(&mut subscriptions, program_id, confirmations, sub_id, sink);
|
||||||
@ -328,8 +334,10 @@ mod tests {
|
|||||||
use crate::genesis_utils::{create_genesis_config, GenesisConfigInfo};
|
use crate::genesis_utils::{create_genesis_config, GenesisConfigInfo};
|
||||||
use jsonrpc_pubsub::typed::Subscriber;
|
use jsonrpc_pubsub::typed::Subscriber;
|
||||||
use solana_budget_program;
|
use solana_budget_program;
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::{
|
||||||
use solana_sdk::system_transaction;
|
signature::{Keypair, KeypairUtil},
|
||||||
|
system_transaction,
|
||||||
|
};
|
||||||
use tokio::prelude::{Async, Stream};
|
use tokio::prelude::{Async, Stream};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -433,7 +441,7 @@ mod tests {
|
|||||||
let string = transport_receiver.poll();
|
let string = transport_receiver.poll();
|
||||||
if let Async::Ready(Some(response)) = string.unwrap() {
|
if let Async::Ready(Some(response)) = string.unwrap() {
|
||||||
let expected = format!(
|
let expected = format!(
|
||||||
r#"{{"jsonrpc":"2.0","method":"programNotification","params":{{"result":["{:?}",{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rentEpoch":1}}],"subscription":0}}}}"#,
|
r#"{{"jsonrpc":"2.0","method":"programNotification","params":{{"result":{{"account":{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rentEpoch":1}},"pubkey":"{:?}"}},"subscription":0}}}}"#,
|
||||||
alice.pubkey()
|
alice.pubkey()
|
||||||
);
|
);
|
||||||
assert_eq!(expected, response);
|
assert_eq!(expected, response);
|
||||||
|
Reference in New Issue
Block a user