-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(db-arch): ctx functions and use of global db #2378
base: dev
Are you sure you want to change the base?
Conversation
mm2src/mm2_core/src/mm_ctx.rs
Outdated
pub fn global_dir(&self) -> Result<PathBuf, String> { | ||
let path = path_to_db_root(self.conf["dbdir"].as_str()).join("global"); | ||
if !path.exists() { | ||
std::fs::create_dir_all(&path).map_err(|e| format!("Failed to create global directory: {}", e))?; |
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.
i opted for this io to be sync to avoid the ripple effect it will cause if it's async (it is A LOT esp in address db usage).
The path will probably always exist (for global and wallet dirs) anyways unless this is the first run.
For address dirs, "first runs" happen more frequently, but still, by no means a lot.
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.
Welldone!
mm2src/mm2_core/src/mm_ctx.rs
Outdated
if !path.exists() { | ||
std::fs::create_dir_all(&path).map_err(|e| format!("Failed to create wallet directory: {}", e))?; | ||
} | ||
Ok(path) |
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.
we probably should add a new field to MmCtx
e.tg rmd160_hex
and initialize once same place rmd160
is initialized.
This will enable us to avoid constructing hex::encode(self.rmd160().as_slice())
every time we need to call wallet_dir
and similar functions
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.
aha agreed. there is a lot of room for optimizations really (e.g. cache connections and return arcs to them). but i didn't wanna optimize early on to not make the review harder.
we def can add this now. or else wait till the skeleton is ready and target unoptimized code then (it should be abstracted behind funcs like these, so the optimization then wouldn't really bloat the review).
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.
by caching the connection, we don't re-calculate the hex every call to wallet DB.
01b7085
// TODO: Can't use `conn` in the return statement because it's a mutex borrow, and also clippy complains when assigning the result into a temporary `result`. | ||
#[allow(clippy::let_and_return)] | ||
let result = conn | ||
.prepare(SELECT_PEERS_NAMES)? | ||
.query_map([], |row| Ok((row.get(0)?, row.get(1)?)))? | ||
.collect::<SqlResult<HashMap<String, String>>>() | ||
.collect::<SqlResult<HashMap<String, String>>>(); | ||
result |
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.
conn
is not dropped at the right place!. In this case, we need to explicitly drop conn after we're done with it.
pub fn select_peers_names(ctx: &MmArc) -> SqlResult<HashMap<String, String>, SqlError> {
#[cfg(not(feature = "new-db-arch"))]
let conn = ctx.sqlite_connection();
#[cfg(feature = "new-db-arch")]
let conn = ctx.global_db().unwrap();
let peers_names = conn
.prepare(SELECT_PEERS_NAMES)?
.query_map([], |row| Ok((row.get(0)?, row.get(1)?)))?
.collect::<SqlResult<HashMap<String, String>>>();
drop(conn);
peers_names
}
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.
ummmm... no it should be dropped since peer_names is owned.
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.
well, compiler doesn't think so.
conn dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type std::ops::ControlFlow<std::result::Result<std::convert::Infallible, db_common::sqlite::rusqlite::Error>, db_common::sqlite::rusqlite::Statement<'_>>
mm2src/mm2_core/src/mm_ctx.rs
Outdated
#[cfg(all(feature = "new-db-arch", not(target_arch = "wasm32")))] | ||
pub fn global_db(&self) -> Result<Connection, String> { | ||
// TODO: Initialize this DB on startup and cache it in the context to avoid having this function return `Result`. | ||
// Note that you are using `unwrap`s in the calls to `global_db`. | ||
let path = self.global_dir()?.join("global.db"); | ||
log_sqlite_file_open_attempt(&path); | ||
let connection = try_s!(Connection::open(path)); | ||
Ok(connection) | ||
} |
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.
/ TODO: Initialize this DB on startup and cache it in the context to avoid having this function return
Result
.
// Note that you are usingunwrap
s in the calls toglobal_db
.
in addition to doing this, it will help us avoid performing these operations every time the function is called. There similar functions too e.g wallet_dir, async_wallet_db
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.
mm2src/mm2_core/src/mm_ctx.rs
Outdated
#[cfg(all(feature = "new-db-arch", not(target_arch = "wasm32")))] | ||
pub fn wallet_db(&self) -> Result<Connection, String> { | ||
// TODO: Initialize this DB on startup and cache it in the context to avoid having this function return `Result`. | ||
let path = self.wallet_dir()?.join("MM2-shared.db"); | ||
log_sqlite_file_open_attempt(&path); | ||
let connection = try_s!(Connection::open(path)); | ||
Ok(connection) | ||
} | ||
|
||
/// Returns an AsyncSQL connection to the shared wallet database. | ||
/// | ||
/// This replaces `self.wallet_db()` and should be used for new implementations. | ||
#[cfg(all(feature = "new-db-arch", not(target_arch = "wasm32")))] | ||
pub async fn async_wallet_db(&self) -> Result<AsyncConnection, String> { | ||
let path = self.wallet_dir()?.join("KOMODEFI.db"); | ||
log_sqlite_file_open_attempt(&path); | ||
let connection = try_s!(AsyncConnection::open(path).await); | ||
Ok(connection) | ||
} | ||
|
||
/// Returns a SQL connection to the address database. | ||
#[cfg(all(feature = "new-db-arch", not(target_arch = "wasm32")))] | ||
pub fn address_db(&self, address: &str) -> Result<Connection, String> { | ||
let path = self.address_dir(address)?.join("MM2.db"); | ||
log_sqlite_file_open_attempt(&path); | ||
let connection = try_s!(Connection::open(path)); | ||
Ok(connection) | ||
} |
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.
We should probably prefer strictly typed errors instead of String
s on these to be able to handle various error situations in the incoming implementations.
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.
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.
I am confident that our tests would fail if there was a problem with using an incorrect DB path/connection/etc.
LGTM other than my previous notes.
this avoids re-computations that will result in the same output. this also removes the fallible method annotation from global and wallet db getters, since we know for sure they are initialized and have a copy of them. note that the name MM2-Shared.db for the wallet db was changed to a simple wallet.db. Also for the async wallet db (KOMODEFI.db), it changes to wallet.db as well for simplicity (merging them/their tables together in the same DB file).
The first PR in the series of PRs related to database architecture changes. Changes here won't have effect on builds since they are guarded with a
new-db-arch
feature flag.This adds some utility methods in the context to get the
global
&wallet
&address
databases and data directories.Also adds some concrete usages of the global db.