Communicate with `lightningd` to tell it about our options, RPC methods and subscribe to hooks, and then process the initialization, configuring the plugin. Returns `None` if we were invoked with `--help` and thus should exit after this handshake
(mut self)
| 351 | /// Returns `None` if we were invoked with `--help` and thus |
| 352 | /// should exit after this handshake |
| 353 | pub async fn configure(mut self) -> Result<Option<ConfiguredPlugin<S, I, O>>, anyhow::Error> { |
| 354 | let mut input = FramedRead::new(self.input.take().unwrap(), JsonRpcCodec::default()); |
| 355 | |
| 356 | // Sadly we need to wrap the output in a mutex in order to |
| 357 | // enable early logging, i.e., logging that is done before the |
| 358 | // PluginDriver is processing events during the |
| 359 | // handshake. Otherwise we could just write the log events to |
| 360 | // the event queue and have the PluginDriver be the sole owner |
| 361 | // of `Stdout`. |
| 362 | let output = Arc::new(Mutex::new(FramedWrite::new( |
| 363 | self.output.take().unwrap(), |
| 364 | JsonCodec::default(), |
| 365 | ))); |
| 366 | |
| 367 | // Now configure the logging, so any `log` call is wrapped |
| 368 | // in a JSON-RPC notification and sent to Core Lightning |
| 369 | if self.logging { |
| 370 | crate::logging::init(output.clone()).await?; |
| 371 | trace!("Plugin logging initialized"); |
| 372 | } |
| 373 | |
| 374 | // Read the `getmanifest` message: |
| 375 | match input.next().await { |
| 376 | Some(Ok(messages::JsonRpc::Request(id, messages::Request::Getmanifest(m)))) => { |
| 377 | output |
| 378 | .lock() |
| 379 | .await |
| 380 | .send(json!({ |
| 381 | "jsonrpc": "2.0", |
| 382 | "result": self.handle_get_manifest(m), |
| 383 | "id": id, |
| 384 | })) |
| 385 | .await? |
| 386 | } |
| 387 | Some(o) => return Err(anyhow!("Got unexpected message {:?} from lightningd", o)), |
| 388 | None => { |
| 389 | return Err(anyhow!( |
| 390 | "Lost connection to lightning expecting getmanifest" |
| 391 | )); |
| 392 | } |
| 393 | }; |
| 394 | let (init_id, configuration) = match input.next().await { |
| 395 | Some(Ok(messages::JsonRpc::Request(id, messages::Request::Init(m)))) => { |
| 396 | (id, self.handle_init(m)?) |
| 397 | } |
| 398 | |
| 399 | Some(o) => return Err(anyhow!("Got unexpected message {:?} from lightningd", o)), |
| 400 | None => { |
| 401 | // If we are being called with --help we will get |
| 402 | // disconnected here. That's expected, so don't |
| 403 | // complain about it. |
| 404 | return Ok(None); |
| 405 | } |
| 406 | }; |
| 407 | |
| 408 | // TODO Split the two hashmaps once we fill in the hook |
| 409 | // payload structs in messages.rs |
| 410 | let mut rpcmethods: HashMap<String, AsyncCallback<S>> = |
no test coverage detected