]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Fixes + BufReader experimentation.
authorArik Sosman <git@arik.io>
Mon, 12 Aug 2024 18:52:12 +0000 (11:52 -0700)
committerArik Sosman <git@arik.io>
Mon, 12 Aug 2024 18:52:12 +0000 (11:52 -0700)
lightning/src/lib.rs
lightning/src/ln/msgs.rs
lightning/src/offers/invoice.rs
lightning/src/util/ser.rs
lightning/src/util/test_utils.rs

index 7cc540af39516295f8d05b79167290327cb30933..431fee5a00381ea1ebcc1157baeea9b688296c34 100644 (file)
@@ -155,6 +155,30 @@ pub mod io {
                Current(i64),
        }
 
+       /// Adaptor to chain together two readers.
+       ///
+       /// This struct is generally created by calling [`chain`] on a reader.
+       /// Please see the documentation of [`chain`] for more details.
+       ///
+       /// [`chain`]: Read::chain
+       pub struct Chain<T, U> {
+               first: T,
+               second: U,
+               done_first: bool,
+       }
+
+       impl<T: Read, U: Read> Read for Chain<T, U> {
+               fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
+                       if !self.done_first {
+                               match self.first.read(buf)? {
+                                       0 if !buf.is_empty() => self.done_first = true,
+                                       n => return Ok(n),
+                               }
+                       }
+                       self.second.read(buf)
+               }
+       }
+
        /// Emulation of std::io::Cursor
        #[derive(Clone, Debug, Default, Eq, PartialEq)]
        pub struct Cursor<T> {
index d1fdb2e20eb8348be502882eca3f80822a8ad622..3d606f4b96640fce06b6ca65928d5885d0a4dc35 100644 (file)
@@ -3958,11 +3958,11 @@ mod tests {
                                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(),
@@ -3981,7 +3981,7 @@ mod tests {
                        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();
@@ -4130,7 +4130,7 @@ mod tests {
                        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();
index 6077043b42c6e22caad291f5d4a1bdc83b466a21..df8acec9507bbd09021d327a8fb79630b8c73e5a 100644 (file)
@@ -1934,7 +1934,7 @@ mod tests {
                        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),
                        ],
                );
@@ -2248,10 +2248,10 @@ mod tests {
                                        invoice.fallbacks(),
                                        vec![
                                                Address::p2wsh(&script, Network::Bitcoin),
-                                               Address::p2wpkh(&CompressedPublicKey(pubkey.inner), Network::Bitcoin).unwrap(),
+                                               Address::p2wpkh(&CompressedPublicKey(pubkey.inner), Network::Bitcoin),
                                                Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin),
-                                               Address::from_witness_program(v1_witness_program, Network::Bitcoin.into()),
-                                               Address::from_witness_program(v2_witness_program, Network::Bitcoin.into()),
+                                               Address::from_witness_program(v1_witness_program, Network::Bitcoin),
+                                               Address::from_witness_program(v2_witness_program, Network::Bitcoin),
                                        ],
                                );
                        },
index 83c80e804cf6f6015c4e5c6b45652728c846e691..35baf71e5ead2f783524b28737844d460643dafe 100644 (file)
@@ -64,24 +64,78 @@ impl<W: Write> Writer for W {
        }
 }
 
-pub(crate) struct ReadBufReadAdapter<R: Read + ?Sized>(pub R);
+// pub(crate) struct ReadBufReadAdapter<R: Read + ?Sized>(pub R);
+pub struct BufReader<R, const S: usize> {
+       inner: R,
+       buf: [u8; S],
+       pos: usize,
+       cap: usize,
+}
+
+impl<R: Read, const S: usize> BufReader<R, S> {
+       pub fn new(inner: R) -> BufReader<R, S> {
+               BufReader {
+                       inner,
+                       buf: [0; S],
+                       pos: 0,
+                       cap: 0,
+               }
+       }
+}
 
-impl<R: Read + ?Sized> Read for ReadBufReadAdapter<R> {
+impl<R: Read, const S: usize> Read for BufReader<R, S> {
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-               self.0.read(buf)
+               // If we don't have any buffered data and we're doing a massive read
+               // (larger than our internal buffer), bypass our internal buffer
+               // entirely.
+               if self.pos == self.cap && buf.len() >= S {
+                       self.discard_buffer();
+                       return self.inner.read(buf);
+               }
+               let nread = {
+                       let mut rem = self.fill_buf()?;
+                       rem.read(buf)?
+               };
+               self.consume(nread);
+               Ok(nread)
        }
 }
 
-impl<R: Read + ?Sized> BufRead for ReadBufReadAdapter<R> {
+impl<R: Read, const S: usize> BufRead for BufReader<R, S> {
        fn fill_buf(&mut self) -> io::Result<&[u8]> {
-               todo!()
+               // If we've reached the end of our internal buffer then we need to fetch
+               // some more data from the underlying reader.
+               // Branch using `>=` instead of the more correct `==`
+               // to tell the compiler that the pos..cap slice is always valid.
+               if self.pos >= self.cap {
+                       debug_assert!(self.pos == self.cap);
+                       self.cap = self.inner.read(&mut self.buf)?;
+                       self.pos = 0;
+               }
+               Ok(&self.buf[self.pos..self.cap])
        }
 
-       fn consume(&mut self, amount: usize) {
-               todo!()
+       fn consume(&mut self, amt: usize) {
+               self.pos = cmp::min(self.pos + amt, self.cap);
        }
 }
 
+// impl<R: Read + ?Sized> Read for ReadBufReadAdapter<R> {
+//     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+//             self.0.read(buf)
+//     }
+// }
+//
+// impl<R: Read + ?Sized> BufRead for ReadBufReadAdapter<R> {
+//     fn fill_buf(&mut self) -> io::Result<&[u8]> {
+//             todo!()
+//     }
+//
+//     fn consume(&mut self, amount: usize) {
+//             todo!()
+//     }
+// }
+
 pub(crate) struct WriterWriteAdaptor<'a, W: Writer + 'a>(pub &'a mut W);
 impl<'a, W: Writer + 'a> Write for WriterWriteAdaptor<'a, W> {
        #[inline]
@@ -1290,7 +1344,7 @@ macro_rules! impl_consensus_ser {
 
                impl Readable for $bitcoin_type {
                        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-                               match consensus::encode::Decodable::consensus_decode(&mut ReadBufReadAdapter(r)) {
+                               match consensus::encode::Decodable::consensus_decode(&mut BufReader::new(r)) {
                                        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().into())),
index 74a7f769df1bafb9d4ef58ee2cfac78f0b20073d..91e659009b20c150fafab82f1e7390c76affcc7a 100644 (file)
@@ -1591,8 +1591,8 @@ impl WalletSource for TestWalletSource {
                                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())