Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add static amountMath. Backwards compatible with old amountMath #2561

Merged
merged 9 commits into from
Mar 8, 2021

Conversation

katelynsills
Copy link
Contributor

@katelynsills katelynsills commented Mar 3, 2021

This PR adds a static version of amountMath that can be imported directly from @agoric/ertp:

  import { amountMath } from '@agoric/ertp';
  const payment = mint.mintPayment(amountMath.make(837n, brand));

AmountMath was serving two purposes simultaneously, which can be teased out separately:

  1. An "absolute" check on the brand in the amounts, against the brand directly from the issuer.
  2. A "relative" check to ensure that we are manipulating amounts of the same brand, regardless of whether the brands in the amounts match the brand directly from the issuer.

This refactoring tries to separate these two purposes. For instance, in add, if an absolute check is necessary, you must pass the brand that you got from the issuer (or from Zoe) as an optional third parameter:

amountMath.add(amount1, amount2, brandFromIssuer)

If only a relative check is required, you can leave out the optional brand, and add will error if the two amounts have different brands:

amountMath.add(amount1, amount2);

ERTP still retains the old amountMath for backwards compatibility, but it has been deprecated. Currently, only the ERTP tests have been converted to use the new amountMath.

TODO: Remove the deprecated amountMath for testing, and convert the rest of agoric-sdk and dapps to the new amountMath.

Starts on #2311

#documentation-branch: redo-amount-math

@katelynsills
Copy link
Contributor Author

Still have some linting issues - converting to draft

Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's tough to tell whether this change will be an improvement in usability and readability. I still think it's likely, but there isn't enough usage in code in vats to tell.

packages/ERTP/src/issuer.js Outdated Show resolved Hide resolved
packages/ERTP/src/mathHelpers/setMathHelpers.js Outdated Show resolved Hide resolved
packages/ERTP/src/amountMath.js Outdated Show resolved Hide resolved
@katelynsills katelynsills force-pushed the 2311-redo-amount-math-backwards-compat branch from 2dd9fb7 to 24bbd9a Compare March 4, 2021 01:25
Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM!

One question, and another suggestion for clarifying an error message.

packages/ERTP/src/amountMath.js Outdated Show resolved Hide resolved
@@ -18,23 +19,26 @@ const BASIS_POINTS = 10000n; // TODO change to 10_000n once tooling copes.
* request, and to do the actual reallocation after an offer has
* been made.
*
* @param {bigint} inputValue - the value of the asset sent
* @param {Value} inputValue - the value of the asset sent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does Typescript want this change? Is it because we can't tell it that the Amounts we started with are from NatMath types?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, Values in Amounts are either NatValues (bigints) or SetValues (arrays), so when we as programmers know that we are using a bigint, the type system doesn't know. We have two choices: do an assert.typeof(value, bigint) before we call the method that requires bigints, or we can loosen the type of the method to be a Value. That's what I chose for this method, otherwise I would have to do 3 or so asserts. We may be able to improve the types, but this is the best I know how to do. The plus side is that instead of Values being any and allowing anything in amounts, we will catch many more problems in linting.

@katelynsills katelynsills marked this pull request as ready for review March 5, 2021 02:38
@katelynsills
Copy link
Contributor Author

This is now ready for review. @erights could you take a look? Thanks!

Copy link
Member

@erights erights left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My confusion about makeExternalStore didn't stop me from doing a differential review. But makeExternalStore does not look like anything I expected.

LGTM!

assert(passStyleOf(list) === 'copyArray', 'list must be an array');
checkForDupes(makeBuckets(list));
return list;
},
doGetEmpty: _ => identity,
doMakeEmpty: _ => identity,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remind me of the rationale for this name change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't remember it exactly, but it was the general consensus of an ERTP meeting. I think @dtribble had an opinion on it. I have no preference between them.

* This version of amountMath is deprecated. Please use `amountMath` directly
* as exported by `@agoric/ertp`.
*
* @property {() => Brand} getBrand Deprecated
Copy link
Member

@erights erights Mar 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do any tools understand this way of saying deprecated? If not but there's no better way, then fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, unfortunately, there's no better way to do this. The @deprecated tag works for standalone functions only, and not on methods. So this is for humans reading the types. That said, makeAmountMath and makeLocalAmountMath are functions and they do have the @deprecated tag so the tools should probably understand that the usual pattern of usage is deprecated.

@@ -1,4 +1,9 @@
// @ts-check

// eslint-disable-next-line import/no-extraneous-dependencies
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we ever figured out why we need these?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, sorry, it's very mysterious to me why I get errors for this in VSCode. The settings in packages/eslint-config should silence this, and they do for the linting at the command line, but not for the "red squigglies". All of the my VSCode settings appear to be correct, and I use the ESLint extension, so I'm at a loss.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess a good question is, does anyone else see these as red squigglies? If it's just me, I should probably take out the eslint-disable-next-line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see them often.

Comment on lines +34 to +35
makeAliceMaker() {
return makeAliceMaker(vatPowers.testLog);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the removal of host related to the rest of this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unrelated.

Comment on lines 128 to 129
mustBeComparable(brand);
assert.typeof(amountMathKind, 'string');

const mathHelpers = {
nat: natMathHelpers,
strSet: strSetMathHelpers,
set: setMathHelpers,
};
const helpers = mathHelpers[amountMathKind];
assert(typeof brand === 'object', msg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps replace both of these with

assert(passStyleOf(brand) === REMOTE_STYLE), msg);

In any case, when you do want to assert a typeof, assert supports that directly

assert.typeof(brand, 'object', msg);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By "both of these" I mean both the mustBeComparable and the typeof check. Then you can also drop the passStyleOf check below.

assert(
helpers !== undefined,
X`unrecognized amountMathKind: ${amountMathKind}`,
passStyleOf(brand) === REMOTE_STYLE && ownKeys.every(inBrandMethods),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I would not have thought to check that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

passStyleOf(brand) === REMOTE_STYLE &&

Having fixed the code on line 128, this part of the check on line 132 is redundant and should be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

op, good eye. I will remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #2597

return amountMath.make(allegedAmount.value, brand);
},
getValue: (amount, brand) => amountMath.coerce(amount, brand).value,
makeEmpty: (mathKind, brand) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, we actually do make a new one each time, which makes sense.

packages/ERTP/src/issuer.js Show resolved Hide resolved
packages/ERTP/src/issuer.js Show resolved Hide resolved
@katelynsills katelynsills force-pushed the 2311-redo-amount-math-backwards-compat branch from 8619635 to 58af196 Compare March 8, 2021 19:59
@katelynsills katelynsills enabled auto-merge (squash) March 8, 2021 20:00
@katelynsills katelynsills merged commit 1620307 into master Mar 8, 2021
@katelynsills katelynsills deleted the 2311-redo-amount-math-backwards-compat branch March 8, 2021 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ERTP package: ERTP
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants