Skip to content

Commit 3fa44a5

Browse files
committed
Merge #1292: fix(store): Remove lifetime
e6433fb feat(persist): Add stage_and_commit to Persist (LLFourn) 0bee46e fix(store): Remove lifetime (LLFourn) Pull request description: Remove gratuitous use of lifetimes in the main persistence struct `Store`. Having lifetimes on this means that you have to keep the magic bytes alive longer than the database which is particularly offensive if you have to send the database to another thread. On top of that the bytes aren't even read. ACKs for top commit: evanlinjin: ACK e6433fb Tree-SHA512: 7f6d9d60951a8ceaee30719d0771e15632c6fad0702294af15409c5df492669a07299874ef5ee34e3d75bdecbbd41df29bced3ff16b2360d5d5c7687ef677ffc
2 parents 25653d7 + e6433fb commit 3fa44a5

File tree

6 files changed

+36
-34
lines changed

6 files changed

+36
-34
lines changed

crates/chain/src/persist.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ where
5555
// if written successfully, take and return `self.stage`
5656
.map(|_| Some(core::mem::take(&mut self.stage)))
5757
}
58+
59+
/// Stages a new changeset and commits it (along with any other previously staged changes) to
60+
/// the persistence backend
61+
///
62+
/// Convience method for calling [`stage`] and then [`commit`].
63+
///
64+
/// [`stage`]: Self::stage
65+
/// [`commit`]: Self::commit
66+
pub fn stage_and_commit(&mut self, changeset: C) -> Result<Option<C>, B::WriteError> {
67+
self.stage(changeset);
68+
self.commit()
69+
}
5870
}
5971

6072
/// A persistence backend for [`Persist`].

crates/file_store/src/store.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ use crate::{bincode_options, EntryIter, FileError, IterError};
1515
///
1616
/// The changesets are the results of altering a tracker implementation (`T`).
1717
#[derive(Debug)]
18-
pub struct Store<'a, C> {
19-
magic: &'a [u8],
18+
pub struct Store<C> {
19+
magic_len: usize,
2020
db_file: File,
2121
marker: PhantomData<C>,
2222
}
2323

24-
impl<'a, C> PersistBackend<C> for Store<'a, C>
24+
impl<C> PersistBackend<C> for Store<C>
2525
where
2626
C: Append + serde::Serialize + serde::de::DeserializeOwned,
2727
{
@@ -38,7 +38,7 @@ where
3838
}
3939
}
4040

41-
impl<'a, C> Store<'a, C>
41+
impl<C> Store<C>
4242
where
4343
C: Append + serde::Serialize + serde::de::DeserializeOwned,
4444
{
@@ -48,7 +48,7 @@ where
4848
/// the `Store` in the future with [`open`].
4949
///
5050
/// [`open`]: Store::open
51-
pub fn create_new<P>(magic: &'a [u8], file_path: P) -> Result<Self, FileError>
51+
pub fn create_new<P>(magic: &[u8], file_path: P) -> Result<Self, FileError>
5252
where
5353
P: AsRef<Path>,
5454
{
@@ -67,7 +67,7 @@ where
6767
.open(file_path)?;
6868
f.write_all(magic)?;
6969
Ok(Self {
70-
magic,
70+
magic_len: magic.len(),
7171
db_file: f,
7272
marker: Default::default(),
7373
})
@@ -83,7 +83,7 @@ where
8383
/// [`FileError::InvalidMagicBytes`] error variant will be returned.
8484
///
8585
/// [`create_new`]: Store::create_new
86-
pub fn open<P>(magic: &'a [u8], file_path: P) -> Result<Self, FileError>
86+
pub fn open<P>(magic: &[u8], file_path: P) -> Result<Self, FileError>
8787
where
8888
P: AsRef<Path>,
8989
{
@@ -99,7 +99,7 @@ where
9999
}
100100

101101
Ok(Self {
102-
magic,
102+
magic_len: magic.len(),
103103
db_file: f,
104104
marker: Default::default(),
105105
})
@@ -111,7 +111,7 @@ where
111111
///
112112
/// [`open`]: Store::open
113113
/// [`create_new`]: Store::create_new
114-
pub fn open_or_create_new<P>(magic: &'a [u8], file_path: P) -> Result<Self, FileError>
114+
pub fn open_or_create_new<P>(magic: &[u8], file_path: P) -> Result<Self, FileError>
115115
where
116116
P: AsRef<Path>,
117117
{
@@ -132,7 +132,7 @@ where
132132
/// always iterate over all entries until `None` is returned if you want your next write to go
133133
/// at the end; otherwise, you will write over existing entries.
134134
pub fn iter_changesets(&mut self) -> EntryIter<C> {
135-
EntryIter::new(self.magic.len() as u64, &mut self.db_file)
135+
EntryIter::new(self.magic_len as u64, &mut self.db_file)
136136
}
137137

138138
/// Loads all the changesets that have been stored as one giant changeset.

example-crates/example_bitcoind_rpc_polling/src/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fn main() -> anyhow::Result<()> {
147147
let rpc_cmd = match args.command {
148148
example_cli::Commands::ChainSpecific(rpc_cmd) => rpc_cmd,
149149
general_cmd => {
150-
let res = example_cli::handle_commands(
150+
return example_cli::handle_commands(
151151
&graph,
152152
&db,
153153
&chain,
@@ -160,8 +160,6 @@ fn main() -> anyhow::Result<()> {
160160
},
161161
general_cmd,
162162
);
163-
db.lock().unwrap().commit()?;
164-
return res;
165163
}
166164
};
167165

example-crates/example_cli/src/lib.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub type KeychainChangeSet<A> = (
2929
local_chain::ChangeSet,
3030
indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<Keychain>>,
3131
);
32-
pub type Database<'m, C> = Persist<Store<'m, C>, C>;
32+
pub type Database<C> = Persist<Store<C>, C>;
3333

3434
#[derive(Parser)]
3535
#[clap(author, version, about, long_about = None)]
@@ -457,11 +457,10 @@ where
457457

458458
let ((spk_i, spk), index_changeset) = spk_chooser(index, &Keychain::External);
459459
let db = &mut *db.lock().unwrap();
460-
db.stage(C::from((
460+
db.stage_and_commit(C::from((
461461
local_chain::ChangeSet::default(),
462462
indexed_tx_graph::ChangeSet::from(index_changeset),
463-
)));
464-
db.commit()?;
463+
)))?;
465464
let addr =
466465
Address::from_script(spk, network).context("failed to derive address")?;
467466
println!("[address @ {}] {}", spk_i, addr);
@@ -601,11 +600,10 @@ where
601600
// If we're unable to persist this, then we don't want to broadcast.
602601
{
603602
let db = &mut *db.lock().unwrap();
604-
db.stage(C::from((
603+
db.stage_and_commit(C::from((
605604
local_chain::ChangeSet::default(),
606605
indexed_tx_graph::ChangeSet::from(index_changeset),
607-
)));
608-
db.commit()?;
606+
)))?;
609607
}
610608

611609
// We don't want other callers/threads to use this address while we're using it
@@ -627,10 +625,10 @@ where
627625
// We know the tx is at least unconfirmed now. Note if persisting here fails,
628626
// it's not a big deal since we can always find it again form
629627
// blockchain.
630-
db.lock().unwrap().stage(C::from((
628+
db.lock().unwrap().stage_and_commit(C::from((
631629
local_chain::ChangeSet::default(),
632630
keychain_changeset,
633-
)));
631+
)))?;
634632
Ok(())
635633
}
636634
Err(e) => {
@@ -646,14 +644,14 @@ where
646644
}
647645

648646
#[allow(clippy::type_complexity)]
649-
pub fn init<'m, CS: clap::Subcommand, S: clap::Args, C>(
650-
db_magic: &'m [u8],
647+
pub fn init<CS: clap::Subcommand, S: clap::Args, C>(
648+
db_magic: &[u8],
651649
db_default_path: &str,
652650
) -> anyhow::Result<(
653651
Args<CS, S>,
654652
KeyMap,
655653
KeychainTxOutIndex<Keychain>,
656-
Mutex<Database<'m, C>>,
654+
Mutex<Database<C>>,
657655
C,
658656
)>
659657
where
@@ -681,7 +679,7 @@ where
681679
index.add_keychain(Keychain::Internal, internal_descriptor);
682680
}
683681

684-
let mut db_backend = match Store::<'m, C>::open_or_create_new(db_magic, &args.db_path) {
682+
let mut db_backend = match Store::<C>::open_or_create_new(db_magic, &args.db_path) {
685683
Ok(db_backend) => db_backend,
686684
// we cannot return `err` directly as it has lifetime `'m`
687685
Err(err) => return Err(anyhow::anyhow!("failed to init db backend: {:?}", err)),

example-crates/example_electrum/src/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn main() -> anyhow::Result<()> {
122122
let electrum_cmd = match &args.command {
123123
example_cli::Commands::ChainSpecific(electrum_cmd) => electrum_cmd,
124124
general_cmd => {
125-
let res = example_cli::handle_commands(
125+
return example_cli::handle_commands(
126126
&graph,
127127
&db,
128128
&chain,
@@ -135,9 +135,6 @@ fn main() -> anyhow::Result<()> {
135135
},
136136
general_cmd.clone(),
137137
);
138-
139-
db.lock().unwrap().commit()?;
140-
return res;
141138
}
142139
};
143140

example-crates/example_esplora/src/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ fn main() -> anyhow::Result<()> {
125125
example_cli::Commands::ChainSpecific(esplora_cmd) => esplora_cmd,
126126
// These are general commands handled by example_cli. Execute the cmd and return.
127127
general_cmd => {
128-
let res = example_cli::handle_commands(
128+
return example_cli::handle_commands(
129129
&graph,
130130
&db,
131131
&chain,
@@ -140,9 +140,6 @@ fn main() -> anyhow::Result<()> {
140140
},
141141
general_cmd.clone(),
142142
);
143-
144-
db.lock().unwrap().commit()?;
145-
return res;
146143
}
147144
};
148145

0 commit comments

Comments
 (0)