diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,12 @@
 `arch-hs` uses [PVP Versioning][1].
 The changelog is available [on GitHub][2].
 
+## 0.3.0.0
+
+* Update name preset
+
+* Add check in submit
+
 ## 0.2.0.0
 
 * More accurate naming conversion between hackage representation and archlinux representation, according to [NAME_PRESET.json](https://github.com/berberman/arch-hs/blob/master/data/NAME_PRESET.json)
diff --git a/arch-hs.cabal b/arch-hs.cabal
--- a/arch-hs.cabal
+++ b/arch-hs.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.4
 name:                arch-hs
-version:             0.2.0.0
+version:             0.3.0.0
 synopsis:            Distribute hackage packages to archlinux
 description:         
     @arch-hs@ is a command-line program, which simplifies the process of producing
diff --git a/data/NAME_PRESET.json b/data/NAME_PRESET.json
--- a/data/NAME_PRESET.json
+++ b/data/NAME_PRESET.json
@@ -1,7 +1,10 @@
 {
   "falseList": [
     "haskell-network2.8",
-    "haskell-sbv8.7"
+    "haskell-sbv8.7",
+    "haskell-ghc-heap",
+    "haskell-libiserv",
+    "haskell-tamarin-prover-sapic"
   ],
   "preset": {
     "agda": "Agda",
@@ -28,11 +31,14 @@
     "haskell-dav": "DAV",
     "haskell-decimal": "Decimal",
     "haskell-diff": "Diff",
+    "haskell-drbg": "DRBG",
     "haskell-edisonapi": "EdisonAPI",
     "haskell-edisoncore": "EdisonCore",
     "haskell-findbin": "FindBin",
     "haskell-floatinghex": "FloatingHex",
     "haskell-gi": "haskell-gi",
+    "haskell-gi-base": "haskell-gi-base",
+    "haskell-gi-overloading": "haskell-gi-overloading",
     "haskell-glob": "Glob",
     "haskell-gtk": "gtk3",
     "haskell-graphscc": "GraphSCC",
@@ -47,6 +53,15 @@
     "haskell-monadlib": "monadLib",
     "haskell-monadrandom": "MonadRandom",
     "haskell-only": "Only",
+    "haskell-hsopenssl": "HsOpenSSL",
+    "haskell-hsyaml": "HsYAML",
+    "haskell-hsyaml-aeson": "HsYAML-aeson",
+    "haskell-libbf": "libBF",
+    "haskell-lsp": "haskell-lsp",
+    "haskell-lsp-types": "haskell-lsp-types",
+    "haskell-memotrie": "MemoTrie",
+    "haskell-monadprompt": "MonadPrompt",
+    "haskell-rsa": "RSA",
     "haskell-puremd5": "pureMD5",
     "haskell-quickcheck": "QuickCheck",
     "haskell-ranged-sets": "Ranged-sets",
diff --git a/src/Distribution/ArchHs/Core.hs b/src/Distribution/ArchHs/Core.hs
--- a/src/Distribution/ArchHs/Core.hs
+++ b/src/Distribution/ArchHs/Core.hs
@@ -238,7 +238,7 @@
 cabalToPkgBuild pkg ignored uusi = do
   let name = pkg ^. pkgName
   cabal <- packageDescription <$> (getLatestCabal name)
-  _sha256sums <- (\s -> "'" <> s <> "'") <$> getLatestSHA256 name
+  _sha256sums <- (\case Just s -> "'" <> s <> "'"; Nothing -> "'SKIP'") <$> getLatestSHA256 name
   let _hkgName = pkg ^. pkgName & unPackageName
       rawName = toLower <$> _hkgName
       _pkgName = maybe rawName id $ stripPrefix "haskell-" rawName
diff --git a/src/Distribution/ArchHs/Hackage.hs b/src/Distribution/ArchHs/Hackage.hs
--- a/src/Distribution/ArchHs/Hackage.hs
+++ b/src/Distribution/ArchHs/Hackage.hs
@@ -16,6 +16,7 @@
     getPackageFlag,
     traverseHackage,
     getLatestSHA256,
+    HackageDB,
   )
 where
 
@@ -90,8 +91,8 @@
 getLatestCabal = withLatestVersion cabalFile
 
 -- | Get the latest SHA256 sum of the tarball .
-getLatestSHA256 :: Members [HackageEnv, WithMyErr] r => PackageName -> Sem r String
-getLatestSHA256 = withLatestVersion (\vdata -> tarballHashes vdata Map.! "sha256")
+getLatestSHA256 :: Members [HackageEnv, WithMyErr] r => PackageName -> Sem r (Maybe String)
+getLatestSHA256 = withLatestVersion (\vdata -> tarballHashes vdata Map.!? "sha256")
 
 -- | Get 'GenericPackageDescription' with a specific version.
 getCabal :: Members [HackageEnv, WithMyErr] r => PackageName -> Version -> Sem r GenericPackageDescription
diff --git a/submit/Main.hs b/submit/Main.hs
--- a/submit/Main.hs
+++ b/submit/Main.hs
@@ -7,6 +7,7 @@
 import qualified Data.Text as T
 import Distribution.ArchHs.Community
 import Distribution.ArchHs.Exception
+import Distribution.ArchHs.Hackage
 import Distribution.ArchHs.Internal.Prelude
 import Distribution.ArchHs.Types
 import Submit
@@ -17,12 +18,12 @@
 main = printHandledIOException $
   do
     Options {..} <- runArgsParser
-    let useDefaultCommunity = "/var/lib/pacman/sync/community.db" == optCommunityPath
 
-    when useDefaultCommunity $ C.skipMessage "You didn't pass -c, use community db file from default path."
+    let useDefaultHackage = isInfixOf "YOUR_HACKAGE_MIRROR" $ optHackagePath
+        useDefaultCommunity = "/var/lib/pacman/sync/community.db" == optCommunityPath
 
-    community <- loadProcessedCommunity $ if useDefaultCommunity then defaultCommunityPath else optCommunityPath
-    C.infoMessage "Loading community.db..."
+    when useDefaultHackage $ C.skipMessage "You didn't pass -h, use hackage index file from default path."
+    when useDefaultCommunity $ C.skipMessage "You didn't pass -c, use community db file from default path."
 
     token <- lookupEnv "HACKAGE_API_TOKEN"
 
@@ -36,8 +37,15 @@
         C.warningMessage $ "File " <> (T.pack optOutput) <> " already existed, overwrite it."
     C.infoMessage "Start running..."
     when (not $ optUpload || hasOutput) $
-      C.warningMessage "Run diff only."
-    runSubmit community (submit token optOutput optUpload) & printAppResult
+      C.warningMessage "Run diff and check only."
 
-runSubmit :: CommunityDB -> Sem '[CommunityEnv, WithMyErr, Embed IO, Final IO] a -> IO (Either MyException a)
-runSubmit community = runFinal . embedToFinal . errorToIOFinal . (runReader community)
+    community <- loadProcessedCommunity $ if useDefaultCommunity then defaultCommunityPath else optCommunityPath
+    C.infoMessage "Loading community.db..."
+
+    hackage <- loadHackageDB =<< if useDefaultHackage then lookupHackagePath else return optHackagePath
+    C.infoMessage "Loading hackage..."
+
+    runSubmit community hackage (submit token optOutput optUpload) & printAppResult
+
+runSubmit :: CommunityDB -> HackageDB -> Sem '[CommunityEnv, HackageEnv, WithMyErr, Embed IO, Final IO] a -> IO (Either MyException a)
+runSubmit community hackage = runFinal . embedToFinal . errorToIOFinal . (runReader hackage) . (runReader community)
diff --git a/submit/Submit.hs b/submit/Submit.hs
--- a/submit/Submit.hs
+++ b/submit/Submit.hs
@@ -11,10 +11,11 @@
 import qualified Colourista as C
 import qualified Data.ByteString.Char8 as BS
 import qualified Data.Map.Strict as Map
-import Data.Maybe (fromJust)
+import Data.Maybe (catMaybes, fromJust)
 import qualified Data.Text as T
 import Data.Void (Void)
 import Distribution.ArchHs.Exception
+import Distribution.ArchHs.Hackage
 import Distribution.ArchHs.Internal.Prelude
 import Distribution.ArchHs.Local
 import Distribution.ArchHs.Name
@@ -26,7 +27,8 @@
 import Text.Megaparsec.Char as M
 
 data Options = Options
-  { optCommunityPath :: FilePath,
+  { optHackagePath :: FilePath,
+    optCommunityPath :: FilePath,
     optOutput :: FilePath,
     optUpload :: Bool
   }
@@ -35,6 +37,14 @@
 cmdOptions =
   Options
     <$> strOption
+      ( long "hackage"
+          <> metavar "PATH"
+          <> short 'h'
+          <> help "Path to hackage index tarball"
+          <> showDefault
+          <> value "~/.cabal/packages/YOUR_HACKAGE_MIRROR/01-index.tar | 00-index.tar"
+      )
+    <*> strOption
       ( long "community"
           <> metavar "PATH"
           <> short 'c'
@@ -111,7 +121,7 @@
          in (unPackageName hackageName, version, prefix <> communityName')
   return $ processField <$> fields
 
-submit :: Members [CommunityEnv, WithMyErr, Embed IO] r => Maybe String -> FilePath -> Bool -> Sem r ()
+submit :: Members [HackageEnv, CommunityEnv, WithMyErr, Embed IO] r => Maybe String -> FilePath -> Bool -> Sem r ()
 submit token output upload = do
   csv <- genCSV
   let v = renderDistroCSV csv
@@ -133,8 +143,21 @@
       C.infoMessage "ResponseBody:"
       putStrLn . BS.unpack $ responseBody result
 
-check :: Members [WithMyErr, Embed IO] r => DistroCSV -> Sem r ()
+check :: Members [HackageEnv, WithMyErr, Embed IO] r => DistroCSV -> Sem r ()
 check community = do
+  embed $ C.infoMessage "Checking generated CSV file..."
+
+  let hackageNames = fmap (\(a, _, _) -> a) community
+      pipe = fmap (\case Left (PkgNotFound x) -> Just (unCommunityName $ toCommunityName x); _ -> Nothing)
+
+  failed <- catMaybes . pipe <$> mapM (\x -> try @MyException (getLatestCabal $ mkPackageName x)) hackageNames
+
+  embed $
+    when (not $ null failed) $
+      C.warningMessage "Following packages in community are not linked to hackage:"
+
+  embed . putStrLn . unlines $ failed
+
   let api = https "hackage.haskell.org" /: "distro" /: "Arch" /: "packages.csv"
       r = req GET api NoReqBody bsResponse mempty
   embed $ C.infoMessage "Downloading csv from hackage..."
@@ -146,10 +169,10 @@
       diffNew = community \\ hackage
       ppRecord b (name, version, url) = (if b then C.formatWith [C.green] else C.formatWith [C.red]) $ "(" <> name <> ", " <> version <> ", " <> url <> ")"
 
+  embed . putStrLn $ C.formatWith [C.magenta] "Diff:"
   embed $ case (diffNew <> diffOld) of
-    [] -> return ()
+    [] -> putStrLn "[]"
     _ -> do
-      putStrLn $ C.formatWith [C.magenta] "Diff:"
       putStr . unlines $ fmap (ppRecord False) diffOld
       putStrLn $ replicate 68 '-'
       putStr . unlines $ fmap (ppRecord True) diffNew
