@@ -1203,19 +1203,42 @@ fn process_sync_pubkey_orderbook_state(
12031203 let order_getter = |uuid : & Uuid | orderbook. order_set . get ( uuid) . cloned ( ) ;
12041204 let pair_orders_diff: Result < HashMap < _ , _ > , _ > = trie_roots
12051205 . into_iter ( )
1206- . map ( |( pair, root ) | {
1207- let actual_pair_root = pubkey_state
1206+ . map ( |( pair, from_root ) | {
1207+ let latest_known_root = pubkey_state
12081208 . trie_roots
12091209 . get ( & pair)
12101210 . ok_or ( ERRL ! ( "No pair trie root for {}" , pair) ) ?;
12111211
1212+ // Determine the target (to) root:
1213+ // - exact v2 sync: use the requester’s expected root
1214+ // - legacy sync: use our latest known root
1215+ let maybe_expected = expected_roots. as_ref ( ) . and_then ( |roots| roots. get ( & pair) ) ;
1216+ let target_root = maybe_expected. unwrap_or ( latest_known_root) ;
1217+
1218+ // NOTE(exact-sync): We allow FullTrie fallback even when `expected_roots` is present.
1219+ // Rationale: `from_root` may originate from GetOrderbook or other flows and is not
1220+ // verifiable today if the sender was malicious; an exact delta chain from `from_root`
1221+ // to `target_root` might be unavailable. Falling back to a FullTrie at `target_root`
1222+ // still lets the requester land exactly on the expected root and pass the apply gate.
1223+ //
1224+ // TODO(exact-sync, removal conditions):
1225+ // - Persist the last KeepAlive root per pubkey and include it with GetOrderbook so
1226+ // the requester’s `from_root` can be anchored/validated against a recent KA.
1227+ // - Once `from_root` is verifiable, change exact mode to error (no fallback) when
1228+ // history cannot reconstruct the from→to chain.
1229+ // - Consider TRIE_STATE_HISTORY_TIMEOUT tuning: larger window ⇒ fewer missing chains;
1230+ // smaller window ⇒ more missing chains but lower memory. Coordinate with gossipsub
1231+ // dedup (~60s) so alternate-source retries are effective within the history window.
1232+
12121233 let delta_result = match pubkey_state. order_pairs_trie_state_history . get ( & pair) {
1213- Some ( history) => {
1214- DeltaOrFullTrie :: from_history ( history, root, * actual_pair_root, & orderbook. memory_db , order_getter)
1215- } ,
1216- None => {
1217- get_full_trie ( actual_pair_root, & orderbook. memory_db , order_getter) . map ( DeltaOrFullTrie :: FullTrie )
1218- } ,
1234+ Some ( history) => DeltaOrFullTrie :: from_history (
1235+ history,
1236+ from_root,
1237+ * target_root,
1238+ & orderbook. memory_db ,
1239+ order_getter,
1240+ ) ,
1241+ None => get_full_trie ( target_root, & orderbook. memory_db , order_getter) . map ( DeltaOrFullTrie :: FullTrie ) ,
12191242 } ;
12201243
12211244 let delta = try_s ! ( delta_result) ;
0 commit comments