use crate::io::{self, Cursor, Read};
use crate::io_extras::read_to_end;
-use crate::events::{EventsProvider, MessageSendEventsProvider};
+use crate::events::MessageSendEventsProvider;
use crate::crypto::streams::ChaChaPolyReadAdapter;
use crate::util::logger;
use crate::util::ser::{BigSize, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname, LengthRead, LengthReadable, LengthReadableArgs, Readable, ReadableArgs, TransactionU16LenLimited, WithoutLength, Writeable, Writer};
pub short_channel_id: u64,
/// A strictly monotonic announcement counter, with gaps allowed, specific to this channel
pub timestamp: u32,
- /// Channel flags
- pub flags: u8,
+ /// Flags pertaining to this message.
+ pub message_flags: u8,
+ /// Flags pertaining to the channel, including to which direction in the channel this update
+ /// applies and whether the direction is currently able to forward HTLCs.
+ pub channel_flags: u8,
/// The number of blocks such that if:
/// `incoming_htlc.cltv_expiry < outgoing_htlc.cltv_expiry + cltv_expiry_delta`
/// then we need to fail the HTLC backwards. When forwarding an HTLC, `cltv_expiry_delta` determines
}
/// A handler for received [`OnionMessage`]s and for providing generated ones to send.
-pub trait OnionMessageHandler: EventsProvider {
+pub trait OnionMessageHandler {
/// Handle an incoming `onion_message` message from the given peer.
fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage);
impl Writeable for UnsignedChannelUpdate {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
- // `message_flags` used to indicate presence of `htlc_maximum_msat`, but was deprecated in the spec.
- const MESSAGE_FLAGS: u8 = 1;
self.chain_hash.write(w)?;
self.short_channel_id.write(w)?;
self.timestamp.write(w)?;
- let all_flags = self.flags as u16 | ((MESSAGE_FLAGS as u16) << 8);
- all_flags.write(w)?;
+ // Thw low bit of message_flags used to indicate the presence of `htlc_maximum_msat`, and
+ // now must be set
+ (self.message_flags | 1).write(w)?;
+ self.channel_flags.write(w)?;
self.cltv_expiry_delta.write(w)?;
self.htlc_minimum_msat.write(w)?;
self.fee_base_msat.write(w)?;
impl Readable for UnsignedChannelUpdate {
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
- Ok(Self {
+ let res = Self {
chain_hash: Readable::read(r)?,
short_channel_id: Readable::read(r)?,
timestamp: Readable::read(r)?,
- flags: {
- let flags: u16 = Readable::read(r)?;
- // Note: we ignore the `message_flags` for now, since it was deprecated by the spec.
- flags as u8
- },
+ message_flags: Readable::read(r)?,
+ channel_flags: Readable::read(r)?,
cltv_expiry_delta: Readable::read(r)?,
htlc_minimum_msat: Readable::read(r)?,
fee_base_msat: Readable::read(r)?,
fee_proportional_millionths: Readable::read(r)?,
htlc_maximum_msat: Readable::read(r)?,
excess_data: read_to_end(r)?,
- })
+ };
+ if res.message_flags & 1 != 1 {
+ // The `must_be_one` flag should be set (historically it indicated the presence of the
+ // `htlc_maximum_msat` field, which is now required).
+ Err(DecodeError::InvalidValue)
+ } else {
+ Ok(res)
+ }
}
}
#[cfg(test)]
mod tests {
- use bitcoin::{Transaction, TxIn, ScriptBuf, Sequence, Witness, TxOut};
+ use bitcoin::{Amount, Transaction, TxIn, ScriptBuf, Sequence, Witness, TxOut};
use hex::DisplayHex;
use crate::ln::types::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
use bitcoin::hashes::hex::FromHex;
use bitcoin::address::Address;
- use bitcoin::network::constants::Network;
+ use bitcoin::network::Network;
use bitcoin::blockdata::constants::ChainHash;
use bitcoin::blockdata::script::Builder;
use bitcoin::blockdata::opcodes;
use bitcoin::hash_types::Txid;
use bitcoin::locktime::absolute::LockTime;
+ use bitcoin::transaction::Version;
use bitcoin::secp256k1::{PublicKey,SecretKey};
use bitcoin::secp256k1::{Secp256k1, Message};
macro_rules! get_sig_on {
($privkey: expr, $ctx: expr, $string: expr) => {
{
- let sighash = Message::from_slice(&$string.into_bytes()[..]).unwrap();
+ let sighash = Message::from_digest_slice(&$string.into_bytes()[..]).unwrap();
$ctx.sign_ecdsa(&sighash, &$privkey)
}
}
chain_hash: ChainHash::using_genesis_block(Network::Bitcoin),
short_channel_id: 2316138423780173,
timestamp: 20190119,
- flags: if direction { 1 } else { 0 } | if disable { 1 << 1 } else { 0 },
+ message_flags: 1, // Only must_be_one
+ channel_flags: if direction { 1 } else { 0 } | if disable { 1 << 1 } else { 0 },
cltv_expiry_delta: 144,
htlc_minimum_msat: 1000000,
htlc_maximum_msat: 131355275467161,
channel_id: ChannelId::from_bytes([2; 32]),
serial_id: 4886718345,
prevtx: TransactionU16LenLimited::new(Transaction {
- version: 2,
+ version: Version::TWO,
lock_time: LockTime::ZERO,
input: vec![TxIn {
previous_output: OutPoint { txid: Txid::from_str("305bab643ee297b8b6b76b320792c8223d55082122cb606bf89382146ced9c77").unwrap(), index: 2 }.into_bitcoin_outpoint(),
}],
output: vec![
TxOut {
- value: 12704566,
- script_pubkey: Address::from_str("bc1qzlffunw52jav8vwdu5x3jfk6sr8u22rmq3xzw2").unwrap().payload.script_pubkey(),
+ value: Amount::from_sat(12704566),
+ script_pubkey: Address::from_str("bc1qzlffunw52jav8vwdu5x3jfk6sr8u22rmq3xzw2").unwrap().payload().script_pubkey(),
},
TxOut {
- value: 245148,
- script_pubkey: Address::from_str("bc1qxmk834g5marzm227dgqvynd23y2nvt2ztwcw2z").unwrap().payload.script_pubkey(),
+ value: Amount::from_sat(245148),
+ script_pubkey: Address::from_str("bc1qxmk834g5marzm227dgqvynd23y2nvt2ztwcw2z").unwrap().payload().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().payload().script_pubkey(),
};
let encoded_value = tx_add_output.encode();
let target_value = <Vec<u8>>::from_hex("0202020202020202020202020202020202020202020202020202020202020202000000012345678900000001234567890016001436ec78d514df462da95e6a00c24daa8915362d42").unwrap();