From cf868506fc0f7711bf665b63cb6a7e04482a5586 Mon Sep 17 00:00:00 2001 From: Yuriy Lazaryev Date: Fri, 1 Apr 2022 17:43:46 +0200 Subject: [PATCH 1/6] Light Mode: time interpreter --- .../src/Cardano/Wallet/Shelley/Network.hs | 2 +- .../Wallet/Shelley/Network/Blockfrost.hs | 36 +++++++++++++++++-- .../Cardano/Wallet/Shelley/Network/Node.hs | 3 +- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network.hs index b6bc3bb62dd..b635ae1feeb 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network.hs @@ -66,5 +66,5 @@ withNetworkLayer tr blockchainSrc net netParams tol = in Node.withNetworkLayer tr' net netParams nodeConn ver tol BlockfrostSource project -> let tr' = BlockfrostNetworkLog >$< tr - in Blockfrost.withNetworkLayer tr' net project + in Blockfrost.withNetworkLayer tr' net project netParams diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs index 7f84fc78583..b418b11f957 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs @@ -36,6 +36,9 @@ import Prelude import qualified Blockfrost.Client as BF import qualified Cardano.Api.Shelley as Node import qualified Data.Sequence as Seq +import qualified Ouroboros.Consensus.HardFork.History.EraParams as HF +import qualified Ouroboros.Consensus.HardFork.History.Qry as HF +import qualified Ouroboros.Consensus.HardFork.History.Summary as HF import Cardano.Api ( AnyCardanoEra (..) @@ -59,6 +62,12 @@ import Cardano.Wallet.Logging ( BracketLog, bracketTracer ) import Cardano.Wallet.Network ( NetworkLayer (..) ) +import Cardano.Wallet.Primitive.Slotting + ( PastHorizonException + , TimeInterpreter + , TimeInterpreterLog + , mkTimeInterpreter + ) import Cardano.Wallet.Primitive.Types ( BlockHeader (..) , DecentralizationLevel (..) @@ -66,16 +75,21 @@ import Cardano.Wallet.Primitive.Types , ExecutionUnitPrices (..) , ExecutionUnits (..) , FeePolicy (LinearFee) + , GenesisParameters (GenesisParameters) , LinearFunction (..) , MinimumUTxOValue (..) + , NetworkParameters (NetworkParameters) , ProtocolParameters (..) , SlotNo (..) , SlottingParameters (..) + , StartTime , TokenBundleMaxSize (..) , TxParameters (..) , emptyEraInfo , executionMemory , executionSteps + , genesisParameters + , getGenesisBlockDate ) import Cardano.Wallet.Primitive.Types.Coin ( Coin (Coin, unCoin) ) @@ -137,25 +151,31 @@ newtype BlockfrostException = BlockfrostException BlockfrostError deriving stock (Show) deriving anyclass (Exception) -data Log = MsgWatcherUpdate BlockHeader BracketLog +data Log + = MsgWatcherUpdate BlockHeader BracketLog + | MsgTimeInterpreterLog TimeInterpreterLog instance ToText Log where toText = \case MsgWatcherUpdate blockHeader bracketLog -> "Update watcher with tip: " <> pretty blockHeader <> ". Callback " <> toText bracketLog <> ". " + MsgTimeInterpreterLog til -> + toText til instance HasSeverityAnnotation Log where getSeverityAnnotation = \case MsgWatcherUpdate _ _ -> Info + MsgTimeInterpreterLog _ -> Info withNetworkLayer :: Tracer IO Log -> NetworkId -> BF.Project + -> NetworkParameters -> (NetworkLayer IO (CardanoBlock StandardCrypto) -> IO a) -> IO a -withNetworkLayer tr net project k = k NetworkLayer +withNetworkLayer tr net project np k = k NetworkLayer { chainSync = \_tr _chainFollower -> pure () , lightSync = Nothing , currentNodeTip @@ -167,10 +187,13 @@ withNetworkLayer tr net project k = k NetworkLayer , stakeDistribution = undefined , getCachedRewardAccountBalance = undefined , fetchRewardAccountBalances = undefined - , timeInterpreter = undefined + , timeInterpreter = timeInterpreter getGenesisBlockDate , syncProgress = undefined } where + NetworkParameters + { genesisParameters = GenesisParameters { getGenesisBlockDate } } = np + currentNodeTip :: IO BlockHeader currentNodeTip = runBlockfrost BF.getLatestBlock -- ^ TODO: use cached value while retrying @@ -193,6 +216,13 @@ withNetworkLayer tr net project k = k NetworkLayer epoch <- fromBlockfrostM _epochInfoEpoch liftEither $ eraByEpoch net epoch + timeInterpreter :: + StartTime -> TimeInterpreter (ExceptT PastHorizonException IO) + timeInterpreter startTime = + mkTimeInterpreter (MsgTimeInterpreterLog >$< tr) startTime $ do + let summary = undefined -- TODO + pure $ HF.mkInterpreter summary + handleBlockfrostError :: ExceptT BlockfrostError IO a -> IO a handleBlockfrostError = either (throwIO . BlockfrostException) pure <=< runExceptT diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Node.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Node.hs index 5fd15535445..48bb8a7614e 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Node.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Node.hs @@ -521,8 +521,7 @@ withNodeNetworkLayerBase tr net np conn versionData tol action = do let readInterpreter = liftIO $ atomically $ readTMVar var mkTimeInterpreter tr' getGenesisBlockDate readInterpreter - _syncProgress - :: TMVar IO (CardanoInterpreter sc) + _syncProgress :: TMVar IO (CardanoInterpreter sc) -> SlotNo -> IO SyncProgress _syncProgress var slot = do From 31d97ed6e09cd444d8ba1d5393805e5c0159d9b3 Mon Sep 17 00:00:00 2001 From: Yuriy Lazaryev Date: Mon, 4 Apr 2022 18:16:30 +0200 Subject: [PATCH 2/6] fix typo --- lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs index b418b11f957..fcefa0843e0 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs @@ -36,9 +36,7 @@ import Prelude import qualified Blockfrost.Client as BF import qualified Cardano.Api.Shelley as Node import qualified Data.Sequence as Seq -import qualified Ouroboros.Consensus.HardFork.History.EraParams as HF import qualified Ouroboros.Consensus.HardFork.History.Qry as HF -import qualified Ouroboros.Consensus.HardFork.History.Summary as HF import Cardano.Api ( AnyCardanoEra (..) @@ -423,7 +421,7 @@ instance FromBlockfrost BF.Epoch EpochNo where {- Epoch-to-Era translation is not available in the Blockfrost API. -The following histories are hardcoded in order to work around this limiation: +The following histories are hardcoded in order to work around this limitation: For the Mainnet: For the Testnet: ┌───────┬─────────┐ ┌───────┬─────────┐ From 3bfdacbcb1c5d3846b2c41be39e2accef6204b5e Mon Sep 17 00:00:00 2001 From: Yuriy Lazaryev Date: Wed, 6 Apr 2022 13:19:16 +0200 Subject: [PATCH 3/6] Light mode: hardcode mainnet summary for time interpreter --- .../Wallet/Shelley/Network/Blockfrost.hs | 120 +++++++++++++++++- 1 file changed, 116 insertions(+), 4 deletions(-) diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs index fcefa0843e0..a75df241161 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs @@ -122,8 +122,24 @@ import Data.Traversable ( for ) import Fmt ( pretty ) +import Ouroboros.Consensus.Block.Abstract + ( EpochSize (EpochSize) ) +import Ouroboros.Consensus.BlockchainTime.WallClock.Types + ( RelativeTime (..), mkSlotLength ) import Ouroboros.Consensus.Cardano.Block - ( CardanoBlock, StandardCrypto ) + ( CardanoBlock, CardanoEras, StandardCrypto ) +import Ouroboros.Consensus.HardFork.History.EraParams + ( EraParams (EraParams, eraEpochSize, eraSafeZone, eraSlotLength) + , SafeZone (..) + ) +import Ouroboros.Consensus.HardFork.History.Summary + ( Bound (Bound, boundEpoch, boundSlot, boundTime) + , EraEnd (EraEnd, EraUnbounded) + , EraSummary (EraSummary, eraEnd, eraParams, eraStart) + , Summary (..) + ) +import Ouroboros.Consensus.Util.Counting + ( NonEmpty (NonEmptyCons, NonEmptyOne) ) import UnliftIO ( throwIO ) import UnliftIO.Async @@ -217,9 +233,8 @@ withNetworkLayer tr net project np k = k NetworkLayer timeInterpreter :: StartTime -> TimeInterpreter (ExceptT PastHorizonException IO) timeInterpreter startTime = - mkTimeInterpreter (MsgTimeInterpreterLog >$< tr) startTime $ do - let summary = undefined -- TODO - pure $ HF.mkInterpreter summary + mkTimeInterpreter (MsgTimeInterpreterLog >$< tr) startTime $ + pure $ HF.mkInterpreter $ networkSummary net handleBlockfrostError :: ExceptT BlockfrostError IO a -> IO a handleBlockfrostError = @@ -419,6 +434,103 @@ instance FromBlockfrost BF.Epoch EpochNo where fromBlockfrost = pure . fromIntegral +networkSummary :: NetworkId -> Summary (CardanoEras StandardCrypto) +networkSummary = \case + Mainnet -> + Summary + { getSummary = + -- Byron + NonEmptyCons EraSummary + { eraStart = Bound + { boundTime = RelativeTime 0 + , boundSlot = 0 + , boundEpoch = 0 + } + , eraEnd = EraEnd Bound + { boundTime = RelativeTime 89856000 + , boundSlot = 4492800 + , boundEpoch = Node.EpochNo 208 + } + , eraParams = EraParams + { eraEpochSize = EpochSize 21600 + , eraSlotLength = mkSlotLength 20 + , eraSafeZone = StandardSafeZone 4320 + } + } + -- Shelley + $ NonEmptyCons EraSummary + { eraStart = Bound + { boundTime = RelativeTime 89856000 + , boundSlot = 4492800 + , boundEpoch = Node.EpochNo 208 + } + , eraEnd = EraEnd Bound + { boundTime = RelativeTime 101952000 + , boundSlot = 16588800 + , boundEpoch = Node.EpochNo 236 + } + , eraParams = EraParams + { eraEpochSize = EpochSize 432000 + , eraSlotLength = mkSlotLength 1 + , eraSafeZone = StandardSafeZone 129600 + } + } + -- Allegra + $ NonEmptyCons EraSummary + { eraStart = Bound + { boundTime = RelativeTime 101952000 + , boundSlot = 16588800 + , boundEpoch = Node.EpochNo 236 + } + , eraEnd = EraEnd Bound + { boundTime = RelativeTime 108432000 + , boundSlot = 23068800 + , boundEpoch = Node.EpochNo 251 + } + , eraParams = EraParams + { eraEpochSize = EpochSize 432000 + , eraSlotLength = mkSlotLength 1 + , eraSafeZone = StandardSafeZone 129600 + } + } + -- Mary + $ NonEmptyCons EraSummary + { eraStart = Bound + { boundTime = RelativeTime 108432000 + , boundSlot = 23068800 + , boundEpoch = Node.EpochNo 251 + } + , eraEnd = EraEnd Bound + { boundTime = RelativeTime 125280000 + , boundSlot = 39916800 + , boundEpoch = Node.EpochNo 290 + } + , eraParams = EraParams + { eraEpochSize = EpochSize 432000 + , eraSlotLength = mkSlotLength 1 + , eraSafeZone = StandardSafeZone 129600 + } + } + -- Alonzo + $ NonEmptyOne EraSummary + { eraStart = Bound + { boundTime = RelativeTime 125280000 + , boundSlot = 39916800 + , boundEpoch = Node.EpochNo 290 + } + , eraEnd = EraUnbounded + , eraParams = EraParams + { eraEpochSize = EpochSize 432000 + , eraSlotLength = mkSlotLength 1 + , eraSafeZone = StandardSafeZone 129600 + } + } + } + Testnet _ -> error + "In light-mode time interpreter is only available for the \ + \mainnet (interpreter uses a hard-coded history of hard forks). \ + \It doesn't seem viable to hardcode it for other networks yet." + {- Epoch-to-Era translation is not available in the Blockfrost API. The following histories are hardcoded in order to work around this limitation: From f58659cd3dfff7d1493abeaac7470c608d4edcd8 Mon Sep 17 00:00:00 2001 From: Yuriy Lazaryev Date: Wed, 6 Apr 2022 15:59:07 +0200 Subject: [PATCH 4/6] refactor: change parameters order --- lib/shelley/src/Cardano/Wallet/Shelley/Network.hs | 2 +- lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network.hs index b635ae1feeb..ffad1a2a08e 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network.hs @@ -66,5 +66,5 @@ withNetworkLayer tr blockchainSrc net netParams tol = in Node.withNetworkLayer tr' net netParams nodeConn ver tol BlockfrostSource project -> let tr' = BlockfrostNetworkLog >$< tr - in Blockfrost.withNetworkLayer tr' net project netParams + in Blockfrost.withNetworkLayer tr' net netParams project diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs index a75df241161..b063d72179c 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs @@ -185,11 +185,11 @@ instance HasSeverityAnnotation Log where withNetworkLayer :: Tracer IO Log -> NetworkId - -> BF.Project -> NetworkParameters + -> BF.Project -> (NetworkLayer IO (CardanoBlock StandardCrypto) -> IO a) -> IO a -withNetworkLayer tr net project np k = k NetworkLayer +withNetworkLayer tr net np project k = k NetworkLayer { chainSync = \_tr _chainFollower -> pure () , lightSync = Nothing , currentNodeTip From 0f36ffe10373174ecc656a41a866123063ff5ffb Mon Sep 17 00:00:00 2001 From: Yuriy Lazaryev Date: Thu, 7 Apr 2022 11:35:37 +0200 Subject: [PATCH 5/6] refactor: rename timeInterpreter --- .../src/Cardano/Wallet/Shelley/Network/Blockfrost.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs index b063d72179c..df51214c24d 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs @@ -201,7 +201,7 @@ withNetworkLayer tr net np project k = k NetworkLayer , stakeDistribution = undefined , getCachedRewardAccountBalance = undefined , fetchRewardAccountBalances = undefined - , timeInterpreter = timeInterpreter getGenesisBlockDate + , timeInterpreter = timeInterpreterFromStartTime getGenesisBlockDate , syncProgress = undefined } where @@ -230,9 +230,9 @@ withNetworkLayer tr net np project k = k NetworkLayer epoch <- fromBlockfrostM _epochInfoEpoch liftEither $ eraByEpoch net epoch - timeInterpreter :: + timeInterpreterFromStartTime :: StartTime -> TimeInterpreter (ExceptT PastHorizonException IO) - timeInterpreter startTime = + timeInterpreterFromStartTime startTime = mkTimeInterpreter (MsgTimeInterpreterLog >$< tr) startTime $ pure $ HF.mkInterpreter $ networkSummary net From 3525610564253e6aa2a972763b7c564013357ca5 Mon Sep 17 00:00:00 2001 From: Yuriy Lazaryev Date: Fri, 8 Apr 2022 09:27:24 +0200 Subject: [PATCH 6/6] Light Mode: hardcode time interpreter summary for the testnet --- .../Wallet/Shelley/Network/Blockfrost.hs | 92 ++++++++++++++++++- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs index df51214c24d..84bc3c1e45f 100644 --- a/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs +++ b/lib/shelley/src/Cardano/Wallet/Shelley/Network/Blockfrost.hs @@ -526,10 +526,94 @@ networkSummary = \case } } } - Testnet _ -> error - "In light-mode time interpreter is only available for the \ - \mainnet (interpreter uses a hard-coded history of hard forks). \ - \It doesn't seem viable to hardcode it for other networks yet." + Testnet (NetworkMagic 1097911063) -> -- Magic of the current public testnet + Summary + { getSummary + = NonEmptyCons EraSummary + { eraStart = Bound + { boundTime = RelativeTime 0 + , boundSlot = SlotNo 0 + , boundEpoch = Node.EpochNo 0 + } + , eraEnd = EraEnd Bound + { boundTime = RelativeTime 31968000 + , boundSlot = SlotNo 1598400 + , boundEpoch = Node.EpochNo 74 + } + , eraParams = EraParams + { eraEpochSize = EpochSize 21600 + , eraSlotLength = mkSlotLength 20 + , eraSafeZone = StandardSafeZone 4320 + } + } + $ NonEmptyCons EraSummary + { eraStart = Bound + { boundTime = RelativeTime 31968000 + , boundSlot = SlotNo 1598400 + , boundEpoch = Node.EpochNo 74 + } + , eraEnd = EraEnd Bound + { boundTime = RelativeTime 44064000 + , boundSlot = SlotNo 13694400 + , boundEpoch = Node.EpochNo 102 + } + , eraParams = EraParams + { eraEpochSize = EpochSize 432000 + , eraSlotLength = mkSlotLength 1 + , eraSafeZone = StandardSafeZone 129600 + } + } + $ NonEmptyCons EraSummary + { eraStart = Bound + { boundTime = RelativeTime 44064000 + , boundSlot = SlotNo 13694400 + , boundEpoch = Node.EpochNo 102 + } + , eraEnd = EraEnd Bound + { boundTime = RelativeTime 48384000 + , boundSlot = SlotNo 18014400 + , boundEpoch = Node.EpochNo 112 + } + , eraParams = EraParams + { eraEpochSize = EpochSize 432000 + , eraSlotLength = mkSlotLength 1 + , eraSafeZone = StandardSafeZone 129600 + } + } + $ NonEmptyCons EraSummary + { eraStart = Bound + { boundTime = RelativeTime 48384000 + , boundSlot = SlotNo 18014400 + , boundEpoch = Node.EpochNo 112 + } + , eraEnd = EraEnd Bound + { boundTime = RelativeTime 66528000 + , boundSlot = SlotNo 36158400 + , boundEpoch = Node.EpochNo 154 + } + , eraParams = EraParams + { eraEpochSize = EpochSize 432000 + , eraSlotLength = mkSlotLength 1 + , eraSafeZone = StandardSafeZone 129600 + } + } + $ NonEmptyOne EraSummary + { eraStart = Bound + { boundTime = RelativeTime 66528000 + , boundSlot = SlotNo 36158400 + , boundEpoch = Node.EpochNo 154 + } + , eraEnd = EraUnbounded + , eraParams = EraParams + { eraEpochSize = EpochSize 432000 + , eraSlotLength = mkSlotLength 1 + , eraSafeZone = StandardSafeZone 129600 + } + } + } + Testnet magic -> + error $ "Epoch/Era conversion isn't provided for the Testnet " + <> show magic {- Epoch-to-Era translation is not available in the Blockfrost API.