@@ -16,10 +16,48 @@ use crate::{Core, CoreDal};
16
16
#[ cfg( test) ]
17
17
mod tests;
18
18
19
+ /// Hash of the batch.
19
20
pub fn batch_hash ( info : & StoredBatchInfo ) -> attester:: BatchHash {
20
21
attester:: BatchHash ( Keccak256 :: from_bytes ( info. hash ( ) . 0 ) )
21
22
}
22
23
24
+ /// Verifies that the transition from `old` to `new` is admissible.
25
+ pub fn verify_config_transition ( old : & GlobalConfig , new : & GlobalConfig ) -> anyhow:: Result < ( ) > {
26
+ anyhow:: ensure!(
27
+ old. genesis. chain_id == new. genesis. chain_id,
28
+ "changing chain_id is not allowed: old = {:?}, new = {:?}" ,
29
+ old. genesis. chain_id,
30
+ new. genesis. chain_id,
31
+ ) ;
32
+ // Note that it may happen that the fork number didn't change,
33
+ // in case the binary was updated to support more fields in genesis struct.
34
+ // In such a case, the old binary was not able to connect to the consensus network,
35
+ // because of the genesis hash mismatch.
36
+ // TODO: Perhaps it would be better to deny unknown fields in the genesis instead.
37
+ // It would require embedding the genesis either as a json string or protobuf bytes within
38
+ // the global config, so that the global config can be parsed with
39
+ // `deny_unknown_fields:false` while genesis would be parsed with
40
+ // `deny_unknown_fields:true`.
41
+ anyhow:: ensure!(
42
+ old. genesis. fork_number <= new. genesis. fork_number,
43
+ "transition to a past fork is not allowed: old = {:?}, new = {:?}" ,
44
+ old. genesis. fork_number,
45
+ new. genesis. fork_number,
46
+ ) ;
47
+ new. genesis . verify ( ) . context ( "genesis.verify()" ) ?;
48
+ // This is a temporary hack until the `consensus_genesis()` RPC is disabled.
49
+ if new
50
+ == ( & GlobalConfig {
51
+ genesis : old. genesis . clone ( ) ,
52
+ registry_address : None ,
53
+ seed_peers : [ ] . into ( ) ,
54
+ } )
55
+ {
56
+ anyhow:: bail!( "new config is equal to truncated old config, which means that it was sourced from the wrong endpoint" ) ;
57
+ }
58
+ Ok ( ( ) )
59
+ }
60
+
23
61
/// Storage access methods for `zksync_core::consensus` module.
24
62
#[ derive( Debug ) ]
25
63
pub struct ConsensusDal < ' a , ' c > {
@@ -94,6 +132,8 @@ impl ConsensusDal<'_, '_> {
94
132
if got == want {
95
133
return Ok ( ( ) ) ;
96
134
}
135
+ verify_config_transition ( got, want) ?;
136
+
97
137
// If genesis didn't change, just update the config.
98
138
if got. genesis == want. genesis {
99
139
let s = zksync_protobuf:: serde:: Serialize ;
@@ -112,30 +152,6 @@ impl ConsensusDal<'_, '_> {
112
152
txn. commit ( ) . await ?;
113
153
return Ok ( ( ) ) ;
114
154
}
115
-
116
- // Verify the genesis change.
117
- anyhow:: ensure!(
118
- got. genesis. chain_id == want. genesis. chain_id,
119
- "changing chain_id is not allowed: old = {:?}, new = {:?}" ,
120
- got. genesis. chain_id,
121
- want. genesis. chain_id,
122
- ) ;
123
- // Note that it may happen that the fork number didn't change,
124
- // in case the binary was updated to support more fields in genesis struct.
125
- // In such a case, the old binary was not able to connect to the consensus network,
126
- // because of the genesis hash mismatch.
127
- // TODO: Perhaps it would be better to deny unknown fields in the genesis instead.
128
- // It would require embedding the genesis either as a json string or protobuf bytes within
129
- // the global config, so that the global config can be parsed with
130
- // `deny_unknown_fields:false` while genesis would be parsed with
131
- // `deny_unknown_fields:true`.
132
- anyhow:: ensure!(
133
- got. genesis. fork_number <= want. genesis. fork_number,
134
- "transition to a past fork is not allowed: old = {:?}, new = {:?}" ,
135
- got. genesis. fork_number,
136
- want. genesis. fork_number,
137
- ) ;
138
- want. genesis . verify ( ) . context ( "genesis.verify()" ) ?;
139
155
}
140
156
141
157
// Reset the consensus state.
0 commit comments