Skip to content

Commit 3a51016

Browse files
authored
Merge pull request #95 from rustaceanrob/cancel-1-20
Make `update` drop-able
2 parents 8f550e4 + d4e1476 commit 3a51016

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

src/lib.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub use kyoto::{
6868

6969
use kyoto::Receiver;
7070
use kyoto::UnboundedReceiver;
71-
use kyoto::{Event, IndexedBlock};
71+
use kyoto::{BlockHash, Event, IndexedBlock};
7272

7373
pub mod builder;
7474

@@ -97,6 +97,8 @@ pub struct UpdateSubscriber {
9797
chain: local_chain::LocalChain,
9898
// receive graph
9999
graph: IndexedTxGraph<ConfirmationBlockTime, KeychainTxOutIndex<KeychainKind>>,
100+
// staged changes for the chain
101+
chain_changeset: BTreeMap<u32, Option<BlockHash>>,
100102
}
101103

102104
impl UpdateSubscriber {
@@ -110,6 +112,7 @@ impl UpdateSubscriber {
110112
receiver,
111113
chain: LocalChain::from_tip(cp)?,
112114
graph: IndexedTxGraph::new(index.clone()),
115+
chain_changeset: BTreeMap::new(),
113116
})
114117
}
115118

@@ -121,47 +124,48 @@ impl UpdateSubscriber {
121124
/// running node. Production applications should define how the application handles
122125
/// these events and displays them to end users.
123126
pub async fn update(&mut self) -> Option<Update> {
124-
let mut chain_changeset = BTreeMap::new();
125127
while let Some(message) = self.receiver.recv().await {
126128
match message {
127129
Event::Block(IndexedBlock { height, block }) => {
128130
let hash = block.header.block_hash();
129-
chain_changeset.insert(height, Some(hash));
131+
self.chain_changeset.insert(height, Some(hash));
130132
let _ = self.graph.apply_block_relevant(&block, height);
131133
}
132134
Event::BlocksDisconnected(headers) => {
133135
for header in headers {
134136
let height = header.height;
135-
chain_changeset.insert(height, None);
137+
self.chain_changeset.insert(height, None);
136138
}
137139
}
138140
Event::Synced(SyncUpdate {
139141
tip,
140142
recent_history,
141143
}) => {
142-
if chain_changeset.is_empty()
144+
if self.chain_changeset.is_empty()
143145
&& self.chain.tip().height() == tip.height
144146
&& self.chain.tip().hash() == tip.hash
145147
{
146148
// return early if we're already synced
147149
return None;
148150
}
149151
recent_history.into_iter().for_each(|(height, header)| {
150-
chain_changeset.insert(height, Some(header.block_hash()));
152+
self.chain_changeset
153+
.insert(height, Some(header.block_hash()));
151154
});
152155
break;
153156
}
154157
}
155158
}
156-
self.chain
157-
.apply_changeset(&local_chain::ChangeSet::from(chain_changeset))
158-
.expect("chain was initialized with genesis");
159159
Some(self.get_scan_response())
160160
}
161161

162162
// When the client is believed to have synced to the chain tip of most work,
163163
// we can return a wallet update.
164164
fn get_scan_response(&mut self) -> Update {
165+
let chain_changeset = core::mem::take(&mut self.chain_changeset);
166+
self.chain
167+
.apply_changeset(&local_chain::ChangeSet::from(chain_changeset))
168+
.expect("chain was initialized with genesis");
165169
let tx_update = TxUpdate::from(self.graph.graph().clone());
166170
let graph = core::mem::take(&mut self.graph);
167171
let last_active_indices = graph.index.last_used_indices();

0 commit comments

Comments
 (0)