-
Notifications
You must be signed in to change notification settings - Fork 8
feat: handle DoS node by sending block #475
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
base: main
Are you sure you want to change the base?
Conversation
frisitano
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Added a few comments inline. Can you add some test cases, please?
I'm also wondering if we can simplify the logic a bit. The idea would be that if we have a connection with a peer over scroll-wire, then we should only gossip on scroll-wire. If we don't have a scroll-wire connection, then we use eth-wire. I think this should allow us to consolidate the block cache per peer into a single cache.
| } else { | ||
| None | ||
| } | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we should change the logic below.
If we have a connection with a peer via scroll wire - only send via scroll wire. If we don't have a connection with a peer via scroll wire then send only via eth wire.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's a good idea! The only thing is about implementation.
If we don't have a connection with a peer via scroll wire then send only via eth wire.
The implementation in my mind is that, we will need to save all none-scroll-wire peerIds here, so we can send block directly to the peer only via eth wire by inner_network_handle. But seems the trait of inner_network_handle does export method send_eth_message.
And also I'm not sure how to maintain the none-scroll-wire peerlist on RN side, how do we handle peer disconnect.
Do you have a viable implementation in your mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modify this trait to implement it https://github.com/scroll-tech/reth/blob/079764e909be74219f32796342c4dd911fdd30a9/crates/net/network-api/src/block.rs#L15-L26
/// Provides a listener for new blocks on the eth wire protocol.
pub trait EthWireProvider<N: NetworkPrimitives> {
/// Create a new eth wire block listener.
fn eth_wire_block_listener(
&self,
) -> impl Future<
Output = Result<EventStream<NewBlockWithPeer<N::Block>>, oneshot::error::RecvError>,
> + Send;
/// Announce a new block to the network over the eth wire protocol.
fn eth_wire_announce_block(&self, block: N::NewBlockPayload, hash: B256);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking you could use something like this
let peers = self.inner_network_handle.get_all_peers().await?;
for peer in peers {
if peer.capabilities.capabilities().iter().any(|cap| matches!(cap, ScrollWire)) {
todo!("send via scroll wire")
} else {
todo!("send via eth wire")
};
}
Problem
Malicious peers can DoS the node by sending old blocks.
Solution
Two-layer defense:
if block_number <= finalized_height { penalize(peer); // Immediately reject}// Cache recent blocks per peerif peer_already_sent_this_block { penalize(peer); // DoS detected }Challenge
Multi-Protocol Handling
Problem: Nodes use both scroll-wire and eth-wire protocols. Same peer may legitimately send same block via both protocols.
Solution: Track duplicates per protocol
Fixes #307