clementine_core/builder/transaction/
deposit_signature_owner.rs

1//! # Deposit Signature Ownership Mapping
2//!
3//! This module provides types and logic for mapping transaction signature requirements to protocol entities in the Clementine bridge.
4//! It is used to determine which entity (operator, verifier, N-of-N, etc.) is responsible for providing a signature for a given transaction input,
5//! and what sighash type is required for that signature. Additionally it encodes when this signature is given to other entities.
6//!
7
8use crate::errors::BridgeError;
9use crate::rpc::clementine::tagged_signature::SignatureId;
10use crate::rpc::clementine::{NormalSignatureKind, NumberedSignatureKind};
11use bitcoin::TapSighashType;
12use eyre::Context;
13
14/// Enumerates the protocol entities that may own a required signature for a transaction input.
15/// Additionally it encodes when this signature is given to other entities. For example signatures with OperatorDeposit are operator's
16/// signatures that are shared with verifiers during a new deposit, while OperatorSetup is operator's signature that is given to the
17/// verifiers when Operator is  being newly setup and added to verifiers databases.
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum EntityType {
20    OperatorDeposit,
21    VerifierDeposit,
22    OperatorSetup,
23}
24
25/// Describes the ownership and sighash type for a required signature.
26///
27/// - `NotOwned`: No signature required or not owned by any protocol entity.
28/// - `OperatorSharedDeposit`: Operator's signature required for deposit, with the given sighash type.
29/// - `NofnSharedDeposit`: N-of-N signature required for deposit, with the given sighash type.
30/// - `Own`: Signature required for the entity running the program, with the given sighash type.
31/// - `OperatorSharedSetup`: Operator's signature required during aggregator setup, with the given sighash type.
32#[derive(Debug, Clone, Copy)]
33pub enum DepositSigKeyOwner {
34    NotOwned,
35    /// Operator's signature required for deposit (shared with verifiers), with the given sighash type.
36    OperatorSharedDeposit(TapSighashType),
37    /// N-of-N signature required for deposit, with the given sighash type.
38    NofnSharedDeposit(TapSighashType),
39    /// Signature required for the entity itself, with the given sighash type.
40    /// Verifiers do not need this signature info, thus it is not saved to DB.
41    /// Added to help define different sighash types for operator's own signatures.
42    Own(TapSighashType),
43    /// Operator's signature required during first setup, with the given sighash type.
44    OperatorSharedSetup(TapSighashType),
45}
46
47impl DepositSigKeyOwner {
48    /// Returns the sighash type for this signature owner, if any.
49    pub fn sighash_type(&self) -> Option<TapSighashType> {
50        match self {
51            DepositSigKeyOwner::NotOwned => None,
52            DepositSigKeyOwner::Own(t)
53            | DepositSigKeyOwner::NofnSharedDeposit(t)
54            | DepositSigKeyOwner::OperatorSharedDeposit(t)
55            | DepositSigKeyOwner::OperatorSharedSetup(t) => Some(*t),
56        }
57    }
58}
59
60impl SignatureId {
61    /// Maps a [`SignatureId`] to its required signature owner and sighash type.
62    ///
63    /// # Returns
64    ///
65    /// A [`DepositSigKeyOwner`] describing the required signature owner and sighash type for this signature ID, or a [`BridgeError`] if the mapping fails.
66    pub fn get_deposit_sig_owner(&self) -> Result<DepositSigKeyOwner, BridgeError> {
67        use DepositSigKeyOwner::*;
68        use TapSighashType::{Default as SighashDefault, SinglePlusAnyoneCanPay};
69        match *self {
70            SignatureId::NormalSignature(normal_sig) => {
71                let normal_sig_type = NormalSignatureKind::try_from(normal_sig.signature_kind)
72                    .wrap_err("Couldn't convert SignatureId::NormalSignature to DepositSigKey")?;
73                use NormalSignatureKind::*;
74                match normal_sig_type {
75                    OperatorSighashDefault => Ok(Own(SighashDefault)),
76                    NormalSignatureUnknown => {
77                        Err(eyre::eyre!("Signature type is unknown, possible bad data").into())
78                    }
79                    Challenge => Ok(OperatorSharedDeposit(SinglePlusAnyoneCanPay)),
80                    DisproveTimeout2 => Ok(NofnSharedDeposit(SighashDefault)),
81                    Disprove2 => Ok(OperatorSharedDeposit(SighashDefault)),
82                    Reimburse1 => Ok(NofnSharedDeposit(SighashDefault)),
83                    KickoffNotFinalized1 => Ok(NofnSharedDeposit(SighashDefault)),
84                    KickoffNotFinalized2 => Ok(OperatorSharedDeposit(SighashDefault)),
85                    Reimburse2 => Ok(NofnSharedDeposit(SighashDefault)),
86                    NoSignature => Ok(NotOwned),
87                    ChallengeTimeout2 => Ok(NofnSharedDeposit(SighashDefault)),
88                    MiniAssert1 => Ok(Own(SighashDefault)),
89                    OperatorChallengeAck1 => Ok(Own(SighashDefault)),
90                    NotStored => Ok(NotOwned),
91                    YieldKickoffTxid => Ok(NotOwned),
92                    LatestBlockhashTimeout1 => Ok(NofnSharedDeposit(SighashDefault)),
93                    LatestBlockhashTimeout2 => Ok(NofnSharedDeposit(SighashDefault)),
94                    LatestBlockhashTimeout3 => Ok(OperatorSharedDeposit(SighashDefault)),
95                    LatestBlockhash => Ok(Own(SighashDefault)),
96                }
97            }
98            SignatureId::NumberedSignature(numbered_sig) => {
99                let numbered_sig_type = NumberedSignatureKind::try_from(
100                    numbered_sig.signature_kind,
101                )
102                .wrap_err("Couldn't convert SignatureId::NumberedSignature to DepositSigKey")?;
103                use NumberedSignatureKind::*;
104                match numbered_sig_type {
105                    OperatorChallengeNack1 => Ok(NofnSharedDeposit(SighashDefault)),
106                    OperatorChallengeNack2 => Ok(NofnSharedDeposit(SighashDefault)),
107                    NumberedSignatureUnknown => Err(eyre::eyre!(
108                        "Numbered signature type is unknown, possible bad data"
109                    )
110                    .into()),
111                    NumberedNotStored => Ok(Own(SighashDefault)),
112                    OperatorChallengeNack3 => Ok(OperatorSharedDeposit(SighashDefault)),
113                    AssertTimeout1 => Ok(NofnSharedDeposit(SighashDefault)),
114                    AssertTimeout2 => Ok(NofnSharedDeposit(SighashDefault)),
115                    AssertTimeout3 => Ok(OperatorSharedDeposit(SighashDefault)),
116                    UnspentKickoff1 => Ok(OperatorSharedSetup(SighashDefault)),
117                    UnspentKickoff2 => Ok(OperatorSharedSetup(SighashDefault)),
118                    WatchtowerChallengeTimeout1 => Ok(NofnSharedDeposit(SighashDefault)),
119                    WatchtowerChallengeTimeout2 => Ok(NofnSharedDeposit(SighashDefault)),
120                    WatchtowerChallenge => Ok(Own(SighashDefault)),
121                }
122            }
123        }
124    }
125}