@@ -400,9 +400,14 @@ fn build_tx_relays(ext: &ArcExtraCli) -> eyre::Result<Vec<String>> {
400400 . map ( |s| s. trim ( ) )
401401 . filter ( |s| !s. is_empty ( ) )
402402 . map ( |s| {
403- url:: Url :: parse ( s)
404- . map ( |_| s. to_string ( ) )
405- . map_err ( |e| eyre:: eyre!( "invalid --arc.tx.relays entry {s:?}: {e}" ) )
403+ let url = url:: Url :: parse ( s)
404+ . map_err ( |e| eyre:: eyre!( "invalid --arc.tx.relays entry {s:?}: {e}" ) ) ?;
405+ if !matches ! ( url. scheme( ) , "http" | "https" ) {
406+ return Err ( eyre:: eyre!(
407+ "invalid --arc.tx.relays entry {s:?}: transaction relay upstreams must use HTTP or HTTPS"
408+ ) ) ;
409+ }
410+ Ok ( s. to_string ( ) )
406411 } )
407412 . collect ( )
408413}
@@ -1028,10 +1033,10 @@ mod tests {
10281033 #[ test]
10291034 fn test_build_tx_relays_parses_csv_in_order ( ) {
10301035 let relays =
1031- tx_relays_from_args ( & [ "--arc.tx.relays" , "http://a:8545,http ://b:8545 " ] ) . unwrap ( ) ;
1036+ tx_relays_from_args ( & [ "--arc.tx.relays" , "http://a:8545,https ://b.example " ] ) . unwrap ( ) ;
10321037 assert_eq ! (
10331038 relays,
1034- vec![ "http://a:8545" . to_string( ) , "http ://b:8545 " . to_string( ) ]
1039+ vec![ "http://a:8545" . to_string( ) , "https ://b.example " . to_string( ) ]
10351040 ) ;
10361041 }
10371042
@@ -1047,6 +1052,23 @@ mod tests {
10471052 assert ! ( err. to_string( ) . contains( "invalid --arc.tx.relays entry" ) ) ;
10481053 }
10491054
1055+ #[ test]
1056+ fn test_build_tx_relays_rejects_non_http_urls ( ) {
1057+ for relay in [
1058+ "file:///tmp/upstream" ,
1059+ "ftp://relay.example" ,
1060+ "ws://relay.example" ,
1061+ "wss://relay.example" ,
1062+ ] {
1063+ let err = tx_relays_from_args ( & [ "--arc.tx.relays" , relay] )
1064+ . expect_err ( "transaction relay upstreams must use HTTP or HTTPS" ) ;
1065+ assert ! (
1066+ err. to_string( ) . contains( "must use HTTP or HTTPS" ) ,
1067+ "unexpected error for {relay}: {err}"
1068+ ) ;
1069+ }
1070+ }
1071+
10501072 #[ test]
10511073 fn test_tx_relays_conflicts_with_forwarder ( ) {
10521074 let result = ArcCli :: try_parse_from ( [
0 commit comments