Skip to content

Commit

Permalink
extra matchers for kickoffs
Browse files Browse the repository at this point in the history
  • Loading branch information
atacann committed Feb 28, 2025
1 parent 05ebe95 commit 51d6c97
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 27 deletions.
10 changes: 10 additions & 0 deletions core/src/config/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ pub struct ProtocolParamset {
pub operator_reimburse_timelock: u16,
/// Number of blocks for watchtower challenge timeout timelock (currently BLOCKS_PER_WEEK * 2)
pub watchtower_challenge_timeout_timelock: u16,
/// Time to wait after a kickoff to send a watchtower challenge
pub wait_to_send_watchtower_challenge: u16,
/// Time to wait before trying to disprove (so that you collect all operator challenge acks before disproving)
pub wait_to_disprove: u16,
}

pub const MAINNET_PARAMSET: ProtocolParamset = ProtocolParamset {
Expand All @@ -102,6 +106,8 @@ pub const MAINNET_PARAMSET: ProtocolParamset = ProtocolParamset {
assert_timeout_timelock: BLOCKS_PER_WEEK * 4,
operator_reimburse_timelock: BLOCKS_PER_DAY * 2,
watchtower_challenge_timeout_timelock: BLOCKS_PER_WEEK * 2,
wait_to_send_watchtower_challenge: BLOCKS_PER_WEEK * 2 / 4 * 3,
wait_to_disprove: BLOCKS_PER_WEEK * 7 / 2, // 3.5 weeks
};

pub const REGTEST_PARAMSET: ProtocolParamset = ProtocolParamset {
Expand All @@ -123,6 +129,8 @@ pub const REGTEST_PARAMSET: ProtocolParamset = ProtocolParamset {
assert_timeout_timelock: BLOCKS_PER_WEEK * 4,
operator_reimburse_timelock: BLOCKS_PER_DAY * 2,
watchtower_challenge_timeout_timelock: BLOCKS_PER_WEEK * 2,
wait_to_send_watchtower_challenge: BLOCKS_PER_WEEK * 2 / 4 * 3,
wait_to_disprove: BLOCKS_PER_WEEK * 7 / 2, // 3.5 weeks
};

pub const TESTNET4_PARAMSET: ProtocolParamset = ProtocolParamset {
Expand All @@ -144,4 +152,6 @@ pub const TESTNET4_PARAMSET: ProtocolParamset = ProtocolParamset {
assert_timeout_timelock: BLOCKS_PER_WEEK * 4,
operator_reimburse_timelock: BLOCKS_PER_DAY * 2,
watchtower_challenge_timeout_timelock: BLOCKS_PER_WEEK * 2,
wait_to_send_watchtower_challenge: BLOCKS_PER_WEEK * 2 / 4 * 3,
wait_to_disprove: BLOCKS_PER_WEEK * 7 / 2, // 3.5 weeks
};
71 changes: 44 additions & 27 deletions core/src/states/kickoff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,16 @@ pub enum KickoffEvent {
},
KickoffFinalizerSpent,
BurnConnectorSpent,
TimeToSendWatchtowerChallenge,
TimeToSendOperatorAssert,
TimeToSendVerifierDisprove,
}

#[derive(Debug, Clone, PartialEq, Eq)]
// TODO: add and save operator challenge acks
// save watchtower challenge utxo's spending (not only challenge, also timeout)
// all timelocks
// delete used matchers?
pub struct KickoffStateMachine<T: Owner> {
pub(crate) matchers: HashMap<Matcher, KickoffEvent>,
pub(crate) dirty: bool,
Expand Down Expand Up @@ -152,6 +159,9 @@ impl<T: Owner> KickoffStateMachine<T> {
.insert(*assert_idx, tx.input[0].witness.clone());
Handled
}
KickoffEvent::BurnConnectorSpent | KickoffEvent::KickoffFinalizerSpent => {
Transition(State::closed())
}
_ => Super,
}
}
Expand All @@ -173,7 +183,7 @@ impl<T: Owner> KickoffStateMachine<T> {
remove_txhandler_from_map(&mut txhandlers, TransactionType::Kickoff)?;

// add operator asserts
let kickoff_txid = kickoff_txhandler.get_txid();
let kickoff_txid = *kickoff_txhandler.get_txid();
let num_asserts = utils::COMBINED_ASSERT_DATA.num_steps.len();
for assert_idx in 0..num_asserts {
// TODO: use dedicated functions or smth else, not hardcoded here.
Expand All @@ -184,12 +194,11 @@ impl<T: Owner> KickoffStateMachine<T> {
TransactionType::MiniAssert(assert_idx),
)?
.get_txid();
let matcher = matcher::Matcher::SpentUtxo(OutPoint {
txid: *kickoff_txid,
vout: mini_assert_vout as u32,
});
self.matchers.insert(
matcher,
Matcher::SpentUtxo(OutPoint {
txid: kickoff_txid,
vout: mini_assert_vout as u32,
}),
KickoffEvent::OperatorAssertSent {
assert_txid: operator_assert_txid,
assert_idx: assert_idx as u32,
Expand All @@ -206,19 +215,36 @@ impl<T: Owner> KickoffStateMachine<T> {
TransactionType::WatchtowerChallenge(watchtower_idx as usize),
)?
.get_txid();
let matcher = matcher::Matcher::SpentUtxo(OutPoint {
txid: *kickoff_txid,
vout: watchtower_challenge_vout as u32,
});
self.matchers.insert(
matcher,
Matcher::SpentUtxo(OutPoint {
txid: kickoff_txid,
vout: watchtower_challenge_vout as u32,
}),
KickoffEvent::WatchtowerChallengeSent {
watchtower_idx,
challenge_txid: watchtower_challenge_txid,
},
);
}
// add challenge tx
// add burn connector tx spent matcher
let round_txhandler = remove_txhandler_from_map(&mut txhandlers, TransactionType::Round)?;
let round_txid = *round_txhandler.get_txid();
self.matchers.insert(
Matcher::SpentUtxo(OutPoint {
txid: round_txid,
vout: 0,
}),
KickoffEvent::BurnConnectorSpent,
);
// add kickoff finalizer tx spent matcher
self.matchers.insert(
Matcher::SpentUtxo(OutPoint {
txid: kickoff_txid,
vout: 1,
}),
KickoffEvent::KickoffFinalizerSpent,
);
// create times to send necessary asserts
Ok(())
}

Expand All @@ -237,27 +263,18 @@ impl<T: Owner> KickoffStateMachine<T> {
.await;
}

#[state(entry_action = "on_challenge_entry")]
pub(crate) async fn challenged(
#[state(entry_action = "on_closed_entry")]
// Terminal state
pub(crate) async fn closed(
&mut self,
event: &KickoffEvent,
context: &mut StateContext<T>,
) -> Response<State> {
match event {
_ => Super,
}
Handled
}

#[action]
pub(crate) async fn on_challenge_entry(&mut self, context: &mut StateContext<T>) {
println!("Watchtower Challenge Stage");
context
.capture_error(async |context| {
context
.dispatch_duty(Duty::WatchtowerChallenge)
.await
.map_err(self.wrap_err("on_watchtower_challenge_entry"))
})
.await;
pub(crate) async fn on_closed_entry(&mut self, context: &mut StateContext<T>) {
self.matchers.clear();
}
}

0 comments on commit 51d6c97

Please sign in to comment.