cosmos / cosmos-sdk

:chains: A Framework for Building High Value Public Blockchains :sparkles:
https://cosmos.network/
Apache License 2.0
6.26k stars 3.62k forks source link

Start chain with initial state + sequence of transactions #1890

Closed UnitylChaos closed 6 years ago

UnitylChaos commented 6 years ago
## 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:

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 - [x] Not duplicate issue - [ ] Appropriate labels applied - [ ] Appropriate contributors tagged - [ ] Contributor assigned/self-assigned
ValarDragon commented 6 years ago

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 commented 6 years ago

@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 commented 6 years ago

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.

rigelrozanski commented 6 years ago

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 https://github.com/cosmos/cosmos-sdk/issues/659

cwgoes commented 6 years ago

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 commented 6 years ago

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

cwgoes commented 6 years ago

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 commented 6 years ago

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

ValarDragon commented 6 years ago

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 :sunglasses: 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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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

cwgoes commented 6 years ago

Consensus in meeting:

alessio commented 6 years ago

Here it comes a slightly more detailed proposal:

cwgoes commented 6 years ago

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 commented 6 years ago

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 :+1:

cwgoes commented 6 years ago

Closed by #2524.