Skip to content

Commit 1074a11

Browse files
committed
Let ChannelSigner provide spks and weights compliant with LN spec
1 parent 5b57776 commit 1074a11

File tree

2 files changed

+103
-166
lines changed

2 files changed

+103
-166
lines changed

lightning/src/sign/mod.rs

Lines changed: 100 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,9 @@ pub trait ChannelSigner {
796796
/// channel_parameters.is_populated() MUST be true.
797797
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
798798

799+
/// Returns the parameters of this signer
800+
fn get_channel_parameters(&self) -> Option<&ChannelTransactionParameters>;
801+
799802
/// Returns the script pubkey that should be placed in the `to_remote` output of commitment
800803
/// transactions.
801804
///
@@ -804,7 +807,15 @@ pub trait ChannelSigner {
804807
///
805808
/// If `is_holder_tx` is set, return the `to_remote` script pubkey for the local party's commitment
806809
/// transaction, otherwise, for the remote party's.
807-
fn get_counterparty_payment_script(&self, is_holder_tx: bool) -> ScriptBuf;
810+
fn get_counterparty_payment_script(&self, is_holder_tx: bool) -> ScriptBuf {
811+
let params = if is_holder_tx {
812+
self.get_channel_parameters().unwrap().as_holder_broadcastable()
813+
} else {
814+
self.get_channel_parameters().unwrap().as_counterparty_broadcastable()
815+
};
816+
let payment_point = &params.countersignatory_pubkeys().payment_point;
817+
get_counterparty_payment_script(params.channel_type_features(), payment_point)
818+
}
808819

809820
/// Returns the script pubkey that should be placed in the `to_local` output of commitment
810821
/// transactions, and in the output of second level HTLC transactions.
@@ -815,9 +826,28 @@ pub trait ChannelSigner {
815826
/// If `is_holder_tx` is set, return the revokeable script pubkey for local party's
816827
/// commitment / htlc transaction, otherwise, for the remote party's.
817828
fn get_revokeable_spk(
818-
&self, is_holder_tx: bool, commitment_number: u64, per_commitment_point: &PublicKey,
829+
&self, is_holder_tx: bool, _commitment_number: u64, per_commitment_point: &PublicKey,
819830
secp_ctx: &Secp256k1<secp256k1::All>,
820-
) -> ScriptBuf;
831+
) -> ScriptBuf {
832+
let params = if is_holder_tx {
833+
self.get_channel_parameters().unwrap().as_holder_broadcastable()
834+
} else {
835+
self.get_channel_parameters().unwrap().as_counterparty_broadcastable()
836+
};
837+
let contest_delay = params.contest_delay();
838+
let keys = TxCreationKeys::from_channel_static_keys(
839+
per_commitment_point,
840+
params.broadcaster_pubkeys(),
841+
params.countersignatory_pubkeys(),
842+
secp_ctx,
843+
);
844+
get_revokeable_redeemscript(
845+
&keys.revocation_key,
846+
contest_delay,
847+
&keys.broadcaster_delayed_payment_key,
848+
)
849+
.to_p2wsh()
850+
}
821851

822852
/// Finalize the given input in a transaction spending an HTLC transaction output
823853
/// or a commitment transaction `to_local` output when our counterparty broadcasts an old state.
@@ -850,7 +880,9 @@ pub trait ChannelSigner {
850880

851881
/// Return the total weight of the witness required to spend the justice path of the revokeable
852882
/// output.
853-
fn get_punishment_witness_weight(&self) -> u64;
883+
fn get_punishment_witness_weight(&self) -> u64 {
884+
WEIGHT_REVOKED_OUTPUT
885+
}
854886

855887
/// Finalize the given input in a transaction spending a revoked HTLC output in a commitment
856888
/// transaction when our counterparty broadcasts an old state.
@@ -884,7 +916,14 @@ pub trait ChannelSigner {
884916

885917
/// Return the total weight of the witness required to spend the justice path of a HTLC output in a
886918
/// commitment transaction.
887-
fn get_htlc_punishment_witness_weight(&self, offered: bool) -> u64;
919+
fn get_htlc_punishment_witness_weight(&self, offered: bool) -> u64 {
920+
let features = &self.get_channel_parameters().unwrap().channel_type_features;
921+
if offered {
922+
weight_revoked_offered_htlc(features)
923+
} else {
924+
weight_revoked_received_htlc(features)
925+
}
926+
}
888927

889928
/// Sweep a HTLC output on a counterparty commitment transaction. Sweep an offered htlc output if
890929
/// the preimage is provided, otherwise, sweep a received htlc output.
@@ -895,7 +934,15 @@ pub trait ChannelSigner {
895934
) -> Result<Transaction, ()>;
896935

897936
/// Weight of the witness that sweeps htlc outputs in counterparty commitment transactions
898-
fn counterparty_htlc_output_witness_weight(&self, offered: bool) -> u64;
937+
fn counterparty_htlc_output_witness_weight(&self, offered: bool) -> u64 {
938+
let features = &self.get_channel_parameters().unwrap().channel_type_features;
939+
if offered {
940+
weight_offered_htlc(features)
941+
} else {
942+
weight_received_htlc(features)
943+
}
944+
}
945+
899946
/// Creates a signature for a holder's commitment transaction.
900947
///
901948
/// This will be called
@@ -950,24 +997,65 @@ pub trait ChannelSigner {
950997

951998
/// Gets the weight of the witness of the input that spends the htlc output of a
952999
/// holder commitment transaction
953-
fn get_holder_htlc_transaction_witness_weight(&self, offered: bool) -> u64;
1000+
fn get_holder_htlc_transaction_witness_weight(&self, offered: bool) -> u64 {
1001+
if offered {
1002+
chan_utils::HTLC_SUCCESS_INPUT_ANCHOR_WITNESS_WEIGHT
1003+
} else {
1004+
chan_utils::HTLC_TIMEOUT_INPUT_ANCHOR_WITNESS_WEIGHT
1005+
}
1006+
}
9541007

9551008
/// Gets the script pubkey of a htlc output in a commitment transaction
9561009
fn get_htlc_spk(
9571010
&self, htlc: &HTLCOutputInCommitment, is_holder_tx: bool, per_commitment_point: &PublicKey,
9581011
secp_ctx: &Secp256k1<secp256k1::All>,
959-
) -> ScriptBuf;
1012+
) -> ScriptBuf {
1013+
let params = if is_holder_tx {
1014+
self.get_channel_parameters().unwrap().as_holder_broadcastable()
1015+
} else {
1016+
self.get_channel_parameters().unwrap().as_counterparty_broadcastable()
1017+
};
1018+
let keys = TxCreationKeys::from_channel_static_keys(
1019+
per_commitment_point,
1020+
params.broadcaster_pubkeys(),
1021+
params.countersignatory_pubkeys(),
1022+
secp_ctx,
1023+
);
1024+
chan_utils::get_htlc_redeemscript(htlc, params.channel_type_features(), &keys).to_p2wsh()
1025+
}
9601026

9611027
/// Get the anchor output of a commit tx
962-
fn get_anchor_txout(&self, is_holder_tx: bool, is_broadcaster_anchor: bool) -> Option<TxOut>;
1028+
fn get_anchor_txout(&self, is_holder_tx: bool, is_broadcaster_anchor: bool) -> Option<TxOut> {
1029+
let channel_parameters = self.get_channel_parameters().unwrap();
1030+
if channel_parameters.channel_type_features.supports_anchors_zero_fee_htlc_tx() {
1031+
let params = if is_holder_tx {
1032+
channel_parameters.as_holder_broadcastable()
1033+
} else {
1034+
channel_parameters.as_counterparty_broadcastable()
1035+
};
1036+
let funding_key = if is_broadcaster_anchor {
1037+
params.broadcaster_pubkeys().funding_pubkey
1038+
} else {
1039+
params.countersignatory_pubkeys().funding_pubkey
1040+
};
1041+
Some(TxOut {
1042+
script_pubkey: get_anchor_redeemscript(&funding_key).to_p2wsh(),
1043+
value: Amount::from_sat(ANCHOR_OUTPUT_VALUE_SATOSHI),
1044+
})
1045+
} else {
1046+
None
1047+
}
1048+
}
9631049

9641050
/// Spend the holder anchor input
9651051
fn spend_holder_anchor_input(
9661052
&self, anchor_tx: &Transaction, input_idx: usize, secp_ctx: &Secp256k1<secp256k1::All>,
9671053
) -> Result<Transaction, ()>;
9681054

9691055
/// Get the weight of the witness to spend the holder anchor input
970-
fn get_holder_anchor_input_witness_weight(&self) -> u64;
1056+
fn get_holder_anchor_input_witness_weight(&self) -> u64 {
1057+
ANCHOR_INPUT_WITNESS_WEIGHT
1058+
}
9711059
}
9721060

9731061
/// Specifies the recipient of an invoice.
@@ -1338,15 +1426,6 @@ impl InMemorySigner {
13381426
self.get_channel_parameters().map(|params| params.funding_outpoint.as_ref()).flatten()
13391427
}
13401428

1341-
/// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
1342-
/// building transactions.
1343-
///
1344-
/// Will return `None` if [`ChannelSigner::provide_channel_parameters`] has not been called.
1345-
/// In general, this is safe to `unwrap` only in [`ChannelSigner`] implementation.
1346-
pub fn get_channel_parameters(&self) -> Option<&ChannelTransactionParameters> {
1347-
self.channel_parameters.as_ref()
1348-
}
1349-
13501429
/// Returns the channel type features of the channel parameters. Should be helpful for
13511430
/// determining a channel's category, i. e. legacy/anchors/taproot/etc.
13521431
///
@@ -1561,38 +1640,8 @@ impl ChannelSigner for InMemorySigner {
15611640
self.channel_parameters = Some(channel_parameters.clone());
15621641
}
15631642

1564-
fn get_counterparty_payment_script(&self, is_holder_tx: bool) -> ScriptBuf {
1565-
let params = if is_holder_tx {
1566-
self.channel_parameters.as_ref().unwrap().as_holder_broadcastable()
1567-
} else {
1568-
self.channel_parameters.as_ref().unwrap().as_counterparty_broadcastable()
1569-
};
1570-
let payment_point = &params.countersignatory_pubkeys().payment_point;
1571-
get_counterparty_payment_script(params.channel_type_features(), payment_point)
1572-
}
1573-
1574-
fn get_revokeable_spk(
1575-
&self, is_holder_tx: bool, _commitment_number: u64, per_commitment_point: &PublicKey,
1576-
secp_ctx: &Secp256k1<secp256k1::All>,
1577-
) -> ScriptBuf {
1578-
let params = if is_holder_tx {
1579-
self.channel_parameters.as_ref().unwrap().as_holder_broadcastable()
1580-
} else {
1581-
self.channel_parameters.as_ref().unwrap().as_counterparty_broadcastable()
1582-
};
1583-
let contest_delay = params.contest_delay();
1584-
let keys = TxCreationKeys::from_channel_static_keys(
1585-
per_commitment_point,
1586-
params.broadcaster_pubkeys(),
1587-
params.countersignatory_pubkeys(),
1588-
secp_ctx,
1589-
);
1590-
get_revokeable_redeemscript(
1591-
&keys.revocation_key,
1592-
contest_delay,
1593-
&keys.broadcaster_delayed_payment_key,
1594-
)
1595-
.to_p2wsh()
1643+
fn get_channel_parameters(&self) -> Option<&ChannelTransactionParameters> {
1644+
self.channel_parameters.as_ref()
15961645
}
15971646

15981647
fn punish_revokeable_output(
@@ -1629,10 +1678,6 @@ impl ChannelSigner for InMemorySigner {
16291678
Ok(justice_tx)
16301679
}
16311680

1632-
fn get_punishment_witness_weight(&self) -> u64 {
1633-
WEIGHT_REVOKED_OUTPUT
1634-
}
1635-
16361681
fn punish_htlc_output(
16371682
&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey,
16381683
secp_ctx: &Secp256k1<secp256k1::All>, per_commitment_point: &PublicKey,
@@ -1667,15 +1712,6 @@ impl ChannelSigner for InMemorySigner {
16671712
Ok(justice_tx)
16681713
}
16691714

1670-
fn get_htlc_punishment_witness_weight(&self, offered: bool) -> u64 {
1671-
let features = &self.channel_parameters.as_ref().unwrap().channel_type_features;
1672-
if offered {
1673-
weight_revoked_offered_htlc(features)
1674-
} else {
1675-
weight_revoked_received_htlc(features)
1676-
}
1677-
}
1678-
16791715
fn sweep_counterparty_htlc_output(
16801716
&self, sweep_tx: &Transaction, input: usize, amount: u64,
16811717
secp_ctx: &Secp256k1<secp256k1::All>, per_commitment_point: &PublicKey,
@@ -1711,15 +1747,6 @@ impl ChannelSigner for InMemorySigner {
17111747
Ok(sweep_tx)
17121748
}
17131749

1714-
fn counterparty_htlc_output_witness_weight(&self, offered: bool) -> u64 {
1715-
let features = &self.channel_parameters.as_ref().unwrap().channel_type_features;
1716-
if offered {
1717-
weight_offered_htlc(features)
1718-
} else {
1719-
weight_received_htlc(features)
1720-
}
1721-
}
1722-
17231750
fn sign_holder_commitment(
17241751
&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>,
17251752
) -> Result<Transaction, ()> {
@@ -1791,59 +1818,6 @@ impl ChannelSigner for InMemorySigner {
17911818
Ok(signed_tx)
17921819
}
17931820

1794-
fn get_holder_htlc_transaction_witness_weight(&self, offered: bool) -> u64 {
1795-
if offered {
1796-
chan_utils::HTLC_SUCCESS_INPUT_ANCHOR_WITNESS_WEIGHT
1797-
} else {
1798-
chan_utils::HTLC_TIMEOUT_INPUT_ANCHOR_WITNESS_WEIGHT
1799-
}
1800-
}
1801-
1802-
fn get_htlc_spk(
1803-
&self, htlc: &HTLCOutputInCommitment, is_holder_tx: bool, per_commitment_point: &PublicKey,
1804-
secp_ctx: &Secp256k1<secp256k1::All>,
1805-
) -> ScriptBuf {
1806-
let params = if is_holder_tx {
1807-
self.channel_parameters.as_ref().unwrap().as_holder_broadcastable()
1808-
} else {
1809-
self.channel_parameters.as_ref().unwrap().as_counterparty_broadcastable()
1810-
};
1811-
let keys = TxCreationKeys::from_channel_static_keys(
1812-
per_commitment_point,
1813-
params.broadcaster_pubkeys(),
1814-
params.countersignatory_pubkeys(),
1815-
secp_ctx,
1816-
);
1817-
chan_utils::get_htlc_redeemscript(htlc, params.channel_type_features(), &keys).to_p2wsh()
1818-
}
1819-
1820-
fn get_anchor_txout(&self, is_holder_tx: bool, is_broadcaster_anchor: bool) -> Option<TxOut> {
1821-
if self
1822-
.channel_parameters
1823-
.as_ref()
1824-
.unwrap()
1825-
.channel_type_features
1826-
.supports_anchors_zero_fee_htlc_tx()
1827-
{
1828-
let params = if is_holder_tx {
1829-
self.channel_parameters.as_ref().unwrap().as_holder_broadcastable()
1830-
} else {
1831-
self.channel_parameters.as_ref().unwrap().as_counterparty_broadcastable()
1832-
};
1833-
let funding_key = if is_broadcaster_anchor {
1834-
params.broadcaster_pubkeys().funding_pubkey
1835-
} else {
1836-
params.countersignatory_pubkeys().funding_pubkey
1837-
};
1838-
Some(TxOut {
1839-
script_pubkey: get_anchor_redeemscript(&funding_key).to_p2wsh(),
1840-
value: Amount::from_sat(ANCHOR_OUTPUT_VALUE_SATOSHI),
1841-
})
1842-
} else {
1843-
None
1844-
}
1845-
}
1846-
18471821
fn spend_holder_anchor_input(
18481822
&self, anchor_tx: &Transaction, input_idx: usize, secp_ctx: &Secp256k1<secp256k1::All>,
18491823
) -> Result<Transaction, ()> {
@@ -1855,10 +1829,6 @@ impl ChannelSigner for InMemorySigner {
18551829
tx.input[input_idx].witness = witness;
18561830
Ok(tx)
18571831
}
1858-
1859-
fn get_holder_anchor_input_witness_weight(&self) -> u64 {
1860-
ANCHOR_INPUT_WITNESS_WEIGHT
1861-
}
18621832
}
18631833

18641834
const MISSING_PARAMS_ERR: &'static str =

0 commit comments

Comments
 (0)