From 28c05a66fe22005134cec2c8dd2097d3f65f5319 Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Tue, 1 Oct 2024 07:57:01 -0500 Subject: [PATCH] feat: implement new `PrivacyPolicy` --- CHANGELOG.md | 22 ++--- src/Zenith/CLI.hs | 6 +- src/Zenith/Core.hs | 16 ++-- test/Spec.hs | 207 +++++++++++++++++++++++++++++++++++++++++++-- zcash-haskell | 2 +- 5 files changed, 226 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa43828..a58632b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,16 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - RPC module -- OpenRPC specification -- `listwallets` RPC method -- `listaccounts` RPC method -- `listaddresses` RPC method -- `listreceived` RPC method -- `getbalance` RPC method -- `getnewwallet` RPC method -- `getnewaccount` RPC method -- `getnewaddress` RPC method -- `getoperationstatus` RPC method + - OpenRPC specification + - `listwallets` RPC method + - `listaccounts` RPC method + - `listaddresses` RPC method + - `listreceived` RPC method + - `getbalance` RPC method + - `getnewwallet` RPC method + - `getnewaccount` RPC method + - `getnewaddress` RPC method + - `getoperationstatus` RPC method +- Function `prepareTxV2` implementing `PrivacyPolicy` ### Changed @@ -27,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Block tracking for chain re-org detection - Refactored `ZcashPool` + ## [0.6.0.0-beta] ### Added diff --git a/src/Zenith/CLI.hs b/src/Zenith/CLI.hs index 5a89a8b..2e5dab6 100644 --- a/src/Zenith/CLI.hs +++ b/src/Zenith/CLI.hs @@ -737,7 +737,11 @@ scanZebra dbP zHost zPort b eChan znet = do logDebugN $ "dbBlock: " <> T.pack (show dbBlock) <> " chkBlock: " <> T.pack (show chkBlock) - let sb = max dbBlock b + when (chkBlock /= dbBlock) $ liftIO $ rewindWalletData pool chkBlock + let sb = + if chkBlock == dbBlock + then max dbBlock b + else max chkBlock b if sb > zgb_blocks bStatus || sb < 1 then do liftIO $ BC.writeBChan eChan $ TickMsg "Invalid starting block for scan" diff --git a/src/Zenith/Core.hs b/src/Zenith/Core.hs index fcfed56..80bc5f7 100644 --- a/src/Zenith/Core.hs +++ b/src/Zenith/Core.hs @@ -44,6 +44,7 @@ import ZcashHaskell.Orchard , encodeUnifiedAddress , genOrchardReceiver , genOrchardSpendingKey + , getOrchardFrontier , getOrchardNotePosition , getOrchardWitness , isValidUnifiedAddress @@ -372,13 +373,16 @@ findOrchardActions config b znet za = do pool <- runNoLoggingT $ initPool dbPath tList <- getOrchardActions pool b znet trees <- getCommitmentTrees zebraHost zebraPort (b - 1) - let sT = OrchardCommitmentTree $ ztiOrchard trees - decryptNotes sT zn pool tList - orchNotes <- getWalletOrchNotes pool (entityKey za) - findOrchSpends pool (entityKey za) orchNotes + let sT = getOrchardFrontier $ OrchardCommitmentTree $ ztiOrchard trees + case sT of + Nothing -> throwIO $ userError "Failed to read Orchard commitment tree" + Just sT' -> do + decryptNotes sT' zn pool tList + orchNotes <- getWalletOrchNotes pool (entityKey za) + findOrchSpends pool (entityKey za) orchNotes where decryptNotes :: - OrchardCommitmentTree + OrchardFrontier -> ZcashNet -> ConnectionPool -> [(Entity ZcashTransaction, Entity OrchAction)] @@ -901,7 +905,7 @@ prepareTxV2 pool zebraHost zebraPort zn za bh amt va memo policy = do None -> return $ Left $ - PrivacyPolicyError "Recipient not allowed by privacy policy" + PrivacyPolicyError "Receiver not compatible with privacy policy" _anyOther -> do let chgRcvr = fromJust $ diff --git a/test/Spec.hs b/test/Spec.hs index 96523c0..79c7aaa 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -32,6 +32,7 @@ import ZcashHaskell.Types , SaplingSpendingKey(..) , Scope(..) , ShieldedOutput(..) + , TxError(..) , ZcashNet(..) ) import Zenith.Core @@ -235,15 +236,15 @@ main = do Just "ztestsapling1tgjr4zppwk4ne8xy6gdq4z2gwq7dmf5jq8z2ctpn8nlmtse0a74fa5z0m8z383gmpgqz6q6duu4" describe "Notes" $ do - it "Check Orchard notes" $ do + xit "Check Orchard notes" $ do pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" oNotes <- getWalletUnspentOrchNotes pool (toSqlKey 1) oNotes `shouldBe` [] - it "Check Sapling notes" $ do + xit "Check Sapling notes" $ do pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" oNotes <- getWalletUnspentSapNotes pool (toSqlKey 4) oNotes `shouldBe` [] - it "Check transparent notes" $ do + xit "Check transparent notes" $ do pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" oNotes <- getWalletUnspentTrNotes pool (toSqlKey 1) oNotes `shouldBe` [] @@ -265,7 +266,7 @@ main = do 18232 TestNet (toSqlKey 1) - 3001230 + 3001331 0.005 (fromJust uaRead) "Sending memo to orchard" @@ -289,7 +290,7 @@ main = do 18232 TestNet (toSqlKey 4) - 3001230 + 3001331 0.005 (fromJust uaRead) "Sending memo to sapling" @@ -297,8 +298,30 @@ main = do case tx of Left e -> assertFailure $ show e Right h -> h `shouldNotBe` (hexString "deadbeef") + it "To Transparent" $ do + let uaRead = parseAddress "tmAmSa4AauSFuJieeanRBjkfnah45ysGtgZ" + case uaRead of + Nothing -> assertFailure "wrong address" + Just ua -> do + pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" + tx <- + runFileLoggingT "zenith.log" $ + prepareTxV2 + pool + "localhost" + 18232 + TestNet + (toSqlKey 4) + 3001331 + 0.005 + (fromJust uaRead) + "" + Full + tx `shouldBe` + Left + (PrivacyPolicyError "Receiver not capable of Full privacy") describe "Medium" $ do - xit "To Orchard" $ do + it "To Orchard" $ do let uaRead = parseAddress "utest1dl54utt6prjj5e0dnlknwumnxq9hycdjpkfr0sy6e6h522remqee8axe9zax0wsjrwpj76v555pdhvj9rnargpfyycs0vpkapq98xcdhem99gc4wchzn0ggepq3y6nz3a9sscwgqxgsh9vzhcad402y3x9szfregck5gslkya3c79d86xx0l33tpk8gnn7ew9vw37w43zh22u8dgdax" @@ -314,7 +337,7 @@ main = do 18232 TestNet (toSqlKey 1) - 3000789 + 3001372 0.005 (fromJust uaRead) "Sending memo to orchard" @@ -322,7 +345,7 @@ main = do case tx of Left e -> assertFailure $ show e Right h -> h `shouldNotBe` (hexString "deadbeef") - xit "To Sapling" $ do + it "To Sapling" $ do let uaRead = parseAddress "ztestsapling136jp8z89v2jh6kqd5rs4dtvlxym90m43svzdwzxaplyvc5ttzppytpvx80ncllcsqzpmukxjl3y" @@ -338,7 +361,7 @@ main = do 18232 TestNet (toSqlKey 1) - 3000789 + 3001372 0.005 (fromJust uaRead) "Sending memo to orchard" @@ -346,3 +369,169 @@ main = do case tx of Left e -> assertFailure $ show e Right h -> h `shouldNotBe` (hexString "deadbeef") + it "To Transparent" $ do + let uaRead = parseAddress "tmAmSa4AauSFuJieeanRBjkfnah45ysGtgZ" + case uaRead of + Nothing -> assertFailure "wrong address" + Just ua -> do + pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" + tx <- + runFileLoggingT "zenith.log" $ + prepareTxV2 + pool + "localhost" + 18232 + TestNet + (toSqlKey 4) + 3001331 + 0.005 + (fromJust uaRead) + "" + Medium + tx `shouldBe` + Left + (PrivacyPolicyError "Receiver not capable of Medium privacy") + describe "Low" $ do + it "To Orchard" $ do + let uaRead = + parseAddress + "utest1dl54utt6prjj5e0dnlknwumnxq9hycdjpkfr0sy6e6h522remqee8axe9zax0wsjrwpj76v555pdhvj9rnargpfyycs0vpkapq98xcdhem99gc4wchzn0ggepq3y6nz3a9sscwgqxgsh9vzhcad402y3x9szfregck5gslkya3c79d86xx0l33tpk8gnn7ew9vw37w43zh22u8dgdax" + case uaRead of + Nothing -> assertFailure "wrong address" + Just ua -> do + pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" + tx <- + runFileLoggingT "zenith.log" $ + prepareTxV2 + pool + "localhost" + 18232 + TestNet + (toSqlKey 1) + 3001372 + 0.005 + (fromJust uaRead) + "Sending memo to orchard" + Low + case tx of + Left e -> assertFailure $ show e + Right h -> h `shouldNotBe` (hexString "deadbeef") + it "To Sapling" $ do + let uaRead = + parseAddress + "ztestsapling136jp8z89v2jh6kqd5rs4dtvlxym90m43svzdwzxaplyvc5ttzppytpvx80ncllcsqzpmukxjl3y" + case uaRead of + Nothing -> assertFailure "wrong address" + Just ua -> do + pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" + tx <- + runFileLoggingT "zenith.log" $ + prepareTxV2 + pool + "localhost" + 18232 + TestNet + (toSqlKey 1) + 3001372 + 0.005 + (fromJust uaRead) + "Sending memo to orchard" + Low + case tx of + Left e -> assertFailure $ show e + Right h -> h `shouldNotBe` (hexString "deadbeef") + it "To Transparent" $ do + let uaRead = parseAddress "tmAmSa4AauSFuJieeanRBjkfnah45ysGtgZ" + case uaRead of + Nothing -> assertFailure "wrong address" + Just ua -> do + pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" + tx <- + runFileLoggingT "zenith.log" $ + prepareTxV2 + pool + "localhost" + 18232 + TestNet + (toSqlKey 1) + 3001372 + 0.005 + (fromJust uaRead) + "" + Low + case tx of + Left e -> assertFailure $ show e + Right h -> h `shouldNotBe` (hexString "deadbeef") + describe "None" $ do + it "To Orchard" $ do + let uaRead = + parseAddress + "utest1dl54utt6prjj5e0dnlknwumnxq9hycdjpkfr0sy6e6h522remqee8axe9zax0wsjrwpj76v555pdhvj9rnargpfyycs0vpkapq98xcdhem99gc4wchzn0ggepq3y6nz3a9sscwgqxgsh9vzhcad402y3x9szfregck5gslkya3c79d86xx0l33tpk8gnn7ew9vw37w43zh22u8dgdax" + case uaRead of + Nothing -> assertFailure "wrong address" + Just ua -> do + pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" + tx <- + runFileLoggingT "zenith.log" $ + prepareTxV2 + pool + "localhost" + 18232 + TestNet + (toSqlKey 1) + 3001372 + 0.005 + (fromJust uaRead) + "Sending memo to orchard" + None + tx `shouldBe` + Left + (PrivacyPolicyError + "Receiver not compatible with privacy policy") + it "To Sapling" $ do + let uaRead = + parseAddress + "ztestsapling136jp8z89v2jh6kqd5rs4dtvlxym90m43svzdwzxaplyvc5ttzppytpvx80ncllcsqzpmukxjl3y" + case uaRead of + Nothing -> assertFailure "wrong address" + Just ua -> do + pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" + tx <- + runFileLoggingT "zenith.log" $ + prepareTxV2 + pool + "localhost" + 18232 + TestNet + (toSqlKey 1) + 3001372 + 0.005 + (fromJust uaRead) + "Sending memo to orchard" + None + tx `shouldBe` + Left + (PrivacyPolicyError + "Receiver not compatible with privacy policy") + it "To Transparent" $ do + let uaRead = parseAddress "tmAmSa4AauSFuJieeanRBjkfnah45ysGtgZ" + case uaRead of + Nothing -> assertFailure "wrong address" + Just ua -> do + pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db" + tx <- + runFileLoggingT "zenith.log" $ + prepareTxV2 + pool + "localhost" + 18232 + TestNet + (toSqlKey 1) + 3001372 + 0.005 + (fromJust uaRead) + "" + None + case tx of + Left e -> assertFailure $ show e + Right h -> h `shouldNotBe` (hexString "deadbeef") diff --git a/zcash-haskell b/zcash-haskell index 1229602..003293c 160000 --- a/zcash-haskell +++ b/zcash-haskell @@ -1 +1 @@ -Subproject commit 12296026a0ebb9a5afe0904b251c5d31080eab18 +Subproject commit 003293cc3f978c146824d0695c5c458cf2cc9bb5