Skip to content

Conversation

Sjors
Copy link
Member

@Sjors Sjors commented Aug 9, 2023

This PR adds an index with the silent payment tweak for every transaction. It builds on top of #28122. Supersedes #24897.

Usage: bitcoind -bip352index

The index does not have wallet dependencies, so it can be built with --disable-wallet.

It also adds a getsilentpaymentblockdata RPC that returns an array of silent payment tweaked public keys, one for each qualifying transaction.

This index serves two purposes:

  1. Light client support, see BIP 352
  2. A more thorough check than the test vectors; e.g. by comparing a checksum of the index for all of mainnet.

TODO:

  • check correctness against another implementation
  • (maybe) implement cut-through (-bip352ctindex)

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 9, 2023

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.
A summary of reviews will appear here.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #30562 (PayToAnchor(P2A) followups by instagibbs)
  • #30546 (util: Use consteval checked format string in FatalErrorf by maflcko)
  • #30409 (Introduce waitTipChanged() mining interface, replace RPCNotifyBlockChange and drop CRPCSignals by Sjors)
  • #30364 (logging: Replace LogError and LogWarning with LogAlert by ryanofsky)
  • #30352 (policy: Add PayToAnchor(P2A), OP_1 <0x4e73> as a standard output script for spending by instagibbs)
  • #30051 (crypto, refactor: add new KeyPair class by josibake)
  • #29468 (rpc: method removeprunedfunds should take an array of txids by araujo88)
  • #29432 (Stratum v2 Template Provider (take 3) by Sjors)
  • #29295 (CKey: add Serialize and Unserialize by Sjors)
  • #28201 (Silent Payments: sending by josibake)
  • #26966 (index: blockfilter initial sync speedup, parallelize process by furszy)
  • #24539 (Add a "tx output spender" index by sstone)
  • #24230 (indexes: Stop using node internal types and locking cs_main, improve sync logic by ryanofsky)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@Sjors
Copy link
Member Author

Sjors commented Aug 9, 2023

I'd like to keep this based on #28122 but that requires some refactoring there. See #28122 (comment).

@josibake
Copy link
Member

josibake commented Aug 9, 2023

I'd like to keep this based on #28122 but that requires some refactoring there. See #28122 (comment).

you can also rebase on #27827 , which has everything, or just the receiving PR. Might be easier then to reason about which functions belong in which PRs if we can see it all together. I think the functions you need are introduced in the receiving PR (#28202)

@Sjors
Copy link
Member Author

Sjors commented Aug 9, 2023

I'll take a stab at rebasing on the bigger thing. It makes sense to do that and then unrebase / debase(?) it later.

@Sjors Sjors force-pushed the 2023/08/silent-index branch from c23e4e7 to d589099 Compare August 9, 2023 12:40
@Sjors
Copy link
Member Author

Sjors commented Aug 9, 2023

I ended up "borrowing" some code from the followup PRs, without having to rebase on them.

This code compiles and the index doesn't crash. That's about the extend of it though :-) For now.

@Sosthene00
Copy link

Sosthene00 commented Sep 4, 2023

Hi, I have a little question about the motivation for making this index in Core. Afaiu, an implementation of electrum server (or any light client backend) could construct this index as easily, and I think it would be better separation of concerns to let them take responsibility for this instead of Core. Or maybe it's necessary for the consistency check you're mentioning? I'm not sure of what it is.

@Sjors
Copy link
Member Author

Sjors commented Sep 4, 2023

@Sosthene00 I find it useful to have this index for developing and reviewing the silent payment implementation. But as you say, it may not be worth merging eventually. I'm not sure about that yet.

There's also the possibility of building something like this on top of the Kernel, when that project is a bit further along.

@Sjors
Copy link
Member Author

Sjors commented Sep 19, 2023

Rebased to use GetSilentPaymentsTweakDataFromTxInputs. Otherwise still WIP.

@Sjors
Copy link
Member Author

Sjors commented Sep 19, 2023

Pushed a simple RPC method to get the tweaked public key for a given transaction. I'd like to sanity check it against some other implementation.

Signet: dacb55db5c506a34771bf8ac3664e2510c17e80ada81347300fb4223f2d6c545

getsilentpaymenttxdata result: 03fc95cfeac43e9179c002d32a042626e5a2b289a8d7a4a0c88fbf81d570cef987

@DrahtBot
Copy link
Contributor

🚧 At least one of the CI tasks failed.
Debug: https://github.com/bitcoin/bitcoin/runs/27526127118

Hints

Make sure to run all tests locally, according to the documentation.

The failure may happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 2, 2024

🐙 This pull request conflicts with the target branch and needs rebase.

@thisIsNotTheFoxUrLookingFor
Copy link

thisIsNotTheFoxUrLookingFor commented Aug 30, 2024

Hi, I have a little question about the motivation for making this index in Core. Afaiu, an implementation of electrum server (or any light client backend) could construct this index as easily, and I think it would be better separation of concerns to let them take responsibility for this instead of Core. Or maybe it's necessary for the consistency check you're mentioning? I'm not sure of what it is.

Personally I think Electrum is for SPV wallet things. Silent Payments would be considered part of a full node and not just an SPV thing. That is why I would think it makes it worthy of being in bitcoind.

return std::nullopt;
}

bool MaybeSilentPayment(CTransactionRef &tx) {

Choose a reason for hiding this comment

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

Suggested change
bool MaybeSilentPayment(CTransactionRef &tx) {
bool MaybeSilentPayment(const CTransactionRef &tx) {


BIP352Index::~BIP352Index() = default;

bool BIP352Index::GetSilentPaymentKeys(std::vector<CTransactionRef> txs, CBlockUndo& block_undo, tweak_index_entry& index_entry)
Copy link

@cculianu cculianu Aug 30, 2024

Choose a reason for hiding this comment

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

Suggested change
bool BIP352Index::GetSilentPaymentKeys(std::vector<CTransactionRef> txs, CBlockUndo& block_undo, tweak_index_entry& index_entry)
bool BIP352Index::GetSilentPaymentKeys(const std::vector<CTransactionRef>& txs, const CBlockUndo& block_undo, tweak_index_entry& index_entry) const

{
assert(txs.size() - 1 == block_undo.vtxundo.size());

for (uint32_t i=0; i < txs.size(); i++) {

Choose a reason for hiding this comment

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

Compare apples to apples and also use idiomatic pre-increment to avoid a temporary in unoptimized builds.

Suggested change
for (uint32_t i=0; i < txs.size(); i++) {
for (size_t i = 0; i < txs.size(); ++i) {

assert(txs.size() - 1 == block_undo.vtxundo.size());

for (uint32_t i=0; i < txs.size(); i++) {
auto& tx = txs.at(i);

Choose a reason for hiding this comment

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

at unnecessary here (and in various places below).. since i is guaranteed to be in-range, since the loop is looping on txs.size().

CTxUndo undoTX{block_undo.vtxundo.at(i - 1)};
std::map<COutPoint, Coin> coins;

for (uint32_t j = 0; j < tx->vin.size(); j++) {

Choose a reason for hiding this comment

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

Apples to apples, and also use pre-increment.

Suggested change
for (uint32_t j = 0; j < tx->vin.size(); j++) {
for (size_t j = 0; j < tx->vin.size(); ++j) {

const CCoinsViewCache& coins_cache = m_chainstate->CoinsTip();

uint32_t spent{0};
for (uint32_t i{0}; i < tx->vout.size(); i++) {

Choose a reason for hiding this comment

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

This loop index shadows an outer variable i. Also should be using size_t here.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll fix this in Sjors#86

@Sjors
Copy link
Member Author

Sjors commented Aug 30, 2024

@cculianu thanks for reviewing the code. However many of your comments refer to #28122 (which this pull request builds on top of), so it's better comment there. Paging @josibake to take a look though.

I'll look at the comments for src/index when I next rebase.

@cculianu
Copy link

@cculianu thanks for reviewing the code. However many of your comments refer to #28122 (which this pull request builds on top of), so it's better comment there. Paging @josibake to take a look though.

I'll look at the comments for src/index when I next rebase.

Ah ok I can review/comment there too. Thanks for the tip.

@DrahtBot
Copy link
Contributor

⌛ There hasn't been much activity lately and the patch still needs rebase. What is the status here?

  • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.
  • Is it no longer relevant? ➡️ Please close.
  • Did the author lose interest or time to work on this? ➡️ Please close it and mark it 'Up for grabs' with the label, so that it can be picked up in the future.

@fanquake
Copy link
Member

Closing this for now, given after a year and a half it's still a draft, based on a draft, based on another PR that is still being worked on. Maybe a new PR can be opened in future.

@Sjors
Copy link
Member Author

Sjors commented Apr 23, 2025

Opened a PR on my own fork for this: Sjors#86

It's a new branch based on this one, rebased on the latest #28122, and fixes conflicts with #28358, #31483, #31490 and the introduction of CMake.

I also applied most of @cculianu's suggestions there (not pushed yet).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.