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> {
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();
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),
],
);
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),
],
);
},
}
}
-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]
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())),
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())