@@ -12,6 +12,7 @@ pub struct EnrBuilder<K: EnrKey> {
12
12
seq : u64 ,
13
13
14
14
/// The key-value pairs for the ENR record.
15
+ /// Values are stored as RLP encoded bytes.
15
16
content : BTreeMap < Key , Vec < u8 > > ,
16
17
17
18
/// Pins the generic key types.
@@ -38,19 +39,24 @@ impl<K: EnrKey> EnrBuilder<K> {
38
39
}
39
40
40
41
/// Adds an arbitrary key-value to the `ENRBuilder`.
41
- pub fn add_value ( & mut self , key : impl AsRef < [ u8 ] > , value : Vec < u8 > ) -> & mut Self {
42
- self . content . insert ( key. as_ref ( ) . to_vec ( ) , value) ;
42
+ pub fn add_value ( & mut self , key : impl AsRef < [ u8 ] > , value : & [ u8 ] ) -> & mut Self {
43
+ self . add_value_rlp ( key, rlp:: encode ( & value) )
44
+ }
45
+
46
+ /// Adds an arbitrary key-value where the value is raw RLP encoded bytes.
47
+ pub fn add_value_rlp ( & mut self , key : impl AsRef < [ u8 ] > , rlp : Vec < u8 > ) -> & mut Self {
48
+ self . content . insert ( key. as_ref ( ) . to_vec ( ) , rlp) ;
43
49
self
44
50
}
45
51
46
52
/// Adds an `ip` field to the `ENRBuilder`.
47
53
pub fn ip ( & mut self , ip : IpAddr ) -> & mut Self {
48
54
match ip {
49
55
IpAddr :: V4 ( addr) => {
50
- self . content . insert ( b "ip". to_vec ( ) , addr. octets ( ) . to_vec ( ) ) ;
56
+ self . add_value ( "ip" , & addr. octets ( ) ) ;
51
57
}
52
58
IpAddr :: V6 ( addr) => {
53
- self . content . insert ( b "ip6". to_vec ( ) , addr. octets ( ) . to_vec ( ) ) ;
59
+ self . add_value ( "ip6" , & addr. octets ( ) ) ;
54
60
}
55
61
}
56
62
self
@@ -62,36 +68,32 @@ impl<K: EnrKey> EnrBuilder<K> {
62
68
63
69
/// Adds an `Id` field to the `ENRBuilder`.
64
70
pub fn id(&mut self, id: &str) -> &mut Self {
65
- self.content.insert ("id".into(), id.as_bytes().to_vec ());
71
+ self.add_value ("id", & id.as_bytes());
66
72
self
67
73
}
68
74
*/
69
75
70
76
/// Adds a `tcp` field to the `ENRBuilder`.
71
77
pub fn tcp ( & mut self , tcp : u16 ) -> & mut Self {
72
- self . content
73
- . insert ( "tcp" . into ( ) , tcp. to_be_bytes ( ) . to_vec ( ) ) ;
78
+ self . add_value ( "tcp" , & tcp. to_be_bytes ( ) ) ;
74
79
self
75
80
}
76
81
77
82
/// Adds a `tcp6` field to the `ENRBuilder`.
78
83
pub fn tcp6 ( & mut self , tcp : u16 ) -> & mut Self {
79
- self . content
80
- . insert ( "tcp6" . into ( ) , tcp. to_be_bytes ( ) . to_vec ( ) ) ;
84
+ self . add_value ( "tcp6" , & tcp. to_be_bytes ( ) ) ;
81
85
self
82
86
}
83
87
84
88
/// Adds a `udp` field to the `ENRBuilder`.
85
89
pub fn udp ( & mut self , udp : u16 ) -> & mut Self {
86
- self . content
87
- . insert ( "udp" . into ( ) , udp. to_be_bytes ( ) . to_vec ( ) ) ;
90
+ self . add_value ( "udp" , & udp. to_be_bytes ( ) ) ;
88
91
self
89
92
}
90
93
91
94
/// Adds a `udp6` field to the `ENRBuilder`.
92
95
pub fn udp6 ( & mut self , udp : u16 ) -> & mut Self {
93
- self . content
94
- . insert ( "udp6" . into ( ) , udp. to_be_bytes ( ) . to_vec ( ) ) ;
96
+ self . add_value ( "udp6" , & udp. to_be_bytes ( ) ) ;
95
97
self
96
98
}
97
99
@@ -102,7 +104,8 @@ impl<K: EnrKey> EnrBuilder<K> {
102
104
stream. append ( & self . seq ) ;
103
105
for ( k, v) in & self . content {
104
106
stream. append ( k) ;
105
- stream. append ( v) ;
107
+ // The values are stored as raw RLP encoded bytes
108
+ stream. append_raw ( v, 1 ) ;
106
109
}
107
110
stream. drain ( )
108
111
}
@@ -120,7 +123,7 @@ impl<K: EnrKey> EnrBuilder<K> {
120
123
121
124
/// Adds a public key to the ENR builder.
122
125
fn add_public_key ( & mut self , key : & K :: PublicKey ) {
123
- self . add_value ( key. enr_key ( ) , key. encode ( ) ) ;
126
+ self . add_value ( key. enr_key ( ) , & key. encode ( ) ) ;
124
127
}
125
128
126
129
/// Constructs an ENR from the `EnrBuilder`.
@@ -133,8 +136,17 @@ impl<K: EnrKey> EnrBuilder<K> {
133
136
return Err ( EnrError :: UnsupportedIdentityScheme ) ;
134
137
}
135
138
136
- self . content
137
- . insert ( "id" . into ( ) , self . id . as_bytes ( ) . to_vec ( ) ) ;
139
+ // Sanitize all data, ensuring all RLP data is correctly formatted.
140
+ for ( key, value) in & self . content {
141
+ if rlp:: Rlp :: new ( value) . data ( ) . is_err ( ) {
142
+ return Err ( EnrError :: InvalidRLPData (
143
+ String :: from_utf8_lossy ( key) . into ( ) ,
144
+ ) ) ;
145
+ }
146
+ }
147
+
148
+ let id_bytes = & self . id . as_bytes ( ) . to_vec ( ) ;
149
+ self . add_value ( "id" , id_bytes) ;
138
150
139
151
self . add_public_key ( & key. public ( ) ) ;
140
152
let rlp_content = self . rlp_content ( ) ;
0 commit comments