Skip to content

Commit

Permalink
Move to right-padded values (cf. #12)
Browse files Browse the repository at this point in the history
  • Loading branch information
ax0 committed Feb 14, 2024
1 parent b9e0412 commit fff3b7a
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 188 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ To streamline RLP decoding, two types are provided:
- `StateProof<PROOF_LEN>` is a type alias for `TrieProof<20, PROOF_LEN, MAX_ACCOUNT_STATE_LENGTH>`.

#### Methods
- `fn verify_storage_root(self: TrieProof<32, PROOF_LEN, MAX_VALUE_LEN>, storage_root: [u8; KEY_LENGTH]) -> bool` takes a storage proof (`self`) and storage root (`storage_root`) as inputs and returns `true` if the proof is successfully verified. `PROOF_LEN` is subject to the restrictions explained above and `MAX_VALUE_LEN <= 32` should be large enough to encapsulate the value that the key resolves to in the proof, which is encoded as a big-endian byte array.
- `fn verify_storage_root(self: TrieProof<32, PROOF_LEN, MAX_VALUE_LEN>, storage_root: [u8; KEY_LENGTH]) -> bool` takes a storage proof (`self`) and storage root (`storage_root`) as inputs and returns `true` if the proof is successfully verified. `PROOF_LEN` is subject to the restrictions explained above and `MAX_VALUE_LEN <= 33` should be large enough to encapsulate the RLP-encoded value that the key resolves to in the proof.
- `fn verify_state_root(self: TrieProof<20, PROOF_LEN, MAX_VALUE_LEN>, state_root: [u8; KEY_LENGTH]) -> bool` takes a state proof (`self`) and state root (`state_root`) as inputs and returns `true` if the proof is successfully verified. `PROOF_LEN` is as before, and `MAX_VALUE_LEN <= MAX_ACCOUNT_STATE_LENGTH` should be large enough to encapsulate the value the key resolves to in the proof, which is the RLP-encoded account state associated with the address given by `self.key`.

#### Examples
Expand All @@ -71,11 +71,11 @@ pad xs = concat
depth_padding = replicate (max_depth - length xs) []
```

Moreover, the values that trie proofs terminate in are assumed to be in a byte array left-padded with zeros to the maximum size of the slot they are stored in, i.e. if `max_len` denotes the maximum possible length of a value, then the mapping to be applied is given as follows:
Moreover, the values that trie proofs terminate in are assumed to be in an RLP-encoded byte array right-padded with zeros to the maximum size of the slot they are stored in, i.e. if `max_len` denotes the maximum possible length of a value, then the mapping to be applied is given as follows:

```haskell
left_pad :: [Word8] -> Int -> [Word8]
left_pad xs max_len = (replicate (max_len - length xs) 0) ++ xs
right_pad :: [Word8] -> Int -> [Word8]
right_pad xs max_len = xs ++ (replicate (max_len - length xs) 0)
```

## Rust component
Expand Down Expand Up @@ -189,4 +189,4 @@ Executing + proving (as `nargo prove` always re-executes for witness) takes appr
nargo prove --package depth_8_storage_proof 408.52s user 18.15s system 548% cpu 1:17.81 total
```

NOTE: Running `nargo prove` the first time / before `nargo compile` would automatically include program compilation. Subsequent runs without program modifications would make use of the cached artifacts and provide more representative benchmarking results.
NOTE: Running `nargo prove` the first time / before `nargo compile` would automatically include program compilation. Subsequent runs without program modifications would make use of the cached artifacts and provide more representative benchmarking results.
115 changes: 24 additions & 91 deletions lib/src/lib.nr

Large diffs are not rendered by default.

40 changes: 14 additions & 26 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use ethers::prelude::*;
use ethers::utils::rlp;
use ethers::utils::rlp::Encodable;

/// Maximum length of a state or storage trie node in bytes
const MAX_TRIE_NODE_LENGTH: usize = 532;

/// Maximum size of the value in a storage slot
const MAX_STORAGE_VALUE_LENGTH: usize = 32;
/// Maximum number of bytes in the RLP-encoded value in a storage slot
const MAX_STORAGE_VALUE_LENGTH: usize = 33;

/// Maximum size of the RLP-encoded list representing an account state
const MAX_ACCOUNT_STATE_LENGTH: usize = 134;
Expand Down Expand Up @@ -123,14 +124,13 @@ pub async fn fetch_storage_proof<T: JsonRpcClient>(
let storage_root = eip1186pr.storage_hash.as_bytes().to_vec();

// Extract value as big endian byte array
let mut value = [0; 32];
storage_proof.value.to_big_endian(&mut value);

let value = storage_proof.value.rlp_bytes().to_vec();

// Preprocess storage proof
let preproc_proof = preprocess_proof(
storage_proof.clone().proof,
key.as_bytes().to_vec(),
value.to_vec(),
value,
max_depth,
MAX_TRIE_NODE_LENGTH,
MAX_STORAGE_VALUE_LENGTH,
Expand All @@ -140,8 +140,6 @@ pub async fn fetch_storage_proof<T: JsonRpcClient>(
}

/// Trie proof preprocessor. Returns a proof suitable for use in a Noir program using the noir-trie-proofs library.
/// Note: Depending on the application, the `value` field of the struct may have to be further processed, e.g.
/// left-padded to 32 bytes for storage proofs.
///
/// # Arguments
/// * `proof` - Trie proof as a vector of `Bytes`
Expand Down Expand Up @@ -180,24 +178,14 @@ pub fn preprocess_proof(
// Append with empty nodes to fill up to depth MAX_DEPTH
vec![vec![]; depth_excess]
})
.map(|mut v| {
let node_len = v.len();
let len_excess = if node_len <= max_node_len
{
Ok(max_node_len - node_len)
} else {
Err("Node length cannot exceed the given maximum.")
}
.unwrap();
// Then pad each node up to length MAX_NODE_LEN
v.append(&mut vec![0; len_excess]);
v
.map(|v| {
right_pad(&v, max_node_len).unwrap()
})
.flatten()
.collect::<Vec<u8>>(); // And flatten

// Left-pad value with zeros
let padded_value = left_pad(&value, max_value_len)?;
// Right-pad value with zeros
let padded_value = right_pad(&value, max_value_len)?;

Ok(TrieProof {
key,
Expand All @@ -207,19 +195,19 @@ pub fn preprocess_proof(
})
}

/// Function for left padding a byte vector with zeros. Returns the padded vector.
/// Function for right-padding a byte vector with zeros. Returns the padded vector.
///
/// # Arguments
/// * `v` - Byte vector
/// * `max_len` - Desired size of padded vector
fn left_pad(v: &Vec<u8>, max_len: usize) -> Result<Vec<u8>, Box<dyn std::error::Error>>
fn right_pad(v: &Vec<u8>, max_len: usize) -> Result<Vec<u8>, Box<dyn std::error::Error>>
{
if v.len() > max_len
{
Err(format!("The vector exceeds its maximum expected dimensions.").into())
} else {
let mut v_r = v.clone();
let mut v_l = vec![0u8; max_len - v.len()];
let mut v_l = v.clone();
let mut v_r = vec![0u8; max_len - v.len()];

v_l.append(&mut v_r);

Expand Down
108 changes: 54 additions & 54 deletions tests/depth_8_state_proof/Prover.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4316,60 +4316,6 @@ proof = [
]
depth = 0x08
value = [
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xf8,
0x4e,
0x01,
Expand Down Expand Up @@ -4450,4 +4396,58 @@ value = [
0x9d,
0x6f,
0x0b,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
]
25 changes: 13 additions & 12 deletions tests/depth_8_storage_proof/Prover.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4328,18 +4328,7 @@ proof = [
]
depth = 0x07
value = [
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x94,
0xb8,
0x8f,
0x61,
Expand All @@ -4360,4 +4349,16 @@ value = [
0x39,
0x80,
0x18,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
]

0 comments on commit fff3b7a

Please sign in to comment.