Merge pull request #1023 from TheBlueMatt/2021-07-par-gossip-processing
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Wed, 11 May 2022 17:24:16 +0000 (17:24 +0000)
committerGitHub <noreply@github.com>
Wed, 11 May 2022 17:24:16 +0000 (17:24 +0000)
51 files changed:
CONTRIBUTING.md
fuzz/Cargo.toml
fuzz/README.md
fuzz/src/chanmon_consistency.rs
fuzz/src/full_stack.rs
fuzz/src/peer_crypt.rs
fuzz/src/router.rs
lightning-background-processor/Cargo.toml
lightning-background-processor/src/lib.rs
lightning-block-sync/Cargo.toml
lightning-block-sync/src/test_utils.rs
lightning-invoice/Cargo.toml
lightning-invoice/src/de.rs
lightning-invoice/src/lib.rs
lightning-invoice/src/payment.rs
lightning-invoice/src/utils.rs
lightning-invoice/tests/ser_de.rs
lightning-net-tokio/Cargo.toml
lightning-net-tokio/src/lib.rs
lightning-persister/Cargo.toml
lightning/Cargo.toml
lightning/src/chain/channelmonitor.rs
lightning/src/chain/keysinterface.rs
lightning/src/chain/onchaintx.rs
lightning/src/chain/package.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/msgs.rs
lightning/src/ln/onion_route_tests.rs
lightning/src/ln/onion_utils.rs
lightning/src/ln/peer_channel_encryptor.rs
lightning/src/ln/peer_handler.rs
lightning/src/ln/priv_short_conf_tests.rs
lightning/src/ln/reorg_tests.rs
lightning/src/ln/script.rs
lightning/src/ln/shutdown_tests.rs
lightning/src/routing/network_graph.rs
lightning/src/routing/router.rs
lightning/src/routing/scoring.rs
lightning/src/util/crypto.rs
lightning/src/util/enforcing_trait_impls.rs
lightning/src/util/events.rs
lightning/src/util/macro_logger.rs
lightning/src/util/message_signing.rs
lightning/src/util/persist.rs
lightning/src/util/ser.rs
lightning/src/util/test_utils.rs
lightning/src/util/transaction_utils.rs

index ab6ba2a410fb245c13fc1c7a6157a36448e9d07f..e2c5252dc6ff4213cddb0d2c21ee184471e2b952 100644 (file)
@@ -56,7 +56,7 @@ The codebase is maintained using the "contributor workflow" where everyone
 without exception contributes patch proposals using "pull requests". This
 facilitates social contribution, easy testing and peer review.
 
-To contribute a patch, the worflow is a as follows:
+To contribute a patch, the workflow is as follows:
 
   1. Fork Repository
   2. Create topic branch
@@ -73,7 +73,7 @@ must be given to the long term technical debt. Every new features should
 be covered by functional tests.
 
 When refactoring, structure your PR to make it easy to review and don't
-hestitate to split it into multiple small, focused PRs.
+hesitate to split it into multiple small, focused PRs.
 
 The Minimum Supported Rust Version is 1.41.1 (enforced by our GitHub Actions).
 
index bc1f0a479f1cb074937d689b33c398c73d2f6420..88e577617b54faeab07ba0e61a213d29f726b1ba 100644 (file)
@@ -19,7 +19,7 @@ stdin_fuzz = []
 [dependencies]
 afl = { version = "0.4", optional = true }
 lightning = { path = "../lightning", features = ["regex"] }
-bitcoin = { version = "0.27", features = ["fuzztarget", "secp-lowmemory"] }
+bitcoin = { version = "0.28.1", features = ["secp-lowmemory"] }
 hex = "0.3"
 honggfuzz = { version = "0.5", optional = true }
 libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git", optional = true }
index dfa90fc0f979aa9d5f41de43e250140183939ec9..bfc8fa5f4bfb5c6ae71b5d1262d17bb831d1ee52 100644 (file)
@@ -24,6 +24,13 @@ cargo update
 cargo install --force honggfuzz
 ```
 
+In some environments, you may want to pin the honggfuzz version to `0.5.52`:
+
+```shell
+cargo update -p honggfuzz --precise "0.5.52"
+cargo install --force honggfuzz --version "0.5.52"
+```
+
 ### Execution
 
 To run the Hongg fuzzer, do
@@ -34,9 +41,11 @@ export HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz"
 export HFUZZ_RUN_ARGS="-n $CPU_COUNT --exit_upon_crash"
 
 export TARGET="msg_ping_target" # replace with the target to be fuzzed
-cargo hfuzz run $TARGET 
+cargo hfuzz run $TARGET
 ```
 
+(Or, for a prettier output, replace the last line with `cargo --color always hfuzz run $TARGET`.)
+
 To see a list of available fuzzing targets, run:
 
 ```shell
@@ -84,4 +93,38 @@ export RUSTFLAGS="--cfg=fuzzing"
 cargo test
 ```
 
+Note that if the fuzz test failed locally, moving the offending run's trace 
+to the `test_cases` folder should also do the trick; simply replace the `echo $HEX |` line above
+with (the trace file name is of course a bit longer than in the example):
+
+```shell
+mv hfuzz_workspace/fuzz_target/SIGABRT.PC.7ffff7e21ce1.STACK.[…].fuzz ./test_cases/$TARGET/
+```
+
 This will reproduce the failing fuzz input and yield a usable stack trace.
+
+
+## How do I add a new fuzz test?
+
+1. The easiest approach is to take one of the files in `fuzz/src/`, such as 
+`process_network_graph.rs`, and duplicate it, renaming the new file to something more 
+suitable. For the sake of example, let's call the new fuzz target we're creating 
+`my_fuzzy_experiment`.
+
+2. In the newly created file `fuzz/src/my_fuzzy_experiment.rs`, run a string substitution
+of `process_network_graph` to `my_fuzzy_experiment`, such that the three methods in the
+file are `do_test`, `my_fuzzy_experiment_test`, and `my_fuzzy_experiment_run`.
+
+3. Adjust the body (not the signature!) of `do_test` as necessary for the new fuzz test.
+
+4. In `fuzz/src/bin/gen_target.sh`, add a line reading `GEN_TEST my_fuzzy_experiment` to the 
+first group of `GEN_TEST` lines (starting in line 9).
+
+5. If your test relies on a new local crate, add that crate as a dependency to `fuzz/Cargo.toml`.
+
+6. In `fuzz/src/lib.rs`, add the line `pub mod my_fuzzy_experiment`. Additionally, if 
+you added a new crate dependency, add the `extern crate […]` import line.
+
+7. Run `fuzz/src/bin/gen_target.sh`.
+
+8. There is no step eight: happy fuzzing!
index 8c4f5adcb64ae64abbbc03b0956c556f3abbf44c..8472f8fa6278a4e158e810a600895545cbbd27ae 100644 (file)
@@ -53,8 +53,8 @@ use lightning::routing::router::{Route, RouteHop};
 use utils::test_logger::{self, Output};
 use utils::test_persister::TestPersister;
 
-use bitcoin::secp256k1::key::{PublicKey,SecretKey};
-use bitcoin::secp256k1::recovery::RecoverableSignature;
+use bitcoin::secp256k1::{PublicKey,SecretKey};
+use bitcoin::secp256k1::ecdsa::RecoverableSignature;
 use bitcoin::secp256k1::Secp256k1;
 
 use std::mem;
index 0412547a0089a150db7f8038d7c4454a8bf05b02..330124f8a8942a23585517148096a80bc984dd4b 100644 (file)
@@ -50,8 +50,8 @@ use lightning::util::ser::ReadableArgs;
 use utils::test_logger;
 use utils::test_persister::TestPersister;
 
-use bitcoin::secp256k1::key::{PublicKey,SecretKey};
-use bitcoin::secp256k1::recovery::RecoverableSignature;
+use bitcoin::secp256k1::{PublicKey,SecretKey};
+use bitcoin::secp256k1::ecdsa::RecoverableSignature;
 use bitcoin::secp256k1::Secp256k1;
 
 use std::cell::RefCell;
index f41137fc828b02c003110d34d4f91f4f84fd51d4..9bef432982497af54dc5c0f9912e22558f79f30b 100644 (file)
@@ -9,7 +9,7 @@
 
 use lightning::ln::peer_channel_encryptor::PeerChannelEncryptor;
 
-use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+use bitcoin::secp256k1::{PublicKey,SecretKey};
 
 use utils::test_logger;
 
index 27c5ee2b7ca108a19bbe9f7ca3c5a7a5f91d01ae..786bfa3e589eb05dc393a807be90efc46c5febf7 100644 (file)
@@ -23,7 +23,7 @@ use lightning::util::ser::Readable;
 use lightning::routing::network_graph::{NetworkGraph, RoutingFees};
 
 use bitcoin::hashes::Hash;
-use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::PublicKey;
 use bitcoin::network::constants::Network;
 use bitcoin::blockdata::constants::genesis_block;
 
index 16ec763fb8c3a4f48f5bb3ea773e4372b12984f3..00061ee6e5e852122e490b42420db81ca53c5859 100644 (file)
@@ -14,7 +14,7 @@ all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
 
 [dependencies]
-bitcoin = "0.27"
+bitcoin = "0.28.1"
 lightning = { version = "0.0.106", path = "../lightning", features = ["std"] }
 
 [dev-dependencies]
index e23737c0adcf16fec641c0d48aac940645c54716..107f65f9b74f141cdb087eded0befe59d4c9dfac 100644 (file)
@@ -18,6 +18,7 @@ use lightning::ln::channelmanager::ChannelManager;
 use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler};
 use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager, SocketDescriptor};
 use lightning::routing::network_graph::{NetworkGraph, NetGraphMsgHandler};
+use lightning::routing::scoring::WriteableScore;
 use lightning::util::events::{Event, EventHandler, EventsProvider};
 use lightning::util::logger::Logger;
 use lightning::util::persist::Persister;
@@ -151,6 +152,7 @@ impl BackgroundProcessor {
        /// [`NetworkGraph`]: lightning::routing::network_graph::NetworkGraph
        /// [`NetworkGraph::write`]: lightning::routing::network_graph::NetworkGraph#impl-Writeable
        pub fn start<
+               'a,
                Signer: 'static + Sign,
                CA: 'static + Deref + Send + Sync,
                CF: 'static + Deref + Send + Sync,
@@ -171,9 +173,11 @@ impl BackgroundProcessor {
                NG: 'static + Deref<Target = NetGraphMsgHandler<G, CA, L>> + Send + Sync,
                UMH: 'static + Deref + Send + Sync,
                PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, L, UMH>> + Send + Sync,
+               S: 'static + Deref<Target = SC> + Send + Sync,
+               SC: WriteableScore<'a>,
        >(
                persister: PS, event_handler: EH, chain_monitor: M, channel_manager: CM,
-               net_graph_msg_handler: Option<NG>, peer_manager: PM, logger: L
+               net_graph_msg_handler: Option<NG>, peer_manager: PM, logger: L, scorer: Option<S>
        ) -> Self
        where
                CA::Target: 'static + chain::Access,
@@ -187,7 +191,7 @@ impl BackgroundProcessor {
                CMH::Target: 'static + ChannelMessageHandler,
                RMH::Target: 'static + RoutingMessageHandler,
                UMH::Target: 'static + CustomMessageHandler,
-               PS::Target: 'static + Persister<Signer, CW, T, K, F, L>
+               PS::Target: 'static + Persister<'a, Signer, CW, T, K, F, L, SC>,
        {
                let stop_thread = Arc::new(AtomicBool::new(false));
                let stop_thread_clone = stop_thread.clone();
@@ -274,9 +278,16 @@ impl BackgroundProcessor {
                                                if let Err(e) = persister.persist_graph(handler.network_graph()) {
                                                        log_error!(logger, "Error: Failed to persist network graph, check your disk and permissions {}", e)
                                                }
-                                               last_prune_call = Instant::now();
-                                               have_pruned = true;
                                        }
+                                       if let Some(ref scorer) = scorer {
+                                               log_trace!(logger, "Persisting scorer");
+                                               if let Err(e) = persister.persist_scorer(&scorer) {
+                                                       log_error!(logger, "Error: Failed to persist scorer, check your disk and permissions {}", e)
+                                               }
+                                       }
+
+                                       last_prune_call = Instant::now();
+                                       have_pruned = true;
                                }
                        }
 
@@ -285,10 +296,16 @@ impl BackgroundProcessor {
                        // ChannelMonitor update(s) persisted without a corresponding ChannelManager update.
                        persister.persist_manager(&*channel_manager)?;
 
+                       // Persist Scorer on exit
+                       if let Some(ref scorer) = scorer {
+                               persister.persist_scorer(&scorer)?;
+                       }
+
                        // Persist NetworkGraph on exit
                        if let Some(ref handler) = net_graph_msg_handler {
                                persister.persist_graph(handler.network_graph())?;
                        }
+
                        Ok(())
                });
                Self { stop_thread: stop_thread_clone, thread_handle: Some(handle) }
@@ -369,6 +386,7 @@ mod tests {
        use std::path::PathBuf;
        use std::sync::{Arc, Mutex};
        use std::time::Duration;
+       use lightning::routing::scoring::{FixedPenaltyScorer};
        use super::{BackgroundProcessor, FRESHNESS_TIMER};
 
        const EVENT_DEADLINE: u64 = 5 * FRESHNESS_TIMER;
@@ -395,6 +413,7 @@ mod tests {
                network_graph: Arc<NetworkGraph>,
                logger: Arc<test_utils::TestLogger>,
                best_block: BestBlock,
+               scorer: Arc<Mutex<FixedPenaltyScorer>>,
        }
 
        impl Drop for Node {
@@ -410,13 +429,14 @@ mod tests {
        struct Persister {
                graph_error: Option<(std::io::ErrorKind, &'static str)>,
                manager_error: Option<(std::io::ErrorKind, &'static str)>,
+               scorer_error: Option<(std::io::ErrorKind, &'static str)>,
                filesystem_persister: FilesystemPersister,
        }
 
        impl Persister {
                fn new(data_dir: String) -> Self {
                        let filesystem_persister = FilesystemPersister::new(data_dir.clone());
-                       Self { graph_error: None, manager_error: None, filesystem_persister }
+                       Self { graph_error: None, manager_error: None, scorer_error: None, filesystem_persister }
                }
 
                fn with_graph_error(self, error: std::io::ErrorKind, message: &'static str) -> Self {
@@ -426,6 +446,10 @@ mod tests {
                fn with_manager_error(self, error: std::io::ErrorKind, message: &'static str) -> Self {
                        Self { manager_error: Some((error, message)), ..self }
                }
+
+               fn with_scorer_error(self, error: std::io::ErrorKind, message: &'static str) -> Self {
+                       Self { scorer_error: Some((error, message)), ..self }
+               }
        }
 
        impl KVStorePersister for Persister {
@@ -442,6 +466,12 @@ mod tests {
                                }
                        }
 
+                       if key == "scorer" {
+                               if let Some((error, message)) = self.scorer_error {
+                                       return Err(std::io::Error::new(error, message))
+                               }
+                       }
+
                        self.filesystem_persister.persist(key, object)
                }
        }
@@ -473,7 +503,8 @@ mod tests {
                        let net_graph_msg_handler = Some(Arc::new(NetGraphMsgHandler::new(network_graph.clone(), Some(chain_source.clone()), logger.clone())));
                        let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new() )};
                        let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), &seed, logger.clone(), IgnoringMessageHandler{}));
-                       let node = Node { node: manager, net_graph_msg_handler, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block };
+                       let scorer = Arc::new(Mutex::new(test_utils::TestScorer::with_penalty(0)));
+                       let node = Node { node: manager, net_graph_msg_handler, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block, scorer };
                        nodes.push(node);
                }
 
@@ -571,7 +602,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                macro_rules! check_persisted_data {
                        ($node: expr, $filepath: expr) => {
@@ -621,6 +652,10 @@ mod tests {
                        check_persisted_data!(network_graph, filepath.clone());
                }
 
+               // Check scorer is persisted
+               let filepath = get_full_filepath("test_background_processor_persister_0".to_string(), "scorer".to_string());
+               check_persisted_data!(nodes[0].scorer, filepath.clone());
+
                assert!(bg_processor.stop().is_ok());
        }
 
@@ -632,7 +667,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
                loop {
                        let log_entries = nodes[0].logger.lines.lock().unwrap();
                        let desired_log = "Calling ChannelManager's timer_tick_occurred".to_string();
@@ -655,7 +690,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir).with_manager_error(std::io::ErrorKind::Other, "test"));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
                match bg_processor.join() {
                        Ok(_) => panic!("Expected error persisting manager"),
                        Err(e) => {
@@ -672,7 +707,7 @@ mod tests {
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir).with_graph_error(std::io::ErrorKind::Other, "test"));
                let event_handler = |_: &_| {};
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                match bg_processor.stop() {
                        Ok(_) => panic!("Expected error persisting network graph"),
@@ -683,6 +718,24 @@ mod tests {
                }
        }
 
+       #[test]
+       fn test_scorer_persist_error() {
+               // Test that if we encounter an error during scorer persistence, an error gets returned.
+               let nodes = create_nodes(2, "test_persist_scorer_error".to_string());
+               let data_dir = nodes[0].persister.get_data_dir();
+               let persister = Arc::new(Persister::new(data_dir).with_scorer_error(std::io::ErrorKind::Other, "test"));
+               let event_handler = |_: &_| {};
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
+
+               match bg_processor.stop() {
+                       Ok(_) => panic!("Expected error persisting scorer"),
+                       Err(e) => {
+                               assert_eq!(e.kind(), std::io::ErrorKind::Other);
+                               assert_eq!(e.get_ref().unwrap().to_string(), "test");
+                       },
+               }
+       }
+
        #[test]
        fn test_background_event_handling() {
                let mut nodes = create_nodes(2, "test_background_event_handling".to_string());
@@ -695,7 +748,7 @@ mod tests {
                let event_handler = move |event: &Event| {
                        sender.send(handle_funding_generation_ready!(event, channel_value)).unwrap();
                };
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                // Open a channel and check that the FundingGenerationReady event was handled.
                begin_open_channel!(nodes[0], nodes[1], channel_value);
@@ -720,7 +773,7 @@ mod tests {
                let (sender, receiver) = std::sync::mpsc::sync_channel(1);
                let event_handler = move |event: &Event| sender.send(event.clone()).unwrap();
                let persister = Arc::new(Persister::new(data_dir));
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
 
                // Force close the channel and check that the SpendableOutputs event was handled.
                nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap();
@@ -747,11 +800,10 @@ mod tests {
                // Initiate the background processors to watch each node.
                let data_dir = nodes[0].persister.get_data_dir();
                let persister = Arc::new(Persister::new(data_dir));
-               let scorer = Arc::new(Mutex::new(test_utils::TestScorer::with_penalty(0)));
                let router = DefaultRouter::new(Arc::clone(&nodes[0].network_graph), Arc::clone(&nodes[0].logger), random_seed_bytes);
-               let invoice_payer = Arc::new(InvoicePayer::new(Arc::clone(&nodes[0].node), router, scorer, Arc::clone(&nodes[0].logger), |_: &_| {}, RetryAttempts(2)));
+               let invoice_payer = Arc::new(InvoicePayer::new(Arc::clone(&nodes[0].node), router, Arc::clone(&nodes[0].scorer), Arc::clone(&nodes[0].logger), |_: &_| {}, RetryAttempts(2)));
                let event_handler = Arc::clone(&invoice_payer);
-               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+               let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone()));
                assert!(bg_processor.stop().is_ok());
        }
 }
index 673034081588e373b6590aff9a4db111987862af..1d6e7f40accd8410ac0c7c42bb78f56665da4b7c 100644 (file)
@@ -18,7 +18,7 @@ rest-client = [ "serde", "serde_json", "chunked_transfer" ]
 rpc-client = [ "serde", "serde_json", "chunked_transfer" ]
 
 [dependencies]
-bitcoin = "0.27"
+bitcoin = "0.28.1"
 lightning = { version = "0.0.106", path = "../lightning" }
 futures = { version = "0.3" }
 tokio = { version = "1.0", features = [ "io-util", "net", "time" ], optional = true }
index c101d4bd3e8f0bdd516d2c0039cb579ceb5d5b89..baaab456b5adeb8fb25df64d6d306c011a0062dd 100644 (file)
@@ -6,6 +6,8 @@ use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::hash_types::BlockHash;
 use bitcoin::network::constants::Network;
 use bitcoin::util::uint::Uint256;
+use bitcoin::util::hash::bitcoin_merkle_root;
+use bitcoin::Transaction;
 
 use lightning::chain;
 
@@ -37,16 +39,27 @@ impl Blockchain {
                        let prev_block = &self.blocks[i - 1];
                        let prev_blockhash = prev_block.block_hash();
                        let time = prev_block.header.time + height as u32;
+                       // Must have at least one transaction, because the merkle root is not defined for an empty block
+                       // and we would fail when we later checked, as of bitcoin crate 0.28.0.
+                       // Note that elsewhere in tests we assume that the merkle root of an empty block is all zeros,
+                       // but that's OK because those tests don't trigger the check.
+                       let coinbase = Transaction {
+                               version: 0,
+                               lock_time: 0,
+                               input: vec![],
+                               output: vec![]
+                       };
+                       let merkle_root = bitcoin_merkle_root(vec![coinbase.txid().as_hash()].into_iter()).unwrap();
                        self.blocks.push(Block {
                                header: BlockHeader {
                                        version: 0,
                                        prev_blockhash,
-                                       merkle_root: Default::default(),
+                                       merkle_root: merkle_root.into(),
                                        time,
                                        bits,
                                        nonce: 0,
                                },
-                               txdata: vec![],
+                               txdata: vec![coinbase],
                        });
                }
                self
index 194f5f70e912627aed2123ad1a1d3aa68ea15051..f65d7ac886992dd488e7ed449486d755067d41ae 100644 (file)
@@ -20,7 +20,7 @@ std = ["bitcoin_hashes/std", "num-traits/std", "lightning/std", "bech32/std"]
 [dependencies]
 bech32 = { version = "0.8", default-features = false }
 lightning = { version = "0.0.106", path = "../lightning", default-features = false }
-secp256k1 = { version = "0.20", default-features = false, features = ["recovery", "alloc"] }
+secp256k1 = { version = "0.22", default-features = false, features = ["recovery", "alloc"] }
 num-traits = { version = "0.2.8", default-features = false }
 bitcoin_hashes = { version = "0.10", default-features = false }
 hashbrown = { version = "0.11", optional = true }
index 5de2b038e8b2d29a25df42705d5d7d378009a7fb..e9b639c101307dccd7e229caee1303c77a0bbca6 100644 (file)
@@ -19,8 +19,8 @@ use lightning::routing::router::{RouteHint, RouteHintHop};
 use num_traits::{CheckedAdd, CheckedMul};
 
 use secp256k1;
-use secp256k1::recovery::{RecoveryId, RecoverableSignature};
-use secp256k1::key::PublicKey;
+use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
+use secp256k1::PublicKey;
 
 use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
        SemanticError, PrivateRoute, ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice,
@@ -967,7 +967,7 @@ mod test {
        #[test]
        fn test_payment_secret_and_features_de_and_ser() {
                use lightning::ln::features::InvoiceFeatures;
-               use secp256k1::recovery::{RecoveryId, RecoverableSignature};
+               use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
                use TaggedField::*;
                use {SiPrefix, SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart,
                                 Currency, Sha256, PositiveTimestamp};
@@ -1014,7 +1014,7 @@ mod test {
        #[test]
        fn test_raw_signed_invoice_deserialization() {
                use TaggedField::*;
-               use secp256k1::recovery::{RecoveryId, RecoverableSignature};
+               use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
                use {SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256,
                         PositiveTimestamp};
 
index 5784607dde937b85fa384ed65a630d7af1d3ca3a..616ea99f0fe253cf2275862b1a63e6f0db3232f2 100644 (file)
@@ -47,9 +47,9 @@ use lightning::routing::network_graph::RoutingFees;
 use lightning::routing::router::RouteHint;
 use lightning::util::invoice::construct_invoice_preimage;
 
-use secp256k1::key::PublicKey;
+use secp256k1::PublicKey;
 use secp256k1::{Message, Secp256k1};
-use secp256k1::recovery::RecoverableSignature;
+use secp256k1::ecdsa::RecoverableSignature;
 
 use core::fmt::{Display, Formatter, self};
 use core::iter::FilterMap;
@@ -163,7 +163,7 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
 /// use bitcoin_hashes::sha256;
 ///
 /// use secp256k1::Secp256k1;
-/// use secp256k1::key::SecretKey;
+/// use secp256k1::SecretKey;
 ///
 /// use lightning::ln::PaymentSecret;
 ///
@@ -191,7 +191,7 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = 18;
 ///    .current_timestamp()
 ///    .min_final_cltv_expiry(144)
 ///    .build_signed(|hash| {
-///            Secp256k1::new().sign_recoverable(hash, &private_key)
+///            Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
 ///    })
 ///    .unwrap();
 ///
@@ -749,7 +749,7 @@ impl SignedRawInvoice {
                let hash = Message::from_slice(&self.hash[..])
                        .expect("Hash is 32 bytes long, same as MESSAGE_SIZE");
 
-               Ok(PayeePubKey(Secp256k1::new().recover(
+               Ok(PayeePubKey(Secp256k1::new().recover_ecdsa(
                        &hash,
                        &self.signature
                )?))
@@ -776,7 +776,7 @@ impl SignedRawInvoice {
                        .expect("Hash is 32 bytes long, same as MESSAGE_SIZE");
 
                let secp_context = Secp256k1::new();
-               let verification_result = secp_context.verify(
+               let verification_result = secp_context.verify_ecdsa(
                        &hash,
                        &self.signature.to_standard(),
                        pub_key
@@ -1576,8 +1576,8 @@ mod test {
        fn test_check_signature() {
                use TaggedField::*;
                use secp256k1::Secp256k1;
-               use secp256k1::recovery::{RecoveryId, RecoverableSignature};
-               use secp256k1::key::{SecretKey, PublicKey};
+               use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
+               use secp256k1::{SecretKey, PublicKey};
                use {SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256,
                         PositiveTimestamp};
 
@@ -1635,7 +1635,7 @@ mod test {
 
                let (raw_invoice, _, _) = invoice.into_parts();
                let new_signed = raw_invoice.sign::<_, ()>(|hash| {
-                       Ok(Secp256k1::new().sign_recoverable(hash, &private_key))
+                       Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
                }).unwrap();
 
                assert!(new_signed.check_signature());
@@ -1646,7 +1646,7 @@ mod test {
                use TaggedField::*;
                use lightning::ln::features::InvoiceFeatures;
                use secp256k1::Secp256k1;
-               use secp256k1::key::SecretKey;
+               use secp256k1::SecretKey;
                use {RawInvoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, Invoice,
                         SemanticError};
 
@@ -1677,7 +1677,7 @@ mod test {
                let invoice = {
                        let mut invoice = invoice_template.clone();
                        invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
-                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
+                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
                }.unwrap();
                assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures));
 
@@ -1686,7 +1686,7 @@ mod test {
                        let mut invoice = invoice_template.clone();
                        invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
                        invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into());
-                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
+                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
                }.unwrap();
                assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures));
 
@@ -1695,14 +1695,14 @@ mod test {
                        let mut invoice = invoice_template.clone();
                        invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
                        invoice.data.tagged_fields.push(Features(InvoiceFeatures::known()).into());
-                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
+                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
                }.unwrap();
                assert!(Invoice::from_signed(invoice).is_ok());
 
                // No payment secret or features
                let invoice = {
                        let invoice = invoice_template.clone();
-                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
+                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
                }.unwrap();
                assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
 
@@ -1710,7 +1710,7 @@ mod test {
                let invoice = {
                        let mut invoice = invoice_template.clone();
                        invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into());
-                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
+                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
                }.unwrap();
                assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
 
@@ -1718,7 +1718,7 @@ mod test {
                let invoice = {
                        let mut invoice = invoice_template.clone();
                        invoice.data.tagged_fields.push(Features(InvoiceFeatures::known()).into());
-                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
+                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
                }.unwrap();
                assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret));
 
@@ -1727,7 +1727,7 @@ mod test {
                        let mut invoice = invoice_template.clone();
                        invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
                        invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into());
-                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_recoverable(hash, &private_key)))
+                       invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)))
                }.unwrap();
                assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::MultiplePaymentSecrets));
        }
@@ -1764,7 +1764,7 @@ mod test {
                use ::*;
                use lightning::routing::router::RouteHintHop;
                use std::iter::FromIterator;
-               use secp256k1::key::PublicKey;
+               use secp256k1::PublicKey;
 
                let builder = InvoiceBuilder::new(Currency::Bitcoin)
                        .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
@@ -1818,7 +1818,7 @@ mod test {
                use ::*;
                use lightning::routing::router::RouteHintHop;
                use secp256k1::Secp256k1;
-               use secp256k1::key::{SecretKey, PublicKey};
+               use secp256k1::{SecretKey, PublicKey};
                use std::time::{UNIX_EPOCH, Duration};
 
                let secp_ctx = Secp256k1::new();
@@ -1897,7 +1897,7 @@ mod test {
                        .basic_mpp();
 
                let invoice = builder.clone().build_signed(|hash| {
-                       secp_ctx.sign_recoverable(hash, &private_key)
+                       secp_ctx.sign_ecdsa_recoverable(hash, &private_key)
                }).unwrap();
 
                assert!(invoice.check_signature().is_ok());
@@ -1932,7 +1932,7 @@ mod test {
        fn test_default_values() {
                use ::*;
                use secp256k1::Secp256k1;
-               use secp256k1::key::SecretKey;
+               use secp256k1::SecretKey;
 
                let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
                        .description("Test".into())
@@ -1944,7 +1944,7 @@ mod test {
                        .sign::<_, ()>(|hash| {
                                let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
                                let secp_ctx = Secp256k1::new();
-                               Ok(secp_ctx.sign_recoverable(hash, &privkey))
+                               Ok(secp_ctx.sign_ecdsa_recoverable(hash, &privkey))
                        })
                        .unwrap();
                let invoice = Invoice::from_signed(signed_invoice).unwrap();
@@ -1958,7 +1958,7 @@ mod test {
        fn test_expiration() {
                use ::*;
                use secp256k1::Secp256k1;
-               use secp256k1::key::SecretKey;
+               use secp256k1::SecretKey;
 
                let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
                        .description("Test".into())
@@ -1970,7 +1970,7 @@ mod test {
                        .sign::<_, ()>(|hash| {
                                let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
                                let secp_ctx = Secp256k1::new();
-                               Ok(secp_ctx.sign_recoverable(hash, &privkey))
+                               Ok(secp_ctx.sign_ecdsa_recoverable(hash, &privkey))
                        })
                        .unwrap();
                let invoice = Invoice::from_signed(signed_invoice).unwrap();
index 82c07199f0db871c1498fb64a21e63603aec2084..6b79a0123d9e872cc3dcebdea7905c5b6d8613b2 100644 (file)
@@ -46,7 +46,7 @@
 //! # use lightning::util::ser::{Writeable, Writer};
 //! # use lightning_invoice::Invoice;
 //! # use lightning_invoice::payment::{InvoicePayer, Payer, RetryAttempts, Router};
-//! # use secp256k1::key::PublicKey;
+//! # use secp256k1::PublicKey;
 //! # use std::cell::RefCell;
 //! # use std::ops::Deref;
 //! #
@@ -148,7 +148,7 @@ use lightning::util::events::{Event, EventHandler};
 use lightning::util::logger::Logger;
 use crate::sync::Mutex;
 
-use secp256k1::key::PublicKey;
+use secp256k1::PublicKey;
 
 use core::ops::Deref;
 use core::time::Duration;
@@ -555,7 +555,7 @@ mod tests {
                        .min_final_cltv_expiry(144)
                        .amount_milli_satoshis(128)
                        .build_signed(|hash| {
-                               Secp256k1::new().sign_recoverable(hash, &private_key)
+                               Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
                        })
                        .unwrap()
        }
@@ -580,7 +580,7 @@ mod tests {
                        .duration_since_epoch(duration_since_epoch())
                        .min_final_cltv_expiry(144)
                        .build_signed(|hash| {
-                               Secp256k1::new().sign_recoverable(hash, &private_key)
+                               Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
                        })
                        .unwrap()
        }
@@ -600,7 +600,7 @@ mod tests {
                        .min_final_cltv_expiry(144)
                        .amount_milli_satoshis(128)
                        .build_signed(|hash| {
-                               Secp256k1::new().sign_recoverable(hash, &private_key)
+                               Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)
                        })
                        .unwrap()
        }
@@ -1558,7 +1558,7 @@ mod tests {
 
                assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
                        &nodes[1].node, nodes[1].keys_manager, Currency::Bitcoin, Some(100_010_000), "Invoice".to_string(),
-                       duration_since_epoch()).unwrap())
+                       duration_since_epoch(), 3600).unwrap())
                        .is_ok());
                let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(htlc_msgs.len(), 2);
@@ -1604,7 +1604,7 @@ mod tests {
 
                assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
                        &nodes[1].node, nodes[1].keys_manager, Currency::Bitcoin, Some(100_010_000), "Invoice".to_string(),
-                       duration_since_epoch()).unwrap())
+                       duration_since_epoch(), 3600).unwrap())
                        .is_ok());
                let htlc_msgs = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(htlc_msgs.len(), 2);
@@ -1686,7 +1686,7 @@ mod tests {
 
                assert!(invoice_payer.pay_invoice(&create_invoice_from_channelmanager_and_duration_since_epoch(
                        &nodes[1].node, nodes[1].keys_manager, Currency::Bitcoin, Some(100_010_000), "Invoice".to_string(),
-                       duration_since_epoch()).unwrap())
+                       duration_since_epoch(), 3600).unwrap())
                        .is_ok());
                let htlc_updates = SendEvent::from_node(&nodes[0]);
                check_added_monitors!(nodes[0], 1);
index a2edc43afc7a17b02f1b7eb13906e9d7837f874e..9b3b41afbedae5f938c01968f221a843870d376c 100644 (file)
@@ -1,6 +1,6 @@
 //! Convenient utilities to create an invoice.
 
-use {CreationError, Currency, DEFAULT_EXPIRY_TIME, Invoice, InvoiceBuilder, SignOrCreationError};
+use {CreationError, Currency, Invoice, InvoiceBuilder, SignOrCreationError};
 use payment::{Payer, Router};
 
 use crate::{prelude::*, Description, InvoiceDescription, Sha256};
@@ -19,8 +19,7 @@ use lightning::routing::scoring::Score;
 use lightning::routing::network_graph::{NetworkGraph, RoutingFees};
 use lightning::routing::router::{Route, RouteHint, RouteHintHop, RouteParameters, find_route};
 use lightning::util::logger::Logger;
-use secp256k1::key::PublicKey;
-use core::convert::TryInto;
+use secp256k1::PublicKey;
 use core::ops::Deref;
 use core::time::Duration;
 use sync::Mutex;
@@ -162,7 +161,8 @@ fn _create_phantom_invoice<Signer: Sign, K: Deref>(
                .current_timestamp()
                .payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
                .payment_secret(payment_secret)
-               .min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into());
+               .min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into())
+               .expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into()));
        if let Some(amt) = amt_msat {
                invoice = invoice.amount_milli_satoshis(amt);
        }
@@ -212,9 +212,12 @@ fn _create_phantom_invoice<Signer: Sign, K: Deref>(
 /// method stores the invoice's payment secret and preimage in `ChannelManager`, so (a) the user
 /// doesn't have to store preimage/payment secret information and (b) `ChannelManager` can verify
 /// that the payment secret is valid when the invoice is paid.
+///
+/// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
+/// in excess of the current time.
 pub fn create_invoice_from_channelmanager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
        channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, network: Currency,
-       amt_msat: Option<u64>, description: String
+       amt_msat: Option<u64>, description: String, invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
        M::Target: chain::Watch<Signer>,
@@ -227,7 +230,8 @@ where
        let duration = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)
                .expect("for the foreseeable future this shouldn't happen");
        create_invoice_from_channelmanager_and_duration_since_epoch(
-               channelmanager, keys_manager, network, amt_msat, description, duration
+               channelmanager, keys_manager, network, amt_msat, description, duration,
+               invoice_expiry_delta_secs
        )
 }
 
@@ -238,9 +242,12 @@ where
 /// doesn't have to store preimage/payment secret information and (b) `ChannelManager` can verify
 /// that the payment secret is valid when the invoice is paid.
 /// Use this variant if you want to pass the `description_hash` to the invoice.
+///
+/// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
+/// in excess of the current time.
 pub fn create_invoice_from_channelmanager_with_description_hash<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
        channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, network: Currency,
-       amt_msat: Option<u64>, description_hash: Sha256,
+       amt_msat: Option<u64>, description_hash: Sha256, invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
        M::Target: chain::Watch<Signer>,
@@ -256,7 +263,8 @@ where
                .expect("for the foreseeable future this shouldn't happen");
 
        create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch(
-               channelmanager, keys_manager, network, amt_msat, description_hash, duration,
+               channelmanager, keys_manager, network, amt_msat,
+               description_hash, duration, invoice_expiry_delta_secs
        )
 }
 
@@ -266,6 +274,7 @@ where
 pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
        channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, network: Currency,
        amt_msat: Option<u64>, description_hash: Sha256, duration_since_epoch: Duration,
+       invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
        M::Target: chain::Watch<Signer>,
@@ -277,7 +286,7 @@ where
        _create_invoice_from_channelmanager_and_duration_since_epoch(
                channelmanager, keys_manager, network, amt_msat,
                InvoiceDescription::Hash(&description_hash),
-               duration_since_epoch,
+               duration_since_epoch, invoice_expiry_delta_secs
        )
 }
 
@@ -287,6 +296,7 @@ where
 pub fn create_invoice_from_channelmanager_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
        channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, network: Currency,
        amt_msat: Option<u64>, description: String, duration_since_epoch: Duration,
+       invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
        M::Target: chain::Watch<Signer>,
@@ -300,13 +310,14 @@ where
                InvoiceDescription::Direct(
                        &Description::new(description).map_err(SignOrCreationError::CreationError)?,
                ),
-               duration_since_epoch,
+               duration_since_epoch, invoice_expiry_delta_secs
        )
 }
 
 fn _create_invoice_from_channelmanager_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
        channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, network: Currency,
        amt_msat: Option<u64>, description: InvoiceDescription, duration_since_epoch: Duration,
+       invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
        M::Target: chain::Watch<Signer>,
@@ -320,7 +331,7 @@ where
        // `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin
        // supply.
        let (payment_hash, payment_secret) = channelmanager
-               .create_inbound_payment(amt_msat, DEFAULT_EXPIRY_TIME.try_into().unwrap())
+               .create_inbound_payment(amt_msat, invoice_expiry_delta_secs)
                .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?;
        let our_node_pubkey = channelmanager.get_our_node_id();
 
@@ -337,7 +348,8 @@ where
                .payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
                .payment_secret(payment_secret)
                .basic_mpp()
-               .min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into());
+               .min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into())
+               .expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into()));
        if let Some(amt) = amt_msat {
                invoice = invoice.amount_milli_satoshis(amt);
        }
@@ -526,12 +538,14 @@ mod test {
                let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
                let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
                create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known());
+               let non_default_invoice_expiry_secs = 4200;
                let invoice = create_invoice_from_channelmanager_and_duration_since_epoch(
                        &nodes[1].node, nodes[1].keys_manager, Currency::BitcoinTestnet, Some(10_000), "test".to_string(),
-                       Duration::from_secs(1234567)).unwrap();
+                       Duration::from_secs(1234567), non_default_invoice_expiry_secs).unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
                assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
                assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
+               assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
 
                // Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is
                // available.
@@ -592,7 +606,7 @@ mod test {
                let description_hash = crate::Sha256(Hash::hash("Testing description_hash".as_bytes()));
                let invoice = ::utils::create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch(
                        &nodes[1].node, nodes[1].keys_manager, Currency::BitcoinTestnet, Some(10_000),
-                       description_hash, Duration::from_secs(1234567),
+                       description_hash, Duration::from_secs(1234567), 3600
                ).unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
                assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
@@ -752,7 +766,7 @@ mod test {
        ) {
                let invoice = create_invoice_from_channelmanager_and_duration_since_epoch(
                        &invoice_node.node, invoice_node.keys_manager, Currency::BitcoinTestnet, invoice_amt, "test".to_string(),
-                       Duration::from_secs(1234567)).unwrap();
+                       Duration::from_secs(1234567), 3600).unwrap();
                let hints = invoice.private_routes();
 
                for hint in hints {
@@ -799,8 +813,13 @@ mod test {
                } else {
                        None
                };
+               let non_default_invoice_expiry_secs = 4200;
 
-               let invoice = ::utils::create_phantom_invoice::<EnforcingSigner, &test_utils::TestKeysInterface>(Some(payment_amt), payment_hash, "test".to_string(), 3600, route_hints, &nodes[1].keys_manager, Currency::BitcoinTestnet).unwrap();
+               let invoice =
+                       ::utils::create_phantom_invoice::<EnforcingSigner, &test_utils::TestKeysInterface>(
+                               Some(payment_amt), payment_hash, "test".to_string(), non_default_invoice_expiry_secs,
+                               route_hints, &nodes[1].keys_manager, Currency::BitcoinTestnet
+                       ).unwrap();
                let (payment_hash, payment_secret) = (PaymentHash(invoice.payment_hash().into_inner()), *invoice.payment_secret());
                let payment_preimage = if user_generated_pmt_hash {
                        user_payment_preimage
@@ -811,6 +830,7 @@ mod test {
                assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
                assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string())));
                assert_eq!(invoice.route_hints().len(), 2);
+               assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
                assert!(!invoice.features().unwrap().supports_basic_mpp());
 
                let payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key())
@@ -931,10 +951,17 @@ mod test {
                ];
 
                let description_hash = crate::Sha256(Hash::hash("Description hash phantom invoice".as_bytes()));
-               let invoice = ::utils::create_phantom_invoice_with_description_hash::<EnforcingSigner,&test_utils::TestKeysInterface>(Some(payment_amt), None, 3600, description_hash, route_hints, &nodes[1].keys_manager, Currency::BitcoinTestnet).unwrap();
-
+               let non_default_invoice_expiry_secs = 4200;
+               let invoice = ::utils::create_phantom_invoice_with_description_hash::<
+                       EnforcingSigner, &test_utils::TestKeysInterface,
+               >(
+                       Some(payment_amt), None, non_default_invoice_expiry_secs, description_hash,
+                       route_hints, &nodes[1].keys_manager, Currency::BitcoinTestnet
+               )
+               .unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(200_000));
                assert_eq!(invoice.min_final_cltv_expiry(), MIN_FINAL_CLTV_EXPIRY as u64);
+               assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
                assert_eq!(invoice.description(), InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Description hash phantom invoice".as_bytes()))));
        }
 
index 1eaeb31378513065e74a7c4958e9b8e0c8befa8e..1d9c481513dd98944514fd25ea2f7601b2e935a2 100644 (file)
@@ -13,7 +13,7 @@ use lightning::routing::router::{RouteHint, RouteHintHop};
 use lightning::routing::network_graph::RoutingFees;
 use lightning_invoice::*;
 use secp256k1::PublicKey;
-use secp256k1::recovery::{RecoverableSignature, RecoveryId};
+use secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
 use std::collections::HashSet;
 use std::time::Duration;
 use std::str::FromStr;
index 40734ff28c3ab3088d3276f3056d01c9d7bf83d9..08c649f79bc1f885e3dabe06a17c7b250733cdb7 100644 (file)
@@ -15,7 +15,7 @@ all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
 
 [dependencies]
-bitcoin = "0.27"
+bitcoin = "0.28.1"
 lightning = { version = "0.0.106", path = "../lightning" }
 tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "sync", "net", "time" ] }
 
index 3cfed870b31f59ae1b36ffbf7a1987eee2b0df00..f7e42b6634147d405e2cfebe1278801940e0a771 100644 (file)
@@ -23,7 +23,7 @@
 //! # Example
 //! ```
 //! use std::net::TcpStream;
-//! use bitcoin::secp256k1::key::PublicKey;
+//! use bitcoin::secp256k1::PublicKey;
 //! use lightning::util::events::{Event, EventHandler, EventsProvider};
 //! use std::net::SocketAddr;
 //! use std::sync::Arc;
@@ -71,7 +71,7 @@
 
 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
 
-use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::PublicKey;
 
 use tokio::net::TcpStream;
 use tokio::{io, time};
@@ -85,7 +85,6 @@ use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, NetAddre
 use lightning::util::logger::Logger;
 
 use std::task;
-use std::net::IpAddr;
 use std::net::SocketAddr;
 use std::net::TcpStream as StdTcpStream;
 use std::sync::{Arc, Mutex};
@@ -236,6 +235,20 @@ impl Connection {
        }
 }
 
+fn get_addr_from_stream(stream: &StdTcpStream) -> Option<NetAddress> {
+       match stream.peer_addr() {
+               Ok(SocketAddr::V4(sockaddr)) => Some(NetAddress::IPv4 {
+                       addr: sockaddr.ip().octets(),
+                       port: sockaddr.port(),
+               }),
+               Ok(SocketAddr::V6(sockaddr)) => Some(NetAddress::IPv6 {
+                       addr: sockaddr.ip().octets(),
+                       port: sockaddr.port(),
+               }),
+               Err(_) => None,
+       }
+}
+
 /// Process incoming messages and feed outgoing messages on the provided socket generated by
 /// accepting an incoming connection.
 ///
@@ -247,21 +260,12 @@ pub fn setup_inbound<CMH, RMH, L, UMH>(peer_manager: Arc<peer_handler::PeerManag
                RMH: RoutingMessageHandler + 'static + Send + Sync,
                L: Logger + 'static + ?Sized + Send + Sync,
                UMH: CustomMessageHandler + 'static + Send + Sync {
-       let ip_addr = stream.peer_addr().unwrap();
+       let remote_addr = get_addr_from_stream(&stream);
        let (reader, write_receiver, read_receiver, us) = Connection::new(stream);
        #[cfg(debug_assertions)]
        let last_us = Arc::clone(&us);
 
-       let handle_opt = if let Ok(_) = peer_manager.new_inbound_connection(SocketDescriptor::new(us.clone()), match ip_addr.ip() {
-               IpAddr::V4(ip) => Some(NetAddress::IPv4 {
-                       addr: ip.octets(),
-                       port: ip_addr.port(),
-               }),
-               IpAddr::V6(ip) => Some(NetAddress::IPv6 {
-                       addr: ip.octets(),
-                       port: ip_addr.port(),
-               }),
-       }) {
+       let handle_opt = if let Ok(_) = peer_manager.new_inbound_connection(SocketDescriptor::new(us.clone()), remote_addr) {
                Some(tokio::spawn(Connection::schedule_read(peer_manager, us, reader, read_receiver, write_receiver)))
        } else {
                // Note that we will skip socket_disconnected here, in accordance with the PeerManager
@@ -298,20 +302,11 @@ pub fn setup_outbound<CMH, RMH, L, UMH>(peer_manager: Arc<peer_handler::PeerMana
                RMH: RoutingMessageHandler + 'static + Send + Sync,
                L: Logger + 'static + ?Sized + Send + Sync,
                UMH: CustomMessageHandler + 'static + Send + Sync {
-       let ip_addr = stream.peer_addr().unwrap();
+       let remote_addr = get_addr_from_stream(&stream);
        let (reader, mut write_receiver, read_receiver, us) = Connection::new(stream);
        #[cfg(debug_assertions)]
        let last_us = Arc::clone(&us);
-       let handle_opt = if let Ok(initial_send) = peer_manager.new_outbound_connection(their_node_id, SocketDescriptor::new(us.clone()), match ip_addr.ip() {
-               IpAddr::V4(ip) => Some(NetAddress::IPv4 {
-                       addr: ip.octets(),
-                       port: ip_addr.port(),
-               }),
-               IpAddr::V6(ip) => Some(NetAddress::IPv6 {
-                       addr: ip.octets(),
-                       port: ip_addr.port(),
-               }),
-       }) {
+       let handle_opt = if let Ok(initial_send) = peer_manager.new_outbound_connection(their_node_id, SocketDescriptor::new(us.clone()), remote_addr) {
                Some(tokio::spawn(async move {
                        // We should essentially always have enough room in a TCP socket buffer to send the
                        // initial 10s of bytes. However, tokio running in single-threaded mode will always
@@ -588,6 +583,22 @@ mod tests {
                }
        }
 
+       fn make_tcp_connection() -> (std::net::TcpStream, std::net::TcpStream) {
+               if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:9735") {
+                       (std::net::TcpStream::connect("127.0.0.1:9735").unwrap(), listener.accept().unwrap().0)
+               } else if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:19735") {
+                       (std::net::TcpStream::connect("127.0.0.1:19735").unwrap(), listener.accept().unwrap().0)
+               } else if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:9997") {
+                       (std::net::TcpStream::connect("127.0.0.1:9997").unwrap(), listener.accept().unwrap().0)
+               } else if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:9998") {
+                       (std::net::TcpStream::connect("127.0.0.1:9998").unwrap(), listener.accept().unwrap().0)
+               } else if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:9999") {
+                       (std::net::TcpStream::connect("127.0.0.1:9999").unwrap(), listener.accept().unwrap().0)
+               } else if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:46926") {
+                       (std::net::TcpStream::connect("127.0.0.1:46926").unwrap(), listener.accept().unwrap().0)
+               } else { panic!("Failed to bind to v4 localhost on common ports"); }
+       }
+
        async fn do_basic_connection_test() {
                let secp_ctx = Secp256k1::new();
                let a_key = SecretKey::from_slice(&[1; 32]).unwrap();
@@ -627,13 +638,7 @@ mod tests {
                // address. This may not always be the case in containers and the like, so if this test is
                // failing for you check that you have a loopback interface and it is configured with
                // 127.0.0.1.
-               let (conn_a, conn_b) = if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:9735") {
-                       (std::net::TcpStream::connect("127.0.0.1:9735").unwrap(), listener.accept().unwrap().0)
-               } else if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:9999") {
-                       (std::net::TcpStream::connect("127.0.0.1:9999").unwrap(), listener.accept().unwrap().0)
-               } else if let Ok(listener) = std::net::TcpListener::bind("127.0.0.1:46926") {
-                       (std::net::TcpStream::connect("127.0.0.1:46926").unwrap(), listener.accept().unwrap().0)
-               } else { panic!("Failed to bind to v4 localhost on common ports"); };
+               let (conn_a, conn_b) = make_tcp_connection();
 
                let fut_a = super::setup_outbound(Arc::clone(&a_manager), b_pub, conn_a);
                let fut_b = super::setup_inbound(b_manager, conn_b);
@@ -661,8 +666,53 @@ mod tests {
        async fn basic_threaded_connection_test() {
                do_basic_connection_test().await;
        }
+
        #[tokio::test]
        async fn basic_unthreaded_connection_test() {
                do_basic_connection_test().await;
        }
+
+       async fn race_disconnect_accept() {
+               // Previously, if we handed an already-disconnected socket to `setup_inbound` we'd panic.
+               // This attempts to find other similar races by opening connections and shutting them down
+               // while connecting. Sadly in testing this did *not* reproduce the previous issue.
+               let secp_ctx = Secp256k1::new();
+               let a_key = SecretKey::from_slice(&[1; 32]).unwrap();
+               let b_key = SecretKey::from_slice(&[2; 32]).unwrap();
+               let b_pub = PublicKey::from_secret_key(&secp_ctx, &b_key);
+
+               let a_manager = Arc::new(PeerManager::new(MessageHandler {
+                       chan_handler: Arc::new(lightning::ln::peer_handler::ErroringMessageHandler::new()),
+                       route_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
+               }, a_key, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
+
+               // Make two connections, one for an inbound and one for an outbound connection
+               let conn_a = {
+                       let (conn_a, _) = make_tcp_connection();
+                       conn_a
+               };
+               let conn_b = {
+                       let (_, conn_b) = make_tcp_connection();
+                       conn_b
+               };
+
+               // Call connection setup inside new tokio tasks.
+               let manager_reference = Arc::clone(&a_manager);
+               tokio::spawn(async move {
+                       super::setup_inbound(manager_reference, conn_a).await
+               });
+               tokio::spawn(async move {
+                       super::setup_outbound(a_manager, b_pub, conn_b).await
+               });
+       }
+
+       #[tokio::test(flavor = "multi_thread")]
+       async fn threaded_race_disconnect_accept() {
+               race_disconnect_accept().await;
+       }
+
+       #[tokio::test]
+       async fn unthreaded_race_disconnect_accept() {
+               race_disconnect_accept().await;
+       }
 }
index d97cd017b2b1856c30b3cb2ea6038c334851a314..1bf4c5d2e75f87a1b759963b09adad28cadb838e 100644 (file)
@@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"]
 _bench_unstable = ["lightning/_bench_unstable"]
 
 [dependencies]
-bitcoin = "0.27"
+bitcoin = "0.28.1"
 lightning = { version = "0.0.106", path = "../lightning" }
 libc = "0.2"
 
index a9df766731b6c59d1bc02b9e9299fe4dc2964a35..5a54d042a32c55654d2be0e8fe8bc3c65113a237 100644 (file)
@@ -38,9 +38,7 @@ grind_signatures = []
 default = ["std", "grind_signatures"]
 
 [dependencies]
-bitcoin = { version = "0.27", default-features = false, features = ["secp-recovery"] }
-# TODO remove this once rust-bitcoin PR #637 is released
-secp256k1 = { version = "0.20.2", default-features = false, features = ["alloc"] }
+bitcoin = { version = "0.28.1", default-features = false, features = ["secp-recovery"] }
 
 hashbrown = { version = "0.11", optional = true }
 hex = { version = "0.4", optional = true }
@@ -52,10 +50,8 @@ core2 = { version = "0.3.0", optional = true, default-features = false }
 [dev-dependencies]
 hex = "0.4"
 regex = "0.2.11"
-# TODO remove this once rust-bitcoin PR #637 is released
-secp256k1 = { version = "0.20.2", default-features = false, features = ["alloc"] }
 
 [dev-dependencies.bitcoin]
-version = "0.27"
+version = "0.28.1"
 default-features = false
 features = ["bitcoinconsensus", "secp-recovery"]
index 681d895f27e05fa6ef42105f468bae7a1a258250..738fff3837ca045f5c8c9e3e93e588bb88974191 100644 (file)
@@ -29,8 +29,8 @@ use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
 
-use bitcoin::secp256k1::{Secp256k1,Signature};
-use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
+use bitcoin::secp256k1::{SecretKey, PublicKey};
 use bitcoin::secp256k1;
 
 use ln::{PaymentHash, PaymentPreimage};
@@ -2653,7 +2653,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                                                        // appears to be spending the correct type (ie that the match would
                                                        // actually succeed in BIP 158/159-style filters).
                                                        if _script_pubkey.is_v0_p2wsh() {
-                                                               assert_eq!(&bitcoin::Address::p2wsh(&Script::from(input.witness.last().unwrap().clone()), bitcoin::Network::Bitcoin).script_pubkey(), _script_pubkey);
+                                                               assert_eq!(&bitcoin::Address::p2wsh(&Script::from(input.witness.last().unwrap().to_vec()), bitcoin::Network::Bitcoin).script_pubkey(), _script_pubkey);
                                                        } else if _script_pubkey.is_v0_p2wpkh() {
                                                                assert_eq!(&bitcoin::Address::p2wpkh(&bitcoin::PublicKey::from_slice(&input.witness.last().unwrap()).unwrap(), bitcoin::Network::Bitcoin).unwrap().script_pubkey(), _script_pubkey);
                                                        } else { panic!(); }
@@ -2736,20 +2736,23 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
        fn is_resolving_htlc_output<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) where L::Target: Logger {
                'outer_loop: for input in &tx.input {
                        let mut payment_data = None;
-                       let revocation_sig_claim = (input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC) && input.witness[1].len() == 33)
-                               || (input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::AcceptedHTLC) && input.witness[1].len() == 33);
-                       let accepted_preimage_claim = input.witness.len() == 5 && HTLCType::scriptlen_to_htlctype(input.witness[4].len()) == Some(HTLCType::AcceptedHTLC);
+                       let witness_items = input.witness.len();
+                       let htlctype = input.witness.last().map(|w| w.len()).and_then(HTLCType::scriptlen_to_htlctype);
+                       let prev_last_witness_len = input.witness.second_to_last().map(|w| w.len()).unwrap_or(0);
+                       let revocation_sig_claim = (witness_items == 3 && htlctype == Some(HTLCType::OfferedHTLC) && prev_last_witness_len == 33)
+                               || (witness_items == 3 && htlctype == Some(HTLCType::AcceptedHTLC) && prev_last_witness_len == 33);
+                       let accepted_preimage_claim = witness_items == 5 && htlctype == Some(HTLCType::AcceptedHTLC);
                        #[cfg(not(fuzzing))]
-                       let accepted_timeout_claim = input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::AcceptedHTLC) && !revocation_sig_claim;
-                       let offered_preimage_claim = input.witness.len() == 3 && HTLCType::scriptlen_to_htlctype(input.witness[2].len()) == Some(HTLCType::OfferedHTLC) && !revocation_sig_claim;
+                       let accepted_timeout_claim = witness_items == 3 && htlctype == Some(HTLCType::AcceptedHTLC) && !revocation_sig_claim;
+                       let offered_preimage_claim = witness_items == 3 && htlctype == Some(HTLCType::OfferedHTLC) && !revocation_sig_claim;
                        #[cfg(not(fuzzing))]
-                       let offered_timeout_claim = input.witness.len() == 5 && HTLCType::scriptlen_to_htlctype(input.witness[4].len()) == Some(HTLCType::OfferedHTLC);
+                       let offered_timeout_claim = witness_items == 5 && htlctype == Some(HTLCType::OfferedHTLC);
 
                        let mut payment_preimage = PaymentPreimage([0; 32]);
                        if accepted_preimage_claim {
-                               payment_preimage.0.copy_from_slice(&input.witness[3]);
+                               payment_preimage.0.copy_from_slice(input.witness.second_to_last().unwrap());
                        } else if offered_preimage_claim {
-                               payment_preimage.0.copy_from_slice(&input.witness[1]);
+                               payment_preimage.0.copy_from_slice(input.witness.second_to_last().unwrap());
                        }
 
                        macro_rules! log_claim {
@@ -3322,15 +3325,15 @@ mod tests {
        use bitcoin::blockdata::block::BlockHeader;
        use bitcoin::blockdata::script::{Script, Builder};
        use bitcoin::blockdata::opcodes;
-       use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, SigHashType};
+       use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, EcdsaSighashType};
        use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
-       use bitcoin::util::bip143;
+       use bitcoin::util::sighash;
        use bitcoin::hashes::Hash;
        use bitcoin::hashes::sha256::Hash as Sha256;
        use bitcoin::hashes::hex::FromHex;
        use bitcoin::hash_types::{BlockHash, Txid};
        use bitcoin::network::constants::Network;
-       use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+       use bitcoin::secp256k1::{SecretKey,PublicKey};
        use bitcoin::secp256k1::Secp256k1;
 
        use hex;
@@ -3355,6 +3358,7 @@ mod tests {
        use util::ser::{ReadableArgs, Writeable};
        use sync::{Arc, Mutex};
        use io;
+       use bitcoin::Witness;
        use prelude::*;
 
        fn do_test_funding_spend_refuses_updates(use_local_txn: bool) {
@@ -3608,24 +3612,27 @@ mod tests {
                                        transaction_output_index: Some($idx as u32),
                                };
                                let redeem_script = if *$weight == WEIGHT_REVOKED_OUTPUT { chan_utils::get_revokeable_redeemscript(&pubkey, 256, &pubkey) } else { chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, $opt_anchors, &pubkey, &pubkey, &pubkey) };
-                               let sighash = hash_to_message!(&$sighash_parts.signature_hash($idx, &redeem_script, $amount, SigHashType::All)[..]);
-                               let sig = secp_ctx.sign(&sighash, &privkey);
-                               $sighash_parts.access_witness($idx).push(sig.serialize_der().to_vec());
-                               $sighash_parts.access_witness($idx)[0].push(SigHashType::All as u8);
-                               $sum_actual_sigs += $sighash_parts.access_witness($idx)[0].len();
+                               let sighash = hash_to_message!(&$sighash_parts.segwit_signature_hash($idx, &redeem_script, $amount, EcdsaSighashType::All).unwrap()[..]);
+                               let sig = secp_ctx.sign_ecdsa(&sighash, &privkey);
+                               let mut ser_sig = sig.serialize_der().to_vec();
+                               ser_sig.push(EcdsaSighashType::All as u8);
+                               $sum_actual_sigs += ser_sig.len();
+                               let witness = $sighash_parts.witness_mut($idx).unwrap();
+                               witness.push(ser_sig);
                                if *$weight == WEIGHT_REVOKED_OUTPUT {
-                                       $sighash_parts.access_witness($idx).push(vec!(1));
+                                       witness.push(vec!(1));
                                } else if *$weight == weight_revoked_offered_htlc($opt_anchors) || *$weight == weight_revoked_received_htlc($opt_anchors) {
-                                       $sighash_parts.access_witness($idx).push(pubkey.clone().serialize().to_vec());
+                                       witness.push(pubkey.clone().serialize().to_vec());
                                } else if *$weight == weight_received_htlc($opt_anchors) {
-                                       $sighash_parts.access_witness($idx).push(vec![0]);
+                                       witness.push(vec![0]);
                                } else {
-                                       $sighash_parts.access_witness($idx).push(PaymentPreimage([1; 32]).0.to_vec());
+                                       witness.push(PaymentPreimage([1; 32]).0.to_vec());
                                }
-                               $sighash_parts.access_witness($idx).push(redeem_script.into_bytes());
-                               println!("witness[0] {}", $sighash_parts.access_witness($idx)[0].len());
-                               println!("witness[1] {}", $sighash_parts.access_witness($idx)[1].len());
-                               println!("witness[2] {}", $sighash_parts.access_witness($idx)[2].len());
+                               witness.push(redeem_script.into_bytes());
+                               let witness = witness.to_vec();
+                               println!("witness[0] {}", witness[0].len());
+                               println!("witness[1] {}", witness[1].len());
+                               println!("witness[2] {}", witness[2].len());
                        }
                }
 
@@ -3644,24 +3651,24 @@ mod tests {
                                        },
                                        script_sig: Script::new(),
                                        sequence: 0xfffffffd,
-                                       witness: Vec::new(),
+                                       witness: Witness::new(),
                                });
                        }
                        claim_tx.output.push(TxOut {
                                script_pubkey: script_pubkey.clone(),
                                value: 0,
                        });
-                       let base_weight = claim_tx.get_weight();
+                       let base_weight = claim_tx.weight();
                        let inputs_weight = vec![WEIGHT_REVOKED_OUTPUT, weight_revoked_offered_htlc(opt_anchors), weight_revoked_offered_htlc(opt_anchors), weight_revoked_received_htlc(opt_anchors)];
                        let mut inputs_total_weight = 2; // count segwit flags
                        {
-                               let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+                               let mut sighash_parts = sighash::SighashCache::new(&mut claim_tx);
                                for (idx, inp) in inputs_weight.iter().enumerate() {
                                        sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors);
                                        inputs_total_weight += inp;
                                }
                        }
-                       assert_eq!(base_weight + inputs_total_weight as usize,  claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_weight.len() - sum_actual_sigs));
+                       assert_eq!(base_weight + inputs_total_weight as usize,  claim_tx.weight() + /* max_length_sig */ (73 * inputs_weight.len() - sum_actual_sigs));
                }
 
                // Claim tx with 1 offered HTLCs, 3 received HTLCs
@@ -3676,24 +3683,24 @@ mod tests {
                                        },
                                        script_sig: Script::new(),
                                        sequence: 0xfffffffd,
-                                       witness: Vec::new(),
+                                       witness: Witness::new(),
                                });
                        }
                        claim_tx.output.push(TxOut {
                                script_pubkey: script_pubkey.clone(),
                                value: 0,
                        });
-                       let base_weight = claim_tx.get_weight();
+                       let base_weight = claim_tx.weight();
                        let inputs_weight = vec![weight_offered_htlc(opt_anchors), weight_received_htlc(opt_anchors), weight_received_htlc(opt_anchors), weight_received_htlc(opt_anchors)];
                        let mut inputs_total_weight = 2; // count segwit flags
                        {
-                               let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+                               let mut sighash_parts = sighash::SighashCache::new(&mut claim_tx);
                                for (idx, inp) in inputs_weight.iter().enumerate() {
                                        sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors);
                                        inputs_total_weight += inp;
                                }
                        }
-                       assert_eq!(base_weight + inputs_total_weight as usize,  claim_tx.get_weight() + /* max_length_sig */ (73 * inputs_weight.len() - sum_actual_sigs));
+                       assert_eq!(base_weight + inputs_total_weight as usize,  claim_tx.weight() + /* max_length_sig */ (73 * inputs_weight.len() - sum_actual_sigs));
                }
 
                // Justice tx with 1 revoked HTLC-Success tx output
@@ -3707,23 +3714,23 @@ mod tests {
                                },
                                script_sig: Script::new(),
                                sequence: 0xfffffffd,
-                               witness: Vec::new(),
+                               witness: Witness::new(),
                        });
                        claim_tx.output.push(TxOut {
                                script_pubkey: script_pubkey.clone(),
                                value: 0,
                        });
-                       let base_weight = claim_tx.get_weight();
+                       let base_weight = claim_tx.weight();
                        let inputs_weight = vec![WEIGHT_REVOKED_OUTPUT];
                        let mut inputs_total_weight = 2; // count segwit flags
                        {
-                               let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
+                               let mut sighash_parts = sighash::SighashCache::new(&mut claim_tx);
                                for (idx, inp) in inputs_weight.iter().enumerate() {
                                        sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, opt_anchors);
                                        inputs_total_weight += inp;
                                }
                        }
-                       assert_eq!(base_weight + inputs_total_weight as usize, claim_tx.get_weight() + /* max_length_isg */ (73 * inputs_weight.len() - sum_actual_sigs));
+                       assert_eq!(base_weight + inputs_total_weight as usize, claim_tx.weight() + /* max_length_isg */ (73 * inputs_weight.len() - sum_actual_sigs));
                }
        }
 
index be31036220a5a720e27d561697aad4a5daa7869c..33c88cf11e38c672d6394bd3027b89b8664bbf0b 100644 (file)
 //! spendable on-chain outputs which the user owns and is responsible for using just as any other
 //! on-chain output which is theirs.
 
-use bitcoin::blockdata::transaction::{Transaction, TxOut, TxIn, SigHashType};
+use bitcoin::blockdata::transaction::{Transaction, TxOut, TxIn, EcdsaSighashType};
 use bitcoin::blockdata::script::{Script, Builder};
 use bitcoin::blockdata::opcodes;
 use bitcoin::network::constants::Network;
 use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, ChildNumber};
-use bitcoin::util::bip143;
+use bitcoin::util::sighash;
 
 use bitcoin::bech32::u5;
 use bitcoin::hashes::{Hash, HashEngine};
@@ -25,10 +25,10 @@ use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::WPubkeyHash;
 
-use bitcoin::secp256k1::key::{SecretKey, PublicKey};
-use bitcoin::secp256k1::{Secp256k1, Signature, Signing};
-use bitcoin::secp256k1::recovery::RecoverableSignature;
-use bitcoin::secp256k1;
+use bitcoin::secp256k1::{SecretKey, PublicKey};
+use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Signing};
+use bitcoin::secp256k1::ecdsa::RecoverableSignature;
+use bitcoin::{secp256k1, Witness};
 
 use util::{byte_utils, transaction_utils};
 use util::crypto::{hkdf_extract_expand_twice, sign};
@@ -588,16 +588,16 @@ impl InMemorySigner {
                if spend_tx.input[input_idx].previous_output != descriptor.outpoint.into_bitcoin_outpoint() { return Err(()); }
 
                let remotepubkey = self.pubkeys().payment_point;
-               let witness_script = bitcoin::Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: remotepubkey}, Network::Testnet).script_pubkey();
-               let sighash = hash_to_message!(&bip143::SigHashCache::new(spend_tx).signature_hash(input_idx, &witness_script, descriptor.output.value, SigHashType::All)[..]);
+               let witness_script = bitcoin::Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: remotepubkey}, Network::Testnet).script_pubkey();
+               let sighash = hash_to_message!(&sighash::SighashCache::new(spend_tx).segwit_signature_hash(input_idx, &witness_script, descriptor.output.value, EcdsaSighashType::All).unwrap()[..]);
                let remotesig = sign(secp_ctx, &sighash, &self.payment_key);
-               let payment_script = bitcoin::Address::p2wpkh(&::bitcoin::PublicKey{compressed: true, key: remotepubkey}, Network::Bitcoin).unwrap().script_pubkey();
+               let payment_script = bitcoin::Address::p2wpkh(&::bitcoin::PublicKey{compressed: true, inner: remotepubkey}, Network::Bitcoin).unwrap().script_pubkey();
 
                if payment_script != descriptor.output.script_pubkey  { return Err(()); }
 
                let mut witness = Vec::with_capacity(2);
                witness.push(remotesig.serialize_der().to_vec());
-               witness[0].push(SigHashType::All as u8);
+               witness[0].push(EcdsaSighashType::All as u8);
                witness.push(remotepubkey.serialize().to_vec());
                Ok(witness)
        }
@@ -623,7 +623,7 @@ impl InMemorySigner {
                        .expect("We constructed the payment_base_key, so we can only fail here if the RNG is busted.");
                let delayed_payment_pubkey = PublicKey::from_secret_key(&secp_ctx, &delayed_payment_key);
                let witness_script = chan_utils::get_revokeable_redeemscript(&descriptor.revocation_pubkey, descriptor.to_self_delay, &delayed_payment_pubkey);
-               let sighash = hash_to_message!(&bip143::SigHashCache::new(spend_tx).signature_hash(input_idx, &witness_script, descriptor.output.value, SigHashType::All)[..]);
+               let sighash = hash_to_message!(&sighash::SighashCache::new(spend_tx).segwit_signature_hash(input_idx, &witness_script, descriptor.output.value, EcdsaSighashType::All).unwrap()[..]);
                let local_delayedsig = sign(secp_ctx, &sighash, &delayed_payment_key);
                let payment_script = bitcoin::Address::p2wsh(&witness_script, Network::Bitcoin).script_pubkey();
 
@@ -631,7 +631,7 @@ impl InMemorySigner {
 
                let mut witness = Vec::with_capacity(3);
                witness.push(local_delayedsig.serialize_der().to_vec());
-               witness[0].push(SigHashType::All as u8);
+               witness[0].push(EcdsaSighashType::All as u8);
                witness.push(vec!()); //MINIMALIF
                witness.push(witness_script.clone().into_bytes());
                Ok(witness)
@@ -670,8 +670,8 @@ impl BaseSign for InMemorySigner {
                for htlc in commitment_tx.htlcs() {
                        let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_tx.feerate_per_kw(), self.holder_selected_contest_delay(), htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
                        let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys);
-                       let htlc_sighashtype = if self.opt_anchors() { SigHashType::SinglePlusAnyoneCanPay } else { SigHashType::All };
-                       let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype)[..]);
+                       let htlc_sighashtype = if self.opt_anchors() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
+                       let htlc_sighash = hash_to_message!(&sighash::SighashCache::new(&htlc_tx).segwit_signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype).unwrap()[..]);
                        let holder_htlc_key = chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key).map_err(|_| ())?;
                        htlc_sigs.push(sign(secp_ctx, &htlc_sighash, &holder_htlc_key));
                }
@@ -712,8 +712,8 @@ impl BaseSign for InMemorySigner {
                        let counterparty_delayedpubkey = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.counterparty_pubkeys().delayed_payment_basepoint).map_err(|_| ())?;
                        chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.holder_selected_contest_delay(), &counterparty_delayedpubkey)
                };
-               let mut sighash_parts = bip143::SigHashCache::new(justice_tx);
-               let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
+               let mut sighash_parts = sighash::SighashCache::new(justice_tx);
+               let sighash = hash_to_message!(&sighash_parts.segwit_signature_hash(input, &witness_script, amount, EcdsaSighashType::All).unwrap()[..]);
                return Ok(sign(secp_ctx, &sighash, &revocation_key))
        }
 
@@ -726,8 +726,8 @@ impl BaseSign for InMemorySigner {
                        let holder_htlcpubkey = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.pubkeys().htlc_basepoint).map_err(|_| ())?;
                        chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, self.opt_anchors(), &counterparty_htlcpubkey, &holder_htlcpubkey, &revocation_pubkey)
                };
-               let mut sighash_parts = bip143::SigHashCache::new(justice_tx);
-               let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
+               let mut sighash_parts = sighash::SighashCache::new(justice_tx);
+               let sighash = hash_to_message!(&sighash_parts.segwit_signature_hash(input, &witness_script, amount, EcdsaSighashType::All).unwrap()[..]);
                return Ok(sign(secp_ctx, &sighash, &revocation_key))
        }
 
@@ -740,8 +740,8 @@ impl BaseSign for InMemorySigner {
                                        } else { return Err(()) }
                                } else { return Err(()) }
                        } else { return Err(()) };
-                       let mut sighash_parts = bip143::SigHashCache::new(htlc_tx);
-                       let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
+                       let mut sighash_parts = sighash::SighashCache::new(htlc_tx);
+                       let sighash = hash_to_message!(&sighash_parts.segwit_signature_hash(input, &witness_script, amount, EcdsaSighashType::All).unwrap()[..]);
                        return Ok(sign(secp_ctx, &sighash, &htlc_key))
                }
                Err(())
@@ -884,10 +884,10 @@ impl KeysManager {
                // Note that when we aren't serializing the key, network doesn't matter
                match ExtendedPrivKey::new_master(Network::Testnet, seed) {
                        Ok(master_key) => {
-                               let node_secret = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0).unwrap()).expect("Your RNG is busted").private_key.key;
+                               let node_secret = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0).unwrap()).expect("Your RNG is busted").private_key;
                                let destination_script = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1).unwrap()) {
                                        Ok(destination_key) => {
-                                               let wpubkey_hash = WPubkeyHash::hash(&ExtendedPubKey::from_private(&secp_ctx, &destination_key).public_key.to_bytes());
+                                               let wpubkey_hash = WPubkeyHash::hash(&ExtendedPubKey::from_priv(&secp_ctx, &destination_key).to_pub().to_bytes());
                                                Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0)
                                                              .push_slice(&wpubkey_hash.into_inner())
                                                              .into_script()
@@ -895,12 +895,12 @@ impl KeysManager {
                                        Err(_) => panic!("Your RNG is busted"),
                                };
                                let shutdown_pubkey = match master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(2).unwrap()) {
-                                       Ok(shutdown_key) => ExtendedPubKey::from_private(&secp_ctx, &shutdown_key).public_key.key,
+                                       Ok(shutdown_key) => ExtendedPubKey::from_priv(&secp_ctx, &shutdown_key).public_key,
                                        Err(_) => panic!("Your RNG is busted"),
                                };
                                let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3).unwrap()).expect("Your RNG is busted");
                                let rand_bytes_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()).expect("Your RNG is busted");
-                               let inbound_payment_key: SecretKey = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap()).expect("Your RNG is busted").private_key.key;
+                               let inbound_payment_key: SecretKey = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap()).expect("Your RNG is busted").private_key;
                                let mut inbound_pmt_key_bytes = [0; 32];
                                inbound_pmt_key_bytes.copy_from_slice(&inbound_payment_key[..]);
 
@@ -951,7 +951,7 @@ impl KeysManager {
                // entropy, everything else just ensures uniqueness. We rely on the unique_start (ie
                // starting_time provided in the constructor) to be unique.
                let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(chan_id as u32).expect("key space exhausted")).expect("Your RNG is busted");
-               unique_start.input(&child_privkey.private_key.key[..]);
+               unique_start.input(&child_privkey.private_key[..]);
 
                let seed = Sha256::from_engine(unique_start).into_inner();
 
@@ -1014,7 +1014,7 @@ impl KeysManager {
                                                previous_output: descriptor.outpoint.into_bitcoin_outpoint(),
                                                script_sig: Script::new(),
                                                sequence: 0,
-                                               witness: Vec::new(),
+                                               witness: Witness::new(),
                                        });
                                        witness_weight += StaticPaymentOutputDescriptor::MAX_WITNESS_LENGTH;
                                        input_value += descriptor.output.value;
@@ -1025,7 +1025,7 @@ impl KeysManager {
                                                previous_output: descriptor.outpoint.into_bitcoin_outpoint(),
                                                script_sig: Script::new(),
                                                sequence: descriptor.to_self_delay as u32,
-                                               witness: Vec::new(),
+                                               witness: Witness::new(),
                                        });
                                        witness_weight += DelayedPaymentOutputDescriptor::MAX_WITNESS_LENGTH;
                                        input_value += descriptor.output.value;
@@ -1036,7 +1036,7 @@ impl KeysManager {
                                                previous_output: outpoint.into_bitcoin_outpoint(),
                                                script_sig: Script::new(),
                                                sequence: 0,
-                                               witness: Vec::new(),
+                                               witness: Witness::new(),
                                        });
                                        witness_weight += 1 + 73 + 34;
                                        input_value += output.value;
@@ -1064,7 +1064,7 @@ impl KeysManager {
                                                        self.derive_channel_keys(descriptor.channel_value_satoshis, &descriptor.channel_keys_id),
                                                        descriptor.channel_keys_id));
                                        }
-                                       spend_tx.input[input_idx].witness = keys_cache.as_ref().unwrap().0.sign_counterparty_payment_input(&spend_tx, input_idx, &descriptor, &secp_ctx)?;
+                                       spend_tx.input[input_idx].witness = Witness::from_vec(keys_cache.as_ref().unwrap().0.sign_counterparty_payment_input(&spend_tx, input_idx, &descriptor, &secp_ctx)?);
                                },
                                SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) => {
                                        if keys_cache.is_none() || keys_cache.as_ref().unwrap().1 != descriptor.channel_keys_id {
@@ -1072,7 +1072,7 @@ impl KeysManager {
                                                        self.derive_channel_keys(descriptor.channel_value_satoshis, &descriptor.channel_keys_id),
                                                        descriptor.channel_keys_id));
                                        }
-                                       spend_tx.input[input_idx].witness = keys_cache.as_ref().unwrap().0.sign_dynamic_p2wsh_input(&spend_tx, input_idx, &descriptor, &secp_ctx)?;
+                                       spend_tx.input[input_idx].witness = Witness::from_vec(keys_cache.as_ref().unwrap().0.sign_dynamic_p2wsh_input(&spend_tx, input_idx, &descriptor, &secp_ctx)?);
                                },
                                SpendableOutputDescriptor::StaticOutput { ref output, .. } => {
                                        let derivation_idx = if output.script_pubkey == self.destination_script {
@@ -1092,29 +1092,30 @@ impl KeysManager {
                                                        Err(_) => panic!("Your rng is busted"),
                                                }
                                        };
-                                       let pubkey = ExtendedPubKey::from_private(&secp_ctx, &secret).public_key;
+                                       let pubkey = ExtendedPubKey::from_priv(&secp_ctx, &secret).to_pub();
                                        if derivation_idx == 2 {
-                                               assert_eq!(pubkey.key, self.shutdown_pubkey);
+                                               assert_eq!(pubkey.inner, self.shutdown_pubkey);
                                        }
                                        let witness_script = bitcoin::Address::p2pkh(&pubkey, Network::Testnet).script_pubkey();
                                        let payment_script = bitcoin::Address::p2wpkh(&pubkey, Network::Testnet).expect("uncompressed key found").script_pubkey();
 
                                        if payment_script != output.script_pubkey { return Err(()); };
 
-                                       let sighash = hash_to_message!(&bip143::SigHashCache::new(&spend_tx).signature_hash(input_idx, &witness_script, output.value, SigHashType::All)[..]);
-                                       let sig = sign(secp_ctx, &sighash, &secret.private_key.key);
-                                       spend_tx.input[input_idx].witness.push(sig.serialize_der().to_vec());
-                                       spend_tx.input[input_idx].witness[0].push(SigHashType::All as u8);
-                                       spend_tx.input[input_idx].witness.push(pubkey.key.serialize().to_vec());
+                                       let sighash = hash_to_message!(&sighash::SighashCache::new(&spend_tx).segwit_signature_hash(input_idx, &witness_script, output.value, EcdsaSighashType::All).unwrap()[..]);
+                                       let sig = sign(secp_ctx, &sighash, &secret.private_key);
+                                       let mut sig_ser = sig.serialize_der().to_vec();
+                                       sig_ser.push(EcdsaSighashType::All as u8);
+                                       spend_tx.input[input_idx].witness.push(sig_ser);
+                                       spend_tx.input[input_idx].witness.push(pubkey.inner.serialize().to_vec());
                                },
                        }
                        input_idx += 1;
                }
 
-               debug_assert!(expected_max_weight >= spend_tx.get_weight());
+               debug_assert!(expected_max_weight >= spend_tx.weight());
                // Note that witnesses with a signature vary somewhat in size, so allow
                // `expected_max_weight` to overshoot by up to 3 bytes per input.
-               debug_assert!(expected_max_weight <= spend_tx.get_weight() + descriptors.len() * 3);
+               debug_assert!(expected_max_weight <= spend_tx.weight() + descriptors.len() * 3);
 
                Ok(spend_tx)
        }
@@ -1157,7 +1158,7 @@ impl KeysInterface for KeysManager {
 
                let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
                let child_privkey = self.rand_bytes_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
-               sha.input(&child_privkey.private_key.key[..]);
+               sha.input(&child_privkey.private_key[..]);
 
                sha.input(b"Unique Secure Random Bytes Salt");
                Sha256::from_engine(sha).into_inner()
@@ -1173,7 +1174,7 @@ impl KeysInterface for KeysManager {
                        Recipient::Node => self.get_node_secret(Recipient::Node)?,
                        Recipient::PhantomNode => return Err(()),
                };
-               Ok(self.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
+               Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
        }
 }
 
@@ -1241,7 +1242,7 @@ impl KeysInterface for PhantomKeysManager {
        fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
                let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
                let secret = self.get_node_secret(recipient)?;
-               Ok(self.inner.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
+               Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
        }
 }
 
index ee6dc9c5c0b6a9fce46d9e610a95bfc872033498..1ca3effabd7e537afc0832cff5085abd3a6abf47 100644 (file)
@@ -18,7 +18,7 @@ use bitcoin::blockdata::script::Script;
 
 use bitcoin::hash_types::Txid;
 
-use bitcoin::secp256k1::{Secp256k1, Signature};
+use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
 use bitcoin::secp256k1;
 
 use ln::msgs::DecodeError;
@@ -394,7 +394,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
 
                                let transaction = cached_request.finalize_package(self, output_value, self.destination_script.clone(), logger).unwrap();
                                log_trace!(logger, "...with timer {} and feerate {}", new_timer.unwrap(), new_feerate);
-                               assert!(predicted_weight >= transaction.get_weight());
+                               assert!(predicted_weight >= transaction.weight());
                                return Some((new_timer, new_feerate, transaction))
                        }
                } else {
index 1cc63a8c8605338875a4ac3c7a95fab7b365d794..b0961293c07c59a3ab71d51912576add191928da 100644 (file)
 //! also includes witness weight computation and fee computation methods.
 
 use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
-use bitcoin::blockdata::transaction::{TxOut,TxIn, Transaction, SigHashType};
+use bitcoin::blockdata::transaction::{TxOut,TxIn, Transaction, EcdsaSighashType};
 use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
 use bitcoin::blockdata::script::Script;
 
 use bitcoin::hash_types::Txid;
 
-use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+use bitcoin::secp256k1::{SecretKey,PublicKey};
 
 use ln::PaymentPreimage;
 use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment};
@@ -36,6 +36,7 @@ use prelude::*;
 use core::cmp;
 use core::mem;
 use core::ops::Deref;
+use bitcoin::Witness;
 
 const MAX_ALLOC_SIZE: usize = 64*1024;
 
@@ -352,8 +353,9 @@ impl PackageSolvingData {
                                        let witness_script = chan_utils::get_revokeable_redeemscript(&chan_keys.revocation_key, outp.on_counterparty_tx_csv, &chan_keys.broadcaster_delayed_payment_key);
                                        //TODO: should we panic on signer failure ?
                                        if let Ok(sig) = onchain_handler.signer.sign_justice_revoked_output(&bumped_tx, i, outp.amount, &outp.per_commitment_key, &onchain_handler.secp_ctx) {
-                                               bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
-                                               bumped_tx.input[i].witness[0].push(SigHashType::All as u8);
+                                               let mut ser_sig = sig.serialize_der().to_vec();
+                                               ser_sig.push(EcdsaSighashType::All as u8);
+                                               bumped_tx.input[i].witness.push(ser_sig);
                                                bumped_tx.input[i].witness.push(vec!(1));
                                                bumped_tx.input[i].witness.push(witness_script.clone().into_bytes());
                                        } else { return false; }
@@ -364,8 +366,9 @@ impl PackageSolvingData {
                                        let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, onchain_handler.opt_anchors(), &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
                                        //TODO: should we panic on signer failure ?
                                        if let Ok(sig) = onchain_handler.signer.sign_justice_revoked_htlc(&bumped_tx, i, outp.amount, &outp.per_commitment_key, &outp.htlc, &onchain_handler.secp_ctx) {
-                                               bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
-                                               bumped_tx.input[i].witness[0].push(SigHashType::All as u8);
+                                               let mut ser_sig = sig.serialize_der().to_vec();
+                                               ser_sig.push(EcdsaSighashType::All as u8);
+                                               bumped_tx.input[i].witness.push(ser_sig);
                                                bumped_tx.input[i].witness.push(chan_keys.revocation_key.clone().serialize().to_vec());
                                                bumped_tx.input[i].witness.push(witness_script.clone().into_bytes());
                                        } else { return false; }
@@ -376,8 +379,9 @@ impl PackageSolvingData {
                                        let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, onchain_handler.opt_anchors(), &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
 
                                        if let Ok(sig) = onchain_handler.signer.sign_counterparty_htlc_transaction(&bumped_tx, i, &outp.htlc.amount_msat / 1000, &outp.per_commitment_point, &outp.htlc, &onchain_handler.secp_ctx) {
-                                               bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
-                                               bumped_tx.input[i].witness[0].push(SigHashType::All as u8);
+                                               let mut ser_sig = sig.serialize_der().to_vec();
+                                               ser_sig.push(EcdsaSighashType::All as u8);
+                                               bumped_tx.input[i].witness.push(ser_sig);
                                                bumped_tx.input[i].witness.push(outp.preimage.0.to_vec());
                                                bumped_tx.input[i].witness.push(witness_script.clone().into_bytes());
                                        }
@@ -389,8 +393,9 @@ impl PackageSolvingData {
 
                                        bumped_tx.lock_time = outp.htlc.cltv_expiry; // Right now we don't aggregate time-locked transaction, if we do we should set lock_time before to avoid breaking hash computation
                                        if let Ok(sig) = onchain_handler.signer.sign_counterparty_htlc_transaction(&bumped_tx, i, &outp.htlc.amount_msat / 1000, &outp.per_commitment_point, &outp.htlc, &onchain_handler.secp_ctx) {
-                                               bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
-                                               bumped_tx.input[i].witness[0].push(SigHashType::All as u8);
+                                               let mut ser_sig = sig.serialize_der().to_vec();
+                                               ser_sig.push(EcdsaSighashType::All as u8);
+                                               bumped_tx.input[i].witness.push(ser_sig);
                                                // Due to BIP146 (MINIMALIF) this must be a zero-length element to relay.
                                                bumped_tx.input[i].witness.push(vec![]);
                                                bumped_tx.input[i].witness.push(witness_script.clone().into_bytes());
@@ -620,7 +625,7 @@ impl PackageTemplate {
                                                previous_output: *outpoint,
                                                script_sig: Script::new(),
                                                sequence: 0xfffffffd,
-                                               witness: Vec::new(),
+                                               witness: Witness::new(),
                                        });
                                }
                                for (i, (outpoint, out)) in self.inputs.iter().enumerate() {
@@ -852,7 +857,7 @@ mod tests {
 
        use bitcoin::hashes::hex::FromHex;
 
-       use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+       use bitcoin::secp256k1::{PublicKey,SecretKey};
        use bitcoin::secp256k1::Secp256k1;
 
        macro_rules! dumb_revk_output {
index 370c0cc8edfe6737f3f1d65f5dab59ea688ee854..9e987c3deec005debbdb81fd7557a6be75e955f1 100644 (file)
@@ -12,8 +12,8 @@
 
 use bitcoin::blockdata::script::{Script,Builder};
 use bitcoin::blockdata::opcodes;
-use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction, SigHashType};
-use bitcoin::util::bip143;
+use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction, EcdsaSighashType};
+use bitcoin::util::sighash;
 
 use bitcoin::hashes::{Hash, HashEngine};
 use bitcoin::hashes::sha256::Hash as Sha256;
@@ -26,10 +26,10 @@ use util::ser::{Readable, Writeable, Writer};
 use util::{byte_utils, transaction_utils};
 
 use bitcoin::hash_types::WPubkeyHash;
-use bitcoin::secp256k1::key::{SecretKey, PublicKey};
-use bitcoin::secp256k1::{Secp256k1, Signature, Message};
+use bitcoin::secp256k1::{SecretKey, PublicKey};
+use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Message};
 use bitcoin::secp256k1::Error as SecpError;
-use bitcoin::secp256k1;
+use bitcoin::{secp256k1, Witness};
 
 use io;
 use prelude::*;
@@ -102,7 +102,7 @@ pub fn build_closing_transaction(to_holder_value_sat: u64, to_counterparty_value
                        previous_output: funding_outpoint,
                        script_sig: Script::new(),
                        sequence: 0xffffffff,
-                       witness: Vec::new(),
+                       witness: Witness::new(),
                });
                ins
        };
@@ -615,7 +615,7 @@ pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, conte
                },
                script_sig: Script::new(),
                sequence: if opt_anchors { 1 } else { 0 },
-               witness: Vec::new(),
+               witness: Witness::new(),
        });
 
        let weight = if htlc.offered {
@@ -891,16 +891,18 @@ impl HolderCommitmentTransaction {
                // First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element.
                let mut tx = self.inner.built.transaction.clone();
                tx.input[0].witness.push(Vec::new());
+               let mut ser_holder_sig = holder_sig.serialize_der().to_vec();
+               ser_holder_sig.push(EcdsaSighashType::All as u8);
+               let mut ser_cp_sig = self.counterparty_sig.serialize_der().to_vec();
+               ser_cp_sig.push(EcdsaSighashType::All as u8);
 
                if self.holder_sig_first {
-                       tx.input[0].witness.push(holder_sig.serialize_der().to_vec());
-                       tx.input[0].witness.push(self.counterparty_sig.serialize_der().to_vec());
+                       tx.input[0].witness.push(ser_holder_sig);
+                       tx.input[0].witness.push(ser_cp_sig);
                } else {
-                       tx.input[0].witness.push(self.counterparty_sig.serialize_der().to_vec());
-                       tx.input[0].witness.push(holder_sig.serialize_der().to_vec());
+                       tx.input[0].witness.push(ser_cp_sig);
+                       tx.input[0].witness.push(ser_holder_sig);
                }
-               tx.input[0].witness[1].push(SigHashType::All as u8);
-               tx.input[0].witness[2].push(SigHashType::All as u8);
 
                tx.input[0].witness.push(funding_redeemscript.as_bytes().to_vec());
                tx
@@ -929,7 +931,7 @@ impl BuiltCommitmentTransaction {
        ///
        /// This can be used to verify a signature.
        pub fn get_sighash_all(&self, funding_redeemscript: &Script, channel_value_satoshis: u64) -> Message {
-               let sighash = &bip143::SigHashCache::new(&self.transaction).signature_hash(0, funding_redeemscript, channel_value_satoshis, SigHashType::All)[..];
+               let sighash = &sighash::SighashCache::new(&self.transaction).segwit_signature_hash(0, funding_redeemscript, channel_value_satoshis, EcdsaSighashType::All).unwrap()[..];
                hash_to_message!(sighash)
        }
 
@@ -1053,7 +1055,7 @@ impl<'a> TrustedClosingTransaction<'a> {
        ///
        /// This can be used to verify a signature.
        pub fn get_sighash_all(&self, funding_redeemscript: &Script, channel_value_satoshis: u64) -> Message {
-               let sighash = &bip143::SigHashCache::new(&self.inner.built).signature_hash(0, funding_redeemscript, channel_value_satoshis, SigHashType::All)[..];
+               let sighash = &sighash::SighashCache::new(&self.inner.built).segwit_signature_hash(0, funding_redeemscript, channel_value_satoshis, EcdsaSighashType::All).unwrap()[..];
                hash_to_message!(sighash)
        }
 
@@ -1291,7 +1293,7 @@ impl CommitmentTransaction {
                                script_sig: Script::new(),
                                sequence: ((0x80 as u32) << 8 * 3)
                                        | ((obscured_commitment_transaction_number >> 3 * 8) as u32),
-                               witness: Vec::new(),
+                               witness: Witness::new(),
                        });
                        ins
                };
@@ -1401,7 +1403,7 @@ impl<'a> TrustedCommitmentTransaction<'a> {
        ///
        /// The returned Vec has one entry for each HTLC, and in the same order.
        ///
-       /// This function is only valid in the holder commitment context, it always uses SigHashType::All.
+       /// This function is only valid in the holder commitment context, it always uses EcdsaSighashType::All.
        pub fn get_htlc_sigs<T: secp256k1::Signing>(&self, htlc_base_key: &SecretKey, channel_parameters: &DirectedChannelTransactionParameters, secp_ctx: &Secp256k1<T>) -> Result<Vec<Signature>, ()> {
                let inner = self.inner;
                let keys = &inner.keys;
@@ -1415,7 +1417,7 @@ impl<'a> TrustedCommitmentTransaction<'a> {
 
                        let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
 
-                       let sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, this_htlc.amount_msat / 1000, SigHashType::All)[..]);
+                       let sighash = hash_to_message!(&sighash::SighashCache::new(&htlc_tx).segwit_signature_hash(0, &htlc_redeemscript, this_htlc.amount_msat / 1000, EcdsaSighashType::All).unwrap()[..]);
                        ret.push(sign(secp_ctx, &sighash, &holder_htlc_key));
                }
                Ok(ret)
@@ -1437,15 +1439,17 @@ impl<'a> TrustedCommitmentTransaction<'a> {
 
                let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
 
-               let sighashtype = if self.opt_anchors() { SigHashType::SinglePlusAnyoneCanPay } else { SigHashType::All };
+               let sighashtype = if self.opt_anchors() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
 
                // First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element.
                htlc_tx.input[0].witness.push(Vec::new());
 
-               htlc_tx.input[0].witness.push(counterparty_signature.serialize_der().to_vec());
-               htlc_tx.input[0].witness.push(signature.serialize_der().to_vec());
-               htlc_tx.input[0].witness[1].push(sighashtype as u8);
-               htlc_tx.input[0].witness[2].push(SigHashType::All as u8);
+               let mut cp_sig_ser = counterparty_signature.serialize_der().to_vec();
+               cp_sig_ser.push(sighashtype as u8);
+               htlc_tx.input[0].witness.push(cp_sig_ser);
+               let mut holder_sig_ser = signature.serialize_der().to_vec();
+               holder_sig_ser.push(EcdsaSighashType::All as u8);
+               htlc_tx.input[0].witness.push(holder_sig_ser);
 
                if this_htlc.offered {
                        // Due to BIP146 (MINIMALIF) this must be a zero-length element to relay.
index 10f18cec32d456d16b5ab2e7867ffadfb3ba5125..43032c51a3c09cdc67988e96050835fd7a17d9d7 100644 (file)
@@ -8,8 +8,8 @@
 // licenses.
 
 use bitcoin::blockdata::script::{Script,Builder};
-use bitcoin::blockdata::transaction::{Transaction, SigHashType};
-use bitcoin::util::bip143;
+use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType};
+use bitcoin::util::sighash;
 use bitcoin::consensus::encode;
 
 use bitcoin::hashes::Hash;
@@ -18,8 +18,8 @@ use bitcoin::hashes::sha256d::Hash as Sha256d;
 use bitcoin::hash_types::{Txid, BlockHash};
 
 use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE;
-use bitcoin::secp256k1::key::{PublicKey,SecretKey};
-use bitcoin::secp256k1::{Secp256k1,Signature};
+use bitcoin::secp256k1::{PublicKey,SecretKey};
+use bitcoin::secp256k1::{Secp256k1,ecdsa::Signature};
 use bitcoin::secp256k1;
 
 use ln::{PaymentPreimage, PaymentHash};
@@ -1946,6 +1946,10 @@ impl<Signer: Sign> Channel<Signer> {
                if msg.dust_limit_satoshis > self.holder_selected_channel_reserve_satoshis {
                        return Err(ChannelError::Close(format!("Dust limit ({}) is bigger than our channel reserve ({})", msg.dust_limit_satoshis, self.holder_selected_channel_reserve_satoshis)));
                }
+               if msg.channel_reserve_satoshis > self.channel_value_satoshis - self.holder_selected_channel_reserve_satoshis {
+                       return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must not be greater than channel value minus our reserve ({})",
+                               msg.channel_reserve_satoshis, self.channel_value_satoshis - self.holder_selected_channel_reserve_satoshis)));
+               }
                let full_channel_value_msat = (self.channel_value_satoshis - msg.channel_reserve_satoshis) * 1000;
                if msg.htlc_minimum_msat >= full_channel_value_msat {
                        return Err(ChannelError::Close(format!("Minimum htlc value ({}) is full channel value ({})", msg.htlc_minimum_msat, full_channel_value_msat)));
@@ -2063,7 +2067,7 @@ impl<Signer: Sign> Channel<Signer> {
                                log_bytes!(sig.serialize_compact()[..]), log_bytes!(self.counterparty_funding_pubkey().serialize()),
                                encode::serialize_hex(&initial_commitment_bitcoin_tx.transaction), log_bytes!(sighash[..]),
                                encode::serialize_hex(&funding_script), log_bytes!(self.channel_id()));
-                       secp_check!(self.secp_ctx.verify(&sighash, &sig, self.counterparty_funding_pubkey()), "Invalid funding_created signature from peer".to_owned());
+                       secp_check!(self.secp_ctx.verify_ecdsa(&sighash, &sig, self.counterparty_funding_pubkey()), "Invalid funding_created signature from peer".to_owned());
                }
 
                let counterparty_keys = self.build_remote_transaction_keys()?;
@@ -2195,7 +2199,7 @@ impl<Signer: Sign> Channel<Signer> {
                        let initial_commitment_bitcoin_tx = trusted_tx.built_transaction();
                        let sighash = initial_commitment_bitcoin_tx.get_sighash_all(&funding_script, self.channel_value_satoshis);
                        // They sign our commitment transaction, allowing us to broadcast the tx if we wish.
-                       if let Err(_) = self.secp_ctx.verify(&sighash, &msg.signature, &self.get_counterparty_pubkeys().funding_pubkey) {
+                       if let Err(_) = self.secp_ctx.verify_ecdsa(&sighash, &msg.signature, &self.get_counterparty_pubkeys().funding_pubkey) {
                                return Err(ChannelError::Close("Invalid funding_signed signature from peer".to_owned()));
                        }
                }
@@ -2833,7 +2837,7 @@ impl<Signer: Sign> Channel<Signer> {
                                log_bytes!(msg.signature.serialize_compact()[..]),
                                log_bytes!(self.counterparty_funding_pubkey().serialize()), encode::serialize_hex(&bitcoin_tx.transaction),
                                log_bytes!(sighash[..]), encode::serialize_hex(&funding_script), log_bytes!(self.channel_id()));
-                       if let Err(_) = self.secp_ctx.verify(&sighash, &msg.signature, &self.counterparty_funding_pubkey()) {
+                       if let Err(_) = self.secp_ctx.verify_ecdsa(&sighash, &msg.signature, &self.counterparty_funding_pubkey()) {
                                return Err((None, ChannelError::Close("Invalid commitment tx signature from peer".to_owned())));
                        }
                        bitcoin_tx.txid
@@ -2883,12 +2887,12 @@ impl<Signer: Sign> Channel<Signer> {
                                        &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
 
                                let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys);
-                               let htlc_sighashtype = if self.opt_anchors() { SigHashType::SinglePlusAnyoneCanPay } else { SigHashType::All };
-                               let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype)[..]);
+                               let htlc_sighashtype = if self.opt_anchors() { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
+                               let htlc_sighash = hash_to_message!(&sighash::SighashCache::new(&htlc_tx).segwit_signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype).unwrap()[..]);
                                log_trace!(logger, "Checking HTLC tx signature {} by key {} against tx {} (sighash {}) with redeemscript {} in channel {}.",
                                        log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(keys.countersignatory_htlc_key.serialize()),
                                        encode::serialize_hex(&htlc_tx), log_bytes!(htlc_sighash[..]), encode::serialize_hex(&htlc_redeemscript), log_bytes!(self.channel_id()));
-                               if let Err(_) = self.secp_ctx.verify(&htlc_sighash, &msg.htlc_signatures[idx], &keys.countersignatory_htlc_key) {
+                               if let Err(_) = self.secp_ctx.verify_ecdsa(&htlc_sighash, &msg.htlc_signatures[idx], &keys.countersignatory_htlc_key) {
                                        return Err((None, ChannelError::Close("Invalid HTLC tx signature from peer".to_owned())));
                                }
                                htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source));
@@ -3756,6 +3760,15 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
 
+               // Before we change the state of the channel, we check if the peer is sending a very old
+               // commitment transaction number, if yes we send a warning message.
+               let our_commitment_transaction = INITIAL_COMMITMENT_NUMBER - self.cur_holder_commitment_transaction_number - 1;
+               if  msg.next_remote_commitment_number + 1 < our_commitment_transaction {
+                       return Err(
+                               ChannelError::Warn(format!("Peer attempted to reestablish channel with a very old local commitment transaction: {} (received) vs {} (expected)", msg.next_remote_commitment_number, our_commitment_transaction))
+                       );
+               }
+
                // Go ahead and unmark PeerDisconnected as various calls we may make check for it (and all
                // remaining cases either succeed or ErrorMessage-fail).
                self.channel_state &= !(ChannelState::PeerDisconnected as u32);
@@ -4125,15 +4138,17 @@ impl<Signer: Sign> Channel<Signer> {
 
                let funding_key = self.get_holder_pubkeys().funding_pubkey.serialize();
                let counterparty_funding_key = self.counterparty_funding_pubkey().serialize();
+               let mut holder_sig = sig.serialize_der().to_vec();
+               holder_sig.push(EcdsaSighashType::All as u8);
+               let mut cp_sig = counterparty_sig.serialize_der().to_vec();
+               cp_sig.push(EcdsaSighashType::All as u8);
                if funding_key[..] < counterparty_funding_key[..] {
-                       tx.input[0].witness.push(sig.serialize_der().to_vec());
-                       tx.input[0].witness.push(counterparty_sig.serialize_der().to_vec());
+                       tx.input[0].witness.push(holder_sig);
+                       tx.input[0].witness.push(cp_sig);
                } else {
-                       tx.input[0].witness.push(counterparty_sig.serialize_der().to_vec());
-                       tx.input[0].witness.push(sig.serialize_der().to_vec());
+                       tx.input[0].witness.push(cp_sig);
+                       tx.input[0].witness.push(holder_sig);
                }
-               tx.input[0].witness[1].push(SigHashType::All as u8);
-               tx.input[0].witness[2].push(SigHashType::All as u8);
 
                tx.input[0].witness.push(self.get_funding_redeemscript().into_bytes());
                tx
@@ -4171,14 +4186,14 @@ impl<Signer: Sign> Channel<Signer> {
                }
                let sighash = closing_tx.trust().get_sighash_all(&funding_redeemscript, self.channel_value_satoshis);
 
-               match self.secp_ctx.verify(&sighash, &msg.signature, &self.get_counterparty_pubkeys().funding_pubkey) {
+               match self.secp_ctx.verify_ecdsa(&sighash, &msg.signature, &self.get_counterparty_pubkeys().funding_pubkey) {
                        Ok(_) => {},
                        Err(_e) => {
                                // The remote end may have decided to revoke their output due to inconsistent dust
                                // limits, so check for that case by re-checking the signature here.
                                closing_tx = self.build_closing_transaction(msg.fee_satoshis, true).0;
                                let sighash = closing_tx.trust().get_sighash_all(&funding_redeemscript, self.channel_value_satoshis);
-                               secp_check!(self.secp_ctx.verify(&sighash, &msg.signature, self.counterparty_funding_pubkey()), "Invalid closing tx signature from peer".to_owned());
+                               secp_check!(self.secp_ctx.verify_ecdsa(&sighash, &msg.signature, self.counterparty_funding_pubkey()), "Invalid closing tx signature from peer".to_owned());
                        },
                };
 
@@ -4739,10 +4754,14 @@ impl<Signer: Sign> Channel<Signer> {
                        }
 
                        // If we've sent funding_locked (or have both sent and received funding_locked), and
-                       // the funding transaction's confirmation count has dipped below minimum_depth / 2,
+                       // the funding transaction has become unconfirmed,
                        // close the channel and hope we can get the latest state on chain (because presumably
                        // the funding transaction is at least still in the mempool of most nodes).
-                       if funding_tx_confirmations < self.minimum_depth.unwrap() as i64 / 2 {
+                       //
+                       // Note that ideally we wouldn't force-close if we see *any* reorg on a 1-conf channel,
+                       // but not doing so may lead to the `ChannelManager::short_to_id` map being
+                       // inconsistent, so we currently have to.
+                       if funding_tx_confirmations == 0 && self.funding_tx_confirmed_in.is_some() {
                                let err_reason = format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.",
                                        self.minimum_depth.unwrap(), funding_tx_confirmations);
                                return Err(ClosureReason::ProcessingError { err: err_reason });
@@ -5064,12 +5083,12 @@ impl<Signer: Sign> Channel<Signer> {
 
                let msghash = hash_to_message!(&Sha256d::hash(&announcement.encode()[..])[..]);
 
-               if self.secp_ctx.verify(&msghash, &msg.node_signature, &self.get_counterparty_node_id()).is_err() {
+               if self.secp_ctx.verify_ecdsa(&msghash, &msg.node_signature, &self.get_counterparty_node_id()).is_err() {
                        return Err(ChannelError::Close(format!(
                                "Bad announcement_signatures. Failed to verify node_signature. UnsignedChannelAnnouncement used for verification is {:?}. their_node_key is {:?}",
                                 &announcement, self.get_counterparty_node_id())));
                }
-               if self.secp_ctx.verify(&msghash, &msg.bitcoin_signature, self.counterparty_funding_pubkey()).is_err() {
+               if self.secp_ctx.verify_ecdsa(&msghash, &msg.bitcoin_signature, self.counterparty_funding_pubkey()).is_err() {
                        return Err(ChannelError::Close(format!(
                                "Bad announcement_signatures. Failed to verify bitcoin_signature. UnsignedChannelAnnouncement used for verification is {:?}. their_bitcoin_key is ({:?})",
                                &announcement, self.counterparty_funding_pubkey())));
@@ -6378,15 +6397,15 @@ mod tests {
        use util::errors::APIError;
        use util::test_utils;
        use util::test_utils::OnGetShutdownScriptpubkey;
-       use bitcoin::secp256k1::{Secp256k1, Signature};
+       use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
        use bitcoin::secp256k1::ffi::Signature as FFISignature;
-       use bitcoin::secp256k1::key::{SecretKey,PublicKey};
-       use bitcoin::secp256k1::recovery::RecoverableSignature;
+       use bitcoin::secp256k1::{SecretKey,PublicKey};
+       use bitcoin::secp256k1::ecdsa::RecoverableSignature;
        use bitcoin::hashes::sha256::Hash as Sha256;
        use bitcoin::hashes::Hash;
        use bitcoin::hash_types::WPubkeyHash;
-       use core::num::NonZeroU8;
        use bitcoin::bech32::u5;
+       use bitcoin::util::address::WitnessVersion;
        use prelude::*;
 
        struct TestFeeEstimator {
@@ -6450,7 +6469,7 @@ mod tests {
        fn upfront_shutdown_script_incompatibility() {
                let features = InitFeatures::known().clear_shutdown_anysegwit();
                let non_v0_segwit_shutdown_script =
-                       ShutdownScript::new_witness_program(NonZeroU8::new(16).unwrap(), &[0, 40]).unwrap();
+                       ShutdownScript::new_witness_program(WitnessVersion::V16, &[0, 40]).unwrap();
 
                let seed = [42; 32];
                let network = Network::Testnet;
@@ -6804,9 +6823,9 @@ mod tests {
        #[cfg(not(feature = "grind_signatures"))]
        #[test]
        fn outbound_commitment_test() {
-               use bitcoin::util::bip143;
+               use bitcoin::util::sighash;
                use bitcoin::consensus::encode::serialize;
-               use bitcoin::blockdata::transaction::SigHashType;
+               use bitcoin::blockdata::transaction::EcdsaSighashType;
                use bitcoin::hashes::hex::FromHex;
                use bitcoin::hash_types::Txid;
                use bitcoin::secp256k1::Message;
@@ -6915,7 +6934,7 @@ mod tests {
                                let counterparty_signature = Signature::from_der(&hex::decode($counterparty_sig_hex).unwrap()[..]).unwrap();
                                let sighash = unsigned_tx.get_sighash_all(&redeemscript, chan.channel_value_satoshis);
                                log_trace!(logger, "unsigned_tx = {}", hex::encode(serialize(&unsigned_tx.transaction)));
-                               assert!(secp_ctx.verify(&sighash, &counterparty_signature, chan.counterparty_funding_pubkey()).is_ok(), "verify counterparty commitment sig");
+                               assert!(secp_ctx.verify_ecdsa(&sighash, &counterparty_signature, chan.counterparty_funding_pubkey()).is_ok(), "verify counterparty commitment sig");
 
                                let mut per_htlc: Vec<(HTLCOutputInCommitment, Option<Signature>)> = Vec::new();
                                per_htlc.clear(); // Don't warn about excess mut for no-HTLC calls
@@ -6954,9 +6973,9 @@ mod tests {
                                                chan.get_counterparty_selected_contest_delay().unwrap(),
                                                &htlc, $opt_anchors, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
                                        let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, $opt_anchors, &keys);
-                                       let htlc_sighashtype = if $opt_anchors { SigHashType::SinglePlusAnyoneCanPay } else { SigHashType::All };
-                                       let htlc_sighash = Message::from_slice(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype)[..]).unwrap();
-                                       assert!(secp_ctx.verify(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key).is_ok(), "verify counterparty htlc sig");
+                                       let htlc_sighashtype = if $opt_anchors { EcdsaSighashType::SinglePlusAnyoneCanPay } else { EcdsaSighashType::All };
+                                       let htlc_sighash = Message::from_slice(&sighash::SighashCache::new(&htlc_tx).segwit_signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype).unwrap()[..]).unwrap();
+                                       assert!(secp_ctx.verify_ecdsa(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key).is_ok(), "verify counterparty htlc sig");
 
                                        let mut preimage: Option<PaymentPreimage> = None;
                                        if !htlc.offered {
index a28d6347332694af4dab7fc0737dd13a2a38c834..2ce466c9ac6d4efe7c0cea8a2af324a7d4ecaf19 100644 (file)
@@ -28,7 +28,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::{BlockHash, Txid};
 
-use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+use bitcoin::secp256k1::{SecretKey,PublicKey};
 use bitcoin::secp256k1::Secp256k1;
 use bitcoin::secp256k1::ecdh::SharedSecret;
 use bitcoin::secp256k1;
@@ -48,6 +48,7 @@ use ln::msgs;
 use ln::msgs::NetAddress;
 use ln::onion_utils;
 use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT, OptionalField};
+use ln::wire::Encode;
 use chain::keysinterface::{Sign, KeysInterface, KeysManager, InMemorySigner, Recipient};
 use util::config::UserConfig;
 use util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
@@ -2070,11 +2071,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
                }
 
-               let shared_secret = {
-                       let mut arr = [0; 32];
-                       arr.copy_from_slice(&SharedSecret::new(&msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key)[..]);
-                       arr
-               };
+               let shared_secret = SharedSecret::new(&msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key).secret_bytes();
 
                if msg.onion_routing_packet.version != 0 {
                        //TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
@@ -2253,7 +2250,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        break None;
                                }
                                {
-                                       let mut res = VecWriter(Vec::with_capacity(chan_update.serialized_length() + 8 + 2));
+                                       let mut res = VecWriter(Vec::with_capacity(chan_update.serialized_length() + 2 + 8 + 2));
                                        if let Some(chan_update) = chan_update {
                                                if code == 0x1000 | 11 || code == 0x1000 | 12 {
                                                        msg.amount_msat.write(&mut res).expect("Writes cannot fail");
@@ -2265,7 +2262,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                        // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
                                                        0u16.write(&mut res).expect("Writes cannot fail");
                                                }
-                                               (chan_update.serialized_length() as u16).write(&mut res).expect("Writes cannot fail");
+                                               (chan_update.serialized_length() as u16 + 2).write(&mut res).expect("Writes cannot fail");
+                                               msgs::ChannelUpdate::TYPE.write(&mut res).expect("Writes cannot fail");
                                                chan_update.write(&mut res).expect("Writes cannot fail");
                                        }
                                        return_err!(err, code, &res.0[..]);
@@ -2324,7 +2322,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                };
 
                let msg_hash = Sha256dHash::hash(&unsigned.encode()[..]);
-               let sig = self.secp_ctx.sign(&hash_to_message!(&msg_hash[..]), &self.our_network_key);
+               let sig = self.secp_ctx.sign_ecdsa(&hash_to_message!(&msg_hash[..]), &self.our_network_key);
 
                Ok(msgs::ChannelUpdate {
                        signature: sig,
@@ -2925,11 +2923,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                        if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
                                                                                                let phantom_secret_res = self.keys_manager.get_node_secret(Recipient::PhantomNode);
                                                                                                if phantom_secret_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id) {
-                                                                                                       let phantom_shared_secret = {
-                                                                                                               let mut arr = [0; 32];
-                                                                                                               arr.copy_from_slice(&SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap())[..]);
-                                                                                                               arr
-                                                                                                       };
+                                                                                                       let phantom_shared_secret = SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap()).secret_bytes();
                                                                                                        let next_hop = match onion_utils::decode_next_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
                                                                                                                Ok(res) => res,
                                                                                                                Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
@@ -3551,12 +3545,13 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        fn get_htlc_temp_fail_err_and_data(&self, desired_err_code: u16, scid: u64, chan: &Channel<Signer>) -> (u16, Vec<u8>) {
                debug_assert_eq!(desired_err_code & 0x1000, 0x1000);
                if let Ok(upd) = self.get_channel_update_for_onion(scid, chan) {
-                       let mut enc = VecWriter(Vec::with_capacity(upd.serialized_length() + 4));
+                       let mut enc = VecWriter(Vec::with_capacity(upd.serialized_length() + 6));
                        if desired_err_code == 0x1000 | 20 {
                                // TODO: underspecified, follow https://github.com/lightning/bolts/issues/791
                                0u16.write(&mut enc).expect("Writes cannot fail");
                        }
-                       (upd.serialized_length() as u16).write(&mut enc).expect("Writes cannot fail");
+                       (upd.serialized_length() as u16 + 2).write(&mut enc).expect("Writes cannot fail");
+                       msgs::ChannelUpdate::TYPE.write(&mut enc).expect("Writes cannot fail");
                        upd.write(&mut enc).expect("Writes cannot fail");
                        (desired_err_code, enc.0)
                } else {
index 163c6cbef568c0689c42716366691800108d345e..b4807ea688629a5a1940a1bb37e9b9ba56aa9760 100644 (file)
@@ -35,7 +35,7 @@ use bitcoin::network::constants::Network;
 
 use bitcoin::hash_types::BlockHash;
 
-use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::PublicKey;
 
 use io;
 use prelude::*;
@@ -859,7 +859,7 @@ macro_rules! check_spends {
                        for output in $tx.output.iter() {
                                total_value_out += output.value;
                        }
-                       let min_fee = ($tx.get_weight() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up)
+                       let min_fee = ($tx.weight() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up)
                        // Input amount - output amount = fee, so check that out + min_fee is smaller than input
                        assert!(total_value_out + min_fee <= total_value_in);
                        $tx.verify(get_output).unwrap();
@@ -2004,7 +2004,10 @@ pub fn check_preimage_claim<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, prev_txn: &Vec<
        for tx in prev_txn {
                if node_txn[0].input[0].previous_output.txid == tx.txid() {
                        check_spends!(node_txn[0], tx);
-                       assert!(node_txn[0].input[0].witness[2].len() > 106); // must spend an htlc output
+                       let mut iter = node_txn[0].input[0].witness.iter();
+                       iter.next().expect("expected 3 witness items");
+                       iter.next().expect("expected 3 witness items");
+                       assert!(iter.next().expect("expected 3 witness items").len() > 106); // must spend an htlc output
                        assert_eq!(tx.input.len(), 1); // must spend a commitment tx
 
                        found_prev = true;
index 73c3a86d782315f87b67b3f1875b09b0fa974e9f..aa68454063a596e6f5895632fe9f1c0763453d66 100644 (file)
@@ -42,7 +42,7 @@ use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::network::constants::Network;
 
 use bitcoin::secp256k1::Secp256k1;
-use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+use bitcoin::secp256k1::{PublicKey,SecretKey};
 
 use regex;
 
@@ -3489,6 +3489,47 @@ fn test_dup_events_on_peer_disconnect() {
        expect_payment_path_successful!(nodes[0]);
 }
 
+#[test]
+fn test_peer_disconnected_before_funding_broadcasted() {
+       // Test that channels are closed with `ClosureReason::DisconnectedPeer` if the peer disconnects
+       // before the funding transaction has been broadcasted.
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       // Open a channel between `nodes[0]` and `nodes[1]`, for which the funding transaction is never
+       // broadcasted, even though it's created by `nodes[0]`.
+       let expected_temporary_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None).unwrap();
+       let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_channel);
+       let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel);
+
+       let (temporary_channel_id, tx, _funding_output) = create_funding_transaction(&nodes[0], 1_000_000, 42);
+       assert_eq!(temporary_channel_id, expected_temporary_channel_id);
+
+       assert!(nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).is_ok());
+
+       let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
+       assert_eq!(funding_created_msg.temporary_channel_id, expected_temporary_channel_id);
+
+       // Even though the funding transaction is created by `nodes[0]`, the `FundingCreated` msg is
+       // never sent to `nodes[1]`, and therefore the tx is never signed by either party nor
+       // broadcasted.
+       {
+               assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
+       }
+
+       // Ensure that the channel is closed with `ClosureReason::DisconnectedPeer` when the peers are
+       // disconnected before the funding transaction was broadcasted.
+       nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
+       nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
+
+       check_closed_event!(nodes[0], 1, ClosureReason::DisconnectedPeer);
+       check_closed_event!(nodes[1], 1, ClosureReason::DisconnectedPeer);
+}
+
 #[test]
 fn test_simple_peer_disconnect() {
        // Test that we can reconnect when there are no lost messages
@@ -5746,8 +5787,8 @@ fn test_key_derivation_params() {
        check_spends!(local_txn_1[0], chan_1.3);
 
        // We check funding pubkey are unique
-       let (from_0_funding_key_0, from_0_funding_key_1) = (PublicKey::from_slice(&local_txn_0[0].input[0].witness[3][2..35]), PublicKey::from_slice(&local_txn_0[0].input[0].witness[3][36..69]));
-       let (from_1_funding_key_0, from_1_funding_key_1) = (PublicKey::from_slice(&local_txn_1[0].input[0].witness[3][2..35]), PublicKey::from_slice(&local_txn_1[0].input[0].witness[3][36..69]));
+       let (from_0_funding_key_0, from_0_funding_key_1) = (PublicKey::from_slice(&local_txn_0[0].input[0].witness.to_vec()[3][2..35]), PublicKey::from_slice(&local_txn_0[0].input[0].witness.to_vec()[3][36..69]));
+       let (from_1_funding_key_0, from_1_funding_key_1) = (PublicKey::from_slice(&local_txn_1[0].input[0].witness.to_vec()[3][2..35]), PublicKey::from_slice(&local_txn_1[0].input[0].witness.to_vec()[3][36..69]));
        if from_0_funding_key_0 == from_1_funding_key_0
            || from_0_funding_key_0 == from_1_funding_key_1
            || from_0_funding_key_1 == from_1_funding_key_0
@@ -7345,7 +7386,7 @@ fn test_data_loss_protect() {
        logger = test_utils::TestLogger::with_id(format!("node {}", 0));
        let mut chain_monitor = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut io::Cursor::new(previous_chain_monitor_state.0), keys_manager).unwrap().1;
        chain_source = test_utils::TestChainSource::new(Network::Testnet);
-       tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))};
+       tx_broadcaster = test_utils::TestBroadcaster { txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new())) };
        fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) };
        persister = test_utils::TestPersister::new();
        monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &tx_broadcaster, &logger, &fee_estimator, &persister, keys_manager);
@@ -7402,22 +7443,48 @@ fn test_data_loss_protect() {
        }
 
        // Check we close channel detecting A is fallen-behind
+       // Check that we sent the warning message when we detected that A has fallen behind,
+       // and give the possibility for A to recover from the warning.
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]);
-       check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: "Peer attempted to reestablish channel with a very old local commitment transaction".to_string() });
-       assert_eq!(check_closed_broadcast!(nodes[1], true).unwrap().data, "Peer attempted to reestablish channel with a very old local commitment transaction");
-       check_added_monitors!(nodes[1], 1);
+       let warn_msg = "Peer attempted to reestablish channel with a very old local commitment transaction".to_owned();
+       assert!(check_warn_msg!(nodes[1], nodes[0].node.get_our_node_id(), chan.2).contains(&warn_msg));
 
        // Check A is able to claim to_remote output
-       let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
-       assert_eq!(node_txn.len(), 1);
-       check_spends!(node_txn[0], chan.3);
-       assert_eq!(node_txn[0].output.len(), 2);
-       mine_transaction(&nodes[0], &node_txn[0]);
-       connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
-       check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: "We have fallen behind - we have received proof that if we broadcast remote is going to claim our funds - we can\'t do any automated broadcasting".to_string() });
-       let spend_txn = check_spendable_outputs!(nodes[0], node_cfgs[0].keys_manager);
-       assert_eq!(spend_txn.len(), 1);
-       check_spends!(spend_txn[0], node_txn[0]);
+       let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
+       // The node B should not broadcast the transaction to force close the channel!
+       assert!(node_txn.is_empty());
+       // B should now detect that there is something wrong and should force close the channel.
+       let exp_err = "We have fallen behind - we have received proof that if we broadcast remote is going to claim our funds - we can\'t do any automated broadcasting";
+       check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: exp_err.to_string() });
+
+       // after the warning message sent by B, we should not able to
+       // use the channel, or reconnect with success to the channel.
+       assert!(nodes[0].node.list_usable_channels().is_empty());
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
+       let retry_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
+
+       nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &retry_reestablish[0]);
+       let mut err_msgs_0 = Vec::with_capacity(1);
+       for msg in nodes[0].node.get_and_clear_pending_msg_events() {
+               if let MessageSendEvent::HandleError { ref action, .. } = msg {
+                       match action {
+                               &ErrorAction::SendErrorMessage { ref msg } => {
+                                       assert_eq!(msg.data, "Failed to find corresponding channel");
+                                       err_msgs_0.push(msg.clone());
+                               },
+                               _ => panic!("Unexpected event!"),
+                       }
+               } else {
+                       panic!("Unexpected event!");
+               }
+       }
+       assert_eq!(err_msgs_0.len(), 1);
+       nodes[1].node.handle_error(&nodes[0].node.get_our_node_id(), &err_msgs_0[0]);
+       assert!(nodes[1].node.list_usable_channels().is_empty());
+       check_added_monitors!(nodes[1], 1);
+       check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: "Failed to find corresponding channel".to_owned() });
+       check_closed_broadcast!(nodes[1], false);
 }
 
 #[test]
@@ -7615,7 +7682,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() {
                assert_eq!(node_txn[0].output.len(), 1);
                check_spends!(node_txn[0], revoked_txn[0]);
                let fee_1 = penalty_sum - node_txn[0].output[0].value;
-               feerate_1 = fee_1 * 1000 / node_txn[0].get_weight() as u64;
+               feerate_1 = fee_1 * 1000 / node_txn[0].weight() as u64;
                penalty_1 = node_txn[0].txid();
                node_txn.clear();
        };
@@ -7635,7 +7702,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() {
                        // Verify new bumped tx is different from last claiming transaction, we don't want spurrious rebroadcast
                        assert_ne!(penalty_2, penalty_1);
                        let fee_2 = penalty_sum - node_txn[0].output[0].value;
-                       feerate_2 = fee_2 * 1000 / node_txn[0].get_weight() as u64;
+                       feerate_2 = fee_2 * 1000 / node_txn[0].weight() as u64;
                        // Verify 25% bump heuristic
                        assert!(feerate_2 * 100 >= feerate_1 * 125);
                        node_txn.clear();
@@ -7658,7 +7725,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() {
                        // Verify new bumped tx is different from last claiming transaction, we don't want spurrious rebroadcast
                        assert_ne!(penalty_3, penalty_2);
                        let fee_3 = penalty_sum - node_txn[0].output[0].value;
-                       feerate_3 = fee_3 * 1000 / node_txn[0].get_weight() as u64;
+                       feerate_3 = fee_3 * 1000 / node_txn[0].weight() as u64;
                        // Verify 25% bump heuristic
                        assert!(feerate_3 * 100 >= feerate_2 * 125);
                        node_txn.clear();
@@ -7777,7 +7844,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
                first = node_txn[4].txid();
                // Store both feerates for later comparison
                let fee_1 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[2].output[0].value - node_txn[4].output[0].value;
-               feerate_1 = fee_1 * 1000 / node_txn[4].get_weight() as u64;
+               feerate_1 = fee_1 * 1000 / node_txn[4].weight() as u64;
                penalty_txn = vec![node_txn[2].clone()];
                node_txn.clear();
        }
@@ -7817,7 +7884,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
                // Verify bumped tx is different and 25% bump heuristic
                assert_ne!(first, node_txn[0].txid());
                let fee_2 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[2].output[0].value - node_txn[0].output[0].value;
-               let feerate_2 = fee_2 * 1000 / node_txn[0].get_weight() as u64;
+               let feerate_2 = fee_2 * 1000 / node_txn[0].weight() as u64;
                assert!(feerate_2 * 100 > feerate_1 * 125);
                let txn = vec![node_txn[0].clone()];
                node_txn.clear();
@@ -7901,12 +7968,12 @@ fn test_bump_penalty_txn_on_remote_commitment() {
                timeout = node_txn[6].txid();
                let index = node_txn[6].input[0].previous_output.vout;
                let fee = remote_txn[0].output[index as usize].value - node_txn[6].output[0].value;
-               feerate_timeout = fee * 1000 / node_txn[6].get_weight() as u64;
+               feerate_timeout = fee * 1000 / node_txn[6].weight() as u64;
 
                preimage = node_txn[0].txid();
                let index = node_txn[0].input[0].previous_output.vout;
                let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value;
-               feerate_preimage = fee * 1000 / node_txn[0].get_weight() as u64;
+               feerate_preimage = fee * 1000 / node_txn[0].weight() as u64;
 
                node_txn.clear();
        };
@@ -7925,13 +7992,13 @@ fn test_bump_penalty_txn_on_remote_commitment() {
 
                let index = preimage_bump.input[0].previous_output.vout;
                let fee = remote_txn[0].output[index as usize].value - preimage_bump.output[0].value;
-               let new_feerate = fee * 1000 / preimage_bump.get_weight() as u64;
+               let new_feerate = fee * 1000 / preimage_bump.weight() as u64;
                assert!(new_feerate * 100 > feerate_timeout * 125);
                assert_ne!(timeout, preimage_bump.txid());
 
                let index = node_txn[0].input[0].previous_output.vout;
                let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value;
-               let new_feerate = fee * 1000 / node_txn[0].get_weight() as u64;
+               let new_feerate = fee * 1000 / node_txn[0].weight() as u64;
                assert!(new_feerate * 100 > feerate_preimage * 125);
                assert_ne!(preimage, node_txn[0].txid());
 
index ef07d4c918f8597f28a6b3df90aeaded15b06bb9..281a2a8e977123158f5daeba45ff8666c96ec403 100644 (file)
@@ -24,8 +24,8 @@
 //! raw socket events into your non-internet-facing system and then send routing events back to
 //! track the network on the less-secure system.
 
-use bitcoin::secp256k1::key::PublicKey;
-use bitcoin::secp256k1::Signature;
+use bitcoin::secp256k1::PublicKey;
+use bitcoin::secp256k1::ecdsa::Signature;
 use bitcoin::secp256k1;
 use bitcoin::blockdata::script::Script;
 use bitcoin::hash_types::{Txid, BlockHash};
@@ -1835,7 +1835,7 @@ mod tests {
        use bitcoin::blockdata::opcodes;
        use bitcoin::hash_types::{Txid, BlockHash};
 
-       use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+       use bitcoin::secp256k1::{PublicKey,SecretKey};
        use bitcoin::secp256k1::{Secp256k1, Message};
 
        use io::Cursor;
@@ -1892,7 +1892,7 @@ mod tests {
                ($privkey: expr, $ctx: expr, $string: expr) => {
                        {
                                let sighash = Message::from_slice(&$string.into_bytes()[..]).unwrap();
-                               $ctx.sign(&sighash, &$privkey)
+                               $ctx.sign_ecdsa(&sighash, &$privkey)
                        }
                }
        }
@@ -2155,7 +2155,7 @@ mod tests {
                        htlc_basepoint: pubkey_5,
                        first_per_commitment_point: pubkey_6,
                        channel_flags: if random_bit { 1 << 5 } else { 0 },
-                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent },
+                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent },
                        channel_type: if incl_chan_type { Some(ChannelTypeFeatures::empty()) } else { None },
                };
                let encoded_value = open_channel.encode();
@@ -2211,7 +2211,7 @@ mod tests {
                        delayed_payment_basepoint: pubkey_4,
                        htlc_basepoint: pubkey_5,
                        first_per_commitment_point: pubkey_6,
-                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent },
+                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent },
                        channel_type: None,
                };
                let encoded_value = accept_channel.encode();
@@ -2279,9 +2279,9 @@ mod tests {
                let shutdown = msgs::Shutdown {
                        channel_id: [2; 32],
                        scriptpubkey:
-                                    if script_type == 1 { Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey() }
-                               else if script_type == 2 { Address::p2sh(&script, Network::Testnet).script_pubkey() }
-                               else if script_type == 3 { Address::p2wpkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).unwrap().script_pubkey() }
+                                    if script_type == 1 { Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey() }
+                               else if script_type == 2 { Address::p2sh(&script, Network::Testnet).unwrap().script_pubkey() }
+                               else if script_type == 3 { Address::p2wpkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).unwrap().script_pubkey() }
                                else                     { Address::p2wsh(&script, Network::Testnet).script_pubkey() },
                };
                let encoded_value = shutdown.encode();
index 834791cba958de960d0c5f90868173f5097f0705..9a07603fafe7e89e90b71a0d943bba59c483a223 100644 (file)
@@ -21,6 +21,7 @@ use routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintH
 use ln::features::{InitFeatures, InvoiceFeatures, NodeFeatures};
 use ln::msgs;
 use ln::msgs::{ChannelMessageHandler, ChannelUpdate, OptionalField};
+use ln::wire::Encode;
 use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
 use util::ser::{Writeable, Writer};
 use util::{byte_utils, test_utils};
@@ -33,7 +34,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
 
 use bitcoin::secp256k1;
 use bitcoin::secp256k1::Secp256k1;
-use bitcoin::secp256k1::key::{PublicKey, SecretKey};
+use bitcoin::secp256k1::{PublicKey, SecretKey};
 
 use io;
 use prelude::*;
@@ -214,7 +215,7 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case:
 impl msgs::ChannelUpdate {
        fn dummy(short_channel_id: u64) -> msgs::ChannelUpdate {
                use bitcoin::secp256k1::ffi::Signature as FFISignature;
-               use bitcoin::secp256k1::Signature;
+               use bitcoin::secp256k1::ecdsa::Signature;
                msgs::ChannelUpdate {
                        signature: Signature::from(unsafe { FFISignature::new() }),
                        contents: msgs::UnsignedChannelUpdate {
@@ -371,7 +372,7 @@ fn test_onion_failure() {
                // and tamper returning error message
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], NODE|2, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), NODE|2, &[0;0]);
        }, ||{}, true, Some(NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: false}), Some(route.paths[0][0].short_channel_id));
 
        // final node failure
@@ -379,7 +380,7 @@ fn test_onion_failure() {
                // and tamper returning error message
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], NODE|2, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[1].shared_secret.as_ref(), NODE|2, &[0;0]);
        }, ||{
                nodes[2].node.fail_htlc_backwards(&payment_hash);
        }, true, Some(NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: false}), Some(route.paths[0][1].short_channel_id));
@@ -391,14 +392,14 @@ fn test_onion_failure() {
        }, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|2, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), PERM|NODE|2, &[0;0]);
        }, ||{}, true, Some(PERM|NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true}), Some(route.paths[0][0].short_channel_id));
 
        // final node failure
        run_onion_failure_test_with_fail_intercept("permanent_node_failure", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|2, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[1].shared_secret.as_ref(), PERM|NODE|2, &[0;0]);
        }, ||{
                nodes[2].node.fail_htlc_backwards(&payment_hash);
        }, false, Some(PERM|NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true}), Some(route.paths[0][1].short_channel_id));
@@ -410,7 +411,7 @@ fn test_onion_failure() {
        }, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|3, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), PERM|NODE|3, &[0;0]);
        }, ||{
                nodes[2].node.fail_htlc_backwards(&payment_hash);
        }, true, Some(PERM|NODE|3), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true}), Some(route.paths[0][0].short_channel_id));
@@ -419,7 +420,7 @@ fn test_onion_failure() {
        run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|3, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[1].shared_secret.as_ref(), PERM|NODE|3, &[0;0]);
        }, ||{
                nodes[2].node.fail_htlc_backwards(&payment_hash);
        }, false, Some(PERM|NODE|3), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true}), Some(route.paths[0][1].short_channel_id));
@@ -438,13 +439,29 @@ fn test_onion_failure() {
                Some(BADONION|PERM|6), None, Some(short_channel_id));
 
        let short_channel_id = channels[1].0.contents.short_channel_id;
+       let chan_update = ChannelUpdate::dummy(short_channel_id);
+
+       let mut err_data = Vec::new();
+       err_data.extend_from_slice(&(chan_update.serialized_length() as u16 + 2).to_be_bytes());
+       err_data.extend_from_slice(&ChannelUpdate::TYPE.to_be_bytes());
+       err_data.extend_from_slice(&chan_update.encode());
+       run_onion_failure_test_with_fail_intercept("temporary_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
+               msg.amount_msat -= 1;
+       }, |msg| {
+               let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
+               let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), UPDATE|7, &err_data);
+       }, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: chan_update.clone()}), Some(short_channel_id));
+
+       // Check we can still handle onion failures that include channel updates without a type prefix
+       let err_data_without_type = chan_update.encode_with_len();
        run_onion_failure_test_with_fail_intercept("temporary_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
                msg.amount_msat -= 1;
        }, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], UPDATE|7, &ChannelUpdate::dummy(short_channel_id).encode_with_len()[..]);
-       }, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id));
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), UPDATE|7, &err_data_without_type);
+       }, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: chan_update}), Some(short_channel_id));
 
        let short_channel_id = channels[1].0.contents.short_channel_id;
        run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
@@ -452,7 +469,7 @@ fn test_onion_failure() {
        }, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|8, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), PERM|8, &[0;0]);
                // short_channel_id from the processing node
        }, ||{}, true, Some(PERM|8), Some(NetworkUpdate::ChannelClosed{short_channel_id, is_permanent: true}), Some(short_channel_id));
 
@@ -462,7 +479,7 @@ fn test_onion_failure() {
        }, |msg| {
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|9, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[0].shared_secret.as_ref(), PERM|9, &[0;0]);
                // short_channel_id from the processing node
        }, ||{}, true, Some(PERM|9), Some(NetworkUpdate::ChannelClosed{short_channel_id, is_permanent: true}), Some(short_channel_id));
 
@@ -571,7 +588,7 @@ fn test_onion_failure() {
                // Tamper returning error message
                let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
                let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
-               msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], 23, &[0;0]);
+               msg.reason = onion_utils::build_first_hop_failure_packet(onion_keys[1].shared_secret.as_ref(), 23, &[0;0]);
        }, ||{
                nodes[2].node.fail_htlc_backwards(&payment_hash);
        }, true, Some(23), None, None);
@@ -1097,11 +1114,15 @@ fn test_phantom_dust_exposure_failure() {
        commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
 
        // Ensure the payment fails with the expected error.
-       let mut error_data = channel.1.encode_with_len();
+       let mut err_data = Vec::new();
+       err_data.extend_from_slice(&(channel.1.serialized_length() as u16 + 2).to_be_bytes());
+       err_data.extend_from_slice(&ChannelUpdate::TYPE.to_be_bytes());
+       err_data.extend_from_slice(&channel.1.encode());
+
        let mut fail_conditions = PaymentFailedConditions::new()
                .blamed_scid(channel.0.contents.short_channel_id)
                .blamed_chan_closed(false)
-               .expected_htlc_error_data(0x1000 | 7, &error_data);
+               .expected_htlc_error_data(0x1000 | 7, &err_data);
                expect_payment_failed_conditions!(nodes[0], payment_hash, false, fail_conditions);
 }
 
index 0dd6087f82018d9faf56d53672325b76284caa00..9e4ae058f8d517bdfb93abb021d02a7eb588e8a5 100644 (file)
@@ -10,6 +10,7 @@
 use ln::{PaymentHash, PaymentPreimage, PaymentSecret};
 use ln::channelmanager::HTLCSource;
 use ln::msgs;
+use ln::wire::Encode;
 use routing::network_graph::NetworkUpdate;
 use routing::router::RouteHop;
 use util::chacha20::{ChaCha20, ChaChaReader};
@@ -22,7 +23,7 @@ use bitcoin::hashes::cmp::fixed_time_eq;
 use bitcoin::hashes::hmac::{Hmac, HmacEngine};
 use bitcoin::hashes::sha256::Hash as Sha256;
 
-use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+use bitcoin::secp256k1::{SecretKey,PublicKey};
 use bitcoin::secp256k1::Secp256k1;
 use bitcoin::secp256k1::ecdh::SharedSecret;
 use bitcoin::secp256k1;
@@ -47,12 +48,12 @@ pub(super) fn gen_rho_mu_from_shared_secret(shared_secret: &[u8]) -> ([u8; 32],
        assert_eq!(shared_secret.len(), 32);
        ({
                let mut hmac = HmacEngine::<Sha256>::new(&[0x72, 0x68, 0x6f]); // rho
-               hmac.input(&shared_secret[..]);
+               hmac.input(&shared_secret);
                Hmac::from_engine(hmac).into_inner()
        },
        {
                let mut hmac = HmacEngine::<Sha256>::new(&[0x6d, 0x75]); // mu
-               hmac.input(&shared_secret[..]);
+               hmac.input(&shared_secret);
                Hmac::from_engine(hmac).into_inner()
        })
 }
@@ -61,7 +62,7 @@ pub(super) fn gen_rho_mu_from_shared_secret(shared_secret: &[u8]) -> ([u8; 32],
 pub(super) fn gen_um_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
        assert_eq!(shared_secret.len(), 32);
        let mut hmac = HmacEngine::<Sha256>::new(&[0x75, 0x6d]); // um
-       hmac.input(&shared_secret[..]);
+       hmac.input(&shared_secret);
        Hmac::from_engine(hmac).into_inner()
 }
 
@@ -69,7 +70,7 @@ pub(super) fn gen_um_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
 pub(super) fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
        assert_eq!(shared_secret.len(), 32);
        let mut hmac = HmacEngine::<Sha256>::new(&[0x61, 0x6d, 0x6d, 0x61, 0x67]); // ammag
-       hmac.input(&shared_secret[..]);
+       hmac.input(&shared_secret);
        Hmac::from_engine(hmac).into_inner()
 }
 
@@ -84,7 +85,7 @@ pub(super) fn construct_onion_keys_callback<T: secp256k1::Signing, FType: FnMut(
 
                let mut sha = Sha256::engine();
                sha.input(&blinded_pub.serialize()[..]);
-               sha.input(&shared_secret[..]);
+               sha.input(shared_secret.as_ref());
                let blinding_factor = Sha256::from_engine(sha).into_inner();
 
                let ephemeral_pubkey = blinded_pub;
@@ -103,7 +104,7 @@ pub(super) fn construct_onion_keys<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T
        let mut res = Vec::with_capacity(path.len());
 
        construct_onion_keys_callback(secp_ctx, path, session_priv, |shared_secret, _blinding_factor, ephemeral_pubkey, _, _| {
-               let (rho, mu) = gen_rho_mu_from_shared_secret(&shared_secret[..]);
+               let (rho, mu) = gen_rho_mu_from_shared_secret(shared_secret.as_ref());
 
                res.push(OnionKeys {
                        #[cfg(test)]
@@ -347,7 +348,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
                        let amt_to_forward = htlc_msat - route_hop.fee_msat;
                        htlc_msat = amt_to_forward;
 
-                       let ammag = gen_ammag_from_shared_secret(&shared_secret[..]);
+                       let ammag = gen_ammag_from_shared_secret(shared_secret.as_ref());
 
                        let mut decryption_tmp = Vec::with_capacity(packet_decrypted.len());
                        decryption_tmp.resize(packet_decrypted.len(), 0);
@@ -361,7 +362,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
                        let failing_route_hop = if is_from_final_node { route_hop } else { &path[route_hop_idx + 1] };
 
                        if let Ok(err_packet) = msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet_decrypted)) {
-                               let um = gen_um_from_shared_secret(&shared_secret[..]);
+                               let um = gen_um_from_shared_secret(shared_secret.as_ref());
                                let mut hmac = HmacEngine::<Sha256>::new(&um);
                                hmac.input(&err_packet.encode()[32..]);
 
@@ -404,7 +405,21 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
                                                else if error_code & UPDATE == UPDATE {
                                                        if let Some(update_len_slice) = err_packet.failuremsg.get(debug_field_size+2..debug_field_size+4) {
                                                                let update_len = u16::from_be_bytes(update_len_slice.try_into().expect("len is 2")) as usize;
-                                                               if let Some(update_slice) = err_packet.failuremsg.get(debug_field_size + 4..debug_field_size + 4 + update_len) {
+                                                               if let Some(mut update_slice) = err_packet.failuremsg.get(debug_field_size + 4..debug_field_size + 4 + update_len) {
+                                                                       // Historically, the BOLTs were unclear if the message type
+                                                                       // bytes should be included here or not. The BOLTs have now
+                                                                       // been updated to indicate that they *are* included, but many
+                                                                       // nodes still send messages without the type bytes, so we
+                                                                       // support both here.
+                                                                       // TODO: Switch to hard require the type prefix, as the current
+                                                                       // permissiveness introduces the (although small) possibility
+                                                                       // that we fail to decode legitimate channel updates that
+                                                                       // happen to start with ChannelUpdate::TYPE, i.e., [0x01, 0x02].
+                                                                       if update_slice.len() > 2 && update_slice[0..2] == msgs::ChannelUpdate::TYPE.to_be_bytes() {
+                                                                               update_slice = &update_slice[2..];
+                                                                       } else {
+                                                                               log_trace!(logger, "Failure provided features a channel update without type prefix. Deprecated, but allowing for now.");
+                                                                       }
                                                                        if let Ok(chan_update) = msgs::ChannelUpdate::read(&mut Cursor::new(&update_slice)) {
                                                                                // if channel_update should NOT have caused the failure:
                                                                                // MAY treat the channel_update as invalid.
@@ -434,6 +449,8 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
                                                                                        // short channel id.
                                                                                        if failing_route_hop.short_channel_id == chan_update.contents.short_channel_id {
                                                                                                short_channel_id = Some(failing_route_hop.short_channel_id);
+                                                                                       } else {
+                                                                                               log_info!(logger, "Node provided a channel_update for which it was not authoritative, ignoring.");
                                                                                        }
                                                                                        network_update = Some(NetworkUpdate::ChannelUpdateMessage {
                                                                                                msg: chan_update,
@@ -478,10 +495,10 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
 
                                                let (description, title) = errors::get_onion_error_description(error_code);
                                                if debug_field_size > 0 && err_packet.failuremsg.len() >= 4 + debug_field_size {
-                                                       log_warn!(logger, "Onion Error[from {}: {}({:#x}) {}({})] {}", route_hop.pubkey, title, error_code, debug_field, log_bytes!(&err_packet.failuremsg[4..4+debug_field_size]), description);
+                                                       log_info!(logger, "Onion Error[from {}: {}({:#x}) {}({})] {}", route_hop.pubkey, title, error_code, debug_field, log_bytes!(&err_packet.failuremsg[4..4+debug_field_size]), description);
                                                }
                                                else {
-                                                       log_warn!(logger, "Onion Error[from {}: {}({:#x})] {}", route_hop.pubkey, title, error_code, description);
+                                                       log_info!(logger, "Onion Error[from {}: {}({:#x})] {}", route_hop.pubkey, title, error_code, description);
                                                }
                                        } else {
                                                // Useless packet that we can't use but it passed HMAC, so it
@@ -627,7 +644,7 @@ mod tests {
        use hex;
 
        use bitcoin::secp256k1::Secp256k1;
-       use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+       use bitcoin::secp256k1::{PublicKey,SecretKey};
 
        use super::OnionKeys;
 
@@ -678,31 +695,31 @@ mod tests {
                // Legacy packet creation test vectors from BOLT 4
                let onion_keys = build_test_onion_keys();
 
-               assert_eq!(onion_keys[0].shared_secret[..], hex::decode("53eb63ea8a3fec3b3cd433b85cd62a4b145e1dda09391b348c4e1cd36a03ea66").unwrap()[..]);
+               assert_eq!(onion_keys[0].shared_secret.secret_bytes(), hex::decode("53eb63ea8a3fec3b3cd433b85cd62a4b145e1dda09391b348c4e1cd36a03ea66").unwrap()[..]);
                assert_eq!(onion_keys[0].blinding_factor[..], hex::decode("2ec2e5da605776054187180343287683aa6a51b4b1c04d6dd49c45d8cffb3c36").unwrap()[..]);
                assert_eq!(onion_keys[0].ephemeral_pubkey.serialize()[..], hex::decode("02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619").unwrap()[..]);
                assert_eq!(onion_keys[0].rho, hex::decode("ce496ec94def95aadd4bec15cdb41a740c9f2b62347c4917325fcc6fb0453986").unwrap()[..]);
                assert_eq!(onion_keys[0].mu, hex::decode("b57061dc6d0a2b9f261ac410c8b26d64ac5506cbba30267a649c28c179400eba").unwrap()[..]);
 
-               assert_eq!(onion_keys[1].shared_secret[..], hex::decode("a6519e98832a0b179f62123b3567c106db99ee37bef036e783263602f3488fae").unwrap()[..]);
+               assert_eq!(onion_keys[1].shared_secret.secret_bytes(), hex::decode("a6519e98832a0b179f62123b3567c106db99ee37bef036e783263602f3488fae").unwrap()[..]);
                assert_eq!(onion_keys[1].blinding_factor[..], hex::decode("bf66c28bc22e598cfd574a1931a2bafbca09163df2261e6d0056b2610dab938f").unwrap()[..]);
                assert_eq!(onion_keys[1].ephemeral_pubkey.serialize()[..], hex::decode("028f9438bfbf7feac2e108d677e3a82da596be706cc1cf342b75c7b7e22bf4e6e2").unwrap()[..]);
                assert_eq!(onion_keys[1].rho, hex::decode("450ffcabc6449094918ebe13d4f03e433d20a3d28a768203337bc40b6e4b2c59").unwrap()[..]);
                assert_eq!(onion_keys[1].mu, hex::decode("05ed2b4a3fb023c2ff5dd6ed4b9b6ea7383f5cfe9d59c11d121ec2c81ca2eea9").unwrap()[..]);
 
-               assert_eq!(onion_keys[2].shared_secret[..], hex::decode("3a6b412548762f0dbccce5c7ae7bb8147d1caf9b5471c34120b30bc9c04891cc").unwrap()[..]);
+               assert_eq!(onion_keys[2].shared_secret.secret_bytes(), hex::decode("3a6b412548762f0dbccce5c7ae7bb8147d1caf9b5471c34120b30bc9c04891cc").unwrap()[..]);
                assert_eq!(onion_keys[2].blinding_factor[..], hex::decode("a1f2dadd184eb1627049673f18c6325814384facdee5bfd935d9cb031a1698a5").unwrap()[..]);
                assert_eq!(onion_keys[2].ephemeral_pubkey.serialize()[..], hex::decode("03bfd8225241ea71cd0843db7709f4c222f62ff2d4516fd38b39914ab6b83e0da0").unwrap()[..]);
                assert_eq!(onion_keys[2].rho, hex::decode("11bf5c4f960239cb37833936aa3d02cea82c0f39fd35f566109c41f9eac8deea").unwrap()[..]);
                assert_eq!(onion_keys[2].mu, hex::decode("caafe2820fa00eb2eeb78695ae452eba38f5a53ed6d53518c5c6edf76f3f5b78").unwrap()[..]);
 
-               assert_eq!(onion_keys[3].shared_secret[..], hex::decode("21e13c2d7cfe7e18836df50872466117a295783ab8aab0e7ecc8c725503ad02d").unwrap()[..]);
+               assert_eq!(onion_keys[3].shared_secret.secret_bytes(), hex::decode("21e13c2d7cfe7e18836df50872466117a295783ab8aab0e7ecc8c725503ad02d").unwrap()[..]);
                assert_eq!(onion_keys[3].blinding_factor[..], hex::decode("7cfe0b699f35525029ae0fa437c69d0f20f7ed4e3916133f9cacbb13c82ff262").unwrap()[..]);
                assert_eq!(onion_keys[3].ephemeral_pubkey.serialize()[..], hex::decode("031dde6926381289671300239ea8e57ffaf9bebd05b9a5b95beaf07af05cd43595").unwrap()[..]);
                assert_eq!(onion_keys[3].rho, hex::decode("cbe784ab745c13ff5cffc2fbe3e84424aa0fd669b8ead4ee562901a4a4e89e9e").unwrap()[..]);
                assert_eq!(onion_keys[3].mu, hex::decode("5052aa1b3d9f0655a0932e50d42f0c9ba0705142c25d225515c45f47c0036ee9").unwrap()[..]);
 
-               assert_eq!(onion_keys[4].shared_secret[..], hex::decode("b5756b9b542727dbafc6765a49488b023a725d631af688fc031217e90770c328").unwrap()[..]);
+               assert_eq!(onion_keys[4].shared_secret.secret_bytes(), hex::decode("b5756b9b542727dbafc6765a49488b023a725d631af688fc031217e90770c328").unwrap()[..]);
                assert_eq!(onion_keys[4].blinding_factor[..], hex::decode("c96e00dddaf57e7edcd4fb5954be5b65b09f17cb6d20651b4e90315be5779205").unwrap()[..]);
                assert_eq!(onion_keys[4].ephemeral_pubkey.serialize()[..], hex::decode("03a214ebd875aab6ddfd77f22c5e7311d7f77f17a169e599f157bbcdae8bf071f4").unwrap()[..]);
                assert_eq!(onion_keys[4].rho, hex::decode("034e18b8cc718e8af6339106e706c52d8df89e2b1f7e9142d996acf88df8799b").unwrap()[..]);
@@ -758,22 +775,22 @@ mod tests {
                // Returning Errors test vectors from BOLT 4
 
                let onion_keys = build_test_onion_keys();
-               let onion_error = super::build_failure_packet(&onion_keys[4].shared_secret[..], 0x2002, &[0; 0]);
+               let onion_error = super::build_failure_packet(onion_keys[4].shared_secret.as_ref(), 0x2002, &[0; 0]);
                assert_eq!(onion_error.encode(), hex::decode("4c2fc8bc08510334b6833ad9c3e79cd1b52ae59dfe5c2a4b23ead50f09f7ee0b0002200200fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap());
 
-               let onion_packet_1 = super::encrypt_failure_packet(&onion_keys[4].shared_secret[..], &onion_error.encode()[..]);
+               let onion_packet_1 = super::encrypt_failure_packet(onion_keys[4].shared_secret.as_ref(), &onion_error.encode()[..]);
                assert_eq!(onion_packet_1.data, hex::decode("a5e6bd0c74cb347f10cce367f949098f2457d14c046fd8a22cb96efb30b0fdcda8cb9168b50f2fd45edd73c1b0c8b33002df376801ff58aaa94000bf8a86f92620f343baef38a580102395ae3abf9128d1047a0736ff9b83d456740ebbb4aeb3aa9737f18fb4afb4aa074fb26c4d702f42968888550a3bded8c05247e045b866baef0499f079fdaeef6538f31d44deafffdfd3afa2fb4ca9082b8f1c465371a9894dd8c243fb4847e004f5256b3e90e2edde4c9fb3082ddfe4d1e734cacd96ef0706bf63c9984e22dc98851bcccd1c3494351feb458c9c6af41c0044bea3c47552b1d992ae542b17a2d0bba1a096c78d169034ecb55b6e3a7263c26017f033031228833c1daefc0dedb8cf7c3e37c9c37ebfe42f3225c326e8bcfd338804c145b16e34e4").unwrap());
 
-               let onion_packet_2 = super::encrypt_failure_packet(&onion_keys[3].shared_secret[..], &onion_packet_1.data[..]);
+               let onion_packet_2 = super::encrypt_failure_packet(onion_keys[3].shared_secret.as_ref(), &onion_packet_1.data[..]);
                assert_eq!(onion_packet_2.data, hex::decode("c49a1ce81680f78f5f2000cda36268de34a3f0a0662f55b4e837c83a8773c22aa081bab1616a0011585323930fa5b9fae0c85770a2279ff59ec427ad1bbff9001c0cd1497004bd2a0f68b50704cf6d6a4bf3c8b6a0833399a24b3456961ba00736785112594f65b6b2d44d9f5ea4e49b5e1ec2af978cbe31c67114440ac51a62081df0ed46d4a3df295da0b0fe25c0115019f03f15ec86fabb4c852f83449e812f141a9395b3f70b766ebbd4ec2fae2b6955bd8f32684c15abfe8fd3a6261e52650e8807a92158d9f1463261a925e4bfba44bd20b166d532f0017185c3a6ac7957adefe45559e3072c8dc35abeba835a8cb01a71a15c736911126f27d46a36168ca5ef7dccd4e2886212602b181463e0dd30185c96348f9743a02aca8ec27c0b90dca270").unwrap());
 
-               let onion_packet_3 = super::encrypt_failure_packet(&onion_keys[2].shared_secret[..], &onion_packet_2.data[..]);
+               let onion_packet_3 = super::encrypt_failure_packet(onion_keys[2].shared_secret.as_ref(), &onion_packet_2.data[..]);
                assert_eq!(onion_packet_3.data, hex::decode("a5d3e8634cfe78b2307d87c6d90be6fe7855b4f2cc9b1dfb19e92e4b79103f61ff9ac25f412ddfb7466e74f81b3e545563cdd8f5524dae873de61d7bdfccd496af2584930d2b566b4f8d3881f8c043df92224f38cf094cfc09d92655989531524593ec6d6caec1863bdfaa79229b5020acc034cd6deeea1021c50586947b9b8e6faa83b81fbfa6133c0af5d6b07c017f7158fa94f0d206baf12dda6b68f785b773b360fd0497e16cc402d779c8d48d0fa6315536ef0660f3f4e1865f5b38ea49c7da4fd959de4e83ff3ab686f059a45c65ba2af4a6a79166aa0f496bf04d06987b6d2ea205bdb0d347718b9aeff5b61dfff344993a275b79717cd815b6ad4c0beb568c4ac9c36ff1c315ec1119a1993c4b61e6eaa0375e0aaf738ac691abd3263bf937e3").unwrap());
 
-               let onion_packet_4 = super::encrypt_failure_packet(&onion_keys[1].shared_secret[..], &onion_packet_3.data[..]);
+               let onion_packet_4 = super::encrypt_failure_packet(onion_keys[1].shared_secret.as_ref(), &onion_packet_3.data[..]);
                assert_eq!(onion_packet_4.data, hex::decode("aac3200c4968f56b21f53e5e374e3a2383ad2b1b6501bbcc45abc31e59b26881b7dfadbb56ec8dae8857add94e6702fb4c3a4de22e2e669e1ed926b04447fc73034bb730f4932acd62727b75348a648a1128744657ca6a4e713b9b646c3ca66cac02cdab44dd3439890ef3aaf61708714f7375349b8da541b2548d452d84de7084bb95b3ac2345201d624d31f4d52078aa0fa05a88b4e20202bd2b86ac5b52919ea305a8949de95e935eed0319cf3cf19ebea61d76ba92532497fcdc9411d06bcd4275094d0a4a3c5d3a945e43305a5a9256e333e1f64dbca5fcd4e03a39b9012d197506e06f29339dfee3331995b21615337ae060233d39befea925cc262873e0530408e6990f1cbd233a150ef7b004ff6166c70c68d9f8c853c1abca640b8660db2921").unwrap());
 
-               let onion_packet_5 = super::encrypt_failure_packet(&onion_keys[0].shared_secret[..], &onion_packet_4.data[..]);
+               let onion_packet_5 = super::encrypt_failure_packet(onion_keys[0].shared_secret.as_ref(), &onion_packet_4.data[..]);
                assert_eq!(onion_packet_5.data, hex::decode("9c5add3963fc7f6ed7f148623c84134b5647e1306419dbe2174e523fa9e2fbed3a06a19f899145610741c83ad40b7712aefaddec8c6baf7325d92ea4ca4d1df8bce517f7e54554608bf2bd8071a4f52a7a2f7ffbb1413edad81eeea5785aa9d990f2865dc23b4bc3c301a94eec4eabebca66be5cf638f693ec256aec514620cc28ee4a94bd9565bc4d4962b9d3641d4278fb319ed2b84de5b665f307a2db0f7fbb757366067d88c50f7e829138fde4f78d39b5b5802f1b92a8a820865af5cc79f9f30bc3f461c66af95d13e5e1f0381c184572a91dee1c849048a647a1158cf884064deddbf1b0b88dfe2f791428d0ba0f6fb2f04e14081f69165ae66d9297c118f0907705c9c4954a199bae0bb96fad763d690e7daa6cfda59ba7f2c8d11448b604d12d").unwrap());
        }
 
index fbd32526ea658470f810c487bcb88da608904e8b..da6dc67aba5c4f52ec9e9dcd819aebf131d33084 100644 (file)
@@ -16,7 +16,7 @@ use bitcoin::hashes::{Hash, HashEngine};
 use bitcoin::hashes::sha256::Hash as Sha256;
 
 use bitcoin::secp256k1::Secp256k1;
-use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+use bitcoin::secp256k1::{PublicKey,SecretKey};
 use bitcoin::secp256k1::ecdh::SharedSecret;
 use bitcoin::secp256k1;
 
@@ -163,7 +163,7 @@ impl PeerChannelEncryptor {
 
        #[inline]
        fn hkdf(state: &mut BidirectionalNoiseState, ss: SharedSecret) -> [u8; 32] {
-               let (t1, t2) = hkdf_extract_expand_twice(&state.ck, &ss[..]);
+               let (t1, t2) = hkdf_extract_expand_twice(&state.ck, ss.as_ref());
                state.ck = t1;
                t2
        }
@@ -473,7 +473,7 @@ impl PeerChannelEncryptor {
 mod tests {
        use super::LN_MAX_MSG_LEN;
 
-       use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+       use bitcoin::secp256k1::{PublicKey,SecretKey};
 
        use hex;
 
index be3b3aeda36085a4d2d53f01294f1214cb2c4ff0..633876ee375124ae2f9008fe8c5f0194bb60deb3 100644 (file)
@@ -15,7 +15,7 @@
 //! call into the provided message handlers (probably a ChannelManager and NetGraphmsgHandler) with messages
 //! they should handle, and encoding/sending response messages.
 
-use bitcoin::secp256k1::key::{SecretKey,PublicKey};
+use bitcoin::secp256k1::{SecretKey,PublicKey};
 
 use ln::features::InitFeatures;
 use ln::msgs;
@@ -1839,7 +1839,7 @@ mod tests {
        use util::test_utils;
 
        use bitcoin::secp256k1::Secp256k1;
-       use bitcoin::secp256k1::key::{SecretKey, PublicKey};
+       use bitcoin::secp256k1::{SecretKey, PublicKey};
 
        use prelude::*;
        use sync::{Arc, Mutex};
index fa44a0655c1462cdf321fede0aeb0de83141626b..d7b940eb90e09dfce8e6557656327440fb987159 100644 (file)
@@ -19,7 +19,8 @@ use routing::network_graph::RoutingFees;
 use routing::router::{PaymentParameters, RouteHint, RouteHintHop};
 use ln::features::{InitFeatures, InvoiceFeatures};
 use ln::msgs;
-use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, OptionalField};
+use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, OptionalField, ChannelUpdate};
+use ln::wire::Encode;
 use util::enforcing_trait_impls::EnforcingSigner;
 use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
 use util::config::UserConfig;
@@ -528,12 +529,17 @@ fn test_scid_alias_returned() {
                excess_data: Vec::new(),
        };
        let msg_hash = Sha256dHash::hash(&contents.encode()[..]);
-       let signature = Secp256k1::new().sign(&hash_to_message!(&msg_hash[..]), &nodes[1].keys_manager.get_node_secret(Recipient::Node).unwrap());
+       let signature = Secp256k1::new().sign_ecdsa(&hash_to_message!(&msg_hash[..]), &nodes[1].keys_manager.get_node_secret(Recipient::Node).unwrap());
        let msg = msgs::ChannelUpdate { signature, contents };
 
+       let mut err_data = Vec::new();
+       err_data.extend_from_slice(&(msg.serialized_length() as u16 + 2).to_be_bytes());
+       err_data.extend_from_slice(&ChannelUpdate::TYPE.to_be_bytes());
+       err_data.extend_from_slice(&msg.encode());
+
        expect_payment_failed_conditions!(nodes[0], payment_hash, false,
                PaymentFailedConditions::new().blamed_scid(last_hop[0].inbound_scid_alias.unwrap())
-                       .blamed_chan_closed(false).expected_htlc_error_data(0x1000|7, &msg.encode_with_len()));
+                       .blamed_chan_closed(false).expected_htlc_error_data(0x1000|7, &err_data));
 
        route.paths[0][1].fee_msat = 10_000; // Reset to the correct payment amount
        route.paths[0][0].fee_msat = 0; // But set fee paid to the middle hop to 0
@@ -551,7 +557,9 @@ fn test_scid_alias_returned() {
 
        let mut err_data = Vec::new();
        err_data.extend_from_slice(&10_000u64.to_be_bytes());
-       err_data.extend_from_slice(&msg.encode_with_len());
+       err_data.extend_from_slice(&(msg.serialized_length() as u16 + 2).to_be_bytes());
+       err_data.extend_from_slice(&ChannelUpdate::TYPE.to_be_bytes());
+       err_data.extend_from_slice(&msg.encode());
        expect_payment_failed_conditions!(nodes[0], payment_hash, false,
                PaymentFailedConditions::new().blamed_scid(last_hop[0].inbound_scid_alias.unwrap())
                        .blamed_chan_closed(false).expected_htlc_error_data(0x1000|12, &err_data));
index 7b36ae0fc4a9d2af97badcbb0c503a1262fdf64d..96fda526d68d2d46369b9c9ec831d96551e86112 100644 (file)
@@ -209,14 +209,14 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
                        let relevant_txids = nodes[0].node.get_relevant_txids();
                        assert_eq!(&relevant_txids[..], &[chan.3.txid()]);
                        nodes[0].node.transaction_unconfirmed(&relevant_txids[0]);
+               } else if connect_style == ConnectStyle::FullBlockViaListen {
+                       disconnect_blocks(&nodes[0], CHAN_CONFIRM_DEPTH - 1);
+                       assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
+                       disconnect_blocks(&nodes[0], 1);
                } else {
                        disconnect_all_blocks(&nodes[0]);
                }
-               if connect_style == ConnectStyle::FullBlockViaListen && !use_funding_unconfirmed {
-                       handle_announce_close_broadcast_events(&nodes, 0, 1, true, "Channel closed because of an exception: Funding transaction was un-confirmed. Locked at 6 confs, now have 2 confs.");
-               } else {
-                       handle_announce_close_broadcast_events(&nodes, 0, 1, true, "Channel closed because of an exception: Funding transaction was un-confirmed. Locked at 6 confs, now have 0 confs.");
-               }
+               handle_announce_close_broadcast_events(&nodes, 0, 1, true, "Channel closed because of an exception: Funding transaction was un-confirmed. Locked at 6 confs, now have 0 confs.");
                check_added_monitors!(nodes[1], 1);
                {
                        let channel_state = nodes[0].node.channel_state.lock().unwrap();
@@ -277,14 +277,14 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
                        let relevant_txids = nodes[0].node.get_relevant_txids();
                        assert_eq!(&relevant_txids[..], &[chan.3.txid()]);
                        nodes[0].node.transaction_unconfirmed(&relevant_txids[0]);
+               } else if connect_style == ConnectStyle::FullBlockViaListen {
+                       disconnect_blocks(&nodes[0], CHAN_CONFIRM_DEPTH - 1);
+                       assert_eq!(nodes[0].node.list_channels().len(), 1);
+                       disconnect_blocks(&nodes[0], 1);
                } else {
                        disconnect_all_blocks(&nodes[0]);
                }
-               if connect_style == ConnectStyle::FullBlockViaListen && !use_funding_unconfirmed {
-                       handle_announce_close_broadcast_events(&nodes, 0, 1, true, "Channel closed because of an exception: Funding transaction was un-confirmed. Locked at 6 confs, now have 2 confs.");
-               } else {
-                       handle_announce_close_broadcast_events(&nodes, 0, 1, true, "Channel closed because of an exception: Funding transaction was un-confirmed. Locked at 6 confs, now have 0 confs.");
-               }
+               handle_announce_close_broadcast_events(&nodes, 0, 1, true, "Channel closed because of an exception: Funding transaction was un-confirmed. Locked at 6 confs, now have 0 confs.");
                check_added_monitors!(nodes[1], 1);
                {
                        let channel_state = nodes[0].node.channel_state.lock().unwrap();
@@ -297,11 +297,7 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
        *nodes[0].chain_monitor.expect_channel_force_closed.lock().unwrap() = Some((chan.2, true));
        nodes[0].node.test_process_background_events(); // Required to free the pending background monitor update
        check_added_monitors!(nodes[0], 1);
-       let expected_err = if connect_style == ConnectStyle::FullBlockViaListen && !use_funding_unconfirmed {
-               "Funding transaction was un-confirmed. Locked at 6 confs, now have 2 confs."
-       } else {
-               "Funding transaction was un-confirmed. Locked at 6 confs, now have 0 confs."
-       };
+       let expected_err = "Funding transaction was un-confirmed. Locked at 6 confs, now have 0 confs.";
        check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: "Channel closed because of an exception: ".to_owned() + expected_err });
        check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: expected_err.to_owned() });
        assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
index a9f44bae1aec79199230d467f426b50934c225dd..7abe3060fa7b666f22fc83048ca330a194e3fdfb 100644 (file)
@@ -4,14 +4,14 @@ use bitcoin::blockdata::opcodes::all::OP_PUSHBYTES_0 as SEGWIT_V0;
 use bitcoin::blockdata::script::{Builder, Script};
 use bitcoin::hashes::Hash;
 use bitcoin::hash_types::{WPubkeyHash, WScriptHash};
-use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::PublicKey;
+use bitcoin::util::address::WitnessVersion;
 
 use ln::features::InitFeatures;
 use ln::msgs::DecodeError;
 use util::ser::{Readable, Writeable, Writer};
 
 use core::convert::TryFrom;
-use core::num::NonZeroU8;
 use io;
 
 /// A script pubkey for shutting down a channel as defined by [BOLT #2].
@@ -68,12 +68,12 @@ impl ShutdownScript {
 
        /// 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)))
+               Self(ShutdownScriptImpl::Bolt2(Script::new_v0_p2wpkh(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)))
+               Self(ShutdownScriptImpl::Bolt2(Script::new_v0_p2wsh(script_hash)))
        }
 
        /// Generates a witness script pubkey from the given segwit version and program.
@@ -84,9 +84,9 @@ impl ShutdownScript {
        /// # Errors
        ///
        /// This function may return an error if `program` is invalid for the segwit `version`.
-       pub fn new_witness_program(version: NonZeroU8, program: &[u8]) -> Result<Self, InvalidShutdownScript> {
+       pub fn new_witness_program(version: WitnessVersion, program: &[u8]) -> Result<Self, InvalidShutdownScript> {
                let script = Builder::new()
-                       .push_int(version.get().into())
+                       .push_int(version as i64)
                        .push_slice(&program)
                        .into_script();
                Self::try_from(script)
@@ -156,7 +156,7 @@ impl Into<Script> for ShutdownScript {
        fn into(self) -> Script {
                match self.0 {
                        ShutdownScriptImpl::Legacy(pubkey) =>
-                               Script::new_v0_wpkh(&WPubkeyHash::hash(&pubkey.serialize())),
+                               Script::new_v0_p2wpkh(&WPubkeyHash::hash(&pubkey.serialize())),
                        ShutdownScriptImpl::Bolt2(script_pubkey) => script_pubkey,
                }
        }
@@ -174,19 +174,18 @@ impl core::fmt::Display for ShutdownScript{
 #[cfg(test)]
 mod shutdown_script_tests {
        use super::ShutdownScript;
-       use bitcoin::bech32::u5;
        use bitcoin::blockdata::opcodes;
        use bitcoin::blockdata::script::{Builder, Script};
        use bitcoin::secp256k1::Secp256k1;
-       use bitcoin::secp256k1::key::{PublicKey, SecretKey};
+       use bitcoin::secp256k1::{PublicKey, SecretKey};
        use ln::features::InitFeatures;
        use core::convert::TryFrom;
-       use core::num::NonZeroU8;
+       use bitcoin::util::address::WitnessVersion;
 
-       fn pubkey() -> bitcoin::util::ecdsa::PublicKey {
+       fn pubkey() -> bitcoin::util::key::PublicKey {
                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, 0, 1]).unwrap();
-               bitcoin::util::ecdsa::PublicKey::new(PublicKey::from_secret_key(&secp_ctx, &secret_key))
+               bitcoin::util::key::PublicKey::new(PublicKey::from_secret_key(&secp_ctx, &secret_key))
        }
 
        fn redeem_script() -> Script {
@@ -204,9 +203,9 @@ mod shutdown_script_tests {
        fn generates_p2wpkh_from_pubkey() {
                let pubkey = pubkey();
                let pubkey_hash = pubkey.wpubkey_hash().unwrap();
-               let p2wpkh_script = Script::new_v0_wpkh(&pubkey_hash);
+               let p2wpkh_script = Script::new_v0_p2wpkh(&pubkey_hash);
 
-               let shutdown_script = ShutdownScript::new_p2wpkh_from_pubkey(pubkey.key);
+               let shutdown_script = ShutdownScript::new_p2wpkh_from_pubkey(pubkey.inner);
                assert!(shutdown_script.is_compatible(&InitFeatures::known()));
                assert!(shutdown_script.is_compatible(&InitFeatures::known().clear_shutdown_anysegwit()));
                assert_eq!(shutdown_script.into_inner(), p2wpkh_script);
@@ -215,7 +214,7 @@ mod shutdown_script_tests {
        #[test]
        fn generates_p2wpkh_from_pubkey_hash() {
                let pubkey_hash = pubkey().wpubkey_hash().unwrap();
-               let p2wpkh_script = Script::new_v0_wpkh(&pubkey_hash);
+               let p2wpkh_script = Script::new_v0_p2wpkh(&pubkey_hash);
 
                let shutdown_script = ShutdownScript::new_p2wpkh(&pubkey_hash);
                assert!(shutdown_script.is_compatible(&InitFeatures::known()));
@@ -227,7 +226,7 @@ mod shutdown_script_tests {
        #[test]
        fn generates_p2wsh_from_script_hash() {
                let script_hash = redeem_script().wscript_hash();
-               let p2wsh_script = Script::new_v0_wsh(&script_hash);
+               let p2wsh_script = Script::new_v0_p2wsh(&script_hash);
 
                let shutdown_script = ShutdownScript::new_p2wsh(&script_hash);
                assert!(shutdown_script.is_compatible(&InitFeatures::known()));
@@ -238,11 +237,8 @@ mod shutdown_script_tests {
 
        #[test]
        fn generates_segwit_from_non_v0_witness_program() {
-               let version = u5::try_from_u8(16).unwrap();
-               let witness_program = Script::new_witness_program(version, &[0; 40]);
-
-               let version = NonZeroU8::new(version.to_u8()).unwrap();
-               let shutdown_script = ShutdownScript::new_witness_program(version, &[0; 40]).unwrap();
+               let witness_program = Script::new_witness_program(WitnessVersion::V16, &[0; 40]);
+               let shutdown_script = ShutdownScript::new_witness_program(WitnessVersion::V16, &[0; 40]).unwrap();
                assert!(shutdown_script.is_compatible(&InitFeatures::known()));
                assert!(!shutdown_script.is_compatible(&InitFeatures::known().clear_shutdown_anysegwit()));
                assert_eq!(shutdown_script.into_inner(), witness_program);
@@ -254,25 +250,17 @@ mod shutdown_script_tests {
                assert!(ShutdownScript::try_from(op_return).is_err());
        }
 
-       #[test]
-       fn fails_from_invalid_segwit_version() {
-               let version = NonZeroU8::new(17).unwrap();
-               assert!(ShutdownScript::new_witness_program(version, &[0; 40]).is_err());
-       }
-
        #[test]
        fn fails_from_invalid_segwit_v0_witness_program() {
-               let witness_program = Script::new_witness_program(u5::try_from_u8(0).unwrap(), &[0; 2]);
+               let witness_program = Script::new_witness_program(WitnessVersion::V0, &[0; 2]);
                assert!(ShutdownScript::try_from(witness_program).is_err());
        }
 
        #[test]
        fn fails_from_invalid_segwit_non_v0_witness_program() {
-               let version = u5::try_from_u8(16).unwrap();
-               let witness_program = Script::new_witness_program(version, &[0; 42]);
+               let witness_program = Script::new_witness_program(WitnessVersion::V16, &[0; 42]);
                assert!(ShutdownScript::try_from(witness_program).is_err());
 
-               let version = NonZeroU8::new(version.to_u8()).unwrap();
-               assert!(ShutdownScript::new_witness_program(version, &[0; 42]).is_err());
+               assert!(ShutdownScript::new_witness_program(WitnessVersion::V16, &[0; 42]).is_err());
        }
 }
index 42c0e3b2f328cc1545edfdf3287dddab9e766ffe..59004547b1489afe21f0a88ae5b71788b1f90fe1 100644 (file)
@@ -26,11 +26,11 @@ use util::config::UserConfig;
 use bitcoin::blockdata::script::Builder;
 use bitcoin::blockdata::opcodes;
 use bitcoin::network::constants::Network;
+use bitcoin::util::address::WitnessVersion;
 
 use regex;
 
 use core::default::Default;
-use core::num::NonZeroU8;
 
 use ln::functional_test_utils::*;
 use ln::msgs::OptionalField::Present;
@@ -654,7 +654,7 @@ fn test_unsupported_anysegwit_shutdown_script() {
        // 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 unsupported_shutdown_script =
-               ShutdownScript::new_witness_program(NonZeroU8::new(16).unwrap(), &[0, 40]).unwrap();
+               ShutdownScript::new_witness_program(WitnessVersion::V16, &[0, 40]).unwrap();
        chanmon_cfgs[1].keys_manager
                .expect(OnGetShutdownScriptpubkey { returns: unsupported_shutdown_script.clone() })
                .expect(OnGetShutdownScriptpubkey { returns: supported_shutdown_script });
index 39c2894b32c429b5115f4eee66c427bed21989b1..2e0679eba79f6cbbb1473ebdf89a0e113cf8fd5e 100644 (file)
@@ -10,7 +10,7 @@
 //! The top-level network map tracking logic lives here.
 
 use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE;
-use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::PublicKey;
 use bitcoin::secp256k1::Secp256k1;
 use bitcoin::secp256k1;
 
@@ -295,7 +295,7 @@ where C::Target: chain::Access, L::Target: Logger
 
 macro_rules! secp_verify_sig {
        ( $secp_ctx: expr, $msg: expr, $sig: expr, $pubkey: expr, $msg_type: expr ) => {
-               match $secp_ctx.verify($msg, $sig, $pubkey) {
+               match $secp_ctx.verify_ecdsa($msg, $sig, $pubkey) {
                        Ok(_) => {},
                        Err(_) => {
                                return Err(LightningError {
@@ -1356,10 +1356,10 @@ impl NetworkGraph {
        /// If built with `no-std`, any updates with a timestamp more than two weeks in the past or
        /// materially in the future will be rejected.
        pub fn update_channel_unsigned(&self, msg: &msgs::UnsignedChannelUpdate) -> Result<(), LightningError> {
-               self.update_channel_intern(msg, None, None::<(&secp256k1::Signature, &Secp256k1<secp256k1::VerifyOnly>)>)
+               self.update_channel_intern(msg, None, None::<(&secp256k1::ecdsa::Signature, &Secp256k1<secp256k1::VerifyOnly>)>)
        }
 
-       fn update_channel_intern<T: secp256k1::Verification>(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig_info: Option<(&secp256k1::Signature, &Secp256k1<T>)>) -> Result<(), LightningError> {
+       fn update_channel_intern<T: secp256k1::Verification>(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig_info: Option<(&secp256k1::ecdsa::Signature, &Secp256k1<T>)>) -> Result<(), LightningError> {
                let dest_node_id;
                let chan_enabled = msg.flags & (1 << 1) != (1 << 1);
                let chan_was_enabled;
@@ -1578,10 +1578,11 @@ mod tests {
 
        use hex;
 
-       use bitcoin::secp256k1::key::{PublicKey, SecretKey};
+       use bitcoin::secp256k1::{PublicKey, SecretKey};
        use bitcoin::secp256k1::{All, Secp256k1};
 
        use io;
+       use bitcoin::secp256k1;
        use prelude::*;
        use sync::Arc;
 
@@ -1628,7 +1629,7 @@ mod tests {
                f(&mut unsigned_announcement);
                let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]);
                NodeAnnouncement {
-                       signature: secp_ctx.sign(&msghash, node_key),
+                       signature: secp_ctx.sign_ecdsa(&msghash, node_key),
                        contents: unsigned_announcement
                }
        }
@@ -1652,10 +1653,10 @@ mod tests {
                f(&mut unsigned_announcement);
                let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]);
                ChannelAnnouncement {
-                       node_signature_1: secp_ctx.sign(&msghash, node_1_key),
-                       node_signature_2: secp_ctx.sign(&msghash, node_2_key),
-                       bitcoin_signature_1: secp_ctx.sign(&msghash, node_1_btckey),
-                       bitcoin_signature_2: secp_ctx.sign(&msghash, node_2_btckey),
+                       node_signature_1: secp_ctx.sign_ecdsa(&msghash, node_1_key),
+                       node_signature_2: secp_ctx.sign_ecdsa(&msghash, node_2_key),
+                       bitcoin_signature_1: secp_ctx.sign_ecdsa(&msghash, node_1_btckey),
+                       bitcoin_signature_2: secp_ctx.sign_ecdsa(&msghash, node_2_btckey),
                        contents: unsigned_announcement,
                }
        }
@@ -1687,7 +1688,7 @@ mod tests {
                f(&mut unsigned_channel_update);
                let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_channel_update.encode()[..])[..]);
                ChannelUpdate {
-                       signature: secp_ctx.sign(&msghash, node_key),
+                       signature: secp_ctx.sign_ecdsa(&msghash, node_key),
                        contents: unsigned_channel_update
                }
        }
@@ -1724,7 +1725,7 @@ mod tests {
                let fake_msghash = hash_to_message!(&zero_hash);
                match net_graph_msg_handler.handle_node_announcement(
                        &NodeAnnouncement {
-                               signature: secp_ctx.sign(&fake_msghash, node_1_privkey),
+                               signature: secp_ctx.sign_ecdsa(&fake_msghash, node_1_privkey),
                                contents: valid_announcement.contents.clone()
                }) {
                        Ok(_) => panic!(),
@@ -1963,7 +1964,7 @@ mod tests {
                }, node_1_privkey, &secp_ctx);
                let zero_hash = Sha256dHash::hash(&[0; 32]);
                let fake_msghash = hash_to_message!(&zero_hash);
-               invalid_sig_channel_update.signature = secp_ctx.sign(&fake_msghash, node_1_privkey);
+               invalid_sig_channel_update.signature = secp_ctx.sign_ecdsa(&fake_msghash, node_1_privkey);
                match net_graph_msg_handler.handle_channel_update(&invalid_sig_channel_update) {
                        Ok(_) => panic!(),
                        Err(e) => assert_eq!(e.err, "Invalid signature on channel_update message")
index 816dfaad3cb4494fcc769bce8dc09ca77e27166f..dc094b9b6e0309a8fc51cd01a75a1ad480c3d432 100644 (file)
@@ -12,7 +12,7 @@
 //! You probably want to create a NetGraphMsgHandler and use that as your RoutingMessageHandler and then
 //! interrogate it to get routes for your own payments.
 
-use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::PublicKey;
 
 use ln::channelmanager::ChannelDetails;
 use ln::features::{ChannelFeatures, InvoiceFeatures, NodeFeatures};
@@ -1721,7 +1721,7 @@ mod tests {
 
        use hex;
 
-       use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+       use bitcoin::secp256k1::{PublicKey,SecretKey};
        use bitcoin::secp256k1::{Secp256k1, All};
 
        use prelude::*;
@@ -1780,10 +1780,10 @@ mod tests {
 
                let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]);
                let valid_announcement = ChannelAnnouncement {
-                       node_signature_1: secp_ctx.sign(&msghash, node_1_privkey),
-                       node_signature_2: secp_ctx.sign(&msghash, node_2_privkey),
-                       bitcoin_signature_1: secp_ctx.sign(&msghash, node_1_privkey),
-                       bitcoin_signature_2: secp_ctx.sign(&msghash, node_2_privkey),
+                       node_signature_1: secp_ctx.sign_ecdsa(&msghash, node_1_privkey),
+                       node_signature_2: secp_ctx.sign_ecdsa(&msghash, node_2_privkey),
+                       bitcoin_signature_1: secp_ctx.sign_ecdsa(&msghash, node_1_privkey),
+                       bitcoin_signature_2: secp_ctx.sign_ecdsa(&msghash, node_2_privkey),
                        contents: unsigned_announcement.clone(),
                };
                match net_graph_msg_handler.handle_channel_announcement(&valid_announcement) {
@@ -1798,7 +1798,7 @@ mod tests {
        ) {
                let msghash = hash_to_message!(&Sha256dHash::hash(&update.encode()[..])[..]);
                let valid_channel_update = ChannelUpdate {
-                       signature: secp_ctx.sign(&msghash, node_privkey),
+                       signature: secp_ctx.sign_ecdsa(&msghash, node_privkey),
                        contents: update.clone()
                };
 
@@ -1825,7 +1825,7 @@ mod tests {
                };
                let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]);
                let valid_announcement = NodeAnnouncement {
-                       signature: secp_ctx.sign(&msghash, node_privkey),
+                       signature: secp_ctx.sign_ecdsa(&msghash, node_privkey),
                        contents: unsigned_announcement.clone()
                };
 
index 3d10a14c6f2cf7c7d63403ef07f70f8c05ee2e59..4c47aac47b64c2e78df2b39d0e740083023ecadc 100644 (file)
 //! # Example
 //!
 //! ```
-//! # extern crate secp256k1;
+//! # extern crate bitcoin;
 //! #
 //! # use lightning::routing::network_graph::NetworkGraph;
 //! # use lightning::routing::router::{RouteParameters, find_route};
 //! # use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters, Scorer, ScoringParameters};
 //! # use lightning::chain::keysinterface::{KeysManager, KeysInterface};
 //! # use lightning::util::logger::{Logger, Record};
-//! # use secp256k1::key::PublicKey;
+//! # use bitcoin::secp256k1::PublicKey;
 //! #
 //! # struct FakeLogger {};
 //! # impl Logger for FakeLogger {
@@ -137,6 +137,14 @@ pub trait LockableScore<'a> {
        fn lock(&'a self) -> Self::Locked;
 }
 
+/// Refers to a scorer that is accessible under lock and also writeable to disk
+///
+/// We need this trait to be able to pass in a scorer to `lightning-background-processor` that will enable us to
+/// use the Persister to persist it.
+pub trait WriteableScore<'a>: LockableScore<'a> + Writeable {}
+
+impl<'a, T> WriteableScore<'a> for T where T: LockableScore<'a> + Writeable {}
+
 /// (C-not exported)
 impl<'a, T: 'a + Score> LockableScore<'a> for Mutex<T> {
        type Locked = MutexGuard<'a, T>;
@@ -1805,10 +1813,10 @@ mod tests {
                };
                let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]);
                let signed_announcement = ChannelAnnouncement {
-                       node_signature_1: secp_ctx.sign(&msghash, &node_1_key),
-                       node_signature_2: secp_ctx.sign(&msghash, &node_2_key),
-                       bitcoin_signature_1: secp_ctx.sign(&msghash, &node_1_secret),
-                       bitcoin_signature_2: secp_ctx.sign(&msghash, &node_2_secret),
+                       node_signature_1: secp_ctx.sign_ecdsa(&msghash, &node_1_key),
+                       node_signature_2: secp_ctx.sign_ecdsa(&msghash, &node_2_key),
+                       bitcoin_signature_1: secp_ctx.sign_ecdsa(&msghash, &node_1_secret),
+                       bitcoin_signature_2: secp_ctx.sign_ecdsa(&msghash, &node_2_secret),
                        contents: unsigned_announcement,
                };
                let chain_source: Option<&::util::test_utils::TestChainSource> = None;
@@ -1837,7 +1845,7 @@ mod tests {
                };
                let msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_update.encode()[..])[..]);
                let signed_update = ChannelUpdate {
-                       signature: secp_ctx.sign(&msghash, &node_key),
+                       signature: secp_ctx.sign_ecdsa(&msghash, &node_key),
                        contents: unsigned_update,
                };
                network_graph.update_channel(&signed_update, &secp_ctx).unwrap();
index 300ddacb020566dac6fc77ac537077918b76e925..2f2d33b29f7ea53c0a2dda084ac7a139583c6345 100644 (file)
@@ -1,7 +1,7 @@
 use bitcoin::hashes::{Hash, HashEngine};
 use bitcoin::hashes::hmac::{Hmac, HmacEngine};
 use bitcoin::hashes::sha256::Hash as Sha256;
-use bitcoin::secp256k1::{Message, Secp256k1, SecretKey, Signature, Signing};
+use bitcoin::secp256k1::{Message, Secp256k1, SecretKey, ecdsa::Signature, Signing};
 
 macro_rules! hkdf_extract_expand {
        ($salt: expr, $ikm: expr) => {{
@@ -41,8 +41,8 @@ pub fn hkdf_extract_expand_thrice(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32
 #[inline]
 pub fn sign<C: Signing>(ctx: &Secp256k1<C>, msg: &Message, sk: &SecretKey) -> Signature {
        #[cfg(feature = "grind_signatures")]
-       let sig = ctx.sign_low_r(msg, sk);
+       let sig = ctx.sign_ecdsa_low_r(msg, sk);
        #[cfg(not(feature = "grind_signatures"))]
-       let sig = ctx.sign(msg, sk);
+       let sig = ctx.sign_ecdsa(msg, sk);
        sig
 }
index 2e22df7c5af10c1c4e68dc9ec6baf40990ab7840..b4b66e8f5feb97d52ff52be9e046b55aa71bd532 100644 (file)
@@ -16,12 +16,12 @@ use core::cmp;
 use sync::{Mutex, Arc};
 #[cfg(test)] use sync::MutexGuard;
 
-use bitcoin::blockdata::transaction::{Transaction, SigHashType};
-use bitcoin::util::bip143;
+use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType};
+use bitcoin::util::sighash;
 
 use bitcoin::secp256k1;
-use bitcoin::secp256k1::key::{SecretKey, PublicKey};
-use bitcoin::secp256k1::{Secp256k1, Signature};
+use bitcoin::secp256k1::{SecretKey, PublicKey};
+use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
 use util::ser::{Writeable, Writer};
 use io::Error;
 
@@ -160,8 +160,8 @@ impl BaseSign for EnforcingSigner {
 
                        let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&this_htlc, self.opt_anchors(), &keys);
 
-                       let sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, this_htlc.amount_msat / 1000, SigHashType::All)[..]);
-                       secp_ctx.verify(&sighash, sig, &keys.countersignatory_htlc_key).unwrap();
+                       let sighash = hash_to_message!(&sighash::SighashCache::new(&htlc_tx).segwit_signature_hash(0, &htlc_redeemscript, this_htlc.amount_msat / 1000, EcdsaSighashType::All).unwrap()[..]);
+                       secp_ctx.verify_ecdsa(&sighash, sig, &keys.countersignatory_htlc_key).unwrap();
                }
 
                Ok(self.inner.sign_holder_commitment_and_htlcs(commitment_tx, secp_ctx).unwrap())
index f35dc14e03555bed83d94e48c9702e6d50a36bc9..b67c2ec77b3e3ed0bac42335e3bd9fb07209392e 100644 (file)
@@ -29,7 +29,7 @@ use bitcoin::Transaction;
 use bitcoin::blockdata::script::Script;
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
-use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::PublicKey;
 use io;
 use prelude::*;
 use core::time::Duration;
index 2dd73d8279cff447576817450601c85112adce74..eadfdbdfc67aaeea13477dc7b5315df4f4ab42cd 100644 (file)
@@ -12,7 +12,7 @@ use chain::keysinterface::SpendableOutputDescriptor;
 
 use bitcoin::hash_types::Txid;
 use bitcoin::blockdata::transaction::Transaction;
-use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::secp256k1::PublicKey;
 
 use routing::router::Route;
 use ln::chan_utils::HTLCType;
index 8beff835a4bffe1f0b3d59e672380323b6164f98..593b01dff90d9b5a36bad535a2269a5e73a7c496 100644 (file)
@@ -23,7 +23,7 @@
 use prelude::*;
 use crate::util::zbase32;
 use bitcoin::hashes::{sha256d, Hash};
-use bitcoin::secp256k1::recovery::{RecoverableSignature, RecoveryId};
+use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
 use bitcoin::secp256k1::{Error, Message, PublicKey, Secp256k1, SecretKey};
 
 static LN_MESSAGE_PREFIX: &[u8] = b"Lightning Signed Message:";
@@ -57,7 +57,7 @@ pub fn sign(msg: &[u8], sk: &SecretKey) -> Result<String, Error> {
     let secp_ctx = Secp256k1::signing_only();
     let msg_hash = sha256d::Hash::hash(&[LN_MESSAGE_PREFIX, msg].concat());
 
-    let sig = secp_ctx.sign_recoverable(&Message::from_slice(&msg_hash)?, sk);
+    let sig = secp_ctx.sign_ecdsa_recoverable(&Message::from_slice(&msg_hash)?, sk);
     Ok(zbase32::encode(&sigrec_encode(sig)))
 }
 
@@ -69,7 +69,7 @@ pub fn recover_pk(msg: &[u8], sig: &str) ->  Result<PublicKey, Error> {
     match zbase32::decode(&sig) {
         Ok(sig_rec) => {
             match sigrec_decode(sig_rec) {
-                Ok(sig) => secp_ctx.recover(&Message::from_slice(&msg_hash)?, &sig),
+                Ok(sig) => secp_ctx.recover_ecdsa(&Message::from_slice(&msg_hash)?, &sig),
                 Err(e) => Err(e)
             }
         },
@@ -90,7 +90,7 @@ pub fn verify(msg: &[u8], sig: &str, pk: &PublicKey) -> bool {
 mod test {
     use core::str::FromStr;
     use util::message_signing::{sign, recover_pk, verify};
-    use bitcoin::secp256k1::key::ONE_KEY;
+    use bitcoin::secp256k1::ONE_KEY;
     use bitcoin::secp256k1::{PublicKey, Secp256k1};
 
     #[test]
index 9476331c15618fb3cf099b7b875dee8e2ec18cd0..5c124c21afdb25984d9d43362726f858fb292c8b 100644 (file)
@@ -11,6 +11,7 @@
 use core::ops::Deref;
 use bitcoin::hashes::hex::ToHex;
 use io::{self};
+use routing::scoring::WriteableScore;
 
 use crate::{chain::{keysinterface::{Sign, KeysInterface}, self, transaction::{OutPoint}, chaininterface::{BroadcasterInterface, FeeEstimator}, chainmonitor::{Persist, MonitorUpdateId}, channelmonitor::{ChannelMonitor, ChannelMonitorUpdate}}, ln::channelmanager::ChannelManager, routing::network_graph::NetworkGraph};
 use super::{logger::Logger, ser::Writeable};
@@ -24,37 +25,47 @@ pub trait KVStorePersister {
        fn persist<W: Writeable>(&self, key: &str, object: &W) -> io::Result<()>;
 }
 
-/// Trait that handles persisting a [`ChannelManager`] and [`NetworkGraph`] to disk.
-pub trait Persister<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
+/// Trait that handles persisting a [`ChannelManager`], [`NetworkGraph`], and [`WriteableScore`] to disk.
+pub trait Persister<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref, S>
        where M::Target: 'static + chain::Watch<Signer>,
                T::Target: 'static + BroadcasterInterface,
                K::Target: 'static + KeysInterface<Signer = Signer>,
                F::Target: 'static + FeeEstimator,
                L::Target: 'static + Logger,
+               S: WriteableScore<'a>,
 {
        /// Persist the given ['ChannelManager'] to disk, returning an error if persistence failed.
        fn persist_manager(&self, channel_manager: &ChannelManager<Signer, M, T, K, F, L>) -> Result<(), io::Error>;
 
        /// Persist the given [`NetworkGraph`] to disk, returning an error if persistence failed.
        fn persist_graph(&self, network_graph: &NetworkGraph) -> Result<(), io::Error>;
+
+       /// Persist the given [`WriteableScore`] to disk, returning an error if persistence failed.
+       fn persist_scorer(&self, scorer: &S) -> Result<(), io::Error>;
 }
 
-impl<A: KVStorePersister, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Persister<Signer, M, T, K, F, L> for A
+impl<'a, A: KVStorePersister, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref, S> Persister<'a, Signer, M, T, K, F, L, S> for A
        where M::Target: 'static + chain::Watch<Signer>,
                T::Target: 'static + BroadcasterInterface,
                K::Target: 'static + KeysInterface<Signer = Signer>,
                F::Target: 'static + FeeEstimator,
                L::Target: 'static + Logger,
+               S: WriteableScore<'a>,
 {
-       /// Persist the given ['ChannelManager'] to disk, returning an error if persistence failed.
+       /// Persist the given ['ChannelManager'] to disk with the name "manager", returning an error if persistence failed.
        fn persist_manager(&self, channel_manager: &ChannelManager<Signer, M, T, K, F, L>) -> Result<(), io::Error> {
                self.persist("manager", channel_manager)
        }
 
-       /// Persist the given [`NetworkGraph`] to disk, returning an error if persistence failed.
+       /// Persist the given [`NetworkGraph`] to disk with the name "network_graph", returning an error if persistence failed.
        fn persist_graph(&self, network_graph: &NetworkGraph) -> Result<(), io::Error> {
                self.persist("network_graph", network_graph)
        }
+
+       /// Persist the given [`WriteableScore`] to disk with name "scorer", returning an error if persistence failed.
+       fn persist_scorer(&self, scorer: &S) -> Result<(), io::Error> {
+               self.persist("scorer", &scorer)
+       }
 }
 
 impl<ChannelSigner: Sign, K: KVStorePersister> Persist<ChannelSigner> for K {
index de12d8506f8d2da87becade08ac82514e30dc6d0..69fd14640ae605bc2d481f40760ee48d3a502eb6 100644 (file)
@@ -17,9 +17,9 @@ use core::hash::Hash;
 use sync::Mutex;
 use core::cmp;
 
-use bitcoin::secp256k1::Signature;
-use bitcoin::secp256k1::key::{PublicKey, SecretKey};
+use bitcoin::secp256k1::{PublicKey, SecretKey};
 use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SIGNATURE_SIZE};
+use bitcoin::secp256k1::ecdsa::Signature;
 use bitcoin::blockdata::script::Script;
 use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
 use bitcoin::consensus;
index 0aa39e8a979ee90c639a6ee97c6f6afb2d1fb7a5..b5953834c8cacbefd28dfc4c892bd7d700b8e94c 100644 (file)
@@ -35,8 +35,8 @@ use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::network::constants::Network;
 use bitcoin::hash_types::{BlockHash, Txid};
 
-use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1, Signature};
-use bitcoin::secp256k1::recovery::RecoverableSignature;
+use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1, ecdsa::Signature};
+use bitcoin::secp256k1::ecdsa::RecoverableSignature;
 
 use regex;
 
index 4d444d7c2aba29f20aa8ad6bee4e4483e008024d..12768543783cd148b7874a0009aa6b44650cd71a 100644 (file)
@@ -50,7 +50,7 @@ pub(crate) fn maybe_add_change_output(tx: &mut Transaction, input_value: u64, wi
                value: 0,
        };
        let change_len = change_output.consensus_encode(&mut sink()).unwrap();
-       let starting_weight = tx.get_weight() + WITNESS_FLAG_BYTES as usize + witness_max_weight;
+       let starting_weight = tx.weight() + WITNESS_FLAG_BYTES as usize + witness_max_weight;
        let mut weight_with_change: i64 = starting_weight as i64 + change_len as i64 * 4;
        // Include any extra bytes required to push an extra output.
        weight_with_change += (VarInt(tx.output.len() as u64 + 1).len() - VarInt(tx.output.len() as u64).len()) as i64 * 4;
@@ -77,6 +77,7 @@ mod tests {
 
        use bitcoin::hashes::sha256d::Hash as Sha256dHash;
        use bitcoin::hashes::Hash;
+       use bitcoin::Witness;
 
        use hex::decode;
 
@@ -230,7 +231,7 @@ mod tests {
                let output_spk = Script::new_p2pkh(&PubkeyHash::hash(&[0; 0]));
                assert_eq!(output_spk.dust_value().as_sat(), 546);
                // 9 sats isn't enough to pay fee on a dummy transaction...
-               assert_eq!(tx.get_weight() as u64, 40); // ie 10 vbytes
+               assert_eq!(tx.weight() as u64, 40); // ie 10 vbytes
                assert!(maybe_add_change_output(&mut tx, 9, 0, 250, output_spk.clone()).is_err());
                assert_eq!(tx.wtxid(), orig_wtxid); // Failure doesn't change the transaction
                // but 10-564 is, just not enough to add a change output...
@@ -250,7 +251,7 @@ mod tests {
                assert_eq!(tx.output.len(), 1);
                assert_eq!(tx.output[0].value, 546);
                assert_eq!(tx.output[0].script_pubkey, output_spk);
-               assert_eq!(tx.get_weight() / 4, 590-546); // New weight is exactly the fee we wanted.
+               assert_eq!(tx.weight() / 4, 590-546); // New weight is exactly the fee we wanted.
 
                tx.output.pop();
                assert_eq!(tx.wtxid(), orig_wtxid); // The only change is the addition of one output.
@@ -260,12 +261,12 @@ mod tests {
        fn test_tx_extra_outputs() {
                // Check that we correctly handle existing outputs
                let mut tx = Transaction { version: 2, lock_time: 0, input: vec![TxIn {
-                       previous_output: OutPoint::new(Txid::from_hash(Sha256dHash::default()), 0), script_sig: Script::new(), witness: Vec::new(), sequence: 0,
+                       previous_output: OutPoint::new(Txid::from_hash(Sha256dHash::default()), 0), script_sig: Script::new(), witness: Witness::new(), sequence: 0,
                }], output: vec![TxOut {
                        script_pubkey: Builder::new().push_int(1).into_script(), value: 1000
                }] };
                let orig_wtxid = tx.wtxid();
-               let orig_weight = tx.get_weight();
+               let orig_weight = tx.weight();
                assert_eq!(orig_weight / 4, 61);
 
                assert_eq!(Builder::new().push_int(2).into_script().dust_value().as_sat(), 474);
@@ -284,7 +285,7 @@ mod tests {
                assert_eq!(tx.output.len(), 2);
                assert_eq!(tx.output[1].value, 474);
                assert_eq!(tx.output[1].script_pubkey, Builder::new().push_int(2).into_script());
-               assert_eq!(tx.get_weight() - orig_weight, 40); // Weight difference matches what we had to add above
+               assert_eq!(tx.weight() - orig_weight, 40); // Weight difference matches what we had to add above
                tx.output.pop();
                assert_eq!(tx.wtxid(), orig_wtxid); // The only change is the addition of one output.
        }