-
Notifications
You must be signed in to change notification settings - Fork 649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Push-based consensus decoding #1251
Comments
So this one is done, when Should it be |
Yes, 0 means done because it's definitely less than |
I'm definitely interested in improving I also can't tell, in your example code, where any actual decoding is happening :) |
|
For decoding example I've added an incomplete macro that implements fixed-size decoding, so hopefully it's more understandable. |
Very interesting, thanks for writing all this up! It's starting to come together in my head. It would be really nice to have an allocation-free API, but that does seem like a difficult goal. |
I'm thinking maybe we should do this for encoding too. trait IntoEncoder<'a>: IsRef<'a> where <Self::Encoder as Iterator>::Item: AsRef<[u8]> {
type Encoder: Iterator;
fn into_consensus_encoder(self) -> Self::Encoder;
fn reserve_suggestion(self) -> usize {
0
}
// other methods related to computation of reserve suggestion
}
mod sealed {
pub trait IsRef<'a> {}
impl<'a, T> IsRef<'a> for &'a T {}
}
// Workaround lack of GAT
trait Encodable: for<'a> &'a Self: IntoEncoder<'a> {
fn consensus_encoder<'a>(&'a self) -> <Self as IntoEncoder<'a>::Encoder> {
self.into_consensus_encoder()
}
#[cfg(feature = "bitcoin_hashes")]
fn hash_consensus_bytes<H: bitcoin_hashes::Hash>(&self) -> H {
let mut engine = H::Engine::default();
for chunk in self.consensus_encoder() {
engine.input(chunk.as_ref());
}
H::from_engine(engine)
}
#[cfg(feature = "std")]
fn consensus_encode<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<usize> {
let mut bytes_written = 0;
for chunk in self.consensus_encoder() {
let chunk = chunk.as_ref();
writer.writ_all(chunk)?;
bytes_written += chunk.len();
}
Ok(bytes_written)
}
#[cfg(feature = "alloc")]
fn collect_consensus_bytes(&self) -> Vec<u8> {
let mut vec = Vec::with_capacity(self.reserve_suggestion());
for chunk in self.consensus_encoder() {
vec.extend_from_slice(chunk.as_ref());
}
vec
}
} Advantages:
Disadvantages:
|
I just realized push-based consensus decoding could solve a bunch of issues:
async
deserializationWrite
traitDesign draft (owned decoding only):
I also envision
MinLenDecodable
andExactLenDecodable
traits to simplify decoding for some types where they'd only have to implement conversions from byte arrays.The text was updated successfully, but these errors were encountered: