Add a new index txoscriptindex which indexes all output scripts. Introduce a new getscripthistory RPC that returns all transactions that create outputs corresponding to the provided scripts, and optionally the transactions that spend those outputs if txospenderindex is also configured.
This has been a long-requested feature, attempted in previous PRs (#2802, #3652, #6835, #10370, #14053).
Some concerns raised were about the ability for an index like this to scale. I think the new techniques being used to build the indexes (https://github.com/bitcoin/bitcoin/pull/35531, #36002) alleviate this concern. This index can be synced in a few hours and the current disk usage is ~52 GB. This is less than the ~66 GB txindex disk usage in v31 and earlier. This index can also be used with a pruned node, so a full node can be supported in < 100 GB of disk space. Missing blocks are returned by hash and can be requested from peers using getblockfrompeer.
Some other previous concerns were more conceptual, that this type of index could encourage address reuse and chain analysis. IMO this ship has sailed, and the current status quo of not shipping an address index is turning off users who expect this functionality. Workarounds involve installing, configuring, and syncing other third-party software, making the UX of using Bitcoin Core in a self-sovereign way unnecessarily difficult.
The index hashes each output script with SHA256, then applies salted SipHash-1-3-UJ and stores a five-byte prefix. This is to support the popular Electrum protocol, which supplies only the script hash. The RPC can also look up by address or descriptors. Ranged descriptors are also supported, so a single RPC call can return the entire history of a receive/change xpub pair.
Because there are some scripts with millions of outputs, we introduce a new OrderedVarInt which serializes the block height after the script hash prefix. This lets LevelDB seek directly to the prefix + block height, so we can page by block height range.
To prevent DoS concerns by supplying an address with millions of outputs, the RPC tracks a byte budget of reads and throws immediately if too many reads are attempted. The error message instructs the user to narrow the block range.
Improvements to txospenderindex (https://github.com/bitcoin/bitcoin/pull/36480) will also allow us to use that pruned. The end result would allow users to run with all optional indexes (including this one) in < 200 GB of disk space. Of course a larger pruned setting would be desired if many historical block lookups were being requested.