@@ -61,9 +61,6 @@ module Chainweb.Chainweb
6161, chainwebPeer
6262, chainwebPayloadDb
6363, chainwebPactData
64- , chainwebThrottler
65- , chainwebPutPeerThrottler
66- , chainwebMempoolThrottler
6764, chainwebConfig
6865, chainwebServiceSocket
6966, chainwebBackup
@@ -79,15 +76,7 @@ module Chainweb.Chainweb
7976, runChainweb
8077
8178-- * Throttler
82- , mkGenericThrottler
83- , mkPutPeerThrottler
8479, checkPathPrefix
85- , mkThrottler
86-
87- , ThrottlingConfig (.. )
88- , throttlingRate
89- , throttlingPeerRate
90- , defaultThrottlingConfig
9180
9281-- * Cut Config
9382, CutConfig (.. )
@@ -128,11 +117,9 @@ import Network.Wai
128117import Network.Wai.Handler.Warp hiding (Port )
129118import Network.Wai.Handler.WarpTLS (WarpTLSException (.. ))
130119import Network.Wai.Middleware.RequestSizeLimit
131- import Network.Wai.Middleware.Throttle
132120
133121import Prelude hiding (log )
134122
135- import System.Clock
136123import System.LogLevel
137124
138125-- internal modules
@@ -184,6 +171,7 @@ import P2P.Peer
184171
185172import qualified Pact.Types.ChainMeta as P
186173import qualified Pact.Types.Command as P
174+ import qualified Chainweb.Utils.Throttle as Throttle
187175
188176-- -------------------------------------------------------------------------- --
189177-- Chainweb Resources
@@ -199,9 +187,6 @@ data Chainweb logger tbl = Chainweb
199187 , _chainwebPayloadDb :: ! (PayloadDb tbl )
200188 , _chainwebManager :: ! HTTP. Manager
201189 , _chainwebPactData :: ! [(ChainId , PactServerData logger tbl )]
202- , _chainwebThrottler :: ! (Throttle Address )
203- , _chainwebPutPeerThrottler :: ! (Throttle Address )
204- , _chainwebMempoolThrottler :: ! (Throttle Address )
205190 , _chainwebConfig :: ! ChainwebConfiguration
206191 , _chainwebServiceSocket :: ! (Port , Socket )
207192 , _chainwebBackup :: ! (BackupEnv logger )
@@ -488,13 +473,6 @@ withChainwebInternal conf logger peer serviceSock rocksDb pactDbDir backupDir re
488473 let ! mLogger = setComponent " miner" logger
489474 ! mConf = _configMining conf
490475 ! mCutDb = _cutResCutDb cuts
491- ! throt = _configThrottling conf
492-
493- -- initialize throttler
494- throttler <- mkGenericThrottler $ _throttlingRate throt
495- putPeerThrottler <- mkPutPeerThrottler $ _throttlingPeerRate throt
496- mempoolThrottler <- mkMempoolThrottler $ _throttlingMempoolRate throt
497- logg Debug " initialized throttlers"
498476
499477 -- synchronize pact dbs with latest cut before we start the server
500478 -- and clients and begin mining.
@@ -588,9 +566,6 @@ withChainwebInternal conf logger peer serviceSock rocksDb pactDbDir backupDir re
588566 , _chainwebPayloadDb = view cutDbPayloadDb $ _cutResCutDb cuts
589567 , _chainwebManager = mgr
590568 , _chainwebPactData = pactData
591- , _chainwebThrottler = throttler
592- , _chainwebPutPeerThrottler = putPeerThrottler
593- , _chainwebMempoolThrottler = mempoolThrottler
594569 , _chainwebConfig = conf
595570 , _chainwebServiceSocket = serviceSock
596571 , _chainwebBackup = BackupEnv
@@ -650,41 +625,13 @@ withChainwebInternal conf logger peer serviceSock rocksDb pactDbDir backupDir re
650625-- -------------------------------------------------------------------------- --
651626-- Throttling
652627
653- mkGenericThrottler :: Double -> IO (Throttle Address )
654- mkGenericThrottler rate = mkThrottler 30 rate (const True )
655-
656- mkPutPeerThrottler :: Double -> IO (Throttle Address )
657- mkPutPeerThrottler rate = mkThrottler 30 rate $ \ r ->
658- elem " peer" (pathInfo r) && requestMethod r == " PUT"
659-
660- mkMempoolThrottler :: Double -> IO (Throttle Address )
661- mkMempoolThrottler rate = mkThrottler 30 rate $ \ r ->
662- elem " mempool" (pathInfo r)
663-
664628checkPathPrefix
665629 :: [T. Text ]
666630 -- ^ the base rate granted to users of the endpoing
667631 -> Request
668632 -> Bool
669633checkPathPrefix endpoint r = endpoint `isPrefixOf` drop 3 (pathInfo r)
670634
671- -- | The period is 1 second. Burst is 2*rate.
672- --
673- mkThrottler
674- :: Double
675- -- ^ expiration of a stall bucket in seconds
676- -> Double
677- -- ^ the base rate granted to users of the endpoint (requests per second)
678- -> (Request -> Bool )
679- -- ^ Predicate to select requests that are throttled
680- -> IO (Throttle Address )
681- mkThrottler e rate c = initThrottler (defaultThrottleSettings $ TimeSpec (ceiling e) 0 ) -- expiration
682- { throttleSettingsRate = rate -- number of allowed requests per period
683- , throttleSettingsPeriod = 1_000_000 -- 1 second
684- , throttleSettingsBurst = 4 * ceiling rate
685- , throttleSettingsIsThrottled = c
686- }
687-
688635-- -------------------------------------------------------------------------- --
689636-- Run Chainweb
690637
@@ -720,28 +667,40 @@ runChainweb cw nowServing = do
720667 logg Warn $ " OpenAPI spec validation enabled on service API, make sure this is what you want"
721668 mkValidationMiddleware
722669 else return id
723-
724- concurrentlies_
725-
726- -- 1. Start serving Rest API
727- [ (if tls then serve else servePlain)
728- $ httpLog
729- . throttle (_chainwebPutPeerThrottler cw)
730- . throttle (_chainwebMempoolThrottler cw)
731- . throttle (_chainwebThrottler cw)
732- . p2pRequestSizeLimit
733- . p2pValidationMiddleware
734-
735- -- 2. Start Clients (with a delay of 500ms)
736- , threadDelay 500000 >> clients
737-
738- -- 3. Start serving local API
739- , threadDelay 500000 >> do
740- serveServiceApi
741- $ serviceHttpLog
742- . serviceRequestSizeLimit
743- . serviceApiValidationMiddleware
744- ]
670+ let theP2pThrottleConfig = cw ^. chainwebConfig . configP2p . p2pConfigThrottleConfig
671+ let theServiceApiThrottleConfig = cw ^. chainwebConfig . configServiceApi . serviceApiConfigThrottleConfig
672+ let withP2pThrottleMiddleware =
673+ if _enableConfigEnabled theP2pThrottleConfig
674+ then Throttle. throttleMiddleware (logFunction $ _chainwebLogger cw) " p2p" (_enableConfigConfig theP2pThrottleConfig)
675+ else \ k -> k id
676+ let withServiceApiThrottleMiddleware =
677+ if _enableConfigEnabled theServiceApiThrottleConfig
678+ then Throttle. throttleMiddleware (logFunction $ _chainwebLogger cw) " p2p" (_enableConfigConfig theServiceApiThrottleConfig)
679+ else \ k -> k id
680+
681+ withP2pThrottleMiddleware $ \ p2pThrottler ->
682+ withServiceApiThrottleMiddleware $ \ serviceThrottler ->
683+
684+ concurrentlies_
685+
686+ -- 1. Start serving Rest API
687+ [ (if tls then serve else servePlain)
688+ $ httpLog
689+ . p2pRequestSizeLimit
690+ . p2pThrottler
691+ . p2pValidationMiddleware
692+
693+ -- 2. Start Clients (with a delay of 500ms)
694+ , threadDelay 500000 >> clients
695+
696+ -- 3. Start serving local API
697+ , threadDelay 500000 >> do
698+ serveServiceApi
699+ $ serviceHttpLog
700+ . serviceRequestSizeLimit
701+ . serviceThrottler
702+ . serviceApiValidationMiddleware
703+ ]
745704
746705 where
747706
@@ -805,12 +764,16 @@ runChainweb cw nowServing = do
805764 when (defaultShouldDisplayException e) $
806765 logg Debug $ loggServerError msg r e
807766
767+ onExceptionResponse ex =
768+ fromMaybe (defaultOnExceptionResponse ex) (Throttle. throttledResponse ex)
769+
808770 -- P2P Server
809771
810772 serverSettings :: Counter " clientClosedConnections" -> Settings
811773 serverSettings clientClosedConnectionsCounter =
812774 peerServerSettings (_peerResPeer $ _chainwebPeer cw)
813775 & setOnException (logWarpException " P2P API" clientClosedConnectionsCounter)
776+ & setOnExceptionResponse onExceptionResponse
814777 & setBeforeMainLoop (nowServing (nowServingP2PAPI .~ True ))
815778
816779 monitorConnectionsClosedByClient :: Counter " clientClosedConnections" -> IO ()
@@ -893,6 +856,7 @@ runChainweb cw nowServing = do
893856 & setHost interface
894857 & setOnException
895858 (logWarpException " Service API" clientClosedConnectionsCounter)
859+ & setOnExceptionResponse onExceptionResponse
896860 & setBeforeMainLoop (nowServing (nowServingServiceAPI .~ True ))
897861 & setServerName " Chainweb Service API"
898862
0 commit comments