@@ -2,6 +2,7 @@ use super::account::UsernameProofStore;
2
2
use super :: account:: { IntoU8 , OnchainEventStorageError , UserDataStore } ;
3
3
use crate :: core:: error:: HubError ;
4
4
use crate :: core:: types:: Height ;
5
+ use crate :: core:: util:: FarcasterTime ;
5
6
use crate :: core:: validations;
6
7
use crate :: core:: validations:: verification;
7
8
use crate :: mempool:: mempool:: MempoolMessagesRequest ;
@@ -17,6 +18,7 @@ use crate::storage::store::BlockStore;
17
18
use crate :: storage:: trie;
18
19
use crate :: storage:: trie:: merkle_trie;
19
20
use crate :: utils:: statsd_wrapper:: StatsdClientWrapper ;
21
+ use crate :: version:: version:: { EngineVersion , ProtocolFeature } ;
20
22
use informalsystems_malachitebft_core_types:: Round ;
21
23
use itertools:: Itertools ;
22
24
use merkle_trie:: TrieKey ;
@@ -122,9 +124,11 @@ impl MempoolMessage {
122
124
#[ derive( Clone ) ]
123
125
pub struct ShardStateChange {
124
126
pub shard_id : u32 ,
127
+ pub timestamp : FarcasterTime ,
125
128
pub new_state_root : Vec < u8 > ,
126
129
pub transactions : Vec < Transaction > ,
127
130
pub events : Vec < HubEvent > ,
131
+ pub version : EngineVersion ,
128
132
}
129
133
130
134
#[ derive( Clone ) ]
@@ -279,18 +283,21 @@ impl ShardEngine {
279
283
txn_batch : & mut RocksDbTransactionBatch ,
280
284
shard_id : u32 ,
281
285
messages : Vec < MempoolMessage > ,
286
+ timestamp : & FarcasterTime ,
282
287
) -> Result < ShardStateChange , EngineError > {
283
288
self . count ( "prepare_proposal.recv_messages" , messages. len ( ) as u64 ) ;
284
289
285
290
let mut snapchain_txns = self . create_transactions_from_mempool ( messages) ?;
286
291
let mut events = vec ! [ ] ;
287
292
let mut validation_error_count = 0 ;
293
+ let version = EngineVersion :: version_for ( timestamp) ;
288
294
for snapchain_txn in & mut snapchain_txns {
289
295
let ( account_root, txn_events, validation_errors) = self . replay_snapchain_txn (
290
296
trie_ctx,
291
297
& snapchain_txn,
292
298
txn_batch,
293
299
ProposalSource :: Propose ,
300
+ version,
294
301
) ?;
295
302
snapchain_txn. account_root = account_root;
296
303
events. extend ( txn_events) ;
@@ -310,6 +317,8 @@ impl ShardEngine {
310
317
let new_root_hash = self . stores . trie . root_hash ( ) ?;
311
318
let result = ShardStateChange {
312
319
shard_id,
320
+ timestamp : timestamp. clone ( ) ,
321
+ version,
313
322
new_state_root : new_root_hash. clone ( ) ,
314
323
transactions : snapchain_txns,
315
324
events,
@@ -375,6 +384,7 @@ impl ShardEngine {
375
384
& mut self ,
376
385
shard : u32 ,
377
386
messages : Vec < MempoolMessage > ,
387
+ timestamp : Option < FarcasterTime > ,
378
388
) -> ShardStateChange {
379
389
let now = std:: time:: Instant :: now ( ) ;
380
390
let mut txn = RocksDbTransactionBatch :: new ( ) ;
@@ -386,12 +396,14 @@ impl ShardEngine {
386
396
count_fn ( "trie.mem_get_count.total" , read_count. 1 ) ;
387
397
count_fn ( "trie.mem_get_count.for_propose" , read_count. 1 ) ;
388
398
} ;
399
+ let timestamp = timestamp. unwrap_or_else ( FarcasterTime :: current) ;
389
400
let result = self
390
401
. prepare_proposal (
391
402
& merkle_trie:: Context :: with_callback ( count_callback) ,
392
403
& mut txn,
393
404
shard,
394
405
messages,
406
+ & timestamp,
395
407
)
396
408
. unwrap ( ) ; //TODO: don't unwrap()
397
409
@@ -470,6 +482,7 @@ impl ShardEngine {
470
482
transactions : & [ Transaction ] ,
471
483
shard_root : & [ u8 ] ,
472
484
source : ProposalSource ,
485
+ version : EngineVersion ,
473
486
) -> Result < Vec < HubEvent > , EngineError > {
474
487
let now = std:: time:: Instant :: now ( ) ;
475
488
let mut events = vec ! [ ] ;
@@ -500,8 +513,13 @@ impl ShardEngine {
500
513
}
501
514
502
515
for snapchain_txn in transactions {
503
- let ( account_root, txn_events, _) =
504
- self . replay_snapchain_txn ( trie_ctx, snapchain_txn, txn_batch, source. clone ( ) ) ?;
516
+ let ( account_root, txn_events, _) = self . replay_snapchain_txn (
517
+ trie_ctx,
518
+ snapchain_txn,
519
+ txn_batch,
520
+ source. clone ( ) ,
521
+ version,
522
+ ) ?;
505
523
// Reject early if account roots fail to match (shard roots will definitely fail)
506
524
if & account_root != & snapchain_txn. account_root {
507
525
warn ! (
@@ -544,6 +562,7 @@ impl ShardEngine {
544
562
snapchain_txn : & Transaction ,
545
563
txn_batch : & mut RocksDbTransactionBatch ,
546
564
source : ProposalSource ,
565
+ version : EngineVersion ,
547
566
) -> Result < ( Vec < u8 > , Vec < HubEvent > , Vec < MessageValidationError > ) , EngineError > {
548
567
let now = std:: time:: Instant :: now ( ) ;
549
568
let total_user_messages = snapchain_txn. user_messages . len ( ) ;
@@ -577,8 +596,7 @@ impl ShardEngine {
577
596
system_messages_count += 1 ;
578
597
match & onchain_event. body {
579
598
Some ( proto:: on_chain_event:: Body :: SignerEventBody ( signer_event) ) => {
580
- if signer_event. event_type == proto:: SignerEventType :: Remove as i32
581
- {
599
+ if Self :: should_revoke_signer ( & signer_event, version) {
582
600
revoked_signers. insert ( signer_event. key . clone ( ) ) ;
583
601
}
584
602
}
@@ -1145,6 +1163,7 @@ impl ShardEngine {
1145
1163
transactions,
1146
1164
shard_root,
1147
1165
ProposalSource :: Validate ,
1166
+ shard_state_change. version ,
1148
1167
) ;
1149
1168
1150
1169
match proposal_result {
@@ -1279,20 +1298,17 @@ impl ShardEngine {
1279
1298
"No valid cached transaction to apply. Replaying proposal"
1280
1299
) ;
1281
1300
// If we need to replay, reset the sequence number on the event id generator, just in case
1282
- let block_number = & shard_chunk
1283
- . header
1284
- . as_ref ( )
1285
- . unwrap ( )
1286
- . height
1287
- . unwrap ( )
1288
- . block_number ;
1289
- self . stores . event_handler . set_current_height ( * block_number) ;
1301
+ let header = & shard_chunk. header . as_ref ( ) . unwrap ( ) ;
1302
+ let block_number = header. height . unwrap ( ) . block_number ;
1303
+ self . stores . event_handler . set_current_height ( block_number) ;
1304
+ let version = EngineVersion :: version_for ( & FarcasterTime :: new ( header. timestamp ) ) ;
1290
1305
match self . replay_proposal (
1291
1306
trie_ctx,
1292
1307
& mut txn,
1293
1308
transactions,
1294
1309
shard_root,
1295
1310
ProposalSource :: Commit ,
1311
+ version,
1296
1312
) {
1297
1313
Err ( err) => {
1298
1314
error ! ( "State change commit failed: {}" , err) ;
@@ -1316,11 +1332,13 @@ impl ShardEngine {
1316
1332
system_messages : vec ! [ ] ,
1317
1333
user_messages : vec ! [ message. clone( ) ] ,
1318
1334
} ;
1335
+ let version = EngineVersion :: version_for ( & FarcasterTime :: current ( ) ) ;
1319
1336
let result = self . replay_snapchain_txn (
1320
1337
& merkle_trie:: Context :: new ( ) ,
1321
1338
& snapchain_txn,
1322
1339
& mut txn,
1323
1340
ProposalSource :: Simulate ,
1341
+ version,
1324
1342
) ;
1325
1343
1326
1344
match result {
@@ -1490,6 +1508,14 @@ impl ShardEngine {
1490
1508
pub fn trie_num_items ( & mut self ) -> usize {
1491
1509
self . stores . trie . items ( ) . unwrap ( )
1492
1510
}
1511
+
1512
+ fn should_revoke_signer ( signer_event : & proto:: SignerEventBody , version : EngineVersion ) -> bool {
1513
+ // When this bug was active, we did not revoke any signers, so, always return false
1514
+ if version. is_enabled ( ProtocolFeature :: SignerRevokeBug ) {
1515
+ return false ;
1516
+ }
1517
+ signer_event. event_type == proto:: SignerEventType :: Remove as i32
1518
+ }
1493
1519
}
1494
1520
1495
1521
pub struct BlockEngine {
0 commit comments