Skip to content

Commit eb5e269

Browse files
authored
fix(gossipsub): signed messages use monotonically increasing seq numbers
This modifies the gossipsub implementation to use monotonically increasing sequence numbers for signed messages (as dictated by the specification). There is a discussion about this in #3453. This change will make rust-libp2p gossipsub align with the go-implementation when messages are signed. Messages will however still use randomized sequence numbers when messages are unsigned for security reasons (as discussed in the issue linked). This shouldn't change any user-level API, only the seqno behavior. It is fully backwards compatible. Resolves #3453. Pull-Request: #3551.
1 parent 2a18f7a commit eb5e269

File tree

4 files changed

+22
-8
lines changed

4 files changed

+22
-8
lines changed

protocols/gossipsub/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# 0.44.2 - unreleased
2+
3+
- Signed messages now use sequential integers in the sequence number field.
4+
See [PR 3551].
5+
6+
[PR 3551]: https://github.com/libp2p/rust-libp2p/pull/3551
7+
18
# 0.44.1
29

310
- Migrate from `prost` to `quick-protobuf`. This removes `protoc` dependency. See [PR 3312].

protocols/gossipsub/src/behaviour.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ mod tests;
8080
#[derive(Clone)]
8181
pub enum MessageAuthenticity {
8282
/// Message signing is enabled. The author will be the owner of the key and the sequence number
83-
/// will be a random number.
83+
/// will be linearly increasing.
8484
Signed(Keypair),
8585
/// Message signing is disabled.
8686
///
@@ -155,6 +155,8 @@ enum PublishConfig {
155155
keypair: Keypair,
156156
author: PeerId,
157157
inline_key: Option<Vec<u8>>,
158+
last_seq_no: u64, // This starts from a random number and increases then overflows (if
159+
// required)
158160
},
159161
Author(PeerId),
160162
RandomAuthor,
@@ -190,6 +192,7 @@ impl From<MessageAuthenticity> for PublishConfig {
190192
keypair,
191193
author: public_key.to_peer_id(),
192194
inline_key: key,
195+
last_seq_no: rand::random(),
193196
}
194197
}
195198
MessageAuthenticity::Author(peer_id) => PublishConfig::Author(peer_id),
@@ -2749,18 +2752,21 @@ where
27492752

27502753
/// Constructs a [`RawMessage`] performing message signing if required.
27512754
pub(crate) fn build_raw_message(
2752-
&self,
2755+
&mut self,
27532756
topic: TopicHash,
27542757
data: Vec<u8>,
27552758
) -> Result<RawMessage, PublishError> {
2756-
match &self.publish_config {
2759+
match &mut self.publish_config {
27572760
PublishConfig::Signing {
27582761
ref keypair,
27592762
author,
27602763
inline_key,
2764+
mut last_seq_no,
27612765
} => {
2762-
// Build and sign the message
2763-
let sequence_number: u64 = rand::random();
2766+
// Increment the last sequence number
2767+
last_seq_no = last_seq_no.wrapping_add(1);
2768+
2769+
let sequence_number = last_seq_no;
27642770

27652771
let signature = {
27662772
let message = proto::Message {

protocols/gossipsub/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@
5050
//! - **Sequence Numbers** - A message on the gossipsub network is identified by the source
5151
//! [`libp2p_core::PeerId`] and a nonce (sequence number) of the message. The sequence numbers in
5252
//! this implementation are sent as raw bytes across the wire. They are 64-bit big-endian unsigned
53-
//! integers. They are chosen at random in this implementation of gossipsub, but are sequential in
54-
//! the current go implementation.
53+
//! integers. When messages are signed, they are monotonically increasing integers starting from a
54+
//! random value and wrapping around u64::MAX. When messages are unsigned, they are chosen at random.
55+
//! NOTE: These numbers are sequential in the current go implementation.
5556
//!
5657
//! # Peer Discovery
5758
//!

protocols/gossipsub/src/protocol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ mod tests {
573573

574574
// generate an arbitrary GossipsubMessage using the behaviour signing functionality
575575
let config = Config::default();
576-
let gs: Behaviour =
576+
let mut gs: Behaviour =
577577
Behaviour::new(crate::MessageAuthenticity::Signed(keypair.0), config).unwrap();
578578
let data = (0..g.gen_range(10..10024u32))
579579
.map(|_| u8::arbitrary(g))

0 commit comments

Comments
 (0)