mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
Check SPV proof inner nodes not to be valid transactions. (#4436)
This commit is contained in:
parent
7797af6ffa
commit
61a9deaa61
1 changed files with 26 additions and 2 deletions
|
@ -20,8 +20,12 @@
|
|||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
from .util import ThreadJob
|
||||
from .util import ThreadJob, bh2u
|
||||
from .bitcoin import Hash, hash_decode, hash_encode
|
||||
from .transaction import Transaction
|
||||
|
||||
|
||||
class InnerNodeOfSpvProofIsValidTx(Exception): pass
|
||||
|
||||
|
||||
class SPV(ThreadJob):
|
||||
|
@ -79,7 +83,12 @@ class SPV(ThreadJob):
|
|||
tx_hash = params[0]
|
||||
tx_height = merkle.get('block_height')
|
||||
pos = merkle.get('pos')
|
||||
merkle_root = self.hash_merkle_root(merkle['merkle'], tx_hash, pos)
|
||||
try:
|
||||
merkle_root = self.hash_merkle_root(merkle['merkle'], tx_hash, pos)
|
||||
except InnerNodeOfSpvProofIsValidTx:
|
||||
self.print_error("merkle verification failed for {} (inner node looks like tx)"
|
||||
.format(tx_hash))
|
||||
return
|
||||
header = self.network.blockchain().read_header(tx_height)
|
||||
# FIXME: if verification fails below,
|
||||
# we should make a fresh connection to a server to
|
||||
|
@ -112,8 +121,23 @@ class SPV(ThreadJob):
|
|||
for i in range(len(merkle_s)):
|
||||
item = merkle_s[i]
|
||||
h = Hash(hash_decode(item) + h) if ((pos >> i) & 1) else Hash(h + hash_decode(item))
|
||||
cls._raise_if_valid_tx(bh2u(h))
|
||||
return hash_encode(h)
|
||||
|
||||
@classmethod
|
||||
def _raise_if_valid_tx(cls, raw_tx: str):
|
||||
# If an inner node of the merkle proof is also a valid tx, chances are, this is an attack.
|
||||
# https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-June/016105.html
|
||||
# https://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20180609/9f4f5b1f/attachment-0001.pdf
|
||||
# https://bitcoin.stackexchange.com/questions/76121/how-is-the-leaf-node-weakness-in-merkle-trees-exploitable/76122#76122
|
||||
tx = Transaction(raw_tx)
|
||||
try:
|
||||
tx.deserialize()
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
raise InnerNodeOfSpvProofIsValidTx()
|
||||
|
||||
def undo_verifications(self):
|
||||
height = self.blockchain.get_checkpoint()
|
||||
tx_hashes = self.wallet.undo_verifications(self.blockchain, height)
|
||||
|
|
Loading…
Add table
Reference in a new issue