Skip to content

Commit abf1739

Browse files
committed
Introduce ClosingTransaction
1 parent 3dd99eb commit abf1739

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

lightning/src/ln/chan_utils.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,129 @@ impl BuiltCommitmentTransaction {
890890
}
891891
}
892892

893+
/// This class tracks the per-transaction information needed to build a closing transaction and to
894+
/// actually build it and sign.
895+
///
896+
/// This class can be used inside a signer implementation to generate a signature given the relevant
897+
/// secret key.
898+
pub struct ClosingTransaction {
899+
to_holder_value_sat: u64,
900+
to_counterparty_value_sat: u64,
901+
to_holder_script: Script,
902+
to_counterparty_script: Script,
903+
built: Transaction,
904+
}
905+
906+
impl ClosingTransaction {
907+
/// Construct an object of the class
908+
pub fn new(
909+
to_holder_value_sat: u64,
910+
to_counterparty_value_sat: u64,
911+
to_holder_script: Script,
912+
to_counterparty_script: Script,
913+
funding_outpoint: OutPoint,
914+
) -> Self {
915+
let built = build_closing_transaction(
916+
to_holder_value_sat, to_counterparty_value_sat,
917+
to_holder_script.clone(), to_counterparty_script.clone(),
918+
funding_outpoint
919+
);
920+
ClosingTransaction {
921+
to_holder_value_sat,
922+
to_counterparty_value_sat,
923+
to_holder_script,
924+
to_counterparty_script,
925+
built
926+
}
927+
}
928+
929+
/// Trust our pre-built transaction.
930+
///
931+
/// Applies a wrapper which allows access to the transaction.
932+
///
933+
/// This should only be used if you fully trust the builder of this object. It should not
934+
/// be used by an external signer - instead use the verify function.
935+
pub fn trust(&self) -> TrustedClosingTransaction {
936+
TrustedClosingTransaction { inner: self }
937+
}
938+
939+
/// Verify our pre-built transaction.
940+
///
941+
/// Applies a wrapper which allows access to the transaction.
942+
///
943+
/// An external validating signer must call this method before signing
944+
/// or using the built transaction.
945+
pub fn verify(&self, funding_outpoint: OutPoint) -> Result<TrustedClosingTransaction, ()> {
946+
let built = build_closing_transaction(
947+
self.to_holder_value_sat, self.to_counterparty_value_sat,
948+
self.to_holder_script.clone(), self.to_counterparty_script.clone(),
949+
funding_outpoint
950+
);
951+
if self.built != built {
952+
return Err(())
953+
}
954+
Ok(TrustedClosingTransaction { inner: self })
955+
}
956+
957+
/// The value to be sent to the holder, or zero if the output will be omitted
958+
pub fn to_holder_value_sat(&self) -> u64 {
959+
self.to_holder_value_sat
960+
}
961+
962+
/// The value to be sent to the counterparty, or zero if the output will be omitted
963+
pub fn to_counterparty_value_sat(&self) -> u64 {
964+
self.to_counterparty_value_sat
965+
}
966+
967+
/// The destination of the holder's output
968+
pub fn to_holder_script(&self) -> &Script {
969+
&self.to_holder_script
970+
}
971+
972+
/// The destination of the counterparty's output
973+
pub fn to_counterparty_script(&self) -> &Script {
974+
&self.to_counterparty_script
975+
}
976+
}
977+
978+
/// A wrapper on ClosingTransaction indicating that the built bitcoin
979+
/// transaction is trusted.
980+
///
981+
/// See trust() and verify() functions on CommitmentTransaction.
982+
///
983+
/// This structure implements Deref.
984+
pub struct TrustedClosingTransaction<'a> {
985+
inner: &'a ClosingTransaction,
986+
}
987+
988+
impl<'a> Deref for TrustedClosingTransaction<'a> {
989+
type Target = ClosingTransaction;
990+
991+
fn deref(&self) -> &Self::Target { self.inner }
992+
}
993+
994+
impl<'a> TrustedClosingTransaction<'a> {
995+
/// The pre-built Bitcoin commitment transaction
996+
pub fn built_transaction(&self) -> &Transaction {
997+
&self.inner.built
998+
}
999+
1000+
/// Get the SIGHASH_ALL sighash value of the transaction.
1001+
///
1002+
/// This can be used to verify a signature.
1003+
pub fn get_sighash_all(&self, funding_redeemscript: &Script, channel_value_satoshis: u64) -> Message {
1004+
let sighash = &bip143::SigHashCache::new(&self.inner.built).signature_hash(0, funding_redeemscript, channel_value_satoshis, SigHashType::All)[..];
1005+
hash_to_message!(sighash)
1006+
}
1007+
1008+
/// Sign a transaction, either because we are counter-signing the counterparty's transaction or
1009+
/// because we are about to broadcast a holder transaction.
1010+
pub fn sign<T: secp256k1::Signing>(&self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>) -> Signature {
1011+
let sighash = self.get_sighash_all(funding_redeemscript, channel_value_satoshis);
1012+
secp_ctx.sign(&sighash, funding_key)
1013+
}
1014+
}
1015+
8931016
/// This class tracks the per-transaction information needed to build a commitment transaction and to
8941017
/// actually build it and sign. It is used for holder transactions that we sign only when needed
8951018
/// and for transactions we sign for the counterparty.

0 commit comments

Comments
 (0)