urma_runtime/p2p/source.rs
1use crate::error::{Error, ensure};
2use bitcoin::{Block, block::Header};
3use urma_chain::{decode, observation::Chain};
4
5/// A block whose hash, transaction Merkle root and witness commitment were
6/// checked against the provider's active header at acquisition time.
7///
8/// Header verification relies on the configured trusted checkpoint and the
9/// existing local header cache (older cached PoW is not rechecked on reload).
10/// This does not establish full script, UTXO or MWEB consensus validity, or
11/// guarantee the globally highest-work chain. Membership can change after
12/// return; consumers must reconcile subsequent reorganizations.
13#[derive(Debug)]
14pub struct VerifiedBlock {
15 height: u64,
16 header: Header,
17 raw: Vec<u8>,
18 block: Block,
19}
20
21impl VerifiedBlock {
22 pub fn height(&self) -> u64 {
23 self.height
24 }
25
26 pub fn header(&self) -> &Header {
27 &self.header
28 }
29
30 /// Original bytes returned by the P2P worker, including Litecoin framing.
31 pub fn raw(&self) -> &[u8] {
32 &self.raw
33 }
34
35 /// Decoded transparent block view. Serializing it need not reproduce
36 /// Litecoin HogEx/MWEB framing; use `raw()` for original bytes.
37 pub fn block(&self) -> &Block {
38 &self.block
39 }
40}
41
42pub(super) fn decode_verified(
43 chain: Chain,
44 height: u64,
45 header: Header,
46 raw: Vec<u8>,
47) -> Result<VerifiedBlock, Error> {
48 let block = decode::esplora_block(&raw, chain, header.block_hash())?;
49 ensure!(
50 block.header == header,
51 "peer block header differs from the captured verified header"
52 );
53 Ok(VerifiedBlock {
54 height,
55 header,
56 raw,
57 block,
58 })
59}