Implement SetOption in coin module

This commit is contained in:
Ethan Frey
2017-07-03 18:58:28 +02:00
parent fa1a300943
commit 7c4f408934
5 changed files with 144 additions and 88 deletions
+48
View 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")
}
+25 -2
View File
@@ -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) {
+57
View File
@@ -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)
}
}
}