You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
paritytech/substrate#6780 did reveal that different input order of changes when processing a root with triedbmut can result in a slightly different query plan and thus different proof of execution.
The root cause is that triedbmut algorithm do 'fuse a branch without value and a single child with this single child' too eagerly.
The operation is applied in function fix and do access the single child.
If later we add a children to the deleted (when fused) branch, the deleted branch can be restored and there will be no use to query the single child.
So we end up querying an unneeded node in respect to a batch update.
This is not really bad as the hash of the fuse node is not calculated (hash are calculated lazily), but it ends up being an issue with the way we register proof in substrate (we store all node queried on the kv backend).
A first way to solve this should be to apply fix lazily (on root calculation) as we do with hash calculation and db writing, but it seems to me that this will require ordering the fix calls and is not as simple as insert node into memorydb.
A second way should be to rewrite the batch update.
I would propose/illustrate with (see #110 draft pr), to use a batch update that works on a sorted change and thus allow applying the node fusing only when we are sure no other change will be done on the branch (when exiting it). This kind of batch update is also good when looking at memory footprint (only a stack of max 16 nodes needs to be kept in memory), but it is not really relevant in substrate use case.
A third way would be to add the additional fix related query to substrate spec.
This is not a sound idea, specifying that the proof should be the strictly the required set of trie nodes to run the operation seems more correct to me and would make conflict with other implementation easier to rules out.
The text was updated successfully, but these errors were encountered:
paritytech/substrate#6780 did reveal that different input order of changes when processing a root with triedbmut can result in a slightly different query plan and thus different proof of execution.
The root cause is that triedbmut algorithm do 'fuse a branch without value and a single child with this single child' too eagerly.
The operation is applied in function
fix
and do access the single child.If later we add a children to the deleted (when fused) branch, the deleted branch can be restored and there will be no use to query the single child.
So we end up querying an unneeded node in respect to a batch update.
This is not really bad as the hash of the fuse node is not calculated (hash are calculated lazily), but it ends up being an issue with the way we register proof in substrate (we store all node queried on the kv backend).
A first way to solve this should be to apply
fix
lazily (on root calculation) as we do with hash calculation and db writing, but it seems to me that this will require ordering thefix
calls and is not as simple as insert node into memorydb.A second way should be to rewrite the batch update.
I would propose/illustrate with (see #110 draft pr), to use a batch update that works on a sorted change and thus allow applying the node fusing only when we are sure no other change will be done on the branch (when exiting it). This kind of batch update is also good when looking at memory footprint (only a stack of max 16 nodes needs to be kept in memory), but it is not really relevant in substrate use case.
A third way would be to add the additional
fix
related query to substrate spec.This is not a sound idea, specifying that the proof should be the strictly the required set of trie nodes to run the operation seems more correct to me and would make conflict with other implementation easier to rules out.
The text was updated successfully, but these errors were encountered: