MsgBlock.deserialize constructor

MsgBlock.deserialize(
  1. Uint8List data
)

Deserializes a MsgBlock from byte data.

Implementation

factory MsgBlock.deserialize(Uint8List data) {
  final buffer = ByteData.sublistView(data);
  var offset = 0;

  // Block header (80 bytes)
  if (offset + blockHeaderLen > data.length) {
    throw WireException('block',
        'Insufficient data for block header: need $blockHeaderLen, got ${data.length - offset}');
  }

  final headerBytes = data.sublist(offset, offset + blockHeaderLen);
  final header = BlockHeader.deserialize(headerBytes);
  offset += blockHeaderLen;

  // Transaction count (VarInt)
  if (offset >= data.length) {
    throw WireException('block', 'Insufficient data for transaction count');
  }

  final txCount = VarInt.read(buffer, offset);
  offset += VarInt.size(txCount);

  // Prevent more transactions than could possibly fit into a block
  final maxTxCount = _maxTxPerBlock();
  if (txCount > maxTxCount) {
    throw WireException('block',
        'Too many transactions to fit into a block: count $txCount, max $maxTxCount');
  }

  // Transactions
  final transactions = <MsgTx>[];
  for (int i = 0; i < txCount; i++) {
    if (offset >= data.length) {
      throw WireException('block', 'Insufficient data for transaction $i');
    }

    // Extract remaining data for transaction parsing
    final remainingData = data.sublist(offset);
    final tx = MsgTx.deserialize(remainingData, 0, latestEncoding);
    transactions.add(tx);

    // Calculate how much data the transaction consumed
    // We need to re-encode it to get the exact size
    final txBytes = tx.encode(0, latestEncoding);
    offset += txBytes.length;
  }

  return MsgBlock(
    header: header,
    transactions: transactions,
  );
}