From fe90ef00104b752a6832f09cb50fabeafc51d1f3 Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Tue, 4 Oct 2022 19:52:27 -0300 Subject: [PATCH 01/11] [#557] Update checkpoints and release 0.16.11-beta Closes #557 --- .../Resources/checkpoints/mainnet/1812500.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1815000.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1817500.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1820000.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1822500.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1825000.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1827500.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1830000.json | 8 ++++++++ ZcashLightClientKit.podspec | 2 +- changelog.md | 13 +++++++++++++ 10 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1812500.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1815000.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1817500.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1820000.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1822500.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1825000.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1827500.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1830000.json diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1812500.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1812500.json new file mode 100644 index 00000000..72e51cf5 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1812500.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1812500", + "hash": "00000000008f6e5ac009390e7daa092a3207581c211e2be70b60ce04b88505c3", + "time": 1663471780, + "saplingTree": "0180d672d65ad56265eeb9632dbe62473447bc7bf3e598d2e896cdcb798887b53d00190139d37c3a694b0104d15e447f51d96800d260a5a1053558cd4b7134b8c77f803400017175873eec18949e09f6df019a3d20530716d2307ba1f00fc0c09bae6656022400000198c1229f3df738745986e8aabc1d3ec92944865b43a910b8c74221f99b8ee0320000014c8a851d7fdb90d17b97621005c826c8b3ce8ee463062e324e2ad886f202b6440158720dd7a931f66eac2ff934b0765f807c9504ea318c18f606831c80feb3770401252adc68c56eae8331764a2d9d72851e7352bd33364963b6618f47d56bc21c6900017d8e001c7be91297f727edf47b650f44cbfbebb535b4f409e357b37c43a621040001ba60d34966fcefe1b8058d28b784f87089e693fde8b99902a4fc956021f7ee04017547ef39c632d9bfd0cf48e3e909dbc2e0890f2791a6929ca0d6674484f4c046000190ca77d38f0a408e33a8633f140441488cdedf7508a06d04771b53e4e4de9861019db47a02109d9232f4c4fa044613a8a0cc508865b185ee28318c86d16829895801acc2d2141fe4e5c43c11710e48bd0b12c0493b1721fad3b03470a4400157e020000001f416eb7e062c981dbbf76f8845fda959b948bc742fc62d9edb2f36bae852ba4e01c5d9822e7aa76d3a758e8dc25ffd8b8c9d4051c66fb92fd7aa263905e238920e0139af7ec003ac4e37c263bab5642fcc4ec294a1e328ff025832eec45239041f6e", + "orchardTree": "01cfc873591e05c184abdc8a1a78659e28df418ea5320a5bd81d2d761c1af5ed0a001f01244feb50d761d34ab22b04045ae9eface10df4b17bbded9d1da9fb71e48cf01400018a07d6cf54e4da1fb1f501850cba2a98ff5a8a8a5722896c3906c09447500f26014be19370bcb96d495a7c1e9719ccc057104a66a5ef6ea217f3fe29e26459131d000172482cc1f1fad25e86299334a24a63e6e86c0b04d319a230bd3aba2dd38279110124de7fbfe4a050ae1427d73491bdddedda1e2e7db48d2365b3cb108eb9833b34000000000000018eb08300830f838c7d212857b7e045a05458264f44f33a9f5d726631634da70201778055c0e5ef68c30c7fa81eb67f0cbf32b64dc5d6ff8138f380cb8f115418260000010fb2cb03705826ca086f605974429cfb0dc60df50a0d15d06c2cfef80017902f01c7146e487b3ae97b190ebf93eac554968e683d31115d13fe83dd620859d9a92d000001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1815000.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1815000.json new file mode 100644 index 00000000..4805a8fe --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1815000.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1815000", + "hash": "0000000000ff971a219416d483ec48af6e055182ab566572fdda7fedb2d15368", + "time": 1663659973, + "saplingTree": "013010baaf80742269ab7061e012c90e4ef805cc07bb62ef71869fe0badc141f6901d003b1d99e5dfc26894e0b1f393399560374425c34f89853df55a4e32be616251901b34b07fcc9a91eb89bc409a51f452bd21327cfdf3328e9913289760e464824710122ccb843dd5775365b143f0cd1cf309c1940a7c3ba7070c92d041f35b8fc3f4601da8ae93a665218fe154683bb6c75e5ded94f1780358591ce7524ca324f22a53601962ea341367529954ac02e5479c129499aae960e8448ec5697f216b45986b3040168c82ca2a31ca7b833886ee0b3dbb60c519a917b2dfcb6590175b38a0cf17944000196c2704fda3d5e124118cc6cbb1514bbdbdff5bab3a334bda2af27b3e1c7f42a0103bdd297e11f1bbf4d438079aefdc797b012e2e90903194011f9f23cd7ed5b510198ba7189c4d8aeaa58402a655214c69bfa4d09c7818a9691629a8643cca9c91d0000016fbc427c11055083f9330cb82d07c7ce7ca37ee43c7bcc687683f6a50cfdfa3e01201e7639e97113adcb84691cca72efb6f8f44293109ccf02f1beabe46412b75c01046ace0bc25d6c3889da89753306be90ce721bc463e9a6662f3ea10141b5db2801ac5fca146985e234d3ae22d84b09f7924d8baeee82fba8235dd9db60db8f6565000001f513025ec4ad6f392fa842db7cb2f0be10e1bc3662046db7cb6d5de314abe33a01ff0944072256da35186a74026d56db14a2c80ffc4dc7a3b2b5a93885c2622b5201471bdfaa9efa8b9adce9654553a07278f7e37156c73b03394ca8288d8983403001bc76949736399cf6d26d21a468ad6c8ee3e563e0ccef01d615c45a91bc9a612e0001f416eb7e062c981dbbf76f8845fda959b948bc742fc62d9edb2f36bae852ba4e01c5d9822e7aa76d3a758e8dc25ffd8b8c9d4051c66fb92fd7aa263905e238920e0139af7ec003ac4e37c263bab5642fcc4ec294a1e328ff025832eec45239041f6e", + "orchardTree": "013f012dabdfb54100613c405576e16bbc19a802910fde444e98827f568143ed0c001f010853c8f2d2423d321b9630781d679b884cde7b3160108ddc1233f955e1bd9628000001b8ef98edd02dbc2b74a63778968d66cb1361cc01f7b4434b141ec35c12a2741901c5a9a64d994fbe4c8d044c80f8f551595ff8a33b2bf98857058ab080aa2fbf31000000000116e9a922d1b143d61c100ff15dc2ffdf92e70721aed5a6c37270d7136fb38a1b013dedd8fa148f4930ad5fc0ac019753a21886453af5c94e8f8817a4e13b7ef810000001f69a0bb2a07942810983d469f50f2285c1ba6f0b3355378356cc62a17860cf170175dca061b72ede5cfcb867aa38ce3a37fc84b7586cbeac75d077c5e0eb33b3250001ccf521db485f5532163391b715519775dc86bbb7b938687551a8547a7c81b425010fb2cb03705826ca086f605974429cfb0dc60df50a0d15d06c2cfef80017902f01c7146e487b3ae97b190ebf93eac554968e683d31115d13fe83dd620859d9a92d000001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1817500.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1817500.json new file mode 100644 index 00000000..bf6ac1e4 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1817500.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1817500", + "hash": "00000000013757a4fc04d1817f08be13cb68212185a21938235d7f9685ef7133", + "time": 1663848803, + "saplingTree": "012b6c4df5794284a452d6486dc5c3a6e15e7daceed97674fb8990242a07d34a1301de28191ca049c8668eb11fb60a6e2d64b496e2c22620a3a3ee31bc0ab496613c190001ddb3f202a4fd2d677c0e4aa44f8f51ab116a7233f6a620ccbc35e27c4043626d0001eda65f389f39694d0a54c893b3d53d32f03b684c3d182198a934834064ed1302000001b235783e1d216027badf69ee580c0890801d7689b52767f0367ab446f7c2ff4701e5cd3f5440dd9f741ff9c12bf94face46d65d4ad396f08944db4b3b8e282b24601a2d8377a97563fdad5693d7e09b1ba3ac87de413e122fb202c826cc46f6d3b0b0000012945d8546f0aca5aef67fef1bf30e463c2fbb03d90e1f505c223f7170739982a0161bd0e7d1808fcbc370ace2968fb64589b4d5a545fe30f5ed671e38c45859f000001506579c448460360aee9a6da1a0bbba5d040a1f72aac41c4f5b443b0eca8743800016930c8a959bd90b1b62e9802f5cbcc3cb3d870517dbb13e929968e90dbc03966000001b0fe8fd198af091f423e1f6c055671b04a35ee33729cfbf33ad1b83b109a78570001b72a593c1c89f26daa1d1c5f5f3f24737ca0848b67a97b0c3a2cf9a0e163091f01f416eb7e062c981dbbf76f8845fda959b948bc742fc62d9edb2f36bae852ba4e01c5d9822e7aa76d3a758e8dc25ffd8b8c9d4051c66fb92fd7aa263905e238920e0139af7ec003ac4e37c263bab5642fcc4ec294a1e328ff025832eec45239041f6e", + "orchardTree": "01d74889ff71b2f7a95bb7f4fec78bc0e63148642ea50c3c353a7be5ba25788e2e001f0131419f315d75aea60effee990fee293d35664d941866ad3bdf3efdad9d44bd2e000000013eb62102cf5d6119d411bee8e92c3af1a5337fe11e8c0760920fe9b3ec6ed90d016aacd5fc71a5527c7b9789bb97078c16c9d1444b84a2a2f5a8d5306cece20f0d00011ebb565f5458dc9e3b49f69f64733873eaff2663f5a5ab4f0651a1835b67622800000001c6dedd851cf25be522f8794de3473dc3169d6e620580f11c8458a844f8aea13501ec6da1180a001154528a755ff85883761ab63a8cda1de497045cfe8235e81e260000000000000118b1d1d9f37857fd4b5b4eb5fca3d9246d9af2ff57dc556456777486cd8a943a0001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1820000.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1820000.json new file mode 100644 index 00000000..80df4523 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1820000.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1820000", + "hash": "0000000000835c776b73524bd19ba4f31e0a2433a1b127d3fc249b76796678b0", + "time": 1664037050, + "saplingTree": "01f32c0a3edd77fb718880da85cb80fd6d700afdcb0c8d941d9cf83fba5af2870200190000012e2a332b86ca3c557c064a8d6e785316c5fa29a8ff0f9f2bf206c2a79273311e00000000000001f97daa24c7111f4d953c4f12ed983e9ff5024ee0bc9b5307cacd62809a63d263012f1870cbe92ff9b955331241ceef9c096782f9deae047f154d45dbe6e06e7a680001bda24aa178c8464c3f7d0f37f8f7b254ab2a28b0ebd0e1cad2b4461585ed650100000001bea76640d0f3a644f7c48d548d61082b1e59888ea45983588ead11372d9a7e220000016ee1f850fb81314c5cb719df85d19a05d71ab03ad0674c290bbedaaaf13f5830011a89f88b2081f74f07b1e3bfb9fa2dad973d38a2778ca9caf804269b1569e51a01b72a593c1c89f26daa1d1c5f5f3f24737ca0848b67a97b0c3a2cf9a0e163091f01f416eb7e062c981dbbf76f8845fda959b948bc742fc62d9edb2f36bae852ba4e01c5d9822e7aa76d3a758e8dc25ffd8b8c9d4051c66fb92fd7aa263905e238920e0139af7ec003ac4e37c263bab5642fcc4ec294a1e328ff025832eec45239041f6e", + "orchardTree": "018b4e53c9b54665efb59b6a574061e4e8c22719e77298207ec59eb450beabc236001f0000000001e571d044e6017197dfadb085a24e0ffb4db345f76802fcc5f855b983ac95ce3b01445284ba4559992af06ab7e0bd62fb6a0586d2c87e2e08538f4e3047fb8f5c270114468166c8102b612e569ed90c38e14d33dc9899974ede1dc1d1a9d537b3f6060140157de80b79ace710090ded467cf09f382c03a57391060b4d80e6caa83ca8290178d8f1f35f97aacd0a3ed6a488eb04a295d068e1101808005a8b991347df0d0e0188ead086968b6763947d155c8607050b9d86fe394563e404a808a4dfd042a21c01da5f438bf911526bc11ab824bf18c29f092a7057650fe30e741c098622fdfe360113696c5ac5b2b94583b6cc6cc01f4be7f9614afcd5a856690ebb18a7b325321f000116ce53cbd2f57591e271c4004c3b7e569383a34c2d0950777b7ee0133b022d05000001db0c50e709ec287e6423e6daa582695335b02a53ad1d5e06bf1499a2ccf5100400000118b1d1d9f37857fd4b5b4eb5fca3d9246d9af2ff57dc556456777486cd8a943a0001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1822500.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1822500.json new file mode 100644 index 00000000..c555e4e7 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1822500.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1822500", + "hash": "0000000000a714468e7fbb0e3804f4ca38362f55cb0d9560a4d0c4e82f27643a", + "time": 1664225376, + "saplingTree": "01e55a3c5796b2057c7d4566262467f321bee7a49446831979c2fe7f00c514be2b001a0114f298f871efa88e8e3f0cf75332800066add4957252cb706c3e0a4a4a9cf812000000011f2ad5179ad1500123ba9ff6e4e3495a00aa51974d1185f7d8071eb63de396460001b2dc078bad9b7941458f393f54af4fefbda6648097a0d7db168dbf838318711801d7bf4d62710e875cbd9b376b9f4ef15b01c5e3a190947b9ee8326a4bba7fd00301f95116e45179eeed5481b4fd815ede7458f06ccde88af55c4e9ce8700875731600000001dfc746f32e8af2b7946f316f61f4b381af6a5d32edac92dbdf0832de6f9f430400000001afb52e8a8582fb920a38445d5dac564825de368d2a57d106b7e378427019176c000122761291bf884b6f5ee5c0b224ca06990534a932241ca10b99b7b978ebc33e6d0000000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "01393f7dbe3707eda351d5ab2326369b818f6b6dfc5f81bb5228e085b2c7707323010c2f0639c08029304a03629453ee97d21c2ed7391edab49a77a5ed925a44f9051f000001c7b9e0d295ab3e74b1aafc5adfb2a1c6829108f8c3bf871edc721f2a78c5b40e0001a8758f3d483121113d71c2826f7a26b8a89017df94710146a844731852ba4d1501223105cff5efd73d74fc593f79f08ace789a6d2df4d6e3e98eb229d3cbe135140135e7a09bf3f8ee46559cc3917af50a5252ba98d51302f4958c4dea04e9f29b3e012a097d3bffa77778f5d2ed0bc6455c148f8d9f33b27e53e13ad71e83077ae408018a9af15099d6903002b63e90e7e2759f107dc427fe722a2e8a47caf811af8819018f54abcc86127e81658368df0e582d2f31595bae46b445caa49a4896ea16633b0001f1e08466d0331539a333be73620fc1f9ef3760be0807e8c087f19f8c5609341a010f099166cd67ccd6af73ada73f726b8667c1999ec18d16f32591ec073091ec0000014e69eda5e0a6dae5c0e259edc1a4883ad9f705bbfa67a19e89253c5318bd4f22000001aa1af2205aa6e2d1dbacb3b0ee2113a8bd8ab9bc326e82c1d0f412517b882b2a000118b1d1d9f37857fd4b5b4eb5fca3d9246d9af2ff57dc556456777486cd8a943a0001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1825000.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1825000.json new file mode 100644 index 00000000..4b81f8ac --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1825000.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1825000", + "hash": "00000000010bcacc0fc5d5c19ad9f7d8ed48611efc59a263e390b7616f874d19", + "time": 1664414144, + "saplingTree": "012e52a9a21c8fcae78103b11f846815a63c33e455347e7813152e9be8b42f6814001a01e67b5e015bbe91da7b4903c9252cf175b64c16b85027ad533357f66d80887a580000012a20a2299b66e1fcd4ca84774727025db6d667c3057198b929490495e4ec355701982e0e26ffa4c89f04e5c463b5499a1eab6566320ee4882602ba9b177b46d05c01b088dad9568f994021da7d4df0708efc28ce412be4006d9249a757d51737d70f000102ac23f0271b5c42a994cdbc0a234e5ef04ad8bb4cd478b770527d646a8f2353000000019870b43adfb257413d26f58805b078ab69bb5cd494b8e94a1d9e5c6843d1486e00000139061f9d2c783f9b9e8575b26a78924295737e997935f0b75c0cf125d1fd7a310000000001505fc602840d05f9586470bb490afbccd86fdf5ac4d0e77e5a9449524dbb732100000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "018c73fb76a5c7d45cb95a5868d4e0464168d48a574824c572e7c1b14092485d33001f01d9f0e6d791cc1843a126113ec3df17afe78c4aa8b272a9a378a2be551477233b00019f01ba3ba2ada7b9fbc9d8f41fd952b19331ff68d5b5697400ab2191d5143939010f84108bf6e3ff0f1e122b52f871296142f56b2fedf210cf4a19d60a35c3ad090000000001624baf89d0e9674562f99abcfcb93dc90139515849e15e2d161b1ecd18a8cd2e016956a06c642fa1ce07638a0034f1621ba90d3745149c2cf71937af51b8487733017a74469c0a99a842c0ab1372538d4f02c2a4aad6bb4e361fc02e36e8e0b25325018503c3bacb212c18b19244328dc6a97f2b8a93e5bd92dd55d7a6dc49d0df642a0000000001f20860c3563401082d950e84fc8735d8925677da13f40f6cd7a38a8c0198d60801aa1af2205aa6e2d1dbacb3b0ee2113a8bd8ab9bc326e82c1d0f412517b882b2a000118b1d1d9f37857fd4b5b4eb5fca3d9246d9af2ff57dc556456777486cd8a943a0001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1827500.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1827500.json new file mode 100644 index 00000000..2f014acb --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1827500.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1827500", + "hash": "00000000002e6ec32020c160a205314eb7646170871ed96e087e21f79d0e211e", + "time": 1664602807, + "saplingTree": "019fb653789bc45e8ef60fe2f657cea80bc835089532652cdcc3ecd637fff37f6d001a00011beea3559174bd9611c5ae3b7492b48bd391a994f418ed56bfae625a2a251b5101abbb8acfc1ea7a2042bc3e022317b05163dd452aa1ebf20dad24fc28c11197170122da960988f7ce15a31ca4d983c99e096c367e8bb937c1784c1b9fe7bc3daa60000124e4eaf466a658118e62307b6e5a8d1f41bdefdd20a312e992060ac8be16866f000000013f2bdccdc5efd952aaad933a00e34af7104b492979988d3a05e7c2460518881000000001b1fcf215ed122ec3fe2a7d939c358571465c971173b178de878c89c6cb969f6000011ed08164a8db56dbd04cad0b6d5cc0db6f2145cc9fc003ccb2094c70a925662500000001505fc602840d05f9586470bb490afbccd86fdf5ac4d0e77e5a9449524dbb732100000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "0128e91d3bea4e0e5075ea8443ff7d9e77f02f2eff009ecdf58782d6202b129114001f0000000001b801335384470e47a439ba9259062f0e914e7cb667fc44ef2af2259dd74a2a1f00016b684c958451f62a81ec79ea5f2ba03b65b2ae0b104706106946d9e396d4553201f7ed8044b12ec079446e47659a8ef170aa7cf0efc323bea8b8a15a336e41941801b4922700d16f0f31fe71f7f0ef427d550795351260b03168725da632d307081a0114b1074e3c2ee621a922a0a60d2aa74573be0e0387d5df7e53c5592b04e5fa0401d5cf6467ad8e2adae024a94ceff61d195410229ce80ae604a8ef66c5c222100d000001cb1bbbee0c509595b73a98bfd941691cddd4432d934207c2d015900dff7d7618000001f20860c3563401082d950e84fc8735d8925677da13f40f6cd7a38a8c0198d60801aa1af2205aa6e2d1dbacb3b0ee2113a8bd8ab9bc326e82c1d0f412517b882b2a000118b1d1d9f37857fd4b5b4eb5fca3d9246d9af2ff57dc556456777486cd8a943a0001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1830000.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1830000.json new file mode 100644 index 00000000..f37840c1 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1830000.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1830000", + "hash": "000000000004def347efa56ae1f4fe002a2a07ad16ca936ff6aeb4f41f3ec0d9", + "time": 1664791147, + "saplingTree": "0178aa88a229972f3f73511e2dbb786855d80fd65f75c0127f3bd4092daaafad0d001a00014d6a6a1d3c1b045c69c680050bc919d86792c2ba284155c198c032d553eb4900019c99d10c165d8221f235330241652a5fb301cdaf2810b15fc420cf914ef9495e0000000109ad606535d23460ec3ec992fa297618128847ff33b05984550e1c47404dbe0900000001cbe7b575c0b2f73f247dbb0cf0f624e465a8afe418d4806fbf1e7855e08fd029000001b1fcf215ed122ec3fe2a7d939c358571465c971173b178de878c89c6cb969f6000011ed08164a8db56dbd04cad0b6d5cc0db6f2145cc9fc003ccb2094c70a925662500000001505fc602840d05f9586470bb490afbccd86fdf5ac4d0e77e5a9449524dbb732100000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "011ad796243f725e67de2145997c30f3def6b7efb15f721327a27790a47773d119001f011da0e512c975812b0923b71f7e43c893d27c70cb2d2d396130d0f516c907aa2c0001d9ca3845b8eff9f9f87091d368282a6147e79b1cdab855d3d77968c78ad3aa0301a0d3959c6722d9dfd0f452629e4696d34167c1dbe0b35f79ba8f13aeb688d00d000106e7a8d22f77f6a3dc8a445beb9aaa29d03212bcf082d2473c4ff99a81596128016b684c958451f62a81ec79ea5f2ba03b65b2ae0b104706106946d9e396d4553201f7ed8044b12ec079446e47659a8ef170aa7cf0efc323bea8b8a15a336e41941801b4922700d16f0f31fe71f7f0ef427d550795351260b03168725da632d307081a0114b1074e3c2ee621a922a0a60d2aa74573be0e0387d5df7e53c5592b04e5fa0401d5cf6467ad8e2adae024a94ceff61d195410229ce80ae604a8ef66c5c222100d000001cb1bbbee0c509595b73a98bfd941691cddd4432d934207c2d015900dff7d7618000001f20860c3563401082d950e84fc8735d8925677da13f40f6cd7a38a8c0198d60801aa1af2205aa6e2d1dbacb3b0ee2113a8bd8ab9bc326e82c1d0f412517b882b2a000118b1d1d9f37857fd4b5b4eb5fca3d9246d9af2ff57dc556456777486cd8a943a0001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/ZcashLightClientKit.podspec b/ZcashLightClientKit.podspec index 6b23ca6c..5065b776 100644 --- a/ZcashLightClientKit.podspec +++ b/ZcashLightClientKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'ZcashLightClientKit' - s.version = '0.16.10-beta' + s.version = '0.16.11-beta' s.summary = 'Zcash Light Client wallet SDK for iOS' s.description = <<-DESC diff --git a/changelog.md b/changelog.md index eacab72e..8af5cfa5 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,16 @@ +# 0.16.11-beta +Checkpoints added: +Mainnet +```` +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1812500.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1815000.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1817500.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1820000.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1822500.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1825000.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1827500.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1830000.json +```` # 0.16.10-beta - [#532] [0.16.x-beta] Download does not stop correctly From bbe5a577d550c3d7d672150c134c21f75d5624a3 Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Fri, 21 Oct 2022 18:47:47 -0300 Subject: [PATCH 02/11] [#572] release 0.16.12-beta with new checkpoints --- .../Resources/checkpoints/mainnet/1832500.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1835000.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1837500.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1840000.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1842500.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1845000.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1847500.json | 8 ++++++++ .../Resources/checkpoints/mainnet/1850000.json | 8 ++++++++ ZcashLightClientKit.podspec | 2 +- changelog.md | 13 +++++++++++++ 10 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1832500.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1835000.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1837500.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1840000.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1842500.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1845000.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1847500.json create mode 100644 Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1850000.json diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1832500.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1832500.json new file mode 100644 index 00000000..1962899c --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1832500.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1832500", + "hash": "00000000009e1bfb5c6b2bd724c919a18596b29c5ac48a30be29754fcdf001a3", + "time": 1664979856, + "saplingTree": "017d35c8b1fe8353fa65b77775deb2a25db4e77ec8198500f3223a4bc3e64d5231010f05785c5acaf53e4e9586000f41bab3048bde42771298e85867c008107a57261a000119d3ef4ec7b507059f4ca2741c339ea4307d50b9ea42616971c030f522390c4f017bb7a761d76618f986273f4f052493fcff21b58666f0b22b5a978281050967570001c7d62da2c0e245bea72e2cc622f03a7cf05905b1fea13f0a4a3b84bccf6134700001c268a889c7578fc7f6f180169117421eac63a993cb5c4608df4d8bbda061f263017119f88798b428978de3d80bc5520861a9c6c3eaaf0b432eadebaa9f2135da280001a712a6184599a51e8aab9749c1c6cc590ec2e91943016143571a6ef5d136164801dbdd827172d09d214ff210c063240e21e3b326c033771314438ecf82b56fb1490001f8bcc88bbd4826d499fb50b5690ebcbb4bf13e8fa94326d7766985c6fc75e7060170e7688fe48251420d10d5e3c793dcc47d75d7994ebb248831f0cd0743bd7f4d000147c0bdf0b09ebcb0ea103f80e6cbe9b02984c2ec7c0523feec25809d4ad599610127c9b9938654aa0663abda2287bfffe3cc54937995c245d097f740153b65012b0000000115e1f20e49fb7935b31b20ea4ee150567e407cfaac8ccdb01048822e64049228000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "018c23927dda449704b1aebdbd99b8c883fc18dc89b9cf843112596ecefef72a19001f000001c039a9bd13c31443457ee252c77b24a80e12c105a81275af484494d43e254810012a442d12b5b33755b5593a64c6844a9a382dc453944bd7f2901909c0febc071e000189302d6ef7e07804db53b968c9751b8bf9a4780f81d81b3d42ca5b2558541f32012005aa830beee12f6906f73489c2fddee52f1a75278a6ac31f8b2fe678c599380001439e5950a544b0ac1967c73130044b57ffb7bf11fb35126fcc632318f4b8cd0d000001886e2f44043fe89abad72ba1543ccd920ad9455e13d8aeef22f783f757dac92101d9ce8e05739fa694e98cdc0f3e0947944606dc5cbe143e30e90e77725aa5321c0147b69b1780056e107c2169154dfad1afd097fe1c12f61a7e627c3fb627a10d120130f9e5f272c54bff347179b604867bc9fbeac88313c3351f89e55c641acbd33401b8d5dfe4cc3065beafa9b04aa3a8009104f7df8b340169e397d6d59673344d070112c5b16c486f2d31e33b79cbbc4453fe52a373e5d7dad19e606bd21a188e88300001b7c55911e9d02efe6a9644edb48e603699a68a9b370fae484ea8af48772ba9340118b1d1d9f37857fd4b5b4eb5fca3d9246d9af2ff57dc556456777486cd8a943a0001020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1835000.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1835000.json new file mode 100644 index 00000000..d4b5ae56 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1835000.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1835000", + "hash": "0000000001103df2732af30631a2f49c5ab605554e9fe2c38f4651e3291ea9bd", + "time": 1665168048, + "saplingTree": "01074ebb332b5fccfed914dfc1a202b5d2a9ddfc114a1e02c275f5750f54238e0f001a0149e6a8d59b2acb7a2f1d9bae9907cb578b2b15e204db734d869ff01f2dbbdf39015a05e3ce4f28e6d8973dc26e4bf56bd40f8d2f2d97fd66217597bb6084508c0a01648930e7524412f434f42b61b6573edde1a4627c3bbab2648379cff9c886d40b0000014b5219957d0a9a35900e4ffb8ade76b2fe962c4ae4c331ff741ce893234a3f1801283589a038b24c537b3fa1db35951586c1c8f08e0c7e7c9d333fd2b399e108690001a25a1c53d083ba71c776cb1fe70d9dfef04786cac96c640c2c0fbbf833028f560001dde05573b84e569e7dde13ba5524abd8d71cda8c3f242c5f5c320fb581db22330000011e83a98f73bd6bb2fdeee9324c0694b295ea1da95f64abf45398890fd476fe5d016c3ab232b9106e87602df81d84416223e173cdbe325158ee7005fe37cbea293c0001e17cfb9ca8a03e9a702563f4c2cb66c4439498c8ae5846b9a750a597e79b4c6e01843bb589116c1fdda2027c517ee89c434b801d141011844df24147eb040b5d6100019b81ed79d6c2b55e902decee63ed1b1c26df85d9c814a74d4e053aba8f8c36560115e1f20e49fb7935b31b20ea4ee150567e407cfaac8ccdb01048822e64049228000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "01488b69c6ae788b6e70812a1662a86df617e9e1c90ec1103aea126d9b77b1322c001f01af126999194487703ca8c7ac015c2cb228538638c9252504903792ab73f4963901e81d8e5b63692593a5180ad6a0e88b44c89b64188f695f63ede66a23f89c65260121f6819a12feda45cf97805120596d3fac5ac133dbb270d5bba2389c598278380157b4834291d7e1fd8fdfce1c2d2594e0e894da3e763b301cf10be71998781f11016ccf9fabf4a575fd371dcb121aa505531b5e09383f4831cbd1b8a07845e91314019d07c968c2b776bf4a81003640be8e36c2736d8b3109564e8cdba8146c78be1d014e53816914b86c5fedab78f38a29c842471ed8b162c9a8d29baac4fe599cde3b01fe3b2f92c9c33cf1b872df89abe09ede252fd848e5c2a93f08f7de4a64070a2001d4a3bd717758b2f5a13d23d2d88526e723259764b640aa8a0a564fee754061050000011fd00a10523c934360f323e75810931fc2f02423a144323dfeebb3773f93d33e01b61c124cb2dbac265a0a93236793532dc850731022e87eeb335837261b84500000010278ad82f36c3eb59257919611ca46d8f752518954fd259315495cb0d3d39e37017720873c334452d2e25834e13f33a70495462e5bfd35ddc3682a66d35aa6a90900000000019038c488e9bf16e4cbea3f12d056e2db48296d81c075f314b40542b1a21dcd2401020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1837500.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1837500.json new file mode 100644 index 00000000..373e2361 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1837500.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1837500", + "hash": "00000000000f877e2a531cc93bdd3131bfaf3b0c05c64b225407f29fd09ef4b7", + "time": 1665356771, + "saplingTree": "011e47f9e3c4b031d671196398bf1dcf16b1a136c5d3bff1522622e1a8cf72cd67001a010eab6056ec7a976f9d49e64af89b3968c0b09d1425ef80bc9013bd3ed9174d660102624a22664951600d137e99b0eef3ffac30b10cde98ade7dd72b896c0b2315d01ede04410d2cbbfd48045108b2fca80857331a059bd735621c8b9129a63ce6d6f000001de1b5fe2626fc7faef37e3bbe82d8629cade50e7808d9fdbf91d08e95feeee16000000000116ffa08dc733175d806958ca7043714802b4c7e36479f686ebab9d7971f24c04016a220b9d29ae06cc77a9b288fc6461d54442c6b9a7336b7b0bd6ca602da7e2690001f91d5afaa3997435b65ae3dfdddfc943cbffd40bb480f936bb28120b8503146c0001654a9c702e5e09cfa0bf35e03e2214c53c346006c7ed7fdbedc3459b14000958017ecdd8bafd85940f76c4d4355dd78e76649ff32f18334c813e5053ec57474e1601d91eb3d1fb1b40ddf6cda125ec8f9340d6a804a53fb842f54088eb0d686c3b6a019e925ac0dce1bdb9f4b8564bd9c7e0413c61f2229749bb4fd1aa8cf3c99f7a61019b81ed79d6c2b55e902decee63ed1b1c26df85d9c814a74d4e053aba8f8c36560115e1f20e49fb7935b31b20ea4ee150567e407cfaac8ccdb01048822e64049228000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "013af54fe790ea1acdf876302eca0e919d10d2add04d914fd592e91655c1f69a2d001f01991b7c0d0944a24478dc16c86924171a6203ce543433c5467272962dcc07523201b756ab3d547f0b1150af4992edb67eaa64ca7b48cb3a169b87c09da4bcf4661601e1b4ecfc1855f4cfb68f5eae6734714e1862e1d369bc9f3b00322be5973370090145b404daed53f95be97ea912c067fec2858cbdc09f70143764c611877eae030d011fa2b687d8456263e12b2949b6d079a55d4c55dfb0f85e153a6645707dd9e01301e5f09ecee154fe022b8e8e0bf06c21b39734723b69a952e075eca0a1dc1a611801b13a0640abc81d688c0c55943945ff680ac514ff8ebecef1dcef86e3768cca1400016ea52315040cfe27c15034c18b2a20e8679bee0fa40632d86cec84082310a9160001414c1227bfa2a90214586a740c34143e095ada26e3554225348ebdedd7cf422400013351bfe677ae28702c7083addefe2057f9561857710c0a0be9bbab8de4756a38011a7e755efdaeedcce837096200c5fd636ca4eab9d8d254d88b3a185325ee9b200000000001d83d50c25ac8bd6b3d7ea1683a59b18771c72d85b43641652d84e319d8be720d00019038c488e9bf16e4cbea3f12d056e2db48296d81c075f314b40542b1a21dcd2401020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1840000.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1840000.json new file mode 100644 index 00000000..a5dfa3de --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1840000.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1840000", + "hash": "0000000000223fa66e8eebb3be09c7bc1e327018c1bfab8bc87a1ac4756b609d", + "time": 1665544594, + "saplingTree": "01857ee7416e6ca3a65c590a912e48648f9ce87ccd1cdb162cde4c8ca5aee2031a001a01e7bb2d86ffb2cf2634fd532e70c529dce92f891ca69d18d32a015f47153f891d015e330e7e1e3214e1cbdd5e85fdfcc39178d74e75a48b4c68dfa36ad9dd8b3005015a1d4f4a559ec1afabbd8e6f88db90b98d609be056c8b9d7c81fd5e63bc5936d016312886e35fd2e65eb758fd077d94d20f6089f53bafab72af633935d3724490301af79b49472899af91e9c6946eee90aac52443a444ebdfa12f1525000916af5570125ff259f5af38bb899502dee5dc34ac14532f847d15a608c5bff2b0e5c4dec24000151360605e535fe2265c67dfe962ecd1b8f071b28177f6ee6ac98369218d1ee4801b984ae125de01fc0f1acc745a7d2ed4237f7c4c6c3ad45ff866ca6954c7bea5f01325df68fb084fa513051a9ebcfabb543055c4e7799b9eb87bf501954e21fcc7100017429a77956ae1275402a408ee286d4927f57ea4073ab53d8f7dcf2f7f760822501b877a72312b8ca0c0d0d00408706e6014d8e291499ba1bb2da7e99167fec49590001b085695ecfea237f02fdd97e66641c19f82146753e23e8d0a50227daf7160e4501654a9c702e5e09cfa0bf35e03e2214c53c346006c7ed7fdbedc3459b14000958017ecdd8bafd85940f76c4d4355dd78e76649ff32f18334c813e5053ec57474e1601d91eb3d1fb1b40ddf6cda125ec8f9340d6a804a53fb842f54088eb0d686c3b6a019e925ac0dce1bdb9f4b8564bd9c7e0413c61f2229749bb4fd1aa8cf3c99f7a61019b81ed79d6c2b55e902decee63ed1b1c26df85d9c814a74d4e053aba8f8c36560115e1f20e49fb7935b31b20ea4ee150567e407cfaac8ccdb01048822e64049228000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "01711e3f4649b675556aecdc4d6658edfee8a99ed3dacae944fc7b385206545225001f000169bc9b81ec14c51edc88e8120c0a7a8238e2a46cb50290e42df86446c6a61a0701274bf921b871c04f28cbdc43cc64694a3c2036a19e4a46bb0b423625cb4f9c0d014ccebdc56f1f516893afd6179b6d319c25bf9e83071ffdacdb4e10a249c5c826015bd9fb52cb016acd1726d91cd99a6cfd5aff846be7d58e3dc11499d42fe8fb32019ad2de520c6ab6761b6fbe75dced8c3b81ce839d30409c1d57f00da42f17a11a01a8ed9b5c8fcd08aa77346029799e0925878bb5e63d6abe209685469fae120401000177de1f17aeb5b0df31b6dc3456435bca969ce2765b645ba256ccccde9244fb36012e52dc44175af3cf903cbb53e47a441590b142a3ecf50bab08a214945f1cd13401917e41edc5417a71ef857fef69f81179fc2e8cb782b2467a73dfdc87f5cc283900013be7f41ae067ada4cbfa2e36c364a51e62b552a7a74ac79f4cd093524d4c0c1200000000019194605343086da1d812d5c0ebcbf1b933523e156b4c542d728b573f9a2b51240001e08fd3be67691a163c5d9b379dee67aac66231338d337b1847d414d0405ad109019038c488e9bf16e4cbea3f12d056e2db48296d81c075f314b40542b1a21dcd2401020d51b05be2e276efa73f2977f5a82defed553b1086897f0bea9b03f4dbd41a000000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1842500.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1842500.json new file mode 100644 index 00000000..a7d8b817 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1842500.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1842500", + "hash": "0000000000399a69b0beaa3320c1bfe61dd7f1b52bf4af1d2fab28694588966d", + "time": 1665733194, + "saplingTree": "014bdf33ed5c693e6a988ae5e315f359951f4350c4c9238a118fc52e4fa6df2e42001a000001375fb8ee8454657a07dd02e27cbbc5f2ef316f90c749d613ff3f93721fbb4205019cf68f5059a52c45184065cfdd351d5ccffaa89eab1c9416e5ab41966b11a26f0155d7d639da967d62403f5b60540d2fdc8b618fb0f31b1e40bf05bf7445d0355e0001ec927b4bc50f2b366446ce51699b70f8cd2b6841c08ab138a87e4c2f095f7d4e01d0f7bfa7f5dc2bc9e02da593effc8f7690f9c59ef631c5e970d67982dfefb6400187b091189fc6be68385778ba02e46a9f6beb52ba43e340a3c326d6e8afc1442c0001c36f357664a4f98e64de8a3589df8ba9eab6c1456ad76f009669314478b58544017429a77956ae1275402a408ee286d4927f57ea4073ab53d8f7dcf2f7f760822501b877a72312b8ca0c0d0d00408706e6014d8e291499ba1bb2da7e99167fec49590001b085695ecfea237f02fdd97e66641c19f82146753e23e8d0a50227daf7160e4501654a9c702e5e09cfa0bf35e03e2214c53c346006c7ed7fdbedc3459b14000958017ecdd8bafd85940f76c4d4355dd78e76649ff32f18334c813e5053ec57474e1601d91eb3d1fb1b40ddf6cda125ec8f9340d6a804a53fb842f54088eb0d686c3b6a019e925ac0dce1bdb9f4b8564bd9c7e0413c61f2229749bb4fd1aa8cf3c99f7a61019b81ed79d6c2b55e902decee63ed1b1c26df85d9c814a74d4e053aba8f8c36560115e1f20e49fb7935b31b20ea4ee150567e407cfaac8ccdb01048822e64049228000000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "01bcf67b86b55901731268ecf83eb2beb10e6da821b7dfd3935ceb69158aea8917019961f93887986e00acffb5b59ed5d6b1d33a13a1473f0cd2e1f3aca973b22c011f0124ebf2c03ee8a2cfc6124a8815843d8ee7a5859273dec9470296dfe2b2ab1728000001785aaade10d232553ed944f61426321e4745b3d2eeb52688a891d8e901e73204000000000001f3749ea86fc0e833fead5d9909c6bd3ccfb83fdff02760bf3f2c3cdff7c1d4340110136ae02b4a36b3621b64626afa6429b5db7277339095550ccfb8610da2420b01842da7ac0e25d444be6e4daa6e453a318b0714772d1ecf15d90b1ef38f6add34019ac96beaa59b7ef829d5ef4d11ed0ed7e2bc4e51ec6d3eeff2103ad848fdad370000011ab64a94431fc2840d761fb5dbf86378b3ad42eca6f64b12933612902644c334000000000000017912a4e2f4dcabdba64cb381a3df33406db480a480c9f3dcf8a5c509804b313d0000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1845000.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1845000.json new file mode 100644 index 00000000..98b3f2df --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1845000.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1845000", + "hash": "0000000000f5a2bc3b7762af88801f728bfcf288f68ac69b2a18b02076ca9794", + "time": 1665921106, + "saplingTree": "019d26046a50688bce14a0bbeb3aa444e22b5066998d42096c9d6eb911f2d9644c014f0e283b0d6e51929d2aa241a7a141927b88e852af11d8026d6b69fab50165561a0000000001aac99b0ff1e97f054ffb6abfe5ec682f8de5da53af12e100fa948ce0e8d7b84101a2a93738fee0ac3b6824b92ea32180489ded0c686a33544fe6650724e2cc0b600141d4dd8f4facb551081238fcc162ef666e29213135ec6465791eef6b08c011350000000001f94055447c1abde88173bebd79f038fde41fe4f68cea5baa49c7ff7ee3039445000000000000000000011619f99023a69bb647eab2d2aa1a73c3673c74bb033c3c4930eacda19e6fd93b0000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "014f38c1948feb179123d524a41a3311b4bc9c8f47b85026ae9ba2f843f7fa7018001f013889806c104d4c33a7b7b0f9258705cf10d76e3137c66537979a817b522a3720010fcc558250f53bc348213cd9d413a3d40d802eea0c9202202454ad7e4b464f29011d42da37e66d92f52554d80379cba8119576caefd4dbfe0a1ecceb089a270639010b6fdc8c06c36e15efe0f1fa69f1938c01814bb687dcd3f7c487d7568dc2e93c014f1ffa059a7ee1a3613a5a89c484bb86e0ddc92274ca0c6bd6f17ed04f32f02f0174fe3be65cfab7ee11e1356574dbcc6d9d6565d893618ed0f7ed9404a6705b0c0175b4f51d12f0b59cb8681c55128d49cc99da012638ad3dc3cc8af874e0261116010b1f7300abb2d54774fd91490b7557808cdb20a221abb6f800e60bf8815f7f1a000179a838662e881000a097029323f10959e6b2ea6bde92a5699c61b91cc7c5031801fd0ef4d4a41eea63029c8d4b10ba03b4731b8d6b74eccc8ef38911184bcbcc1e0111e07e142952f8c5822186f5a2b49cdd82c343f7cd963c72212bec368ccc550d01454191efd5452c67c8131f8b6be5ff8bd2fe281b22bb6208860af93cb1c8eb3801802ed7757badfc6f1770a5eeb3b7de0764c2fa47cfe88935e82e3b96797686130001c85cff1cf283d1185df96957ba7144dd39c1ce3cbe8f2c9751ca7adc1a38d5240001effece4db23774e28a0d2b5a4186344d564bff1fb33b0328640aa7b8deeba1330191e0f307afd0eb763ca3e38e501bb22825457000c7d5e26a1f038da44110480e000000017912a4e2f4dcabdba64cb381a3df33406db480a480c9f3dcf8a5c509804b313d0000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1847500.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1847500.json new file mode 100644 index 00000000..f47612bd --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1847500.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1847500", + "hash": "00000000015111c7f227c28f8388276950a2620ed1e45b5fbd1d630e1d496c34", + "time": 1666110079, + "saplingTree": "01f0f1dc7cc3b35e13ea03581cc9c10551bdc6663f87ece9ff8d2f1401511b993301cb658fc164c9fe6de844c72fc111f0bfdd208653a0b9226e5878a747f4dc6c6a1a000000016bf21d8bd0ceca9cf6deb036fc284b8c331bf926363172edfd61fa95c782ad0c00016f48c06ff0a773902c689003f9ffdefe10329bd957f04c79cf3e18ad4b1224350000000001bc8b862431d75642d34ee03c642dad35c3048582036781f8614d24e8b050d40701f5e7a27e93dd3e86b4cbf4be383df45b1394b9e6cc9bee489a47b775700b034f00018ef950dc76c9a46c255c0b68bfc2e997d7c94b94dc95609da2020ce448ff81160123d4b12c4de65c87bb2b4d7ea7716c279202d8af8a612d6882d72b173a8ce863000000000000011619f99023a69bb647eab2d2aa1a73c3673c74bb033c3c4930eacda19e6fd93b0000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "01efbdf8d91ddbe82aea16f8b95c9b9cffa38ba4bea58feb734ca9fce899096712001f011ade282ecbbf3fc17d4d6479d4fc3d5f761f7038f1f1b5d822587eb442adf720000001529f257d7869d9ece35f6bc089cb4bff0477e7027c8b5e1c2186b206778bd8150123d376274cc690625117ecbea0c3b5910d880331088cb4c450a03427091410360001e410649cda393f50729ebe137bffaf7c559dae2ea82d5712a6cd2b058e330f1401d80ea561a8f13ab5beb9f08c43056ac3a96eccb2270ed11876b4d98587eb7722000154b687eb1d5a6230ec29e587b7aa025cf1ca1c92ceccb31685ce37606c6f611900019859858dd37ae0f62be01bbb976106c7ff5c716c2220e1a674968f88d4a84832000001719bf63ec1d2d116dc1f78e20819408e7e03c0cf7c60ad90180bfb68be32791b015a96543adf51a9938c770417dd7815501251033f1d3fbb08f036cff15615b909000001382eaedd95be3cd7bf424f0b2992735fb542d4dd5a8c8c2e3d76d20e3cd0f6300104e9e9ad2aef9cef887765208a8bca0da58543c1a3bde7bcc88c92280bd2b30b0000017912a4e2f4dcabdba64cb381a3df33406db480a480c9f3dcf8a5c509804b313d0000000000000000" +} diff --git a/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1850000.json b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1850000.json new file mode 100644 index 00000000..5b4e55f8 --- /dev/null +++ b/Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1850000.json @@ -0,0 +1,8 @@ +{ + "network": "main", + "height": "1850000", + "hash": "0000000000801f2c54b8fbe2f90496ea9dc0c0c992dd44d465c0ad3254d08066", + "time": 1666298056, + "saplingTree": "013778854e8aeb653352d1012fbeec74549c339d74332744820bdb5eb0d173636d001a016550aebcf982e60191e22ae349bfd7af0343e63f52b2d0648090ebc92feb575501c1b5e06a96ff169650015725ab9f1320eaeee71de34ee0b353792a690548d240010a977f9695ccffbc6dd1d8f8add32fb6295104bd4efc0deb7841635657b4f6720000011edc84073fb7e5428d031ef7d2cf71da367b04b641d1beae3d942900e070c3130118edb07e8e3de97cba932b09ca0bb37621aba1047dddb8b0a707751d9077f00201c237a7fab2a1339da31fc1155560929ea6c0a1d15b697908feb2f208665c03220001a43ecd6cd81187462b72251758504ce86cd69b77b2db3707280d354fac9a863e00000161809ba4619dab88fb42a8af5bb1f2b8f6dd5a48bbd8ec37482ff400c9e59f3c010dc073684263cb36b4cc1392af7287bf691433a7018f3778a49478a83d6e39050001d1020dfaef715ebcdab3a87327ea51ff75af24daa0ee45738941c69c2f7d225b0000000000011619f99023a69bb647eab2d2aa1a73c3673c74bb033c3c4930eacda19e6fd93b0000000160272b134ca494b602137d89e528c751c06d3ef4a87a45f33af343c15060cc1e", + "orchardTree": "0142b513693c44e6ee3190620981368e394cf8ff366e174465bc9dd395c2cd7829016a488c69835a1a8443faeef51d678b63171063e53537eced682ca1fb228bfb371f00011f1bf47c60b0bfbfa7855625fc32b2f9c8193d771be77ddae5812deb2e11332d017e11bddb81f36691aed35d7924c571d9720013bc64934abf6b414dda6e8a711901cfcc4f4e287c41afe7dd46df23732f55e1118c062aa48644d3791d5c9774a50601dc1e5280c2619a5e8cbe56de4c943c4fc7892a9d3dc98c3722ea50ae88c6023c0001405cd14f0159b70e8c5cc3af59ef9103dd7d37bae7ace2b53e8565dfeb460f0b014b39bca2a42615434bdac8042f373d5c5874025d99fbf1b34702dd6e46e9c73a01e5744f5c39d2ad4b6c57dee68097bc0ef3148b2865689376a70c6187d0559a26010138877a4bba42daada8e17045a8205cc89993d8167271c83de50c57943fe23c0001545921e1a8e2149f83c0edbcc76f803fd72b55a9554b799a72fcc201b8ac413501e13a71fdf4151f7e1ea31fb333c3a71a40c3488e6c1773f277ecac498a3f00150105012c93c4325d8c302d78ab98b206742504d14354e97a1c4f1b4c7b9804311a01d37e48d4f74c5d13ec873ec09680f556732a223e3173eb9cc377aba8bed86e15000001616c27d1588b1e06f59e6d53898217e11a4a66749d1682168dc4d1af7df7e10a000001ca59317d757278a838b884b284b60aa986c43a1324e394312ad3b2203759651d00017912a4e2f4dcabdba64cb381a3df33406db480a480c9f3dcf8a5c509804b313d0000000000000000" +} diff --git a/ZcashLightClientKit.podspec b/ZcashLightClientKit.podspec index 5065b776..98e26609 100644 --- a/ZcashLightClientKit.podspec +++ b/ZcashLightClientKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'ZcashLightClientKit' - s.version = '0.16.11-beta' + s.version = '0.16.12-beta' s.summary = 'Zcash Light Client wallet SDK for iOS' s.description = <<-DESC diff --git a/changelog.md b/changelog.md index 8af5cfa5..6f3e125a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,16 @@ +# 0.16.12-beta +Checkpoints added: +Mainnet +```` +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1832500.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1835000.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1837500.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1840000.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1842500.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1845000.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1847500.json +Sources/ZcashLightClientKit/Resources/checkpoints/mainnet/1850000.json +```` # 0.16.11-beta Checkpoints added: Mainnet From cfe71d5da2b47d31d5f9b5dd53db1566e9260668 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Thu, 27 Oct 2022 12:51:38 +0200 Subject: [PATCH 03/11] [#523] Make a CompactBlockProcessor an Actor (#565) - Sample app refactored for the processor being an actor - tests refactored as well - dark side tests fixed - utilities separated to new file - synchronizer's start and stop are no longer in async context - updating the UI for the scan fixed --- .../DemoAppConfig.swift | 1 + .../Get UTXOs/GetUTXOsViewController.swift | 12 +- .../Send/SendViewController.swift | 20 +- .../SyncBlocksViewController.swift | 48 ++-- .../Processor/CompactBlockDownload.swift | 2 +- .../Processor/CompactBlockEnhancement.swift | 4 +- .../Processor/CompactBlockProcessor.swift | 249 ++++++++---------- .../Processor/CompactBlockScanning.swift | 10 +- .../CompactBlockValidationInformation.swift | 8 +- .../Processor/FetchUnspentTxOutputs.swift | 8 +- .../Block/Utils/NotificationCenter+Post.swift | 30 +++ .../Service/LightWalletGRPCService.swift | 2 +- .../ZcashLightClientKit/Synchronizer.swift | 16 +- .../Synchronizer/SDKSynchronizer.swift | 120 +++++---- Tests/DarksideTests/AdvancedReOrgTests.swift | 124 ++++++--- Tests/DarksideTests/RewindRescanTests.swift | 12 +- Tests/DarksideTests/ShieldFundsTests.swift | 14 +- Tests/DarksideTests/SynchronizerTests.swift | 12 +- .../TransactionEnhancementTests.swift | 12 +- Tests/NetworkTests/BlockScanTests.swift | 2 +- Tests/NetworkTests/BlockStreamingTest.swift | 3 +- .../CompactBlockProcessorTests.swift | 24 +- .../NetworkTests/CompactBlockReorgTests.swift | 12 +- Tests/OfflineTests/WalletTests.swift | 8 +- Tests/TestUtils/FakeService.swift | 6 +- Tests/TestUtils/TestCoordinator.swift | 42 ++- 26 files changed, 442 insertions(+), 359 deletions(-) create mode 100644 Sources/ZcashLightClientKit/Block/Utils/NotificationCenter+Post.swift diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/DemoAppConfig.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/DemoAppConfig.swift index fd589065..1c4a07cb 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/DemoAppConfig.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/DemoAppConfig.swift @@ -16,6 +16,7 @@ enum DemoAppConfig { static var birthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 935000 : 1386000 static var seed = try! Mnemonic.deterministicSeedBytes(from: "live combine flight accident slow soda mind bright absent bid hen shy decade biology amazing mix enlist ensure biology rhythm snap duty soap armor") + static var address: String { "\(host):\(port)" } diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Get UTXOs/GetUTXOsViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Get UTXOs/GetUTXOsViewController.swift index a0ed553c..5db349db 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Get UTXOs/GetUTXOsViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Get UTXOs/GetUTXOsViewController.swift @@ -29,11 +29,13 @@ class GetUTXOsViewController: UIViewController { self.transparentAddressLabel.text = tAddress - // swiftlint:disable:next force_try - let balance = try! AppDelegate.shared.sharedSynchronizer.getTransparentBalance(accountIndex: 0) - - self.totalBalanceLabel.text = NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: balance.total.amount)) - self.verifiedBalanceLabel.text = NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: balance.verified.amount)) + Task { @MainActor in + // swiftlint:disable:next force_try + let balance = try! await AppDelegate.shared.sharedSynchronizer.getTransparentBalance(accountIndex: 0) + + self.totalBalanceLabel.text = NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: balance.total.amount)) + self.verifiedBalanceLabel.text = NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: balance.verified.amount)) + } } @IBAction func shieldFunds(_ sender: Any) { diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift index abc6f62e..fa335309 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift @@ -32,8 +32,10 @@ class SendViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() synchronizer = AppDelegate.shared.sharedSynchronizer - // swiftlint:disable:next force_try - try! synchronizer.prepare() + Task { @MainActor in + // swiftlint:disable:next force_try + try! await synchronizer.prepare() + } let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(viewTapped(_:))) self.view.addGestureRecognizer(tapRecognizer) setUp() @@ -41,12 +43,14 @@ class SendViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - do { - try synchronizer.start(retry: false) - self.synchronizerStatusLabel.text = SDKSynchronizer.textFor(state: synchronizer.status) - } catch { - self.synchronizerStatusLabel.text = SDKSynchronizer.textFor(state: synchronizer.status) - fail(error) + Task { @MainActor in + do { + try await synchronizer.start(retry: false) + self.synchronizerStatusLabel.text = SDKSynchronizer.textFor(state: synchronizer.status) + } catch { + self.synchronizerStatusLabel.text = SDKSynchronizer.textFor(state: synchronizer.status) + fail(error) + } } } diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksViewController.swift index 2e7760c2..8c657acd 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksViewController.swift @@ -31,7 +31,9 @@ class SyncBlocksViewController: UIViewController { // swiftlint:disable:next force_try try! wallet.initialize() processor = CompactBlockProcessor(initializer: wallet) - statusLabel.text = textFor(state: processor?.state.getState() ?? .stopped) + Task { @MainActor in + statusLabel.text = textFor(state: await processor?.state ?? .stopped) + } progressBar.progress = 0 NotificationCenter.default.addObserver( @@ -47,14 +49,16 @@ class SyncBlocksViewController: UIViewController { NotificationCenter.default.removeObserver(self) guard let processor = self.processor else { return } - processor.stop() + Task { + await processor.stop() + } } @objc func processorNotification(_ notification: Notification) { - DispatchQueue.main.async { + Task { @MainActor in guard self.processor != nil else { return } - self.updateUI() + await self.updateUI() switch notification.name { case let not where not == Notification.Name.blockProcessorUpdated: @@ -70,30 +74,28 @@ class SyncBlocksViewController: UIViewController { @IBAction func startStop() { guard let processor = processor else { return } - switch processor.state.getState() { - case .stopped: - startProcessor() - default: - stopProcessor() + Task { @MainActor in + switch await processor.state { + case .stopped: + await startProcessor() + default: + await stopProcessor() + } } } - func startProcessor() { + func startProcessor() async { guard let processor = processor else { return } - do { - try processor.start() - updateUI() - } catch { - fail(error: error) - } + await processor.start() + await updateUI() } - func stopProcessor() { + func stopProcessor() async { guard let processor = processor else { return } - processor.stop() - updateUI() + await processor.stop() + await updateUI() } func fail(error: Error) { @@ -110,11 +112,13 @@ class SyncBlocksViewController: UIViewController { ) self.present(alert, animated: true, completion: nil) - updateUI() + Task { @MainActor in + await updateUI() + } } - func updateUI() { - guard let state = processor?.state.getState() else { return } + func updateUI() async { + guard let state = await processor?.state else { return } statusLabel.text = textFor(state: state) startPause.setTitle(buttonText(for: state), for: .normal) diff --git a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockDownload.swift b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockDownload.swift index 4a78030e..f02b8e07 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockDownload.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockDownload.swift @@ -16,7 +16,7 @@ extension CompactBlockProcessor { ) async throws { try Task.checkCancellation() - setState(.downloading) + state = .downloading var buffer: [ZcashCompactBlock] = [] var targetHeightInternal: BlockHeight? diff --git a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockEnhancement.swift b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockEnhancement.swift index cb284414..98a22d32 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockEnhancement.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockEnhancement.swift @@ -56,8 +56,8 @@ extension CompactBlockProcessor { try Task.checkCancellation() LoggerProxy.debug("Started Enhancing range: \(range)") - setState(.enhancing) - + state = .enhancing + let blockRange = range.blockRange() var retries = 0 let maxRetries = 5 diff --git a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift index fe30bf6d..bd0c538c 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift @@ -103,7 +103,7 @@ public enum CompactBlockProgress { } protocol EnhancementStreamDelegate: AnyObject { - func transactionEnhancementProgressUpdated(_ progress: EnhancementProgress) + func transactionEnhancementProgressUpdated(_ progress: EnhancementProgress) async } public protocol EnhancementProgress { @@ -213,7 +213,7 @@ public extension Notification.Name { /// The compact block processor is in charge of orchestrating the download and caching of compact blocks from a LightWalletEndpoint /// when started the processor downloads does a download - validate - scan cycle until it reaches latest height on the blockchain. -public class CompactBlockProcessor { +public actor CompactBlockProcessor { /// Compact Block Processor configuration /// @@ -312,31 +312,12 @@ public class CompactBlockProcessor { case synced } - // TODO: this isn't an Actor even though it looks like a good candidate, the reason: - // `state` lives in both sync and async environments. An Actor is demanding async context only - // so we can't take the advantage unless we encapsulate all `state` reads/writes to async context. - // Therefore solution with class + lock works for us butr eventually will be replaced. - // The future of CompactBlockProcessor is an actor (we won't need to encapsulate the state separately), issue 523, - // https://github.com/zcash/ZcashLightClientKit/issues/523 - public class ThreadSafeState { - private var state: State = .stopped - let lock = NSLock() - - func setState(_ newState: State) { - lock.lock() - defer { lock.unlock() } - state = newState - } - - public func getState() -> State { - lock.lock() - defer { lock.unlock() } - return state + public internal(set) var state: State = .stopped { + didSet { + transitionState(from: oldValue, to: self.state) } } - public internal(set) var state = ThreadSafeState() - var config: Configuration { willSet { self.stop() @@ -348,7 +329,7 @@ public class CompactBlockProcessor { } var shouldStart: Bool { - switch self.state.getState() { + switch self.state { case .stopped, .synced, .error: return !maxAttemptsReached default: @@ -386,7 +367,7 @@ public class CompactBlockProcessor { /// - storage: concrete implementation of `CompactBlockStorage` protocol /// - backend: a class that complies to `ZcashRustBackendWelding` /// - config: `Configuration` struct for this processor - convenience init( + init( service: LightWalletService, storage: CompactBlockStorage, backend: ZcashRustBackendWelding.Type, @@ -407,7 +388,7 @@ public class CompactBlockProcessor { /// Initializes a CompactBlockProcessor instance from an Initialized object /// - Parameters: /// - initializer: an instance that complies to CompactBlockDownloading protocol - public convenience init(initializer: Initializer) { + public init(initializer: Initializer) { self.init( service: initializer.lightWalletService, storage: initializer.storage, @@ -448,12 +429,6 @@ public class CompactBlockProcessor { cancelableTask?.cancel() } - func setState(_ newState: State) { - let oldValue = state.getState() - state.setState(newState) - transitionState(from: oldValue, to: newState) - } - static func validateServerInfo( _ info: LightWalletdInfo, saplingActivation: BlockHeight, @@ -500,7 +475,7 @@ public class CompactBlockProcessor { /// triggers the blockProcessorStartedDownloading notification /// /// - Important: subscribe to the notifications before calling this method - public func start(retry: Bool = false) throws { + public func start(retry: Bool = false) async { if retry { self.retryAttempts = 0 self.processingError = nil @@ -509,12 +484,12 @@ public class CompactBlockProcessor { } guard shouldStart else { - switch self.state.getState() { + switch self.state { case .error(let e): // max attempts have been reached LoggerProxy.info("max retry attempts reached with error: \(e)") notifyError(CompactBlockProcessorError.maxAttemptsReached(attempts: self.maxAttempts)) - setState(.stopped) + state = .stopped case .stopped: // max attempts have been reached LoggerProxy.info("max retry attempts reached") @@ -529,7 +504,7 @@ public class CompactBlockProcessor { return } - self.nextBatch() + await self.nextBatch() } /** @@ -545,14 +520,13 @@ public class CompactBlockProcessor { cancelableTask?.cancel() self.retryAttempts = 0 - setState(.stopped) } /** Rewinds to provided height. If nil is provided, it will rescan to nearest height (quick rescan) */ - public func rewindTo(_ height: BlockHeight?) throws -> BlockHeight { + public func rewindTo(_ height: BlockHeight?) async throws -> BlockHeight { self.stop() let lastDownloaded = try downloader.lastDownloadedBlockHeight() @@ -563,7 +537,7 @@ public class CompactBlockProcessor { let error = rustBackend.lastError() ?? RustWeldingError.genericError( message: "unknown error getting nearest rewind height for height: \(height)" ) - fail(error) + await fail(error) throw error } @@ -571,7 +545,7 @@ public class CompactBlockProcessor { let rewindHeight = max(Int32(nearestHeight - 1), Int32(config.walletBirthday)) guard rustBackend.rewindToHeight(dbData: config.dataDb, height: rewindHeight, networkType: self.config.network.networkType) else { let error = rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error rewinding to height \(height)") - fail(error) + await fail(error) throw error } @@ -588,7 +562,7 @@ public class CompactBlockProcessor { - Throws CompactBlockProcessorError.invalidConfiguration if block height is invalid or if processor is already started */ func setStartHeight(_ startHeight: BlockHeight) throws { - guard self.state.getState() == .stopped, startHeight >= config.network.constants.saplingActivationHeight else { + guard self.state == .stopped, startHeight >= config.network.constants.saplingActivationHeight else { throw CompactBlockProcessorError.invalidConfiguration } @@ -597,27 +571,24 @@ public class CompactBlockProcessor { self.config = config } - func validateServer(completionBlock: @escaping (() -> Void)) { - Task { @MainActor in - do { - let info = try await self.service.getInfo() - try Self.validateServerInfo( - info, - saplingActivation: self.config.saplingActivation, - localNetwork: self.config.network, - rustBackend: self.rustBackend - ) - completionBlock() - } catch let error as LightWalletServiceError { - self.severeFailure(error.mapToProcessorError()) - } catch { - self.severeFailure(error) - } + func validateServer() async { + do { + let info = try await self.service.getInfo() + try Self.validateServerInfo( + info, + saplingActivation: self.config.saplingActivation, + localNetwork: self.config.network, + rustBackend: self.rustBackend + ) + } catch let error as LightWalletServiceError { + self.severeFailure(error.mapToProcessorError()) + } catch { + self.severeFailure(error) } } /// Processes new blocks on the given range based on the configuration set for this instance - func processNewBlocks(range: CompactBlockRange) { + func processNewBlocks(range: CompactBlockRange) async { self.foundBlocks = true self.backoffTimer?.invalidate() self.backoffTimer = nil @@ -633,13 +604,12 @@ public class CompactBlockProcessor { try await compactBlockBatchScanning(range: range) try await compactBlockEnhancement(range: range) try await fetchUnspentTxOutputs(range: range) + //state = .stopped } catch { - if error is CancellationError { - - } - if !(Task.isCancelled) { - fail(error) + await fail(error) + } else { + state = .stopped } } } @@ -658,7 +628,7 @@ public class CompactBlockProcessor { LoggerProxy.debug("progress: \(progress)") - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: Notification.Name.blockProcessorUpdated, object: self, userInfo: userInfo @@ -666,7 +636,7 @@ public class CompactBlockProcessor { } func notifyTransactions(_ txs: [ConfirmedTransactionEntity], in range: BlockRange) { - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: .blockProcessorFoundTransactions, object: self, userInfo: [ @@ -691,29 +661,29 @@ public class CompactBlockProcessor { self.backoffTimer?.invalidate() self.retryAttempts = config.retries self.processingError = error - setState(.error(error)) + state = .error(error) self.notifyError(error) } - func fail(_ error: Error) { + func fail(_ error: Error) async { // todo specify: failure LoggerProxy.error("\(error)") cancelableTask?.cancel() self.retryAttempts += 1 self.processingError = error - switch self.state.getState() { + switch self.state { case .error: notifyError(error) default: break } - setState(.error(error)) + state = .error(error) guard self.maxAttemptsReached else { return } // don't set a new timer if there are no more attempts. - self.setTimer() + await self.setTimer() } - func retryProcessing(range: CompactBlockRange) { + func retryProcessing(range: CompactBlockRange) async { cancelableTask?.cancel() // update retries self.retryAttempts += 1 @@ -728,10 +698,9 @@ public class CompactBlockProcessor { try downloader.rewind(to: max(range.lowerBound, self.config.walletBirthday)) // process next batch - // processNewBlocks(range: Self.nextBatchBlockRange(latestHeight: latestBlockHeight, latestDownloadedHeight: try downloader.lastDownloadedBlockHeight(), walletBirthday: config.walletBirthday)) - nextBatch() + await nextBatch() } catch { - self.fail(error) + await self.fail(error) } } @@ -766,41 +735,39 @@ public class CompactBlockProcessor { } } - private func nextBatch() { - setState(.downloading) - Task { @MainActor [self] in - do { - let nextState = try await NextStateHelper.nextStateAsync( - service: self.service, - downloader: self.downloader, - config: self.config, - rustBackend: self.rustBackend + private func nextBatch() async { + state = .downloading + do { + let nextState = try await NextStateHelper.nextStateAsync( + service: self.service, + downloader: self.downloader, + config: self.config, + rustBackend: self.rustBackend + ) + switch nextState { + case .finishProcessing(let height): + self.latestBlockHeight = height + await self.processingFinished(height: height) + case .processNewBlocks(let range): + self.latestBlockHeight = range.upperBound + self.lowerBoundHeight = range.lowerBound + await self.processNewBlocks(range: range) + case let .wait(latestHeight, latestDownloadHeight): + // Lightwalletd might be syncing + self.lowerBoundHeight = latestDownloadHeight + self.latestBlockHeight = latestHeight + LoggerProxy.info( + "Lightwalletd might be syncing: latest downloaded block height is: \(latestDownloadHeight)" + + "while latest blockheight is reported at: \(latestHeight)" ) - switch nextState { - case .finishProcessing(let height): - self.latestBlockHeight = height - self.processingFinished(height: height) - case .processNewBlocks(let range): - self.latestBlockHeight = range.upperBound - self.lowerBoundHeight = range.lowerBound - self.processNewBlocks(range: range) - case let .wait(latestHeight, latestDownloadHeight): - // Lightwalletd might be syncing - self.lowerBoundHeight = latestDownloadHeight - self.latestBlockHeight = latestHeight - LoggerProxy.info( - "Lightwalletd might be syncing: latest downloaded block height is: \(latestDownloadHeight)" + - "while latest blockheight is reported at: \(latestHeight)" - ) - self.processingFinished(height: latestDownloadHeight) - } - } catch { - self.severeFailure(error) + await self.processingFinished(height: latestDownloadHeight) } + } catch { + self.severeFailure(error) } } - internal func validationFailed(at height: BlockHeight) { + internal func validationFailed(at height: BlockHeight) async { // cancel all Tasks cancelableTask?.cancel() @@ -816,7 +783,7 @@ public class CompactBlockProcessor { ) guard rustBackend.rewindToHeight(dbData: config.dataDb, height: Int32(rewindHeight), networkType: self.config.network.networkType) else { - fail(rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error rewinding to height \(height)")) + await fail(rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error rewinding to height \(height)")) return } @@ -824,7 +791,7 @@ public class CompactBlockProcessor { try downloader.rewind(to: rewindHeight) // notify reorg - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: Notification.Name.blockProcessorHandledReOrg, object: self, userInfo: [ @@ -833,15 +800,15 @@ public class CompactBlockProcessor { ) // process next batch - self.nextBatch() + await self.nextBatch() } catch { - self.fail(error) + await self.fail(error) } } - internal func processBatchFinished(range: CompactBlockRange) { + internal func processBatchFinished(range: CompactBlockRange) async { guard processingError == nil else { - retryProcessing(range: range) + await retryProcessing(range: range) return } @@ -849,15 +816,15 @@ public class CompactBlockProcessor { consecutiveChainValidationErrors = 0 guard !range.isEmpty else { - processingFinished(height: range.upperBound) + await processingFinished(height: range.upperBound) return } - nextBatch() + await nextBatch() } - private func processingFinished(height: BlockHeight) { - NotificationCenter.default.post( + private func processingFinished(height: BlockHeight) async { + NotificationCenter.default.mainThreadPost( name: Notification.Name.blockProcessorFinished, object: self, userInfo: [ @@ -865,35 +832,33 @@ public class CompactBlockProcessor { CompactBlockProcessorNotificationKey.foundBlocks: self.foundBlocks ] ) - setState(.synced) - setTimer() + state = .synced + await setTimer() } - private func setTimer() { + private func setTimer() async { let interval = self.config.blockPollInterval self.backoffTimer?.invalidate() let timer = Timer( timeInterval: interval, repeats: true, block: { [weak self] _ in - guard let self = self else { return } - do { - if self.shouldStart { + Task { [self] in + guard let self = self else { return } + if await self.shouldStart { LoggerProxy.debug( - """ - Timer triggered: Starting compact Block processor!. - Processor State: \(self.state) - latestHeight: \(self.latestBlockHeight) - attempts: \(self.retryAttempts) - lowerbound: \(String(describing: self.lowerBoundHeight)) - """ + """ + Timer triggered: Starting compact Block processor!. + Processor State: \(await self.state) + latestHeight: \(await self.latestBlockHeight) + attempts: \(await self.retryAttempts) + lowerbound: \(String(describing: await self.lowerBoundHeight)) + """ ) - try self.start() - } else if self.maxAttemptsReached { - self.fail(CompactBlockProcessorError.maxAttemptsReached(attempts: self.config.retries)) + await self.start() + } else if await self.maxAttemptsReached { + await self.fail(CompactBlockProcessorError.maxAttemptsReached(attempts: self.config.retries)) } - } catch { - self.fail(error) } } ) @@ -907,7 +872,7 @@ public class CompactBlockProcessor { return } - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: .blockProcessorStatusChanged, object: self, userInfo: [ @@ -918,27 +883,27 @@ public class CompactBlockProcessor { switch newValue { case .downloading: - NotificationCenter.default.post(name: Notification.Name.blockProcessorStartedDownloading, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.blockProcessorStartedDownloading, object: self) case .synced: // transition to this state is handled by `processingFinished(height: BlockHeight)` break case .error(let err): notifyError(err) case .scanning: - NotificationCenter.default.post(name: Notification.Name.blockProcessorStartedScanning, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.blockProcessorStartedScanning, object: self) case .stopped: - NotificationCenter.default.post(name: Notification.Name.blockProcessorStopped, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.blockProcessorStopped, object: self) case .validating: - NotificationCenter.default.post(name: Notification.Name.blockProcessorStartedValidating, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.blockProcessorStartedValidating, object: self) case .enhancing: - NotificationCenter.default.post(name: Notification.Name.blockProcessorStartedEnhancing, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.blockProcessorStartedEnhancing, object: self) case .fetching: - NotificationCenter.default.post(name: Notification.Name.blockProcessorStartedFetching, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.blockProcessorStartedFetching, object: self) } } private func notifyError(_ err: Error) { - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: Notification.Name.blockProcessorFailed, object: self, userInfo: [CompactBlockProcessorNotificationKey.error: mapError(err)] @@ -1157,7 +1122,7 @@ extension CompactBlockProcessorError: LocalizedError { extension CompactBlockProcessor: EnhancementStreamDelegate { func transactionEnhancementProgressUpdated(_ progress: EnhancementProgress) { - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: .blockProcessorEnhancementProgress, object: self, userInfo: [CompactBlockProcessorNotificationKey.enhancementProgress: progress] diff --git a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockScanning.swift b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockScanning.swift index f85f1b8d..45535ca5 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockScanning.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockScanning.swift @@ -12,7 +12,7 @@ extension CompactBlockProcessor { func compactBlockBatchScanning(range: CompactBlockRange) async throws { try Task.checkCancellation() - setState(.scanning) + state = .scanning let batchSize = UInt32(config.scanningBatchSize) do { @@ -24,7 +24,7 @@ extension CompactBlockProcessor { throw error } let scanFinishTime = Date() - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPostNotification( SDKMetrics.progressReportNotification( progress: BlockProgress( startHeight: range.lowerBound, @@ -68,7 +68,7 @@ extension CompactBlockProcessor { if scannedNewBlocks { let progress = BlockProgress(startHeight: scanStartHeight, targetHeight: targetScanHeight, progressHeight: lastScannedHeight) notifyProgress(.scan(progress)) - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPostNotification( SDKMetrics.progressReportNotification( progress: progress, start: scanStartTime, @@ -81,9 +81,11 @@ extension CompactBlockProcessor { let seconds = scanFinishTime.timeIntervalSinceReferenceDate - scanStartTime.timeIntervalSinceReferenceDate LoggerProxy.debug("Scanned \(heightCount) blocks in \(seconds) seconds") } + + await Task.yield() } while !Task.isCancelled && scannedNewBlocks && lastScannedHeight < targetScanHeight if Task.isCancelled { - setState(.stopped) + state = .stopped LoggerProxy.debug("Warning: compactBlockBatchScanning cancelled") } } diff --git a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockValidationInformation.swift b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockValidationInformation.swift index fccf1fec..f7bf6853 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockValidationInformation.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockValidationInformation.swift @@ -17,7 +17,7 @@ extension CompactBlockProcessor { func compactBlockValidation() async throws { try Task.checkCancellation() - setState(.validating) + state = .validating let result = rustBackend.validateCombinedChain(dbCache: config.cacheDb, dbData: config.dataDb, networkType: config.network.networkType) @@ -30,7 +30,7 @@ extension CompactBlockProcessor { case ZcashRustBackendWeldingConstants.validChain: if Task.isCancelled { - setState(.stopped) + state = .stopped LoggerProxy.debug("Warning: compactBlockValidation cancelled") } LoggerProxy.debug("validateChainFinished") @@ -50,11 +50,11 @@ extension CompactBlockProcessor { switch validationError { case .validationFailed(let height): LoggerProxy.debug("chain validation at height: \(height)") - validationFailed(at: height) + await validationFailed(at: height) case .failedWithError(let err): guard let validationFailure = err else { LoggerProxy.error("validation failed without a specific error") - self.fail(CompactBlockProcessorError.generalError(message: "validation failed without a specific error")) + await self.fail(CompactBlockProcessorError.generalError(message: "validation failed without a specific error")) return } diff --git a/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputs.swift b/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputs.swift index 2e5e5265..1a497841 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputs.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/FetchUnspentTxOutputs.swift @@ -16,8 +16,8 @@ extension CompactBlockProcessor { func fetchUnspentTxOutputs(range: CompactBlockRange) async throws { try Task.checkCancellation() - setState(.fetching) - + state = .fetching + do { let tAddresses = try accountRepository.getAll().map({ $0.transparentAddress }) do { @@ -64,7 +64,7 @@ extension CompactBlockProcessor { let result = (inserted: refreshed, skipped: skipped) - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: .blockProcessorStoredUTXOs, object: self, userInfo: [CompactBlockProcessorNotificationKey.refreshedUTXOs: result] @@ -73,7 +73,7 @@ extension CompactBlockProcessor { if Task.isCancelled { LoggerProxy.debug("Warning: fetchUnspentTxOutputs on range \(range) cancelled") } else { - processBatchFinished(range: range) + await processBatchFinished(range: range) } } catch { throw error diff --git a/Sources/ZcashLightClientKit/Block/Utils/NotificationCenter+Post.swift b/Sources/ZcashLightClientKit/Block/Utils/NotificationCenter+Post.swift new file mode 100644 index 00000000..5193640b --- /dev/null +++ b/Sources/ZcashLightClientKit/Block/Utils/NotificationCenter+Post.swift @@ -0,0 +1,30 @@ +// +// NotificationCenter+Post.swift +// +// +// Created by Lukáš Korba on 12.10.2022. +// + +import Foundation + +extension NotificationCenter { + func mainThreadPost( + name aName: NSNotification.Name, + object anObject: Any?, + userInfo aUserInfo: [AnyHashable : Any]? = nil + ) { + DispatchQueue.main.async { + NotificationCenter.default.post( + name: aName, + object: anObject, + userInfo: aUserInfo + ) + } + } + + func mainThreadPostNotification(_ notification: Notification) { + DispatchQueue.main.async { + NotificationCenter.default.post(notification) + } + } +} diff --git a/Sources/ZcashLightClientKit/Service/LightWalletGRPCService.swift b/Sources/ZcashLightClientKit/Service/LightWalletGRPCService.swift index d3f8828d..d78ab118 100644 --- a/Sources/ZcashLightClientKit/Service/LightWalletGRPCService.swift +++ b/Sources/ZcashLightClientKit/Service/LightWalletGRPCService.swift @@ -417,7 +417,7 @@ extension LightWalletServiceError { class ConnectionStatusManager: ConnectivityStateDelegate { func connectivityStateDidChange(from oldState: ConnectivityState, to newState: ConnectivityState) { LoggerProxy.event("Connection Changed from \(oldState) to \(newState)") - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: .blockProcessorConnectivityStateChanged, object: self, userInfo: [ diff --git a/Sources/ZcashLightClientKit/Synchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer.swift index f48248d9..a3ac5e82 100644 --- a/Sources/ZcashLightClientKit/Synchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer.swift @@ -80,7 +80,7 @@ public protocol Synchronizer { /// prepares this initializer to operate. Initializes the internal state with the given /// Extended Viewing Keys and a wallet birthday found in the initializer object - func prepare() throws + func prepare() async throws ///Starts this synchronizer within the given scope. /// @@ -95,18 +95,18 @@ public protocol Synchronizer { /// Gets the sapling shielded address for the given account. /// - Parameter accountIndex: the optional accountId whose address is of interest. By default, the first account is used. /// - Returns the address or nil if account index is incorrect - func getShieldedAddress(accountIndex: Int) -> SaplingShieldedAddress? + func getShieldedAddress(accountIndex: Int) async -> SaplingShieldedAddress? /// Gets the unified address for the given account. /// - Parameter accountIndex: the optional accountId whose address is of interest. By default, the first account is used. /// - Returns the address or nil if account index is incorrect - func getUnifiedAddress(accountIndex: Int) -> UnifiedAddress? + func getUnifiedAddress(accountIndex: Int) async -> UnifiedAddress? /// Gets the transparent address for the given account. /// - Parameter accountIndex: the optional accountId whose address is of interest. By default, the first account is used. /// - Returns the address or nil if account index is incorrect - func getTransparentAddress(accountIndex: Int) -> TransparentAddress? + func getTransparentAddress(accountIndex: Int) async -> TransparentAddress? /// Sends zatoshi. /// - Parameter spendingKey: the key that allows spends to occur. @@ -167,7 +167,7 @@ public protocol Synchronizer { func allConfirmedTransactions(from transaction: ConfirmedTransactionEntity?, limit: Int) throws -> [ConfirmedTransactionEntity]? /// Returns the latest downloaded height from the compact block cache - func latestDownloadedHeight() throws -> BlockHeight + func latestDownloadedHeight() async throws -> BlockHeight /// Returns the latest block height from the provided Lightwallet endpoint @@ -176,14 +176,14 @@ public protocol Synchronizer { /// Returns the latest block height from the provided Lightwallet endpoint /// Blocking - func latestHeight() throws -> BlockHeight + func latestHeight() async throws -> BlockHeight /// Returns the latests UTXOs for the given address from the specified height on func refreshUTXOs(address: String, from height: BlockHeight) async throws -> RefreshedUTXOs /// Returns the last stored unshielded balance - func getTransparentBalance(accountIndex: Int) throws -> WalletBalance + func getTransparentBalance(accountIndex: Int) async throws -> WalletBalance /// Returns the shielded total balance (includes verified and unverified balance) @@ -207,7 +207,7 @@ public protocol Synchronizer { /// - Throws rewindErrorUnknownArchorHeight when the rewind points to an invalid height /// - Throws rewindError for other errors /// - Note rewind does not trigger notifications as a reorg would. You need to restart the synchronizer afterwards - func rewind(_ policy: RewindPolicy) throws + func rewind(_ policy: RewindPolicy) async throws } public enum SyncStatus: Equatable { diff --git a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift index 2512441b..b84df400 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift @@ -151,17 +151,19 @@ public class SDKSynchronizer: Synchronizer { deinit { NotificationCenter.default.removeObserver(self) - self.blockProcessor.stop() + Task { [blockProcessor] in + await blockProcessor.stop() + } } - public func initialize() throws { + public func initialize() async throws { try self.initializer.initialize() - try self.blockProcessor.setStartHeight(initializer.walletBirthday) + try await self.blockProcessor.setStartHeight(initializer.walletBirthday) } - public func prepare() throws { + public func prepare() async throws { try self.initializer.initialize() - try self.blockProcessor.setStartHeight(initializer.walletBirthday) + try await self.blockProcessor.setStartHeight(initializer.walletBirthday) self.status = .disconnected } @@ -177,10 +179,8 @@ public class SDKSynchronizer: Synchronizer { return case .stopped, .synced, .disconnected, .error: - do { - try blockProcessor.start(retry: retry) - } catch { - throw mapError(error) + Task { + await blockProcessor.start(retry: retry) } } } @@ -192,8 +192,10 @@ public class SDKSynchronizer: Synchronizer { return } - blockProcessor.stop() - self.status = .stopped + Task(priority: .high) { + await blockProcessor.stop() + self.status = .stopped + } } private func subscribeToProcessorNotifications(_ processor: CompactBlockProcessor) { @@ -314,7 +316,7 @@ public class SDKSynchronizer: Synchronizer { } let currentState = ConnectionState(current) - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: .synchronizerConnectionStateChanged, object: self, userInfo: [ @@ -336,7 +338,7 @@ public class SDKSynchronizer: Synchronizer { return } - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: .synchronizerFoundTransactions, object: self, userInfo: [ @@ -489,7 +491,7 @@ public class SDKSynchronizer: Synchronizer { do { let tAddr = try derivationTool.deriveTransparentAddressFromPrivateKey(transparentSecretKey) - let tBalance = try utxoRepository.balance(address: tAddr, latestHeight: self.latestDownloadedHeight()) + let tBalance = try await utxoRepository.balance(address: tAddr, latestHeight: self.latestDownloadedHeight()) // Verify that at least there are funds for the fee. Ideally this logic will be improved by the shielding wallet. guard tBalance.verified >= self.network.constants.defaultFee(for: self.latestScannedHeight) else { @@ -566,8 +568,8 @@ public class SDKSynchronizer: Synchronizer { PagedTransactionRepositoryBuilder.build(initializer: initializer, kind: .all) } - public func latestDownloadedHeight() throws -> BlockHeight { - try blockProcessor.downloader.lastDownloadedBlockHeight() + public func latestDownloadedHeight() async throws -> BlockHeight { + try await blockProcessor.downloader.lastDownloadedBlockHeight() } public func latestHeight(result: @escaping (Result) -> Void) { @@ -581,8 +583,8 @@ public class SDKSynchronizer: Synchronizer { } } - public func latestHeight() throws -> BlockHeight { - try blockProcessor.downloader.latestBlockHeight() + public func latestHeight() async throws -> BlockHeight { + try await blockProcessor.downloader.latestBlockHeight() } public func latestUTXOs(address: String) async throws -> [UnspentTransactionOutputEntity] { @@ -626,34 +628,34 @@ public class SDKSynchronizer: Synchronizer { initializer.getVerifiedBalance(account: accountIndex) } - public func getShieldedAddress(accountIndex: Int) -> SaplingShieldedAddress? { - blockProcessor.getShieldedAddress(accountIndex: accountIndex) + public func getShieldedAddress(accountIndex: Int) async -> SaplingShieldedAddress? { + await blockProcessor.getShieldedAddress(accountIndex: accountIndex) } - public func getUnifiedAddress(accountIndex: Int) -> UnifiedAddress? { - blockProcessor.getUnifiedAddres(accountIndex: accountIndex) + public func getUnifiedAddress(accountIndex: Int) async -> UnifiedAddress? { + await blockProcessor.getUnifiedAddres(accountIndex: accountIndex) } - public func getTransparentAddress(accountIndex: Int) -> TransparentAddress? { - blockProcessor.getTransparentAddress(accountIndex: accountIndex) + public func getTransparentAddress(accountIndex: Int) async -> TransparentAddress? { + await blockProcessor.getTransparentAddress(accountIndex: accountIndex) } - public func getTransparentBalance(accountIndex: Int) throws -> WalletBalance { - try blockProcessor.getTransparentBalance(accountIndex: accountIndex) + public func getTransparentBalance(accountIndex: Int) async throws -> WalletBalance { + try await blockProcessor.getTransparentBalance(accountIndex: accountIndex) } /** Returns the last stored unshielded balance */ - public func getTransparentBalance(address: String) throws -> WalletBalance { + public func getTransparentBalance(address: String) async throws -> WalletBalance { do { - return try self.blockProcessor.utxoCacheBalance(tAddress: address) + return try await self.blockProcessor.utxoCacheBalance(tAddress: address) } catch { throw SynchronizerError.uncategorized(underlyingError: error) } } - public func rewind(_ policy: RewindPolicy) throws { + public func rewind(_ policy: RewindPolicy) async throws { self.stop() var height: BlockHeight? @@ -663,7 +665,7 @@ public class SDKSynchronizer: Synchronizer { break case .birthday: - let birthday = self.blockProcessor.config.walletBirthday + let birthday = await self.blockProcessor.config.walletBirthday height = birthday case .height(let rewindHeight): @@ -677,7 +679,7 @@ public class SDKSynchronizer: Synchronizer { } do { - let rewindHeight = try self.blockProcessor.rewindTo(height) + let rewindHeight = try await self.blockProcessor.rewindTo(height) try self.transactionManager.handleReorg(at: rewindHeight) } catch { throw SynchronizerError.rewindError(underlyingError: error) @@ -691,11 +693,11 @@ public class SDKSynchronizer: Synchronizer { userInfo[NotificationKeys.blockHeight] = progress.progressHeight self.status = SyncStatus(progress) - NotificationCenter.default.post(name: Notification.Name.synchronizerProgressUpdated, object: self, userInfo: userInfo) + NotificationCenter.default.mainThreadPost(name: Notification.Name.synchronizerProgressUpdated, object: self, userInfo: userInfo) } private func notifyStatusChange(newValue: SyncStatus, oldValue: SyncStatus) { - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: .synchronizerStatusWillUpdate, object: self, userInfo: @@ -709,38 +711,40 @@ public class SDKSynchronizer: Synchronizer { private func notify(status: SyncStatus) { switch status { case .disconnected: - NotificationCenter.default.post(name: Notification.Name.synchronizerDisconnected, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.synchronizerDisconnected, object: self) case .stopped: - NotificationCenter.default.post(name: Notification.Name.synchronizerStopped, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.synchronizerStopped, object: self) case .synced: - NotificationCenter.default.post( - name: Notification.Name.synchronizerSynced, - object: self, - userInfo: [ - SDKSynchronizer.NotificationKeys.blockHeight: self.latestScannedHeight, - SDKSynchronizer.NotificationKeys.synchronizerState: SynchronizerState( - shieldedBalance: WalletBalance( - verified: initializer.getVerifiedBalance(), - total: initializer.getBalance() - ), - transparentBalance: (try? self.getTransparentBalance(accountIndex: 0)) ?? WalletBalance.zero, - syncStatus: status, - latestScannedHeight: self.latestScannedHeight - ) - ] - ) + Task { + NotificationCenter.default.mainThreadPost( + name: Notification.Name.synchronizerSynced, + object: self, + userInfo: [ + SDKSynchronizer.NotificationKeys.blockHeight: self.latestScannedHeight, + SDKSynchronizer.NotificationKeys.synchronizerState: SynchronizerState( + shieldedBalance: WalletBalance( + verified: initializer.getVerifiedBalance(), + total: initializer.getBalance() + ), + transparentBalance: (try? await self.getTransparentBalance(accountIndex: 0)) ?? WalletBalance.zero, + syncStatus: status, + latestScannedHeight: self.latestScannedHeight + ) + ] + ) + } case .unprepared: break case .downloading: - NotificationCenter.default.post(name: Notification.Name.synchronizerDownloading, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.synchronizerDownloading, object: self) case .validating: - NotificationCenter.default.post(name: Notification.Name.synchronizerValidating, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.synchronizerValidating, object: self) case .scanning: - NotificationCenter.default.post(name: Notification.Name.synchronizerScanning, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.synchronizerScanning, object: self) case .enhancing: - NotificationCenter.default.post(name: Notification.Name.synchronizerEnhancing, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.synchronizerEnhancing, object: self) case .fetching: - NotificationCenter.default.post(name: Notification.Name.synchronizerFetching, object: self) + NotificationCenter.default.mainThreadPost(name: Notification.Name.synchronizerFetching, object: self) case .error(let e): self.notifyFailure(e) } @@ -782,7 +786,7 @@ public class SDKSynchronizer: Synchronizer { DispatchQueue.main.async { [weak self] in guard let self = self else { return } - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: Notification.Name.synchronizerMinedTransaction, object: self, userInfo: [NotificationKeys.minedTransaction: transaction] @@ -832,7 +836,7 @@ public class SDKSynchronizer: Synchronizer { private func notifyFailure(_ error: Error) { DispatchQueue.main.async { [weak self] in guard let self = self else { return } - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: Notification.Name.synchronizerFailed, object: self, userInfo: [NotificationKeys.error: self.mapError(error)] diff --git a/Tests/DarksideTests/AdvancedReOrgTests.swift b/Tests/DarksideTests/AdvancedReOrgTests.swift index 8d02d393..d8891ebd 100644 --- a/Tests/DarksideTests/AdvancedReOrgTests.swift +++ b/Tests/DarksideTests/AdvancedReOrgTests.swift @@ -83,7 +83,7 @@ class AdvancedReOrgTests: XCTestCase { 10. sync up to received_Tx_height + 3 11. verify that balance equals initial balance + tx amount */ - func testReOrgChangesInboundTxMinedHeight() throws { + func testReOrgChangesInboundTxMinedHeight() async throws { hookToReOrgNotification() try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName) var shouldContinue = false @@ -101,16 +101,23 @@ class AdvancedReOrgTests: XCTestCase { var synchronizer: SDKSynchronizer? - try coordinator.sync( - completion: { synchro in - synchronizer = synchro - initialVerifiedBalance = synchro.initializer.getVerifiedBalance() - initialTotalBalance = synchro.initializer.getBalance() - preTxExpectation.fulfill() - shouldContinue = true - }, - error: self.handleError - ) + try await withCheckedThrowingContinuation { continuation in + do { + try coordinator.sync( + completion: { synchro in + synchronizer = synchro + initialVerifiedBalance = synchro.initializer.getVerifiedBalance() + initialTotalBalance = synchro.initializer.getBalance() + preTxExpectation.fulfill() + shouldContinue = true + continuation.resume() + }, + error: self.handleError + ) + } catch { + continuation.resume(with: .failure(error)) + } + } wait(for: [preTxExpectation], timeout: 10) @@ -132,12 +139,20 @@ class AdvancedReOrgTests: XCTestCase { var receivedTxTotalBalance = Zatoshi(-1) var receivedTxVerifiedBalance = Zatoshi(-1) - try coordinator.sync(completion: { synchro in - synchronizer = synchro - receivedTxVerifiedBalance = synchro.initializer.getVerifiedBalance() - receivedTxTotalBalance = synchro.initializer.getBalance() - receivedTxExpectation.fulfill() - }, error: self.handleError) + try await withCheckedThrowingContinuation { continuation in + do { + try coordinator.sync(completion: { synchro in + synchronizer = synchro + receivedTxVerifiedBalance = synchro.initializer.getVerifiedBalance() + receivedTxTotalBalance = synchro.initializer.getBalance() + receivedTxExpectation.fulfill() + continuation.resume() + }, error: self.handleError) + } catch { + continuation.resume(with: .failure(error)) + } + } + sleep(2) wait(for: [receivedTxExpectation], timeout: 10) @@ -196,11 +211,21 @@ class AdvancedReOrgTests: XCTestCase { var afterReorgTxTotalBalance = Zatoshi(-1) var afterReorgTxVerifiedBalance = Zatoshi(-1) - try coordinator.sync(completion: { synchronizer in - afterReorgTxTotalBalance = synchronizer.initializer.getBalance() - afterReorgTxVerifiedBalance = synchronizer.initializer.getVerifiedBalance() - reorgSyncexpectation.fulfill() - }, error: self.handleError(_:)) + try await withCheckedThrowingContinuation { continuation in + do { + try coordinator.sync( + completion: { synchronizer in + afterReorgTxTotalBalance = synchronizer.initializer.getBalance() + afterReorgTxVerifiedBalance = synchronizer.initializer.getVerifiedBalance() + reorgSyncexpectation.fulfill() + continuation.resume() + }, + error: self.handleError + ) + } catch { + continuation.resume(with: .failure(error)) + } + } /* 8. assert that reorg happened at received_Tx_height @@ -224,11 +249,22 @@ class AdvancedReOrgTests: XCTestCase { try coordinator.applyStaged(blockheight: reorgedTxheight + 1) sleep(3) - try coordinator.sync(completion: { synchronizer in - finalReorgTxTotalBalance = synchronizer.initializer.getBalance() - finalReorgTxVerifiedBalance = synchronizer.initializer.getVerifiedBalance() - finalsyncExpectation.fulfill() - }, error: self.handleError(_:)) + + try await withCheckedThrowingContinuation { continuation in + do { + try coordinator.sync( + completion: { synchronizer in + finalReorgTxTotalBalance = synchronizer.initializer.getBalance() + finalReorgTxVerifiedBalance = synchronizer.initializer.getVerifiedBalance() + finalsyncExpectation.fulfill() + continuation.resume() + }, + error: self.handleError + ) + } catch { + continuation.resume(with: .failure(error)) + } + } wait(for: [finalsyncExpectation], timeout: 5) sleep(3) @@ -1239,7 +1275,7 @@ class AdvancedReOrgTests: XCTestCase { XCTAssertEqual(coordinator.synchronizer.initializer.getBalance(), initialTotalBalance) } - func testLongSync() throws { + func testLongSync() async throws { hookToReOrgNotification() /* @@ -1258,21 +1294,31 @@ class AdvancedReOrgTests: XCTestCase { /* sync to latest height */ - try coordinator.sync(completion: { _ in - firstSyncExpectation.fulfill() - }, error: { error in - _ = try? self.coordinator.stop() - firstSyncExpectation.fulfill() - guard let testError = error else { - XCTFail("failed with nil error") - return + try await withCheckedThrowingContinuation { continuation in + do { + try coordinator.sync( + completion: { _ in + firstSyncExpectation.fulfill() + continuation.resume() + }, error: { error in + _ = try? self.coordinator.stop() + firstSyncExpectation.fulfill() + guard let testError = error else { + XCTFail("failed with nil error") + return + } + XCTFail("Failed with error: \(testError)") + } + ) + } catch { + continuation.resume(throwing: error) } - XCTFail("Failed with error: \(testError)") - }) + } wait(for: [firstSyncExpectation], timeout: 500) - XCTAssertEqual(try coordinator.synchronizer.latestDownloadedHeight(), birthday + fullSyncLength) + let latestDownloadedHeight = try await coordinator.synchronizer.latestDownloadedHeight() + XCTAssertEqual(latestDownloadedHeight, birthday + fullSyncLength) } func handleError(_ error: Error?) { diff --git a/Tests/DarksideTests/RewindRescanTests.swift b/Tests/DarksideTests/RewindRescanTests.swift index ce677576..9331fc28 100644 --- a/Tests/DarksideTests/RewindRescanTests.swift +++ b/Tests/DarksideTests/RewindRescanTests.swift @@ -64,7 +64,7 @@ class RewindRescanTests: XCTestCase { XCTFail("Failed with error: \(testError)") } - func testBirthdayRescan() throws { + func testBirthdayRescan() async throws { // 1 sync and get spendable funds try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName) @@ -86,7 +86,7 @@ class RewindRescanTests: XCTestCase { XCTAssertEqual(verifiedBalance, totalBalance) // rewind to birthday - try coordinator.synchronizer.rewind(.birthday) + try await coordinator.synchronizer.rewind(.birthday) // assert that after the new height is XCTAssertEqual(try coordinator.synchronizer.initializer.transactionRepository.lastScannedHeight(), self.birthday) @@ -145,7 +145,7 @@ class RewindRescanTests: XCTestCase { height: Int32(targetHeight), networkType: network.networkType ) - try coordinator.synchronizer.rewind(.height(blockheight: targetHeight)) + try await coordinator.synchronizer.rewind(.height(blockheight: targetHeight)) guard rewindHeight > 0 else { XCTFail("get nearest height failed error: \(ZcashRustBackend.getLastError() ?? "null")") @@ -190,7 +190,7 @@ class RewindRescanTests: XCTestCase { wait(for: [sendExpectation], timeout: 15) } - func testRescanToTransaction() throws { + func testRescanToTransaction() async throws { // 1 sync and get spendable funds try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName) @@ -216,7 +216,7 @@ class RewindRescanTests: XCTestCase { return } - try coordinator.synchronizer.rewind(.transaction(transaction.transactionEntity)) + try await coordinator.synchronizer.rewind(.transaction(transaction.transactionEntity)) // assert that after the new height is XCTAssertEqual( @@ -363,7 +363,7 @@ class RewindRescanTests: XCTestCase { // rewind 5 blocks prior to sending - try coordinator.synchronizer.rewind(.height(blockheight: sentTxHeight - 5)) + try await coordinator.synchronizer.rewind(.height(blockheight: sentTxHeight - 5)) guard let pendingEntity = try coordinator.synchronizer.allPendingTransactions() diff --git a/Tests/DarksideTests/ShieldFundsTests.swift b/Tests/DarksideTests/ShieldFundsTests.swift index c0a4463b..9d4790f5 100644 --- a/Tests/DarksideTests/ShieldFundsTests.swift +++ b/Tests/DarksideTests/ShieldFundsTests.swift @@ -93,7 +93,7 @@ class ShieldFundsTests: XCTestCase { var shouldContinue = false var initialTotalBalance = Zatoshi(-1) var initialVerifiedBalance = Zatoshi(-1) - var initialTransparentBalance: WalletBalance = try coordinator.synchronizer.getTransparentBalance(accountIndex: 0) + var initialTransparentBalance: WalletBalance = try await coordinator.synchronizer.getTransparentBalance(accountIndex: 0) let utxo = try GetAddressUtxosReply(jsonString: """ { @@ -135,7 +135,7 @@ class ShieldFundsTests: XCTestCase { // at this point the balance should be all zeroes for transparent and shielded funds XCTAssertEqual(initialTotalBalance, Zatoshi.zero) XCTAssertEqual(initialVerifiedBalance, Zatoshi.zero) - initialTransparentBalance = try coordinator.synchronizer.getTransparentBalance(accountIndex: 0) + initialTransparentBalance = try await coordinator.synchronizer.getTransparentBalance(accountIndex: 0) XCTAssertEqual(initialTransparentBalance.total, .zero) XCTAssertEqual(initialTransparentBalance.verified, .zero) @@ -169,7 +169,7 @@ class ShieldFundsTests: XCTestCase { // at this point the balance should be zero for shielded, then zero verified transparent funds // and 10000 zatoshi of total (not verified) transparent funds. - let tFundsDetectedBalance = try coordinator.synchronizer.getTransparentBalance(accountIndex: 0) + let tFundsDetectedBalance = try await coordinator.synchronizer.getTransparentBalance(accountIndex: 0) XCTAssertEqual(tFundsDetectedBalance.total, Zatoshi(10000)) XCTAssertEqual(tFundsDetectedBalance.verified, Zatoshi(10000)) //FIXME: this should be zero @@ -199,7 +199,7 @@ class ShieldFundsTests: XCTestCase { wait(for: [tFundsConfirmationSyncExpectation], timeout: 5) // the transparent funds should be 10000 zatoshis both total and verified - let confirmedTFundsBalance = try coordinator.synchronizer.getTransparentBalance(accountIndex: 0) + let confirmedTFundsBalance = try await coordinator.synchronizer.getTransparentBalance(accountIndex: 0) XCTAssertEqual(confirmedTFundsBalance.total, Zatoshi(10000)) XCTAssertEqual(confirmedTFundsBalance.verified, Zatoshi(10000)) @@ -239,7 +239,7 @@ class ShieldFundsTests: XCTestCase { guard shouldContinue else { return } - let postShieldingBalance = try coordinator.synchronizer.getTransparentBalance(accountIndex: 0) + let postShieldingBalance = try await coordinator.synchronizer.getTransparentBalance(accountIndex: 0) // when funds are shielded the UTXOs should be marked as spend and not shown on the balance. // now balance should be zero shielded, zero transaparent. // verify that the balance has been marked as spent regardless of confirmation @@ -290,7 +290,7 @@ class ShieldFundsTests: XCTestCase { // Now it should verify that the balance has been shielded. The resulting balance should be zero // transparent funds and `10000 - fee` total shielded funds, zero verified shielded funds. // Fees at the time of writing the tests are 1000 zatoshi as defined on ZIP-313 - let postShieldingShieldedBalance = try coordinator.synchronizer.getTransparentBalance(accountIndex: 0) + let postShieldingShieldedBalance = try await coordinator.synchronizer.getTransparentBalance(accountIndex: 0) XCTAssertEqual(postShieldingShieldedBalance.total, Zatoshi(10000)) //FIXME: this should be zero XCTAssertEqual(postShieldingShieldedBalance.verified, Zatoshi(10000)) //FIXME: this should be zero @@ -327,7 +327,7 @@ class ShieldFundsTests: XCTestCase { XCTAssertNotNil(clearedTransaction) XCTAssertEqual(coordinator.synchronizer.getShieldedBalance(), Zatoshi(9000)) - let postShieldingConfirmationShieldedBalance = try coordinator.synchronizer.getTransparentBalance(accountIndex: 0) + let postShieldingConfirmationShieldedBalance = try await coordinator.synchronizer.getTransparentBalance(accountIndex: 0) XCTAssertEqual(postShieldingConfirmationShieldedBalance.total, .zero) XCTAssertEqual(postShieldingConfirmationShieldedBalance.verified, .zero) diff --git a/Tests/DarksideTests/SynchronizerTests.swift b/Tests/DarksideTests/SynchronizerTests.swift index d12c3fc1..12918a99 100644 --- a/Tests/DarksideTests/SynchronizerTests.swift +++ b/Tests/DarksideTests/SynchronizerTests.swift @@ -67,7 +67,7 @@ final class SynchronizerTests: XCTestCase { reorgExpectation.fulfill() } - func testSynchronizerStops() throws { + func testSynchronizerStops() async throws { hookToReOrgNotification() /* @@ -102,14 +102,14 @@ final class SynchronizerTests: XCTestCase { XCTFail("Failed with error: \(testError)") }) - DispatchQueue.main.asyncAfter(deadline: .now() + 5) { - self.coordinator.synchronizer.stop() - } + try await Task.sleep(nanoseconds: 5_000_000_000) + self.coordinator.synchronizer.stop() - wait(for: [processorStoppedExpectation,syncStoppedExpectation], timeout: 6, enforceOrder: true) + wait(for: [syncStoppedExpectation, processorStoppedExpectation], timeout: 6, enforceOrder: true) XCTAssertEqual(coordinator.synchronizer.status, .stopped) - XCTAssertEqual(coordinator.synchronizer.blockProcessor.state.getState(), .stopped) + let state = await coordinator.synchronizer.blockProcessor.state + XCTAssertEqual(state, .stopped) } func handleError(_ error: Error?) { diff --git a/Tests/DarksideTests/TransactionEnhancementTests.swift b/Tests/DarksideTests/TransactionEnhancementTests.swift index 575f8b90..e83ea32a 100644 --- a/Tests/DarksideTests/TransactionEnhancementTests.swift +++ b/Tests/DarksideTests/TransactionEnhancementTests.swift @@ -110,7 +110,7 @@ class TransactionEnhancementTests: XCTestCase { NotificationCenter.default.removeObserver(self) } - private func startProcessing() throws { + private func startProcessing() async throws { XCTAssertNotNil(processor) // Subscribe to notifications @@ -120,17 +120,17 @@ class TransactionEnhancementTests: XCTestCase { startedValidatingNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedValidating, object: processor) startedScanningNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedScanning, object: processor) - try processor.start() + try await processor.start() } - func testBasicEnhacement() throws { + func testBasicEnhacement() async throws { let targetLatestHeight = BlockHeight(663250) let walletBirthday = Checkpoint.birthday(with: 663151, network: network).height - try basicEnhancementTest(latestHeight: targetLatestHeight, walletBirthday: walletBirthday) + try await basicEnhancementTest(latestHeight: targetLatestHeight, walletBirthday: walletBirthday) } - func basicEnhancementTest(latestHeight: BlockHeight, walletBirthday: BlockHeight) throws { + func basicEnhancementTest(latestHeight: BlockHeight, walletBirthday: BlockHeight) async throws { do { try darksideWalletService.reset(saplingActivation: 663150, branchID: branchID, chainName: chainName) try darksideWalletService.useDataset(DarksideDataset.beforeReOrg.rawValue) @@ -157,7 +157,7 @@ class TransactionEnhancementTests: XCTestCase { download and sync blocks from walletBirthday to firstLatestHeight */ do { - try startProcessing() + try await startProcessing() } catch { XCTFail("Error: \(error)") } diff --git a/Tests/NetworkTests/BlockScanTests.swift b/Tests/NetworkTests/BlockScanTests.swift index 920fb0e5..b0d99f7d 100644 --- a/Tests/NetworkTests/BlockScanTests.swift +++ b/Tests/NetworkTests/BlockScanTests.swift @@ -91,7 +91,7 @@ class BlockScanTests: XCTestCase { range: range ) XCTAssertFalse(Task.isCancelled) - try compactBlockProcessor.compactBlockScanning( + try await compactBlockProcessor.compactBlockScanning( rustWelding: rustWelding, cacheDb: cacheDbURL, dataDb: dataDbURL, diff --git a/Tests/NetworkTests/BlockStreamingTest.swift b/Tests/NetworkTests/BlockStreamingTest.swift index d174fe77..8b497750 100644 --- a/Tests/NetworkTests/BlockStreamingTest.swift +++ b/Tests/NetworkTests/BlockStreamingTest.swift @@ -78,9 +78,8 @@ class BlockStreamingTest: XCTestCase { blockBufferSize: 10, startHeight: startHeight ) - XCTAssertTrue(Task.isCancelled) } catch { - XCTFail("failed with error: \(error)") + XCTAssertTrue(Task.isCancelled) } } diff --git a/Tests/NetworkTests/CompactBlockProcessorTests.swift b/Tests/NetworkTests/CompactBlockProcessorTests.swift index 8e273b53..0e91b597 100644 --- a/Tests/NetworkTests/CompactBlockProcessorTests.swift +++ b/Tests/NetworkTests/CompactBlockProcessorTests.swift @@ -96,7 +96,7 @@ class CompactBlockProcessorTests: XCTestCase { } } - private func startProcessing() { + private func startProcessing() async { XCTAssertNotNil(processor) // Subscribe to notifications @@ -107,11 +107,15 @@ class CompactBlockProcessorTests: XCTestCase { startedScanningNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedScanning, object: processor) idleNotificationExpectation.subscribe(to: Notification.Name.blockProcessorFinished, object: processor) - XCTAssertNoThrow(try processor.start()) + do { + try await processor.start() + } catch { + XCTFail("shouldn't fail") + } } - func testStartNotifiesSuscriptors() { - startProcessing() + func testStartNotifiesSuscriptors() async { + await startProcessing() wait( for: [ @@ -125,7 +129,7 @@ class CompactBlockProcessorTests: XCTestCase { ) } - func testProgressNotifications() { + func testProgressNotifications() async { let expectedUpdates = expectedBatches( currentHeight: processorConfig.walletBirthday, targetHeight: mockLatestHeight, @@ -133,7 +137,7 @@ class CompactBlockProcessorTests: XCTestCase { ) updatedNotificationExpectation.expectedFulfillmentCount = expectedUpdates - startProcessing() + await startProcessing() wait(for: [updatedNotificationExpectation], timeout: 300) } @@ -189,23 +193,23 @@ class CompactBlockProcessorTests: XCTestCase { ) } - func testDetermineLowerBoundPastBirthday() { + func testDetermineLowerBoundPastBirthday() async { let errorHeight = 781_906 let walletBirthday = 781_900 - let result = processor.determineLowerBound(errorHeight: errorHeight, consecutiveErrors: 1, walletBirthday: walletBirthday) + let result = await processor.determineLowerBound(errorHeight: errorHeight, consecutiveErrors: 1, walletBirthday: walletBirthday) let expected = 781_886 XCTAssertEqual(result, expected) } - func testDetermineLowerBound() { + func testDetermineLowerBound() async { let errorHeight = 781_906 let walletBirthday = 780_900 - let result = processor.determineLowerBound(errorHeight: errorHeight, consecutiveErrors: 0, walletBirthday: walletBirthday) + let result = await processor.determineLowerBound(errorHeight: errorHeight, consecutiveErrors: 0, walletBirthday: walletBirthday) let expected = 781_896 XCTAssertEqual(result, expected) diff --git a/Tests/NetworkTests/CompactBlockReorgTests.swift b/Tests/NetworkTests/CompactBlockReorgTests.swift index e8a3fbd8..22cdce16 100644 --- a/Tests/NetworkTests/CompactBlockReorgTests.swift +++ b/Tests/NetworkTests/CompactBlockReorgTests.swift @@ -127,7 +127,7 @@ class CompactBlockReorgTests: XCTestCase { } } - private func startProcessing() { + private func startProcessing() async { XCTAssertNotNil(processor) // Subscribe to notifications @@ -139,11 +139,15 @@ class CompactBlockReorgTests: XCTestCase { idleNotificationExpectation.subscribe(to: Notification.Name.blockProcessorFinished, object: processor) reorgNotificationExpectation.subscribe(to: Notification.Name.blockProcessorHandledReOrg, object: processor) - XCTAssertNoThrow(try processor.start()) + do { + try await processor.start() + } catch { + XCTFail("shouldn't fail") + } } - func testNotifiesReorg() { - startProcessing() + func testNotifiesReorg() async { + await startProcessing() wait( for: [ diff --git a/Tests/OfflineTests/WalletTests.swift b/Tests/OfflineTests/WalletTests.swift index 000d9c37..0ea9f154 100644 --- a/Tests/OfflineTests/WalletTests.swift +++ b/Tests/OfflineTests/WalletTests.swift @@ -33,7 +33,7 @@ class WalletTests: XCTestCase { } } - func testWalletInitialization() throws { + func testWalletInitialization() async throws { let derivationTool = DerivationTool(networkType: network.networkType) let uvk = try derivationTool.deriveUnifiedViewingKeysFromSeed(seedData.bytes, numberOfAccounts: 1) let wallet = Initializer( @@ -49,7 +49,11 @@ class WalletTests: XCTestCase { ) let synchronizer = try SDKSynchronizer(initializer: wallet) - XCTAssertNoThrow(try synchronizer.prepare()) + do { + try await synchronizer.prepare() + } catch { + XCTFail("shouldn't fail here") + } // fileExists actually sucks, so attempting to delete the file and checking what happens is far better :) XCTAssertNoThrow( try FileManager.default.removeItem(at: dbData!) ) diff --git a/Tests/TestUtils/FakeService.swift b/Tests/TestUtils/FakeService.swift index db061395..5a3f7389 100644 --- a/Tests/TestUtils/FakeService.swift +++ b/Tests/TestUtils/FakeService.swift @@ -25,18 +25,18 @@ class MockLightWalletService: LightWalletService { var queue = DispatchQueue(label: "mock service queue") func blockStream(startHeight: BlockHeight, endHeight: BlockHeight) -> AsyncThrowingStream { - AsyncThrowingStream { _ in } + service.blockStream(startHeight: startHeight, endHeight: endHeight) } func closeConnection() { } func fetchUTXOs(for tAddress: String, height: BlockHeight) -> AsyncThrowingStream { - AsyncThrowingStream { _ in } + service.fetchUTXOs(for: tAddress, height: height) } func fetchUTXOs(for tAddresses: [String], height: BlockHeight) -> AsyncThrowingStream { - AsyncThrowingStream { _ in } + service.fetchUTXOs(for: tAddresses, height: height) } private var service: LightWalletService diff --git a/Tests/TestUtils/TestCoordinator.swift b/Tests/TestUtils/TestCoordinator.swift index 0d79cb9c..c5ef85da 100644 --- a/Tests/TestUtils/TestCoordinator.swift +++ b/Tests/TestUtils/TestCoordinator.swift @@ -200,6 +200,12 @@ class TestCoordinator { } } +extension CompactBlockProcessor { + public func setConfig(_ config: Configuration) { + self.config = config + } +} + extension TestCoordinator { func resetBlocks(dataset: DarksideData) throws { switch dataset { @@ -233,19 +239,25 @@ extension TestCoordinator { } func reset(saplingActivation: BlockHeight, branchID: String, chainName: String) throws { - let config = self.synchronizer.blockProcessor.config - - self.synchronizer.blockProcessor.config = CompactBlockProcessor.Configuration( - cacheDb: config.cacheDb, - dataDb: config.dataDb, - downloadBatchSize: config.downloadBatchSize, - retries: config.retries, - maxBackoffInterval: config.maxBackoffInterval, - rewindDistance: config.rewindDistance, - walletBirthday: config.walletBirthday, - saplingActivation: config.saplingActivation, - network: config.network - ) + Task { + await self.synchronizer.blockProcessor.stop() + let config = await self.synchronizer.blockProcessor.config + + let newConfig = CompactBlockProcessor.Configuration( + cacheDb: config.cacheDb, + dataDb: config.dataDb, + downloadBatchSize: config.downloadBatchSize, + retries: config.retries, + maxBackoffInterval: config.maxBackoffInterval, + rewindDistance: config.rewindDistance, + walletBirthday: config.walletBirthday, + saplingActivation: config.saplingActivation, + network: config.network + ) + + await self.synchronizer.blockProcessor.setConfig(newConfig) + } + try service.reset(saplingActivation: saplingActivation, branchID: branchID, chainName: chainName) } @@ -308,7 +320,9 @@ enum TestSynchronizerBuilder { ) let synchronizer = try SDKSynchronizer(initializer: initializer) - try synchronizer.prepare() + Task { + try await synchronizer.prepare() + } return ([spendingKey], synchronizer) } From 02ee0a54ea524d52edb9aeb96e687e9ce6c16091 Mon Sep 17 00:00:00 2001 From: Michal Fousek Date: Fri, 28 Oct 2022 12:18:19 +0200 Subject: [PATCH 04/11] [#593] Fix testSmallDownloadAsync test - Test was failling with: generalError(message: "block not found in cache, should always be in cache in darkside mode") - There was no wait so lightwalletd in darkside mode didn't have enough time to accept mocked state. --- Tests/DarksideTests/BlockDownloaderTests.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/DarksideTests/BlockDownloaderTests.swift b/Tests/DarksideTests/BlockDownloaderTests.swift index b78ed5e1..ceb1fafd 100644 --- a/Tests/DarksideTests/BlockDownloaderTests.swift +++ b/Tests/DarksideTests/BlockDownloaderTests.swift @@ -31,6 +31,8 @@ class BlockDownloaderTests: XCTestCase { try FakeChainBuilder.buildChain(darksideWallet: darksideWalletService, branchID: branchID, chainName: chainName) try darksideWalletService.applyStaged(nextLatestHeight: 663250) + + sleep(2) } override func tearDown() { From 085257881d357f8cc51a30a8f2723ab9cde24864 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Fri, 28 Oct 2022 15:08:17 +0200 Subject: [PATCH 05/11] [#595] Update Travis to use Xcode 14 - yml file updated to the latest Xcode --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 20229f0e..82930504 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: swift os: osx -osx_image: xcode13.4 +osx_image: xcode14 xcode_project: ./Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj xcode_scheme: ZcashLightClientSample xcode_destination: platform=iOS Simulator,OS=15.2,name=iPhone 8 From 245f2324b530a01d0fc1f55c9dc97fe8cd2f6022 Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Fri, 28 Oct 2022 14:20:52 -0300 Subject: [PATCH 06/11] [#597] SDK does not build with SQLite 0.14 --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- Package.swift | 2 +- ZcashLightClientKit.podspec | 4 ++-- changelog.md | 2 ++ 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 370dc422..c4579987 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -60,8 +60,8 @@ "repositoryURL": "https://github.com/stephencelis/SQLite.swift.git", "state": { "branch": null, - "revision": "60a65015f6402b7c34b9a924f755ca0a73afeeaa", - "version": "0.13.1" + "revision": "4d543d811ee644fa4cc4bfa0be996b4dd6ba0f54", + "version": "0.13.3" } }, { diff --git a/Package.swift b/Package.swift index f98146d4..69176630 100644 --- a/Package.swift +++ b/Package.swift @@ -15,7 +15,7 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.8.0"), - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.13.0"), + .package(url: "https://github.com/stephencelis/SQLite.swift.git", Version(stringLiteral: "0.13.0")...Version(stringLiteral: "0.13.99")), .package(name:"libzcashlc", url: "https://github.com/zcash-hackworks/zcash-light-client-ffi.git", from: "0.0.3"), ], targets: [ diff --git a/ZcashLightClientKit.podspec b/ZcashLightClientKit.podspec index 98e26609..c4a10d3c 100644 --- a/ZcashLightClientKit.podspec +++ b/ZcashLightClientKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'ZcashLightClientKit' - s.version = '0.16.12-beta' + s.version = '0.16.13-beta' s.summary = 'Zcash Light Client wallet SDK for iOS' s.description = <<-DESC @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.swift_version = '5.6' s.ios.deployment_target = '13.0' s.dependency 'gRPC-Swift', '~> 1.8.0' - s.dependency 'SQLite.swift', '~> 0.13' + s.dependency 'SQLite.swift', '~> 0.13.0' s.dependency 'libzcashlc', '0.0.3' s.static_framework = true diff --git a/changelog.md b/changelog.md index 6f3e125a..79ba22e1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,5 @@ +# 0.16-13-beta +- [#597] SDK does not build with SQLite 0.14 # 0.16.12-beta Checkpoints added: Mainnet From 01d85f574845a2fcba7acc461086331cf3b15b19 Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Mon, 31 Oct 2022 09:57:10 -0300 Subject: [PATCH 07/11] Fix compiler errors --- .../Block/Processor/CompactBlockProcessor.swift | 4 ---- Sources/ZcashLightClientKit/Synchronizer.swift | 2 +- .../Synchronizer/SDKSynchronizer.swift | 4 ++-- Tests/DarksideTests/AdvancedReOrgTests.swift | 14 ++++++++------ Tests/DarksideTests/BalanceTests.swift | 14 ++++++++------ .../DarksideSanityCheckTests.swift | 14 ++++++++------ .../PendingTransactionUpdatesTest.swift | 15 +++++++++------ Tests/DarksideTests/ReOrgTests.swift | 17 +++++++++++------ Tests/DarksideTests/RewindRescanTests.swift | 16 ++++++++-------- Tests/DarksideTests/ShieldFundsTests.swift | 14 ++++++++------ .../SychronizerDarksideTests.swift | 14 ++++++++------ Tests/DarksideTests/SynchronizerTests.swift | 15 +++++++++------ .../TransactionEnhancementTests.swift | 4 ++-- Tests/DarksideTests/Z2TReceiveTests.swift | 14 ++++++++------ Tests/NetworkTests/CompactBlockReorgTests.swift | 13 ++++++------- Tests/OfflineTests/WalletTests.swift | 10 ++++------ Tests/TestUtils/TestCoordinator.swift | 14 +++++++------- 17 files changed, 107 insertions(+), 91 deletions(-) diff --git a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift index 6a7f7e36..e2d460e2 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift @@ -500,7 +500,6 @@ public actor CompactBlockProcessor { notifyError(CompactBlockProcessorError.maxAttemptsReached(attempts: self.maxAttempts)) case .downloading, .validating, .scanning, .enhancing, .fetching: LoggerProxy.debug("Warning: compact block processor was started while busy!!!!") - needsToStartScanningWhenStopped.set(true) } return } @@ -1000,9 +999,6 @@ extension CompactBlockProcessor { guard accountIndex >= 0 else { throw CompactBlockProcessorError.invalidAccount } - return try utxoCacheBalance(tAddress: tAddress) - } -} return WalletBalance( verified: Zatoshi( diff --git a/Sources/ZcashLightClientKit/Synchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer.swift index 3b51e434..e88c4b69 100644 --- a/Sources/ZcashLightClientKit/Synchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer.swift @@ -93,7 +93,7 @@ public protocol Synchronizer { /// Gets the sapling shielded address for the given account. /// - Parameter accountIndex: the optional accountId whose address is of interest. By default, the first account is used. /// - Returns the address or nil if account index is incorrect - func getSaplingAddress(accountIndex: Int) -> SaplingAddress? + func getSaplingAddress(accountIndex: Int) async -> SaplingAddress? /// Gets the unified address for the given account. /// - Parameter accountIndex: the optional accountId whose address is of interest. By default, the first account is used. diff --git a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift index 100e2534..e24a4207 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift @@ -627,10 +627,10 @@ public class SDKSynchronizer: Synchronizer { /// Returns the last stored transparent balance public func getTransparentBalance(accountIndex: Int) async throws -> WalletBalance { - try blockProcessor.getTransparentBalance(accountIndex: accountIndex) + try await blockProcessor.getTransparentBalance(accountIndex: accountIndex) } - public func rewind(_ policy: RewindPolicy) throws { + public func rewind(_ policy: RewindPolicy) async throws { self.stop() var height: BlockHeight? diff --git a/Tests/DarksideTests/AdvancedReOrgTests.swift b/Tests/DarksideTests/AdvancedReOrgTests.swift index 61448cb8..a0281985 100644 --- a/Tests/DarksideTests/AdvancedReOrgTests.swift +++ b/Tests/DarksideTests/AdvancedReOrgTests.swift @@ -34,12 +34,14 @@ class AdvancedReOrgTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday + 50, //don't use an exact birthday, users never do. - channelProvider: ChannelProvider(), - network: network - ) + Task{ @MainActor [self] in + self.coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday + 50, //don't use an exact birthday, users never do. + channelProvider: ChannelProvider(), + network: network + ) + } try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) } diff --git a/Tests/DarksideTests/BalanceTests.swift b/Tests/DarksideTests/BalanceTests.swift index c1a69836..aa91092f 100644 --- a/Tests/DarksideTests/BalanceTests.swift +++ b/Tests/DarksideTests/BalanceTests.swift @@ -30,12 +30,14 @@ class BalanceTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network - ) + Task{ @MainActor [self] in + self.coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday, + channelProvider: ChannelProvider(), + network: network + ) + } try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } diff --git a/Tests/DarksideTests/DarksideSanityCheckTests.swift b/Tests/DarksideTests/DarksideSanityCheckTests.swift index 0df6bf6b..d80af160 100644 --- a/Tests/DarksideTests/DarksideSanityCheckTests.swift +++ b/Tests/DarksideTests/DarksideSanityCheckTests.swift @@ -33,12 +33,14 @@ class DarksideSanityCheckTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network - ) + Task { @MainActor [self] in + self.coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday, + channelProvider: ChannelProvider(), + network: network + ) + } try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName) try coordinator.resetBlocks(dataset: .default) } diff --git a/Tests/DarksideTests/PendingTransactionUpdatesTest.swift b/Tests/DarksideTests/PendingTransactionUpdatesTest.swift index 4756be85..28d17715 100644 --- a/Tests/DarksideTests/PendingTransactionUpdatesTest.swift +++ b/Tests/DarksideTests/PendingTransactionUpdatesTest.swift @@ -31,12 +31,15 @@ class PendingTransactionUpdatesTest: XCTestCase { let network = DarksideWalletDNetwork() override func setUpWithError() throws { try super.setUpWithError() - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network - ) + Task{ @MainActor in + coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday, + channelProvider: ChannelProvider(), + network: network + ) + } + try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } diff --git a/Tests/DarksideTests/ReOrgTests.swift b/Tests/DarksideTests/ReOrgTests.swift index d0063979..97afc85b 100644 --- a/Tests/DarksideTests/ReOrgTests.swift +++ b/Tests/DarksideTests/ReOrgTests.swift @@ -47,18 +47,23 @@ class ReOrgTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() + NotificationCenter.default.addObserver( self, selector: #selector(handleReOrgNotification(_:)), name: Notification.Name.blockProcessorHandledReOrg, object: nil ) - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network - ) + + Task{ @MainActor [self] in + coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday, + channelProvider: ChannelProvider(), + network: network + ) + } + try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName) try coordinator.resetBlocks(dataset: .default) } diff --git a/Tests/DarksideTests/RewindRescanTests.swift b/Tests/DarksideTests/RewindRescanTests.swift index aa869dcc..8ac8248b 100644 --- a/Tests/DarksideTests/RewindRescanTests.swift +++ b/Tests/DarksideTests/RewindRescanTests.swift @@ -34,14 +34,14 @@ class RewindRescanTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network - ) - + Task{ @MainActor [self] in + self.coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday, + channelProvider: ChannelProvider(), + network: network + ) + } try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } diff --git a/Tests/DarksideTests/ShieldFundsTests.swift b/Tests/DarksideTests/ShieldFundsTests.swift index 22610b22..1721d6dd 100644 --- a/Tests/DarksideTests/ShieldFundsTests.swift +++ b/Tests/DarksideTests/ShieldFundsTests.swift @@ -30,12 +30,14 @@ class ShieldFundsTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network - ) + Task { @MainActor [self] in + self.coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday, + channelProvider: ChannelProvider(), + network: network + ) + } try coordinator.reset(saplingActivation: birthday, branchID: self.branchID, chainName: self.chainName) try coordinator.service.clearAddedUTXOs() } diff --git a/Tests/DarksideTests/SychronizerDarksideTests.swift b/Tests/DarksideTests/SychronizerDarksideTests.swift index 53645c2c..e8a7bfb7 100644 --- a/Tests/DarksideTests/SychronizerDarksideTests.swift +++ b/Tests/DarksideTests/SychronizerDarksideTests.swift @@ -34,12 +34,14 @@ class SychronizerDarksideTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network - ) + Task{ @MainActor [self] in + coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday, + channelProvider: ChannelProvider(), + network: network + ) + } try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } diff --git a/Tests/DarksideTests/SynchronizerTests.swift b/Tests/DarksideTests/SynchronizerTests.swift index 12918a99..2393efe1 100644 --- a/Tests/DarksideTests/SynchronizerTests.swift +++ b/Tests/DarksideTests/SynchronizerTests.swift @@ -34,12 +34,15 @@ final class SynchronizerTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday + 50, //don't use an exact birthday, users never do. - channelProvider: ChannelProvider(), - network: network - ) + Task { @MainActor [self] in + coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday + 50, //don't use an exact birthday, users never do. + channelProvider: ChannelProvider(), + network: network + ) + } + try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) } diff --git a/Tests/DarksideTests/TransactionEnhancementTests.swift b/Tests/DarksideTests/TransactionEnhancementTests.swift index af7d6987..e2418fa8 100644 --- a/Tests/DarksideTests/TransactionEnhancementTests.swift +++ b/Tests/DarksideTests/TransactionEnhancementTests.swift @@ -147,10 +147,10 @@ class TransactionEnhancementTests: XCTestCase { txFoundNotificationExpectation.subscribe(to: .blockProcessorFoundTransactions, object: processor) idleNotificationExpectation.subscribe(to: .blockProcessorIdle, object: processor) - try await processor.start() + await processor.start() } - func testBasicEnhacement() throws { + func testBasicEnhacement() async throws { let targetLatestHeight = BlockHeight(663200) do { diff --git a/Tests/DarksideTests/Z2TReceiveTests.swift b/Tests/DarksideTests/Z2TReceiveTests.swift index 5dc356ba..da8cd937 100644 --- a/Tests/DarksideTests/Z2TReceiveTests.swift +++ b/Tests/DarksideTests/Z2TReceiveTests.swift @@ -31,12 +31,14 @@ class Z2TReceiveTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - coordinator = try TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network - ) + Task{ @MainActor [self] in + coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday, + channelProvider: ChannelProvider(), + network: network + ) + } try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) } diff --git a/Tests/NetworkTests/CompactBlockReorgTests.swift b/Tests/NetworkTests/CompactBlockReorgTests.swift index 22cdce16..18f5cc28 100644 --- a/Tests/NetworkTests/CompactBlockReorgTests.swift +++ b/Tests/NetworkTests/CompactBlockReorgTests.swift @@ -47,7 +47,10 @@ class CompactBlockReorgTests: XCTestCase { info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight) } - try ZcashRustBackend.initDataDb(dbData: processorConfig.dataDb, networkType: .testnet) + guard case .success = try ZcashRustBackend.initDataDb(dbData: processorConfig.dataDb, seed: nil, networkType: .testnet) else { + XCTFail("initDataDb failed. Expected Success but got .seedRequired") + return + } let storage = CompactBlockStorage.init(connectionProvider: SimpleConnectionProvider(path: processorConfig.cacheDb.absoluteString)) try! storage.createTable() @@ -138,12 +141,8 @@ class CompactBlockReorgTests: XCTestCase { startedScanningNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedScanning, object: processor) idleNotificationExpectation.subscribe(to: Notification.Name.blockProcessorFinished, object: processor) reorgNotificationExpectation.subscribe(to: Notification.Name.blockProcessorHandledReOrg, object: processor) - - do { - try await processor.start() - } catch { - XCTFail("shouldn't fail") - } + + await processor.start() } func testNotifiesReorg() async { diff --git a/Tests/OfflineTests/WalletTests.swift b/Tests/OfflineTests/WalletTests.swift index 5132f767..b939c15b 100644 --- a/Tests/OfflineTests/WalletTests.swift +++ b/Tests/OfflineTests/WalletTests.swift @@ -51,12 +51,10 @@ class WalletTests: XCTestCase { let synchronizer = try SDKSynchronizer(initializer: wallet) do { - try await synchronizer.prepare() - - guard case .success = dbInit else { - XCTFail("Failed to initDataDb. Expected `.success` got: \(String(describing: dbInit))") - return - } + guard case .success = try await synchronizer.prepare(with: seedData.bytes) else { + XCTFail("Failed to initDataDb. Expected `.success` got: `.seedRequired`") + return + } } catch { XCTFail("shouldn't fail here") } diff --git a/Tests/TestUtils/TestCoordinator.swift b/Tests/TestUtils/TestCoordinator.swift index 7affee69..f2f517db 100644 --- a/Tests/TestUtils/TestCoordinator.swift +++ b/Tests/TestUtils/TestCoordinator.swift @@ -50,7 +50,7 @@ class TestCoordinator { walletBirthday: BlockHeight, channelProvider: ChannelProvider, network: ZcashNetwork - ) throws { + ) async throws { let derivationTool = DerivationTool(networkType: network.networkType) let spendingKey = try derivationTool.deriveUnifiedSpendingKey( @@ -60,7 +60,7 @@ class TestCoordinator { let ufvk = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey) - try self.init( + await try self.init( spendingKey: spendingKey, unifiedFullViewingKey: ufvk, walletBirthday: walletBirthday, @@ -75,7 +75,7 @@ class TestCoordinator { walletBirthday: BlockHeight, channelProvider: ChannelProvider, network: ZcashNetwork - ) throws { + ) async throws { self.spendingKey = spendingKey self.birthday = walletBirthday self.channelProvider = channelProvider @@ -93,7 +93,7 @@ class TestCoordinator { let storage = CompactBlockStorage(url: databases.cacheDB, readonly: false) try storage.createTable() - let buildResult = try TestSynchronizerBuilder.build( + let buildResult = try await TestSynchronizerBuilder.build( rustBackend: ZcashRustBackend.self, lowerBoundHeight: self.birthday, cacheDbURL: databases.cacheDB, @@ -291,7 +291,7 @@ enum TestSynchronizerBuilder { network: ZcashNetwork, seed: [UInt8]? = nil, loggerProxy: Logger? = nil - ) throws -> (spendingKeys: [UnifiedSpendingKey]?, synchronizer: SDKSynchronizer) { + ) async throws -> (spendingKeys: [UnifiedSpendingKey]?, synchronizer: SDKSynchronizer) { let initializer = Initializer( cacheDbURL: cacheDbURL, dataDbURL: dataDbURL, @@ -331,7 +331,7 @@ enum TestSynchronizerBuilder { walletBirthday: BlockHeight, network: ZcashNetwork, loggerProxy: Logger? = nil - ) throws -> (spendingKeys: [UnifiedSpendingKey]?, synchronizer: SDKSynchronizer) { + ) async throws -> (spendingKeys: [UnifiedSpendingKey]?, synchronizer: SDKSynchronizer) { let spendingKey = try DerivationTool(networkType: network.networkType) .deriveUnifiedSpendingKey(seed: seedBytes, accountIndex: 0) @@ -339,7 +339,7 @@ enum TestSynchronizerBuilder { let uvk = try DerivationTool(networkType: network.networkType) .deriveUnifiedFullViewingKey(from: spendingKey) - return try build( + return try await build( rustBackend: rustBackend, lowerBoundHeight: lowerBoundHeight, cacheDbURL: cacheDbURL, From 1c8e06742abb2b683dd044db66159dadac9e0d19 Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Mon, 31 Oct 2022 10:17:48 -0300 Subject: [PATCH 08/11] Fix Tests than need to call the async TestCoordinator build function --- Tests/DarksideTests/AdvancedReOrgTests.swift | 24 +++++------ Tests/TestUtils/XCAsyncTestCase.swift | 42 ++++++++++++++++++++ 2 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 Tests/TestUtils/XCAsyncTestCase.swift diff --git a/Tests/DarksideTests/AdvancedReOrgTests.swift b/Tests/DarksideTests/AdvancedReOrgTests.swift index a0281985..5d0b2d8b 100644 --- a/Tests/DarksideTests/AdvancedReOrgTests.swift +++ b/Tests/DarksideTests/AdvancedReOrgTests.swift @@ -11,7 +11,7 @@ import XCTest // swiftlint:disable implicitly_unwrapped_optional force_unwrapping type_body_length //@MainActor -class AdvancedReOrgTests: XCTestCase { +class AdvancedReOrgTests: XCAsyncTestCase { // TODO: Parameterize this from environment? // swiftlint:disable:next line_length var seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread" @@ -31,22 +31,18 @@ class AdvancedReOrgTests: XCTestCase { let branchID = "2bb40e60" let chainName = "main" let network = DarksideWalletDNetwork() - - override func setUpWithError() throws { - try super.setUpWithError() - Task{ @MainActor [self] in - self.coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday + 50, //don't use an exact birthday, users never do. - channelProvider: ChannelProvider(), - network: network - ) - } + + override func asyncSetUpWithError() async throws { + self.coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday + 50, //don't use an exact birthday, users never do. + channelProvider: ChannelProvider(), + network: network + ) try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) } - override func tearDownWithError() throws { - try super.tearDownWithError() + override func asyncTearDownWithError() async throws { NotificationCenter.default.removeObserver(self) try coordinator.stop() try? FileManager.default.removeItem(at: coordinator.databases.cacheDB) diff --git a/Tests/TestUtils/XCAsyncTestCase.swift b/Tests/TestUtils/XCAsyncTestCase.swift new file mode 100644 index 00000000..d9020ac0 --- /dev/null +++ b/Tests/TestUtils/XCAsyncTestCase.swift @@ -0,0 +1,42 @@ +// +// XCAsyncTestCase.swift +// +// +// credits: https://betterprogramming.pub/async-setup-and-teardown-in-xctestcase-dc7a2cdb9fb +// +/// +/// A subclass of ``XCTestCase`` that supports async setup and teardown. +/// +import Foundation +import XCTest +class XCAsyncTestCase: XCTestCase { + + func asyncSetUpWithError() async throws { + fatalError("Must override") + } + + func asyncTearDownWithError() async throws { + fatalError("Must override") + } + + override func setUpWithError() throws { + wait { + try await self.asyncSetUpWithError() + } + } + + override func tearDownWithError() throws { + wait { + try await self.asyncTearDownWithError() + } + } + + func wait(asyncBlock: @escaping (() async throws -> Void)) { + let semaphore = DispatchSemaphore(value: 0) + Task.init { + try await asyncBlock() + semaphore.signal() + } + semaphore.wait() + } +} From a0d02c4d57b54de50282d83c8f49e167d581dddb Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Mon, 31 Oct 2022 20:17:05 -0300 Subject: [PATCH 09/11] PR Suggestions `XCAsyncTestCase` does not work as intended but `wait {}` does what we need. restored `needsToStartScanningWhenStopped` as a Bool var on actor fixed Enhancement test --- .../Processor/CompactBlockProcessor.swift | 10 ++++-- Tests/DarksideTests/AdvancedReOrgTests.swift | 24 +++++++------ Tests/DarksideTests/BalanceTests.swift | 11 +++--- .../DarksideSanityCheckTests.swift | 15 ++++---- .../PendingTransactionUpdatesTest.swift | 15 ++++---- Tests/DarksideTests/ReOrgTests.swift | 35 +++++++++---------- Tests/DarksideTests/RewindRescanTests.swift | 12 +++---- .../SychronizerDarksideTests.swift | 13 +++---- Tests/DarksideTests/SynchronizerTests.swift | 14 ++++---- .../TransactionEnhancementTests.swift | 4 +-- Tests/DarksideTests/Z2TReceiveTests.swift | 16 ++++----- Tests/TestUtils/XCAsyncTestCase.swift | 22 +----------- ZcashLightClientKit.podspec | 8 ----- 13 files changed, 88 insertions(+), 111 deletions(-) diff --git a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift index e2d460e2..6df52856 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift @@ -318,6 +318,7 @@ public actor CompactBlockProcessor { } } + private var needsToStartScanningWhenStopped = false var config: Configuration { willSet { self.stop() @@ -500,6 +501,7 @@ public actor CompactBlockProcessor { notifyError(CompactBlockProcessorError.maxAttemptsReached(attempts: self.maxAttempts)) case .downloading, .validating, .scanning, .enhancing, .fetching: LoggerProxy.debug("Warning: compact block processor was started while busy!!!!") + self.needsToStartScanningWhenStopped = true } return } @@ -596,7 +598,7 @@ public actor CompactBlockProcessor { self.backoffTimer?.invalidate() self.backoffTimer = nil - cancelableTask = Task(priority: .userInitiated) { [weak self] in + cancelableTask = Task(priority: .userInitiated) { do { try await compactBlockStreamDownload( blockBufferSize: config.downloadBufferSize, @@ -607,12 +609,14 @@ public actor CompactBlockProcessor { try await compactBlockBatchScanning(range: range) try await compactBlockEnhancement(range: range) try await fetchUnspentTxOutputs(range: range) - //state = .stopped } catch { if !(Task.isCancelled) { await fail(error) } else { state = .stopped + if needsToStartScanningWhenStopped { + await nextBatch() + } } } } @@ -837,7 +841,7 @@ public actor CompactBlockProcessor { ) state = .synced await setTimer() - NotificationCenter.default.post( + NotificationCenter.default.mainThreadPost( name: Notification.Name.blockProcessorIdle, object: self, userInfo: nil diff --git a/Tests/DarksideTests/AdvancedReOrgTests.swift b/Tests/DarksideTests/AdvancedReOrgTests.swift index 5d0b2d8b..0a68f746 100644 --- a/Tests/DarksideTests/AdvancedReOrgTests.swift +++ b/Tests/DarksideTests/AdvancedReOrgTests.swift @@ -11,7 +11,7 @@ import XCTest // swiftlint:disable implicitly_unwrapped_optional force_unwrapping type_body_length //@MainActor -class AdvancedReOrgTests: XCAsyncTestCase { +class AdvancedReOrgTests: XCTestCase { // TODO: Parameterize this from environment? // swiftlint:disable:next line_length var seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread" @@ -32,17 +32,21 @@ class AdvancedReOrgTests: XCAsyncTestCase { let chainName = "main" let network = DarksideWalletDNetwork() - override func asyncSetUpWithError() async throws { - self.coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday + 50, //don't use an exact birthday, users never do. - channelProvider: ChannelProvider(), - network: network - ) - try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) + override func setUpWithError() throws { + try super.setUpWithError() + wait { [self] in + self.coordinator = try await TestCoordinator( + seed: seedPhrase, + walletBirthday: birthday + 50, //don't use an exact birthday, users never do. + channelProvider: ChannelProvider(), + network: network + ) + try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) + } } - override func asyncTearDownWithError() async throws { + override func tearDownWithError() throws { + super.tearDownWithError() NotificationCenter.default.removeObserver(self) try coordinator.stop() try? FileManager.default.removeItem(at: coordinator.databases.cacheDB) diff --git a/Tests/DarksideTests/BalanceTests.swift b/Tests/DarksideTests/BalanceTests.swift index aa91092f..940e50c6 100644 --- a/Tests/DarksideTests/BalanceTests.swift +++ b/Tests/DarksideTests/BalanceTests.swift @@ -30,15 +30,16 @@ class BalanceTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - Task{ @MainActor [self] in + wait { [self] in self.coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, + seed: self.seedPhrase, + walletBirthday: self.birthday, channelProvider: ChannelProvider(), - network: network + network: self.network ) + + try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } - try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } /** diff --git a/Tests/DarksideTests/DarksideSanityCheckTests.swift b/Tests/DarksideTests/DarksideSanityCheckTests.swift index d80af160..500bd574 100644 --- a/Tests/DarksideTests/DarksideSanityCheckTests.swift +++ b/Tests/DarksideTests/DarksideSanityCheckTests.swift @@ -33,16 +33,17 @@ class DarksideSanityCheckTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - Task { @MainActor [self] in + wait { [self] in self.coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, + seed: self.seedPhrase, + walletBirthday: self.birthday, channelProvider: ChannelProvider(), - network: network + network: self.network ) + + try self.coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName) + try self.coordinator.resetBlocks(dataset: .default) } - try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName) - try coordinator.resetBlocks(dataset: .default) } override func tearDownWithError() throws { @@ -76,7 +77,7 @@ class DarksideSanityCheckTests: XCTestCase { wait(for: [syncExpectation], timeout: 5) - let blocksDao = BlockSQLDAO(dbProvider: SimpleConnectionProvider(path: coordinator.databases.dataDB.absoluteString, readonly: true)) + let blocksDao = BlockSQLDAO(dbProvider: SimpleConnectionProvider(path: coordinator.databases.dataDB.absoluteString, readonly: false)) let firstBlock = try blocksDao.block(at: expectedFirstBlock.height) let lastBlock = try blocksDao.block(at: expectedLastBlock.height) diff --git a/Tests/DarksideTests/PendingTransactionUpdatesTest.swift b/Tests/DarksideTests/PendingTransactionUpdatesTest.swift index 28d17715..1baab7c7 100644 --- a/Tests/DarksideTests/PendingTransactionUpdatesTest.swift +++ b/Tests/DarksideTests/PendingTransactionUpdatesTest.swift @@ -31,20 +31,19 @@ class PendingTransactionUpdatesTest: XCTestCase { let network = DarksideWalletDNetwork() override func setUpWithError() throws { try super.setUpWithError() - Task{ @MainActor in - coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, + wait { + self.coordinator = try await TestCoordinator( + seed: self.seedPhrase, + walletBirthday: self.birthday, channelProvider: ChannelProvider(), - network: network + network: self.network ) - } - try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") + try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") + } } override func tearDownWithError() throws { - try super.tearDownWithError() NotificationCenter.default.removeObserver(self) try coordinator.stop() try? FileManager.default.removeItem(at: coordinator.databases.cacheDB) diff --git a/Tests/DarksideTests/ReOrgTests.swift b/Tests/DarksideTests/ReOrgTests.swift index 97afc85b..afae7c0b 100644 --- a/Tests/DarksideTests/ReOrgTests.swift +++ b/Tests/DarksideTests/ReOrgTests.swift @@ -47,29 +47,28 @@ class ReOrgTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - - NotificationCenter.default.addObserver( - self, - selector: #selector(handleReOrgNotification(_:)), - name: Notification.Name.blockProcessorHandledReOrg, - object: nil - ) - - Task{ @MainActor [self] in - coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, - channelProvider: ChannelProvider(), - network: network + wait { [self] in + NotificationCenter.default.addObserver( + self, + selector: #selector(self.handleReOrgNotification(_:)), + name: Notification.Name.blockProcessorHandledReOrg, + object: nil ) - } - try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName) - try coordinator.resetBlocks(dataset: .default) + self.coordinator = try await TestCoordinator( + seed: self.seedPhrase, + walletBirthday: self.birthday, + channelProvider: ChannelProvider(), + network: self.network + ) + + try self.coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName) + + try self.coordinator.resetBlocks(dataset: .default) + } } override func tearDownWithError() throws { - try super.tearDownWithError() try? FileManager.default.removeItem(at: coordinator.databases.cacheDB) try? FileManager.default.removeItem(at: coordinator.databases.dataDB) try? FileManager.default.removeItem(at: coordinator.databases.pendingDB) diff --git a/Tests/DarksideTests/RewindRescanTests.swift b/Tests/DarksideTests/RewindRescanTests.swift index 8ac8248b..5e54fd5b 100644 --- a/Tests/DarksideTests/RewindRescanTests.swift +++ b/Tests/DarksideTests/RewindRescanTests.swift @@ -34,20 +34,20 @@ class RewindRescanTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - Task{ @MainActor [self] in + wait { [self] in self.coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, + seed: self.seedPhrase, + walletBirthday: self.birthday, channelProvider: ChannelProvider(), - network: network + network: self.network ) + + try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } - try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } override func tearDownWithError() throws { try super.tearDownWithError() - NotificationCenter.default.removeObserver(self) try coordinator.stop() diff --git a/Tests/DarksideTests/SychronizerDarksideTests.swift b/Tests/DarksideTests/SychronizerDarksideTests.swift index e8a7bfb7..2a45e40b 100644 --- a/Tests/DarksideTests/SychronizerDarksideTests.swift +++ b/Tests/DarksideTests/SychronizerDarksideTests.swift @@ -34,15 +34,16 @@ class SychronizerDarksideTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - Task{ @MainActor [self] in - coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, + wait { [self] in + self.coordinator = try await TestCoordinator( + seed: self.seedPhrase, + walletBirthday: self.birthday, channelProvider: ChannelProvider(), - network: network + network: self.network ) + + try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } - try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main") } override func tearDownWithError() throws { diff --git a/Tests/DarksideTests/SynchronizerTests.swift b/Tests/DarksideTests/SynchronizerTests.swift index 2393efe1..bd0ef520 100644 --- a/Tests/DarksideTests/SynchronizerTests.swift +++ b/Tests/DarksideTests/SynchronizerTests.swift @@ -34,16 +34,16 @@ final class SynchronizerTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - Task { @MainActor [self] in - coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday + 50, //don't use an exact birthday, users never do. + wait { [self] in + self.coordinator = try await TestCoordinator( + seed: self.seedPhrase, + walletBirthday:self.birthday + 50, //don't use an exact birthday, users never do. channelProvider: ChannelProvider(), - network: network + network: self.network ) - } - try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) + try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) + } } override func tearDownWithError() throws { diff --git a/Tests/DarksideTests/TransactionEnhancementTests.swift b/Tests/DarksideTests/TransactionEnhancementTests.swift index e2418fa8..bb05205c 100644 --- a/Tests/DarksideTests/TransactionEnhancementTests.swift +++ b/Tests/DarksideTests/TransactionEnhancementTests.swift @@ -83,8 +83,6 @@ class TransactionEnhancementTests: XCTestCase { return } - - guard case .success = dbInit else { XCTFail("Failed to initDataDb. Expected `.success` got: \(String(describing: dbInit))") return @@ -150,7 +148,7 @@ class TransactionEnhancementTests: XCTestCase { await processor.start() } - func testBasicEnhacement() async throws { + func testBasicEnhancement() async throws { let targetLatestHeight = BlockHeight(663200) do { diff --git a/Tests/DarksideTests/Z2TReceiveTests.swift b/Tests/DarksideTests/Z2TReceiveTests.swift index da8cd937..000330dd 100644 --- a/Tests/DarksideTests/Z2TReceiveTests.swift +++ b/Tests/DarksideTests/Z2TReceiveTests.swift @@ -30,22 +30,20 @@ class Z2TReceiveTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() - - Task{ @MainActor [self] in - coordinator = try await TestCoordinator( - seed: seedPhrase, - walletBirthday: birthday, + wait { [self] in + self.coordinator = try await TestCoordinator( + seed: self.seedPhrase, + walletBirthday: self.birthday, channelProvider: ChannelProvider(), - network: network + network: self.network ) - } - try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) + try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName) + } } override func tearDownWithError() throws { try super.tearDownWithError() - NotificationCenter.default.removeObserver(self) try coordinator.stop() diff --git a/Tests/TestUtils/XCAsyncTestCase.swift b/Tests/TestUtils/XCAsyncTestCase.swift index d9020ac0..14c25de4 100644 --- a/Tests/TestUtils/XCAsyncTestCase.swift +++ b/Tests/TestUtils/XCAsyncTestCase.swift @@ -9,28 +9,8 @@ /// import Foundation import XCTest -class XCAsyncTestCase: XCTestCase { - - func asyncSetUpWithError() async throws { - fatalError("Must override") - } - - func asyncTearDownWithError() async throws { - fatalError("Must override") - } - - override func setUpWithError() throws { - wait { - try await self.asyncSetUpWithError() - } - } - - override func tearDownWithError() throws { - wait { - try await self.asyncTearDownWithError() - } - } +extension XCTestCase { func wait(asyncBlock: @escaping (() async throws -> Void)) { let semaphore = DispatchSemaphore(value: 0) Task.init { diff --git a/ZcashLightClientKit.podspec b/ZcashLightClientKit.podspec index 92954037..a9761a27 100644 --- a/ZcashLightClientKit.podspec +++ b/ZcashLightClientKit.podspec @@ -1,10 +1,6 @@ Pod::Spec.new do |s| s.name = 'ZcashLightClientKit' -<<<<<<< HEAD s.version = '0.17.0-alpha.2' -======= - s.version = '0.16.13-beta' ->>>>>>> master s.summary = 'Zcash Light Client wallet SDK for iOS' s.description = <<-DESC @@ -25,11 +21,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '13.0' s.dependency 'gRPC-Swift', '~> 1.8.0' s.dependency 'SQLite.swift', '~> 0.13.0' -<<<<<<< HEAD s.dependency 'libzcashlc', '0.1.0-beta.1' -======= - s.dependency 'libzcashlc', '0.0.3' ->>>>>>> master s.static_framework = true end From c0f1aa959af2291531e5a5c0c2bdfc6fe0fc7557 Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Mon, 31 Oct 2022 20:45:58 -0300 Subject: [PATCH 10/11] Fix SendViewController `viewDidLoad` --- .../ZcashLightClientSample/Send/SendViewController.swift | 6 +++--- .../Block/Processor/CompactBlockProcessor.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift index daab58af..9768db81 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift @@ -33,13 +33,13 @@ class SendViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() synchronizer = AppDelegate.shared.sharedSynchronizer + let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(viewTapped(_:))) + self.view.addGestureRecognizer(tapRecognizer) + setUp() Task { @MainActor in // swiftlint:disable:next force_try try! await synchronizer.prepare() } - let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(viewTapped(_:))) - self.view.addGestureRecognizer(tapRecognizer) - setUp() } override func viewDidAppear(_ animated: Bool) { diff --git a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift index 6df52856..d5c3c4f8 100644 --- a/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift +++ b/Sources/ZcashLightClientKit/Block/Processor/CompactBlockProcessor.swift @@ -501,7 +501,7 @@ public actor CompactBlockProcessor { notifyError(CompactBlockProcessorError.maxAttemptsReached(attempts: self.maxAttempts)) case .downloading, .validating, .scanning, .enhancing, .fetching: LoggerProxy.debug("Warning: compact block processor was started while busy!!!!") - self.needsToStartScanningWhenStopped = true + self.`needsToStartScanningWhenStopped` = true } return } From 08e6738cf700de03936614473a28fe4228c834fb Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Tue, 1 Nov 2022 07:47:31 -0300 Subject: [PATCH 11/11] Fix compiler error --- Tests/DarksideTests/AdvancedReOrgTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/DarksideTests/AdvancedReOrgTests.swift b/Tests/DarksideTests/AdvancedReOrgTests.swift index 0a68f746..5b8f6068 100644 --- a/Tests/DarksideTests/AdvancedReOrgTests.swift +++ b/Tests/DarksideTests/AdvancedReOrgTests.swift @@ -46,7 +46,7 @@ class AdvancedReOrgTests: XCTestCase { } override func tearDownWithError() throws { - super.tearDownWithError() + try super.tearDownWithError() NotificationCenter.default.removeObserver(self) try coordinator.stop() try? FileManager.default.removeItem(at: coordinator.databases.cacheDB)