bundlr_sdk/verify/
file.rs1use super::types::{Header, Item};
2use crate::error::BundlrError;
3use crate::utils::read_offset;
4use crate::BundlrTx;
5use data_encoding::BASE64URL;
6use primitive_types::U256;
7use std::{cmp, fs::File};
8
9impl From<std::io::Error> for BundlrError {
10 fn from(e: std::io::Error) -> Self {
11 BundlrError::FsError(e.to_string())
12 }
13}
14
15pub async fn verify_file_bundle(filename: String) -> Result<Vec<Item>, BundlrError> {
16 let mut file = File::open(&filename)?;
17
18 let bundle_length = U256::from_little_endian(&read_offset(&mut file, 0, 32)?).as_u64();
19
20 let header_bytes = read_offset(&mut file, 32, bundle_length as usize * 64)?;
22 let mut headers = Vec::with_capacity(cmp::min(bundle_length as usize, 1000));
24
25 for i in (0..(64
26 * usize::try_from(bundle_length)
27 .map_err(|err| BundlrError::TypeParseError(err.to_string()))?))
28 .step_by(64)
29 {
30 let h = Header(
31 U256::from_little_endian(&header_bytes[i..i + 32]).as_u64(),
32 BASE64URL.encode(&header_bytes[i + 32..i + 64]),
33 );
34 headers.push(h);
35 }
36
37 let mut offset = 32 + (64 * bundle_length);
38 let mut items = Vec::with_capacity(cmp::min(bundle_length as usize, 1000));
39
40 for Header(size, id) in headers {
41 let mut tx = BundlrTx::from_file_position(&mut file, size, offset, 4096)?;
44
45 match tx.verify().await {
46 Err(err) => return Err(err),
47 Ok(_) => {
48 let sig = tx.get_signarure();
49 let item = Item {
50 tx_id: id,
51 signature: sig,
52 };
53 items.push(item);
54 offset += size;
55 }
56 }
57 }
58
59 Ok(items)
60}
61
62#[cfg(test)]
63mod tests {
64 use crate::error::BundlrError;
65
66 use super::verify_file_bundle;
67
68 #[tokio::test]
69 async fn should_verify_test_bundle() -> Result<(), BundlrError> {
70 verify_file_bundle("./res/test_bundles/test_bundle".to_string())
71 .await
72 .map(|_| ())
73 }
74
75 #[tokio::test]
76 async fn should_verify_arweave() -> Result<(), BundlrError> {
77 verify_file_bundle("./res/test_bundles/arweave_sig".to_string())
78 .await
79 .map(|_| ())
80 }
81
82 #[tokio::test]
83 async fn should_verify_secp256k1() -> Result<(), BundlrError> {
84 verify_file_bundle("./res/test_bundles/ethereum_sig".to_string()).await?;
85 verify_file_bundle("./res/test_bundles/typedethereum_sig".to_string()).await?;
86 verify_file_bundle("./res/test_bundles/arbitrum_sig".to_string()).await?;
87 verify_file_bundle("./res/test_bundles/avalanche_sig".to_string()).await?;
88 verify_file_bundle("./res/test_bundles/bnb_sig".to_string()).await?;
89 verify_file_bundle("./res/test_bundles/boba-eth_sig".to_string()).await?;
90 verify_file_bundle("./res/test_bundles/chainlink_sig".to_string()).await?;
91 verify_file_bundle("./res/test_bundles/kyve_sig".to_string()).await?;
92 verify_file_bundle("./res/test_bundles/matic_sig".to_string()).await?;
93 Ok(())
94 }
95
96 #[tokio::test]
110 async fn should_verify_ed25519() -> Result<(), BundlrError> {
111 verify_file_bundle("./res/test_bundles/solana_sig".to_string()).await?;
112 verify_file_bundle("./res/test_bundles/algorand_sig".to_string()).await?;
113 verify_file_bundle("./res/test_bundles/near_sig".to_string()).await?;
114 verify_file_bundle("./res/test_bundles/aptos_sig".to_string()).await?;
115 verify_file_bundle("./res/test_bundles/aptos_multisig".to_string()).await?;
116 Ok(())
117 }
118
119 #[tokio::test]
120 async fn should_verify_random_bundles() -> Result<(), BundlrError> {
121 for i in 1..100 {
122 verify_file_bundle(format!("./res/gen_bundles/bundle_{}", i).to_string()).await?;
123 }
124 Ok(())
125 }
126}