From 51d6c97c334a85d5003907b92b7b47c33cf58520 Mon Sep 17 00:00:00 2001 From: atacann Date: Fri, 28 Feb 2025 17:22:23 +0300 Subject: [PATCH] extra matchers for kickoffs --- core/src/config/protocol.rs | 10 ++++++ core/src/states/kickoff.rs | 71 +++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/core/src/config/protocol.rs b/core/src/config/protocol.rs index b4a8957f..79cfc752 100644 --- a/core/src/config/protocol.rs +++ b/core/src/config/protocol.rs @@ -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 { @@ -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 { @@ -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 { @@ -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 }; diff --git a/core/src/states/kickoff.rs b/core/src/states/kickoff.rs index 1212620b..03c625f1 100644 --- a/core/src/states/kickoff.rs +++ b/core/src/states/kickoff.rs @@ -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 { pub(crate) matchers: HashMap, pub(crate) dirty: bool, @@ -152,6 +159,9 @@ impl KickoffStateMachine { .insert(*assert_idx, tx.input[0].witness.clone()); Handled } + KickoffEvent::BurnConnectorSpent | KickoffEvent::KickoffFinalizerSpent => { + Transition(State::closed()) + } _ => Super, } } @@ -173,7 +183,7 @@ impl KickoffStateMachine { 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. @@ -184,12 +194,11 @@ impl KickoffStateMachine { 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, @@ -206,19 +215,36 @@ impl KickoffStateMachine { 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(()) } @@ -237,27 +263,18 @@ impl KickoffStateMachine { .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, ) -> Response { - match event { - _ => Super, - } + Handled } #[action] - pub(crate) async fn on_challenge_entry(&mut self, context: &mut StateContext) { - 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) { + self.matchers.clear(); } }