Add issuer position to grant credit
This commit is contained in:
parent
89a8c0bf08
commit
6135345af8
|
@ -120,7 +120,10 @@ func GetGenesisJSON(chainID, addr string) string {
|
||||||
"amount": 9007199254740992
|
"amount": 9007199254740992
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}]
|
}],
|
||||||
|
"plugin_options": [
|
||||||
|
"coin/issuer", {"app": "sigs", "address": "%s"}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}`, chainID, addr)
|
}`, chainID, addr, addr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package coin
|
package coin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
|
@ -83,7 +81,6 @@ func (h Handler) DeliverTx(ctx basecoin.Context, store state.SimpleDB,
|
||||||
out.Address.ChainID = ""
|
out.Address.ChainID = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Giving %#v to %#v\n\n", out.Coins, out.Address)
|
|
||||||
_, err = ChangeCoins(store, out.Address, out.Coins)
|
_, err = ChangeCoins(store, out.Address, out.Coins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
|
@ -117,25 +114,11 @@ func (h Handler) SetOption(l log.Logger, store state.SimpleDB,
|
||||||
if module != NameCoin {
|
if module != NameCoin {
|
||||||
return "", errors.ErrUnknownModule(module)
|
return "", errors.ErrUnknownModule(module)
|
||||||
}
|
}
|
||||||
if key == "account" {
|
switch key {
|
||||||
var acc GenesisAccount
|
case "account":
|
||||||
err = data.FromJSON([]byte(value), &acc)
|
return setAccount(store, value)
|
||||||
if err != nil {
|
case "issuer":
|
||||||
return "", err
|
return setIssuer(store, value)
|
||||||
}
|
|
||||||
acc.Balance.Sort()
|
|
||||||
addr, err := acc.GetAddr()
|
|
||||||
if err != nil {
|
|
||||||
return "", ErrInvalidAddress()
|
|
||||||
}
|
|
||||||
// this sets the permission for a public key signature, use that app
|
|
||||||
actor := auth.SigPerm(addr)
|
|
||||||
err = storeAccount(store, actor.Bytes(), acc.ToAccount())
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return "Success", nil
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return "", errors.ErrUnknownKey(key)
|
return "", errors.ErrUnknownKey(key)
|
||||||
}
|
}
|
||||||
|
@ -159,3 +142,38 @@ func checkTx(ctx basecoin.Context, tx basecoin.Tx) (send SendTx, err error) {
|
||||||
}
|
}
|
||||||
return send, nil
|
return send, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setAccount(store state.KVStore, value string) (log string, err error) {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
// this sets the permission for a public key signature, use that app
|
||||||
|
actor := auth.SigPerm(addr)
|
||||||
|
err = storeAccount(store, actor.Bytes(), acc.ToAccount())
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return "Success", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setIssuer sets a permission for some super-powerful account to
|
||||||
|
// mint money
|
||||||
|
func setIssuer(store state.KVStore, value string) (log string, err error) {
|
||||||
|
var issuer basecoin.Actor
|
||||||
|
err = data.FromJSON([]byte(value), &issuer)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
err = storeIssuer(store, issuer)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return "Success", nil
|
||||||
|
}
|
||||||
|
|
|
@ -216,3 +216,34 @@ func TestSetOption(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetIssuer(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
issuer basecoin.Actor
|
||||||
|
}{
|
||||||
|
{basecoin.Actor{App: "sig", Address: []byte("gwkfgk")}},
|
||||||
|
// and set back to empty (nil is valid, but assert.Equals doesn't match)
|
||||||
|
{basecoin.Actor{Address: []byte{}}},
|
||||||
|
{basecoin.Actor{ChainID: "other", App: "role", Address: []byte("vote")}},
|
||||||
|
}
|
||||||
|
|
||||||
|
h := NewHandler()
|
||||||
|
l := log.NewNopLogger()
|
||||||
|
for i, tc := range cases {
|
||||||
|
store := state.NewMemKVStore()
|
||||||
|
key := "issuer"
|
||||||
|
|
||||||
|
value, err := json.Marshal(tc.issuer)
|
||||||
|
require.Nil(err, "%d,%d: %+v", i, err)
|
||||||
|
_, err = h.SetOption(l, store, NameCoin, key, string(value), nil)
|
||||||
|
require.Nil(err, "%+v", err)
|
||||||
|
|
||||||
|
// check state is proper
|
||||||
|
info, err := loadHandlerInfo(store)
|
||||||
|
assert.Nil(err, "%d: %+v", i, err)
|
||||||
|
assert.Equal(tc.issuer, info.Issuer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -84,7 +84,11 @@ func updateCoins(store state.SimpleDB, addr basecoin.Actor, coins Coins) (acct A
|
||||||
|
|
||||||
// Account - coin account structure
|
// Account - coin account structure
|
||||||
type Account struct {
|
type Account struct {
|
||||||
|
// Coins is how much is on the account
|
||||||
Coins Coins `json:"coins"`
|
Coins Coins `json:"coins"`
|
||||||
|
// Credit is how much has been "fronted" to the account
|
||||||
|
// (this is usually 0 except for trusted chains)
|
||||||
|
Credit Coins `json:"credit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadAccount(store state.SimpleDB, key []byte) (acct Account, err error) {
|
func loadAccount(store state.SimpleDB, key []byte) (acct Account, err error) {
|
||||||
|
@ -107,3 +111,35 @@ func storeAccount(store state.SimpleDB, key []byte, acct Account) error {
|
||||||
store.Set(key, bin)
|
store.Set(key, bin)
|
||||||
return nil // real stores can return error...
|
return nil // real stores can return error...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandlerInfo - this is global info on the coin handler
|
||||||
|
type HandlerInfo struct {
|
||||||
|
Issuer basecoin.Actor `json:"issuer"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: where to store these special pieces??
|
||||||
|
var handlerKey = []byte{12, 34}
|
||||||
|
|
||||||
|
func loadHandlerInfo(store state.KVStore) (info HandlerInfo, err error) {
|
||||||
|
data := store.Get(handlerKey)
|
||||||
|
if len(data) == 0 {
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
err = wire.ReadBinaryBytes(data, &info)
|
||||||
|
if err != nil {
|
||||||
|
msg := "Error reading handler info"
|
||||||
|
return info, errors.ErrInternal(msg)
|
||||||
|
}
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func storeIssuer(store state.KVStore, issuer basecoin.Actor) error {
|
||||||
|
info, err := loadHandlerInfo(store)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.Issuer = issuer
|
||||||
|
d := wire.BinaryBytes(info)
|
||||||
|
store.Set(handlerKey, d)
|
||||||
|
return nil // real stores can return error...
|
||||||
|
}
|
||||||
|
|
|
@ -157,3 +157,30 @@ func (tx SendTx) String() string {
|
||||||
func (tx SendTx) Wrap() basecoin.Tx {
|
func (tx SendTx) Wrap() basecoin.Tx {
|
||||||
return basecoin.Tx{tx}
|
return basecoin.Tx{tx}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// CreditTx - this allows a special issuer to give an account credit
|
||||||
|
// Satisfies: TxInner
|
||||||
|
type CreditTx struct {
|
||||||
|
Debitor basecoin.Actor `json:"debitor"`
|
||||||
|
// Credit is the amount to change the credit...
|
||||||
|
// This may be negative to remove some over-issued credit,
|
||||||
|
// but can never bring the credit or the balance to negative
|
||||||
|
Credit Coins `json:"credit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCreditTx - modify the credit granted to a given account
|
||||||
|
func NewCreditTx(debitor basecoin.Actor, credit Coins) basecoin.Tx {
|
||||||
|
return CreditTx{Debitor: debitor, Credit: credit}.Wrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap - used to satisfy TxInner
|
||||||
|
func (tx CreditTx) Wrap() basecoin.Tx {
|
||||||
|
return basecoin.Tx{tx}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateBasic - used to satisfy TxInner
|
||||||
|
func (tx CreditTx) ValidateBasic() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue