use ckb_network::{CKBProtocolContext, PeerIndex};
use ckb_types::{packed, prelude::*};
use std::sync::Arc;
use crate::{LightClientProtocol, Status, StatusCode, prelude::*};
pub(crate) struct GetLastStateProcess<'a> {
message: packed::GetLastStateReader<'a>,
protocol: &'a LightClientProtocol,
peer: PeerIndex,
nc: &'a Arc<dyn CKBProtocolContext + Sync>,
}
impl<'a> GetLastStateProcess<'a> {
pub(crate) fn new(
message: packed::GetLastStateReader<'a>,
protocol: &'a LightClientProtocol,
peer: PeerIndex,
nc: &'a Arc<dyn CKBProtocolContext + Sync>,
) -> Self {
Self {
message,
protocol,
peer,
nc,
}
}
pub(crate) async fn execute(self) -> Status {
let subscribe: bool = self.message.subscribe().into();
if subscribe {
self.nc.with_peer_mut(
self.peer,
Box::new(|peer| {
peer.if_lightclient_subscribed = true;
}),
);
}
let tip_header = match self.protocol.get_verifiable_tip_header() {
Ok(tip_state) => tip_state,
Err(errmsg) => {
return StatusCode::InternalError.with_context(errmsg);
}
};
let content = packed::SendLastState::new_builder()
.last_header(tip_header)
.build();
let message = packed::LightClientMessage::new_builder()
.set(content)
.build();
self.nc.reply(self.peer, &message).await
}
}