Page MenuHomePhabricator

[Cashtab] [Alias-server] - pt 1 - Alias server api integration
ClosedPublic

Authored by emack on Mar 17 2023, 02:39.

Details

Summary

T3003

Pretty big refactor but they couldn't be split out into smaller diffs as they're all interconnected.

Refactored logic:

  1. Upon Cashtab loading, if the alias setting is enabled in Ticker.js, then handleUpdateWallet in useWallet.js will execute synchronizeAliasCache.
  2. synchronizeAliasCache calls getAliasServerHistory to hit the alias-server to retrieve the latest valid aliases and if the alias count does not match between aliasCache.aliases and the alias-server, then localforage is updated via updateAliases
  3. When updateAliases is commiting the alias-server response to the cashtabCache.aliasCache object, it now looks like:

aliasCache: {

aliases: [],
cachedAliasCount: 0,

},

The integration with alias-server made all processes relating to parsing paymentTxHistory, extracting valid aliases, parsing onchain count...etc redundant, hence a much simplified aliasCache object going forward.

  1. When the user is registering a new alias, isAliasAvailable and isAliasRegistered are called to check whether it has been taken.
  2. If alias is available, the remaining registration logic remains unchanged, other than now calling registerAliasNotification for successful notification that explains the need for 1 conf for alias to be active.
  3. Upon registration, processChronikWsMsg in useWallet.js (from the abandoned D13301) will wait for a new block to be found and then refresh the aliasCache so the newly registered alias will show up in registered aliases list in Alias.js and resolve to the appropriate address in send and sendToken screens.
  4. Also fixed an existing bug in Alias.js where synchronizeAliasCache was returning an outdated aliasCache IF it determined a cache refresh was required i.e. it was originally returning the aliasCache that was retrieved at the start of the function before the refresh action. Now Alias.js' useEffect calls await synchronizeAliasCache() first then directly retrieves latest from getAliasesFromLocalForage()` afterwards
  5. Various unit tests and mocks updated to reflect the above refactors and the new aliasCache object

Refactor Change log

updated

  • updateAliases: now takes in the alias server response and commits it to localforage
  • synchronizeAliasCache: compares onchain vs cached alias count and updates the latest alias-server response into local storage when required
  • isAliasAvailable: retrieves alias list from storage rather than hitting chronik
  • send.js now passes cached aliases into isAliasAvailable rather than chronik instance, as well as updated error message "eCash Alias does not exist or yet to receive 1 confirmation"
  • sendToken.js: updated error message "eCash Alias does not exist or yet to receive 1 confirmation"
  • isValidCashtabCache: updated to reflect the new aliasCache structure
  • getAliasesFromLocalForage: returning the updated aliasCache object but kept the alphanumeric validation in there to migrate pre-alias-server wallet caches
  • processChronikWsMsg: monitors for a new block and then triggers an alias cache update

Removed

  • getAllTxHistory: no need to hit chronik anymore
  • getAliasAndAddresses: redundant now the alias-server does the heavy lifting to parse payment tx history
  • calculateAliasTxCount: redundant now that we're using alias count
  • sortAliasTxsByTxidAndBlockheight: redundant now the alias-server is doing this
  • filterDuplicateAliasTxs: redundant now the alias-server is doing this

Unchanged

  • isAliasRegistered: local caching logic only
  • isAddressRegistered: local caching logic only
  • isAlphanumeric: kept for getAliasesFromLocalForage
  • getAddressFromAlias: local caching logic only
  • isAddressRegistered: local caching logic only
  • getAliasRegistrationFee: local parsing only
  • registerNewAlias: still broadcasting via chronik

New

  • getAliasServerHistory: fetches the alias server response
  • registerAliasNotification: as advertised
Test Plan
  • npm test
  • enable alias in ticker.js
  • npm start
  • retest alias input validation for valid alphanumeric inputs, invalid inputs (uppercase, spaces, symbols, special chars, emojis)
  • register a new alias and ensure it is initially not displayed on the registered alias list nor resolves to any addresses in send/sendToken
  • wait for a new block to be found and observe the New block found, updating aliasCache message in console log
  • ensure the new alias is now reflected in Alias.js' registered aliases list and now resolves to the correct address in send/sendToken screens
  • register another new alias, close cashtab, wait for 1 conf, then re-open cashtab and ensure via console log the onchain vs cached alias count does not match and it still triggers an aliasCache update
  • disable alias in ticker.js and ensure nothing blows up, wait for 1 block to be found and ensure no errors in console log

Diff Detail

Repository
rABC Bitcoin ABC
Branch
aliasServerIntegration
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 22648
Build 44916: Build Diffcashtab-tests
Build 44915: arc lint + arc unit

Event Timeline

emack requested review of this revision.Mar 17 2023, 02:39
emack edited the summary of this revision. (Show Details)

Okay, this is working well. Due to incremental developments and the refactor, things have gotten a bit messy.

We need a central function that lives inside useWallet.js and does nothing but update the cashtabCache object to have the latest aliases.

Since cashtabCache is already available through wallet context, this function should

  1. Update cashtabCache in localforage after synchronizing with the latest aliases
  2. setState on cashtabCache after synchronizing with the latest aliases

Then we just pull in cashtabCache from wallet context on any screen that needs it (e.g. Alias.js), and this state variable is always the latest cache (because it is being updated and set onBlock in useWallet.js

Action

  1. Rename synchronizeAliasCache to getLatestAliases
  2. This function should pull in cashtabCache from localforage, validate aliases, and update aliases to the most current information
  3. The function must setState on cashtabCache after updating it with the latest aliases
  4. The function must save cashtabCache to localforage after updating it with the latest aliases
  5. When a new block is found, we just call getLatestAliases. All the logic should be in that function.
  6. Refactor Alias.js to pull in cashtabCache from wallet context, and use cashtabCache.aliases for all its "i need to know the latest state of aliases" needs
web/cashtab/src/components/Alias/Alias.js
96 ↗(On Diff #38653)

await synchronizeAliasCache() already calls await getAliasesFromLocalForage()

No need to do it twice here.

See main review comment with list of Actions.

148 ↗(On Diff #38653)

the cachedAliases object should be available from context. We shouldn't be getting it from local storage on page load and then again at other times on this page.

See Actions in main review comment

web/cashtab/src/hooks/useWallet.js
281 ↗(On Diff #38653)

This function should do nothing but get aliases from local forage.

Your function to get the latest valid alias info (see Actions in review comment) should do the validation checks on this.

320 ↗(On Diff #38653)

Not clear why we have this function and also synchronizeAliasCache

I think we only need one function. See actions in main review comment.

936 ↗(On Diff #38653)

We don't want to be resetting the cache every single block. We just want to add new aliases, if any

So, we should just be calling synchronizeAliasCache on block. See Actions in main review comment.

This revision now requires changes to proceed.Mar 20 2023, 17:42
emack marked 5 inline comments as done.
  • renamed synchronizeAliasCache to getLatestAliases, which now validates the aliases in storage and performs the updating of the latest aliases to storage/state
  • removed redundant updateAliases function
  • getAliasesFromLocalForage updated to do nothing but retrieve cashtabCache from storage
  • new blocks found in processChronikWsMsg will now call getLatestAliases and let it do all the work in updating aliases
  • Alias.js refactored to pull in cashtabCache.aliasCache instead of making further calls to localstorage

Note: I noticed there's some sort of lag or server side caching going on with the alias-server api. i.e. let's say the onchain alias count is 345. If you register a new alias, then when a new block is found cashtab calls the alias server via getLatestAliases()->getAliasServerHistory() but it will still give 345 and the JSON response will not contain the new alias, regardless of how long it took for the next block to be found. It's not until the subsequent call (another block or app refresh) that it will increment to 346.

This results in onchain and cached alias counts incorrectly matching and not executing a refresh, leaving the cached aliases out of date even though the new alias has received 1 conf. in the newly found block. Refreshing the app will result in the correct response being retrieved from the alias server and triggering an alias cache update.

Note: I noticed there's some sort of lag or server side caching going on with the alias-server api. i.e. let's say the onchain alias count is 345. If you register a new alias, then when a new block is found cashtab calls the alias server via getLatestAliases()->getAliasServerHistory() but it will still give 345 and the JSON response will not contain the new alias, regardless of how long it took for the next block to be found. It's not until the subsequent call (another block or app refresh) that it will increment to 346.

Is this using aliasdev.etokens.cash endpoint as well? This is significantly further along now than alias.etokens.cash. Should do testing using this endpoint.

In particular, should use the https://aliasdev.etokens.cash/aliasesRegisteredAfterBlockheight/784500 endpoint -- this should be much faster.

switched to the aliasdev.etokens.cash end point and outdated json response issue is now resolved. Issue was specific to the deprecated alias.etokens.cash endpoint

bytesofman added inline comments.
web/cashtab/src/components/Alias/Alias.js
147 ↗(On Diff #38816)

higher up in the page, cachedAliases is defined as cashtabCache.aliasCache; here we assign that value to aliasesFromLocalForage

should have only one definition in this file.

This revision now requires changes to proceed.Mar 24 2023, 12:31
web/cashtab/src/components/Alias/Alias.js
67

Do we need getLatestAliases here?

cashtabCache will be updating in the background on block. Should be updating alias cache var used on this screen in a useEffect loop every time cashtabCache changes.

177

Instead of await getLatestAliases(), this would be a good time to check the /pending endpoint. Doesn't need to be in this diff though. Should have a diff that does nothing but handle pending case with the pending endpoint.

web/cashtab/src/components/Common/Ticker.js
28

Need your support on getting the outstanding alias-server diffs reviewed.

web/cashtab/src/hooks/useWallet.js
1164

isAlphanumeric should be renamed isValidAliasString ; we may change the logic in the future. It's a coincidence that isAlphanumeric means the same thing as isValidAliasString at the moment.

1194

This approach (getting all the aliases, seeing if you have the same amount, if not refresh the whole list) is okay for this diff but we will have to refine later. We don't want every cashtab user querying the entire set of registered aliases on every block.

I'll do some thinking and improve the endpoints.

What we want to happen onBlock is

  • get cached aliases in cashtab
  • compare with server and determine if any aliases are missing
  • get only the missing aliases and add to cashtab cache

one way to do this now with available endpoints is to take the blockheight attribute off the most recent alias in your cache and then call https://aliasdev.etokens.cash/aliasesRegisteredAfterBlockheight/<yourHighestCachedBlockheight -- this will give you a list of all the aliases you are missing

Anyway, don't refactor this diff. But keep in mind for the next diff.

emack marked 6 inline comments as done.
  • updated all aliasCache references to use the cashtabCache object from wallet context in Alias.js
  • removed getLatestAliases in Alias.js, with useEffect loop set to update upon cashtabCache changes
  • isAlphanumeric renamed to isValidAliasString throughout the app
  • subsequent diff will implement the /pending endpoint and refactor the onBlock logic
bytesofman added inline comments.
web/cashtab/src/components/Common/Notifications.js
46 ↗(On Diff #38868)

pass the registered alias string to this function for use in the notification

53 ↗(On Diff #38868)

too much text.

Alias "${yourAliasString}" registration pending 1 confirmation.
60 ↗(On Diff #38868)

If we're doing a special notification for this, it should have its own icon

web/cashtab/src/components/Send/Send.js
141 ↗(On Diff #38868)

pull in cashtabCache and monitor it in a useEffect loop, same as Alias.js

getAliasesFromLocalForage should only be used in useWallet.js

web/cashtab/src/components/Send/SendToken.js
109 ↗(On Diff #38868)

pull in cashtabCache and monitor it in a useEffect loop, same as Alias.js

getAliasesFromLocalForage should only be used in useWallet.js

web/cashtab/src/utils/transactions.js
34 ↗(On Diff #38868)

not a great fit in transactions.js

just create a new aliasUtils.js and put this function in it. we'll probably get more

This revision now requires changes to proceed.Mar 25 2023, 04:33
emack marked 6 inline comments as done.
  • Updated alias registration notification including its own icon
  • Updated Send.js and SendToken.js to pull in cashtabCache and monitor it in useEffect loop
  • Moved getAliasServerHistory into a newly created aliasUtils.js. Since this is just an api wrapper no unit tests added for it.
emack retitled this revision from [Cashtab] [Alias] - Alias server api integration to [Cashtab] [Alias] - pt 1 - Alias server api integration.Mar 25 2023, 07:32
This revision is now accepted and ready to land.Mar 25 2023, 13:41
emack retitled this revision from [Cashtab] [Alias] - pt 1 - Alias server api integration to [Cashtab] [Alias-server] - pt 1 - Alias server api integration.Mar 26 2023, 07:20