unified_bridge/
bridge_exit.rs1use agglayer_primitives::{
2 keccak::{keccak256, keccak256_combine},
3 Address, Digest, Hashable, U256,
4};
5use hex_literal::hex;
6use serde::{Deserialize, Serialize};
7
8use crate::{LeafType, NetworkId, TokenInfo, L1_ETH};
9
10const EMPTY_METADATA_HASH: Digest = Digest(hex!(
11 "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
12));
13
14impl Hashable for TokenInfo {
15 #[inline]
16 fn hash(&self) -> Digest {
17 keccak256_combine([
18 &self.origin_network.to_be_bytes(),
19 self.origin_token_address.as_slice(),
20 ])
21 }
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
27#[cfg_attr(feature = "testutils", derive(arbitrary::Arbitrary))]
28pub struct BridgeExit {
29 pub leaf_type: LeafType,
30
31 pub token_info: TokenInfo,
33
34 pub dest_network: NetworkId,
36 pub dest_address: Address,
38
39 pub amount: U256,
41
42 pub metadata: Option<Digest>,
43}
44
45impl BridgeExit {
46 #[inline]
48 pub fn new(
49 leaf_type: LeafType,
50 origin_network: NetworkId,
51 origin_token_address: Address,
52 dest_network: NetworkId,
53 dest_address: Address,
54 amount: U256,
55 metadata: Vec<u8>,
56 ) -> Self {
57 Self {
58 leaf_type,
59 token_info: TokenInfo {
60 origin_network,
61 origin_token_address,
62 },
63 dest_network,
64 dest_address,
65 amount,
66 metadata: Some(keccak256(metadata.as_slice())),
67 }
68 }
69
70 #[inline]
71 pub fn is_transfer(&self) -> bool {
72 self.leaf_type == LeafType::Transfer
73 }
74}
75
76impl Hashable for BridgeExit {
77 #[inline]
78 fn hash(&self) -> Digest {
79 keccak256_combine([
80 [self.leaf_type as u8].as_slice(),
81 &self.token_info.origin_network.to_be_bytes(),
82 self.token_info.origin_token_address.as_slice(),
83 &self.dest_network.to_be_bytes(),
84 self.dest_address.as_slice(),
85 &self.amount.to_be_bytes::<32>(),
86 &self.metadata.unwrap_or(EMPTY_METADATA_HASH).0,
87 ])
88 }
89}
90
91impl BridgeExit {
92 #[inline]
93 pub fn is_message(&self) -> bool {
94 self.leaf_type == LeafType::Message
95 }
96
97 #[inline]
100 pub fn amount_token_info(&self) -> TokenInfo {
101 match self.leaf_type {
102 LeafType::Message => L1_ETH,
103 LeafType::Transfer => self.token_info,
104 }
105 }
106}