I'm trying to invoke a transaction with anchor_client
from a tokio context. Here's how I'm doing it:
let pid = Keypair::new().pubkey(); let payer = Rc::new(Keypair::new()); let client = Client::new_with_options(Cluster::Localnet, &payer, CommitmentConfig::processed()); let program = client.program(pid).unwrap(); // `Initialize` parameters. let dummy_a = Keypair::new(); let dummy_b = Keypair::new(); tokio::spawn(async { program .request() .accounts(CompositeUpdate { foo: Foo { dummy_a: dummy_a.pubkey(), }, bar: Bar { dummy_b: dummy_b.pubkey(), }, }) .args(composite_instruction::CompositeUpdate { dummy_a: 1234, dummy_b: 4321, }) .send() .await .unwrap(); println!("Composite success!"); });
Unfortunately this gives me the error
error[E0277]: `Rc<solana_sdk::signature::Keypair>` cannot be shared between threads safely --> src/nonblocking.rs:73:18 |73 | tokio::spawn(async { | _____------------_^ | | | | | required by a bound introduced by this call74 | | program75 | | .request()76 | | .accounts(CompositeUpdate {... |92 | | println!("Composite success!");93 | | }); | |_____^ `Rc<solana_sdk::signature::Keypair>` cannot be shared between threads safely | = help: within `anchor_client::Program<&Rc<solana_sdk::signature::Keypair>>`, the trait `Sync` is not implemented for `Rc<solana_sdk::signature::Keypair>`, which is required by `{async block@src/nonblocking.rs:73:18: 93:6}: Send` = note: required because it appears within the type `&Rc<solana_sdk::signature::Keypair>`
What I've tried:
- Switching from an
Rc
to anArc
- Switching from
async
toasync move
- Putting all the client and program declaration stuff inside
tokio::spawn
- Making my own type like in this question. The answer to this question says
The best approach as of now is to just create the Signer in each thread separately, instead of having a single signer being used across threads.
, but I couldn't really figure out how to change my code accordingly.
For anyone wanting to recreate this MRE locally: This MRE is based on https://github.com/coral-xyz/anchor/blob/master/client/example/src/nonblocking.rs. The only change I made was adding tokio::spawn
(since I need this in my own code) and enabling the async
feature for anchor_client
.
Thanks in advance!