Skip to content

Commit

Permalink
Use ipfs gateways
Browse files Browse the repository at this point in the history
Fixes #1792
  • Loading branch information
kderme committed Sep 17, 2024
1 parent 182cdb4 commit 78e1109
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 14 deletions.
5 changes: 1 addition & 4 deletions cardano-db-sync/app/http-get-json-metadata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,7 @@ runHttpGetVote voteUrl mHash vtype =
reportSuccess =<< runOrThrowIO (runExceptT httpGet)
where
httpGet :: ExceptT OffChainFetchError IO SimplifiedOffChainVoteData
httpGet = do
request <- parseOffChainUrl $ OffChainVoteUrl voteUrl
manager <- liftIO $ Http.newManager tlsManagerSettings
httpGetOffChainVoteData manager request voteUrl mHash vtype
httpGet = httpGetOffChainVoteData [] voteUrl mHash vtype

reportSuccess :: SimplifiedOffChainVoteData -> IO ()
reportSuccess spod = do
Expand Down
1 change: 1 addition & 0 deletions cardano-db-sync/app/test-http-get-json-metadata.hs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ classifyFetchError tf fe =
OCFErrIOException {} -> tf {tfIOException = tfIOException tf + 1}
OCFErrTimeout {} -> tf {tfTimeout = tfTimeout tf + 1}
OCFErrConnectionFailure {} -> tf {tfConnectionFailure = tfConnectionFailure tf + 1}
_ -> tf

emptyTestFailure :: TestFailure
emptyTestFailure = TestFailure 0 0 0 0 0 0 0 0 0 0 0
Expand Down
5 changes: 5 additions & 0 deletions cardano-db-sync/src/Cardano/DbSync/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import Cardano.DbSync.Config.Node (NodeConfig (..), parseNodeConfig, parseSyncPr
import Cardano.DbSync.Config.Shelley
import Cardano.DbSync.Config.Types
import Cardano.Prelude
import qualified Data.Text as Text
import System.FilePath (takeDirectory, (</>))

configureLogging :: SyncNodeConfig -> Text -> IO (Trace IO Text)
Expand Down Expand Up @@ -91,7 +92,11 @@ coalesceConfig pcfg ncfg adjustGenesisPath = do
, dncBabbageHardFork = ncBabbageHardFork ncfg
, dncConwayHardFork = ncConwayHardFork ncfg
, dncInsertOptions = extractInsertOptions pcfg
, dncIpfsGateway = endsInSlash <$> pcIpfsGateway pcfg
}

mkAdjustPath :: SyncPreConfig -> (FilePath -> FilePath)
mkAdjustPath cfg fp = takeDirectory (pcNodeConfigFilePath cfg) </> fp

endsInSlash :: Text -> Text
endsInSlash txt = if Text.isSuffixOf "/" txt then txt else txt <> "/"
3 changes: 3 additions & 0 deletions cardano-db-sync/src/Cardano/DbSync/Config/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ data SyncNodeConfig = SyncNodeConfig
, dncBabbageHardFork :: !TriggerHardFork
, dncConwayHardFork :: !TriggerHardFork
, dncInsertOptions :: !SyncInsertOptions
, dncIpfsGateway :: [Text]
}

data SyncPreConfig = SyncPreConfig
Expand All @@ -153,6 +154,7 @@ data SyncPreConfig = SyncPreConfig
, pcEnableMetrics :: !Bool
, pcPrometheusPort :: !Int
, pcInsertConfig :: !SyncInsertConfig
, pcIpfsGateway :: ![Text]
}
deriving (Show)

Expand Down Expand Up @@ -390,6 +392,7 @@ parseGenSyncNodeConfig o =
<*> o .: "EnableLogMetrics"
<*> fmap (fromMaybe 8080) (o .:? "PrometheusPort")
<*> o .:? "insert_options" .!= def
<*> o .:? "ipfs_gateway" .!= ["ipfs.io"]

instance FromJSON SyncProtocol where
parseJSON o =
Expand Down
12 changes: 6 additions & 6 deletions cardano-db-sync/src/Cardano/DbSync/OffChain.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Cardano.Db (runIohkLogging)
import qualified Cardano.Db as DB
import Cardano.DbSync.Api
import Cardano.DbSync.Api.Types (InsertOptions (..), SyncEnv (..))
import Cardano.DbSync.Config.Types
import Cardano.DbSync.OffChain.Http
import Cardano.DbSync.OffChain.Query
import qualified Cardano.DbSync.OffChain.Vote.Types as Vote
Expand Down Expand Up @@ -212,12 +213,12 @@ runFetchOffChainVoteThread syncEnv = do
-- load the offChain vote work queue using the db
_ <- runReaderT (loadOffChainVoteWorkQueue trce (envOffChainVoteWorkQueue syncEnv)) backendVote
voteq <- atomically $ flushTBQueue (envOffChainVoteWorkQueue syncEnv)
manager <- Http.newManager tlsManagerSettings
now <- liftIO Time.getPOSIXTime
mapM_ (queueVoteInsert <=< fetchOffChainVoteData trce manager now) voteq
mapM_ (queueVoteInsert <=< fetchOffChainVoteData gateways now) voteq
where
trce = getTrace syncEnv
iopts = getInsertOptions syncEnv
gateways = dncIpfsGateway $ envSyncNodeConfig syncEnv

queueVoteInsert :: OffChainVoteResult -> IO ()
queueVoteInsert = atomically . writeTBQueue (envOffChainVoteResultQueue syncEnv)
Expand Down Expand Up @@ -260,13 +261,12 @@ fetchOffChainPoolData _tracer manager time oPoolWorkQ =
, DB.offChainPoolFetchErrorRetryCount = retryCount (oPoolWqRetry oPoolWorkQ)
}

fetchOffChainVoteData :: Trace IO Text -> Http.Manager -> Time.POSIXTime -> OffChainVoteWorkQueue -> IO OffChainVoteResult
fetchOffChainVoteData _tracer manager time oVoteWorkQ =
fetchOffChainVoteData :: [Text] -> Time.POSIXTime -> OffChainVoteWorkQueue -> IO OffChainVoteResult
fetchOffChainVoteData gateways time oVoteWorkQ =
convert <<$>> runExceptT $ do
let url = oVoteWqUrl oVoteWorkQ
metaHash = oVoteWqMetaHash oVoteWorkQ
request <- parseOffChainUrl $ OffChainVoteUrl url
httpGetOffChainVoteData manager request url (Just metaHash) (oVoteWqType oVoteWorkQ)
httpGetOffChainVoteData gateways url (Just metaHash) (oVoteWqType oVoteWorkQ)
where
convert :: Either OffChainFetchError SimplifiedOffChainVoteData -> OffChainVoteResult
convert eres =
Expand Down
34 changes: 30 additions & 4 deletions cardano-db-sync/src/Cardano/DbSync/OffChain/Http.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import qualified Data.Text.Encoding as Text
import GHC.Show (show)
import Network.HTTP.Client (HttpException (..))
import qualified Network.HTTP.Client as Http
import Network.HTTP.Client.TLS (tlsManagerSettings)
import qualified Network.HTTP.Types as Http

-------------------------------------------------------------------------------------
Expand Down Expand Up @@ -78,13 +79,33 @@ httpGetOffChainPoolData manager request purl expectedMetaHash = do
url = OffChainPoolUrl purl

httpGetOffChainVoteData ::
Http.Manager ->
Http.Request ->
[Text] ->
VoteUrl ->
Maybe VoteMetaHash ->
DB.AnchorType ->
ExceptT OffChainFetchError IO SimplifiedOffChainVoteData
httpGetOffChainVoteData manager request vurl metaHash anchorType = do
httpGetOffChainVoteData gateways vurl metaHash anchorType = do
case useIpfsGatewayMaybe vurl gateways of
Nothing -> httpGetOffChainVoteDataSingle vurl metaHash anchorType
Just [] -> left $ OCFErrNoIpfsGateway (OffChainVoteUrl vurl)
Just urls -> tryAllGatewaysRec urls []
where
tryAllGatewaysRec [] acc = left $ OCFErrIpfsGatewayFailures (OffChainVoteUrl vurl) (reverse acc)
tryAllGatewaysRec (url : rest) acc = do
msocd <- liftIO $ runExceptT $ httpGetOffChainVoteDataSingle url metaHash anchorType
case msocd of
Right socd -> pure socd
Left err -> tryAllGatewaysRec rest (err : acc)

httpGetOffChainVoteDataSingle ::
VoteUrl ->
Maybe VoteMetaHash ->
DB.AnchorType ->
ExceptT OffChainFetchError IO SimplifiedOffChainVoteData
httpGetOffChainVoteDataSingle vurl metaHash anchorType = do
manager <- liftIO $ Http.newManager tlsManagerSettings
request <- parseOffChainUrl url
let req = httpGetBytes manager request 10000 30000 url
httpRes <- handleExceptT (convertHttpException url) req
(respBS, respLBS, mContentType) <- hoistEither httpRes
(ocvd, decodedValue, metadataHash, mWarning) <- parseAndValidateVoteData respBS respLBS metaHash anchorType (Just $ OffChainVoteUrl vurl)
Expand All @@ -98,7 +119,6 @@ httpGetOffChainVoteData manager request vurl metaHash anchorType = do
, sovaWarning = mWarning
}
where
req = httpGetBytes manager request 10000 30000 url
url = OffChainVoteUrl vurl

parseAndValidateVoteData :: ByteString -> LBS.ByteString -> Maybe VoteMetaHash -> DB.AnchorType -> Maybe OffChainUrlType -> ExceptT OffChainFetchError IO (Vote.OffChainVoteData, Aeson.Value, ByteString, Maybe Text)
Expand Down Expand Up @@ -217,3 +237,9 @@ convertHttpException url he =
case url of
OffChainPoolUrl _ -> OCFErrUrlParseFail (OffChainPoolUrl $ PoolUrl $ Text.pack urlx) (Text.pack err)
OffChainVoteUrl _ -> OCFErrUrlParseFail (OffChainVoteUrl $ VoteUrl $ Text.pack urlx) (Text.pack err)

useIpfsGatewayMaybe :: VoteUrl -> [Text] -> Maybe [VoteUrl]
useIpfsGatewayMaybe vu gateways =
case Text.stripPrefix "ipfs://" (unVoteUrl vu) of
Just sf -> Just $ VoteUrl . (<> sf) <$> gateways
Nothing -> Nothing
6 changes: 6 additions & 0 deletions cardano-db-sync/src/Cardano/DbSync/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ data OffChainFetchError
| OCFErrIOException !Text
| OCFErrTimeout !OffChainUrlType !Text
| OCFErrConnectionFailure !OffChainUrlType
| OCFErrNoIpfsGateway !OffChainUrlType
| OCFErrIpfsGatewayFailures !OffChainUrlType [OffChainFetchError]
deriving (Eq, Generic)

instance Exception OffChainFetchError
Expand Down Expand Up @@ -271,6 +273,10 @@ instance Show OffChainFetchError where
mconcat
[fetchUrlToString url, "Connection failure error when fetching metadata from ", show url, "."]
OCFErrIOException err -> "IO Exception: " <> show err
OCFErrNoIpfsGateway url ->
mconcat [fetchUrlToString url, "No ipfs_gateway provided in the db-sync config"]
OCFErrIpfsGatewayFailures url errs ->
mconcat $ [fetchUrlToString url, "List of errors for the each ipfs gateway: "] <> fmap show errs

showMUrl :: Maybe OffChainUrlType -> String
showMUrl = \case
Expand Down
2 changes: 2 additions & 0 deletions cardano-db-sync/test/Cardano/DbSync/Gen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ syncPreConfig =
<*> Gen.bool
<*> Gen.int (Range.linear 0 10000)
<*> syncInsertConfig
<*> pure []

syncNodeParams :: MonadGen m => m SyncNodeParams
syncNodeParams =
Expand Down Expand Up @@ -103,6 +104,7 @@ syncNodeConfig loggingCfg =
<*> triggerHardFork
<*> triggerHardFork
<*> syncInsertOptions
<*> pure []

syncInsertConfig :: Gen SyncInsertConfig
syncInsertConfig =
Expand Down

0 comments on commit 78e1109

Please sign in to comment.