@@ -3,14 +3,16 @@ use std::sync::Arc;
33
44use bfte_util_array_type:: {
55 array_type_define, array_type_define_fixed_size, array_type_impl_base32_str,
6- array_type_impl_serde, array_type_impl_zero_default,
6+ array_type_impl_debug_as_display , array_type_impl_serde, array_type_impl_zero_default,
77} ;
88use bincode:: { Decode , Encode } ;
99use num_bigint:: BigUint ;
10+ use snafu:: Snafu ;
1011
12+ use crate :: bincode:: STD_BINCODE_CONFIG ;
13+ use crate :: consensus_params:: ConsensusParamsHash ;
1114use crate :: num_peers:: NumPeers ;
1215use crate :: peer:: PeerIdx ;
13- use crate :: ver:: ConsensusVersionMinor ;
1416
1517array_type_define_fixed_size ! {
1618 /// Non-dumy block sequence number
@@ -28,15 +30,6 @@ array_type_define_fixed_size! {
2830 pub struct BlockRound ( u64 ) ;
2931}
3032
31- // array_type_fixed_size_u64!(BlockSeq);
32- // array_type_define! {
33- // /// Round the block was produced in
34- // #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
35- // pub struct BlockRound[8];
36- // }
37-
38- // array_type_fixed_size_u64!(BlockRound);
39-
4033impl BlockRound {
4134 pub fn hash ( self ) -> blake3:: Hash {
4235 blake3:: hash ( & self . 0 )
@@ -75,57 +68,127 @@ fn block_round_leader_test() {
7568 }
7669}
7770array_type_define ! {
78- #[ derive( Encode , Decode ) ]
71+ #[ derive( Encode , Decode , Copy , Clone ) ]
7972 pub struct BlockHash [ 32 ] ;
8073}
8174array_type_impl_zero_default ! ( BlockHash ) ;
8275array_type_impl_base32_str ! ( BlockHash ) ;
8376array_type_impl_serde ! ( BlockHash ) ;
77+ array_type_impl_debug_as_display ! ( BlockHash ) ;
8478
85- #[ derive( Encode , Decode ) ]
79+ impl From < blake3:: Hash > for BlockHash {
80+ fn from ( value : blake3:: Hash ) -> Self {
81+ Self ( * value. as_bytes ( ) )
82+ }
83+ }
84+
85+ impl From < BlockHash > for blake3:: Hash {
86+ fn from ( value : BlockHash ) -> Self {
87+ blake3:: Hash :: from_bytes ( value. 0 )
88+ }
89+ }
90+
91+ #[ derive( Debug , Encode , Decode , Copy , Clone , PartialEq , Eq ) ]
8692pub struct BlockHeader {
87- pub consensus_minor_version : ConsensusVersionMinor ,
88- pub seq : BlockSeq ,
89- pub round : BlockRound ,
90- pub prev_block_id : BlockHash ,
91- pub payload_hash : BlockPayloadHash ,
93+ pub seq : BlockSeq , // 8B
94+ pub round : BlockRound , // 8B
95+ /// Commits to previous non-dummy `BlockHeader`
96+ pub prev_block_hash : BlockHash , // 32B
97+ /// Commits to [`ConsensusParams`] used for this block
98+ pub consensus_params_hash : ConsensusParamsHash , // 32B
99+ /// Commits to [`BlockPayload`]
100+ pub payload_hash : BlockPayloadHash , // 32B
101+ }
102+
103+ #[ test]
104+ fn block_header_size_sanity ( ) {
105+ let block = BlockHeader :: dummy ( 0 . into ( ) , ConsensusParamsHash :: ZERO ) ;
106+ assert_eq ! (
107+ bincode:: encode_to_vec( block, STD_BINCODE_CONFIG )
108+ . expect( "Can't fail" )
109+ . len( ) ,
110+ 112
111+ )
92112}
93113
114+ #[ derive( Debug , Snafu ) ]
115+ pub struct PayloadHashMismatchError ;
116+
117+ pub type PayloadHashMismatchResult < T > = std:: result:: Result < T , PayloadHashMismatchError > ;
118+
94119impl BlockHeader {
95- pub fn dummy ( round : BlockRound , consensus_minor_version : ConsensusVersionMinor ) -> Self {
120+ pub fn hash ( & self ) -> BlockHash {
121+ // TODO: use static array for encoding output
122+ blake3:: hash ( & bincode:: encode_to_vec ( self , STD_BINCODE_CONFIG ) . expect ( "Can't fail" ) ) . into ( )
123+ }
124+
125+ pub fn verify_payload ( & self , payload : & BlockPayload ) -> PayloadHashMismatchResult < ( ) > {
126+ if payload. hash ( ) != self . payload_hash {
127+ return Err ( PayloadHashMismatchError ) ;
128+ }
129+
130+ Ok ( ( ) )
131+ }
132+ pub fn dummy ( round : BlockRound , consensus_params_hash : ConsensusParamsHash ) -> Self {
96133 Self {
97134 seq : BlockSeq :: default ( ) ,
98135 round,
99- prev_block_id : BlockHash :: ZERO ,
136+ prev_block_hash : BlockHash :: ZERO ,
137+ consensus_params_hash,
100138 payload_hash : BlockPayloadHash :: ZERO ,
101- consensus_minor_version,
102139 }
103140 }
104141
105142 pub fn is_dummy ( & self ) -> bool {
106143 self . seq == BlockSeq :: ZERO
107- && self . prev_block_id == BlockHash :: ZERO
144+ && self . prev_block_hash == BlockHash :: ZERO
108145 && self . payload_hash == BlockPayloadHash :: ZERO
109146 }
110147
111148 pub fn sign_by ( & self , _secret_key : ed25519_dalek:: SecretKey ) {
112149 todo ! ( )
113150 }
151+
152+ pub fn does_extend (
153+ & self ,
154+ prev_block : Option < BlockHeader > ,
155+ consensus_params_hash : ConsensusParamsHash ,
156+ ) -> bool {
157+ if self . consensus_params_hash . to_bytes ( ) != consensus_params_hash. to_bytes ( ) {
158+ return false ;
159+ }
160+
161+ if let Some ( prev_block) = prev_block {
162+ prev_block. seq . next ( ) == Some ( self . seq )
163+ && prev_block. round < self . round
164+ && prev_block. hash ( ) == self . prev_block_hash
165+ } else {
166+ // Note: 0 round block could be a dummy, so we can't require round to be 0
167+ self . seq == BlockSeq :: ZERO && self . prev_block_hash == BlockHash :: ZERO
168+ }
169+ }
114170}
171+
115172#[ derive( Encode , Decode ) ]
116173pub struct SignedBlock {
117174 block : BlockHeader ,
118175 signatures : BTreeMap < PeerIdx , BlockSignature > ,
119176}
120177
121178array_type_define ! {
122- #[ derive( Encode , Decode ) ]
179+ #[ derive( Encode , Decode , Copy , Clone ) ]
123180 pub struct BlockPayloadHash [ 32 ] ;
124181}
125182array_type_impl_zero_default ! ( BlockPayloadHash ) ;
126183array_type_impl_base32_str ! ( BlockPayloadHash ) ;
127184array_type_impl_serde ! ( BlockPayloadHash ) ;
185+ array_type_impl_debug_as_display ! ( BlockPayloadHash ) ;
128186
187+ impl From < blake3:: Hash > for BlockPayloadHash {
188+ fn from ( value : blake3:: Hash ) -> Self {
189+ Self ( * value. as_bytes ( ) )
190+ }
191+ }
129192array_type_define ! {
130193 #[ derive( Encode , Decode ) ]
131194 pub struct BlockSignature [ 32 ] ;
@@ -135,4 +198,14 @@ array_type_impl_base32_str!(BlockSignature);
135198array_type_impl_serde ! ( BlockSignature ) ;
136199
137200#[ derive( Encode , Decode , Clone ) ]
138- pub struct BlockPayload ( Arc < u8 > ) ;
201+ pub struct BlockPayload ( Arc < [ u8 ] > ) ;
202+
203+ impl BlockPayload {
204+ pub fn empty ( ) -> Self {
205+ Self ( Default :: default ( ) )
206+ }
207+
208+ pub fn hash ( & self ) -> BlockPayloadHash {
209+ blake3:: hash ( & self . 0 ) . into ( )
210+ }
211+ }
0 commit comments