cosmos-sdk/server/init.go
Alessio Treglia 593921d04d Merge PR #2524: Replace GenTx with StdTx
Rework the process of loading a genesis.json file to load a starting app state and set of initial transactions to process.

* New function to create genesis account from MsgCreateValidator
* Add arg to PrintUnsignedStdTx() to actually operate in offline mode
* New func processStdTxs()
* Remove gen-tx command
* Cleanup, return validators as they need to be written into genesis.json
* Modify gaiad init to allow auto-create of stdTx
* Remove server/testnet.go
* Don't load node_key.json, which might not be available
* Get the txs through DeliverTx
* Add app.slashingKeeper.AddValidators at the end of genesis
* On InitChain(), Signature's account number must be 0
* Add (tentative?) command to generate {node_key,priv_validator}.json files
* Reintroduce gaiad testnet
* Prompt user for passwords
* Update gaia to work with auth.StdTx
* Remove test_utils, NewTestGaiaAppGenState is now deprecated
* Combine --genesis-format and --generate-only
* Improve sign command's --offline flag documentation
* Moniker must be set
* Call app.slashingKeeper.AddValidators() even if len(txs) == 0
* Refactoring, introduce gaiad init --skip-genesis, code cleanup
* Drop unnecessary workaround to make lcd_tests pass
* Reintroduce gentx
* Simple name changes, GenesisState.Txs -> .GenTxs; OWK -> OverwriteKey; OverwriteKeys -> OverwriteKey
2018-10-19 20:00:27 +02:00

140 lines
3.7 KiB
Go

package server
import (
"encoding/json"
"errors"
"fmt"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/tendermint/tendermint/crypto"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/types"
clkeys "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
tmtypes "github.com/tendermint/tendermint/types"
)
// Core functionality passed from the application to the server init command
type AppInit struct {
// AppGenState creates the core parameters initialization. It takes in a
// pubkey meant to represent the pubkey of the validator of this machine.
AppGenState func(cdc *codec.Codec, appGenTx []json.RawMessage) (appState json.RawMessage, err error)
}
// SimpleGenTx is a simple genesis tx
type SimpleGenTx struct {
Addr sdk.AccAddress `json:"addr"`
}
//_____________________________________________________________________
// simple default application init
var DefaultAppInit = AppInit{
AppGenState: SimpleAppGenState,
}
// Generate a genesis transaction
func SimpleAppGenTx(cdc *codec.Codec, pk crypto.PubKey) (appGenTx, cliPrint json.RawMessage, validator types.GenesisValidator, err error) {
var addr sdk.AccAddress
var secret string
addr, secret, err = GenerateCoinKey()
if err != nil {
return
}
var bz []byte
simpleGenTx := SimpleGenTx{Addr: addr}
bz, err = cdc.MarshalJSON(simpleGenTx)
if err != nil {
return
}
appGenTx = json.RawMessage(bz)
mm := map[string]string{"secret": secret}
bz, err = cdc.MarshalJSON(mm)
if err != nil {
return
}
cliPrint = json.RawMessage(bz)
validator = tmtypes.GenesisValidator{
PubKey: pk,
Power: 10,
}
return
}
// create the genesis app state
func SimpleAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
if len(appGenTxs) != 1 {
err = errors.New("must provide a single genesis transaction")
return
}
var tx SimpleGenTx
err = cdc.UnmarshalJSON(appGenTxs[0], &tx)
if err != nil {
return
}
appState = json.RawMessage(fmt.Sprintf(`{
"accounts": [{
"address": "%s",
"coins": [
{
"denom": "mycoin",
"amount": "9007199254740992"
}
]
}]
}`, tx.Addr))
return
}
//___________________________________________________________________________________________
// GenerateCoinKey returns the address of a public key, along with the secret
// phrase to recover the private key.
func GenerateCoinKey() (sdk.AccAddress, string, error) {
// construct an in-memory key store
keybase := keys.New(
dbm.NewMemDB(),
)
// generate a private key, with recovery phrase
info, secret, err := keybase.CreateMnemonic("name", keys.English, "pass", keys.Secp256k1)
if err != nil {
return sdk.AccAddress([]byte{}), "", err
}
addr := info.GetPubKey().Address()
return sdk.AccAddress(addr), secret, nil
}
// GenerateSaveCoinKey returns the address of a public key, along with the secret
// phrase to recover the private key.
func GenerateSaveCoinKey(clientRoot, keyName, keyPass string, overwrite bool) (sdk.AccAddress, string, error) {
// get the keystore from the client
keybase, err := clkeys.GetKeyBaseFromDir(clientRoot)
if err != nil {
return sdk.AccAddress([]byte{}), "", err
}
// ensure no overwrite
if !overwrite {
_, err := keybase.Get(keyName)
if err == nil {
return sdk.AccAddress([]byte{}), "", fmt.Errorf(
"key already exists, overwrite is disabled (clientRoot: %s)", clientRoot)
}
}
// generate a private key, with recovery phrase
info, secret, err := keybase.CreateMnemonic(keyName, keys.English, keyPass, keys.Secp256k1)
if err != nil {
return sdk.AccAddress([]byte{}), "", err
}
addr := info.GetPubKey().Address()
return sdk.AccAddress(addr), secret, nil
}