diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index a00404497fa..96180a6c5a5 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -259,18 +259,18 @@ impl SignerProvider for KeyProvider { }) } - fn get_destination_script(&self) -> Script { + fn get_destination_script(&self) -> Result { let secp_ctx = Secp256k1::signing_only(); let channel_monitor_claim_key = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, self.node_secret[31]]).unwrap(); let our_channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); - Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script() + Ok(Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script()) } - fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { + fn get_shutdown_scriptpubkey(&self) -> Result { let secp_ctx = Secp256k1::signing_only(); let secret_key = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, self.node_secret[31]]).unwrap(); let pubkey_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &secret_key).serialize()); - ShutdownScript::new_p2wpkh(&pubkey_hash) + Ok(ShutdownScript::new_p2wpkh(&pubkey_hash)) } } diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index b1290708b95..eb4943520dc 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -545,13 +545,13 @@ pub trait SignerProvider { /// /// This method should return a different value each time it is called, to avoid linking /// on-chain funds across channels as controlled to the same user. - fn get_destination_script(&self) -> Script; + fn get_destination_script(&self) -> Result; /// Get a script pubkey which we will send funds to when closing a channel. /// /// This method should return a different value each time it is called, to avoid linking /// on-chain funds across channels as controlled to the same user. - fn get_shutdown_scriptpubkey(&self) -> ShutdownScript; + fn get_shutdown_scriptpubkey(&self) -> Result; } /// A simple implementation of [`WriteableEcdsaChannelSigner`] that just keeps the private keys in memory. @@ -1366,12 +1366,12 @@ impl SignerProvider for KeysManager { InMemorySigner::read(&mut io::Cursor::new(reader), self) } - fn get_destination_script(&self) -> Script { - self.destination_script.clone() + fn get_destination_script(&self) -> Result { + Ok(self.destination_script.clone()) } - fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { - ShutdownScript::new_p2wpkh_from_pubkey(self.shutdown_pubkey.clone()) + fn get_shutdown_scriptpubkey(&self) -> Result { + Ok(ShutdownScript::new_p2wpkh_from_pubkey(self.shutdown_pubkey.clone())) } } @@ -1461,11 +1461,11 @@ impl SignerProvider for PhantomKeysManager { self.inner.read_chan_signer(reader) } - fn get_destination_script(&self) -> Script { + fn get_destination_script(&self) -> Result { self.inner.get_destination_script() } - fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { + fn get_shutdown_scriptpubkey(&self) -> Result { self.inner.get_shutdown_scriptpubkey() } } diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index dd553c1ff86..453349ab277 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -986,7 +986,10 @@ impl Channel { secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes()); let shutdown_scriptpubkey = if config.channel_handshake_config.commit_upfront_shutdown_pubkey { - Some(signer_provider.get_shutdown_scriptpubkey()) + match signer_provider.get_shutdown_scriptpubkey() { + Ok(scriptpubkey) => Some(scriptpubkey), + Err(_) => return Err(APIError::ChannelUnavailable { err: "Failed to get shutdown scriptpubkey".to_owned()}), + } } else { None }; if let Some(shutdown_scriptpubkey) = &shutdown_scriptpubkey { @@ -995,6 +998,11 @@ impl Channel { } } + let destination_script = match signer_provider.get_destination_script() { + Ok(script) => script, + Err(_) => return Err(APIError::ChannelUnavailable { err: "Failed to get destination script".to_owned()}), + }; + let temporary_channel_id = entropy_source.get_secure_random_bytes(); Ok(Channel { @@ -1021,7 +1029,7 @@ impl Channel { holder_signer, shutdown_scriptpubkey, - destination_script: signer_provider.get_destination_script(), + destination_script, cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER, cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER, @@ -1333,7 +1341,10 @@ impl Channel { } else { None }; let shutdown_scriptpubkey = if config.channel_handshake_config.commit_upfront_shutdown_pubkey { - Some(signer_provider.get_shutdown_scriptpubkey()) + match signer_provider.get_shutdown_scriptpubkey() { + Ok(scriptpubkey) => Some(scriptpubkey), + Err(_) => return Err(ChannelError::Close("Failed to get upfront shutdown scriptpubkey".to_owned())), + } } else { None }; if let Some(shutdown_scriptpubkey) = &shutdown_scriptpubkey { @@ -1342,6 +1353,11 @@ impl Channel { } } + let destination_script = match signer_provider.get_destination_script() { + Ok(script) => script, + Err(_) => return Err(ChannelError::Close("Failed to get destination script".to_owned())), + }; + let mut secp_ctx = Secp256k1::new(); secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes()); @@ -1368,7 +1384,7 @@ impl Channel { holder_signer, shutdown_scriptpubkey, - destination_script: signer_provider.get_destination_script(), + destination_script, cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER, cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER, @@ -4355,7 +4371,10 @@ impl Channel { Some(_) => false, None => { assert!(send_shutdown); - let shutdown_scriptpubkey = signer_provider.get_shutdown_scriptpubkey(); + let shutdown_scriptpubkey = match signer_provider.get_shutdown_scriptpubkey() { + Ok(scriptpubkey) => scriptpubkey, + Err(_) => return Err(ChannelError::Close("Failed to get upfront shutdown scriptpubkey".to_owned())), + }; if !shutdown_scriptpubkey.is_compatible(their_features) { return Err(ChannelError::Close(format!("Provided a scriptpubkey format not accepted by peer: {}", shutdown_scriptpubkey))); } @@ -6062,7 +6081,10 @@ impl Channel { let update_shutdown_script = match self.shutdown_scriptpubkey { Some(_) => false, None if !chan_closed => { - let shutdown_scriptpubkey = signer_provider.get_shutdown_scriptpubkey(); + let shutdown_scriptpubkey = match signer_provider.get_shutdown_scriptpubkey() { + Ok(scriptpubkey) => scriptpubkey, + Err(_) => return Err(APIError::ChannelUnavailable { err: "Failed to get upfront shutdown scriptpubkey".to_owned() }), + }; if !shutdown_scriptpubkey.is_compatible(their_features) { return Err(APIError::IncompatibleShutdownScript { script: shutdown_scriptpubkey.clone() }); } @@ -7086,17 +7108,17 @@ mod tests { fn read_chan_signer(&self, _data: &[u8]) -> Result { panic!(); } - fn get_destination_script(&self) -> Script { + fn get_destination_script(&self) -> Result { let secp_ctx = Secp256k1::signing_only(); let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); let channel_monitor_claim_key_hash = WPubkeyHash::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); - Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&channel_monitor_claim_key_hash[..]).into_script() + Ok(Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&channel_monitor_claim_key_hash[..]).into_script()) } - fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { + fn get_shutdown_scriptpubkey(&self) -> Result { let secp_ctx = Secp256k1::signing_only(); let channel_close_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); - ShutdownScript::new_p2wpkh_from_pubkey(PublicKey::from_secret_key(&secp_ctx, &channel_close_key)) + Ok(ShutdownScript::new_p2wpkh_from_pubkey(PublicKey::from_secret_key(&secp_ctx, &channel_close_key))) } } diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index f5be1069858..49e0c6c31e6 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -669,7 +669,7 @@ fn test_unsupported_anysegwit_shutdown_script() { let nodes = create_network(3, &node_cfgs, &node_chanmgrs); // Check that using an unsupported shutdown script fails and a supported one succeeds. - let supported_shutdown_script = chanmon_cfgs[1].keys_manager.get_shutdown_scriptpubkey(); + let supported_shutdown_script = chanmon_cfgs[1].keys_manager.get_shutdown_scriptpubkey().unwrap(); let unsupported_shutdown_script = ShutdownScript::new_witness_program(WitnessVersion::V16, &[0, 40]).unwrap(); chanmon_cfgs[1].keys_manager diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 679652b2da4..a6d83e4563f 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -171,8 +171,8 @@ impl SignerProvider for OnlyReadsKeysInterface { )) } - fn get_destination_script(&self) -> Script { unreachable!(); } - fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); } + fn get_destination_script(&self) -> Result { Err(()) } + fn get_shutdown_scriptpubkey(&self) -> Result { Err(()) } } pub struct TestChainMonitor<'a> { @@ -793,14 +793,14 @@ impl SignerProvider for TestKeysInterface { )) } - fn get_destination_script(&self) -> Script { self.backing.get_destination_script() } + fn get_destination_script(&self) -> Result { self.backing.get_destination_script() } - fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { + fn get_shutdown_scriptpubkey(&self) -> Result { match &mut *self.expectations.lock().unwrap() { None => self.backing.get_shutdown_scriptpubkey(), Some(expectations) => match expectations.pop_front() { None => panic!("Unexpected get_shutdown_scriptpubkey"), - Some(expectation) => expectation.returns, + Some(expectation) => Ok(expectation.returns), }, } }