diff --git a/cabal.project b/cabal.project index d6e9c25058..77242c571e 100644 --- a/cabal.project +++ b/cabal.project @@ -14,9 +14,9 @@ repository cardano-haskell-packages -- update either of these. index-state: -- Bump this if you need newer packages from Hackage - , hackage.haskell.org 2024-08-26T10:41:44Z + , hackage.haskell.org 2024-09-16T12:20:25Z -- Bump this if you need newer packages from CHaP - , cardano-haskell-packages 2024-09-03T00:18:11Z + , cardano-haskell-packages 2024-09-11T14:05:05Z packages: ouroboros-consensus @@ -56,3 +56,21 @@ if impl(ghc >= 9.10) , cardano-ledger-binary:plutus-ledger-api , cardano-ledger-conway:plutus-ledger-api +source-repository-package + type: git + location: https://github.com/IntersectMBO/ouroboros-network + tag: 388cc6906b83f41ac2da192b1fd89ab986b4af74 + --sha256: sha256-LUwryrP5jK+/c4lDitJf/oKg/DqLgbIc68bn83FsHI0= + subdir: + cardano-client + cardano-ping + monoidal-synchronisation + network-mux + ntp-client + ouroboros-network-api + ouroboros-network-framework + ouroboros-network-mock + ouroboros-network-protocols + ouroboros-network-testing + ouroboros-network + quickcheck-monoids diff --git a/flake.lock b/flake.lock index f90219a450..28aea5f4c8 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "CHaP": { "flake": false, "locked": { - "lastModified": 1725366660, - "narHash": "sha256-TasR2Xcz8jkI9J/iP1DLSZ/F8pRl+I+G5MuVAd0iRfw=", + "lastModified": 1726511307, + "narHash": "sha256-sF62qOJCRlQZT8NYG+xGCl8Or3N7iRUR4D8oDHnYC6M=", "owner": "intersectmbo", "repo": "cardano-haskell-packages", - "rev": "33e6e90010b5635e1c732941efded22e8c4bde8d", + "rev": "993bf544a0b3fb7614403b902d835b528dc3ab5d", "type": "github" }, "original": { @@ -237,11 +237,11 @@ "hackageNix": { "flake": false, "locked": { - "lastModified": 1725237437, - "narHash": "sha256-I0u6xOAf/KzbR/92iXtb3+G8CWSDg8VOEYW42MyZZR4=", + "lastModified": 1726636349, + "narHash": "sha256-Fh+GjlpDnWtUpc02zvjULcgHZQEHuHrfKviweM7U6UY=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "77bd0734b3506f33f6a066f2aaac38434f803018", + "rev": "1d222a41735184d1fb52fa6959516cb9bf7ea319", "type": "github" }, "original": { diff --git a/ouroboros-consensus-cardano/changelog.d/20240808_125131_marcin.wojtowicz_tx_wire_size.md b/ouroboros-consensus-cardano/changelog.d/20240808_125131_marcin.wojtowicz_tx_wire_size.md new file mode 100644 index 0000000000..6d83f5fa2b --- /dev/null +++ b/ouroboros-consensus-cardano/changelog.d/20240808_125131_marcin.wojtowicz_tx_wire_size.md @@ -0,0 +1,21 @@ + + + + +### Breaking + +- Implement txWireSize of TxLimits instantiations for Byron and Shelley diff --git a/ouroboros-consensus-cardano/src/byron/Ouroboros/Consensus/Byron/Ledger/Mempool.hs b/ouroboros-consensus-cardano/src/byron/Ouroboros/Consensus/Byron/Ledger/Mempool.hs index 8200ddf8c1..42d3c708a5 100644 --- a/ouroboros-consensus-cardano/src/byron/Ouroboros/Consensus/Byron/Ledger/Mempool.hs +++ b/ouroboros-consensus-cardano/src/byron/Ouroboros/Consensus/Byron/Ledger/Mempool.hs @@ -73,6 +73,7 @@ import Ouroboros.Consensus.Ledger.Abstract import Ouroboros.Consensus.Ledger.SupportsMempool import Ouroboros.Consensus.Util (ShowProxy (..)) import Ouroboros.Consensus.Util.Condense +import Ouroboros.Network.SizeInBytes as Network {------------------------------------------------------------------------------- Transactions @@ -127,6 +128,11 @@ instance LedgerSupportsMempool ByronBlock where instance TxLimits ByronBlock where type TxMeasure ByronBlock = IgnoringOverflow ByteSize32 + txWireSize = fromIntegral + . Strict.length + . CC.mempoolPayloadRecoverBytes + . toMempoolPayload + blockCapacityTxMeasure _cfg st = IgnoringOverflow $ ByteSize32 diff --git a/ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Mempool.hs b/ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Mempool.hs index ce57f1bb3c..3facb48d92 100644 --- a/ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Mempool.hs +++ b/ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Mempool.hs @@ -39,7 +39,7 @@ module Ouroboros.Consensus.Shelley.Ledger.Mempool ( import qualified Cardano.Crypto.Hash as Hash import qualified Cardano.Ledger.Allegra.Rules as AllegraEra import Cardano.Ledger.Alonzo.Core (Tx, TxSeq, bodyTxL, eraProtVerLow, - fromTxSeq, ppMaxBBSizeL, ppMaxBlockExUnitsL, sizeTxF) + fromTxSeq, ppMaxBBSizeL, ppMaxBlockExUnitsL, sizeTxF, wireSizeTxF) import qualified Cardano.Ledger.Alonzo.Rules as AlonzoEra import Cardano.Ledger.Alonzo.Scripts (ExUnits, ExUnits', pointWiseExUnits, unWrapExUnits) @@ -385,16 +385,19 @@ instance MaxTxSizeUTxO (ConwayEra c) where instance ShelleyCompatible p (ShelleyEra c) => TxLimits (ShelleyBlock p (ShelleyEra c)) where type TxMeasure (ShelleyBlock p (ShelleyEra c)) = IgnoringOverflow ByteSize32 + txWireSize (ShelleyTx _ tx) = fromIntegral (tx ^. wireSizeTxF) txMeasure _cfg st tx = runValidation $ txInBlockSize st tx blockCapacityTxMeasure _cfg = txsMaxBytes instance ShelleyCompatible p (AllegraEra c) => TxLimits (ShelleyBlock p (AllegraEra c)) where type TxMeasure (ShelleyBlock p (AllegraEra c)) = IgnoringOverflow ByteSize32 + txWireSize (ShelleyTx _ tx) = fromIntegral (tx ^. wireSizeTxF) txMeasure _cfg st tx = runValidation $ txInBlockSize st tx blockCapacityTxMeasure _cfg = txsMaxBytes instance ShelleyCompatible p (MaryEra c) => TxLimits (ShelleyBlock p (MaryEra c)) where type TxMeasure (ShelleyBlock p (MaryEra c)) = IgnoringOverflow ByteSize32 + txWireSize (ShelleyTx _ tx) = fromIntegral (tx ^. wireSizeTxF) txMeasure _cfg st tx = runValidation $ txInBlockSize st tx blockCapacityTxMeasure _cfg = txsMaxBytes @@ -485,6 +488,7 @@ instance ( ShelleyCompatible p (AlonzoEra c) ) => TxLimits (ShelleyBlock p (AlonzoEra c)) where type TxMeasure (ShelleyBlock p (AlonzoEra c)) = AlonzoMeasure + txWireSize (ShelleyTx _ tx) = fromIntegral (tx ^. wireSizeTxF) txMeasure _cfg st tx = runValidation $ txMeasureAlonzo st tx blockCapacityTxMeasure _cfg = blockCapacityAlonzoMeasure @@ -582,6 +586,7 @@ instance ( ShelleyCompatible p (BabbageEra c) ) => TxLimits (ShelleyBlock p (BabbageEra c)) where type TxMeasure (ShelleyBlock p (BabbageEra c)) = ConwayMeasure + txWireSize (ShelleyTx _ tx) = fromIntegral (tx ^. wireSizeTxF) txMeasure _cfg st tx = runValidation $ txMeasureBabbage st tx blockCapacityTxMeasure _cfg = blockCapacityConwayMeasure @@ -589,5 +594,6 @@ instance ( ShelleyCompatible p (ConwayEra c) ) => TxLimits (ShelleyBlock p (ConwayEra c)) where type TxMeasure (ShelleyBlock p (ConwayEra c)) = ConwayMeasure + txWireSize (ShelleyTx _ tx) = fromIntegral (tx ^. wireSizeTxF) txMeasure _cfg st tx = runValidation $ txMeasureConway st tx blockCapacityTxMeasure _cfg = blockCapacityConwayMeasure diff --git a/ouroboros-consensus-cardano/src/unstable-byronspec/Ouroboros/Consensus/ByronSpec/Ledger/Mempool.hs b/ouroboros-consensus-cardano/src/unstable-byronspec/Ouroboros/Consensus/ByronSpec/Ledger/Mempool.hs index 24f9e2453b..f2512ae12d 100644 --- a/ouroboros-consensus-cardano/src/unstable-byronspec/Ouroboros/Consensus/ByronSpec/Ledger/Mempool.hs +++ b/ouroboros-consensus-cardano/src/unstable-byronspec/Ouroboros/Consensus/ByronSpec/Ledger/Mempool.hs @@ -57,6 +57,7 @@ instance TxLimits ByronSpecBlock where type TxMeasure ByronSpecBlock = IgnoringOverflow ByteSize32 -- Dummy values, as these are not used in practice. + txWireSize = const . fromIntegral $ (0 :: Int) blockCapacityTxMeasure _cfg _st = IgnoringOverflow $ ByteSize32 1 txMeasure _cfg _st _tx = pure $ IgnoringOverflow $ ByteSize32 0 diff --git a/ouroboros-consensus-diffusion/changelog.d/20240808_125632_marcin.wojtowicz_tx_wire_size.md b/ouroboros-consensus-diffusion/changelog.d/20240808_125632_marcin.wojtowicz_tx_wire_size.md new file mode 100644 index 0000000000..b774e09a01 --- /dev/null +++ b/ouroboros-consensus-diffusion/changelog.d/20240808_125632_marcin.wojtowicz_tx_wire_size.md @@ -0,0 +1,23 @@ + + + + +### Non-Breaking + +- Provide txWireSize to tx-submission protocol + + diff --git a/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Network/NodeToNode.hs b/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Network/NodeToNode.hs index 50957bce77..6d0aef8f34 100644 --- a/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Network/NodeToNode.hs +++ b/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Network/NodeToNode.hs @@ -118,6 +118,13 @@ import Ouroboros.Network.Protocol.TxSubmission2.Codec import Ouroboros.Network.Protocol.TxSubmission2.Server import Ouroboros.Network.Protocol.TxSubmission2.Type import Ouroboros.Network.TxSubmission.Inbound +import Ouroboros.Network.TxSubmission.Inbound.Policy + (TxDecisionPolicy (..)) +import Ouroboros.Network.TxSubmission.Inbound.Registry (PeerTxAPI, + withPeer) +import Ouroboros.Network.TxSubmission.Inbound.Server + (EnableNewTxSubmissionProtocol (..), txSubmissionInboundV2) +import Ouroboros.Network.TxSubmission.Inbound.Types (TraceTxLogic) import Ouroboros.Network.TxSubmission.Mempool.Reader (mapTxSubmissionMempoolReader) import Ouroboros.Network.TxSubmission.Outbound @@ -168,7 +175,13 @@ data Handlers m addr blk = Handlers { , hTxSubmissionServer :: NodeToNodeVersion -> ConnectionId addr - -> TxSubmissionServerPipelined (GenTxId blk) (GenTx blk) m () + -> Either + (TxSubmissionServerPipelined (GenTxId blk) (GenTx blk) m ()) + (PeerTxAPI m (GenTxId blk) (GenTx blk) + -> TxSubmissionServerPipelined (GenTxId blk) (GenTx blk) m ()) + -- ^ Either we use the legacy tx submission protocol or the newest one + -- which require PeerTxAPI. This is decided by + -- 'EnableNewTxSubmissionProtocol' flag. , hKeepAliveClient :: NodeToNodeVersion @@ -209,10 +222,12 @@ mkHandlers :: ) => NodeKernelArgs m addrNTN addrNTC blk -> NodeKernel m addrNTN addrNTC blk + -> EnableNewTxSubmissionProtocol -> Handlers m addrNTN blk mkHandlers NodeKernelArgs {chainSyncFutureCheck, chainSyncHistoricityCheck, keepAliveRng, miniProtocolParameters} - NodeKernel {getChainDB, getMempool, getTopLevelConfig, getTracers = tracers, getPeerSharingAPI, getGsmState} = + NodeKernel {getChainDB, getMempool, getTopLevelConfig, getTracers = tracers, getPeerSharingAPI, getGsmState} + enableNewTxSubmissionProtocol = Handlers { hChainSyncClient = \peer _isBigLedgerpeer dynEnv -> CsClient.chainSyncClient @@ -243,17 +258,32 @@ mkHandlers , hTxSubmissionClient = \version controlMessageSTM peer -> txSubmissionOutbound (contramap (TraceLabelPeer peer) (Node.txOutboundTracer tracers)) - (NumTxIdsToAck $ txSubmissionMaxUnacked miniProtocolParameters) + (NumTxIdsToAck $ getNumTxIdsToReq + $ maxUnacknowledgedTxIds + $ txDecisionPolicy + $ miniProtocolParameters) (mapTxSubmissionMempoolReader txForgetValidated $ getMempoolReader getMempool) version controlMessageSTM , hTxSubmissionServer = \version peer -> - txSubmissionInbound - (contramap (TraceLabelPeer peer) (Node.txInboundTracer tracers)) - (NumTxIdsToAck $ txSubmissionMaxUnacked miniProtocolParameters) - (mapTxSubmissionMempoolReader txForgetValidated $ getMempoolReader getMempool) - (getMempoolWriter getMempool) - version + case enableNewTxSubmissionProtocol of + EnableNewTxSubmissionProtocol -> + Right $ \api -> + txSubmissionInboundV2 + (contramap (TraceLabelPeer peer) (Node.txInboundTracer tracers)) + (getMempoolWriter getMempool) + api + DisableNewTxSubmissionProtocol -> + Left + $ txSubmissionInbound + (contramap (TraceLabelPeer peer) (Node.txInboundTracer tracers)) + (NumTxIdsToAck $ getNumTxIdsToReq + $ maxUnacknowledgedTxIds + $ txDecisionPolicy + $ miniProtocolParameters) + (mapTxSubmissionMempoolReader txForgetValidated $ getMempoolReader getMempool) + (getMempoolWriter getMempool) + version , hKeepAliveClient = \_version -> keepAliveClient (Node.keepAliveClientTracer tracers) keepAliveRng , hKeepAliveServer = \_version _peer -> keepAliveServer , hPeerSharingClient = \_version controlMessageSTM _peer -> peerSharingClient controlMessageSTM @@ -375,6 +405,7 @@ data Tracers' peer blk e f = Tracers { , tBlockFetchTracer :: f (TraceLabelPeer peer (TraceSendRecv (BlockFetch blk (Point blk)))) , tBlockFetchSerialisedTracer :: f (TraceLabelPeer peer (TraceSendRecv (BlockFetch (Serialised blk) (Point blk)))) , tTxSubmission2Tracer :: f (TraceLabelPeer peer (TraceSendRecv (TxSubmission2 (GenTxId blk) (GenTx blk)))) + , tTxLogicTracer :: f (TraceLabelPeer peer (TraceTxLogic peer (GenTxId blk) (GenTx blk))) } instance (forall a. Semigroup (f a)) => Semigroup (Tracers' peer blk e f) where @@ -384,6 +415,7 @@ instance (forall a. Semigroup (f a)) => Semigroup (Tracers' peer blk e f) where , tBlockFetchTracer = f tBlockFetchTracer , tBlockFetchSerialisedTracer = f tBlockFetchSerialisedTracer , tTxSubmission2Tracer = f tTxSubmission2Tracer + , tTxLogicTracer = f tTxLogicTracer } where f :: forall a. Semigroup a @@ -399,6 +431,7 @@ nullTracers = Tracers { , tBlockFetchTracer = nullTracer , tBlockFetchSerialisedTracer = nullTracer , tTxSubmission2Tracer = nullTracer + , tTxLogicTracer = nullTracer } showTracers :: ( Show blk @@ -416,6 +449,7 @@ showTracers tr = Tracers { , tBlockFetchTracer = showTracing tr , tBlockFetchSerialisedTracer = showTracing tr , tTxSubmission2Tracer = showTracing tr + , tTxLogicTracer = showTracing tr } {------------------------------------------------------------------------------- @@ -533,7 +567,7 @@ mkApps :: , ShowProxy blk , ShowProxy (Header blk) , ShowProxy (TxId (GenTx blk)) - , ShowProxy (GenTx blk) + , ShowProxy (GenTx blk), HasTxId (GenTx blk), LedgerSupportsMempool blk, Show addrNTN ) => NodeKernel m addrNTN addrNTC blk -- ^ Needed for bracketing only -> Tracers m (ConnectionId addrNTN) blk e @@ -695,13 +729,28 @@ mkApps kernel Tracers {..} mkCodecs ByteLimits {..} genChainSyncTimeout lopBucke -> m ((), Maybe bTX) aTxSubmission2Server version ResponderContext { rcConnectionId = them } channel = do labelThisThread "TxSubmissionServer" - runPipelinedPeerWithLimits - (contramap (TraceLabelPeer them) tTxSubmission2Tracer) - (cTxSubmission2Codec (mkCodecs version)) - blTxSubmission2 - timeLimitsTxSubmission2 - channel - (txSubmissionServerPeerPipelined (hTxSubmissionServer version them)) + + let runServer serverApi = + runPipelinedPeerWithLimits + (contramap (TraceLabelPeer them) tTxSubmission2Tracer) + (cTxSubmission2Codec (mkCodecs version)) + blTxSubmission2 + timeLimitsTxSubmission2 + channel + (txSubmissionServerPeerPipelined serverApi) + + case hTxSubmissionServer version them of + Left legacyTxSubmissionServer -> + runServer legacyTxSubmissionServer + Right newTxSubmissionServer -> + withPeer (contramap (TraceLabelPeer them) tTxLogicTracer) + (getTxChannelsVar kernel) + (getSharedTxStateVar kernel) + (mapTxSubmissionMempoolReader txForgetValidated + $ getMempoolReader (getMempool kernel)) + txWireSize + them $ \api -> + runServer (newTxSubmissionServer api) aKeepAliveClient :: NodeToNodeVersion diff --git a/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node.hs b/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node.hs index d980a52799..7dae6d407c 100644 --- a/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node.hs +++ b/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node.hs @@ -136,6 +136,8 @@ import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing) import Ouroboros.Network.PeerSelection.PeerSharing.Codec (decodeRemoteAddress, encodeRemoteAddress) import Ouroboros.Network.RethrowPolicy +import Ouroboros.Network.TxSubmission.Inbound.Server + (EnableNewTxSubmissionProtocol) import qualified SafeWildCards import System.Exit (ExitCode (..)) import System.FilePath (()) @@ -200,6 +202,9 @@ data RunNodeArgs m addrNTN addrNTC blk (p2p :: Diffusion.P2P) = RunNodeArgs { , rnGetUseBootstrapPeers :: STM m UseBootstrapPeers , rnGenesisConfig :: GenesisConfig + + -- | Enable or disable the new tx submission protocol + , rnEnableNewTxSubmissionProtocol :: EnableNewTxSubmissionProtocol } @@ -400,6 +405,7 @@ runWith :: forall m addrNTN addrNTC versionDataNTN versionDataNTC blk p2p. , Hashable addrNTN -- the constraint comes from `initNodeKernel` , NetworkIO m , NetworkAddr addrNTN + , Show addrNTN ) => RunNodeArgs m addrNTN addrNTC blk p2p -> (NodeToNodeVersion -> addrNTN -> CBOR.Encoding) @@ -567,7 +573,7 @@ runWith RunNodeArgs{..} encAddrNtN decAddrNtN LowLevelRunNodeArgs{..} = (gcChainSyncLoPBucketConfig llrnGenesisConfig) (gcCSJConfig llrnGenesisConfig) (reportMetric Diffusion.peerMetricsConfiguration peerMetrics) - (NTN.mkHandlers nodeKernelArgs nodeKernel) + (NTN.mkHandlers nodeKernelArgs nodeKernel rnEnableNewTxSubmissionProtocol) mkNodeToClientApps :: NodeKernelArgs m addrNTN (ConnectionId addrNTC) blk diff --git a/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node/Tracers.hs b/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node/Tracers.hs index e41da95bd2..57f345e403 100644 --- a/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node/Tracers.hs +++ b/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/Node/Tracers.hs @@ -42,6 +42,7 @@ import Ouroboros.Network.BlockFetch (FetchDecision, import Ouroboros.Network.KeepAlive (TraceKeepAliveClient) import Ouroboros.Network.TxSubmission.Inbound (TraceTxSubmissionInbound) +import Ouroboros.Network.TxSubmission.Inbound.Types (TraceTxLogic) import Ouroboros.Network.TxSubmission.Outbound (TraceTxSubmissionOutbound) @@ -59,6 +60,7 @@ data Tracers' remotePeer localPeer blk f = Tracers , txInboundTracer :: f (TraceLabelPeer remotePeer (TraceTxSubmissionInbound (GenTxId blk) (GenTx blk))) , txOutboundTracer :: f (TraceLabelPeer remotePeer (TraceTxSubmissionOutbound (GenTxId blk) (GenTx blk))) , localTxSubmissionServerTracer :: f (TraceLocalTxSubmissionServerEvent blk) + , txLogicTracer :: f (TraceTxLogic remotePeer (GenTxId blk) (GenTx blk)) , mempoolTracer :: f (TraceEventMempool blk) , forgeTracer :: f (TraceLabelCreds (TraceForgeEvent blk)) , blockchainTimeTracer :: f (TraceBlockchainTimeEvent UTCTime) @@ -82,6 +84,7 @@ instance (forall a. Semigroup (f a)) , txInboundTracer = f txInboundTracer , txOutboundTracer = f txOutboundTracer , localTxSubmissionServerTracer = f localTxSubmissionServerTracer + , txLogicTracer = f txLogicTracer , mempoolTracer = f mempoolTracer , forgeTracer = f forgeTracer , blockchainTimeTracer = f blockchainTimeTracer @@ -113,6 +116,7 @@ nullTracers = Tracers , txInboundTracer = nullTracer , txOutboundTracer = nullTracer , localTxSubmissionServerTracer = nullTracer + , txLogicTracer = nullTracer , mempoolTracer = nullTracer , forgeTracer = nullTracer , blockchainTimeTracer = nullTracer @@ -147,6 +151,7 @@ showTracers tr = Tracers , txInboundTracer = showTracing tr , txOutboundTracer = showTracing tr , localTxSubmissionServerTracer = showTracing tr + , txLogicTracer = showTracing tr , mempoolTracer = showTracing tr , forgeTracer = showTracing tr , blockchainTimeTracer = showTracing tr diff --git a/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/NodeKernel.hs b/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/NodeKernel.hs index 6729962fac..2ab1e7bc11 100644 --- a/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/NodeKernel.hs +++ b/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion/Ouroboros/Consensus/NodeKernel.hs @@ -94,6 +94,7 @@ import Ouroboros.Network.AnchoredFragment (AnchoredFragment, import qualified Ouroboros.Network.AnchoredFragment as AF import Ouroboros.Network.Block (castTip, tipFromHeader) import Ouroboros.Network.BlockFetch +import Ouroboros.Network.BlockFetch.ClientRegistry (readPeerGSVs) import Ouroboros.Network.Diffusion (PublicPeerSelectionState) import Ouroboros.Network.NodeToNode (ConnectionId, MiniProtocolParameters (..)) @@ -110,6 +111,9 @@ import Ouroboros.Network.SizeInBytes import Ouroboros.Network.TxSubmission.Inbound (TxSubmissionMempoolWriter) import qualified Ouroboros.Network.TxSubmission.Inbound as Inbound +import Ouroboros.Network.TxSubmission.Inbound.Registry + (SharedTxStateVar, TxChannelsVar, + decisionLogicThread, newSharedTxStateVar, newTxChannelsVar) import Ouroboros.Network.TxSubmission.Mempool.Reader (TxSubmissionMempoolReader) import qualified Ouroboros.Network.TxSubmission.Mempool.Reader as MempoolReader @@ -162,6 +166,14 @@ data NodeKernel m addrNTN addrNTC blk = NodeKernel { , getOutboundConnectionsState :: StrictTVar m OutboundConnectionsState + + -- | Communication channels between `TxSubmission` client mini-protocol and + -- decision logic. + , getTxChannelsVar :: TxChannelsVar m (ConnectionId addrNTN) (GenTxId blk) (GenTx blk) + + -- | Shared state of all `TxSubmission` clients. + -- + , getSharedTxStateVar :: SharedTxStateVar m (ConnectionId addrNTN) (GenTxId blk) (GenTx blk) } -- | Arguments required when initializing a node @@ -207,6 +219,7 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers , peerSharingRng , publicPeerSelectionStateVar , genesisArgs + , miniProtocolParameters } = do -- using a lazy 'TVar', 'BlockForging' does not have a 'NoThunks' instance. blockForgingVar :: LazySTM.TMVar m [BlockForging m blk] <- LazySTM.newTMVarIO [] @@ -279,6 +292,9 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers ps_POLICY_PEER_SHARE_STICKY_TIME ps_POLICY_PEER_SHARE_MAX_PEERS + txChannelsVar <- newTxChannelsVar + sharedTxStateVar <- newSharedTxStateVar + case gnkaGetLoEFragment genesisArgs of LoEAndGDDDisabled -> pure () LoEAndGDDEnabled varGetLoEFragment -> do @@ -311,6 +327,14 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers fetchClientRegistry blockFetchConfiguration + void $ forkLinkedThread registry "NodeKernel.decisionLogicThread" $ + decisionLogicThread + (txLogicTracer tracers) + (txDecisionPolicy miniProtocolParameters) + (readPeerGSVs fetchClientRegistry) + txChannelsVar + sharedTxStateVar + return NodeKernel { getChainDB = chainDB , getMempool = mempool @@ -325,6 +349,8 @@ initNodeKernel args@NodeKernelArgs { registry, cfg, tracers , getPeerSharingAPI = peerSharingAPI , getOutboundConnectionsState = varOutboundConnectionsState + , getTxChannelsVar = txChannelsVar + , getSharedTxStateVar = sharedTxStateVar } where blockForgingController :: InternalState m remotePeer localPeer blk diff --git a/ouroboros-consensus-diffusion/src/unstable-diffusion-testlib/Test/ThreadNet/Network.hs b/ouroboros-consensus-diffusion/src/unstable-diffusion-testlib/Test/ThreadNet/Network.hs index 88f8387746..edfc936ed3 100644 --- a/ouroboros-consensus-diffusion/src/unstable-diffusion-testlib/Test/ThreadNet/Network.hs +++ b/ouroboros-consensus-diffusion/src/unstable-diffusion-testlib/Test/ThreadNet/Network.hs @@ -122,6 +122,10 @@ import Ouroboros.Network.Protocol.KeepAlive.Type import Ouroboros.Network.Protocol.Limits (waitForever) import Ouroboros.Network.Protocol.PeerSharing.Type (PeerSharing) import Ouroboros.Network.Protocol.TxSubmission2.Type +import Ouroboros.Network.TxSubmission.Inbound.Policy + (TxDecisionPolicy (..), defaultTxDecisionPolicy) +import Ouroboros.Network.TxSubmission.Inbound.Server + (EnableNewTxSubmissionProtocol (..)) import qualified System.FS.Sim.MockFS as Mock import System.FS.Sim.MockFS (MockFS) import System.Random (mkStdGen, split) @@ -1015,7 +1019,8 @@ runThreadNetwork systemTime ThreadNetworkArgs chainSyncPipeliningHighMark = 4, chainSyncPipeliningLowMark = 2, blockFetchPipeliningMax = 10, - txSubmissionMaxUnacked = 1000 -- TODO ? + txDecisionPolicy = + defaultTxDecisionPolicy { maxUnacknowledgedTxIds = 1000 } -- TODO ? } , blockFetchConfiguration = BlockFetchConfiguration { bfcMaxConcurrencyBulkSync = 1 @@ -1071,7 +1076,7 @@ runThreadNetwork systemTime ThreadNetworkArgs -- The purpose of this test is not testing protocols, so -- returning constant empty list is fine if we have thorough -- tests about the peer sharing protocol itself. - (NTN.mkHandlers nodeKernelArgs nodeKernel) + (NTN.mkHandlers nodeKernelArgs nodeKernel DisableNewTxSubmissionProtocol) -- In practice, a robust wallet/user can persistently add a transaction -- until it appears on the chain. This thread adds robustness for the diff --git a/ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator/A.hs b/ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator/A.hs index 4aa3b65074..4c24bc5edc 100644 --- a/ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator/A.hs +++ b/ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator/A.hs @@ -330,6 +330,7 @@ instance LedgerSupportsMempool BlockA where instance TxLimits BlockA where type TxMeasure BlockA = IgnoringOverflow ByteSize32 + txWireSize = const . fromIntegral $ (0 :: Int) blockCapacityTxMeasure _cfg _st = IgnoringOverflow $ ByteSize32 $ 100 * 1024 -- arbitrary txMeasure _cfg _st _tx = pure $ IgnoringOverflow $ ByteSize32 0 diff --git a/ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator/B.hs b/ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator/B.hs index 7c45c64137..3119f87bf9 100644 --- a/ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator/B.hs +++ b/ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator/B.hs @@ -266,6 +266,7 @@ instance LedgerSupportsMempool BlockB where instance TxLimits BlockB where type TxMeasure BlockB = IgnoringOverflow ByteSize32 + txWireSize = const . fromIntegral $ (0 :: Int) blockCapacityTxMeasure _cfg _st = IgnoringOverflow $ ByteSize32 $ 100 * 1024 -- arbitrary txMeasure _cfg _st _tx = pure $ IgnoringOverflow $ ByteSize32 0 diff --git a/ouroboros-consensus/bench/mempool-bench/Bench/Consensus/Mempool/TestBlock.hs b/ouroboros-consensus/bench/mempool-bench/Bench/Consensus/Mempool/TestBlock.hs index 2d865028bb..df84700e7b 100644 --- a/ouroboros-consensus/bench/mempool-bench/Bench/Consensus/Mempool/TestBlock.hs +++ b/ouroboros-consensus/bench/mempool-bench/Bench/Consensus/Mempool/TestBlock.hs @@ -151,6 +151,7 @@ instance Ledger.LedgerSupportsMempool TestBlock where instance Ledger.TxLimits TestBlock where type TxMeasure TestBlock = Ledger.IgnoringOverflow Ledger.ByteSize32 + txWireSize = fromIntegral . Ledger.unByteSize32 . txSize -- We tweaked this in such a way that we test the case in which we exceed the -- maximum mempool capacity. The value used here depends on 'txInBlockSize'. blockCapacityTxMeasure _cfg _st = diff --git a/ouroboros-consensus/changelog.d/20240808_101916_marcin.wojtowicz_tx_wire_size.md b/ouroboros-consensus/changelog.d/20240808_101916_marcin.wojtowicz_tx_wire_size.md new file mode 100644 index 0000000000..69ad0fb64c --- /dev/null +++ b/ouroboros-consensus/changelog.d/20240808_101916_marcin.wojtowicz_tx_wire_size.md @@ -0,0 +1,23 @@ + + + + +### Breaking + +- Added txWireSize method to TxLimits class to provide + a CBOR-encoded transaction size as it is when transmitted + over the network. diff --git a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Mempool.hs b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Mempool.hs index a987cb7c32..d7a08275ec 100644 --- a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Mempool.hs +++ b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Mempool.hs @@ -119,6 +119,12 @@ instance CanHardFork xs => LedgerSupportsMempool (HardForkBlock xs) where instance CanHardFork xs => TxLimits (HardForkBlock xs) where type TxMeasure (HardForkBlock xs) = HardForkTxMeasure xs + txWireSize = + hcollapse + . hcmap proxySingle (K . txWireSize) + . getOneEraGenTx + . getHardForkGenTx + blockCapacityTxMeasure HardForkLedgerConfig{..} (TickedHardForkLedgerState transition hardForkState) diff --git a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Ledger/Dual.hs b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Ledger/Dual.hs index a5dc517634..3aefd79c5d 100644 --- a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Ledger/Dual.hs +++ b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Ledger/Dual.hs @@ -625,6 +625,7 @@ instance Bridge m a => LedgerSupportsMempool (DualBlock m a) where instance Bridge m a => TxLimits (DualBlock m a) where type TxMeasure (DualBlock m a) = TxMeasure m + txWireSize = txWireSize . dualGenTxMain txMeasure DualLedgerConfig{..} TickedDualLedgerState{..} DualGenTx{..} = do mapExcept (inj +++ id) $ txMeasure dualLedgerConfigMain tickedDualLedgerStateMain dualGenTxMain diff --git a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Ledger/SupportsMempool.hs b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Ledger/SupportsMempool.hs index 3a218241f3..11b494ae0b 100644 --- a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Ledger/SupportsMempool.hs +++ b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Ledger/SupportsMempool.hs @@ -37,6 +37,7 @@ import NoThunks.Class import Ouroboros.Consensus.Block.Abstract import Ouroboros.Consensus.Ledger.Abstract import Ouroboros.Consensus.Ticked +import Ouroboros.Network.SizeInBytes as Network -- | Generalized transaction -- @@ -179,6 +180,10 @@ class ( Measure (TxMeasure blk) -- | The (possibly multi-dimensional) size of a transaction in a block. type TxMeasure blk + -- | The size of the transaction from the perspective of diffusion layer + -- + txWireSize :: GenTx blk -> Network.SizeInBytes + -- | The various sizes (bytes, Plutus script ExUnits, etc) of a tx /when it's -- in a block/ -- diff --git a/ouroboros-consensus/src/unstable-mock-block/Ouroboros/Consensus/Mock/Ledger/Block.hs b/ouroboros-consensus/src/unstable-mock-block/Ouroboros/Consensus/Mock/Ledger/Block.hs index c006b0e6f0..30a2978c44 100644 --- a/ouroboros-consensus/src/unstable-mock-block/Ouroboros/Consensus/Mock/Ledger/Block.hs +++ b/ouroboros-consensus/src/unstable-mock-block/Ouroboros/Consensus/Mock/Ledger/Block.hs @@ -438,6 +438,7 @@ instance MockProtocolSpecific c ext instance TxLimits (SimpleBlock c ext) where type TxMeasure (SimpleBlock c ext) = IgnoringOverflow ByteSize32 + txWireSize = fromIntegral . unByteSize32 . txSize -- Large value so that the Mempool tests never run out of capacity when they -- don't override it. -- diff --git a/ouroboros-consensus/test/consensus-test/Test/Consensus/Mempool/Fairness/TestBlock.hs b/ouroboros-consensus/test/consensus-test/Test/Consensus/Mempool/Fairness/TestBlock.hs index 82131b3479..1fe4bda4cc 100644 --- a/ouroboros-consensus/test/consensus-test/Test/Consensus/Mempool/Fairness/TestBlock.hs +++ b/ouroboros-consensus/test/consensus-test/Test/Consensus/Mempool/Fairness/TestBlock.hs @@ -91,6 +91,7 @@ instance Ledger.LedgerSupportsMempool TestBlock where instance Ledger.TxLimits TestBlock where type TxMeasure TestBlock = Ledger.IgnoringOverflow Ledger.ByteSize32 + txWireSize = fromIntegral . Ledger.unByteSize32 . txSize . unGenTx blockCapacityTxMeasure _cfg _st = -- The tests will override this value. By using 1, @computeMempoolCapacity@ -- can be exactly what each test requests.