hbs2/hbs2-git/hbs2-git-oracle/lib/HBS2/Git/Oracle/Run.hs

147 lines
3.8 KiB
Haskell

module HBS2.Git.Oracle.Run where
import HBS2.Git.Oracle.Prelude
import HBS2.Git.Oracle.App
import HBS2.Hash
import HBS2.Merkle
import HBS2.Git.Data.LWWBlock
import HBS2.Git.Data.Tx
import Data.Maybe
import Lens.Micro.Platform
import Data.Word
import Streaming.Prelude qualified as S
import Codec.Serialise
import Control.Monad.Trans.Maybe
import Data.Coerce
import Data.Ord
import Data.Text qualified as Text
import Control.Monad.Trans.Except
import Data.List
import Safe
{- HLINT ignore "Functor law" -}
data GitRepoRefFact =
GitRepoFact1
{ gitLwwRef :: LWWRefKey HBS2Basic
, gitLwwSeq :: Word64
, gitRefLog :: RefLogKey HBS2Basic
}
deriving stock (Generic)
data GitRepoHeadFact =
GitRepoHeadFact1
{ gitRepoName :: Text
, gitRepoBrief :: Text
, gitRepoEncrypted :: Bool
, gitRepoHeadRef :: HashRef
}
deriving stock (Generic)
data GitRepoFacts =
GitRepoRefFact GitRepoRefFact
| GitRepoHeadFact HashRef GitRepoHeadFact
deriving stock (Generic)
instance Serialise GitRepoRefFact
instance Serialise GitRepoHeadFact
instance Serialise GitRepoFacts
instance Pretty GitRepoRefFact where
pretty (GitRepoFact1{..}) =
parens ( "gitrepofact1" <+> hsep [pretty gitLwwRef, pretty gitLwwSeq, pretty gitRefLog])
runOracle :: forall m . MonadUnliftIO m => Oracle m ()
runOracle = do
debug "hbs2-git-oracle"
debug "list all git references from peer"
peer <- asks _peerAPI
reflog <- asks _reflogAPI
sto <- asks _storage
polls <- callRpcWaitMay @RpcPollList2 (TimeoutSec 1) peer (Just "lwwref", Nothing)
<&> join . maybeToList
<&> fmap (LWWRefKey @HBS2Basic . view _1)
repos <- S.toList_ $ forM_ polls $ \r -> void $ runMaybeT do
(lw,blk) <- readLWWBlock sto r >>= toMPlus
let rk = lwwRefLogPubKey blk
lift $ S.yield $
GitRepoFact1 r
(lwwSeq lw)
(RefLogKey rk)
for_ repos $ \what@GitRepoFact1{..} -> do
mhead <- callRpcWaitMay @RpcRefLogGet (TimeoutSec 1) reflog (coerce gitRefLog)
<&> join
forM_ mhead $ \mh -> do
txs <- S.toList_ $ do
walkMerkle @[HashRef] (fromHashRef mh) (getBlock sto) $ \case
Left{} -> do
pure ()
Right hxs -> do
for_ hxs $ \htx -> void $ runMaybeT do
getBlock sto (fromHashRef htx) >>= toMPlus
<&> deserialiseOrFail @(RefLogUpdate L4Proto)
>>= toMPlus
>>= unpackTx
>>= \(n,h,_) -> lift (S.yield (n,htx))
let tx' = maximumByMay (comparing fst) txs
headFact <- forM tx' $ \(n,tx) -> void $ runMaybeT do
(rhh,RepoHeadSimple{..}) <- readRepoHeadFromTx sto tx
>>= toMPlus
let enc = isJust _repoHeadGK0
let name = Text.take 256 $ _repoHeadName
let brief = Text.take 1024 $ _repoHeadBrief
let manifest = _repoManifest
debug $ "found head"
<+> pretty enc
<+> pretty n
<+> pretty gitLwwRef
<+> pretty gitRefLog
<+> pretty tx
<> line
<+> pretty name
<+> pretty brief
<+> pretty manifest
<> line
<> line
let f1 = GitRepoRefFact what
let f2 = GitRepoHeadFact
repoFactHash
(GitRepoHeadFact1 name brief enc undefined
)
pure undefined
pure ()
-- debug $ "found head"
-- <+> pretty gitLwwRef
-- <+> pretty n
-- <+> pretty enc
-- <+> pretty gitRefLog
-- <+> pretty name
-- <+> pretty brief
-- <+> pretty manifest
-- <+> pretty tx