Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(l1): support snap capability message GetTrieNodes #1031

Merged
merged 183 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 182 commits
Commits
Show all changes
183 commits
Select commit Hold shift + click to select a range
02fe744
Corrupted History Fix
fmoletta Oct 22, 2024
a2a2aac
Fix slim encoding for AccountState
fmoletta Oct 22, 2024
aef7441
Fix slim encoding for AccountState
fmoletta Oct 22, 2024
13d9bc3
Commit progress
fmoletta Oct 22, 2024
0ca3589
Commit progress
fmoletta Oct 22, 2024
66b6f90
Add snap as supported cap
fmoletta Oct 22, 2024
41dcaff
Push missing changes
fmoletta Oct 23, 2024
a526c10
Initial peer listen loop
ElFantasma Oct 23, 2024
562bc49
Deprecate `RLPEncodeSlim` trait and use `AccountStateSlim` instead
fmoletta Oct 23, 2024
3893b05
Fix logic
fmoletta Oct 23, 2024
dbe110f
Remove debug print
fmoletta Oct 23, 2024
8b8eacb
Limit response bytes
fmoletta Oct 23, 2024
4ee1790
Add test
fmoletta Oct 23, 2024
d87b1ca
Add more tests
fmoletta Oct 23, 2024
89621bf
Cleanup test code + Fix logic + add test
fmoletta Oct 23, 2024
3a14cdd
Add test
fmoletta Oct 23, 2024
c354321
Add test
fmoletta Oct 23, 2024
7abd4f7
Add test
fmoletta Oct 23, 2024
7cee2b7
Add test
fmoletta Oct 23, 2024
579309f
Also fetch limit proof
fmoletta Oct 23, 2024
9fccb07
Trim test state 408 -> 100
fmoletta Oct 24, 2024
38a7d5b
Simplify logic
fmoletta Oct 24, 2024
574299b
Merge branch 'main' into 840-rlpx-listen-loop
ElFantasma Oct 24, 2024
704da4c
Encode accounts while building range so we do not encode twice
fmoletta Oct 24, 2024
b55294b
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
fmoletta Oct 24, 2024
6d5cc45
Clippy
fmoletta Oct 24, 2024
9514037
Add allow tag
fmoletta Oct 24, 2024
a5b3934
Remove comment
fmoletta Oct 24, 2024
68dcef6
Fix typo
fmoletta Oct 24, 2024
f23077e
Sending eth Status message first
ElFantasma Oct 24, 2024
122778d
Small fixes
ElFantasma Oct 25, 2024
7a4f9cf
Merge branch 'main' into 840-rlpx-listen-loop
ElFantasma Oct 25, 2024
5ae41fe
Small fixes
ElFantasma Oct 25, 2024
66b0bd8
Added TODO comments for pending tasks
ElFantasma Oct 25, 2024
6a5f580
Refactored code to separate encoding/decoding from backend logic
ElFantasma Oct 25, 2024
6c04bb6
Merge branch '840-rlpx-listen-loop' of github.com:lambdaclass/lambda_…
fmoletta Oct 25, 2024
05c9a5e
Replaced hardcoded capabilities strings with enums
ElFantasma Oct 25, 2024
f011aa6
Merge branch 'main' into 840-rlpx-listen-loop
ElFantasma Oct 25, 2024
8ea2644
Add snap messages to liste loop
fmoletta Oct 25, 2024
42049ab
Made Status test to pass
ElFantasma Oct 28, 2024
34e0d9c
Merge branch 'main' into 840-rlpx-listen-loop
ElFantasma Oct 28, 2024
940b6f3
Fixed format
ElFantasma Oct 28, 2024
8047f41
Removed required Debug format on error printing
ElFantasma Oct 28, 2024
f474617
Trying previous commit from hive to see if CI works
ElFantasma Oct 28, 2024
1d5223b
Fix `AccountRange message decoding
fmoletta Oct 28, 2024
80329c7
Fix
fmoletta Oct 28, 2024
297a37b
fix
fmoletta Oct 28, 2024
f25fb1a
Fix: build proof for last account not limit hash
fmoletta Oct 28, 2024
0fdf562
Using apply_fork_choice to set last block number and make blocks cann…
ElFantasma Oct 28, 2024
c989418
Merge branch 'main' into 840-rlpx-listen-loop
ElFantasma Oct 28, 2024
12010b3
Fmt + Return error instead of pancking if invalid root is used
fmoletta Oct 28, 2024
ed0186f
Calling apply_fork_choice only once for the whole chain
ElFantasma Oct 28, 2024
42f2af3
Revert change
fmoletta Oct 28, 2024
61ad329
Return empty proof if root is missing
fmoletta Oct 28, 2024
13c44cf
Calling apply_fork_choice only once for the whole chain
ElFantasma Oct 28, 2024
ecb682f
Clippy fix
ElFantasma Oct 28, 2024
f8bd1dc
use trait method
fmoletta Oct 28, 2024
b890f60
Merge remote-tracking branch 'origin/840-rlpx-listen-loop' into trie_…
fmoletta Oct 28, 2024
31aa8ac
Update hive revision
fmoletta Oct 28, 2024
34d8d84
Reorganize module
fmoletta Oct 28, 2024
9b85c69
Merge branch 'main' into 840-rlpx-listen-loop
ElFantasma Oct 29, 2024
013a977
Update hive revision
fmoletta Oct 29, 2024
66f759a
Add hive snap worflow
fmoletta Oct 29, 2024
67cb57a
Merge branch 'main' into 840-rlpx-listen-loop
ElFantasma Oct 29, 2024
b1ea882
Reverting hive version
ElFantasma Oct 29, 2024
58da873
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
fmoletta Oct 29, 2024
fe2fb77
Removed unnecessary info! messages
ElFantasma Oct 29, 2024
50ca190
Merge branch '840-rlpx-listen-loop' into trie_iter
fmoletta Oct 29, 2024
7062b1b
Add messages + inner structs
fmoletta Oct 29, 2024
d609cae
progress
fmoletta Oct 29, 2024
c69690d
Bump hive version
fmoletta Oct 29, 2024
65f8c77
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
fmoletta Oct 29, 2024
b7c0211
Fix bug in response bytes length calculation
fmoletta Oct 29, 2024
74173d2
Restore Makefile
fmoletta Oct 29, 2024
777732a
Identify storage tries by hashed account address
fmoletta Oct 29, 2024
0e3e276
Merge branch 'trie_iter' into snap-storage-range
fmoletta Oct 29, 2024
abb28cf
Impl logic
fmoletta Oct 29, 2024
fea174d
Connect to main loop
fmoletta Oct 30, 2024
dc6752c
Compute proofs
fmoletta Oct 30, 2024
03d9928
Clippy
fmoletta Oct 30, 2024
c791a89
Chamge type
fmoletta Oct 30, 2024
9fd88d3
Add test
fmoletta Oct 30, 2024
2b9d207
Add messages
fmoletta Oct 30, 2024
37becaa
Add hive test
fmoletta Oct 30, 2024
a6d2f08
fmt
fmoletta Oct 30, 2024
c502f06
Impl messages
fmoletta Oct 31, 2024
242502e
Impl Trie::get_node
fmoletta Oct 31, 2024
3b7d70e
Fix
fmoletta Oct 31, 2024
384eff7
Merge branch 'trie_iter' into snap-storage-range
fmoletta Oct 31, 2024
fa4be1b
Merge branch 'snap-storage-range' into snap-bytecodes
fmoletta Oct 31, 2024
1cf1e9b
implement get_trie_nodes for storage
fmoletta Oct 31, 2024
349d05f
Add byte limit
fmoletta Oct 31, 2024
4fd0ee5
Add request processing
fmoletta Oct 31, 2024
d02e8f2
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
fmoletta Oct 31, 2024
0575a44
Merge branch 'snap-storage-range' of github.com:lambdaclass/lambda_et…
fmoletta Oct 31, 2024
aa29e5f
Fix lingering conflicts
fmoletta Oct 31, 2024
89e144a
Save progress
fmoletta Oct 31, 2024
1d8c3f9
Progress
fmoletta Nov 1, 2024
ea34fbc
Progress
fmoletta Nov 1, 2024
e57f386
remove unused code
fmoletta Nov 1, 2024
0a31fc9
Handle wrong path input lens
fmoletta Nov 1, 2024
2c0e30e
Add restrictions
fmoletta Nov 1, 2024
b3c4816
Fix error handling
fmoletta Nov 1, 2024
80bbc30
clippy+fmt
fmoletta Nov 1, 2024
b7b978a
Add hive test
fmoletta Nov 1, 2024
f02d29a
Cleanup
fmoletta Nov 1, 2024
0e5a005
Draft
fmoletta Nov 1, 2024
003d445
:(
fmoletta Nov 1, 2024
23974bb
Fix code to handle nibbles properly
fmoletta Nov 1, 2024
b159f7d
Simplify code
fmoletta Nov 1, 2024
12b0268
refactor
fmoletta Nov 1, 2024
8e4c884
Remove debug code
fmoletta Nov 1, 2024
b80f19f
Cleanup code
fmoletta Nov 1, 2024
f03ef1e
Merge branch 'snap-bytecodes' into snap-trie-nodes
fmoletta Nov 1, 2024
098a584
Remove debug command
fmoletta Nov 1, 2024
9a57e37
Un-comment noisy info
fmoletta Nov 1, 2024
f54af1d
Update comment
fmoletta Nov 1, 2024
b307261
reorder
fmoletta Nov 1, 2024
9da6ec9
Cite sources
fmoletta Nov 1, 2024
8a0fbbb
Move funcs to encodings module
fmoletta Nov 1, 2024
200d014
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
fmoletta Nov 4, 2024
2332889
Merge branch 'snap-storage-range' into snap-bytecodes
fmoletta Nov 4, 2024
1805ef6
Update workflow
fmoletta Nov 4, 2024
b270580
Update workflow
fmoletta Nov 4, 2024
6af2d6e
Merge branch 'snap-storage-range' into snap-bytecodes
fmoletta Nov 4, 2024
9ec2129
Update workflow
fmoletta Nov 4, 2024
09f688b
Clippy
fmoletta Nov 5, 2024
f494ad9
Merge branch 'snap-storage-range' into snap-bytecodes
fmoletta Nov 5, 2024
64610c3
Merge branch 'snap-bytecodes' into snap-trie-nodes
fmoletta Nov 5, 2024
4f31c37
Merge branch 'main' into snap-trie-nodes
fmoletta Nov 5, 2024
19c0bf0
Remove path field from BranchNode
fmoletta Nov 5, 2024
d32bb4e
Start dumb nibbles impl
fmoletta Nov 5, 2024
7cad9b6
Impl common_prefix
fmoletta Nov 5, 2024
3b69cd7
Update name & doc
fmoletta Nov 5, 2024
16d1432
Impl next
fmoletta Nov 5, 2024
d7c036f
Use DumbNibbles: LeafNode get & insert
fmoletta Nov 5, 2024
a2afdfd
Use DumbNibbles: ExtensionNode get & insert
fmoletta Nov 5, 2024
3a65df9
Make code compile
fmoletta Nov 5, 2024
43ae680
Fix node encoding for LeafNode
fmoletta Nov 5, 2024
e69e954
Fix leaf nibbles
fmoletta Nov 5, 2024
998ed51
Fix leaf partial when inserting to leaf
fmoletta Nov 6, 2024
3cfd7c4
Fixes
fmoletta Nov 6, 2024
ad40f23
Fix
fmoletta Nov 6, 2024
a41cf2b
Fix
fmoletta Nov 6, 2024
68d5f83
Fix
fmoletta Nov 6, 2024
275659a
Fix
fmoletta Nov 6, 2024
6e1b4b7
[DEBUG] Add debug prints
fmoletta Nov 6, 2024
8ff338c
Update crates/storage/store/storage.rs
fmoletta Nov 6, 2024
fc33022
Uncomment feature gate
fmoletta Nov 6, 2024
167c591
[DEBUG] Add debug prints
fmoletta Nov 6, 2024
aad0bcf
Fix
fmoletta Nov 6, 2024
71357dd
[DEBUG] Add debug prints
fmoletta Nov 6, 2024
cd847b9
refactor: add next_choice method
fmoletta Nov 6, 2024
37c93d7
Simplify leaf node encoding
fmoletta Nov 7, 2024
92313f0
Simplify encoding of Leaf
fmoletta Nov 7, 2024
3eb5ee9
Simplify encoding of Extension
fmoletta Nov 7, 2024
eb4fd0c
Simplify encoding of Branch
fmoletta Nov 7, 2024
d50e0ff
Remove the NodeEncoder
fmoletta Nov 7, 2024
856224d
Clippy
fmoletta Nov 7, 2024
f713657
Update TrieIterator
fmoletta Nov 7, 2024
30ba82f
Add proptest
fmoletta Nov 7, 2024
21537d4
Remove old nibble representation
fmoletta Nov 7, 2024
28bd344
Rename DumbNibbles -> Nibbles
fmoletta Nov 7, 2024
c56ad04
Update some doc
fmoletta Nov 7, 2024
bebce62
Simplify BranchNode::remove
fmoletta Nov 7, 2024
08c6668
Simplify
fmoletta Nov 7, 2024
e1f032f
Update doc
fmoletta Nov 7, 2024
9dc2752
Fix unit test
fmoletta Nov 7, 2024
bbe367d
Fix test + code
fmoletta Nov 7, 2024
63f1645
Update test values
fmoletta Nov 7, 2024
237f291
Fix potential panick
fmoletta Nov 7, 2024
d5dfa30
Fix
fmoletta Nov 7, 2024
55b0c37
Fix unit tests
fmoletta Nov 7, 2024
01090b4
Remove outdated comment
fmoletta Nov 7, 2024
e1be0c6
[DEBUG] Remove debug prints
fmoletta Nov 7, 2024
bed25f7
Remove funny name test
fmoletta Nov 7, 2024
f2c2eef
doc nibbles module
fmoletta Nov 7, 2024
9050b0c
Remove todo
fmoletta Nov 7, 2024
345ae96
remove debug print
fmoletta Nov 7, 2024
0fa490f
avoid clone
fmoletta Nov 7, 2024
e6ea561
Merge branch 'refactor-node-structure' into snap-trie-nodes
fmoletta Nov 8, 2024
76640ef
Update trie code with refactored nibble paths
fmoletta Nov 8, 2024
e0f83a3
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
fmoletta Nov 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/hive_and_assertoor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
run_command: make run-hive-on-latest SIMULATION=devp2p TEST_PATTERN="discv4"
- simulation: snap
name: "Devp2p snap tests"
run_command: make run-hive-on-latest SIMULATION=devp2p TEST_PATTERN="/AccountRange|StorageRanges|ByteCodes"
run_command: make run-hive-on-latest SIMULATION=devp2p TEST_PATTERN="/AccountRange|StorageRanges|ByteCodes|TrieNodes"
- simulation: engine
name: "Engine tests"
run_command: make run-hive-on-latest SIMULATION=ethereum/engine TEST_PATTERN="/Blob Transactions On Block 1, Cancun Genesis|Blob Transactions On Block 1, Shanghai Genesis|Blob Transaction Ordering, Single Account, Single Blob|Blob Transaction Ordering, Single Account, Dual Blob|Blob Transaction Ordering, Multiple Accounts|Replace Blob Transactions|Parallel Blob Transactions|ForkchoiceUpdatedV3 Modifies Payload ID on Different Beacon Root|NewPayloadV3 After Cancun|NewPayloadV3 Versioned Hashes|ForkchoiceUpdated Version on Payload Request"
Expand Down
13 changes: 13 additions & 0 deletions crates/common/rlp/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,19 @@ impl<'a> Encoder<'a> {
encode_length(self.temp_buf.len(), self.buf);
self.buf.put_slice(&self.temp_buf);
}

/// Adds a raw value to the buffer without rlp-encoding it
pub fn encode_raw(mut self, value: &[u8]) -> Self {
self.temp_buf.put_slice(value);
self
}

/// Stores a field to be encoded as bytes
/// This method is used to bypass the conflicting implementations between Vec<T> and Vec<u8>
pub fn encode_bytes(mut self, value: &[u8]) -> Self {
<[u8] as RLPEncode>::encode(value, &mut self.temp_buf);
self
}
}

#[cfg(test)]
Expand Down
5 changes: 5 additions & 0 deletions crates/networking/p2p/rlpx/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
rlpx::{eth::backend, handshake::encode_ack_message, message::Message, p2p, utils::id2pubkey},
snap::{
process_account_range_request, process_byte_codes_request, process_storage_ranges_request,
process_trie_nodes_request,
},
MAX_DISC_PACKET_SIZE,
};
Expand Down Expand Up @@ -161,6 +162,10 @@ impl<S: AsyncWrite + AsyncRead + std::marker::Unpin> RLPxConnection<S> {
let response = process_byte_codes_request(req, self.storage.clone())?;
self.send(Message::ByteCodes(response)).await
}
Message::GetTrieNodes(req) => {
let response = process_trie_nodes_request(req, self.storage.clone())?;
self.send(Message::TrieNodes(response)).await
}
// TODO: Add new message types and handlers as they are implemented
message => return Err(RLPxError::UnexpectedMessage(message)),
};
Expand Down
2 changes: 2 additions & 0 deletions crates/networking/p2p/rlpx/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ pub(crate) enum RLPxError {
UnexpectedMessage(Message),
#[error(transparent)]
Store(#[from] StoreError),
#[error("Bad Request: {0}")]
BadRequest(String),
}
17 changes: 16 additions & 1 deletion crates/networking/p2p/rlpx/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use std::fmt::Display;
use super::eth::status::StatusMessage;
use super::p2p::{DisconnectMessage, HelloMessage, PingMessage, PongMessage};
use super::snap::{
AccountRange, ByteCodes, GetAccountRange, GetByteCodes, GetStorageRanges, StorageRanges,
AccountRange, ByteCodes, GetAccountRange, GetByteCodes, GetStorageRanges, GetTrieNodes,
StorageRanges, TrieNodes,
};

use ethereum_rust_rlp::encode::RLPEncode;
Expand All @@ -29,6 +30,8 @@ pub(crate) enum Message {
StorageRanges(StorageRanges),
GetByteCodes(GetByteCodes),
ByteCodes(ByteCodes),
GetTrieNodes(GetTrieNodes),
TrieNodes(TrieNodes),
}

impl Message {
Expand All @@ -47,6 +50,8 @@ impl Message {
0x24 => Ok(Message::StorageRanges(StorageRanges::decode(msg_data)?)),
0x25 => Ok(Message::GetByteCodes(GetByteCodes::decode(msg_data)?)),
0x26 => Ok(Message::ByteCodes(ByteCodes::decode(msg_data)?)),
0x27 => Ok(Message::GetTrieNodes(GetTrieNodes::decode(msg_data)?)),
0x28 => Ok(Message::TrieNodes(TrieNodes::decode(msg_data)?)),
_ => Err(RLPDecodeError::MalformedData),
}
}
Expand Down Expand Up @@ -82,6 +87,14 @@ impl Message {
0x26_u8.encode(buf);
msg.encode(buf)
}
Message::GetTrieNodes(msg) => {
0x27_u8.encode(buf);
msg.encode(buf)
}
Message::TrieNodes(msg) => {
0x28_u8.encode(buf);
msg.encode(buf)
}
}
}
}
Expand All @@ -100,6 +113,8 @@ impl Display for Message {
Message::StorageRanges(_) => "snap:StorageRanges".fmt(f),
Message::GetByteCodes(_) => "snap:GetByteCodes".fmt(f),
Message::ByteCodes(_) => "snap:ByteCodes".fmt(f),
Message::GetTrieNodes(_) => "snap:GetTrieNodes".fmt(f),
Message::TrieNodes(_) => "snap:TrieNodes".fmt(f),
}
}
}
79 changes: 79 additions & 0 deletions crates/networking/p2p/rlpx/snap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ pub(crate) struct ByteCodes {
pub codes: Vec<Bytes>,
}

#[derive(Debug)]
pub(crate) struct GetTrieNodes {
pub id: u64,
pub root_hash: H256,
// [[acc_path, slot_path_1, slot_path_2,...]...]
// The paths can be either full paths (hash) or only the partial path (compact-encoded nibbles)
pub paths: Vec<Vec<Bytes>>,
pub bytes: u64,
}

#[derive(Debug)]
pub(crate) struct TrieNodes {
pub id: u64,
pub nodes: Vec<Bytes>,
}

impl RLPxMessage for GetAccountRange {
fn encode(&self, buf: &mut dyn BufMut) -> Result<(), RLPEncodeError> {
let mut encoded_data = vec![];
Expand Down Expand Up @@ -262,6 +278,69 @@ impl RLPxMessage for ByteCodes {
}
}

impl RLPxMessage for GetTrieNodes {
fn encode(&self, buf: &mut dyn BufMut) -> Result<(), RLPEncodeError> {
let mut encoded_data = vec![];
Encoder::new(&mut encoded_data)
.encode_field(&self.id)
.encode_field(&self.root_hash)
.encode_field(&self.paths)
.encode_field(&self.bytes)
.finish();

let msg_data = snappy_encode(encoded_data)?;
buf.put_slice(&msg_data);
Ok(())
}

fn decode(msg_data: &[u8]) -> Result<Self, RLPDecodeError> {
let mut snappy_decoder = SnappyDecoder::new();
let decompressed_data = snappy_decoder
.decompress_vec(msg_data)
.map_err(|e| RLPDecodeError::Custom(e.to_string()))?;
let decoder = Decoder::new(&decompressed_data)?;
let (id, decoder) = decoder.decode_field("request-id")?;
let (root_hash, decoder) = decoder.decode_field("root_hash")?;
let (paths, decoder) = decoder.decode_field("paths")?;
let (bytes, decoder) = decoder.decode_field("bytes")?;
decoder.finish()?;

Ok(Self {
id,
root_hash,
paths,
bytes,
})
}
}

impl RLPxMessage for TrieNodes {
fn encode(&self, buf: &mut dyn BufMut) -> Result<(), RLPEncodeError> {
let mut encoded_data = vec![];
Encoder::new(&mut encoded_data)
.encode_field(&self.id)
.encode_field(&self.nodes)
.finish();

let msg_data = snappy_encode(encoded_data)?;
buf.put_slice(&msg_data);
Ok(())
}

fn decode(msg_data: &[u8]) -> Result<Self, RLPDecodeError> {
let mut snappy_decoder = SnappyDecoder::new();
let decompressed_data = snappy_decoder
.decompress_vec(msg_data)
.map_err(|e| RLPDecodeError::Custom(e.to_string()))?;
let decoder = Decoder::new(&decompressed_data)?;
let (id, decoder) = decoder.decode_field("request-id")?;
let (nodes, decoder) = decoder.decode_field("nodes")?;
decoder.finish()?;

Ok(Self { id, nodes })
}
}

// Intermediate structures

#[derive(Debug)]
Expand Down
40 changes: 37 additions & 3 deletions crates/networking/p2p/snap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ use bytes::Bytes;
use ethereum_rust_rlp::encode::RLPEncode;
use ethereum_rust_storage::{error::StoreError, Store};

use crate::rlpx::snap::{
AccountRange, AccountRangeUnit, AccountStateSlim, ByteCodes, GetAccountRange, GetByteCodes,
GetStorageRanges, StorageRanges, StorageSlot,
use crate::rlpx::{
error::RLPxError,
snap::{
AccountRange, AccountRangeUnit, AccountStateSlim, ByteCodes, GetAccountRange, GetByteCodes,
GetStorageRanges, GetTrieNodes, StorageRanges, StorageSlot, TrieNodes,
},
};

pub fn process_account_range_request(
Expand Down Expand Up @@ -119,6 +122,37 @@ pub fn process_byte_codes_request(
})
}

pub fn process_trie_nodes_request(
request: GetTrieNodes,
store: Store,
) -> Result<TrieNodes, RLPxError> {
let mut nodes = vec![];
let mut remaining_bytes = request.bytes;
for paths in request.paths {
if paths.is_empty() {
return Err(RLPxError::BadRequest(
"zero-item pathset requested".to_string(),
));
}
let trie_nodes = store.get_trie_nodes(
request.root_hash,
paths.into_iter().map(|bytes| bytes.to_vec()).collect(),
remaining_bytes,
)?;
nodes.extend(trie_nodes.iter().map(|nodes| Bytes::copy_from_slice(nodes)));
remaining_bytes = remaining_bytes
.saturating_sub(trie_nodes.iter().fold(0, |acc, nodes| acc + nodes.len()) as u64);
if remaining_bytes == 0 {
break;
}
}

Ok(TrieNodes {
id: request.id,
nodes,
})
}

#[cfg(test)]
mod tests {
use std::str::FromStr;
Expand Down
51 changes: 51 additions & 0 deletions crates/storage/store/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,57 @@ impl Store {
Ok(Some(proof))
}

/// Receives the root of the state trie and a list of paths where the first path will correspond to a path in the state trie
/// (aka a hashed account address) and the following paths will be paths in the account's storage trie (aka hashed storage keys)
/// If only one hash (account) is received, then the state trie node containing the account will be returned.
/// If more than one hash is received, then the storage trie nodes where each storage key is stored will be returned
/// For more information check out snap capability message [`GetTrieNodes`](https://github.com/ethereum/devp2p/blob/master/caps/snap.md#gettrienodes-0x06)
/// The paths can be either full paths (hash) or partial paths (compact-encoded nibbles), if a partial path is given for the account this method will not return storage nodes for it
pub fn get_trie_nodes(
&self,
state_root: H256,
paths: Vec<Vec<u8>>,
byte_limit: u64,
) -> Result<Vec<Vec<u8>>, StoreError> {
let Some(account_path) = paths.first() else {
return Ok(vec![]);
};
let state_trie = self.engine.open_state_trie(state_root);
// State Trie Nodes Request
if paths.len() == 1 {
// Fetch state trie node
let node = state_trie.get_node(account_path)?;
return Ok(vec![node]);
}
// Storage Trie Nodes Request
let Some(account_state) = state_trie
.get(account_path)?
.map(|ref rlp| AccountState::decode(rlp))
.transpose()?
else {
return Ok(vec![]);
};
// We can't access the storage trie without the account's address hash
let Ok(hashed_address) = account_path.clone().try_into().map(H256) else {
return Ok(vec![]);
};
let storage_trie = self
.engine
.open_storage_trie(hashed_address, account_state.storage_root);
// Fetch storage trie nodes
let mut nodes = vec![];
let mut bytes_used = 0;
for path in paths.iter().skip(1) {
if bytes_used >= byte_limit {
break;
}
let node = storage_trie.get_node(path)?;
bytes_used += node.len() as u64;
nodes.push(node);
}
Ok(nodes)
}

pub fn add_payload(&self, payload_id: u64, block: Block) -> Result<(), StoreError> {
self.engine.add_payload(payload_id, block)
}
Expand Down
Loading