Skip to content

Commit

Permalink
Can now parse LTC blocks with mweb transactions.
Browse files Browse the repository at this point in the history
Mempool mweb transactions don't work yet.
  • Loading branch information
richardkiss committed Jun 3, 2023
1 parent db7f39f commit afe87a2
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 5 deletions.
84 changes: 80 additions & 4 deletions pycoin/coins/litecoin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,82 @@
class Tx:
pass
from pycoin.block import Block
from pycoin.coins.bitcoin.Tx import Tx
from pycoin.satoshi.satoshi_int import parse_satoshi_int
from pycoin.satoshi.satoshi_string import parse_satoshi_string
from pycoin.satoshi.satoshi_struct import parse_struct


class Block:
pass
class LTCTx(Tx):
@classmethod
def parse(class_, f):
"""Parse a Bitcoin transaction Tx.
:param f: a file-like object that contains a binary streamed transaction
"""
(version,) = parse_struct("L", f)
v1 = ord(f.read(1))
is_segwit = v1 == 0
has_mweb = False
if is_segwit:
flag = ord(f.read(1))
if flag == 0:
raise ValueError("bad flag in segwit")
has_mweb = flag & 0x8 != 0
is_segwit = flag & 0x1 != 0
v1 = None
count = parse_satoshi_int(f, v=v1)
txs_in = []
for i in range(count):
txs_in.append(class_.TxIn.parse(f))
count = parse_satoshi_int(f)
txs_out = []
for i in range(count):
txs_out.append(class_.TxOut.parse(f))
if is_segwit:
for tx_in in txs_in:
stack = []
count = parse_satoshi_int(f)
for i in range(count):
stack.append(parse_satoshi_string(f))
tx_in.witness = stack
if has_mweb:
mweb_tx_type = ord(f.read(1))
if mweb_tx_type:
# TODO: read serialized MWEB transaction data
# TODO: save this away
pass
(lock_time,) = parse_struct("L", f)
return class_(version, txs_in, txs_out, lock_time)


class LTCBlock(Block):
Tx = LTCTx

@classmethod
def parse(
class_,
f,
include_transactions=True,
include_offsets=None,
check_merkle_hash=True,
):
"""
Parse the Block from the file-like object
"""
block = class_.parse_as_header(f)
if include_transactions:
count = parse_struct("I", f)[0]
txs = block._parse_transactions(f, count, include_offsets=include_offsets)
block.set_txs(txs, check_merkle_hash=check_merkle_hash)
return block

@classmethod
def _parse_transactions(class_, f, count, include_offsets=None):
txs = []
for i in range(count):
if include_offsets:
offset_in_block = f.tell()
tx = class_.Tx.parse(f)
txs.append(tx)
if include_offsets:
tx.offset_in_block = offset_in_block

return txs
7 changes: 6 additions & 1 deletion pycoin/symbols/ltc.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import struct

from pycoin.coins.litecoin import LTCTx, LTCBlock
from pycoin.networks.bitcoinish import create_bitcoinish_network
from pycoin.satoshi.satoshi_struct import parse_struct


network = create_bitcoinish_network(
network_name="Litecoin", symbol="LTC", subnet_name="mainnet",
wif_prefix_hex="b0", sec_prefix="LTCSEC:", address_prefix_hex="30", pay_to_script_prefix_hex="32",
bip32_prv_prefix_hex="019d9cfe", bip32_pub_prefix_hex="019da462", bech32_hrp="ltc")
bip32_prv_prefix_hex="019d9cfe", bip32_pub_prefix_hex="019da462", bech32_hrp="ltc",
block=LTCBlock, tx=LTCTx)
54 changes: 54 additions & 0 deletions tests/litecoin_mweb_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import unittest

from pycoin.symbols.ltc import network


BLOCK_BLOB = bytes.fromhex(
"00000020aa9ae9f67b58a2293624a906cbcd538f54551b343ba11be46857eb779"
"44851a15ed60060b9d11ba304c819a03e72a2d6e2f56d329c49ddbe2167436964"
"86c65705245163ffff0f1e0000c23804010000000001010000000000000000000"
"000000000000000000000000000000000000000000000ffffffff1b039cf72600"
"000000737472616e676520656e6f7567680001000000ffffffff0239444125000"
"000001976a914fd22672c72b3e41b0cbc6052ccb048183aa1770f88ac00000000"
"00000000266a24aa21a9eda382d6ac11e42a2008bef156f8ea279a4b9d2e536ff"
"a119fd17c6facd8aeb7ac01200000000000000000000000000000000000000000"
"0000000000000000000000000000000001000000019eeb47d40744d90495a214d"
"1c41483a5fd2a7302552cfb9ed7b1538f701ed5240100000085483045022100e4"
"8ba89089eab3cf69c87cbe996e476bef6dc772500e7cc0be759909b4aae8c6022"
"071dc39100262cb9e6405ca1a579cdb1976423aec5308ba93d739437f5b3d1f03"
"012103d7dc4bc0c1b25a918bbda2431fc693c72940dbf81f8168413560e377e7d"
"293ef1976a9145bbb2e434952c656c061945a5243a40f867ca2c488acfdffffff"
"02102700000000000017a914614b04a4979915bc0b3d6560d8e47a24c9fd01728"
"770590e000000000017a914f35de0762f71f8dcbc23799838ca95250e6a8b3a87"
"0000000001000000000103584f0bb29fffb5bb7f6e3b8aee41b87a730ced08dc7"
"3c3c21aee96ea7f704342000000006a47304402205b6f956fedb21dbf83940375"
"dc3bf7e7049af2981602fd60d20fad1f089cfed1022012f54f02b957e7486e700"
"24c5b5bb980917398cc5de8862871b40d465663e72d01210279bc0d505cf765bb"
"837bf705cd6015d45e5b0fcb057e8adca26a311c76a76e55fdffffff9deab2a0e"
"f8d6f0ecc498c971d3865d46763726510a358d7c232ab9117b3009d000000006a"
"47304402200762be7239be9e54bc0f944643f2396c2af5b0d23c26b69237b257e"
"a2c9f9dbb0220324702aab637074c6ee0e63bdfe60a503d48df35b5398073b4aa"
"0d4b7d46562b01210279bc0d505cf765bb837bf705cd6015d45e5b0fcb057e8ad"
"ca26a311c76a76e55fdffffffc88912269e5fa3174f47f6d0cc587eeac00045ca"
"ed1c5ba53cda331a82c19558010000001716001493e3b88e659fe793dd14a3e31"
"6f62ac70418c20afdffffff0200c2eb0b000000001976a914701641f135c1706b"
"83f6aaef804582011d81fe4788acb49ceb0b0000000017a914bf0a93fed47f247"
"13270ac25d7ca9d86c03885128700000247304402204c0fed21dd655519211660"
"5ff4e220a8c76af6b7362127a203bde89289b6c6110220406748ec790859941d2"
"b90a488307ea95dffccbefc46f7d3c5072042ad9bb54e01210279bc0d505cf765"
"bb837bf705cd6015d45e5b0fcb057e8adca26a311c76a76e55000000000200000"
"0000801cb6ade7dca1add1bafbf69f78f8bbc3c63174c247f7cf6e00e645f8845"
"20841a0000000000ffffffff0163b98c3a9f320000225820c000742df1236e7d0"
"ac716292423b6f2333a4d7433ba9afd8173694e265a21c2000000000001809aee"
"1c4b539abb1d9c8d93de7944339217dfa788e55eea4256101070350bc44224548"
"b0000000000000000000000000000000000000000000000000000000000000000"
"c587d488ae5ad91ad2b19125de8702a816a87a7cf7123fb1fca1f58e342dc096e"
"ab97755e84e9abf23281be3c2d6865a643f95531dbec11f972bbd78961d49e500"
"000000000000000000000000000000000000000000000000000000000000009c4"
"700000000"
)


class LTCMWebTestCase(unittest.TestCase):
def test_parse_block(self):
block = network.Block.from_bin(BLOCK_BLOB)

0 comments on commit afe87a2

Please sign in to comment.