-
Notifications
You must be signed in to change notification settings - Fork 10
FCMP++: cleaner/safer get_outs_by_last_locked_block #460
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
base: fcmp++-stage
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -156,6 +156,29 @@ namespace cryptonote | |
| return tx.vout.size(); | ||
| } | ||
| //--------------------------------------------------------------- | ||
| static OutsByLastLockedBlockMeta get_outs_by_last_locked_block( | ||
| const std::vector<std::reference_wrapper<const cryptonote::transaction>> &txs, | ||
| const std::unordered_map<uint64_t, rct::key> &transparent_amount_commitments, | ||
| const uint64_t first_unified_id, | ||
| const uint64_t block_idx) | ||
| { | ||
| OutsByLastLockedBlockMeta outs; | ||
| outs.next_unified_id = first_unified_id; | ||
|
|
||
| for (const auto &tx : txs) | ||
| { | ||
| outs.next_unified_id += set_tx_outs_by_last_locked_block( | ||
| tx.get(), | ||
| transparent_amount_commitments, | ||
| outs.next_unified_id, | ||
| block_idx, | ||
| outs.outs_by_last_locked_block, | ||
| outs.timelocked_outputs); | ||
| } | ||
|
|
||
| return outs; | ||
| } | ||
| //--------------------------------------------------------------- | ||
| } | ||
|
|
||
| namespace cryptonote | ||
|
|
@@ -1986,26 +2009,33 @@ namespace cryptonote | |
| } | ||
| //--------------------------------------------------------------- | ||
| OutsByLastLockedBlockMeta get_outs_by_last_locked_block( | ||
| const std::vector<std::reference_wrapper<const cryptonote::transaction>> &txs, | ||
| const cryptonote::transaction &miner_tx, | ||
| const std::vector<cryptonote::transaction> &txs, | ||
| const std::unordered_map<uint64_t, rct::key> &transparent_amount_commitments, | ||
| const uint64_t first_unified_id, | ||
| const uint64_t block_idx) | ||
| { | ||
| OutsByLastLockedBlockMeta outs_by_last_locked_block_meta_out; | ||
| outs_by_last_locked_block_meta_out.next_unified_id = first_unified_id; | ||
|
|
||
| std::vector<std::reference_wrapper<const transaction>> tx_refs; | ||
| tx_refs.reserve(1 + txs.size()); | ||
| tx_refs.push_back(std::cref(miner_tx)); | ||
| for (const auto &tx : txs) | ||
| { | ||
| outs_by_last_locked_block_meta_out.next_unified_id += set_tx_outs_by_last_locked_block( | ||
| tx.get(), | ||
| transparent_amount_commitments, | ||
| outs_by_last_locked_block_meta_out.next_unified_id, | ||
| block_idx, | ||
| outs_by_last_locked_block_meta_out.outs_by_last_locked_block, | ||
| outs_by_last_locked_block_meta_out.timelocked_outputs); | ||
| } | ||
| tx_refs.push_back(std::cref(tx)); | ||
| return get_outs_by_last_locked_block(tx_refs, transparent_amount_commitments, first_unified_id, block_idx); | ||
| } | ||
|
|
||
| return outs_by_last_locked_block_meta_out; | ||
| OutsByLastLockedBlockMeta get_outs_by_last_locked_block( | ||
| const cryptonote::transaction &miner_tx, | ||
| const std::vector<std::pair<transaction, blobdata>> &tx_pairs, | ||
| const std::unordered_map<uint64_t, rct::key> &transparent_amount_commitments, | ||
| const uint64_t first_unified_id, | ||
| const uint64_t block_idx) | ||
| { | ||
| std::vector<std::reference_wrapper<const transaction>> tx_refs; | ||
| tx_refs.reserve(1 + tx_pairs.size()); | ||
| tx_refs.push_back(std::cref(miner_tx)); | ||
|
Comment on lines
+2033
to
+2035
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you set up the API to do so, it would be nice to collect without this intermediate allocate + copy.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I see what you mean, it's using reference wrappers to avoid allocating and copying the actual transactions, while allowing the distinct vectors holding transactions
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I meant skipping allocating vectors of references
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see it as a tradeoff of duplicating a good bit of internal logic versus allocating vectors of references. The latter seemed the desirable tradeoff to me and is an insignificant perf hit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No |
||
| for (const auto &tx : tx_pairs) | ||
| tx_refs.push_back(std::cref(tx.first)); | ||
| return get_outs_by_last_locked_block(tx_refs, transparent_amount_commitments, first_unified_id, block_idx); | ||
| } | ||
| //--------------------------------------------------------------- | ||
| fcmp_pp::OutputPair to_output_pair(const cryptonote::txout_target_v &tx_out, const rct::key &commitment) | ||
|
|
||
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.
This throw would leave the db in an invalid state, with new block added but fcmp unhandled. Maybe debug_assert?
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.
The db would be in an invalid state if it doesn't throw and proceeds
Uh oh!
There was an error while loading. Please reload this page.
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.
Could make the whole sequence atomic but that may not be worth the effort. If
h == (new_height-1)is an invariant ofadd_blockthendebug_assertshould be adequate. AndBlockchainDB::add_blockshould explicitly call out that invariant in the header comment.Like if the comment said "Returns the previous height + 1." then the assert wouldn't be necessary.
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.
On the other hand
handle_block_to_main_chainhas the same validity properties, so I'll retract my complaint.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.
FWIW handle_block_to_main_chain is guaranteed always atomic because it's always called in the context of a batch db txn (prepare_handle starts the db txn, cleanup_handle commits it)
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.
Would that be appropriate to include here? I'm not well versed in db stuff.
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.
It does it here when use_batch is true. This is the blockchain import tool which I expect is a pretty rarely used tool, so I don't think worth spending a whole bunch of time on it