From d521dd0744649301f43bc4819afcf9fb0962bbfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 6 Nov 2019 08:32:13 +0100 Subject: [PATCH 1/3] Make `TestExternalities` implement `Send` + `Sync` --- core/externalities/src/extensions.rs | 19 ++++++++++++++----- core/primitives/src/offchain.rs | 4 ++-- core/state-machine/src/testing.rs | 6 ++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/core/externalities/src/extensions.rs b/core/externalities/src/extensions.rs index c7d7bc48538ac..acb4cc0867dc4 100644 --- a/core/externalities/src/extensions.rs +++ b/core/externalities/src/extensions.rs @@ -27,7 +27,12 @@ use std::{collections::HashMap, any::{Any, TypeId}, ops::DerefMut}; /// /// As extensions are stored as `Box`, this trait should give more confidence that the correct /// type is registered and requested. -pub trait Extension: Sized {} +pub trait Extension: Send + Sync + Any { + /// Return the extension as `&mut dyn Any`. + /// + /// This is a trick to make the trait type castable into an `Any`. + fn as_mut_any(&mut self) -> &mut dyn Any; +} /// Macro for declaring an extension that usable with [`Extensions`]. /// @@ -51,7 +56,11 @@ macro_rules! decl_extension { $( #[ $attr ] )* $vis struct $ext_name (pub $inner); - impl $crate::Extension for $ext_name {} + impl $crate::Extension for $ext_name { + fn as_mut_any(&mut self) -> &mut dyn std::any::Any { + self + } + } impl std::ops::Deref for $ext_name { type Target = $inner; @@ -83,7 +92,7 @@ pub trait ExtensionStore { /// Stores extensions that should be made available through the externalities. #[derive(Default)] pub struct Extensions { - extensions: HashMap>, + extensions: HashMap>, } impl Extensions { @@ -93,13 +102,13 @@ impl Extensions { } /// Register the given extension. - pub fn register(&mut self, ext: E) { + pub fn register(&mut self, ext: E) { self.extensions.insert(ext.type_id(), Box::new(ext)); } /// Return a mutable reference to the requested extension. pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> { - self.extensions.get_mut(&ext_type_id).map(DerefMut::deref_mut) + self.extensions.get_mut(&ext_type_id).map(DerefMut::deref_mut).map(Extension::as_mut_any) } } diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 27bd29a00df8d..92011e96ec694 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -658,13 +658,13 @@ impl Externalities for LimitedExternalities { #[cfg(feature = "std")] externalities::decl_extension! { /// The offchain extension that will be registered at the Substrate externalities. - pub struct OffchainExt(Box); + pub struct OffchainExt(Box); } #[cfg(feature = "std")] impl OffchainExt { /// Create a new instance of `Self`. - pub fn new(offchain: O) -> Self { + pub fn new(offchain: O) -> Self { Self(Box::new(offchain)) } } diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 16ff62020b594..2b483fbf3f8a2 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -192,4 +192,10 @@ mod tests { assert_eq!(&ext.storage(CODE).unwrap(), &code); } + + #[test] + fn check_send_and_sync() { + fn assert_send_sync() {} + assert_send_sync::>(); + } } From ccd5fe246cf20d6d3ec1a936476d2a5b300ff3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 6 Nov 2019 08:59:31 +0100 Subject: [PATCH 2/3] Fixes offchain --- core/primitives/src/offchain.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 92011e96ec694..1d363402c55a4 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -289,7 +289,7 @@ impl<'a> From<&'a [Capability]> for Capabilities { } /// An extended externalities for offchain workers. -pub trait Externalities { +pub trait Externalities: Send + Sync { /// Returns if the local node is a potential validator. /// /// Even if this function returns `true`, it does not mean that any keys are configured @@ -658,13 +658,13 @@ impl Externalities for LimitedExternalities { #[cfg(feature = "std")] externalities::decl_extension! { /// The offchain extension that will be registered at the Substrate externalities. - pub struct OffchainExt(Box); + pub struct OffchainExt(Box); } #[cfg(feature = "std")] impl OffchainExt { /// Create a new instance of `Self`. - pub fn new(offchain: O) -> Self { + pub fn new(offchain: O) -> Self { Self(Box::new(offchain)) } } From b149121be9bcaef30ac51db0fd05ec5d82d00aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 6 Nov 2019 10:29:52 +0100 Subject: [PATCH 3/3] Make it just `Send` --- core/externalities/src/extensions.rs | 13 +++++++------ core/primitives/src/offchain.rs | 2 +- core/state-machine/src/testing.rs | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/core/externalities/src/extensions.rs b/core/externalities/src/extensions.rs index acb4cc0867dc4..a1a83cb197d4f 100644 --- a/core/externalities/src/extensions.rs +++ b/core/externalities/src/extensions.rs @@ -27,7 +27,7 @@ use std::{collections::HashMap, any::{Any, TypeId}, ops::DerefMut}; /// /// As extensions are stored as `Box`, this trait should give more confidence that the correct /// type is registered and requested. -pub trait Extension: Send + Sync + Any { +pub trait Extension: Send + Any { /// Return the extension as `&mut dyn Any`. /// /// This is a trick to make the trait type castable into an `Any`. @@ -116,11 +116,12 @@ impl Extensions { mod tests { use super::*; - struct DummyExt(u32); - impl Extension for DummyExt {} - - struct DummyExt2(u32); - impl Extension for DummyExt2 {} + decl_extension! { + struct DummyExt(u32); + } + decl_extension! { + struct DummyExt2(u32); + } #[test] fn register_and_retrieve_extension() { diff --git a/core/primitives/src/offchain.rs b/core/primitives/src/offchain.rs index 1d363402c55a4..c69c074b747b1 100644 --- a/core/primitives/src/offchain.rs +++ b/core/primitives/src/offchain.rs @@ -289,7 +289,7 @@ impl<'a> From<&'a [Capability]> for Capabilities { } /// An extended externalities for offchain workers. -pub trait Externalities: Send + Sync { +pub trait Externalities: Send { /// Returns if the local node is a potential validator. /// /// Even if this function returns `true`, it does not mean that any keys are configured diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 2b483fbf3f8a2..8253f20c8bd01 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -194,8 +194,8 @@ mod tests { } #[test] - fn check_send_and_sync() { - fn assert_send_sync() {} - assert_send_sync::>(); + fn check_send() { + fn assert_send() {} + assert_send::>(); } }