mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 04:41:02 +00:00
Update to parity-scale-codec (#3232)
* WIP: update codec * WIP * compiling * WIP * rename parity-scale-codec to codec * WIP * fix * remove old comments * use published crates * fix expected error msg * bump version * fmt and fix * remove old comment * fix wrong decoding impl * implement encode like for structures * undo removal of old pending changes * trailingzeroinput * Apply suggestions from code review Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * update codec * fmt * version is 1.0.0 * show more error * fmt
This commit is contained in:
committed by
Bastian Köcher
parent
a0d442333f
commit
4ed67e03a4
@@ -22,7 +22,7 @@ use serde::Serialize;
|
||||
use rstd::prelude::*;
|
||||
|
||||
use crate::ConsensusEngineId;
|
||||
use crate::codec::{Decode, Encode, Input};
|
||||
use crate::codec::{Decode, Encode, Input, Error};
|
||||
|
||||
/// Generic header digest.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
@@ -221,27 +221,29 @@ impl<Hash: Encode> Encode for DigestItem<Hash> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Hash: Encode> codec::EncodeLike for DigestItem<Hash> {}
|
||||
|
||||
impl<Hash: Decode> Decode for DigestItem<Hash> {
|
||||
#[allow(deprecated)]
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
|
||||
let item_type: DigestItemType = Decode::decode(input)?;
|
||||
match item_type {
|
||||
DigestItemType::ChangesTrieRoot => Some(DigestItem::ChangesTrieRoot(
|
||||
DigestItemType::ChangesTrieRoot => Ok(DigestItem::ChangesTrieRoot(
|
||||
Decode::decode(input)?,
|
||||
)),
|
||||
DigestItemType::PreRuntime => {
|
||||
let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
|
||||
Some(DigestItem::PreRuntime(vals.0, vals.1))
|
||||
Ok(DigestItem::PreRuntime(vals.0, vals.1))
|
||||
},
|
||||
DigestItemType::Consensus => {
|
||||
let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
|
||||
Some(DigestItem::Consensus(vals.0, vals.1))
|
||||
Ok(DigestItem::Consensus(vals.0, vals.1))
|
||||
}
|
||||
DigestItemType::Seal => {
|
||||
let vals: (ConsensusEngineId, Vec<u8>) = Decode::decode(input)?;
|
||||
Some(DigestItem::Seal(vals.0, vals.1))
|
||||
Ok(DigestItem::Seal(vals.0, vals.1))
|
||||
},
|
||||
DigestItemType::Other => Some(DigestItem::Other(
|
||||
DigestItemType::Other => Ok(DigestItem::Other(
|
||||
Decode::decode(input)?,
|
||||
)),
|
||||
}
|
||||
@@ -305,7 +307,7 @@ impl<'a, Hash> DigestItemRef<'a, Hash> {
|
||||
/// Try to match this digest item to the given opaque item identifier; if it matches, then
|
||||
/// try to cast to the given datatype; if that works, return it.
|
||||
pub fn try_to<T: Decode>(&self, id: OpaqueDigestItemId) -> Option<T> {
|
||||
self.try_as_raw(id).and_then(|mut x| Decode::decode(&mut x))
|
||||
self.try_as_raw(id).and_then(|mut x| Decode::decode(&mut x).ok())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,6 +342,8 @@ impl<'a, Hash: Encode> Encode for DigestItemRef<'a, Hash> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Hash: Encode> codec::EncodeLike for DigestItemRef<'a, Hash> {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use crate::codec::{Decode, Encode, Input, Output};
|
||||
use crate::codec::{Decode, Encode, Input, Output, Error};
|
||||
|
||||
/// Era period
|
||||
pub type Period = u64;
|
||||
@@ -111,20 +111,22 @@ impl Encode for Era {
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::EncodeLike for Era {}
|
||||
|
||||
impl Decode for Era {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
|
||||
let first = input.read_byte()?;
|
||||
if first == 0 {
|
||||
Some(Era::Immortal)
|
||||
Ok(Era::Immortal)
|
||||
} else {
|
||||
let encoded = first as u64 + ((input.read_byte()? as u64) << 8);
|
||||
let period = 2 << (encoded % (1 << 4));
|
||||
let quantize_factor = (period >> 12).max(1);
|
||||
let phase = (encoded >> 4) * quantize_factor;
|
||||
if period >= 4 && phase < period {
|
||||
Some(Era::Mortal(period, phase))
|
||||
Ok(Era::Mortal(period, phase))
|
||||
} else {
|
||||
None
|
||||
Err("Invalid period and phase".into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
use serde::Serialize;
|
||||
#[cfg(feature = "std")]
|
||||
use log::debug;
|
||||
use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef};
|
||||
use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef, Error};
|
||||
use crate::traits::{
|
||||
self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, Hash as HashT, MaybeSerializeDebug,
|
||||
MaybeSerializeDebugButNotDeserialize
|
||||
@@ -60,8 +60,8 @@ impl<Number, Hash> Decode for Header<Number, Hash> where
|
||||
Hash: HashT,
|
||||
Hash::Output: Decode,
|
||||
{
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Header {
|
||||
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
|
||||
Ok(Header {
|
||||
parent_hash: Decode::decode(input)?,
|
||||
number: <<Number as HasCompact>::Type>::decode(input)?.into(),
|
||||
state_root: Decode::decode(input)?,
|
||||
@@ -85,6 +85,12 @@ impl<Number, Hash> Encode for Header<Number, Hash> where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Number, Hash> codec::EncodeLike for Header<Number, Hash> where
|
||||
Number: HasCompact + Copy + Into<u128>,
|
||||
Hash: HashT,
|
||||
Hash::Output: Encode,
|
||||
{}
|
||||
|
||||
impl<Number, Hash> traits::Header for Header<Number, Hash> where
|
||||
Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + MaybeDisplay + SimpleArithmetic + Codec + Copy + Into<u128>,
|
||||
Hash: HashT,
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::fmt;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use runtime_io::blake2_256;
|
||||
use crate::codec::{Decode, Encode, Input};
|
||||
use crate::codec::{Decode, Encode, Input, Error};
|
||||
use crate::traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic};
|
||||
use super::CheckedExtrinsic;
|
||||
|
||||
@@ -131,7 +131,7 @@ where
|
||||
Call: Decode,
|
||||
Extra: SignedExtension,
|
||||
{
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
|
||||
// This is a little more complicated than usual since the binary format must be compatible
|
||||
// with substrate's generic `Vec<u8>` type. Basically this just means accepting that there
|
||||
// will be a prefix of vector length (we don't need
|
||||
@@ -143,10 +143,10 @@ where
|
||||
let is_signed = version & 0b1000_0000 != 0;
|
||||
let version = version & 0b0111_1111;
|
||||
if version != TRANSACTION_VERSION {
|
||||
return None
|
||||
return Err("Invalid transaction version".into());
|
||||
}
|
||||
|
||||
Some(UncheckedExtrinsic {
|
||||
Ok(UncheckedExtrinsic {
|
||||
signature: if is_signed { Some(Decode::decode(input)?) } else { None },
|
||||
function: Decode::decode(input)?,
|
||||
})
|
||||
@@ -245,7 +245,7 @@ mod tests {
|
||||
fn unsigned_codec_should_work() {
|
||||
let ux = Ex::new_unsigned(vec![0u8; 0]);
|
||||
let encoded = ux.encode();
|
||||
assert_eq!(Ex::decode(&mut &encoded[..]), Some(ux));
|
||||
assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -257,7 +257,7 @@ mod tests {
|
||||
TestExtra
|
||||
);
|
||||
let encoded = ux.encode();
|
||||
assert_eq!(Ex::decode(&mut &encoded[..]), Some(ux));
|
||||
assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -270,7 +270,7 @@ mod tests {
|
||||
TestExtra
|
||||
);
|
||||
let encoded = ux.encode();
|
||||
assert_eq!(Ex::decode(&mut &encoded[..]), Some(ux));
|
||||
assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -694,6 +694,8 @@ impl codec::Encode for ApplyOutcome {
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::EncodeLike for ApplyOutcome {}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
|
||||
#[repr(u8)]
|
||||
@@ -717,6 +719,8 @@ impl codec::Encode for ApplyError {
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::EncodeLike for ApplyError {}
|
||||
|
||||
/// Result from attempt to apply an extrinsic.
|
||||
pub type ApplyResult = Result<ApplyOutcome, ApplyError>;
|
||||
|
||||
|
||||
@@ -70,7 +70,9 @@ impl OpaqueKeys for UintAuthorityId {
|
||||
)
|
||||
}
|
||||
}
|
||||
fn get<T: Decode>(&self, _: KeyTypeId) -> Option<T> { self.0.using_encoded(|mut x| T::decode(&mut x)) }
|
||||
fn get<T: Decode>(&self, _: KeyTypeId) -> Option<T> {
|
||||
self.0.using_encoded(|mut x| T::decode(&mut x)).ok()
|
||||
}
|
||||
}
|
||||
|
||||
/// Digest item
|
||||
@@ -136,7 +138,8 @@ impl traits::Header for Header {
|
||||
impl<'a> Deserialize<'a> for Header {
|
||||
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
|
||||
let r = <Vec<u8>>::deserialize(de)?;
|
||||
Decode::decode(&mut &r[..]).ok_or(DeError::custom("Invalid value passed into decode"))
|
||||
Decode::decode(&mut &r[..])
|
||||
.map_err(|e| DeError::custom(format!("Invalid value passed into decode: {}", e.what())))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +207,8 @@ impl<Xt: 'static + Codec + Sized + Send + Sync + Serialize + Clone + Eq + Debug
|
||||
impl<'a, Xt> Deserialize<'a> for Block<Xt> where Block<Xt>: Decode {
|
||||
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
|
||||
let r = <Vec<u8>>::deserialize(de)?;
|
||||
Decode::decode(&mut &r[..]).ok_or(DeError::custom("Invalid value passed into decode"))
|
||||
Decode::decode(&mut &r[..])
|
||||
.map_err(|e| DeError::custom(format!("Invalid value passed into decode: {}", e.what())))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1029,21 +1029,30 @@ pub trait OpaqueKeys: Clone {
|
||||
/// Get the raw bytes of key with key-type ID `i`.
|
||||
fn get_raw(&self, i: super::KeyTypeId) -> &[u8];
|
||||
/// Get the decoded key with index `i`.
|
||||
fn get<T: Decode>(&self, i: super::KeyTypeId) -> Option<T> { T::decode(&mut self.get_raw(i)) }
|
||||
fn get<T: Decode>(&self, i: super::KeyTypeId) -> Option<T> {
|
||||
T::decode(&mut self.get_raw(i)).ok()
|
||||
}
|
||||
/// Verify a proof of ownership for the keys.
|
||||
fn ownership_proof_is_valid(&self, _proof: &[u8]) -> bool { true }
|
||||
}
|
||||
|
||||
/// Input that adds infinite number of zero after wrapped input.
|
||||
struct TrailingZeroInput<'a>(&'a [u8]);
|
||||
|
||||
impl<'a> codec::Input for TrailingZeroInput<'a> {
|
||||
fn read(&mut self, into: &mut [u8]) -> usize {
|
||||
let len = into.len().min(self.0.len());
|
||||
into[..len].copy_from_slice(&self.0[..len]);
|
||||
for i in &mut into[len..] {
|
||||
fn remaining_len(&mut self) -> Result<Option<usize>, codec::Error> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn read(&mut self, into: &mut [u8]) -> Result<(), codec::Error> {
|
||||
let len_from_inner = into.len().min(self.0.len());
|
||||
into[..len_from_inner].copy_from_slice(&self.0[..len_from_inner]);
|
||||
for i in &mut into[len_from_inner..] {
|
||||
*i = 0;
|
||||
}
|
||||
self.0 = &self.0[len..];
|
||||
into.len()
|
||||
self.0 = &self.0[len_from_inner..];
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1091,7 +1100,7 @@ impl<T: Encode + Decode + Default, Id: Encode + Decode + TypeId> AccountIdConver
|
||||
x.using_encoded(|d| {
|
||||
if &d[0..4] != Id::TYPE_ID { return None }
|
||||
let mut cursor = &d[4..];
|
||||
let result = Decode::decode(&mut cursor)?;
|
||||
let result = Decode::decode(&mut cursor).ok()?;
|
||||
if cursor.iter().all(|x| *x == 0) {
|
||||
Some(result)
|
||||
} else {
|
||||
@@ -1104,7 +1113,7 @@ impl<T: Encode + Decode + Default, Id: Encode + Decode + TypeId> AccountIdConver
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::AccountIdConversion;
|
||||
use crate::codec::{Encode, Decode};
|
||||
use crate::codec::{Encode, Decode, Input};
|
||||
|
||||
#[derive(Encode, Decode, Default, PartialEq, Debug)]
|
||||
struct U32Value(u32);
|
||||
@@ -1153,6 +1162,22 @@ mod tests {
|
||||
let r = U16Value::try_from_account(&0x0100_c0da_f00dcafe_u64);
|
||||
assert!(r.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trailing_zero_should_work() {
|
||||
let mut t = super::TrailingZeroInput(&[1, 2, 3]);
|
||||
assert_eq!(t.remaining_len(), Ok(None));
|
||||
let mut buffer = [0u8; 2];
|
||||
assert_eq!(t.read(&mut buffer), Ok(()));
|
||||
assert_eq!(t.remaining_len(), Ok(None));
|
||||
assert_eq!(buffer, [1, 2]);
|
||||
assert_eq!(t.read(&mut buffer), Ok(()));
|
||||
assert_eq!(t.remaining_len(), Ok(None));
|
||||
assert_eq!(buffer, [3, 0]);
|
||||
assert_eq!(t.read(&mut buffer), Ok(()));
|
||||
assert_eq!(t.remaining_len(), Ok(None));
|
||||
assert_eq!(buffer, [0, 0]);
|
||||
}
|
||||
}
|
||||
|
||||
/// Calls a given macro a number of times with a set of fixed params and an incrementing numeral.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Transaction validity interface.
|
||||
|
||||
use rstd::prelude::*;
|
||||
use crate::codec::{Encode, Decode};
|
||||
use crate::codec::{Encode, Decode, Error};
|
||||
use crate::traits::DispatchError;
|
||||
|
||||
/// Priority for a transaction. Additive. Higher is better.
|
||||
@@ -113,9 +113,9 @@ impl ValidTransaction {
|
||||
}
|
||||
|
||||
impl Decode for TransactionValidity {
|
||||
fn decode<I: crate::codec::Input>(value: &mut I) -> Option<Self> {
|
||||
fn decode<I: crate::codec::Input>(value: &mut I) -> Result<Self, Error> {
|
||||
match value.read_byte()? {
|
||||
0 => Some(TransactionValidity::Invalid(i8::decode(value)?)),
|
||||
0 => Ok(TransactionValidity::Invalid(i8::decode(value)?)),
|
||||
1 => {
|
||||
let priority = TransactionPriority::decode(value)?;
|
||||
let requires = Vec::decode(value)?;
|
||||
@@ -123,12 +123,12 @@ impl Decode for TransactionValidity {
|
||||
let longevity = TransactionLongevity::decode(value)?;
|
||||
let propagate = bool::decode(value).unwrap_or(true);
|
||||
|
||||
Some(TransactionValidity::Valid(ValidTransaction {
|
||||
Ok(TransactionValidity::Valid(ValidTransaction {
|
||||
priority, requires, provides, longevity, propagate,
|
||||
}))
|
||||
},
|
||||
2 => Some(TransactionValidity::Unknown(i8::decode(value)?)),
|
||||
_ => None,
|
||||
2 => Ok(TransactionValidity::Unknown(i8::decode(value)?)),
|
||||
_ => Err("Invalid transaction validity variant".into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,7 @@ mod tests {
|
||||
1, 5, 0, 0, 0, 0, 0, 0, 0, 4, 16, 1, 2, 3, 4, 4, 12, 4, 5, 6, 42, 0, 0, 0, 0, 0, 0, 0
|
||||
];
|
||||
|
||||
assert_eq!(TransactionValidity::decode(&mut &*old_encoding), Some(TransactionValidity::Valid(ValidTransaction {
|
||||
assert_eq!(TransactionValidity::decode(&mut &*old_encoding), Ok(TransactionValidity::Valid(ValidTransaction {
|
||||
priority: 5,
|
||||
requires: vec![vec![1, 2, 3, 4]],
|
||||
provides: vec![vec![4, 5, 6]],
|
||||
@@ -169,6 +169,6 @@ mod tests {
|
||||
);
|
||||
|
||||
// decode back
|
||||
assert_eq!(TransactionValidity::decode(&mut &*encoded), Some(v));
|
||||
assert_eq!(TransactionValidity::decode(&mut &*encoded), Ok(v));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user