use agglayer_primitives::{
keccak::{keccak256, keccak256_combine},
Address, Digest, Hashable, U256,
};
use hex_literal::hex;
use serde::{Deserialize, Serialize};
use crate::{LeafType, NetworkId, TokenInfo, L1_ETH};
const EMPTY_METADATA_HASH: Digest = Digest(hex!(
"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
));
impl Hashable for TokenInfo {
#[inline]
fn hash(&self) -> Digest {
keccak256_combine([
&self.origin_network.to_be_bytes(),
self.origin_token_address.as_slice(),
])
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "testutils", derive(arbitrary::Arbitrary))]
pub struct BridgeExit {
pub leaf_type: LeafType,
pub token_info: TokenInfo,
pub dest_network: NetworkId,
pub dest_address: Address,
pub amount: U256,
pub metadata: Option<Digest>,
}
impl BridgeExit {
#[inline]
pub fn new(
leaf_type: LeafType,
origin_network: NetworkId,
origin_token_address: Address,
dest_network: NetworkId,
dest_address: Address,
amount: U256,
metadata: Vec<u8>,
) -> Self {
Self {
leaf_type,
token_info: TokenInfo {
origin_network,
origin_token_address,
},
dest_network,
dest_address,
amount,
metadata: Some(keccak256(metadata.as_slice())),
}
}
#[inline]
pub fn is_transfer(&self) -> bool {
self.leaf_type == LeafType::Transfer
}
}
impl Hashable for BridgeExit {
#[inline]
fn hash(&self) -> Digest {
keccak256_combine([
[self.leaf_type as u8].as_slice(),
&self.token_info.origin_network.to_be_bytes(),
self.token_info.origin_token_address.as_slice(),
&self.dest_network.to_be_bytes(),
self.dest_address.as_slice(),
&self.amount.to_be_bytes::<32>(),
&self.metadata.unwrap_or(EMPTY_METADATA_HASH).0,
])
}
}
impl BridgeExit {
#[inline]
pub fn is_message(&self) -> bool {
self.leaf_type == LeafType::Message
}
#[inline]
pub fn amount_token_info(&self) -> TokenInfo {
match self.leaf_type {
LeafType::Message => L1_ETH,
LeafType::Transfer => self.token_info,
}
}
}