-
Notifications
You must be signed in to change notification settings - Fork 95
Expand file tree
/
Copy pathmod.rs
More file actions
147 lines (126 loc) · 4.19 KB
/
Copy pathmod.rs
File metadata and controls
147 lines (126 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
pub mod message;
use bounded_collections::BoundedVec;
use bounded_collections::ConstU32;
use codec::{Decode, Encode};
use derive_more::Constructor;
use primitive_types::H256;
use scale_info::TypeInfo;
use sp_std::vec::Vec;
#[cfg(feature = "runtime")]
use binary_merkle_tree::MerkleProof;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
/// Max data supported on bridge (Ethereum calldata limits)
pub const BOUNDED_DATA_MAX_LENGTH: u32 = 102_400;
/// Maximum size of data allowed in the bridge
pub type BoundedData = BoundedVec<u8, ConstU32<BOUNDED_DATA_MAX_LENGTH>>;
pub use message::{AddressedMessage, Message, MessageType};
/// Unique Tx identifier based on its block number and index.
pub fn tx_uid(block: u32, tx_index: u32) -> u64 {
let mut buf = [0u8; 8];
buf[..4].copy_from_slice(&block.to_be_bytes());
buf[4..].copy_from_slice(&tx_index.to_be_bytes());
u64::from_be_bytes(buf)
}
/// Deconstructs the Unique Tx identifier into its block number and index.
pub fn tx_uid_deconstruct(uid: u64) -> (u32, u32) {
const SLICE_ERR: &str = "Valid slice .qed";
let id: [u8; 8] = uid.to_be_bytes();
let block = u32::from_be_bytes(id[..4].try_into().expect(SLICE_ERR));
let tx_index = u32::from_be_bytes(id[4..].try_into().expect(SLICE_ERR));
(block, tx_index)
}
#[derive(Clone, Debug, Encode, Decode, Constructor, TypeInfo)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct ProofResponse {
pub data_proof: DataProof,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub message: Option<AddressedMessage>,
}
#[derive(Debug, PartialEq, Eq)]
pub enum SubTrie {
DataSubmit,
Bridge,
}
#[derive(Debug, Clone, Copy, Encode, Decode, PartialEq, Eq, Default, TypeInfo)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct TxDataRoots {
/// Global Merkle root
pub data_root: H256,
/// Merkle root hash of submitted data
pub blob_root: H256,
/// Merkle root of bridged data
pub bridge_root: H256,
}
impl TxDataRoots {
pub fn new(submitted: H256, bridged: H256) -> Self {
use crate::from_substrate::keccak_256;
// keccak_256(submitted, bridged)
let sub_roots = [submitted.to_fixed_bytes(), bridged.to_fixed_bytes()].concat();
let root = keccak_256(sub_roots.as_slice()).into();
Self {
data_root: root,
blob_root: submitted,
bridge_root: bridged,
}
}
}
/// Wrapper of `binary-merkle-tree::MerkleProof` with codec support.
#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode, Default, TypeInfo)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct DataProof {
pub roots: TxDataRoots,
/// Proof items (does not contain the leaf hash, nor the root obviously).
///
/// This vec contains all inner node hashes necessary to reconstruct the root hash given the
/// leaf hash.
pub proof: Vec<H256>,
/// Number of leaves in the original tree.
///
/// This is needed to detect a case where we have an odd number of leaves that "get promoted"
/// to upper layers.
#[codec(compact)]
pub number_of_leaves: u32,
/// Index of the leaf the proof is for (0-based).
#[codec(compact)]
pub leaf_index: u32,
/// Leaf content.
pub leaf: H256,
}
#[cfg(feature = "runtime")]
impl DataProof {
pub fn new(sub_trie: SubTrie, roots: TxDataRoots, m_proof: MerkleProof<H256, Vec<u8>>) -> Self {
use crate::from_substrate::keccak_256;
let leaf = match sub_trie {
SubTrie::DataSubmit => H256::from_slice(m_proof.leaf.as_slice()),
SubTrie::Bridge => keccak_256(m_proof.leaf.as_slice()).into(),
};
Self {
roots,
leaf,
proof: m_proof.proof,
number_of_leaves: m_proof.number_of_leaves as u32,
leaf_index: m_proof.leaf_index as u32,
}
}
pub fn as_sub_merkle_proof(
&self,
sub_trie: SubTrie,
leaf: Vec<u8>,
) -> MerkleProof<H256, Vec<u8>> {
let root = match sub_trie {
SubTrie::DataSubmit => self.roots.blob_root,
SubTrie::Bridge => self.roots.bridge_root,
};
MerkleProof {
root,
proof: self.proof.clone(),
leaf,
number_of_leaves: self.number_of_leaves,
leaf_index: self.leaf_index,
}
}
}