Merge pull request #325 from sigp/yaml-test-downloads
Yaml Tests for state transitions and SSZ
This commit is contained in:
commit
0fd509ee82
@ -4,6 +4,7 @@ members = [
|
|||||||
"eth2/block_proposer",
|
"eth2/block_proposer",
|
||||||
"eth2/fork_choice",
|
"eth2/fork_choice",
|
||||||
"eth2/state_processing",
|
"eth2/state_processing",
|
||||||
|
"eth2/state_processing/yaml_utils",
|
||||||
"eth2/types",
|
"eth2/types",
|
||||||
"eth2/utils/bls",
|
"eth2/utils/bls",
|
||||||
"eth2/utils/boolean-bitfield",
|
"eth2/utils/boolean-bitfield",
|
||||||
|
@ -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::{BeaconBlock, Hash256, Slot};
|
use types::{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))
|
||||||
|
@ -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::{BeaconState, Hash256};
|
use types::{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))
|
||||||
|
@ -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),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use grpcio::{RpcContext, RpcStatus, RpcStatusCode, UnarySink};
|
|||||||
use protos::services::{ActiveValidator, GetDutiesRequest, GetDutiesResponse, ValidatorDuty};
|
use protos::services::{ActiveValidator, GetDutiesRequest, GetDutiesResponse, ValidatorDuty};
|
||||||
use protos::services_grpc::ValidatorService;
|
use protos::services_grpc::ValidatorService;
|
||||||
use slog::{debug, info, warn, Logger};
|
use slog::{debug, info, warn, Logger};
|
||||||
use ssz::Decodable;
|
use ssz::decode;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use types::{Epoch, RelativeEpoch};
|
use types::{Epoch, RelativeEpoch};
|
||||||
|
|
||||||
@ -75,8 +75,8 @@ impl ValidatorService for ValidatorServiceInstance {
|
|||||||
for validator_pk in validators.get_public_keys() {
|
for validator_pk in validators.get_public_keys() {
|
||||||
let mut active_validator = ActiveValidator::new();
|
let mut active_validator = ActiveValidator::new();
|
||||||
|
|
||||||
let public_key = match PublicKey::ssz_decode(validator_pk, 0) {
|
let public_key = match decode::<PublicKey>(validator_pk) {
|
||||||
Ok((v, _index)) => v,
|
Ok(v) => v,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let log_clone = self.log.clone();
|
let log_clone = self.log.clone();
|
||||||
let f = sink
|
let f = sink
|
||||||
|
@ -14,6 +14,7 @@ env_logger = "0.6.0"
|
|||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_yaml = "0.8"
|
serde_yaml = "0.8"
|
||||||
|
yaml-utils = { path = "yaml_utils" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bls = { path = "../utils/bls" }
|
bls = { path = "../utils/bls" }
|
||||||
|
@ -1,708 +0,0 @@
|
|||||||
title: Sanity tests -- small config -- 32 validators
|
|
||||||
summary: Basic sanity checks from phase 0 spec pythonization using a small state configuration and 32 validators.
|
|
||||||
All tests are run with `verify_signatures` as set to False.
|
|
||||||
Tests generated via https://github.com/ethereum/research/blob/master/spec_pythonizer/sanity_check.py
|
|
||||||
test_suite: beacon_state
|
|
||||||
fork: phase0-0.5.0
|
|
||||||
test_cases:
|
|
||||||
- name: test_empty_block_transition
|
|
||||||
config:
|
|
||||||
SHARD_COUNT: 8
|
|
||||||
TARGET_COMMITTEE_SIZE: 4
|
|
||||||
MAX_BALANCE_CHURN_QUOTIENT: 32
|
|
||||||
MAX_INDICES_PER_SLASHABLE_VOTE: 4096
|
|
||||||
MAX_EXIT_DEQUEUES_PER_EPOCH: 4
|
|
||||||
SHUFFLE_ROUND_COUNT: 90
|
|
||||||
DEPOSIT_CONTRACT_TREE_DEPTH: 32
|
|
||||||
MIN_DEPOSIT_AMOUNT: 1000000000
|
|
||||||
MAX_DEPOSIT_AMOUNT: 32000000000
|
|
||||||
FORK_CHOICE_BALANCE_INCREMENT: 1000000000
|
|
||||||
EJECTION_BALANCE: 16000000000
|
|
||||||
GENESIS_FORK_VERSION: 0
|
|
||||||
GENESIS_SLOT: 4294967296
|
|
||||||
GENESIS_EPOCH: 536870912
|
|
||||||
GENESIS_START_SHARD: 0
|
|
||||||
BLS_WITHDRAWAL_PREFIX_BYTE: '0x00'
|
|
||||||
SECONDS_PER_SLOT: 6
|
|
||||||
MIN_ATTESTATION_INCLUSION_DELAY: 2
|
|
||||||
SLOTS_PER_EPOCH: 8
|
|
||||||
MIN_SEED_LOOKAHEAD: 1
|
|
||||||
ACTIVATION_EXIT_DELAY: 4
|
|
||||||
EPOCHS_PER_ETH1_VOTING_PERIOD: 16
|
|
||||||
SLOTS_PER_HISTORICAL_ROOT: 64
|
|
||||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
|
|
||||||
PERSISTENT_COMMITTEE_PERIOD: 2048
|
|
||||||
LATEST_RANDAO_MIXES_LENGTH: 64
|
|
||||||
LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 64
|
|
||||||
LATEST_SLASHED_EXIT_LENGTH: 64
|
|
||||||
BASE_REWARD_QUOTIENT: 32
|
|
||||||
WHISTLEBLOWER_REWARD_QUOTIENT: 512
|
|
||||||
ATTESTATION_INCLUSION_REWARD_QUOTIENT: 8
|
|
||||||
INACTIVITY_PENALTY_QUOTIENT: 16777216
|
|
||||||
MIN_PENALTY_QUOTIENT: 32
|
|
||||||
MAX_PROPOSER_SLASHINGS: 16
|
|
||||||
MAX_ATTESTER_SLASHINGS: 1
|
|
||||||
MAX_ATTESTATIONS: 128
|
|
||||||
MAX_DEPOSITS: 16
|
|
||||||
MAX_VOLUNTARY_EXITS: 16
|
|
||||||
MAX_TRANSFERS: 16
|
|
||||||
DOMAIN_BEACON_BLOCK: 0
|
|
||||||
DOMAIN_RANDAO: 1
|
|
||||||
DOMAIN_ATTESTATION: 2
|
|
||||||
DOMAIN_DEPOSIT: 3
|
|
||||||
DOMAIN_VOLUNTARY_EXIT: 4
|
|
||||||
DOMAIN_TRANSFER: 5
|
|
||||||
verify_signatures: false
|
|
||||||
initial_state:
|
|
||||||
slot: 4294967296
|
|
||||||
genesis_time: 0
|
|
||||||
fork:
|
|
||||||
previous_version: '0x00000000'
|
|
||||||
current_version: '0x00000000'
|
|
||||||
epoch: 536870912
|
|
||||||
validator_registry:
|
|
||||||
- pubkey: '0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000001'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xa572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000002'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x89ece308f9d1f0131765212deca99697b112d61f9be9a5f1f3780a51335b3ff981747a0b2ca2179b96d2c0c9024e5224'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000003'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xac9b60d5afcbd5663a8a44b7c5a02f19e9a77ab0a35bd65809bb5c67ec582c897feb04decc694b13e08587f3ff9b5b60'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000004'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xb0e7791fb972fe014159aa33a98622da3cdc98ff707965e536d8636b5fcc5ac7a91a8c46e59a00dca575af0f18fb13dc'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000005'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xa6e82f6da4520f85c5d27d8f329eccfa05944fd1096b20734c894966d12a9e2a9a9744529d7212d33883113a0cadb909'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000006'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xb928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000007'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xa85ae765588126f5e860d019c0e26235f567a9c0c0b2d8ff30f3e8d436b1082596e5e7462d20f5be3764fd473e57f9cf'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000008'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x99cdf3807146e68e041314ca93e1fee0991224ec2a74beb2866816fd0826ce7b6263ee31e953a86d1b72cc2215a57793'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000009'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xaf81da25ecf1c84b577fefbedd61077a81dc43b00304015b2b596ab67f00e41c86bb00ebd0f90d4b125eb0539891aeed'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000000a'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x80fd75ebcc0a21649e3177bcce15426da0e4f25d6828fbf4038d4d7ed3bd4421de3ef61d70f794687b12b2d571971a55'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000000b'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x8345dd80ffef0eaec8920e39ebb7f5e9ae9c1d6179e9129b705923df7830c67f3690cbc48649d4079eadf5397339580c'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000000c'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x851f8a0b82a6d86202a61cbc3b0f3db7d19650b914587bde4715ccd372e1e40cab95517779d840416e1679c84a6db24e'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000000d'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x99bef05aaba1ea467fcbc9c420f5e3153c9d2b5f9bf2c7e2e7f6946f854043627b45b008607b9a9108bb96f3c1c089d3'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000000e'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x8d9e19b3f4c7c233a6112e5397309f9812a4f61f754f11dd3dcb8b07d55a7b1dfea65f19a1488a14fef9a41495083582'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000000f'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xa73eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000010'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xb098f178f84fc753a76bb63709e9be91eec3ff5f7f3a5f4836f34fe8a1a6d6c5578d8fd820573cef3a01e2bfef3eaf3a'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000011'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x9252a4ac3529f8b2b6e8189b95a60b8865f07f9a9b73f98d5df708511d3f68632c4c7d1e2b03e6b1d1e2c01839752ada'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000012'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xb271205227c7aa27f45f20b3ba380dfea8b51efae91fd32e552774c99e2a1237aa59c0c43f52aad99bba3783ea2f36a4'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000013'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xa272e9d1d50a4aea7d8f0583948090d0888be5777f2846800b8281139cd4aa9eee05f89b069857a3e77ccfaae1615f9c'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000014'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x9780e853f8ce7eda772c6691d25e220ca1d2ab0db51a7824b700620f7ac94c06639e91c98bb6abd78128f0ec845df8ef'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000015'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xab48aa2cc6f4a0bb63b5d67be54ac3aed10326dda304c5aeb9e942b40d6e7610478377680ab90e092ef1895e62786008'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000016'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x8c8b694b04d98a749a0763c72fc020ef61b2bb3f63ebb182cb2e568f6a8b9ca3ae013ae78317599e7e7ba2a528ec754a'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000017'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x9717182463fbe215168e6762abcbb55c5c65290f2b5a2af616f8a6f50d625b46164178a11622d21913efdfa4b800648d'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000018'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xacb58c81ae0cae2e9d4d446b730922239923c345744eee58efaadb36e9a0925545b18a987acf0bad469035b291e37269'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000019'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x81ccc19e3b938ec2405099e90022a4218baa5082a3ca0974b24be0bc8b07e5fffaed64bef0d02c4dbfb6a307829afc5c'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000001a'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xab83dfefb120fab7665a607d749ef1765fbb3cc0ba5827a20a135402c09d987c701ddb5b60f0f5495026817e8ab6ea2e'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000001b'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xb6ad11e5d15f77c1143b1697344911b9c590110fdd8dd09df2e58bfd757269169deefe8be3544d4e049fb3776fb0bcfb'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000001c'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0x8515e7f61ca0470e165a44d247a23f17f24bf6e37185467bedb7981c1003ea70bbec875703f793dd8d11e56afa7f74ba'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000001d'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xad84464b3966ec5bede84aa487facfca7823af383715078da03b387cc2f5d5597cdd7d025aa07db00a38b953bdeb6e3f'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000001e'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xb29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d'
|
|
||||||
withdrawal_credentials: '0x000000000000000000000000000000000000000000000000000000000000001f'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
- pubkey: '0xa72841987e4f219d54f2b6a9eac5fe6e78704644753c3579e776a3691bc123743f8c63770ed0f72a71e9e964dbf58f43'
|
|
||||||
withdrawal_credentials: '0x0000000000000000000000000000000000000000000000000000000000000020'
|
|
||||||
activation_epoch: 536870912
|
|
||||||
exit_epoch: 18446744073709551615
|
|
||||||
withdrawable_epoch: 18446744073709551615
|
|
||||||
initiated_exit: false
|
|
||||||
slashed: false
|
|
||||||
validator_balances:
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
- 32000000000
|
|
||||||
validator_registry_update_epoch: 536870912
|
|
||||||
latest_randao_mixes:
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
previous_shuffling_start_shard: 0
|
|
||||||
current_shuffling_start_shard: 0
|
|
||||||
previous_shuffling_epoch: 536870912
|
|
||||||
current_shuffling_epoch: 536870912
|
|
||||||
previous_shuffling_seed: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
current_shuffling_seed: '0x7a81d831e99dc63f9f10d4abce84c26473d4c2f65ec4acf9000684059473b072'
|
|
||||||
previous_epoch_attestations: []
|
|
||||||
current_epoch_attestations: []
|
|
||||||
previous_justified_epoch: 536870912
|
|
||||||
current_justified_epoch: 536870912
|
|
||||||
previous_justified_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
current_justified_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
justification_bitfield: 0
|
|
||||||
finalized_epoch: 536870912
|
|
||||||
finalized_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
latest_crosslinks:
|
|
||||||
- epoch: 536870912
|
|
||||||
crosslink_data_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- epoch: 536870912
|
|
||||||
crosslink_data_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- epoch: 536870912
|
|
||||||
crosslink_data_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- epoch: 536870912
|
|
||||||
crosslink_data_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- epoch: 536870912
|
|
||||||
crosslink_data_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- epoch: 536870912
|
|
||||||
crosslink_data_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- epoch: 536870912
|
|
||||||
crosslink_data_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- epoch: 536870912
|
|
||||||
crosslink_data_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
latest_block_roots:
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
latest_state_roots:
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
- '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
latest_active_index_roots:
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
- '0x429a7560eb31fa5d1192496997a78ffc590e70f5b39220abff4420298061501a'
|
|
||||||
latest_slashed_balances:
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
- 0
|
|
||||||
latest_block_header:
|
|
||||||
slot: 4294967296
|
|
||||||
previous_block_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
state_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
block_body_root: '0x13f2001ff0ee4a528b3c43f63d70a997aefca990ed8eada2223ee6ec3807f7cc'
|
|
||||||
signature: '0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
historical_roots: []
|
|
||||||
latest_eth1_data:
|
|
||||||
deposit_root: '0x826d25bfcb9161aabc799844c5176f7b3444dc5288856f65e0b8060560488912'
|
|
||||||
block_hash: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
eth1_data_votes: []
|
|
||||||
deposit_index: 32
|
|
||||||
blocks:
|
|
||||||
- slot: 4294967297
|
|
||||||
previous_block_root: '0x2befbd4b4fe8c91f3059082c8048e3376a9b7fb309e93044fac32b7cc8849773'
|
|
||||||
state_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
body:
|
|
||||||
randao_reveal: '0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
eth1_data:
|
|
||||||
deposit_root: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
block_hash: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
proposer_slashings: []
|
|
||||||
attester_slashings: []
|
|
||||||
attestations: []
|
|
||||||
deposits: []
|
|
||||||
voluntary_exits: []
|
|
||||||
transfers: []
|
|
||||||
signature: '0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
|
||||||
expected_state:
|
|
||||||
slot: 4294967297
|
|
@ -1,5 +1,7 @@
|
|||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use types::*;
|
use types::*;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use yaml_utils;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct TestCase {
|
pub struct TestCase {
|
||||||
@ -23,9 +25,10 @@ fn yaml() {
|
|||||||
use serde_yaml;
|
use serde_yaml;
|
||||||
use std::{fs::File, io::prelude::*, path::PathBuf};
|
use std::{fs::File, io::prelude::*, path::PathBuf};
|
||||||
|
|
||||||
|
// Test sanity-check_small-config_32-vals.yaml
|
||||||
let mut file = {
|
let mut file = {
|
||||||
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
file_path_buf.push("specs/example.yml");
|
file_path_buf.push("yaml_utils/specs/sanity-check_small-config_32-vals.yaml");
|
||||||
|
|
||||||
File::open(file_path_buf).unwrap()
|
File::open(file_path_buf).unwrap()
|
||||||
};
|
};
|
||||||
@ -34,7 +37,23 @@ fn yaml() {
|
|||||||
|
|
||||||
file.read_to_string(&mut yaml_str).unwrap();
|
file.read_to_string(&mut yaml_str).unwrap();
|
||||||
|
|
||||||
let yaml_str = yaml_str.to_lowercase();
|
yaml_str = yaml_str.to_lowercase();
|
||||||
|
|
||||||
|
let _doc: TestDoc = serde_yaml::from_str(&yaml_str.as_str()).unwrap();
|
||||||
|
|
||||||
|
// Test sanity-check_default-config_100-vals.yaml
|
||||||
|
file = {
|
||||||
|
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
file_path_buf.push("yaml_utils/specs/sanity-check_default-config_100-vals.yaml");
|
||||||
|
|
||||||
|
File::open(file_path_buf).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
yaml_str = String::new();
|
||||||
|
|
||||||
|
file.read_to_string(&mut yaml_str).unwrap();
|
||||||
|
|
||||||
|
yaml_str = yaml_str.to_lowercase();
|
||||||
|
|
||||||
let _doc: TestDoc = serde_yaml::from_str(&yaml_str.as_str()).unwrap();
|
let _doc: TestDoc = serde_yaml::from_str(&yaml_str.as_str()).unwrap();
|
||||||
}
|
}
|
||||||
|
15
eth2/state_processing/yaml_utils/Cargo.toml
Normal file
15
eth2/state_processing/yaml_utils/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "yaml-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Kirk Baird <baird.k@outlook.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
reqwest = "0.9"
|
||||||
|
tempdir = "0.3"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "yaml_utils"
|
||||||
|
path = "src/lib.rs"
|
28
eth2/state_processing/yaml_utils/build.rs
Normal file
28
eth2/state_processing/yaml_utils/build.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
extern crate reqwest;
|
||||||
|
extern crate tempdir;
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::copy;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// These test files are not to be stored in the lighthouse repo as they are quite large (32MB).
|
||||||
|
// They will be downloaded at build time by yaml-utils crate (in build.rs)
|
||||||
|
let git_path = "https://raw.githubusercontent.com/ethereum/eth2.0-tests/master/state/";
|
||||||
|
let test_names = vec![
|
||||||
|
"sanity-check_default-config_100-vals.yaml",
|
||||||
|
"sanity-check_small-config_32-vals.yaml",
|
||||||
|
];
|
||||||
|
|
||||||
|
for test in test_names {
|
||||||
|
let mut target = String::from(git_path);
|
||||||
|
target.push_str(test);
|
||||||
|
let mut response = reqwest::get(target.as_str()).unwrap();
|
||||||
|
|
||||||
|
let mut dest = {
|
||||||
|
let mut file_name = String::from("specs/");
|
||||||
|
file_name.push_str(test);
|
||||||
|
File::create(file_name).unwrap()
|
||||||
|
};
|
||||||
|
copy(&mut response, &mut dest).unwrap();
|
||||||
|
}
|
||||||
|
}
|
1
eth2/state_processing/yaml_utils/specs/.gitignore
vendored
Normal file
1
eth2/state_processing/yaml_utils/specs/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.yaml
|
1
eth2/state_processing/yaml_utils/src/lib.rs
Normal file
1
eth2/state_processing/yaml_utils/src/lib.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
// This is a place holder such that yaml-utils is now a crate hence build.rs will be run when 'cargo test' is called
|
@ -130,4 +130,15 @@ mod epoch_tests {
|
|||||||
assert_eq!(Slot::from(i), slots[i as usize])
|
assert_eq!(Slot::from(i), slots[i as usize])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn max_epoch_ssz() {
|
||||||
|
let max_epoch = Epoch::max_value();
|
||||||
|
let mut ssz = SszStream::new();
|
||||||
|
ssz.append(&max_epoch);
|
||||||
|
let encoded = ssz.drain();
|
||||||
|
assert_eq!(&encoded, &[255, 255, 255, 255, 255, 255, 255, 255]);
|
||||||
|
let (decoded, _i): (Epoch, usize) = <_>::ssz_decode(&encoded, 0).unwrap();
|
||||||
|
assert_eq!(max_epoch, decoded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ macro_rules! ssz_tests {
|
|||||||
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, usize) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
|
|
||||||
assert_eq!(original, decoded);
|
assert_eq!(original, decoded);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use serde::de::Error;
|
use serde::de::Error;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
|
pub const FORK_BYTES_LEN: usize = 4;
|
||||||
|
|
||||||
pub fn u8_from_hex_str<'de, D>(deserializer: D) -> Result<u8, D::Error>
|
pub fn u8_from_hex_str<'de, D>(deserializer: D) -> Result<u8, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
@ -10,14 +12,18 @@ where
|
|||||||
u8::from_str_radix(&s.as_str()[2..], 16).map_err(D::Error::custom)
|
u8::from_str_radix(&s.as_str()[2..], 16).map_err(D::Error::custom)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fork_from_hex_str<'de, D>(deserializer: D) -> Result<[u8; 4], D::Error>
|
pub fn fork_from_hex_str<'de, D>(deserializer: D) -> Result<[u8; FORK_BYTES_LEN], D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let s: String = Deserialize::deserialize(deserializer)?;
|
let s: String = Deserialize::deserialize(deserializer)?;
|
||||||
let mut array = [0 as u8; 4];
|
let mut array = [0 as u8; FORK_BYTES_LEN];
|
||||||
let decoded: Vec<u8> = hex::decode(&s.as_str()[2..]).map_err(D::Error::custom)?;
|
let decoded: Vec<u8> = hex::decode(&s.as_str()[2..]).map_err(D::Error::custom)?;
|
||||||
|
|
||||||
|
if decoded.len() > FORK_BYTES_LEN {
|
||||||
|
return Err(D::Error::custom("Fork length too long"));
|
||||||
|
}
|
||||||
|
|
||||||
for (i, item) in array.iter_mut().enumerate() {
|
for (i, item) in array.iter_mut().enumerate() {
|
||||||
if i > decoded.len() {
|
if i > decoded.len() {
|
||||||
break;
|
break;
|
||||||
|
@ -1,30 +1,39 @@
|
|||||||
use super::{AggregatePublicKey, Signature};
|
use super::{AggregatePublicKey, Signature, BLS_AGG_SIG_BYTE_SIZE};
|
||||||
use bls_aggregates::{
|
use bls_aggregates::{
|
||||||
AggregatePublicKey as RawAggregatePublicKey, AggregateSignature as RawAggregateSignature,
|
AggregatePublicKey as RawAggregatePublicKey, AggregateSignature as RawAggregateSignature,
|
||||||
};
|
};
|
||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use serde_hex::{encode as hex_encode, PrefixedHexVisitor};
|
use serde_hex::{encode as hex_encode, HexVisitor};
|
||||||
use ssz::{
|
use ssz::{decode, hash, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||||
decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A BLS aggregate signature.
|
/// A BLS aggregate signature.
|
||||||
///
|
///
|
||||||
/// This struct is a wrapper upon a base type and provides helper functions (e.g., SSZ
|
/// This struct is a wrapper upon a base type and provides helper functions (e.g., SSZ
|
||||||
/// serialization).
|
/// serialization).
|
||||||
#[derive(Debug, PartialEq, Clone, Default, Eq)]
|
#[derive(Debug, PartialEq, Clone, Default, Eq)]
|
||||||
pub struct AggregateSignature(RawAggregateSignature);
|
pub struct AggregateSignature {
|
||||||
|
aggregate_signature: RawAggregateSignature,
|
||||||
|
is_empty: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl AggregateSignature {
|
impl AggregateSignature {
|
||||||
/// Instantiate a new AggregateSignature.
|
/// Instantiate a new AggregateSignature.
|
||||||
|
///
|
||||||
|
/// is_empty is false
|
||||||
|
/// AggregateSiganture is point at infinity
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
AggregateSignature(RawAggregateSignature::new())
|
Self {
|
||||||
|
aggregate_signature: RawAggregateSignature::new(),
|
||||||
|
is_empty: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add (aggregate) a signature to the `AggregateSignature`.
|
/// Add (aggregate) a signature to the `AggregateSignature`.
|
||||||
pub fn add(&mut self, signature: &Signature) {
|
pub fn add(&mut self, signature: &Signature) {
|
||||||
self.0.add(signature.as_raw())
|
if !self.is_empty {
|
||||||
|
self.aggregate_signature.add(signature.as_raw())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify the `AggregateSignature` against an `AggregatePublicKey`.
|
/// Verify the `AggregateSignature` against an `AggregatePublicKey`.
|
||||||
@ -37,7 +46,11 @@ impl AggregateSignature {
|
|||||||
domain: u64,
|
domain: u64,
|
||||||
aggregate_public_key: &AggregatePublicKey,
|
aggregate_public_key: &AggregatePublicKey,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.0.verify(msg, domain, aggregate_public_key.as_raw())
|
if self.is_empty {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.aggregate_signature
|
||||||
|
.verify(msg, domain, aggregate_public_key.as_raw())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify this AggregateSignature against multiple AggregatePublickeys with multiple Messages.
|
/// Verify this AggregateSignature against multiple AggregatePublickeys with multiple Messages.
|
||||||
@ -50,6 +63,9 @@ impl AggregateSignature {
|
|||||||
domain: u64,
|
domain: u64,
|
||||||
aggregate_public_keys: &[&AggregatePublicKey],
|
aggregate_public_keys: &[&AggregatePublicKey],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
if self.is_empty {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let aggregate_public_keys: Vec<&RawAggregatePublicKey> =
|
let aggregate_public_keys: Vec<&RawAggregatePublicKey> =
|
||||||
aggregate_public_keys.iter().map(|pk| pk.as_raw()).collect();
|
aggregate_public_keys.iter().map(|pk| pk.as_raw()).collect();
|
||||||
|
|
||||||
@ -59,50 +75,93 @@ impl AggregateSignature {
|
|||||||
msg.extend_from_slice(message);
|
msg.extend_from_slice(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.0
|
self.aggregate_signature
|
||||||
.verify_multiple(&msg[..], domain, &aggregate_public_keys[..])
|
.verify_multiple(&msg[..], domain, &aggregate_public_keys[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return AggregateSiganture as bytes
|
||||||
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
|
if self.is_empty {
|
||||||
|
return vec![0; BLS_AGG_SIG_BYTE_SIZE];
|
||||||
|
}
|
||||||
|
self.aggregate_signature.as_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert bytes to AggregateSiganture
|
||||||
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||||
|
for byte in bytes {
|
||||||
|
if *byte != 0 {
|
||||||
|
let sig =
|
||||||
|
RawAggregateSignature::from_bytes(&bytes).map_err(|_| DecodeError::Invalid)?;
|
||||||
|
return Ok(Self {
|
||||||
|
aggregate_signature: sig,
|
||||||
|
is_empty: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Self::empty_signature())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns if the AggregateSiganture `is_empty`
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.is_empty
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new AggregateSignature
|
||||||
|
///
|
||||||
|
/// aggregate_signature set to the point infinity
|
||||||
|
/// is_empty set to true
|
||||||
|
pub fn empty_signature() -> Self {
|
||||||
|
Self {
|
||||||
|
aggregate_signature: RawAggregateSignature::new(),
|
||||||
|
is_empty: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for AggregateSignature {
|
impl Encodable for AggregateSignature {
|
||||||
fn ssz_append(&self, s: &mut SszStream) {
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
s.append_vec(&self.0.as_bytes());
|
s.append_encoded_raw(&self.as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for AggregateSignature {
|
impl Decodable for AggregateSignature {
|
||||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
let (sig_bytes, i) = decode_ssz_list(bytes, i)?;
|
if bytes.len() - i < BLS_AGG_SIG_BYTE_SIZE {
|
||||||
let raw_sig =
|
return Err(DecodeError::TooShort);
|
||||||
RawAggregateSignature::from_bytes(&sig_bytes).map_err(|_| DecodeError::TooShort)?;
|
}
|
||||||
Ok((AggregateSignature(raw_sig), i))
|
let agg_sig = AggregateSignature::from_bytes(&bytes[i..(i + BLS_AGG_SIG_BYTE_SIZE)])
|
||||||
|
.map_err(|_| DecodeError::Invalid)?;
|
||||||
|
Ok((agg_sig, i + BLS_AGG_SIG_BYTE_SIZE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for AggregateSignature {
|
impl Serialize for AggregateSignature {
|
||||||
|
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_str(&hex_encode(ssz_encode(self)))
|
serializer.serialize_str(&hex_encode(self.as_bytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for AggregateSignature {
|
impl<'de> Deserialize<'de> for AggregateSignature {
|
||||||
|
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let bytes = deserializer.deserialize_str(PrefixedHexVisitor)?;
|
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||||
let (obj, _) = <_>::ssz_decode(&bytes[..], 0)
|
let agg_sig = decode(&bytes[..])
|
||||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||||
Ok(obj)
|
Ok(agg_sig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TreeHash for AggregateSignature {
|
impl TreeHash for AggregateSignature {
|
||||||
fn hash_tree_root(&self) -> Vec<u8> {
|
fn hash_tree_root(&self) -> Vec<u8> {
|
||||||
hash(&self.0.as_bytes())
|
hash(&self.as_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +169,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() {
|
||||||
@ -120,7 +179,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);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
use super::{fake_signature::FakeSignature, AggregatePublicKey};
|
use super::{fake_signature::FakeSignature, AggregatePublicKey, BLS_AGG_SIG_BYTE_SIZE};
|
||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use serde_hex::{encode as hex_encode, PrefixedHexVisitor};
|
use serde_hex::{encode as hex_encode, PrefixedHexVisitor};
|
||||||
use ssz::{
|
use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||||
decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash,
|
|
||||||
};
|
|
||||||
|
|
||||||
const SIGNATURE_LENGTH: usize = 48;
|
|
||||||
|
|
||||||
/// A BLS aggregate signature.
|
/// A BLS aggregate signature.
|
||||||
///
|
///
|
||||||
@ -26,7 +22,7 @@ impl FakeAggregateSignature {
|
|||||||
/// Creates a new all-zero's signature
|
/// Creates a new all-zero's signature
|
||||||
pub fn zero() -> Self {
|
pub fn zero() -> Self {
|
||||||
Self {
|
Self {
|
||||||
bytes: vec![0; SIGNATURE_LENGTH],
|
bytes: vec![0; BLS_AGG_SIG_BYTE_SIZE],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,14 +54,21 @@ impl FakeAggregateSignature {
|
|||||||
|
|
||||||
impl Encodable for FakeAggregateSignature {
|
impl Encodable for FakeAggregateSignature {
|
||||||
fn ssz_append(&self, s: &mut SszStream) {
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
s.append_vec(&self.bytes);
|
s.append_encoded_raw(&self.bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for FakeAggregateSignature {
|
impl Decodable for FakeAggregateSignature {
|
||||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
let (sig_bytes, i) = decode_ssz_list(bytes, i)?;
|
if bytes.len() - i < BLS_AGG_SIG_BYTE_SIZE {
|
||||||
Ok((FakeAggregateSignature { bytes: sig_bytes }, i))
|
return Err(DecodeError::TooShort);
|
||||||
|
}
|
||||||
|
Ok((
|
||||||
|
FakeAggregateSignature {
|
||||||
|
bytes: bytes[i..(i + BLS_AGG_SIG_BYTE_SIZE)].to_vec(),
|
||||||
|
},
|
||||||
|
i + BLS_AGG_SIG_BYTE_SIZE,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
use super::serde_vistors::HexVisitor;
|
use super::{PublicKey, SecretKey, BLS_SIG_BYTE_SIZE};
|
||||||
use super::{PublicKey, SecretKey};
|
|
||||||
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::{
|
use serde_hex::HexVisitor;
|
||||||
decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash,
|
use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||||
};
|
|
||||||
|
|
||||||
const SIGNATURE_LENGTH: usize = 48;
|
|
||||||
|
|
||||||
/// A single BLS signature.
|
/// A single BLS signature.
|
||||||
///
|
///
|
||||||
@ -27,7 +23,7 @@ impl FakeSignature {
|
|||||||
/// Creates a new all-zero's signature
|
/// Creates a new all-zero's signature
|
||||||
pub fn zero() -> Self {
|
pub fn zero() -> Self {
|
||||||
Self {
|
Self {
|
||||||
bytes: vec![0; SIGNATURE_LENGTH],
|
bytes: vec![0; BLS_SIG_BYTE_SIZE],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,14 +55,21 @@ impl FakeSignature {
|
|||||||
|
|
||||||
impl Encodable for FakeSignature {
|
impl Encodable for FakeSignature {
|
||||||
fn ssz_append(&self, s: &mut SszStream) {
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
s.append_vec(&self.bytes);
|
s.append_encoded_raw(&self.bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for FakeSignature {
|
impl Decodable for FakeSignature {
|
||||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
let (sig_bytes, i) = decode_ssz_list(bytes, i)?;
|
if bytes.len() - i < BLS_SIG_BYTE_SIZE {
|
||||||
Ok((FakeSignature { bytes: sig_bytes }, i))
|
return Err(DecodeError::TooShort);
|
||||||
|
}
|
||||||
|
Ok((
|
||||||
|
FakeSignature {
|
||||||
|
bytes: bytes[i..(i + BLS_SIG_BYTE_SIZE)].to_vec(),
|
||||||
|
},
|
||||||
|
i + BLS_SIG_BYTE_SIZE,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ mod aggregate_public_key;
|
|||||||
mod keypair;
|
mod keypair;
|
||||||
mod public_key;
|
mod public_key;
|
||||||
mod secret_key;
|
mod secret_key;
|
||||||
mod serde_vistors;
|
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
mod aggregate_signature;
|
mod aggregate_signature;
|
||||||
@ -31,6 +30,9 @@ pub use crate::public_key::PublicKey;
|
|||||||
pub use crate::secret_key::SecretKey;
|
pub use crate::secret_key::SecretKey;
|
||||||
|
|
||||||
pub const BLS_AGG_SIG_BYTE_SIZE: usize = 96;
|
pub const BLS_AGG_SIG_BYTE_SIZE: usize = 96;
|
||||||
|
pub const BLS_SIG_BYTE_SIZE: usize = 96;
|
||||||
|
pub const BLS_SECRET_KEY_BYTE_SIZE: usize = 48;
|
||||||
|
pub const BLS_PUBLIC_KEY_BYTE_SIZE: usize = 48;
|
||||||
|
|
||||||
use hashing::hash;
|
use hashing::hash;
|
||||||
use ssz::ssz_encode;
|
use ssz::ssz_encode;
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
use super::SecretKey;
|
use super::{SecretKey, BLS_PUBLIC_KEY_BYTE_SIZE};
|
||||||
use bls_aggregates::PublicKey as RawPublicKey;
|
use bls_aggregates::PublicKey as RawPublicKey;
|
||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use serde_hex::{encode as hex_encode, PrefixedHexVisitor};
|
use serde_hex::{encode as hex_encode, HexVisitor};
|
||||||
use ssz::{
|
use ssz::{decode, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||||
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};
|
||||||
|
|
||||||
@ -63,15 +61,18 @@ impl default::Default for PublicKey {
|
|||||||
|
|
||||||
impl Encodable for PublicKey {
|
impl Encodable for PublicKey {
|
||||||
fn ssz_append(&self, s: &mut SszStream) {
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
s.append_vec(&self.0.as_bytes());
|
s.append_encoded_raw(&self.0.as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for PublicKey {
|
impl Decodable for PublicKey {
|
||||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
let (sig_bytes, i) = decode_ssz_list(bytes, i)?;
|
if bytes.len() - i < BLS_PUBLIC_KEY_BYTE_SIZE {
|
||||||
let raw_sig = RawPublicKey::from_bytes(&sig_bytes).map_err(|_| DecodeError::TooShort)?;
|
return Err(DecodeError::TooShort);
|
||||||
Ok((PublicKey(raw_sig), i))
|
}
|
||||||
|
let raw_sig = RawPublicKey::from_bytes(&bytes[i..(i + BLS_PUBLIC_KEY_BYTE_SIZE)])
|
||||||
|
.map_err(|_| DecodeError::TooShort)?;
|
||||||
|
Ok((PublicKey(raw_sig), i + BLS_PUBLIC_KEY_BYTE_SIZE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,10 +90,10 @@ impl<'de> Deserialize<'de> for PublicKey {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let bytes = deserializer.deserialize_str(PrefixedHexVisitor)?;
|
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||||
let obj = PublicKey::from_bytes(&bytes[..])
|
let pubkey = decode(&bytes[..])
|
||||||
.map_err(|e| serde::de::Error::custom(format!("invalid pubkey ({:?})", e)))?;
|
.map_err(|e| serde::de::Error::custom(format!("invalid pubkey ({:?})", e)))?;
|
||||||
Ok(obj)
|
Ok(pubkey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use super::serde_vistors::HexVisitor;
|
use super::BLS_SECRET_KEY_BYTE_SIZE;
|
||||||
use bls_aggregates::{DecodeError as BlsDecodeError, SecretKey as RawSecretKey};
|
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 serde_hex::HexVisitor;
|
||||||
|
use ssz::{decode, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||||
|
|
||||||
/// A single BLS signature.
|
/// A single BLS signature.
|
||||||
///
|
///
|
||||||
@ -32,15 +33,18 @@ impl SecretKey {
|
|||||||
|
|
||||||
impl Encodable for SecretKey {
|
impl Encodable for SecretKey {
|
||||||
fn ssz_append(&self, s: &mut SszStream) {
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
s.append_vec(&self.0.as_bytes());
|
s.append_encoded_raw(&self.0.as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for SecretKey {
|
impl Decodable for SecretKey {
|
||||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
let (sig_bytes, i) = decode_ssz_list(bytes, i)?;
|
if bytes.len() - i < BLS_SECRET_KEY_BYTE_SIZE {
|
||||||
let raw_sig = RawSecretKey::from_bytes(&sig_bytes).map_err(|_| DecodeError::TooShort)?;
|
return Err(DecodeError::TooShort);
|
||||||
Ok((SecretKey(raw_sig), i))
|
}
|
||||||
|
let raw_sig = RawSecretKey::from_bytes(&bytes[i..(i + BLS_SECRET_KEY_BYTE_SIZE)])
|
||||||
|
.map_err(|_| DecodeError::TooShort)?;
|
||||||
|
Ok((SecretKey(raw_sig), i + BLS_SECRET_KEY_BYTE_SIZE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,9 +63,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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
use hex;
|
|
||||||
use serde::de::{self, Visitor};
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
pub struct HexVisitor;
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for HexVisitor {
|
|
||||||
type Value = Vec<u8>;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("a hex string (irrelevant of prefix)")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
Ok(hex::decode(value.trim_start_matches("0x"))
|
|
||||||
.map_err(|e| de::Error::custom(format!("invalid hex ({:?})", e)))?)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,10 @@
|
|||||||
use super::serde_vistors::HexVisitor;
|
use super::{PublicKey, SecretKey, BLS_SIG_BYTE_SIZE};
|
||||||
use super::{PublicKey, SecretKey};
|
|
||||||
use bls_aggregates::Signature as RawSignature;
|
use bls_aggregates::Signature as RawSignature;
|
||||||
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::{
|
use serde_hex::HexVisitor;
|
||||||
decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash,
|
use ssz::{decode, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||||
};
|
|
||||||
|
|
||||||
/// A single BLS signature.
|
/// A single BLS signature.
|
||||||
///
|
///
|
||||||
@ -63,7 +61,7 @@ impl Signature {
|
|||||||
/// Returns a new empty signature.
|
/// Returns a new empty signature.
|
||||||
pub fn empty_signature() -> Self {
|
pub fn empty_signature() -> Self {
|
||||||
// Set RawSignature = infinity
|
// Set RawSignature = infinity
|
||||||
let mut empty: Vec<u8> = vec![0; 96];
|
let mut empty: Vec<u8> = vec![0; BLS_SIG_BYTE_SIZE];
|
||||||
empty[0] += u8::pow(2, 6) + u8::pow(2, 7);
|
empty[0] += u8::pow(2, 6) + u8::pow(2, 7);
|
||||||
Signature {
|
Signature {
|
||||||
signature: RawSignature::from_bytes(&empty).unwrap(),
|
signature: RawSignature::from_bytes(&empty).unwrap(),
|
||||||
@ -102,15 +100,17 @@ impl Signature {
|
|||||||
|
|
||||||
impl Encodable for Signature {
|
impl Encodable for Signature {
|
||||||
fn ssz_append(&self, s: &mut SszStream) {
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
s.append_vec(&self.as_bytes());
|
s.append_encoded_raw(&self.as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Signature {
|
impl Decodable for Signature {
|
||||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
let (sig_bytes, i) = decode_ssz_list(bytes, i)?;
|
if bytes.len() - i < BLS_SIG_BYTE_SIZE {
|
||||||
let signature = Signature::from_bytes(&sig_bytes)?;
|
return Err(DecodeError::TooShort);
|
||||||
Ok((signature, i))
|
}
|
||||||
|
let signature = Signature::from_bytes(&bytes[i..(i + BLS_SIG_BYTE_SIZE)])?;
|
||||||
|
Ok((signature, i + BLS_SIG_BYTE_SIZE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +121,7 @@ impl TreeHash for Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for Signature {
|
impl Serialize for Signature {
|
||||||
|
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
@ -130,14 +131,15 @@ impl Serialize for Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Signature {
|
impl<'de> Deserialize<'de> for Signature {
|
||||||
|
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
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(&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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +156,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);
|
||||||
}
|
}
|
||||||
@ -165,7 +167,7 @@ mod tests {
|
|||||||
|
|
||||||
let sig_as_bytes: Vec<u8> = sig.as_raw().as_bytes();
|
let sig_as_bytes: Vec<u8> = sig.as_raw().as_bytes();
|
||||||
|
|
||||||
assert_eq!(sig_as_bytes.len(), 96);
|
assert_eq!(sig_as_bytes.len(), BLS_SIG_BYTE_SIZE);
|
||||||
for (i, one_byte) in sig_as_bytes.iter().enumerate() {
|
for (i, one_byte) in sig_as_bytes.iter().enumerate() {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
assert_eq!(*one_byte, u8::pow(2, 6) + u8::pow(2, 7));
|
assert_eq!(*one_byte, u8::pow(2, 6) + u8::pow(2, 7));
|
||||||
|
@ -6,7 +6,7 @@ use bit_vec::BitVec;
|
|||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use serde_hex::{encode, PrefixedHexVisitor};
|
use serde_hex::{encode, PrefixedHexVisitor};
|
||||||
use ssz::Decodable;
|
use ssz::{Decodable, Encodable};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::default;
|
use std::default;
|
||||||
|
|
||||||
@ -144,14 +144,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() {
|
||||||
@ -186,7 +186,7 @@ impl Serialize for BooleanBitfield {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_str(&encode(&ssz::ssz_encode(self)))
|
serializer.serialize_str(&encode(&self.to_bytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,9 +197,7 @@ impl<'de> Deserialize<'de> for BooleanBitfield {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let bytes = deserializer.deserialize_str(PrefixedHexVisitor)?;
|
let bytes = deserializer.deserialize_str(PrefixedHexVisitor)?;
|
||||||
let (bitfield, _) = <_>::ssz_decode(&bytes[..], 0)
|
Ok(BooleanBitfield::from_bytes(&bytes))
|
||||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
|
||||||
Ok(bitfield)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +210,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() {
|
||||||
@ -380,12 +378,12 @@ mod tests {
|
|||||||
|
|
||||||
let mut stream = SszStream::new();
|
let mut stream = SszStream::new();
|
||||||
stream.append(&field);
|
stream.append(&field);
|
||||||
assert_eq!(stream.drain(), vec![0, 0, 0, 2, 225, 192]);
|
assert_eq!(stream.drain(), vec![2, 0, 0, 0, 225, 192]);
|
||||||
|
|
||||||
let field = BooleanBitfield::from_elem(18, true);
|
let field = BooleanBitfield::from_elem(18, true);
|
||||||
let mut stream = SszStream::new();
|
let mut stream = SszStream::new();
|
||||||
stream.append(&field);
|
stream.append(&field);
|
||||||
assert_eq!(stream.drain(), vec![0, 0, 0, 3, 255, 255, 192]);
|
assert_eq!(stream.drain(), vec![3, 0, 0, 0, 255, 255, 192]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_test_bitfield() -> BooleanBitfield {
|
fn create_test_bitfield() -> BooleanBitfield {
|
||||||
@ -401,13 +399,13 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ssz_decode() {
|
fn test_ssz_decode() {
|
||||||
let encoded = vec![0, 0, 0, 2, 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![0, 0, 0, 3, 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);
|
||||||
}
|
}
|
||||||
@ -416,7 +414,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,24 @@ impl<'de> Visitor<'de> for PrefixedHexVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct HexVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for HexVisitor {
|
||||||
|
type Value = Vec<u8>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("a hex string (irrelevant of prefix)")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
Ok(hex::decode(value.trim_start_matches("0x"))
|
||||||
|
.map_err(|e| de::Error::custom(format!("invalid hex ({:?})", e)))?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -8,3 +8,5 @@ edition = "2018"
|
|||||||
bytes = "0.4.9"
|
bytes = "0.4.9"
|
||||||
ethereum-types = "0.5"
|
ethereum-types = "0.5"
|
||||||
hashing = { path = "../hashing" }
|
hashing = { path = "../hashing" }
|
||||||
|
hex = "0.3"
|
||||||
|
yaml-rust = "0.4"
|
||||||
|
@ -69,7 +69,7 @@ Syntax:
|
|||||||
|
|
||||||
| Shorthand | Meaning |
|
| Shorthand | Meaning |
|
||||||
|:-------------|:----------------------------------------------------|
|
|:-------------|:----------------------------------------------------|
|
||||||
| `big` | ``big endian`` |
|
| `little` | ``little endian`` |
|
||||||
| `to_bytes` | convert to bytes. Params: ``(size, byte order)`` |
|
| `to_bytes` | convert to bytes. Params: ``(size, byte order)`` |
|
||||||
| `from_bytes` | convert from bytes. Params: ``(bytes, byte order)`` |
|
| `from_bytes` | convert from bytes. Params: ``(bytes, byte order)`` |
|
||||||
| `value` | the value to serialize |
|
| `value` | the value to serialize |
|
||||||
@ -82,7 +82,7 @@ Syntax:
|
|||||||
|
|
||||||
Convert directly to bytes the size of the int. (e.g. ``int16 = 2 bytes``)
|
Convert directly to bytes the size of the int. (e.g. ``int16 = 2 bytes``)
|
||||||
|
|
||||||
All integers are serialized as **big endian**.
|
All integers are serialized as **little endian**.
|
||||||
|
|
||||||
| Check to perform | Code |
|
| Check to perform | Code |
|
||||||
|:-----------------------|:------------------------|
|
|:-----------------------|:------------------------|
|
||||||
@ -92,7 +92,7 @@ All integers are serialized as **big endian**.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
buffer_size = int_size / 8
|
buffer_size = int_size / 8
|
||||||
return value.to_bytes(buffer_size, 'big')
|
return value.to_bytes(buffer_size, 'little')
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Address
|
#### Address
|
||||||
@ -131,7 +131,7 @@ For general `byte` type:
|
|||||||
value_bytes ]``
|
value_bytes ]``
|
||||||
|
|
||||||
```python
|
```python
|
||||||
byte_length = (len(value)).to_bytes(4, 'big')
|
byte_length = (len(value)).to_bytes(4, 'little')
|
||||||
return byte_length + value
|
return byte_length + value
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -175,12 +175,12 @@ At each step, the following checks should be made:
|
|||||||
Convert directly from bytes into integer utilising the number of bytes the same
|
Convert directly from bytes into integer utilising the number of bytes the same
|
||||||
size as the integer length. (e.g. ``int16 == 2 bytes``)
|
size as the integer length. (e.g. ``int16 == 2 bytes``)
|
||||||
|
|
||||||
All integers are interpreted as **big endian**.
|
All integers are interpreted as **little endian**.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
byte_length = int_size / 8
|
byte_length = int_size / 8
|
||||||
new_index = current_index + int_size
|
new_index = current_index + int_size
|
||||||
return int.from_bytes(rawbytes[current_index:current_index+int_size], 'big'), new_index
|
return int.from_bytes(rawbytes[current_index:current_index+int_size], 'little'), new_index
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Address
|
#### Address
|
||||||
@ -206,7 +206,7 @@ return rawbytes[current_index:current_index+32], new_index
|
|||||||
Get the length of the bytes, return the bytes.
|
Get the length of the bytes, return the bytes.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
bytes_length = int.from_bytes(rawbytes[current_index:current_index+4], 'big')
|
bytes_length = int.from_bytes(rawbytes[current_index:current_index+4], 'little')
|
||||||
new_index = current_index + 4 + bytes_lenth
|
new_index = current_index + 4 + bytes_lenth
|
||||||
return rawbytes[current_index+4:current_index+4+bytes_length], new_index
|
return rawbytes[current_index+4:current_index+4+bytes_length], new_index
|
||||||
```
|
```
|
||||||
@ -224,7 +224,7 @@ entire length of the list.
|
|||||||
| rawbytes has enough left for length | ``len(rawbytes) > current_index + 4`` |
|
| rawbytes has enough left for length | ``len(rawbytes) > current_index + 4`` |
|
||||||
|
|
||||||
```python
|
```python
|
||||||
total_length = int.from_bytes(rawbytes[current_index:current_index+4], 'big')
|
total_length = int.from_bytes(rawbytes[current_index:current_index+4], 'little')
|
||||||
new_index = current_index + 4 + total_length
|
new_index = current_index + 4 + total_length
|
||||||
item_index = current_index + 4
|
item_index = current_index + 4
|
||||||
deserialized_list = []
|
deserialized_list = []
|
||||||
|
@ -9,7 +9,7 @@ publish = false
|
|||||||
cargo-fuzz = true
|
cargo-fuzz = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ethereum-types = "0.4.0"
|
ethereum-types = "0.5"
|
||||||
|
|
||||||
[dependencies.ssz]
|
[dependencies.ssz]
|
||||||
path = ".."
|
path = ".."
|
||||||
@ -84,22 +84,22 @@ path = "fuzz_targets/fuzz_target_address_decode.rs"
|
|||||||
name = "fuzz_target_address_encode"
|
name = "fuzz_target_address_encode"
|
||||||
path = "fuzz_targets/fuzz_target_address_encode.rs"
|
path = "fuzz_targets/fuzz_target_address_encode.rs"
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_target_vec_decode"
|
|
||||||
path = "fuzz_targets/fuzz_target_vec_decode.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_target_vec_address_decode"
|
name = "fuzz_target_vec_address_decode"
|
||||||
path = "fuzz_targets/fuzz_target_vec_address_decode.rs"
|
path = "fuzz_targets/fuzz_target_vec_address_decode.rs"
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "fuzz_target_vec_u64_decode"
|
|
||||||
path = "fuzz_targets/fuzz_target_vec_u64_decode.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_target_vec_bool_decode"
|
name = "fuzz_target_vec_bool_decode"
|
||||||
path = "fuzz_targets/fuzz_target_vec_bool_decode.rs"
|
path = "fuzz_targets/fuzz_target_vec_bool_decode.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "fuzz_target_vec_decode"
|
||||||
|
path = "fuzz_targets/fuzz_target_vec_decode.rs"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "fuzz_target_vec_encode"
|
name = "fuzz_target_vec_encode"
|
||||||
path = "fuzz_targets/fuzz_target_vec_encode.rs"
|
path = "fuzz_targets/fuzz_target_vec_encode.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "fuzz_target_vec_u64_decode"
|
||||||
|
path = "fuzz_targets/fuzz_target_vec_u64_decode.rs"
|
||||||
|
@ -4,18 +4,17 @@ extern crate ethereum_types;
|
|||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ethereum_types::Address;
|
use ethereum_types::Address;
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{DecodeError, decode};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let result: Result<(Address, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let result: Result<Address, DecodeError> = decode(data);
|
||||||
if data.len() >= 20 {
|
if data.len() == 20 {
|
||||||
// Should have valid result
|
// Should have valid result
|
||||||
let (address, index) = result.unwrap();
|
let address = result.unwrap();
|
||||||
assert_eq!(index, 20);
|
|
||||||
assert_eq!(address, Address::from_slice(&data[..20]));
|
assert_eq!(address, Address::from_slice(&data[..20]));
|
||||||
} else {
|
} else {
|
||||||
// Length of less than 32 should return error
|
// Length of less than 32 should return error
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2,27 +2,23 @@
|
|||||||
#[macro_use] extern crate libfuzzer_sys;
|
#[macro_use] extern crate libfuzzer_sys;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{DecodeError, decode};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let result: Result<(bool, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let result: Result<bool, DecodeError> = decode(data);
|
||||||
if data.len() >= 1 {
|
if data.len() == 1 {
|
||||||
// TODO: change to little endian bytes
|
if data[0] == 1 {
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
let val_bool = result.unwrap();
|
||||||
if data[0] == u8::pow(2,7) {
|
|
||||||
let (val_bool, index) = result.unwrap();
|
|
||||||
assert!(val_bool);
|
assert!(val_bool);
|
||||||
assert_eq!(index, 1);
|
|
||||||
} else if data[0] == 0 {
|
} else if data[0] == 0 {
|
||||||
let (val_bool, index) = result.unwrap();
|
let val_bool = result.unwrap();
|
||||||
assert!(!val_bool);
|
assert!(!val_bool);
|
||||||
assert_eq!(index, 1);
|
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(result, Err(DecodeError::Invalid));
|
assert_eq!(result, Err(DecodeError::Invalid));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Length of 0 should return error
|
// Length of 0 should return error
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -15,8 +15,6 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
ssz.append(&val_bool);
|
ssz.append(&val_bool);
|
||||||
let ssz = ssz.drain();
|
let ssz = ssz.drain();
|
||||||
|
|
||||||
// TODO: change to little endian bytes
|
assert_eq!(val_bool, ssz[0]);
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
assert_eq!(val_bool, ssz[0] % u8::pow(2, 6));
|
|
||||||
assert_eq!(ssz.len(), 1);
|
assert_eq!(ssz.len(), 1);
|
||||||
});
|
});
|
||||||
|
@ -4,18 +4,17 @@ extern crate ethereum_types;
|
|||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{DecodeError, decode};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let result: Result<(H256, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let result: Result<H256, DecodeError> = decode(data);
|
||||||
if data.len() >= 32 {
|
if data.len() == 32 {
|
||||||
// Should have valid result
|
// Should have valid result
|
||||||
let (hash, index) = result.unwrap();
|
let hash = result.unwrap();
|
||||||
assert_eq!(index, 32);
|
|
||||||
assert_eq!(hash, H256::from_slice(&data[..32]));
|
assert_eq!(hash, H256::from_slice(&data[..32]));
|
||||||
} else {
|
} else {
|
||||||
// Length of less than 32 should return error
|
// Length of less than 32 should return error
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2,21 +2,18 @@
|
|||||||
#[macro_use] extern crate libfuzzer_sys;
|
#[macro_use] extern crate libfuzzer_sys;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{DecodeError, decode};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let result: Result<(u16, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let result: Result<u16, DecodeError> = decode(data);
|
||||||
if data.len() >= 2 {
|
if data.len() == 2 {
|
||||||
// Valid result
|
// Valid result
|
||||||
let (number_u16, index) = result.unwrap();
|
let number_u16 = result.unwrap();
|
||||||
assert_eq!(index, 2);
|
let val = u16::from_le_bytes([data[0], data[1]]);
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
let val = u16::from_be_bytes([data[0], data[1]]);
|
|
||||||
assert_eq!(number_u16, val);
|
assert_eq!(number_u16, val);
|
||||||
} else {
|
} else {
|
||||||
// Length of 0 or 1 should return error
|
// Length of 0 or 1 should return error
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -15,8 +15,6 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
ssz.append(&number_u16);
|
ssz.append(&number_u16);
|
||||||
let ssz = ssz.drain();
|
let ssz = ssz.drain();
|
||||||
|
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
assert_eq!(ssz.len(), 2);
|
assert_eq!(ssz.len(), 2);
|
||||||
assert_eq!(number_u16, u16::from_be_bytes([ssz[0], ssz[1]]));
|
assert_eq!(number_u16, u16::from_le_bytes([ssz[0], ssz[1]]));
|
||||||
});
|
});
|
||||||
|
@ -2,21 +2,18 @@
|
|||||||
#[macro_use] extern crate libfuzzer_sys;
|
#[macro_use] extern crate libfuzzer_sys;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{DecodeError, decode};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let result: Result<(u32, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let result: Result<u32, DecodeError> = decode(data);
|
||||||
if data.len() >= 4 {
|
if data.len() == 4 {
|
||||||
// Valid result
|
// Valid result
|
||||||
let (number_u32, index) = result.unwrap();
|
let number_u32 = result.unwrap();
|
||||||
assert_eq!(index, 4);
|
let val = u32::from_le_bytes([data[0], data[1], data[2], data[3]]);
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
let val = u32::from_be_bytes([data[0], data[1], data[2], data[3]]);
|
|
||||||
assert_eq!(number_u32, val);
|
assert_eq!(number_u32, val);
|
||||||
} else {
|
} else {
|
||||||
// Length less then 4 should return error
|
// Length not 4 should return error
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -15,8 +15,6 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
ssz.append(&number_u32);
|
ssz.append(&number_u32);
|
||||||
let ssz = ssz.drain();
|
let ssz = ssz.drain();
|
||||||
|
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
assert_eq!(ssz.len(), 4);
|
assert_eq!(ssz.len(), 4);
|
||||||
assert_eq!(number_u32, u32::from_be_bytes([ssz[0], ssz[1], ssz[2], ssz[3]]));
|
assert_eq!(number_u32, u32::from_le_bytes([ssz[0], ssz[1], ssz[2], ssz[3]]));
|
||||||
});
|
});
|
||||||
|
@ -2,18 +2,15 @@
|
|||||||
#[macro_use] extern crate libfuzzer_sys;
|
#[macro_use] extern crate libfuzzer_sys;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{DecodeError, decode};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let result: Result<(u64, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let result: Result<u64, DecodeError> = decode(data);
|
||||||
if data.len() >= 8 {
|
if data.len() == 8 {
|
||||||
// Valid result
|
// Valid result
|
||||||
let (number_u64, index) = result.unwrap();
|
let number_u64 = result.unwrap();
|
||||||
assert_eq!(index, 8);
|
let val = u64::from_le_bytes([
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
let val = u64::from_be_bytes([
|
|
||||||
data[0],
|
data[0],
|
||||||
data[1],
|
data[1],
|
||||||
data[2],
|
data[2],
|
||||||
@ -25,7 +22,7 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
]);
|
]);
|
||||||
assert_eq!(number_u64, val);
|
assert_eq!(number_u64, val);
|
||||||
} else {
|
} else {
|
||||||
// Length less then 8 should return error
|
// Length not 8 should return error
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,7 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
let mut number_u64 = 0;
|
let mut number_u64 = 0;
|
||||||
if data.len() >= 8 {
|
if data.len() >= 8 {
|
||||||
number_u64 = u64::from_be_bytes([
|
number_u64 = u64::from_le_bytes([
|
||||||
data[0],
|
data[0],
|
||||||
data[1],
|
data[1],
|
||||||
data[2],
|
data[2],
|
||||||
@ -24,10 +24,8 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
ssz.append(&number_u64);
|
ssz.append(&number_u64);
|
||||||
let ssz = ssz.drain();
|
let ssz = ssz.drain();
|
||||||
|
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
assert_eq!(ssz.len(), 8);
|
assert_eq!(ssz.len(), 8);
|
||||||
assert_eq!(number_u64, u64::from_be_bytes([
|
assert_eq!(number_u64, u64::from_le_bytes([
|
||||||
ssz[0],
|
ssz[0],
|
||||||
ssz[1],
|
ssz[1],
|
||||||
ssz[2],
|
ssz[2],
|
||||||
|
@ -2,20 +2,17 @@
|
|||||||
#[macro_use] extern crate libfuzzer_sys;
|
#[macro_use] extern crate libfuzzer_sys;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{DecodeError, decode};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let result: Result<(u8, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let result: Result<u8, DecodeError> = decode(data);
|
||||||
if data.len() >= 1 {
|
if data.len() == 1 {
|
||||||
// Should have valid result
|
// Should have valid result
|
||||||
let (number_u8, index) = result.unwrap();
|
let number_u8 = result.unwrap();
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
assert_eq!(index, 1);
|
|
||||||
assert_eq!(number_u8, data[0]);
|
assert_eq!(number_u8, data[0]);
|
||||||
} else {
|
} else {
|
||||||
// Length of 0 should return error
|
// Length not 1 should return error
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -15,8 +15,6 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
ssz.append(&number_u8);
|
ssz.append(&number_u8);
|
||||||
let ssz = ssz.drain();
|
let ssz = ssz.drain();
|
||||||
|
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
assert_eq!(number_u8, ssz[0]);
|
assert_eq!(number_u8, ssz[0]);
|
||||||
assert_eq!(ssz.len(), 1);
|
assert_eq!(ssz.len(), 1);
|
||||||
});
|
});
|
||||||
|
@ -2,19 +2,16 @@
|
|||||||
#[macro_use] extern crate libfuzzer_sys;
|
#[macro_use] extern crate libfuzzer_sys;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{DecodeError, decode};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
// Note: we assume architecture is 64 bit -> usize == 64 bits
|
// Note: we assume architecture is 64 bit -> usize == 64 bits
|
||||||
let result: Result<(usize, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let result: Result<usize, DecodeError> = decode(data);
|
||||||
if data.len() >= 8 {
|
if data.len() == 8 {
|
||||||
// Valid result
|
// Valid result
|
||||||
let (number_usize, index) = result.unwrap();
|
let number_usize = result.unwrap();
|
||||||
assert_eq!(index, 8);
|
let val = u64::from_le_bytes([
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
let val = u64::from_be_bytes([
|
|
||||||
data[0],
|
data[0],
|
||||||
data[1],
|
data[1],
|
||||||
data[2],
|
data[2],
|
||||||
@ -27,6 +24,6 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
assert_eq!(number_usize, val as usize);
|
assert_eq!(number_usize, val as usize);
|
||||||
} else {
|
} else {
|
||||||
// Length less then 8 should return error
|
// Length less then 8 should return error
|
||||||
assert_eq!(result, Err(DecodeError::TooShort));
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,7 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
let mut number_usize = 0;
|
let mut number_usize = 0;
|
||||||
if data.len() >= 8 {
|
if data.len() >= 8 {
|
||||||
number_usize = u64::from_be_bytes([
|
number_usize = u64::from_le_bytes([
|
||||||
data[0],
|
data[0],
|
||||||
data[1],
|
data[1],
|
||||||
data[2],
|
data[2],
|
||||||
@ -24,10 +24,8 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
ssz.append(&number_usize);
|
ssz.append(&number_usize);
|
||||||
let ssz = ssz.drain();
|
let ssz = ssz.drain();
|
||||||
|
|
||||||
// TODO: change to little endian bytes
|
|
||||||
// https://github.com/sigp/lighthouse/issues/215
|
|
||||||
assert_eq!(ssz.len(), 8);
|
assert_eq!(ssz.len(), 8);
|
||||||
assert_eq!(number_usize, u64::from_be_bytes([
|
assert_eq!(number_usize, u64::from_le_bytes([
|
||||||
ssz[0],
|
ssz[0],
|
||||||
ssz[1],
|
ssz[1],
|
||||||
ssz[2],
|
ssz[2],
|
||||||
|
@ -4,9 +4,9 @@ extern crate ethereum_types;
|
|||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ethereum_types::{Address};
|
use ethereum_types::{Address};
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{decode, DecodeError};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let _result: Result<(Vec<Address>, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let _result: Result<Vec<Address>, DecodeError> = decode(data);
|
||||||
});
|
});
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#[macro_use] extern crate libfuzzer_sys;
|
#[macro_use] extern crate libfuzzer_sys;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{decode, DecodeError};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let _result: Result<(Vec<bool>, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let _result: Result<Vec<bool>, DecodeError> = decode(data);
|
||||||
});
|
});
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ethereum_types::{Address, H256};
|
use ssz::{decode, DecodeError, Decodable};
|
||||||
use ssz::{DecodeError, Decodable};
|
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let _result: Result<(Vec<u8>, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let _result: Result<Vec<u8>, DecodeError> = decode(data);
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ethereum_types::{Address, H256};
|
|
||||||
use ssz::SszStream;
|
use ssz::SszStream;
|
||||||
|
|
||||||
// Fuzz ssz_encode()
|
// Fuzz ssz_encode()
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#[macro_use] extern crate libfuzzer_sys;
|
#[macro_use] extern crate libfuzzer_sys;
|
||||||
extern crate ssz;
|
extern crate ssz;
|
||||||
|
|
||||||
use ssz::{DecodeError, Decodable};
|
use ssz::{decode, DecodeError};
|
||||||
|
|
||||||
// Fuzz ssz_decode()
|
// Fuzz ssz_decode()
|
||||||
fuzz_target!(|data: &[u8]| {
|
fuzz_target!(|data: &[u8]| {
|
||||||
let _result: Result<(Vec<u64>, usize), DecodeError> = Decodable::ssz_decode(data, 0);
|
let _result: Result<Vec<u64>, DecodeError> = decode(data);
|
||||||
});
|
});
|
||||||
|
@ -13,16 +13,23 @@ 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>
|
/// Check on totality for underflowing the length of bytes and overflow checks done per container
|
||||||
|
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.
|
||||||
@ -65,7 +72,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Given some number of bytes, interpret the first four
|
/// Given some number of bytes, interpret the first four
|
||||||
/// bytes as a 32-bit big-endian integer and return the
|
/// bytes as a 32-bit little-endian integer and return the
|
||||||
/// result.
|
/// result.
|
||||||
pub fn decode_length(
|
pub fn decode_length(
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
@ -82,7 +89,7 @@ pub fn decode_length(
|
|||||||
.take(index + length_bytes)
|
.take(index + length_bytes)
|
||||||
.skip(index)
|
.skip(index)
|
||||||
{
|
{
|
||||||
let offset = (index + length_bytes - i - 1) * 8;
|
let offset = (i - index) * 8;
|
||||||
len |= (*byte as usize) << offset;
|
len |= (*byte as usize) << offset;
|
||||||
}
|
}
|
||||||
Ok(len)
|
Ok(len)
|
||||||
@ -90,18 +97,18 @@ pub fn decode_length(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::super::encode::encode_length;
|
use super::super::encode::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ssz_decode_length() {
|
fn test_ssz_decode_length() {
|
||||||
let decoded = decode_length(&vec![0, 0, 0, 1], 0, LENGTH_BYTES);
|
let decoded = decode_length(&vec![1, 0, 0, 0], 0, LENGTH_BYTES);
|
||||||
assert_eq!(decoded.unwrap(), 1);
|
assert_eq!(decoded.unwrap(), 1);
|
||||||
|
|
||||||
let decoded = decode_length(&vec![0, 0, 1, 0], 0, LENGTH_BYTES);
|
let decoded = decode_length(&vec![0, 1, 0, 0], 0, LENGTH_BYTES);
|
||||||
assert_eq!(decoded.unwrap(), 256);
|
assert_eq!(decoded.unwrap(), 256);
|
||||||
|
|
||||||
let decoded = decode_length(&vec![0, 0, 1, 255], 0, LENGTH_BYTES);
|
let decoded = decode_length(&vec![255, 1, 0, 0], 0, LENGTH_BYTES);
|
||||||
assert_eq!(decoded.unwrap(), 511);
|
assert_eq!(decoded.unwrap(), 511);
|
||||||
|
|
||||||
let decoded = decode_length(&vec![255, 255, 255, 255], 0, LENGTH_BYTES);
|
let decoded = decode_length(&vec![255, 255, 255, 255], 0, LENGTH_BYTES);
|
||||||
@ -132,21 +139,35 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_decode_ssz_list() {
|
||||||
|
let test_vec: Vec<u16> = vec![256; 12];
|
||||||
|
let mut stream = SszStream::new();
|
||||||
|
stream.append_vec(&test_vec);
|
||||||
|
let ssz = stream.drain();
|
||||||
|
|
||||||
|
// u16
|
||||||
|
let decoded: (Vec<u16>, usize) = decode_ssz_list(&ssz, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(decoded.0, test_vec);
|
||||||
|
assert_eq!(decoded.1, LENGTH_BYTES + (12 * 2));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_ssz_list() {
|
fn test_decode_ssz_list() {
|
||||||
// u16
|
// u16
|
||||||
let v: Vec<u16> = vec![10, 10, 10, 10];
|
let v: Vec<u16> = vec![10, 10, 10, 10];
|
||||||
let decoded: (Vec<u16>, usize) =
|
let decoded: (Vec<u16>, usize) =
|
||||||
decode_ssz_list(&vec![0, 0, 0, 8, 0, 10, 0, 10, 0, 10, 0, 10], 0).unwrap();
|
decode_ssz_list(&vec![8, 0, 0, 0, 10, 0, 10, 0, 10, 0, 10, 0], 0).unwrap();
|
||||||
|
|
||||||
assert_eq!(decoded.0, v);
|
assert_eq!(decoded.0, v);
|
||||||
assert_eq!(decoded.1, 12);
|
assert_eq!(decoded.1, LENGTH_BYTES + (4 * 2));
|
||||||
|
|
||||||
// u32
|
// u32
|
||||||
let v: Vec<u32> = vec![10, 10, 10, 10];
|
let v: Vec<u32> = vec![10, 10, 10, 10];
|
||||||
let decoded: (Vec<u32>, usize) = decode_ssz_list(
|
let decoded: (Vec<u32>, usize) = decode_ssz_list(
|
||||||
&vec![
|
&vec![
|
||||||
0, 0, 0, 16, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10,
|
16, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 00,
|
||||||
],
|
],
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
@ -158,36 +179,37 @@ mod tests {
|
|||||||
let v: Vec<u64> = vec![10, 10, 10, 10];
|
let v: Vec<u64> = vec![10, 10, 10, 10];
|
||||||
let decoded: (Vec<u64>, usize) = decode_ssz_list(
|
let decoded: (Vec<u64>, usize) = decode_ssz_list(
|
||||||
&vec![
|
&vec![
|
||||||
0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
|
32, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0,
|
||||||
10, 0, 0, 0, 0, 0, 0, 0, 10,
|
0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
|
||||||
],
|
],
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(decoded.0, v);
|
assert_eq!(decoded.0, v);
|
||||||
assert_eq!(decoded.1, 36);
|
assert_eq!(decoded.1, LENGTH_BYTES + (8 * 4));
|
||||||
|
|
||||||
// Check that it can accept index
|
// Check that it can accept index
|
||||||
let v: Vec<usize> = vec![15, 15, 15, 15];
|
let v: Vec<usize> = vec![15, 15, 15, 15];
|
||||||
|
let offset = 10;
|
||||||
let decoded: (Vec<usize>, usize) = decode_ssz_list(
|
let decoded: (Vec<usize>, usize) = decode_ssz_list(
|
||||||
&vec![
|
&vec![
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0,
|
||||||
0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15,
|
0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0,
|
||||||
],
|
],
|
||||||
10,
|
offset,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(decoded.0, v);
|
assert_eq!(decoded.0, v);
|
||||||
assert_eq!(decoded.1, 46);
|
assert_eq!(decoded.1, offset + LENGTH_BYTES + (8 * 4));
|
||||||
|
|
||||||
// Check that length > bytes throws error
|
// Check that length > bytes throws error
|
||||||
let decoded: Result<(Vec<usize>, usize), DecodeError> =
|
let decoded: Result<(Vec<usize>, usize), DecodeError> =
|
||||||
decode_ssz_list(&vec![0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 15], 0);
|
decode_ssz_list(&vec![32, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0], 0);
|
||||||
assert_eq!(decoded, Err(DecodeError::TooShort));
|
assert_eq!(decoded, Err(DecodeError::TooShort));
|
||||||
|
|
||||||
// Check that incorrect index throws error
|
// Check that incorrect index throws error
|
||||||
let decoded: Result<(Vec<usize>, usize), DecodeError> =
|
let decoded: Result<(Vec<usize>, usize), DecodeError> =
|
||||||
decode_ssz_list(&vec![0, 0, 0, 0, 0, 0, 0, 15], 16);
|
decode_ssz_list(&vec![15, 0, 0, 0, 0, 0, 0, 0], 16);
|
||||||
assert_eq!(decoded, Err(DecodeError::TooShort));
|
assert_eq!(decoded, Err(DecodeError::TooShort));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,13 +70,13 @@ impl SszStream {
|
|||||||
/// Encode some length into a ssz size prefix.
|
/// Encode some length into a ssz size prefix.
|
||||||
///
|
///
|
||||||
/// The ssz size prefix is 4 bytes, which is treated as a continuious
|
/// The ssz size prefix is 4 bytes, which is treated as a continuious
|
||||||
/// 32bit big-endian integer.
|
/// 32bit little-endian integer.
|
||||||
pub fn encode_length(len: usize, length_bytes: usize) -> Vec<u8> {
|
pub fn encode_length(len: usize, length_bytes: usize) -> Vec<u8> {
|
||||||
assert!(length_bytes > 0); // For sanity
|
assert!(length_bytes > 0); // For sanity
|
||||||
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 - i - 1) * 8;
|
let offset = i * 8;
|
||||||
*header_byte = ((len >> offset) & 0xff) as u8;
|
*header_byte = ((len >> offset) & 0xff) as u8;
|
||||||
}
|
}
|
||||||
header
|
header
|
||||||
@ -95,15 +95,27 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_encode_length_4_bytes() {
|
fn test_encode_length_4_bytes() {
|
||||||
assert_eq!(encode_length(0, LENGTH_BYTES), vec![0; 4]);
|
assert_eq!(encode_length(0, LENGTH_BYTES), vec![0; 4]);
|
||||||
assert_eq!(encode_length(1, LENGTH_BYTES), vec![0, 0, 0, 1]);
|
assert_eq!(encode_length(1, LENGTH_BYTES), vec![1, 0, 0, 0]);
|
||||||
assert_eq!(encode_length(255, LENGTH_BYTES), vec![0, 0, 0, 255]);
|
assert_eq!(encode_length(255, LENGTH_BYTES), vec![255, 0, 0, 0]);
|
||||||
assert_eq!(encode_length(256, LENGTH_BYTES), vec![0, 0, 1, 0]);
|
assert_eq!(encode_length(256, LENGTH_BYTES), vec![0, 1, 0, 0]);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
encode_length(4294967295, LENGTH_BYTES), // 2^(3*8) - 1
|
encode_length(4294967295, LENGTH_BYTES), // 2^(3*8) - 1
|
||||||
vec![255, 255, 255, 255]
|
vec![255, 255, 255, 255]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_lower_length() {
|
||||||
|
assert_eq!(encode_length(0, LENGTH_BYTES - 2), vec![0; 2]);
|
||||||
|
assert_eq!(encode_length(1, LENGTH_BYTES - 2), vec![1, 0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_higher_length() {
|
||||||
|
assert_eq!(encode_length(0, LENGTH_BYTES + 2), vec![0; 6]);
|
||||||
|
assert_eq!(encode_length(1, LENGTH_BYTES + 2), vec![1, 0, 0, 0, 0, 0]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_encode_length_4_bytes_panic() {
|
fn test_encode_length_4_bytes_panic() {
|
||||||
@ -117,8 +129,42 @@ mod tests {
|
|||||||
stream.append_vec(&test_vec);
|
stream.append_vec(&test_vec);
|
||||||
let ssz = stream.drain();
|
let ssz = stream.drain();
|
||||||
|
|
||||||
assert_eq!(ssz.len(), 4 + (12 * 2));
|
assert_eq!(ssz.len(), LENGTH_BYTES + (12 * 2));
|
||||||
assert_eq!(ssz[0..4], *vec![0, 0, 0, 24]);
|
assert_eq!(ssz[0..4], *vec![24, 0, 0, 0]);
|
||||||
assert_eq!(ssz[4..6], *vec![1, 0]);
|
assert_eq!(ssz[4..6], *vec![0, 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_mixed_prefixed() {
|
||||||
|
let test_vec: Vec<u16> = vec![100, 200];
|
||||||
|
let test_value: u8 = 5;
|
||||||
|
|
||||||
|
let mut stream = SszStream::new();
|
||||||
|
stream.append_vec(&test_vec);
|
||||||
|
stream.append(&test_value);
|
||||||
|
let ssz = stream.drain();
|
||||||
|
|
||||||
|
assert_eq!(ssz.len(), LENGTH_BYTES + (2 * 2) + 1);
|
||||||
|
assert_eq!(ssz[0..4], *vec![4, 0, 0, 0]);
|
||||||
|
assert_eq!(ssz[4..6], *vec![100, 0]);
|
||||||
|
assert_eq!(ssz[6..8], *vec![200, 0]);
|
||||||
|
assert_eq!(ssz[8], 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encode_mixed_postfixed() {
|
||||||
|
let test_value: u8 = 5;
|
||||||
|
let test_vec: Vec<u16> = vec![100, 200];
|
||||||
|
|
||||||
|
let mut stream = SszStream::new();
|
||||||
|
stream.append(&test_value);
|
||||||
|
stream.append_vec(&test_vec);
|
||||||
|
let ssz = stream.drain();
|
||||||
|
|
||||||
|
assert_eq!(ssz.len(), 1 + LENGTH_BYTES + (2 * 2));
|
||||||
|
assert_eq!(ssz[0], 5);
|
||||||
|
assert_eq!(ssz[1..5], *vec![4, 0, 0, 0]);
|
||||||
|
assert_eq!(ssz[5..7], *vec![100, 0]);
|
||||||
|
assert_eq!(ssz[7..9], *vec![200, 0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 - i - 1) * 8;
|
let offset = (i - index) * 8;
|
||||||
result |= ($type::from(*byte)) << offset;
|
result |= ($type::from(*byte)) << offset;
|
||||||
}
|
}
|
||||||
Ok((result, end_bytes))
|
Ok((result, end_bytes))
|
||||||
@ -65,7 +65,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))
|
||||||
@ -104,7 +104,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]
|
||||||
@ -138,139 +138,169 @@ 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![0, 16];
|
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![1, 0];
|
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, 0, 1, 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, 0, 1, 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, 200, 1, 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![0, 0, 1];
|
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, 255, 0, 0, 0, 0, 0, 0, 0];
|
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, 0, 1], 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_u8_array() {
|
fn test_decode_u8_array() {
|
||||||
let ssz = vec![0, 1, 2, 3];
|
let ssz = vec![0, 1, 2, 3];
|
||||||
let (result, index): ([u8; 4], usize) = decode_ssz(&ssz, 0).unwrap();
|
let result: [u8; 4] = decode(&ssz).unwrap();
|
||||||
assert_eq!(index, 4);
|
assert_eq!(result.len(), 4);
|
||||||
assert_eq!(result, [0, 1, 2, 3]);
|
assert_eq!(result, [0, 1, 2, 3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,9 @@ macro_rules! impl_encodable_for_uint {
|
|||||||
// Match bit size with encoding
|
// Match bit size with encoding
|
||||||
match $bit_size {
|
match $bit_size {
|
||||||
8 => buf.put_u8(*self as u8),
|
8 => buf.put_u8(*self as u8),
|
||||||
16 => buf.put_u16_be(*self as u16),
|
16 => buf.put_u16_le(*self as u16),
|
||||||
32 => buf.put_u32_be(*self as u32),
|
32 => buf.put_u32_le(*self as u32),
|
||||||
64 => buf.put_u64_be(*self as u64),
|
64 => buf.put_u64_le(*self as u64),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ impl_encodable_for_u8_array!(4);
|
|||||||
|
|
||||||
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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,17 +136,17 @@ mod tests {
|
|||||||
let x: u16 = 1;
|
let x: u16 = 1;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 1]);
|
assert_eq!(ssz.drain(), vec![1, 0]);
|
||||||
|
|
||||||
let x: u16 = 100;
|
let x: u16 = 100;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 100]);
|
assert_eq!(ssz.drain(), vec![100, 0]);
|
||||||
|
|
||||||
let x: u16 = 1 << 8;
|
let x: u16 = 1 << 8;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![1, 0]);
|
assert_eq!(ssz.drain(), vec![0, 1]);
|
||||||
|
|
||||||
let x: u16 = 65535;
|
let x: u16 = 65535;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
@ -159,22 +159,22 @@ mod tests {
|
|||||||
let x: u32 = 1;
|
let x: u32 = 1;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 0, 0, 1]);
|
assert_eq!(ssz.drain(), vec![1, 0, 0, 0]);
|
||||||
|
|
||||||
let x: u32 = 100;
|
let x: u32 = 100;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 0, 0, 100]);
|
assert_eq!(ssz.drain(), vec![100, 0, 0, 0]);
|
||||||
|
|
||||||
let x: u32 = 1 << 16;
|
let x: u32 = 1 << 16;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 1, 0, 0]);
|
assert_eq!(ssz.drain(), vec![0, 0, 1, 0]);
|
||||||
|
|
||||||
let x: u32 = 1 << 24;
|
let x: u32 = 1 << 24;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![1, 0, 0, 0]);
|
assert_eq!(ssz.drain(), vec![0, 0, 0, 1]);
|
||||||
|
|
||||||
let x: u32 = !0;
|
let x: u32 = !0;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
@ -187,17 +187,17 @@ mod tests {
|
|||||||
let x: u64 = 1;
|
let x: u64 = 1;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 1]);
|
assert_eq!(ssz.drain(), vec![1, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
let x: u64 = 100;
|
let x: u64 = 100;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 100]);
|
assert_eq!(ssz.drain(), vec![100, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
let x: u64 = 1 << 32;
|
let x: u64 = 1 << 32;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 0, 0, 1, 0, 0, 0, 0]);
|
assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 1, 0, 0, 0]);
|
||||||
|
|
||||||
let x: u64 = !0;
|
let x: u64 = !0;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
@ -210,17 +210,17 @@ mod tests {
|
|||||||
let x: usize = 1;
|
let x: usize = 1;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 1]);
|
assert_eq!(ssz.drain(), vec![1, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
let x: usize = 100;
|
let x: usize = 100;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 100]);
|
assert_eq!(ssz.drain(), vec![100, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
let x: usize = 1 << 32;
|
let x: usize = 1 << 32;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
ssz.append(&x);
|
ssz.append(&x);
|
||||||
assert_eq!(ssz.drain(), vec![0, 0, 0, 1, 0, 0, 0, 0]);
|
assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 1, 0, 0, 0]);
|
||||||
|
|
||||||
let x: usize = !0;
|
let x: usize = !0;
|
||||||
let mut ssz = SszStream::new();
|
let mut ssz = SszStream::new();
|
||||||
@ -228,6 +228,27 @@ mod tests {
|
|||||||
assert_eq!(ssz.drain(), vec![255, 255, 255, 255, 255, 255, 255, 255]);
|
assert_eq!(ssz.drain(), vec![255, 255, 255, 255, 255, 255, 255, 255]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ssz_mixed() {
|
||||||
|
let mut stream = SszStream::new();
|
||||||
|
|
||||||
|
let h = Address::zero();
|
||||||
|
let a: u8 = 100;
|
||||||
|
let b: u16 = 65535;
|
||||||
|
let c: u32 = 1 << 24;
|
||||||
|
|
||||||
|
stream.append(&h);
|
||||||
|
stream.append(&a);
|
||||||
|
stream.append(&b);
|
||||||
|
stream.append(&c);
|
||||||
|
|
||||||
|
let ssz = stream.drain();
|
||||||
|
assert_eq!(ssz[0..20], *vec![0; 20]);
|
||||||
|
assert_eq!(ssz[20], 100);
|
||||||
|
assert_eq!(ssz[21..23], *vec![255, 255]);
|
||||||
|
assert_eq!(ssz[23..27], *vec![0, 0, 0, 1]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ssz_encode_bool() {
|
fn test_ssz_encode_bool() {
|
||||||
let x: bool = false;
|
let x: bool = false;
|
||||||
@ -238,7 +259,7 @@ 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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -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};
|
||||||
@ -38,3 +38,193 @@ where
|
|||||||
ssz_stream.append(val);
|
ssz_stream.append(val);
|
||||||
ssz_stream.drain()
|
ssz_stream.drain()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
extern crate hex;
|
||||||
|
extern crate yaml_rust;
|
||||||
|
|
||||||
|
use self::yaml_rust::yaml;
|
||||||
|
use super::*;
|
||||||
|
use std::{fs::File, io::prelude::*, path::PathBuf};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_vector_uint_bounds() {
|
||||||
|
let mut file = {
|
||||||
|
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
file_path_buf.push("src/test_vectors/uint_bounds.yaml");
|
||||||
|
|
||||||
|
File::open(file_path_buf).unwrap()
|
||||||
|
};
|
||||||
|
let mut yaml_str = String::new();
|
||||||
|
file.read_to_string(&mut yaml_str).unwrap();
|
||||||
|
let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap();
|
||||||
|
let doc = &docs[0];
|
||||||
|
|
||||||
|
// Load test cases
|
||||||
|
let test_cases = doc["test_cases"].clone();
|
||||||
|
|
||||||
|
for test_case in test_cases {
|
||||||
|
// Only the valid cases are checked as parse::<uX>() will fail for all invalid cases
|
||||||
|
if test_case["valid"].as_bool().unwrap() {
|
||||||
|
// Convert test vector 'ssz' encoded yaml to Vec<u8>
|
||||||
|
let ssz = test_case["ssz"].as_str().unwrap().trim_start_matches("0x");
|
||||||
|
let test_vector_bytes = hex::decode(ssz).unwrap();
|
||||||
|
|
||||||
|
// Convert test vector 'value' to ssz encoded bytes
|
||||||
|
let mut bytes: Vec<u8>;
|
||||||
|
match test_case["type"].as_str().unwrap() {
|
||||||
|
"uint8" => {
|
||||||
|
let value: u8 = test_case["value"].as_str().unwrap().parse::<u8>().unwrap();
|
||||||
|
bytes = ssz_encode::<u8>(&value); // check encoding
|
||||||
|
|
||||||
|
// Check decoding
|
||||||
|
let decoded = decode::<u8>(&test_vector_bytes).unwrap();
|
||||||
|
assert_eq!(decoded, value);
|
||||||
|
}
|
||||||
|
"uint16" => {
|
||||||
|
let value: u16 =
|
||||||
|
test_case["value"].as_str().unwrap().parse::<u16>().unwrap();
|
||||||
|
bytes = ssz_encode::<u16>(&value);
|
||||||
|
|
||||||
|
// Check decoding
|
||||||
|
let decoded = decode::<u16>(&test_vector_bytes).unwrap();
|
||||||
|
assert_eq!(decoded, value);
|
||||||
|
}
|
||||||
|
"uint32" => {
|
||||||
|
let value: u32 =
|
||||||
|
test_case["value"].as_str().unwrap().parse::<u32>().unwrap();
|
||||||
|
bytes = ssz_encode::<u32>(&value);
|
||||||
|
|
||||||
|
// Check decoding
|
||||||
|
let decoded = decode::<u32>(&test_vector_bytes).unwrap();
|
||||||
|
assert_eq!(decoded, value);
|
||||||
|
}
|
||||||
|
"uint64" => {
|
||||||
|
let value: u64 =
|
||||||
|
test_case["value"].as_str().unwrap().parse::<u64>().unwrap();
|
||||||
|
bytes = ssz_encode::<u64>(&value);
|
||||||
|
|
||||||
|
// Check decoding
|
||||||
|
let decoded = decode::<u64>(&test_vector_bytes).unwrap();
|
||||||
|
assert_eq!(decoded, value);
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
assert_eq!(test_vector_bytes, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_vector_uint_random() {
|
||||||
|
let mut file = {
|
||||||
|
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
file_path_buf.push("src/test_vectors/uint_random.yaml");
|
||||||
|
|
||||||
|
File::open(file_path_buf).unwrap()
|
||||||
|
};
|
||||||
|
let mut yaml_str = String::new();
|
||||||
|
file.read_to_string(&mut yaml_str).unwrap();
|
||||||
|
let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap();
|
||||||
|
let doc = &docs[0];
|
||||||
|
|
||||||
|
// Load test cases
|
||||||
|
let test_cases = doc["test_cases"].clone();
|
||||||
|
|
||||||
|
for test_case in test_cases {
|
||||||
|
// Only the valid cases are checked as parse::<uX>() will fail for all invalid cases
|
||||||
|
if test_case["valid"].as_bool().unwrap() {
|
||||||
|
// Convert test vector 'ssz' encoded yaml to Vec<u8>
|
||||||
|
let ssz = test_case["ssz"].as_str().unwrap().trim_start_matches("0x");
|
||||||
|
let test_vector_bytes = hex::decode(ssz).unwrap();
|
||||||
|
|
||||||
|
// Convert test vector 'value' to ssz encoded bytes
|
||||||
|
let mut bytes: Vec<u8>;
|
||||||
|
match test_case["type"].as_str().unwrap() {
|
||||||
|
"uint8" => {
|
||||||
|
let value: u8 = test_case["value"].as_str().unwrap().parse::<u8>().unwrap();
|
||||||
|
bytes = ssz_encode::<u8>(&value); // check encoding
|
||||||
|
|
||||||
|
// Check decoding
|
||||||
|
let decoded = decode::<u8>(&test_vector_bytes).unwrap();
|
||||||
|
assert_eq!(decoded, value);
|
||||||
|
}
|
||||||
|
"uint16" => {
|
||||||
|
let value: u16 =
|
||||||
|
test_case["value"].as_str().unwrap().parse::<u16>().unwrap();
|
||||||
|
bytes = ssz_encode::<u16>(&value);
|
||||||
|
|
||||||
|
// Check decoding
|
||||||
|
let decoded = decode::<u16>(&test_vector_bytes).unwrap();
|
||||||
|
assert_eq!(decoded, value);
|
||||||
|
}
|
||||||
|
"uint32" => {
|
||||||
|
let value: u32 =
|
||||||
|
test_case["value"].as_str().unwrap().parse::<u32>().unwrap();
|
||||||
|
bytes = ssz_encode::<u32>(&value);
|
||||||
|
|
||||||
|
// Check decoding
|
||||||
|
let decoded = decode::<u32>(&test_vector_bytes).unwrap();
|
||||||
|
assert_eq!(decoded, value);
|
||||||
|
}
|
||||||
|
"uint64" => {
|
||||||
|
let value: u64 =
|
||||||
|
test_case["value"].as_str().unwrap().parse::<u64>().unwrap();
|
||||||
|
bytes = ssz_encode::<u64>(&value);
|
||||||
|
|
||||||
|
// Check decoding
|
||||||
|
let decoded = decode::<u64>(&test_vector_bytes).unwrap();
|
||||||
|
assert_eq!(decoded, value);
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
assert_eq!(test_vector_bytes, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_vector_uint_wrong_length() {
|
||||||
|
let mut file = {
|
||||||
|
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
file_path_buf.push("src/test_vectors/uint_wrong_length.yaml");
|
||||||
|
|
||||||
|
File::open(file_path_buf).unwrap()
|
||||||
|
};
|
||||||
|
let mut yaml_str = String::new();
|
||||||
|
file.read_to_string(&mut yaml_str).unwrap();
|
||||||
|
let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap();
|
||||||
|
let doc = &docs[0];
|
||||||
|
|
||||||
|
// Load test cases
|
||||||
|
let test_cases = doc["test_cases"].clone();
|
||||||
|
|
||||||
|
for test_case in test_cases {
|
||||||
|
// Convert test vector 'ssz' encoded yaml to Vec<u8>
|
||||||
|
let ssz = test_case["ssz"].as_str().unwrap().trim_start_matches("0x");
|
||||||
|
let test_vector_bytes = hex::decode(ssz).unwrap();
|
||||||
|
|
||||||
|
// Attempt to decode invalid ssz bytes
|
||||||
|
match test_case["type"].as_str().unwrap() {
|
||||||
|
"uint8" => {
|
||||||
|
let decoded = decode::<u8>(&test_vector_bytes);
|
||||||
|
assert!(decoded.is_err());
|
||||||
|
}
|
||||||
|
"uint16" => {
|
||||||
|
let decoded = decode::<u16>(&test_vector_bytes);
|
||||||
|
assert!(decoded.is_err());
|
||||||
|
}
|
||||||
|
"uint32" => {
|
||||||
|
let decoded = decode::<u32>(&test_vector_bytes);
|
||||||
|
assert!(decoded.is_err());
|
||||||
|
}
|
||||||
|
"uint64" => {
|
||||||
|
let decoded = decode::<u64>(&test_vector_bytes);
|
||||||
|
assert!(decoded.is_err());
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1924
eth2/utils/ssz/src/test_vectors/uint_bounds.yaml
Normal file
1924
eth2/utils/ssz/src/test_vectors/uint_bounds.yaml
Normal file
File diff suppressed because it is too large
Load Diff
5124
eth2/utils/ssz/src/test_vectors/uint_random.yaml
Normal file
5124
eth2/utils/ssz/src/test_vectors/uint_random.yaml
Normal file
File diff suppressed because it is too large
Load Diff
6640
eth2/utils/ssz/src/test_vectors/uint_wrong_length.yaml
Normal file
6640
eth2/utils/ssz/src/test_vectors/uint_wrong_length.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -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, Signature, Slot};
|
use types::{BeaconBlock, Signature, Slot};
|
||||||
|
|
||||||
@ -42,8 +42,7 @@ impl BeaconNode for BeaconBlockGrpcClient {
|
|||||||
let block = reply.get_block();
|
let block = reply.get_block();
|
||||||
let ssz = block.get_ssz();
|
let ssz = block.get_ssz();
|
||||||
|
|
||||||
let (block, _i) =
|
let block = decode::<BeaconBlock>(&ssz).map_err(|_| BeaconNodeError::DecodeFailure)?;
|
||||||
BeaconBlock::ssz_decode(&ssz, 0).map_err(|_| BeaconNodeError::DecodeFailure)?;
|
|
||||||
|
|
||||||
Ok(Some(block))
|
Ok(Some(block))
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user