kona_protocol/
output_root.rs1use alloy_primitives::{B256, keccak256};
4use derive_more::Display;
5
6#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash)]
14#[display("OutputRootV0({}, {}, {})", state_root, bridge_storage_root, block_hash)]
15pub struct OutputRoot {
16 pub state_root: B256,
18 pub bridge_storage_root: B256,
21 pub block_hash: B256,
23}
24
25impl OutputRoot {
26 pub const ENCODED_LENGTH: usize = 128;
28
29 pub const VERSION: u8 = 0;
32
33 pub const fn version(&self) -> B256 {
36 B256::ZERO
37 }
38
39 pub const fn from_parts(state_root: B256, bridge_storage_root: B256, block_hash: B256) -> Self {
41 Self { state_root, bridge_storage_root, block_hash }
42 }
43
44 pub fn encode(&self) -> [u8; Self::ENCODED_LENGTH] {
46 let mut encoded = [0u8; Self::ENCODED_LENGTH];
47 encoded[31] = Self::VERSION;
48 encoded[32..64].copy_from_slice(self.state_root.as_slice());
49 encoded[64..96].copy_from_slice(self.bridge_storage_root.as_slice());
50 encoded[96..128].copy_from_slice(self.block_hash.as_slice());
51 encoded
52 }
53
54 pub fn hash(&self) -> B256 {
56 keccak256(self.encode())
57 }
58}
59
60#[cfg(test)]
61mod test {
62 use super::OutputRoot;
63 use alloy_primitives::{B256, Bytes, b256, bytes};
64
65 fn test_or() -> OutputRoot {
66 OutputRoot::from_parts(
67 B256::left_padding_from(&[0xbe, 0xef]),
68 B256::left_padding_from(&[0xba, 0xbe]),
69 B256::left_padding_from(&[0xc0, 0xde]),
70 )
71 }
72
73 #[test]
74 fn test_hash_output_root() {
75 const EXPECTED_HASH: B256 =
76 b256!("0c39fb6b07cf6694b13e63e59f7b15255be1c93a4d6d3e0da6c99729647c0d11");
77
78 let root = test_or();
79 assert_eq!(root.hash(), EXPECTED_HASH);
80 }
81
82 #[test]
83 fn test_encode_output_root() {
84 const EXPECTED_ENCODING: Bytes = bytes!(
85 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef000000000000000000000000000000000000000000000000000000000000babe000000000000000000000000000000000000000000000000000000000000c0de"
86 );
87
88 let root = OutputRoot::from_parts(
89 B256::left_padding_from(&[0xbe, 0xef]),
90 B256::left_padding_from(&[0xba, 0xbe]),
91 B256::left_padding_from(&[0xc0, 0xde]),
92 );
93
94 assert_eq!(root.encode().as_ref(), EXPECTED_ENCODING.as_ref());
95 }
96}