-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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: Added IsValid to Coin #4558
Conversation
Codecov Report
@@ Coverage Diff @@
## master #4558 +/- ##
=========================================
+ Coverage 53.04% 53.5% +0.45%
=========================================
Files 258 257 -1
Lines 16288 16177 -111
=========================================
+ Hits 8640 8655 +15
+ Misses 7002 6876 -126
Partials 646 646 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s add a blank string test with more than 3 spaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet ! Thanks Colin !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IsValid()
was removed for two reasons:
- developers must use
NewCoin()
to initialise coins - we wanted validation to live in one place only
I believe this PR requires further discussion before merging.
types/coin.go
Outdated
@@ -51,6 +51,15 @@ func (coin Coin) String() string { | |||
return fmt.Sprintf("%v%v", coin.Amount, coin.Denom) | |||
} | |||
|
|||
// IsValid asserts that the Coin has a positive amount and the Denom does not contain | |||
// upper case characters and has a length of 3 ~ 16 characters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would simply update this godoc to state:
// IsValid asserts that the Coin has a positive amount and the Denom is valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK
We can by not providing |
Plus, validation should really live in one place only. It does not feel right to duplicate validation logic in multiple places... |
func NewCoin(denom string, amount Int) Coin {
if err := validate(denom, amount); err != nil {
panic(err)
}
}
func validate(denom string, amount Int) error {
if err := validateDenom(c.Denom); err != nil {
return err
}
if amount.LT(ZeroInt()) {
return fmt.Errorf("negative coin amount: %v", amount)
}
return nil
}
func (c Coin) IsValid() bool {
if err := validate(denom, amount); err != nil {
return true
}
return false
} |
@colin-axner just had a quick chat with @alessio. What he's saying is that for @alexanderbez and I agree on having the 0 amount coin to be invalid in both funcs. |
Agreed. We should not allow 0 coins as input anywhere. We should have a single public validation function that we use. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also change the coins.IsValid()
func to just iterate over the coins and call the coin.IsValid
func() ?
EDIT: completely forgot about the sort, please ignore the comment
Should |
I have been going through trying to update tests and code to reflect 0 amount coin as invalid, but the usage of 0 coins seems to be deeply ingrained in the code/tests. For example: in minter it appears it should be valid to have block provisions of zero. Abiding by the updated constructor for A lot of the simulations/tests also use empty/zero coins to test various functionality, originally I was changing these to use Also This is starting to be a time sink and causing me a lot of trouble. What direction should I take this? I still think it is very important to introduce some sort of public validation function coin(s)/denoms can use, though I starting to wonder if removal of zero coins should be done in a separate pr. Thoughts? @fedekunze @alexanderbez @alessio |
I did remember that in few places we do take 0 as valid Coin amount. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK, I think the changes are fine for now @colin-axner.
types/coin.go
Outdated
return err | ||
} | ||
|
||
if amount.LTE(ZeroInt()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@colin-axner lets go with LT
for now so we can get the build passing and as this was the original behavior.
types/coin.go
Outdated
@@ -51,6 +49,28 @@ func (coin Coin) String() string { | |||
return fmt.Sprintf("%v%v", coin.Amount, coin.Denom) | |||
} | |||
|
|||
// Validate returns an error if the Coin has a nonpositive amount or if | |||
// the Denom is invalid. | |||
func Validate(denom string, amount Int) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not export this one please
types/coin.go
Outdated
@@ -51,6 +49,28 @@ func (coin Coin) String() string { | |||
return fmt.Sprintf("%v%v", coin.Amount, coin.Denom) | |||
} | |||
|
|||
// Validate returns an error if the Coin has a nonpositive amount or if | |||
// the Denom is invalid. | |||
func Validate(denom string, amount Int) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
func Validate(denom string, amount Int) error { | |
func validate(denom string, amount Int) error { |
types/coin.go
Outdated
|
||
if amount.LT(ZeroInt()) { | ||
panic(fmt.Errorf("negative coin amount: %v", amount)) | ||
if err := Validate(denom, amount); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if err := Validate(denom, amount); err != nil { | |
if err := validate(denom, amount); err != nil { |
types/coin.go
Outdated
|
||
// IsValid asserts that the Coin has a positive amount and the Denom is vaild. | ||
func (coin Coin) IsValid() bool { | ||
if err := Validate(coin.Denom, coin.Amount); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if err := Validate(coin.Denom, coin.Amount); err != nil { | |
if err := validate(coin.Denom, coin.Amount); err != nil { |
types/coin_test.go
Outdated
@@ -56,7 +77,7 @@ func TestAddCoin(t *testing.T) { | |||
shouldPanic bool | |||
}{ | |||
{NewInt64Coin(testDenom1, 1), NewInt64Coin(testDenom1, 1), NewInt64Coin(testDenom1, 2), false}, | |||
{NewInt64Coin(testDenom1, 1), NewInt64Coin(testDenom1, 0), NewInt64Coin(testDenom1, 1), false}, | |||
{NewInt64Coin(testDenom1, 1), Coin{testDenom1, NewInt(0)}, NewInt64Coin(testDenom1, 1), false}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd revert this
types/coin_test.go
Outdated
@@ -80,7 +101,7 @@ func TestSubCoin(t *testing.T) { | |||
{NewInt64Coin(testDenom1, 1), NewInt64Coin(testDenom2, 1), NewInt64Coin(testDenom1, 1), true}, | |||
{NewInt64Coin(testDenom1, 10), NewInt64Coin(testDenom1, 1), NewInt64Coin(testDenom1, 9), false}, | |||
{NewInt64Coin(testDenom1, 5), NewInt64Coin(testDenom1, 3), NewInt64Coin(testDenom1, 2), false}, | |||
{NewInt64Coin(testDenom1, 5), NewInt64Coin(testDenom1, 0), NewInt64Coin(testDenom1, 5), false}, | |||
{NewInt64Coin(testDenom1, 5), Coin{testDenom1, NewInt(0)}, NewInt64Coin(testDenom1, 5), false}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto - I'd revert this
types/coin_test.go
Outdated
@@ -133,7 +154,7 @@ func TestIsLTCoin(t *testing.T) { | |||
}{ | |||
{NewInt64Coin(testDenom1, 1), NewInt64Coin(testDenom1, 1), false, false}, | |||
{NewInt64Coin(testDenom1, 2), NewInt64Coin(testDenom1, 1), false, false}, | |||
{NewInt64Coin(testDenom1, 0), NewInt64Coin(testDenom2, 1), false, true}, | |||
{Coin{testDenom1, NewInt(0)}, NewInt64Coin(testDenom2, 1), false, true}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
types/coin_test.go
Outdated
@@ -150,7 +171,7 @@ func TestIsLTCoin(t *testing.T) { | |||
} | |||
|
|||
func TestCoinIsZero(t *testing.T) { | |||
coin := NewInt64Coin(testDenom1, 0) | |||
coin := Coin{testDenom1, NewInt(0)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto - and so on
types/coin.go
Outdated
return err | ||
} | ||
|
||
if amount.LTE(ZeroInt()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if amount.LTE(ZeroInt()) { | |
if amount.LT(ZeroInt()) { |
types/coin.go
Outdated
return nil | ||
} | ||
|
||
// IsValid asserts that the Coin has a positive amount and the Denom is vaild. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// IsValid asserts that the Coin has a positive amount and the Denom is vaild. | |
// IsValid returns true if the Coin has a non-negative amount and the denom is valid. |
Comments addressed or taken back (#4558 (review))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good one!
Codecov Report
@@ Coverage Diff @@
## master #4558 +/- ##
=========================================
+ Coverage 53.04% 53.5% +0.45%
=========================================
Files 258 257 -1
Lines 16288 16177 -111
=========================================
+ Hits 8640 8655 +15
+ Misses 7002 6876 -126
Partials 646 646 |
closes #4556
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 a relevant changelog entry:
clog add [section] [stanza] [message]
rereviewed
Files changed
in the github PR explorerFor Admin Use: