-
Notifications
You must be signed in to change notification settings - Fork 0
Temp pr to review pubsub more efficiently #1
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: pre-feat/pubsub
Are you sure you want to change the base?
Conversation
Work in progress pubsub for cross-chain state monitoring. Quick and dirty approach to validate e2e flow viability. Needs polish: tests, benchmarks, error handling, cleanup.
…kadot-sdk into feat/pubsub-polish
| // Copyright (C) Parity Technologies (UK) Ltd. | ||
| // This file is part of Polkadot. | ||
|
|
||
| // Polkadot is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
|
|
||
| // Polkadot is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU General Public License for more details. | ||
|
|
||
| // You should have received a copy of the GNU General Public License | ||
| // along with Polkadot. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| //! Traits for publish/subscribe operations in the broadcaster pallet. | ||
| use alloc::vec::Vec; | ||
| use polkadot_primitives::Id as ParaId; | ||
| use sp_runtime::DispatchResult; | ||
|
|
||
| /// Trait for handling publish and subscribe operations for parachains. | ||
| /// | ||
| /// This trait provides the interface for parachains to publish key-value data | ||
| /// and manage subscriptions to other parachains' published data. | ||
| pub trait PublishSubscribe { | ||
| /// Publish key-value data for a specific parachain. | ||
| fn publish_data(publisher: ParaId, data: Vec<(Vec<u8>, Vec<u8>)>) -> DispatchResult; | ||
|
|
||
| /// Toggle subscription to a publisher's data. | ||
| fn toggle_subscription(subscriber: ParaId, publisher: ParaId) -> DispatchResult; | ||
| } |
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.
all good with placing the trait in traits.rs under src quite a few crates do the same and most of them are also just trait definitions with no default implementations.
./substrate/frame/conviction-voting/src/traits.rs
./substrate/frame/support/src/traits.rs
./substrate/frame/election-provider-support/src/traits.rs
./substrate/primitives/core/src/traits.rs
./substrate/primitives/arithmetic/src/traits.rs
./substrate/primitives/application-crypto/src/traits.rs
./substrate/primitives/npos-elections/src/traits.rs
./substrate/client/network/src/service/traits.rs
./bridges/snowbridge/primitives/inbound-queue/src/v2/traits.rs
./bridges/relays/client-substrate/src/client/traits.rs
./polkadot/xcm/src/v5/traits.rs
./polkadot/xcm/src/v4/traits.rs
./polkadot/xcm/src/v3/traits.rs
./polkadot/runtime/common/src/traits.rs
| /// - `p`: Number of publishers with changed data | ||
| /// - `k`: Number of key-value pairs per publisher | ||
| /// - `v`: Size of each value in bytes | ||
| #[benchmark] | ||
| fn process_published_data( | ||
| p: Linear<1, 100>, | ||
| k: Linear<1, 16>, | ||
| v: Linear<1, 1024>, |
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.
Are they supposed to stay hard coded or become configs?
| let should_update = match previous_roots.get(publisher) { | ||
| Some(prev_root) => match current_roots_map.get(publisher) { | ||
| Some(curr_root) if prev_root == curr_root => false, | ||
| _ => true, | ||
| }, | ||
| None => true, | ||
| }; |
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.
Just an idea to simplify the nested match statements.
let should_update = previous_roots
.get(publisher)
.and_then(|prev| current_roots_map.get(publisher).map(|curr| prev != curr))
.unwrap_or(true);| }; | ||
|
|
||
| if should_update { | ||
| let result = PublishedData::<T>::clear_prefix(publisher, u32::MAX, 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.
is it fine to have a u32::MAX be the limit limit? can't it cause weight issues with large datasets?
| let k = published_data.values() | ||
| .map(|entries| entries.len() as u32) | ||
| .max() | ||
| .unwrap_or(0); | ||
| let v = published_data.values() | ||
| .flat_map(|entries| entries.iter()) | ||
| .map(|(_, value)| value.len() as u32) | ||
| .max() | ||
| .unwrap_or(0); |
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.
This iterates stuff twice because .max() consumes the iterator, using fold you can remove one of the iterations while still getting the same result.
let (k, v) = published_data.values().fold((0u32, 0u32), |(max_k, max_v), entries| {
let k = entries.len() as u32;
let v = entries.iter().map(|(_, value)| value.len() as u32).max().unwrap_or(0);
(max_k.max(k), max_v.max(v))
});
No description provided.