-
Notifications
You must be signed in to change notification settings - Fork 321
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
Refactor TxGraph::walk_conflicts
to check for ancestors
#1099
Comments
can we get a deeper exposition on why we need to do this. What problem are we solving and what others solutions have we considered? |
@LagginTimes's work on testing conflict resolution in The BugGiven transactions:
Where:
Expectations:
Reality:
Why the bug existsSo why was When
How #1064 fixes the bug#1064 does not modify the implementation of However, the behavior of Why we want
|
Thanks for the explanation. I think this approach to the problem misses the mark. It does modify the API of [EDIT] @evanlinjin has explained to me that 25 is some magic network number. I still think the points below still stand. Let's state the problem again. We have graph of transactions where we can query an oracle to determine whether it's in the chain or not. The answer can be "yes", "no", "I don't know". When a transaction is in the chain, we know that every directly conflicting transaction is not. We also know that every ancestor is in the chain and every transaction that conflicts with them is not. However, sometimes the answer will be "no" or "I don't know" for a set of conflicting transactions and we still want to choose one of the set to be canonical so we can report a transaction as being unconfirmed. So what we are trying to do is to create conflict free sub-graph from our directed acyclic graph. Why modifying walk conflicts is suboptimalWalking ancestors of every single TX up to some arbitrary limit (25) is creating a conflict free subgraph for nodes not more than 25 nodes earlier in the graph. We are likely redoing work for every tx. This is inefficient and error prone due to the limit. A simple algorithm sketchWhy not just create a canonical subgraph once for the whole graph rather than redoing it for every tx? Start with a topological traversal of the graph and create the conflict free subgraph by starting at the root txouts (the txouts the root transactions spend from which are the transactions that do not spend the txouts of any other transactions in the graph). You can find these by taking any of the transactions you are interested in and and traversing ancestors until you have a tx that doesn't spend from any other in the graph. Start by adding the outpoints of the inputs from the root tx to the queue (and do this every time the queue is empty -- but don't start at transactions you've already visited).
To choose the canonical tx:
I think something like this will work and be efficient enough for now. The key point to note is that we are not finding a maximal conflict free subgraph since we are dropping transactions that actually could be in valid in the mempool because they have a lower To see why this is justified imagine A B C where both A and C conflict with B and the Optimizing to only focus on transactions not in the chainRather than starting with the root txouts of the whole graph, first emit and filter out all the transactions that are in chain according to the oracle. Now treat the root txouts as those that are confirmed already e.g. we start with a subgraph of the unconfirmed transactions where the root unconfirmed transactions spend from confirmed txouts (or txouts that don't exist in the graph). Applying to txouts and utoxsTo filter lists of txouts that are in the chain just start with the txout transactions as your arbitrary starting point. Any time you find a tx is canonical, the txouts of that transaction becomes canonical and can be emitted. UTXOs can be emitted whenever you would emit the txout with the added constraint that there are no canonical spends from it (which is determined when you later visit that outpoint in the main traversal). |
However, we should consider changing the behavior of
TxGraph::walk_conflicts
to walk ancestors to a given depth and check conflicts on those ancestors. This can be a separate issue.Originally posted by @evanlinjin in #1064 (review)
The text was updated successfully, but these errors were encountered: