@@ -506,15 +506,15 @@ async fn process_orders_keep_alive(
506506 expected_pair_roots. insert ( pair, plan. to ) ;
507507 }
508508
509- // Build the V1 request using our local "from" roots (no extra lock needed)
510- // TODO(sync-v2): Extend this to include per-pair from_root and to_root ,
511- // requesting an exact diff targeted at our state, even if the responder
512- // advanced after propagating the keep-alive. This should reduce false
513- // InvalidOrIncomplete classifications and unnecessary bans .
509+ // Build the V2 request using our local "from" roots and the keep-alive "to_root"
510+ // values we intend to land on. This requests an exact diff targeted at our state ,
511+ // even if the responder advanced after propagating the keep-alive. This should reduce
512+ // false InvalidOrIncomplete classifications and unnecessary bans.
513+ // Backward-compatibility: legacy peers ignore `expected_roots` optional field .
514514 let current_req = OrdermatchRequest :: SyncPubkeyOrderbookState {
515515 pubkey : from_pubkey. clone ( ) ,
516516 trie_roots : from_roots_by_pair,
517- expected_roots : None ,
517+ expected_roots : Some ( expected_pair_roots . clone ( ) ) ,
518518 } ;
519519
520520 let mut had_response = false ;
@@ -1182,8 +1182,20 @@ fn process_sync_pubkey_orderbook_state(
11821182 ctx : MmArc ,
11831183 pubkey : String ,
11841184 trie_roots : HashMap < AlbOrderedOrderbookPair , H64 > ,
1185- _expected_roots : Option < HashMap < AlbOrderedOrderbookPair , H64 > > ,
1185+ expected_roots : Option < HashMap < AlbOrderedOrderbookPair , H64 > > ,
11861186) -> Result < Option < SyncPubkeyOrderbookStateRes > , String > {
1187+ if let Some ( exp) = expected_roots. as_ref ( ) {
1188+ if exp. len ( ) != trie_roots. len ( ) || trie_roots. keys ( ) . any ( |pair| !exp. contains_key ( pair) ) {
1189+ // TODO(rate-limit/ban): accept at most one SyncPubkeyOrderbookState per peer we sent a KeepAlive to.
1190+ return ERR ! (
1191+ "Rejecting SyncPubkeyOrderbookState for pubkey {}: expected_roots keys mismatch vs trie_roots (expected_roots: {}, trie_roots: {})" ,
1192+ pubkey,
1193+ exp. len( ) ,
1194+ trie_roots. len( )
1195+ ) ;
1196+ }
1197+ }
1198+
11871199 let ordermatch_ctx = OrdermatchContext :: from_ctx ( & ctx) . unwrap ( ) ;
11881200 let orderbook = ordermatch_ctx. orderbook . lock ( ) ;
11891201 let pubkey_state = some_or_return_ok_none ! ( orderbook. pubkeys_state. get( & pubkey) ) ;
0 commit comments