89: Add support for setting accounts by address (not just pub_key) in genesis.json
This commit is contained in:
parent
b53d71c5cf
commit
ecaff359d2
11
app/app.go
11
app/app.go
|
@ -1,6 +1,7 @@
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -77,14 +78,18 @@ func (app *Basecoin) SetOption(key string, value string) string {
|
||||||
app.state.SetChainID(value)
|
app.state.SetChainID(value)
|
||||||
return "Success"
|
return "Success"
|
||||||
case "account":
|
case "account":
|
||||||
var acc types.Account
|
var acc GenesisAccount
|
||||||
err := json.Unmarshal([]byte(value), &acc)
|
err := json.Unmarshal([]byte(value), &acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "Error decoding acc message: " + err.Error()
|
return "Error decoding acc message: " + err.Error()
|
||||||
}
|
}
|
||||||
acc.Balance.Sort()
|
acc.Balance.Sort()
|
||||||
app.state.SetAccount(acc.PubKey.Address(), &acc)
|
addr, err := acc.GetAddr()
|
||||||
app.logger.Info("SetAccount", "addr", acc.PubKey.Address(), "acc", acc)
|
if err != nil {
|
||||||
|
return "Invalid address: " + err.Error()
|
||||||
|
}
|
||||||
|
app.state.SetAccount(addr, acc.ToAccount())
|
||||||
|
app.logger.Info("SetAccount", "addr", hex.EncodeToString(addr), "acc", acc)
|
||||||
|
|
||||||
return "Success"
|
return "Success"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/tendermint/basecoin/types"
|
"github.com/tendermint/basecoin/types"
|
||||||
|
crypto "github.com/tendermint/go-crypto"
|
||||||
|
"github.com/tendermint/go-wire/data"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,7 +52,7 @@ type FullGenesisDoc struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type GenesisDoc struct {
|
type GenesisDoc struct {
|
||||||
Accounts []types.Account `json:"accounts"`
|
Accounts []GenesisAccount `json:"accounts"`
|
||||||
PluginOptions []json.RawMessage `json:"plugin_options"`
|
PluginOptions []json.RawMessage `json:"plugin_options"`
|
||||||
|
|
||||||
pluginOptions []keyValue // unmarshaled rawmessages
|
pluginOptions []keyValue // unmarshaled rawmessages
|
||||||
|
@ -98,3 +101,40 @@ func parseGenesisList(kvz_ []json.RawMessage) (kvz []keyValue, err error) {
|
||||||
}
|
}
|
||||||
return kvz, nil
|
return kvz, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**** code to parse accounts from genesis docs ***/
|
||||||
|
|
||||||
|
type GenesisAccount struct {
|
||||||
|
Address data.Bytes `json:"address"`
|
||||||
|
// this from types.Account (don't know how to embed this properly)
|
||||||
|
PubKey crypto.PubKey `json:"pub_key"` // May be nil, if not known.
|
||||||
|
Sequence int `json:"sequence"`
|
||||||
|
Balance types.Coins `json:"coins"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GenesisAccount) ToAccount() *types.Account {
|
||||||
|
return &types.Account{
|
||||||
|
PubKey: g.PubKey,
|
||||||
|
Sequence: g.Sequence,
|
||||||
|
Balance: g.Balance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g GenesisAccount) GetAddr() ([]byte, error) {
|
||||||
|
noAddr, noPk := len(g.Address) == 0, g.PubKey.Empty()
|
||||||
|
|
||||||
|
if noAddr {
|
||||||
|
if noPk {
|
||||||
|
return nil, errors.New("No address given")
|
||||||
|
}
|
||||||
|
return g.PubKey.Address(), nil
|
||||||
|
}
|
||||||
|
if noPk { // but is addr...
|
||||||
|
return g.Address, nil
|
||||||
|
}
|
||||||
|
// now, we have both, make sure they check out
|
||||||
|
if bytes.Equal(g.Address, g.PubKey.Address()) {
|
||||||
|
return g.Address, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("Address and pubkey don't match")
|
||||||
|
}
|
||||||
|
|
|
@ -7,12 +7,14 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/tendermint/basecoin/types"
|
||||||
"github.com/tendermint/go-crypto"
|
"github.com/tendermint/go-crypto"
|
||||||
eyescli "github.com/tendermint/merkleeyes/client"
|
eyescli "github.com/tendermint/merkleeyes/client"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
const genesisFilepath = "./testdata/genesis.json"
|
const genesisFilepath = "./testdata/genesis.json"
|
||||||
|
const genesisAcctFilepath = "./testdata/genesis2.json"
|
||||||
|
|
||||||
func TestLoadGenesis(t *testing.T) {
|
func TestLoadGenesis(t *testing.T) {
|
||||||
assert, require := assert.New(t), require.New(t)
|
assert, require := assert.New(t), require.New(t)
|
||||||
|
@ -50,6 +52,51 @@ func TestLoadGenesis(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix for issue #89, change the parse format for accounts in genesis.json
|
||||||
|
func TestLoadGenesisAccountAddress(t *testing.T) {
|
||||||
|
assert, require := assert.New(t), require.New(t)
|
||||||
|
|
||||||
|
eyesCli := eyescli.NewLocalClient("", 0)
|
||||||
|
app := NewBasecoin(eyesCli)
|
||||||
|
err := app.LoadGenesis(genesisAcctFilepath)
|
||||||
|
require.Nil(err, "%+v", err)
|
||||||
|
|
||||||
|
// check the chain id
|
||||||
|
assert.Equal("addr_accounts_chain", app.GetState().GetChainID())
|
||||||
|
|
||||||
|
// make sure the accounts were set properly
|
||||||
|
cases := []struct {
|
||||||
|
addr string
|
||||||
|
exists bool
|
||||||
|
hasPubkey bool
|
||||||
|
coins types.Coins
|
||||||
|
}{
|
||||||
|
// this comes from a public key, should be stored proper (alice)
|
||||||
|
{"62035D628DE7543332544AA60D90D3693B6AD51B", true, true, types.Coins{{"one", 111}}},
|
||||||
|
// this comes from an address, should be stored proper (bob)
|
||||||
|
{"C471FB670E44D219EE6DF2FC284BE38793ACBCE1", true, false, types.Coins{{"two", 222}}},
|
||||||
|
// this one had a mismatched address and pubkey, should not store under either (carl)
|
||||||
|
{"1234ABCDD18E8EFE3FFC4B0506BF9BF8E5B0D9E9", false, false, nil}, // this is given addr
|
||||||
|
{"700BEC5ED18E8EFE3FFC4B0506BF9BF8E5B0D9E9", false, false, nil}, // this is addr of the given pubkey
|
||||||
|
// this comes from a secp256k1 public key, should be stored proper (sam)
|
||||||
|
{"979F080B1DD046C452C2A8A250D18646C6B669D4", true, true, types.Coins{{"four", 444}}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
addr, err := hex.DecodeString(tc.addr)
|
||||||
|
require.Nil(err, tc.addr)
|
||||||
|
acct := app.GetState().GetAccount(addr)
|
||||||
|
if !tc.exists {
|
||||||
|
assert.Nil(acct, tc.addr)
|
||||||
|
} else if assert.NotNil(acct, tc.addr) {
|
||||||
|
// it should and does exist...
|
||||||
|
assert.True(acct.Balance.IsValid())
|
||||||
|
assert.Equal(tc.coins, acct.Balance)
|
||||||
|
assert.Equal(!tc.hasPubkey, acct.PubKey.Empty(), tc.addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseGenesisList(t *testing.T) {
|
func TestParseGenesisList(t *testing.T) {
|
||||||
assert, require := assert.New(t), require.New(t)
|
assert, require := assert.New(t), require.New(t)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
"chain_id": "addr_accounts_chain",
|
||||||
|
"app_options": {
|
||||||
|
"accounts": [{
|
||||||
|
"name": "alice",
|
||||||
|
"pub_key": {
|
||||||
|
"type": "ed25519",
|
||||||
|
"data": "DBD9A46C45868F0A37C92B53113C09B048FBD87B5FBC2F8B199052973B8FAA36"
|
||||||
|
},
|
||||||
|
"coins": [
|
||||||
|
{
|
||||||
|
"denom": "one",
|
||||||
|
"amount": 111
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
"name": "bob",
|
||||||
|
"address": "C471FB670E44D219EE6DF2FC284BE38793ACBCE1",
|
||||||
|
"coins": [
|
||||||
|
{
|
||||||
|
"denom": "two",
|
||||||
|
"amount": 222
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
"name": "carl",
|
||||||
|
"address": "1234ABCDD18E8EFE3FFC4B0506BF9BF8E5B0D9E9",
|
||||||
|
"pub_key": {
|
||||||
|
"type": "ed25519",
|
||||||
|
"data": "177C0AC45E86257F0708DC085D592AB22AAEECD1D26381B757F7C96135921858"
|
||||||
|
},
|
||||||
|
"coins": [
|
||||||
|
{
|
||||||
|
"denom": "three",
|
||||||
|
"amount": 333
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
"name": "sam",
|
||||||
|
"pub_key": {
|
||||||
|
"type": "secp256k1",
|
||||||
|
"data": "02AA8342F63CCCCE6DDB128525BA048CE0B2993DA3B4308746E1F216361A87651E"
|
||||||
|
},
|
||||||
|
"coins": [
|
||||||
|
{
|
||||||
|
"denom": "four",
|
||||||
|
"amount": 444
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue