Add notify_subscribers()
This commit is contained in:
parent
377d45c9dd
commit
905b1e2775
|
@ -557,6 +557,10 @@ impl Bank {
|
||||||
Accounts::load_slow(&accounts, pubkey)
|
Accounts::load_slow(&accounts, pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_account_modified_since_parent(&self, pubkey: &Pubkey) -> Option<Account> {
|
||||||
|
Accounts::load_slow(&[&self.accounts], pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn transaction_count(&self) -> u64 {
|
pub fn transaction_count(&self) -> u64 {
|
||||||
self.accounts.transaction_count()
|
self.accounts.transaction_count()
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,24 +200,16 @@ mod tests {
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::prelude::{Async, Stream};
|
use tokio::prelude::{Async, Stream};
|
||||||
|
|
||||||
pub fn process_transaction_and_notify(
|
fn process_transaction_and_notify(
|
||||||
bank: &Bank,
|
bank: &Arc<Bank>,
|
||||||
tx: &Transaction,
|
tx: &Transaction,
|
||||||
subscriptions: &RpcSubscriptions,
|
subscriptions: &RpcSubscriptions,
|
||||||
) -> bank::Result<()> {
|
) -> bank::Result<Arc<Bank>> {
|
||||||
bank.process_transaction(tx)?;
|
bank.process_transaction(tx)?;
|
||||||
|
subscriptions.notify_subscribers(&bank);
|
||||||
|
|
||||||
for pubkey in &tx.account_keys {
|
// Simulate a block boundary
|
||||||
if let Some(account) = &bank.get_account(pubkey) {
|
Ok(Arc::new(Bank::new_from_parent(&bank)))
|
||||||
subscriptions.check_account(pubkey, account);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let signature = &tx.signatures[0];
|
|
||||||
let status = bank.get_signature_status(signature).unwrap();
|
|
||||||
subscriptions.check_signature(signature, &status);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_session() -> Arc<Session> {
|
fn create_session() -> Arc<Session> {
|
||||||
|
@ -323,7 +315,7 @@ mod tests {
|
||||||
budget_program_id,
|
budget_program_id,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
let arc_bank = process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
||||||
|
|
||||||
let tx = SystemTransaction::new_program_account(
|
let tx = SystemTransaction::new_program_account(
|
||||||
&alice,
|
&alice,
|
||||||
|
@ -335,7 +327,7 @@ mod tests {
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
let arc_bank = process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
||||||
|
|
||||||
// Test signature confirmation notification #1
|
// Test signature confirmation notification #1
|
||||||
let string = receiver.poll();
|
let string = receiver.poll();
|
||||||
|
@ -363,7 +355,6 @@ mod tests {
|
||||||
if let Async::Ready(Some(response)) = string.unwrap() {
|
if let Async::Ready(Some(response)) = string.unwrap() {
|
||||||
assert_eq!(serde_json::to_string(&expected).unwrap(), response);
|
assert_eq!(serde_json::to_string(&expected).unwrap(), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx = BudgetTransaction::new_when_signed(
|
let tx = BudgetTransaction::new_when_signed(
|
||||||
&contract_funds,
|
&contract_funds,
|
||||||
bob_pubkey,
|
bob_pubkey,
|
||||||
|
@ -373,7 +364,7 @@ mod tests {
|
||||||
50,
|
50,
|
||||||
last_id,
|
last_id,
|
||||||
);
|
);
|
||||||
process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
let arc_bank = process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
||||||
sleep(Duration::from_millis(200));
|
sleep(Duration::from_millis(200));
|
||||||
|
|
||||||
// Test signature confirmation notification #2
|
// Test signature confirmation notification #2
|
||||||
|
@ -401,7 +392,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx = SystemTransaction::new_account(&alice, witness.pubkey(), 1, last_id, 0);
|
let tx = SystemTransaction::new_account(&alice, witness.pubkey(), 1, last_id, 0);
|
||||||
process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
let arc_bank = process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
||||||
sleep(Duration::from_millis(200));
|
sleep(Duration::from_millis(200));
|
||||||
let tx = BudgetTransaction::new_signature(
|
let tx = BudgetTransaction::new_signature(
|
||||||
&witness,
|
&witness,
|
||||||
|
@ -409,7 +400,7 @@ mod tests {
|
||||||
bob_pubkey,
|
bob_pubkey,
|
||||||
last_id,
|
last_id,
|
||||||
);
|
);
|
||||||
process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
let arc_bank = process_transaction_and_notify(&arc_bank, &tx, &rpc.subscriptions).unwrap();
|
||||||
sleep(Duration::from_millis(200));
|
sleep(Duration::from_millis(200));
|
||||||
|
|
||||||
let expected_userdata = arc_bank
|
let expected_userdata = arc_bank
|
||||||
|
|
|
@ -5,7 +5,6 @@ use crate::cluster_info::ClusterInfo;
|
||||||
use crate::rpc::*;
|
use crate::rpc::*;
|
||||||
use crate::service::Service;
|
use crate::service::Service;
|
||||||
use crate::storage_stage::StorageState;
|
use crate::storage_stage::StorageState;
|
||||||
use bs58;
|
|
||||||
use jsonrpc_core::MetaIoHandler;
|
use jsonrpc_core::MetaIoHandler;
|
||||||
use jsonrpc_http_server::{hyper, AccessControlAllowOrigin, DomainsValidation, ServerBuilder};
|
use jsonrpc_http_server::{hyper, AccessControlAllowOrigin, DomainsValidation, ServerBuilder};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! The `pubsub` module implements a threaded subscription service on client RPC request
|
//! The `pubsub` module implements a threaded subscription service on client RPC request
|
||||||
|
|
||||||
use crate::bank::{self, BankError};
|
use crate::bank::{self, Bank, BankError};
|
||||||
use crate::rpc_status::RpcSignatureStatus;
|
use crate::rpc_status::RpcSignatureStatus;
|
||||||
use jsonrpc_core::futures::Future;
|
use jsonrpc_core::futures::Future;
|
||||||
use jsonrpc_pubsub::typed::Sink;
|
use jsonrpc_pubsub::typed::Sink;
|
||||||
|
@ -116,12 +116,34 @@ impl RpcSubscriptions {
|
||||||
});
|
});
|
||||||
found
|
found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Notify subscribers of changes to any accounts or new signatures since
|
||||||
|
/// the bank's last checkpoint.
|
||||||
|
pub fn notify_subscribers(&self, bank: &Bank) {
|
||||||
|
let pubkeys: Vec<_> = {
|
||||||
|
let subs = self.account_subscriptions.read().unwrap();
|
||||||
|
subs.keys().cloned().collect()
|
||||||
|
};
|
||||||
|
for pubkey in &pubkeys {
|
||||||
|
if let Some(account) = &bank.get_account_modified_since_parent(pubkey) {
|
||||||
|
self.check_account(pubkey, account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let signatures: Vec<_> = {
|
||||||
|
let subs = self.signature_subscriptions.read().unwrap();
|
||||||
|
subs.keys().cloned().collect()
|
||||||
|
};
|
||||||
|
for signature in &signatures {
|
||||||
|
let status = bank.get_signature_status(signature).unwrap();
|
||||||
|
self.check_signature(signature, &status);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::bank::Bank;
|
|
||||||
use crate::genesis_block::GenesisBlock;
|
use crate::genesis_block::GenesisBlock;
|
||||||
use jsonrpc_pubsub::typed::Subscriber;
|
use jsonrpc_pubsub::typed::Subscriber;
|
||||||
use solana_sdk::budget_program;
|
use solana_sdk::budget_program;
|
||||||
|
@ -155,7 +177,7 @@ mod tests {
|
||||||
|
|
||||||
assert!(subscriptions
|
assert!(subscriptions
|
||||||
.account_subscriptions
|
.account_subscriptions
|
||||||
.write()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.contains_key(&alice.pubkey()));
|
.contains_key(&alice.pubkey()));
|
||||||
|
|
||||||
|
@ -170,7 +192,7 @@ mod tests {
|
||||||
subscriptions.remove_account_subscription(&sub_id);
|
subscriptions.remove_account_subscription(&sub_id);
|
||||||
assert!(!subscriptions
|
assert!(!subscriptions
|
||||||
.account_subscriptions
|
.account_subscriptions
|
||||||
.write()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.contains_key(&alice.pubkey()));
|
.contains_key(&alice.pubkey()));
|
||||||
}
|
}
|
||||||
|
@ -193,7 +215,7 @@ mod tests {
|
||||||
|
|
||||||
assert!(subscriptions
|
assert!(subscriptions
|
||||||
.signature_subscriptions
|
.signature_subscriptions
|
||||||
.write()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.contains_key(&signature));
|
.contains_key(&signature));
|
||||||
|
|
||||||
|
@ -207,7 +229,7 @@ mod tests {
|
||||||
subscriptions.remove_signature_subscription(&sub_id);
|
subscriptions.remove_signature_subscription(&sub_id);
|
||||||
assert!(!subscriptions
|
assert!(!subscriptions
|
||||||
.signature_subscriptions
|
.signature_subscriptions
|
||||||
.write()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.contains_key(&signature));
|
.contains_key(&signature));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue