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

[R4R] Add Safety Measures to Coin/Coins #2797

Merged
merged 50 commits into from
Nov 20, 2018
Merged

[R4R] Add Safety Measures to Coin/Coins #2797

merged 50 commits into from
Nov 20, 2018

Conversation

alexanderbez
Copy link
Contributor

@alexanderbez alexanderbez commented Nov 13, 2018

So initial attempts to move to unsigned integers caused headaches in implementation (e.g. (A) - (B) should panic) under given time constraints 😞 . So I see this PR as a big step in improving safety, but an ultimate refactor should still take place (#1273) to utilize unsigned integers.

That being said, this PR does the following:

  • Keep the int type, but adds safety checks and measures (panics) whenever amounts are negative.
    • Minus panics on any negative coin, SafeMinus returns a bool if a negative coin exists.
  • Update IsValid to check if not positive.
  • Sort coins during Equal to obey the associativity axiom.
  • Fix pre-existing plus method to obey arithmetic laws.
    • e.g. We were returning remaining coins even when they included zero coins.
  • Cleanup, reorg and add unit tests
  • DRY-up overflow checks/code in the Uint type.

TL;DR Review int.go, coin.go, and ante.go 🍍

closes: #2776


  • Targeted PR against correct branch (see CONTRIBUTING.md)

  • Linked to github-issue with discussion and accepted design OR link to spec that describes this work.

  • Wrote tests

  • Updated relevant documentation (docs/)

  • Added entries in PENDING.md with issue #

  • rereviewed Files changed in the github PR explorer


For Admin Use:

  • Added appropriate labels to PR (ex. wip, ready-for-review, docs)
  • Reviewers Assigned
  • Squashed all commits, uses message "Merge pull request #XYZ: [title]" (coding standards)

@gamarin2 gamarin2 mentioned this pull request Nov 14, 2018
@alexanderbez alexanderbez changed the title [WIP] Unsigned Integers for Coins [WIP] Arithmetic Refactor for Coins Nov 15, 2018
types/coin.go Outdated Show resolved Hide resolved
types/coin.go Show resolved Hide resolved
@alexanderbez alexanderbez changed the title [WIP] Arithmetic Refactor for Coins [WIP] Add Safety Measures to Coin/Coins Nov 16, 2018
@codecov
Copy link

codecov bot commented Nov 16, 2018

Codecov Report

❗ No coverage uploaded for pull request base (develop@47eed39). Click here to learn what that means.
The diff coverage is 44.44%.

@@            Coverage Diff             @@
##             develop    #2797   +/-   ##
==========================================
  Coverage           ?   56.94%           
==========================================
  Files              ?      120           
  Lines              ?     8281           
  Branches           ?        0           
==========================================
  Hits               ?     4716           
  Misses             ?     3247           
  Partials           ?      318

@alexanderbez alexanderbez changed the title [WIP] Add Safety Measures to Coin/Coins [R4R] Add Safety Measures to Coin/Coins Nov 16, 2018
Copy link
Collaborator

@fedekunze fedekunze left a comment

Choose a reason for hiding this comment

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

thanks @alexanderbez, some comments:

types/coin.go Outdated Show resolved Hide resolved
types/coin.go Outdated Show resolved Hide resolved
types/coin.go Outdated Show resolved Hide resolved
types/coin.go Show resolved Hide resolved
cmd/gaia/app/genesis.go Outdated Show resolved Hide resolved
types/coin_test.go Show resolved Hide resolved
types/coin_test.go Show resolved Hide resolved
types/int.go Show resolved Hide resolved
return nil, sdk.ErrInsufficientFee(fmt.Sprintf("invalid fee amount: %s", feeAmount)).Result()
}

newCoins, ok := coins.SafeMinus(feeAmount)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why are we not using plain Minus ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because Minus will panic on any negative amount! So here want to gracefully return the error. As mentioned in a similar conversation above, I think we can do IsAllLTE here instead and then once sure, we can safely do subtraction.

oldCoins := getCoins(ctx, am, addr)
newCoins := oldCoins.Minus(amt)
if !newCoins.IsNotNegative() {
newCoins, hasNeg := oldCoins.SafeMinus(amt)
Copy link
Collaborator

Choose a reason for hiding this comment

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

ditto

Copy link
Contributor

@cwgoes cwgoes left a comment

Choose a reason for hiding this comment

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

A very few minor comments, otherwise LGTM.

cmd/gaia/app/genesis.go Outdated Show resolved Hide resolved
types/coin.go Show resolved Hide resolved
types/coin.go Show resolved Hide resolved
types/coin.go Outdated
diff := coins.Minus(coinsB)
if len(diff) == 0 {
diff, hasNeg := coins.SafeMinus(coinsB)
if len(diff) == 0 || hasNeg {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is weird semantically. False isn't safe to return, esp when people might use !A.IsAllGT(B) as a synonym for A.IsAllLTE(B), etc.

types/coin.go Outdated
func (coins Coins) IsAllGTE(coinsB Coins) bool {
diff := coins.Minus(coinsB)
diff, hasNeg := coins.SafeMinus(coinsB)
if hasNeg {
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T: API Breaking Breaking changes that impact APIs and the SDK only (not state machine).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Attacker can submit TX with negative Fee minting tokens
5 participants