transact/contract/address/triple_key_hash.rs
1// Copyright 2019 Cargill Incorporated
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::contract::address::{hash, Addresser, AddresserError, ADDRESS_LENGTH};
16
17pub struct TripleKeyHashAddresser {
18 prefix: String,
19 first_hash_length: usize,
20 second_hash_length: usize,
21}
22
23impl TripleKeyHashAddresser {
24 pub fn new(
25 prefix: String,
26 first_hash_length: Option<usize>,
27 second_hash_length: Option<usize>,
28 ) -> Result<TripleKeyHashAddresser, AddresserError> {
29 let (first, second) =
30 calculate_hash_lengths(prefix.len(), first_hash_length, second_hash_length)?;
31 Ok(TripleKeyHashAddresser {
32 prefix,
33 first_hash_length: first,
34 second_hash_length: second,
35 })
36 }
37}
38
39impl Addresser<(String, String, String)> for TripleKeyHashAddresser {
40 fn compute(&self, key: &(String, String, String)) -> Result<String, AddresserError> {
41 let last_hash_length =
42 ADDRESS_LENGTH - self.prefix.len() - (self.first_hash_length + self.second_hash_length);
43
44 let first_hash = &hash(self.first_hash_length, &key.0);
45 let second_hash = &hash(self.second_hash_length, &key.1);
46 let third_hash = &hash(last_hash_length, &key.2);
47
48 Ok(String::from(&self.prefix) + first_hash + second_hash + third_hash)
49 }
50
51 fn normalize(&self, key: &(String, String, String)) -> String {
52 key.0.to_string() + "_" + &key.1 + "_" + &key.2
53 }
54}
55
56// Used to calculate the lengths of the key hashes to be used to create an address by the
57// TripleKeyHashAddresser.
58fn calculate_hash_lengths(
59 prefix_length: usize,
60 first_length: Option<usize>,
61 second_length: Option<usize>,
62) -> Result<(usize, usize), AddresserError> {
63 // Validate the length of the provided prefix is not greater than the ADDRESS_LENGTH.
64 if prefix_length > ADDRESS_LENGTH {
65 return Err(AddresserError {
66 message: format!(
67 "Prefix length ({}) is greater than total address length ({})",
68 prefix_length, ADDRESS_LENGTH
69 ),
70 });
71 }
72 match (first_length, second_length) {
73 (Some(first), Some(second)) => {
74 // Validate the hash lengths plus the prefix length is not greater than ADDRESS_LENGTH.
75 if prefix_length + first + second > ADDRESS_LENGTH {
76 return Err(AddresserError {
77 message: format!(
78 "Prefix length ({}) and hash lengths ({}) combined are greater than \
79 total address length ({})",
80 prefix_length,
81 (first + second),
82 ADDRESS_LENGTH
83 ),
84 });
85 }
86 Ok((first, second))
87 }
88 (None, Some(second)) => {
89 // Validate the hash length plus the prefix length is not greater than ADDRESS_LENGTH.
90 if prefix_length + second > ADDRESS_LENGTH {
91 return Err(AddresserError {
92 message: format!(
93 "Prefix length ({}) and hash length ({}) combined are greater than \
94 total address length ({})",
95 prefix_length, second, ADDRESS_LENGTH
96 ),
97 });
98 }
99 // If the prefix length and hash length are not greater than ADDRESS_LENGTH, the
100 // other hash length can be calculated and returned.
101 let calculated_length = (ADDRESS_LENGTH - prefix_length - second) / 2;
102 Ok((calculated_length, second))
103 }
104 (Some(first), None) => {
105 // Validate the hash length plus the prefix length is not greater than ADDRESS_LENGTH.
106 if prefix_length + first > ADDRESS_LENGTH {
107 return Err(AddresserError {
108 message: format!(
109 "Prefix length ({}) and hash length ({}) combined are greater than \
110 total address length ({})",
111 prefix_length, first, ADDRESS_LENGTH
112 ),
113 });
114 }
115 // If the prefix length and hash ength are not greater than ADDRESS_LENGTH, the other
116 // hash length can be calculated and returned.
117 let calculated_length = (ADDRESS_LENGTH - prefix_length - first) / 2;
118 Ok((first, calculated_length))
119 }
120 (None, None) => {
121 // Calculate the first and second hash length.
122 let calculated_first = (ADDRESS_LENGTH - prefix_length) / 3;
123 let calculated_second = calculated_first;
124 // Validate the calculated hash lengths plus the prefix length is not greater than the
125 // ADDRESS_LENGTH.
126 if prefix_length + calculated_first + calculated_second > ADDRESS_LENGTH {
127 return Err(AddresserError {
128 message: format!(
129 "Prefix length ({}) and hash lengths ({}) combined are greater than \
130 total address length ({})",
131 prefix_length,
132 (calculated_first + calculated_second),
133 ADDRESS_LENGTH
134 ),
135 });
136 }
137 // If the validation is passed, return the calculated hash lengths.
138 Ok((calculated_first, calculated_second))
139 }
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146
147 #[test]
148 /// This test constructs a TripleKeyHashAddresser with a 6 character `prefix` and a None option
149 /// for the `first_hash_length` and `second_hash_length.` The default value for these hash lengths
150 /// is the ADDRESS_LENGTH const minus the length of the prefix, then divided by 3. This test
151 /// ensures this addresser computes a valid radix address from the provided key, `('a', 'b', 'c')`.
152 /// Specifically, this test validates:
153 ///
154 /// 1. The address length matches the ADDRESS_LENGTH const
155 /// 2. The prefix is present in the beginning of the address
156 /// 3. The next characters, the length of which matches the default value `first_hash_length`,
157 /// match the hash of the first key, 'a', of the tuple provided to the `compute` method
158 /// 4. The next characters, the length of which matches the default `second_hash_length`,
159 /// match the hash of the second key, 'b', of the tuple provided to the `compute` method
160 /// 5. The remaining characters, the length of which matches the ADDRESS_LENGTH const less the
161 /// length of the provided `prefix`, the default `first_hash_length` and `second_hash_length`,
162 /// match the hash of the last key, 'c', of the tuple provided to the `compute` method
163 ///
164 /// This test also ensures that the instantiated TripleKeyHashAddresser can transform the natural
165 /// key into a single string with the individual keys within the tuple of three strings separated
166 /// by an underscore(`_`), using the `normalize` method.
167 fn test_triple_key_default_length() {
168 // Creating a DoubleKeyHashAddresser with a 6 character `prefix` and None options for the
169 // `first_hash_length` and `second_hash_length`
170 let addresser = TripleKeyHashAddresser::new("prefix".to_string(), None, None)
171 .expect("Unable to construct TripleKeyHashAddresser");
172 // Create the hashes of the individual keys to verify the constructed address
173 let key1 = "a";
174 let key1_hash = hash(21, key1);
175 let key2 = "b";
176 let key2_hash = hash(21, key2);
177 let key3 = "c";
178 let key3_hash = hash(22, key3);
179 // Compute the address
180 let addr = addresser
181 .compute(&(key1.to_string(), key2.to_string(), key3.to_string()))
182 .unwrap();
183 // Verify the `prefix` characters and the length
184 assert_eq!(addr[..6], "prefix".to_string());
185 assert_eq!(addr.len(), ADDRESS_LENGTH);
186 // Verify the remaining characters match the hash of each key created above
187 assert_eq!(addr[6..27], key1_hash[..21]);
188 assert_eq!(addr[27..48], key2_hash[..21]);
189 assert_eq!(addr[48..], key3_hash[..22]);
190 // Verify the `normalize` method generates the correct single string
191 let normalized =
192 addresser.normalize(&(key1.to_string(), key2.to_string(), key3.to_string()));
193 assert_eq!(normalized, "a_b_c".to_string());
194 }
195
196 #[test]
197 /// This test constructs a TripleKeyHashAddresser with a 6 character `prefix` and a Some option
198 /// with a value of 14 for the `first_hash_length` and a None option for `second_hash_length.`
199 /// The `second_hash_length` should be equal to the ADDRESS_LENGTH minus the length of the
200 /// prefix and the `first_hash_length`, then divided by two.
201 /// This test ensures this addresser computes a valid radix address from the provided key,
202 /// `('a', 'b', 'c')`. Specifically, this test validates:
203 ///
204 /// 1. The address length matches the ADDRESS_LENGTH const
205 /// 2. The prefix is present in the beginning of the address
206 /// 3. The next characters, the length of which matches the value `first_hash_length` (14)
207 /// used to construct the TripleKeyHashAddresser, match the hash of the first key, 'a', of
208 /// the tuple provided to the `compute` method
209 /// 4. The next characters, the length of which matches the calculated `second_hash_length`,
210 /// match the hash of the second key, 'b', of the tuple provided to the `compute` method
211 /// 5. The remaining characters, the length of which matches the ADDRESS_LENGTH const less the
212 /// length of the provided `prefix`, the `first_hash_length` and `second_hash_length`,
213 /// match the hash of the last key, 'c', of the tuple provided to the `compute` method
214 ///
215 /// This test also ensures that the instantiated TripleKeyHashAddresser can transform the natural
216 /// key into a single string with the individual keys within the tuple of three strings separated
217 /// by an underscore(`_`), using the `normalize` method.
218 fn test_triple_key_custom_first_length() {
219 // Creating a DoubleKeyHashAddresser with a 6 character `prefix,` a Some option for the
220 // `first_hash_length` and a None option for the `second_hash_length`
221 let addresser = TripleKeyHashAddresser::new("prefix".to_string(), Some(14), None)
222 .expect("Unable to construct TripleKeyHashAddresser");
223 // Create the hashes of the individual keys to verify the constructed address
224 let key1 = "a";
225 let key1_hash = hash(14, key1);
226 let key2 = "b";
227 let key2_hash = hash(25, key2);
228 let key3 = "c";
229 let key3_hash = hash(25, key3);
230 // Compute the address
231 let addr = addresser
232 .compute(&(key1.to_string(), key2.to_string(), key3.to_string()))
233 .unwrap();
234 // Verify the `prefix` characters and the length
235 assert_eq!(addr[..6], "prefix".to_string());
236 assert_eq!(addr.len(), ADDRESS_LENGTH);
237 // Verify the remaining characters match the hash of each key created above
238 assert_eq!(addr[6..20], key1_hash[..14]);
239 assert_eq!(addr[20..45], key2_hash[..25]);
240 assert_eq!(addr[45..], key3_hash[..25]);
241 // Verify the `normalize` method generates the correct single string
242 let normalized =
243 addresser.normalize(&(key1.to_string(), key2.to_string(), key3.to_string()));
244 assert_eq!(normalized, "a_b_c".to_string());
245 }
246
247 #[test]
248 /// This test constructs a TripleKeyHashAddresser with a 6 character `prefix` and a None optional
249 /// for the `first_hash_length` and a Some option for `second_hash_length` with a value of 14.
250 /// The `first_hash_length` should be equal to the ADDRESS_LENGTH minus the length of the prefix
251 /// and the `second_hash_length`, then divided by two.
252 /// This test ensures this addresser computes a valid radix address from the provided key,
253 /// `('a', 'b', 'c')`. Specifically, this test validates:
254 ///
255 /// 1. The address length matches the ADDRESS_LENGTH const
256 /// 2. The prefix is present in the beginning of the address
257 /// 3. The next characters, the length of which matches the calculated `first_hash_length`,
258 /// match the hash of the first key, 'a', of the tuple provided to the `compute` method
259 /// 4. The next characters, the length of which matches the `second_hash_length` value (14),
260 /// match the hash of the second key, 'a', of the tuple provided to the `compute` method
261 /// 5. The remaining characters, the length of which matches the ADDRESS_LENGTH const less the
262 /// length of the provided `prefix`, the `first_hash_length` and `second_hash_length`,
263 /// match the hash of the last key, 'c', of the tuple provided to the `compute` method
264 ///
265 /// This test also ensures that the instantiated TripleKeyHashAddresser can transform the natural
266 /// key into a single string with the individual keys within the tuple of three strings separated
267 /// by an underscore(`_`), using the `normalize` method.
268 fn test_triple_key_custom_second_length() {
269 // Creating a DoubleKeyHashAddresser with a 6 character `prefix,` a Some option for the
270 // `second_hash_length` and a None option for the `first_hash_length`
271 let addresser = TripleKeyHashAddresser::new("prefix".to_string(), None, Some(14))
272 .expect("Unable to construct TripleKeyHashAddresser");
273 // Create the hashes of the individual keys to verify the constructed address
274 let key1 = "a";
275 let key1_hash = hash(25, key1);
276 let key2 = "b";
277 let key2_hash = hash(14, key2);
278 let key3 = "c";
279 let key3_hash = hash(25, key3);
280 // Compute the address
281 let addr = addresser
282 .compute(&(key1.to_string(), key2.to_string(), key3.to_string()))
283 .unwrap();
284 // Verify the `prefix` characters and the length
285 assert_eq!(addr[..6], "prefix".to_string());
286 assert_eq!(addr.len(), ADDRESS_LENGTH);
287 // Verify the remaining characters match the hash of each key created above
288 assert_eq!(addr[6..31], key1_hash[..25]);
289 assert_eq!(addr[31..45], key2_hash[..14]);
290 assert_eq!(addr[45..], key3_hash[..25]);
291 // Verify the `normalize` method generates the correct single string
292 let normalized =
293 addresser.normalize(&(key1.to_string(), key2.to_string(), key3.to_string()));
294 assert_eq!(normalized, "a_b_c".to_string());
295 }
296
297 #[test]
298 /// This test constructs a TripleKeyHashAddresser with a 6 character `prefix` and a Some option
299 /// with a value of 10 for `first_hash_length` and a Some option with a value of 10 for
300 /// `second_hash_length.`
301 /// This test ensures this addresser computes a valid radix address from the provided key,
302 /// `('a', 'b', 'c')`. Specifically, this test validates:
303 ///
304 /// 1. The address length matches the ADDRESS_LENGTH const
305 /// 2. The prefix is present in the beginning of the address
306 /// 3. The next characters, the length of which matches the `first_hash_length` value (10),
307 /// match the hash of the first key, 'a', of the tuple provided to the `compute` method
308 /// 4. The next characters, the length of which matches the `second_hash_length` value (10),
309 /// match the hash of the second key, 'a', of the tuple provided to the `compute` method
310 /// 5. The remaining characters, the length of which matches the ADDRESS_LENGTH const less the
311 /// length of the provided `prefix`, the `first_hash_length` and `second_hash_length`,
312 /// match the hash of the last key, 'c', of the tuple provided to the `compute` method
313 ///
314 /// This test also ensures that the instantiated TripleKeyHashAddresser can transform the natural
315 /// key into a single string with the individual keys within the tuple of three strings separated
316 /// by an underscore(`_`), using the `normalize` method.
317 fn test_triple_key_custom_lengths() {
318 // Creating a DoubleKeyHashAddresser with a 6 character `prefix,` and Some options for the
319 // `first_hash_length` and `second_hash_length`
320 let addresser = TripleKeyHashAddresser::new("prefix".to_string(), Some(10), Some(10))
321 .expect("Unable to construct TripleKeyHashAddresser");
322 // Create the hashes of the individual keys to verify the constructed address
323 let key1 = "a";
324 let key1_hash = hash(10, key1);
325 let key2 = "b";
326 let key2_hash = hash(10, key2);
327 let key3 = "c";
328 let key3_hash = hash(44, key3);
329 // Compute the address
330 let addr = addresser
331 .compute(&(key1.to_string(), key2.to_string(), key3.to_string()))
332 .unwrap();
333 // Verify the `prefix` characters and the length
334 assert_eq!(addr[..6], "prefix".to_string());
335 assert_eq!(addr.len(), ADDRESS_LENGTH);
336 // Verify the remaining characters match the hash of each key created above
337 assert_eq!(addr[6..16], key1_hash[..10]);
338 assert_eq!(addr[16..26], key2_hash[..10]);
339 assert_eq!(addr[26..], key3_hash[..44]);
340 // Verify the `normalize` method generates the correct single string
341 let normalized =
342 addresser.normalize(&(key1.to_string(), key2.to_string(), key3.to_string()));
343 assert_eq!(normalized, "a_b_c".to_string());
344 }
345
346 #[test]
347 /// Tests the `calculate_hash_lengths` function to ensure it provides the correct values from
348 /// various inputs. Specifically, this test validates the correct output when provided with a
349 /// `prefix_length` of 6, a Some option with various values as the `first_hash_length`,
350 /// and a None option as the `second_hash_length.` As the `second_hash_length` is None, the
351 /// resulting value should be equal to ADDRESS_LENGTH less the `prefix_length` and
352 /// `first_hash_length`, then divided by 2.
353 ///
354 /// This test validates the correct calculation for the `second_hash_length` and the matching
355 /// value of the Some option for the `first_hash_length`
356 fn test_calculate_hash_custom_first_length() {
357 let (first_length, second_length) = calculate_hash_lengths(6, Some(21), None).unwrap();
358 assert_eq!(first_length, 21);
359 let remaining = ADDRESS_LENGTH - 6 - 21;
360 assert_eq!(second_length, (remaining / 2));
361
362 let (first_length, second_length) = calculate_hash_lengths(6, Some(41), None).unwrap();
363 assert_eq!(first_length, 41);
364 let remaining = ADDRESS_LENGTH - 6 - 41;
365 assert_eq!(second_length, (remaining / 2));
366
367 let (first_length, second_length) = calculate_hash_lengths(6, Some(61), None).unwrap();
368 assert_eq!(first_length, 61);
369 let remaining = ADDRESS_LENGTH - 6 - 61;
370 assert_eq!(second_length, (remaining / 2));
371 }
372
373 #[test]
374 /// Tests the `calculate_hash_lengths` function to ensure it provides the correct values from
375 /// various inputs. Specifically, this test validates the correct output when provided with a
376 /// `prefix_length` of 6, a Some option with various values as the `second_hash_length`,
377 /// and a None option as the `first_hash_length.` As the `first_hash_length` is None, the
378 /// resulting value should be equal to ADDRESS_LENGTH less the `prefix_length` and
379 /// `second_hash_length`, then divided by 2.
380 ///
381 /// This test validates the correct calculation for the `first_hash_length` and the matching
382 /// value of the Some option for the `second_hash_length`
383 fn test_calculate_hash_custom_second_length() {
384 let (first_length, second_length) = calculate_hash_lengths(6, None, Some(21)).unwrap();
385 let remaining = ADDRESS_LENGTH - 6 - 21;
386 assert_eq!(first_length, (remaining / 2));
387 assert_eq!(second_length, 21);
388
389 let (first_length, second_length) = calculate_hash_lengths(6, None, Some(41)).unwrap();
390 let remaining = ADDRESS_LENGTH - 6 - 41;
391 assert_eq!(first_length, (remaining / 2));
392 assert_eq!(second_length, 41);
393
394 let (first_length, second_length) = calculate_hash_lengths(6, None, Some(61)).unwrap();
395 let remaining = ADDRESS_LENGTH - 6 - 61;
396 assert_eq!(first_length, (remaining / 2));
397 assert_eq!(second_length, 61);
398 }
399
400 #[test]
401 /// Tests the `calculate_hash_lengths` function to ensure it provides the correct values from
402 /// various inputs. Specifically, this test validates the correct output when provided with a
403 /// `prefix_length` of 6, and Some options with various values for the `first_hash_length` and
404 /// `second_hash_length.`
405 ///
406 /// This test validates the matching value of the Some option for the `first_hash_length` and
407 /// `second_hash_length`
408 fn test_calculate_hash_custom_lengths() {
409 let (first_length, second_length) = calculate_hash_lengths(6, Some(42), Some(12)).unwrap();
410 assert_eq!(first_length, 42);
411 assert_eq!(second_length, 12);
412
413 let (first_length, second_length) = calculate_hash_lengths(6, Some(12), Some(42)).unwrap();
414 assert_eq!(first_length, 12);
415 assert_eq!(second_length, 42);
416
417 let (first_length, second_length) = calculate_hash_lengths(6, Some(20), Some(20)).unwrap();
418 assert_eq!(first_length, 20);
419 assert_eq!(second_length, 20);
420 }
421
422 #[test]
423 /// Tests the `calculate_hash_lengths` function to ensure it provides the correct values from
424 /// various inputs. Specifically, this test validates the correct output when provided with
425 /// various values for the `prefix_length`, and a None option for the `first_hash_length` and
426 /// `second_hash_length.` As both the provided hash lengths are None, they must be calculated.
427 /// The resulting values should both be equal to ADDRESS_LENGTH less the `prefix_length`, then
428 /// divided by 3.
429 ///
430 /// This test validates the correct calculation for the `first_hash_length` and `second_hash_length`
431 fn test_calculate_hash_no_custom_lengths() {
432 let (first_length, second_length) = calculate_hash_lengths(6, None, None).unwrap();
433 let remaining = ADDRESS_LENGTH - 6;
434 assert_eq!(first_length, (remaining / 3));
435 assert_eq!(second_length, (remaining / 3));
436
437 let (first_length, second_length) = calculate_hash_lengths(30, None, None).unwrap();
438 let remaining = ADDRESS_LENGTH - 30;
439 assert_eq!(first_length, (remaining / 3));
440 assert_eq!(second_length, (remaining / 3));
441
442 let (first_length, second_length) = calculate_hash_lengths(50, None, None).unwrap();
443 let remaining = ADDRESS_LENGTH - 50;
444 assert_eq!(first_length, (remaining / 3));
445 assert_eq!(second_length, (remaining / 3));
446 }
447
448 #[test]
449 #[should_panic]
450 /// This test constructs a TripleKeyHashAddresser with a 6 character `prefix` and an optional
451 /// value of the ADDRESS_LENGTH for the `first_hash_length` and None for the `second_hash_length.`
452 /// This test ensures that an error will be returned as the length of the prefix and the custom
453 /// length combined are greater than the const ADDRESS_LENGTH, currently set to 70.
454 ///
455 /// This test will attempt to construct a TripleKeyHashAddresser with an invalid custom hash
456 /// length and should return an error. Also validates the expected error message.
457 fn test_invalid_first_custom_length_construction() {
458 // Creating a TripleKeyHashAddresser with a 6 character `prefix` and the `first_hash_length`
459 // equal to the ADDRESS_LENGTH const which will return an error as the prefix length and
460 // custom length combined are greater than the ADDRESS_LENGTH.
461 let addresser =
462 TripleKeyHashAddresser::new("prefix".to_string(), Some(ADDRESS_LENGTH), None);
463
464 // Assert the Addresser constructor returned an error.
465 assert!(addresser.is_err());
466 // Unwrap to validate that this will panic.
467 addresser.unwrap();
468 }
469
470 #[test]
471 #[should_panic]
472 /// This test constructs a TripleKeyHashAddresser with a 6 character `prefix` and an optional
473 /// value of the ADDRESS_LENGTH for the `second_hash_length` and None for the `first_hash_length.`
474 /// This test ensures that an error will be returned as the length of the prefix and the custom
475 /// length combined are greater than the const ADDRESS_LENGTH, currently set to 70.
476 ///
477 /// This test will attempt to construct a TripleKeyHashAddresser with an invalid custom hash
478 /// length and should return an error.
479 fn test_invalid_second_custom_length_construction() {
480 // Creating a TripleKeyHashAddresser with a 6 character `prefix` and the `second_hash_length`
481 // equal to the ADDRESS_LENGTH const which will return an error as the prefix length and
482 // custom length combined are greater than the ADDRESS_LENGTH.
483 let addresser =
484 TripleKeyHashAddresser::new("prefix".to_string(), None, Some(ADDRESS_LENGTH));
485
486 // Assert the Addresser constructor returned an error.
487 assert!(addresser.is_err());
488 // Unwrap to validate that this will panic.
489 addresser.unwrap();
490 }
491
492 #[test]
493 #[should_panic]
494 /// This test constructs a TripleKeyHashAddresser with a 6 character `prefix` and an optional
495 /// value of half the ADDRESS_LENGTH const for both `second_hash_length` and `first_hash_length.`
496 /// This test ensures that an error will be returned as the length of the prefix and the custom
497 /// lengths combined are greater than the const ADDRESS_LENGTH, currently set to 70.
498 ///
499 /// This test will attempt to construct a TripleKeyHashAddresser with invalid custom hash
500 /// lengths and should return an error.
501 fn test_invalid_custom_lengths_construction() {
502 // Creating a TripleKeyHashAddresser with a 6 character `prefix` and value of half the
503 // ADDRESS_LENGTH const for the `first_hash_length` and `second_hash_length` which will
504 // return an error as the prefixlength and custom lengths combined are greater than the
505 // ADDRESS_LENGTH.
506 let addresser = TripleKeyHashAddresser::new(
507 "prefix".to_string(),
508 Some(ADDRESS_LENGTH / 2),
509 Some(ADDRESS_LENGTH / 2),
510 );
511
512 // Assert the Addresser constructor returned an error.
513 assert!(addresser.is_err());
514 // Unwrap to validate that this will panic.
515 addresser.unwrap();
516 }
517
518 #[test]
519 #[should_panic]
520 /// This test constructs a TripleKeyHashAddresser with a 72 character `prefix` and a None
521 /// value for both `second_hash_length` and `first_hash_length.` This test ensures that an error
522 /// will be returned as the length of the prefix and the custom lengths combined are greater
523 /// than the const ADDRESS_LENGTH, currently set to 70.
524 ///
525 /// This test will attempt to construct a TripleKeyHashAddresser with invalid prefix
526 /// length and should return an error.
527 fn test_invalid_prefix_length_construction() {
528 // Creating a TripleKeyHashAddresser with a 72 character `prefix` and value of None for the
529 // `first_hash_length` and `second_hash_length` which will return an error as the prefix
530 // length is greater than the ADDRESS_LENGTH const.
531 let addresser = TripleKeyHashAddresser::new(
532 "prefixprefixprefixprefixprefixprefixprefixprefixprefixprefixprefixprefix".to_string(),
533 None,
534 None,
535 );
536
537 // Assert the Addresser constructor returned an error.
538 assert!(addresser.is_err());
539 // Unwrap to validate that this will panic.
540 addresser.unwrap();
541 }
542}