-
Notifications
You must be signed in to change notification settings - Fork 324
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: change data store backend to use liblmdb directly (#11357)
This PR adds a new backend implementation for data stores that's based on a thin layer on top of lmdb.c. This is the same layer used by `NativeWorldState`. This enables us to have tighter control over how data is serialized (no more bigint issues #9690 #9793), how it's accessed and enable us to use a consistent version of lmdb across our stack. Things brings with it a change of interface since reads and writes are asynchronous. ## Architecture The architecture is similar to `NativeWorldState`: a module that wraps lmdb.c and provides C++ idiomatic access to databases/transactions/cursors [liblmdb](https://github.com/AztecProtocol/aztec-packages/blob/feat/lmdb-wrapper/barretenberg/cpp/src/barretenberg/lmdblib/lmdb_store.hpp). This module is thread safe. This module is then exposed through node-module-api to Nodejs. The communication interface between the C++ code and Nodejs is based on passing msgpack encoded messages around. The addon interface is really simple, only exposing a single class with a single asynchronous method `call: (message: Buffer) => Promise<Buffer>`. The C++ module does not have its own thread pool, it will piggy back off the Nodejs thread pool, which means we have to be careful not to exhaust it. On the Nodejs side we create a new `AsyncStore` backend that implements the same interface (only async). ## Transactions LMDB supports multiple concurrent readers, but one writer. The `WriteTransaction` class in Nodejs accumulates writes locally and sends them to the database as one big, atomic batch. Any reads that happen while a write transaction is open (and in the same async context) take the uncommitted data into account. While `WriteTransaction` is accumulating writes, reads to the database are still honoured, but they will only see committed data (providing isolation from dirty writes). The `WriteTransaction` object is only available in the async context (using `AsyncLocalStorage`) that started that operation. The Nodejs store queues up write transactions so that only one is active at a time. ## Cursors Cursors on the Nodejs side implement the `AsyncIterable` protocol so they can be used in `for await of` loops and can be passed to our helpers in aztec/foundation (e.g. `toArray`, `take`, etc) Cursors use a long-lived read transaction. A lot of the queries used in our stores actual depend on cursors (e.g. `getLatestSynchedL2Block` - starts a cursor at the end of the database and reads one block). We have a limited number of readers available in C++, if this number is reached then the text read will block until a reader becomes available. The Nodejs store uses a semaphore that only allows up to `maxReaders - 1` cursors to be open at any one time. We always leave one reader available to perform simple gets (otherwise we'd risk blocking the entire thread pool) We've added two 'optimizations' to our cursor implementation: (1) when starting a cursor the first page of results is sent back immediately and (2) if we know we want a small number of results (e.g. the last block in `getLatestSynchedL2Block`) then close the cursors in the same operation (this way we avoid keeping a reader open that will be closed in the next async execution) ## Performance In tests the performance is similar to the old backend. There is a penalty to reads (reads are async now) but writes are on par. ## Changes to existing stores The only modification necessary has been to have async reads and await the write operations in transactions. ## Ported data stores - the archiver (blocks, logs, contracts, txs) - the tx mempool - the proving job store ## TODO - [x] port attestation pool, peer store - [ ] add metrics - [ ] fix merge conflicts 😢 --------- Co-authored-by: PhilWindle <philip.windle@gmail.com>
- Loading branch information
1 parent
ccaf6db
commit 7e3a38e
Showing
161 changed files
with
6,607 additions
and
1,801 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -e | ||
|
||
# run commands relative to parent directory | ||
cd $(dirname $0)/.. | ||
|
||
DEFAULT_TESTS=LMDBStoreTest.*:LMDBEnvironmentTest.* | ||
TEST=${1:-$DEFAULT_TESTS} | ||
PRESET=${PRESET:-clang16} | ||
|
||
cmake --build --preset $PRESET --target lmdblib_tests | ||
./build/bin/lmdblib_tests --gtest_filter=$TEST |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 1 addition & 6 deletions
7
barretenberg/cpp/src/barretenberg/crypto/merkle_tree/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,11 @@ | ||
# merkle tree is agnostic to hash function | ||
barretenberg_module( | ||
crypto_merkle_tree | ||
lmdb | ||
lmdblib | ||
) | ||
|
||
if (NOT FUZZING) | ||
# but the tests use pedersen and poseidon | ||
target_link_libraries(crypto_merkle_tree_tests PRIVATE stdlib_pedersen_hash stdlib_poseidon2) | ||
add_dependencies(crypto_merkle_tree_tests lmdb_repo) | ||
add_dependencies(crypto_merkle_tree_test_objects lmdb_repo) | ||
endif() | ||
|
||
add_dependencies(crypto_merkle_tree lmdb_repo) | ||
add_dependencies(crypto_merkle_tree_objects lmdb_repo) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 0 additions & 38 deletions
38
barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_database.cpp
This file was deleted.
Oops, something went wrong.
14 changes: 0 additions & 14 deletions
14
barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_db_transaction.cpp
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
7e3a38e
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.
Possible performance regression was detected for benchmark 'C++ Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold
1.05
.wasmClientIVCBench/Full/6
82651.25711600001
ms/iter75002.674347
ms/iter1.10
commit(t)
3757146058
ns/iter3232912435
ns/iter1.16
This comment was automatically generated by workflow using github-action-benchmark.
CC: @ludamad @codygunton