Skip to content
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

[WIP] full-chain membership proof++ integration #9436

Draft
wants to merge 127 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
e1c03f4
rough fcmp++ tree impl (lots of work remaining to clean it up and fix)
j-berman May 17, 2024
1ba876b
remove whitespaces
j-berman May 17, 2024
9e6b93b
test validates lowest layer in tree
j-berman May 17, 2024
33ad50b
fix c1 c2 layer indexing issue in test helper get_last_chunk
j-berman May 18, 2024
c05bd80
actual indexing fix, tests now passing
j-berman May 18, 2024
ad8872a
Cleaner file organization
j-berman May 20, 2024
5103a94
template all curve_trees types & funcs, rename tower_cycle_types to t…
j-berman May 21, 2024
d9390c7
Implement CurveTrees & CurveTreesUnitTest classes to simplify callers
j-berman May 21, 2024
29e0fe7
Add Curve class, and Helios & Selene classes that derive from Curve
j-berman May 22, 2024
9e68475
Use widths from fcmp++ repo test & align tests with width
j-berman May 22, 2024
26009ba
slight simplification to CurveTrees::hash_layer
j-berman May 22, 2024
4ade675
Consolidate hash_leaf_layer into hash_layer
j-berman May 23, 2024
9ba00be
Move curve_trees.h implementations into curve_trees.cpp file
j-berman May 23, 2024
5ad0269
Cleaner template usage, moved static functions out of CurveTrees class
j-berman May 23, 2024
e68ea2e
small cleanup
j-berman May 23, 2024
af9b74f
start LMDB grow_tree
j-berman May 24, 2024
af47a13
Remove cxx and expose scalars/points directly
kayabaNerve May 24, 2024
42f6ef2
fmt, clippy
kayabaNerve May 24, 2024
c792b21
Use statics on the Rust side for generators
kayabaNerve May 24, 2024
effa9ee
Only pass a single prior child
kayabaNerve May 24, 2024
517f5a3
don't want to expose generator lengths in ffi
j-berman May 24, 2024
a1ee603
explicit type response to hash_grow 's
j-berman May 24, 2024
988c4ea
Remove reference from m_hash_init_point
kayabaNerve May 24, 2024
ab7c741
Simplify edge case handling in hash_layer
j-berman May 25, 2024
1ffde09
Implement get_tree_last_chunks in db, can now extend tree in db
j-berman May 25, 2024
6045357
implement db->audit_tree, and flesh out db test to init/extend tree
j-berman May 27, 2024
17b1f42
cleaner lmdb test structure for curve trees
j-berman May 27, 2024
c7c6c6a
CurveTreesUnitTest -> CurveTreesGlobalTree class
j-berman May 27, 2024
ae89fdd
Set up trim_tree_in_memory test
j-berman Jun 4, 2024
e8af709
expose and test hash_trim from rust lib
j-berman Jun 6, 2024
ed040ca
implement trim_tree_in_memory
j-berman Jun 7, 2024
8287ba6
faster trim_tree tests
j-berman Jun 7, 2024
36f1e19
Fix grow_tree, restructure it, and clean the approach
j-berman Jun 28, 2024
5ddca0c
Implement and test trim_tree algo in memory
j-berman Jul 9, 2024
4be2d7c
whitespace fixes
j-berman Jul 9, 2024
55caee9
Better tests for hash_trim
j-berman Jul 9, 2024
42fd22c
Better organization
j-berman Jul 9, 2024
f50ad5b
trim_tree db impl + db test + some housekeeping
j-berman Jul 10, 2024
8a89c20
lmdb migration to init curve trees tree from existing outputs
j-berman Jul 18, 2024
306488b
Implemented growing the tree on sync + lots of cleaning
j-berman Jul 24, 2024
634e12e
Guarantee insertion order into the tree using global output ID
j-berman Jul 25, 2024
93795b4
Match output unlock time (fix off by 1)
j-berman Jul 25, 2024
db12610
Remove leaves from locked leaves table upon insertion to tree
j-berman Jul 25, 2024
b585a7f
Remove copy in get_tree_extension and better named funcs
j-berman Jul 25, 2024
af4de99
Use a pointer for the value in CResult
kayabaNerve May 25, 2024
d6ca636
use void * to try to fix CResult
j-berman May 25, 2024
8b76958
Rust cross compilation
kayabaNerve May 25, 2024
389274a
Correct path to the staticlib
kayabaNerve May 25, 2024
75faba1
Increase misc discrepancies in ARM ARCH spec which we support
kayabaNerve May 25, 2024
8b279a0
i386 -> i686, riscv64 -> riscv64gc
kayabaNerve May 25, 2024
8c47c0d
Further match off RUST_ARCH, not ARCH_ID
kayabaNerve May 26, 2024
03679d1
Install Rust when doing the Windows build
kayabaNerve May 26, 2024
e5ed232
Use the armv7 HF Rust toolchain
kayabaNerve May 26, 2024
d69e6bd
Install Rust via the msys2 package on Windows (not the unavailable ru…
kayabaNerve May 26, 2024
0620be1
Cross-compile from Ubuntu 22.04
kayabaNerve May 26, 2024
38f1935
Ubuntu 20.04, Rust 1.72
kayabaNerve May 26, 2024
5d6a7fd
_x86_64 -> -x86_64
kayabaNerve May 26, 2024
8664736
Normalize x86-64 to x86_64
kayabaNerve May 26, 2024
170324a
Rust 1.69
kayabaNerve May 26, 2024
98569b0
LTO off
kayabaNerve May 26, 2024
6d6a2e4
Correct typo in MATCHES statement
kayabaNerve May 26, 2024
c6327cc
Correct in-tree code to Rust 1.69
kayabaNerve May 26, 2024
8eb3f29
Link additional libs on Windows
kayabaNerve May 26, 2024
da9f101
Abort on panic, fix 32-bit Windows undefined reference
kayabaNerve May 26, 2024
16536f3
Only provide dummy _Unwind_Resume on x86 Windows
kayabaNerve May 26, 2024
1a44ceb
Link additional libs on Windows (yet actually adding the relevant cha…
kayabaNerve May 26, 2024
23be5f6
Use a single target_link_libraries call
kayabaNerve May 26, 2024
aadea07
Touch up merge for cross-compilation fixes
j-berman Jul 26, 2024
420b4b6
Resolve cross-compile errors
j-berman Jul 26, 2024
d36b6fe
resolve rebase to master issues
j-berman Jul 26, 2024
c383087
Instantiate m_curve_trees on BlockchainLMDB class in c'tor
j-berman Jul 26, 2024
729e31d
include fcmp/curve_trees.h in db_lmdb.h
j-berman Jul 26, 2024
16a8ce3
Add * point from bytes
kayabaNerve Jul 27, 2024
54d5d0d
fcmp++: add support for new fcmp types in cryptonote::transaction
j-berman Aug 1, 2024
e40c5bb
fix json tagging in fcmp_pp serialization
j-berman Aug 1, 2024
95114f9
Use explicit code instead of macro in custom fcmp_pp serialization
j-berman Aug 1, 2024
34eafa8
Store points in the tree in compressed encoding (32 bytes)
j-berman Aug 1, 2024
b90cee8
Store {O,C} for each leaf tuple instead of {O.x,I.x,C.x}
j-berman Aug 2, 2024
cbf6a5d
Optimize conversion from output to leaf tuple
j-berman Aug 3, 2024
30fc80b
Don't copy when flattening leaves
j-berman Aug 3, 2024
5e76191
cleaner crypto for converting output to leaf tuple
j-berman Aug 3, 2024
edded7e
fcmp++: Restart migration from where it leaves off
j-berman Aug 8, 2024
10c6c12
fcmp++: compilation fixes + misc. cleanup
j-berman Aug 8, 2024
3a5cf70
32-bit platform compatibility in Rust FFI (untested)
j-berman Aug 8, 2024
d72f405
Revert DELETE_DB macro to original spot
j-berman Aug 8, 2024
d4847f6
Rename everything from fcmp* to fcmp_pp
j-berman Aug 8, 2024
9f0dd85
fix clang compile errors
j-berman Aug 8, 2024
8b12a33
fcmp++: implement iterative audit_tree function
j-berman Aug 9, 2024
f17db01
fcmp++: store {output pubkey, commitment} in db, pre-torsion clear
j-berman Aug 9, 2024
9ad4918
link correct cncrypto and ringct_basic libs
j-berman Aug 9, 2024
b6bcca9
Remove ringct dep in fcmp_pp, impl in fcmp_pp_crypto
j-berman Aug 9, 2024
7389cb6
add missing files
j-berman Aug 9, 2024
6525df1
Don't store output_id in locked_outpust table, table stays ordered
j-berman Aug 10, 2024
83d5659
Clean lmbd impl
j-berman Aug 10, 2024
67f5546
lmdb touchup && OutputsByUnlockBlock map -> unordered_map
j-berman Aug 13, 2024
918befb
new_leaf_tuples -> new_outputs
j-berman Aug 13, 2024
ee19361
Remove extra gcc install fixes windows build
j-berman Aug 14, 2024
47d47bd
fcmp++: proof len from inputs *AND merkle tree depth
j-berman Aug 14, 2024
41b1985
Fix compile on arm-linux-androideabi (32-bit) using a newer NDK
j-berman Sep 3, 2024
16ff6a9
fcmp++: trim tree when removing a block
j-berman Sep 4, 2024
0a604a9
fcmp++: Enable trimming to empty tree
j-berman Sep 5, 2024
acc7d05
fcmp++ LMDB: use dummy key optimization on leaves table
j-berman Sep 5, 2024
2890e8c
fcmp++: LMDB touchups
j-berman Sep 6, 2024
072a82d
fcmp++: tests now test trimming to empty tree
j-berman Sep 6, 2024
0688538
fcmp++: add test to trim the tree then grow again after trimming
j-berman Sep 6, 2024
b71f244
fcmp++: better test names
j-berman Sep 6, 2024
0ff1eaf
Use macro to de-dupe curve trees test logic
j-berman Sep 6, 2024
9784ced
fcmp++ tests: init tree once in memory and grow copy
j-berman Sep 8, 2024
f47c60e
fcmp++ tests: init tree in db once, then copy db for tests
j-berman Sep 9, 2024
e636c38
fix ubuntu 20 compile
j-berman Sep 9, 2024
90164e3
fcmp++: multithreaded hashing children chunks into tree
j-berman Sep 10, 2024
8fc87d7
fcmp++: multithreaded convert valid outputs into leaf tuples
j-berman Sep 10, 2024
b055eb3
fcmp++: output may not be present in locked outputs table on remove
j-berman Sep 11, 2024
0435974
fcmp++ lmdb: migration touchups
j-berman Sep 12, 2024
7fa01d2
fcmp++: key image migration
j-berman Sep 12, 2024
5f4b20b
fcmp++: fix build errs for ki_context_t hash specialization
j-berman Sep 12, 2024
358a66f
crypto: fe_batch_invert using Montgomery's trick
j-berman Sep 16, 2024
b2ea862
fcmp++: use batch inversion when converting outputs to leaf tupels
j-berman Sep 16, 2024
330b82f
Fix build errs + warnings
j-berman Sep 17, 2024
21664f9
fcmp++: use fe * instead of vector<fe> + clean up
j-berman Sep 17, 2024
513dae8
small touchups
j-berman Sep 17, 2024
da710fc
crypto: test more batch inversions
j-berman Sep 17, 2024
a74f7ae
fcmp++: rename "PreWeiX" -> "EdYDerivatives" + small touchups
j-berman Sep 17, 2024
901cc87
missing ref
j-berman Sep 17, 2024
036fc2a
fcmp++ tests: set up test for prove
j-berman Sep 18, 2024
1241172
fcmp++: fix trim_tree get_trim_layer_instructions logic err
j-berman Oct 7, 2024
3ac3e53
fcmp++: fix migration batching to resize db as needed
j-berman Oct 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
- uses: msys2/setup-msys2@v2
with:
update: true
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-ccache mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-libusb mingw-w64-x86_64-unbound git
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-ccache mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-libusb mingw-w64-x86_64-unbound git mingw-w64-x86_64-rust
- shell: msys2 {0}
run: |
curl -O https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-protobuf-c-1.4.1-1-any.pkg.tar.zst
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/depends.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,47 @@ jobs:
toolchain:
- name: "RISCV 64bit"
host: "riscv64-linux-gnu"
rust_host: "riscv64gc-unknown-linux-gnu"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this stuff too should go into a "General Rust FFI" PR IMO

packages: "python3 gperf g++-riscv64-linux-gnu"
- name: "ARM v7"
host: "arm-linux-gnueabihf"
rust_host: "armv7-unknown-linux-gnueabihf"
packages: "python3 gperf g++-arm-linux-gnueabihf"
- name: "ARM v8"
host: "aarch64-linux-gnu"
rust_host: "aarch64-unknown-linux-gnu"
packages: "python3 gperf g++-aarch64-linux-gnu"
- name: "i686 Win"
host: "i686-w64-mingw32"
rust_host: "i686-pc-windows-gnu"
packages: "python3 g++-mingw-w64-i686"
- name: "i686 Linux"
host: "i686-pc-linux-gnu"
rust_host: "i686-unknown-linux-gnu"
packages: "gperf cmake g++-multilib python3-zmq"
- name: "Win64"
host: "x86_64-w64-mingw32"
rust_host: "x86_64-pc-windows-gnu"
packages: "cmake python3 g++-mingw-w64-x86-64"
- name: "x86_64 Linux"
host: "x86_64-unknown-linux-gnu"
rust_host: "x86_64-unknown-linux-gnu"
packages: "gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
- name: "Cross-Mac x86_64"
host: "x86_64-apple-darwin"
rust_host: "x86_64-apple-darwin"
packages: "cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git"
- name: "Cross-Mac aarch64"
host: "aarch64-apple-darwin"
rust_host: "aarch64-apple-darwin"
packages: "cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git"
- name: "x86_64 Freebsd"
host: "x86_64-unknown-freebsd"
rust_host: "x86_64-unknown-freebsd"
packages: "clang-8 gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
- name: "ARMv8 Android"
host: "aarch64-linux-android"
rust_host: "aarch64-linux-android"
packages: "gperf cmake python3"
name: ${{ matrix.toolchain.name }}
steps:
Expand Down Expand Up @@ -95,6 +106,11 @@ jobs:
run: ${{env.APT_SET_CONF}}
- name: install dependencies
run: sudo apt update; sudo apt -y install build-essential libtool cmake autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache ${{ matrix.toolchain.packages }}
- name: install rust target
# We can't use the latest Rust due to LLVM 17 not working with old `ld`s (such as in Ubuntu 20.04) for RISC-V
# We could update ld (a pain), update Ubuntu (requires a large amount of changes), or downgrade Rust
# We can't use Rust 1.70 due to LLVM 16 requiring ld >= 2.40 when building for Windows
run: rustup toolchain install 1.69; rustup default 1.69; rustup target add ${{ matrix.toolchain.rust_host }}
- name: prepare w64-mingw32
if: ${{ matrix.toolchain.host == 'x86_64-w64-mingw32' || matrix.toolchain.host == 'i686-w64-mingw32' }}
run: |
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ add_subdirectory(ringct)
add_subdirectory(checkpoints)
add_subdirectory(cryptonote_basic)
add_subdirectory(cryptonote_core)
add_subdirectory(fcmp_pp)
add_subdirectory(lmdb)
add_subdirectory(multisig)
add_subdirectory(net)
Expand Down
1 change: 1 addition & 0 deletions src/blockchain_db/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ target_link_libraries(blockchain_db
PUBLIC
common
cncrypto
fcmp_pp
ringct
${LMDB_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
Expand Down
108 changes: 101 additions & 7 deletions src/blockchain_db/blockchain_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,60 @@

using epee::string_tools::pod_to_hex;

//---------------------------------------------------------------
// Helper function to group outputs by unlock block
static void get_outs_by_unlock_block(const cryptonote::transaction &tx,
const std::vector<uint64_t> &output_ids,
const uint64_t tx_height,
const bool miner_tx,
fcmp_pp::curve_trees::OutputsByUnlockBlock &outs_by_unlock_block_inout)
{
const uint64_t unlock_block = cryptonote::get_unlock_block_index(tx.unlock_time, tx_height);

CHECK_AND_ASSERT_THROW_MES(tx.vout.size() == output_ids.size(), "unexpected size of output ids");

for (std::size_t i = 0; i < tx.vout.size(); ++i)
{
const auto &out = tx.vout[i];

crypto::public_key output_public_key;
if (!cryptonote::get_output_public_key(out, output_public_key))
throw std::runtime_error("Could not get an output public key from a tx output.");

static_assert(CURRENT_TRANSACTION_VERSION == 2, "This section of code was written with 2 tx versions in mind. "
"Revisit this section and update for the new tx version.");
CHECK_AND_ASSERT_THROW_MES(tx.version == 1 || tx.version == 2, "encountered unexpected tx version");

if (!miner_tx && tx.version == 2)
CHECK_AND_ASSERT_THROW_MES(tx.rct_signatures.outPk.size() > i, "unexpected size of outPk");

rct::key commitment = (miner_tx || tx.version != 2)
? rct::zeroCommit(out.amount)
: tx.rct_signatures.outPk[i].mask;

auto output_pair = fcmp_pp::curve_trees::OutputPair{
.output_pubkey = std::move(output_public_key),
.commitment = std::move(commitment)
};

auto output_context = fcmp_pp::curve_trees::OutputContext{
.output_id = output_ids[i],
.output_pair = std::move(output_pair)
};

if (outs_by_unlock_block_inout.find(unlock_block) == outs_by_unlock_block_inout.end())
{
auto new_vec = std::vector<fcmp_pp::curve_trees::OutputContext>{std::move(output_context)};
outs_by_unlock_block_inout[unlock_block] = std::move(new_vec);
}
else
{
outs_by_unlock_block_inout[unlock_block].emplace_back(std::move(output_context));
}
}
}
//---------------------------------------------------------------

namespace cryptonote
{

Expand Down Expand Up @@ -179,7 +233,7 @@ void BlockchainDB::pop_block()
pop_block(blk, txs);
}

void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& txp, const crypto::hash* tx_hash_ptr, const crypto::hash* tx_prunable_hash_ptr)
std::vector<uint64_t> BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& txp, const crypto::hash* tx_hash_ptr, const crypto::hash* tx_prunable_hash_ptr)
{
const transaction &tx = txp.first;

Expand Down Expand Up @@ -223,29 +277,43 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair

uint64_t tx_id = add_transaction_data(blk_hash, txp, tx_hash, tx_prunable_hash);

std::vector<uint64_t> amount_output_indices(tx.vout.size());
std::vector<output_indexes_t> output_indices(tx.vout.size());

// iterate tx.vout using indices instead of C++11 foreach syntax because
// we need the index
for (uint64_t i = 0; i < tx.vout.size(); ++i)
{
// miner v2 txes have their coinbase output in one single out to save space,
// and we store them as rct outputs with an identity mask
// note: get_outs_by_unlock_block mirrors this logic
if (miner_tx && tx.version == 2)
{
cryptonote::tx_out vout = tx.vout[i];
rct::key commitment = rct::zeroCommit(vout.amount);
vout.amount = 0;
amount_output_indices[i] = add_output(tx_hash, vout, i, tx.unlock_time,
output_indices[i] = add_output(tx_hash, vout, i, tx.unlock_time,
&commitment);
}
else
{
amount_output_indices[i] = add_output(tx_hash, tx.vout[i], i, tx.unlock_time,
output_indices[i] = add_output(tx_hash, tx.vout[i], i, tx.unlock_time,
tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL);
}
}

std::vector<uint64_t> amount_output_indices;
std::vector<uint64_t> output_ids;
amount_output_indices.reserve(output_indices.size());
output_ids.reserve(output_indices.size());
for (const auto &o_idx : output_indices)
{
amount_output_indices.push_back(o_idx.amount_index);
output_ids.push_back(o_idx.output_id);
}

add_tx_amount_output_indices(tx_id, amount_output_indices);

return output_ids;
}

uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
Expand Down Expand Up @@ -273,17 +341,20 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck

time1 = epee::misc_utils::get_tick_count();

std::vector<std::vector<uint64_t>> output_ids;
output_ids.reserve(txs.size());

uint64_t num_rct_outs = 0;
blobdata miner_bd = tx_to_blob(blk.miner_tx);
add_transaction(blk_hash, std::make_pair(blk.miner_tx, blobdata_ref(miner_bd)));
std::vector<uint64_t> miner_output_ids = add_transaction(blk_hash, std::make_pair(blk.miner_tx, blobdata_ref(miner_bd)));
if (blk.miner_tx.version == 2)
num_rct_outs += blk.miner_tx.vout.size();
int tx_i = 0;
crypto::hash tx_hash = crypto::null_hash;
for (const std::pair<transaction, blobdata>& tx : txs)
{
tx_hash = blk.tx_hashes[tx_i];
add_transaction(blk_hash, tx, &tx_hash);
output_ids.push_back(add_transaction(blk_hash, tx, &tx_hash));
for (const auto &vout: tx.first.vout)
{
if (vout.amount == 0)
Expand All @@ -294,9 +365,32 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
TIME_MEASURE_FINISH(time1);
time_add_transaction += time1;

// When adding a block, we also need to keep track of when outputs unlock, so
// we can use them to grow the merkle tree used in fcmp's at that point.
fcmp_pp::curve_trees::OutputsByUnlockBlock outs_by_unlock_block;

// Get miner tx's leaf tuples
get_outs_by_unlock_block(
blk.miner_tx,
miner_output_ids,
prev_height,
true/*miner_tx*/,
outs_by_unlock_block);

// Get all other txs' leaf tuples
for (std::size_t i = 0; i < txs.size(); ++i)
{
get_outs_by_unlock_block(
txs[i].first,
output_ids[i],
prev_height,
false/*miner_tx*/,
outs_by_unlock_block);
}

// call out to subclass implementation to add the block & metadata
time1 = epee::misc_utils::get_tick_count();
add_block(blk, block_weight, long_term_block_weight, cumulative_difficulty, coins_generated, num_rct_outs, blk_hash);
add_block(blk, block_weight, long_term_block_weight, cumulative_difficulty, coins_generated, num_rct_outs, blk_hash, outs_by_unlock_block);
TIME_MEASURE_FINISH(time1);
time_add_block1 += time1;

Expand Down
41 changes: 34 additions & 7 deletions src/blockchain_db/blockchain_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

#include <string>
#include <exception>
#include <map>
#include <memory>
#include <boost/program_options.hpp>
#include "common/command_line.h"
#include "crypto/hash.h"
Expand All @@ -40,6 +42,7 @@
#include "cryptonote_basic/difficulty.h"
#include "cryptonote_basic/hardfork.h"
#include "cryptonote_protocol/enums.h"
#include "fcmp_pp/curve_trees.h"

/** \file
* Cryptonote Blockchain Database Interface
Expand Down Expand Up @@ -187,6 +190,14 @@ struct txpool_tx_meta_t
}
};

/**
* @brief a struct containing output indexes for convenience
*/
struct output_indexes_t
{
uint64_t amount_index;
uint64_t output_id;
};

#define DBF_SAFE 1
#define DBF_FAST 2
Expand Down Expand Up @@ -398,6 +409,7 @@ class BlockchainDB
* @param cumulative_difficulty the accumulated difficulty after this block
* @param coins_generated the number of coins generated total after this block
* @param blk_hash the hash of the block
* @param outs_by_unlock_block the outputs from this block to add to the merkle tree
*/
virtual void add_block( const block& blk
, size_t block_weight
Expand All @@ -406,6 +418,7 @@ class BlockchainDB
, const uint64_t& coins_generated
, uint64_t num_rct_outs
, const crypto::hash& blk_hash
, const fcmp_pp::curve_trees::OutputsByUnlockBlock& outs_by_unlock_block
) = 0;

/**
Expand Down Expand Up @@ -470,8 +483,9 @@ class BlockchainDB
* future, this tracking (of the number, at least) should be moved to
* this class, as it is necessary and the same among all BlockchainDB.
*
* It returns an amount output index, which is the index of the output
* for its specified amount.
* It returns the output indexes, which contains an amount output index (the
* index of the output for its specified amount) and output id (the global
* index of the output among all outputs of any amount).
*
* This data should be stored in such a manner that the only thing needed to
* reverse the process is the tx_out.
Expand All @@ -484,9 +498,9 @@ class BlockchainDB
* @param local_index index of the output in its transaction
* @param unlock_time unlock time/height of the output
* @param commitment the rct commitment to the output amount
* @return amount output index
* @return output indexes
*/
virtual uint64_t add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time, const rct::key *commitment) = 0;
virtual output_indexes_t add_output(const crypto::hash& tx_hash, const tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time, const rct::key *commitment) = 0;

/**
* @brief store amount output indices for a tx's outputs
Expand Down Expand Up @@ -567,21 +581,25 @@ class BlockchainDB
* @param tx the transaction to add
* @param tx_hash_ptr the hash of the transaction, if already calculated
* @param tx_prunable_hash_ptr the hash of the prunable part of the transaction, if already calculated
*
* @return the global output ids of all outputs inserted
*/
void add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& tx, const crypto::hash* tx_hash_ptr = NULL, const crypto::hash* tx_prunable_hash_ptr = NULL);
std::vector<uint64_t> add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& tx, const crypto::hash* tx_hash_ptr = NULL, const crypto::hash* tx_prunable_hash_ptr = NULL);

mutable uint64_t time_tx_exists = 0; //!< a performance metric
uint64_t time_commit1 = 0; //!< a performance metric
bool m_auto_remove_logs = true; //!< whether or not to automatically remove old logs

HardFork* m_hardfork;

std::shared_ptr<fcmp_pp::curve_trees::CurveTreesV1> m_curve_trees;

public:

/**
* @brief An empty constructor.
*/
BlockchainDB(): m_hardfork(NULL), m_open(false) { }
BlockchainDB(): m_hardfork(NULL), m_open(false), m_curve_trees() { }

/**
* @brief An empty destructor.
Expand Down Expand Up @@ -1685,7 +1703,7 @@ class BlockchainDB
*
* @return false if the function returns false for any key image, otherwise true
*/
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const = 0;
virtual bool for_all_key_images(std::function<bool(const crypto::key_image_y&)>) const = 0;

/**
* @brief runs a function over a range of blocks
Expand Down Expand Up @@ -1764,6 +1782,15 @@ class BlockchainDB
*/
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata_ref *blob)> f, bool include_blob = false) const = 0;

// TODO: description and make private
virtual void grow_tree(std::vector<fcmp_pp::curve_trees::OutputContext> &&new_outputs) = 0;

virtual void trim_tree(const uint64_t trim_n_leaf_tuples, const uint64_t trim_block_id) = 0;

// TODO: description
virtual bool audit_tree(const uint64_t expected_n_leaf_tuples) const = 0;
virtual uint64_t get_num_leaf_tuples() const = 0;
virtual std::array<uint8_t, 32UL> get_tree_root() const = 0;

//
// Hard fork related storage
Expand Down
Loading