Page MenuHomePhabricator

[Cashtab] Patch firma redemptions calc issue
ClosedPublic

Authored by bytesofman on Wed, Apr 23, 04:29.

Details

Reviewers
Fabien
Group Reviewers
Restricted Project
Commits
rABCa472781e2e98: [Cashtab] Patch firma redemptions calc issue
Summary

There is not a great way to generate an agora partial as close as possible to (but below) a given price. So, in Cashtab, we iteratively generate offers until we get "just below" the this threshhold.

In initial testing, usually it took 2 or 3 attempts. But getting lots of reports about hitting max attempts, and I am able to repeat. It depends on the bid price and the quantity.

Bump the max attempts to 25. I have not seen more than 10. But as long as we are preventing an infinite loop, it is better to try 25 times than to have an inexplicable error at 5 times.

We also need to clear the error so the button is not disabled, requiring a refresh when this happens.

Test Plan

npm test

We have an existing test that confirms we iteratively generate partial offers. It would be possible to test a case where we iterate 10 times or do not reach a max, but I think the impact is not worth the effort to create and maintain such a test. It would be better to add a method to ecash-agora that supports creating an offer at or below a target price and test there.

error:

image.png (206×706 px, 45 KB)

  • Try to redeem firma, say $5, then try 10, 15, 20, etc, wait to see this error, notice the button spinner is there until page refresh
  • Try the same quantity on the test site with this patch, no error (https://cashtab-local-dev.netlify.app/)

Diff Detail

Repository
rABC Bitcoin ABC
Branch
patch-firma-redeems
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 33066
Build 65616: Build Diffcashtab-tests
Build 65615: arc lint + arc unit

Event Timeline

bytesofman added inline comments.
cashtab/src/components/Etokens/Token/index.tsx
1835 ↗(On Diff #53616)

this error msg makes it look like a price API issue, but that is not what is happening here

1837 ↗(On Diff #53616)

when we hit an error, unlock the UI bc we are no longer calculating this partial. this prevents the user from having to reload when this error is hit.

Fabien added inline comments.
cashtab/src/components/Etokens/Token/index.tsx
1819 ↗(On Diff #53616)

Then move the error below the loop. The current code flow is very unusual

1828 ↗(On Diff #53616)

So this is the value that changes. Is it expected to change in the time the loop iterates with no delay at all ?

1831 ↗(On Diff #53616)
cashtab/src/components/Etokens/Token/index.tsx
1828 ↗(On Diff #53616)

Ah because it's a user entry right ?

1837 ↗(On Diff #53616)

So this is the actual fix, right ? The retry attempts increment is just a UX improvement ?

Overall, the approach here is not ideal. It's not straightforward to handle this elegantly in ecash-agora (or mb it is and I just haven't sat down to work out the math) -- but even if we do handle it in ecash-agora, the performance delta is probably not user noticeable.

What would be user noticeable is better price resolution in agora with 64-bit ints.

cashtab/src/components/Etokens/Token/index.tsx
1828 ↗(On Diff #53616)

Part of a broader software problem in agora management.

Due to number encoding restrictions, agora prices can only be set at certain discrete intervals.

The agora.selectParams function takes user input and shims it into these intervals. Whether or not the actual price of the offer matches the user's desired price is a function of the quantity being sold and the desired sale price.

For now, there is no lib-ready method to "create a partial with a price NO HIGHER THAN x". For a given quantity, a range of user input prices will result in the same output price -- since the available prices are at discrete intervals. So one effective way (used here) is to keep trying with incrementally lower price, until we hit the "next tick lower".

64-bit ints would help here, probably make the problem unnoticeable. In practice, the price deltas from user input -- at high enough quantities -- are small. But, understandably, users really do not like prices to be different from what they input, and the complex technical explanation is unpopular.

1828 ↗(On Diff #53616)

No, there is a delay, but in practice 1 attempt and 10 attempts both seem to take a few seconds. selectParams is async because it must ping agora to confirm this offer does not interfere with existing offers; it does this by using a unique locktime.

1837 ↗(On Diff #53616)

The number of attempts required to get an offer at "price that is as high as possible but below the prevailing auto-redeem price" is --- given the current design of ecash-agora -- a function of the prevailing redeem price and the quantity being redeemed.

Before bumping retry attempts, users were running into the "Unable to determine FIRMA redemption price" error -- and not really knowing why that error shows up. Apart from the spinner continuing to go, the error makes it look like the service is simply unavailable. So, bumping the retry attempts is the actual fix, in that in practice it prevents the error by allowing more attempts -- which have proved to be necessary for some price/quantity combinations.

From a high level software standpoint, the fix is to improve the ecash-agora lib to get a better way of creating a partial with the price at the "next tick lower." Even without library changes, there is (probably) a way to do this by using the given number resolution constraints to condition the target price we use as a param in generating the partial offer.

The root problem: the lib improvement will be complex and needs some thought (and is possibly not high impact beyond this niche case), while the approach used here rightnow is effective and ready.

bytesofman marked an inline comment as done.

better while loop logic, more clarity in error msg, use variable instead of hardcode 5 in comment

cashtab/src/components/Etokens/Token/index.tsx
1830

sample output

image.png (141×304 px, 8 KB)

So, another potential improvement here would be to increase NANOSATS_PER_ATOM_REDUCTION_PER_ITERATION

For now though, I think accepting more iterations for the guarantee of not missing the next-lowest available price is an acceptable trade-off.

Could also be more exact if I instead iterate by changing the quantity of atoms listed instead of the price 🤔 -- but this would be an optimization.

In its current form, this diff fixes an issue in prod where users are unable to redeem FIRMA and do not know exactly why. So whatever direction this goes, this diff is an important first step.

Fabien requested changes to this revision.Wed, Apr 23, 13:50
Fabien added inline comments.
cashtab/src/components/Etokens/Token/index.tsx
1808

you don't need this anymore

1830

Don't keep this in prod

1834

wow

This revision now requires changes to proceed.Wed, Apr 23, 13:50
bytesofman marked 2 inline comments as done.

clean up loop logic, remove debug log, comments

This revision is now accepted and ready to land.Wed, Apr 23, 18:53