Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Make TestExternalities implement Send #4030

Merged
merged 4 commits into from
Nov 6, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions core/externalities/src/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ use std::{collections::HashMap, any::{Any, TypeId}, ops::DerefMut};
///
/// As extensions are stored as `Box<Any>`, this trait should give more confidence that the correct
/// type is registered and requested.
pub trait Extension: Sized {}
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`.
fn as_mut_any(&mut self) -> &mut dyn Any;
}

/// Macro for declaring an extension that usable with [`Extensions`].
///
Expand All @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't this be a default implementation?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, that doesn't work :(

}
}

impl std::ops::Deref for $ext_name {
type Target = $inner;
Expand Down Expand Up @@ -83,7 +92,7 @@ pub trait ExtensionStore {
/// Stores extensions that should be made available through the externalities.
#[derive(Default)]
pub struct Extensions {
extensions: HashMap<TypeId, Box<dyn Any>>,
extensions: HashMap<TypeId, Box<dyn Extension>>,
}

impl Extensions {
Expand All @@ -93,25 +102,26 @@ impl Extensions {
}

/// Register the given extension.
pub fn register<E: Any + Extension>(&mut self, ext: E) {
pub fn register<E: Extension>(&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)
}
}

#[cfg(test)]
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() {
Expand Down
2 changes: 1 addition & 1 deletion core/primitives/src/offchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ impl<'a> From<&'a [Capability]> for Capabilities {
}

/// An extended externalities for offchain workers.
pub trait Externalities {
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
Expand Down
6 changes: 6 additions & 0 deletions core/state-machine/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,10 @@ mod tests {

assert_eq!(&ext.storage(CODE).unwrap(), &code);
}

#[test]
fn check_send() {
fn assert_send<T: Send>() {}
assert_send::<TestExternalities::<Blake2Hasher, u64>>();
}
}