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

Start chain with initial state + sequence of transactions #1890

Closed
1 of 4 tasks
UnitylChaos opened this issue Jul 31, 2018 · 17 comments
Closed
1 of 4 tasks

Start chain with initial state + sequence of transactions #1890

UnitylChaos opened this issue Jul 31, 2018 · 17 comments
Assignees

Comments

@UnitylChaos
Copy link
Contributor

UnitylChaos commented Jul 31, 2018

Summary

Rework the process of loading a genesis.json file, to load a starting app state, and set of initial transactions to process.

Problem Definition

Currently gaiad init gen-tx generates a json blob for each intended validator, and the gaiad init --gen-txs command processes those and generates a genesis.json file which includes data in the following structure:

  • Validators (pubkey, power, moniker)
  • App State
    • Accounts (address, coins)
    • Validators (operator address, tokens, + lots of data needed for stake module)
    • Bonds (delegator address, validator operator address, amount)

gaiad export also dumps the current blockchain state into a genesis.json file with the same structure, so that a chain can be restarted with the same distribution of tokens / validator power.

This scheme works, but currently does not have any sort of authorization, validation, or consistency checking of the gentx files or the resulting genesis.json file.
This can lead to problems where gentx files are created for validators without their permission, or one user creates a validator under another's owner address, blocking them from making their own. This also has no system for validating the distribution of tokens that result.

Proposal

The proposed scheme is that we allow the genesis.json file to include both a starting state, and a set of fully valid transactions to be executed in a "block 0" of sorts. The starting state could be as minimal as just the distribution of coins in accounts, with the starting transactions being the self bonds and delegations needed to build the initial validator set. This would allow for "genesis transactions" to be actual transactions, which are validated the same way as bond/delegation transactions in a live chain. The system could also be used to allow chains to start with more complex state such as premade governance proposals or other app specific setup transactions without modifying the initial genesis state.
In the context of state exports for chain restarts or for generation of forks, the starting state could encapsulate the full state without using any additional transactions.

The implementation of this change would consist of adding functionality to run a sequence of transactions included in the genesis file. This would have to happen between when the genesis state is loaded, and when the initial set of validators is passed to tendermint.

This would allow for starfish to be simpler, as users would create self bond/delegation transactions with gaiacli, and submit them for inclusion through some mechanism such as github PRs, or a web form.


For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned
@ValarDragon
Copy link
Contributor

ValarDragon commented Sep 16, 2018

Why not just require self-signed gen-txs, or have the validator sign the Hash of the genesis file sans the validator set? Seems simpler to implement, and we can just include the signature in the genesis file.

@alexanderbez
Copy link
Contributor

@ValarDragon that does sound simpler indeed, but does not allow for the flexibility of running an initial series of txs. I think both ideas are good in their respective ways. I guess it really depends on what were aiming for here. If it's just verification & authentication, then I'd vouch for the simpler route.

@ValarDragon
Copy link
Contributor

ValarDragon commented Sep 20, 2018

Does anyone else have thoughts on this? The more I think about this, the more I'm in favor of just having self-signed gen-txs for simplicity. (Previous proposed in #659)

gaiad export already puts the governance and staking states into the genesis file. So I see no need for engineering a system for these txs.

@alessio alessio self-assigned this Sep 25, 2018
@rigelrozanski
Copy link
Contributor

Based on our SDK call today we decided to go with the original idea of simple signing gen-tx's offline using the CLI and then somehow distributing them - something along the lines of #659

@cwgoes
Copy link
Contributor

cwgoes commented Sep 26, 2018

Based on our SDK call today we decided to go with the original idea of simple signing gen-tx's offline using the CLI and then somehow distributing them - something along the lines of #659

Is there a particular reason we can't execute normal transactions in a fake "genesis block" then run the EndBlock handler and return the associated validator set updates? That way we don't have to implement additional logic duplicating some subset of our existing signature checking & state machine code for validator initialization.

I guess it might not be possible to declare-candidacy from a nonexistent account - but in that case do we want to make that possible for awhile? (holders of Atoms at genesis should be fine, since they can declare-candidacy from their existing account which will be initialized before the transactions are run). I'm a bit concerned about having some actions be possible at genesis but not immediately afterwards, since no genesis ceremony is going to be perfectly fair.

@cwgoes
Copy link
Contributor

cwgoes commented Sep 26, 2018

Ref #1840 - if we no longer need that logic after making these updates we should get rid of it.

@cwgoes
Copy link
Contributor

cwgoes commented Sep 26, 2018

One concern per discussion with @alessio - we need some way to order genesis transactions, whether GenesisTx or StdTx. In rare cases ordering will matter - if two validator candidates have the exact same stake, for example, the first might become the 100th validator and the second wouldn't get a slot.

Is there a fair way to order? If we order by the transaction hash validator addresses or memos can be ground. Maybe we could order by already-known account addresses - but I'm not sure if we'll have those if we want zero-balance accounts to be able to declare candidacy at genesis.

@alexanderbez
Copy link
Contributor

alexanderbez commented Sep 26, 2018

Could we have a lottery based on a PoW chain? 🤷‍♂️ In all seriousness, this is a fair point. Is there anything you can game by simply using the validator address?

@ValarDragon
Copy link
Contributor

ValarDragon commented Sep 26, 2018

Noooo lets not encourage validator grinding. This is an extremely solvable problem. In the below discussion of biasability I take the (not likely) model where AIB / ICF personel control the entire genesis tx set. (This is because it may be seen this way to others) Before genesis creation begins, ICF hash commits to a 256 bit nonce, and we state that we will use the bitcoin block hash for a certain block height in the future, which will occur after the genesis tx set is finalized.

The genesis file proceeds as follows. First collect and finalize the genesis tx set. After this ICF hash reveals, and we wait for a pre-stated Bitcoin Block Hash for a certain future height to occur. The ordering_key we now use is ordering_key = H(ICF_Nonce, Bitcoin_block_hash). As ICF can't control the Bitcoin block hash (we presume), and anyone who can bias the bitcoin block hash can't bias the ICF nonce, we presume this key secure. Now we derive a priority for each gen_tx as HKDF(sha256, key=ordering_key, data=tx_hash, info="gaia_genesis"). We could probably just use a hash, but HKDF is cooler 😎 Now that we have an unbiasable priority, sorting is easy and safe for everything :).

If we want the gen_tx priority to depend on the genesis file itself (not entirely sure I see a reason why), we can easily throw in the incorrectly prioritized genesis file hash into the data file. (We would have to order gen_tx's by some arbitrary ordering then, but that doesn't really matter)

If for some reason ICF comitting to a hash is problematic, I have another idea with the same security properties using VRF's. It will just require a second wave of interactivity, and we probably won't get it working for ledger users, but w/e. If we need to support ledger users and ICF can't produce a nonce for us, theres a third idea involving VDF's. It would rely on the world trusting that AIB didn't have VDF hardware though, but otherwise requires no interactivity after genesis tx set is decided. Note that just using the bitcoin block hash isn't done, because 1) that isn't as cool as any of the above, 2) a validator on our network could conceivably be a bitcoin miner.

@cwgoes
Copy link
Contributor

cwgoes commented Sep 26, 2018

Ah yes, we just need an external random oracle, thanks @ValarDragon. We can use H(BTC block hash | ETH block hash) just to highlight the spiritual predecessors of the Cosmos Hub if we want (plus additional security).

I don't see why we need to commit to a nonce, can't we just release the initial genesis file, sans the "external random seed" field, prior to the BTC/ETH blocks, then users can verify the values from the blocks themselves?

@ValarDragon
Copy link
Contributor

We could, but tin foil hat time what if a cosmos validator is a significant miner on both BTC and ETH? I guess we could say that if they had enough money to make it worth losing profits in order to bias the chains, they could guarantee themselves a spot in the top 100 validators anyway, so they would just be grinding for being the technical "first" validator. I like the idea of ICF providing a hash committed nonce tho, since it prevents that but with no loss of security. Your right, we don't need the ICF hash, but I still think it'd be nice.

@alexanderbez
Copy link
Contributor

Neat idea. Seems like the nonce would be a bonus but not necessary.

@cwgoes
Copy link
Contributor

cwgoes commented Sep 26, 2018

Consensus in meeting:

  • List of random nonces hashes together
  • StdTx, not GenesisTx

@alessio
Copy link
Contributor

alessio commented Sep 28, 2018

Here it comes a slightly more detailed proposal:

  • Drop GenesisTx in favor of StdTx with only one MsgCreateValidator message
  • Modify gaiad init gen-tx so that it
    1. loads or creates priv_validator.json file
    2. passes control to gaiacli tx create-validator --generate-only (we may actually want to add a task specific --genesis-format flag and drop gaiad init gen-tx altogether).
  • Modify MsgCreateValidator to include two extra NodeID and IP fields, only required by genesis processing/validation, skipped otherwise.
  • Port gaiad init --with-txs to work with StdTx.
  • Port gaiad testnet to work with the new StdTx based implementation.

@cwgoes
Copy link
Contributor

cwgoes commented Sep 28, 2018

I agree with everything except:

Modify MsgCreateValidator to include two extra NodeID and IP fields, only required by genesis processing/validation, skipped otherwise.

Why do we need these fields anymore? Those were convenient for fast testnet setup, but I think we've mostly stopped using that process and we don't need it for Hub launch.

If we still want to preserve that flow (which is helpful for one-off testnets) let's use the memo field of the tx or something.

@alessio
Copy link
Contributor

alessio commented Sep 28, 2018

If we still want to preserve that flow (which is helpful for one-off testnets) let's use the memo field of the tx or something.

Agreed 👍

@cwgoes
Copy link
Contributor

cwgoes commented Oct 19, 2018

Closed by #2524.

@cwgoes cwgoes closed this as completed Oct 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants