diff --git a/librustzcash-wrapper/src/lib.rs b/librustzcash-wrapper/src/lib.rs index 81f7235..3a59f00 100644 --- a/librustzcash-wrapper/src/lib.rs +++ b/librustzcash-wrapper/src/lib.rs @@ -1179,23 +1179,37 @@ pub extern "C" fn rust_wrapper_read_sapling_commitment_tree( ){ let tree_in: Vec = marshall_from_haskell_var(tree, tree_len, RW); let tree_reader = Cursor::new(tree_in); - let mut ct: CommitmentTree = read_commitment_tree(tree_reader).unwrap(); - - let node_in: Vec = marshall_from_haskell_var(node, node_len, RW); - let n = Node::from_cmu(&SaplingNoteCommitment::from_bytes(&to_array(node_in)).unwrap()); - ct.append(n); - let mut out_bytes: Vec = Vec::new(); - let result = write_commitment_tree(&ct, &mut out_bytes ); - match result { - Ok(()) => { - let h = Hhex { bytes: out_bytes}; - marshall_to_haskell_var(&h, out, out_len, RW); + let mut ct = read_commitment_tree::>, SAPLING_DEPTH>(tree_reader); + match ct { + Ok(mut comm_tree) => { + let node_in: Vec = marshall_from_haskell_var(node, node_len, RW); + let sap_note_comm = SaplingNoteCommitment::from_bytes(&to_array(node_in)); + if sap_note_comm.is_some().into() { + let n = Node::from_cmu(&sap_note_comm.unwrap()); + comm_tree.append(n); + let mut out_bytes: Vec = Vec::new(); + let result = write_commitment_tree(&comm_tree, &mut out_bytes ); + match result { + Ok(()) => { + let h = Hhex { bytes: out_bytes}; + marshall_to_haskell_var(&h, out, out_len, RW); + }, + Err(_e) => { + let h0 = Hhex { bytes: vec![0]}; + marshall_to_haskell_var(&h0, out, out_len, RW); + } + } + } else { + let h0 = Hhex { bytes: vec![0]}; + marshall_to_haskell_var(&h0, out, out_len, RW); + } }, Err(_e) => { let h0 = Hhex { bytes: vec![0]}; marshall_to_haskell_var(&h0, out, out_len, RW); } } + } #[no_mangle] diff --git a/src/ZcashHaskell/Sapling.hs b/src/ZcashHaskell/Sapling.hs index a108eaa..52f8689 100644 --- a/src/ZcashHaskell/Sapling.hs +++ b/src/ZcashHaskell/Sapling.hs @@ -133,8 +133,8 @@ decodeSaplingOutputEsk key out znet scope pos = rustWrapperSaplingDecodeEsk (getBytes key) (serializeShieldedOutput out) - (znet == MainNet) (scope == External) + (znet == MainNet) (fromIntegral pos) -- | Attempts to obtain a sapling SpendingKey using a HDSeed diff --git a/test/Spec.hs b/test/Spec.hs index 3f66d1d..df54d4f 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -47,6 +47,7 @@ import ZcashHaskell.Keys (generateWalletSeedPhrase, getWalletSeed) import ZcashHaskell.Orchard import ZcashHaskell.Sapling ( decodeSaplingOutput + , decodeSaplingOutputEsk , genSaplingInternalAddress , genSaplingPaymentAddress , genSaplingSpendingKey @@ -911,6 +912,42 @@ main = do t_rec u (ta_receiver <$> decodeTransparentAddress (E.encodeUtf8 tAdd)) `shouldBe` t_rec u + describe "Decode Sapling Output with spending key" $ do + let tree = + SaplingCommitmentTree $ + hexString + "01fef9aa4cfdc8c26eb2693907e96eccaacd61ed04ed7860f1d83260e6e383b936001001bdd6575663c970df26d8eb84b0be6411f65337912c90b1a0a8ba2b9303326d350000000000012f4f72c03f8c937a94919a01a07f21165cc8394295291cb888ca91ed003810390107114fe4bb4cd08b47f6ae47477c182d5da9fe5c189061808c1091e9bf3b4524000001447d6b9100cddd5f80c8cf4ddee2b87eba053bd987465aec2293bd0514e68b0d015f6c95e75f4601a0a31670a7deb970fc8988c611685161d2e1629d0a1a0ebd07015f8b9205e0514fa235d75c150b87e23866b882b39786852d1ab42aab11d31a4a0117ddeb3a5f8d2f6b2d0a07f28f01ab25e03a05a9319275bb86d72fcaef6fc01501f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39" + let sk = + SaplingSpendingKey + "\ETX\189\201\190\128\NUL\NUL\NUL\128$q\CAN+P\196\229VM\129:+\SI\171W\248)\216\196\215\141\229\239\141*Y\175}\253\232s\156(K\179\GS\139\232\246\ETB\181`l\226i\156\211#\tdNT\248\138i\220\136\209>U\150cl\f+\201i\132\250\220\208\137\178\196\238\141\\,\208\194*\245\145b\FS\244\164\230\194C`\ACK\140\220\194\ACK\190\224u\FS\167CK\181\DC2\r\US\152\237\238\137\209S\238\240D'\248 \255\164F\254)n\a\231r\128!\177\168\210\141\234\STX5\189\b=\191\ETX:\USgvB\155 \162\234\200\DC1$z\252\177C+\252" + let so1 = + ShieldedOutput + (hexString + "c84c0f8f7de5248ce38861de909f90eec765603c590c3b6c95c56efabe43748e") + (hexString + "58f8ee8f4246f6a90f2e3d49d2ecbb116b9cde55ff4c7682b78d10bb510c43fa") + (hexString + "bf2dda6cd8ea626bfef2b8ba806227147b5649b2d814d02a07f6c72b8e2522d3") + (hexString + "1264a89d07964845acb2ac5f9187f01f3980f0edfcee5f4082ad30f0c9512766063a55974c876cfb1b2115cbd46d9d49a3929ba42f4f9ba5ab15ddb106376a24786ba6631860f1e04df72a8a9dde04fb9128d453436f34eb560f52629deded87d46f0a6355da1070f14a0ea10fcae274bbc1b3f190858eb32ef47cf4fbca4d86fabe737ca1291f40979b6cda84bb43231598363ac9fc3d9af0d74a0a0797eb0dacc6dbd2687f3c8cd92468d39915edf9e45161ed10d78e17b629c5d5c73a09ff737fb370ce80a710bc97c391936223e926563f0ba27ec983c09477e23f8c288e35c57da1ce05ab740dd2d7afc800257c17276e4b9970f08288623c506275e0b0c8d5f60aab32974c24164d1b547e756218acf68849eea30480f529c8c05e62a65c9d070285b46c4a477ca5df220c696364523cc5d6db9ca852b1eb036846b537f4b566913660ad8b83d9c72daeb45274a55032cab9a3e0b3a1e386829dd10c6ba01dbc393843d67c553d74be7969b1879bf0a2ce05f108159a0df47f279b490d5a45ca1d90ff1a61650c6ae87611746d35f8410b39f2301a1be54711d58243cbc3afa29df2a7be5565cff1cad0bd34c370c345b2f38ac7020ac79f9d6c9eeaf2c7165acade98faf18a4e1b55a4e2a18a6dd4790057008ad40c51b0967b87a8d54cde958801ef98ae4a6c9f0e94f5c02a498a9173780b5b0790c248241125fe762c4697a320f1d08d782029c4fcb34fc8580c8c9885ba8339c5693170c157d1ebc663cdccd0a4bf6e77bdc3026252696ae0317ff7a3d9c190476e4605128e50eb42d3d5d8") + (hexString + "6459d6fe8c22e5482822b61f0bcbfbc28374ed93ccbe97e3af400265f02ea525a8c4853dba3d667d7502e914f99ab5062f81fe1c699663694944c8a2fe4679a6866d1d3fc07acf31041881dad5faa083") + (hexString + "85f51c5880265fe6f6bbd7961cfb9c8ceb8d1f5e1a99f7bc606585136c18d2eb3b9222576614c7092ff47d32696b50faa67c0170a2b3212a32f7bd79daa69a84fe2ef3b62081d78418d0a5902dc65d9442f1824366d8906d514ff1db6bfcb39202257e9e523cea9c311c0d4c13efc6fe6bea7dbd0c1c9ad39594ebca64586701a2384d40e62198cf379ecf21ddd8522e98a447f1c0f79e03abd232da7c8b9c39260a21097eedff86744445c7785ba0251fea0572d5ec7f78134c75fd03fc3d62") + it "Sap output 1" $ do + let pos + --getSaplingNotePosition <$> + = + updateSaplingCommitmentTree + tree + (fromText + "58f8ee8f4246f6a90f2e3d49d2ecbb116b9cde55ff4c7682b78d10bb510c43fa") + pos `shouldNotBe` Nothing + {-case pos of-} + {-Nothing -> assertFailure "couldn't get note position"-} + {-Just p -> do-} + {-let dn = decodeSaplingOutputEsk sk so1 TestNet External p-} + {-dn `shouldNotBe` Nothing-} -- | Properties prop_PhraseLength :: Property