[Cashtab] Improve wallet state management to properly deal with websocket-triggered state changes
Summary:
T3826
Cashtab does not have fine-grained tx update ability. When we need to update one tx, we need to update the whole state of the app.
This issue should be fixed (i.e. we should have more specific db queries), but that will require sqlite across platforms and a migration to sqlite on web and extension.
Cashtab's key-value storage needs async updating. We update the whole state when we update a utxo or a tx in history. When Cashtab was originally designed, this was acceptable, because we did not even have websockets (let alone strongly typed utxos and other libs). But now websockets can and should drive the state of the app. With the android app launching soon, we should also begin optimizing storage and app speed using a database to enhance caching and updates.
In this diff we do what we can to optimize state updates without changing the key-value storage.
- We introduce useRef instead of passing state vars as params. Have avoided this for a long time because useRef is a complication, and the alternative of passing params was acceptable when we only had to worry about the price updating every 90s. But now that cashtabState can change on every tx, it does not make sense at all to re-initialize websockets every time there is a state change. This has been true for some time but we were getting away with it by accepting poor performance in tx updating. We need to useRef so functions have access to the current state, and not the state that existed when the function was first initialized (this is a quirk of React that was previously handled by passing params and re-initializing functions with useEffect).
- Queue async methods that are triggered by ws msgs (we can have race conditions with multiple onMessage calls trying to update the same state with different inputs)
- Batch finalized updates. This is esp important now as tx finalization only occurs with postconsensus, so the user often has many txs finalize at the same time. Async queueing alone may not fully resolve some finalizing txs being missed as we cannot await react state changes.
Test Plan:
npm test, try it out at cashtab.io, send and receive txs and watch them finalize correctly
this diff is deployed at cashtab.io with debug logging for receiving finalized txs
Reviewers: #bitcoin_abc, Fabien
Reviewed By: #bitcoin_abc, Fabien
Subscribers: Fabien
Differential Revision: https://reviews.bitcoinabc.org/D18507