nectar_primitives/
overlay.rs1use alloy_primitives::{Address, Keccak256};
9
10use crate::{NetworkId, Nonce, SwarmAddress};
11
12#[must_use]
19pub fn compute_overlay(eth_addr: &Address, network_id: NetworkId, nonce: &Nonce) -> SwarmAddress {
20 let mut hasher = Keccak256::new();
21 hasher.update(eth_addr.as_slice());
22 hasher.update(network_id.to_le_bytes());
23 hasher.update(nonce.as_slice());
24 SwarmAddress::from(hasher.finalize())
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30 use alloy_primitives::{address, b256};
31
32 #[test]
33 fn deterministic_zero_nonce_zero_addr() {
34 let eth = Address::ZERO;
35 let nonce = Nonce::ZERO;
36 let net = NetworkId::MAINNET;
37 let overlay = compute_overlay(ð, net, &nonce);
38 let mut h = Keccak256::new();
40 h.update([0u8; 20]);
41 h.update(1u64.to_le_bytes());
42 h.update([0u8; 32]);
43 let expected = SwarmAddress::from(h.finalize());
44 assert_eq!(overlay, expected);
45 }
46
47 #[test]
48 fn different_network_yields_different_overlay() {
49 let eth = address!("0102030405060708091011121314151617181920");
50 let nonce = Nonce::new([0x55; 32]);
51 let m = compute_overlay(ð, NetworkId::MAINNET, &nonce);
52 let t = compute_overlay(ð, NetworkId::TESTNET, &nonce);
53 assert_ne!(m, t);
54 }
55
56 #[test]
57 fn different_nonce_yields_different_overlay() {
58 let eth = address!("0102030405060708091011121314151617181920");
59 let a = compute_overlay(ð, NetworkId::MAINNET, &Nonce::new([0; 32]));
60 let b = compute_overlay(ð, NetworkId::MAINNET, &Nonce::new([1; 32]));
61 assert_ne!(a, b);
62 }
63
64 #[test]
65 fn network_id_is_little_endian() {
66 let eth = address!("aabbccddeeff00112233445566778899aabbccdd");
68 let nonce = Nonce::new([0x42; 32]);
69 let net = NetworkId::new(0x0102_0304_0506_0708);
70 let overlay = compute_overlay(ð, net, &nonce);
71
72 let mut h = Keccak256::new();
73 h.update(eth.as_slice());
74 h.update([0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]); h.update(nonce.as_slice());
76 assert_eq!(overlay, SwarmAddress::from(h.finalize()));
77
78 let mut h_be = Keccak256::new();
80 h_be.update(eth.as_slice());
81 h_be.update([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); h_be.update(nonce.as_slice());
83 let be_overlay = SwarmAddress::from(h_be.finalize());
84 assert_ne!(overlay, be_overlay);
85 let _ = b256!("0000000000000000000000000000000000000000000000000000000000000000");
86 }
87}