# SSZ comparison Attempting to compare the result of Ssz from py-ssz (python library) and eth2-ssz (rust crate) The sede structure is currently being tried out by me in the hopes of implementing it as the epoch accumulator in the portal network ## Sedes Structure `List[ Container[ block_hash : byte32, total_difficulty : int], 2048]` ## Test data The examples are constructed using the data of Block#0 which resembles: ``` Block { block_hash:String = "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", total_difficulty:u64 = 17179869184 } ``` ## Example of code snippet ### Python (py-ssz) ``` from typing import NamedTuple, Optional, Tuple, List from eth_typing import Hash32 import ssz from ssz import sedes as ssz_sedes from eth_utils import to_bytes class AccumulatorLeaf(NamedTuple): block_hash: Hash32 total_difficulty: int AccumulatorLeafSedes = ssz_sedes.Container( field_sedes=(ssz_sedes.bytes32, ssz_sedes.uint256) ) EpochAccumulatorSedes = ssz_sedes.List(AccumulatorLeafSedes, max_length=EPOCH_SIZE) class Block: def __init__(self, block_hash: Hash32, total_difficulty: int): self.block_hash = block_hash self.total_difficulty = total_difficulty def test() : ##block data here block = Block("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",17179869184) leaf = AccumulatorLeaf( block_hash=Hash32(to_bytes(hexstr=block.block_hash)), total_difficulty=int(block.total_difficulty), ) epoch_accumulator = (leaf,) #getting the hash epoch_accumulator_root = ssz.get_hash_tree_root( epoch_accumulator, sedes=EpochAccumulatorSedes, ) #encode to ssz epoch_encoded = ssz.encode(epoch_accumulator, sedes=EpochAccumulatorSedes) ``` hash result (converted to readable form using HexBytes): `"0x30d1ed68b3b224f25c19cf109a0ebf354b407728432aabe83fd608ee8ec1dca7"` epoch_encoded result (printing out value of each byte): `[212, 229, 103, 64, 248, 118, 174, 248, 192, 16, 184, 106, 64, 213, 245, 103, 69, 161, 24, 208, 144, 106, 52, 230, 154, 236, 140, 13, 177, 203, 143, 163, 0, 0, 0, 0, 4, 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]` ### Rust (eth2-ssz) ``` use ethereum_types::H256; use ssz::{Decode, DecodeError, Encode}; use ssz_derive::{Decode, Encode}; use ssz_types::{typenum, VariableList}; use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use typenum::U2048; #[derive(Clone, Copy, Encode, Decode, Debug, PartialEq, TreeHash, Default)] pub struct EpochSede { block_hash: H256, total_difficulty: U256, } #[derive(Debug, Clone)] pub struct Block { pub block_hash: String, pub total_difficulty: u64, } fn main() { //defined block data let block = Block { block_hash: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3".to_string(), total_difficulty: 17179869184 }; let serialized = impl_serde::serialize::from_hex(&block.block_hash).unwrap(); let typed_block_hash = <H256>::from_slice(&serialized[..]); //convert total_diffuculty to U256 let total_difficulty = let epoch_sede = EpochSede::new(typed_block_hash, total_difficulty); let epoch_accumulator: Vec<EpochSede> = vec![epoch_sede]; let epoch_sede_var_list: VariableList<_, U2048> = VariableList::from(epoch_accumulator.clone()); let epoch_hash = epoch_sede_var_list.tree_hash_root(); let epoch_encoded = &epoch_sede_fixed_vec.as_ssz_bytes(); } impl EpochSede { pub fn new(block_hash: H256, total_difficulty: u64) -> EpochSede { EpochSede { block_hash, total_difficulty, } } } ``` hash result: `0x30d1ed68b3b224f25c19cf109a0ebf354b407728432aabe83fd608ee8ec1dca7` epoch_encoded result: ``` [212, 229, 103, 64, 248, 118, 174, 248, 192, 16, 184, 106, 64, 213, 245, 103, 69, 161, 24, 208, 144, 106, 52, 230, 154, 236, 140, 13, 177, 203, 143, 163, 0, 0, 0, 0, 4, 0, 0, 0] ``` ## Thoughts These 2 methods return the same hash and a similar looking ssz encoded version. Peforming ssz encoding only to the container sede returns a matching result in both implementation However in the List sede, py-ssz seems to have 24 more 0's being padded towards the end of the encoded result. Digging deeper while keeping an open mind that my code may not be correct