Modularize beacon node backend#4718
Conversation
…dularize-beacon-node-backend
|
I'm currently working on adding Redb to the beacon node backend. Here are some notes I've taken so far on my work RedbTheres a few difference's between LevelDB and Redb that I'll describe below fsyncInfo about redb transaction durability can be found here For now I translate We could decide to use CompactionLevelDB allows for compacting over a range of values. Redb only allows for compacting the full db. It seems like our LevelDB implementation compacts across all keys in the DB. If thats the case we should be all good here. TablesRedb introduces the concept of tables. We can either use one table for everything, or spin up tables by column name. I'm currently going down the path of spinning up tables by column name. This causes issues with |
…serilev/lighthouse into modularize-beacon-node-backend
michaelsproul
left a comment
There was a problem hiding this comment.
Looking really good, I think we're getting close!
I just had a few questions and some suggested cosmetic changes
| let results = store.hot_db.iter_column_from::<Vec<u8>>( | ||
| DBColumn::LightClientUpdate, | ||
| &start_period.to_le_bytes(), | ||
| move |sync_committee_bytes, _| match u64::from_ssz_bytes(sync_committee_bytes) { | ||
| Ok(sync_committee_period) => { | ||
| if sync_committee_period >= start_period + count { | ||
| return false; | ||
| } | ||
| true | ||
| } | ||
| Err(e) => { | ||
| error!( | ||
| log, | ||
| "Error decoding sync committee bytes from the db"; | ||
| "error" => ?e | ||
| ); | ||
| false | ||
| } | ||
| }, | ||
| ); |
There was a problem hiding this comment.
Why is this change required? It seems we had to remove an assert to get the test related to this method to pass
There was a problem hiding this comment.
I've removed this change and updated iter_column_from to not take in a predicate anymore
There was a problem hiding this comment.
Heh, I think Jimmy wanted the predicate for data column stuff, but looks like we can probably just use take_while chained onto the iter_column_from. We can reassess in the context of his PR.
| pub fn delete_batch(&self, col: DBColumn, ops: Vec<Hash256>) -> Result<(), Error> { | ||
| let new_ops: HashSet<&[u8]> = ops.iter().map(|v| v.as_slice()).collect(); | ||
| self.hot_db.delete_batch(col, new_ops) | ||
| } |
There was a problem hiding this comment.
I feel like if we use do_atomically in delete_temp_states we don't need delete_batch?
There was a problem hiding this comment.
delete_temp_states was very slow w/ redb because we were deleting data across multiple columns via do_atomically. This meant we were opening/closing database tables a bunch of times. delete_batch was added to do deletions across a single column.
Another option could be to ensure db operations in do_atomically are ordered by DBColumn so that we only open/close the table once per set of column operations.
maybe the API could look something like
pub fn do_atomically(&self, ops_batch: HashMap<DBColumn, Vec<KeyValueStoreOp>>)
lmk what you think
There was a problem hiding this comment.
Ok, makes sense. Let's leave delete_batch for now and we can work on improving the API to optimise redb further
…serilev/lighthouse into modularize-beacon-node-backend
|
@mergify queue |
✅ The pull request has been merged automaticallyDetailsThe pull request has been merged automatically at a1b7d61 |
Issue Addressed
#4669
Proposed Changes
Modularize the beacon node backend to make it easier to add new database implementations
Additional Info
The existing
KeyValueStoretrait already does some abstraction, however the codebases assumes the KV store is always LevelDB.I created a
BeaconNodeBackendtype that implements theKeyValueStoreandItemStoretraits. I then replaced all references ofLevelDbto the newBeaconNodeBackendtype. Within theBeaconNodeBackendtype I used thecfgmacro which should allow us to switch between different database implementations via config changes.