-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Let the thread which fetched a TX add it to the mempool #4984
base: bolt12/coot/tx-submission
Are you sure you want to change the base?
Changes from 2 commits
a9cd34d
a3de87b
cff7de3
64b8292
b681619
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ import Data.Foldable (traverse_ | |
, foldl' | ||
#endif | ||
) | ||
import Data.Functor (void) | ||
import Data.Map.Strict (Map) | ||
import Data.Map.Strict qualified as Map | ||
import Data.Maybe (fromMaybe) | ||
|
@@ -75,8 +76,14 @@ data PeerTxAPI m txid tx = PeerTxAPI { | |
-- ^ requested txids | ||
-> Map txid tx | ||
-- ^ received txs | ||
-> m () | ||
-> m (), | ||
-- ^ handle received txs | ||
|
||
countRejectedTxs :: Int | ||
-> m Int, | ||
|
||
consumeFetchedTxs :: Set txid | ||
-> m (Set txid) | ||
} | ||
|
||
|
||
|
@@ -123,7 +130,9 @@ withPeer tracer | |
( TxChannels { txChannelMap = txChannelMap' } | ||
, PeerTxAPI { readTxDecision = takeMVar chann', | ||
handleReceivedTxIds, | ||
handleReceivedTxs } | ||
handleReceivedTxs, | ||
countRejectedTxs, | ||
consumeFetchedTxs } | ||
) | ||
|
||
atomically $ modifyTVar sharedStateVar registerPeer | ||
|
@@ -151,7 +160,9 @@ withPeer tracer | |
requestedTxsInflightSize = 0, | ||
requestedTxsInflight = Set.empty, | ||
unacknowledgedTxIds = StrictSeq.empty, | ||
unknownTxs = Set.empty } | ||
unknownTxs = Set.empty, | ||
rejectedTxs = 0, | ||
fetchedTxs = Set.empty } | ||
peerTxStates | ||
} | ||
|
||
|
@@ -210,8 +221,43 @@ withPeer tracer | |
-> Map txid tx | ||
-- ^ received txs | ||
-> m () | ||
handleReceivedTxs txids txs = | ||
handleReceivedTxs txids txs = do | ||
void $ atomically $ modifyTVar sharedStateVar addFethed | ||
collectTxs tracer sharedStateVar peeraddr txids txs | ||
where | ||
addFethed :: SharedTxState peeraddr txid tx | ||
-> SharedTxState peeraddr txid tx | ||
addFethed st@SharedTxState { peerTxStates } = | ||
let peerTxStates' = Map.update (\ps -> Just $! ps { fetchedTxs = Set.union (fetchedTxs ps) txids }) peeraddr peerTxStates in | ||
st {peerTxStates = peerTxStates' } | ||
|
||
countRejectedTxs :: Int | ||
-> m Int | ||
countRejectedTxs n = atomically $ do | ||
modifyTVar sharedStateVar cntRejects | ||
st <- readTVar sharedStateVar | ||
case Map.lookup peeraddr (peerTxStates st) of | ||
Nothing -> error "missing peer updated" | ||
Just ps -> return $ rejectedTxs ps | ||
where | ||
cntRejects :: SharedTxState peeraddr txid tx | ||
-> SharedTxState peeraddr txid tx | ||
cntRejects st@SharedTxState { peerTxStates } = | ||
let peerTxStates' = Map.update (\ps -> Just $! ps { rejectedTxs = min 42 (max (-42) (rejectedTxs ps + n)) }) peeraddr peerTxStates in | ||
st {peerTxStates = peerTxStates'} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will be more efficient to update it for all peers at once, but it might be harder to implement it. Another way would be to store the counts in |
||
|
||
consumeFetchedTxs :: Set txid | ||
-> m (Set txid) | ||
consumeFetchedTxs otxids = atomically $ do | ||
st <- readTVar sharedStateVar | ||
case Map.lookup peeraddr (peerTxStates st) of | ||
Nothing -> error "missing peer in consumeFetchedTxs" | ||
Just ps -> do | ||
let o = Set.intersection (fetchedTxs ps) otxids | ||
r = Set.difference (fetchedTxs ps) otxids | ||
st' = st { peerTxStates = Map.update (\ps' -> Just $! ps' { fetchedTxs = r }) peeraddr (peerTxStates st) } | ||
writeTVar sharedStateVar st' | ||
return o | ||
|
||
|
||
decisionLogicThread | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -16,14 +16,16 @@ import Data.Set qualified as Set | |||||
import Control.Concurrent.Class.MonadSTM.Strict | ||||||
import Control.Exception (assert) | ||||||
import Control.Monad.Class.MonadThrow | ||||||
import Control.Monad.Class.MonadTime.SI | ||||||
import Control.Tracer (Tracer, traceWith) | ||||||
|
||||||
import Network.TypedProtocol.Pipelined | ||||||
|
||||||
import Control.Monad (unless) | ||||||
import Control.Monad (unless, when) | ||||||
import Ouroboros.Network.Protocol.TxSubmission2.Server | ||||||
import Ouroboros.Network.TxSubmission.Inbound.Registry (PeerTxAPI (..)) | ||||||
import Ouroboros.Network.TxSubmission.Inbound.Types | ||||||
import Ouroboros.Network.TxSubmission.Mempool.Reader | ||||||
|
||||||
-- | Flag to enable/disable the usage of the new tx submission protocol | ||||||
-- | ||||||
|
@@ -43,22 +45,29 @@ txSubmissionInboundV2 | |||||
:: forall txid tx idx m. | ||||||
( MonadSTM m | ||||||
, MonadThrow m | ||||||
, MonadMonotonicTime m | ||||||
, Ord txid | ||||||
) | ||||||
=> Tracer m (TraceTxSubmissionInbound txid tx) | ||||||
-> TxSubmissionMempoolReader txid tx idx m | ||||||
-> TxSubmissionMempoolWriter txid tx idx m | ||||||
-> PeerTxAPI m txid tx | ||||||
-> TxSubmissionServerPipelined txid tx m () | ||||||
txSubmissionInboundV2 | ||||||
tracer | ||||||
TxSubmissionMempoolReader{ | ||||||
mempoolGetSnapshot | ||||||
} | ||||||
TxSubmissionMempoolWriter { | ||||||
txId, | ||||||
mempoolAddTxs | ||||||
} | ||||||
PeerTxAPI { | ||||||
readTxDecision, | ||||||
handleReceivedTxIds, | ||||||
handleReceivedTxs | ||||||
handleReceivedTxs, | ||||||
countRejectedTxs, | ||||||
consumeFetchedTxs | ||||||
} | ||||||
= | ||||||
TxSubmissionServerPipelined serverIdle | ||||||
|
@@ -70,18 +79,53 @@ txSubmissionInboundV2 | |||||
txd@TxDecision { txdTxsToRequest = txsToReq, txdTxsToMempool = txs } | ||||||
<- readTxDecision | ||||||
traceWith tracer (TraceTxInboundDecision txd) | ||||||
txidsAccepted <- mempoolAddTxs txs | ||||||
traceWith tracer $ | ||||||
TraceTxInboundAddedToMempool txidsAccepted | ||||||
|
||||||
let !collected = length txs | ||||||
let !accepted = length txidsAccepted | ||||||
traceWith tracer $ | ||||||
TraceTxSubmissionCollected collected | ||||||
|
||||||
traceWith tracer $ TraceTxSubmissionProcessed ProcessedTxCount { | ||||||
ptxcAccepted = accepted | ||||||
, ptxcRejected = collected - accepted | ||||||
} | ||||||
mpSnapshot <- atomically mempoolGetSnapshot | ||||||
let receivedL = [ (txId tx, tx) | tx <- txs ] | ||||||
fetchedSet <- consumeFetchedTxs (Set.fromList (map fst receivedL)) | ||||||
|
||||||
-- Only attempt to add TXs if we actually has fetched some. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
when (not $ Set.null fetchedSet) $ do | ||||||
let fetched = filter | ||||||
(\(txid, _) -> Set.member txid fetchedSet) | ||||||
receivedL | ||||||
fetchedS = Set.fromList $ map fst fetched | ||||||
|
||||||
-- Note that checking if the mempool contains a TX before | ||||||
-- spending several ms attempting to add it to the pool has | ||||||
-- been judged immoral. | ||||||
Comment on lines
+94
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😁 |
||||||
let fresh = filter | ||||||
(\(txid, _) -> not $ mempoolHasTx mpSnapshot txid) | ||||||
receivedL | ||||||
|
||||||
!start <- getMonotonicTime | ||||||
txidsAccepted <- mempoolAddTxs $ map snd fresh | ||||||
!end <- getMonotonicTime | ||||||
let duration = diffTime end start | ||||||
|
||||||
let acceptedS = Set.fromList txidsAccepted | ||||||
acceptedFetched = Set.intersection fetchedS acceptedS | ||||||
!accepted = Set.size acceptedFetched | ||||||
!rejected = Set.size fetchedS - accepted | ||||||
|
||||||
traceWith tracer $ | ||||||
TraceTxInboundAddedToMempool txidsAccepted duration | ||||||
traceWith tracer $ | ||||||
TraceTxSubmissionCollected collected | ||||||
|
||||||
-- Accepted TXs are discounted from rejected. | ||||||
-- | ||||||
-- The number of rejected TXs may be too high. | ||||||
-- The reason for that is that any peer which has downloaded a | ||||||
-- TX is permitted to add TXs for all TXids hit has offered. | ||||||
-- This is done to preserve TX ordering. | ||||||
!s <- countRejectedTxs (rejected - accepted) -- accepted TXs are discounted | ||||||
traceWith tracer $ TraceTxSubmissionProcessed ProcessedTxCount { | ||||||
ptxcAccepted = accepted | ||||||
, ptxcRejected = rejected | ||||||
, ptxcScore = s | ||||||
} | ||||||
|
||||||
-- TODO: | ||||||
-- We can update the state so that other `tx-submission` servers will | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be a
TODO
?