Implement SetOption in coin module
This commit is contained in:
parent
fa1a300943
commit
7c4f408934
44
app/app.go
44
app/app.go
@ -18,6 +18,7 @@ import (
|
||||
|
||||
const (
|
||||
PluginNameBase = "base"
|
||||
ChainKey = "base/chain_id"
|
||||
)
|
||||
|
||||
type Basecoin struct {
|
||||
@ -67,41 +68,16 @@ func (app *Basecoin) Info() abci.ResponseInfo {
|
||||
|
||||
// ABCI::SetOption
|
||||
func (app *Basecoin) SetOption(key string, value string) string {
|
||||
// TODO
|
||||
return "todo"
|
||||
// pluginName, key := splitKey(key)
|
||||
// if pluginName != PluginNameBase {
|
||||
// // Set option on plugin
|
||||
// plugin := app.plugins.GetByName(pluginName)
|
||||
// if plugin == nil {
|
||||
// return "Invalid plugin name: " + pluginName
|
||||
// }
|
||||
// app.logger.Info("SetOption on plugin", "plugin", pluginName, "key", key, "value", value)
|
||||
// return plugin.SetOption(app.state, key, value)
|
||||
// } else {
|
||||
// // Set option on basecoin
|
||||
// switch key {
|
||||
// case "chain_id":
|
||||
// app.state.SetChainID(value)
|
||||
// return "Success"
|
||||
// case "account":
|
||||
// var acc GenesisAccount
|
||||
// err := json.Unmarshal([]byte(value), &acc)
|
||||
// if err != nil {
|
||||
// return "Error decoding acc message: " + err.Error()
|
||||
// }
|
||||
// acc.Balance.Sort()
|
||||
// addr, err := acc.GetAddr()
|
||||
// if err != nil {
|
||||
// return "Invalid address: " + err.Error()
|
||||
// }
|
||||
// app.state.SetAccount(addr, acc.ToAccount())
|
||||
// app.logger.Info("SetAccount", "addr", hex.EncodeToString(addr), "acc", acc)
|
||||
if key == ChainKey {
|
||||
app.state.SetChainID(value)
|
||||
return "Success"
|
||||
}
|
||||
|
||||
// return "Success"
|
||||
// }
|
||||
// return "Unrecognized option key " + key
|
||||
// }
|
||||
log, err := app.handler.SetOption(app.logger, app.state, key, value)
|
||||
if err == nil {
|
||||
return log
|
||||
}
|
||||
return "Error: " + err.Error()
|
||||
}
|
||||
|
||||
// ABCI::DeliverTx
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tendermint/basecoin/types"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
@ -22,20 +18,13 @@ func (app *Basecoin) LoadGenesis(path string) error {
|
||||
app.SetOption("base/chain_id", genDoc.ChainID)
|
||||
|
||||
// set accounts
|
||||
for _, acc := range genDoc.AppOptions.Accounts {
|
||||
accBytes, err := json.Marshal(acc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r := app.SetOption("base/account", string(accBytes))
|
||||
// TODO: SetOption returns an error
|
||||
app.logger.Info("Done setting Account via SetOption", "result", r)
|
||||
for _, acct := range genDoc.AppOptions.Accounts {
|
||||
_ = app.SetOption("base/account", string(acct))
|
||||
}
|
||||
|
||||
// set plugin options
|
||||
for _, kv := range genDoc.AppOptions.pluginOptions {
|
||||
r := app.SetOption(kv.Key, kv.Value)
|
||||
app.logger.Info("Done setting Plugin key-value pair via SetOption", "result", r, "k", kv.Key, "v", kv.Value)
|
||||
_ = app.SetOption(kv.Key, kv.Value)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -53,7 +42,7 @@ type FullGenesisDoc struct {
|
||||
}
|
||||
|
||||
type GenesisDoc struct {
|
||||
Accounts []GenesisAccount `json:"accounts"`
|
||||
Accounts []json.RawMessage `json:"accounts"`
|
||||
PluginOptions []json.RawMessage `json:"plugin_options"`
|
||||
|
||||
pluginOptions []keyValue // unmarshaled rawmessages
|
||||
@ -106,40 +95,3 @@ func parseGenesisList(kvz_ []json.RawMessage) (kvz []keyValue, err error) {
|
||||
}
|
||||
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")
|
||||
}
|
||||
|
||||
48
modules/coin/genesis.go
Normal file
48
modules/coin/genesis.go
Normal file
@ -0,0 +1,48 @@
|
||||
package coin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
|
||||
"github.com/tendermint/basecoin/types"
|
||||
)
|
||||
|
||||
/**** 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() Account {
|
||||
return Account{
|
||||
Sequence: g.Sequence,
|
||||
Coins: 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")
|
||||
}
|
||||
@ -1,6 +1,9 @@
|
||||
package coin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
@ -77,8 +80,28 @@ func (h Handler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoi
|
||||
}
|
||||
|
||||
func (h Handler) SetOption(l log.Logger, store types.KVStore, key, value string) (log string, err error) {
|
||||
// TODO
|
||||
return "ok", nil
|
||||
if key == "base/account" {
|
||||
var acc GenesisAccount
|
||||
err = data.FromJSON([]byte(value), &acc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
acc.Balance.Sort()
|
||||
addr, err := acc.GetAddr()
|
||||
if err != nil {
|
||||
return "", ErrInvalidAddress()
|
||||
}
|
||||
actor := basecoin.Actor{App: NameCoin, Address: addr}
|
||||
err = storeAccount(store, h.makeKey(actor), acc.ToAccount())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "Success", nil
|
||||
|
||||
} else {
|
||||
msg := fmt.Sprintf("Unknown key: %s", key)
|
||||
return "", errors.ErrInternal(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (send SendTx, err error) {
|
||||
|
||||
@ -1,10 +1,15 @@
|
||||
package coin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/stack"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
@ -158,5 +163,57 @@ func TestDeliverTx(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetOption(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
// some sample settings
|
||||
pk := crypto.GenPrivKeySecp256k1().Wrap()
|
||||
addr := pk.PubKey().Address()
|
||||
actor := basecoin.Actor{App: "coin", Address: addr}
|
||||
// actor2 := basecoin.Actor{App: "foo", Address: addr}
|
||||
|
||||
someCoins := types.Coins{{"atom", 123}}
|
||||
otherCoins := types.Coins{{"eth", 11}}
|
||||
mixedCoins := someCoins.Plus(otherCoins)
|
||||
|
||||
type money struct {
|
||||
addr basecoin.Actor
|
||||
coins types.Coins
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
init []GenesisAccount
|
||||
expected []money
|
||||
}{
|
||||
{
|
||||
[]GenesisAccount{{Address: addr, Balance: mixedCoins}},
|
||||
[]money{{actor, mixedCoins}},
|
||||
},
|
||||
}
|
||||
|
||||
h := NewHandler()
|
||||
l := log.NewNopLogger()
|
||||
for i, tc := range cases {
|
||||
store := types.NewMemKVStore()
|
||||
key := "base/account"
|
||||
|
||||
// set the options
|
||||
for j, gen := range tc.init {
|
||||
value, err := json.Marshal(gen)
|
||||
require.Nil(err, "%d,%d: %+v", i, j, err)
|
||||
_, err = h.SetOption(l, store, key, string(value))
|
||||
require.Nil(err)
|
||||
}
|
||||
|
||||
// check state is proper
|
||||
for _, f := range tc.expected {
|
||||
acct, err := loadAccount(store, h.makeKey(f.addr))
|
||||
assert.Nil(err, "%d: %+v", i, err)
|
||||
assert.Equal(f.coins, acct.Coins)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user