Skip to content

Commit 6265da0

Browse files
committed
Correct the on-chain script checked in gossip verification
The `bitcoin_key_1` and `bitcoin_key_2` fields in `channel_announcement` messages are sorted according to node_ids rather than the keys themselves, however the on-chain funding script is sorted according to the bitcoin keys themselves. Thus, with some probability, we end up checking that the on-chain script matches the wrong script and rejecting the channel announcement. The correct solution is to use our existing channel funding script generation function which ensure we always match what we generate. This was found in testing the Java bindings, where a test checks that retunring the generated funding script in `chain::Access` results in the constructed channel ending up in our network graph.
1 parent d024251 commit 6265da0

File tree

1 file changed

+9
-17
lines changed

1 file changed

+9
-17
lines changed

lightning/src/routing/gossip.rs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@ use bitcoin::secp256k1;
1616

1717
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
1818
use bitcoin::hashes::Hash;
19-
use bitcoin::blockdata::script::Builder;
2019
use bitcoin::blockdata::transaction::TxOut;
21-
use bitcoin::blockdata::opcodes;
2220
use bitcoin::hash_types::BlockHash;
2321

2422
use chain;
2523
use chain::Access;
24+
use ln::chan_utils::make_funding_redeemscript;
2625
use ln::features::{ChannelFeatures, NodeFeatures};
2726
use ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHandler, NetAddress, MAX_VALUE_MSAT};
2827
use ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, GossipTimestampFilter};
@@ -1455,11 +1454,8 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
14551454
&Some(ref chain_access) => {
14561455
match chain_access.get_utxo(&msg.chain_hash, msg.short_channel_id) {
14571456
Ok(TxOut { value, script_pubkey }) => {
1458-
let expected_script = Builder::new().push_opcode(opcodes::all::OP_PUSHNUM_2)
1459-
.push_slice(&msg.bitcoin_key_1.serialize())
1460-
.push_slice(&msg.bitcoin_key_2.serialize())
1461-
.push_opcode(opcodes::all::OP_PUSHNUM_2)
1462-
.push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script().to_v0_p2wsh();
1457+
let expected_script =
1458+
make_funding_redeemscript(&msg.bitcoin_key_1, &msg.bitcoin_key_2).to_v0_p2wsh();
14631459
if script_pubkey != expected_script {
14641460
return Err(LightningError{err: format!("Channel announcement key ({}) didn't match on-chain script ({})", script_pubkey.to_hex(), expected_script.to_hex()), action: ErrorAction::IgnoreError});
14651461
}
@@ -1836,6 +1832,7 @@ impl ReadOnlyNetworkGraph<'_> {
18361832
#[cfg(test)]
18371833
mod tests {
18381834
use chain;
1835+
use ln::chan_utils::make_funding_redeemscript;
18391836
use ln::PaymentHash;
18401837
use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
18411838
use routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate, NodeAlias, MAX_EXCESS_BYTES_FOR_RELAY, NodeId, RoutingFees, ChannelUpdateInfo, ChannelInfo, NodeAnnouncementInfo, NodeInfo};
@@ -1853,9 +1850,8 @@ mod tests {
18531850
use bitcoin::hashes::Hash;
18541851
use bitcoin::network::constants::Network;
18551852
use bitcoin::blockdata::constants::genesis_block;
1856-
use bitcoin::blockdata::script::{Builder, Script};
1853+
use bitcoin::blockdata::script::Script;
18571854
use bitcoin::blockdata::transaction::TxOut;
1858-
use bitcoin::blockdata::opcodes;
18591855

18601856
use hex;
18611857

@@ -1945,14 +1941,10 @@ mod tests {
19451941
}
19461942

19471943
fn get_channel_script(secp_ctx: &Secp256k1<secp256k1::All>) -> Script {
1948-
let node_1_btckey = &SecretKey::from_slice(&[40; 32]).unwrap();
1949-
let node_2_btckey = &SecretKey::from_slice(&[39; 32]).unwrap();
1950-
Builder::new().push_opcode(opcodes::all::OP_PUSHNUM_2)
1951-
.push_slice(&PublicKey::from_secret_key(&secp_ctx, node_1_btckey).serialize())
1952-
.push_slice(&PublicKey::from_secret_key(&secp_ctx, node_2_btckey).serialize())
1953-
.push_opcode(opcodes::all::OP_PUSHNUM_2)
1954-
.push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script()
1955-
.to_v0_p2wsh()
1944+
let node_1_btckey = SecretKey::from_slice(&[40; 32]).unwrap();
1945+
let node_2_btckey = SecretKey::from_slice(&[39; 32]).unwrap();
1946+
make_funding_redeemscript(&PublicKey::from_secret_key(secp_ctx, &node_1_btckey),
1947+
&PublicKey::from_secret_key(secp_ctx, &node_2_btckey)).to_v0_p2wsh()
19561948
}
19571949

19581950
fn get_signed_channel_update<F: Fn(&mut UnsignedChannelUpdate)>(f: F, node_key: &SecretKey, secp_ctx: &Secp256k1<secp256k1::All>) -> ChannelUpdate {

0 commit comments

Comments
 (0)