Skip to content

Commit d6bf451

Browse files
committed
WIP: Use the same TX fetch preference as V1
1 parent f952b66 commit d6bf451

3 files changed

Lines changed: 43 additions & 32 deletions

File tree

  • ouroboros-network

ouroboros-network/lib/Ouroboros/Network/TxSubmission/Inbound/V2/State.hs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module Ouroboros.Network.TxSubmission.Inbound.V2.State
1818

1919
import Control.Monad.Class.MonadTime.SI (DiffTime, Time, addTime, diffTime)
2020
import Data.Foldable (foldl', toList)
21+
import Data.List (sortOn)
2122
import Data.IntMap.Strict qualified as IntMap
2223
import Data.IntSet (IntSet)
2324
import Data.IntSet qualified as IntSet
@@ -373,13 +374,14 @@ pickRequestTxsAction ctx@PeerActionContext { pacNow, pacPolicy, pacPeerState, pa
373374

374375
leaseUntil = addTime (interTxSpace pacPolicy) pacNow
375376

376-
-- Iterate the peer's unacknowledged queue, which preserves the peer's
377-
-- advertisement order. Peers are expected to advertise in chain-
378-
-- topological order (parents before children), so walking in that
379-
-- order aligns fetch order with submission-validity order and a
380-
-- child is never requested ahead of its parent when the same peer
381-
-- carries both.
377+
-- Order candidates by raw txid bytes so every node in the network
378+
-- prioritises the same fetches, regardless of which peer
379+
-- advertised them first locally. This mirrors V1's
380+
-- 'Map.splitAt' on 'Map txid SizeInBytes' priority and produces
381+
-- convergent cross-node propagation. Submission still happens
382+
-- in advertisement order via 'pickSubmitAction'.
382383
candidates =
384+
sortOn (\(k, _) -> IntMap.lookup k (sharedKeyToRawTxId pacSharedState))
383385
[ (k, txSize)
384386
| TxKey k <- toList (peerUnacknowledgedTxIds pacPeerState)
385387
, IntSet.notMember k (peerRequestedTxs pacPeerState)
@@ -771,14 +773,15 @@ dropTxKeys :: HasRawTxId txid
771773
-> SharedTxState peeraddr txid
772774
-> SharedTxState peeraddr txid
773775
dropTxKeys keys st@SharedTxState { sharedTxTable, sharedRetainedTxs, sharedTxIdToKey
774-
, sharedKeyToTxId }
776+
, sharedKeyToTxId, sharedKeyToRawTxId }
775777
| IntSet.null keys = st
776778
| otherwise =
777779
st {
778-
sharedTxTable = IntMap.withoutKeys sharedTxTable keys,
779-
sharedRetainedTxs = retainedDeleteKeys keys sharedRetainedTxs,
780-
sharedTxIdToKey = IntSet.foldl' deleteTxId sharedTxIdToKey keys,
781-
sharedKeyToTxId = IntMap.withoutKeys sharedKeyToTxId keys
780+
sharedTxTable = IntMap.withoutKeys sharedTxTable keys,
781+
sharedRetainedTxs = retainedDeleteKeys keys sharedRetainedTxs,
782+
sharedTxIdToKey = IntSet.foldl' deleteTxId sharedTxIdToKey keys,
783+
sharedKeyToTxId = IntMap.withoutKeys sharedKeyToTxId keys,
784+
sharedKeyToRawTxId = IntMap.withoutKeys sharedKeyToRawTxId keys
782785
}
783786
where
784787
deleteTxId txIdToKey k =
@@ -794,12 +797,13 @@ dropLookupOnly :: HasRawTxId txid
794797
=> IntSet.IntSet
795798
-> SharedTxState peeraddr txid
796799
-> SharedTxState peeraddr txid
797-
dropLookupOnly keys st@SharedTxState { sharedTxIdToKey, sharedKeyToTxId }
800+
dropLookupOnly keys st@SharedTxState { sharedTxIdToKey, sharedKeyToTxId, sharedKeyToRawTxId }
798801
| IntSet.null keys = st
799802
| otherwise =
800803
st {
801-
sharedTxIdToKey = IntSet.foldl' deleteTxId sharedTxIdToKey keys,
802-
sharedKeyToTxId = IntMap.withoutKeys sharedKeyToTxId keys
804+
sharedTxIdToKey = IntSet.foldl' deleteTxId sharedTxIdToKey keys,
805+
sharedKeyToTxId = IntMap.withoutKeys sharedKeyToTxId keys,
806+
sharedKeyToRawTxId = IntMap.withoutKeys sharedKeyToRawTxId keys
803807
}
804808
where
805809
deleteTxId txIdToKey k =
@@ -1308,16 +1312,18 @@ handleReceivedTxIds mempoolHasTx now policy requestedTxIds txidsAndSizes
13081312
sharedChangedAcc' = sharedChangedAcc || txKeyWasNew
13091313
(txKey@(TxKey k), txKeyWasNew, sharedAcc') = lookupOrInternTxId txid sharedAcc
13101314

1311-
lookupOrInternTxId txid st@SharedTxState { sharedTxIdToKey, sharedKeyToTxId, sharedNextTxKey }
1315+
lookupOrInternTxId txid st@SharedTxState { sharedTxIdToKey, sharedKeyToTxId
1316+
, sharedKeyToRawTxId, sharedNextTxKey }
13121317
| Just key <- Map.lookup rawId sharedTxIdToKey = (key, False, st)
13131318
| otherwise =
13141319
let key = TxKey sharedNextTxKey
13151320
in ( key
13161321
, True
13171322
, st {
1318-
sharedTxIdToKey = Map.insert rawId key sharedTxIdToKey,
1319-
sharedKeyToTxId = IntMap.insert sharedNextTxKey txid sharedKeyToTxId,
1320-
sharedNextTxKey = sharedNextTxKey + 1
1323+
sharedTxIdToKey = Map.insert rawId key sharedTxIdToKey,
1324+
sharedKeyToTxId = IntMap.insert sharedNextTxKey txid sharedKeyToTxId,
1325+
sharedKeyToRawTxId = IntMap.insert sharedNextTxKey rawId sharedKeyToRawTxId,
1326+
sharedNextTxKey = sharedNextTxKey + 1
13211327
}
13221328
)
13231329
where rawId = getRawTxId txid

ouroboros-network/lib/Ouroboros/Network/TxSubmission/Inbound/V2/Types.hs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,11 @@ data SharedTxState peeraddr txid = SharedTxState {
489489
-- | Accepted txs retained locally for a bounded time so later txid
490490
-- advertisements can be acked without re-requesting the body.
491491
sharedRetainedTxs :: !RetainedTxs,
492-
sharedTxIdToKey :: !(Map RawTxId TxKey),
493-
sharedKeyToTxId :: !(IntMap txid),
494-
sharedNextTxKey :: !Int,
495-
sharedGeneration :: !Word64
492+
sharedTxIdToKey :: !(Map RawTxId TxKey),
493+
sharedKeyToTxId :: !(IntMap txid),
494+
sharedKeyToRawTxId :: !(IntMap RawTxId),
495+
sharedNextTxKey :: !Int,
496+
sharedGeneration :: !Word64
496497
}
497498
deriving stock (Eq, Show, Generic)
498499
deriving anyclass (NFData, NoThunks)
@@ -517,6 +518,7 @@ emptySharedTxState = SharedTxState {
517518
sharedRetainedTxs = retainedEmpty,
518519
sharedTxIdToKey = Map.empty,
519520
sharedKeyToTxId = IntMap.empty,
521+
sharedKeyToRawTxId = IntMap.empty,
520522
sharedNextTxKey = 0,
521523
sharedGeneration = 0
522524
}
@@ -635,15 +637,17 @@ internTxId :: HasRawTxId txid
635637
=> txid
636638
-> SharedTxState peeraddr txid
637639
-> (RawTxId, TxKey, SharedTxState peeraddr txid)
638-
internTxId txid st@SharedTxState { sharedTxIdToKey, sharedKeyToTxId, sharedNextTxKey }
640+
internTxId txid st@SharedTxState { sharedTxIdToKey, sharedKeyToTxId
641+
, sharedKeyToRawTxId, sharedNextTxKey }
639642
| Just key <- Map.lookup rawId sharedTxIdToKey = (rawId, key, st)
640643
| otherwise =
641644
let key = TxKey sharedNextTxKey in
642645
( rawId
643646
, key
644-
, st { sharedTxIdToKey = Map.insert rawId key sharedTxIdToKey
645-
, sharedKeyToTxId = IntMap.insert sharedNextTxKey txid sharedKeyToTxId
646-
, sharedNextTxKey = sharedNextTxKey + 1
647+
, st { sharedTxIdToKey = Map.insert rawId key sharedTxIdToKey
648+
, sharedKeyToTxId = IntMap.insert sharedNextTxKey txid sharedKeyToTxId
649+
, sharedKeyToRawTxId = IntMap.insert sharedNextTxKey rawId sharedKeyToRawTxId
650+
, sharedNextTxKey = sharedNextTxKey + 1
647651
}
648652
)
649653
where

ouroboros-network/tests/lib/Test/Ouroboros/Network/TxSubmission/TxLogic.hs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import Data.Foldable (foldl', toList)
3232
import Data.Function (on)
3333
import Data.IntMap.Strict qualified as IntMap
3434
import Data.IntSet qualified as IntSet
35-
import Data.List (elemIndex, mapAccumL, nub, nubBy, sortBy)
35+
import Data.List (elemIndex, mapAccumL, nub, nubBy, sortBy, sortOn)
3636
import Data.Map.Strict qualified as Map
3737
import Data.Maybe (listToMaybe)
3838
import Data.Sequence.Strict qualified as StrictSeq
@@ -990,9 +990,7 @@ prop_nextPeerAction_picksTxsRespectingBudget (ArbTxDecisionPolicy policy0)
990990
(IntMap.lookup k (peerAvailableTxIds peerState1))
991991

992992
budget = getSizeInBytes (txsSizeInflightPerPeer policy)
993-
isPrefix _ [] = True
994-
isPrefix [] _ = False
995-
isPrefix (x:xs) (y:ys) = x == y && isPrefix xs ys
993+
rawIdOf k = IntMap.lookup k (sharedKeyToRawTxId sharedState1)
996994
in
997995
case action of
998996
PeerRequestTxs picked ->
@@ -1003,8 +1001,11 @@ prop_nextPeerAction_picksTxsRespectingBudget (ArbTxDecisionPolicy policy0)
10031001
-- total at or below the budget.
10041002
tailSize = pickedSize - maybe 0 sizeOf (listToMaybe pickedKeys)
10051003
in conjoin
1006-
[ counterexample "picked is not a prefix of the unacked queue"
1007-
(property (pickedKeys `isPrefix` keyOrder))
1004+
[ counterexample "picked is not a subset of the unacked queue"
1005+
(property (IntSet.fromList pickedKeys
1006+
`IntSet.isSubsetOf` IntSet.fromList keyOrder))
1007+
, counterexample "picked is not in raw-txid order"
1008+
(property (pickedKeys == sortOn rawIdOf pickedKeys))
10081009
, counterexample
10091010
("tail of picked exceeds budget: " ++ show pickedSize)
10101011
(property (tailSize <= budget))

0 commit comments

Comments
 (0)