lbryio / lbrycrd

The blockchain that provides the digital content namespace for the LBRY protocol
https://lbry.com
MIT License
2.57k stars 178 forks source link

Lbrycrd can crash when a support and abandon is on the same block #77

Closed kaykurokawa closed 6 years ago

kaykurokawa commented 6 years ago

It's possible to crash lbrycrd if two conditions are met

a) the claim is the only claim that exists for that claim's node in the claimtrie and any parent node up to the root node of the claimtrie. (i.e, the claim is for the name "zed" and there is no other claim on any name that starts with the letter "z")

b) The claim is abandoned and supported in the same block, or the claim is abandoned and a support of the claim is also abandoned.

This was due to a bug in the function reorderTrieNode which is called when reordering the claims in a node when a support is detected. In order to find that particular node for a given block update, it has to check the cache for any node updates which contains updated information for the nodes if claims in the node are deleted or updated. There was a bug where reorderTrieNode, failed to check the cache on the root node, thus any update cache entry for the root node (this would result when a children on a root node is deleted, for this to happen every single claim on a children of a root node need to be deleted) would be ignored when searching for the node to reorder. Thus it would find the old node before the udpate/delete and would attempt to reorder it and store it in the cache. This would fail , when we flush the block and update the claim trie and there is a cache entry for a node that should have been deleted, and lbrycrd will crash.

Firstly, to prevent malicious actors from using this exploit, I'm going to make claims at every children node off of the root node (we have a lot of claims on standard ascii characters so we don't need to do that for names that starts with "a" for example, but we need to make claims on non-ascii characters), so that condition a) cannot be met (this has been done on 12/28/2017).

Secondly, we are going to roll a fix for it which will prevent the crash from happening and the claimtrie will be updated as expected. After the fix is applied, this new lbrycrd node can accept blocks where the above scenario occurs. Since the old lbrycrd node cannot accept blocks where the above scenario occurs, this will technically be a hard fork , although the condition for this hard fork is not likely to cause a split due to the first action we've taken.