Enhancements to blockchain scanner #74

Merged
pitmutt merged 2 commits from rav001 into dev041 2024-04-04 19:39:08 +00:00
5 changed files with 69 additions and 31 deletions
Showing only changes of commit bf192a77f6 - Show all commits

View file

@ -8,8 +8,7 @@ import Zenith.Scanner (scanZebra)
main :: IO () main :: IO ()
main = do main = do
config <- load ["zenith.cfg"] config <- load ["zenith.cfg"]
--dbFilePath <- require config "dbFilePath" dbFilePath <- require config "dbFilePath"
dataStorePath <- require config "dataStorePath"
zebraPort <- require config "zebraPort" zebraPort <- require config "zebraPort"
zebraHost <- require config "zebraHost" zebraHost <- require config "zebraHost"
scanZebra 2781518 zebraHost zebraPort dataStorePath scanZebra 2762066 zebraHost zebraPort dbFilePath

View file

@ -157,3 +157,12 @@ createWalletAddress n i zNet scope za = do
(UnifiedAddressDB $ (UnifiedAddressDB $
encodeUnifiedAddress $ UnifiedAddress zNet oRec sRec (Just tRec)) encodeUnifiedAddress $ UnifiedAddress zNet oRec sRec (Just tRec))
(ScopeDB scope) (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

View file

@ -78,23 +78,46 @@ share
UniqueAddress index scope accId UniqueAddress index scope accId
UniqueAddName accId name UniqueAddName accId name
deriving Show Eq deriving Show Eq
|]
share
[mkPersist sqlSettings, mkMigrate "rawStorage"]
[persistLowerCase|
WalletTransaction 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 block Int
txId HexStringDB txId HexStringDB
conf Int conf Int
time Int time Int
deriving Show Eq deriving Show Eq
TransparentNote TransparentNote
tx WalletTransactionId tx ZcashTransactionId
value Int value Int
script BS.ByteString script BS.ByteString
OrchAction OrchAction
tx WalletTransactionId tx ZcashTransactionId
nf HexStringDB nf HexStringDB
rk HexStringDB rk HexStringDB
cmx HexStringDB cmx HexStringDB
@ -105,7 +128,7 @@ share
auth HexStringDB auth HexStringDB
deriving Show Eq deriving Show Eq
ShieldOutput ShieldOutput
tx WalletTransactionId tx ZcashTransactionId
cv HexStringDB cv HexStringDB
cmu HexStringDB cmu HexStringDB
ephKey HexStringDB ephKey HexStringDB
@ -114,7 +137,7 @@ share
proof HexStringDB proof HexStringDB
deriving Show Eq deriving Show Eq
ShieldSpend ShieldSpend
tx WalletTransactionId tx ZcashTransactionId
cv HexStringDB cv HexStringDB
anchor HexStringDB anchor HexStringDB
nullifier HexStringDB nullifier HexStringDB
@ -132,12 +155,6 @@ initDb ::
initDb dbName = do initDb dbName = do
runSqlite dbName $ do runMigration migrateAll 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 -- | Get existing wallets from database
getWallets :: T.Text -> ZcashNet -> IO [Entity ZcashWallet] getWallets :: T.Text -> ZcashNet -> IO [Entity ZcashWallet]
getWallets dbFp n = getWallets dbFp n =
@ -177,6 +194,18 @@ saveAccount ::
-> IO (Maybe (Entity ZcashAccount)) -> IO (Maybe (Entity ZcashAccount))
saveAccount dbFp a = runSqlite dbFp $ insertUniqueEntity a 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 -- | Returns a list of addresses associated with the given account
getAddresses :: getAddresses ::
T.Text -- ^ The database path T.Text -- ^ The database path
@ -216,12 +245,12 @@ saveTransaction ::
T.Text -- ^ the database path T.Text -- ^ the database path
-> Int -- ^ block time -> Int -- ^ block time
-> Transaction -- ^ The transaction to save -> Transaction -- ^ The transaction to save
-> IO (Key WalletTransaction) -> IO (Key ZcashTransaction)
saveTransaction dbFp t wt = saveTransaction dbFp t wt =
runSqlite dbFp $ do runSqlite dbFp $ do
w <- w <-
insert $ 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) $ when (isJust $ tx_transpBundle wt) $
insertMany_ $ insertMany_ $
map (storeTxOut w) $ (tb_vout . fromJust . tx_transpBundle) wt 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 map (storeOrchAction w) $ (obActions . fromJust . tx_orchardBundle) wt
return w return w
where where
storeTxOut :: WalletTransactionId -> TxOut -> TransparentNote storeTxOut :: ZcashTransactionId -> TxOut -> TransparentNote
storeTxOut wid (TxOut v s) = TransparentNote wid (fromIntegral v) s storeTxOut wid (TxOut v s) = TransparentNote wid (fromIntegral v) s
storeSapSpend :: WalletTransactionId -> ShieldedSpend -> ShieldSpend storeSapSpend :: ZcashTransactionId -> ShieldedSpend -> ShieldSpend
storeSapSpend wid sp = storeSapSpend wid sp =
ShieldSpend ShieldSpend
wid wid
@ -250,7 +279,7 @@ saveTransaction dbFp t wt =
(HexStringDB $ sp_rk sp) (HexStringDB $ sp_rk sp)
(HexStringDB $ sp_proof sp) (HexStringDB $ sp_proof sp)
(HexStringDB $ sp_auth sp) (HexStringDB $ sp_auth sp)
storeSapOutput :: WalletTransactionId -> ShieldedOutput -> ShieldOutput storeSapOutput :: ZcashTransactionId -> ShieldedOutput -> ShieldOutput
storeSapOutput wid so = storeSapOutput wid so =
ShieldOutput ShieldOutput
wid wid
@ -260,7 +289,7 @@ saveTransaction dbFp t wt =
(HexStringDB $ s_encCipherText so) (HexStringDB $ s_encCipherText so)
(HexStringDB $ s_outCipherText so) (HexStringDB $ s_outCipherText so)
(HexStringDB $ s_proof so) (HexStringDB $ s_proof so)
storeOrchAction :: WalletTransactionId -> OrchardAction -> OrchAction storeOrchAction :: ZcashTransactionId -> OrchardAction -> OrchAction
storeOrchAction wid oa = storeOrchAction wid oa =
OrchAction OrchAction
wid wid

View file

@ -20,7 +20,7 @@ import ZcashHaskell.Types
) )
import ZcashHaskell.Utils (getBlockTime, makeZebraCall, readZebraTransaction) import ZcashHaskell.Utils (getBlockTime, makeZebraCall, readZebraTransaction)
import Zenith.Core (checkBlockChain) import Zenith.Core (checkBlockChain)
import Zenith.DB (initRawStore, saveTransaction) import Zenith.DB (getMaxBlock, initDb, saveTransaction)
import Zenith.Utils (jsonNumber) import Zenith.Utils (jsonNumber)
-- | Function to scan the Zcash blockchain through the Zebra node and populate the Zenith database -- | 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 -> T.Text -- ^ Path to database file
-> IO () -> IO ()
scanZebra b host port dbFilePath = do scanZebra b host port dbFilePath = do
_ <- initRawStore dbFilePath _ <- initDb dbFilePath
bc <- bc <-
try $ checkBlockChain host port :: IO try $ checkBlockChain host port :: IO
(Either IOError ZebraGetBlockChainInfo) (Either IOError ZebraGetBlockChainInfo)
case bc of case bc of
Left e -> print e Left e -> print e
Right bStatus -> do 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" then throwIO $ userError "Invalid starting block for scan"
else do else do
let bList = [b .. (zgb_blocks bStatus)] let bList = [sb .. (zgb_blocks bStatus)]
txList <- txList <-
try $ mapM_ (processBlock host port dbFilePath) bList :: IO try $ mapM_ (processBlock host port dbFilePath) bList :: IO
(Either IOError ()) (Either IOError ())
@ -108,7 +110,7 @@ processTx host port bt dbFp t = do
case readZebraTransaction (ztr_hex rawTx) of case readZebraTransaction (ztr_hex rawTx) of
Nothing -> return () Nothing -> return ()
Just rzt -> do Just rzt -> do
k <- _ <-
saveTransaction dbFp bt $ saveTransaction dbFp bt $
Transaction Transaction
t t
@ -118,4 +120,4 @@ processTx host port bt dbFp t = do
(fromRawTBundle $ zt_tBundle rzt) (fromRawTBundle $ zt_tBundle rzt)
(fromRawSBundle $ zt_sBundle rzt) (fromRawSBundle $ zt_sBundle rzt)
(fromRawOBundle $ zt_oBundle rzt) (fromRawOBundle $ zt_oBundle rzt)
print k return ()

View file

@ -3,4 +3,3 @@ nodePwd = "superSecret"
dbFilePath = "zenith.db" dbFilePath = "zenith.db"
zebraHost = "127.0.0.1" zebraHost = "127.0.0.1"
zebraPort = 18232 zebraPort = 18232
dataStorePath = "datastore.db"