unified_bridge/
token_info.rs1use agglayer_primitives::{address, Address};
2use agglayer_tries::proof::ToBits;
3use serde::{Deserialize, Serialize};
4
5use crate::NetworkId;
6
7pub const L1_ETH: TokenInfo = TokenInfo {
8 origin_network: NetworkId::ETH_L1,
9 origin_token_address: address!("0000000000000000000000000000000000000000"),
10};
11
12#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Copy)]
15#[cfg_attr(feature = "testutils", derive(arbitrary::Arbitrary))]
16pub struct TokenInfo {
17 pub origin_network: NetworkId,
19
20 pub origin_token_address: Address,
22}
23
24#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
25#[cfg_attr(feature = "testutils", derive(arbitrary::Arbitrary))]
26pub enum LeafType {
27 Transfer = 0,
28 Message = 1,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
32#[error("Invalid leaf type number")]
33pub struct LeafTypeFromU8Error;
34
35impl TryFrom<u8> for LeafType {
36 type Error = LeafTypeFromU8Error;
37
38 #[inline]
39 fn try_from(value: u8) -> Result<Self, Self::Error> {
40 match value {
41 0 => Ok(Self::Transfer),
42 1 => Ok(Self::Message),
43 _ => Err(LeafTypeFromU8Error),
44 }
45 }
46}
47
48impl ToBits<192> for TokenInfo {
49 #[inline]
50 fn to_bits(&self) -> [bool; 192] {
51 let address_bytes = self.origin_token_address.as_slice();
52 std::array::from_fn(|i| {
55 if i < 32 {
56 (self.origin_network.to_u32() >> i) & 1 == 1
57 } else {
58 ((address_bytes[(i - 32) / 8]) >> (i % 8)) & 1 == 1
59 }
60 })
61 }
62}
63
64impl TokenInfo {
65 pub fn from_bits(bits: &[bool; 192]) -> Self {
67 let mut network_id_u32 = 0u32;
69 for (i, &bit) in bits[0..32].iter().enumerate() {
70 if bit {
71 network_id_u32 |= 1 << i;
72 }
73 }
74
75 let mut address_bytes = [0u8; 20];
77 for (i, &bit) in bits[32..192].iter().enumerate() {
78 if bit {
79 let byte_index = i / 8;
80 let bit_offset = i % 8;
81 address_bytes[byte_index] |= 1 << bit_offset;
82 }
83 }
84
85 TokenInfo {
86 origin_network: NetworkId::from(network_id_u32),
87 origin_token_address: Address::from(address_bytes),
88 }
89 }
90}
91
92#[test]
93fn test_token_info_round_trip() {
94 let initial = TokenInfo {
95 origin_network: NetworkId::from(1234),
96 origin_token_address: Address::from([0xab; 20]),
97 };
98
99 assert_eq!(initial, TokenInfo::from_bits(&initial.to_bits()));
100}