@@ -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,12 @@ 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 ( & committed_block. signatures ( ) . into_iter ( ) . map ( |id| id. public_key . clone ( ) ) . collect :: < Vec < PublicKey > > ( ) ) ;
418
+ current_topology. rotate_a_set ( ) ;
419
+ current_topology. update_peer_list ( & state. wsv . peers_ids ( ) . iter ( ) . map ( |id| id. clone ( ) ) . collect :: < Vec < PeerId > > ( ) ) ;
420
+
421
421
sumeragi. kura . store_block ( committed_block) ;
422
- current_topology. recreate ( & state. wsv , block_hash) ;
423
422
424
423
cache_transaction ( state, sumeragi) ;
425
424
}
@@ -458,8 +457,12 @@ fn replace_top_block<F: FaultInjection>(
458
457
%block_hash, "Replacing top block"
459
458
) ;
460
459
460
+ * current_topology = committed_block. header ( ) . committed_with_topology . clone ( ) ;
461
+ current_topology. lift_up_peers ( & committed_block. signatures ( ) . into_iter ( ) . map ( |id| id. public_key . clone ( ) ) . collect :: < Vec < PublicKey > > ( ) ) ;
462
+ current_topology. rotate_a_set ( ) ;
463
+ current_topology. update_peer_list ( & state. wsv . peers_ids ( ) . iter ( ) . map ( |id| id. clone ( ) ) . collect :: < Vec < PeerId > > ( ) ) ;
464
+
461
465
sumeragi. kura . replace_top_block ( committed_block) ;
462
- current_topology. recreate ( & state. wsv , block_hash) ;
463
466
464
467
cache_transaction ( state, sumeragi)
465
468
}
@@ -491,7 +494,7 @@ fn suggest_view_change<F: FaultInjection>(
491
494
492
495
view_change_proof_chain
493
496
. insert_proof (
494
- state. current_topology . sorted_peers ( ) ,
497
+ & state. current_topology . sorted_peers ,
495
498
state. current_topology . max_faults ( ) ,
496
499
state. latest_block_hash ,
497
500
suspect_proof,
@@ -511,7 +514,7 @@ fn prune_view_change_proofs_and_calculate_current_index(
511
514
) -> u64 {
512
515
view_change_proof_chain. prune ( state. latest_block_hash ) ;
513
516
view_change_proof_chain. verify_with_state (
514
- state. current_topology . sorted_peers ( ) ,
517
+ & state. current_topology . sorted_peers ,
515
518
state. current_topology . max_faults ( ) ,
516
519
state. latest_block_hash ,
517
520
) as u64
@@ -622,6 +625,9 @@ fn handle_message<F: FaultInjection>(
622
625
let voting_block_hash = voted_block. block . hash ( ) ;
623
626
624
627
if hash == voting_block_hash. transmute ( ) {
628
+ // The manipulation of the topology relies upon all peers seeing the same signature set.
629
+ // Therefore we must clear the signatures and accept what the proxy tail giveth.
630
+ voted_block. block . signatures . clear ( ) ;
625
631
add_signatures :: < true > ( & mut voted_block, signatures. transmute ( ) ) ;
626
632
627
633
match voted_block. block . commit ( current_topology) {
@@ -743,6 +749,7 @@ fn process_message_independent<F: FaultInjection>(
743
749
state. latest_block_height ,
744
750
state. latest_block_hash ,
745
751
current_view_change_index,
752
+ state. current_topology . clone ( ) ,
746
753
)
747
754
. validate ( & sumeragi. transaction_validator , & state. wsv )
748
755
. sign ( sumeragi. key_pair . clone ( ) )
@@ -836,17 +843,21 @@ fn reset_state(
836
843
// a view change a new block is immediately created by the leader
837
844
* round_start_time = Instant :: now ( ) ;
838
845
was_commit_or_view_change = true ;
846
+ * old_view_change_index = 0 ;
839
847
}
840
848
841
- if current_view_change_index != * old_view_change_index {
842
- current_topology. rebuild_with_new_view_change_count ( current_view_change_index) ;
849
+ while * old_view_change_index < current_view_change_index {
850
+ * old_view_change_index += 1 ;
851
+ error ! ( addr=%peer_id. address, "Rotating the entire topology." ) ;
852
+ current_topology. rotate_all ( ) ;
843
853
was_commit_or_view_change = true ;
854
+
855
+ println ! ( "{:?}" , current_topology) ;
844
856
}
845
857
846
858
// Reset state for the next round.
847
859
if was_commit_or_view_change {
848
860
* old_latest_block_height = current_latest_block_height;
849
- * old_view_change_index = current_view_change_index;
850
861
851
862
* voting_block = None ;
852
863
voting_signatures. clear ( ) ;
@@ -970,11 +981,11 @@ pub(crate) fn run<F: FaultInjection>(
970
981
971
982
if let Some ( VotingBlock { block, .. } ) = voting_block. as_ref ( ) {
972
983
// 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..." ) ;
984
+ warn ! ( peer_public_key=?sumeragi . peer_id . public_key , %role, block=%block. hash( ) , "Block not committed in due time, requesting view change..." ) ;
974
985
} else {
975
986
// NOTE: Suspecting the leader node because it hasn't produced a block
976
987
// 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..." ) ;
988
+ warn ! ( peer_public_key=?sumeragi . peer_id . public_key , %role, "No block produced in due time, requesting view change..." ) ;
978
989
}
979
990
980
991
suggest_view_change (
@@ -1059,6 +1070,16 @@ fn vote_for_block<F: FaultInjection>(
1059
1070
return None ;
1060
1071
}
1061
1072
1073
+ if block. header ( ) . committed_with_topology != state. current_topology
1074
+ {
1075
+ error ! (
1076
+ %addr, %role, block_topology=?block. header( ) . committed_with_topology, my_topology=?state. current_topology, hash=%block. hash( ) ,
1077
+ "The block is rejected as because the topology field is incorrect."
1078
+ ) ;
1079
+
1080
+ return None ;
1081
+ }
1082
+
1062
1083
let block = {
1063
1084
let span = span ! ( Level :: TRACE , "block revalidation" ) ;
1064
1085
let _enter = span. enter ( ) ;
@@ -1104,7 +1125,7 @@ fn sumeragi_init_commit_genesis<F: FaultInjection>(
1104
1125
"Genesis transaction set contains no valid transactions"
1105
1126
) ;
1106
1127
let block = PendingBlock :: new ( transactions, Vec :: new ( ) )
1107
- . chain_first_with_genesis_topology ( state. current_topology . clone ( ) ) ;
1128
+ . chain_first_with_topology ( state. current_topology . clone ( ) ) ;
1108
1129
1109
1130
{
1110
1131
info ! ( block_hash = %block. hash( ) , "Publishing genesis block." ) ;
0 commit comments