[WIP] feat: predicate chaining
This PR introduces the concept of predicate chaining - one predicate can create subsequent predicates.
The first example of this is the bitcoin input predicate. It now has the "follow_inputs" field:
"if_this": {
"scope": "inputs",
"txid": {
"txid": "0x32ed7f5c82d51d3ffdb8544190704e6b11e06d6d675fc527633adbde6a468e0f",
"follow_inputs": true
}
}
Consider the following chain of transactions:
block1 - tx1
block2 - tx2 (with input.previous_output == tx1)
block3 - tx3 (with input.previous_output == tx2)
...
Previously, this predicate would just allow you to find any bitcoin transactions that have a transaction input with previous_output.txid equal to the provided txid. So for the example, we could put the txid for tx1, and the predicate would match tx2, since it has an input that uses tx1 for its prevout.
Now, by setting the follow_inputs field to true, you can get all transactions that use txid as input, and all transactions that use those subsequent transaction's id's as inputs. So for our example, providing a txid of tx1 for the predicate would match for tx2 (because it's prevout has tx1) and tx3 (because it's output has a prevout of tx2) and so on.
Notes
Here are some notes on where this PR is, since it doesn't look like I'll be able to finish this during my tenure at Hiro 😞
As this PR currently is, predicate chaining works in that we have a predicate that can create more downstream predicates. The part that is not yet working, and will probably get kind of messy is handling reorgs.
Reorgs will not only have to check against predicates to see if the user needs to be notified of blocks to roll back, but it also needs to actually delete predicates that were generated from reorged blocks.
Maybe the new predicates that can create other predicates have some metadata with them when they're created, such as the identifier of the block that created the predicate? As this is done, we should also implement a more general interface for this new type of predicate.