lightning-invoice = { path = "../lightning-invoice" }
lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" }
bech32 = "0.9.1"
-bitcoin = { version = "0.31.2", features = ["secp-lowmemory"] }
+bitcoin = { version = "0.32.2", features = ["secp-lowmemory"] }
afl = { version = "0.12", optional = true }
honggfuzz = { version = "0.5", optional = true, default-features = false }
use bitcoin::secp256k1::schnorr;
use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey};
+use lightning::io::Cursor;
use std::cmp::{self, Ordering};
-use std::io::Cursor;
use std::mem;
use std::sync::atomic;
use std::sync::{Arc, Mutex};
pub struct VecWriter(pub Vec<u8>);
impl Writer for VecWriter {
- fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), ::lightning::io::Error> {
self.0.extend_from_slice(buf);
Ok(())
}
}
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::EcdsaSigner, DecodeError> {
- let mut reader = std::io::Cursor::new(buffer);
+ let mut reader = lightning::io::Cursor::new(buffer);
let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?;
let state = self.make_enforcement_state_cell(inner.commitment_seed);
use crate::utils::test_logger;
-use std::io::Cursor;
+use lightning::io::Cursor;
struct VecWriter(Vec<u8>);
impl Writer for VecWriter {
- fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), ::lightning::io::Error> {
self.0.extend_from_slice(buf);
Ok(())
}
Some(&self.data[old_pos..old_pos + len])
}
}
-impl std::io::Read for &InputData {
- fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+impl lightning::io::Read for &InputData {
+ fn read(&mut self, buf: &mut [u8]) -> lightning::io::Result<usize> {
if let Some(sl) = self.get_slice(buf.len()) {
buf.copy_from_slice(sl);
Ok(buf.len())
use lightning::util::ser::Writer;
pub struct VecWriter(pub Vec<u8>);
impl Writer for VecWriter {
- fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), ::lightning::io::Error> {
self.0.extend_from_slice(buf);
Ok(())
}
macro_rules! test_msg {
($MsgType: path, $data: ident) => {{
use lightning::util::ser::{Readable, Writeable};
- let mut r = ::std::io::Cursor::new($data);
+ let mut r = ::lightning::io::Cursor::new($data);
if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
let p = r.position() as usize;
let mut w = VecWriter(Vec::new());
macro_rules! test_msg_simple {
($MsgType: path, $data: ident) => {{
use lightning::util::ser::{Readable, Writeable};
- let mut r = ::std::io::Cursor::new($data);
+ let mut r = ::lightning::io::Cursor::new($data);
if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
let mut w = VecWriter(Vec::new());
msg.write(&mut w).unwrap();
assert_eq!(msg.serialized_length(), w.0.len());
- let msg = <$MsgType as Readable>::read(&mut ::std::io::Cursor::new(&w.0)).unwrap();
+ let msg =
+ <$MsgType as Readable>::read(&mut ::lightning::io::Cursor::new(&w.0)).unwrap();
let mut w_two = VecWriter(Vec::new());
msg.write(&mut w_two).unwrap();
assert_eq!(&w.0[..], &w_two.0[..]);
macro_rules! test_msg_exact {
($MsgType: path, $data: ident) => {{
use lightning::util::ser::{Readable, Writeable};
- let mut r = ::std::io::Cursor::new($data);
+ let mut r = ::lightning::io::Cursor::new($data);
if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
let mut w = VecWriter(Vec::new());
msg.write(&mut w).unwrap();
macro_rules! test_msg_hole {
($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => {{
use lightning::util::ser::{Readable, Writeable};
- let mut r = ::std::io::Cursor::new($data);
+ let mut r = ::lightning::io::Cursor::new($data);
if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
let mut w = VecWriter(Vec::new());
msg.write(&mut w).unwrap();
pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
use bitcoin::secp256k1::PublicKey;
use lightning::util::ser::ReadableArgs;
- let mut r = ::std::io::Cursor::new(data);
+ let mut r = ::lightning::io::Cursor::new(data);
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
use bitcoin::secp256k1::PublicKey;
use lightning::util::ser::ReadableArgs;
let data = unsafe { std::slice::from_raw_parts(data, datalen) };
- let mut r = ::std::io::Cursor::new(data);
+ let mut r = ::lightning::io::Cursor::new(data);
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(
Option<PublicKey>,
use crate::utils::test_logger;
-use std::io::{self, Cursor};
+use lightning::io::{self, Cursor};
use std::sync::atomic::{AtomicU64, Ordering};
#[inline]
&self, _message_type: u64, buffer: &mut R,
) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
let mut buf = Vec::new();
- buffer.read_to_end(&mut buf)?;
+ buffer.read_to_limit(&mut buf, u64::MAX)?;
return Ok(Some(TestCustomMessage {}));
}
fn release_pending_custom_messages(&self) -> Vec<PendingOnionMessage<Self::CustomMessage>> {
pub struct VecWriter(pub Vec<u8>);
impl Writer for VecWriter {
- fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), ::lightning::io::Error> {
self.0.extend_from_slice(buf);
Ok(())
}
macro_rules! decode_msg {
($MsgType: path, $len: expr) => {{
- let mut reader = ::std::io::Cursor::new(get_slice!($len));
+ let mut reader = ::lightning::io::Cursor::new(get_slice!($len));
match <$MsgType>::read(&mut reader) {
Ok(msg) => {
assert_eq!(reader.position(), $len as u64);
[features]
futures = [ ]
std = ["bitcoin/std", "lightning/std", "lightning-rapid-gossip-sync/std"]
-no-std = ["bitcoin/no-std", "lightning/no-std", "lightning-rapid-gossip-sync/no-std"]
+no-std = ["lightning/no-std", "lightning-rapid-gossip-sync/no-std"]
default = ["std"]
[dependencies]
-bitcoin = { version = "0.31.2", default-features = false }
+bitcoin = { version = "0.32.2", default-features = false }
lightning = { version = "0.0.123-beta", path = "../lightning", default-features = false }
lightning-rapid-gossip-sync = { version = "0.0.123-beta", path = "../lightning-rapid-gossip-sync", default-features = false }
&& key == CHANNEL_MANAGER_PERSISTENCE_KEY
{
if let Some((error, message)) = self.manager_error {
- return Err(std::io::Error::new(error, message));
+ return Err(std::io::Error::new(error, message).into());
}
}
};
if let Some((error, message)) = self.graph_error {
- return Err(std::io::Error::new(error, message));
+ return Err(std::io::Error::new(error, message).into());
}
}
&& key == SCORER_PERSISTENCE_KEY
{
if let Some((error, message)) = self.scorer_error {
- return Err(std::io::Error::new(error, message));
+ return Err(std::io::Error::new(error, message).into());
}
}
match bp_future.await {
Ok(_) => panic!("Expected error persisting manager"),
Err(e) => {
- assert_eq!(e.kind(), std::io::ErrorKind::Other);
+ assert_eq!(e.kind(), lightning::io::ErrorKind::Other);
assert_eq!(e.get_ref().unwrap().to_string(), "test");
},
}
rpc-client = [ "serde_json", "chunked_transfer" ]
[dependencies]
-bitcoin = "0.31.2"
+bitcoin = "0.32.2"
lightning = { version = "0.0.123-beta", path = "../lightning" }
tokio = { version = "1.35", features = [ "io-util", "net", "time", "rt" ], optional = true }
serde_json = { version = "1.0", optional = true }
match TryInto::<Txid>::try_into(response) {
Err(e) => {
assert_eq!(e.kind(), io::ErrorKind::InvalidData);
- assert_eq!(
- e.get_ref().unwrap().to_string(),
- "bad hex string length 6 (expected 64)"
- );
+ assert_eq!(e.get_ref().unwrap().to_string(), "failed to parse hex");
},
Ok(_) => panic!("Expected error"),
}
match TryInto::<Txid>::try_into(response) {
Err(e) => {
assert_eq!(e.kind(), io::ErrorKind::InvalidData);
- assert_eq!(
- e.get_ref().unwrap().to_string(),
- "bad hex string length 4 (expected 64)"
- );
+ assert_eq!(e.get_ref().unwrap().to_string(), "failed to parse hex");
},
Ok(_) => panic!("Expected error"),
}
///
/// use lightning_block_sync::*;
///
-/// use std::io::Cursor;
+/// use lightning::io::Cursor;
///
/// async fn init_sync<
/// B: BlockSource,
#[cfg(test)]
mod tests {
use super::*;
- use bitcoin::hex::HexToBytesError;
use bitcoin::pow::Work;
#[test]
#[test]
fn hex_to_work_too_short_str() {
let hex = String::from_utf8(vec![b'0'; 32]).unwrap();
- assert_eq!(hex_to_work(&hex), Err(HexToArrayError::InvalidLength(32, 64)));
+ assert!(hex_to_work(&hex).is_err());
}
#[test]
fn hex_to_work_too_long_str() {
let hex = String::from_utf8(vec![b'0'; 128]).unwrap();
- assert_eq!(hex_to_work(&hex), Err(HexToArrayError::InvalidLength(128, 64)));
+ assert!(hex_to_work(&hex).is_err());
}
#[test]
fn hex_to_work_odd_length_str() {
let hex = String::from_utf8(vec![b'0'; 65]).unwrap();
- assert_eq!(
- hex_to_work(&hex),
- Err(HexToArrayError::Conversion(HexToBytesError::OddLengthString(65)))
- );
+ assert!(hex_to_work(&hex).is_err());
}
#[test]
fn hex_to_work_invalid_char() {
let hex = String::from_utf8(vec![b'G'; 64]).unwrap();
- assert_eq!(
- hex_to_work(&hex),
- Err(HexToArrayError::Conversion(HexToBytesError::InvalidChar(b'G')))
- );
+ assert!(hex_to_work(&hex).is_err());
}
#[test]
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
-bitcoin = "0.31.2"
+bitcoin = "0.32.2"
lightning = { version = "0.0.123-beta", path = "../lightning" }
[lints]
[features]
default = ["std"]
-no-std = ["bitcoin/no-std"]
-std = ["bitcoin/std", "bech32/std"]
+no-std = []
+std = ["bech32/std"]
[dependencies]
bech32 = { version = "0.9.1", default-features = false }
lightning-types = { version = "0.1", path = "../lightning-types", default-features = false }
-secp256k1 = { version = "0.28.0", default-features = false, features = ["recovery", "alloc"] }
+secp256k1 = { version = "0.29.0", default-features = false, features = ["recovery", "alloc"] }
serde = { version = "1.0.118", optional = true }
-bitcoin = { version = "0.31.2", default-features = false }
+bitcoin = { version = "0.32.2", default-features = false }
[dev-dependencies]
serde_json = { version = "1"}
use bech32::{FromBase32, u5};
use bitcoin::{Address, Network, PubkeyHash, ScriptHash, WitnessProgram, WitnessVersion};
-use bitcoin::address::Payload;
use bitcoin::hashes::{Hash, sha256};
use lightning_types::features::Bolt11InvoiceFeatures;
/// Returns a list of all fallback addresses as [`Address`]es
pub fn fallback_addresses(&self) -> Vec<Address> {
self.fallbacks().iter().filter_map(|fallback| {
- let payload = match fallback {
+ let address = match fallback {
Fallback::SegWitProgram { version, program } => {
- match WitnessProgram::new(*version, program.clone()) {
- Ok(witness_program) => Payload::WitnessProgram(witness_program),
+ match WitnessProgram::new(*version, &program) {
+ Ok(witness_program) => Address::from_witness_program(witness_program, self.network()),
Err(_) => return None,
}
}
Fallback::PubKeyHash(pkh) => {
- Payload::PubkeyHash(*pkh)
+ Address::p2pkh(*pkh, self.network())
}
Fallback::ScriptHash(sh) => {
- Payload::ScriptHash(*sh)
+ Address::p2sh_from_hash(*sh, self.network())
}
};
- Some(Address::new(self.network(), payload))
+ Some(address)
}).collect()
}
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
-bitcoin = "0.31.2"
+bitcoin = "0.32.2"
lightning = { version = "0.0.123-beta", path = "../lightning" }
tokio = { version = "1.35", features = [ "rt", "sync", "net", "time" ] }
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
-bitcoin = "0.31.2"
+bitcoin = "0.32.2"
lightning = { version = "0.0.123-beta", path = "../lightning" }
[target.'cfg(windows)'.dependencies]
[dev-dependencies]
lightning = { version = "0.0.123-beta", path = "../lightning", features = ["_test_utils"] }
-bitcoin = { version = "0.31.2", default-features = false }
+bitcoin = { version = "0.32.2", default-features = false }
[lints]
workspace = true
}
impl KVStore for FilesystemStore {
- fn read(&self, primary_namespace: &str, secondary_namespace: &str, key: &str) -> std::io::Result<Vec<u8>> {
+ fn read(&self, primary_namespace: &str, secondary_namespace: &str, key: &str) -> lightning::io::Result<Vec<u8>> {
check_namespace_key_validity(primary_namespace, secondary_namespace, Some(key), "read")?;
let mut dest_file_path = self.get_dest_dir_path(primary_namespace, secondary_namespace)?;
Ok(buf)
}
- fn write(&self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: &[u8]) -> std::io::Result<()> {
+ fn write(&self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: &[u8]) -> lightning::io::Result<()> {
check_namespace_key_validity(primary_namespace, secondary_namespace, Some(key), "write")?;
let mut dest_file_path = self.get_dest_dir_path(primary_namespace, secondary_namespace)?;
dest_file.sync_all()?;
Ok(())
}
- Err(e) => Err(e),
+ Err(e) => Err(e.into()),
}
}
};
res
}
- fn remove(&self, primary_namespace: &str, secondary_namespace: &str, key: &str, lazy: bool) -> std::io::Result<()> {
+ fn remove(&self, primary_namespace: &str, secondary_namespace: &str, key: &str, lazy: bool) -> lightning::io::Result<()> {
check_namespace_key_validity(primary_namespace, secondary_namespace, Some(key), "remove")?;
let mut dest_file_path = self.get_dest_dir_path(primary_namespace, secondary_namespace)?;
Ok(())
}
- fn list(&self, primary_namespace: &str, secondary_namespace: &str) -> std::io::Result<Vec<String>> {
+ fn list(&self, primary_namespace: &str, secondary_namespace: &str) -> lightning::io::Result<Vec<String>> {
check_namespace_key_validity(primary_namespace, secondary_namespace, None, "list")?;
let prefixed_dest = self.get_dest_dir_path(primary_namespace, secondary_namespace)?;
PrintableString(primary_namespace), PrintableString(secondary_namespace));
let msg = format!("Failed to list keys of {}/{}: file couldn't be accessed.",
PrintableString(primary_namespace), PrintableString(secondary_namespace));
- return Err(std::io::Error::new(std::io::ErrorKind::Other, msg));
+ return Err(lightning::io::Error::new(lightning::io::ErrorKind::Other, msg));
}
match p.strip_prefix(&prefixed_dest) {
PrintableString(primary_namespace), PrintableString(secondary_namespace));
let msg = format!("Failed to list keys of {}/{}: file path is not valid UTF-8",
PrintableString(primary_namespace), PrintableString(secondary_namespace));
- return Err(std::io::Error::new(std::io::ErrorKind::Other, msg));
+ return Err(lightning::io::Error::new(lightning::io::ErrorKind::Other, msg));
}
}
Err(e) => {
PrintableString(primary_namespace), PrintableString(secondary_namespace), e);
let msg = format!("Failed to list keys of {}/{}: {}",
PrintableString(primary_namespace), PrintableString(secondary_namespace), e);
- return Err(std::io::Error::new(std::io::ErrorKind::Other, msg));
+ return Err(lightning::io::Error::new(lightning::io::ErrorKind::Other, msg));
}
}
}
[dependencies]
lightning = { version = "0.0.123-beta", path = "../lightning", default-features = false }
-bitcoin = { version = "0.31.2", default-features = false }
+bitcoin = { version = "0.32.2", default-features = false }
[target.'cfg(ldk_bench)'.dependencies]
criterion = { version = "0.4", optional = true, default-features = false }
use core::ops::Deref;
use core::sync::atomic::{AtomicBool, Ordering};
-#[cfg(feature = "std")]
-use std::fs::File;
-
use lightning::io;
use lightning::ln::msgs::{DecodeError, LightningError};
use lightning::routing::gossip::NetworkGraph;
///
/// `sync_path`: Path to the file where the gossip update data is located
///
- #[cfg(feature = "std")]
+ #[cfg(all(feature = "std", not(feature = "no-std")))]
pub fn sync_network_graph_with_file_path(
&self, sync_path: &str,
) -> Result<u32, GraphSyncError> {
- let mut file = File::open(sync_path)?;
- self.update_network_graph_from_byte_stream(&mut file)
+ let file = std::fs::File::open(sync_path).map_err(|e| {
+ let bitcoin_error: lightning::io::Error = e.into();
+ bitcoin_error
+ })?;
+ let mut buf_reader = std::io::BufReader::new(file);
+ self.update_network_graph_from_byte_stream(&mut buf_reader)
}
/// Update network graph from binary data.
}
}
-#[cfg(feature = "std")]
+#[cfg(all(feature = "std", not(feature = "no-std")))]
#[cfg(test)]
mod tests {
use std::fs;
[dependencies]
lightning = { version = "0.0.123-beta", path = "../lightning", default-features = false, features = ["std"] }
-bitcoin = { version = "0.31.2", default-features = false }
+bitcoin = { version = "0.32.2", default-features = false }
bdk-macros = "0.6"
futures = { version = "0.3", optional = true }
-esplora-client = { version = "0.7", default-features = false, optional = true }
-electrum-client = { version = "0.19.0", optional = true }
+esplora-client = { version = "0.9", default-features = false, optional = true }
+electrum-client = { version = "0.21.0", optional = true }
[dev-dependencies]
lightning = { version = "0.0.123-beta", path = "../lightning", default-features = false, features = ["std", "_test_utils"] }
tokio = { version = "1.35.0", features = ["full"] }
[target.'cfg(not(target_os = "windows"))'.dev-dependencies]
-electrsd = { version = "0.27.3", default-features = false, features = ["legacy"] }
+electrsd = { version = "0.28.0", default-features = false, features = ["legacy"] }
[lints]
workspace = true
None,
)
.unwrap();
- $tx_sync.register_tx(&txid, &new_address.payload().script_pubkey());
+ $tx_sync.register_tx(&txid, &new_address.script_pubkey());
maybe_await!($tx_sync.sync(vec![&$confirmable])).unwrap();
_test_utils = []
[dependencies]
-bitcoin = { version = "0.31", default-features = false }
+bitcoin = { version = "0.32.2", default-features = false }
# TODO: Once we switch to bitcoin 0.32 drop this explicit dep:
hex-conservative = { version = "0.2", default-features = false }
bech32 = { version = "0.9", default-features = false }
# Override signing to not include randomness when generating signatures for test vectors.
_test_vectors = []
-no-std = ["hashbrown", "possiblyrandom", "bitcoin/no-std", "lightning-invoice/no-std", "core2/alloc", "libm"]
-std = ["bitcoin/std", "bech32/std", "lightning-invoice/std"]
+no-std = ["hashbrown", "possiblyrandom", "lightning-invoice/no-std", "libm"]
+std = ["lightning-invoice/std", "bech32/std"]
# Generates low-r bitcoin signatures, which saves 1 byte in 50% of the cases
grind_signatures = []
lightning-invoice = { version = "0.31.0-beta", path = "../lightning-invoice", default-features = false }
bech32 = { version = "0.9.1", default-features = false }
-bitcoin = { version = "0.31.2", default-features = false, features = ["secp-recovery"] }
+bitcoin = { version = "0.32.2", default-features = false, features = ["secp-recovery"] }
hashbrown = { version = "0.13", optional = true, default-features = false }
possiblyrandom = { version = "0.2", optional = true, default-features = false }
regex = { version = "1.5.6", optional = true }
backtrace = { version = "0.3", optional = true }
-core2 = { version = "0.3.0", optional = true, default-features = false }
libm = { version = "0.2", optional = true, default-features = false }
[dev-dependencies]
lightning-types = { version = "0.1", path = "../lightning-types", features = ["_test_utils"] }
[dev-dependencies.bitcoin]
-version = "0.31.2"
+version = "0.32.2"
default-features = false
features = ["bitcoinconsensus", "secp-recovery"]
criterion = { version = "0.4", optional = true, default-features = false }
[target.'cfg(taproot)'.dependencies]
-musig2 = { git = "https://github.com/arik-so/rust-musig2", rev = "739533fc" }
+musig2 = { git = "https://github.com/arik-so/rust-musig2", rev = "6f95a05718cbb44d8fe3fa6021aea8117aa38d50" }
[lints]
workspace = true
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::ecdsa::Signature as BitcoinSignature;
-use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
-use bitcoin::secp256k1::{SecretKey, PublicKey};
-use bitcoin::secp256k1;
+use bitcoin::secp256k1::{self, SecretKey, PublicKey, Secp256k1, ecdsa::Signature};
use crate::ln::channel::INITIAL_COMMITMENT_NUMBER;
use crate::ln::types::{PaymentHash, PaymentPreimage, ChannelId};
assert_eq!(&bitcoin::Address::p2wsh(&ScriptBuf::from(input.witness.last().unwrap().to_vec()), bitcoin::Network::Bitcoin).script_pubkey(), _script_pubkey);
} else if _script_pubkey.is_p2wpkh() {
- assert_eq!(&bitcoin::Address::p2wpkh(&bitcoin::PublicKey::from_slice(&input.witness.last().unwrap()).unwrap(), bitcoin::Network::Bitcoin).unwrap().script_pubkey(), _script_pubkey);
+ assert_eq!(&bitcoin::Address::p2wpkh(&bitcoin::CompressedPublicKey(bitcoin::PublicKey::from_slice(&input.witness.last().unwrap()).unwrap().inner), bitcoin::Network::Bitcoin).script_pubkey(), _script_pubkey);
} else { panic!(); }
}
return true;
-#[cfg(not(feature = "std"))]
-/// Re-export of either `core2::io` or `std::io`, depending on the `std` feature flag.
-pub use core2::io::*;
-#[cfg(feature = "std")]
-/// Re-export of either `core2::io` or `std::io`, depending on the `std` feature flag.
-pub use std::io::*;
+pub use bitcoin::io::*;
/// Emulation of std::io::Cursor
#[derive(Clone, Debug, Default, Eq, PartialEq)]
#[cfg(any(test, feature = "_test_utils"))] extern crate regex;
-#[cfg(not(feature = "std"))] extern crate core2;
#[cfg(not(feature = "std"))] extern crate libm;
#[cfg(ldk_bench)] extern crate criterion;
/// Extension of the bitcoin::io module
pub mod io;
-#[cfg(not(feature = "std"))]
#[doc(hidden)]
/// IO utilities public only for use by in-crate macros. These should not be used externally
///
/// This is not exported to bindings users as it is not intended for public consumption.
pub mod io_extras {
- use core2::io::{self, Read, Write};
-
- /// A writer which will move data into the void.
- pub struct Sink {
- _priv: (),
- }
+ use bitcoin::io::{self, Read, Write};
/// Creates an instance of a writer which will successfully consume all data.
- pub const fn sink() -> Sink {
- Sink { _priv: () }
- }
-
- impl core2::io::Write for Sink {
- #[inline]
- fn write(&mut self, buf: &[u8]) -> core2::io::Result<usize> {
- Ok(buf.len())
- }
-
- #[inline]
- fn flush(&mut self) -> core2::io::Result<()> {
- Ok(())
- }
- }
+ pub use bitcoin::io::sink;
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64, io::Error>
where
}
}
-#[cfg(feature = "std")]
-#[doc(hidden)]
-/// IO utilities public only for use by in-crate macros. These should not be used externally
-///
-/// This is not exported to bindings users as it is not intended for public consumption.
-mod io_extras {
- pub fn read_to_end<D: ::std::io::Read>(mut d: D) -> Result<Vec<u8>, ::std::io::Error> {
- let mut buf = Vec::new();
- d.read_to_end(&mut buf)?;
- Ok(buf)
- }
-
- pub use std::io::{copy, sink};
-}
-
mod prelude {
#![allow(unused_imports)]
let mut witness = Witness::new();
// First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element.
witness.push(vec![]);
- witness.push_ecdsa_signature(&BitcoinSignature { sig: *remote_sig, hash_ty: remote_sighash_type });
+ witness.push_ecdsa_signature(&BitcoinSignature { signature: *remote_sig, sighash_type: remote_sighash_type });
witness.push_ecdsa_signature(&BitcoinSignature::sighash_all(*local_sig));
if let Some(preimage) = preimage {
witness.push(preimage.0.to_vec());
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
use crate::util::test_utils;
use crate::sign::{ChannelSigner, SignerProvider};
- use bitcoin::{Network, Txid, ScriptBuf};
+ use bitcoin::{Network, Txid, ScriptBuf, CompressedPublicKey};
use bitcoin::hashes::Hash;
use bitcoin::hex::FromHex;
use crate::ln::types::PaymentHash;
- use bitcoin::address::Payload;
use bitcoin::PublicKey as BitcoinPublicKey;
use crate::ln::features::ChannelTypeFeatures;
// Generate broadcaster and counterparty outputs
let tx = builder.build(1000, 2000);
assert_eq!(tx.built.transaction.output.len(), 2);
- assert_eq!(tx.built.transaction.output[1].script_pubkey, Payload::p2wpkh(&BitcoinPublicKey::new(builder.counterparty_pubkeys.payment_point)).unwrap().script_pubkey());
+ assert_eq!(tx.built.transaction.output[1].script_pubkey, bitcoin::address::Address::p2wpkh(&CompressedPublicKey(builder.counterparty_pubkeys.payment_point), Network::Testnet).script_pubkey());
// Generate broadcaster and counterparty outputs as well as two anchors
builder.channel_parameters.channel_type_features = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
}, |msg_type: u64, msg_reader: &mut FixedLengthReader<_>| -> Result<bool, DecodeError> {
if msg_type < 1 << 16 { return Ok(false) }
let mut value = Vec::new();
- msg_reader.read_to_end(&mut value)?;
+ msg_reader.read_to_limit(&mut value, u64::MAX)?;
custom_tlvs.push((msg_type, value));
Ok(true)
});
output: vec![
TxOut {
value: Amount::from_sat(12704566),
- script_pubkey: Address::from_str("bc1qzlffunw52jav8vwdu5x3jfk6sr8u22rmq3xzw2").unwrap().payload().script_pubkey(),
+ script_pubkey: Address::from_str("bc1qzlffunw52jav8vwdu5x3jfk6sr8u22rmq3xzw2").unwrap().assume_checked().script_pubkey(),
},
TxOut {
value: Amount::from_sat(245148),
- script_pubkey: Address::from_str("bc1qxmk834g5marzm227dgqvynd23y2nvt2ztwcw2z").unwrap().payload().script_pubkey(),
+ script_pubkey: Address::from_str("bc1qxmk834g5marzm227dgqvynd23y2nvt2ztwcw2z").unwrap().assume_checked().script_pubkey(),
},
],
}).unwrap(),
channel_id: ChannelId::from_bytes([2; 32]),
serial_id: 4886718345,
sats: 4886718345,
- script: Address::from_str("bc1qxmk834g5marzm227dgqvynd23y2nvt2ztwcw2z").unwrap().payload().script_pubkey(),
+ script: Address::from_str("bc1qxmk834g5marzm227dgqvynd23y2nvt2ztwcw2z").unwrap().assume_checked().script_pubkey(),
};
let encoded_value = tx_add_output.encode();
let target_value = <Vec<u8>>::from_hex("0202020202020202020202020202020202020202020202020202020202020202000000012345678900000001234567890016001436ec78d514df462da95e6a00c24daa8915362d42").unwrap();
scriptpubkey:
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 if script_type == 3 { Address::p2wpkh(&::bitcoin::CompressedPublicKey(pubkey_1), Network::Testnet).script_pubkey() }
else { Address::p2wsh(&script, Network::Testnet).script_pubkey() },
};
let encoded_value = shutdown.encode();
use bitcoin::constants::ChainHash;
use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, self};
use bitcoin::secp256k1::schnorr::Signature;
-use bitcoin::address::{Address, Payload};
+use bitcoin::address::Address;
use core::time::Duration;
use core::hash::{Hash, Hasher};
use crate::io;
Err(_) => return None,
};
- let program = address.program.clone();
- let witness_program = match WitnessProgram::new(version, program) {
+ let witness_program = match WitnessProgram::new(version, &address.program) {
Ok(witness_program) => witness_program,
Err(_) => return None,
};
- Some(Address::new(network, Payload::WitnessProgram(witness_program)))
+ Some(Address::from_witness_program(witness_program, network))
};
fallbacks.iter().filter_map(to_valid_address).collect()
mod tests {
use super::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, InvoiceTlvStreamRef, SIGNATURE_TAG, UnsignedBolt12Invoice};
- use bitcoin::{WitnessProgram, WitnessVersion};
+ use bitcoin::{CompressedPublicKey, WitnessProgram, WitnessVersion};
use bitcoin::constants::ChainHash;
use bitcoin::script::ScriptBuf;
use bitcoin::hashes::Hash;
use bitcoin::network::Network;
use bitcoin::secp256k1::{Keypair, Message, Secp256k1, SecretKey, XOnlyPublicKey, self};
- use bitcoin::address::{Address, Payload};
+ use bitcoin::address::Address;
use bitcoin::key::TweakedPublicKey;
use core::time::Duration;
invoice.fallbacks(),
vec![
Address::p2wsh(&script, Network::Bitcoin),
- Address::p2wpkh(&pubkey, Network::Bitcoin).unwrap(),
+ Address::p2wpkh(&CompressedPublicKey(pubkey.inner), Network::Bitcoin),
Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
],
);
.sign(payer_sign)
{
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, SignError::Verification(secp256k1::Error::InvalidSignature)),
+ Err(e) => assert_eq!(e, SignError::Verification(secp256k1::Error::IncorrectSignature)),
}
}
match Bolt12Invoice::try_from(buffer) {
Ok(invoice) => {
- let v1_witness_program = WitnessProgram::new(WitnessVersion::V1, vec![0u8; 33]).unwrap();
- let v2_witness_program = WitnessProgram::new(WitnessVersion::V2, vec![0u8; 40]).unwrap();
+ let v1_witness_program = WitnessProgram::new(WitnessVersion::V1, &[0u8; 33]).unwrap();
+ let v2_witness_program = WitnessProgram::new(WitnessVersion::V2, &[0u8; 40]).unwrap();
assert_eq!(
invoice.fallbacks(),
vec![
Address::p2wsh(&script, Network::Bitcoin),
- Address::p2wpkh(&pubkey, Network::Bitcoin).unwrap(),
+ Address::p2wpkh(&CompressedPublicKey(pubkey.inner), Network::Bitcoin),
Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
- Address::new(Network::Bitcoin, Payload::WitnessProgram(v1_witness_program)),
- Address::new(Network::Bitcoin, Payload::WitnessProgram(v2_witness_program)),
+ Address::from_witness_program(v1_witness_program, Network::Bitcoin),
+ Address::from_witness_program(v2_witness_program, Network::Bitcoin),
],
);
},
match Bolt12Invoice::try_from(buffer) {
Ok(_) => panic!("expected error"),
Err(e) => {
- assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature));
+ assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature));
},
}
}
.sign(recipient_sign)
{
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, SignError::Verification(secp256k1::Error::InvalidSignature)),
+ Err(e) => assert_eq!(e, SignError::Verification(secp256k1::Error::IncorrectSignature)),
}
}
match InvoiceRequest::try_from(buffer) {
Ok(_) => panic!("expected error"),
Err(e) => {
- assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature));
+ assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature));
},
}
}
Err(e) => {
assert_eq!(
e,
- Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature)
+ Bolt12ParseError::InvalidSignature(secp256k1::Error::IncorrectSignature)
);
},
}
}
let mut bytes = Vec::new();
- r.read_to_end(&mut bytes).unwrap();
+ r.read_to_limit(&mut bytes, u64::MAX).unwrap();
match Self::parse(tlv_type, bytes) {
Ok(message) => Ok(message),
pub(crate) mod bench_utils {
use super::*;
use std::fs::File;
-
+ use std::io::Read;
use bitcoin::hashes::Hash;
use bitcoin::secp256k1::SecretKey;
pub(crate) fn read_graph_scorer(logger: &TestLogger)
-> Result<(Arc<NetworkGraph<&TestLogger>>, ProbabilisticScorer<Arc<NetworkGraph<&TestLogger>>, &TestLogger>), &'static str> {
let (mut graph_file, mut scorer_file) = get_graph_scorer_file()?;
- let graph = Arc::new(NetworkGraph::read(&mut graph_file, logger).unwrap());
+ let mut graph_buffer = Vec::new();
+ let mut scorer_buffer = Vec::new();
+ graph_file.read_to_end(&mut graph_buffer).unwrap();
+ scorer_file.read_to_end(&mut scorer_buffer).unwrap();
+ let graph = Arc::new(NetworkGraph::read(&mut &graph_buffer[..], logger).unwrap());
let scorer_args = (Default::default(), Arc::clone(&graph), logger);
- let scorer = ProbabilisticScorer::read(&mut scorer_file, scorer_args).unwrap();
+ let scorer = ProbabilisticScorer::read(&mut &scorer_buffer[..], scorer_args).unwrap();
Ok((graph, scorer))
}
.unwrap()[..]
);
let local_delayedsig = EcdsaSignature {
- sig: sign_with_aux_rand(secp_ctx, &sighash, &delayed_payment_key, &self),
- hash_ty: EcdsaSighashType::All,
+ signature: sign_with_aux_rand(secp_ctx, &sighash, &delayed_payment_key, &self),
+ sighash_type: EcdsaSighashType::All,
};
let payment_script =
bitcoin::Address::p2wsh(&witness_script, Network::Bitcoin).script_pubkey();
};
let pubkey = Xpub::from_priv(&secp_ctx, &secret).to_pub();
if derivation_idx == 2 {
- assert_eq!(pubkey.inner, self.shutdown_pubkey);
+ assert_eq!(pubkey.0, 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();
+ let payment_script =
+ bitcoin::Address::p2wpkh(&pubkey, Network::Testnet).script_pubkey();
if payment_script != output.script_pubkey {
return Err(());
let sig = sign_with_aux_rand(secp_ctx, &sighash, &secret.private_key, &self);
let mut sig_ser = sig.serialize_der().to_vec();
sig_ser.push(EcdsaSighashType::All as u8);
- let witness =
- Witness::from_slice(&[&sig_ser, &pubkey.inner.serialize().to_vec()]);
+ let witness = Witness::from_slice(&[&sig_ser, &pubkey.0.serialize().to_vec()]);
psbt.inputs[input_idx].final_script_witness = Some(witness);
},
}
//! [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
use crate::prelude::*;
-use crate::io::{self, Read, Write};
+use crate::io::{self, BufRead, Read, Write};
use crate::io_extras::{copy, sink};
use core::hash::Hash;
use crate::sync::{Mutex, RwLock};
}
}
+/// Wrap buffering support for implementations of Read.
+/// A [`Read`]er which keeps an internal buffer to avoid hitting the underlying stream directly for
+/// every read, implementing [`BufRead`].
+///
+/// In order to avoid reading bytes past the first object, and those bytes then ending up getting
+/// dropped, this BufReader operates in one-byte-increments.
+struct BufReader<'a, R: Read> {
+ inner: &'a mut R,
+ buf: [u8; 1],
+ is_consumed: bool
+}
+
+impl<'a, R: Read> BufReader<'a, R> {
+ /// Creates a [`BufReader`] which will read from the given `inner`.
+ pub fn new(inner: &'a mut R) -> Self {
+ BufReader {
+ inner,
+ buf: [0; 1],
+ is_consumed: true
+ }
+ }
+}
+
+impl<'a, R: Read> Read for BufReader<'a, R> {
+ #[inline]
+ fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
+ let input = self.fill_buf()?;
+ let count = cmp::min(input.len(), output.len());
+ output[..count].copy_from_slice(&input[..count]);
+ self.consume(count);
+ Ok(count)
+ }
+}
+
+impl<'a, R: Read> BufRead for BufReader<'a, R> {
+ #[inline]
+ fn fill_buf(&mut self) -> io::Result<&[u8]> {
+ if self.is_consumed {
+ let count = self.inner.read(&mut self.buf[..])?;
+ debug_assert!(count <= 1, "read gave us a garbage length");
+
+ // upon hitting EOF, assume the byte is already consumed
+ self.is_consumed = count == 0;
+ }
+
+ Ok(&self.buf[..])
+ }
+
+ #[inline]
+ fn consume(&mut self, amount: usize) {
+ if amount >= 1 {
+ debug_assert_eq!(amount, 1, "Can only consume one byte");
+ debug_assert!(!self.is_consumed, "Cannot consume more than had been read");
+ self.is_consumed = true;
+ }
+ }
+}
+
pub(crate) struct WriterWriteAdaptor<'a, W: Writer + 'a>(pub &'a mut W);
impl<'a, W: Writer + 'a> Write for WriterWriteAdaptor<'a, W> {
#[inline]
impl Readable for $bitcoin_type {
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
- match consensus::encode::Decodable::consensus_decode(r) {
+ let mut reader = BufReader::<_>::new(r);
+ match consensus::encode::Decodable::consensus_decode(&mut reader) {
Ok(t) => Ok(t),
Err(consensus::encode::Error::Io(ref e)) if e.kind() == io::ErrorKind::UnexpectedEof => Err(DecodeError::ShortRead),
- Err(consensus::encode::Error::Io(e)) => Err(DecodeError::Io(e.kind())),
+ Err(consensus::encode::Error::Io(e)) => Err(DecodeError::Io(e.kind().into())),
Err(_) => Err(DecodeError::InvalidValue),
}
}
let sighash = SighashCache::new(&tx)
.legacy_signature_hash(i, &utxo.output.script_pubkey, EcdsaSighashType::All as u32)
.map_err(|_| ())?;
- let sig = self.secp.sign_ecdsa(&secp256k1::Message::from_digest(sighash.to_byte_array()), &self.secret_key);
- let bitcoin_sig = bitcoin::ecdsa::Signature { sig, hash_ty: EcdsaSighashType::All };
+ let signature = self.secp.sign_ecdsa(&secp256k1::Message::from_digest(sighash.to_byte_array()), &self.secret_key);
+ let bitcoin_sig = bitcoin::ecdsa::Signature { signature, sighash_type: EcdsaSighashType::All };
tx.input[i].script_sig = Builder::new()
.push_slice(&bitcoin_sig.serialize())
.push_slice(&self.secret_key.public_key(&self.secp).serialize())