Skip to content

Commit

Permalink
Merge pull request #376 from iov-one/type_dependent_fees_issue_232
Browse files Browse the repository at this point in the history
Per message type fee
  • Loading branch information
husio authored Mar 7, 2019
2 parents 904296b + 36f162f commit c062966
Show file tree
Hide file tree
Showing 13 changed files with 991 additions and 37 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ protoc:
protoc --gogofaster_out=. -I=. -I=./vendor -I=$(GOPATH)/src cmd/bnsd/x/nft/username/*.proto
protoc --gogofaster_out=. -I=. -I=$(GOPATH)/src x/cash/*.proto
protoc --gogofaster_out=. -I=. -I=$(GOPATH)/src x/sigs/*.proto
protoc --gogofaster_out=. -I=. -I=$(GOPATH)/src x/msgfee/*.proto
protoc --gogofaster_out=. -I=. -I=./vendor -I=$(GOPATH)/src x/multisig/*.proto
protoc --gogofaster_out=. -I=. -I=./vendor -I=$(GOPATH)/src x/validators/*.proto
protoc --gogofaster_out=. -I=. -I=$(GOPATH)/src x/batch/*.proto
Expand Down
23 changes: 20 additions & 3 deletions coin/coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@ const (
)

// NewCoin creates a new coin object
func NewCoin(whole int64, fractional int64,
ticker string) Coin {

func NewCoin(whole int64, fractional int64, ticker string) Coin {
return Coin{
Whole: whole,
Fractional: fractional,
Ticker: ticker,
}
}

// NewCoinp returns a pointer to a new coin.
func NewCoinp(whole, fractional int64, ticker string) *Coin {
c := NewCoin(whole, fractional, ticker)
return &c
}

// ID returns a coin ticker name.
func (c Coin) ID() string {
return c.Ticker
Expand Down Expand Up @@ -128,10 +132,20 @@ func mul64(a, b int64) (int64, error) {
// currencies, or if the combination would cause
// an overflow
func (c Coin) Add(o Coin) (Coin, error) {
// If any of the coins represents no value and does not have a ticker
// set then it has no influence on the addition result.
if c.Ticker == "" && c.IsZero() {
return o, nil
}
if o.Ticker == "" && o.IsZero() {
return c, nil
}

if !c.SameType(o) {
err := ErrInvalidCurrency.Newf("adding %s to %s", c.Ticker, o.Ticker)
return Coin{}, err
}

c.Whole += o.Whole
c.Fractional += o.Fractional
return c.normalize()
Expand Down Expand Up @@ -225,6 +239,9 @@ func (c Coin) SameType(o Coin) bool {

// Clone provides an independent copy of a coin pointer
func (c *Coin) Clone() *Coin {
if c == nil {
return nil
}
return &Coin{
Ticker: c.Ticker,
Whole: c.Whole,
Expand Down
87 changes: 53 additions & 34 deletions coin/coin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,44 +155,63 @@ func TestValidCoin(t *testing.T) {

func TestAddCoin(t *testing.T) {
base := NewCoin(17, 2345566, "DEF")
cases := []struct {
a, b Coin
res Coin
bad bool
cases := map[string]struct {
a, b Coin
wantRes Coin
wantErr error
}{
// plus and minus equals 0
{base, base.Negative(), NewCoin(0, 0, "DEF"), false},
// wrong types
{
NewCoin(1, 2, "FOO"),
NewCoin(2, 3, "BAR"),
Coin{},
true,
},
// normal math
{
NewCoin(7, 5000, "ABC"),
NewCoin(-4, -12000, "ABC"),
NewCoin(2, 999993000, "ABC"),
false,
},
// overflow
{
NewCoin(500500500123456, 0, "SEE"),
NewCoin(500500500123456, 0, "SEE"),
Coin{},
true,
"plus and minus equals 0": {
a: base,
b: base.Negative(),
wantRes: NewCoin(0, 0, "DEF"),
},
"wrong types": {
a: NewCoin(1, 2, "FOO"),
b: NewCoin(2, 3, "BAR"),
wantRes: Coin{},
wantErr: ErrInvalidCurrency,
},
"normal math": {
a: NewCoin(7, 5000, "ABC"),
b: NewCoin(-4, -12000, "ABC"),
wantRes: NewCoin(2, 999993000, "ABC"),
},
"overflow": {
a: NewCoin(500500500123456, 0, "SEE"),
b: NewCoin(500500500123456, 0, "SEE"),
wantRes: NewCoin(0, 0, ""),
wantErr: ErrInvalidCoin,
},
"adding to zero coin": {
a: NewCoin(0, 0, ""),
b: NewCoin(1, 0, "DOGE"),
wantRes: NewCoin(1, 0, "DOGE"),
},
"adding a zero coin": {
a: NewCoin(1, 0, "DOGE"),
b: NewCoin(0, 0, ""),
wantRes: NewCoin(1, 0, "DOGE"),
},
"adding a non zero coin without a ticker": {
a: NewCoin(1, 0, "DOGE"),
b: NewCoin(1, 0, ""),
wantErr: ErrInvalidCurrency,
},
"adding to non zero coin without a ticker": {
a: NewCoin(1, 0, ""),
b: NewCoin(1, 0, "DOGE"),
wantErr: ErrInvalidCurrency,
},
}

for idx, tc := range cases {
t.Run(fmt.Sprintf("case-%d", idx), func(t *testing.T) {
c, err := tc.a.Add(tc.b)
if tc.bad {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.res, c)
for testName, tc := range cases {
t.Run(testName, func(t *testing.T) {
res, err := tc.a.Add(tc.b)
if !errors.Is(tc.wantErr, err) {
t.Fatalf("got error: %v", err)
}
if tc.wantErr == nil {
assert.Equal(t, tc.wantRes, res)
}
})
}
Expand Down
9 changes: 9 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,15 @@ func Wrap(err error, description string) TMError {
}
}

// Wrapf extends given error with an additional information.
//
// This function works like Wrap function with additional funtionality of
// formatting the input as specified.
func Wrapf(err error, format string, args ...interface{}) TMError {
desc := fmt.Sprintf(format, args...)
return Wrap(err, desc)
}

type wrappedError struct {
// This error layer description.
msg string
Expand Down
Loading

0 comments on commit c062966

Please sign in to comment.