@@ -196,7 +196,7 @@ impl<F: FaultInjection> SumeragiWithFault<F> {
196
196
197
197
#[ allow( clippy:: needless_pass_by_value) ]
198
198
fn broadcast_packet ( & self , msg : MessagePacket , topology : & Topology ) {
199
- self . broadcast_packet_to ( msg, topology. sorted_peers ( ) ) ;
199
+ self . broadcast_packet_to ( msg, & topology. sorted_peers ) ;
200
200
}
201
201
202
202
fn gossip_transactions ( & self , state : & State , view_change_proof_chain : & ProofChain ) {
@@ -222,7 +222,7 @@ impl<F: FaultInjection> SumeragiWithFault<F> {
222
222
/// Connect or disconnect peers according to the current network topology.
223
223
fn connect_peers ( & self , topology : & Topology ) {
224
224
let peers_expected = {
225
- let mut res = topology. sorted_peers ( ) . to_owned ( ) ;
225
+ let mut res = topology. sorted_peers . clone ( ) ;
226
226
res. retain ( |id| id. address != self . peer_id . address ) ;
227
227
res. shuffle ( & mut rand:: thread_rng ( ) ) ;
228
228
res
@@ -286,7 +286,7 @@ impl<F: FaultInjection> SumeragiWithFault<F> {
286
286
Ok ( packet) => {
287
287
if let Err ( error) = view_change_proof_chain. merge (
288
288
packet. view_change_proofs ,
289
- current_topology. sorted_peers ( ) ,
289
+ & current_topology. sorted_peers ,
290
290
current_topology. max_faults ( ) ,
291
291
state. latest_block_hash ,
292
292
) {
@@ -368,11 +368,6 @@ impl<F: FaultInjection> SumeragiWithFault<F> {
368
368
} ;
369
369
370
370
if block. header ( ) . is_genesis ( ) {
371
- if let Some ( topology) = block. header ( ) . genesis_topology . clone ( ) . take ( ) {
372
- state. current_topology = topology;
373
- info ! ( "Using genesis topology" ) ;
374
- }
375
-
376
371
commit_block ( self , state, block) ;
377
372
return Err ( EarlyReturn :: GenesisBlockReceivedAndCommitted ) ;
378
373
}
@@ -418,8 +413,25 @@ fn commit_block<F: FaultInjection>(
418
413
%block_hash, "Committing block"
419
414
) ;
420
415
416
+ * current_topology = committed_block. header ( ) . committed_with_topology . clone ( ) ;
417
+ current_topology. lift_up_peers (
418
+ & committed_block
419
+ . signatures ( )
420
+ . into_iter ( )
421
+ . map ( |s| s. public_key ( ) . clone ( ) )
422
+ . collect :: < Vec < PublicKey > > ( ) ,
423
+ ) ;
424
+ current_topology. rotate_a_set ( ) ;
425
+ current_topology. update_peer_list (
426
+ & state
427
+ . wsv
428
+ . peers_ids ( )
429
+ . iter ( )
430
+ . map ( |id| id. clone ( ) )
431
+ . collect :: < Vec < PeerId > > ( ) ,
432
+ ) ;
433
+
421
434
sumeragi. kura . store_block ( committed_block) ;
422
- current_topology. recreate ( & state. wsv , block_hash) ;
423
435
424
436
cache_transaction ( state, sumeragi) ;
425
437
}
@@ -458,8 +470,25 @@ fn replace_top_block<F: FaultInjection>(
458
470
%block_hash, "Replacing top block"
459
471
) ;
460
472
473
+ * current_topology = committed_block. header ( ) . committed_with_topology . clone ( ) ;
474
+ current_topology. lift_up_peers (
475
+ & committed_block
476
+ . signatures ( )
477
+ . into_iter ( )
478
+ . map ( |s| s. public_key ( ) . clone ( ) )
479
+ . collect :: < Vec < PublicKey > > ( ) ,
480
+ ) ;
481
+ current_topology. rotate_a_set ( ) ;
482
+ current_topology. update_peer_list (
483
+ & state
484
+ . wsv
485
+ . peers_ids ( )
486
+ . iter ( )
487
+ . map ( |id| id. clone ( ) )
488
+ . collect :: < Vec < PeerId > > ( ) ,
489
+ ) ;
490
+
461
491
sumeragi. kura . replace_top_block ( committed_block) ;
462
- current_topology. recreate ( & state. wsv , block_hash) ;
463
492
464
493
cache_transaction ( state, sumeragi)
465
494
}
@@ -491,7 +520,7 @@ fn suggest_view_change<F: FaultInjection>(
491
520
492
521
view_change_proof_chain
493
522
. insert_proof (
494
- state. current_topology . sorted_peers ( ) ,
523
+ & state. current_topology . sorted_peers ,
495
524
state. current_topology . max_faults ( ) ,
496
525
state. latest_block_hash ,
497
526
suspect_proof,
@@ -511,7 +540,7 @@ fn prune_view_change_proofs_and_calculate_current_index(
511
540
) -> u64 {
512
541
view_change_proof_chain. prune ( state. latest_block_hash ) ;
513
542
view_change_proof_chain. verify_with_state (
514
- state. current_topology . sorted_peers ( ) ,
543
+ & state. current_topology . sorted_peers ,
515
544
state. current_topology . max_faults ( ) ,
516
545
state. latest_block_hash ,
517
546
) as u64
@@ -622,6 +651,9 @@ fn handle_message<F: FaultInjection>(
622
651
let voting_block_hash = voted_block. block . hash ( ) ;
623
652
624
653
if hash == voting_block_hash. transmute ( ) {
654
+ // The manipulation of the topology relies upon all peers seeing the same signature set.
655
+ // Therefore we must clear the signatures and accept what the proxy tail giveth.
656
+ voted_block. block . signatures . clear ( ) ;
625
657
add_signatures :: < true > ( & mut voted_block, signatures. transmute ( ) ) ;
626
658
627
659
match voted_block. block . commit ( current_topology) {
@@ -743,6 +775,7 @@ fn process_message_independent<F: FaultInjection>(
743
775
state. latest_block_height ,
744
776
state. latest_block_hash ,
745
777
current_view_change_index,
778
+ state. current_topology . clone ( ) ,
746
779
)
747
780
. validate ( & sumeragi. transaction_validator , & state. wsv )
748
781
. sign ( sumeragi. key_pair . clone ( ) )
@@ -836,17 +869,19 @@ fn reset_state(
836
869
// a view change a new block is immediately created by the leader
837
870
* round_start_time = Instant :: now ( ) ;
838
871
was_commit_or_view_change = true ;
872
+ * old_view_change_index = 0 ;
839
873
}
840
874
841
- if current_view_change_index != * old_view_change_index {
842
- current_topology. rebuild_with_new_view_change_count ( current_view_change_index) ;
875
+ while * old_view_change_index < current_view_change_index {
876
+ * old_view_change_index += 1 ;
877
+ error ! ( addr=%peer_id. address, "Rotating the entire topology." ) ;
878
+ current_topology. rotate_all ( ) ;
843
879
was_commit_or_view_change = true ;
844
880
}
845
881
846
882
// Reset state for the next round.
847
883
if was_commit_or_view_change {
848
884
* old_latest_block_height = current_latest_block_height;
849
- * old_view_change_index = current_view_change_index;
850
885
851
886
* voting_block = None ;
852
887
voting_signatures. clear ( ) ;
@@ -970,11 +1005,11 @@ pub(crate) fn run<F: FaultInjection>(
970
1005
971
1006
if let Some ( VotingBlock { block, .. } ) = voting_block. as_ref ( ) {
972
1007
// NOTE: Suspecting the tail node because it hasn't yet committed a block produced by leader
973
- warn ! ( %role, block=%block. hash( ) , "Block not committed in due time, requesting view change..." ) ;
1008
+ warn ! ( peer_public_key=?sumeragi . peer_id . public_key , %role, block=%block. hash( ) , "Block not committed in due time, requesting view change..." ) ;
974
1009
} else {
975
1010
// NOTE: Suspecting the leader node because it hasn't produced a block
976
1011
// If the current node has a transaction, the leader should have as well
977
- warn ! ( %role, "No block produced in due time, requesting view change..." ) ;
1012
+ warn ! ( peer_public_key=?sumeragi . peer_id . public_key , %role, "No block produced in due time, requesting view change..." ) ;
978
1013
}
979
1014
980
1015
suggest_view_change (
@@ -1059,6 +1094,15 @@ fn vote_for_block<F: FaultInjection>(
1059
1094
return None ;
1060
1095
}
1061
1096
1097
+ if block. header ( ) . committed_with_topology != state. current_topology {
1098
+ error ! (
1099
+ %addr, %role, block_topology=?block. header( ) . committed_with_topology, my_topology=?state. current_topology, hash=%block. hash( ) ,
1100
+ "The block is rejected as because the topology field is incorrect."
1101
+ ) ;
1102
+
1103
+ return None ;
1104
+ }
1105
+
1062
1106
let block = {
1063
1107
let span = span ! ( Level :: TRACE , "block revalidation" ) ;
1064
1108
let _enter = span. enter ( ) ;
@@ -1104,7 +1148,7 @@ fn sumeragi_init_commit_genesis<F: FaultInjection>(
1104
1148
"Genesis transaction set contains no valid transactions"
1105
1149
) ;
1106
1150
let block = PendingBlock :: new ( transactions, Vec :: new ( ) )
1107
- . chain_first_with_genesis_topology ( state. current_topology . clone ( ) ) ;
1151
+ . chain_first_with_topology ( state. current_topology . clone ( ) ) ;
1108
1152
1109
1153
{
1110
1154
info ! ( block_hash = %block. hash( ) , "Publishing genesis block." ) ;
0 commit comments