@@ -3,11 +3,15 @@ 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 ;
14+ use crate :: federation_id:: FederationId ;
1115use crate :: num_peers:: NumPeers ;
1216use crate :: peer:: PeerIdx ;
1317use crate :: ver:: ConsensusVersionMinor ;
@@ -28,15 +32,6 @@ array_type_define_fixed_size! {
2832 pub struct BlockRound ( u64 ) ;
2933}
3034
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-
4035impl BlockRound {
4136 pub fn hash ( self ) -> blake3:: Hash {
4237 blake3:: hash ( & self . 0 )
@@ -75,57 +70,127 @@ fn block_round_leader_test() {
7570 }
7671}
7772array_type_define ! {
78- #[ derive( Encode , Decode ) ]
73+ #[ derive( Encode , Decode , Copy , Clone ) ]
7974 pub struct BlockHash [ 32 ] ;
8075}
8176array_type_impl_zero_default ! ( BlockHash ) ;
8277array_type_impl_base32_str ! ( BlockHash ) ;
8378array_type_impl_serde ! ( BlockHash ) ;
79+ array_type_impl_debug_as_display ! ( BlockHash ) ;
8480
85- #[ derive( Encode , Decode ) ]
81+ impl From < blake3:: Hash > for BlockHash {
82+ fn from ( value : blake3:: Hash ) -> Self {
83+ Self ( * value. as_bytes ( ) )
84+ }
85+ }
86+
87+ impl From < BlockHash > for blake3:: Hash {
88+ fn from ( value : BlockHash ) -> Self {
89+ blake3:: Hash :: from_bytes ( value. 0 )
90+ }
91+ }
92+
93+ #[ derive( Debug , Encode , Decode , Copy , Clone , PartialEq , Eq ) ]
8694pub 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 ,
95+ pub seq : BlockSeq , // 8B
96+ pub round : BlockRound , // 8B
97+ /// Commits to previous non-dummy `BlockHeader`
98+ pub prev_block_hash : BlockHash , // 32B
99+ /// Commits to [`ConsensusParams`] used for this block
100+ pub consensus_params_hash : ConsensusParamsHash , // 32B
101+ /// Commits to [`BlockPayload`]
102+ pub payload_hash : BlockPayloadHash , // 32B
103+ }
104+
105+ #[ test]
106+ fn block_header_size_sanity ( ) {
107+ let block = BlockHeader :: dummy ( 0 . into ( ) , 0 . into ( ) ) ;
108+ assert_eq ! (
109+ bincode:: encode_to_vec( block, STD_BINCODE_CONFIG )
110+ . expect( "Can't fail" )
111+ . len( ) ,
112+ 112
113+ )
92114}
93115
116+ #[ derive( Debug , Snafu ) ]
117+ pub struct PayloadHashMismatchError ;
118+
119+ pub type PayloadHashMismatchResult < T > = std:: result:: Result < T , PayloadHashMismatchError > ;
120+
94121impl BlockHeader {
95- pub fn dummy ( round : BlockRound , consensus_minor_version : ConsensusVersionMinor ) -> Self {
122+ pub fn hash ( & self ) -> BlockHash {
123+ // TODO: use static array for encoding output
124+ blake3:: hash ( & bincode:: encode_to_vec ( self , STD_BINCODE_CONFIG ) . expect ( "Can't fail" ) ) . into ( )
125+ }
126+
127+ pub fn verify_payload ( & self , payload : & BlockPayload ) -> PayloadHashMismatchResult < ( ) > {
128+ if payload. hash ( ) != self . payload_hash {
129+ return Err ( PayloadHashMismatchError ) ;
130+ }
131+
132+ Ok ( ( ) )
133+ }
134+ pub fn dummy ( round : BlockRound , consensus_params_hash : ConsensusParamsHash ) -> Self {
96135 Self {
97136 seq : BlockSeq :: default ( ) ,
98137 round,
99- prev_block_id : BlockHash :: ZERO ,
138+ prev_block_hash : BlockHash :: ZERO ,
139+ consensus_params_hash,
100140 payload_hash : BlockPayloadHash :: ZERO ,
101- consensus_minor_version,
102141 }
103142 }
104143
105144 pub fn is_dummy ( & self ) -> bool {
106145 self . seq == BlockSeq :: ZERO
107- && self . prev_block_id == BlockHash :: ZERO
146+ && self . prev_block_hash == BlockHash :: ZERO
108147 && self . payload_hash == BlockPayloadHash :: ZERO
109148 }
110149
111150 pub fn sign_by ( & self , _secret_key : ed25519_dalek:: SecretKey ) {
112151 todo ! ( )
113152 }
153+
154+ pub fn does_extend (
155+ & self ,
156+ prev_block : Option < BlockHeader > ,
157+ consensus_params_hash : ConsensusParamsHash ,
158+ ) -> bool {
159+ if self . consensus_params_hash . to_bytes ( ) != consensus_params_hash. to_bytes ( ) {
160+ return false ;
161+ }
162+
163+ if let Some ( prev_block) = prev_block {
164+ prev_block. seq . next ( ) == Some ( self . seq )
165+ && prev_block. round < self . round
166+ && prev_block. hash ( ) == self . prev_block_hash
167+ } else {
168+ // Note: 0 round block could be a dummy, so we can't require round to be 0
169+ self . seq == BlockSeq :: ZERO && self . prev_block_hash == BlockHash :: ZERO
170+ }
171+ }
114172}
173+
115174#[ derive( Encode , Decode ) ]
116175pub struct SignedBlock {
117176 block : BlockHeader ,
118177 signatures : BTreeMap < PeerIdx , BlockSignature > ,
119178}
120179
121180array_type_define ! {
122- #[ derive( Encode , Decode ) ]
181+ #[ derive( Encode , Decode , Copy , Clone ) ]
123182 pub struct BlockPayloadHash [ 32 ] ;
124183}
125184array_type_impl_zero_default ! ( BlockPayloadHash ) ;
126185array_type_impl_base32_str ! ( BlockPayloadHash ) ;
127186array_type_impl_serde ! ( BlockPayloadHash ) ;
187+ array_type_impl_debug_as_display ! ( BlockPayloadHash ) ;
128188
189+ impl From < blake3:: Hash > for BlockPayloadHash {
190+ fn from ( value : blake3:: Hash ) -> Self {
191+ Self ( * value. as_bytes ( ) )
192+ }
193+ }
129194array_type_define ! {
130195 #[ derive( Encode , Decode ) ]
131196 pub struct BlockSignature [ 32 ] ;
@@ -135,4 +200,10 @@ array_type_impl_base32_str!(BlockSignature);
135200array_type_impl_serde ! ( BlockSignature ) ;
136201
137202#[ derive( Encode , Decode , Clone ) ]
138- pub struct BlockPayload ( Arc < u8 > ) ;
203+ pub struct BlockPayload ( Arc < [ u8 ] > ) ;
204+
205+ impl BlockPayload {
206+ pub fn hash ( & self ) -> BlockPayloadHash {
207+ blake3:: hash ( & self . 0 ) . into ( )
208+ }
209+ }
0 commit comments