Custom types from library result in: `Cell<bool>` cannot be shared between threads safely
JonasHiltl opened this issue · comments
Description:
I'm trying to implement the iota/identity library into flutter+rust. Most of the functions are asynchronous so I'm using allo-isolate. But some custom types of the IOTA library cannot be shared between threads safely.
My async function which mostly uses custom types:
pub async fn create_did_document() -> Result<String> {
// Generate a new DID Document and public/private key pair.
// The generated document will have an authentication key associated with
// the keypair.
let client = &Client::new().await?;
let keypair: KeyPair = KeyPair::new_ed25519()?;
let mut document: IotaDocument = IotaDocument::from_keypair(&keypair)?;
// Sign the DID Document with the default authentication key.
document.sign(keypair.secret())?;
// Use the Client to publish the DID Document to the Tangle.
document.publish(client).await?;
println!("DID document: {}", document);
println!("Transaktion link: {}", document.message_id());
// Return document and keypair.
Ok(document.to_json().unwrap())
}
Exposing the async create_did_document
function:
lazy_static! {
static ref RUNTIME: io::Result<Runtime> = Builder::new()
.threaded_scheduler()
.enable_all()
.core_threads(4)
.thread_name("flutterust")
.build();
}
/// Simple Macro to help getting the value of the runtime.
macro_rules! runtime {
() => {
match RUNTIME.as_ref() {
Ok(rt) => rt,
Err(_) => {
return 0;
}
}
};
}
#[no_mangle]
pub extern "C" fn create_did_document(port: i64) -> i32 {
let rt = runtime!();
let t = Isolate::new(port).task(iota_did::create_did_document()); // not satisfied
rt.spawn(t);
1
}
Full error message:
`Cell<bool>` cannot be shared between threads safely
within `identity_iota::did::doc::iota_document::IotaDocument`, the trait `Sync` is not implemented for `Cell<bool>`
required because it appears within the type `identity_core::crypto::signature::signature::Signature`
required because it appears within the type `Option<identity_core::crypto::signature::signature::Signature>`
required because it appears within the type `identity_did::verifiable::properties::Properties<identity_iota::did::doc::properties::Properties>`
required because it appears within the type `identity_did::document::core_document::CoreDocument<identity_did::verifiable::properties::Properties<identity_iota::did::doc::properties::Properties>>`
required because it appears within the type `identity_iota::did::doc::iota_document::IotaDocument`
required because of the requirements on the impl of `Send` for `&identity_iota::did::doc::iota_document::IotaDocument`
required because it appears within the type `for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, &'r mut identity_iota::did::doc::iota_document::IotaDocument, &identity_iota::tangle::client::Client, identity_iota::tangle::network::Network, Option<&'s identity_iota::tangle::client::Client>, &'t0 identity_iota::tangle::client::Client, &'t1 identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future, (), impl std::future::Future, Result<identity_iota::tangle::client::Client, identity_iota::error::Error>, identity_iota::tangle::client::Client}`
required because it appears within the type `[static generator@identity_iota::did::doc::iota_document::IotaDocument::publish<'_, &identity_iota::tangle::client::Client>::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, &'r mut identity_iota::did::doc::iota_document::IotaDocument, &identity_iota::tangle::client::Client, identity_iota::tangle::network::Network, Option<&'s identity_iota::tangle::client::Client>, &'t0 identity_iota::tangle::client::Client, &'t1 identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future, (), impl std::future::Future, Result<identity_iota::tangle::client::Client, identity_iota::error::Error>, identity_iota::tangle::client::Client}]`
required because it appears within the type `from_generator::GenFuture<[static generator@identity_iota::did::doc::iota_document::IotaDocument::publish<'_, &identity_iota::tangle::client::Client>::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, &'r mut identity_iota::did::doc::iota_document::IotaDocument, &identity_iota::tangle::client::Client, identity_iota::tangle::network::Network, Option<&'s identity_iota::tangle::client::Client>, &'t0 identity_iota::tangle::client::Client, &'t1 identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future, (), impl std::future::Future, Result<identity_iota::tangle::client::Client, identity_iota::error::Error>, identity_iota::tangle::client::Client}]>`
required because it appears within the type `impl std::future::Future`
required because it appears within the type `impl std::future::Future`
required because it appears within the type `for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, impl std::future::Future, (), identity_iota::tangle::client::Client, &'r identity_iota::tangle::client::Client, identity_core::crypto::key::pair::KeyPair, identity_iota::did::doc::iota_document::IotaDocument, &'s mut identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future}`
required because it appears within the type `[static generator@iota_did::create_did_document::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, impl std::future::Future, (), identity_iota::tangle::client::Client, &'r identity_iota::tangle::client::Client, identity_core::crypto::key::pair::KeyPair, identity_iota::did::doc::iota_document::IotaDocument, &'s mut identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future}]`
required because it appears within the type `from_generator::GenFuture<[static generator@iota_did::create_did_document::{closure#0} for<'r, 's, 't0, 't1, 't2, 't3> {ResumeTy, impl std::future::Future, (), identity_iota::tangle::client::Client, &'r identity_iota::tangle::client::Client, identity_core::crypto::key::pair::KeyPair, identity_iota::did::doc::iota_document::IotaDocument, &'s mut identity_iota::did::doc::iota_document::IotaDocument, impl std::future::Future}]>`
required because it appears within the type `impl std::future::Future`
required because it appears within the type `impl std::future::Future`
Full Code:
This is the full repo of my project with the corresponding rust implementation of iota-identity. my_project
Yes, that's a constraint for the task that would run, it must be Send + Sync
that's how it also required by tokio::spawn
and async_std::task::spawn
Closed for inactivity, feel free to ask us to open it again or open a new issue if you still have any questions.