pub trait Decodable: Sized {
// Provided methods
fn consensus_decode_from_finite_reader<R: Read>(
r: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> { ... }
fn consensus_decode<R: Read>(
r: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> { ... }
fn consensus_decode_hex(
hex: &str,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> { ... }
fn consensus_decode_vec(
bytes: Vec<u8>,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> { ... }
}
Expand description
Data which can be encoded in a consensus-consistent way
Provided Methods§
Sourcefn consensus_decode_from_finite_reader<R: Read>(
r: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError>
fn consensus_decode_from_finite_reader<R: Read>( r: &mut R, modules: &ModuleDecoderRegistry, ) -> Result<Self, DecodeError>
Decode Self
from a size-limited reader.
Like consensus_decode
but relies on the reader being limited in the
amount of data it returns, e.g. by being wrapped in
std::io::Take
.
Failing to abide to this requirement might lead to memory exhaustion caused by malicious inputs.
Users should default to consensus_decode
, but when data to be decoded
is already in a byte vector of a limited size, calling this function
directly might be marginally faster (due to avoiding extra checks).
§Rules for trait implementations
- Simple types that that have a fixed size (own and member fields),
don’t have to overwrite this method, or be concern with it, should
only impl
consensus_decode
. - Types that deserialize based on decoded untrusted length should
implement
consensus_decode_from_finite_reader
only:- Default implementation of
consensus_decode
will forward toconsensus_decode_bytes_from_finite_reader
with the reader wrapped byTake
, protecting from readers that keep returning data. - Implementation must make sure to put a cap on things like
Vec::with_capacity
and other allocations to avoid oversized allocations, and rely on the reader being finite and running out of data, and collections reallocating on a legitimately oversized input data, instead of trying to enforce arbitrary length limits.
- Default implementation of
- Types that contain other types that might be require limited reader
(thus implementing
consensus_decode_from_finite_reader
), should also implement it applying same rules, and in addition make sure to callconsensus_decode_from_finite_reader
on all members, to avoid creating redundantTake
wrappers (Take<Take<...>>
). Failure to do so might result only in a tiny performance hit.
Sourcefn consensus_decode<R: Read>(
r: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError>
fn consensus_decode<R: Read>( r: &mut R, modules: &ModuleDecoderRegistry, ) -> Result<Self, DecodeError>
Decode an object with a well-defined format.
This is the method that should be implemented for a typical, fixed sized
type implementing this trait. Default implementation is wrapping the
reader in std::io::Take
to limit the input size to
MAX_DECODE_SIZE
, and forwards the call to
Self::consensus_decode_from_finite_reader
, which is convenient
for types that override Self::consensus_decode_from_finite_reader
instead.
Sourcefn consensus_decode_hex(
hex: &str,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError>
fn consensus_decode_hex( hex: &str, modules: &ModuleDecoderRegistry, ) -> Result<Self, DecodeError>
Decode an object from hex
fn consensus_decode_vec( bytes: Vec<u8>, modules: &ModuleDecoderRegistry, ) -> Result<Self, DecodeError>
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.