1
// This file is part of Substrate.
2

            
3
// Copyright (C) Parity Technologies (UK) Ltd.
4
// SPDX-License-Identifier: Apache-2.0
5

            
6
// Licensed under the Apache License, Version 2.0 (the "License");
7
// you may not use this file except in compliance with the License.
8
// You may obtain a copy of the License at
9
//
10
// 	http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software
13
// distributed under the License is distributed on an "AS IS" BASIS,
14
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
// See the License for the specific language governing permissions and
16
// limitations under the License.
17

            
18
#![cfg_attr(not(feature = "std"), no_std)]
19
#![warn(missing_docs)]
20

            
21
//! This crate implements a simple binary Merkle Tree utilities required for inter-op with Ethereum
22
//! bridge & Solidity contract.
23
//!
24
//! The implementation is optimised for usage within Substrate Runtime and supports no-std
25
//! compilation targets.
26
//!
27
//! Merkle Tree is constructed from arbitrary-length leaves, that are initially hashed using the
28
//! same hasher as the inner nodes.
29
//! Inner nodes are created by concatenating child hashes and hashing again. The implementation
30
//! does not perform any sorting of the input data (leaves) nor when inner nodes are created.
31
//!
32
//! If the number of leaves is not even, last leaf (hash of) is promoted to the upper layer.
33
#[cfg(not(feature = "std"))]
34
extern crate alloc;
35
#[cfg(not(feature = "std"))]
36
use alloc::vec;
37
#[cfg(not(feature = "std"))]
38
use alloc::vec::Vec;
39

            
40
use hash_db::Hasher;
41

            
42
/// Construct a root hash of a Binary Merkle Tree created from given leaves.
43
///
44
/// See crate-level docs for details about Merkle Tree construction.
45
///
46
/// In case an empty list of leaves is passed the function returns a 0-filled hash.
47
194769
pub fn merkle_root<H, I>(leaves: I) -> H::Out
48
194769
where
49
194769
	H: Hasher,
50
194769
	H::Out: Default + AsRef<[u8]>,
51
194769
	I: IntoIterator,
52
194769
	I::Item: AsRef<[u8]>,
53
194769
{
54
194769
	let iter = leaves.into_iter().map(|l| <H as Hasher>::hash(l.as_ref()));
55
194769
	merkelize::<H, _, _>(iter, &mut ()).into()
56
194769
}
57

            
58
194769
fn merkelize<H, V, I>(leaves: I, visitor: &mut V) -> H::Out
59
194769
where
60
194769
	H: Hasher,
61
194769
	H::Out: Default + AsRef<[u8]>,
62
194769
	V: Visitor<H::Out>,
63
194769
	I: Iterator<Item = H::Out>,
64
194769
{
65
194769
	let upper = Vec::with_capacity((leaves.size_hint().1.unwrap_or(0).saturating_add(1)) / 2);
66
194769
	let mut next = match merkelize_row::<H, _, _>(leaves, upper, visitor) {
67
		Ok(root) => return root,
68
194769
		Err(next) if next.is_empty() => return H::Out::default(),
69
6
		Err(next) => next,
70
6
	};
71
6

            
72
6
	let mut upper = Vec::with_capacity((next.len().saturating_add(1)) / 2);
73
	loop {
74
12
		visitor.move_up();
75
12

            
76
12
		match merkelize_row::<H, _, _>(next.drain(..), upper, visitor) {
77
6
			Ok(root) => return root,
78
6
			Err(t) => {
79
6
				// swap collections to avoid allocations
80
6
				upper = next;
81
6
				next = t;
82
6
			},
83
		};
84
	}
85
194769
}
86

            
87
/// A generated merkle proof.
88
///
89
/// The structure contains all necessary data to later on verify the proof and the leaf itself.
90
#[derive(Debug, PartialEq, Eq)]
91
pub struct MerkleProof<H, L> {
92
	/// Root hash of generated merkle tree.
93
	pub root: H,
94
	/// Proof items (does not contain the leaf hash, nor the root obviously).
95
	///
96
	/// This vec contains all inner node hashes necessary to reconstruct the root hash given the
97
	/// leaf hash.
98
	pub proof: Vec<H>,
99
	/// Number of leaves in the original tree.
100
	///
101
	/// This is needed to detect a case where we have an odd number of leaves that "get promoted"
102
	/// to upper layers.
103
	pub number_of_leaves: usize,
104
	/// Index of the leaf the proof is for (0-based).
105
	pub leaf_index: usize,
106
	/// Leaf content.
107
	pub leaf: L,
108
}
109

            
110
/// A trait of object inspecting merkle root creation.
111
///
112
/// It can be passed to [`merkelize_row`] or [`merkelize`] functions and will be notified
113
/// about tree traversal.
114
trait Visitor<T> {
115
	/// We are moving one level up in the tree.
116
	fn move_up(&mut self);
117

            
118
	/// We are creating an inner node from given `left` and `right` nodes.
119
	///
120
	/// Note that in case of last odd node in the row `right` might be empty.
121
	/// The method will also visit the `root` hash (level 0).
122
	///
123
	/// The `index` is an index of `left` item.
124
	fn visit(&mut self, index: usize, left: &Option<T>, right: &Option<T>);
125
}
126

            
127
/// No-op implementation of the visitor.
128
impl<T> Visitor<T> for () {
129
12
	fn move_up(&mut self) {}
130
194799
	fn visit(&mut self, _index: usize, _left: &Option<T>, _right: &Option<T>) {}
131
}
132

            
133
/// Construct a Merkle Proof for leaves given by indices.
134
///
135
/// The function constructs a (partial) Merkle Tree first and stores all elements required
136
/// to prove requested item (leaf) given the root hash.
137
///
138
/// Both the Proof and the Root Hash is returned.
139
///
140
/// # Panic
141
///
142
/// The function will panic if given `leaf_index` is greater than the number of leaves.
143
pub fn merkle_proof<H, I, T>(leaves: I, leaf_index: usize) -> MerkleProof<H::Out, T>
144
where
145
	H: Hasher,
146
	H::Out: Default + Copy + AsRef<[u8]>,
147
	I: IntoIterator<Item = T>,
148
	I::IntoIter: ExactSizeIterator,
149
	T: AsRef<[u8]>,
150
{
151
	let mut leaf = None;
152
	let iter = leaves.into_iter().enumerate().map(|(idx, l)| {
153
		let hash = <H as Hasher>::hash(l.as_ref());
154
		if idx == leaf_index {
155
			leaf = Some(l);
156
		}
157
		hash
158
	});
159

            
160
	/// The struct collects a proof for single leaf.
161
	struct ProofCollection<T> {
162
		proof: Vec<T>,
163
		position: usize,
164
	}
165

            
166
	impl<T> ProofCollection<T> {
167
		fn new(position: usize) -> Self {
168
			ProofCollection { proof: Default::default(), position }
169
		}
170
	}
171

            
172
	impl<T: Copy> Visitor<T> for ProofCollection<T> {
173
		fn move_up(&mut self) {
174
			self.position /= 2;
175
		}
176

            
177
		fn visit(&mut self, index: usize, left: &Option<T>, right: &Option<T>) {
178
			// we are at left branch - right goes to the proof.
179
			if self.position == index {
180
				if let Some(right) = right {
181
					self.proof.push(*right);
182
				}
183
			}
184
			// we are at right branch - left goes to the proof.
185
			if self.position == index + 1 {
186
				if let Some(left) = left {
187
					self.proof.push(*left);
188
				}
189
			}
190
		}
191
	}
192

            
193
	let number_of_leaves = iter.len();
194
	let mut collect_proof = ProofCollection::new(leaf_index);
195

            
196
	let root = merkelize::<H, _, _>(iter, &mut collect_proof);
197
	let leaf = leaf.expect("Requested `leaf_index` is greater than number of leaves.");
198

            
199
	#[cfg(feature = "debug")]
200
	log::debug!(
201
		"[merkle_proof] Proof: {:?}",
202
		collect_proof
203
			.proof
204
			.iter()
205
			.map(|s| array_bytes::bytes2hex("", s))
206
			.collect::<Vec<_>>()
207
	);
208

            
209
	MerkleProof { root, proof: collect_proof.proof, number_of_leaves, leaf_index, leaf }
210
}
211

            
212
/// Leaf node for proof verification.
213
///
214
/// Can be either a value that needs to be hashed first,
215
/// or the hash itself.
216
#[derive(Debug, PartialEq, Eq)]
217
pub enum Leaf<'a, H> {
218
	/// Leaf content.
219
	Value(&'a [u8]),
220
	/// Hash of the leaf content.
221
	Hash(H),
222
}
223

            
224
impl<'a, H, T: AsRef<[u8]>> From<&'a T> for Leaf<'a, H> {
225
	fn from(v: &'a T) -> Self {
226
		Leaf::Value(v.as_ref())
227
	}
228
}
229

            
230
/// Verify Merkle Proof correctness versus given root hash.
231
///
232
/// The proof is NOT expected to contain leaf hash as the first
233
/// element, but only all adjacent nodes required to eventually by process of
234
/// concatenating and hashing end up with given root hash.
235
///
236
/// The proof must not contain the root hash.
237
pub fn verify_proof<'a, H, P, L>(
238
	root: &'a H::Out,
239
	proof: P,
240
	number_of_leaves: usize,
241
	leaf_index: usize,
242
	leaf: L,
243
) -> bool
244
where
245
	H: Hasher,
246
	H::Out: PartialEq + AsRef<[u8]>,
247
	P: IntoIterator<Item = H::Out>,
248
	L: Into<Leaf<'a, H::Out>>,
249
{
250
	if leaf_index >= number_of_leaves {
251
		return false
252
	}
253

            
254
	let leaf_hash = match leaf.into() {
255
		Leaf::Value(content) => <H as Hasher>::hash(content),
256
		Leaf::Hash(hash) => hash,
257
	};
258

            
259
	let hash_len = <H as Hasher>::LENGTH;
260
	let mut combined = vec![0_u8; hash_len * 2];
261
	let mut position = leaf_index;
262
	let mut width = number_of_leaves;
263
	let computed = proof.into_iter().fold(leaf_hash, |a, b| {
264
		if position % 2 == 1 || position + 1 == width {
265
			combined[..hash_len].copy_from_slice(&b.as_ref());
266
			combined[hash_len..].copy_from_slice(&a.as_ref());
267
		} else {
268
			combined[..hash_len].copy_from_slice(&a.as_ref());
269
			combined[hash_len..].copy_from_slice(&b.as_ref());
270
		}
271
		let hash = <H as Hasher>::hash(&combined);
272
		#[cfg(feature = "debug")]
273
		log::debug!(
274
			"[verify_proof]: (a, b) {:?}, {:?} => {:?} ({:?}) hash",
275
			array_bytes::bytes2hex("", a),
276
			array_bytes::bytes2hex("", b),
277
			array_bytes::bytes2hex("", hash),
278
			array_bytes::bytes2hex("", &combined)
279
		);
280
		position /= 2;
281
		width = ((width - 1) / 2) + 1;
282
		hash
283
	});
284

            
285
	root == &computed
286
}
287

            
288
/// Processes a single row (layer) of a tree by taking pairs of elements,
289
/// concatenating them, hashing and placing into resulting vector.
290
///
291
/// In case only one element is provided it is returned via `Ok` result, in any other case (also an
292
/// empty iterator) an `Err` with the inner nodes of upper layer is returned.
293
194781
fn merkelize_row<H, V, I>(
294
194781
	mut iter: I,
295
194781
	mut next: Vec<H::Out>,
296
194781
	visitor: &mut V,
297
194781
) -> Result<H::Out, Vec<H::Out>>
298
194781
where
299
194781
	H: Hasher,
300
194781
	H::Out: AsRef<[u8]>,
301
194781
	V: Visitor<H::Out>,
302
194781
	I: Iterator<Item = H::Out>,
303
194781
{
304
194781
	#[cfg(feature = "debug")]
305
194781
	log::debug!("[merkelize_row]");
306
194781
	next.clear();
307
194781

            
308
194781
	let hash_len = <H as Hasher>::LENGTH;
309
194781
	let mut index = 0;
310
194781
	let mut combined = vec![0_u8; hash_len * 2];
311
	loop {
312
194799
		let a = iter.next();
313
194799
		let b = iter.next();
314
194799
		visitor.visit(index, &a, &b);
315
194799

            
316
194799
		#[cfg(feature = "debug")]
317
194799
		log::debug!(
318
194799
			"  {:?}\n  {:?}",
319
194799
			a.as_ref().map(|s| array_bytes::bytes2hex("", s)),
320
194799
			b.as_ref().map(|s| array_bytes::bytes2hex("", s))
321
194799
		);
322
194799

            
323
194799
		index += 2;
324
194799
		match (a, b) {
325
18
			(Some(a), Some(b)) => {
326
18
				combined[..hash_len].copy_from_slice(a.as_ref());
327
18
				combined[hash_len..].copy_from_slice(b.as_ref());
328
18

            
329
18
				next.push(<H as Hasher>::hash(&combined));
330
18
			},
331
			// Odd number of items. Promote the item to the upper layer.
332
6
			(Some(a), None) if !next.is_empty() => {
333
				next.push(a);
334
			},
335
			// Last item = root.
336
6
			(Some(a), None) => return Ok(a),
337
			// Finish up, no more items.
338
			_ => {
339
				#[cfg(feature = "debug")]
340
				log::debug!(
341
					"[merkelize_row] Next: {:?}",
342
					next.iter().map(|s| array_bytes::bytes2hex("", s)).collect::<Vec<_>>()
343
				);
344
194775
				return Err(next)
345
			},
346
		}
347
	}
348
194781
}
349

            
350
#[cfg(test)]
351
mod tests {
352
	use super::*;
353
	use sp_core::H256;
354
	use sp_runtime::traits::Keccak256;
355

            
356
	#[test]
357
	fn should_generate_empty_root() {
358
		// given
359
		let _ = env_logger::try_init();
360
		let data: Vec<[u8; 1]> = Default::default();
361

            
362
		// when
363
		let out = merkle_root::<Keccak256, _>(data);
364

            
365
		// then
366
		assert_eq!(
367
			array_bytes::bytes2hex("", out),
368
			"0000000000000000000000000000000000000000000000000000000000000000"
369
		);
370
	}
371

            
372
	#[test]
373
	fn should_generate_single_root() {
374
		// given
375
		let _ = env_logger::try_init();
376
		let data = vec![array_bytes::hex2array_unchecked::<_, 20>(
377
			"E04CC55ebEE1cBCE552f250e85c57B70B2E2625b",
378
		)];
379

            
380
		// when
381
		let out = merkle_root::<Keccak256, _>(data);
382

            
383
		// then
384
		assert_eq!(
385
			array_bytes::bytes2hex("", out),
386
			"aeb47a269393297f4b0a3c9c9cfd00c7a4195255274cf39d83dabc2fcc9ff3d7"
387
		);
388
	}
389

            
390
	#[test]
391
	fn should_generate_root_pow_2() {
392
		// given
393
		let _ = env_logger::try_init();
394
		let data = vec![
395
			array_bytes::hex2array_unchecked::<_, 20>("E04CC55ebEE1cBCE552f250e85c57B70B2E2625b"),
396
			array_bytes::hex2array_unchecked::<_, 20>("25451A4de12dcCc2D166922fA938E900fCc4ED24"),
397
		];
398

            
399
		// when
400
		let out = merkle_root::<Keccak256, _>(data);
401

            
402
		// then
403
		assert_eq!(
404
			array_bytes::bytes2hex("", out),
405
			"697ea2a8fe5b03468548a7a413424a6292ab44a82a6f5cc594c3fa7dda7ce402"
406
		);
407
	}
408

            
409
	#[test]
410
	fn should_generate_root_complex() {
411
		let _ = env_logger::try_init();
412
		let test = |root, data| {
413
			assert_eq!(array_bytes::bytes2hex("", &merkle_root::<Keccak256, _>(data)), root);
414
		};
415

            
416
		test(
417
			"aff1208e69c9e8be9b584b07ebac4e48a1ee9d15ce3afe20b77a4d29e4175aa3",
418
			vec!["a", "b", "c"],
419
		);
420

            
421
		test(
422
			"b8912f7269068901f231a965adfefbc10f0eedcfa61852b103efd54dac7db3d7",
423
			vec!["a", "b", "a"],
424
		);
425

            
426
		test(
427
			"dc8e73fe6903148ff5079baecc043983625c23b39f31537e322cd0deee09fa9c",
428
			vec!["a", "b", "a", "b"],
429
		);
430

            
431
		test(
432
			"fb3b3be94be9e983ba5e094c9c51a7d96a4fa2e5d8e891df00ca89ba05bb1239",
433
			vec!["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"],
434
		);
435
	}
436

            
437
	#[test]
438
	fn should_generate_and_verify_proof_simple() {
439
		// given
440
		let _ = env_logger::try_init();
441
		let data = vec!["a", "b", "c"];
442

            
443
		// when
444
		let proof0 = merkle_proof::<Keccak256, _, _>(data.clone(), 0);
445
		assert!(verify_proof::<Keccak256, _, _>(
446
			&proof0.root,
447
			proof0.proof.clone(),
448
			data.len(),
449
			proof0.leaf_index,
450
			&proof0.leaf,
451
		));
452

            
453
		let proof1 = merkle_proof::<Keccak256, _, _>(data.clone(), 1);
454
		assert!(verify_proof::<Keccak256, _, _>(
455
			&proof1.root,
456
			proof1.proof,
457
			data.len(),
458
			proof1.leaf_index,
459
			&proof1.leaf,
460
		));
461

            
462
		let proof2 = merkle_proof::<Keccak256, _, _>(data.clone(), 2);
463
		assert!(verify_proof::<Keccak256, _, _>(
464
			&proof2.root,
465
			proof2.proof,
466
			data.len(),
467
			proof2.leaf_index,
468
			&proof2.leaf
469
		));
470

            
471
		// then
472
		assert_eq!(
473
			array_bytes::bytes2hex("", &proof0.root),
474
			array_bytes::bytes2hex("", &proof1.root)
475
		);
476
		assert_eq!(
477
			array_bytes::bytes2hex("", &proof2.root),
478
			array_bytes::bytes2hex("", &proof1.root)
479
		);
480

            
481
		assert!(!verify_proof::<Keccak256, _, _>(
482
			&array_bytes::hex2array_unchecked(
483
				"fb3b3be94be9e983ba5e094c9c51a7d96a4fa2e5d8e891df00ca89ba05bb1239"
484
			)
485
			.into(),
486
			proof0.proof,
487
			data.len(),
488
			proof0.leaf_index,
489
			&proof0.leaf
490
		));
491

            
492
		assert!(!verify_proof::<Keccak256, _, _>(
493
			&proof0.root.into(),
494
			vec![],
495
			data.len(),
496
			proof0.leaf_index,
497
			&proof0.leaf
498
		));
499
	}
500

            
501
	#[test]
502
	fn should_generate_and_verify_proof_complex() {
503
		// given
504
		let _ = env_logger::try_init();
505
		let data = vec!["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
506

            
507
		for l in 0..data.len() {
508
			// when
509
			let proof = merkle_proof::<Keccak256, _, _>(data.clone(), l);
510
			// then
511
			assert!(verify_proof::<Keccak256, _, _>(
512
				&proof.root,
513
				proof.proof,
514
				data.len(),
515
				proof.leaf_index,
516
				&proof.leaf
517
			));
518
		}
519
	}
520

            
521
	#[test]
522
	fn should_generate_and_verify_proof_large() {
523
		// given
524
		let _ = env_logger::try_init();
525
		let mut data = vec![];
526
		for i in 1..16 {
527
			for c in 'a'..'z' {
528
				if c as usize % i != 0 {
529
					data.push(c.to_string());
530
				}
531
			}
532

            
533
			for l in 0..data.len() {
534
				// when
535
				let proof = merkle_proof::<Keccak256, _, _>(data.clone(), l);
536
				// then
537
				assert!(verify_proof::<Keccak256, _, _>(
538
					&proof.root,
539
					proof.proof,
540
					data.len(),
541
					proof.leaf_index,
542
					&proof.leaf
543
				));
544
			}
545
		}
546
	}
547

            
548
	#[test]
549
	fn should_generate_and_verify_proof_large_tree() {
550
		// given
551
		let _ = env_logger::try_init();
552
		let mut data = vec![];
553
		for i in 0..6000 {
554
			data.push(format!("{}", i));
555
		}
556

            
557
		for l in (0..data.len()).step_by(13) {
558
			// when
559
			let proof = merkle_proof::<Keccak256, _, _>(data.clone(), l);
560
			// then
561
			assert!(verify_proof::<Keccak256, _, _>(
562
				&proof.root,
563
				proof.proof,
564
				data.len(),
565
				proof.leaf_index,
566
				&proof.leaf
567
			));
568
		}
569
	}
570

            
571
	#[test]
572
	#[should_panic]
573
	fn should_panic_on_invalid_leaf_index() {
574
		let _ = env_logger::try_init();
575
		merkle_proof::<Keccak256, _, _>(vec!["a"], 5);
576
	}
577

            
578
	#[test]
579
	fn should_generate_and_verify_proof_on_test_data() {
580
		let addresses = vec![
581
			"0x9aF1Ca5941148eB6A3e9b9C741b69738292C533f",
582
			"0xDD6ca953fddA25c496165D9040F7F77f75B75002",
583
			"0x60e9C47B64Bc1C7C906E891255EaEC19123E7F42",
584
			"0xfa4859480Aa6D899858DE54334d2911E01C070df",
585
			"0x19B9b128470584F7209eEf65B69F3624549Abe6d",
586
			"0xC436aC1f261802C4494504A11fc2926C726cB83b",
587
			"0xc304C8C2c12522F78aD1E28dD86b9947D7744bd0",
588
			"0xDa0C2Cba6e832E55dE89cF4033affc90CC147352",
589
			"0xf850Fd22c96e3501Aad4CDCBf38E4AEC95622411",
590
			"0x684918D4387CEb5E7eda969042f036E226E50642",
591
			"0x963F0A1bFbb6813C0AC88FcDe6ceB96EA634A595",
592
			"0x39B38ad74b8bCc5CE564f7a27Ac19037A95B6099",
593
			"0xC2Dec7Fdd1fef3ee95aD88EC8F3Cd5bd4065f3C7",
594
			"0x9E311f05c2b6A43C2CCF16fB2209491BaBc2ec01",
595
			"0x927607C30eCE4Ef274e250d0bf414d4a210b16f0",
596
			"0x98882bcf85E1E2DFF780D0eB360678C1cf443266",
597
			"0xFBb50191cd0662049E7C4EE32830a4Cc9B353047",
598
			"0x963854fc2C358c48C3F9F0A598B9572c581B8DEF",
599
			"0xF9D7Bc222cF6e3e07bF66711e6f409E51aB75292",
600
			"0xF2E3fd32D063F8bBAcB9e6Ea8101C2edd899AFe6",
601
			"0x407a5b9047B76E8668570120A96d580589fd1325",
602
			"0xEAD9726FAFB900A07dAd24a43AE941d2eFDD6E97",
603
			"0x42f5C8D9384034A9030313B51125C32a526b6ee8",
604
			"0x158fD2529Bc4116570Eb7C80CC76FEf33ad5eD95",
605
			"0x0A436EE2E4dEF3383Cf4546d4278326Ccc82514E",
606
			"0x34229A215db8FeaC93Caf8B5B255e3c6eA51d855",
607
			"0xEb3B7CF8B1840242CB98A732BA464a17D00b5dDF",
608
			"0x2079692bf9ab2d6dc7D79BBDdEE71611E9aA3B72",
609
			"0x46e2A67e5d450e2Cf7317779f8274a2a630f3C9B",
610
			"0xA7Ece4A5390DAB18D08201aE18800375caD78aab",
611
			"0x15E1c0D24D62057Bf082Cb2253dA11Ef0d469570",
612
			"0xADDEF4C9b5687Eb1F7E55F2251916200A3598878",
613
			"0xe0B16Fb96F936035db2b5A68EB37D470fED2f013",
614
			"0x0c9A84993feaa779ae21E39F9793d09e6b69B62D",
615
			"0x3bc4D5148906F70F0A7D1e2756572655fd8b7B34",
616
			"0xFf4675C26903D5319795cbd3a44b109E7DDD9fDe",
617
			"0xCec4450569A8945C6D2Aba0045e4339030128a92",
618
			"0x85f0584B10950E421A32F471635b424063FD8405",
619
			"0xb38bEe7Bdc0bC43c096e206EFdFEad63869929E3",
620
			"0xc9609466274Fef19D0e58E1Ee3b321D5C141067E",
621
			"0xa08EA868cF75268E7401021E9f945BAe73872ecc",
622
			"0x67C9Cb1A29E964Fe87Ff669735cf7eb87f6868fE",
623
			"0x1B6BEF636aFcdd6085cD4455BbcC93796A12F6E2",
624
			"0x46B37b243E09540b55cF91C333188e7D5FD786dD",
625
			"0x8E719E272f62Fa97da93CF9C941F5e53AA09e44a",
626
			"0xa511B7E7DB9cb24AD5c89fBb6032C7a9c2EfA0a5",
627
			"0x4D11FDcAeD335d839132AD450B02af974A3A66f8",
628
			"0xB8cf790a5090E709B4619E1F335317114294E17E",
629
			"0x7f0f57eA064A83210Cafd3a536866ffD2C5eDCB3",
630
			"0xC03C848A4521356EF800e399D889e9c2A25D1f9E",
631
			"0xC6b03DF05cb686D933DD31fCa5A993bF823dc4FE",
632
			"0x58611696b6a8102cf95A32c25612E4cEF32b910F",
633
			"0x2ed4bC7197AEF13560F6771D930Bf907772DE3CE",
634
			"0x3C5E58f334306be029B0e47e119b8977B2639eb4",
635
			"0x288646a1a4FeeC560B349d210263c609aDF649a6",
636
			"0xb4F4981E0d027Dc2B3c86afA0D0fC03d317e83C0",
637
			"0xaAE4A87F8058feDA3971f9DEd639Ec9189aA2500",
638
			"0x355069DA35E598913d8736E5B8340527099960b8",
639
			"0x3cf5A0F274cd243C0A186d9fCBdADad089821B93",
640
			"0xca55155dCc4591538A8A0ca322a56EB0E4aD03C4",
641
			"0xE824D0268366ec5C4F23652b8eD70D552B1F2b8B",
642
			"0x84C3e9B25AE8a9b39FF5E331F9A597F2DCf27Ca9",
643
			"0xcA0018e278751De10d26539915d9c7E7503432FE",
644
			"0xf13077dE6191D6c1509ac7E088b8BE7Fe656c28b",
645
			"0x7a6bcA1ec9Db506e47ac6FD86D001c2aBc59C531",
646
			"0xeA7f9A2A9dd6Ba9bc93ca615C3Ddf26973146911",
647
			"0x8D0d8577e16F8731d4F8712BAbFa97aF4c453458",
648
			"0xB7a7855629dF104246997e9ACa0E6510df75d0ea",
649
			"0x5C1009BDC70b0C8Ab2e5a53931672ab448C17c89",
650
			"0x40B47D1AfefEF5eF41e0789F0285DE7b1C31631C",
651
			"0x5086933d549cEcEB20652CE00973703CF10Da373",
652
			"0xeb364f6FE356882F92ae9314fa96116Cf65F47d8",
653
			"0xdC4D31516A416cEf533C01a92D9a04bbdb85EE67",
654
			"0x9b36E086E5A274332AFd3D8509e12ca5F6af918d",
655
			"0xBC26394fF36e1673aE0608ce91A53B9768aD0D76",
656
			"0x81B5AB400be9e563fA476c100BE898C09966426c",
657
			"0x9d93C8ae5793054D28278A5DE6d4653EC79e90FE",
658
			"0x3B8E75804F71e121008991E3177fc942b6c28F50",
659
			"0xC6Eb5886eB43dD473f5BB4e21e56E08dA464D9B4",
660
			"0xfdf1277b71A73c813cD0e1a94B800f4B1Db66DBE",
661
			"0xc2ff2cCc98971556670e287Ff0CC39DA795231ad",
662
			"0x76b7E1473f0D0A87E9B4a14E2B179266802740f5",
663
			"0xA7Bc965660a6EF4687CCa4F69A97563163A3C2Ef",
664
			"0xB9C2b47888B9F8f7D03dC1de83F3F55E738CebD3",
665
			"0xEd400162E6Dd6bD2271728FFb04176bF770De94a",
666
			"0xE3E8331156700339142189B6E555DCb2c0962750",
667
			"0xbf62e342Bc7706a448EdD52AE871d9C4497A53b1",
668
			"0xb9d7A1A111eed75714a0AcD2dd467E872eE6B03D",
669
			"0x03942919DFD0383b8c574AB8A701d89fd4bfA69D",
670
			"0x0Ef4C92355D3c8c7050DFeb319790EFCcBE6fe9e",
671
			"0xA6895a3cf0C60212a73B3891948ACEcF1753f25E",
672
			"0x0Ed509239DB59ef3503ded3d31013C983d52803A",
673
			"0xc4CE8abD123BfAFc4deFf37c7D11DeCd5c350EE4",
674
			"0x4A4Bf59f7038eDcd8597004f35d7Ee24a7Bdd2d3",
675
			"0x5769E8e8A2656b5ed6b6e6fa2a2bFAeaf970BB87",
676
			"0xf9E15cCE181332F4F57386687c1776b66C377060",
677
			"0xc98f8d4843D56a46C21171900d3eE538Cc74dbb5",
678
			"0x3605965B47544Ce4302b988788B8195601AE4dEd",
679
			"0xe993BDfdcAac2e65018efeE0F69A12678031c71d",
680
			"0x274fDf8801385D3FAc954BCc1446Af45f5a8304c",
681
			"0xBFb3f476fcD6429F4a475bA23cEFdDdd85c6b964",
682
			"0x806cD16588Fe812ae740e931f95A289aFb4a4B50",
683
			"0xa89488CE3bD9C25C3aF797D1bbE6CA689De79d81",
684
			"0xd412f1AfAcf0Ebf3Cd324593A231Fc74CC488B12",
685
			"0xd1f715b2D7951d54bc31210BbD41852D9BF98Ed1",
686
			"0xf65aD707c344171F467b2ADba3d14f312219cE23",
687
			"0x2971a4b242e9566dEF7bcdB7347f5E484E11919B",
688
			"0x12b113D6827E07E7D426649fBd605f427da52314",
689
			"0x1c6CA45171CDb9856A6C9Dba9c5F1216913C1e97",
690
			"0x11cC6ee1d74963Db23294FCE1E3e0A0555779CeA",
691
			"0x8Aa1C721255CDC8F895E4E4c782D86726b068667",
692
			"0xA2cDC1f37510814485129aC6310b22dF04e9Bbf0",
693
			"0xCf531b71d388EB3f5889F1f78E0d77f6fb109767",
694
			"0xBe703e3545B2510979A0cb0C440C0Fba55c6dCB5",
695
			"0x30a35886F989db39c797D8C93880180Fdd71b0c8",
696
			"0x1071370D981F60c47A9Cd27ac0A61873a372cBB2",
697
			"0x3515d74A11e0Cb65F0F46cB70ecf91dD1712daaa",
698
			"0x50500a3c2b7b1229c6884505D00ac6Be29Aecd0C",
699
			"0x9A223c2a11D4FD3585103B21B161a2B771aDA3d1",
700
			"0xd7218df03AD0907e6c08E707B15d9BD14285e657",
701
			"0x76CfD72eF5f93D1a44aD1F80856797fBE060c70a",
702
			"0x44d093cB745944991EFF5cBa151AA6602d6f5420",
703
			"0x626516DfF43bf09A71eb6fd1510E124F96ED0Cde",
704
			"0x6530824632dfe099304E2DC5701cA99E6d031E08",
705
			"0x57e6c423d6a7607160d6379A0c335025A14DaFC0",
706
			"0x3966D4AD461Ef150E0B10163C81E79b9029E69c3",
707
			"0xF608aCfd0C286E23721a3c347b2b65039f6690F1",
708
			"0xbfB8FAac31A25646681936977837f7740fCd0072",
709
			"0xd80aa634a623a7ED1F069a1a3A28a173061705c7",
710
			"0x9122a77B36363e24e12E1E2D73F87b32926D3dF5",
711
			"0x62562f0d1cD31315bCCf176049B6279B2bfc39C2",
712
			"0x48aBF7A2a7119e5675059E27a7082ba7F38498b2",
713
			"0xb4596983AB9A9166b29517acD634415807569e5F",
714
			"0x52519D16E20BC8f5E96Da6d736963e85b2adA118",
715
			"0x7663893C3dC0850EfC5391f5E5887eD723e51B83",
716
			"0x5FF323a29bCC3B5b4B107e177EccEF4272959e61",
717
			"0xee6e499AdDf4364D75c05D50d9344e9daA5A9AdF",
718
			"0x1631b0BD31fF904aD67dD58994C6C2051CDe4E75",
719
			"0xbc208e9723D44B9811C428f6A55722a26204eEF2",
720
			"0xe76103a222Ee2C7Cf05B580858CEe625C4dc00E1",
721
			"0xC71Bb2DBC51760f4fc2D46D84464410760971B8a",
722
			"0xB4C18811e6BFe564D69E12c224FFc57351f7a7ff",
723
			"0xD11DB0F5b41061A887cB7eE9c8711438844C298A",
724
			"0xB931269934A3D4432c084bAAc3d0de8143199F4f",
725
			"0x070037cc85C761946ec43ea2b8A2d5729908A2a1",
726
			"0x2E34aa8C95Ffdbb37f14dCfBcA69291c55Ba48DE",
727
			"0x052D93e8d9220787c31d6D83f87eC7dB088E998f",
728
			"0x498dAC6C69b8b9ad645217050054840f1D91D029",
729
			"0xE4F7D60f9d84301e1fFFd01385a585F3A11F8E89",
730
			"0xEa637992f30eA06460732EDCBaCDa89355c2a107",
731
			"0x4960d8Da07c27CB6Be48a79B96dD70657c57a6bF",
732
			"0x7e471A003C8C9fdc8789Ded9C3dbe371d8aa0329",
733
			"0xd24265Cc10eecb9e8d355CCc0dE4b11C556E74D7",
734
			"0xDE59C8f7557Af779674f41CA2cA855d571018690",
735
			"0x2fA8A6b3b6226d8efC9d8f6EBDc73Ca33DDcA4d8",
736
			"0xe44102664c6c2024673Ff07DFe66E187Db77c65f",
737
			"0x94E3f4f90a5f7CBF2cc2623e66B8583248F01022",
738
			"0x0383EdBbc21D73DEd039E9C1Ff6bf56017b4CC40",
739
			"0x64C3E49898B88d1E0f0d02DA23E0c00A2Cd0cA99",
740
			"0xF4ccfB67b938d82B70bAb20975acFAe402E812E1",
741
			"0x4f9ee5829e9852E32E7BC154D02c91D8E203e074",
742
			"0xb006312eF9713463bB33D22De60444Ba95609f6B",
743
			"0x7Cbe76ef69B52110DDb2e3b441C04dDb11D63248",
744
			"0x70ADEEa65488F439392B869b1Df7241EF317e221",
745
			"0x64C0bf8AA36Ba590477585Bc0D2BDa7970769463",
746
			"0xA4cDc98593CE52d01Fe5Ca47CB3dA5320e0D7592",
747
			"0xc26B34D375533fFc4c5276282Fa5D660F3d8cbcB",
748
		];
749
		let root: H256 = array_bytes::hex2array_unchecked(
750
			"72b0acd7c302a84f1f6b6cefe0ba7194b7398afb440e1b44a9dbbe270394ca53",
751
		)
752
		.into();
753

            
754
		let data = addresses
755
			.into_iter()
756
			.map(|address| array_bytes::hex2bytes_unchecked(&address))
757
			.collect::<Vec<_>>();
758

            
759
		for l in 0..data.len() {
760
			// when
761
			let proof = merkle_proof::<Keccak256, _, _>(data.clone(), l);
762
			assert_eq!(array_bytes::bytes2hex("", &proof.root), array_bytes::bytes2hex("", &root));
763
			assert_eq!(proof.leaf_index, l);
764
			assert_eq!(&proof.leaf, &data[l]);
765

            
766
			// then
767
			assert!(verify_proof::<Keccak256, _, _>(
768
				&proof.root,
769
				proof.proof,
770
				data.len(),
771
				proof.leaf_index,
772
				&proof.leaf
773
			));
774
		}
775

            
776
		let proof = merkle_proof::<Keccak256, _, _>(data.clone(), data.len() - 1);
777

            
778
		assert_eq!(
779
			proof,
780
			MerkleProof {
781
				root,
782
				proof: vec![
783
					array_bytes::hex2array_unchecked(
784
						"340bcb1d49b2d82802ddbcf5b85043edb3427b65d09d7f758fbc76932ad2da2f"
785
					)
786
					.into(),
787
					array_bytes::hex2array_unchecked(
788
						"ba0580e5bd530bc93d61276df7969fb5b4ae8f1864b4a28c280249575198ff1f"
789
					)
790
					.into(),
791
					array_bytes::hex2array_unchecked(
792
						"d02609d2bbdb28aa25f58b85afec937d5a4c85d37925bce6d0cf802f9d76ba79"
793
					)
794
					.into(),
795
					array_bytes::hex2array_unchecked(
796
						"ae3f8991955ed884613b0a5f40295902eea0e0abe5858fc520b72959bc016d4e"
797
					)
798
					.into(),
799
				],
800
				number_of_leaves: data.len(),
801
				leaf_index: data.len() - 1,
802
				leaf: array_bytes::hex2array_unchecked::<_, 20>(
803
					"c26B34D375533fFc4c5276282Fa5D660F3d8cbcB"
804
				)
805
				.to_vec(),
806
			}
807
		);
808
	}
809
}