From bf192a77f6a239a3b6c5eadf2815708286334bc2 Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Thu, 4 Apr 2024 13:21:55 -0500 Subject: [PATCH] Add check of existing db for scan --- app/ZenScan.hs | 5 ++- src/Zenith/Core.hs | 9 ++++++ src/Zenith/DB.hs | 71 ++++++++++++++++++++++++++++++------------- src/Zenith/Scanner.hs | 14 +++++---- zenith.cfg | 1 - 5 files changed, 69 insertions(+), 31 deletions(-) diff --git a/app/ZenScan.hs b/app/ZenScan.hs index 803a822..fd7530e 100644 --- a/app/ZenScan.hs +++ b/app/ZenScan.hs @@ -8,8 +8,7 @@ import Zenith.Scanner (scanZebra) main :: IO () main = do config <- load ["zenith.cfg"] - --dbFilePath <- require config "dbFilePath" - dataStorePath <- require config "dataStorePath" + dbFilePath <- require config "dbFilePath" zebraPort <- require config "zebraPort" zebraHost <- require config "zebraHost" - scanZebra 2781518 zebraHost zebraPort dataStorePath + scanZebra 2762066 zebraHost zebraPort dbFilePath diff --git a/src/Zenith/Core.hs b/src/Zenith/Core.hs index 81ce9ff..2b7cf00 100644 --- a/src/Zenith/Core.hs +++ b/src/Zenith/Core.hs @@ -157,3 +157,12 @@ createWalletAddress n i zNet scope za = do (UnifiedAddressDB $ encodeUnifiedAddress $ UnifiedAddress zNet oRec sRec (Just tRec)) (ScopeDB scope) + +-- * Wallet +-- | Sync the wallet with the data store +syncWallet :: + T.Text -- ^ Wallet database + -> T.Text -- ^ Data store database + -> Entity ZcashWallet + -> IO () +syncWallet walletDb dataDb w = undefined diff --git a/src/Zenith/DB.hs b/src/Zenith/DB.hs index 8b91d8c..d59629c 100644 --- a/src/Zenith/DB.hs +++ b/src/Zenith/DB.hs @@ -78,23 +78,46 @@ share UniqueAddress index scope accId UniqueAddName accId name deriving Show Eq - |] - -share - [mkPersist sqlSettings, mkMigrate "rawStorage"] - [persistLowerCase| WalletTransaction + addrId WalletAddressId + txId HexStringDB + conf Int + time Int + deriving Show Eq + WalletTrNote + tx WalletTransactionId + value Int + rawId TransparentNoteId + spent Bool + deriving Show Eq + WalletSapNote + tx WalletTransactionId + value Int + recipient BS.ByteString + memo T.Text + rawId ShieldOutputId + spent Bool + deriving Show Eq + WalletOrchNote + tx WalletTransactionId + value Int + recipient BS.ByteString + memo T.Text + rawId OrchActionId + spent Bool + deriving Show Eq + ZcashTransaction block Int txId HexStringDB conf Int time Int deriving Show Eq TransparentNote - tx WalletTransactionId + tx ZcashTransactionId value Int script BS.ByteString OrchAction - tx WalletTransactionId + tx ZcashTransactionId nf HexStringDB rk HexStringDB cmx HexStringDB @@ -105,7 +128,7 @@ share auth HexStringDB deriving Show Eq ShieldOutput - tx WalletTransactionId + tx ZcashTransactionId cv HexStringDB cmu HexStringDB ephKey HexStringDB @@ -114,7 +137,7 @@ share proof HexStringDB deriving Show Eq ShieldSpend - tx WalletTransactionId + tx ZcashTransactionId cv HexStringDB anchor HexStringDB nullifier HexStringDB @@ -132,12 +155,6 @@ initDb :: initDb dbName = do runSqlite dbName $ do runMigration migrateAll --- | Initializes the raw data storage -initRawStore :: - T.Text -- ^ the database path - -> IO () -initRawStore dbFilePath = runSqlite dbFilePath $ runMigration rawStorage - -- | Get existing wallets from database getWallets :: T.Text -> ZcashNet -> IO [Entity ZcashWallet] getWallets dbFp n = @@ -177,6 +194,18 @@ saveAccount :: -> IO (Maybe (Entity ZcashAccount)) saveAccount dbFp a = runSqlite dbFp $ insertUniqueEntity a +-- | Returns the largest block in storage +getMaxBlock :: + T.Text -- ^ The database path + -> IO Int +getMaxBlock dbPath = do + b <- + runSqlite dbPath $ + selectFirst [ZcashTransactionBlock >. 0] [Desc ZcashTransactionBlock] + case b of + Nothing -> return $ -1 + Just x -> return $ zcashTransactionBlock $ entityVal x + -- | Returns a list of addresses associated with the given account getAddresses :: T.Text -- ^ The database path @@ -216,12 +245,12 @@ saveTransaction :: T.Text -- ^ the database path -> Int -- ^ block time -> Transaction -- ^ The transaction to save - -> IO (Key WalletTransaction) + -> IO (Key ZcashTransaction) saveTransaction dbFp t wt = runSqlite dbFp $ do w <- insert $ - WalletTransaction (tx_height wt) (HexStringDB $ tx_id wt) (tx_conf wt) t + ZcashTransaction (tx_height wt) (HexStringDB $ tx_id wt) (tx_conf wt) t when (isJust $ tx_transpBundle wt) $ insertMany_ $ map (storeTxOut w) $ (tb_vout . fromJust . tx_transpBundle) wt @@ -238,9 +267,9 @@ saveTransaction dbFp t wt = map (storeOrchAction w) $ (obActions . fromJust . tx_orchardBundle) wt return w where - storeTxOut :: WalletTransactionId -> TxOut -> TransparentNote + storeTxOut :: ZcashTransactionId -> TxOut -> TransparentNote storeTxOut wid (TxOut v s) = TransparentNote wid (fromIntegral v) s - storeSapSpend :: WalletTransactionId -> ShieldedSpend -> ShieldSpend + storeSapSpend :: ZcashTransactionId -> ShieldedSpend -> ShieldSpend storeSapSpend wid sp = ShieldSpend wid @@ -250,7 +279,7 @@ saveTransaction dbFp t wt = (HexStringDB $ sp_rk sp) (HexStringDB $ sp_proof sp) (HexStringDB $ sp_auth sp) - storeSapOutput :: WalletTransactionId -> ShieldedOutput -> ShieldOutput + storeSapOutput :: ZcashTransactionId -> ShieldedOutput -> ShieldOutput storeSapOutput wid so = ShieldOutput wid @@ -260,7 +289,7 @@ saveTransaction dbFp t wt = (HexStringDB $ s_encCipherText so) (HexStringDB $ s_outCipherText so) (HexStringDB $ s_proof so) - storeOrchAction :: WalletTransactionId -> OrchardAction -> OrchAction + storeOrchAction :: ZcashTransactionId -> OrchardAction -> OrchAction storeOrchAction wid oa = OrchAction wid diff --git a/src/Zenith/Scanner.hs b/src/Zenith/Scanner.hs index a2a8c19..5a92959 100644 --- a/src/Zenith/Scanner.hs +++ b/src/Zenith/Scanner.hs @@ -20,7 +20,7 @@ import ZcashHaskell.Types ) import ZcashHaskell.Utils (getBlockTime, makeZebraCall, readZebraTransaction) import Zenith.Core (checkBlockChain) -import Zenith.DB (initRawStore, saveTransaction) +import Zenith.DB (getMaxBlock, initDb, saveTransaction) import Zenith.Utils (jsonNumber) -- | Function to scan the Zcash blockchain through the Zebra node and populate the Zenith database @@ -31,17 +31,19 @@ scanZebra :: -> T.Text -- ^ Path to database file -> IO () scanZebra b host port dbFilePath = do - _ <- initRawStore dbFilePath + _ <- initDb dbFilePath bc <- try $ checkBlockChain host port :: IO (Either IOError ZebraGetBlockChainInfo) case bc of Left e -> print e Right bStatus -> do - if b > zgb_blocks bStatus || b < 1 + dbBlock <- getMaxBlock dbFilePath + let sb = min dbBlock b + if sb > zgb_blocks bStatus || sb < 1 then throwIO $ userError "Invalid starting block for scan" else do - let bList = [b .. (zgb_blocks bStatus)] + let bList = [sb .. (zgb_blocks bStatus)] txList <- try $ mapM_ (processBlock host port dbFilePath) bList :: IO (Either IOError ()) @@ -108,7 +110,7 @@ processTx host port bt dbFp t = do case readZebraTransaction (ztr_hex rawTx) of Nothing -> return () Just rzt -> do - k <- + _ <- saveTransaction dbFp bt $ Transaction t @@ -118,4 +120,4 @@ processTx host port bt dbFp t = do (fromRawTBundle $ zt_tBundle rzt) (fromRawSBundle $ zt_sBundle rzt) (fromRawOBundle $ zt_oBundle rzt) - print k + return () diff --git a/zenith.cfg b/zenith.cfg index 9fb953b..efedae5 100644 --- a/zenith.cfg +++ b/zenith.cfg @@ -3,4 +3,3 @@ nodePwd = "superSecret" dbFilePath = "zenith.db" zebraHost = "127.0.0.1" zebraPort = 18232 -dataStorePath = "datastore.db"