Introduce encode_to_writer for bitcoin io Write trait
What changed, and why it matters
This commit adds a new helper function that lets no-std code write encoded Bitcoin data to custom I/O writers. It is a straightforward feature addition mirroring an existing std-only helper. There is no indication of a security bug, fix, or vulnerability.
No security action required. Review as normal feature code.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces bitcoin_io::encode_to_writer, which wraps encoding::Encodable objects and streams them into any bitcoin_io::Write implementation. It adds a dependency from bitcoin-io to bitcoin-consensus-encoding and includes unit tests. The implementation is a thin, idiomatic wrapper around the encoder’s chunk iterator.
Changed components
bitcoin-io cratebitcoin-consensus-encoding crate (as new dependency)Inspect captured patch +46 / −0
diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock
index 7aafa642..24aa9556 100644
--- a/Cargo-minimal.lock
+++ b/Cargo-minimal.lock
@@ -112,6 +112,7 @@ checksum = "17e5b76b88667412087beea1882980ad843b660490bbf6cce0a6cfc999c5b989"
name = "bitcoin-io"
version = "0.2.0"
dependencies = [
+ "bitcoin-consensus-encoding",
"bitcoin-internals",
"bitcoin_hashes 0.17.0",
]
diff --git a/Cargo-recent.lock b/Cargo-recent.lock
index 2def4487..a21c057f 100644
--- a/Cargo-recent.lock
+++ b/Cargo-recent.lock
@@ -111,6 +111,7 @@ checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf"
name = "bitcoin-io"
version = "0.2.0"
dependencies = [
+ "bitcoin-consensus-encoding",
"bitcoin-internals",
"bitcoin_hashes 0.17.0",
]
diff --git a/io/Cargo.toml b/io/Cargo.toml
index d331125f..e29e6cd4 100644
--- a/io/Cargo.toml
+++ b/io/Cargo.toml
@@ -20,6 +20,7 @@ alloc = ["hashes?/alloc", "internals/alloc"]
[dependencies]
internals = { package = "bitcoin-internals", path = "../internals" }
+encoding = { package = "bitcoin-consensus-encoding", path = "../consensus_encoding", version = "1.0.0-rc.1", default-features = false }
hashes = { package = "bitcoin_hashes", path = "../hashes", default-features = false, optional = true }
diff --git a/io/src/lib.rs b/io/src/lib.rs
index 15ecdb00..3de7c99b 100644
--- a/io/src/lib.rs
+++ b/io/src/lib.rs
@@ -41,6 +41,8 @@ mod hash;
use alloc::vec::Vec;
use core::cmp;
+use encoding::Encoder;
+
#[cfg(feature = "std")]
pub use bridge::{FromStd, ToStd};
@@ -404,10 +406,27 @@ pub const fn from_std<T>(std_io: T) -> FromStd<T> { FromStd::new(std_io) }
#[inline]
pub fn from_std_mut<T>(std_io: &mut T) -> &mut FromStd<T> { FromStd::new_mut(std_io) }
+/// Encodes a consensus_encoding object to an I/O writer.
+pub fn encode_to_writer<T, W>(object: &T, mut writer: W) -> Result<()>
+where
+ T: encoding::Encodable + ?Sized,
+ W: Write,
+{
+ let mut encoder = object.encoder();
+ loop {
+ writer.write_all(encoder.current_chunk())?;
+ if !encoder.advance() {
+ break;
+ }
+ }
+ Ok(())
+}
+
#[cfg(test)]
mod tests {
#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::{string::ToString, vec};
+ use encoding::ArrayEncoder;
use super::*;
@@ -533,4 +552,28 @@ mod tests {
cursor.consume(5);
assert_eq!(cursor.position(), 15);
}
+
+ // Simple test type that implements Encodable.
+ struct TestData(u32);
+
+ impl encoding::Encodable for TestData {
+ type Encoder<'s>
+ = ArrayEncoder<4>
+ where
+ Self: 's;
+
+ fn encoder(&self) -> Self::Encoder<'_> {
+ ArrayEncoder::without_length_prefix(self.0.to_le_bytes())
+ }
+ }
+
+ #[test]
+ fn encode_io_writer() {
+ let data = TestData(0x1234_5678);
+
+ let mut buf = [0_u8; 4];
+ encode_to_writer(&data, buf.as_mut_slice()).unwrap();
+
+ assert_eq!(buf, [0x78, 0x56, 0x34, 0x12]);
+ }
}
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.