Skip to content

Commit e149ec2

Browse files
sanityclaude
andauthored
fix(test): add transport keypair uniqueness verification (#2225)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent b9309dc commit e149ec2

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

crates/freenet-macros/src/codegen.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,41 @@ pub fn generate_test_code(args: FreenetTestArgs, input_fn: ItemFn) -> Result<Tok
187187
/// Generate node configuration setup code
188188
fn generate_node_setup(args: &FreenetTestArgs) -> TokenStream {
189189
let mut setup_code = Vec::new();
190+
let node_count = args.nodes.len();
191+
let node_count_lit = LitInt::new(&node_count.to_string(), proc_macro2::Span::call_site());
192+
193+
// First, generate all keypairs upfront and verify uniqueness
194+
// This prevents rare RNG collisions from causing confusing test failures
195+
setup_code.push(quote! {
196+
// Generate all transport keypairs upfront
197+
let __keypairs: Vec<freenet::dev_tool::TransportKeypair> = (0..#node_count_lit)
198+
.map(|_| freenet::dev_tool::TransportKeypair::new())
199+
.collect();
200+
201+
// Verify all public keys are unique (sanity check against RNG issues)
202+
{
203+
let mut seen_keys = std::collections::HashSet::new();
204+
for (idx, keypair) in __keypairs.iter().enumerate() {
205+
let key_str = format!("{}", keypair.public());
206+
if !seen_keys.insert(key_str.clone()) {
207+
return Err(anyhow::anyhow!(
208+
"FATAL: Generated duplicate transport keypair for node {} (key: {}). \
209+
This indicates an RNG issue in the test environment. \
210+
Please report this to the Freenet developers.",
211+
idx,
212+
key_str
213+
));
214+
}
215+
}
216+
tracing::debug!("Verified {} unique transport keypairs", #node_count_lit);
217+
}
218+
});
190219

191220
for (idx, node_label) in args.nodes.iter().enumerate() {
192221
let config_var = format_ident!("config_{}", idx);
193222
let temp_var = format_ident!("temp_{}", idx);
194223
let is_gw = is_gateway(args, node_label, idx);
224+
let idx_lit = LitInt::new(&idx.to_string(), proc_macro2::Span::call_site());
195225

196226
if is_gw {
197227
// Gateway node configuration
@@ -203,7 +233,7 @@ fn generate_node_setup(args: &FreenetTestArgs) -> TokenStream {
203233
let #ws_port_var_local = freenet::test_utils::reserve_local_port()?;
204234
let (#config_var, #temp_var) = {
205235
let temp_dir = tempfile::tempdir()?;
206-
let key = freenet::dev_tool::TransportKeypair::new();
236+
let key = &__keypairs[#idx_lit];
207237
let transport_keypair = temp_dir.path().join("private.pem");
208238
key.save(&transport_keypair)?;
209239
key.public().save(temp_dir.path().join("public.pem"))?;
@@ -278,6 +308,7 @@ fn generate_node_setup(args: &FreenetTestArgs) -> TokenStream {
278308
let config_var = format_ident!("config_{}", idx);
279309
let temp_var = format_ident!("temp_{}", idx);
280310
let is_gw = is_gateway(args, node_label, idx);
311+
let idx_lit = LitInt::new(&idx.to_string(), proc_macro2::Span::call_site());
281312

282313
if !is_gw {
283314
let location_expr = node_location(args, idx, node_label);
@@ -322,7 +353,7 @@ fn generate_node_setup(args: &FreenetTestArgs) -> TokenStream {
322353
let #ws_port_var_local = freenet::test_utils::reserve_local_port()?;
323354
let (#config_var, #temp_var) = {
324355
let temp_dir = tempfile::tempdir()?;
325-
let key = freenet::dev_tool::TransportKeypair::new();
356+
let key = &__keypairs[#idx_lit];
326357
let transport_keypair = temp_dir.path().join("private.pem");
327358
key.save(&transport_keypair)?;
328359
key.public().save(temp_dir.path().join("public.pem"))?;

0 commit comments

Comments
 (0)