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

Low inflation rate creates invalid module account - potential chain halt #5569

Closed
4 tasks
rhuairahrighairidh opened this issue Jan 25, 2020 · 8 comments · Fixed by #5749
Closed
4 tasks

Low inflation rate creates invalid module account - potential chain halt #5569

rhuairahrighairidh opened this issue Jan 25, 2020 · 8 comments · Fixed by #5749
Assignees
Labels

Comments

@rhuairahrighairidh
Copy link
Contributor

Summary of Bug

  • If a chain starts with a low inflation rate (or low number of coins), an invalid mint module account is created.
  • This invalid account can then trigger a chain halt if the inflation rate (or coin amount) is increased.

Details:

  • For new chains, after InitGenesis,mint's module account doesn't exist. Normaly it's created as needed when mint's beginblocker runs.
    • mint's begin blocker calls supply.Mint which creates a mod account if one doesn't exist.
    • then newly minted coins are sent from this to the fee mod account
  • However if the coins to be minted that block are 0, then minting is skipped, so no account is created.
  • But sending coins from this non existant account to the fee mod account is not skipped. So zero coins are sent.
  • This triggers the bank module to create an empty BaseAccount with the address for mint's module account
  • Then if supplyever accesses this account it panics in the type assertion trying to convert it to module account. (
    macc, ok := acc.(exported.ModuleAccountI)
    )

Version

current

Steps to Reproduce

  • Set up a new chain using gaia master
  • modify the genesis file to set the current inflation rate (and min rate) to zero
  • start chain
  • gaiacli q account cosmos1m3h30wlvsf8llruxtpukdvsy0km2kum8g38c8q should return the mint module account, however it is not a module account

For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned
@rhuairahrighairidh rhuairahrighairidh changed the title Low inflation rate creates invalid module account in state Low inflation rate creates invalid module account in state - potential chain halt Jan 25, 2020
@rhuairahrighairidh rhuairahrighairidh changed the title Low inflation rate creates invalid module account in state - potential chain halt Low inflation rate creates invalid module account - potential chain halt Jan 25, 2020
@alexanderbez
Copy link
Contributor

Excellent investigation! Thanks, @rhuairahrighairidh.

@fedekunze, I don't understand why this is the flow of execution in the context of the minting module account not existing in genesis (or any module account for that matter).

It seems much more intuitive and sound to have the module accounts created (if they don't exist) during InitGenesis. Why is this not the case? Was this approach ever considered and decided against for some reason?

@alexanderbez
Copy link
Contributor

alexanderbez commented Jan 27, 2020

Alternatively, I've noticed x/staking takes care of this in its constructor. We can also do this for minting.

@rhuairahrighairidh would you like to take a stab at this simple approach?

@rhuairahrighairidh
Copy link
Contributor Author

Looks like mint already has the same account checks in it's constructor as staking. These don't check for the presence of an account in the store, just that the account and permissions were registered in the app definition.

@alexanderbez
Copy link
Contributor

alexanderbez commented Jan 28, 2020

@rhuairahrighairidh calling sk.GetModuleAccount(ctx, moduleName) does create the account. You can simply call this method. Although I do agree this is a poor API design.

/cc @fedekunze

@rhuairahrighairidh
Copy link
Contributor Author

Correct me if I'm missing something, but staking's keeper constructor calls sk.GetModuleAddress, not Account, which doesn't create the accounts.
Calling GetModuleAccount in NewKeeper would need access to the db, which isn't initialised yet at app creation

@alexanderbez
Copy link
Contributor

Correct, so not only are current constructors broken in their intent of using GetModuleAddress, we also cannot call GetModuleAccount as we do not have a Context.

So I would recommend we:

  1. Remove GetModuleAddress from constructors as it's pointless.
  2. Call GetModuleAccount during InitGenesis (for the relevant modules)

Changes should be pretty trivial to implement.

@rhuairahrighairidh
Copy link
Contributor Author

I agree with point 2, that would align mint with how other modules do it. However I believe GetModuleAddress does check whether the account has had permissions set in the app constructor.
I'm lacking some context for why things were set up this way. @fedekunze do you have any recommendations?

Also what do you think about skipping sending 0 coins in the mint begin blocker? Even with an account set up it will emit a send event for 0 which seems a bit odd.

@alexanderbez
Copy link
Contributor

I agree that we should avoid a zero balance send, but I don't see why (1) won't fix the overall issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants