Skip to content

Commit 01795b0

Browse files
committed
Merge remote-tracking branch 'origin/master' into alindima/add-systematic-chunks-av-recovery
2 parents 345d896 + 313fe0f commit 01795b0

File tree

90 files changed

+2246
-1338
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+2246
-1338
lines changed

.gitlab/pipeline/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ trigger_workflow:
129129
curl -q -X POST \
130130
-H "Accept: application/vnd.github.v3+json" \
131131
-H "Authorization: token $GITHUB_TOKEN" \
132-
https://api.github.com/repos/paritytech/${CI_PROJECT_NAME}/actions/workflows/subsystem-benchmarks.yml/dispatches \
132+
https://api.github.com/repos/paritytech/${CI_PROJECT_NAME}/actions/workflows/publish-subsystem-benchmarks.yml/dispatches \
133133
-d "{\"ref\":\"refs/heads/master\",\"inputs\":{\"benchmark-data-dir-path\":\"$benchmark_dir\",\"output-file-path\":\"$benchmark_name\"}}";
134134
sleep 300;
135135
done

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bridges/relays/client-substrate/src/client.rs

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ pub fn is_ancient_block<N: From<u32> + PartialOrd + Saturating>(block: N, best:
7777
}
7878

7979
/// Opaque justifications subscription type.
80-
pub struct Subscription<T>(pub(crate) Mutex<futures::channel::mpsc::Receiver<Option<T>>>);
80+
pub struct Subscription<T>(
81+
pub(crate) Mutex<futures::channel::mpsc::Receiver<Option<T>>>,
82+
// The following field is not explicitly used by the code. But when it is dropped,
83+
// the bakground task receives a shutdown signal.
84+
#[allow(dead_code)] pub(crate) futures::channel::oneshot::Sender<()>,
85+
);
8186

8287
/// Opaque GRANDPA authorities set.
8388
pub type OpaqueGrandpaAuthoritiesSet = Vec<u8>;
@@ -621,6 +626,7 @@ impl<C: Chain> Client<C> {
621626
e
622627
})??;
623628

629+
let (cancel_sender, cancel_receiver) = futures::channel::oneshot::channel();
624630
let (sender, receiver) = futures::channel::mpsc::channel(MAX_SUBSCRIPTION_CAPACITY);
625631
let (tracker, subscription) = self
626632
.jsonrpsee_execute(move |client| async move {
@@ -639,7 +645,7 @@ impl<C: Chain> Client<C> {
639645
self_clone,
640646
stall_timeout,
641647
tx_hash,
642-
Subscription(Mutex::new(receiver)),
648+
Subscription(Mutex::new(receiver), cancel_sender),
643649
);
644650
Ok((tracker, subscription))
645651
})
@@ -649,6 +655,7 @@ impl<C: Chain> Client<C> {
649655
"extrinsic".into(),
650656
subscription,
651657
sender,
658+
cancel_receiver,
652659
));
653660
Ok(tracker)
654661
}
@@ -790,14 +797,16 @@ impl<C: Chain> Client<C> {
790797
Ok(FC::subscribe_justifications(&client).await?)
791798
})
792799
.await?;
800+
let (cancel_sender, cancel_receiver) = futures::channel::oneshot::channel();
793801
let (sender, receiver) = futures::channel::mpsc::channel(MAX_SUBSCRIPTION_CAPACITY);
794802
self.data.read().await.tokio.spawn(Subscription::background_worker(
795803
C::NAME.into(),
796804
"justification".into(),
797805
subscription,
798806
sender,
807+
cancel_receiver,
799808
));
800-
Ok(Subscription(Mutex::new(receiver)))
809+
Ok(Subscription(Mutex::new(receiver), cancel_sender))
801810
}
802811

803812
/// Generates a proof of key ownership for the given authority in the given set.
@@ -843,9 +852,17 @@ impl<C: Chain> Client<C> {
843852
impl<T: DeserializeOwned> Subscription<T> {
844853
/// Consumes subscription and returns future statuses stream.
845854
pub fn into_stream(self) -> impl futures::Stream<Item = T> {
846-
futures::stream::unfold(self, |this| async {
855+
futures::stream::unfold(Some(self), |mut this| async move {
856+
let Some(this) = this.take() else { return None };
847857
let item = this.0.lock().await.next().await.unwrap_or(None);
848-
item.map(|i| (i, this))
858+
match item {
859+
Some(item) => Some((item, Some(this))),
860+
None => {
861+
// let's make it explicit here
862+
let _ = this.1.send(());
863+
None
864+
},
865+
}
849866
})
850867
}
851868

@@ -860,36 +877,61 @@ impl<T: DeserializeOwned> Subscription<T> {
860877
async fn background_worker(
861878
chain_name: String,
862879
item_type: String,
863-
mut subscription: jsonrpsee::core::client::Subscription<T>,
880+
subscription: jsonrpsee::core::client::Subscription<T>,
864881
mut sender: futures::channel::mpsc::Sender<Option<T>>,
882+
cancel_receiver: futures::channel::oneshot::Receiver<()>,
865883
) {
884+
log::trace!(
885+
target: "bridge",
886+
"Starting background worker for {} {} subscription stream.",
887+
chain_name,
888+
item_type,
889+
);
890+
891+
futures::pin_mut!(subscription, cancel_receiver);
866892
loop {
867-
match subscription.next().await {
868-
Some(Ok(item)) =>
893+
match futures::future::select(subscription.next(), &mut cancel_receiver).await {
894+
futures::future::Either::Left((Some(Ok(item)), _)) =>
869895
if sender.send(Some(item)).await.is_err() {
896+
log::trace!(
897+
target: "bridge",
898+
"{} {} subscription stream: no listener. Stopping background worker.",
899+
chain_name,
900+
item_type,
901+
);
902+
870903
break
871904
},
872-
Some(Err(e)) => {
905+
futures::future::Either::Left((Some(Err(e)), _)) => {
873906
log::trace!(
874907
target: "bridge",
875-
"{} {} subscription stream has returned '{:?}'. Stream needs to be restarted.",
908+
"{} {} subscription stream has returned '{:?}'. Stream needs to be restarted. Stopping background worker.",
876909
chain_name,
877910
item_type,
878911
e,
879912
);
880913
let _ = sender.send(None).await;
881914
break
882915
},
883-
None => {
916+
futures::future::Either::Left((None, _)) => {
884917
log::trace!(
885918
target: "bridge",
886-
"{} {} subscription stream has returned None. Stream needs to be restarted.",
919+
"{} {} subscription stream has returned None. Stream needs to be restarted. Stopping background worker.",
887920
chain_name,
888921
item_type,
889922
);
890923
let _ = sender.send(None).await;
891924
break
892925
},
926+
futures::future::Either::Right((_, _)) => {
927+
log::trace!(
928+
target: "bridge",
929+
"{} {} subscription stream: listener has been dropped. Stopping background worker.",
930+
chain_name,
931+
item_type,
932+
);
933+
break;
934+
},
893935
}
894936
}
895937
}

bridges/relays/client-substrate/src/transaction_tracker.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,13 @@ mod tests {
306306
TrackedTransactionStatus<HeaderIdOf<TestChain>>,
307307
InvalidationStatus<HeaderIdOf<TestChain>>,
308308
)> {
309+
let (cancel_sender, _cancel_receiver) = futures::channel::oneshot::channel();
309310
let (mut sender, receiver) = futures::channel::mpsc::channel(1);
310311
let tx_tracker = TransactionTracker::<TestChain, TestEnvironment>::new(
311312
TestEnvironment(Ok(HeaderId(0, Default::default()))),
312313
Duration::from_secs(0),
313314
Default::default(),
314-
Subscription(async_std::sync::Mutex::new(receiver)),
315+
Subscription(async_std::sync::Mutex::new(receiver), cancel_sender),
315316
);
316317

317318
let wait_for_stall_timeout = futures::future::pending();
@@ -428,12 +429,13 @@ mod tests {
428429

429430
#[async_std::test]
430431
async fn lost_on_timeout_when_waiting_for_invalidation_status() {
432+
let (cancel_sender, _cancel_receiver) = futures::channel::oneshot::channel();
431433
let (_sender, receiver) = futures::channel::mpsc::channel(1);
432434
let tx_tracker = TransactionTracker::<TestChain, TestEnvironment>::new(
433435
TestEnvironment(Ok(HeaderId(0, Default::default()))),
434436
Duration::from_secs(0),
435437
Default::default(),
436-
Subscription(async_std::sync::Mutex::new(receiver)),
438+
Subscription(async_std::sync::Mutex::new(receiver), cancel_sender),
437439
);
438440

439441
let wait_for_stall_timeout = futures::future::ready(()).shared();

bridges/relays/lib-substrate-relay/src/cli/mod.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,13 @@ impl PrometheusParams {
125125
None
126126
};
127127

128-
let relay_version = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown");
128+
let relay_version = relay_utils::initialize::RELAYER_VERSION
129+
.lock()
130+
.clone()
131+
.unwrap_or_else(|| "unknown".to_string());
129132
let relay_commit = SubstrateRelayBuildInfo::get_git_commit();
130-
relay_utils::metrics::MetricsParams::new(
131-
metrics_address,
132-
relay_version.into(),
133-
relay_commit,
134-
)
135-
.map_err(|e| anyhow::format_err!("{:?}", e))
133+
relay_utils::metrics::MetricsParams::new(metrics_address, relay_version, relay_commit)
134+
.map_err(|e| anyhow::format_err!("{:?}", e))
136135
}
137136
}
138137

bridges/relays/utils/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ futures = "0.3.30"
2222
jsonpath_lib = "0.3"
2323
log = { workspace = true }
2424
num-traits = "0.2"
25+
parking_lot = "0.12.1"
2526
serde_json = { workspace = true, default-features = true }
2627
sysinfo = "0.30"
2728
time = { version = "0.3", features = ["formatting", "local-offset", "std"] }

bridges/relays/utils/src/initialize.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@
1616

1717
//! Relayer initialization functions.
1818
19+
use parking_lot::Mutex;
1920
use std::{cell::RefCell, fmt::Display, io::Write};
2021

22+
/// Relayer version that is provided as metric. Must be set by a binary
23+
/// (get it with `option_env!("CARGO_PKG_VERSION")` from a binary package code).
24+
pub static RELAYER_VERSION: Mutex<Option<String>> = Mutex::new(None);
25+
2126
async_std::task_local! {
2227
pub(crate) static LOOP_NAME: RefCell<String> = RefCell::new(String::default());
2328
}

bridges/snowbridge/pallets/ethereum-client/src/lib.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ pub mod pallet {
104104
#[pallet::error]
105105
pub enum Error<T> {
106106
SkippedSyncCommitteePeriod,
107+
SyncCommitteeUpdateRequired,
107108
/// Attested header is older than latest finalized header.
108109
IrrelevantUpdate,
109110
NotBootstrapped,
@@ -138,41 +139,39 @@ pub mod pallet {
138139
/// Latest imported checkpoint root
139140
#[pallet::storage]
140141
#[pallet::getter(fn initial_checkpoint_root)]
141-
pub(super) type InitialCheckpointRoot<T: Config> = StorageValue<_, H256, ValueQuery>;
142+
pub type InitialCheckpointRoot<T: Config> = StorageValue<_, H256, ValueQuery>;
142143

143144
/// Latest imported finalized block root
144145
#[pallet::storage]
145146
#[pallet::getter(fn latest_finalized_block_root)]
146-
pub(super) type LatestFinalizedBlockRoot<T: Config> = StorageValue<_, H256, ValueQuery>;
147+
pub type LatestFinalizedBlockRoot<T: Config> = StorageValue<_, H256, ValueQuery>;
147148

148149
/// Beacon state by finalized block root
149150
#[pallet::storage]
150151
#[pallet::getter(fn finalized_beacon_state)]
151-
pub(super) type FinalizedBeaconState<T: Config> =
152+
pub type FinalizedBeaconState<T: Config> =
152153
StorageMap<_, Identity, H256, CompactBeaconState, OptionQuery>;
153154

154155
/// Finalized Headers: Current position in ring buffer
155156
#[pallet::storage]
156-
pub(crate) type FinalizedBeaconStateIndex<T: Config> = StorageValue<_, u32, ValueQuery>;
157+
pub type FinalizedBeaconStateIndex<T: Config> = StorageValue<_, u32, ValueQuery>;
157158

158159
/// Finalized Headers: Mapping of ring buffer index to a pruning candidate
159160
#[pallet::storage]
160-
pub(crate) type FinalizedBeaconStateMapping<T: Config> =
161+
pub type FinalizedBeaconStateMapping<T: Config> =
161162
StorageMap<_, Identity, u32, H256, ValueQuery>;
162163

163164
#[pallet::storage]
164165
#[pallet::getter(fn validators_root)]
165-
pub(super) type ValidatorsRoot<T: Config> = StorageValue<_, H256, ValueQuery>;
166+
pub type ValidatorsRoot<T: Config> = StorageValue<_, H256, ValueQuery>;
166167

167168
/// Sync committee for current period
168169
#[pallet::storage]
169-
pub(super) type CurrentSyncCommittee<T: Config> =
170-
StorageValue<_, SyncCommitteePrepared, ValueQuery>;
170+
pub type CurrentSyncCommittee<T: Config> = StorageValue<_, SyncCommitteePrepared, ValueQuery>;
171171

172172
/// Sync committee for next period
173173
#[pallet::storage]
174-
pub(super) type NextSyncCommittee<T: Config> =
175-
StorageValue<_, SyncCommitteePrepared, ValueQuery>;
174+
pub type NextSyncCommittee<T: Config> = StorageValue<_, SyncCommitteePrepared, ValueQuery>;
176175

177176
/// The current operating mode of the pallet.
178177
#[pallet::storage]
@@ -320,6 +319,7 @@ pub mod pallet {
320319

321320
// Verify update is relevant.
322321
let update_attested_period = compute_period(update.attested_header.slot);
322+
let update_finalized_period = compute_period(update.finalized_header.slot);
323323
let update_has_next_sync_committee = !<NextSyncCommittee<T>>::exists() &&
324324
(update.next_sync_committee_update.is_some() &&
325325
update_attested_period == store_period);
@@ -395,6 +395,11 @@ pub mod pallet {
395395
),
396396
Error::<T>::InvalidSyncCommitteeMerkleProof
397397
);
398+
} else {
399+
ensure!(
400+
update_finalized_period == store_period,
401+
Error::<T>::SyncCommitteeUpdateRequired
402+
);
398403
}
399404

400405
// Verify sync committee aggregate signature.

bridges/snowbridge/pallets/ethereum-client/src/tests.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,20 +362,32 @@ fn submit_update_with_sync_committee_in_current_period() {
362362
}
363363

364364
#[test]
365-
fn submit_update_in_next_period() {
365+
fn reject_submit_update_in_next_period() {
366366
let checkpoint = Box::new(load_checkpoint_update_fixture());
367367
let sync_committee_update = Box::new(load_sync_committee_update_fixture());
368368
let update = Box::new(load_next_finalized_header_update_fixture());
369369
let sync_committee_period = compute_period(sync_committee_update.finalized_header.slot);
370370
let next_sync_committee_period = compute_period(update.finalized_header.slot);
371371
assert_eq!(sync_committee_period + 1, next_sync_committee_period);
372+
let next_sync_committee_update = Box::new(load_next_sync_committee_update_fixture());
372373

373374
new_tester().execute_with(|| {
374375
assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint));
375376
assert_ok!(EthereumBeaconClient::submit(
376377
RuntimeOrigin::signed(1),
377378
sync_committee_update.clone()
378379
));
380+
// check an update in the next period is rejected
381+
assert_err!(
382+
EthereumBeaconClient::submit(RuntimeOrigin::signed(1), update.clone()),
383+
Error::<Test>::SyncCommitteeUpdateRequired
384+
);
385+
// submit update with next sync committee
386+
assert_ok!(EthereumBeaconClient::submit(
387+
RuntimeOrigin::signed(1),
388+
next_sync_committee_update
389+
));
390+
// check same header in the next period can now be submitted successfully
379391
assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), update.clone()));
380392
let block_root: H256 = update.finalized_header.clone().hash_tree_root().unwrap();
381393
assert!(<FinalizedBeaconState<Test>>::contains_key(block_root));

bridges/snowbridge/pallets/ethereum-client/src/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub type NextSyncCommitteeUpdate = primitives::NextSyncCommitteeUpdate<SC_SIZE>;
1818
pub use primitives::{AncestryProof, ExecutionProof};
1919

2020
/// FinalizedState ring buffer implementation
21-
pub(crate) type FinalizedBeaconStateBuffer<T> = RingBufferMapImpl<
21+
pub type FinalizedBeaconStateBuffer<T> = RingBufferMapImpl<
2222
u32,
2323
crate::MaxFinalizedHeadersToKeep<T>,
2424
crate::FinalizedBeaconStateIndex<T>,

0 commit comments

Comments
 (0)