lbry-sdk/lbry/blockchain/block.py

62 lines
1.7 KiB
Python
Raw Normal View History

2020-02-14 18:19:55 +01:00
import struct
2020-05-01 15:28:51 +02:00
from typing import Set
from typing import NamedTuple, List
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-05-18 14:22:23 +02:00
def create_block_filter(address_hashes: Set[bytes]) -> bytes:
return bytes(PyBIP158([bytearray(a) for a in address_hashes]).GetEncoded())
2020-05-01 15:28:51 +02:00
2020-05-18 14:22:23 +02:00
def get_block_filter(block_filter: bytes) -> PyBIP158:
return PyBIP158(bytearray(block_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