From 0d0dbf0aa191d44ba75f0d079958893d856b36ac Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Wed, 17 Apr 2024 15:31:06 +0000 Subject: [PATCH 1/4] all commits squashed --- darkside-tests/src/constants.rs | 2 +- zingolib/CHANGELOG.md | 14 +- .../blaze/block_management_reorg_detection.rs | 2 +- .../src/blaze/fetch_taddr_transactions.rs | 2 +- zingolib/src/test_framework.rs | 49 ----- zingolib/src/test_framework/mocks.rs | 167 ++++++++++++------ zingolib/src/wallet.rs | 2 +- zingolib/src/wallet/data.rs | 7 - zingolib/src/wallet/message.rs | 36 +--- zingolib/src/wallet/notes.rs | 64 +++++++ zingolib/src/wallet/notes/sapling.rs | 105 +++++++++++ zingolib/src/wallet/notes/transparent.rs | 68 +++++++ zingolib/src/wallet/transaction_record.rs | 78 +++++++- 13 files changed, 446 insertions(+), 150 deletions(-) diff --git a/darkside-tests/src/constants.rs b/darkside-tests/src/constants.rs index 0af380252..aa2dad778 100644 --- a/darkside-tests/src/constants.rs +++ b/darkside-tests/src/constants.rs @@ -45,7 +45,7 @@ pub const ABANDON_TO_DARKSIDE_SAP_10_000_000_ZAT: &str = "050000800a27a726b4d0d6 pub const ABANDON_TO_DARKSIDE_ORCH_10_000_000_ZAT: &str = "050000800a27a726b4d0d6c2000000003100000000000000025e2dfdbbcc77198acd76db36074eadee7d7a6041c9342071a0b75812d606c39a45bfdcccb9f955457fd703b707fb6eba9a62a9f26a42c0e2cdad4afb33611b24bb2d5886ce67f0f126064892dd8e8754a94687e4f9387bf5097786c142a102171e8dd4f727a23ed8dccfcc19c413079826a706ff0a13b87e70baabfb7528d30ebc563d3fcb28189daa2511a79c2218993e53edfad269c61234a8acfc8fb70e111d6686f3b65394aca6d67bdf80888b827b8314e634b987936e05ba821590115837693a6c95bb96d2356384dc0788f0db1bfd6aa83145208d66c1005bc3952ff8c5401299cc73daeb49ffaa76cb344ae0cbabb43ec507a1580e88c31b93d4781c0546215601678826556449a0db2d3ea2c2e320e070bf8bfba0566aa8414187987545c516891311d2691efd5c29bfa4ac508c23f7ba3c52917dc19c139d56a530120d8470da04d79e0fb57feedd81a99ea26ddc3c7359f880f3d522e1043c1f461a83214f94e038f52b70de534018ad61ef2d07bdfdaacea9bea9b2c4a776ec1e0eef95dbee61b0562a6e9b219040ec2b37649e69cd5b1be332210eb78e43ed606094356a7a14b96c1fa3a3adfb1e6503c6384c04440a1a5175a5c2cc07f69964b438551ac4f8639b70257495fbbe8ad02182f7aa69a5334163f31a4fe4af9948d591005bb9094f2d37b4ade2b099320f304444631a06fa3b1c5ac60c2373132e87449fc45693b69ca30f256f3e5a70d14e4fb889cdfc8fc2e339f578513433b72708fac3585449e69fb14681c1c2998f713b98c4d5c9b807cac6e7d2a8ebabc2943dcaaf73bbe07420bd8c72841fa73898c451489a844dd91ac2f0cdc0bcd1a0e4a37a0849671c72e6af3bf8f6bf29e1d1c7c18a3e7babf7779f082f75e3ddbf20b89ee5972066b4bbc55d36db7d84880c0b440090e208c0b727fe04f0e608cf5637cabe2271b3306e0a79f845d63a6e59355eb5b673fb6f50a477095ea06229736536a67434480d9c4c35945994d5738f5d84ff960d690d88022b69a4069cf6e7ef067279baf4d92683f42def069991403d915c0d803a72aa4fbf352143f8d6b4c00741ad865a73a0b1422493d3efe64303d08f554f92c5f9b3de6fd443fa14c474011bca58bb95f2fbf5bb94ee7563292e5fcab5bdb4da1e75bd780c859aeed13b65c2b34df5c11e500685707289cfab9f620c43c0f6878d90d4c7bc92a05998d944c644cde8c4eb5f848a2600d8c83c67ee02fd5477cf9774bc42d5488b7b623a429bb1f4638b03c9276c42e96ceb9876a58ab78caf7ad715ffc32074a8c43333650d6a711eae0cf39bddd8df35720e8c031a159901a0b7018f4b109e0ebaf47c791eaafe955883b04000764c14c27840571d3fec6a244f9066fbeec887d2f5b8fbafd5a5139f72c417ca728d7c2b2c27e9b692e0e41707be7a66f2e1eef1259ea514aa513cdc7274d71b697fd2c64e36450fd3db7302fe8dd55d941f3787d1c954686bbf64845f3f5a607442963b46bd206754c7d808665a177f00b330adee0276ed1d91f0d8f317e3f10fc300d93b521f83383d6757691e233017054c797b4a84155430995d71481a0b05eb5dad85e6c1e3c730023191c32de67b12f570b2b61ad207f4c632509ba8b4da99fe29397dc5925f3ff47563b6d93c6410e1294f85f0d33b7df63591a3f61be9311c98a983b4570f9b30d845e6a705c63ebbdadce209288053f70599dbbb204cfaa3d6452808b206a2ee90f7c16bfb85d98d4dfdf56b4a795e343a17cef4a9209e4ba5617c3663061e253bfa301ddff35afe8f5c940893201ca4aaaa86e2ee1a06119355e169f21dd78ad0a99e2fe0eb2a7d3627316190679b127994cd133ce78aef7f3b78366cf2d67591ad7989f9749ab5250557f3d184cef0e7220aa69d299573602bc8055d1e8ed3c32a15e99c066bb566f7bb02e49e6d095987c4e69db76b703c44accae1176ff7400642a39c4a6b16a01e8f1878a4c9b3cd4fcd6f986152bd76c520cc8ec94434dd40b46a84a3afb3e245373efda6ab8249d4b2adfbe4b7df79e52e447e29e0ad89c1e4c3a3e3e81f96f5e5356f938417b072ac48f64cea7ecc571aaa95f2a1853e93388ca9852bd789d9ae5f9a5e2d8d7935752639e39d85e259a7f7dd2de904f759778fd0891aea091f33bbc0e0946e3690ff03bcdebe08dcb12038f3329307402e22b619e505f6c211ef2fd5f90ffb487248f98b923ccb2fba94724c4cb5d01620dd410ae3c6ea0b0664ba417dfb4efc60814ae6371376882c8be563c135086876bd007e3403e53aa45a0f1b12350be00310270000000000007912dcda1ae864fdf0c2079069ce82c7e3b74a3a20d2abefb04e6b0f281e5527fd601c17ed97bcb58262e034133c505a18cab8e317fafa4c618c1b5f72880395df7bb2c0063f224297db2295faed73bd77afdd2df93e18f0e0922e4a80060dc800931c64873120aa99fb0b20cb03724f562d1424add842503864d3b7ac919f9f4eb78a0b805f3291083f10310c3f754c7ae3fe445ba815693fe883290821b4b967db15918b581c5d213a342aa4e8215d53a2889b1fcd7d042ee3c1453d89d75ac3afb08cf6378521f30c4bd2c065e493d20340b73ff5cc8d1f11f947942ad27bee4ea530464197e9e1112fb096ba50287b92f390a9da6a1b7143745e260e478c536308a689a86fac8718527b91f28d8e4e62cba2186c700a74b7d8f79564dac6874ba0c0bca207ae4602ea9b267d977bbe70e569bd88ab1a0e96d9aff3038895bbd98e57c88adbc5cfea6a899dbfbd43b22c27b2fb12b8e7842a9112849bc26de4b903e078c8f99b5cb84e469e6686e3da4b38b2aa5729c55aa1bdd2ba775b37320308792c484c2ec4e2d24db87fa9744a28ea586b7d9bb18860640d900bc2f41a6e273f7c2426277eaeba5bf4a0de16ce5bb4d63a54b83004d885f096cb60d834e989f25f0d221b1852461bb3eebf09439c565315815c61683040856b1bf1e5d933045d1e78df93de69a878c4be5576040bec6ea8da76f2fb232af9b12f1dcc56b9bb16499f119d260dcd1eba2eca94f5bd48d5c7261fec5e9a48fbc286e251f81a0b0a2c52729bf2d1f49dd2e1ff1eee91f6a8f82f5749129371706ad7e348de73a710480bbed25dcfd4db0be314de37e99d740950e1490fb5d5a2008473dfb01705f34abd7e9602b3c18be01a8cca05be926185a850e6b1a20eb4df74b65c6ef7918a829e151c6c68305fedc6504a55b1fc569179a4967bdc88632ba8e47066d99fb56989ff59e4cb98828b63956f562ce3cb3e8a5886a7c90ea6ea627c6c715fa30b2770d954494b949607b43741793fbd4ee27069f009413e8dbd5626eabc248d3311ddc1c1b539493a7c53462e2f09712e02710d35bb674b6924536e8d3480bce230244a84166ed6e26b87d616a5a47868b3b583463b9feff2116ec7c032e6adbee726e43dbb07881ea8905e304a0da6dc98a8c884210059837567f862c7a4bafdd71dce2c52adfff189e88c9ca532468601c4ddfde2d62ddab1d783379ad29c317492921f4fe348bc70054d080830464e2f2878c810e7603bd22294de40f28aee0bb0df1f2ce4ec461d1b02f6018ac4e438fad9f5365defb7e72a17fbe9589ed94ef01220b71854f829037217d996a708d0addbf8645b8b4ecc4112867bae8244a4ffb4fdc6186b2ceb4989317c894f5cbc30db722d7d7845f5d815d759a39b5b3bcfef9d471918a46639ce3aef3f72f55bd6d32aec54629f55409e06b5d21cb79573471a9c6cb71bc2197d88fe9d5bda89eb228c9b1ec918a61ef616637116cbb825b23285a25ebda4ec1e14554c3367505d5645671bf186266c5c1aa0a1adf493ccba80215f33939f1b0f1b3a4cd0a1eb7b6b0513b362c7cd9c07893d873d4d85f74f33c94097e454a27c8452fbc7ac0ac0ea90ed855b292e0934ef5342900f14608924f8e80e7c11a36dd67e61a05fbd2c5fc9aafa7089359e1d8a5f77ada4bb977919641c78d66346bd6c509f5011e7ac4d37eccc9205e2212fc0eac296eb7e64d385679b494a1b716cb5861bd7acd265de6ebb0cf71e128ac565bd0aba16ce1e6aa1ef7ab800b865d759c7959b8df2f11730c2eaf446c33d14860ccfa3df98184e90599de29e4d38259da9a30a07d95d8cd1d2581520345312c27ceb1e7d51824ccdc4f66f960c9963f95b805c4eddbc1b28095378451eb51a1745dc8f71ebed142d737069abe59cc8dd33540550e650dc9526f42a88438133e59043bc993caadf14e47c5882732e023c53c709564d54b8422d857e4cd52e573d29f7321be77466ba127f4580d2f82a3bbea114d0b75dc38b11c1ba08b6cb75206ef7a5cbe140cc04a41aded912d8a735141ef380407052f7911665b5e5b0c70838ec004b22e6c3bd4b2074c53312e1059a6a20829ca342421a8a1076a00a272ed7f708e55323af0dc5c2fba96b059ed9ccf60a98616596033a99b55758a6ab50c93532d055ef33f9b04d38d6e1c1ec1ba4da7373ec91df1311ced847f446ee2e4b6e254d9ba00f3ec1d5a7d38ba869b9b1e30ea3df23031ceb45348496eecadd40d3a48b13f4954060cfec0f21164cd8e2273caebf77c808f85fc4672e01dd3a920c38e30be34fe3d34fe04f7168a1f8f417d2ba3091a77d62d5427e5267923ea203a4b165d8ef8b6ac6be00d0c8a656a7c790a5ba19da96acfff02aca8c93e71ff614174b850ebd0ad8714c572bab2998a80074892927abf24821d43d62f147a2873061e752a309cfda014b83c93de217a1e25503f993fbbd47c6ae2bc26110718c2da5d42d77cf4aae5ec632bd3d345cf3abcfe89904e5ea7870572829e41ade22232e97c3f6f46d54fb13d8815f65e2cd62fe851eaa23fec221eaa3c77021b4d106be8f4ed6ec69b4965b11356bde2819240465980721a0090971a4681720159f1afbe0d5868964884b874cf58e1e993d359cd913e836d57696c13760b23b8c9c106243c25aa20f497fcd106218f81e46525037fff3b626c7c6508d11c02e2fb42d53a9aec8f2737abb08f155d5a52c879724403cda822220625ac2c08e6558dc214361b6b5bdf04b5b5663fd326803666e0531e3c6ff80492e67728df1e14e942755c71781635ed07c2fdce68849ea40f8f7c5bf3d177a5c2f3834760fa77eb8323ee9fcaa7b3b64327b2bb06dda57e567b41819dacfc9edb563cee8de6643681eb25b08c32b4695dfe059a0f8d1cbfc1df5019d64161102e27be6dae0af9af11f622e455c6bc53369c7b26f170c5b8c4baffc65226583d0c2e5bf3ec51bf60937499fbbf2f67d82d3391428480a33eb4b580c5d3d6e04c3e82450dd5255c3e1369f6b6ff9431b916b87b07a9e913893cb84d20ee8776c0bce0aab15596f3d0304f05c57e03743bc03bf53c110a8d1bd13174ed6d7ad7025f27a3f22fdac3755215b3cc4b2f90c9196eaa1f313648dbdffb8706aed372800a123f304f58421852241cf83c5adbc6f96b1034d0631c8d9fe0dff98a0e5dd87e05539d9e1d6749c21bbd47be5d304da338e6cca3a440119a0a1d18fb4d20a90070b1e3609747d3b33174bc19e06df0ef73a75022e09316cc8b123dc395dfb4f3f18fb0e3b4ea30137b8786e54909e0230f1c7672b62544c9578298df3380decbfbe58228b4fb7133c5d30d2c93b98c5bce3847ac8ee47d64d7cf2cea5771d6ec56251d57f20dd6202a7da4f63fac34e257c2da4cc1ac215e47da670dee7f25f7ce9216f42fb83ba2b075972aa7f26dc560c61108165e81762317d2d209cbd8e3ba7664f5fd6d4450f33751343e0d33c4697f9bd39c138780c97f0e5cc9ba2af6011fbe38462c70d3763489b31340f34f7aecd335328edb04fbf617379fd64d8fc202d031690c88a24de77ba82874459d343f89155b799438224aedfd01971a54b534220dd7ec1ef19a70a7960204bf96fdfaf3c29eac703406e52893f71fc0c1db1931895ba4d4104a4e580e0e1dede68b164b4a54aac19b27c005c23955e774fca19b617a4850230babd2fb531dd3ea506d06a30d15317dfe16a046ce6b78037731d9513d0e32c338db9431c222721720c9687f8433dab20b76e2bfc6e48f2412f3675d369198528b2d3fa6e80407ec9f118791303a00316fb75a1b13d836428e7725752f16b410a64dc6fc35073f841e6d5692488be9ee8e1c860e4b5692f50434951538f60520be7fecae789b2881eb4b7b15e175d151dc187445e5d18dedb96c1c9b1f55a852e4ad719cae2017b6d5d8eb24cafaa075e0773176f5bf9c94762e945b346d9740d9bf6ced4193f1ec0b2ae8ad95d94a0b6274a4fe712809ae163884e5e8b10002813271dc58a277a44d323a6d7d043f59a776dcc524ccff20def16419e187f272c2b565d5242da67fddff9ab4b1c2e79ba634e141c3dddd9d9f855cee05b17650a439f419605374bc72056ae9c43d0bacc2a90b66725f46125955fbcfc32472f16c36dc78032d83e17e2beb53fd78f44f0863ab5b9526c7fb394497f2f83b71e0aca61e03fe36a4eb193b821b43f3981ec996fb1133dbd97d52697236af2b483261e769a4cec4d4116a355c7450c3e47462f3c19e015ea161b8332247fdfad72308039a9187f5862de73efe749b07b52605a3f5c0ea2f960f1be083107afb4ea01ca7e177e8d8deb030a8cd204bf6de3ae45f65ec4ff3e8bc11b98238e95bd03055a7574f91bc1d1f0d03f0786f78aa99388849165fab900ed33947f3c2e7f411348777f50e402ecc0790b8036b63277ef534096ec5be6bd00a9d2845f1e015e14671a154e072e1a711db29a20309b41c6af5e788232587b20e8f8cba013accb2f330cd1f61e7efe27c76d723bb6c06f6df26eaea2cf4734da1089d23f71c84a2d6e6aee4649dc789f7c3135a3750ad7deac11537a06a25e0dce16e02cfc0da60dd6b9e5b8a2c8cc497367163d0b3919ac38f2ec82756989231c2b9c2a3cd6af05deca06d69880b3ce740a22564ce81b26fd8e30efc8eec3d4acfab4d8340ec311efc4b11fb87ca521cb661e60289f1c9a19899e134c0fd66db981d258c66fe401ce40cbce0ec35ff3246c9ebf12ced1c9bb72e9f8a58b406e803c4aec2ca3fa14290e0ed4c5c78f7fb589b11d20a3f9fd4db950bf8458939d1f6529bbbc8820278b7ff13973fb137b61b1c92704ff610b94d4df3810792d2247a8efc652ec4527b57a9e998c6657982af78d552c6a3b9aceb395050d8129f023e73f93d76e9b02c91faf40a002ecbb2fbab6d480e689e2be1a9bb2ad8fa244bcd7bf7c03bfac33d5a5a527c34be8aed42eacd3c29df01a269bd9383e234fc6c9aa32099cbda93fcec092abbd9da9990ae56c6f37da6f9772c46954bac9470f79a35b8958a44b03112e5c9b64ca039b52aed2e8313f74d0a7be43eb3bb4a25c579f4fb95abe201de387db8cd6cf0a142942512b926d15447711b640f730e93ff2599cc109248c3294618ae55f50a1f5d239bb18e054cd81c686dbb915357356afafc1f877e9720ce2ea1ba232ccd846bea8dc39cb1bd06eae1d343849474d11034e96538d60ad3b5aa469ca44c292ef3ca1d5bec0460e8c1ff2f8e544d37e9e17c36162f5e850244c5fc3bc14ccb0a2db041b99c8e4b429308168768debb3f672a075d4c4b1133196402b44e53d33be0538a97a01005898fd228cba98f33eca236f75e3884c313caca7a1146c1add104b0553d53a95f4bef1ba07ab65ab9e13672137f4ed149731b1bdb3f64e35e4e6a35b59d93887edfaa7a2689076fee7c1eb332ca9060059206b185fcf5fe90e76c9c57f66b9df124bb12f54309bf8dc086456ac4eb5e07519badc3545dc972c1d02c478aabd89b7ce7ff5a7a4df043bdf9b1fc194908d3e196c2769abce40b0741ba28c9df1da1ba464e12c0c01a548ed8dd397976c2c903a3715c7cb669a86d7867d8241e61955948e63aacfcb97247a3e46a6b263ff911a69cd4bd47ae3a211f93ee3ebe276ab153af34ab4276e81659f3af305d8ec17176765360c5d1d97dcacaec558f66fca40523d42cf56550f43539e3fb5dd496d25eccf4bc1226986c20b37829d1ef08ac7f6b14ae0f843e0d03995452713dd292602f9e2cb213bc86f7e6066551849a7471c8b91507b5ce1fc0cf8e6813c5e320e29724db2f594bab4c9c62e439dc467eca7bc83c6095501959be7e8ba8c28e71333e7f30deb2fda72aa56eca169839d3f4c0deb77cdbef0c5e1c24d151c3e470b23d37611871e426222d9d5fc022c6d9a048ea50192712300427311c0e484d1156344d9ef9fc4517bddc637e713458cf91aae174ebe9265271587a69a32f4e81280c795bc13e701746073d60fdcdf6705c2563484b3e35993403f4731043ca41214eb82e27de36e41a5385203b3446a4bfb0e7b272bfa92d116400570c7778820e02540288918f39f6acccd0bd3eddfea73308aca3530109c6ac30dfefec2bf1dd705cf8a1e6dc24508d14329f63c61cbfa8ffe368c0518c398c8ae83b8cd2f00333e08b90a6d7334ae7b5d5a0cdc95c9ffd8ea26f0e6b67f24a1bfeaf3d0a32b96f4a85de8f11d686c87dc6fec5a0ce395670b966395243b0ff739f69159ae0735c8fd32669e261af604318a5768b34f2644cbd881755203d8d801654eae1025d899655673b6844f34c4b90dc8c0b759465a1f00f708404693ac5f063c939c0da785f48c606e994ff3ae4da8858d903e2704718c0d1d6bbbe23cb3460961540dc0dba312d183c3665a30ba2f932ec5bc11590975e3f6c4f3dd83a6f881729534f536c531f571b67038fc624e1aa2ba2aa23f9d6e3b86d29af4d840176b2c0c14bbd3162fc488b9349fa33fd15b604877bfb151a93e270ec2558d062e92eabc2e6664fcc343b628ce428f3de788bf7d8f7e4ac74d6cee764f2f82a65cd31881313a0f50e59ade83b3475604bce15d56ea7d323d8afbbfda0f1402c6b0de11d43e8c6f12756f74a56f221976debbbfc4697da7cd039c7da98d4574a3bf992bff24ae02e1eb7dee60c403f325eb239bac6f289b5083cd5728244c9a49b536851101f66eca3f113249e98867008e05a13aff1822892a5398d0b1892310a0ef4c253c2363e385d009e9306f381ba0deccfe8fa61b78d78c2760381a9e6cceacbd44194a9b6fa31a8f6e70637c50fe002e0e4c15a663b4357bd9f612814ad446f2ae0a83b6b77c149e2980d937cc005233f4c5b918ca491567aaae7f0ffaa33434c809a9d3c0912f00c2af75dcd7f7dcf53fd218c42ef9d3b4dfb78c81c0c5ffb920084321f3f84446bf07ed2de3e8bcc43d3059e52f2c431cedc75ca6cbc7b816513c8af7dea2ff56e9affee13775979c000eb476a5efe81f96709b5fb63f98e41e3298af8e756836d85d3a325e3e7082b008af5fee1d973665070a0cf3364bd6cc0bec5b692c05f8e8571c736480496dd14c2c4c604707caea0e1aa5779fead3ab033ccf0594e2176b697adfd8b9ee30fed7b067ebf74e033cd7e7fec76ca3d7fe2587e4129ca591a9c5111b5e5d7253e66f766d2f6d90860a0771ddd367614c293f16bbcc235eb8888bd2f1884415b5efb90fbf5ec7db2b1ed16672f74d4e2d4c2364c9ee117d082b61665765df2f1a3fd654721047364b60785681aa5259eff2274bf77569f37876e6e4c783acd49f242c05b48188aeb88da212403b13a11e372d80cab45cc53db67bedbfba7309bfaa7738b1b31a14eb6eff582e4bf8322e790f024456cfa33249aa3f6a259b7b4984c98ef22d5921e60eec109c8e70d9ac5a086fe46a7d4d6f1d6b84eced63366d875540c6bbab53490a6229ad187fa7e2193843c26b250ce42dbf746515e9eb02de31fdf3a983d4151e40516c0b70968e4f2a9f9933fce02cf72ad3e895cdcd8afb5ad7d93acf9fe08bccc4773aa8884d9317f0ce3dd24240f2e4b8d49af8e6c26a61114f6bfef5b592e87e6ee892e7545b2c51e2d4cb0bad788e692ffdd75059b6efbf7f90cbdaf28f7374e7991046fc5c0b22cf22a76590d60133d36376e486a6af42787de6c7ab833b293b62c84876b72ed3db13d76a608709ab4057dabbd3683adfc8737aafc2647037de73502e6eea1dae7eb1d56cec0fbee465012eb4e6e32c6ef720512821104a997bf01819975334426f6ab94d8d7b3f8ff8e4ca9fb8d9e100f4f97bade1f408ef5793f83882d9309a5d8b5cec78ad4a2f91878f542fe5880523266cb1dfa8802505fc5f5b17162f30f679e38aa89d9ac8c0500bdd8b2846abb09fa80492da8ec36316139880cb2d0a21dd730e14504175340358f88d63866222bcc0cd3a2610360872a0d81e0539bcd9fb66bf7fdd7f73107bcccfafc12d78e2c16fa5485eea2b8d308a67e8a401b29935c436e632b82839cb90ecf95a172e115af85917a08dda7d37bf02988e252765e3056ca90074476149bcd66fa459acefecb0793dbadb73b465871f012215774793ec79e886785da2e49cc4349a2876606918cb7ab4822004ad698e69550c8dd1714f062d1ef7b2c382eaef9ed0b5b4fbb7091c4f541f3c6eb2e0d1b23d2e09e3eb467a798ae388109d3f3e6e93fd45741d15f6eaeeb2b80a8a331b67f81f8254dca993aec558feaea9912ae34c725ea8ef533dcd1d5e01738297255d35259694a497842e736841741f5d4e4178b368bf616ac3b943e3d5cb53ef8950821d830fe2b0d34af2786ad65aff4cd99a52806eba0e9adeebf8e185ae630f70c43462a596e4b1cc70c809b000cc17ba8322c382e77a7f17e30ced1f36a276837816c269ff60268aac31e8203bebfde58fb7d0d7869cc04e63940916f7370d3dcb27b961f7be1a23036cbbbd7867860a6f4474a93db1e1d1634a7e94a0050cce170ab1df1b7077c9e90427e730f21d672495e43426efb3e09027c2d29994f81179000f8ecf1c61a8eec149f2492923e81565af8a922ef4717da25fbb188249bc253af9c2206fb5ac9f86c80eef842741432255a2e72467ef67312448f67264a987256fa3f3098654bad8e8c188d7a527976cde89bd5c5f72667abb4f7f04c08286230b6515d57678c70b42147b2b2aa3852a7673a5d1ae7271309421bcd1d4c53d099ae5f857e0b7a41e30eacd366c84586fa67325cc7c145c1b7769648f97c371201792d416ad068e198bf28a27e29d156810c33092b7beaf90c52d174181998d1cddbc8ccbfafb7cb74713b0b338879eb1d6c912a092ccbb8cdb7c14a5343bc52672d33fee29a9b8a5ea31617939d628eb2563840cc873c96f5bc070b893b2f2194c28f1c790e7e9ccf23b5a7668ea5ccc60cb3d056569487732c13d76450f793d68737ab393f972a27c55af2f69ce4b34c3fd9aacb7dab82710bb9a8f30916c05acdc661e3300f98d7581070cbfd195b26ab281977e7fdff7d1009b16223ab720cc3cbc16f528ac3019b55b12fa225126dee248f4320e85c34b912677dabc393c148ece1dc274e3cd9615426b5ab2da6e2188916587736c0130545db26e8e973652b2820c1eb6fcf208510da84b9ce223595737ea0e84b9ee6be56d7fd0b38402de56092f5fcfc39ee7f7aae0bb82ad2ba329b2a0e5294f521ed236573a706799a65d25b74f3319c90d963f5044a97f9a0fa5837505cfd0b5dfc8811570658c0efa95934a2f1b5507f2d607573d8c3e24fab7c3f774cb458e9a1e5763a65fdb0b6cc734f631d615cff84bc878069d258e36b0296e1bb2aeae8c22ff16feb75736b5c909d4d95a15253d52a218e92ad0f5387deeaea3f8ddbf58c53b5bb33abf08ec4322acd3308c57afba0ce568bf6f243851f7cb6a3a0c8b51dbdb038c4a739ebcd1eef339cf1f3cfe28a7b19c93ead400956fe6ba604410cd4acd6090dfbab7b8f94e66f1a967b84a313df0605fc90146af4ea2a0125a3fa7273b8f1dc8bd85b3b64a1abdc27c41d8f2576a54f2284c847e6feb755e8fba09dc3174eee5e01a182c2168386b4aab0c7a5333fbf6d80001394344b0555614563f6d40f3ff2836410a6cb31b9510649bf46a05a43899001d70a8d0c390db13161fd8409f71a69cf4f3011065b487ef7e01468b1ae69a81512bd3f7f5032e4b4d2c71bf3626c61d0119ed596020e74222c67876371a23abb95842436f4382673c3701c19fe11a00c861357583c69b86aeecda6173d75551e47d21221bb4339bc29212d7def07388093a99d1255b9175075d83863d650ca4f0b2e042f904205a0436c58c5e532c9e05ab85a1b76d5b85159c9063c2ab7427a4d8c3f64f0644553f3899ed4eab53a29677812b40d8203db0b59ae5f1b56dab5c9b526989c868007cb7bb949459d826954ede52867b0a95f1cc14fba8fa83bbb592644c48187dca40236bee196e70979133998e993ecc681d47327b904af8fc7367de3eae30cd4d6d7fa46e9da9d31cfc4fcde7d53166e23d8b7aecec7db4306d9d77e0c1ee4d68ccaa18c8ad8c8a98888de3018b04e79b35eb070e28f16f807497d5821349db8594b427c32714531111e2ab612ce858dfdda1ba9b1487558eb9f09cb44afac0609944fc5e2114c3a0428f197378fde144de84fd1d9dc1758aa165bd64f3cdbcc138cc91244a3f8a054729ff42c9915c29c25b4bf1f585f820ff659746e263fd4c5a82a0da8e16600936ac7ec715d824136528c06d9bb82b2920d5e6bbf6404d00f8f1b8ca6c1485a36f278159e3a2eb05350de6508c219042b2b3ef1d0859513048dad708085e4237c2e421ef54a7ca8fd6a361c2600092ceaf823c7558453990ee21f09fbc02f8a66f8e5c7d08ae4d9db4a4379bb1585aeb4ecd480f843202aa75bb957787215a39670fd74947fc0a5bc0fbd2f2f3ee345a82badf5f0ecde5ea46949a54e52fc8889f16f659d93c9ed75281dd2e4a9df8dd91bf2aebf87eec4c80c43830ca2cfc12"; #[cfg(test)] -mod test { +mod tests { use super::*; #[test] diff --git a/zingolib/CHANGELOG.md b/zingolib/CHANGELOG.md index 25de17e2b..ac0bf34e4 100644 --- a/zingolib/CHANGELOG.md +++ b/zingolib/CHANGELOG.md @@ -19,8 +19,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `get_wallet_dir_location` - `wallet::keys::is_transparent_address` fn - `wallet::notes::NoteRecordIdentifier` struct -- `utils` mod -- `test_framework` mod +- `utils::txid_from_hex_encoded_str` fn + +- `test-features` flag + - `test_framework` mod + - `mocks` module + - `ProposalBuilder` struct + - `StepBuilder` struct + - `LRZSaplingNoteBuilder` struct + - `default_txid` fn + - `random_txid` fn + - `default_zaddr` fn + - `random_zaddr` fn ### Changed diff --git a/zingolib/src/blaze/block_management_reorg_detection.rs b/zingolib/src/blaze/block_management_reorg_detection.rs index 58b999876..8e5dfd76a 100644 --- a/zingolib/src/blaze/block_management_reorg_detection.rs +++ b/zingolib/src/blaze/block_management_reorg_detection.rs @@ -744,7 +744,7 @@ pub fn update_tree_with_compact_transaction( } #[cfg(test)] -mod test { +mod tests { use crate::{blaze::test_utils::FakeCompactBlock, wallet::data::BlockData}; use orchard::tree::MerkleHashOrchard; use zcash_primitives::block::BlockHash; diff --git a/zingolib/src/blaze/fetch_taddr_transactions.rs b/zingolib/src/blaze/fetch_taddr_transactions.rs index 8a089bad9..82af789de 100644 --- a/zingolib/src/blaze/fetch_taddr_transactions.rs +++ b/zingolib/src/blaze/fetch_taddr_transactions.rs @@ -162,7 +162,7 @@ impl FetchTaddrTransactions { // TODO: Reexamine this test, which relies on explicit creation of transparent spend auths /* #[cfg(test)] -mod test { +mod tests { use futures::future::join_all; use rand::Rng; use std::sync::Arc; diff --git a/zingolib/src/test_framework.rs b/zingolib/src/test_framework.rs index da3c1bfb5..6bc84c838 100644 --- a/zingolib/src/test_framework.rs +++ b/zingolib/src/test_framework.rs @@ -1,51 +1,2 @@ -use zcash_primitives::transaction::TxId; - -use crate::wallet::notes::TransparentNote; pub(crate) mod macros; pub mod mocks; - -#[allow(dead_code)] -pub(crate) fn create_empty_txid_and_tnote() -> (zcash_primitives::transaction::TxId, TransparentNote) -{ - // A single transparent note makes is_incoming_trsaction true. - let txid = zcash_primitives::transaction::TxId::from_bytes([0u8; 32]); - ( - txid, - mocks::TransparentNoteBuilder::new() - .address("t".to_string()) - .spent(Some((txid, 3))) - .build(), - ) -} -#[allow(dead_code)] -pub(crate) fn create_transaction_record_with_one_tnote( - txid: TxId, - transparent_note: TransparentNote, -) -> crate::wallet::transaction_record::TransactionRecord { - // A single transparent note makes is_incoming_trsaction true. - let mut transaction_record = crate::wallet::transaction_record::TransactionRecord::new( - zingo_status::confirmation_status::ConfirmationStatus::Confirmed( - zcash_primitives::consensus::BlockHeight::from_u32(5), - ), - 1705077003, - &txid, - ); - transaction_record.transparent_notes.push(transparent_note); - transaction_record -} -#[allow(dead_code)] -pub(crate) fn default_trecord_with_one_tnote( -) -> crate::wallet::transaction_record::TransactionRecord { - let (txid, transparent_note) = create_empty_txid_and_tnote(); - create_transaction_record_with_one_tnote(txid, transparent_note) -} -#[allow(dead_code)] -pub(crate) fn create_note_record_id() -> crate::wallet::notes::NoteRecordIdentifier { - let (txid, _tnote) = create_empty_txid_and_tnote(); - let index = 5u32; - crate::wallet::notes::NoteRecordIdentifier { - txid, - pool: zcash_client_backend::PoolType::Transparent, - index, - } -} diff --git a/zingolib/src/test_framework/mocks.rs b/zingolib/src/test_framework/mocks.rs index 8e07ebbb5..89153f1c1 100644 --- a/zingolib/src/test_framework/mocks.rs +++ b/zingolib/src/test_framework/mocks.rs @@ -1,67 +1,126 @@ //! Tools to facilitate mocks for testing -use zcash_primitives::transaction::TxId; - -use crate::wallet::notes::TransparentNote; - pub use proposal::{ProposalBuilder, StepBuilder}; +pub use sapling_note::LRZSaplingNoteBuilder; macro_rules! build_method { ($name:ident, $localtype:ty) => { + #[doc = "Set the $name field of the builder."] pub fn $name(mut self, $name: $localtype) -> Self { self.$name = Some($name); self } }; } +pub(crate) use build_method; + +fn zaddr_from_seed( + seed: [u8; 32], +) -> ( + ExtendedSpendingKey, + PreparedIncomingViewingKey, + PaymentAddress, +) { + let extsk = ExtendedSpendingKey::master(&seed); + let dfvk = extsk.to_diversifiable_full_viewing_key(); + let fvk = dfvk; + let (_, addr) = fvk.default_address(); -pub struct TransparentNoteBuilder { - address: Option, - txid: Option, - output_index: Option, - script: Option>, - value: Option, - spent: Option>, - unconfirmed_spent: Option>, + ( + extsk, + PreparedIncomingViewingKey::new(&fvk.fvk().vk.ivk()), + addr, + ) } -#[allow(dead_code)] //TODO: fix this gross hack that I tossed in to silence the language-analyzer false positive -impl TransparentNoteBuilder { - pub fn new() -> Self { - Self::default() - } - // Methods to set each field - build_method!(address, String); - build_method!(txid, TxId); - build_method!(output_index, u64); - build_method!(script, Vec); - build_method!(value, u64); - build_method!(spent, Option<(TxId, u32)>); - build_method!(unconfirmed_spent, Option<(TxId, u32)>); - - // Build method - pub fn build(self) -> TransparentNote { - TransparentNote::from_parts( - self.address.unwrap(), - self.txid.unwrap(), - self.output_index.unwrap(), - self.script.unwrap(), - self.value.unwrap(), - self.spent.unwrap(), - self.unconfirmed_spent.unwrap(), - ) - } + +pub fn default_txid() -> zcash_primitives::transaction::TxId { + zcash_primitives::transaction::TxId::from_bytes([0u8; 32]) +} +pub fn default_zaddr() -> ( + ExtendedSpendingKey, + PreparedIncomingViewingKey, + PaymentAddress, +) { + zaddr_from_seed([0u8; 32]) } -impl Default for TransparentNoteBuilder { - fn default() -> Self { - TransparentNoteBuilder { - address: Some("default_address".to_string()), - txid: Some(TxId::from_bytes([0u8; 32])), - output_index: Some(0), - script: Some(vec![]), - value: Some(0), - spent: Some(None), - unconfirmed_spent: Some(None), +use rand::{rngs::OsRng, Rng}; +use sapling_crypto::{ + note_encryption::PreparedIncomingViewingKey, zip32::ExtendedSpendingKey, PaymentAddress, +}; + +pub fn random_txid() -> zcash_primitives::transaction::TxId { + let mut rng = OsRng; + let mut seed = [0u8; 32]; + rng.fill(&mut seed); + zcash_primitives::transaction::TxId::from_bytes(seed) +} +pub fn random_zaddr() -> ( + ExtendedSpendingKey, + PreparedIncomingViewingKey, + PaymentAddress, +) { + let mut rng = OsRng; + let mut seed = [0u8; 32]; + rng.fill(&mut seed); + + zaddr_from_seed(seed) +} + +// Sapling Note Mocker +mod sapling_note { + + use sapling_crypto::value::NoteValue; + use sapling_crypto::Note; + use sapling_crypto::PaymentAddress; + use sapling_crypto::Rseed; + + use super::default_zaddr; + + /// A struct to build a mock sapling_crypto::Note from scratch. + /// Distinguish sapling_crypto::Note from crate::wallet::notes::SaplingNote. The latter wraps the former with some other attributes. + pub struct LRZSaplingNoteBuilder { + recipient: Option, + value: Option, + rseed: Option, + } + + impl LRZSaplingNoteBuilder { + /// Instantiate an empty builder. + pub fn new() -> Self { + LRZSaplingNoteBuilder { + recipient: None, + value: None, + rseed: None, + } + } + + // Methods to set each field + build_method!(recipient, PaymentAddress); + build_method!(value, NoteValue); + build_method!(rseed, Rseed); + + pub fn randomize_recipient(self) -> Self { + let (_, _, address) = super::random_zaddr(); + self.recipient(address) + } + + /// Build the note. + pub fn build(self) -> Note { + Note::from_parts( + self.recipient.unwrap(), + self.value.unwrap(), + self.rseed.unwrap(), + ) + } + } + impl Default for LRZSaplingNoteBuilder { + fn default() -> Self { + let (_, _, address) = default_zaddr(); + Self::new() + .recipient(address) + .value(NoteValue::from_raw(1000000)) + .rseed(Rseed::AfterZip212([7; 32])) } } } @@ -74,7 +133,7 @@ pub mod proposal { use incrementalmerkletree::Position; use nonempty::NonEmpty; use sapling_crypto::value::NoteValue; - use sapling_crypto::zip32::ExtendedSpendingKey; + use sapling_crypto::Rseed; use zcash_client_backend::fees::TransactionBalance; use zcash_client_backend::proposal::{Proposal, ShieldedInputs, Step, StepOutput}; @@ -83,11 +142,13 @@ pub mod proposal { use zcash_client_backend::PoolType; use zcash_primitives::consensus::BlockHeight; use zcash_primitives::transaction::{ - components::amount::NonNegativeAmount, fees::zip317::FeeRule, TxId, + components::amount::NonNegativeAmount, fees::zip317::FeeRule, }; use crate::wallet::notes::NoteRecordIdentifier; + use super::{default_txid, default_zaddr}; + /// Provides a builder for constructing a mock [`zcash_client_backend::proposal::Proposal`]. /// /// # Examples @@ -221,10 +282,8 @@ pub mod proposal { impl Default for StepBuilder { /// Constructs a new [`StepBuilder`] where all fields are preset to default values. fn default() -> Self { - let txid = TxId::from_bytes([0u8; 32]); - let seed = [0u8; 32]; - let dfvk = ExtendedSpendingKey::master(&seed).to_diversifiable_full_viewing_key(); - let (_, address) = dfvk.default_address(); + let txid = default_txid(); + let (_, _, address) = default_zaddr(); let note = sapling_crypto::Note::from_parts( address, NoteValue::from_raw(20_000), diff --git a/zingolib/src/wallet.rs b/zingolib/src/wallet.rs index 5da5d253a..4f33d8d6f 100644 --- a/zingolib/src/wallet.rs +++ b/zingolib/src/wallet.rs @@ -437,7 +437,7 @@ fn decode_orchard_spending_key( } #[cfg(test)] -mod test { +mod tests { use incrementalmerkletree::frontier::CommitmentTree; use orchard::tree::MerkleHashOrchard; diff --git a/zingolib/src/wallet/data.rs b/zingolib/src/wallet/data.rs index f222622ad..7021418c6 100644 --- a/zingolib/src/wallet/data.rs +++ b/zingolib/src/wallet/data.rs @@ -699,13 +699,6 @@ pub mod summaries { pub use crate::wallet::transaction_record::TransactionRecord; -#[test] -#[cfg(feature = "test-features")] -fn single_transparent_note_makes_is_incoming_true() { - // A single transparent note makes is_incoming_trsaction true. - let transaction_record = crate::test_framework::default_trecord_with_one_tnote(); - assert!(transaction_record.is_incoming_transaction()); -} #[derive(Debug)] pub struct SpendableSaplingNote { pub transaction_id: TxId, diff --git a/zingolib/src/wallet/message.rs b/zingolib/src/wallet/message.rs index e5e07db31..0c516934d 100644 --- a/zingolib/src/wallet/message.rs +++ b/zingolib/src/wallet/message.rs @@ -208,37 +208,17 @@ impl Message { } #[cfg(test)] -pub mod tests { +mod tests { use ff::Field; - use sapling_crypto::zip32::ExtendedSpendingKey; use zcash_note_encryption::OUT_PLAINTEXT_SIZE; - use super::*; - - fn get_random_zaddr() -> ( - ExtendedSpendingKey, - PreparedIncomingViewingKey, - PaymentAddress, - ) { - let mut rng = OsRng; - let mut seed = [0u8; 32]; - rng.fill(&mut seed); - - let extsk = ExtendedSpendingKey::master(&seed); - let dfvk = extsk.to_diversifiable_full_viewing_key(); - let fvk = dfvk; - let (_, addr) = fvk.default_address(); + use crate::test_framework::mocks::random_zaddr; - ( - extsk, - PreparedIncomingViewingKey::new(&fvk.fvk().vk.ivk()), - addr, - ) - } + use super::*; #[test] fn test_encrpyt_decrypt() { - let (_, ivk, to) = get_random_zaddr(); + let (_, ivk, to) = random_zaddr(); let msg = Memo::from_bytes("Hello World with some value!".to_string().as_bytes()).unwrap(); @@ -264,8 +244,8 @@ pub mod tests { #[test] fn test_bad_inputs() { - let (_, ivk1, to1) = get_random_zaddr(); - let (_, ivk2, _) = get_random_zaddr(); + let (_, ivk1, to1) = random_zaddr(); + let (_, ivk2, _) = random_zaddr(); let msg = Memo::from_bytes("Hello World with some value!".to_string().as_bytes()).unwrap(); @@ -286,7 +266,7 @@ pub mod tests { let magic_len = Message::magic_word().len(); let prefix_len = magic_len + 1; // version byte - let (_, ivk, to) = get_random_zaddr(); + let (_, ivk, to) = random_zaddr(); let msg_str = "Hello World with some value!"; let msg = Memo::from_bytes(msg_str.to_string().as_bytes()).unwrap(); @@ -373,7 +353,7 @@ pub mod tests { #[test] fn test_individual_bytes() { - let (_, ivk, to) = get_random_zaddr(); + let (_, ivk, to) = random_zaddr(); let msg_str = "Hello World with some value!"; let msg = Memo::from_bytes(msg_str.to_string().as_bytes()).unwrap(); diff --git a/zingolib/src/wallet/notes.rs b/zingolib/src/wallet/notes.rs index bdd9d529e..9b8392840 100644 --- a/zingolib/src/wallet/notes.rs +++ b/zingolib/src/wallet/notes.rs @@ -19,6 +19,12 @@ pub struct NoteRecordIdentifier { pub index: u32, } +impl NoteRecordIdentifier { + pub fn from_parts(txid: TxId, pool: PoolType, index: u32) -> Self { + NoteRecordIdentifier { txid, pool, index } + } +} + impl std::fmt::Display for NoteRecordIdentifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( @@ -28,3 +34,61 @@ impl std::fmt::Display for NoteRecordIdentifier { ) } } + +#[cfg(any(test, feature = "test-features"))] +pub mod mocks { + //! Mock version of the struct for testing + use zcash_client_backend::PoolType; + use zcash_primitives::transaction::TxId; + + use crate::test_framework::mocks::{build_method, default_txid}; + + use super::NoteRecordIdentifier; + + /// to build a mock NoteRecordIdentifier + pub struct NoteRecordIdentifierBuilder { + txid: Option, + pool: Option, + index: Option, + } + #[allow(dead_code)] //TODO: fix this gross hack that I tossed in to silence the language-analyzer false positive + impl NoteRecordIdentifierBuilder { + /// blank builder + pub fn new() -> Self { + Self { + txid: None, + pool: None, + index: None, + } + } + // Methods to set each field + build_method!(txid, TxId); + build_method!(pool, PoolType); + build_method!(index, u32); + + /// selects a random probablistically unique txid + pub fn randomize_txid(self) -> Self { + self.txid(crate::test_framework::mocks::random_txid()) + } + + /// builds a mock NoteRecordIdentifier after all pieces are supplied + pub fn build(self) -> NoteRecordIdentifier { + NoteRecordIdentifier::from_parts( + self.txid.unwrap(), + self.pool.unwrap(), + self.index.unwrap(), + ) + } + } + + impl Default for NoteRecordIdentifierBuilder { + fn default() -> Self { + Self::new() + .txid(default_txid()) + .pool(PoolType::Shielded( + zcash_client_backend::ShieldedProtocol::Orchard, + )) + .index(0) + } + } +} diff --git a/zingolib/src/wallet/notes/sapling.rs b/zingolib/src/wallet/notes/sapling.rs index bca1de599..989562371 100644 --- a/zingolib/src/wallet/notes/sapling.rs +++ b/zingolib/src/wallet/notes/sapling.rs @@ -171,3 +171,108 @@ impl ShieldedNoteInterface for SaplingNote { zcash_client_backend::wallet::Note::Sapling(self.note().clone()) } } + +#[cfg(any(test, feature = "test-features"))] +pub mod mocks { + //! Mock version of the struct for testing + use incrementalmerkletree::Position; + use zcash_primitives::{memo::Memo, transaction::TxId}; + + use crate::{ + test_framework::mocks::build_method, + wallet::{notes::ShieldedNoteInterface, traits::FromBytes}, + }; + + use super::SaplingNote; + + /// to create a mock SaplingNote + pub(crate) struct SaplingNoteBuilder { + diversifier: Option, + note: Option, + witnessed_position: Option>, + output_index: Option>, + nullifier: Option>, + spent: Option>, + unconfirmed_spent: Option>, + memo: Option>, + is_change: Option, + have_spending_key: Option, + } + + #[allow(dead_code)] //TODO: fix this gross hack that I tossed in to silence the language-analyzer false positive + impl SaplingNoteBuilder { + /// blank builder + pub fn new() -> Self { + SaplingNoteBuilder { + diversifier: None, + note: None, + witnessed_position: None, + output_index: None, + nullifier: None, + spent: None, + unconfirmed_spent: None, + memo: None, + is_change: None, + have_spending_key: None, + } + } + + // Methods to set each field + build_method!(diversifier, sapling_crypto::Diversifier); + build_method!(note, sapling_crypto::Note); + build_method!(witnessed_position, Option); + build_method!(output_index, Option); + build_method!(nullifier, Option); + build_method!(spent, Option<(TxId, u32)>); + build_method!(unconfirmed_spent, Option<(TxId, u32)>); + build_method!(memo, Option); + #[doc = "Set the is_change field of the builder."] + pub fn set_change(mut self, is_change: bool) -> Self { + self.is_change = Some(is_change); + self + } + build_method!(have_spending_key, bool); + + /// builds a mock SaplingNote after all pieces are supplied + pub fn build(self) -> SaplingNote { + SaplingNote::from_parts( + self.diversifier.unwrap(), + self.note.unwrap(), + self.witnessed_position.unwrap(), + self.nullifier.unwrap(), + self.spent.unwrap(), + self.unconfirmed_spent.unwrap(), + self.memo.unwrap(), + self.is_change.unwrap(), + self.have_spending_key.unwrap(), + self.output_index.unwrap(), + ) + } + } + + impl Default for SaplingNoteBuilder { + fn default() -> Self { + SaplingNoteBuilder::new() + .diversifier(sapling_crypto::Diversifier([0; 11])) + .note(crate::test_framework::mocks::LRZSaplingNoteBuilder::default().build()) + .witnessed_position(Some(Position::from(0))) + .output_index(Some(0)) + .nullifier(Some(sapling_crypto::Nullifier::from_bytes([0; 32]))) + .spent(None) + .unconfirmed_spent(None) + .memo(None) + .set_change(false) + .have_spending_key(true) + } + } +} + +#[cfg(test)] +mod tests { + use super::mocks::SaplingNoteBuilder; + + #[test] + pub fn build_sapling_note() { + let _sapling_note = SaplingNoteBuilder::default().build(); + } +} diff --git a/zingolib/src/wallet/notes/transparent.rs b/zingolib/src/wallet/notes/transparent.rs index 16b012f96..550d1c70c 100644 --- a/zingolib/src/wallet/notes/transparent.rs +++ b/zingolib/src/wallet/notes/transparent.rs @@ -165,3 +165,71 @@ impl TransparentNote { }) } } + +#[cfg(any(test, feature = "test-features"))] +pub mod mocks { + //! Mock version of the struct for testing + use zcash_primitives::transaction::TxId; + + use crate::{test_framework::mocks::build_method, wallet::notes::TransparentNote}; + + /// to create a mock TransparentNote + pub struct TransparentNoteBuilder { + address: Option, + txid: Option, + output_index: Option, + script: Option>, + value: Option, + spent: Option>, + unconfirmed_spent: Option>, + } + #[allow(dead_code)] //TODO: fix this gross hack that I tossed in to silence the language-analyzer false positive + impl TransparentNoteBuilder { + /// blank builder + pub fn new() -> Self { + Self { + address: None, + txid: None, + output_index: None, + script: None, + value: None, + spent: None, + unconfirmed_spent: None, + } + } + // Methods to set each field + build_method!(address, String); + build_method!(txid, TxId); + build_method!(output_index, u64); + build_method!(script, Vec); + build_method!(value, u64); + build_method!(spent, Option<(TxId, u32)>); + build_method!(unconfirmed_spent, Option<(TxId, u32)>); + + /// builds a mock TransparentNote after all pieces are supplied + pub fn build(self) -> TransparentNote { + TransparentNote::from_parts( + self.address.unwrap(), + self.txid.unwrap(), + self.output_index.unwrap(), + self.script.unwrap(), + self.value.unwrap(), + self.spent.unwrap(), + self.unconfirmed_spent.unwrap(), + ) + } + } + + impl Default for TransparentNoteBuilder { + fn default() -> Self { + Self::new() + .address("default_address".to_string()) + .txid(TxId::from_bytes([0u8; 32])) + .output_index(0) + .script(vec![]) + .value(0) + .spent(None) + .unconfirmed_spent(None) + } + } +} diff --git a/zingolib/src/wallet/transaction_record.rs b/zingolib/src/wallet/transaction_record.rs index 532cee20c..18d8ce094 100644 --- a/zingolib/src/wallet/transaction_record.rs +++ b/zingolib/src/wallet/transaction_record.rs @@ -324,19 +324,76 @@ impl TransactionRecord { } } +#[cfg(any(test, feature = "test-features"))] +pub mod mocks { + //! Mock version of the struct for testing + use zcash_primitives::transaction::TxId; + use zingo_status::confirmation_status::ConfirmationStatus; + + use crate::test_framework::mocks::build_method; + + use super::TransactionRecord; + + /// to create a mock TransactionRecord + pub struct TransactionRecordBuilder { + status: Option, + datetime: Option, + txid: Option, + } + #[allow(dead_code)] //TODO: fix this gross hack that I tossed in to silence the language-analyzer false positive + impl TransactionRecordBuilder { + /// blank builder + pub fn new() -> Self { + Self { + status: None, + datetime: None, + txid: None, + } + } + // Methods to set each field + build_method!(status, ConfirmationStatus); + build_method!(datetime, u64); + build_method!(txid, TxId); + + pub fn randomize_txid(self) -> Self { + self.txid(crate::test_framework::mocks::random_txid()) + } + + /// builds a mock TransactionRecord after all pieces are supplied + pub fn build(self) -> TransactionRecord { + TransactionRecord::new( + self.status.unwrap(), + self.datetime.unwrap(), + &self.txid.unwrap(), + ) + } + } + + impl Default for TransactionRecordBuilder { + fn default() -> Self { + Self { + status: Some( + zingo_status::confirmation_status::ConfirmationStatus::Confirmed( + zcash_primitives::consensus::BlockHeight::from_u32(5), + ), + ), + datetime: Some(1705077003), + txid: Some(crate::test_framework::mocks::default_txid()), + } + } + } +} + #[cfg(test)] mod tests { - use crate::wallet::utils::txid_from_slice; + use crate::wallet::notes::transparent::mocks::TransparentNoteBuilder; + use crate::wallet::transaction_record::mocks::TransactionRecordBuilder; use super::*; #[test] pub fn blank_record() { - let new = TransactionRecord::new( - ConfirmationStatus::Confirmed(2_000_000.into()), - 103, - &txid_from_slice(&[0u8; 32]), - ); + let new = TransactionRecordBuilder::default().build(); assert_eq!(new.get_transparent_value_spent(), 0); assert_eq!(new.get_transaction_fee().unwrap(), 0); assert!(!new.is_outgoing_transaction()); @@ -350,4 +407,13 @@ mod tests { let t: [u64; 3] = [0, 0, 0]; assert_eq!(new.value_spent_by_pool(), t); } + #[test] + fn single_transparent_note_makes_is_incoming_true() { + // A single transparent note makes is_incoming_transaction true. + let mut transaction_record = TransactionRecordBuilder::default().build(); + transaction_record + .transparent_notes + .push(TransparentNoteBuilder::default().build()); + assert!(transaction_record.is_incoming_transaction()); + } } From 35199c41ca1a08a1aea82f86142e747357a80e72 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Wed, 17 Apr 2024 15:34:18 +0000 Subject: [PATCH 2/4] addressed feedback --- zingolib/src/test_framework/mocks.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/zingolib/src/test_framework/mocks.rs b/zingolib/src/test_framework/mocks.rs index 89153f1c1..aeefbc182 100644 --- a/zingolib/src/test_framework/mocks.rs +++ b/zingolib/src/test_framework/mocks.rs @@ -1,8 +1,5 @@ //! Tools to facilitate mocks for testing -pub use proposal::{ProposalBuilder, StepBuilder}; -pub use sapling_note::LRZSaplingNoteBuilder; - macro_rules! build_method { ($name:ident, $localtype:ty) => { #[doc = "Set the $name field of the builder."] @@ -13,6 +10,8 @@ macro_rules! build_method { }; } pub(crate) use build_method; +pub use proposal::{ProposalBuilder, StepBuilder}; +pub use sapling_note::LRZSaplingNoteBuilder; fn zaddr_from_seed( seed: [u8; 32], @@ -78,7 +77,7 @@ mod sapling_note { use super::default_zaddr; /// A struct to build a mock sapling_crypto::Note from scratch. - /// Distinguish sapling_crypto::Note from crate::wallet::notes::SaplingNote. The latter wraps the former with some other attributes. + /// Distinguish [`sapling_crypto::Note`] from [`crate::wallet::notes::SaplingNote`]. The latter wraps the former with some other attributes. pub struct LRZSaplingNoteBuilder { recipient: Option, value: Option, From d2d6137b0293c14e65bd3eacc80cd1322edc92f0 Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Wed, 17 Apr 2024 15:43:53 +0000 Subject: [PATCH 3/4] Update CHANGELOG.md --- zingolib/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zingolib/CHANGELOG.md b/zingolib/CHANGELOG.md index 2b3b599cb..84bd32433 100644 --- a/zingolib/CHANGELOG.md +++ b/zingolib/CHANGELOG.md @@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `wallet::keys::is_transparent_address` fn - `wallet::notes::NoteRecordIdentifier` struct - `utils` mod -- `utils::txid_from_hex_encoded_str` fn + - `utils::txid_from_hex_encoded_str` fn - `lightclient::LightClient`: - `do_propose` behind "zip317" feature - `do_send_proposal` behind "zip317" feature From 59fc31f91ad98bf79104e3fbccc69189df2435aa Mon Sep 17 00:00:00 2001 From: fluidvanadium Date: Wed, 17 Apr 2024 15:49:49 +0000 Subject: [PATCH 4/4] Update CHANGELOG.md --- zingolib/CHANGELOG.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/zingolib/CHANGELOG.md b/zingolib/CHANGELOG.md index 84bd32433..196b4126a 100644 --- a/zingolib/CHANGELOG.md +++ b/zingolib/CHANGELOG.md @@ -20,7 +20,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `wallet::keys::is_transparent_address` fn - `wallet::notes::NoteRecordIdentifier` struct - `utils` mod - - `utils::txid_from_hex_encoded_str` fn - `lightclient::LightClient`: - `do_propose` behind "zip317" feature - `do_send_proposal` behind "zip317" feature @@ -29,14 +28,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `QuickSendCommand` struct and methods behind "zip317" feature - `test_framework` mod behind "test-features" feature - - `mocks` module - - `ProposalBuilder` struct - - `StepBuilder` struct - - `LRZSaplingNoteBuilder` struct - - `default_txid` fn - - `random_txid` fn - - `default_zaddr` fn - - `random_zaddr` fn ### Changed