Finish implementing Darrens migrate-ssz-little-endian and add wrapper to check for ssz underflow
This commit is contained in:
parent
10efc9a934
commit
9cef6a5814
@ -1,6 +1,6 @@
|
|||||||
use super::BLOCKS_DB_COLUMN as DB_COLUMN;
|
use super::BLOCKS_DB_COLUMN as DB_COLUMN;
|
||||||
use super::{ClientDB, DBError};
|
use super::{ClientDB, DBError};
|
||||||
use ssz::Decodable;
|
use ssz::decode;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use types::{readers::BeaconBlockReader, BeaconBlock, Hash256, Slot};
|
use types::{readers::BeaconBlockReader, BeaconBlock, Hash256, Slot};
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ impl<T: ClientDB> BeaconBlockStore<T> {
|
|||||||
match self.get(&hash)? {
|
match self.get(&hash)? {
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(ssz) => {
|
Some(ssz) => {
|
||||||
let (block, _) = BeaconBlock::ssz_decode(&ssz, 0).map_err(|_| DBError {
|
let block = decode::<BeaconBlock>(&ssz).map_err(|_| DBError {
|
||||||
message: "Bad BeaconBlock SSZ.".to_string(),
|
message: "Bad BeaconBlock SSZ.".to_string(),
|
||||||
})?;
|
})?;
|
||||||
Ok(Some(block))
|
Ok(Some(block))
|
||||||
@ -47,7 +47,7 @@ impl<T: ClientDB> BeaconBlockStore<T> {
|
|||||||
match self.get(&hash)? {
|
match self.get(&hash)? {
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(ssz) => {
|
Some(ssz) => {
|
||||||
let (block, _) = BeaconBlock::ssz_decode(&ssz, 0).map_err(|_| DBError {
|
let block = decode::<BeaconBlock>(&ssz).map_err(|_| DBError {
|
||||||
message: "Bad BeaconBlock SSZ.".to_string(),
|
message: "Bad BeaconBlock SSZ.".to_string(),
|
||||||
})?;
|
})?;
|
||||||
Ok(Some(block))
|
Ok(Some(block))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::STATES_DB_COLUMN as DB_COLUMN;
|
use super::STATES_DB_COLUMN as DB_COLUMN;
|
||||||
use super::{ClientDB, DBError};
|
use super::{ClientDB, DBError};
|
||||||
use ssz::Decodable;
|
use ssz::decode;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use types::{readers::BeaconStateReader, BeaconState, Hash256};
|
use types::{readers::BeaconStateReader, BeaconState, Hash256};
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ impl<T: ClientDB> BeaconStateStore<T> {
|
|||||||
match self.get(&hash)? {
|
match self.get(&hash)? {
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(ssz) => {
|
Some(ssz) => {
|
||||||
let (state, _) = BeaconState::ssz_decode(&ssz, 0).map_err(|_| DBError {
|
let state = decode::<BeaconState>(&ssz).map_err(|_| DBError {
|
||||||
message: "Bad State SSZ.".to_string(),
|
message: "Bad State SSZ.".to_string(),
|
||||||
})?;
|
})?;
|
||||||
Ok(Some(state))
|
Ok(Some(state))
|
||||||
@ -40,7 +40,7 @@ impl<T: ClientDB> BeaconStateStore<T> {
|
|||||||
match self.get(&hash)? {
|
match self.get(&hash)? {
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(ssz) => {
|
Some(ssz) => {
|
||||||
let (state, _) = BeaconState::ssz_decode(&ssz, 0).map_err(|_| DBError {
|
let state = decode::<BeaconState>(&ssz).map_err(|_| DBError {
|
||||||
message: "Bad State SSZ.".to_string(),
|
message: "Bad State SSZ.".to_string(),
|
||||||
})?;
|
})?;
|
||||||
Ok(Some(state))
|
Ok(Some(state))
|
||||||
|
@ -4,7 +4,7 @@ use self::bytes::{BufMut, BytesMut};
|
|||||||
use super::VALIDATOR_DB_COLUMN as DB_COLUMN;
|
use super::VALIDATOR_DB_COLUMN as DB_COLUMN;
|
||||||
use super::{ClientDB, DBError};
|
use super::{ClientDB, DBError};
|
||||||
use bls::PublicKey;
|
use bls::PublicKey;
|
||||||
use ssz::{ssz_encode, Decodable};
|
use ssz::{decode, ssz_encode};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -69,8 +69,8 @@ impl<T: ClientDB> ValidatorStore<T> {
|
|||||||
let val = self.db.get(DB_COLUMN, &key[..])?;
|
let val = self.db.get(DB_COLUMN, &key[..])?;
|
||||||
match val {
|
match val {
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(val) => match PublicKey::ssz_decode(&val, 0) {
|
Some(val) => match decode::<PublicKey>(&val) {
|
||||||
Ok((key, _)) => Ok(Some(key)),
|
Ok(key) => Ok(Some(key)),
|
||||||
Err(_) => Err(ValidatorStoreError::DecodeError),
|
Err(_) => Err(ValidatorStoreError::DecodeError),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use protos::services::{
|
|||||||
};
|
};
|
||||||
use protos::services_grpc::ValidatorService;
|
use protos::services_grpc::ValidatorService;
|
||||||
use slog::{debug, Logger};
|
use slog::{debug, Logger};
|
||||||
use ssz::Decodable;
|
use ssz::decode;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ValidatorServiceInstance {
|
pub struct ValidatorServiceInstance {
|
||||||
@ -20,7 +20,7 @@ impl ValidatorService for ValidatorServiceInstance {
|
|||||||
req: PublicKeyRequest,
|
req: PublicKeyRequest,
|
||||||
sink: UnarySink<IndexResponse>,
|
sink: UnarySink<IndexResponse>,
|
||||||
) {
|
) {
|
||||||
if let Ok((public_key, _)) = PublicKey::ssz_decode(req.get_public_key(), 0) {
|
if let Ok(public_key) = decode::<PublicKey>(req.get_public_key()) {
|
||||||
debug!(self.log, "RPC request"; "endpoint" => "ValidatorIndex", "public_key" => public_key.concatenated_hex_id());
|
debug!(self.log, "RPC request"; "endpoint" => "ValidatorIndex", "public_key" => public_key.concatenated_hex_id());
|
||||||
|
|
||||||
let mut resp = IndexResponse::new();
|
let mut resp = IndexResponse::new();
|
||||||
|
@ -5,13 +5,13 @@ macro_rules! ssz_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
pub fn test_ssz_round_trip() {
|
pub fn test_ssz_round_trip() {
|
||||||
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
|
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
|
||||||
use ssz::{ssz_encode, Decodable};
|
use ssz::{decode, ssz_encode};
|
||||||
|
|
||||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
let original = $type::random_for_test(&mut rng);
|
let original = $type::random_for_test(&mut rng);
|
||||||
|
|
||||||
let bytes = ssz_encode(&original);
|
let bytes = ssz_encode(&original);
|
||||||
let (decoded, _) = $type::ssz_decode(&bytes, 0).unwrap();
|
let decoded: $type = decode(&bytes).unwrap();
|
||||||
|
|
||||||
assert_eq!(original, decoded);
|
assert_eq!(original, decoded);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ impl TreeHash for AggregateSignature {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::super::{Keypair, Signature};
|
use super::super::{Keypair, Signature};
|
||||||
use super::*;
|
use super::*;
|
||||||
use ssz::ssz_encode;
|
use ssz::{decode, ssz_encode};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_ssz_round_trip() {
|
pub fn test_ssz_round_trip() {
|
||||||
@ -106,7 +106,7 @@ mod tests {
|
|||||||
original.add(&Signature::new(&[42, 42], 0, &keypair.sk));
|
original.add(&Signature::new(&[42, 42], 0, &keypair.sk));
|
||||||
|
|
||||||
let bytes = ssz_encode(&original);
|
let bytes = ssz_encode(&original);
|
||||||
let (decoded, _) = AggregateSignature::ssz_decode(&bytes, 0).unwrap();
|
let decoded = decode::<AggregateSignature>(&bytes).unwrap();
|
||||||
|
|
||||||
assert_eq!(original, decoded);
|
assert_eq!(original, decoded);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ use hex::encode as hex_encode;
|
|||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use ssz::{
|
use ssz::{
|
||||||
decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash,
|
decode, decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream,
|
||||||
|
TreeHash,
|
||||||
};
|
};
|
||||||
use std::default;
|
use std::default;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
@ -91,7 +92,7 @@ impl<'de> Deserialize<'de> for PublicKey {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||||
let (pubkey, _) = <_>::ssz_decode(&bytes[..], 0)
|
let pubkey = decode::<PublicKey>(&bytes[..])
|
||||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||||
Ok(pubkey)
|
Ok(pubkey)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,9 @@ use bls_aggregates::{DecodeError as BlsDecodeError, SecretKey as RawSecretKey};
|
|||||||
use hex::encode as hex_encode;
|
use hex::encode as hex_encode;
|
||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use ssz::{decode_ssz_list, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
use ssz::{
|
||||||
|
decode, decode_ssz_list, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash,
|
||||||
|
};
|
||||||
|
|
||||||
/// A single BLS signature.
|
/// A single BLS signature.
|
||||||
///
|
///
|
||||||
@ -59,9 +61,9 @@ impl<'de> Deserialize<'de> for SecretKey {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||||
let (pubkey, _) = <_>::ssz_decode(&bytes[..], 0)
|
let secret_key = decode::<SecretKey>(&bytes[..])
|
||||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||||
Ok(pubkey)
|
Ok(secret_key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ use hex::encode as hex_encode;
|
|||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use ssz::{
|
use ssz::{
|
||||||
decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash,
|
decode, decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream,
|
||||||
|
TreeHash,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A single BLS signature.
|
/// A single BLS signature.
|
||||||
@ -99,9 +100,9 @@ impl<'de> Deserialize<'de> for Signature {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||||
let (pubkey, _) = <_>::ssz_decode(&bytes[..], 0)
|
let signature = decode::<Signature>(&bytes[..])
|
||||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||||
Ok(pubkey)
|
Ok(signature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +119,7 @@ mod tests {
|
|||||||
let original = Signature::new(&[42, 42], 0, &keypair.sk);
|
let original = Signature::new(&[42, 42], 0, &keypair.sk);
|
||||||
|
|
||||||
let bytes = ssz_encode(&original);
|
let bytes = ssz_encode(&original);
|
||||||
let (decoded, _) = Signature::ssz_decode(&bytes, 0).unwrap();
|
let decoded = decode::<Signature>(&bytes).unwrap();
|
||||||
|
|
||||||
assert_eq!(original, decoded);
|
assert_eq!(original, decoded);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ extern crate ssz;
|
|||||||
use bit_vec::BitVec;
|
use bit_vec::BitVec;
|
||||||
|
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
|
use ssz::{Decodable, Encodable};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::default;
|
use std::default;
|
||||||
|
|
||||||
@ -141,14 +142,14 @@ impl std::ops::BitAnd for BooleanBitfield {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ssz::Encodable for BooleanBitfield {
|
impl Encodable for BooleanBitfield {
|
||||||
// ssz_append encodes Self according to the `ssz` spec.
|
// ssz_append encodes Self according to the `ssz` spec.
|
||||||
fn ssz_append(&self, s: &mut ssz::SszStream) {
|
fn ssz_append(&self, s: &mut ssz::SszStream) {
|
||||||
s.append_vec(&self.to_bytes())
|
s.append_vec(&self.to_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ssz::Decodable for BooleanBitfield {
|
impl Decodable for BooleanBitfield {
|
||||||
fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), ssz::DecodeError> {
|
fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), ssz::DecodeError> {
|
||||||
let len = ssz::decode::decode_length(bytes, index, ssz::LENGTH_BYTES)?;
|
let len = ssz::decode::decode_length(bytes, index, ssz::LENGTH_BYTES)?;
|
||||||
if (ssz::LENGTH_BYTES + len) > bytes.len() {
|
if (ssz::LENGTH_BYTES + len) > bytes.len() {
|
||||||
@ -195,7 +196,7 @@ impl ssz::TreeHash for BooleanBitfield {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use ssz::{ssz_encode, Decodable, SszStream};
|
use ssz::{decode, ssz_encode, SszStream};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_bitfield() {
|
fn test_new_bitfield() {
|
||||||
@ -385,12 +386,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_ssz_decode() {
|
fn test_ssz_decode() {
|
||||||
let encoded = vec![2, 0, 0, 0, 225, 192];
|
let encoded = vec![2, 0, 0, 0, 225, 192];
|
||||||
let (field, _): (BooleanBitfield, usize) = ssz::decode_ssz(&encoded, 0).unwrap();
|
let field = decode::<BooleanBitfield>(&encoded).unwrap();
|
||||||
let expected = create_test_bitfield();
|
let expected = create_test_bitfield();
|
||||||
assert_eq!(field, expected);
|
assert_eq!(field, expected);
|
||||||
|
|
||||||
let encoded = vec![3, 0, 0, 0, 255, 255, 3];
|
let encoded = vec![3, 0, 0, 0, 255, 255, 3];
|
||||||
let (field, _): (BooleanBitfield, usize) = ssz::decode_ssz(&encoded, 0).unwrap();
|
let field = decode::<BooleanBitfield>(&encoded).unwrap();
|
||||||
let expected = BooleanBitfield::from_bytes(&[255, 255, 3]);
|
let expected = BooleanBitfield::from_bytes(&[255, 255, 3]);
|
||||||
assert_eq!(field, expected);
|
assert_eq!(field, expected);
|
||||||
}
|
}
|
||||||
@ -399,7 +400,7 @@ mod tests {
|
|||||||
fn test_ssz_round_trip() {
|
fn test_ssz_round_trip() {
|
||||||
let original = BooleanBitfield::from_bytes(&vec![18; 12][..]);
|
let original = BooleanBitfield::from_bytes(&vec![18; 12][..]);
|
||||||
let ssz = ssz_encode(&original);
|
let ssz = ssz_encode(&original);
|
||||||
let (decoded, _) = BooleanBitfield::ssz_decode(&ssz, 0).unwrap();
|
let decoded = decode::<BooleanBitfield>(&ssz).unwrap();
|
||||||
assert_eq!(original, decoded);
|
assert_eq!(original, decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,16 +13,22 @@ pub trait Decodable: Sized {
|
|||||||
|
|
||||||
/// Decode the given bytes for the given type
|
/// Decode the given bytes for the given type
|
||||||
///
|
///
|
||||||
/// The single ssz encoded value will be decoded as the given type at the
|
/// The single ssz encoded value/container/list will be decoded as the given type,
|
||||||
/// given index.
|
/// by recursively calling `ssz_decode`.
|
||||||
pub fn decode_ssz<T>(ssz_bytes: &[u8], index: usize) -> Result<(T, usize), DecodeError>
|
pub fn decode<T>(ssz_bytes: &[u8]) -> Result<(T), DecodeError>
|
||||||
where
|
where
|
||||||
T: Decodable,
|
T: Decodable,
|
||||||
{
|
{
|
||||||
if index >= ssz_bytes.len() {
|
let (decoded, i): (T, usize) = match T::ssz_decode(ssz_bytes, 0) {
|
||||||
return Err(DecodeError::TooShort);
|
Err(e) => return Err(e),
|
||||||
|
Ok(v) => v,
|
||||||
|
};
|
||||||
|
|
||||||
|
if i < ssz_bytes.len() {
|
||||||
|
return Err(DecodeError::TooLong);
|
||||||
}
|
}
|
||||||
T::ssz_decode(ssz_bytes, index)
|
|
||||||
|
Ok(decoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode a vector (list) of encoded bytes.
|
/// Decode a vector (list) of encoded bytes.
|
||||||
@ -82,7 +88,7 @@ pub fn decode_length(
|
|||||||
.take(index + length_bytes)
|
.take(index + length_bytes)
|
||||||
.skip(index)
|
.skip(index)
|
||||||
{
|
{
|
||||||
let offset = (length_bytes - (length_bytes - (i - index))) * 8;
|
let offset = (i - index) * 8;
|
||||||
len |= (*byte as usize) << offset;
|
len |= (*byte as usize) << offset;
|
||||||
}
|
}
|
||||||
Ok(len)
|
Ok(len)
|
||||||
|
@ -76,7 +76,7 @@ pub fn encode_length(len: usize, length_bytes: usize) -> Vec<u8> {
|
|||||||
assert!((len as usize) < 2usize.pow(length_bytes as u32 * 8));
|
assert!((len as usize) < 2usize.pow(length_bytes as u32 * 8));
|
||||||
let mut header: Vec<u8> = vec![0; length_bytes];
|
let mut header: Vec<u8> = vec![0; length_bytes];
|
||||||
for (i, header_byte) in header.iter_mut().enumerate() {
|
for (i, header_byte) in header.iter_mut().enumerate() {
|
||||||
let offset = (length_bytes - (length_bytes - i)) * 8;
|
let offset = i * 8;
|
||||||
*header_byte = ((len >> offset) & 0xff) as u8;
|
*header_byte = ((len >> offset) & 0xff) as u8;
|
||||||
}
|
}
|
||||||
header
|
header
|
||||||
|
@ -12,7 +12,7 @@ macro_rules! impl_decodable_for_uint {
|
|||||||
let end_bytes = index + max_bytes;
|
let end_bytes = index + max_bytes;
|
||||||
let mut result: $type = 0;
|
let mut result: $type = 0;
|
||||||
for (i, byte) in bytes.iter().enumerate().take(end_bytes).skip(index) {
|
for (i, byte) in bytes.iter().enumerate().take(end_bytes).skip(index) {
|
||||||
let offset = (end_bytes - (end_bytes - (i - index))) * 8;
|
let offset = (i - index) * 8;
|
||||||
result |= ($type::from(*byte)) << offset;
|
result |= ($type::from(*byte)) << offset;
|
||||||
}
|
}
|
||||||
Ok((result, end_bytes))
|
Ok((result, end_bytes))
|
||||||
@ -46,7 +46,7 @@ impl Decodable for bool {
|
|||||||
} else {
|
} else {
|
||||||
let result = match bytes[index] {
|
let result = match bytes[index] {
|
||||||
0b0000_0000 => false,
|
0b0000_0000 => false,
|
||||||
0b1000_0000 => true,
|
0b0000_0001 => true,
|
||||||
_ => return Err(DecodeError::Invalid),
|
_ => return Err(DecodeError::Invalid),
|
||||||
};
|
};
|
||||||
Ok((result, index + 1))
|
Ok((result, index + 1))
|
||||||
@ -85,7 +85,7 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::super::{decode_ssz, DecodeError};
|
use super::super::{decode, DecodeError};
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -119,131 +119,161 @@ mod tests {
|
|||||||
fn test_ssz_decode_u16() {
|
fn test_ssz_decode_u16() {
|
||||||
let ssz = vec![0, 0];
|
let ssz = vec![0, 0];
|
||||||
|
|
||||||
let (result, index): (u16, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u16, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
assert_eq!(index, 2);
|
assert_eq!(index, 2);
|
||||||
|
|
||||||
let ssz = vec![16, 0];
|
let ssz = vec![16, 0];
|
||||||
let (result, index): (u16, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u16, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(result, 16);
|
assert_eq!(result, 16);
|
||||||
assert_eq!(index, 2);
|
assert_eq!(index, 2);
|
||||||
|
|
||||||
let ssz = vec![0, 1];
|
let ssz = vec![0, 1];
|
||||||
let (result, index): (u16, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u16, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(result, 256);
|
assert_eq!(result, 256);
|
||||||
assert_eq!(index, 2);
|
assert_eq!(index, 2);
|
||||||
|
|
||||||
let ssz = vec![255, 255];
|
let ssz = vec![255, 255];
|
||||||
let (result, index): (u16, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u16, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 2);
|
assert_eq!(index, 2);
|
||||||
assert_eq!(result, 65535);
|
assert_eq!(result, 65535);
|
||||||
|
|
||||||
let ssz = vec![1];
|
let ssz = vec![1];
|
||||||
let result: Result<(u16, usize), DecodeError> = decode_ssz(&ssz, 0);
|
let result: Result<(u16, usize), DecodeError> = <_>::ssz_decode(&ssz, 0);
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert_eq!(result, Err(DecodeError::TooShort));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ssz_decode_u32() {
|
fn test_ssz_decode_u32() {
|
||||||
let ssz = vec![0, 0, 0, 0];
|
let ssz = vec![0, 0, 0, 0];
|
||||||
let (result, index): (u32, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u32, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
assert_eq!(index, 4);
|
assert_eq!(index, 4);
|
||||||
|
|
||||||
let ssz = vec![0, 1, 0, 0];
|
let ssz = vec![0, 1, 0, 0];
|
||||||
let (result, index): (u32, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u32, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 4);
|
assert_eq!(index, 4);
|
||||||
assert_eq!(result, 256);
|
assert_eq!(result, 256);
|
||||||
|
|
||||||
let ssz = vec![255, 255, 255, 0, 1, 0, 0];
|
let ssz = vec![255, 255, 255, 0, 1, 0, 0];
|
||||||
let (result, index): (u32, usize) = decode_ssz(&ssz, 3).unwrap();
|
let (result, index): (u32, usize) = <_>::ssz_decode(&ssz, 3).unwrap();
|
||||||
assert_eq!(index, 7);
|
assert_eq!(index, 7);
|
||||||
assert_eq!(result, 256);
|
assert_eq!(result, 256);
|
||||||
|
|
||||||
let ssz = vec![0, 1, 200, 0];
|
let ssz = vec![0, 1, 200, 0];
|
||||||
let (result, index): (u32, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u32, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 4);
|
assert_eq!(index, 4);
|
||||||
assert_eq!(result, 13107456);
|
assert_eq!(result, 13107456);
|
||||||
|
|
||||||
let ssz = vec![255, 255, 255, 255];
|
let ssz = vec![255, 255, 255, 255];
|
||||||
let (result, index): (u32, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u32, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 4);
|
assert_eq!(index, 4);
|
||||||
assert_eq!(result, 4294967295);
|
assert_eq!(result, 4294967295);
|
||||||
|
|
||||||
let ssz = vec![1, 0, 0];
|
let ssz = vec![1, 0, 0];
|
||||||
let result: Result<(u32, usize), DecodeError> = decode_ssz(&ssz, 0);
|
let result: Result<(u32, usize), DecodeError> = <_>::ssz_decode(&ssz, 0);
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert_eq!(result, Err(DecodeError::TooShort));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ssz_decode_u64() {
|
fn test_ssz_decode_u64() {
|
||||||
let ssz = vec![0, 0, 0, 0, 0, 0, 0, 0];
|
let ssz = vec![0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
let (result, index): (u64, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u64, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 8);
|
assert_eq!(index, 8);
|
||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
|
|
||||||
let ssz = vec![255, 255, 255, 255, 255, 255, 255, 255];
|
let ssz = vec![255, 255, 255, 255, 255, 255, 255, 255];
|
||||||
let (result, index): (u64, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (u64, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 8);
|
assert_eq!(index, 8);
|
||||||
assert_eq!(result, 18446744073709551615);
|
assert_eq!(result, 18446744073709551615);
|
||||||
|
|
||||||
let ssz = vec![0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 255];
|
let ssz = vec![0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 255];
|
||||||
let (result, index): (u64, usize) = decode_ssz(&ssz, 3).unwrap();
|
let (result, index): (u64, usize) = <_>::ssz_decode(&ssz, 3).unwrap();
|
||||||
assert_eq!(index, 11);
|
assert_eq!(index, 11);
|
||||||
assert_eq!(result, 18374686479671623680);
|
assert_eq!(result, 18374686479671623680);
|
||||||
|
|
||||||
let ssz = vec![0, 0, 0, 0, 0, 0, 0];
|
let ssz = vec![0, 0, 0, 0, 0, 0, 0];
|
||||||
let result: Result<(u64, usize), DecodeError> = decode_ssz(&ssz, 0);
|
let result: Result<(u64, usize), DecodeError> = <_>::ssz_decode(&ssz, 0);
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert_eq!(result, Err(DecodeError::TooShort));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ssz_decode_usize() {
|
fn test_ssz_decode_usize() {
|
||||||
let ssz = vec![0, 0, 0, 0, 0, 0, 0, 0];
|
let ssz = vec![0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
let (result, index): (usize, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (usize, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 8);
|
assert_eq!(index, 8);
|
||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
|
|
||||||
let ssz = vec![0, 0, 8, 255, 255, 255, 255, 255, 255, 255, 255];
|
let ssz = vec![0, 0, 8, 255, 255, 255, 255, 255, 255, 255, 255];
|
||||||
let (result, index): (usize, usize) = decode_ssz(&ssz, 3).unwrap();
|
let (result, index): (usize, usize) = <_>::ssz_decode(&ssz, 3).unwrap();
|
||||||
assert_eq!(index, 11);
|
assert_eq!(index, 11);
|
||||||
assert_eq!(result, 18446744073709551615);
|
assert_eq!(result, 18446744073709551615);
|
||||||
|
|
||||||
let ssz = vec![255, 255, 255, 255, 255, 255, 255, 255, 255];
|
let ssz = vec![255, 255, 255, 255, 255, 255, 255, 255, 255];
|
||||||
let (result, index): (usize, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (usize, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 8);
|
assert_eq!(index, 8);
|
||||||
assert_eq!(result, 18446744073709551615);
|
assert_eq!(result, 18446744073709551615);
|
||||||
|
|
||||||
let ssz = vec![0, 0, 0, 0, 0, 0, 1];
|
let ssz = vec![0, 0, 0, 0, 0, 0, 1];
|
||||||
let result: Result<(usize, usize), DecodeError> = decode_ssz(&ssz, 0);
|
let result: Result<(usize, usize), DecodeError> = <_>::ssz_decode(&ssz, 0);
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert_eq!(result, Err(DecodeError::TooShort));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_ssz_bounds() {
|
fn test_decode_ssz_bounds() {
|
||||||
let err: Result<(u16, usize), DecodeError> = decode_ssz(&vec![1], 2);
|
let err: Result<(u16, usize), DecodeError> = <_>::ssz_decode(&vec![1], 2);
|
||||||
assert_eq!(err, Err(DecodeError::TooShort));
|
assert_eq!(err, Err(DecodeError::TooShort));
|
||||||
|
|
||||||
let err: Result<(u16, usize), DecodeError> = decode_ssz(&vec![0, 0, 0, 0], 3);
|
let err: Result<(u16, usize), DecodeError> = <_>::ssz_decode(&vec![0, 0, 0, 0], 3);
|
||||||
assert_eq!(err, Err(DecodeError::TooShort));
|
assert_eq!(err, Err(DecodeError::TooShort));
|
||||||
|
|
||||||
let result: u16 = decode_ssz(&vec![0, 0, 0, 1, 0], 3).unwrap().0;
|
let result: u16 = <_>::ssz_decode(&vec![0, 0, 0, 1, 0], 3).unwrap().0;
|
||||||
assert_eq!(result, 1);
|
assert_eq!(result, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_ssz_bool() {
|
fn test_decode_ssz_bool() {
|
||||||
let ssz = vec![0b0000_0000, 0b1000_0000];
|
let ssz = vec![0b0000_0000, 0b0000_0001];
|
||||||
let (result, index): (bool, usize) = decode_ssz(&ssz, 0).unwrap();
|
let (result, index): (bool, usize) = <_>::ssz_decode(&ssz, 0).unwrap();
|
||||||
assert_eq!(index, 1);
|
assert_eq!(index, 1);
|
||||||
assert_eq!(result, false);
|
assert_eq!(result, false);
|
||||||
|
|
||||||
let (result, index): (bool, usize) = decode_ssz(&ssz, 1).unwrap();
|
let (result, index): (bool, usize) = <_>::ssz_decode(&ssz, 1).unwrap();
|
||||||
assert_eq!(index, 2);
|
assert_eq!(index, 2);
|
||||||
assert_eq!(result, true);
|
assert_eq!(result, true);
|
||||||
|
|
||||||
let ssz = vec![0b0100_0000];
|
let ssz = vec![0b0100_0000];
|
||||||
let result: Result<(bool, usize), DecodeError> = decode_ssz(&ssz, 0);
|
let result: Result<(bool, usize), DecodeError> = <_>::ssz_decode(&ssz, 0);
|
||||||
assert_eq!(result, Err(DecodeError::Invalid));
|
assert_eq!(result, Err(DecodeError::Invalid));
|
||||||
|
|
||||||
|
let ssz = vec![];
|
||||||
|
let result: Result<(bool, usize), DecodeError> = <_>::ssz_decode(&ssz, 0);
|
||||||
|
assert_eq!(result, Err(DecodeError::TooShort));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_decode_ssz_list_underflow() {
|
||||||
|
// SSZ encoded (u16::[1, 1, 1], u16::2)
|
||||||
|
let mut encoded = vec![6, 0, 0, 0, 1, 0, 1, 0, 1, 0, 2, 0];
|
||||||
|
let (decoded_array, i): (Vec<u16>, usize) = <_>::ssz_decode(&encoded, 0).unwrap();
|
||||||
|
let (decoded_u16, i): (u16, usize) = <_>::ssz_decode(&encoded, i).unwrap();
|
||||||
|
assert_eq!(decoded_array, vec![1, 1, 1]);
|
||||||
|
assert_eq!(decoded_u16, 2);
|
||||||
|
assert_eq!(i, 12);
|
||||||
|
|
||||||
|
// Underflow
|
||||||
|
encoded[0] = 4; // change length to 4 from 6
|
||||||
|
let (decoded_array, i): (Vec<u16>, usize) = <_>::ssz_decode(&encoded, 0).unwrap();
|
||||||
|
let (decoded_u16, _): (u16, usize) = <_>::ssz_decode(&encoded, i).unwrap();
|
||||||
|
assert_eq!(decoded_array, vec![1, 1]);
|
||||||
|
assert_eq!(decoded_u16, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_decode_too_long() {
|
||||||
|
let encoded = vec![6, 0, 0, 0, 1, 0, 1, 0, 1, 0, 2];
|
||||||
|
let decoded_array: Result<Vec<u16>, DecodeError> = decode(&encoded);
|
||||||
|
assert_eq!(decoded_array, Err(DecodeError::TooLong));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ impl_encodable_for_uint!(usize, 64);
|
|||||||
|
|
||||||
impl Encodable for bool {
|
impl Encodable for bool {
|
||||||
fn ssz_append(&self, s: &mut SszStream) {
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
let byte = if *self { 0b1000_0000 } else { 0b0000_0000 };
|
let byte = if *self { 0b0000_0001 } else { 0b0000_0000 };
|
||||||
s.append_encoded_raw(&[byte]);
|
s.append_encoded_raw(&[byte]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,6 +245,6 @@ mod tests {
|
|||||||
let x: bool = true;
|
let x: bool = true;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0b1000_0000]);
|
assert_eq!(ssz.drain(), vec![0b0000_0001]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ mod impl_decode;
|
|||||||
mod impl_encode;
|
mod impl_encode;
|
||||||
mod impl_tree_hash;
|
mod impl_tree_hash;
|
||||||
|
|
||||||
pub use crate::decode::{decode_ssz, decode_ssz_list, Decodable, DecodeError};
|
pub use crate::decode::{decode, decode_ssz_list, Decodable, DecodeError};
|
||||||
pub use crate::encode::{Encodable, SszStream};
|
pub use crate::encode::{Encodable, SszStream};
|
||||||
pub use crate::signed_root::SignedRoot;
|
pub use crate::signed_root::SignedRoot;
|
||||||
pub use crate::tree_hash::{merkle_hash, TreeHash};
|
pub use crate::tree_hash::{merkle_hash, TreeHash};
|
||||||
|
@ -3,7 +3,7 @@ use protos::services::{
|
|||||||
BeaconBlock as GrpcBeaconBlock, ProduceBeaconBlockRequest, PublishBeaconBlockRequest,
|
BeaconBlock as GrpcBeaconBlock, ProduceBeaconBlockRequest, PublishBeaconBlockRequest,
|
||||||
};
|
};
|
||||||
use protos::services_grpc::BeaconBlockServiceClient;
|
use protos::services_grpc::BeaconBlockServiceClient;
|
||||||
use ssz::{ssz_encode, Decodable};
|
use ssz::{decode, ssz_encode};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use types::{BeaconBlock, BeaconBlockBody, Eth1Data, Hash256, Signature, Slot};
|
use types::{BeaconBlock, BeaconBlockBody, Eth1Data, Hash256, Signature, Slot};
|
||||||
|
|
||||||
@ -41,10 +41,10 @@ impl BeaconNode for BeaconBlockGrpcClient {
|
|||||||
if reply.has_block() {
|
if reply.has_block() {
|
||||||
let block = reply.get_block();
|
let block = reply.get_block();
|
||||||
|
|
||||||
let (signature, _) = Signature::ssz_decode(block.get_signature(), 0)
|
let signature = decode::<Signature>(block.get_signature())
|
||||||
.map_err(|_| BeaconNodeError::DecodeFailure)?;
|
.map_err(|_| BeaconNodeError::DecodeFailure)?;
|
||||||
|
|
||||||
let (randao_reveal, _) = Signature::ssz_decode(block.get_randao_reveal(), 0)
|
let randao_reveal = decode::<Signature>(block.get_randao_reveal())
|
||||||
.map_err(|_| BeaconNodeError::DecodeFailure)?;
|
.map_err(|_| BeaconNodeError::DecodeFailure)?;
|
||||||
|
|
||||||
// TODO: this conversion is incomplete; fix it.
|
// TODO: this conversion is incomplete; fix it.
|
||||||
|
Loading…
Reference in New Issue
Block a user