Skip to content

Commit

Permalink
Merge pull request #64 from quake/quake/fix-actor-panic
Browse files Browse the repository at this point in the history
fix: actor panic
  • Loading branch information
quake authored Jun 13, 2024
2 parents 6ad6ce5 + 3920ae1 commit d8c77fe
Show file tree
Hide file tree
Showing 2 changed files with 298 additions and 247 deletions.
140 changes: 84 additions & 56 deletions src/ckb/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ const FUNDING_CELL_WITNESS_LEN: usize = 8 + 36 + 32 + 64;
// is funded or not.
pub const INITIAL_COMMITMENT_NUMBER: u64 = 0;

const ASSUME_NETWORK_ACTOR_ALIVE: &'static str = "network actor must be alive";

pub enum ChannelActorMessage {
/// Command are the messages that are sent to the channel actor to perform some action.
/// It is normally generated from a user request.
Expand Down Expand Up @@ -205,7 +207,7 @@ impl<S> ChannelActor<S> {
state.remote_ckb_amount,
),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
Ok(())
}
PCNMessage::TxUpdate(tx) => {
Expand Down Expand Up @@ -240,7 +242,7 @@ impl<S> ChannelActor<S> {
),
),
))
.expect("myself alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
}
}
Ok(())
Expand Down Expand Up @@ -276,7 +278,7 @@ impl<S> ChannelActor<S> {
state.get_id(),
),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);

state.state =
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::empty());
Expand Down Expand Up @@ -550,7 +552,7 @@ impl<S> ChannelActor<S> {
message: PCNMessage::CommitmentSigned(commitment_signed),
}),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);

match flags {
CommitmentSignedFlags::SigningCommitment(flags) => {
Expand Down Expand Up @@ -599,7 +601,7 @@ impl<S> ChannelActor<S> {
.send_message(NetworkActorMessage::new_command(
NetworkActorCommand::SendPcnMessage(msg),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);

// Update the state for this tlc.
state.pending_offered_tlcs.insert(tlc.id, tlc);
Expand Down Expand Up @@ -655,7 +657,7 @@ impl<S> ChannelActor<S> {
.send_message(NetworkActorMessage::new_command(
NetworkActorCommand::SendPcnMessage(msg),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
match command.reason {
RemoveTlcReason::RemoveTlcFail(_) => {
state.to_remote_amount += tlc.amount;
Expand Down Expand Up @@ -711,7 +713,7 @@ impl<S> ChannelActor<S> {
}),
}),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
state.local_shutdown_script = Some(command.close_script.clone());
state.local_shutdown_fee = Some(command.fee);
let flags = flags | ShuttingDownFlags::OUR_SHUTDOWN_SENT;
Expand Down Expand Up @@ -796,7 +798,7 @@ impl<S> ChannelActor<S> {
pcn_msg,
)),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);

state.update_state(ChannelState::CollaboratingFundingTx(
CollaboratingFundingTxFlags::AWAITING_REMOTE_TX_COLLABORATION_MSG,
Expand All @@ -819,7 +821,8 @@ impl<S> ChannelActor<S> {
pcn_msg,
)),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);

state.update_state(ChannelState::CollaboratingFundingTx(
flags | CollaboratingFundingTxFlags::OUR_TX_COMPLETE_SENT,
));
Expand Down Expand Up @@ -868,6 +871,48 @@ impl<S> ChannelActor<S> {
ChannelCommand::Shutdown(command) => self.handle_shutdown_command(state, command),
}
}

pub fn handle_event(
&self,
myself: &ActorRef<ChannelActorMessage>,
state: &mut ChannelActorState,
event: ChannelEvent,
) -> Result<(), ProcessingChannelError> {
match event {
ChannelEvent::FundingTransactionConfirmed => {
let flags = match state.state {
ChannelState::AwaitingChannelReady(flags) => flags,
ChannelState::AwaitingTxSignatures(f)
if f.contains(AwaitingTxSignaturesFlags::TX_SIGNATURES_SENT) =>
{
AwaitingChannelReadyFlags::empty()
}
_ => {
panic!("Expecting funding transaction confirmed event in state AwaitingChannelReady or after TX_SIGNATURES_SENT, but got state {:?}", &state.state);
}
};
self.network
.send_message(NetworkActorMessage::new_command(
NetworkActorCommand::SendPcnMessage(PCNMessageWithPeerId {
peer_id: state.peer_id.clone(),
message: PCNMessage::ChannelReady(ChannelReady {
channel_id: state.get_id(),
}),
}),
))
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
let flags = flags | AwaitingChannelReadyFlags::OUR_CHANNEL_READY;
state.update_state(ChannelState::AwaitingChannelReady(flags));
if flags.contains(AwaitingChannelReadyFlags::CHANNEL_READY) {
state.on_channel_ready(&self.network);
}
}
ChannelEvent::PeerDisconnected => {
myself.stop(Some("PeerDisconnected".to_string()));
}
}
Ok(())
}
}

#[rasync_trait]
Expand Down Expand Up @@ -964,7 +1009,7 @@ where
.send_message(NetworkActorMessage::new_command(
NetworkActorCommand::SendPcnMessage(command),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);

self.network
.send_message(NetworkActorMessage::new_event(
Expand All @@ -974,7 +1019,7 @@ where
myself,
),
))
.expect("peer actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
state.update_state(ChannelState::NegotiatingFunding(
NegotiatingFundingFlags::INIT_SENT,
));
Expand Down Expand Up @@ -1050,7 +1095,7 @@ where
message,
}),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
// TODO: note that we can't actually guarantee that this OpenChannel message is sent here.
// It is even possible that the peer_id is bogus, and we can't send a message to it.
// We need some book-keeping service to remove all the OUR_INIT_SENT channels.
Expand Down Expand Up @@ -1079,7 +1124,7 @@ where
myself,
),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);

tx.send(channel.get_id()).expect("Receive not dropped");
Ok(channel)
Expand All @@ -1098,7 +1143,7 @@ where
myself,
),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
Ok(channel)
}
}
Expand All @@ -1121,39 +1166,11 @@ where
error!("Error while processing channel command: {:?}", err);
}
}
ChannelActorMessage::Event(e) => match e {
ChannelEvent::FundingTransactionConfirmed => {
let flags = match state.state {
ChannelState::AwaitingChannelReady(flags) => flags,
ChannelState::AwaitingTxSignatures(f)
if f.contains(AwaitingTxSignaturesFlags::TX_SIGNATURES_SENT) =>
{
AwaitingChannelReadyFlags::empty()
}
_ => {
panic!("Expecting funding transaction confirmed event in state AwaitingChannelReady or after TX_SIGNATURES_SENT, but got state {:?}", &state.state);
}
};
self.network
.send_message(NetworkActorMessage::new_command(
NetworkActorCommand::SendPcnMessage(PCNMessageWithPeerId {
peer_id: state.peer_id.clone(),
message: PCNMessage::ChannelReady(ChannelReady {
channel_id: state.get_id(),
}),
}),
))
.expect("network actor alive");
let flags = flags | AwaitingChannelReadyFlags::OUR_CHANNEL_READY;
state.update_state(ChannelState::AwaitingChannelReady(flags));
if flags.contains(AwaitingChannelReadyFlags::CHANNEL_READY) {
state.on_channel_ready(&self.network);
}
ChannelActorMessage::Event(e) => {
if let Err(err) = self.handle_event(&myself, state, e) {
error!("Error while processing channel event: {:?}", err);
}
ChannelEvent::PeerDisconnected => {
myself.stop(Some("PeerDisconnected".to_string()));
}
},
}
}
match state.state {
ChannelState::Closed => {
Expand Down Expand Up @@ -1761,7 +1778,18 @@ impl ChannelActorState {

pub fn check_state_for_tlc_update(&self) -> ProcessingChannelResult {
match self.state {
ChannelState::ChannelReady(flags) if flags.is_empty() => Ok(()),
ChannelState::ChannelReady(flags) => {
// TODO: Even if we are awaiting remote revoke, we should still stash these tlc updates,
// and perform corresponding actions after we receive the revoke_and_ack message.
if flags.contains(ChannelReadyFlags::AWAITING_REMOTE_REVOKE) {
Err(ProcessingChannelError::InvalidState(
"Trying to update tlc while channel is awaiting remote revocation"
.to_string(),
))
} else {
Ok(())
}
}
ChannelState::ShuttingDown(_) => Ok(()),
_ => Err(ProcessingChannelError::InvalidState(format!(
"Invalid state {:?} for adding tlc",
Expand Down Expand Up @@ -1973,7 +2001,7 @@ impl ChannelActorState {
}),
}),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
signature
});

Expand All @@ -1990,7 +2018,7 @@ impl ChannelActorState {
.send_message(NetworkActorMessage::new_event(
NetworkActorEvent::ChannelClosed(self.get_id(), self.peer_id.clone(), tx),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
}

None => {
Expand Down Expand Up @@ -2109,7 +2137,7 @@ impl ChannelActorState {
self.get_funding_request(20000),
),
))
.expect("network alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
self.update_state(ChannelState::CollaboratingFundingTx(
CollaboratingFundingTxFlags::PREPARING_LOCAL_TX_COLLABORATION_MSG,
));
Expand All @@ -2131,7 +2159,7 @@ impl ChannelActorState {
),
),
))
.expect("myself alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
}
}
}
Expand Down Expand Up @@ -2234,7 +2262,7 @@ impl ChannelActorState {
),
),
))
.expect("myself alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);

debug!("Updating peer next local nonce");
self.remote_nonce = Some(commitment_signed.next_local_nonce);
Expand Down Expand Up @@ -2264,7 +2292,7 @@ impl ChannelActorState {
}),
}),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
match flags {
CommitmentSignedFlags::ChannelReady(_) => {
self.update_state(ChannelState::ChannelReady(ChannelReadyFlags::empty()));
Expand Down Expand Up @@ -2369,7 +2397,7 @@ impl ChannelActorState {
partial_witnesses,
),
))
.expect("network alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
let flags = flags | AwaitingTxSignaturesFlags::OUR_TX_SIGNATURES_SENT;
self.update_state(ChannelState::AwaitingTxSignatures(flags));

Expand All @@ -2388,7 +2416,7 @@ impl ChannelActorState {
.send_message(NetworkActorMessage::new_event(
NetworkActorEvent::ChannelReady(self.get_id(), self.peer_id.clone()),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
}

pub fn append_remote_commitment_point(&mut self, commitment_point: Pubkey) {
Expand Down Expand Up @@ -2497,7 +2525,7 @@ impl ChannelActorState {
}),
)),
))
.expect("network actor alive");
.expect(ASSUME_NETWORK_ACTOR_ALIVE);
let old_flags = match self.state {
ChannelState::CollaboratingFundingTx(flags) => flags,
_ => {
Expand Down
Loading

0 comments on commit d8c77fe

Please sign in to comment.