-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Storage changes subscription #464
Changes from 7 commits
d9ce1f9
59f3a3b
f9f8099
b157e1d
44e07d6
b6f0967
7b3b494
79d3507
4883259
e5e7c4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ authors = ["Parity Technologies <[email protected]>"] | |
|
|
||
| [dependencies] | ||
| error-chain = "0.12" | ||
| fnv = "1.0" | ||
| log = "0.3" | ||
| parking_lot = "0.4" | ||
| triehash = "0.1" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ use backend::{self, BlockImportOperation}; | |
| use blockchain::{self, Info as ChainInfo, Backend as ChainBackend, HeaderBackend as ChainHeaderBackend}; | ||
| use call_executor::{CallExecutor, LocalCallExecutor}; | ||
| use executor::{RuntimeVersion, RuntimeInfo}; | ||
| use notifications::{StorageNotifications, StorageEventStream}; | ||
| use {error, in_mem, block_builder, runtime_io, bft, genesis}; | ||
|
|
||
| /// Type that implements `futures::Stream` of block import events. | ||
|
|
@@ -40,6 +41,7 @@ pub type BlockchainEventStream<Block> = mpsc::UnboundedReceiver<BlockImportNotif | |
| pub struct Client<B, E, Block> where Block: BlockT { | ||
| backend: Arc<B>, | ||
| executor: E, | ||
| storage_notifications: Mutex<StorageNotifications<Block>>, | ||
| import_notification_sinks: Mutex<Vec<mpsc::UnboundedSender<BlockImportNotification<Block>>>>, | ||
| import_lock: Mutex<()>, | ||
| importing_block: RwLock<Option<Block::Hash>>, // holds the block hash currently being imported. TODO: replace this with block queue | ||
|
|
@@ -49,7 +51,12 @@ pub struct Client<B, E, Block> where Block: BlockT { | |
| /// A source of blockchain evenets. | ||
| pub trait BlockchainEvents<Block: BlockT> { | ||
| /// Get block import event stream. | ||
| fn import_notification_stream(&self) -> mpsc::UnboundedReceiver<BlockImportNotification<Block>>; | ||
| fn import_notification_stream(&self) -> BlockchainEventStream<Block>; | ||
|
|
||
| /// Get storage changes event stream. | ||
| /// | ||
| /// Passing `None` as keys subscribes to all possible keys | ||
| fn storage_changes_notification_stream(&self, filter_keys: Option<&[StorageKey]>) -> error::Result<StorageEventStream<Block::Hash>>; | ||
| } | ||
|
|
||
| /// Chain head information. | ||
|
|
@@ -182,9 +189,10 @@ impl<B, E, Block> Client<B, E, Block> where | |
| Ok(Client { | ||
| backend, | ||
| executor, | ||
| import_notification_sinks: Mutex::new(Vec::new()), | ||
| import_lock: Mutex::new(()), | ||
| importing_block: RwLock::new(None), | ||
| storage_notifications: Default::default(), | ||
| import_notification_sinks: Default::default(), | ||
| import_lock: Default::default(), | ||
| importing_block: Default::default(), | ||
| execution_strategy, | ||
| }) | ||
| } | ||
|
|
@@ -359,7 +367,8 @@ impl<B, E, Block> Client<B, E, Block> where | |
| }, | ||
| ); | ||
| let (_, storage_update) = r?; | ||
| Some(storage_update) | ||
| overlay.commit_prospective(); | ||
| Some((storage_update, overlay.into_committed())) | ||
| }, | ||
| None => None, | ||
| }; | ||
|
|
@@ -369,8 +378,11 @@ impl<B, E, Block> Client<B, E, Block> where | |
| let unchecked: bft::UncheckedJustification<_> = justification.uncheck().into(); | ||
| transaction.set_block_data(header.clone(), body, Some(unchecked.into()), is_new_best)?; | ||
| transaction.update_authorities(authorities); | ||
| if let Some(storage_update) = storage_update { | ||
| if let Some((storage_update, changes)) = storage_update { | ||
| transaction.update_storage(storage_update)?; | ||
| // TODO [ToDr] How to handle re-orgs? Should we re-emit all storage changes? | ||
|
||
| self.storage_notifications.lock() | ||
|
||
| .trigger(&hash, changes); | ||
| } | ||
| self.backend.commit_operation(transaction)?; | ||
| if origin == BlockOrigin::NetworkBroadcast || origin == BlockOrigin::Own || origin == BlockOrigin::ConsensusBroadcast { | ||
|
|
@@ -516,16 +528,20 @@ impl<B, E, Block> bft::Authorities<Block> for Client<B, E, Block> | |
|
|
||
| impl<B, E, Block> BlockchainEvents<Block> for Client<B, E, Block> | ||
| where | ||
| B: backend::Backend<Block>, | ||
| E: CallExecutor<Block>, | ||
| Block: BlockT, | ||
| { | ||
| /// Get block import event stream. | ||
| fn import_notification_stream(&self) -> mpsc::UnboundedReceiver<BlockImportNotification<Block>> { | ||
| fn import_notification_stream(&self) -> BlockchainEventStream<Block> { | ||
| let (sink, stream) = mpsc::unbounded(); | ||
| self.import_notification_sinks.lock().push(sink); | ||
| stream | ||
| } | ||
|
|
||
| /// Get storage changes event stream. | ||
| fn storage_changes_notification_stream(&self, filter_keys: Option<&[StorageKey]>) -> error::Result<StorageEventStream<Block::Hash>> { | ||
| Ok(self.storage_notifications.lock().listen(filter_keys)) | ||
| } | ||
| } | ||
|
|
||
| impl<B, E, Block> ChainHead<Block> for Client<B, E, Block> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo:
…as keysshould be…as keyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rephrased the whole sentence, hope it's clearer now.