1
1
use addressing;
2
+ use addressing:: AddressTypeError ;
2
3
use sphinx:: route:: { Destination , DestinationAddressBytes , SURBIdentifier } ;
3
4
use sphinx:: SphinxPacket ;
4
5
use std:: net:: SocketAddr ;
5
- use topology:: NymTopology ;
6
+ use topology:: { NymTopology , NymTopologyError } ;
6
7
7
8
pub const LOOP_COVER_MESSAGE_PAYLOAD : & [ u8 ] = b"The cake is a lie!" ;
8
9
pub const LOOP_COVER_MESSAGE_AVERAGE_DELAY : f64 = 2.0 ;
9
10
11
+ #[ derive( Debug ) ]
12
+ pub enum SphinxPacketEncapsulationError {
13
+ NoValidProvidersError ,
14
+ InvalidTopologyError ,
15
+ SphinxEncapsulationError ( sphinx:: header:: SphinxUnwrapError ) ,
16
+ InvalidFirstMixAddress ,
17
+ }
18
+
19
+ impl From < topology:: NymTopologyError > for SphinxPacketEncapsulationError {
20
+ fn from ( _: NymTopologyError ) -> Self {
21
+ use SphinxPacketEncapsulationError :: * ;
22
+ InvalidTopologyError
23
+ }
24
+ }
25
+
26
+ // it is correct error we're converting from, it just has an unfortunate name
27
+ // related issue: https://github.com/nymtech/sphinx/issues/40
28
+ impl From < sphinx:: header:: SphinxUnwrapError > for SphinxPacketEncapsulationError {
29
+ fn from ( err : sphinx:: header:: SphinxUnwrapError ) -> Self {
30
+ use SphinxPacketEncapsulationError :: * ;
31
+ SphinxEncapsulationError ( err)
32
+ }
33
+ }
34
+
35
+ impl From < AddressTypeError > for SphinxPacketEncapsulationError {
36
+ fn from ( _: AddressTypeError ) -> Self {
37
+ use SphinxPacketEncapsulationError :: * ;
38
+ InvalidFirstMixAddress
39
+ }
40
+ }
41
+
10
42
pub fn loop_cover_message < T : NymTopology > (
11
43
our_address : DestinationAddressBytes ,
12
44
surb_id : SURBIdentifier ,
13
45
topology : & T ,
14
- ) -> ( SocketAddr , SphinxPacket ) {
46
+ ) -> Result < ( SocketAddr , SphinxPacket ) , SphinxPacketEncapsulationError > {
15
47
let destination = Destination :: new ( our_address, surb_id) ;
16
48
17
49
encapsulate_message (
@@ -27,19 +59,24 @@ pub fn encapsulate_message<T: NymTopology>(
27
59
message : Vec < u8 > ,
28
60
topology : & T ,
29
61
average_delay : f64 ,
30
- ) -> ( SocketAddr , SphinxPacket ) {
62
+ ) -> Result < ( SocketAddr , SphinxPacket ) , SphinxPacketEncapsulationError > {
31
63
let mut providers = topology. providers ( ) ;
64
+ if providers. len ( ) == 0 {
65
+ return Err ( SphinxPacketEncapsulationError :: NoValidProvidersError ) ;
66
+ }
67
+ // unwrap is fine here as we asserted there is at least single provider
32
68
let provider = providers. pop ( ) . unwrap ( ) . into ( ) ;
33
69
34
- let route = topology. route_to ( provider) . unwrap ( ) ;
70
+ let route = topology. route_to ( provider) ? ;
35
71
36
72
let delays = sphinx:: header:: delays:: generate ( route. len ( ) , average_delay) ;
37
73
38
74
// build the packet
39
- let packet = sphinx:: SphinxPacket :: new ( message, & route[ ..] , & recipient, & delays) . unwrap ( ) ;
75
+ let packet = sphinx:: SphinxPacket :: new ( message, & route[ ..] , & recipient, & delays) ? ;
40
76
77
+ // we know the mix route must be valid otherwise we would have already returned an error
41
78
let first_node_address =
42
- addressing:: socket_address_from_encoded_bytes ( route. first ( ) . unwrap ( ) . address . to_bytes ( ) ) ;
79
+ addressing:: socket_address_from_encoded_bytes ( route. first ( ) . unwrap ( ) . address . to_bytes ( ) ) ? ;
43
80
44
- ( first_node_address, packet)
81
+ Ok ( ( first_node_address, packet) )
45
82
}
0 commit comments