X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fscript.rs;fp=lightning%2Fsrc%2Fln%2Fscript.rs;h=69b09e958d9f08507529f4da890710b585a77d97;hb=25a6a77468b3108555cc6ab3b716cd8934584646;hp=0000000000000000000000000000000000000000;hpb=e861ad66f162b2546507cfedcf160462ea39a8eb;p=rust-lightning diff --git a/lightning/src/ln/script.rs b/lightning/src/ln/script.rs new file mode 100644 index 00000000..69b09e95 --- /dev/null +++ b/lightning/src/ln/script.rs @@ -0,0 +1,196 @@ +//! Abstractions for scripts used in the Lightning Network. + +use bitcoin::bech32::u5; +use bitcoin::blockdata::opcodes::all::OP_PUSHBYTES_0 as SEGWIT_V0; +use bitcoin::blockdata::script::Script; +use bitcoin::hashes::Hash; +use bitcoin::hash_types::{PubkeyHash, ScriptHash, WPubkeyHash, WScriptHash}; +use bitcoin::secp256k1::key::PublicKey; + +use ln::features::InitFeatures; + +use std::convert::From; +use std::convert::TryFrom; + +/// A script pubkey for shutting down a channel as defined by [BOLT #2]. +/// +/// [BOLT #2]: https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md +pub struct ShutdownScript(ShutdownScriptImpl); + +/// An error occurring when converting from [`Script`] to [`ShutdownScript`]. +#[derive(Debug)] +pub struct InvalidShutdownScript(Script); + +enum ShutdownScriptImpl { + /// [`PublicKey`] used to form a P2WPKH script pubkey. Used to support backward-compatible + /// serialization. + Legacy(PublicKey), + + /// [`Script`] adhering to a script pubkey format specified in BOLT #2. + Bolt2(Script), +} + +impl ShutdownScript { + /// Generates a P2PKH script pubkey from the given [`PubkeyHash`]. + pub fn new_p2pkh(pubkey_hash: &PubkeyHash) -> Self { + Self(ShutdownScriptImpl::Bolt2(Script::new_p2pkh(pubkey_hash))) + } + + /// Generates a P2SH script pubkey from the given [`ScriptHash`]. + pub fn new_p2sh(script_hash: &ScriptHash) -> Self { + Self(ShutdownScriptImpl::Bolt2(Script::new_p2sh(script_hash))) + } + + /// Generates a P2WPKH script pubkey from the given [`WPubkeyHash`]. + pub fn new_p2wpkh(pubkey_hash: &WPubkeyHash) -> Self { + Self(ShutdownScriptImpl::Bolt2(Script::new_v0_wpkh(pubkey_hash))) + } + + /// Generates a P2WSH script pubkey from the given [`WScriptHash`]. + pub fn new_p2wsh(script_hash: &WScriptHash) -> Self { + Self(ShutdownScriptImpl::Bolt2(Script::new_v0_wsh(script_hash))) + } + + /// Generates a P2WSH script pubkey from the given segwit version and program. + /// + /// # Panics + /// + /// This function may panic if given a segwit program with an invalid length. + pub fn new_witness_program(version: u5, program: &[u8]) -> Self { + let script = Script::new_witness_program(version, program); + Self::try_from(script).expect("Invalid segwit program") + } + + /// Converts the shutdown script into the underlying [`Script`]. + pub fn into_inner(self) -> Script { + self.into() + } +} + +impl From for ShutdownScript { + fn from(pubkey: PublicKey) -> Self { + Self(ShutdownScriptImpl::Legacy(pubkey)) + } +} + +impl TryFrom