Skip to content

statement-store: allow light clients to specify topic affinity#11329

Merged
alexggh merged 25 commits into
masterfrom
alexggh/explicit_affinity
Apr 14, 2026
Merged

statement-store: allow light clients to specify topic affinity#11329
alexggh merged 25 commits into
masterfrom
alexggh/explicit_affinity

Conversation

@alexggh

@alexggh alexggh commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Description

Add explicit topic affinity support to the statement protocol, allowing nodes to advertise at P2P level which statement topics they're interested in. When a peer's affinity changes, relevant statements are re-sent.

The topic affinity is specified as a BloomFilter, all statements that match the filter are forwarded to new peers.

Currently, this is meant to be used by light clients like smoldot to receive only the statements they are interested in. In the future, this can also be used by statement store full nodes, but some other changes will also be needed.

Changes

  • Change the format of the message and introduce a new protocol "statement/2".
enum StatementMessage {
	Statements(Vec<Statement>),
	/// Bloom filter bytes representing the topics this peer is interested in.
	ExplicitTopicAffinity(AffinityFilter),
}
  • Light client nodes connected on the new protocol need to also advertise a topic affinity before they are receiving any statements.
  • If node define a topic affinity send them only the statements matching that affinity.

TODO

  • Integration testing of the new flow, tested with modify node
  • E2E integrations tests with smoldot: e9a20b6.
  • Rate limit Explicit Affinity

Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Comment thread substrate/client/network/statement/src/affinity.rs
Comment thread substrate/client/network/statement/src/lib.rs Outdated
Comment thread substrate/client/network/statement/src/lib.rs Outdated
Comment thread substrate/client/network/statement/src/lib.rs Outdated
Comment thread substrate/client/network/statement/src/lib.rs Outdated
Comment thread substrate/client/network/statement/src/lib.rs Outdated
Comment thread substrate/client/network/statement/src/lib.rs
Comment thread substrate/client/network/statement/src/lib.rs
Comment thread substrate/client/network/statement/src/lib.rs Outdated
Comment thread substrate/client/network/statement/src/lib.rs Outdated
Comment thread substrate/client/network/statement/src/lib.rs
Comment thread substrate/client/network/statement/src/lib.rs
@AndreiEres

Copy link
Copy Markdown
Contributor

@alexggh please consider merging this PR to your branch
#11372

Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Co-authored-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
@alexggh alexggh marked this pull request as ready for review March 18, 2026 13:18
@alexggh alexggh added the T8-polkadot This PR/Issue is related to/affects the Polkadot network. label Mar 18, 2026
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>

@AndreiEres AndreiEres left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job!

Comment thread substrate/client/network/statement/src/lib.rs
Comment thread substrate/client/network/statement/src/lib.rs
Comment thread substrate/client/network/statement/src/lib.rs Outdated
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
alexggh added 3 commits March 24, 2026 13:35
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>

@P1sar P1sar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now!

@socket-security

socket-security Bot commented Apr 7, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedcargo/​fastbloom@​0.17.010010093100100

View full report

@alexggh alexggh enabled auto-merge April 14, 2026 11:37
@alexggh alexggh added this pull request to the merge queue Apr 14, 2026
Merged via the queue into master with commit 54108b3 Apr 14, 2026
280 of 283 checks passed
@alexggh alexggh deleted the alexggh/explicit_affinity branch April 14, 2026 13:34
/// Maximum number of bits allowed in a bloom filter received from the network.
/// Derived from [`MAX_STATEMENT_NOTIFICATION_SIZE`] so the affinity filter can never exceed the
/// protocol's notification budget. 1 MiB = 8_388_608 bits.
const MAX_BLOOM_BITS: usize = MAX_STATEMENT_NOTIFICATION_SIZE as usize * 8;

@dmitry-markin dmitry-markin Apr 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We unlikely ever encounter a 1 MiB filter, but should this also account for the v2 envelope size and other data sent on the wire?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, may be set a way lower cap on the filter size? For example, Bitcoin caps a transaction Bloom filter size to 36 kB: https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki

Given the false positive rate of 1% and 10000 topics (which is already a lot), we only need a 12 kB filter.

@dmitry-markin dmitry-markin Apr 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, realized that 10k topics for a chat of 1m daily users is not enough :D

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: 1m users should be irrelevant to a single client/filter, if I am not mistaking something.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1m users should be irrelevant to a single client/filter, if I am not mistaking something.

No it is not irelevant, the number bits is related to the total number of topics in the system, not just the ones a client subscribes to, because if the system has 10M topics that get check against your filter then 1% means you still get 100K topics(which is not what you want), so you would have to have a lower FP rate let's say 0.001% and that automatically translate in more bits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T8-polkadot This PR/Issue is related to/affects the Polkadot network.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants