2020-02-14 18:19:55 +01:00
|
|
|
import struct
|
2020-09-21 16:26:19 +02:00
|
|
|
from typing import NamedTuple, List
|
2020-05-01 15:28:51 +02:00
|
|
|
|
2020-06-05 06:35:22 +02:00
|
|
|
from chiabip158 import PyBIP158 # pylint: disable=no-name-in-module
|
2020-05-01 15:28:51 +02:00
|
|
|
|
2020-02-14 18:19:55 +01:00
|
|
|
from lbry.crypto.hash import double_sha256
|
2020-05-01 15:28:51 +02:00
|
|
|
from lbry.blockchain.transaction import Transaction
|
|
|
|
from lbry.blockchain.bcd_data_stream import BCDataStream
|
2020-02-14 18:19:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
ZERO_BLOCK = bytes((0,)*32)
|
|
|
|
|
|
|
|
|
2020-09-21 16:26:19 +02:00
|
|
|
def create_address_filter(address_hashes: List[bytes]) -> bytes:
|
|
|
|
return bytes(PyBIP158([bytearray(a) for a in address_hashes]).GetEncoded())
|
2020-05-01 15:28:51 +02:00
|
|
|
|
|
|
|
|
2020-09-21 16:26:19 +02:00
|
|
|
def get_address_filter(address_filter: bytes) -> PyBIP158:
|
|
|
|
return PyBIP158(bytearray(address_filter))
|
2020-05-01 15:28:51 +02:00
|
|
|
|
2020-02-14 18:19:55 +01:00
|
|
|
|
2020-05-01 15:28:51 +02:00
|
|
|
class Block(NamedTuple):
|
|
|
|
height: int
|
|
|
|
version: int
|
|
|
|
file_number: int
|
|
|
|
block_hash: bytes
|
|
|
|
prev_block_hash: bytes
|
|
|
|
merkle_root: bytes
|
|
|
|
claim_trie_root: bytes
|
|
|
|
timestamp: int
|
|
|
|
bits: int
|
|
|
|
nonce: int
|
|
|
|
txs: List[Transaction]
|
2020-02-14 18:19:55 +01:00
|
|
|
|
2020-05-01 15:28:51 +02:00
|
|
|
@staticmethod
|
|
|
|
def from_data_stream(stream: BCDataStream, height: int, file_number: int):
|
2020-02-14 18:19:55 +01:00
|
|
|
header = stream.data.read(112)
|
|
|
|
version, = struct.unpack('<I', header[:4])
|
|
|
|
timestamp, bits, nonce = struct.unpack('<III', header[100:112])
|
|
|
|
tx_count = stream.read_compact_size()
|
2020-05-01 15:28:51 +02:00
|
|
|
return Block(
|
|
|
|
height=height,
|
|
|
|
version=version,
|
|
|
|
file_number=file_number,
|
|
|
|
block_hash=double_sha256(header),
|
|
|
|
prev_block_hash=header[4:36],
|
|
|
|
merkle_root=header[36:68],
|
|
|
|
claim_trie_root=header[68:100][::-1],
|
|
|
|
timestamp=timestamp,
|
|
|
|
bits=bits,
|
|
|
|
nonce=nonce,
|
2020-06-19 20:28:34 +02:00
|
|
|
txs=[
|
|
|
|
Transaction(height=height, position=i, timestamp=timestamp).deserialize(stream)
|
|
|
|
for i in range(tx_count)
|
|
|
|
]
|
2020-05-01 15:28:51 +02:00
|
|
|
)
|
2020-02-14 18:19:55 +01:00
|
|
|
|
|
|
|
@property
|
|
|
|
def is_first_block(self):
|
|
|
|
return self.prev_block_hash == ZERO_BLOCK
|