Skip to content

Commit

Permalink
feat: new world state (#8776)
Browse files Browse the repository at this point in the history
This PR enables a new WorldState implementation written in C++. This
brings huge performance benefits.

---------

Co-authored-by: PhilWindle <[email protected]>
  • Loading branch information
alexghr and PhilWindle authored Oct 8, 2024
1 parent 814b6d0 commit 41f3934
Show file tree
Hide file tree
Showing 122 changed files with 9,635 additions and 6,153 deletions.
2 changes: 1 addition & 1 deletion barretenberg/cpp/scripts/merkle_tree_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set -e
# run commands relative to parent directory
cd $(dirname $0)/..

DEFAULT_TESTS=PersistedIndexedTreeTest.*:PersistedAppendOnlyTreeTest.*:LMDBStoreTest.*
DEFAULT_TESTS=PersistedIndexedTreeTest.*:PersistedAppendOnlyTreeTest.*:LMDBStoreTest.*:PersistedContentAddressedIndexedTreeTest.*:PersistedContentAddressedAppendOnlyTreeTest.*
TEST=${1:-$DEFAULT_TESTS}
PRESET=${PRESET:-clang16}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
#include "barretenberg/crypto/merkle_tree/append_only_tree/append_only_tree.hpp"
#include "barretenberg/common/thread_pool.hpp"
#include "barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.hpp"
#include "barretenberg/crypto/merkle_tree/fixtures.hpp"
#include "barretenberg/crypto/merkle_tree/hash.hpp"
#include "barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp"
#include "barretenberg/crypto/merkle_tree/indexed_tree/indexed_tree.hpp"
#include "barretenberg/crypto/merkle_tree/lmdb_store/lmdb_store.hpp"
#include "barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp"
#include "barretenberg/crypto/merkle_tree/node_store/array_store.hpp"
#include "barretenberg/crypto/merkle_tree/node_store/cached_tree_store.hpp"
#include "barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp"
#include "barretenberg/crypto/merkle_tree/response.hpp"
#include "barretenberg/crypto/merkle_tree/signal.hpp"
#include "barretenberg/ecc/curves/bn254/fr.hpp"
#include "barretenberg/numeric/random/engine.hpp"
#include <benchmark/benchmark.h>
#include <cstdint>
#include <filesystem>
#include <memory>

using namespace benchmark;
using namespace bb::crypto::merkle_tree;

namespace {
using StoreType = CachedTreeStore<LMDBStore, fr>;
using StoreType = ContentAddressedCachedTreeStore<bb::fr>;

using Pedersen = AppendOnlyTree<StoreType, PedersenHashPolicy>;
using Poseidon2 = AppendOnlyTree<StoreType, Poseidon2HashPolicy>;
using Pedersen = ContentAddressedAppendOnlyTree<StoreType, PedersenHashPolicy>;
using Poseidon2 = ContentAddressedAppendOnlyTree<StoreType, Poseidon2HashPolicy>;

const size_t TREE_DEPTH = 32;
const size_t MAX_BATCH_SIZE = 128;
const size_t MAX_BATCH_SIZE = 64;

template <typename TreeType> void perform_batch_insert(TreeType& tree, const std::vector<fr>& values)
{
Expand Down Expand Up @@ -52,12 +53,11 @@ template <typename TreeType> void append_only_tree_bench(State& state) noexcept
std::string name = random_string();
std::filesystem::create_directories(directory);
uint32_t num_threads = 16;
LMDBEnvironment environment = LMDBEnvironment(directory, 1024 * 1024, 2, num_threads);

LMDBStore db(environment, name, false, false, integer_key_cmp);
StoreType store(name, depth, db);
ThreadPool workers(num_threads);
TreeType tree = TreeType(store, workers);
LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
std::unique_ptr<StoreType> store = std::make_unique<StoreType>(name, depth, db);
std::shared_ptr<ThreadPool> workers = std::make_shared<ThreadPool>(num_threads);
TreeType tree = TreeType(std::move(store), workers);

for (auto _ : state) {
state.PauseTiming();
Expand All @@ -71,16 +71,16 @@ template <typename TreeType> void append_only_tree_bench(State& state) noexcept

std::filesystem::remove_all(directory);
}
BENCHMARK(append_only_tree_bench<Pedersen>)
BENCHMARK(append_only_tree_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(2, MAX_BATCH_SIZE)
->Iterations(100);
->Iterations(1000);
BENCHMARK(append_only_tree_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(2, MAX_BATCH_SIZE)
->Iterations(1000);
->Range(512, 8192)
->Iterations(10);

} // namespace

Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,44 @@
#include "barretenberg/crypto/merkle_tree/indexed_tree/indexed_tree.hpp"
#include "barretenberg/common/thread_pool.hpp"
#include "barretenberg/crypto/merkle_tree/fixtures.hpp"
#include "barretenberg/crypto/merkle_tree/hash.hpp"
#include "barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.hpp"
#include "barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp"
#include "barretenberg/crypto/merkle_tree/lmdb_store/callbacks.hpp"
#include "barretenberg/crypto/merkle_tree/lmdb_store/lmdb_store.hpp"
#include "barretenberg/crypto/merkle_tree/node_store/cached_tree_store.hpp"
#include "barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp"
#include "barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp"
#include "barretenberg/crypto/merkle_tree/response.hpp"
#include "barretenberg/numeric/random/engine.hpp"
#include <benchmark/benchmark.h>
#include <filesystem>
#include <memory>
#include <vector>

using namespace benchmark;
using namespace bb::crypto::merkle_tree;

using StoreType = CachedTreeStore<LMDBStore, NullifierLeafValue>;
using StoreType = ContentAddressedCachedTreeStore<NullifierLeafValue>;

using Poseidon2 = IndexedTree<StoreType, Poseidon2HashPolicy>;
using Pedersen = IndexedTree<StoreType, PedersenHashPolicy>;
using Poseidon2 = ContentAddressedIndexedTree<StoreType, Poseidon2HashPolicy>;
using Pedersen = ContentAddressedIndexedTree<StoreType, PedersenHashPolicy>;

const size_t TREE_DEPTH = 40;
const size_t MAX_BATCH_SIZE = 128;
const size_t MAX_BATCH_SIZE = 64;

template <typename TreeType> void add_values(TreeType& tree, const std::vector<NullifierLeafValue>& values)
{
Signal signal(1);
auto completion = [&](const auto&) -> void { signal.signal_level(0); };
typename TreeType::AddCompletionCallback completion = [&](const auto&) -> void { signal.signal_level(0); };

tree.add_or_update_values(values, completion);
signal.wait_for_level(0);
}

template <typename TreeType> void add_values_with_witness(TreeType& tree, const std::vector<NullifierLeafValue>& values)
{
Signal signal(1);
typename TreeType::AddCompletionCallbackWithWitness completion = [&](const auto&) -> void {
signal.signal_level(0);
};

tree.add_or_update_values(values, completion);
signal.wait_for_level(0);
Expand All @@ -39,12 +53,18 @@ template <typename TreeType> void multi_thread_indexed_tree_bench(State& state)
std::string name = random_string();
std::filesystem::create_directories(directory);
uint32_t num_threads = 16;
LMDBEnvironment environment = LMDBEnvironment(directory, 1024 * 1024, 2, num_threads);

LMDBStore db(environment, name, false, false, integer_key_cmp);
StoreType store(name, depth, db);
ThreadPool workers(num_threads);
TreeType tree = TreeType(store, workers, batch_size);
LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
std::unique_ptr<StoreType> store = std::make_unique<StoreType>(name, depth, db);
std::shared_ptr<ThreadPool> workers = std::make_shared<ThreadPool>(num_threads);
TreeType tree = TreeType(std::move(store), workers, batch_size);

const size_t initial_size = 1024 * 16;
std::vector<NullifierLeafValue> initial_batch(initial_size);
for (size_t i = 0; i < batch_size; ++i) {
initial_batch[i] = fr(random_engine.get_random_uint256());
}
add_values(tree, initial_batch);

for (auto _ : state) {
state.PauseTiming();
Expand All @@ -66,12 +86,18 @@ template <typename TreeType> void single_thread_indexed_tree_bench(State& state)
std::string name = random_string();
std::filesystem::create_directories(directory);
uint32_t num_threads = 1;
LMDBEnvironment environment = LMDBEnvironment(directory, 1024 * 1024, 2, num_threads);

LMDBStore db(environment, name, false, false, integer_key_cmp);
StoreType store(name, depth, db);
ThreadPool workers(num_threads);
TreeType tree = TreeType(store, workers, batch_size);
LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
std::unique_ptr<StoreType> store = std::make_unique<StoreType>(name, depth, db);
std::shared_ptr<ThreadPool> workers = std::make_shared<ThreadPool>(num_threads);
TreeType tree = TreeType(std::move(store), workers, batch_size);

const size_t initial_size = 1024 * 16;
std::vector<NullifierLeafValue> initial_batch(initial_size);
for (size_t i = 0; i < batch_size; ++i) {
initial_batch[i] = fr(random_engine.get_random_uint256());
}
add_values(tree, initial_batch);

for (auto _ : state) {
state.PauseTiming();
Expand All @@ -83,27 +109,119 @@ template <typename TreeType> void single_thread_indexed_tree_bench(State& state)
add_values(tree, values);
}
}
BENCHMARK(single_thread_indexed_tree_bench<Pedersen>)

template <typename TreeType> void multi_thread_indexed_tree_with_witness_bench(State& state) noexcept
{
const size_t batch_size = size_t(state.range(0));
const size_t depth = TREE_DEPTH;

std::string directory = random_temp_directory();
std::string name = random_string();
std::filesystem::create_directories(directory);
uint32_t num_threads = 16;

LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
std::unique_ptr<StoreType> store = std::make_unique<StoreType>(name, depth, db);
std::shared_ptr<ThreadPool> workers = std::make_shared<ThreadPool>(num_threads);
TreeType tree = TreeType(std::move(store), workers, batch_size);

const size_t initial_size = 1024 * 16;
std::vector<NullifierLeafValue> initial_batch(initial_size);
for (size_t i = 0; i < batch_size; ++i) {
initial_batch[i] = fr(random_engine.get_random_uint256());
}
add_values(tree, initial_batch);

for (auto _ : state) {
state.PauseTiming();
std::vector<NullifierLeafValue> values(batch_size);
for (size_t i = 0; i < batch_size; ++i) {
values[i] = fr(random_engine.get_random_uint256());
}
state.ResumeTiming();
add_values_with_witness(tree, values);
}
}

template <typename TreeType> void single_thread_indexed_tree_with_witness_bench(State& state) noexcept
{
const size_t batch_size = size_t(state.range(0));
const size_t depth = TREE_DEPTH;

std::string directory = random_temp_directory();
std::string name = random_string();
std::filesystem::create_directories(directory);
uint32_t num_threads = 1;

LMDBTreeStore::SharedPtr db = std::make_shared<LMDBTreeStore>(directory, name, 1024 * 1024, num_threads);
std::unique_ptr<StoreType> store = std::make_unique<StoreType>(name, depth, db);
std::shared_ptr<ThreadPool> workers = std::make_shared<ThreadPool>(num_threads);
TreeType tree = TreeType(std::move(store), workers, batch_size);

const size_t initial_size = 1024 * 16;
std::vector<NullifierLeafValue> initial_batch(initial_size);
for (size_t i = 0; i < batch_size; ++i) {
initial_batch[i] = fr(random_engine.get_random_uint256());
}
add_values(tree, initial_batch);

for (auto _ : state) {
state.PauseTiming();
std::vector<NullifierLeafValue> values(batch_size);
for (size_t i = 0; i < batch_size; ++i) {
values[i] = fr(random_engine.get_random_uint256());
}
state.ResumeTiming();
add_values_with_witness(tree, values);
}
}

BENCHMARK(single_thread_indexed_tree_with_witness_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(2, MAX_BATCH_SIZE)
->Iterations(100);
->Iterations(1000);

BENCHMARK(multi_thread_indexed_tree_bench<Pedersen>)
BENCHMARK(single_thread_indexed_tree_with_witness_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(512, 8192)
->Iterations(10);

BENCHMARK(multi_thread_indexed_tree_with_witness_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(2, MAX_BATCH_SIZE)
->Iterations(100);
->Iterations(1000);

BENCHMARK(multi_thread_indexed_tree_with_witness_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(512, 8192)
->Iterations(10);

BENCHMARK(single_thread_indexed_tree_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(2, MAX_BATCH_SIZE)
->Iterations(1000);

BENCHMARK(single_thread_indexed_tree_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(512, 8192)
->Iterations(10);

BENCHMARK(multi_thread_indexed_tree_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(2, MAX_BATCH_SIZE)
->Iterations(1000);

BENCHMARK(multi_thread_indexed_tree_bench<Poseidon2>)
->Unit(benchmark::kMillisecond)
->RangeMultiplier(2)
->Range(512, 8192)
->Iterations(100);

BENCHMARK_MAIN();
Loading

0 comments on commit 41f3934

Please sign in to comment.