Commit Graph

81 Commits

Author SHA1 Message Date
Lukas Korba 7e0ef54656 [#1469] Use Tor for single-shot lightwalletd requests
- TorLwdConn refactored to resolve SwiftLint issues and best practives
- TorLwdConn getInfo, getTreeState and latestBlockHeight methids implemented
- LightWalletGRPCService enhanced to use available TOR methods
- Code cleaned up
- Changelog updated
- documented tor connection methods
- torConnection initialization when fails, fallback to classic compactTxStreamer
2025-05-30 18:52:49 +02:00
Jack Grigg 07b33f11a2 Migrate to second preview of FFI 0.13.0 2025-02-28 02:46:47 +13:00
Jack Grigg bce8085690 Add APIs for fetching the ZEC-USD exchange rate over Tor. 2024-07-30 11:02:10 +01:00
Lukas Korba 3429afa9dc [#1177] Remove globalDBLock
- globalDBLock has been removed and replaced with global DBActor

[#1177] Remove globalDBLock (#1409)

- linter issues
2024-04-09 18:58:20 +02:00
Lukas Korba 3e263f0c35 [#1325] Log metrics
- the logger has been extended to log the level as well
- there is only partial match of levels between SDK logger levels, OSLogEntryLogLevel and OSLogType so only debug, info, error are fully matched
- this is a base for the exporter on client's side

[#1325] Log metrics

- typos fixed

[#1325] Log metrics

- scan metric logs added

[#1325] Log metrics

- Scan & Enhance logs

[#1325] Log metrics

- checkpoints updated
- every CBP action is measured separately and collects the data, when the sync is done it dumps overview of the run to the logger
- next run clears out the previous data and starts to collect fresh reports for the run

[#1325] Log metrics (#1327)

- changelog update

[#1325] Log metrics (#1327)

- SDKMetrics updated to be mockable
- unit test updated

[#1325] Log metrics (#1327)

- performance tests cleaned out

[#1325] Log metrics (#1327)

- Network tests buildable again
2023-12-12 08:59:52 +01:00
Lukas Korba 4b45c15a96 Comments addressed
- all comments from the review (round 1) resolved
2023-09-13 09:24:26 +02:00
Lukas Korba f3f519bfea [#1252] NetworkTests fails to run
- NetworkTests are buildable and can run not crashing due to lack of mocked properties
- most tests have been fixed and pass again
2023-09-11 08:34:09 +02:00
Lukas Korba 2f521d7857 [#1242] Fix unit tests after SBS changes
- DarkSide, Network and Performance tests were modified to be buildable again
2023-09-10 08:43:33 +02:00
Lukas Korba 95536638e5 [#1176] Cover Spend before Sync with tests
- WIP

[#1176] Cover Spend before Sync with tests

- next batch of updates

[#1176] Cover Spend before Sync with tests

- last batch of fixes and new tests

[#1176] Cover Spend before Sync with tests

- package.resolved updated

[#1176] Cover Spend before Sync with tests (#1212)

- added tests for brand new actions related Spend before Sync
- RewindActionTests
- UpdateChainTipActionTests
- UpdateSubtreeRootsActionTests
- ProcessSuggestedScanRangesActionTests
2023-09-07 13:23:50 +02:00
Jack Grigg e7621204e5 Update Rust dependencies with account birthdays and scan progress
The previous FFI repo revisions no longer exist; commits between
87faf91096 and here will not build.

Update Rust dependencies with account birthdays and scan progress

- fixes for SampleApp
2023-09-07 09:26:48 +02:00
Lukas Korba 34af1f1611 [#1140] ClearCache action before anything starts
- draft

[#1140] ClearCache action before anything starts

- ClearCache action right after the idle action, clearing out metadata so the sync process can be fully restored from the DB and live blockchain values only.
- InternalSyncProgress removed
- InternalSyncProgressStorage removed
- Sync process control logic updated, controlled by latestScannedHeight and firstUnenhancedHeight only
- cleaned up unused code

[#1140] ClearCache action before anything starts

- ChecksBeforeSyncAction removed
- Offline tests fixed

[#1140] ClearCache action before anything starts

- fixed injection of a wallet birthday, the sync range must start with wallet BD instead of lower bound

[#1140] ClearCache action before anything starts

- Network tests fixed
- DarkSideTests partially fixed

[#1140] ClearCache action before anything starts

- rewind actions extension in compact block processor added

[#1140] ClearCache action before anything starts

- draft

[#1140] ClearCache action before anything starts

- DarkSideTests fixed

[#1140] ClearCache action before anything starts

- SyncRanges modified to be even less dependent on ranges, now it holds just 3 values (latest block height, latest scanned height if any, first unenhanced height if any), the rest is computed on the fly

[#1140] ClearCache action before anything starts

- SyncRanges struct not anymore, refactored to SyncControlData, holding just 3 mentioned values

[#1140] ClearCache action before anything starts

- cleanup

[#1140] ClearCache action before anything starts (#1148)

- TODO solved, the UTXOs fetcher doesn't work with range anymore, therefore reporting 100%
2023-06-28 12:34:41 +02:00
Michal Fousek 21a3c06b00 [#700] CompactBlockProcessor as state machine proof of concept
- For now I created `CompactBlockProcessorNG` where I started with
  implementation of the state machine. I did it to not break the rest of
  the SDK. This change will be merged to the feature branch. And before
  it is merged to `main` branch code from `CompactBlockProcessorNG` will
  be moved to `CompactBlockProcessor`.
- The new code is not used. It just shows and explains how it is done.
  It is proof of concept.
- I did put either commented current code or comment to some places to
  explain what should be done there.
- New important data types:
  - `ActionContext` is context that can hold any data that needs to be
    shared between actions. For example sync ranges or current state.
  - `CBPState` is state of the `CompactBlockProcessor`. Each state is
    handled by one action. This doesn't apply to terminal states like
    `finished` or `failed`.
  - `ActionProgress` is very similar to `CompactBlockProgress`.
    Different actions reports progress differently and `ActionProgress`
    represents this.
  - `Action` is protocol that defines API of an action. It has one run
    method that executes the code of the action
- CBP first creates actions for (almost) each state in `makeActions()`
  method. Then the "magic" is done in `CompactBlockProcessorNG.run()` method.
  Here is main loop which takes action for current state and execute it.
  It's expected that action does it's work and then updates the context
  with new state. And this happens until some terminal state
  (`finished`, `failed`, `stopped`) is reached.
- After the transition to state machine API of the
  `CompactBlockProcessor` should stay the same. No changes should be
  required in `SDKSynchronizer`.

[#700] Add documentation for CompactBlockProcessor state machine

- plantuml tool is used to generate diagram.

[#1054] Add config to state machine CBP

Closes #1054

[#1043] Implement DownloadAction

Closes #1043

[#1049] Implement ValidateAction

Closes #1049

[#1050] Implement ValidateServerAction

Closes #1050

[#1056] Add constructors to state machine CBP

Closes #1056

[#1061] Add failure methods for state machine CBP

Closes #1061

[#1055] Implement retry timer to state machine CBP

Closes #1055

[#1057] Implement start for state machine CBP

Closes #1057

[#1058] Implement stop for state machine CBP

Closes #1058

[#1052] Implement AfterSyncHooksManager when using state machine CBP

Closes #1052

[#1060] Implement wipe for state machine CBP

Closes #1060

[#1059] Implement rewind for state machine CBP

Closes #1059

[#700] Add idle state to CBP state machine

This is required so the CBP can detect start of the sync process.

[#700] Implement sending of some events from CompactBlockProcessorNG

[#700] Implement progress reporting in state machine CBP

[#1045] Implement FetchUTXOsAction

- draft of the fetching

[#1045] Implement FetchUTXOsAction

- updated the way Actions communicate data back to the CBP
- used this mechanism to pass result of utxos fetch so it's passed to the SDKSynchronizer as an Event

[#1042] Implement ComputeSyncRangesAction

Closes #1042

[#700] Implement cache clearing when some actions fail

[#1043] Fix batch range computation in DownloadAction

[#1046] Implement SaplingParamsAction

- action for sapling param files finished

[#1048] Implement ScanDownloadedButUnscannedAction

- scan downloaded but unscanned blocks

[#1047] Implement ScanAction

- scan action with the proper ranges computed

[#1047] Implement ScanAction (#1085)

- fixed logger message

[#1044] Implement EnhanceAction

Closes #1044

[#1041] Implement ClearCacheAction

Closes #1041

[#1040] Implement ClearAlreadyScannedBlocksAction

Closes #1040

[#1039] Implement ChecksBeforeSyncAction

Closes #1039

[#700] Make CBP state machine work

[#1050] Implement ValidateServerAction

- broken tests commented out and tracked in the tickets
- new test for ValidateServerAction

[#1051] Update how progress is computed after switch to state machine

Closes #1051

- new proposal for the progress computation
- OverallProgress value is passed to the Synchronizer as a Float
- OverallProgress is a result of fetch, scan and enhance operations
- Order of actions no longer influences the computation
- Actions report partial updates, CompactBlockProgress actor holds current state and computes the OverallProgress

[#1049] Implement ValidateAction

- synchronizer offline tests updated so it compiles, review is requested in a different ticket
- ValidateAction tests added
- BlockValidator mock generated

[#1047] Implement ScanAction

- ScanAction tests
- refactor of validateAction -> validateServerAction
- generated few more mocks for the DI

[#1045] Implement FetchUTXOsAction

- FetchUTXOsAction tests
- UTXOFetcher mocks

[#1045] Implement FetchUTXOsAction

- enhanced with mocked values and more checks

[#1046] Implement SaplingParamsAction

- SaplingParamsAction tests
- added TODO for TestCoordinator reset()
- SaplingParametersHandler mock added

[#1046] Implement SaplingParamsAction

- SaplingParamsAction tests
- added TODO for TestCoordinator reset()
- SaplingParametersHandler mock added

[#1046] Implement SaplingParamsAction

- rebased so I get functionality of improved mock checks
- enhanced SaplingParamsAction tests
- enhanced ValidateAction tests
- enhanced ScanAction tests

[#1046] Implement SaplingParamsAction

- scanAction tests more checks added

[#1044] Implement EnhanceAction

- EnhanceAction tests focused on 2 different methods:
- decideWhatToDoNext covered separately, decisions where the state machine goes next
- run tests for different cases
- new mocks generated for enhacer
- some typos fixed

[#1044] Implement EnhanceAction (#1107)

- empty assert messages fixed

[#700] Get rid of ScanDownloadedButUnscannedAction

Before the state machine download and scan was called in one loop. And
processing range for one batch was same for both of them. Therefore
there was code which scanned downloaded but not scanned blocks.

But now download and scan are independent. So it is possible to remove
`ScanDownloadedButUnscannedAction`.

[#700] Make NetworkTests compilable

Some tests are disabled for now (list is in #1115). And `NetworkTests`
can be compiled and all the enabled tests work.

[#1043] Implement DownloadAction

- DownloadAction tests
- BlockDownloader mock

[#1043] Implement DownloadAction (#1110)

- support functions set to private

[#1039] Implement ChecksBeforeSyncAction

- ChecksBeforeSyncAction tests
- all support functions in Action tests are set to private
- let _ = -> _ = refactor
- CompactBlockRepository mock added

[#1040] Implement ClearAlreadyScannedBlocksAction

- Implement ClearAlreadyScannedBlocksAction tests
- CompactBlockRepository mock added

[#1041] Implement ClearCacheAction

- ClearCacheAction tests
- CompactBlockRepository mock added

[#1042] Implement ComputeSyncRangesAction

- ComputeSyncRangesAction tests
- fixed all tests after merge of latest SDK changes related InternalSyncProgress
- all actions marked as final class

[#1042] Implement ComputeSyncRangesAction (#1120)

- Custom LatestBlocksDataProviderMock removed from the project

[#1122] Implement FileManager protocol and dependency

- ZcashFileManager implemented
- MigrateLegacyCacheDBAction refactored to be dependent on ZcashFileManager
- ZcashFileManager mock added

[#1122] Implement FileManager protocol and dependency (#1124)

- code cleanup

[#1121] Implement MigrateLegacyCacheDBAction

- MigrateLegacyCacheDBAction tests WIP
- tests naming cleanup

[#1121] Implement MigrateLegacyCacheDBAction

- MigrateLegacyCacheDBAction tests finished

[#700] Fix DarksideTests

Closes #1102

Some tests that can't be compiled are disabled for now. List is in #1126.

This PR contains multiple fixes. Most of the fixes is done in the code.
Not in the tests. That is good news.

Fixes:
- `config` inside `CompactBlockProcessor` can be updated during the
  tests. And it must be also updated inside the actions. So
  `ConfigProvider` is added and it is wrapper for config that is passed
  to any instance of `Action` and provides updated config.
- Fixed `EnhanceAction`. Now it should update all the blocks in the
  enhance range even when the remaining count of blocks is lower than
  1000.
- Fixed `fail()` and `validationFailed()`. These two were canceling
  `syncTask`. But that stopped run loop in a bad way.

[#1129] Final check of all State Machine Action tests

- XTCAsset messages checked
- test naming checked and fixed

[#1126] Fix DarksideTests in state machine branch

Closes #1126

Fix offline tests

Closes #1098
Closes #1095
Closes #1094

Most of the tests is removed. Either the code that was tested doesn't
exists. Or now tests for state machine actions do this work.

[#1115] Fix NetworkTests in state machine branch

Closes #1115

[#700] Fix progress reporting

Some actions in the sync process may not run. For example there are no
transactions to enhance and therefore there is no enhance progress. And in
cases like this computation of final progress won't work properly.
So let's fake 100% progress at the end of the sync process.
2023-05-30 15:01:42 +02:00
Michal Fousek c0c0c426d5 [#1111] Change storage for InternalSyncProgress
Closes #1111

- `InternalSyncProgress` has now new disk storage implementation:
  `InternalSyncProgressDiskStorage`.
- When then `UserDefaults` was used as disk storage there were no IO errors
  to handle. But now the code in `InternalSyncProgressDiskStorage`
  writes to files and reads from files. So there are errors to handle.
  Because of this protocol `InternalSyncProgressStorage` changed a bit
  and API of `InternalSyncProgress` changed a bit. Now all the functions
  throws.
- It is possible to make progress storage IO errors silent but I think
  that storing of the progress is very essential to the sync process. So
  I think that when progress storage fails then the sync process should
  fail.
- `Initializer` has new parameter `generalStorageURL`. It is directory
  where `InternalSyncProgressDiskStorage` stores progress files. In
  future this can be used for storing any data the SDK wants.
2023-05-22 20:42:11 +02:00
Michal Fousek d091660b79 [#1016] Rebuild download stream periodically while downloading
- Rebuild download stream in `BlockDownloaderImpl` each 10 batches. So
  currently stream downloads 1000 blocks and then new stream is created.
- Memory stays between 60MB and 70MB during sync in the Sample app.
2023-05-17 10:36:02 +02:00
Michal Fousek 5d2b2298b5 [#1012] Introduce dependency injection in the SDK
Closes #1012

- This is the first change for the dependency injection. This change
  adds `DIContainer` which is used to register and resolve dependencies.
- Then this change shows how `DIContainer` can be used to resolve
  dependencies. And it also shows how to mock dependencies in tests.
- Constructors of `Initializer` are changed to support mocking of
  depedendencies. But it doesn't affect public API in any way.
- Depedencies are registered in `Dependencies.setup()`. Then in the code
  `container.resolve(SomeType.self)` is called to get instance of the
  dependency.
- `ZcashTestCase` class is added. It inherits from `XCTestCase` and
  should be used for base class in tests. `ZcashTestCase` takes care of
  creation of `DIContainer` for dependencies mocking. In future we can
  maybe move there more things that are used in each test.
- Lot is missing here. Not all the code is using dependency injection.
  Tests for `DIContainer` are missing. Only `OfflineTests` work now
  (other tests can't be even compiled). It will be added in future
  changes.
2023-05-08 14:58:49 +02:00
Michal Fousek 84d8002ddb Fix tests related to blocks downloading
- Call `setSyncRange()` in tests.
- Little update to `BlockDownloader` API so it makes more sense.
2023-05-08 11:08:54 +02:00
Michal Fousek 0032fedde7 [#442] Introduce parallel downloading and scanning
- `BlockDownloaderImpl` is changed. It now spawns detached Task to
  download blocks. So blocks can be downloaded in parallel with scanning
  process.
- `Synchronizer.stop()` is no longer async.
- Blocks cache cleaning is changed. It's not possible to drop the whole
  cache now. There are some blocks pre-downloaded which weren't scanned
  yet.
2023-05-05 09:35:43 +02:00
Michal Fousek 3ffea42454 [#901] Use fulfillment instead of wait in async context in tests
Closes #901
2023-05-01 09:07:43 +02:00
Michal Fousek 5f162d01f8 Make all methods in ZcashKeyDerivationBackendWelding non async
It looks like that some methods in `ZcashKeyDerivationBackendWelding`
were left async by mistake. There is no reason for any method there to
be async.

After this change no method in `DerivationTool` has to async. It makes
things much easier.
2023-04-25 16:16:04 +02:00
Michal Fousek 724d410fad
[#361] Introduce ZcashError (#1005)
This PR introduces `ZcashError` enum. This enum represents any error
that can be thrown inside of the SDK and outside of the SDK. Also
`ZcashError` is used in `LightWalletGRPCService` and handled in
`CompactBlockProcessor` as example.

Why enum? First I tried this with some structure which contained code,
message and underlyingError. Problem was when some specific place in the
SDK would like to attach some additional data to error. I didn't want to
add some generic dictionary to store anything with the error.

So I used enum to identify error. Each member can have specified amount
of associated values. So specific error can bring some context data. And
it's type safe.

Each error has also a code. Relationship between errors and codes is
1:1. It may looks bit redundant but it's important. The client app now
can choose how to process errors. Either identify those by the error
itself or by code.

Definition or errors and codes is in `ZcashErrorDefinition`. And then
`ZcashError` and `ZcashErrorCode` are generated by Sourcery. Thanks to
this it is easier to maintain the final code. And it gives us ability to
generate any kind of documentation for the errors and codes. I created
simple example of this in this PR. And it doesn't make the SDK
completely dependent on the Sourcery. Final structures aren't super
complicated and can be written manually if needed.

[#923] Update error handling in DatabaseStorageManager.swift

- cleanup of DatabaseStorageManager, not used anymore
- ZcashError for SimpleConnectionProvider

Revert "[#923] Update error handling in DatabaseStorageManager.swift"

This reverts commit 94e028d31a.

Fix script which generates ZcashError

[#922] Update error handling in DatabaseMigrationManager.swift

Closes #922

[#923] Update error handling in DatabaseStorageManager.swift

- The DatabaseStorageManager is not used so I deleted it
- SimpleConnectionProvider's errors updated

Fix tests

[#955] Update error handling in SaplingParameterDownloader

Closes #955

[#936] Update error handling in NotesDao

Closes #936

[#935] Update error handling in BlockDao

Closes #935

[#931] InternalSyncProgress.computeNextState doesn't need to throw

Closes #931

[#950] Update error handling in rust backend

Closes #949
Closes #950

[#941] Update error handling in AccountEntity

Closes #941

[#928] Update error handling in FSCompactBlockRepository

Closes #928

[#925] Update error handling in BlockDownloaderService (#974)

- BlockDownloaderService errors updated

[#924] Update error handling in BlockDownloader (#973)

- BlockDownloaderStream nextBlock updated

[#942] Update error handling in TransactionEntity (#977)

- ZcashTransaction init errors converted to the ZcashError

[#939] Update error handling in TransactionDao (#976)

- TransactionRepositoryError removed and replaced with ZcashError
- all TransactionDAO errors converted to ZcashError

[#943] Update error handling in ZcashCompactBlock

Closes #943

[#945] Update error handling in Memo

Closes #945

[#934] Update error handling in Checkpoint

Closes #944
Closes #934

[#938] Update error handling in PendingTransactionDao

Closes #938

[#926] Update error handling in BlockEnhancer

- WIP, switching to transaction repository to unblock this ticket

[#926] Update error handling in BlockEnhancer

- enhancer's errors done

[#926] Update error handling in BlockEnhancer (#994)

- cleanup

[#952] Update error handling in DerivationTool

Closes #952

[#932] Update error handling in BlockValidator

Closes #932

[#940] Update error handling in UnspentTransactionOutputDao

Closes #940

[#946] Update error handling in WalletTypes

Closes #946

[#954] Update error handling in WalletTransactionEncoder

Closes #954

[#953] Update error handling in PersistentTransactionManager

Closes #953

[#956] Update error handling in Initializer

Closes #956

[#947] Update error handling in Zatoshi (#996)

- Zatoshi's errors converted to ZcashError

[#927] Update error handling in UTXOFetcher (#997)

- UTXOFetcher resolved

Use let instead of var where applicable

In the SDK `var` was used on places where `let` would be sufficient. And
default strategy in Swift should use use `let` until mutability is
required. So all these places are changed. No logic is changed.

[#933] Update error handling in CompactBlockProcessor

- CompactBlockProcessor's errors refactored to ZcashError

[#933] Update error handling in CompactBlockProcessor #999

- comments addressed

[#951] Update error handling in SDKSynchronizer

- SDKSynchronizer's errors refactored to ZcashError

[#951] Update error handling in SDKSynchronizer (#1002)

- comments resolved

Make DerivationTool constructor public

DerivationTool.init should be public. This was removed by accident when
adopting async.

[#361] Add changelog
2023-04-24 18:15:20 -03:00
Lukas Korba 99b24c2081
[#908] Add last and latest blocks data to Synchronizer State (#911)
- attached to the processor's timer
- added latest scanned time and latest block height
- sample app showing the new values alongside with the %
- unit tests fixed
- latestBlock() API added
- the transaction repository is no longer used to update the exposed values during the syncing
2023-04-14 09:08:37 +02:00
Michal Fousek 2bbc5800bd [#888] Make actor from ZcashRustBackendWelding
Closes #888.

- `ZcashRustBackend` is actor now. So majority of methods in this actor
  are now async.
- Some methods stayed `static` in `ZcashRustBackend`. It would be hard
  to pass instance of the `ZcashRustBackend` to the places where these
  methods are used in static manner. And it would change lot of APIs.
  But it isn't problem from technical perspective because these methods
  would be `nonisolated` otherwise.
- Methods `lastError()` and `getLastError()` in `ZcashRustBackend` are
  now private. This makes sure that ther won't be aby race condition
  between other methods and these two error methods.
- All the methods for which was `lastError()` used in code now throw
  error. So `lastError()` is no longer needed outside of the
  `ZcashRustBackend`.
- There are in the public API related to `DerivationTool`.
- `DerivationTool` now requires instance of the `ZcashRustBackend`. And
  `ZcashRustBackend` isn't public type. So `DerivationTool` doesn't have
  any public constructor now. It can be created only via
  `Initializer.makeDerivationTool()` instance method.
- `deriveUnifiedSpendingKey()` and `deriveUnifiedFullViewingKey()` in
  `DerivationTool` are now async. It is because these are using
  `ZcashRustBackend` inside. `DerivationTool` offers alternative
  (closure and combine) APIs. But downside is that there is no sync API
  to dervie spending key or viewing key.
- Some methods of the `DerivationTool` are now static. These methods
  don't use anything that requires instance of the `DerivationTool`
  inside.

[#888] Use Sourcery to generate mocks

- I wrote mock for `Synchronizer` manually. And it's tedious and long
  and boring work.
- Now `ZcashRustBackendWelding` is changed a lot so it means
  `MockRustBackend` must be changed a lot. So I decided to introduce
  `sourcery` to generate mocks from protocols so we don't have to do it
  manually ever.
- To generate mocks go to `ZcashLightClientKit/Tests/TestUtils/Sourcery`
  directory and run `generateMocks.sh` script.
- Your protocol must be mentioned in `AutoMockable.swift` file.
  Generated mocks are in `AutoMockable.generated.swift` file.

[#888] Fix Offline tests

- Offline tests target now runs and tests are green.
- There is log of changes in tests. But logic is not changed.
- Updated `AutoMockable.stencil` so sourcery is able to generate mock as
  actor when protocol is marked with: `// sourcery: mockActor`.
- Last few updates in `ZcashRustBackendWelding`. In previous PR `rewindCacheToHeight`
  methods was overlooked and it didn't throw error.
- Removed `MockRustBackend` and using generated
  `ZCashRustBackendWeldingMock` instead.
- Using generated `SynchronizerMock`.

[#888] Fix NetworkTests

- Changed a bit how rust backend mock is used in the tests. Introduced
  `RustBackendMockHelper`. There are some state variables that must be
  preserved within one instance of the mock. This helper does exactly
  this. It keeps this state variables in the memory and helping mock to
  work as expected.

[#888] Fix Darkside tests

Create ZcashKeyDeriving internal protocol

Use New DerivationTool that does not require RustBackend

Remove duplicated methods that had been copied over

[#888] Fix potentially broken tests

I broke the tests because I moved `testTempDirectory` from each
`TestCase` to the `Environment`. By this I caused that each tests uses
exactly same URL. Which is directly against purpose of
`testTempDirectory`.

So now each test calls this one and store it to local variable. So each
test has unique URL.

[#888] Add ability to mock nonisolated methods to AutoMockable.stencil

[#888] Add changelog and fix the documentation in ZcashRustBackendWelding

[#888] Rename derivation rust backend protocol and remove static methods

- Renamed `ZcashKeyDeriving` to `ZcashKeyDerivationBackendWelding`. So
  the naming scheme is same as for `ZcashRustBackendWelding`.
- `ZcashKeyDerivationBackend` is now struct instead of enum.
- Methods in `ZcashKeyDerivationBackendWelding` (except one) are no
  longer static. Because of this the respective methods in
  `DerivationTool` aren't also static anymore.
2023-04-11 17:51:28 +02:00
Michal Fousek 866fe3d6f0 Remove anything related to Notifications
- There was still some code inside the SDK related to NotificationCenter
  and notifications. But notifications are no longer needed. So all this
  code can go away.
2023-03-31 11:04:39 +02:00
Michal Fousek 96f763d42f [#462] Get rid of XCTestCase.wait 2023-03-31 08:58:19 +02:00
Michal Fousek c4f7f6ff1e [#469] Make ZcashRustBackendWelding async
Closes #469.

- Methods defined in `ZcashRustBackendWelding` protocol which are doing
  some IO operations are now async.
- `Initializer` no longer have methods to get balance. Only
  `Synchronizer` now have these methods. These methods are newly async.
  And `Initilializer` doesn't have alternative APIs.
- There is lot of changes in tests but those are mostly adding `await`.
  No logic is changed.
2023-03-30 19:08:56 +02:00
Michal Fousek 5c979f42e6 [#209] Add support for multiple instances of the SDKSynchronizer
Closes #209.

[#845] Introduce ZcashSynchronizerAlias enum

Closes #845.

[#852] SDKSynchronizer using queues label based on the alias

Closes #852.

[#847] Remove posibility to use DatabaseStorageManager as singleton

Closes #847.

[#850] Remove synchronizerConnectionStateChanged notification

Closes #850.

[#855] Add check if the Alias is already used

Closes #855

- Added `UsedAliasesChecker` utility which is used to register aliases
  that are in use.
- `prepare()` and `wipe()` methods now check if the current alias can't
  be used and if not then `InitializerError.aliasAlreadyInUse` is
  thrown/emitted.
- Some public methods that could cause harm if used with the Alias that
  is already in use now throw `SynchronizerError.notPrepared`. Thanks to
  this the client app is forced to call `prepare()` first. And
  `prepare()` does check for the Alias.
- Added tests for new conditions.

[#849] Make InternalSyncProgress aware of the Alias

Closes #849.

[#853] Only instance with default Alias migrates legacy cache DB

Closes #853.

[#851] Apply the Alias to the URLs

Closes #851.

- `Initializer` now updates paths according to alias before paths are
  used anywhere in the SDK.
- Paths update can fail. It would be incovenient for the client apps to
  handle errors thrown from `Initiliazer` constructor. So the error is
  then handled in `SDKSynchronizer.prepare()` or `SDKSynchronizer.wipe()`.

[#846] Stop using SDKMetrics as singleton (#862)

- metrics are not longer a singleton
- tests fixed
- metrics outside init of the synchronizer

[#848] Make logger aware of the alias

- logger is now an instance passed throughout the sdk instead of a static proxy

[#848] Make logger aware of the alias (#868)

- comments addressed

[#848] Make logger aware of the alias (#868)

- returning protocol back

Fix typos

[#856] Add possibility to test multiple synchronizers in the sample app

Closes #856.

- Added `alias` property to `Synchronizer`.
- Added `SyncBlocksListViewController` which provides UI to use multiple
  synchronizers at once.

[#209] Add changelog

- Add changelog for #209.
- Overall improve readability of the rendered changelog. Tickets
  references are now prefixed with `###` instead of `- `.

Fix compilation
2023-03-27 20:42:52 +02:00
Michal Fousek c2d9c6f1e8 [#871] Cleanup internals of the SDK and use async where applicable
Closes #871.
2023-03-27 16:16:42 +02:00
Michal Fousek ce83dcef12 [#870] LightWalletGRPCService is using only async streamer
Closes #870.
2023-03-27 13:45:22 +02:00
Michal Fousek 436fa1fc47 [#831] Add SDKSynchronizer wrappers for non-async API
This change introduces two new protocols: `ClosureSynchronizer` and
`CombineSynchronizer`. These two protocols define API that doesn't use
`async`. So the client can choose exactly which API it wants to use.
    This change also introduces two new objects: `ClosureSDKSynchronizer`
and `CombineSDKSynchronizer`. These two implement the respective protocols
mentioned above. Both are structures. Neither of these two keeps any state.
Thanks to this each is very cheap to create. And usage of these two isn't
mutually exclusive. So devs can really choose the best SDK API for each
part of the client app.

[#831] Use async inside of the SDKSynchronizer

- In general lot of methods inside the `SDKSynchronizer` and
  `CompactBlockProcessoer` which weren't async are now async. And other
  changes are made because of this change.
- `CompactBlockProcessor` no longer uses Combine to communicate with
  `SDKSynchronizer`. Reason for this is that Combine doesn't play great
  with async. Closure passed to `sink` isn't async.
- Because of this and because of how our tests work (receiving signals
  from CBP directly) `CompactBlockProcessor` must be able to handle more
  event closures. Not just one. So it now has `eventClosures`
  dictionary. It's little bit strange but it works fine.
- `SyncStatus` inside the `SDKSynchronizer` was previously protected by
  lock. Now it's protected by simple actor wrapper.
- Changes in tests are minimal. Changes were mady only because
  `CompactBlockProcessor` changes from Combine to closures.

[#831] Add tests for ClosureSDKSynchronizer

- Added tests are testing in general if the `ClosuresSDKSynchronizer` is correctly
  calling `Synchronizer` and if the values are correctly returned.
- `ClosuresSDKSynchronizer` doesn't contain any logic but it is public
  API and we should be sure that it works correctly.

[#831] Add tests for CombineSDKSynchronizer

[#831] Add changelog
2023-03-21 22:47:19 +01:00
Michal Fousek cb31acdd81 [#826] Change how the SDK is initialised
Closes #826

- `viewingKeys` and `walletBirthday` are removed from `Initializer`
  constuctor. These parameters are moved to `SDKSynchronizer.prepare`
  function.
- Constructor of the `SDKSynchronizer` no longer throws exception.
- Any value emitted from `lastState` stream before `SDKSynchronizer.prepare`
  is called has `latestScannedHeight` set to 0.
- `Initializer.initialize` function isn't public anymore. To initialize
  SDK call `SDKSynchronizer.prepare` instead.
- Real birthday is now known after the `SDKSynchronizer.prepare` is
  called. But this function isn't async and therefore it's hard to
  pass birthday from here to `CompactBlockProcessor` in synchronous
  manner. We must be sure that it's safe to call start() after prepare
  function finishes.
    For this reason `CompactBlockProcessor` has `walletBirthdayProvider`
  instead of `walletBirthday`. And this new parameter is closure which
  reads birthday from `Initiliazer` on each call. Thanks to this
  `CompactBlockProcessor` has always the right birthday.
- Some cleanup is done in `TestCoordinator`.
2023-03-13 15:32:55 +01:00
Francisco Gindre 24da80d36b
[#821] `failedToWriteMetadata` at sync startup (#822)
contains no public API changes.

Adds `func shouldClearBlockCacheAndUpdateInternalState() -> BlockHeight?` to `SyncRanges`
so that the compact block processor can advert internal states that are not consistent and
recover from such state.

Closes #821
2023-03-09 15:40:06 -03:00
Michal Fousek d09b00cabe [#795] Include sapling-spend file into bundle for tests
Closes #795

- Added structure `SaplingParamsSourceURL` which holds source URLs for
  sapling-spend file and sapling-output file. URLs are ultimately passed
  to `SaplingParameterDownloader`.
- This is done so it's possible to pass different URLs when running
  tests.
- sapling-spend file and sapling-output file are in tests bundle. And
  when running tests these files are loaded from bundle and not from
  network.
2023-02-20 10:03:16 +01:00
Michal Fousek 65a096d6cd [#796] Fix tests 2023-02-16 17:14:31 +01:00
Michal Fousek 65d6347bcf [#778] Add swiflint config file only for tests
Closes #778

- .swiftlint.yml is now used to lint only the code of the SDK.
- .swiftlint_tests.yml is now used to lint only the code of the tests.
  This config disables rules that were previously disabled in the code
  in lot of tests.
2023-02-13 13:36:58 +01:00
Michal Fousek 1ec12269ae [#764] Stop using Notifications inside the SDK
Closes #764

- All notification that were previously sent from CompactBlockProcessor are now gone.
- `CompactBlockProcessor` now provides `eventStream` to communicate with `SDKSynchronizer`.
- Added `synchronizerStoredUTXOs` notification.
- Tests are updated to not use notifications anymore. Some tests there
  weren't working before are now fixed.
- Added `CompactBlockProcessorEventHandler` utility class. Previously
  expectations were subscribing to notifications. This class replaces
  this functionality. It subscribes to events from
  `CompactBlockProcessor` and fullfill expectations.
2023-02-09 20:09:51 +01:00
Michal Fousek 34c08a3a81 [#771] Fix tests failing because of different paths passed to `FSCompactBlockRepository` and `FSMetadataStore`
Closes #771

- Renamed `cacheDirectory` param in `FSCompactBlockRepository`
  constructor to `fsBlockDbRoot`.
- Pass same paths to `FSCompactBlockRepository` and `FSMetadataStore`
  from tests.
2023-02-09 13:58:49 +01:00
Michal Fousek 385c0a7195 [#746] Modularize GRPC related code
Closes #746

- `LightWalletGRPCService` is no longer public. `LightWalletService` is no longer public.
- `LightWalletGRPCService` shouldn't be used dicrectly. Use `LightWalletServiceFactory` to create instance of the service.
- Moved sending of `blockProcessorConnectivityStateChanged` notification to `Initilizer`.
- All the errors from GRPC are mapped to `LightWalletServiceError`. Handling of `GRPCStatus` in the SDK is no longer required.
- `Service` directory (that contains GRPC code) is moved to `Modules/Service`. We can put more code to `Modules/` if we decide
to modularize more code.
2023-02-03 22:25:54 +01:00
Michal Fousek 34e444e632 [#742] Refactor blocks scanning in CompactBlockProcessor
Closes #742

- Added new protocol `BlockScanner` and new struct `BlockScannerImpl`. Scanning related code is extracted to `BlockScannerImpl`.
2023-02-03 15:54:10 +01:00
Michal Fousek 1a03fa6f7c [#743] Refactor blocks validation in CompactBlockProcessor
Closes #743

- Added new protocol `BlockValidator` and `BlockValidatorImpl` class. All the code related to blocks validation is extracted to `BlockValidatorImpl`.
- Fixed `testSingleDownloadAndScan()` test.
- Changed how validation error are handled. Previously validation error were handled directly next to validation code. And when some validation
errors happened method from `CompactBlockProcessor` were called. Now validation errors are handled in `CompactBlockProcessor.processNewBlocks`
in a same way as any other error that can occur during sync process.
2023-02-03 09:58:36 +01:00
Francisco Gindre fad3aae174
- [#679] Implementation of the File-system based block cache (#679)
Closes https://github.com/zcash/ZcashLightClientKit/issues/697
Closes https://github.com/zcash/ZcashLightClientKit/issues/720
Closes https://github.com/zcash/ZcashLightClientKit/issues/587
Closes https://github.com/zcash/ZcashLightClientKit/issues/667
Closes https://github.com/zcash/ZcashLightClientKit/issues/443
Closes https://github.com/zcash/ZcashLightClientKit/issues/754

- [#790] Fix ShieldFundsTests

Closes #790
Removes comments on `ShieldFundsTests` since those issues have been fixed

Depends on zcash-light-client-ffi changes that adopt newer versions of
 librustzcash crates `zcash_primitives 0.10`, `zcash_client_backend 0.7`,
`zcash_proofs 0.10`, `zcash_client_sqlite 0.5.0`.

Also allows wallets to define a shielding_threshold and will set
foundations to customize minimum confirmations for balances, spends
and shielding operations.

**Test Bootstrapping**

- `ZcashCompactBlockDescriptor`: struct that holds functions to
describe blocks as filenames and compare those filenames

`ZcashCompactBlockDescriptor.live` has the actual implementation
but it can be replaced by mocks if needed on Tests

main implementations are held under `FSCompactBlockRepository.filenameDescription` and `FSCompactBlockRepository.filenameComparison` on a separate extention

`DirectoryListingProviders` provide two default implementations of listing a
directory deterministically. `FileManager` does not define a sorting and needs to be done in-memory by calling `.sorted()` on the resulting collection. If this
is a big toll on performance it can be changed to a POSIX implementation but
this is good for now.

`ZcashCompactBlockDescriptor` adds a `height` helper function to
turn a filename into the height of the block stored.

Implemented `func latestHeight() throws -> BlockHeight ` that
returns the blockheight by querying the cache directory in a sorted
fashion and getting the last value and turning the filename into a
`BlockHeight`

Added `Meta` struct to ZcashCompactBlock.

Tests implemented:
- `filterBlockFiles`
- `testClearTheCache`
- `testLatestHeightEmptyCacheThrows`
- `testLatestHeightEmptyCacheThrowsAsync`
- `testRewindEmptyCacheDoesNothing`
- `testRewindEmptyCacheDoesNothingAsync`
- `testWhenBlockIsStoredItFollowsTheDescribedFormat`
- `testWhenBlockIsStoredItFollowsTheFilenameConvention`
- `testGetLatestHeight`
- `testRewindDeletesTheRightBlocks` test
- `testPerformanceExample` test. This isn't a real performance test because the API doesn't work with async/await yet

adopts `shield_funds` shielding threshold parameter

Implements `initBlockMetadataDb` and fix tests
Renames dbCache parameter to `fsBlockDbRoot`. Builds but tests don't pass.
Removes cacheDb uses from code. Testing utilities still persist.
Added needed information in  MIGRATING and CHANGELOG.
Added helper to perform deletion of legacy db and creation a the
new file system backed cache.

Renames parameters and changes code where needed.
Network Constants turned into `enum` with static methods.
DeletelastDownloadedBlock helper from initializer
Removes CompactBlockStorage and CompactBlockEntity.
Implements `latestCachedBlockHeight` on rustbackend.

*Replaces dependencies on ZcashRustWelding with `FSMetadataStore`*

This allows the tests to not depend in a particular implementation
of either the MockRustBackend of or ZcashRustBackend. Also provides
a way to test errors properly and switch implementations of critical
areas like `writeBlocks`.
2023-02-02 13:58:12 -03:00
Michal Fousek 6bbaad4cb1 [#740] Refator blocks downloading in CompactBlockProcessor
Closes #740

`CompactBlockDownloading` protocol is renamed to `BlockDownloaderService`. `CompactBlockDownloader` is renamed to `BlockDownloaderServiceImpl`.

What is the motivation for this rename?
Goal of this change is to extract code from `CompactBlockProcessor` which is related to downloading. So naturaly it should be called "downloader".
But `CompactBlockDownloader` was already taken. After analysis of `CompactBlockDownloading` and `CompactBlockDownloader` I found out that
`CompactBlockDownloader` doesn't download blocks exactly. It's more like abstraction over `LightWalletService`. And it does very similar job to
`LightWalletService`. That is why I decided to rename it to "service".

What is the motivation for protoco/impl naming scheme?
First `BlockDownloaderService` protocol doesn't describe capability in my eyes. It describe what something is. Also `BlockDownloaderServicing` sounds
strange. I agree that add suffix "Impl" to class name isn't super nice. But it is acceptable. And it makes sense to use nicer type name
(e.g. `BlockDownloaderService`) for protocol because it's used on much more places in the code.

- Added `BlockDownloader` protocol and `BlockDownloaderImpl` class. The code related to downloading was exctracted to this class.
2023-01-31 15:24:41 +01:00
Lukas Korba f69da50ba9
[#747] Remove SampleLogger and replace it with OSLogger (#748)
- SampleLogger removed
- OSLogger used
- category default
2023-01-26 18:14:07 +01:00
Lukas Korba 372ea5af70
[#711] Add Swiftlint plug in to SDK (#722)
- plugin integrated
- errors resolved
- warnings resolved
- package.swift macos platform version 10_15 -> 12
2023-01-18 17:09:04 +01:00
Lukas Korba dcc6ef1757
[#671] Make CompactBlockProcessor Internal (#710)
- sdk and demo app modified
- changelog updated
2023-01-12 13:05:11 +01:00
Michal Fousek becadf21c8 Merge branch 'main' into 657_download_change 2023-01-05 09:50:00 +01:00
Dimitris Apostolou 6c3423181d
Fix typos 2022-12-31 12:50:16 +02:00
Michal Fousek 4b4416b1e1 Merge branch 'master' into 657_merge_master
- Changed how metrics are pushed when downloading and scanning blocks.
2022-12-22 15:35:11 +01:00
Lukas Korba 3c3b97ca42
[#663] Create a benchmarking section on the Demo App that can be automated (#681)
- SDKMetrics singleton for the measurement
- download, validate and scan blocks supported
- Sample app refactored to use SDKMetrics, connected to appropriate notifications and labels
- enhancement metric added
- total sync time metric added
- sample app extended to show summary time and operations summaries
- unit tests for the SDKMetrics
- doc for the SDKMetrics and our approach for the performance testing in general
- changelog update
2022-12-21 13:30:05 +01:00
Michal Fousek 349148cd38 [#657] Change how blocks are downloaded and processed
Closes #657

- Now SDK downloads N downloads and scan those. And repeat until sync is
  done. This safes lot of space of disk used to store downloaded blocks.
- Most changes are done in `CompactBlockProcessor.processNewBlocks`.
- `SyncRanges` structure is changed a bit.
- `SyncStatus` is changed. SDK now report that it's syncing with
  progress. It doesn't report each phase of the sync process separately.
  Also appropriate notifications were updated.

Address review comments

- Small changes
- Add tests to check computation of processing ranges for single loop
2022-12-19 09:35:09 +01:00
Michal Fousek e01c83690f [#646] SDK sync process resumes correctly
- Previously we had one range for each sync which was used for each
  phase of sync process. Newly there is separate range for each phase of
  the sync process.
- I added `InternalSyncProgress` utility. This utility tracks progress
  of some phases. And it is able to compute right ranges which should be
  used for syncing.
- Some unused download code from `CompactBlockProcessor` is removed.

Fix tests

Address review comments

- Rebase to master
- Update how range for `processBatchFinished()` is computed.
- Refactor `InternalSyncProgress`
- Add tests for `InternalSyncProgress`

Address review comments

Change how latest downloaded block is tracked

- Cache DB is no longer used to track which block was downloaded as
  latest. `InternalSyncProgress` is used to do that.
- Thanks to that #660 is fixed. And cache DB can be completely removed
  after sync process.
- Added sleep(1) to some darkside tests when latest block height is set.
  Otherwise lightwalletd in darkside mode doesn't have time to setup and
  tests are flaky.

Fix TransactionEnhancementTests.testBasicEnhancement test
2022-12-12 14:27:30 +01:00