1
- use std:: { env:: Args , time:: Instant , usize} ;
1
+ use std:: {
2
+ env,
3
+ str:: FromStr ,
4
+ time:: { Duration , Instant } ,
5
+ } ;
2
6
3
- use anyhow:: Result ;
7
+ use anyhow:: { Context , Result } ;
4
8
use clap:: Parser ;
5
- use iroh:: { protocol:: Router , Endpoint , NodeAddr , Watcher } ;
9
+ use iroh:: { protocol:: Router , Endpoint , NodeAddr , SecretKey , Watcher } ;
6
10
use iroh_base:: ticket:: NodeTicket ;
7
11
use ping:: EchoApi ;
12
+ use rand:: SeedableRng ;
8
13
9
14
#[ tokio:: main]
10
15
async fn main ( ) -> Result < ( ) > {
@@ -13,7 +18,8 @@ async fn main() -> Result<()> {
13
18
match args {
14
19
cli:: Args :: Listen { use_0rtt } => {
15
20
let ( server_router, server_addr) = {
16
- let endpoint = Endpoint :: builder ( ) . bind ( ) . await ?;
21
+ let secret_key = get_or_generate_secret_key ( ) ?;
22
+ let endpoint = Endpoint :: builder ( ) . secret_key ( secret_key) . bind ( ) . await ?;
17
23
endpoint. home_relay ( ) . initialized ( ) . await ;
18
24
let addr = endpoint. node_addr ( ) . initialized ( ) . await ;
19
25
let api = EchoApi :: spawn ( ) ;
@@ -41,6 +47,7 @@ async fn main() -> Result<()> {
41
47
n,
42
48
delay_ms,
43
49
use_0rtt,
50
+ wait_for_ticket,
44
51
} => {
45
52
let n = n
46
53
. iter ( )
@@ -56,11 +63,26 @@ async fn main() -> Result<()> {
56
63
let msg = i. to_be_bytes ( ) ;
57
64
let t0 = Instant :: now ( ) ;
58
65
let res = api. echo_0rtt ( msg. to_vec ( ) ) . await ;
59
- drop ( api) ;
66
+ let latency = endpoint. remote_info ( addr. node_id ) . and_then ( |x| x. latency ) ;
67
+ if wait_for_ticket {
68
+ tokio:: spawn ( async move {
69
+ let latency = latency. unwrap_or ( Duration :: from_millis ( 500 ) ) ;
70
+ tokio:: time:: sleep ( latency * 2 ) . await ;
71
+ drop ( api) ;
72
+ } ) ;
73
+ } else {
74
+ drop ( api) ;
75
+ }
60
76
match res {
61
77
Ok ( data) => {
62
78
let elapsed = t0. elapsed ( ) ;
63
79
assert ! ( data == msg) ;
80
+ println ! (
81
+ "latency: {}" ,
82
+ latency
83
+ . map( |x| format!( "{}ms" , x. as_micros( ) as f64 / 1000.0 ) )
84
+ . unwrap_or( "unknown" . into( ) )
85
+ ) ;
64
86
println ! ( "{}ms" , elapsed. as_micros( ) as f64 / 1000.0 ) ;
65
87
}
66
88
Err ( err) => {
@@ -76,10 +98,26 @@ async fn main() -> Result<()> {
76
98
Ok ( ( ) )
77
99
}
78
100
101
+ /// Gets a secret key from the IROH_SECRET environment variable or generates a new random one.
102
+ /// If the environment variable is set, it must be a valid string representation of a secret key.
103
+ pub fn get_or_generate_secret_key ( ) -> Result < SecretKey > {
104
+ if let Ok ( secret) = env:: var ( "IROH_SECRET" ) {
105
+ // Parse the secret key from string
106
+ SecretKey :: from_str ( & secret) . context ( "Invalid secret key format" )
107
+ } else {
108
+ // Generate a new random key
109
+ let secret_key = SecretKey :: generate ( & mut rand:: rngs:: StdRng :: from_entropy ( ) ) ;
110
+ println ! (
111
+ "Generated new secret key: {}" ,
112
+ hex:: encode( secret_key. to_bytes( ) )
113
+ ) ;
114
+ println ! ( "To reuse this key, set the IROH_SECRET environment variable to this value" ) ;
115
+ Ok ( secret_key)
116
+ }
117
+ }
118
+
79
119
mod cli {
80
- use anyhow:: Result ;
81
120
use clap:: Parser ;
82
- use iroh:: NodeId ;
83
121
use iroh_base:: ticket:: NodeTicket ;
84
122
85
123
#[ derive( Debug , Parser ) ]
@@ -96,6 +134,8 @@ mod cli {
96
134
use_0rtt : bool ,
97
135
#[ clap( long, default_value = "1000" ) ]
98
136
delay_ms : u64 ,
137
+ #[ clap( long, default_value = "false" ) ]
138
+ wait_for_ticket : bool ,
99
139
} ,
100
140
}
101
141
}
0 commit comments