@@ -26,6 +26,8 @@ import Cardano.BM.Data.Tracer
2626 ( HasPrivacyAnnotation (.. ), HasSeverityAnnotation (.. ) )
2727import Cardano.Wallet.Api.Types
2828 ( ApiNetworkClock (.. ), ApiNtpStatus (.. ), NtpSyncingStatus (.. ) )
29+ import Control.Concurrent.STM
30+ ( atomically , check )
2931import Control.Tracer
3032 ( Tracer )
3133import Data.Quantity
@@ -61,7 +63,7 @@ ntpSettings = NtpSettings
6163 { ntpServers = [ " 0.de.pool.ntp.org" , " 0.europe.pool.ntp.org"
6264 , " 0.pool.ntp.org" , " 1.pool.ntp.org"
6365 , " 2.pool.ntp.org" , " 3.pool.ntp.org" ]
64- , ntpRequiredNumberOfResults = 2
66+ , ntpRequiredNumberOfResults = 3
6567 , ntpResponseTimeout = 1_000_000
6668 , ntpPollDelay = 300_000_000
6769 }
@@ -121,8 +123,24 @@ instance HasSeverityAnnotation NtpTrace where
121123 NtpTracePacketReceived _ _ -> Debug
122124 NtpTraceWaitingForRepliesTimeout _ -> Notice
123125
124- getNtpStatus :: NtpClient -> IO ApiNetworkClock
125- getNtpStatus = fmap (ApiNetworkClock . toStatus) . ntpQueryBlocking
126+ getNtpStatus
127+ :: NtpClient
128+ -> Bool
129+ -- ^ When 'True', will block and force a NTP check instead of using cached results
130+ -> IO ApiNetworkClock
131+ getNtpStatus client forceCheck = (ApiNetworkClock . toStatus) <$>
132+ if forceCheck
133+ -- Forces an NTP check / query on the central servers, use with care
134+ then do
135+ ntpQueryBlocking client
136+
137+ else atomically $ do
138+ -- Reads a cached NTP status from an STM.TVar so we don't get
139+ -- blacklisted by the central NTP "authorities" for sending too many NTP
140+ -- requests.
141+ s <- ntpGetStatus client
142+ check (s /= NtpSyncPending )
143+ pure s
126144 where
127145 toStatus = \ case
128146 NtpSyncPending ->
0 commit comments