RPC Server #103
5 changed files with 226 additions and 27 deletions
22
CHANGELOG.md
22
CHANGELOG.md
|
@ -10,16 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- RPC module
|
- RPC module
|
||||||
- OpenRPC specification
|
- OpenRPC specification
|
||||||
- `listwallets` RPC method
|
- `listwallets` RPC method
|
||||||
- `listaccounts` RPC method
|
- `listaccounts` RPC method
|
||||||
- `listaddresses` RPC method
|
- `listaddresses` RPC method
|
||||||
- `listreceived` RPC method
|
- `listreceived` RPC method
|
||||||
- `getbalance` RPC method
|
- `getbalance` RPC method
|
||||||
- `getnewwallet` RPC method
|
- `getnewwallet` RPC method
|
||||||
- `getnewaccount` RPC method
|
- `getnewaccount` RPC method
|
||||||
- `getnewaddress` RPC method
|
- `getnewaddress` RPC method
|
||||||
- `getoperationstatus` RPC method
|
- `getoperationstatus` RPC method
|
||||||
|
- Function `prepareTxV2` implementing `PrivacyPolicy`
|
||||||
|
|
||||||
### Changed
|
### 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
|
- Block tracking for chain re-org detection
|
||||||
- Refactored `ZcashPool`
|
- Refactored `ZcashPool`
|
||||||
|
|
||||||
|
|
||||||
## [0.6.0.0-beta]
|
## [0.6.0.0-beta]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -752,7 +752,11 @@ scanZebra dbP zHost zPort b eChan znet = do
|
||||||
logDebugN $
|
logDebugN $
|
||||||
"dbBlock: " <>
|
"dbBlock: " <>
|
||||||
T.pack (show dbBlock) <> " chkBlock: " <> T.pack (show chkBlock)
|
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
|
if sb > zgb_blocks bStatus || sb < 1
|
||||||
then do
|
then do
|
||||||
liftIO $ BC.writeBChan eChan $ TickMsg "Invalid starting block for scan"
|
liftIO $ BC.writeBChan eChan $ TickMsg "Invalid starting block for scan"
|
||||||
|
|
|
@ -44,6 +44,7 @@ import ZcashHaskell.Orchard
|
||||||
, encodeUnifiedAddress
|
, encodeUnifiedAddress
|
||||||
, genOrchardReceiver
|
, genOrchardReceiver
|
||||||
, genOrchardSpendingKey
|
, genOrchardSpendingKey
|
||||||
|
, getOrchardFrontier
|
||||||
, getOrchardNotePosition
|
, getOrchardNotePosition
|
||||||
, getOrchardWitness
|
, getOrchardWitness
|
||||||
, isValidUnifiedAddress
|
, isValidUnifiedAddress
|
||||||
|
@ -372,13 +373,16 @@ findOrchardActions config b znet za = do
|
||||||
pool <- runNoLoggingT $ initPool dbPath
|
pool <- runNoLoggingT $ initPool dbPath
|
||||||
tList <- getOrchardActions pool b znet
|
tList <- getOrchardActions pool b znet
|
||||||
trees <- getCommitmentTrees zebraHost zebraPort (b - 1)
|
trees <- getCommitmentTrees zebraHost zebraPort (b - 1)
|
||||||
let sT = OrchardCommitmentTree $ ztiOrchard trees
|
let sT = getOrchardFrontier $ OrchardCommitmentTree $ ztiOrchard trees
|
||||||
decryptNotes sT zn pool tList
|
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)
|
orchNotes <- getWalletOrchNotes pool (entityKey za)
|
||||||
findOrchSpends pool (entityKey za) orchNotes
|
findOrchSpends pool (entityKey za) orchNotes
|
||||||
where
|
where
|
||||||
decryptNotes ::
|
decryptNotes ::
|
||||||
OrchardCommitmentTree
|
OrchardFrontier
|
||||||
-> ZcashNet
|
-> ZcashNet
|
||||||
-> ConnectionPool
|
-> ConnectionPool
|
||||||
-> [(Entity ZcashTransaction, Entity OrchAction)]
|
-> [(Entity ZcashTransaction, Entity OrchAction)]
|
||||||
|
@ -901,7 +905,7 @@ prepareTxV2 pool zebraHost zebraPort zn za bh amt va memo policy = do
|
||||||
None ->
|
None ->
|
||||||
return $
|
return $
|
||||||
Left $
|
Left $
|
||||||
PrivacyPolicyError "Recipient not allowed by privacy policy"
|
PrivacyPolicyError "Receiver not compatible with privacy policy"
|
||||||
_anyOther -> do
|
_anyOther -> do
|
||||||
let chgRcvr =
|
let chgRcvr =
|
||||||
fromJust $
|
fromJust $
|
||||||
|
|
207
test/Spec.hs
207
test/Spec.hs
|
@ -32,6 +32,7 @@ import ZcashHaskell.Types
|
||||||
, SaplingSpendingKey(..)
|
, SaplingSpendingKey(..)
|
||||||
, Scope(..)
|
, Scope(..)
|
||||||
, ShieldedOutput(..)
|
, ShieldedOutput(..)
|
||||||
|
, TxError(..)
|
||||||
, ZcashNet(..)
|
, ZcashNet(..)
|
||||||
)
|
)
|
||||||
import Zenith.Core
|
import Zenith.Core
|
||||||
|
@ -235,15 +236,15 @@ main = do
|
||||||
Just
|
Just
|
||||||
"ztestsapling1tgjr4zppwk4ne8xy6gdq4z2gwq7dmf5jq8z2ctpn8nlmtse0a74fa5z0m8z383gmpgqz6q6duu4"
|
"ztestsapling1tgjr4zppwk4ne8xy6gdq4z2gwq7dmf5jq8z2ctpn8nlmtse0a74fa5z0m8z383gmpgqz6q6duu4"
|
||||||
describe "Notes" $ do
|
describe "Notes" $ do
|
||||||
it "Check Orchard notes" $ do
|
xit "Check Orchard notes" $ do
|
||||||
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
|
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
|
||||||
oNotes <- getWalletUnspentOrchNotes pool (toSqlKey 1)
|
oNotes <- getWalletUnspentOrchNotes pool (toSqlKey 1)
|
||||||
oNotes `shouldBe` []
|
oNotes `shouldBe` []
|
||||||
it "Check Sapling notes" $ do
|
xit "Check Sapling notes" $ do
|
||||||
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
|
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
|
||||||
oNotes <- getWalletUnspentSapNotes pool (toSqlKey 4)
|
oNotes <- getWalletUnspentSapNotes pool (toSqlKey 4)
|
||||||
oNotes `shouldBe` []
|
oNotes `shouldBe` []
|
||||||
it "Check transparent notes" $ do
|
xit "Check transparent notes" $ do
|
||||||
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
|
pool <- runNoLoggingT $ initPool "/home/rav/Zenith/zenith.db"
|
||||||
oNotes <- getWalletUnspentTrNotes pool (toSqlKey 1)
|
oNotes <- getWalletUnspentTrNotes pool (toSqlKey 1)
|
||||||
oNotes `shouldBe` []
|
oNotes `shouldBe` []
|
||||||
|
@ -265,7 +266,7 @@ main = do
|
||||||
18232
|
18232
|
||||||
TestNet
|
TestNet
|
||||||
(toSqlKey 1)
|
(toSqlKey 1)
|
||||||
3001230
|
3001331
|
||||||
0.005
|
0.005
|
||||||
(fromJust uaRead)
|
(fromJust uaRead)
|
||||||
"Sending memo to orchard"
|
"Sending memo to orchard"
|
||||||
|
@ -289,7 +290,7 @@ main = do
|
||||||
18232
|
18232
|
||||||
TestNet
|
TestNet
|
||||||
(toSqlKey 4)
|
(toSqlKey 4)
|
||||||
3001230
|
3001331
|
||||||
0.005
|
0.005
|
||||||
(fromJust uaRead)
|
(fromJust uaRead)
|
||||||
"Sending memo to sapling"
|
"Sending memo to sapling"
|
||||||
|
@ -297,8 +298,30 @@ main = do
|
||||||
case tx of
|
case tx of
|
||||||
Left e -> assertFailure $ show e
|
Left e -> assertFailure $ show e
|
||||||
Right h -> h `shouldNotBe` (hexString "deadbeef")
|
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
|
describe "Medium" $ do
|
||||||
xit "To Orchard" $ do
|
it "To Orchard" $ do
|
||||||
let uaRead =
|
let uaRead =
|
||||||
parseAddress
|
parseAddress
|
||||||
"utest1dl54utt6prjj5e0dnlknwumnxq9hycdjpkfr0sy6e6h522remqee8axe9zax0wsjrwpj76v555pdhvj9rnargpfyycs0vpkapq98xcdhem99gc4wchzn0ggepq3y6nz3a9sscwgqxgsh9vzhcad402y3x9szfregck5gslkya3c79d86xx0l33tpk8gnn7ew9vw37w43zh22u8dgdax"
|
"utest1dl54utt6prjj5e0dnlknwumnxq9hycdjpkfr0sy6e6h522remqee8axe9zax0wsjrwpj76v555pdhvj9rnargpfyycs0vpkapq98xcdhem99gc4wchzn0ggepq3y6nz3a9sscwgqxgsh9vzhcad402y3x9szfregck5gslkya3c79d86xx0l33tpk8gnn7ew9vw37w43zh22u8dgdax"
|
||||||
|
@ -314,7 +337,7 @@ main = do
|
||||||
18232
|
18232
|
||||||
TestNet
|
TestNet
|
||||||
(toSqlKey 1)
|
(toSqlKey 1)
|
||||||
3000789
|
3001372
|
||||||
0.005
|
0.005
|
||||||
(fromJust uaRead)
|
(fromJust uaRead)
|
||||||
"Sending memo to orchard"
|
"Sending memo to orchard"
|
||||||
|
@ -322,7 +345,7 @@ main = do
|
||||||
case tx of
|
case tx of
|
||||||
Left e -> assertFailure $ show e
|
Left e -> assertFailure $ show e
|
||||||
Right h -> h `shouldNotBe` (hexString "deadbeef")
|
Right h -> h `shouldNotBe` (hexString "deadbeef")
|
||||||
xit "To Sapling" $ do
|
it "To Sapling" $ do
|
||||||
let uaRead =
|
let uaRead =
|
||||||
parseAddress
|
parseAddress
|
||||||
"ztestsapling136jp8z89v2jh6kqd5rs4dtvlxym90m43svzdwzxaplyvc5ttzppytpvx80ncllcsqzpmukxjl3y"
|
"ztestsapling136jp8z89v2jh6kqd5rs4dtvlxym90m43svzdwzxaplyvc5ttzppytpvx80ncllcsqzpmukxjl3y"
|
||||||
|
@ -338,7 +361,7 @@ main = do
|
||||||
18232
|
18232
|
||||||
TestNet
|
TestNet
|
||||||
(toSqlKey 1)
|
(toSqlKey 1)
|
||||||
3000789
|
3001372
|
||||||
0.005
|
0.005
|
||||||
(fromJust uaRead)
|
(fromJust uaRead)
|
||||||
"Sending memo to orchard"
|
"Sending memo to orchard"
|
||||||
|
@ -346,3 +369,169 @@ main = do
|
||||||
case tx of
|
case tx of
|
||||||
Left e -> assertFailure $ show e
|
Left e -> assertFailure $ show e
|
||||||
Right h -> h `shouldNotBe` (hexString "deadbeef")
|
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")
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 12296026a0ebb9a5afe0904b251c5d31080eab18
|
Subproject commit 003293cc3f978c146824d0695c5c458cf2cc9bb5
|
Loading…
Reference in a new issue