pub trait Decodable: Sized {
// Provided methods
fn consensus_decode_partial_from_finite_reader<R: Read>(
r: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> { ... }
fn consensus_decode_whole(
slice: &[u8],
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> { ... }
fn consensus_decode_partial<R: Read>(
r: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> { ... }
fn consensus_decode_hex(
hex: &str,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> { ... }
}
Expand description
Data which can be encoded in a consensus-consistent way
Provided Methods§
Sourcefn consensus_decode_partial_from_finite_reader<R: Read>(
r: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError>
fn consensus_decode_partial_from_finite_reader<R: Read>( r: &mut R, modules: &ModuleDecoderRegistry, ) -> Result<Self, DecodeError>
Decode Self
from a size-limited reader.
Like consensus_decode_partial
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_partial
, 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_partial
. - Types that deserialize based on decoded untrusted length should
implement
consensus_decode_partial_from_finite_reader
only:- Default implementation of
consensus_decode_partial
will forward toconsensus_decode_partial_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_partial_from_finite_reader
), should also implement it applying same rules, and in addition make sure to callconsensus_decode_partial_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.
fn consensus_decode_whole( slice: &[u8], modules: &ModuleDecoderRegistry, ) -> Result<Self, DecodeError>
Sourcefn consensus_decode_partial<R: Read>(
r: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError>
fn consensus_decode_partial<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_partial_from_finite_reader
, which is
convenient for types that override
Self::consensus_decode_partial_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
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.