cfxcore/light_protocol/handler/sync/common/
ledger_proof.rs1use cfx_types::H256;
6use primitives::{BlockHeader, BlockHeaderBuilder};
7use std::ops::Index;
8
9use crate::light_protocol::Error;
10
11pub enum LedgerProof {
12 StateRoot(Vec<H256>),
13 ReceiptsRoot(Vec<H256>),
14 LogsBloomHash(Vec<H256>),
15}
16
17impl Index<usize> for LedgerProof {
18 type Output = H256;
19
20 fn index(&self, ii: usize) -> &Self::Output {
21 let hashes = match self {
22 LedgerProof::StateRoot(hs) => hs,
23 LedgerProof::ReceiptsRoot(hs) => hs,
24 LedgerProof::LogsBloomHash(hs) => hs,
25 };
26
27 &hashes[ii]
28 }
29}
30
31impl LedgerProof {
32 pub fn validate(&self, witness: &BlockHeader) -> Result<(), Error> {
33 let (hashes, expected) = match self {
35 LedgerProof::StateRoot(hashes) => {
36 (hashes, *witness.deferred_state_root())
37 }
38 LedgerProof::ReceiptsRoot(hashes) => {
39 (hashes, *witness.deferred_receipts_root())
40 }
41 LedgerProof::LogsBloomHash(hashes) => {
42 (hashes, *witness.deferred_logs_bloom_hash())
43 }
44 };
45
46 let hash = witness.hash();
48 let blame = witness.blame() as u64;
49
50 if hashes.len() as u64 != blame + 1 {
51 bail!(Error::InvalidLedgerProofSize {
52 hash,
53 expected: blame + 1,
54 received: hashes.len() as u64
55 });
56 }
57
58 let received = match blame {
60 0 => hashes[0],
61 _ => {
62 let hashes = hashes.clone();
63 BlockHeaderBuilder::compute_blame_state_root_vec_root(hashes)
64 }
65 };
66
67 if received != expected {
69 bail!(Error::InvalidWitnessRoot {
70 hash,
71 expected,
72 received,
73 });
74 }
75
76 Ok(())
77 }
78}