Skip to content

Commit ce28476

Browse files
committed
Introduce ClosingTransaction
1 parent 4268562 commit ce28476

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
@@ -872,6 +872,129 @@ impl BuiltCommitmentTransaction {
872872
}
873873
}
874874

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

0 commit comments

Comments
 (0)