Milestone 3: RPC server, ZIP-320 #104

Merged
pitmutt merged 152 commits from milestone3 into master 2024-11-21 15:39:19 +00:00
4 changed files with 87 additions and 38 deletions
Showing only changes of commit b6b586f9bf - Show all commits

View file

@ -10,7 +10,7 @@ import qualified Brick.BChan as BC
import qualified Brick.Focus as F import qualified Brick.Focus as F
import Brick.Forms import Brick.Forms
( Form(..) ( Form(..)
, radioField , (@@=)
, allFieldsValid , allFieldsValid
, editShowableFieldWithValidate , editShowableFieldWithValidate
, editTextField , editTextField
@ -18,10 +18,10 @@ import Brick.Forms
, handleFormEvent , handleFormEvent
, invalidFormInputAttr , invalidFormInputAttr
, newForm , newForm
, radioField
, renderForm , renderForm
, setFieldValid , setFieldValid
, updateFormState , updateFormState
, (@@=)
) )
import qualified Brick.Main as M import qualified Brick.Main as M
import qualified Brick.Types as BT import qualified Brick.Types as BT
@ -99,9 +99,9 @@ import Zenith.Types
( Config(..) ( Config(..)
, HexStringDB(..) , HexStringDB(..)
, PhraseDB(..) , PhraseDB(..)
, PrivacyPolicy(..)
, UnifiedAddressDB(..) , UnifiedAddressDB(..)
, ZcashNetDB(..) , ZcashNetDB(..)
, PrivacyPolicy(..)
) )
import Zenith.Utils import Zenith.Utils
( displayTaz ( displayTaz
@ -184,7 +184,8 @@ data Tick
| TickMsg !String | TickMsg !String
| TickTx !HexString | TickTx !HexString
data DropDownItem = DropdownItem String data DropDownItem =
DropdownItem String
data State = State data State = State
{ _network :: !ZcashNet { _network :: !ZcashNet
@ -619,7 +620,9 @@ mkSendForm :: Integer -> SendInput -> Form SendInput e Name
mkSendForm bal = mkSendForm bal =
newForm newForm
[ label "Privacy Level :" @@= [ label "Privacy Level :" @@=
radioField policyField [ (Full, PrivacyFullField, "Full") radioField
policyField
[ (Full, PrivacyFullField, "Full")
, (Medium, PrivacyMediumField, "Medium") , (Medium, PrivacyMediumField, "Medium")
, (Low, PrivacyLowField, "Low") , (Low, PrivacyLowField, "Low")
, (None, PrivacyNoneField, "None") , (None, PrivacyNoneField, "None")
@ -1403,6 +1406,7 @@ runZenithTUI config = do
Left e1 -> throwIO e1 Left e1 -> throwIO e1
Right chainInfo -> do Right chainInfo -> do
x <- initDb dbFilePath x <- initDb dbFilePath
_ <- upgradeQrTable pool
case x of case x of
Left e2 -> throwIO $ userError e2 Left e2 -> throwIO $ userError e2
Right x' -> do Right x' -> do

View file

@ -19,7 +19,7 @@
module Zenith.DB where module Zenith.DB where
import Control.Exception (SomeException(..), throw, throwIO, try) import Control.Exception (SomeException(..), throw, throwIO, try)
import Control.Monad (when) import Control.Monad (unless, when)
import Control.Monad.IO.Class (MonadIO, liftIO) import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Logger (NoLoggingT, runNoLoggingT) import Control.Monad.Logger (NoLoggingT, runNoLoggingT)
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
@ -448,8 +448,10 @@ initDb dbName = do
(Either SomeException [T.Text]) (Either SomeException [T.Text])
case m of case m of
Left e2 -> return $ Left $ "Failed to migrate data tables" ++ show e2 Left e2 -> return $ Left $ "Failed to migrate data tables" ++ show e2
Right _ -> return $ Right True Right _ -> do
Right _ -> return $ Right False return $ Right True
Right _ -> do
return $ Right False
initPool :: T.Text -> NoLoggingT IO ConnectionPool initPool :: T.Text -> NoLoggingT IO ConnectionPool
initPool dbPath = do initPool dbPath = do
@ -839,6 +841,32 @@ getQrCode pool zp wId = do
return qrs return qrs
return $ entityVal <$> r return $ entityVal <$> r
upgradeQrTable :: ConnectionPool -> IO ()
upgradeQrTable pool = do
r <-
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $
selectOne $ do
qrs <- from $ table @QrCode
where_ $ qrs ^. QrCodeVersion ==. val OrchardPool
return countRows
unless (maybe 0 (\(Value x) -> x) r > (0 :: Int)) $ do
_ <-
runNoLoggingT $
PS.retryOnBusy $
flip PS.runSqlPool pool $ do
rawExecute
"update qr_code set version = ? where version = ?"
[PersistText "OrchardPool", PersistText "Orchard"]
rawExecute
"update qr_code set version = ? where version = ?"
[PersistText "SaplingPool", PersistText "Sapling"]
rawExecute
"update qr_code set version = ? where version = ?"
[PersistText "TransparentPool", PersistText "Transparent"]
return ()
-- * Wallet -- * Wallet
-- | Get the block of the last transaction known to the wallet -- | Get the block of the last transaction known to the wallet
getMaxWalletBlock :: getMaxWalletBlock ::

View file

@ -32,7 +32,11 @@ import Text.Printf
import Text.Wrap (FillScope(..), FillStrategy(..), WrapSettings(..), wrapText) import Text.Wrap (FillScope(..), FillStrategy(..), WrapSettings(..), wrapText)
import TextShow hiding (toText) import TextShow hiding (toText)
import ZcashHaskell.Keys (generateWalletSeedPhrase) import ZcashHaskell.Keys (generateWalletSeedPhrase)
import ZcashHaskell.Orchard (getSaplingFromUA, isValidUnifiedAddress) import ZcashHaskell.Orchard
( getSaplingFromUA
, isValidUnifiedAddress
, parseAddress
)
import ZcashHaskell.Transparent (encodeTransparentReceiver) import ZcashHaskell.Transparent (encodeTransparentReceiver)
import ZcashHaskell.Types import ZcashHaskell.Types
( BlockResponse(..) ( BlockResponse(..)
@ -51,13 +55,11 @@ import Zenith.Scanner (checkIntegrity, processTx, rescanZebra, updateConfs)
import Zenith.Types hiding (ZcashAddress(..)) import Zenith.Types hiding (ZcashAddress(..))
import Zenith.Utils import Zenith.Utils
( displayAmount ( displayAmount
, isRecipientValid
, isRecipientValidGUI , isRecipientValidGUI
, isZecAddressValid
, isValidString , isValidString
, isZecAddressValid
, jsonNumber , jsonNumber
, padWithZero , padWithZero
, parseAddressUA
, showAddress , showAddress
, validBarValue , validBarValue
) )
@ -605,8 +607,8 @@ buildUI wenv model = widgetTree
, separatorLine `styleBasic` [fgColor btnColor] , separatorLine `styleBasic` [fgColor btnColor]
, spacer , spacer
, hstack , hstack
[ [ label "Privacy Level:" `styleBasic`
label "Privacy Level:" `styleBasic` [width 70, textFont "Bold"] [width 70, textFont "Bold"]
, spacer , spacer
, label "Full " `styleBasic` [width 40] , label "Full " `styleBasic` [width 40]
, radio Full privacyChoice , radio Full privacyChoice
@ -615,8 +617,8 @@ buildUI wenv model = widgetTree
, radio Medium privacyChoice , radio Medium privacyChoice
] ]
, hstack , hstack
[ [ label " " `styleBasic`
label " " `styleBasic` [width 70, textFont "Bold"] [width 70, textFont "Bold"]
, spacer , spacer
, label "Low " `styleBasic` [width 40] , label "Low " `styleBasic` [width 40]
, radio Low privacyChoice , radio Low privacyChoice
@ -636,7 +638,8 @@ buildUI wenv model = widgetTree
] ]
] ]
, hstack , hstack
[ label "Amount:" `styleBasic` [width 50, textFont "Bold"] [ label "Amount:" `styleBasic`
[width 50, textFont "Bold"]
, spacer , spacer
, numericField_ , numericField_
sendAmount sendAmount
@ -654,7 +657,8 @@ buildUI wenv model = widgetTree
] ]
] ]
, hstack , hstack
[ label "Memo:" `styleBasic` [width 50, textFont "Bold"] [ label "Memo:" `styleBasic`
[width 50, textFont "Bold"]
, spacer , spacer
, textArea sendMemo `styleBasic` , textArea sendMemo `styleBasic`
[width 150, height 40] [width 150, height 40]
@ -1079,7 +1083,11 @@ handleEvent wenv node model evt =
] ]
ConfirmCancel -> [Model $ model & confirmTitle .~ Nothing & mainInput .~ ""] ConfirmCancel -> [Model $ model & confirmTitle .~ Nothing & mainInput .~ ""]
ShowSeed -> [Model $ model & showSeed .~ True & menuPopup .~ False] ShowSeed -> [Model $ model & showSeed .~ True & menuPopup .~ False]
ShowSend -> [Model $ model & openSend .~ True & privacyChoice .~ Full & recipientValid .~ False] ShowSend ->
[ Model $
model & openSend .~ True & privacyChoice .~ Full & recipientValid .~
False
]
SendTx -> SendTx ->
case currentAccount of case currentAccount of
Nothing -> [Event $ ShowError "No account available", Event CancelSend] Nothing -> [Event $ ShowError "No account available", Event CancelSend]
@ -1097,6 +1105,7 @@ handleEvent wenv node model evt =
(model ^. sendAmount) (model ^. sendAmount)
(model ^. sendRecipient) (model ^. sendRecipient)
(model ^. sendMemo) (model ^. sendMemo)
(model ^. privacyChoice)
, Event CancelSend , Event CancelSend
] ]
CancelSend -> CancelSend ->
@ -1263,9 +1272,10 @@ handleEvent wenv node model evt =
T.pack (printf "%.2f%%" (model ^. barValue * 100))) T.pack (printf "%.2f%%" (model ^. barValue * 100)))
] ]
ResetRecipientValid -> [Model $ model & recipientValid .~ False] ResetRecipientValid -> [Model $ model & recipientValid .~ False]
CheckRecipient a -> [Model $ CheckRecipient a ->
model & recipientValid .~ isRecipientValidGUI (model ^.privacyChoice) a ] [ Model $
-- model & recipientValid .~ ((model ^. privacyChoice) == Low) ] model & recipientValid .~ isRecipientValidGUI (model ^. privacyChoice) a
]
CheckAmount i -> CheckAmount i ->
[ Model $ [ Model $
model & amountValid .~ model & amountValid .~
@ -1465,6 +1475,7 @@ handleEvent wenv node model evt =
res <- liftIO $ updateAdrsInAdrBook pool d a a res <- liftIO $ updateAdrsInAdrBook pool d a a
return $ ShowMessage "Address Book entry updated!!" return $ ShowMessage "Address Book entry updated!!"
-- model & recipientValid .~ ((model ^. privacyChoice) == Low) ]
scanZebra :: T.Text -> T.Text -> Int -> ZcashNet -> (AppEvent -> IO ()) -> IO () scanZebra :: T.Text -> T.Text -> Int -> ZcashNet -> (AppEvent -> IO ()) -> IO ()
scanZebra dbPath zHost zPort net sendMsg = do scanZebra dbPath zHost zPort net sendMsg = do
bStatus <- liftIO $ checkBlockChain zHost zPort bStatus <- liftIO $ checkBlockChain zHost zPort
@ -1533,20 +1544,21 @@ sendTransaction ::
-> Float -> Float
-> T.Text -> T.Text
-> T.Text -> T.Text
-> PrivacyPolicy
-> (AppEvent -> IO ()) -> (AppEvent -> IO ())
-> IO () -> IO ()
sendTransaction config znet accId bl amt ua memo sendMsg = do sendTransaction config znet accId bl amt ua memo policy sendMsg = do
sendMsg $ ShowModal "Preparing transaction..." sendMsg $ ShowModal "Preparing transaction..."
case parseAddressUA ua znet of case parseAddress (E.encodeUtf8 ua) of
Nothing -> sendMsg $ ShowError "Incorrect address" Nothing -> sendMsg $ ShowError "Incorrect address"
Just outUA -> do Just addr -> do
let dbPath = c_dbPath config let dbPath = c_dbPath config
let zHost = c_zebraHost config let zHost = c_zebraHost config
let zPort = c_zebraPort config let zPort = c_zebraPort config
pool <- runNoLoggingT $ initPool dbPath pool <- runNoLoggingT $ initPool dbPath
res <- res <-
runFileLoggingT "zenith.log" $ runFileLoggingT "zenith.log" $
prepareTx pool zHost zPort znet accId bl amt outUA memo prepareTxV2 pool zHost zPort znet accId bl amt addr memo policy
case res of case res of
Left e -> sendMsg $ ShowError $ T.pack $ show e Left e -> sendMsg $ ShowError $ T.pack $ show e
Right rawTx -> do Right rawTx -> do
@ -1593,6 +1605,7 @@ runZenithGUI config = do
Left e1 -> throwIO e1 Left e1 -> throwIO e1
Right chainInfo -> do Right chainInfo -> do
x <- initDb dbFilePath x <- initDb dbFilePath
_ <- upgradeQrTable pool
case x of case x of
Left e2 -> throwIO $ userError e2 Left e2 -> throwIO $ userError e2
Right x' -> do Right x' -> do

View file

@ -48,6 +48,7 @@ import Zenith.DB
, saveConfs , saveConfs
, saveTransaction , saveTransaction
, updateWalletSync , updateWalletSync
, upgradeQrTable
) )
import Zenith.Types (Config(..), HexStringDB(..), ZcashNetDB(..)) import Zenith.Types (Config(..), HexStringDB(..), ZcashNetDB(..))
import Zenith.Utils (jsonNumber) import Zenith.Utils (jsonNumber)
@ -69,6 +70,8 @@ rescanZebra host port dbFilePath = do
pool1 <- runNoLoggingT $ initPool dbFilePath pool1 <- runNoLoggingT $ initPool dbFilePath
{-pool2 <- runNoLoggingT $ initPool dbFilePath-} {-pool2 <- runNoLoggingT $ initPool dbFilePath-}
{-pool3 <- runNoLoggingT $ initPool dbFilePath-} {-pool3 <- runNoLoggingT $ initPool dbFilePath-}
_ <- initDb dbFilePath
upgradeQrTable pool1
clearWalletTransactions pool1 clearWalletTransactions pool1
clearWalletData pool1 clearWalletData pool1
dbBlock <- getMaxBlock pool1 znet dbBlock <- getMaxBlock pool1 znet
@ -211,6 +214,7 @@ clearSync config = do
Left e1 -> throwIO e1 Left e1 -> throwIO e1
Right chainInfo -> do Right chainInfo -> do
x <- initDb dbPath x <- initDb dbPath
_ <- upgradeQrTable pool
case x of case x of
Left e2 -> throwIO $ userError e2 Left e2 -> throwIO $ userError e2
Right x' -> do Right x' -> do