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

Adding more specialized keepers to bank #831

Merged
merged 3 commits into from
Apr 17, 2018
Merged

Conversation

sunnya97
Copy link
Member

@sunnya97 sunnya97 commented Apr 9, 2018

Closes #802
Also added test coverage to bank keepers.

  • Updated all relevant documentation in docs
  • Updated all code comments where relevant
  • Wrote tests
  • Updated CHANGELOG.md

@sunnya97 sunnya97 requested a review from ebuchman as a code owner April 9, 2018 21:47
@sunnya97 sunnya97 force-pushed the sunny/bank-additions branch from c060388 to 52b143d Compare April 9, 2018 22:11
@codecov
Copy link

codecov bot commented Apr 9, 2018

Codecov Report

Merging #831 into develop will increase coverage by 1.31%.
The diff coverage is 96.92%.

@@             Coverage Diff             @@
##           develop     #831      +/-   ##
===========================================
+ Coverage    65.48%   66.79%   +1.31%     
===========================================
  Files           67       67              
  Lines         3546     3581      +35     
===========================================
+ Hits          2322     2392      +70     
+ Misses        1034      995      -39     
- Partials       190      194       +4

@sunnya97 sunnya97 requested review from rigelrozanski and cwgoes and removed request for ebuchman April 10, 2018 11:04
@cwgoes
Copy link
Contributor

cwgoes commented Apr 10, 2018

See #802 (comment).

@sunnya97 sunnya97 changed the title WIP: Adding more specialized keepers to bank Adding more specialized keepers to bank Apr 10, 2018
// wire registration while we're at it ... TODO
var _ = oldwire.RegisterInterface(
struct{ sdk.Account }{},
oldwire.ConcreteType{&auth.BaseAccount{}, 0x1},
Copy link
Contributor

Choose a reason for hiding this comment

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

We're on go-amino now :) - let's update these tests to use go-amino


// ViewKeeper only allows reading of balances
type ViewKeeper struct {
am sdk.AccountMapper
Copy link
Contributor

@rigelrozanski rigelrozanski Apr 10, 2018

Choose a reason for hiding this comment

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

Do we actually need to create explicit structs for this? Is it not safe for some reason to use just create more limited interfaces and of CoinKeeper and cast a new object to that interface? I'm actually not sure and would like to know
@jaekwon

Copy link
Contributor

Choose a reason for hiding this comment

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

More on this I really like @cwgoes design #802 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

base on 802 conversation ... YES we do want explicit structs - aka this comment is stale

@rigelrozanski
Copy link
Contributor

Oh yeah also should update the changelog before merge - see you have a checkbox for that

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.

Agreed on general design per suggestion, a few minor quibbles.

func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) {
oldCoins := getCoins(ctx, am, addr)
newCoins := oldCoins.Plus(amt)
if !newCoins.IsNotNegative() {
Copy link
Contributor

Choose a reason for hiding this comment

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

When does this happen - overflow? Should we just panic on overflow? This error would be confusing.

Copy link
Member Author

@sunnya97 sunnya97 Apr 17, 2018

Choose a reason for hiding this comment

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

I was thinking more if someone passes in a negative amount of coins to be added.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh OK, that's fine I guess.

In general, I find representing negative coins a bit confusing (as you never want anyone to end up with negative coins, it's just an intermediate representation, but it uses the same datatype), but maybe that's just me.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. Negative coins is weird.

x/bank/keeper.go Outdated
}

// SendCoins moves coins from one account to another
func (ck CoinKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error {
_, err := ck.SubtractCoins(ctx, fromAddr, amt)
func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we be explicit (in the comment) that if an error is returned, the caller must revert state changes (otherwise coins could be subtracted but not added).

Copy link
Contributor

Choose a reason for hiding this comment

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

Or at least the CacheWrap should be thrown out. That should be the general behavior upon error.

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought this was going to be handled by BaseApp or something?

Copy link
Contributor

Choose a reason for hiding this comment

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

It is - just make it clear in the comment so if someone writes a different baseapp they don't accidentally destroy coins

x/bank/keeper.go Outdated
@@ -73,20 +69,119 @@ func (ck CoinKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk
}

// InputOutputCoins handles a list of inputs and outputs
func (ck CoinKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error {
func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, outputs []Output) sdk.Error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto on above - if an error is returned, the caller must revert state changes.


}

func TestViewKeeper(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Add tests to make sure ViewKeeper can't be cast to SendKeeper.

Copy link
Member Author

Choose a reason for hiding this comment

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

They are currently both structs, so can't cast them to each other already. Won't compile.

// CoinKeeper manages transfers between accounts
type CoinKeeper struct {
am sdk.AccountMapper
func getCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address) sdk.Coins {
Copy link
Contributor

Choose a reason for hiding this comment

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

This extra method indirection is not useful, I think we should just define these as CoinKeeper methods.

Copy link
Member Author

Choose a reason for hiding this comment

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

But then how would I call it from the ViewKeeper for example?

Copy link
Member Author

@sunnya97 sunnya97 Apr 17, 2018

Choose a reason for hiding this comment

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

I could embed a CoinKeeper in ViewKeeper, but I would prefer to not have to create a new CoinKeeper just to create a ViewKeeper.

Copy link
Contributor

@cwgoes cwgoes Apr 17, 2018

Choose a reason for hiding this comment

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

Can you embed the ViewKeeper in the CoinKeeper though? The creation can happen in NewCoinKeeper, which is already an exported function.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't like embedding structs because if you have "diamond inheritance" it cries unambiguous selector. https://play.golang.org/p/-t7jTejvaTg

I think the unexported functions in the module which each keeper can call is cleanest and most versatile without ever having to think about inheritance issues.

@cwgoes cwgoes force-pushed the sunny/bank-additions branch from 500f71b to d2013ec Compare April 17, 2018 21:40
@cwgoes cwgoes merged commit ffd428d into develop Apr 17, 2018
@cwgoes cwgoes deleted the sunny/bank-additions branch April 17, 2018 21:44
@sunnya97 sunnya97 mentioned this pull request Nov 7, 2018
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants