From 396b85b303e5c071040469f3e230a9d052d9cb80 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Fri, 13 Apr 2018 02:47:18 -0700 Subject: [PATCH 001/176] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 63a40aaa7..640cd2874 100644 --- a/README.md +++ b/README.md @@ -70,4 +70,8 @@ The key directories of the SDK are: ## Getting Started -See the [documentation](https://cosmos-sdk.readthedocs.io). \ No newline at end of file +See the [documentation](https://cosmos-sdk.readthedocs.io). + +## Disambiguation + +This Cosmos-SDK project is not related to the [React-Cosmos](https://github.com/react-cosmos/react-cosmos) project (yet). Many thanks to Evan Coury and Ovidiu (@skidding) for this Github organization name. As per our agreement, this disambiguation notice will stay here. From c7bd05f0b8107880312e756a1647d6f32c97f742 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 10 Apr 2018 00:10:58 +0200 Subject: [PATCH 002/176] hard reset --- x/bank/keeper.go | 211 +++++++++++++++++++++++++++++----------- x/bank/keeper_test.go | 217 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 58 deletions(-) create mode 100644 x/bank/keeper_test.go diff --git a/x/bank/keeper.go b/x/bank/keeper.go index b52b480f6..4c20f962d 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -8,6 +8,85 @@ import ( const moduleName = "bank" +func getCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address) sdk.Coins { + acc := am.GetAccount(ctx, addr) + if acc == nil { + return sdk.Coins{} + } + return acc.GetCoins() +} + +func setCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) sdk.Error { + acc := am.GetAccount(ctx, addr) + if acc == nil { + acc = am.NewAccountWithAddress(ctx, addr) + } + acc.SetCoins(amt) + am.SetAccount(ctx, acc) + return nil +} + +// HasCoins returns whether or not an account has at least amt coins. +func hasCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) bool { + return getCoins(ctx, am, addr).IsGTE(amt) +} + +// SubtractCoins subtracts amt from the coins at the addr. +func subtractCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { + oldCoins := getCoins(ctx, am, addr) + newCoins := oldCoins.Minus(amt) + if !newCoins.IsNotNegative() { + return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) + } + err := setCoins(ctx, am, addr, newCoins) + return newCoins, err +} + +// AddCoins adds amt to the coins at the addr. +func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { + oldCoins := getCoins(ctx, am, addr) + newCoins := oldCoins.Plus(amt) + if !newCoins.IsNotNegative() { + return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) + } + err := setCoins(ctx, am, addr, newCoins) + return newCoins, err +} + +// SendCoins moves coins from one account to another +func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { + _, err := subtractCoins(ctx, am, fromAddr, amt) + if err != nil { + return err + } + + _, err = addCoins(ctx, am, toAddr, amt) + if err != nil { + return err + } + + return nil +} + +// InputOutputCoins handles a list of inputs and outputs +func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, outputs []Output) sdk.Error { + for _, in := range inputs { + _, err := subtractCoins(ctx, am, in.Address, in.Coins) + if err != nil { + return err + } + } + + for _, out := range outputs { + _, err := addCoins(ctx, am, out.Address, out.Coins) + if err != nil { + return err + } + } + + return nil +} + // CoinKeeper manages transfers between accounts type CoinKeeper struct { am sdk.AccountMapper @@ -19,74 +98,90 @@ func NewCoinKeeper(am sdk.AccountMapper) CoinKeeper { } // GetCoins returns the coins at the addr. -func (ck CoinKeeper) GetCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) sdk.Coins { - acc := ck.am.GetAccount(ctx, addr) - return acc.GetCoins() +func (keeper CoinKeeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { + return getCoins(ctx, keeper.am, addr) +} + +// SetCoins sets the coins at the addr. +func (keeper CoinKeeper) SetCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) sdk.Error { + return setCoins(ctx, keeper.am, addr, amt) +} + +// HasCoins returns whether or not an account has at least amt coins. +func (keeper CoinKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { + return hasCoins(ctx, keeper.am, addr, amt) } // SubtractCoins subtracts amt from the coins at the addr. -func (ck CoinKeeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { - acc := ck.am.GetAccount(ctx, addr) - if acc == nil { - return amt, sdk.ErrUnknownAddress(addr.String()) - } - - coins := acc.GetCoins() - newCoins := coins.Minus(amt) - if !newCoins.IsNotNegative() { - return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", coins, amt)) - } - - acc.SetCoins(newCoins) - ck.am.SetAccount(ctx, acc) - return newCoins, nil +func (keeper CoinKeeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { + return subtractCoins(ctx, keeper.am, addr, amt) } // AddCoins adds amt to the coins at the addr. -func (ck CoinKeeper) AddCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { - acc := ck.am.GetAccount(ctx, addr) - if acc == nil { - acc = ck.am.NewAccountWithAddress(ctx, addr) - } - - coins := acc.GetCoins() - newCoins := coins.Plus(amt) - - acc.SetCoins(newCoins) - ck.am.SetAccount(ctx, acc) - return newCoins, nil +func (keeper CoinKeeper) AddCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { + return addCoins(ctx, keeper.am, addr, amt) } // SendCoins moves coins from one account to another -func (ck CoinKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { - _, err := ck.SubtractCoins(ctx, fromAddr, amt) - if err != nil { - return err - } - - _, err = ck.AddCoins(ctx, toAddr, amt) - if err != nil { - return err - } - - return nil +func (keeper CoinKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { + return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt) } // InputOutputCoins handles a list of inputs and outputs -func (ck CoinKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { - for _, in := range inputs { - _, err := ck.SubtractCoins(ctx, in.Address, in.Coins) - if err != nil { - return err - } - } - - for _, out := range outputs { - _, err := ck.AddCoins(ctx, out.Address, out.Coins) - if err != nil { - return err - } - } - - return nil +func (keeper CoinKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { + return inputOutputCoins(ctx, keeper.am, inputs, outputs) +} + +// -------------------------------------------------- + +// SendKeeper only allows transfers between accounts, without the possibility of creating coins +type SendKeeper struct { + am sdk.AccountMapper +} + +// NewSendKeeper returns a new CoinKeeper +func NewSendKeeper(am sdk.AccountMapper) SendKeeper { + return SendKeeper{am: am} +} + +// GetCoins returns the coins at the addr. +func (keeper SendKeeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { + return getCoins(ctx, keeper.am, addr) +} + +// HasCoins returns whether or not an account has at least amt coins. +func (keeper SendKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { + return hasCoins(ctx, keeper.am, addr, amt) +} + +// SendCoins moves coins from one account to another +func (keeper SendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { + return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt) +} + +// InputOutputCoins handles a list of inputs and outputs +func (keeper SendKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { + return inputOutputCoins(ctx, keeper.am, inputs, outputs) +} + +// -------------------------------------------------- + +// ViewKeeper only allows reading of balances +type ViewKeeper struct { + am sdk.AccountMapper +} + +// NewViewKeeper returns a new CoinKeeper +func NewViewKeeper(am sdk.AccountMapper) ViewKeeper { + return ViewKeeper{am: am} +} + +// GetCoins returns the coins at the addr. +func (keeper ViewKeeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { + return getCoins(ctx, keeper.am, addr) +} + +// HasCoins returns whether or not an account has at least amt coins. +func (keeper ViewKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { + return hasCoins(ctx, keeper.am, addr, amt) } diff --git a/x/bank/keeper_test.go b/x/bank/keeper_test.go new file mode 100644 index 000000000..0f5ce128f --- /dev/null +++ b/x/bank/keeper_test.go @@ -0,0 +1,217 @@ +package bank + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + abci "github.com/tendermint/abci/types" + dbm "github.com/tendermint/tmlibs/db" + + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + oldwire "github.com/tendermint/go-wire" + + "github.com/cosmos/cosmos-sdk/x/auth" +) + +func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { + db := dbm.NewMemDB() + authKey := sdk.NewKVStoreKey("authkey") + ms := store.NewCommitMultiStore(db) + ms.MountStoreWithDB(authKey, sdk.StoreTypeIAVL, db) + ms.LoadLatestVersion() + return ms, authKey +} + +func TestCoinKeeper(t *testing.T) { + ms, authKey := setupMultiStore() + + // wire registration while we're at it ... TODO + var _ = oldwire.RegisterInterface( + struct{ sdk.Account }{}, + oldwire.ConcreteType{&auth.BaseAccount{}, 0x1}, + ) + + ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + accountMapper := auth.NewAccountMapper(authKey, &auth.BaseAccount{}) + coinKeeper := NewCoinKeeper(accountMapper) + + addr := sdk.Address([]byte("addr1")) + addr2 := sdk.Address([]byte("addr2")) + addr3 := sdk.Address([]byte("addr3")) + acc := accountMapper.NewAccountWithAddress(ctx, addr) + + // Test GetCoins/SetCoins + accountMapper.SetAccount(ctx, acc) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{})) + + coinKeeper.SetCoins(ctx, addr, sdk.Coins{{"foocoin", 10}}) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) + + // Test HasCoins + assert.True(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 10}})) + assert.True(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 5}})) + assert.False(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 15}})) + assert.False(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{{"barcoin", 5}})) + + // Test AddCoins + coinKeeper.AddCoins(ctx, addr, sdk.Coins{{"foocoin", 15}}) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 25}})) + + coinKeeper.AddCoins(ctx, addr, sdk.Coins{{"barcoin", 15}}) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 15}, {"foocoin", 25}})) + + // Test SubtractCoins + coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{{"foocoin", 10}}) + coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{{"barcoin", 5}}) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 10}, {"foocoin", 15}})) + + _, err := coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{{"barcoin", 11}}) + assert.Implements(t, (*sdk.Error)(nil), err) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 10}, {"foocoin", 15}})) + + coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{{"barcoin", 10}}) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 15}})) + assert.False(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{{"barcoin", 1}})) + + // Test SendCoins + coinKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"foocoin", 5}}) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) + assert.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"foocoin", 5}})) + + err2 := coinKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"foocoin", 50}}) + assert.Implements(t, (*sdk.Error)(nil), err2) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) + assert.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"foocoin", 5}})) + + coinKeeper.AddCoins(ctx, addr, sdk.Coins{{"barcoin", 30}}) + coinKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"barcoin", 10}, {"foocoin", 5}}) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 20}, {"foocoin", 5}})) + assert.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"barcoin", 10}, {"foocoin", 10}})) + + // Test InputOutputCoins + input1 := NewInput(addr2, sdk.Coins{{"foocoin", 2}}) + output1 := NewOutput(addr, sdk.Coins{{"foocoin", 2}}) + coinKeeper.InputOutputCoins(ctx, []Input{input1}, []Output{output1}) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 20}, {"foocoin", 7}})) + assert.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"barcoin", 10}, {"foocoin", 8}})) + + inputs := []Input{ + NewInput(addr, sdk.Coins{{"foocoin", 3}}), + NewInput(addr2, sdk.Coins{{"barcoin", 3}, {"foocoin", 2}}), + } + + outputs := []Output{ + NewOutput(addr, sdk.Coins{{"barcoin", 1}}), + NewOutput(addr3, sdk.Coins{{"barcoin", 2}, {"foocoin", 5}}), + } + coinKeeper.InputOutputCoins(ctx, inputs, outputs) + assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 21}, {"foocoin", 4}})) + assert.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"barcoin", 7}, {"foocoin", 6}})) + assert.True(t, coinKeeper.GetCoins(ctx, addr3).IsEqual(sdk.Coins{{"barcoin", 2}, {"foocoin", 5}})) + +} + +func TestSendKeeper(t *testing.T) { + ms, authKey := setupMultiStore() + + // wire registration while we're at it ... TODO + var _ = oldwire.RegisterInterface( + struct{ sdk.Account }{}, + oldwire.ConcreteType{&auth.BaseAccount{}, 0x1}, + ) + + ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + accountMapper := auth.NewAccountMapper(authKey, &auth.BaseAccount{}) + coinKeeper := NewCoinKeeper(accountMapper) + sendKeeper := NewSendKeeper(accountMapper) + + addr := sdk.Address([]byte("addr1")) + addr2 := sdk.Address([]byte("addr2")) + addr3 := sdk.Address([]byte("addr3")) + acc := accountMapper.NewAccountWithAddress(ctx, addr) + + // Test GetCoins/SetCoins + accountMapper.SetAccount(ctx, acc) + assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{})) + + coinKeeper.SetCoins(ctx, addr, sdk.Coins{{"foocoin", 10}}) + assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) + + // Test HasCoins + assert.True(t, sendKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 10}})) + assert.True(t, sendKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 5}})) + assert.False(t, sendKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 15}})) + assert.False(t, sendKeeper.HasCoins(ctx, addr, sdk.Coins{{"barcoin", 5}})) + + coinKeeper.SetCoins(ctx, addr, sdk.Coins{{"foocoin", 15}}) + + // Test SendCoins + sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"foocoin", 5}}) + assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) + assert.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"foocoin", 5}})) + + err2 := sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"foocoin", 50}}) + assert.Implements(t, (*sdk.Error)(nil), err2) + assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) + assert.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"foocoin", 5}})) + + coinKeeper.AddCoins(ctx, addr, sdk.Coins{{"barcoin", 30}}) + sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"barcoin", 10}, {"foocoin", 5}}) + assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 20}, {"foocoin", 5}})) + assert.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"barcoin", 10}, {"foocoin", 10}})) + + // Test InputOutputCoins + input1 := NewInput(addr2, sdk.Coins{{"foocoin", 2}}) + output1 := NewOutput(addr, sdk.Coins{{"foocoin", 2}}) + sendKeeper.InputOutputCoins(ctx, []Input{input1}, []Output{output1}) + assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 20}, {"foocoin", 7}})) + assert.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"barcoin", 10}, {"foocoin", 8}})) + + inputs := []Input{ + NewInput(addr, sdk.Coins{{"foocoin", 3}}), + NewInput(addr2, sdk.Coins{{"barcoin", 3}, {"foocoin", 2}}), + } + + outputs := []Output{ + NewOutput(addr, sdk.Coins{{"barcoin", 1}}), + NewOutput(addr3, sdk.Coins{{"barcoin", 2}, {"foocoin", 5}}), + } + sendKeeper.InputOutputCoins(ctx, inputs, outputs) + assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 21}, {"foocoin", 4}})) + assert.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"barcoin", 7}, {"foocoin", 6}})) + assert.True(t, sendKeeper.GetCoins(ctx, addr3).IsEqual(sdk.Coins{{"barcoin", 2}, {"foocoin", 5}})) + +} + +func TestViewKeeper(t *testing.T) { + ms, authKey := setupMultiStore() + + // wire registration while we're at it ... TODO + var _ = oldwire.RegisterInterface( + struct{ sdk.Account }{}, + oldwire.ConcreteType{&auth.BaseAccount{}, 0x1}, + ) + + ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + accountMapper := auth.NewAccountMapper(authKey, &auth.BaseAccount{}) + coinKeeper := NewCoinKeeper(accountMapper) + viewKeeper := NewViewKeeper(accountMapper) + + addr := sdk.Address([]byte("addr1")) + acc := accountMapper.NewAccountWithAddress(ctx, addr) + + // Test GetCoins/SetCoins + accountMapper.SetAccount(ctx, acc) + assert.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{})) + + coinKeeper.SetCoins(ctx, addr, sdk.Coins{{"foocoin", 10}}) + assert.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) + + // Test HasCoins + assert.True(t, viewKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 10}})) + assert.True(t, viewKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 5}})) + assert.False(t, viewKeeper.HasCoins(ctx, addr, sdk.Coins{{"foocoin", 15}})) + assert.False(t, viewKeeper.HasCoins(ctx, addr, sdk.Coins{{"barcoin", 5}})) +} From fcc164fab1a620afd372b1562ec225e413396dc8 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 17 Apr 2018 17:07:55 +0200 Subject: [PATCH 003/176] rebase and switch test to amino --- x/bank/keeper_test.go | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/x/bank/keeper_test.go b/x/bank/keeper_test.go index 0f5ce128f..1e160d472 100644 --- a/x/bank/keeper_test.go +++ b/x/bank/keeper_test.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" - oldwire "github.com/tendermint/go-wire" + wire "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" ) @@ -27,14 +27,11 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { func TestCoinKeeper(t *testing.T) { ms, authKey := setupMultiStore() - // wire registration while we're at it ... TODO - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&auth.BaseAccount{}, 0x1}, - ) + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - accountMapper := auth.NewAccountMapper(authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := NewCoinKeeper(accountMapper) addr := sdk.Address([]byte("addr1")) @@ -116,14 +113,11 @@ func TestCoinKeeper(t *testing.T) { func TestSendKeeper(t *testing.T) { ms, authKey := setupMultiStore() - // wire registration while we're at it ... TODO - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&auth.BaseAccount{}, 0x1}, - ) + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - accountMapper := auth.NewAccountMapper(authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := NewCoinKeeper(accountMapper) sendKeeper := NewSendKeeper(accountMapper) @@ -188,14 +182,11 @@ func TestSendKeeper(t *testing.T) { func TestViewKeeper(t *testing.T) { ms, authKey := setupMultiStore() - // wire registration while we're at it ... TODO - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&auth.BaseAccount{}, 0x1}, - ) + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - accountMapper := auth.NewAccountMapper(authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := NewCoinKeeper(accountMapper) viewKeeper := NewViewKeeper(accountMapper) From d2013ec2a09c71e2ff8bfe3c6ea1fa961593617e Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 17 Apr 2018 21:08:32 +0200 Subject: [PATCH 004/176] added state change revert comment --- x/bank/keeper.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/bank/keeper.go b/x/bank/keeper.go index 4c20f962d..a5fabdbb0 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -54,6 +54,7 @@ func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.C } // SendCoins moves coins from one account to another +// NOTE: Make sure to revert state changes from tx on error func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { _, err := subtractCoins(ctx, am, fromAddr, amt) if err != nil { @@ -69,6 +70,7 @@ func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAd } // InputOutputCoins handles a list of inputs and outputs +// NOTE: Make sure to revert state changes from tx on error func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, outputs []Output) sdk.Error { for _, in := range inputs { _, err := subtractCoins(ctx, am, in.Address, in.Coins) From f8e44b5b00d62eba5eaded6bcd1272422b46e581 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 18 Apr 2018 04:16:21 +0200 Subject: [PATCH 005/176] Error codespacing (#809) * Initial codespacing layout (ref #766) * Add codespace to Router (ref #766) * Implement Codespacer and update modules * Default codespaces, testcases * Update error formatting, codespacer tests * Add RegisterOrPanic testcase * Update CHANGELOG --- CHANGELOG.md | 1 + Gopkg.lock | 9 +- baseapp/baseapp.go | 34 +++-- client/lcd/lcd_test.go | 8 +- examples/basecoin/app/app.go | 6 +- examples/basecoin/app/app_test.go | 12 +- examples/democoin/app/app.go | 10 +- examples/democoin/app/app_test.go | 18 +-- examples/democoin/x/cool/errors.go | 6 +- examples/democoin/x/cool/handler.go | 2 +- examples/democoin/x/cool/keeper.go | 6 +- examples/democoin/x/pow/errors.go | 34 +++-- examples/democoin/x/pow/handler_test.go | 2 +- examples/democoin/x/pow/keeper.go | 19 +-- examples/democoin/x/pow/keeper_test.go | 2 +- examples/democoin/x/pow/types.go | 6 +- store/rootmultistore_test.go | 12 +- types/codespacer.go | 35 +++++ types/codespacer_test.go | 47 ++++++ types/errors.go | 191 +++++++++++++----------- types/errors_test.go | 9 +- types/rational.go | 8 +- types/result.go | 2 +- x/auth/ante_test.go | 4 +- x/bank/errors.go | 22 +-- x/bank/msgs.go | 6 +- x/ibc/errors.go | 14 +- x/ibc/handler.go | 2 +- x/ibc/ibc_test.go | 2 +- x/ibc/mapper.go | 12 +- x/ibc/types.go | 2 +- x/simplestake/errors.go | 22 +-- x/simplestake/handler.go | 4 +- x/simplestake/keeper.go | 22 +-- x/simplestake/keeper_test.go | 8 +- x/simplestake/msgs.go | 2 +- x/stake/errors.go | 82 +++++----- x/stake/handler.go | 24 +-- x/stake/keeper.go | 6 +- x/stake/msg.go | 28 ++-- x/stake/test_common.go | 2 +- 41 files changed, 438 insertions(+), 305 deletions(-) create mode 100644 types/codespacer.go create mode 100644 types/codespacer_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 1612f083f..873824c48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ BREAKING CHANGES * Remove go-wire, use go-amino * [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface * [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores +* All module keepers now require a codespace, see basecoin or democoin for usage BUG FIXES diff --git a/Gopkg.lock b/Gopkg.lock index eb2a1c8ca..6d225e261 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -342,7 +342,7 @@ "types/priv_validator", "version" ] - revision = "d0beaba7e8a5652506a34b5fab299cc2dc274c02" + revision = "a2930cd7233f04f5a651020669289296545e70dc" version = "v0.19.0" [[projects]] @@ -384,6 +384,7 @@ name = "golang.org/x/net" packages = [ "context", + "http/httpguts", "http2", "http2/hpack", "idna", @@ -391,13 +392,13 @@ "lex/httplex", "trace" ] - revision = "61147c48b25b599e5b561d2e9c4f3e1ef489ca41" + revision = "8d16fa6dc9a85c1cd3ed24ad08ff21cf94f10888" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "3b87a42e500a6dc65dae1a55d0b641295971163e" + revision = "b126b21c05a91c856b027c16779c12e3bf236954" [[projects]] name = "golang.org/x/text" @@ -424,7 +425,7 @@ branch = "master" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] - revision = "51d0944304c3cbce4afe9e5247e21100037bff78" + revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200" [[projects]] name = "google.golang.org/grpc" diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 884528876..115748ca5 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -24,11 +24,12 @@ var dbHeaderKey = []byte("header") // The ABCI application type BaseApp struct { // initialized on creation - Logger log.Logger - name string // application name from abci.Info - db dbm.DB // common DB backend - cms sdk.CommitMultiStore // Main (uncached) state - router Router // handle any kind of message + Logger log.Logger + name string // application name from abci.Info + db dbm.DB // common DB backend + cms sdk.CommitMultiStore // Main (uncached) state + router Router // handle any kind of message + codespacer *sdk.Codespacer // handle module codespacing // must be set txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx @@ -56,13 +57,18 @@ var _ abci.Application = (*BaseApp)(nil) // Create and name new BaseApp // NOTE: The db is used to store the version number for now. func NewBaseApp(name string, logger log.Logger, db dbm.DB) *BaseApp { - return &BaseApp{ - Logger: logger, - name: name, - db: db, - cms: store.NewCommitMultiStore(db), - router: NewRouter(), + app := &BaseApp{ + Logger: logger, + name: name, + db: db, + cms: store.NewCommitMultiStore(db), + router: NewRouter(), + codespacer: sdk.NewCodespacer(), } + // Register the undefined & root codespaces, which should not be used by any modules + app.codespacer.RegisterOrPanic(sdk.CodespaceUndefined) + app.codespacer.RegisterOrPanic(sdk.CodespaceRoot) + return app } // BaseApp Name @@ -70,6 +76,11 @@ func (app *BaseApp) Name() string { return app.name } +// Register the next available codespace through the baseapp's codespacer, starting from a default +func (app *BaseApp) RegisterCodespace(codespace sdk.CodespaceType) sdk.CodespaceType { + return app.codespacer.RegisterNext(codespace) +} + // Mount a store to the provided key in the BaseApp multistore func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) { for _, key := range keys { @@ -355,6 +366,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk // Validate the Msg. err := msg.ValidateBasic() if err != nil { + err = err.WithDefaultCodespace(sdk.CodespaceRoot) return err.Result() } diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 0e7ce7b7b..e84ff8e9b 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -80,7 +80,7 @@ func TestKeys(t *testing.T) { jsonStr = []byte(fmt.Sprintf(`{"name":"%s", "password":"%s", "seed": "%s"}`, newName, newPassword, newSeed)) res, body = request(t, port, "POST", "/keys", jsonStr) - assert.Equal(t, http.StatusOK, res.StatusCode, body) + require.Equal(t, http.StatusOK, res.StatusCode, body) addr := body assert.Len(t, addr, 40, "Returned address has wrong format", addr) @@ -311,7 +311,11 @@ func TestTxs(t *testing.T) { // strt TM and the LCD in process, listening on their respective sockets func startTMAndLCD() (*nm.Node, net.Listener, error) { - viper.Set(cli.HomeFlag, os.TempDir()) + dir, err := ioutil.TempDir("", "lcd_test") + if err != nil { + return nil, nil, err + } + viper.Set(cli.HomeFlag, dir) kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( if err != nil { return nil, nil, err diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index ae60e8a73..bb3ef05ac 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -65,8 +65,8 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // Add handlers. coinKeeper := bank.NewCoinKeeper(app.accountMapper) - ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) - stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper) + ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) + stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). @@ -123,7 +123,7 @@ func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { // are registered by MakeTxCodec in bank.RegisterAmino. err := app.cdc.UnmarshalBinary(txBytes, &tx) if err != nil { - return nil, sdk.ErrTxDecode("").TraceCause(err, "") + return nil, sdk.ErrTxDecode("").Trace(err.Error()) } return tx, nil } diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index ead49adc2..bc1735dde 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -166,7 +166,7 @@ func TestSortGenesis(t *testing.T) { // Unsorted coins means invalid err := sendMsg5.ValidateBasic() - require.Equal(t, sdk.CodeInvalidCoins, err.ABCICode(), err.ABCILog()) + require.Equal(t, sdk.CodeInvalidCoins, err.Code(), err.ABCILog()) // Sort coins, should be valid sendMsg5.Inputs[0].Coins.Sort() @@ -243,7 +243,7 @@ func TestSendMsgWithAccounts(t *testing.T) { tx.Signatures[0].Sequence = 1 res := bapp.Deliver(tx) - assert.Equal(t, sdk.CodeUnauthorized, res.Code, res.Log) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) // resigning the tx with the bumped sequence should work SignCheckDeliver(t, bapp, sendMsg1, []int64{1}, true, priv1) @@ -437,18 +437,18 @@ func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq []int64, // Run a Check res := bapp.Check(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) } // Simulate a Block bapp.BeginBlock(abci.RequestBeginBlock{}) res = bapp.Deliver(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) } bapp.EndBlock(abci.RequestEndBlock{}) //bapp.Commit() diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 151241d14..4e5e4e22f 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -70,10 +70,10 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { // Add handlers. coinKeeper := bank.NewCoinKeeper(app.accountMapper) - coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper) - powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewPowConfig("pow", int64(1)), coinKeeper) - ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) - stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper) + coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper, app.RegisterCodespace(cool.DefaultCodespace)) + powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewPowConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) + ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) + stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). AddRoute("cool", cool.NewHandler(coolKeeper)). @@ -136,7 +136,7 @@ func (app *DemocoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { // are registered by MakeTxCodec in bank.RegisterWire. err := app.cdc.UnmarshalBinary(txBytes, &tx) if err != nil { - return nil, sdk.ErrTxDecode("").TraceCause(err, "") + return nil, sdk.ErrTxDecode("").Trace(err.Error()) } return tx, nil } diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index ca4e2509e..f17e2a9b0 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -202,12 +202,12 @@ func TestSendMsgWithAccounts(t *testing.T) { // Run a Check res := bapp.Check(tx) - assert.Equal(t, sdk.CodeOK, res.Code, res.Log) + assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) // Simulate a Block bapp.BeginBlock(abci.RequestBeginBlock{}) res = bapp.Deliver(tx) - assert.Equal(t, sdk.CodeOK, res.Code, res.Log) + assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) // Check balances ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) @@ -218,19 +218,19 @@ func TestSendMsgWithAccounts(t *testing.T) { // Delivering again should cause replay error res = bapp.Deliver(tx) - assert.Equal(t, sdk.CodeInvalidSequence, res.Code, res.Log) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeInvalidSequence), sdk.ABCICodeType(res.Code), res.Log) // bumping the txnonce number without resigning should be an auth error tx.Signatures[0].Sequence = 1 res = bapp.Deliver(tx) - assert.Equal(t, sdk.CodeUnauthorized, res.Code, res.Log) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), sdk.ABCICodeType(res.Code), res.Log) // resigning the tx with the bumped sequence should work sequences = []int64{1} sig = priv1.Sign(sdk.StdSignBytes(chainID, sequences, fee, tx.Msg)) tx.Signatures[0].Signature = sig res = bapp.Deliver(tx) - assert.Equal(t, sdk.CodeOK, res.Code, res.Log) + assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } func TestMineMsg(t *testing.T) { @@ -403,18 +403,18 @@ func SignCheckDeliver(t *testing.T, bapp *DemocoinApp, msg sdk.Msg, seq int64, e // Run a Check res := bapp.Check(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) } // Simulate a Block bapp.BeginBlock(abci.RequestBeginBlock{}) res = bapp.Deliver(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) } bapp.EndBlock(abci.RequestEndBlock{}) //bapp.Commit() diff --git a/examples/democoin/x/cool/errors.go b/examples/democoin/x/cool/errors.go index 5db3efc39..4c28f94ba 100644 --- a/examples/democoin/x/cool/errors.go +++ b/examples/democoin/x/cool/errors.go @@ -7,11 +7,13 @@ import ( ) const ( + DefaultCodespace sdk.CodespaceType = 6 + // Cool module reserves error 400-499 lawl CodeIncorrectCoolAnswer sdk.CodeType = 400 ) // ErrIncorrectCoolAnswer - Error returned upon an incorrect guess -func ErrIncorrectCoolAnswer(answer string) sdk.Error { - return sdk.NewError(CodeIncorrectCoolAnswer, fmt.Sprintf("Incorrect cool answer: %v", answer)) +func ErrIncorrectCoolAnswer(codespace sdk.CodespaceType, answer string) sdk.Error { + return sdk.NewError(codespace, CodeIncorrectCoolAnswer, fmt.Sprintf("Incorrect cool answer: %v", answer)) } diff --git a/examples/democoin/x/cool/handler.go b/examples/democoin/x/cool/handler.go index ce86ecd5b..e2b36b218 100644 --- a/examples/democoin/x/cool/handler.go +++ b/examples/democoin/x/cool/handler.go @@ -44,7 +44,7 @@ func handleQuizMsg(ctx sdk.Context, k Keeper, msg QuizMsg) sdk.Result { correct := k.CheckTrend(ctx, msg.CoolAnswer) if !correct { - return ErrIncorrectCoolAnswer(msg.CoolAnswer).Result() + return ErrIncorrectCoolAnswer(k.codespace, msg.CoolAnswer).Result() } if ctx.IsCheckTx() { diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index 0a4fc81e1..3b6c8e9ae 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -10,11 +10,13 @@ type Keeper struct { ck bank.CoinKeeper storeKey sdk.StoreKey // The (unexposed) key used to access the store from the Context. + + codespace sdk.CodespaceType } // NewKeeper - Returns the Keeper -func NewKeeper(key sdk.StoreKey, bankKeeper bank.CoinKeeper) Keeper { - return Keeper{bankKeeper, key} +func NewKeeper(key sdk.StoreKey, bankKeeper bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { + return Keeper{bankKeeper, key, codespace} } // Key to knowing the trend on the streets! diff --git a/examples/democoin/x/pow/errors.go b/examples/democoin/x/pow/errors.go index b44eb93d6..d387f9b9a 100644 --- a/examples/democoin/x/pow/errors.go +++ b/examples/democoin/x/pow/errors.go @@ -7,6 +7,8 @@ import ( type CodeType = sdk.CodeType const ( + DefaultCodespace sdk.CodespaceType = 5 + CodeInvalidDifficulty CodeType = 201 CodeNonexistentDifficulty CodeType = 202 CodeNonexistentReward CodeType = 203 @@ -40,32 +42,32 @@ func codeToDefaultMsg(code CodeType) string { } } -func ErrInvalidDifficulty(msg string) sdk.Error { - return newError(CodeInvalidDifficulty, msg) +func ErrInvalidDifficulty(codespace sdk.CodespaceType, msg string) sdk.Error { + return newError(codespace, CodeInvalidDifficulty, msg) } -func ErrNonexistentDifficulty() sdk.Error { - return newError(CodeNonexistentDifficulty, "") +func ErrNonexistentDifficulty(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeNonexistentDifficulty, "") } -func ErrNonexistentReward() sdk.Error { - return newError(CodeNonexistentReward, "") +func ErrNonexistentReward(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeNonexistentReward, "") } -func ErrNonexistentCount() sdk.Error { - return newError(CodeNonexistentCount, "") +func ErrNonexistentCount(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeNonexistentCount, "") } -func ErrInvalidProof(msg string) sdk.Error { - return newError(CodeInvalidProof, msg) +func ErrInvalidProof(codespace sdk.CodespaceType, msg string) sdk.Error { + return newError(codespace, CodeInvalidProof, msg) } -func ErrNotBelowTarget(msg string) sdk.Error { - return newError(CodeNotBelowTarget, msg) +func ErrNotBelowTarget(codespace sdk.CodespaceType, msg string) sdk.Error { + return newError(codespace, CodeNotBelowTarget, msg) } -func ErrInvalidCount(msg string) sdk.Error { - return newError(CodeInvalidCount, msg) +func ErrInvalidCount(codespace sdk.CodespaceType, msg string) sdk.Error { + return newError(codespace, CodeInvalidCount, msg) } func msgOrDefaultMsg(msg string, code CodeType) string { @@ -76,7 +78,7 @@ func msgOrDefaultMsg(msg string, code CodeType) string { } } -func newError(code CodeType, msg string) sdk.Error { +func newError(codespace sdk.CodespaceType, code CodeType, msg string) sdk.Error { msg = msgOrDefaultMsg(msg, code) - return sdk.NewError(code, msg) + return sdk.NewError(codespace, code, msg) } diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index a05932780..4b1a571f7 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -22,7 +22,7 @@ func TestPowHandler(t *testing.T) { ctx := sdk.NewContext(ms, abci.Header{}, false, nil) config := NewPowConfig("pow", int64(1)) ck := bank.NewCoinKeeper(am) - keeper := NewKeeper(capKey, config, ck) + keeper := NewKeeper(capKey, config, ck, DefaultCodespace) handler := keeper.Handler diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 73558632c..70453d6d6 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -21,17 +21,18 @@ type PowGenesis struct { } type Keeper struct { - key sdk.StoreKey - config PowConfig - ck bank.CoinKeeper + key sdk.StoreKey + config PowConfig + ck bank.CoinKeeper + codespace sdk.CodespaceType } func NewPowConfig(denomination string, reward int64) PowConfig { return PowConfig{denomination, reward} } -func NewKeeper(key sdk.StoreKey, config PowConfig, ck bank.CoinKeeper) Keeper { - return Keeper{key, config, ck} +func NewKeeper(key sdk.StoreKey, config PowConfig, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { + return Keeper{key, config, ck, codespace} } func (pk Keeper) InitGenesis(ctx sdk.Context, genesis PowGenesis) error { @@ -78,24 +79,24 @@ func (pk Keeper) CheckValid(ctx sdk.Context, difficulty uint64, count uint64) (u lastDifficulty, err := pk.GetLastDifficulty(ctx) if err != nil { - return 0, 0, ErrNonexistentDifficulty() + return 0, 0, ErrNonexistentDifficulty(pk.codespace) } newDifficulty := lastDifficulty + 1 lastCount, err := pk.GetLastCount(ctx) if err != nil { - return 0, 0, ErrNonexistentCount() + return 0, 0, ErrNonexistentCount(pk.codespace) } newCount := lastCount + 1 if count != newCount { - return 0, 0, ErrInvalidCount(fmt.Sprintf("invalid count: was %d, should have been %d", count, newCount)) + return 0, 0, ErrInvalidCount(pk.codespace, fmt.Sprintf("invalid count: was %d, should have been %d", count, newCount)) } if difficulty != newDifficulty { - return 0, 0, ErrInvalidDifficulty(fmt.Sprintf("invalid difficulty: was %d, should have been %d", difficulty, newDifficulty)) + return 0, 0, ErrInvalidDifficulty(pk.codespace, fmt.Sprintf("invalid difficulty: was %d, should have been %d", difficulty, newDifficulty)) } return newDifficulty, newCount, nil diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index cb3492a86..d0b60fa17 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -35,7 +35,7 @@ func TestPowKeeperGetSet(t *testing.T) { ctx := sdk.NewContext(ms, abci.Header{}, false, nil) config := NewPowConfig("pow", int64(1)) ck := bank.NewCoinKeeper(am) - keeper := NewKeeper(capKey, config, ck) + keeper := NewKeeper(capKey, config, ck, DefaultCodespace) err := keeper.InitGenesis(ctx, PowGenesis{uint64(1), uint64(0)}) assert.Nil(t, err) diff --git a/examples/democoin/x/pow/types.go b/examples/democoin/x/pow/types.go index ea368c306..69d56e4f1 100644 --- a/examples/democoin/x/pow/types.go +++ b/examples/democoin/x/pow/types.go @@ -52,7 +52,7 @@ func (msg MineMsg) ValidateBasic() sdk.Error { hex.Encode(hashHex, hash) hashHex = hashHex[:16] if !bytes.Equal(hashHex, msg.Proof) { - return ErrInvalidProof(fmt.Sprintf("hashHex: %s, proof: %s", hashHex, msg.Proof)) + return ErrInvalidProof(DefaultCodespace, fmt.Sprintf("hashHex: %s, proof: %s", hashHex, msg.Proof)) } // check proof below difficulty @@ -60,10 +60,10 @@ func (msg MineMsg) ValidateBasic() sdk.Error { target := math.MaxUint64 / msg.Difficulty hashUint, err := strconv.ParseUint(string(msg.Proof), 16, 64) if err != nil { - return ErrInvalidProof(fmt.Sprintf("proof: %s", msg.Proof)) + return ErrInvalidProof(DefaultCodespace, fmt.Sprintf("proof: %s", msg.Proof)) } if hashUint >= target { - return ErrNotBelowTarget(fmt.Sprintf("hashuint: %d, target: %d", hashUint, target)) + return ErrNotBelowTarget(DefaultCodespace, fmt.Sprintf("hashuint: %d, target: %d", hashUint, target)) } return nil diff --git a/store/rootmultistore_test.go b/store/rootmultistore_test.go index 3796bd477..f4164f0b5 100644 --- a/store/rootmultistore_test.go +++ b/store/rootmultistore_test.go @@ -128,34 +128,34 @@ func TestMultiStoreQuery(t *testing.T) { // Test bad path. query := abci.RequestQuery{Path: "/key", Data: k, Height: ver} qres := multi.Query(query) - assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnknownRequest), sdk.ABCICodeType(qres.Code)) query.Path = "h897fy32890rf63296r92" qres = multi.Query(query) - assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnknownRequest), sdk.ABCICodeType(qres.Code)) // Test invalid store name. query.Path = "/garbage/key" qres = multi.Query(query) - assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnknownRequest), sdk.ABCICodeType(qres.Code)) // Test valid query with data. query.Path = "/store1/key" qres = multi.Query(query) - assert.Equal(t, uint32(sdk.CodeOK), qres.Code) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeOK), sdk.ABCICodeType(qres.Code)) assert.Equal(t, v, qres.Value) // Test valid but empty query. query.Path = "/store2/key" query.Prove = true qres = multi.Query(query) - assert.Equal(t, uint32(sdk.CodeOK), qres.Code) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeOK), sdk.ABCICodeType(qres.Code)) assert.Nil(t, qres.Value) // Test store2 data. query.Data = k2 qres = multi.Query(query) - assert.Equal(t, uint32(sdk.CodeOK), qres.Code) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeOK), sdk.ABCICodeType(qres.Code)) assert.Equal(t, v2, qres.Value) } diff --git a/types/codespacer.go b/types/codespacer.go new file mode 100644 index 000000000..92025c1a6 --- /dev/null +++ b/types/codespacer.go @@ -0,0 +1,35 @@ +package types + +// Codespacer is a simple struct to track reserved codespaces +type Codespacer struct { + reserved map[CodespaceType]bool +} + +// NewCodespacer generates a new Codespacer with the starting codespace +func NewCodespacer() *Codespacer { + return &Codespacer{ + reserved: make(map[CodespaceType]bool), + } +} + +// RegisterNext reserves and returns the next available codespace, starting from a default, and panics if the maximum codespace is reached +func (c *Codespacer) RegisterNext(codespace CodespaceType) CodespaceType { + for { + if !c.reserved[codespace] { + c.reserved[codespace] = true + return codespace + } + codespace++ + if codespace == MaximumCodespace { + panic("Maximum codespace reached!") + } + } +} + +// RegisterOrPanic reserved a codespace or panics if it is unavailable +func (c *Codespacer) RegisterOrPanic(codespace CodespaceType) { + if c.reserved[codespace] { + panic("Cannot register codespace, already reserved") + } + c.reserved[codespace] = true +} diff --git a/types/codespacer_test.go b/types/codespacer_test.go new file mode 100644 index 000000000..7052aa92a --- /dev/null +++ b/types/codespacer_test.go @@ -0,0 +1,47 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestRegisterNext(t *testing.T) { + codespacer := NewCodespacer() + // unregistered, allow + code1 := codespacer.RegisterNext(CodespaceType(2)) + require.Equal(t, code1, CodespaceType(2)) + // registered, pick next + code2 := codespacer.RegisterNext(CodespaceType(2)) + require.Equal(t, code2, CodespaceType(3)) + // pick next + code3 := codespacer.RegisterNext(CodespaceType(2)) + require.Equal(t, code3, CodespaceType(4)) + // skip 1 + code4 := codespacer.RegisterNext(CodespaceType(6)) + require.Equal(t, code4, CodespaceType(6)) + code5 := codespacer.RegisterNext(CodespaceType(2)) + require.Equal(t, code5, CodespaceType(5)) + code6 := codespacer.RegisterNext(CodespaceType(2)) + require.Equal(t, code6, CodespaceType(7)) + // panic on maximum + defer func() { + r := recover() + require.NotNil(t, r, "Did not panic on maximum codespace") + }() + codespacer.RegisterNext(MaximumCodespace - 1) + codespacer.RegisterNext(MaximumCodespace - 1) +} + +func TestRegisterOrPanic(t *testing.T) { + codespacer := NewCodespacer() + // unregistered, allow + code1 := codespacer.RegisterNext(CodespaceType(2)) + require.Equal(t, code1, CodespaceType(2)) + // panic on duplicate + defer func() { + r := recover() + require.NotNil(t, r, "Did not panic on duplicate codespace") + }() + codespacer.RegisterOrPanic(CodespaceType(2)) +} diff --git a/types/errors.go b/types/errors.go index 4874c4362..c2fe726a2 100644 --- a/types/errors.go +++ b/types/errors.go @@ -2,25 +2,42 @@ package types import ( "fmt" - "runtime" + + cmn "github.com/tendermint/tmlibs/common" abci "github.com/tendermint/abci/types" ) -// ABCI Response Code -type CodeType uint32 +// ABCICodeType - combined codetype / codespace +type ABCICodeType uint32 -// is everything okay? -func (code CodeType) IsOK() bool { - if code == CodeOK { +// CodeType - code identifier within codespace +type CodeType uint16 + +// CodespaceType - codespace identifier +type CodespaceType uint16 + +// IsOK - is everything okay? +func (code ABCICodeType) IsOK() bool { + if code == ABCICodeOK { return true } return false } -// ABCI Response Codes -// Base SDK reserves 0 - 99. +func ToABCICode(space CodespaceType, code CodeType) ABCICodeType { + // TODO: Make Tendermint more aware of codespaces. + if space == CodespaceRoot && code == CodeOK { + return ABCICodeOK + } + return ABCICodeType((uint32(space) << 16) | uint32(code)) +} + const ( + // ABCI error codes + ABCICodeOK ABCICodeType = 0 + + // Base error codes CodeOK CodeType = 0 CodeInternal CodeType = 1 CodeTxDecode CodeType = 2 @@ -34,7 +51,14 @@ const ( CodeInsufficientCoins CodeType = 10 CodeInvalidCoins CodeType = 11 - CodeGenesisParse CodeType = 0xdead // TODO: remove ? // why remove? + // CodespaceRoot is a codespace for error codes in this file only. + // Notice that 0 is an "unset" codespace, which can be overridden with + // Error.WithDefaultCodespace(). + CodespaceUndefined CodespaceType = 0 + CodespaceRoot CodespaceType = 1 + + // Maximum reservable codespace (2^16 - 1) + MaximumCodespace CodespaceType = 65535 ) // NOTE: Don't stringer this, we'll put better messages in later. @@ -44,8 +68,6 @@ func CodeToDefaultMsg(code CodeType) string { return "Internal error" case CodeTxDecode: return "Tx parse error" - case CodeGenesisParse: - return "Genesis parse error" case CodeInvalidSequence: return "Invalid sequence" case CodeUnauthorized: @@ -75,40 +97,37 @@ func CodeToDefaultMsg(code CodeType) string { // nolint func ErrInternal(msg string) Error { - return newError(CodeInternal, msg) + return newErrorWithRootCodespace(CodeInternal, msg) } func ErrTxDecode(msg string) Error { - return newError(CodeTxDecode, msg) -} -func ErrGenesisParse(msg string) Error { - return newError(CodeGenesisParse, msg) + return newErrorWithRootCodespace(CodeTxDecode, msg) } func ErrInvalidSequence(msg string) Error { - return newError(CodeInvalidSequence, msg) + return newErrorWithRootCodespace(CodeInvalidSequence, msg) } func ErrUnauthorized(msg string) Error { - return newError(CodeUnauthorized, msg) + return newErrorWithRootCodespace(CodeUnauthorized, msg) } func ErrInsufficientFunds(msg string) Error { - return newError(CodeInsufficientFunds, msg) + return newErrorWithRootCodespace(CodeInsufficientFunds, msg) } func ErrUnknownRequest(msg string) Error { - return newError(CodeUnknownRequest, msg) + return newErrorWithRootCodespace(CodeUnknownRequest, msg) } func ErrInvalidAddress(msg string) Error { - return newError(CodeInvalidAddress, msg) + return newErrorWithRootCodespace(CodeInvalidAddress, msg) } func ErrUnknownAddress(msg string) Error { - return newError(CodeUnknownAddress, msg) + return newErrorWithRootCodespace(CodeUnknownAddress, msg) } func ErrInvalidPubKey(msg string) Error { - return newError(CodeInvalidPubKey, msg) + return newErrorWithRootCodespace(CodeInvalidPubKey, msg) } func ErrInsufficientCoins(msg string) Error { - return newError(CodeInsufficientCoins, msg) + return newErrorWithRootCodespace(CodeInsufficientCoins, msg) } func ErrInvalidCoins(msg string) Error { - return newError(CodeInvalidCoins, msg) + return newErrorWithRootCodespace(CodeInvalidCoins, msg) } //---------------------------------------- @@ -117,104 +136,98 @@ func ErrInvalidCoins(msg string) Error { // sdk Error type type Error interface { Error() string - ABCICode() CodeType + Code() CodeType + Codespace() CodespaceType ABCILog() string + ABCICode() ABCICodeType + WithDefaultCodespace(codespace CodespaceType) Error Trace(msg string) Error - TraceCause(cause error, msg string) Error - Cause() error + T() interface{} Result() Result QueryResult() abci.ResponseQuery } -func NewError(code CodeType, msg string) Error { - return newError(code, msg) +// NewError - create an error +func NewError(codespace CodespaceType, code CodeType, msg string) Error { + return newError(codespace, code, msg) } -type traceItem struct { - msg string - filename string - lineno int +func newErrorWithRootCodespace(code CodeType, msg string) *sdkError { + return newError(CodespaceRoot, code, msg) } -func (ti traceItem) String() string { - return fmt.Sprintf("%v:%v %v", ti.filename, ti.lineno, ti.msg) -} - -type sdkError struct { - code CodeType - msg string - cause error - traces []traceItem -} - -func newError(code CodeType, msg string) *sdkError { - // TODO capture stacktrace if ENV is set. +func newError(codespace CodespaceType, code CodeType, msg string) *sdkError { if msg == "" { msg = CodeToDefaultMsg(code) } return &sdkError{ - code: code, - msg: msg, - cause: nil, - traces: nil, + codespace: codespace, + code: code, + err: cmn.NewErrorWithT(code, msg), } } +type sdkError struct { + codespace CodespaceType + code CodeType + err cmn.Error +} + // Implements ABCIError. func (err *sdkError) Error() string { - return fmt.Sprintf("Error{%d:%s,%v,%v}", err.code, err.msg, err.cause, len(err.traces)) + return fmt.Sprintf("Error{%d:%d,%#v}", err.codespace, err.code, err.err) } // Implements ABCIError. -func (err *sdkError) ABCICode() CodeType { +func (err *sdkError) ABCICode() ABCICodeType { + return ToABCICode(err.codespace, err.code) +} + +// Implements Error. +func (err *sdkError) Codespace() CodespaceType { + return err.codespace +} + +// Implements Error. +func (err *sdkError) Code() CodeType { return err.code } // Implements ABCIError. func (err *sdkError) ABCILog() string { - traceLog := "" - for _, ti := range err.traces { - traceLog += ti.String() + "\n" - } - return fmt.Sprintf("msg: %v\ntrace:\n%v", - err.msg, - traceLog, - ) + return fmt.Sprintf(`=== ABCI Log === +Codespace: %v +Code: %v +ABCICode: %v +Error: %#v +=== /ABCI Log === +`, err.codespace, err.code, err.ABCICode(), err.err) } // Add tracing information with msg. func (err *sdkError) Trace(msg string) Error { - return err.doTrace(msg, 2) -} - -// Add tracing information with cause and msg. -func (err *sdkError) TraceCause(cause error, msg string) Error { - err.cause = cause - return err.doTrace(msg, 2) -} - -func (err *sdkError) doTrace(msg string, n int) Error { - _, fn, line, ok := runtime.Caller(n) - if !ok { - if fn == "" { - fn = "" - } - if line <= 0 { - line = -1 - } + return &sdkError{ + codespace: err.codespace, + code: err.code, + err: err.err.Trace(msg), } - // Include file & line number & msg. - // Do not include the whole stack trace. - err.traces = append(err.traces, traceItem{ - filename: fn, - lineno: line, - msg: msg, - }) - return err } -func (err *sdkError) Cause() error { - return err.cause +// Implements Error. +func (err *sdkError) WithDefaultCodespace(cs CodespaceType) Error { + codespace := err.codespace + if codespace == CodespaceUndefined { + codespace = cs + } + return &sdkError{ + codespace: codespace, + code: err.code, + err: err.err, + } +} + +func (err *sdkError) T() interface{} { + return err.err.T() } func (err *sdkError) Result() Result { diff --git a/types/errors_test.go b/types/errors_test.go index 939cced7c..798eafefc 100644 --- a/types/errors_test.go +++ b/types/errors_test.go @@ -16,7 +16,6 @@ var codeTypes = []CodeType{ CodeUnknownRequest, CodeUnknownAddress, CodeInvalidPubKey, - CodeGenesisParse, } type errFn func(msg string) Error @@ -30,14 +29,12 @@ var errFns = []errFn{ ErrUnknownRequest, ErrUnknownAddress, ErrInvalidPubKey, - ErrGenesisParse, } func TestCodeType(t *testing.T) { - assert.True(t, CodeOK.IsOK()) + assert.True(t, ABCICodeOK.IsOK()) for _, c := range codeTypes { - assert.False(t, c.IsOK()) msg := CodeToDefaultMsg(c) assert.False(t, strings.HasPrefix(msg, "Unknown code")) } @@ -47,7 +44,7 @@ func TestErrFn(t *testing.T) { for i, errFn := range errFns { err := errFn("") codeType := codeTypes[i] - assert.Equal(t, err.ABCICode(), codeType) - assert.Equal(t, err.Result().Code, codeType) + assert.Equal(t, err.Code(), codeType) + assert.Equal(t, err.Result().Code, ToABCICode(CodespaceRoot, codeType)) } } diff --git a/types/rational.go b/types/rational.go index 8ebee7140..9199520b2 100644 --- a/types/rational.go +++ b/types/rational.go @@ -97,23 +97,23 @@ func NewRatFromDecimal(decimalStr string) (f Rat, err Error) { switch len(str) { case 1: if len(str[0]) == 0 { - return f, NewError(CodeUnknownRequest, "not a decimal string") + return f, ErrUnknownRequest("not a decimal string") } numStr = str[0] case 2: if len(str[0]) == 0 || len(str[1]) == 0 { - return f, NewError(CodeUnknownRequest, "not a decimal string") + return f, ErrUnknownRequest("not a decimal string") } numStr = str[0] + str[1] len := int64(len(str[1])) denom = new(big.Int).Exp(big.NewInt(10), big.NewInt(len), nil).Int64() default: - return f, NewError(CodeUnknownRequest, "not a decimal string") + return f, ErrUnknownRequest("not a decimal string") } num, errConv := strconv.Atoi(numStr) if errConv != nil { - return f, NewError(CodeUnknownRequest, errConv.Error()) + return f, ErrUnknownRequest(errConv.Error()) } if neg { diff --git a/types/result.go b/types/result.go index 412a9778d..7b0c1a593 100644 --- a/types/result.go +++ b/types/result.go @@ -9,7 +9,7 @@ import ( type Result struct { // Code is the response code, is stored back on the chain. - Code CodeType + Code ABCICodeType // Data is any data returned from the app. Data []byte diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index 58633ff9a..3baf8ee71 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -40,7 +40,7 @@ func privAndAddr() (crypto.PrivKey, sdk.Address) { func checkValidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx) { _, result, abort := anteHandler(ctx, tx) assert.False(t, abort) - assert.Equal(t, sdk.CodeOK, result.Code) + assert.Equal(t, sdk.ABCICodeOK, result.Code) assert.True(t, result.IsOK()) } @@ -48,7 +48,7 @@ func checkValidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, code sdk.CodeType) { _, result, abort := anteHandler(ctx, tx) assert.True(t, abort) - assert.Equal(t, code, result.Code) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, code), result.Code) } func newTestTx(ctx sdk.Context, msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, fee sdk.StdFee) sdk.Tx { diff --git a/x/bank/errors.go b/x/bank/errors.go index 4223dd30b..d7c7e9748 100644 --- a/x/bank/errors.go +++ b/x/bank/errors.go @@ -7,6 +7,8 @@ import ( // Coin errors reserve 100 ~ 199. const ( + DefaultCodespace sdk.CodespaceType = 2 + CodeInvalidInput sdk.CodeType = 101 CodeInvalidOutput sdk.CodeType = 102 ) @@ -26,20 +28,20 @@ func codeToDefaultMsg(code sdk.CodeType) string { //---------------------------------------- // Error constructors -func ErrInvalidInput(msg string) sdk.Error { - return newError(CodeInvalidInput, msg) +func ErrInvalidInput(codespace sdk.CodespaceType, msg string) sdk.Error { + return newError(codespace, CodeInvalidInput, msg) } -func ErrNoInputs() sdk.Error { - return newError(CodeInvalidInput, "") +func ErrNoInputs(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidInput, "") } -func ErrInvalidOutput(msg string) sdk.Error { - return newError(CodeInvalidOutput, msg) +func ErrInvalidOutput(codespace sdk.CodespaceType, msg string) sdk.Error { + return newError(codespace, CodeInvalidOutput, msg) } -func ErrNoOutputs() sdk.Error { - return newError(CodeInvalidOutput, "") +func ErrNoOutputs(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidOutput, "") } //---------------------------------------- @@ -51,7 +53,7 @@ func msgOrDefaultMsg(msg string, code sdk.CodeType) string { return codeToDefaultMsg(code) } -func newError(code sdk.CodeType, msg string) sdk.Error { +func newError(codespace sdk.CodespaceType, code sdk.CodeType, msg string) sdk.Error { msg = msgOrDefaultMsg(msg, code) - return sdk.NewError(code, msg) + return sdk.NewError(codespace, code, msg) } diff --git a/x/bank/msgs.go b/x/bank/msgs.go index 15822eed7..c0f2ad46a 100644 --- a/x/bank/msgs.go +++ b/x/bank/msgs.go @@ -28,10 +28,10 @@ func (msg SendMsg) ValidateBasic() sdk.Error { // this just makes sure all the inputs and outputs are properly formatted, // not that they actually have the money inside if len(msg.Inputs) == 0 { - return ErrNoInputs().Trace("") + return ErrNoInputs(DefaultCodespace).Trace("") } if len(msg.Outputs) == 0 { - return ErrNoOutputs().Trace("") + return ErrNoOutputs(DefaultCodespace).Trace("") } // make sure all inputs and outputs are individually valid var totalIn, totalOut sdk.Coins @@ -102,7 +102,7 @@ func (msg IssueMsg) Type() string { return "bank" } // TODO: "bank/issue" func (msg IssueMsg) ValidateBasic() sdk.Error { // XXX if len(msg.Outputs) == 0 { - return ErrNoOutputs().Trace("") + return ErrNoOutputs(DefaultCodespace).Trace("") } for _, out := range msg.Outputs { if err := out.ValidateBasic(); err != nil { diff --git a/x/ibc/errors.go b/x/ibc/errors.go index f3c988b59..3c52bed7b 100644 --- a/x/ibc/errors.go +++ b/x/ibc/errors.go @@ -5,6 +5,8 @@ import ( ) const ( + DefaultCodespace sdk.CodespaceType = 3 + // IBC errors reserve 200 - 299. CodeInvalidSequence sdk.CodeType = 200 CodeIdenticalChains sdk.CodeType = 201 @@ -22,20 +24,20 @@ func codeToDefaultMsg(code sdk.CodeType) string { } } -func ErrInvalidSequence() sdk.Error { - return newError(CodeInvalidSequence, "") +func ErrInvalidSequence(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidSequence, "") } -func ErrIdenticalChains() sdk.Error { - return newError(CodeIdenticalChains, "") +func ErrIdenticalChains(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeIdenticalChains, "") } // ------------------------- // Helpers -func newError(code sdk.CodeType, msg string) sdk.Error { +func newError(codespace sdk.CodespaceType, code sdk.CodeType, msg string) sdk.Error { msg = msgOrDefaultMsg(msg, code) - return sdk.NewError(code, msg) + return sdk.NewError(codespace, code, msg) } func msgOrDefaultMsg(msg string, code sdk.CodeType) string { diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 2922f6dab..dcd00359f 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -44,7 +44,7 @@ func handleIBCReceiveMsg(ctx sdk.Context, ibcm IBCMapper, ck bank.CoinKeeper, ms seq := ibcm.GetIngressSequence(ctx, packet.SrcChain) if msg.Sequence != seq { - return ErrInvalidSequence().Result() + return ErrInvalidSequence(ibcm.codespace).Result() } _, err := ck.AddCoins(ctx, packet.DestAddr, packet.Coins) diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index db172a5ca..1fc724e54 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -73,7 +73,7 @@ func TestIBC(t *testing.T) { assert.Nil(t, err) assert.Equal(t, mycoins, coins) - ibcm := NewIBCMapper(cdc, key) + ibcm := NewIBCMapper(cdc, key, DefaultCodespace) h := NewHandler(ibcm, ck) packet := IBCPacket{ SrcAddr: src, diff --git a/x/ibc/mapper.go b/x/ibc/mapper.go index 1e8f9de25..d3ecc779d 100644 --- a/x/ibc/mapper.go +++ b/x/ibc/mapper.go @@ -8,17 +8,19 @@ import ( ) type IBCMapper struct { - key sdk.StoreKey - cdc *wire.Codec + key sdk.StoreKey + cdc *wire.Codec + codespace sdk.CodespaceType } // XXX: The IBCMapper should not take a CoinKeeper. Rather have the CoinKeeper // take an IBCMapper. -func NewIBCMapper(cdc *wire.Codec, key sdk.StoreKey) IBCMapper { +func NewIBCMapper(cdc *wire.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) IBCMapper { // XXX: How are these codecs supposed to work? return IBCMapper{ - key: key, - cdc: cdc, + key: key, + cdc: cdc, + codespace: codespace, } } diff --git a/x/ibc/types.go b/x/ibc/types.go index 495d2a900..2bf2c4267 100644 --- a/x/ibc/types.go +++ b/x/ibc/types.go @@ -33,7 +33,7 @@ func NewIBCPacket(srcAddr sdk.Address, destAddr sdk.Address, coins sdk.Coins, func (ibcp IBCPacket) ValidateBasic() sdk.Error { if ibcp.SrcChain == ibcp.DestChain { - return ErrIdenticalChains().Trace("") + return ErrIdenticalChains(DefaultCodespace).Trace("") } if !ibcp.Coins.IsValid() { return sdk.ErrInvalidCoins("") diff --git a/x/simplestake/errors.go b/x/simplestake/errors.go index f69ffcbeb..0fb7eebce 100644 --- a/x/simplestake/errors.go +++ b/x/simplestake/errors.go @@ -5,6 +5,8 @@ import ( ) const ( + DefaultCodespace sdk.CodespaceType = 4 + // simplestake errors reserve 300 - 399. CodeEmptyValidator sdk.CodeType = 300 CodeInvalidUnbond sdk.CodeType = 301 @@ -12,25 +14,25 @@ const ( CodeIncorrectStakingToken sdk.CodeType = 303 ) -func ErrIncorrectStakingToken() sdk.Error { - return newError(CodeIncorrectStakingToken, "") +func ErrIncorrectStakingToken(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeIncorrectStakingToken, "") } -func ErrEmptyValidator() sdk.Error { - return newError(CodeEmptyValidator, "") +func ErrEmptyValidator(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeEmptyValidator, "") } -func ErrInvalidUnbond() sdk.Error { - return newError(CodeInvalidUnbond, "") +func ErrInvalidUnbond(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidUnbond, "") } -func ErrEmptyStake() sdk.Error { - return newError(CodeEmptyStake, "") +func ErrEmptyStake(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeEmptyStake, "") } // ----------------------------- // Helpers -func newError(code sdk.CodeType, msg string) sdk.Error { - return sdk.NewError(code, msg) +func newError(codespace sdk.CodespaceType, code sdk.CodeType, msg string) sdk.Error { + return sdk.NewError(codespace, code, msg) } diff --git a/x/simplestake/handler.go b/x/simplestake/handler.go index 31e5a7d24..894da04b2 100644 --- a/x/simplestake/handler.go +++ b/x/simplestake/handler.go @@ -32,7 +32,7 @@ func handleBondMsg(ctx sdk.Context, k Keeper, msg BondMsg) sdk.Result { } return sdk.Result{ - Code: sdk.CodeOK, + Code: sdk.ABCICodeOK, ValidatorUpdates: abci.Validators{valSet}, } } @@ -49,7 +49,7 @@ func handleUnbondMsg(ctx sdk.Context, k Keeper, msg UnbondMsg) sdk.Result { } return sdk.Result{ - Code: sdk.CodeOK, + Code: sdk.ABCICodeOK, ValidatorUpdates: abci.Validators{valSet}, } } diff --git a/x/simplestake/keeper.go b/x/simplestake/keeper.go index 7dcdbc20f..934d0b5a0 100644 --- a/x/simplestake/keeper.go +++ b/x/simplestake/keeper.go @@ -15,17 +15,19 @@ const moduleName = "simplestake" type Keeper struct { ck bank.CoinKeeper - key sdk.StoreKey - cdc *wire.Codec + key sdk.StoreKey + cdc *wire.Codec + codespace sdk.CodespaceType } -func NewKeeper(key sdk.StoreKey, coinKeeper bank.CoinKeeper) Keeper { +func NewKeeper(key sdk.StoreKey, coinKeeper bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { cdc := wire.NewCodec() wire.RegisterCrypto(cdc) return Keeper{ - key: key, - cdc: cdc, - ck: coinKeeper, + key: key, + cdc: cdc, + ck: coinKeeper, + codespace: codespace, } } @@ -59,7 +61,7 @@ func (k Keeper) deleteBondInfo(ctx sdk.Context, addr sdk.Address) { func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) { if stake.Denom != stakingToken { - return 0, ErrIncorrectStakingToken() + return 0, ErrIncorrectStakingToken(k.codespace) } _, err := k.ck.SubtractCoins(ctx, addr, []sdk.Coin{stake}) @@ -84,7 +86,7 @@ func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, st func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) { bi := k.getBondInfo(ctx, addr) if bi.isEmpty() { - return nil, 0, ErrInvalidUnbond() + return nil, 0, ErrInvalidUnbond(k.codespace) } k.deleteBondInfo(ctx, addr) @@ -102,7 +104,7 @@ func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, func (k Keeper) bondWithoutCoins(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) { if stake.Denom != stakingToken { - return 0, ErrIncorrectStakingToken() + return 0, ErrIncorrectStakingToken(k.codespace) } bi := k.getBondInfo(ctx, addr) @@ -122,7 +124,7 @@ func (k Keeper) bondWithoutCoins(ctx sdk.Context, addr sdk.Address, pubKey crypt func (k Keeper) unbondWithoutCoins(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) { bi := k.getBondInfo(ctx, addr) if bi.isEmpty() { - return nil, 0, ErrInvalidUnbond() + return nil, 0, ErrInvalidUnbond(k.codespace) } k.deleteBondInfo(ctx, addr) diff --git a/x/simplestake/keeper_test.go b/x/simplestake/keeper_test.go index 7f9a120b9..833227968 100644 --- a/x/simplestake/keeper_test.go +++ b/x/simplestake/keeper_test.go @@ -33,7 +33,7 @@ func TestKeeperGetSet(t *testing.T) { ms, _, capKey := setupMultiStore() ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil)) + stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil), DefaultCodespace) addr := sdk.Address([]byte("some-address")) bi := stakeKeeper.getBondInfo(ctx, addr) @@ -63,13 +63,13 @@ func TestBonding(t *testing.T) { accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := bank.NewCoinKeeper(accountMapper) - stakeKeeper := NewKeeper(capKey, coinKeeper) + stakeKeeper := NewKeeper(capKey, coinKeeper, DefaultCodespace) addr := sdk.Address([]byte("some-address")) privKey := crypto.GenPrivKeyEd25519() pubKey := privKey.PubKey() _, _, err := stakeKeeper.unbondWithoutCoins(ctx, addr) - assert.Equal(t, err, ErrInvalidUnbond()) + assert.Equal(t, err, ErrInvalidUnbond(DefaultCodespace)) _, err = stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.Coin{"steak", 10}) assert.Nil(t, err) @@ -82,5 +82,5 @@ func TestBonding(t *testing.T) { assert.Equal(t, pubKey, pk) _, _, err = stakeKeeper.unbondWithoutCoins(ctx, addr) - assert.Equal(t, err, ErrInvalidUnbond()) + assert.Equal(t, err, ErrInvalidUnbond(DefaultCodespace)) } diff --git a/x/simplestake/msgs.go b/x/simplestake/msgs.go index 9f4133484..963bfae7b 100644 --- a/x/simplestake/msgs.go +++ b/x/simplestake/msgs.go @@ -31,7 +31,7 @@ func (msg BondMsg) Type() string { func (msg BondMsg) ValidateBasic() sdk.Error { if msg.Stake.IsZero() { - return ErrEmptyStake() + return ErrEmptyStake(DefaultCodespace) } if msg.PubKey == nil { diff --git a/x/stake/errors.go b/x/stake/errors.go index e5b3e0cb3..008d51bc9 100644 --- a/x/stake/errors.go +++ b/x/stake/errors.go @@ -10,6 +10,8 @@ import ( type CodeType = sdk.CodeType const ( + DefaultCodespace sdk.CodespaceType = 4 + // Gaia errors reserve 200 ~ 299. CodeInvalidValidator CodeType = 201 CodeInvalidCandidate CodeType = 202 @@ -45,62 +47,62 @@ func codeToDefaultMsg(code CodeType) string { //---------------------------------------- // Error constructors -func ErrNotEnoughBondShares(shares string) sdk.Error { - return newError(CodeInvalidBond, fmt.Sprintf("not enough shares only have %v", shares)) +func ErrNotEnoughBondShares(codespace sdk.CodespaceType, shares string) sdk.Error { + return newError(codespace, CodeInvalidBond, fmt.Sprintf("not enough shares only have %v", shares)) } -func ErrCandidateEmpty() sdk.Error { - return newError(CodeInvalidValidator, "Cannot bond to an empty candidate") +func ErrCandidateEmpty(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Cannot bond to an empty candidate") } -func ErrBadBondingDenom() sdk.Error { - return newError(CodeInvalidBond, "Invalid coin denomination") +func ErrBadBondingDenom(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidBond, "Invalid coin denomination") } -func ErrBadBondingAmount() sdk.Error { - return newError(CodeInvalidBond, "Amount must be > 0") +func ErrBadBondingAmount(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidBond, "Amount must be > 0") } -func ErrNoBondingAcct() sdk.Error { - return newError(CodeInvalidValidator, "No bond account for this (address, validator) pair") +func ErrNoBondingAcct(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "No bond account for this (address, validator) pair") } -func ErrCommissionNegative() sdk.Error { - return newError(CodeInvalidValidator, "Commission must be positive") +func ErrCommissionNegative(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Commission must be positive") } -func ErrCommissionHuge() sdk.Error { - return newError(CodeInvalidValidator, "Commission cannot be more than 100%") +func ErrCommissionHuge(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Commission cannot be more than 100%") } -func ErrBadValidatorAddr() sdk.Error { - return newError(CodeInvalidValidator, "Validator does not exist for that address") +func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address") } -func ErrBadCandidateAddr() sdk.Error { - return newError(CodeInvalidValidator, "Candidate does not exist for that address") +func ErrBadCandidateAddr(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Candidate does not exist for that address") } -func ErrBadDelegatorAddr() sdk.Error { - return newError(CodeInvalidValidator, "Delegator does not exist for that address") +func ErrBadDelegatorAddr(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Delegator does not exist for that address") } -func ErrCandidateExistsAddr() sdk.Error { - return newError(CodeInvalidValidator, "Candidate already exist, cannot re-declare candidacy") +func ErrCandidateExistsAddr(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Candidate already exist, cannot re-declare candidacy") } -func ErrCandidateRevoked() sdk.Error { - return newError(CodeInvalidValidator, "Candidacy for this address is currently revoked") +func ErrCandidateRevoked(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Candidacy for this address is currently revoked") } -func ErrMissingSignature() sdk.Error { - return newError(CodeInvalidValidator, "Missing signature") +func ErrMissingSignature(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Missing signature") } -func ErrBondNotNominated() sdk.Error { - return newError(CodeInvalidValidator, "Cannot bond to non-nominated account") +func ErrBondNotNominated(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Cannot bond to non-nominated account") } -func ErrNoCandidateForAddress() sdk.Error { - return newError(CodeInvalidValidator, "Validator does not exist for that address") +func ErrNoCandidateForAddress(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address") } -func ErrNoDelegatorForAddress() sdk.Error { - return newError(CodeInvalidValidator, "Delegator does not contain validator bond") +func ErrNoDelegatorForAddress(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Delegator does not contain validator bond") } -func ErrInsufficientFunds() sdk.Error { - return newError(CodeInvalidInput, "Insufficient bond shares") +func ErrInsufficientFunds(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidInput, "Insufficient bond shares") } -func ErrBadShares() sdk.Error { - return newError(CodeInvalidInput, "bad shares provided as input, must be MAX or decimal") +func ErrBadShares(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidInput, "bad shares provided as input, must be MAX or decimal") } -func ErrBadRemoveValidator() sdk.Error { - return newError(CodeInvalidValidator, "Error removing validator") +func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error { + return newError(codespace, CodeInvalidValidator, "Error removing validator") } //---------------------------------------- @@ -114,7 +116,7 @@ func msgOrDefaultMsg(msg string, code CodeType) string { return codeToDefaultMsg(code) } -func newError(code CodeType, msg string) sdk.Error { +func newError(codespace sdk.CodespaceType, code CodeType, msg string) sdk.Error { msg = msgOrDefaultMsg(msg, code) - return sdk.NewError(code, msg) + return sdk.NewError(codespace, code, msg) } diff --git a/x/stake/handler.go b/x/stake/handler.go index 2f351a608..5f80ecb37 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -57,10 +57,10 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe // check to see if the pubkey or sender has been registered before _, found := k.GetCandidate(ctx, msg.CandidateAddr) if found { - return ErrCandidateExistsAddr().Result() + return ErrCandidateExistsAddr(k.codespace).Result() } if msg.Bond.Denom != k.GetParams(ctx).BondDenom { - return ErrBadBondingDenom().Result() + return ErrBadBondingDenom(k.codespace).Result() } if ctx.IsCheckTx() { return sdk.Result{ @@ -85,7 +85,7 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk // candidate must already be registered candidate, found := k.GetCandidate(ctx, msg.CandidateAddr) if !found { - return ErrBadCandidateAddr().Result() + return ErrBadCandidateAddr(k.codespace).Result() } if ctx.IsCheckTx() { return sdk.Result{ @@ -93,7 +93,7 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk } } if candidate.Status == Unbonded { //candidate has been withdrawn - return ErrBondNotNominated().Result() + return ErrBondNotNominated(k.codespace).Result() } // XXX move to types @@ -111,13 +111,13 @@ func handleMsgDelegate(ctx sdk.Context, msg MsgDelegate, k Keeper) sdk.Result { candidate, found := k.GetCandidate(ctx, msg.CandidateAddr) if !found { - return ErrBadCandidateAddr().Result() + return ErrBadCandidateAddr(k.codespace).Result() } if msg.Bond.Denom != k.GetParams(ctx).BondDenom { - return ErrBadBondingDenom().Result() + return ErrBadBondingDenom(k.codespace).Result() } if candidate.Status == Revoked { - return ErrCandidateRevoked().Result() + return ErrCandidateRevoked(k.codespace).Result() } if ctx.IsCheckTx() { return sdk.Result{ @@ -165,10 +165,10 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { // check if bond has any shares in it unbond bond, found := k.getDelegatorBond(ctx, msg.DelegatorAddr, msg.CandidateAddr) if !found { - return ErrNoDelegatorForAddress().Result() + return ErrNoDelegatorForAddress(k.codespace).Result() } if !bond.Shares.GT(sdk.ZeroRat) { // bond shares < msg shares - return ErrInsufficientFunds().Result() + return ErrInsufficientFunds(k.codespace).Result() } // test getting rational number from decimal provided @@ -180,18 +180,18 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { // test that there are enough shares to unbond if msg.Shares == "MAX" { if !bond.Shares.GT(sdk.ZeroRat) { - return ErrNotEnoughBondShares(msg.Shares).Result() + return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result() } } else { if bond.Shares.LT(shares) { - return ErrNotEnoughBondShares(msg.Shares).Result() + return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result() } } // get candidate candidate, found := k.GetCandidate(ctx, msg.CandidateAddr) if !found { - return ErrNoCandidateForAddress().Result() + return ErrNoCandidateForAddress(k.codespace).Result() } if ctx.IsCheckTx() { diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 0f29b177b..ae3dfb7c7 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -19,13 +19,17 @@ type Keeper struct { // caches gs Pool params Params + + // codespace + codespace sdk.CodespaceType } -func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper) Keeper { +func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { keeper := Keeper{ storeKey: key, cdc: cdc, coinKeeper: ck, + codespace: codespace, } return keeper } diff --git a/x/stake/msg.go b/x/stake/msg.go index 28a2edf79..b5ba09b5a 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -60,18 +60,18 @@ func (msg MsgDeclareCandidacy) GetSignBytes() []byte { // quick validity check func (msg MsgDeclareCandidacy) ValidateBasic() sdk.Error { if msg.CandidateAddr == nil { - return ErrCandidateEmpty() + return ErrCandidateEmpty(DefaultCodespace) } if msg.Bond.Denom != StakingToken { - return ErrBadBondingDenom() + return ErrBadBondingDenom(DefaultCodespace) } if msg.Bond.Amount <= 0 { - return ErrBadBondingAmount() + return ErrBadBondingAmount(DefaultCodespace) // return sdk.ErrInvalidCoins(sdk.Coins{msg.Bond}.String()) } empty := Description{} if msg.Description == empty { - return newError(CodeInvalidInput, "description must be included") + return newError(DefaultCodespace, CodeInvalidInput, "description must be included") } return nil } @@ -111,11 +111,11 @@ func (msg MsgEditCandidacy) GetSignBytes() []byte { // quick validity check func (msg MsgEditCandidacy) ValidateBasic() sdk.Error { if msg.CandidateAddr == nil { - return ErrCandidateEmpty() + return ErrCandidateEmpty(DefaultCodespace) } empty := Description{} if msg.Description == empty { - return newError(CodeInvalidInput, "Transaction must include some information to modify") + return newError(DefaultCodespace, CodeInvalidInput, "Transaction must include some information to modify") } return nil } @@ -157,16 +157,16 @@ func (msg MsgDelegate) GetSignBytes() []byte { // quick validity check func (msg MsgDelegate) ValidateBasic() sdk.Error { if msg.DelegatorAddr == nil { - return ErrBadDelegatorAddr() + return ErrBadDelegatorAddr(DefaultCodespace) } if msg.CandidateAddr == nil { - return ErrBadCandidateAddr() + return ErrBadCandidateAddr(DefaultCodespace) } if msg.Bond.Denom != StakingToken { - return ErrBadBondingDenom() + return ErrBadBondingDenom(DefaultCodespace) } if msg.Bond.Amount <= 0 { - return ErrBadBondingAmount() + return ErrBadBondingAmount(DefaultCodespace) // return sdk.ErrInvalidCoins(sdk.Coins{msg.Bond}.String()) } return nil @@ -209,18 +209,18 @@ func (msg MsgUnbond) GetSignBytes() []byte { // quick validity check func (msg MsgUnbond) ValidateBasic() sdk.Error { if msg.DelegatorAddr == nil { - return ErrBadDelegatorAddr() + return ErrBadDelegatorAddr(DefaultCodespace) } if msg.CandidateAddr == nil { - return ErrBadCandidateAddr() + return ErrBadCandidateAddr(DefaultCodespace) } if msg.Shares != "MAX" { rat, err := sdk.NewRatFromDecimal(msg.Shares) if err != nil { - return ErrBadShares() + return ErrBadShares(DefaultCodespace) } if rat.IsZero() || rat.LT(sdk.ZeroRat) { - return ErrBadShares() + return ErrBadShares(DefaultCodespace) } } return nil diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 395a5bce0..6470abbc7 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -132,7 +132,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context &auth.BaseAccount{}, // prototype ).Seal() ck := bank.NewCoinKeeper(accountMapper) - keeper := NewKeeper(ctx, cdc, keyStake, ck) + keeper := NewKeeper(ctx, cdc, keyStake, ck, DefaultCodespace) keeper.setPool(ctx, initialPool()) keeper.setParams(ctx, defaultParams()) From f7437fd899edc54a4ec5e6d1a1467e69c21c493e Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 6 Apr 2018 14:35:54 -0400 Subject: [PATCH 006/176] connected stake cli --- examples/basecoin/app/app.go | 7 ++++--- examples/basecoin/app/app_test.go | 5 +++-- examples/basecoin/cmd/basecli/main.go | 21 +++++++++------------ x/stake/commands/query.go | 8 ++++---- x/stake/commands/tx.go | 4 ++-- x/stake/handler.go | 3 +-- x/stake/wire.go | 2 +- 7 files changed, 24 insertions(+), 26 deletions(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index bb3ef05ac..9ef48bfb5 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/simplestake" + "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" ) @@ -32,7 +33,7 @@ type BasecoinApp struct { capKeyMainStore *sdk.KVStoreKey capKeyAccountStore *sdk.KVStoreKey capKeyIBCStore *sdk.KVStoreKey - capKeyStakingStore *sdk.KVStoreKey + capKeyStakeStore *sdk.KVStoreKey // Manage getting and setting accounts accountMapper sdk.AccountMapper @@ -53,7 +54,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyAccountStore: sdk.NewKVStoreKey("acc"), capKeyIBCStore: sdk.NewKVStoreKey("ibc"), - capKeyStakingStore: sdk.NewKVStoreKey("stake"), + capKeyStakeStore: sdk.NewKVStoreKey("stake"), } // Define the accountMapper. @@ -70,7 +71,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). - AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) + AddRoute("stake", stake.NewHandler(stakeKeeper)) // Define the feeHandler. app.feeHandler = auth.BurnFeeHandler diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index bc1735dde..1f635f53f 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -143,7 +143,7 @@ func TestSortGenesis(t *testing.T) { // Note the order: the coins are unsorted! coinDenom1, coinDenom2 := "foocoin", "barcoin" - genState := fmt.Sprintf(`{ + str := `{ "accounts": [{ "address": "%s", "coins": [ @@ -157,7 +157,8 @@ func TestSortGenesis(t *testing.T) { } ] }] - }`, addr1.String(), coinDenom1, coinDenom2) + }` + genState := fmt.Sprintf(str, addr1.String(), coinDenom1, coinDenom2) // Initialize the chain vals := []abci.Validator{} diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 6271adcec..bab24f91b 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -17,7 +17,7 @@ import ( authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands" - simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/commands" + stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" @@ -52,23 +52,20 @@ func main() { rootCmd.AddCommand( client.GetCommands( authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)), + stakecmd.GetCmdQueryCandidates("stake", cdc), + stakecmd.GetCmdQueryCandidate("stake", cdc), + stakecmd.GetCmdQueryDelegatorBond("stake", cdc), + stakecmd.GetCmdQueryDelegatorBonds("stake", cdc), )...) rootCmd.AddCommand( client.PostCommands( bankcmd.SendTxCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( ibccmd.IBCTransferCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( ibccmd.IBCRelayCmd(cdc), - simplestakingcmd.BondTxCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( - simplestakingcmd.UnbondTxCmd(cdc), + stakecmd.GetCmdDeclareCandidacy(cdc), + stakecmd.GetCmdEditCandidacy(cdc), + stakecmd.GetCmdDelegate(cdc), + stakecmd.GetCmdUnbond(cdc), )...) // add proxy, version and key info diff --git a/x/stake/commands/query.go b/x/stake/commands/query.go index 8cbb877ce..38e16f333 100644 --- a/x/stake/commands/query.go +++ b/x/stake/commands/query.go @@ -38,7 +38,7 @@ func init() { } // create command to query for all candidates -func GetCmdQueryCandidates(cdc *wire.Codec, storeName string) *cobra.Command { +func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "candidates", Short: "Query for the set of validator-candidates pubkeys", @@ -74,7 +74,7 @@ func GetCmdQueryCandidates(cdc *wire.Codec, storeName string) *cobra.Command { } // get the command to query a candidate -func GetCmdQueryCandidate(cdc *wire.Codec, storeName string) *cobra.Command { +func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "candidate", Short: "Query a validator-candidate account", @@ -116,7 +116,7 @@ func GetCmdQueryCandidate(cdc *wire.Codec, storeName string) *cobra.Command { } // get the command to query a single delegator bond -func GetCmdQueryDelegatorBond(cdc *wire.Codec, storeName string) *cobra.Command { +func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "delegator-bond", Short: "Query a delegators bond based on address and candidate pubkey", @@ -165,7 +165,7 @@ func GetCmdQueryDelegatorBond(cdc *wire.Codec, storeName string) *cobra.Command } // get the command to query all the candidates bonded to a delegator -func GetCmdQueryDelegatorBonds(cdc *wire.Codec, storeName string) *cobra.Command { +func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "delegator-candidates", Short: "Query all delegators candidates' pubkeys based on address", diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index 5cc9747b6..679e59b15 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -20,8 +20,8 @@ import ( // nolint const ( - FlagAddressDelegator = "addressD" - FlagAddressCandidate = "addressC" + FlagAddressDelegator = "address-delegator" + FlagAddressCandidate = "address-candidate" FlagPubKey = "pubkey" FlagAmount = "amount" FlagShares = "shares" diff --git a/x/stake/handler.go b/x/stake/handler.go index 5f80ecb37..e1f624f10 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -4,7 +4,6 @@ import ( "bytes" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank" abci "github.com/tendermint/abci/types" ) @@ -18,7 +17,7 @@ const ( //_______________________________________________________________________ -func NewHandler(k Keeper, ck bank.CoinKeeper) sdk.Handler { +func NewHandler(k Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { // NOTE msg already has validate basic run switch msg := msg.(type) { diff --git a/x/stake/wire.go b/x/stake/wire.go index 4516f89f2..f444ce14e 100644 --- a/x/stake/wire.go +++ b/x/stake/wire.go @@ -4,7 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/wire" ) -// XXX complete +// TODO complete when go-amino is ported func RegisterWire(cdc *wire.Codec) { // TODO include option to always include prefix bytes. //cdc.RegisterConcrete(SendMsg{}, "cosmos-sdk/SendMsg", nil) From 179caa5768b1e35c25015f5b529c3729a104578a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 7 Apr 2018 01:12:00 -0400 Subject: [PATCH 007/176] refactor gaia with stake --- Makefile | 4 +- cmd/gaia/app/account.go | 32 ++ cmd/gaia/app/app.go | 158 ++++++++++ cmd/gaia/app/app_test.go | 432 ++++++++++++++++++++++++++ cmd/gaia/cmd/gaiacli/main.go | 79 +++++ cmd/{ => gaia/cmd}/gaiad/main.go | 25 +- examples/basecoin/app/app.go | 7 +- examples/basecoin/app/app_test.go | 8 +- examples/basecoin/cmd/basecli/main.go | 21 +- x/stake/handler.go | 37 --- 10 files changed, 744 insertions(+), 59 deletions(-) create mode 100644 cmd/gaia/app/account.go create mode 100644 cmd/gaia/app/app.go create mode 100644 cmd/gaia/app/app_test.go create mode 100644 cmd/gaia/cmd/gaiacli/main.go rename cmd/{ => gaia/cmd}/gaiad/main.go (60%) diff --git a/Makefile b/Makefile index b5177621a..4d21c61c5 100644 --- a/Makefile +++ b/Makefile @@ -36,8 +36,8 @@ else endif install: - go install $(BUILD_FLAGS) ./cmd/gaiad - go install $(BUILD_FLAGS) ./cmd/gaiacli + go install $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiad + go install $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiacli install_examples: go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecoind diff --git a/cmd/gaia/app/account.go b/cmd/gaia/app/account.go new file mode 100644 index 000000000..3d5673b87 --- /dev/null +++ b/cmd/gaia/app/account.go @@ -0,0 +1,32 @@ +package app + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" +) + +// State to Unmarshal +type GenesisState struct { + Accounts []GenesisAccount `json:"accounts"` +} + +// GenesisAccount doesn't need pubkey or sequence +type GenesisAccount struct { + Address sdk.Address `json:"address"` + Coins sdk.Coins `json:"coins"` +} + +func NewGenesisAccount(acc auth.BaseAccount) GenesisAccount { + return GenesisAccount{ + Address: acc.Address, + Coins: acc.Coins, + } +} + +// convert GenesisAccount to GaiaAccount +func (ga *GenesisAccount) ToAccount() (acc auth.BaseAccount) { + return auth.BaseAccount{ + Address: ga.Address, + Coins: ga.Coins.Sort(), + } +} diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go new file mode 100644 index 000000000..64b1619f8 --- /dev/null +++ b/cmd/gaia/app/app.go @@ -0,0 +1,158 @@ +package app + +import ( + "encoding/json" + + abci "github.com/tendermint/abci/types" + oldwire "github.com/tendermint/go-wire" + cmn "github.com/tendermint/tmlibs/common" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" + + bam "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/ibc" + "github.com/cosmos/cosmos-sdk/x/stake" +) + +const ( + appName = "GaiaApp" +) + +// Extended ABCI application +type GaiaApp struct { + *bam.BaseApp + cdc *wire.Codec + + // keys to access the substores + capKeyMainStore *sdk.KVStoreKey + capKeyAccountStore *sdk.KVStoreKey + capKeyIBCStore *sdk.KVStoreKey + capKeyStakeStore *sdk.KVStoreKey + + // Manage getting and setting accounts + accountMapper sdk.AccountMapper +} + +func NewGaiaApp(logger log.Logger, dbs map[string]dbm.DB) *GaiaApp { + // create your application object + var app = &GaiaApp{ + BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]), + cdc: MakeCodec(), + capKeyMainStore: sdk.NewKVStoreKey("main"), + capKeyAccountStore: sdk.NewKVStoreKey("acc"), + capKeyIBCStore: sdk.NewKVStoreKey("ibc"), + capKeyStakeStore: sdk.NewKVStoreKey("stake"), + } + + // define the accountMapper + app.accountMapper = auth.NewAccountMapperSealed( + app.capKeyMainStore, // target store + &auth.BaseAccount{}, // prototype + ) + + // add handlers + coinKeeper := bank.NewCoinKeeper(app.accountMapper) + ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) + stakeKeeper := stake.NewKeeper(app.cdc, app.capKeyStakeStore, coinKeeper) + app.Router(). + AddRoute("bank", bank.NewHandler(coinKeeper)). + AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). + AddRoute("stake", stake.NewHandler(stakeKeeper)) + + // initialize BaseApp + app.SetTxDecoder(app.txDecoder) + app.SetInitChainer(app.initChainer) + app.SetEndBlocker(stake.NewEndBlocker(stakeKeeper)) + app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) + app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) + app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"]) + app.MountStoreWithDB(app.capKeyStakeStore, sdk.StoreTypeIAVL, dbs["stake"]) + + // NOTE: Broken until #532 lands + //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) + err := app.LoadLatestVersion(app.capKeyMainStore) + if err != nil { + cmn.Exit(err.Error()) + } + + return app +} + +// custom tx codec +// TODO: use new go-wire +func MakeCodec() *wire.Codec { + const ( + msgTypeSend = 0x1 + msgTypeIssue = 0x2 + msgTypeIBCTransferMsg = 0x3 + msgTypeIBCReceiveMsg = 0x4 + msgDeclareCandidacy = 0x5 + msgEditCandidacy = 0x6 + msgDelegate = 0x7 + msgUnbond = 0x8 + ) + var _ = oldwire.RegisterInterface( + struct{ sdk.Msg }{}, + oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, + oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, + oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, + oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, + oldwire.ConcreteType{stake.MsgDeclareCandidacy{}, msgDeclareCandidacy}, + oldwire.ConcreteType{stake.MsgEditCandidacy{}, msgEditCandidacy}, + oldwire.ConcreteType{stake.MsgDelegate{}, msgDelegate}, + oldwire.ConcreteType{stake.MsgUnbond{}, msgUnbond}, + ) + + const accTypeApp = 0x1 + var _ = oldwire.RegisterInterface( + struct{ sdk.Account }{}, + oldwire.ConcreteType{&auth.BaseAccount{}, accTypeApp}, + ) + cdc := wire.NewCodec() + + // cdc.RegisterInterface((*sdk.Msg)(nil), nil) + // bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] + // crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] + // ibc.RegisterWire(cdc) // Register ibc.[IBCTransferMsg, IBCReceiveMsg] + return cdc +} + +// custom logic for transaction decoding +func (app *GaiaApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { + var tx = sdk.StdTx{} + + if len(txBytes) == 0 { + return nil, sdk.ErrTxDecode("txBytes are empty") + } + + // StdTx.Msg is an interface. The concrete types + // are registered by MakeTxCodec in bank.RegisterWire. + err := app.cdc.UnmarshalBinary(txBytes, &tx) + if err != nil { + return nil, sdk.ErrTxDecode("").TraceCause(err, "") + } + return tx, nil +} + +// custom logic for gaia initialization +func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + stateJSON := req.AppStateBytes + + genesisState := new(GenesisState) + err := json.Unmarshal(stateJSON, genesisState) + if err != nil { + panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 + // return sdk.ErrGenesisParse("").TraceCause(err, "") + } + + for _, gacc := range genesisState.Accounts { + acc := gacc.ToAccount() + app.accountMapper.SetAccount(ctx, &acc) + } + return abci.ResponseInitChain{} +} diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go new file mode 100644 index 000000000..a440e7e38 --- /dev/null +++ b/cmd/gaia/app/app_test.go @@ -0,0 +1,432 @@ +package app + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/ibc" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" +) + +// Construct some global addrs and txs for tests. +var ( + chainID = "" // TODO + + accName = "foobart" + + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + priv2 = crypto.GenPrivKeyEd25519() + addr2 = priv2.PubKey().Address() + addr3 = crypto.GenPrivKeyEd25519().PubKey().Address() + priv4 = crypto.GenPrivKeyEd25519() + addr4 = priv4.PubKey().Address() + coins = sdk.Coins{{"foocoin", 10}} + halfCoins = sdk.Coins{{"foocoin", 5}} + manyCoins = sdk.Coins{{"foocoin", 1}, {"barcoin", 1}} + fee = sdk.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 0, + } + + sendMsg1 = bank.SendMsg{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, + } + + sendMsg2 = bank.SendMsg{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{ + bank.NewOutput(addr2, halfCoins), + bank.NewOutput(addr3, halfCoins), + }, + } + + sendMsg3 = bank.SendMsg{ + Inputs: []bank.Input{ + bank.NewInput(addr1, coins), + bank.NewInput(addr4, coins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr2, coins), + bank.NewOutput(addr3, coins), + }, + } + + sendMsg4 = bank.SendMsg{ + Inputs: []bank.Input{ + bank.NewInput(addr2, coins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr1, coins), + }, + } + + sendMsg5 = bank.SendMsg{ + Inputs: []bank.Input{ + bank.NewInput(addr1, manyCoins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr2, manyCoins), + }, + } +) + +func loggerAndDBs() (log.Logger, map[string]dbm.DB) { + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") + dbs := map[string]dbm.DB{ + "main": dbm.NewMemDB(), + "acc": dbm.NewMemDB(), + "ibc": dbm.NewMemDB(), + "staking": dbm.NewMemDB(), + } + return logger, dbs +} + +func newGaiaApp() *GaiaApp { + logger, dbs := loggerAndDBs() + return NewGaiaApp(logger, dbs) +} + +func setGenesisAccounts(gapp *GaiaApp, accs ...auth.BaseAccount) error { + genaccs := make([]GenesisAccount, len(accs)) + for i, acc := range accs { + genaccs[i] = NewGenesisAccount(acc) + } + + genesisState := GenesisState{ + Accounts: genaccs, + } + + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + if err != nil { + return err + } + + // Initialize the chain + vals := []abci.Validator{} + gapp.InitChain(abci.RequestInitChain{vals, stateBytes}) + gapp.Commit() + + return nil +} + +//_______________________________________________________________________ + +func TestMsgs(t *testing.T) { + gapp := newGaiaApp() + + msgs := []struct { + msg sdk.Msg + }{ + {sendMsg1}, + } + + for i, m := range msgs { + // Run a CheckDeliver + SignCheckDeliver(t, gapp, m.msg, []int64{int64(i)}, false, priv1) + } +} + +func TestSortGenesis(t *testing.T) { + logger, dbs := loggerAndDBs() + gapp := NewGaiaApp(logger, dbs) + + // Note the order: the coins are unsorted! + coinDenom1, coinDenom2 := "foocoin", "barcoin" + + str := `{ + "accounts": [{ + "address": "%s", + "coins": [ + { + "denom": "%s", + "amount": 10 + }, + { + "denom": "%s", + "amount": 20 + } + ] + }] + }` + genState := fmt.Sprintf(str, addr1.String(), coinDenom1, coinDenom2) + + // Initialize the chain + vals := []abci.Validator{} + gapp.InitChain(abci.RequestInitChain{vals, []byte(genState)}) + gapp.Commit() + + // Unsorted coins means invalid + err := sendMsg5.ValidateBasic() + require.Equal(t, sdk.CodeInvalidCoins, err.ABCICode(), err.ABCILog()) + + // Sort coins, should be valid + sendMsg5.Inputs[0].Coins.Sort() + sendMsg5.Outputs[0].Coins.Sort() + err = sendMsg5.ValidateBasic() + require.Nil(t, err) + + // Ensure we can send + SignCheckDeliver(t, gapp, sendMsg5, []int64{0}, true, priv1) +} + +func TestGenesis(t *testing.T) { + logger, dbs := loggerAndDBs() + gapp := NewGaiaApp(logger, dbs) + + // Construct some genesis bytes to reflect GaiaAccount + pk := crypto.GenPrivKeyEd25519().PubKey() + addr := pk.Address() + coins, err := sdk.ParseCoins("77foocoin,99barcoin") + require.Nil(t, err) + baseAcc := auth.BaseAccount{ + Address: addr, + Coins: coins, + } + + err = setGenesisAccounts(gapp, baseAcc) + assert.Nil(t, err) + + // A checkTx context + ctx := gapp.BaseApp.NewContext(true, abci.Header{}) + res1 := gapp.accountMapper.GetAccount(ctx, baseAcc.Address) + assert.Equal(t, baseAcc, res1) + + // reload app and ensure the account is still there + gapp = NewGaiaApp(logger, dbs) + ctx = gapp.BaseApp.NewContext(true, abci.Header{}) + res1 = gapp.accountMapper.GetAccount(ctx, baseAcc.Address) + assert.Equal(t, baseAcc, res1) +} + +func TestSendMsgWithAccounts(t *testing.T) { + gapp := newGaiaApp() + + // Construct some genesis bytes to reflect GaiaAccount + // Give 77 foocoin to the first key + coins, err := sdk.ParseCoins("77foocoin") + require.Nil(t, err) + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + + // Construct genesis state + err = setGenesisAccounts(gapp, baseAcc) + assert.Nil(t, err) + // A checkTx context (true) + ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) + res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, baseAcc, res1.(*auth.BaseAccount)) + + // Run a CheckDeliver + SignCheckDeliver(t, gapp, sendMsg1, []int64{0}, true, priv1) + + // Check balances + CheckBalance(t, gapp, addr1, "67foocoin") + CheckBalance(t, gapp, addr2, "10foocoin") + + // Delivering again should cause replay error + SignCheckDeliver(t, gapp, sendMsg1, []int64{0}, false, priv1) + + // bumping the txnonce number without resigning should be an auth error + tx := genTx(sendMsg1, []int64{0}, priv1) + tx.Signatures[0].Sequence = 1 + res := gapp.Deliver(tx) + + assert.Equal(t, sdk.CodeUnauthorized, res.Code, res.Log) + + // resigning the tx with the bumped sequence should work + SignCheckDeliver(t, gapp, sendMsg1, []int64{1}, true, priv1) +} + +func TestSendMsgMultipleOut(t *testing.T) { + gapp := newGaiaApp() + + genCoins, err := sdk.ParseCoins("42foocoin") + require.Nil(t, err) + + acc1 := auth.BaseAccount{ + Address: addr1, + Coins: genCoins, + } + + acc2 := auth.BaseAccount{ + Address: addr2, + Coins: genCoins, + } + + err = setGenesisAccounts(gapp, acc1, acc2) + assert.Nil(t, err) + + // Simulate a Block + SignCheckDeliver(t, gapp, sendMsg2, []int64{0}, true, priv1) + + // Check balances + CheckBalance(t, gapp, addr1, "32foocoin") + CheckBalance(t, gapp, addr2, "47foocoin") + CheckBalance(t, gapp, addr3, "5foocoin") +} + +func TestSengMsgMultipleInOut(t *testing.T) { + gapp := newGaiaApp() + + genCoins, err := sdk.ParseCoins("42foocoin") + require.Nil(t, err) + + acc1 := auth.BaseAccount{ + Address: addr1, + Coins: genCoins, + } + + acc2 := auth.BaseAccount{ + Address: addr2, + Coins: genCoins, + } + + acc4 := auth.BaseAccount{ + Address: addr4, + Coins: genCoins, + } + + err = setGenesisAccounts(gapp, acc1, acc2, acc4) + assert.Nil(t, err) + + // CheckDeliver + SignCheckDeliver(t, gapp, sendMsg3, []int64{0, 0}, true, priv1, priv4) + + // Check balances + CheckBalance(t, gapp, addr1, "32foocoin") + CheckBalance(t, gapp, addr4, "32foocoin") + CheckBalance(t, gapp, addr2, "52foocoin") + CheckBalance(t, gapp, addr3, "10foocoin") +} + +func TestSendMsgDependent(t *testing.T) { + gapp := newGaiaApp() + + genCoins, err := sdk.ParseCoins("42foocoin") + require.Nil(t, err) + + acc1 := auth.BaseAccount{ + Address: addr1, + Coins: genCoins, + } + + err = setGenesisAccounts(gapp, acc1) + assert.Nil(t, err) + + // CheckDeliver + SignCheckDeliver(t, gapp, sendMsg1, []int64{0}, true, priv1) + + // Check balances + CheckBalance(t, gapp, addr1, "32foocoin") + CheckBalance(t, gapp, addr2, "10foocoin") + + // Simulate a Block + SignCheckDeliver(t, gapp, sendMsg4, []int64{0}, true, priv2) + + // Check balances + CheckBalance(t, gapp, addr1, "42foocoin") +} + +func TestIBCMsgs(t *testing.T) { + gapp := newGaiaApp() + + sourceChain := "source-chain" + destChain := "dest-chain" + + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + + err := setGenesisAccounts(gapp, baseAcc) + assert.Nil(t, err) + // A checkTx context (true) + ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) + res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, baseAcc, res1) + + packet := ibc.IBCPacket{ + SrcAddr: addr1, + DestAddr: addr1, + Coins: coins, + SrcChain: sourceChain, + DestChain: destChain, + } + + transferMsg := ibc.IBCTransferMsg{ + IBCPacket: packet, + } + + receiveMsg := ibc.IBCReceiveMsg{ + IBCPacket: packet, + Relayer: addr1, + Sequence: 0, + } + + SignCheckDeliver(t, gapp, transferMsg, []int64{0}, true, priv1) + CheckBalance(t, gapp, addr1, "") + SignCheckDeliver(t, gapp, transferMsg, []int64{1}, false, priv1) + SignCheckDeliver(t, gapp, receiveMsg, []int64{2}, true, priv1) + CheckBalance(t, gapp, addr1, "10foocoin") + SignCheckDeliver(t, gapp, receiveMsg, []int64{3}, false, priv1) +} + +func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.StdTx { + sigs := make([]sdk.StdSignature, len(priv)) + for i, p := range priv { + sigs[i] = sdk.StdSignature{ + PubKey: p.PubKey(), + Signature: p.Sign(sdk.StdSignBytes(chainID, seq, fee, msg)), + Sequence: seq[i], + } + } + + return sdk.NewStdTx(msg, fee, sigs) + +} + +func SignCheckDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { + + // Sign the tx + tx := genTx(msg, seq, priv...) + // Run a Check + res := gapp.Check(tx) + if expPass { + require.Equal(t, sdk.CodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + } + + // Simulate a Block + gapp.BeginBlock(abci.RequestBeginBlock{}) + res = gapp.Deliver(tx) + if expPass { + require.Equal(t, sdk.CodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + } + gapp.EndBlock(abci.RequestEndBlock{}) + //gapp.Commit() +} + +func CheckBalance(t *testing.T, gapp *GaiaApp, addr sdk.Address, balExpected string) { + ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{}) + res2 := gapp.accountMapper.GetAccount(ctxDeliver, addr) + assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) +} diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go new file mode 100644 index 000000000..c5c3190c3 --- /dev/null +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "os" + + "github.com/spf13/cobra" + + "github.com/tendermint/tmlibs/cli" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/client/lcd" + "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/client/tx" + + "github.com/cosmos/cosmos-sdk/version" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" + ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands" + stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands" + + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" +) + +// rootCmd is the entry point for this binary +var ( + rootCmd = &cobra.Command{ + Use: "gaiacli", + Short: "Gaia light-client", + } +) + +func main() { + cobra.EnableCommandSorting = false + cdc := app.MakeCodec() + + // TODO: setup keybase, viper object, etc. to be passed into + // the below functions and eliminate global vars, like we do + // with the cdc + + // add standard rpc, and tx commands + rpc.AddCommands(rootCmd) + rootCmd.AddCommand(client.LineBreak) + tx.AddCommands(rootCmd, cdc) + rootCmd.AddCommand(client.LineBreak) + + // add query/post commands (custom to binary) + rootCmd.AddCommand( + client.GetCommands( + authcmd.GetAccountCmd("main", cdc, authcmd.GetAccountDecoder(cdc)), + stakecmd.GetCmdQueryCandidates("stake", cdc), + stakecmd.GetCmdQueryCandidate("stake", cdc), + stakecmd.GetCmdQueryDelegatorBond("stake", cdc), + stakecmd.GetCmdQueryDelegatorBonds("stake", cdc), + )...) + rootCmd.AddCommand( + client.PostCommands( + bankcmd.SendTxCmd(cdc), + ibccmd.IBCTransferCmd(cdc), + ibccmd.IBCRelayCmd(cdc), + stakecmd.GetCmdDeclareCandidacy(cdc), + stakecmd.GetCmdEditCandidacy(cdc), + stakecmd.GetCmdDelegate(cdc), + stakecmd.GetCmdUnbond(cdc), + )...) + + // add proxy, version and key info + rootCmd.AddCommand( + client.LineBreak, + lcd.ServeCommand(cdc), + keys.Commands(), + client.LineBreak, + version.VersionCmd, + ) + + // prepare and add flags + executor := cli.PrepareMainCmd(rootCmd, "GA", os.ExpandEnv("$HOME/.gaiacli")) + executor.Execute() +} diff --git a/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go similarity index 60% rename from cmd/gaiad/main.go rename to cmd/gaia/cmd/gaiad/main.go index 9ebf196db..f966c446a 100644 --- a/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -11,7 +11,7 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/examples/basecoin/app" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" ) @@ -25,7 +25,6 @@ var ( } ) -// TODO: distinguish from basecoin func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { dataDir := filepath.Join(rootDir, "data") db, err := dbm.NewGoLevelDB("gaia", dataDir) @@ -33,6 +32,25 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { return nil, err } bapp := app.NewBasecoinApp(logger, db) + //dbAcc, err := dbm.NewGoLevelDB("gaia-acc", dataDir) + //if err != nil { + //return nil, err + //} + //dbIBC, err := dbm.NewGoLevelDB("gaia-ibc", dataDir) + //if err != nil { + //return nil, err + //} + //dbStaking, err := dbm.NewGoLevelDB("gaia-staking", dataDir) + //if err != nil { + //return nil, err + //} + //dbs := map[string]dbm.DB{ + //"main": dbMain, + //"acc": dbAcc, + //"ibc": dbIBC, + //"staking": dbStaking, + //} + //bapp := app.NewGaiaApp(logger, dbs) return bapp, nil } @@ -40,6 +58,7 @@ func main() { server.AddCommands(rootCmd, server.DefaultGenAppState, generateApp, context) // prepare and add flags - executor := cli.PrepareBaseCmd(rootCmd, "GA", os.ExpandEnv("$HOME/.gaiad")) + rootDir := os.ExpandEnv("$HOME/.gaiad") + executor := cli.PrepareBaseCmd(rootCmd, "GA", rootDir) executor.Execute() } diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 9ef48bfb5..bb3ef05ac 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -15,7 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/simplestake" - "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" ) @@ -33,7 +32,7 @@ type BasecoinApp struct { capKeyMainStore *sdk.KVStoreKey capKeyAccountStore *sdk.KVStoreKey capKeyIBCStore *sdk.KVStoreKey - capKeyStakeStore *sdk.KVStoreKey + capKeyStakingStore *sdk.KVStoreKey // Manage getting and setting accounts accountMapper sdk.AccountMapper @@ -54,7 +53,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyAccountStore: sdk.NewKVStoreKey("acc"), capKeyIBCStore: sdk.NewKVStoreKey("ibc"), - capKeyStakeStore: sdk.NewKVStoreKey("stake"), + capKeyStakingStore: sdk.NewKVStoreKey("stake"), } // Define the accountMapper. @@ -71,7 +70,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). - AddRoute("stake", stake.NewHandler(stakeKeeper)) + AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) // Define the feeHandler. app.feeHandler = auth.BurnFeeHandler diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 1f635f53f..36461a8e3 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -143,7 +143,7 @@ func TestSortGenesis(t *testing.T) { // Note the order: the coins are unsorted! coinDenom1, coinDenom2 := "foocoin", "barcoin" - str := `{ + genState := fmt.Sprintf(`{ "accounts": [{ "address": "%s", "coins": [ @@ -157,8 +157,7 @@ func TestSortGenesis(t *testing.T) { } ] }] - }` - genState := fmt.Sprintf(str, addr1.String(), coinDenom1, coinDenom2) + }`, addr1.String(), coinDenom1, coinDenom2) // Initialize the chain vals := []abci.Validator{} @@ -345,9 +344,10 @@ func TestQuizMsg(t *testing.T) { // Construct genesis state // Construct some genesis bytes to reflect basecoin/types/AppAccount + coins := sdk.Coins{} baseAcc := auth.BaseAccount{ Address: addr1, - Coins: nil, + Coins: coins, } acc1 := &types.AppAccount{baseAcc, "foobart"} diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index bab24f91b..6271adcec 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -17,7 +17,7 @@ import ( authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands" - stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands" + simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/commands" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" @@ -52,20 +52,23 @@ func main() { rootCmd.AddCommand( client.GetCommands( authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)), - stakecmd.GetCmdQueryCandidates("stake", cdc), - stakecmd.GetCmdQueryCandidate("stake", cdc), - stakecmd.GetCmdQueryDelegatorBond("stake", cdc), - stakecmd.GetCmdQueryDelegatorBonds("stake", cdc), )...) rootCmd.AddCommand( client.PostCommands( bankcmd.SendTxCmd(cdc), + )...) + rootCmd.AddCommand( + client.PostCommands( ibccmd.IBCTransferCmd(cdc), + )...) + rootCmd.AddCommand( + client.PostCommands( ibccmd.IBCRelayCmd(cdc), - stakecmd.GetCmdDeclareCandidacy(cdc), - stakecmd.GetCmdEditCandidacy(cdc), - stakecmd.GetCmdDelegate(cdc), - stakecmd.GetCmdUnbond(cdc), + simplestakingcmd.BondTxCmd(cdc), + )...) + rootCmd.AddCommand( + client.PostCommands( + simplestakingcmd.UnbondTxCmd(cdc), )...) // add proxy, version and key info diff --git a/x/stake/handler.go b/x/stake/handler.go index e1f624f10..af1ad291d 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -252,40 +252,3 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { k.setPool(ctx, p) return sdk.Result{} } - -// TODO use or remove -//// Perform all the actions required to bond tokens to a delegator bond from their account -//func BondCoins(ctx sdk.Context, k Keeper, bond DelegatorBond, -//candidate Candidate, amount sdk.Coin) (DelegatorBond, Candidate, Pool, sdk.Error) { - -//pool := k.GetPool(ctx) -//_, err := k.coinKeeper.SubtractCoins(ctx, bond.DelegatorAddr, sdk.Coins{amount}) -//if err != nil { -//return bond, candidate, pool, err -//} -//pool, candidate, newShares := pool.candidateAddTokens(candidate, amount.Amount) -//bond.Shares = bond.Shares.Add(newShares) -//return bond, candidate, pool, nil -//} -//// Perform all the actions required to bond tokens to a delegator bond from their account -//func UnbondCoins(ctx sdk.Context, k Keeper, bond DelegatorBond, -//candidate Candidate, shares sdk.Rat) (DelegatorBond, Candidate, Pool, sdk.Error) { - -//pool := k.GetPool(ctx) - -//// subtract bond tokens from delegator bond -//if bond.Shares.LT(shares) { -//errMsg := fmt.Sprintf("cannot unbond %v shares, only have %v shares available", shares, bond.Shares) -//return bond, candidate, pool, sdk.ErrInsufficientFunds(errMsg) -//} -//bond.Shares = bond.Shares.Sub(shares) - -//pool, candidate, returnAmount := p.candidateRemoveShares(candidate, shares) -//returnCoins := sdk.Coins{{k.GetParams(ctx).BondDenom, returnAmount}} - -//_, err := k.coinKeeper.AddCoins(ctx, candidate.Address, returnCoins) -//if err != nil { -//return err -//} -//return bond, candidate, pool, nil -//} From 8a34b91facbe8dd113163d4c92dfa66ae4caa9a9 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 7 Apr 2018 01:50:46 -0400 Subject: [PATCH 008/176] fix existing gaia tests --- cmd/gaia/app/account.go | 32 ------------------------ cmd/gaia/app/app.go | 53 ++++++++++++++++++++++++++++++++++------ cmd/gaia/app/app_test.go | 38 +++++++++++++++------------- x/stake/handler.go | 16 +++++++++++- x/stake/handler_test.go | 9 +++++++ x/stake/keeper.go | 12 --------- x/stake/keeper_test.go | 29 ---------------------- x/stake/test_common.go | 25 +++++++++++++++++++ x/stake/types.go | 24 +++++++++--------- 9 files changed, 127 insertions(+), 111 deletions(-) delete mode 100644 cmd/gaia/app/account.go diff --git a/cmd/gaia/app/account.go b/cmd/gaia/app/account.go deleted file mode 100644 index 3d5673b87..000000000 --- a/cmd/gaia/app/account.go +++ /dev/null @@ -1,32 +0,0 @@ -package app - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" -) - -// State to Unmarshal -type GenesisState struct { - Accounts []GenesisAccount `json:"accounts"` -} - -// GenesisAccount doesn't need pubkey or sequence -type GenesisAccount struct { - Address sdk.Address `json:"address"` - Coins sdk.Coins `json:"coins"` -} - -func NewGenesisAccount(acc auth.BaseAccount) GenesisAccount { - return GenesisAccount{ - Address: acc.Address, - Coins: acc.Coins, - } -} - -// convert GenesisAccount to GaiaAccount -func (ga *GenesisAccount) ToAccount() (acc auth.BaseAccount) { - return auth.BaseAccount{ - Address: ga.Address, - Coins: ga.Coins.Sort(), - } -} diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 64b1619f8..6cf67b0f2 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -35,6 +35,9 @@ type GaiaApp struct { // Manage getting and setting accounts accountMapper sdk.AccountMapper + coinKeeper bank.CoinKeeper + ibcMapper ibc.IBCMapper + stakeKeeper stake.Keeper } func NewGaiaApp(logger log.Logger, dbs map[string]dbm.DB) *GaiaApp { @@ -55,18 +58,18 @@ func NewGaiaApp(logger log.Logger, dbs map[string]dbm.DB) *GaiaApp { ) // add handlers - coinKeeper := bank.NewCoinKeeper(app.accountMapper) - ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) - stakeKeeper := stake.NewKeeper(app.cdc, app.capKeyStakeStore, coinKeeper) + app.coinKeeper = bank.NewCoinKeeper(app.accountMapper) + app.ibcMapper = ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) + app.stakeKeeper = stake.NewKeeper(app.cdc, app.capKeyStakeStore, app.coinKeeper) app.Router(). - AddRoute("bank", bank.NewHandler(coinKeeper)). - AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). - AddRoute("stake", stake.NewHandler(stakeKeeper)) + AddRoute("bank", bank.NewHandler(app.coinKeeper)). + AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). + AddRoute("stake", stake.NewHandler(app.stakeKeeper)) // initialize BaseApp app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) - app.SetEndBlocker(stake.NewEndBlocker(stakeKeeper)) + app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"]) @@ -150,9 +153,43 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci // return sdk.ErrGenesisParse("").TraceCause(err, "") } + // load the accounts for _, gacc := range genesisState.Accounts { acc := gacc.ToAccount() - app.accountMapper.SetAccount(ctx, &acc) + app.accountMapper.SetAccount(ctx, acc) } + + // load the initial stake information + stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + return abci.ResponseInitChain{} } + +//__________________________________________________________ + +// State to Unmarshal +type GenesisState struct { + Accounts []GenesisAccount `json:"accounts"` + StakeData json.RawMessage `json:"stake"` +} + +// GenesisAccount doesn't need pubkey or sequence +type GenesisAccount struct { + Address sdk.Address `json:"address"` + Coins sdk.Coins `json:"coins"` +} + +func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { + return GenesisAccount{ + Address: acc.Address, + Coins: acc.Coins, + } +} + +// convert GenesisAccount to GaiaAccount +func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { + return &auth.BaseAccount{ + Address: ga.Address, + Coins: ga.Coins.Sort(), + } +} diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index a440e7e38..a9cc4b739 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" + "github.com/cosmos/cosmos-sdk/x/stake" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" @@ -100,14 +101,15 @@ func newGaiaApp() *GaiaApp { return NewGaiaApp(logger, dbs) } -func setGenesisAccounts(gapp *GaiaApp, accs ...auth.BaseAccount) error { +func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { genaccs := make([]GenesisAccount, len(accs)) for i, acc := range accs { genaccs[i] = NewGenesisAccount(acc) } genesisState := GenesisState{ - Accounts: genaccs, + Accounts: genaccs, + StakeData: stake.GetGenesisJSON(), } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") @@ -127,6 +129,7 @@ func setGenesisAccounts(gapp *GaiaApp, accs ...auth.BaseAccount) error { func TestMsgs(t *testing.T) { gapp := newGaiaApp() + assert.Nil(t, setGenesis(gapp)) msgs := []struct { msg sdk.Msg @@ -180,6 +183,7 @@ func TestSortGenesis(t *testing.T) { require.Nil(t, err) // Ensure we can send + assert.Nil(t, setGenesis(gapp)) // initialize the pool SignCheckDeliver(t, gapp, sendMsg5, []int64{0}, true, priv1) } @@ -192,12 +196,12 @@ func TestGenesis(t *testing.T) { addr := pk.Address() coins, err := sdk.ParseCoins("77foocoin,99barcoin") require.Nil(t, err) - baseAcc := auth.BaseAccount{ + baseAcc := &auth.BaseAccount{ Address: addr, Coins: coins, } - err = setGenesisAccounts(gapp, baseAcc) + err = setGenesis(gapp, baseAcc) assert.Nil(t, err) // A checkTx context @@ -219,13 +223,13 @@ func TestSendMsgWithAccounts(t *testing.T) { // Give 77 foocoin to the first key coins, err := sdk.ParseCoins("77foocoin") require.Nil(t, err) - baseAcc := auth.BaseAccount{ + baseAcc := &auth.BaseAccount{ Address: addr1, Coins: coins, } // Construct genesis state - err = setGenesisAccounts(gapp, baseAcc) + err = setGenesis(gapp, baseAcc) assert.Nil(t, err) // A checkTx context (true) ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) @@ -259,17 +263,17 @@ func TestSendMsgMultipleOut(t *testing.T) { genCoins, err := sdk.ParseCoins("42foocoin") require.Nil(t, err) - acc1 := auth.BaseAccount{ + acc1 := &auth.BaseAccount{ Address: addr1, Coins: genCoins, } - acc2 := auth.BaseAccount{ + acc2 := &auth.BaseAccount{ Address: addr2, Coins: genCoins, } - err = setGenesisAccounts(gapp, acc1, acc2) + err = setGenesis(gapp, acc1, acc2) assert.Nil(t, err) // Simulate a Block @@ -287,22 +291,22 @@ func TestSengMsgMultipleInOut(t *testing.T) { genCoins, err := sdk.ParseCoins("42foocoin") require.Nil(t, err) - acc1 := auth.BaseAccount{ + acc1 := &auth.BaseAccount{ Address: addr1, Coins: genCoins, } - acc2 := auth.BaseAccount{ + acc2 := &auth.BaseAccount{ Address: addr2, Coins: genCoins, } - acc4 := auth.BaseAccount{ + acc4 := &auth.BaseAccount{ Address: addr4, Coins: genCoins, } - err = setGenesisAccounts(gapp, acc1, acc2, acc4) + err = setGenesis(gapp, acc1, acc2, acc4) assert.Nil(t, err) // CheckDeliver @@ -321,12 +325,12 @@ func TestSendMsgDependent(t *testing.T) { genCoins, err := sdk.ParseCoins("42foocoin") require.Nil(t, err) - acc1 := auth.BaseAccount{ + acc1 := &auth.BaseAccount{ Address: addr1, Coins: genCoins, } - err = setGenesisAccounts(gapp, acc1) + err = setGenesis(gapp, acc1) assert.Nil(t, err) // CheckDeliver @@ -349,12 +353,12 @@ func TestIBCMsgs(t *testing.T) { sourceChain := "source-chain" destChain := "dest-chain" - baseAcc := auth.BaseAccount{ + baseAcc := &auth.BaseAccount{ Address: addr1, Coins: coins, } - err := setGenesisAccounts(gapp, baseAcc) + err := setGenesis(gapp, baseAcc) assert.Nil(t, err) // A checkTx context (true) ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) diff --git a/x/stake/handler.go b/x/stake/handler.go index af1ad291d..36b4509da 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -2,6 +2,7 @@ package stake import ( "bytes" + "encoding/json" sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/abci/types" @@ -35,7 +36,7 @@ func NewHandler(k Keeper) sdk.Handler { } } -//_______________________________________________ +//_____________________________________________________________________ // NewEndBlocker generates sdk.EndBlocker // Performs tick functionality @@ -48,6 +49,19 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ +// InitGenesis - store genesis parameters +func InitGenesis(ctx sdk.Context, k Keeper, data json.RawMessage) error { + var state GenesisState + if err := json.Unmarshal(data, &state); err != nil { + return err + } + k.setPool(ctx, state.Pool) + k.setParams(ctx, state.Params) + return nil +} + +//_____________________________________________________________________ + // These functions assume everything has been authenticated, // now we just perform action and save diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 1f0bc6415..82b33cf2c 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -12,6 +12,15 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +func TestInitGenesis(t *testing.T) { + ctx, _, keeper := createTestInput(t, false, 0) + encoded := GetGenesisJSON() + err := InitGenesis(ctx, keeper, encoded) + require.Nil(t, err) + require.Equal(t, keeper.GetPool(ctx), initialPool()) + require.Equal(t, keeper.GetParams(ctx), defaultParams()) +} + //______________________________________________________________________ func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt int64) MsgDeclareCandidacy { diff --git a/x/stake/keeper.go b/x/stake/keeper.go index ae3dfb7c7..8b73e81db 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -2,7 +2,6 @@ package stake import ( "bytes" - "encoding/json" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" @@ -34,17 +33,6 @@ func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinK return keeper } -// InitGenesis - store genesis parameters -func (k Keeper) InitGenesis(ctx sdk.Context, data json.RawMessage) error { - var state GenesisState - if err := json.Unmarshal(data, &state); err != nil { - return err - } - k.setPool(ctx, state.Pool) - k.setParams(ctx, state.Params) - return nil -} - //_________________________________________________________________________ // get a single candidate diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 088bc5e30..e8d8e0594 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -2,7 +2,6 @@ package stake import ( "bytes" - "encoding/json" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -584,31 +583,3 @@ func TestPool(t *testing.T) { resPool = keeper.GetPool(ctx) assert.Equal(t, expPool, resPool) } - -func TestInitGenesis(t *testing.T) { - ctx, _, keeper := createTestInput(t, false, 0) - jsonStr := `{ - "params": { - "inflation_rate_change": {"num": 13, "denom": 100}, - "inflation_max": {"num": 20, "denom": 100}, - "inflation_min": {"num": 7, "denom": 100}, - "goal_bonded": {"num": 67, "denom": 100}, - "max_validators": 100, - "bond_denom": "fermion" - }, - "pool": { - "total_supply": 0, - "bonded_shares": {"num": 0, "denom": 1}, - "unbonded_shares": {"num": 0, "denom": 1}, - "bonded_pool": 0, - "unbonded_pool": 0, - "inflation_last_time": 0, - "inflation": {"num": 7, "denom": 100} - } -}` - encoded := json.RawMessage(jsonStr) - err := keeper.InitGenesis(ctx, encoded) - require.Nil(t, err) - require.Equal(t, keeper.GetPool(ctx), initialPool()) - require.Equal(t, keeper.GetParams(ctx), defaultParams()) -} diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 6470abbc7..5b0bc97e0 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -2,6 +2,7 @@ package stake import ( "encoding/hex" + "encoding/json" "testing" "github.com/stretchr/testify/require" @@ -75,6 +76,30 @@ func initialPool() Pool { } } +// get raw genesis raw message for testing +func GetGenesisJSON() json.RawMessage { + jsonStr := `{ + "params": { + "inflation_rate_change": {"num": 13, "denom": 100}, + "inflation_max": {"num": 20, "denom": 100}, + "inflation_min": {"num": 7, "denom": 100}, + "goal_bonded": {"num": 67, "denom": 100}, + "max_validators": 100, + "bond_denom": "fermion" + }, + "pool": { + "total_supply": 0, + "bonded_shares": {"num": 0, "denom": 1}, + "unbonded_shares": {"num": 0, "denom": 1}, + "bonded_pool": 0, + "unbonded_pool": 0, + "inflation_last_time": 0, + "inflation": {"num": 7, "denom": 100} + } +}` + return json.RawMessage(jsonStr) +} + // XXX reference the common declaration of this function func subspace(prefix []byte) (start, end []byte) { end = make([]byte, len(prefix)) diff --git a/x/stake/types.go b/x/stake/types.go index 1154f7962..240f3fe2a 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -7,6 +7,14 @@ import ( crypto "github.com/tendermint/go-crypto" ) +// GenesisState - all staking state that must be provided at genesis +type GenesisState struct { + Pool Pool `json:"pool"` + Params Params `json:"params"` +} + +//_________________________________________________________________________ + // Params defines the high level settings for staking type Params struct { InflationRateChange sdk.Rat `json:"inflation_rate_change"` // maximum annual change in inflation rate @@ -31,13 +39,7 @@ type Pool struct { Inflation sdk.Rat `json:"inflation"` // current annual inflation rate } -// GenesisState - all staking state that must be provided at genesis -type GenesisState struct { - Pool Pool `json:"pool"` - Params Params `json:"params"` -} - -//_______________________________________________________________________________________________________ +//_________________________________________________________________________ // CandidateStatus - status of a validator-candidate type CandidateStatus byte @@ -65,6 +67,9 @@ type Candidate struct { Description Description `json:"description"` // Description terms for the candidate } +// Candidates - list of Candidates +type Candidates []Candidate + // NewCandidate - initialize a new candidate func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Description) Candidate { return Candidate{ @@ -151,11 +156,6 @@ func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator { //_________________________________________________________________________ -// Candidates - list of Candidates -type Candidates []Candidate - -//_________________________________________________________________________ - // DelegatorBond represents the bond with tokens held by an account. It is // owned by one delegator, and is associated with the voting power of one // pubKey. From c4a1c12119e7c91f573a7f78a731e780aaed51ed Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 7 Apr 2018 02:11:08 -0400 Subject: [PATCH 009/176] gaia app_test for declare candidacy --- cmd/gaia/app/app_test.go | 65 +++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index a9cc4b739..544249a8a 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -129,7 +129,7 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { func TestMsgs(t *testing.T) { gapp := newGaiaApp() - assert.Nil(t, setGenesis(gapp)) + require.Nil(t, setGenesis(gapp)) msgs := []struct { msg sdk.Msg @@ -183,7 +183,7 @@ func TestSortGenesis(t *testing.T) { require.Nil(t, err) // Ensure we can send - assert.Nil(t, setGenesis(gapp)) // initialize the pool + require.Nil(t, setGenesis(gapp)) // initialize the pool SignCheckDeliver(t, gapp, sendMsg5, []int64{0}, true, priv1) } @@ -230,7 +230,8 @@ func TestSendMsgWithAccounts(t *testing.T) { // Construct genesis state err = setGenesis(gapp, baseAcc) - assert.Nil(t, err) + require.Nil(t, err) + // A checkTx context (true) ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1) @@ -274,7 +275,7 @@ func TestSendMsgMultipleOut(t *testing.T) { } err = setGenesis(gapp, acc1, acc2) - assert.Nil(t, err) + require.Nil(t, err) // Simulate a Block SignCheckDeliver(t, gapp, sendMsg2, []int64{0}, true, priv1) @@ -295,12 +296,10 @@ func TestSengMsgMultipleInOut(t *testing.T) { Address: addr1, Coins: genCoins, } - acc2 := &auth.BaseAccount{ Address: addr2, Coins: genCoins, } - acc4 := &auth.BaseAccount{ Address: addr4, Coins: genCoins, @@ -331,7 +330,7 @@ func TestSendMsgDependent(t *testing.T) { } err = setGenesis(gapp, acc1) - assert.Nil(t, err) + require.Nil(t, err) // CheckDeliver SignCheckDeliver(t, gapp, sendMsg1, []int64{0}, true, priv1) @@ -359,7 +358,8 @@ func TestIBCMsgs(t *testing.T) { } err := setGenesis(gapp, baseAcc) - assert.Nil(t, err) + require.Nil(t, err) + // A checkTx context (true) ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1) @@ -391,6 +391,49 @@ func TestIBCMsgs(t *testing.T) { SignCheckDeliver(t, gapp, receiveMsg, []int64{3}, false, priv1) } +func TestStakeMsgs(t *testing.T) { + gapp := newGaiaApp() + + genCoins, err := sdk.ParseCoins("42fermion") + require.Nil(t, err) + bondCoin, err := sdk.ParseCoin("10fermion") + require.Nil(t, err) + + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: genCoins, + } + acc2 := &auth.BaseAccount{ + Address: addr2, + Coins: genCoins, + } + + err = setGenesis(gapp, acc1, acc2) + require.Nil(t, err) + + // A checkTx context (true) + ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) + res1 := gapp.accountMapper.GetAccount(ctxCheck, addr1) + res2 := gapp.accountMapper.GetAccount(ctxCheck, addr2) + require.Equal(t, acc1, res1) + require.Equal(t, acc2, res2) + + description := stake.NewDescription("foo_moniker", "", "", "") + declareCandidacyMsg := stake.NewMsgDeclareCandidacy( + addr1, priv1.PubKey(), bondCoin, description, + ) + + SignCheckDeliver(t, gapp, declareCandidacyMsg, []int64{0}, true, priv1) +} + +//____________________________________________________________________________________ + +func CheckBalance(t *testing.T, gapp *GaiaApp, addr sdk.Address, balExpected string) { + ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{}) + res2 := gapp.accountMapper.GetAccount(ctxDeliver, addr) + assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) +} + func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.StdTx { sigs := make([]sdk.StdSignature, len(priv)) for i, p := range priv { @@ -428,9 +471,3 @@ func SignCheckDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, exp gapp.EndBlock(abci.RequestEndBlock{}) //gapp.Commit() } - -func CheckBalance(t *testing.T, gapp *GaiaApp, addr sdk.Address, balExpected string) { - ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{}) - res2 := gapp.accountMapper.GetAccount(ctxDeliver, addr) - assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) -} From abce3850ec69a9053b3d3003bab21843a211985e Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 7 Apr 2018 11:11:47 -0400 Subject: [PATCH 010/176] build fixes --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 4d21c61c5..78a5c9dcc 100644 --- a/Makefile +++ b/Makefile @@ -15,11 +15,11 @@ ci: get_tools get_vendor_deps build test_cover # This can be unified later, here for easy demos build: ifeq ($(OS),Windows_NT) - go build $(BUILD_FLAGS) -o build/gaiad.exe ./cmd/gaiad - go build $(BUILD_FLAGS) -o build/gaiacli.exe ./cmd/gaiacli + go build $(BUILD_FLAGS) -o build/gaiad.exe ./cmd/gaia/cmd/gaiad + go build $(BUILD_FLAGS) -o build/gaiacli.exe ./cmd/gaia/cmd/gaiacli else - go build $(BUILD_FLAGS) -o build/gaiad ./cmd/gaiad - go build $(BUILD_FLAGS) -o build/gaiacli ./cmd/gaiacli + go build $(BUILD_FLAGS) -o build/gaiad ./cmd/gaia/cmd/gaiad + go build $(BUILD_FLAGS) -o build/gaiacli ./cmd/gaia/cmd/gaiacli endif build_examples: From c90d62e03527462a83a374a740cabc1a87b33411 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 9 Apr 2018 23:08:00 -0400 Subject: [PATCH 011/176] rebase fixes --- cmd/gaia/app/app.go | 56 ++++++++------------ cmd/gaiacli/main.go | 88 ------------------------------- examples/basecoin/app/app_test.go | 3 +- 3 files changed, 22 insertions(+), 125 deletions(-) delete mode 100644 cmd/gaiacli/main.go diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 6cf67b0f2..49b5bc724 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -4,7 +4,6 @@ import ( "encoding/json" abci "github.com/tendermint/abci/types" - oldwire "github.com/tendermint/go-wire" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -52,10 +51,11 @@ func NewGaiaApp(logger log.Logger, dbs map[string]dbm.DB) *GaiaApp { } // define the accountMapper - app.accountMapper = auth.NewAccountMapperSealed( + app.accountMapper = auth.NewAccountMapper( + app.cdc, app.capKeyMainStore, // target store &auth.BaseAccount{}, // prototype - ) + ).Seal() // add handlers app.coinKeeper = bank.NewCoinKeeper(app.accountMapper) @@ -87,41 +87,27 @@ func NewGaiaApp(logger log.Logger, dbs map[string]dbm.DB) *GaiaApp { } // custom tx codec -// TODO: use new go-wire func MakeCodec() *wire.Codec { - const ( - msgTypeSend = 0x1 - msgTypeIssue = 0x2 - msgTypeIBCTransferMsg = 0x3 - msgTypeIBCReceiveMsg = 0x4 - msgDeclareCandidacy = 0x5 - msgEditCandidacy = 0x6 - msgDelegate = 0x7 - msgUnbond = 0x8 - ) - var _ = oldwire.RegisterInterface( - struct{ sdk.Msg }{}, - oldwire.ConcreteType{bank.SendMsg{}, msgTypeSend}, - oldwire.ConcreteType{bank.IssueMsg{}, msgTypeIssue}, - oldwire.ConcreteType{ibc.IBCTransferMsg{}, msgTypeIBCTransferMsg}, - oldwire.ConcreteType{ibc.IBCReceiveMsg{}, msgTypeIBCReceiveMsg}, - oldwire.ConcreteType{stake.MsgDeclareCandidacy{}, msgDeclareCandidacy}, - oldwire.ConcreteType{stake.MsgEditCandidacy{}, msgEditCandidacy}, - oldwire.ConcreteType{stake.MsgDelegate{}, msgDelegate}, - oldwire.ConcreteType{stake.MsgUnbond{}, msgUnbond}, - ) + var cdc = wire.NewCodec() - const accTypeApp = 0x1 - var _ = oldwire.RegisterInterface( - struct{ sdk.Account }{}, - oldwire.ConcreteType{&auth.BaseAccount{}, accTypeApp}, - ) - cdc := wire.NewCodec() + // Register Msgs + cdc.RegisterInterface((*sdk.Msg)(nil), nil) + cdc.RegisterConcrete(bank.SendMsg{}, "gaia/Send", nil) + cdc.RegisterConcrete(bank.IssueMsg{}, "gaia/Issue", nil) + cdc.RegisterConcrete(ibc.IBCTransferMsg{}, "gaia/IBCTransferMsg", nil) + cdc.RegisterConcrete(ibc.IBCReceiveMsg{}, "gaia/IBCReceiveMsg", nil) + cdc.RegisterConcrete(stake.MsgDeclareCandidacy{}, "gaia/MsgDeclareCandidacy", nil) + cdc.RegisterConcrete(stake.MsgEditCandidacy{}, "gaia/MsgEditCandidacy", nil) + cdc.RegisterConcrete(stake.MsgDelegate{}, "gaia/MsgDelegate", nil) + cdc.RegisterConcrete(stake.MsgUnbond{}, "gaia/MsgUnbond", nil) + + // Register AppAccount + cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterConcrete(&auth.BaseAccount{}, "gaia/Account", nil) + + // Register crypto. + wire.RegisterCrypto(cdc) - // cdc.RegisterInterface((*sdk.Msg)(nil), nil) - // bank.RegisterWire(cdc) // Register bank.[SendMsg,IssueMsg] - // crypto.RegisterWire(cdc) // Register crypto.[PubKey,PrivKey,Signature] - // ibc.RegisterWire(cdc) // Register ibc.[IBCTransferMsg, IBCReceiveMsg] return cdc } diff --git a/cmd/gaiacli/main.go b/cmd/gaiacli/main.go deleted file mode 100644 index 1c71d7829..000000000 --- a/cmd/gaiacli/main.go +++ /dev/null @@ -1,88 +0,0 @@ -package main - -import ( - "os" - - "github.com/spf13/cobra" - - "github.com/tendermint/tmlibs/cli" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/client/lcd" - "github.com/cosmos/cosmos-sdk/client/rpc" - "github.com/cosmos/cosmos-sdk/client/tx" - - "github.com/cosmos/cosmos-sdk/version" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" - bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" - ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands" - simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/commands" - - "github.com/cosmos/cosmos-sdk/examples/basecoin/app" - "github.com/cosmos/cosmos-sdk/examples/basecoin/types" -) - -// TODO: distinguish from basecli - -// rootCmd is the entry point for this binary -var ( - rootCmd = &cobra.Command{ - Use: "gaiacli", - Short: "Gaia light-client", - } -) - -func main() { - // disable sorting - cobra.EnableCommandSorting = false - - // get the codec - cdc := app.MakeCodec() - - // TODO: setup keybase, viper object, etc. to be passed into - // the below functions and eliminate global vars, like we do - // with the cdc - - // add standard rpc, and tx commands - rpc.AddCommands(rootCmd) - rootCmd.AddCommand(client.LineBreak) - tx.AddCommands(rootCmd, cdc) - rootCmd.AddCommand(client.LineBreak) - - // add query/post commands (custom to binary) - rootCmd.AddCommand( - client.GetCommands( - authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)), - )...) - rootCmd.AddCommand( - client.PostCommands( - bankcmd.SendTxCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( - ibccmd.IBCTransferCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( - ibccmd.IBCRelayCmd(cdc), - simplestakingcmd.BondTxCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( - simplestakingcmd.UnbondTxCmd(cdc), - )...) - - // add proxy, version and key info - rootCmd.AddCommand( - client.LineBreak, - lcd.ServeCommand(cdc), - keys.Commands(), - client.LineBreak, - version.VersionCmd, - ) - - // prepare and add flags - executor := cli.PrepareMainCmd(rootCmd, "BC", os.ExpandEnv("$HOME/.gaiacli")) - executor.Execute() -} diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 36461a8e3..bc1735dde 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -344,10 +344,9 @@ func TestQuizMsg(t *testing.T) { // Construct genesis state // Construct some genesis bytes to reflect basecoin/types/AppAccount - coins := sdk.Coins{} baseAcc := auth.BaseAccount{ Address: addr1, - Coins: coins, + Coins: nil, } acc1 := &types.AppAccount{baseAcc, "foobart"} From c63a5452064a8857b7c30d4b5179e15f0c06defe Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 10 Apr 2018 23:51:09 -0400 Subject: [PATCH 012/176] stake handler tests --- baseapp/baseapp.go | 7 ++-- cmd/gaia/app/app.go | 2 +- cmd/gaia/app/app_test.go | 80 +++++++++++++++++++++++++++++++++++++--- types/result.go | 2 +- x/stake/handler.go | 18 ++++----- x/stake/handler_test.go | 8 ++-- x/stake/keeper.go | 5 ++- x/stake/keeper_test.go | 24 ++++++------ 8 files changed, 107 insertions(+), 39 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 115748ca5..3eebb1eb4 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -322,9 +322,8 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) { if result.IsOK() { app.valUpdates = append(app.valUpdates, result.ValidatorUpdates...) } else { - // Even though the Code is not OK, there will be some side - // effects, like those caused by fee deductions or sequence - // incrementations. + // Even though the Result.Code is not OK, there are still effects, + // namely fee deductions and sequence incrementing. } // Tell the blockchain engine (i.e. Tendermint). @@ -453,7 +452,7 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) { // Use the header from this latest block. app.setCheckState(header) - // Emtpy the Deliver state + // Empty the Deliver state app.deliverState = nil return abci.ResponseCommit{ diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 49b5bc724..0fa4f4181 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -76,7 +76,7 @@ func NewGaiaApp(logger log.Logger, dbs map[string]dbm.DB) *GaiaApp { app.MountStoreWithDB(app.capKeyStakeStore, sdk.StoreTypeIAVL, dbs["stake"]) // NOTE: Broken until #532 lands - //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore) + //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakeStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 544249a8a..4ca1cd959 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -88,10 +88,10 @@ var ( func loggerAndDBs() (log.Logger, map[string]dbm.DB) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") dbs := map[string]dbm.DB{ - "main": dbm.NewMemDB(), - "acc": dbm.NewMemDB(), - "ibc": dbm.NewMemDB(), - "staking": dbm.NewMemDB(), + "main": dbm.NewMemDB(), + "acc": dbm.NewMemDB(), + "ibc": dbm.NewMemDB(), + "stake": dbm.NewMemDB(), } return logger, dbs } @@ -418,12 +418,59 @@ func TestStakeMsgs(t *testing.T) { require.Equal(t, acc1, res1) require.Equal(t, acc2, res2) + // Declare Candidacy + description := stake.NewDescription("foo_moniker", "", "", "") declareCandidacyMsg := stake.NewMsgDeclareCandidacy( addr1, priv1.PubKey(), bondCoin, description, ) - SignCheckDeliver(t, gapp, declareCandidacyMsg, []int64{0}, true, priv1) + + ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{}) + res1 = gapp.accountMapper.GetAccount(ctxDeliver, addr1) + require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res1.GetCoins()) + candidate, found := gapp.stakeKeeper.GetCandidate(ctxDeliver, addr1) + require.True(t, found) + require.Equal(t, candidate.Address, addr1) + + // Edit Candidacy + + description = stake.NewDescription("bar_moniker", "", "", "") + editCandidacyMsg := stake.NewMsgEditCandidacy( + addr1, description, + ) + SignDeliver(t, gapp, editCandidacyMsg, []int64{1}, true, priv1) + + candidate, found = gapp.stakeKeeper.GetCandidate(ctxDeliver, addr1) + require.True(t, found) + require.Equal(t, candidate.Description, description) + + // Delegate + + delegateMsg := stake.NewMsgDelegate( + addr2, addr1, bondCoin, + ) + SignDeliver(t, gapp, delegateMsg, []int64{0}, true, priv2) + + ctxDeliver = gapp.BaseApp.NewContext(false, abci.Header{}) + res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) + require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res2.GetCoins()) + bond, found := gapp.stakeKeeper.GetDelegatorBond(ctxDeliver, addr2, addr1) + require.True(t, found) + require.Equal(t, bond.DelegatorAddr, addr2) + + // Unbond + + unbondMsg := stake.NewMsgUnbond( + addr2, addr1, "MAX", + ) + SignDeliver(t, gapp, unbondMsg, []int64{1}, true, priv2) + + ctxDeliver = gapp.BaseApp.NewContext(false, abci.Header{}) + res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) + require.Equal(t, genCoins, res2.GetCoins()) + _, found = gapp.stakeKeeper.GetDelegatorBond(ctxDeliver, addr2, addr1) + require.False(t, found) } //____________________________________________________________________________________ @@ -452,6 +499,7 @@ func SignCheckDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, exp // Sign the tx tx := genTx(msg, seq, priv...) + // Run a Check res := gapp.Check(tx) if expPass { @@ -469,5 +517,27 @@ func SignCheckDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, exp require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) } gapp.EndBlock(abci.RequestEndBlock{}) + + // XXX fix code or add explaination as to why using commit breaks a bunch of these tests //gapp.Commit() } + +// XXX the only reason we are using Sign Deliver here is because the tests +// break on check tx the second time you use SignCheckDeliver in a test because +// the checktx state has not been updated likely because commit is not being +// called! +func SignDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { + + // Sign the tx + tx := genTx(msg, seq, priv...) + + // Simulate a Block + gapp.BeginBlock(abci.RequestBeginBlock{}) + res := gapp.Deliver(tx) + if expPass { + require.Equal(t, sdk.CodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + } + gapp.EndBlock(abci.RequestEndBlock{}) +} diff --git a/types/result.go b/types/result.go index 7b0c1a593..f4f7454e2 100644 --- a/types/result.go +++ b/types/result.go @@ -20,7 +20,7 @@ type Result struct { // GasWanted is the maximum units of work we allow this tx to perform. GasWanted int64 - // GasUsed is the amount of gas actually consumed. NOTE: not used. + // GasUsed is the amount of gas actually consumed. NOTE: unimplemented GasUsed int64 // Tx fee amount and denom. diff --git a/x/stake/handler.go b/x/stake/handler.go index 36b4509da..cf36cf10a 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -105,9 +105,6 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk GasUsed: GasEditCandidacy, } } - if candidate.Status == Unbonded { //candidate has been withdrawn - return ErrBondNotNominated(k.codespace).Result() - } // XXX move to types // replace all editable fields (clients should autofill existing values) @@ -149,7 +146,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, bondAmt sdk.Coin, candidate Candidate) sdk.Error { // Get or create the delegator bond - bond, found := k.getDelegatorBond(ctx, delegatorAddr, candidate.Address) + bond, found := k.GetDelegatorBond(ctx, delegatorAddr, candidate.Address) if !found { bond = DelegatorBond{ DelegatorAddr: delegatorAddr, @@ -176,7 +173,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { // check if bond has any shares in it unbond - bond, found := k.getDelegatorBond(ctx, msg.DelegatorAddr, msg.CandidateAddr) + bond, found := k.GetDelegatorBond(ctx, msg.DelegatorAddr, msg.CandidateAddr) if !found { return ErrNoDelegatorForAddress(k.codespace).Result() } @@ -184,11 +181,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { return ErrInsufficientFunds(k.codespace).Result() } - // test getting rational number from decimal provided - shares, err := sdk.NewRatFromDecimal(msg.Shares) - if err != nil { - return err.Result() - } + var shares sdk.Rat // test that there are enough shares to unbond if msg.Shares == "MAX" { @@ -196,6 +189,11 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result() } } else { + var err sdk.Error + shares, err = sdk.NewRatFromDecimal(msg.Shares) + if err != nil { + return err.Result() + } if bond.Shares.LT(shares) { return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result() } diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 82b33cf2c..00ec07712 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -92,7 +92,7 @@ func TestIncrementsMsgDelegate(t *testing.T) { //Check that the accounts and the bond account have the appropriate values candidate, found := keeper.GetCandidate(ctx, candidateAddr) require.True(t, found) - bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr) + bond, found := keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr) require.True(t, found) expBond := int64(i+1) * bondAmount @@ -148,7 +148,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { //Check that the accounts and the bond account have the appropriate values candidate, found = keeper.GetCandidate(ctx, candidateAddr) require.True(t, found) - bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr) + bond, found := keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr) require.True(t, found) expBond := initBond - int64(i+1)*unbondShares @@ -263,7 +263,7 @@ func TestMultipleMsgDelegate(t *testing.T) { require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) //Check that the account is bonded - bond, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr) + bond, found := keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr) require.True(t, found) require.NotNil(t, bond, "expected delegatee bond %d to exist", bond) } @@ -275,7 +275,7 @@ func TestMultipleMsgDelegate(t *testing.T) { require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) //Check that the account is unbonded - _, found := keeper.getDelegatorBond(ctx, delegatorAddr, candidateAddr) + _, found := keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr) require.False(t, found) } } diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 8b73e81db..c2b054eba 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -297,7 +297,8 @@ func (k Keeper) clearAccUpdateValidators(ctx sdk.Context) { //_____________________________________________________________________ -func (k Keeper) getDelegatorBond(ctx sdk.Context, +// load a delegator bong +func (k Keeper) GetDelegatorBond(ctx sdk.Context, delegatorAddr, candidateAddr sdk.Address) (bond DelegatorBond, found bool) { store := ctx.KVStore(k.storeKey) @@ -314,7 +315,7 @@ func (k Keeper) getDelegatorBond(ctx sdk.Context, } // load all bonds of a delegator -func (k Keeper) getDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []DelegatorBond) { +func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []DelegatorBond) { store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetDelegatorBondsKey(delegator, k.cdc) iterator := store.Iterator(subspace(delegatorPrefixKey)) //smallest to largest diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index e8d8e0594..9d6f69cc6 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -127,19 +127,19 @@ func TestBond(t *testing.T) { } // check the empty keeper first - _, found := keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0]) + _, found := keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) assert.False(t, found) // set and retrieve a record keeper.setDelegatorBond(ctx, bond1to1) - resBond, found := keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0]) + resBond, found := keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) assert.True(t, found) assert.True(t, bondsEqual(bond1to1, resBond)) // modify a records, save, and retrieve bond1to1.Shares = sdk.NewRat(99) keeper.setDelegatorBond(ctx, bond1to1) - resBond, found = keeper.getDelegatorBond(ctx, addrDels[0], addrVals[0]) + resBond, found = keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) assert.True(t, found) assert.True(t, bondsEqual(bond1to1, resBond)) @@ -158,16 +158,16 @@ func TestBond(t *testing.T) { keeper.setDelegatorBond(ctx, bond2to3) // test all bond retrieve capabilities - resBonds := keeper.getDelegatorBonds(ctx, addrDels[0], 5) + resBonds := keeper.GetDelegatorBonds(ctx, addrDels[0], 5) require.Equal(t, 3, len(resBonds)) assert.True(t, bondsEqual(bond1to1, resBonds[0])) assert.True(t, bondsEqual(bond1to2, resBonds[1])) assert.True(t, bondsEqual(bond1to3, resBonds[2])) - resBonds = keeper.getDelegatorBonds(ctx, addrDels[0], 3) + resBonds = keeper.GetDelegatorBonds(ctx, addrDels[0], 3) require.Equal(t, 3, len(resBonds)) - resBonds = keeper.getDelegatorBonds(ctx, addrDels[0], 2) + resBonds = keeper.GetDelegatorBonds(ctx, addrDels[0], 2) require.Equal(t, 2, len(resBonds)) - resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5) + resBonds = keeper.GetDelegatorBonds(ctx, addrDels[1], 5) require.Equal(t, 3, len(resBonds)) assert.True(t, bondsEqual(bond2to1, resBonds[0])) assert.True(t, bondsEqual(bond2to2, resBonds[1])) @@ -175,9 +175,9 @@ func TestBond(t *testing.T) { // delete a record keeper.removeDelegatorBond(ctx, bond2to3) - _, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[2]) + _, found = keeper.GetDelegatorBond(ctx, addrDels[1], addrVals[2]) assert.False(t, found) - resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5) + resBonds = keeper.GetDelegatorBonds(ctx, addrDels[1], 5) require.Equal(t, 2, len(resBonds)) assert.True(t, bondsEqual(bond2to1, resBonds[0])) assert.True(t, bondsEqual(bond2to2, resBonds[1])) @@ -185,11 +185,11 @@ func TestBond(t *testing.T) { // delete all the records from delegator 2 keeper.removeDelegatorBond(ctx, bond2to1) keeper.removeDelegatorBond(ctx, bond2to2) - _, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[0]) + _, found = keeper.GetDelegatorBond(ctx, addrDels[1], addrVals[0]) assert.False(t, found) - _, found = keeper.getDelegatorBond(ctx, addrDels[1], addrVals[1]) + _, found = keeper.GetDelegatorBond(ctx, addrDels[1], addrVals[1]) assert.False(t, found) - resBonds = keeper.getDelegatorBonds(ctx, addrDels[1], 5) + resBonds = keeper.GetDelegatorBonds(ctx, addrDels[1], 5) require.Equal(t, 0, len(resBonds)) } From 068ca5e3e6318e109248bd797892ef8320bab7a8 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 11 Apr 2018 11:58:11 -0400 Subject: [PATCH 013/176] fix gaia init genesis creation int int --- cmd/gaia/app/app.go | 22 ++++++++++++++++++++++ cmd/gaia/cmd/gaiad/main.go | 12 ++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 0fa4f4181..792a6bbd9 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -179,3 +179,25 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { Coins: ga.Coins.Sort(), } } + +// DefaultGenAppState expects two args: an account address +// and a coin denomination, and gives lots of coins to that address. +func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) { + + accAuth := auth.NewBaseAccountWithAddress(addr) + accAuth.Coins = sdk.Coins{{"fermion", 100000}} + acc := NewGenesisAccount(&accAuth) + genaccs := []GenesisAccount{acc} + + genesisState := GenesisState{ + Accounts: genaccs, + StakeData: stake.GetGenesisJSON(), + } + + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + if err != nil { + return nil, err + } + + return stateBytes, nil +} diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index f966c446a..b84a4e20d 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -40,22 +40,22 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { //if err != nil { //return nil, err //} - //dbStaking, err := dbm.NewGoLevelDB("gaia-staking", dataDir) + //dbStake, err := dbm.NewGoLevelDB("gaia-stake", dataDir) //if err != nil { //return nil, err //} //dbs := map[string]dbm.DB{ - //"main": dbMain, - //"acc": dbAcc, - //"ibc": dbIBC, - //"staking": dbStaking, + //"main": dbMain, + //"acc": dbAcc, + //"ibc": dbIBC, + //"stake": dbStake, //} //bapp := app.NewGaiaApp(logger, dbs) return bapp, nil } func main() { - server.AddCommands(rootCmd, server.DefaultGenAppState, generateApp, context) + server.AddCommands(rootCmd, app.DefaultGenAppState, generateApp, context) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.gaiad") From 996cafe97223c6bda8e24f6e19e2837d4d393245 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 11 Apr 2018 13:27:36 -0400 Subject: [PATCH 014/176] register wire, stake changelog, stake genesis update --- CHANGELOG.md | 5 +++++ cmd/gaia/app/app.go | 18 +++++++----------- cmd/gaia/app/app_test.go | 2 +- x/bank/wire.go | 5 ++--- x/ibc/wire.go | 4 ++-- x/stake/handler.go | 12 +++--------- x/stake/handler_test.go | 9 --------- x/stake/test_common.go | 27 +++++---------------------- x/stake/wire.go | 9 +++++---- 9 files changed, 30 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 873824c48..2cfbe82dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,12 @@ BREAKING CHANGES * All module keepers now require a codespace, see basecoin or democoin for usage BUG FIXES +* Gaia now uses stake, ported from github.com/cosmos/gaia +FEATURES: + +* Add CacheContext +* Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond * MountStoreWithDB without providing a custom store works. ## 0.14.1 (April 9, 2018) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 792a6bbd9..eeb64a7a7 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -92,14 +92,10 @@ func MakeCodec() *wire.Codec { // Register Msgs cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.SendMsg{}, "gaia/Send", nil) - cdc.RegisterConcrete(bank.IssueMsg{}, "gaia/Issue", nil) - cdc.RegisterConcrete(ibc.IBCTransferMsg{}, "gaia/IBCTransferMsg", nil) - cdc.RegisterConcrete(ibc.IBCReceiveMsg{}, "gaia/IBCReceiveMsg", nil) - cdc.RegisterConcrete(stake.MsgDeclareCandidacy{}, "gaia/MsgDeclareCandidacy", nil) - cdc.RegisterConcrete(stake.MsgEditCandidacy{}, "gaia/MsgEditCandidacy", nil) - cdc.RegisterConcrete(stake.MsgDelegate{}, "gaia/MsgDelegate", nil) - cdc.RegisterConcrete(stake.MsgUnbond{}, "gaia/MsgUnbond", nil) + + ibc.RegisterWire(cdc) + bank.RegisterWire(cdc) + stake.RegisterWire(cdc) // Register AppAccount cdc.RegisterInterface((*sdk.Account)(nil), nil) @@ -155,8 +151,8 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci // State to Unmarshal type GenesisState struct { - Accounts []GenesisAccount `json:"accounts"` - StakeData json.RawMessage `json:"stake"` + Accounts []GenesisAccount `json:"accounts"` + StakeData stake.GenesisState `json:"stake"` } // GenesisAccount doesn't need pubkey or sequence @@ -191,7 +187,7 @@ func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json genesisState := GenesisState{ Accounts: genaccs, - StakeData: stake.GetGenesisJSON(), + StakeData: stake.GetDefaultGenesisState(), } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 4ca1cd959..ea10cebc5 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -109,7 +109,7 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { genesisState := GenesisState{ Accounts: genaccs, - StakeData: stake.GetGenesisJSON(), + StakeData: stake.GetDefaultGenesisState(), } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") diff --git a/x/bank/wire.go b/x/bank/wire.go index 846103a52..c53f06564 100644 --- a/x/bank/wire.go +++ b/x/bank/wire.go @@ -6,7 +6,6 @@ import ( // Register concrete types on wire codec func RegisterWire(cdc *wire.Codec) { - // TODO include option to always include prefix bytes. - //cdc.RegisterConcrete(SendMsg{}, "github.com/cosmos/cosmos-sdk/bank/SendMsg", nil) - //cdc.RegisterConcrete(IssueMsg{}, "github.com/cosmos/cosmos-sdk/bank/IssueMsg", nil) + cdc.RegisterConcrete(SendMsg{}, "cosmos-sdk/Send", nil) + cdc.RegisterConcrete(IssueMsg{}, "cosmos-sdk/Issue", nil) } diff --git a/x/ibc/wire.go b/x/ibc/wire.go index 91e6d88bb..f5644acc5 100644 --- a/x/ibc/wire.go +++ b/x/ibc/wire.go @@ -6,6 +6,6 @@ import ( // Register concrete types on wire codec func RegisterWire(cdc *wire.Codec) { - //cdc.RegisterConcrete(IBCTransferMsg{}, "github.com/cosmos/cosmos-sdk/x/ibc/IBCTransferMsg", nil) - //cdc.RegisterConcrete(IBCReceiveMsg{}, "github.com/cosmos/cosmos-sdk/x/ibc/IBCReceiveMsg", nil) + cdc.RegisterConcrete(IBCTransferMsg{}, "cosmos-sdk/IBCTransferMsg", nil) + cdc.RegisterConcrete(IBCReceiveMsg{}, "cosmos-sdk/IBCReceiveMsg", nil) } diff --git a/x/stake/handler.go b/x/stake/handler.go index cf36cf10a..84eeca3c4 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -2,7 +2,6 @@ package stake import ( "bytes" - "encoding/json" sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/tendermint/abci/types" @@ -50,14 +49,9 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ // InitGenesis - store genesis parameters -func InitGenesis(ctx sdk.Context, k Keeper, data json.RawMessage) error { - var state GenesisState - if err := json.Unmarshal(data, &state); err != nil { - return err - } - k.setPool(ctx, state.Pool) - k.setParams(ctx, state.Params) - return nil +func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { + k.setPool(ctx, data.Pool) + k.setParams(ctx, data.Params) } //_____________________________________________________________________ diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 00ec07712..538c664e9 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -12,15 +12,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func TestInitGenesis(t *testing.T) { - ctx, _, keeper := createTestInput(t, false, 0) - encoded := GetGenesisJSON() - err := InitGenesis(ctx, keeper, encoded) - require.Nil(t, err) - require.Equal(t, keeper.GetPool(ctx), initialPool()) - require.Equal(t, keeper.GetParams(ctx), defaultParams()) -} - //______________________________________________________________________ func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt int64) MsgDeclareCandidacy { diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 5b0bc97e0..75781777a 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -2,7 +2,6 @@ package stake import ( "encoding/hex" - "encoding/json" "testing" "github.com/stretchr/testify/require" @@ -77,27 +76,11 @@ func initialPool() Pool { } // get raw genesis raw message for testing -func GetGenesisJSON() json.RawMessage { - jsonStr := `{ - "params": { - "inflation_rate_change": {"num": 13, "denom": 100}, - "inflation_max": {"num": 20, "denom": 100}, - "inflation_min": {"num": 7, "denom": 100}, - "goal_bonded": {"num": 67, "denom": 100}, - "max_validators": 100, - "bond_denom": "fermion" - }, - "pool": { - "total_supply": 0, - "bonded_shares": {"num": 0, "denom": 1}, - "unbonded_shares": {"num": 0, "denom": 1}, - "bonded_pool": 0, - "unbonded_pool": 0, - "inflation_last_time": 0, - "inflation": {"num": 7, "denom": 100} - } -}` - return json.RawMessage(jsonStr) +func GetDefaultGenesisState() GenesisState { + return GenesisState{ + Pool: initialPool(), + Params: defaultParams(), + } } // XXX reference the common declaration of this function diff --git a/x/stake/wire.go b/x/stake/wire.go index f444ce14e..e99c621fa 100644 --- a/x/stake/wire.go +++ b/x/stake/wire.go @@ -4,9 +4,10 @@ import ( "github.com/cosmos/cosmos-sdk/wire" ) -// TODO complete when go-amino is ported +// Register concrete types on wire codec func RegisterWire(cdc *wire.Codec) { - // TODO include option to always include prefix bytes. - //cdc.RegisterConcrete(SendMsg{}, "cosmos-sdk/SendMsg", nil) - //cdc.RegisterConcrete(IssueMsg{}, "cosmos-sdk/IssueMsg", nil) + cdc.RegisterConcrete(MsgDeclareCandidacy{}, "cosmos-sdk/MsgDeclareCandidacy", nil) + cdc.RegisterConcrete(MsgEditCandidacy{}, "cosmos-sdk/MsgEditCandidacy", nil) + cdc.RegisterConcrete(MsgDelegate{}, "cosmos-sdk/MsgDelegate", nil) + cdc.RegisterConcrete(MsgUnbond{}, "cosmos-sdk/MsgUnbond", nil) } From 8ab77e2ab5cea35f144103ef1c343d9183be450a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 12 Apr 2018 22:51:14 -0400 Subject: [PATCH 015/176] started gaia go-bash cli testing --- cmd/gaia/cmd/app_test.go | 42 ++++++++++++++++++++++++++++++++++ tests/gobash.go | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 cmd/gaia/cmd/app_test.go create mode 100644 tests/gobash.go diff --git a/cmd/gaia/cmd/app_test.go b/cmd/gaia/cmd/app_test.go new file mode 100644 index 000000000..98cf2a0d2 --- /dev/null +++ b/cmd/gaia/cmd/app_test.go @@ -0,0 +1,42 @@ +package common + +import ( + "encoding/json" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/tests" +) + +func TestGaiaCLI(t *testing.T) { + + _, out := tests.ExecuteT(t, "gaiad init") + var initRes map[string]interface{} + outCut := "{" + strings.SplitN(out, "{", 2)[1] + err := json.Unmarshal([]byte(outCut), &initRes) + require.NoError(t, err, "out %v outCut %v err %v", out, outCut, err) + masterKey := (initRes["secret"]).(string) + _ = masterKey + + //wc1, _ := tests.GoExecuteT(t, "gaiacli keys add foo --recover") + //time.Sleep(time.Second) + //_, err = wc1.Write([]byte("1234567890\n")) + //time.Sleep(time.Second) + //_, err = wc1.Write([]byte(masterKey + "\n")) + //time.Sleep(time.Second) + //out = <-outChan + //wc1.Close() + //fmt.Println(out) + + //_, out = tests.ExecuteT(t, "gaiacli keys show foo") + //fooAddr := strings.TrimLeft(out, "foo\t") + + //wc2, _ := tests.GoExecuteT(t, "gaiad start") + //defer wc2.Close() + //time.Sleep(time.Second) + + //_, out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v", fooAddr)) + //fmt.Println(fooAddr) +} diff --git a/tests/gobash.go b/tests/gobash.go new file mode 100644 index 000000000..edef7ccd5 --- /dev/null +++ b/tests/gobash.go @@ -0,0 +1,49 @@ +package tests + +import ( + "io" + "os/exec" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func getCmd(t *testing.T, command string) *exec.Cmd { + + //split command into command and args + split := strings.Split(command, " ") + require.True(t, len(split) > 0, "no command provided") + + var cmd *exec.Cmd + if len(split) == 1 { + cmd = exec.Command(split[0]) + } else { + cmd = exec.Command(split[0], split[1:]...) + } + return cmd +} + +// Execute the command, return standard output and error +func ExecuteT(t *testing.T, command string) (pipe io.WriteCloser, out string) { + cmd := getCmd(t, command) + pipe, err := cmd.StdinPipe() + require.NoError(t, err) + bz, err := cmd.CombinedOutput() + require.NoError(t, err) + out = strings.Trim(string(bz), "\n") //trim any new lines + return pipe, out +} + +// Asynchronously execute the command, return standard output and error +func GoExecuteT(t *testing.T, command string) (pipe io.WriteCloser, outChan chan string) { + cmd := getCmd(t, command) + pipe, err := cmd.StdinPipe() + require.NoError(t, err) + go func() { + bz, err := cmd.CombinedOutput() + require.NoError(t, err) + outChan <- strings.Trim(string(bz), "\n") //trim any new lines + }() + return pipe, outChan +} From 3ab032e1c671e885b9d2d48260b9518b9216b131 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 13 Apr 2018 16:08:06 -0400 Subject: [PATCH 016/176] cli testing --- cmd/gaia/cmd/app_test.go | 42 -------------------- cmd/gaia/cmd/cli_test.go | 83 ++++++++++++++++++++++++++++++++++++++++ tests/gobash.go | 25 ++++++------ 3 files changed, 97 insertions(+), 53 deletions(-) delete mode 100644 cmd/gaia/cmd/app_test.go create mode 100644 cmd/gaia/cmd/cli_test.go diff --git a/cmd/gaia/cmd/app_test.go b/cmd/gaia/cmd/app_test.go deleted file mode 100644 index 98cf2a0d2..000000000 --- a/cmd/gaia/cmd/app_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package common - -import ( - "encoding/json" - "strings" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/tests" -) - -func TestGaiaCLI(t *testing.T) { - - _, out := tests.ExecuteT(t, "gaiad init") - var initRes map[string]interface{} - outCut := "{" + strings.SplitN(out, "{", 2)[1] - err := json.Unmarshal([]byte(outCut), &initRes) - require.NoError(t, err, "out %v outCut %v err %v", out, outCut, err) - masterKey := (initRes["secret"]).(string) - _ = masterKey - - //wc1, _ := tests.GoExecuteT(t, "gaiacli keys add foo --recover") - //time.Sleep(time.Second) - //_, err = wc1.Write([]byte("1234567890\n")) - //time.Sleep(time.Second) - //_, err = wc1.Write([]byte(masterKey + "\n")) - //time.Sleep(time.Second) - //out = <-outChan - //wc1.Close() - //fmt.Println(out) - - //_, out = tests.ExecuteT(t, "gaiacli keys show foo") - //fooAddr := strings.TrimLeft(out, "foo\t") - - //wc2, _ := tests.GoExecuteT(t, "gaiad start") - //defer wc2.Close() - //time.Sleep(time.Second) - - //_, out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v", fooAddr)) - //fmt.Println(fooAddr) -} diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go new file mode 100644 index 000000000..db5e272c1 --- /dev/null +++ b/cmd/gaia/cmd/cli_test.go @@ -0,0 +1,83 @@ +package common + +import ( + "encoding/json" + "fmt" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/tests" +) + +func TestGaiaCLI(t *testing.T) { + + // clear genesis/keys + _ = tests.ExecuteT(t, "gaiad unsafe_reset_all") + _, wc0, _ := tests.GoExecuteT(t, "gaiacli keys delete foo") + defer wc0.Close() + _, err := wc0.Write([]byte("1234567890\n")) + require.NoError(t, err) + _, wc1, _ := tests.GoExecuteT(t, "gaiacli keys delete bar") + defer wc1.Close() + _, err = wc1.Write([]byte("1234567890\n")) + require.NoError(t, err) + time.Sleep(time.Second) + + // init genesis get master key + out := tests.ExecuteT(t, "gaiad init") + var initRes map[string]interface{} + outCut := "{" + strings.SplitN(out, "{", 2)[1] + err = json.Unmarshal([]byte(outCut), &initRes) + require.NoError(t, err, "out %v outCut %v err %v", out, outCut, err) + masterKey := (initRes["secret"]).(string) + chainID := (initRes["chain_id"]).(string) + + // start gaiad server + _, wc2, _ := tests.GoExecuteT(t, "gaiad start") + defer wc2.Close() + time.Sleep(time.Second) + + // add the master key + _, wc3, _ := tests.GoExecuteT(t, "gaiacli keys add foo --recover") + defer wc3.Close() + _, err = wc3.Write([]byte("1234567890\n")) + require.NoError(t, err) + _, err = wc3.Write([]byte(masterKey + "\n")) + require.NoError(t, err) + time.Sleep(time.Second) + + // add a secondary key + _, wc4, _ := tests.GoExecuteT(t, "gaiacli keys add bar") + time.Sleep(time.Second * 5) + _, err = wc4.Write([]byte("1234567890\n")) + require.NoError(t, err) + time.Sleep(time.Second * 5) + + // get addresses + out = tests.ExecuteT(t, "gaiacli keys show foo") + fooAddr := strings.TrimLeft(out, "foo\t") + out = tests.ExecuteT(t, "gaiacli keys show bar") + barAddr := strings.TrimLeft(out, "bar\t") + fmt.Printf("debug barAddr: %v\n", barAddr) + + // send money from foo to bar + cmdStr := fmt.Sprintf("gaiacli send --sequence=0 --chain-id=%v --amount=10fermion --to=%v --name=foo", chainID, barAddr) + _, wc5, rc5 := tests.GoExecuteT(t, cmdStr) + _, err = wc5.Write([]byte("1234567890\n")) + require.NoError(t, err) + fmt.Printf("debug outCh: %v\n", out) + time.Sleep(time.Second) + bz := make([]byte, 1000000) + rc5.Read(bz) + fmt.Printf("debug ex: %v\n", string(bz)) + + // verify money sent to bar + time.Sleep(time.Second) + out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v", fooAddr)) + fmt.Printf("debug out: %v\n", out) + out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v", barAddr)) + require.Fail(t, "debug out: %v\n", out) +} diff --git a/tests/gobash.go b/tests/gobash.go index edef7ccd5..8095a7d90 100644 --- a/tests/gobash.go +++ b/tests/gobash.go @@ -2,6 +2,7 @@ package tests import ( "io" + "os" "os/exec" "strings" "testing" @@ -25,25 +26,27 @@ func getCmd(t *testing.T, command string) *exec.Cmd { } // Execute the command, return standard output and error -func ExecuteT(t *testing.T, command string) (pipe io.WriteCloser, out string) { +func ExecuteT(t *testing.T, command string) (out string) { cmd := getCmd(t, command) - pipe, err := cmd.StdinPipe() - require.NoError(t, err) bz, err := cmd.CombinedOutput() - require.NoError(t, err) + require.NoError(t, err, string(bz)) out = strings.Trim(string(bz), "\n") //trim any new lines - return pipe, out + return out } // Asynchronously execute the command, return standard output and error -func GoExecuteT(t *testing.T, command string) (pipe io.WriteCloser, outChan chan string) { +func GoExecuteT(t *testing.T, command string) (proc *os.Process, pipeIn io.WriteCloser, pipeOut io.ReadCloser) { cmd := getCmd(t, command) - pipe, err := cmd.StdinPipe() + pipeIn, err := cmd.StdinPipe() require.NoError(t, err) + pipeOut, err = cmd.StdoutPipe() + require.NoError(t, err) + go func() { - bz, err := cmd.CombinedOutput() - require.NoError(t, err) - outChan <- strings.Trim(string(bz), "\n") //trim any new lines + cmd.Start() + //bz, _ := cmd.CombinedOutput() + //require.NoError(t, err, string(bz)) + //outChan <- strings.Trim(string(bz), "\n") //trim any new lines }() - return pipe, outChan + return nil, pipeIn, pipeOut } From ebb2faabe07576584fd416ae2af6d6ee14947409 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 13 Apr 2018 19:45:26 -0400 Subject: [PATCH 017/176] go-bash working --- cmd/gaia/cmd/cli_test.go | 92 +++++++++++++++++++++++----------------- tests/gobash.go | 10 +++-- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go index db5e272c1..6d3e9db11 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cmd/cli_test.go @@ -3,81 +3,93 @@ package common import ( "encoding/json" "fmt" + "io" "strings" "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" + "github.com/cosmos/cosmos-sdk/x/auth" ) +func password(t *testing.T, wc io.WriteCloser) { + _, err := wc.Write([]byte("1234567890\n")) + require.NoError(t, err) +} + func TestGaiaCLI(t *testing.T) { // clear genesis/keys - _ = tests.ExecuteT(t, "gaiad unsafe_reset_all") - _, wc0, _ := tests.GoExecuteT(t, "gaiacli keys delete foo") - defer wc0.Close() - _, err := wc0.Write([]byte("1234567890\n")) - require.NoError(t, err) - _, wc1, _ := tests.GoExecuteT(t, "gaiacli keys delete bar") - defer wc1.Close() - _, err = wc1.Write([]byte("1234567890\n")) - require.NoError(t, err) - time.Sleep(time.Second) + tests.ExecuteT(t, "gaiad unsafe_reset_all") + cmd, wc0, _ := tests.GoExecuteT(t, "gaiacli keys delete foo") + password(t, wc0) + cmd.Wait() + cmd, wc1, _ := tests.GoExecuteT(t, "gaiacli keys delete bar") + password(t, wc1) + cmd.Wait() // init genesis get master key out := tests.ExecuteT(t, "gaiad init") var initRes map[string]interface{} - outCut := "{" + strings.SplitN(out, "{", 2)[1] - err = json.Unmarshal([]byte(outCut), &initRes) + outCut := "{" + strings.SplitN(out, "{", 2)[1] // weird I'm sorry + err := json.Unmarshal([]byte(outCut), &initRes) require.NoError(t, err, "out %v outCut %v err %v", out, outCut, err) masterKey := (initRes["secret"]).(string) chainID := (initRes["chain_id"]).(string) + servAddr := server.FreeTCPAddr(t) + gaiacliFlags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) + // start gaiad server - _, wc2, _ := tests.GoExecuteT(t, "gaiad start") - defer wc2.Close() - time.Sleep(time.Second) + cmd, _, _ = tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) + defer cmd.Process.Kill() // add the master key - _, wc3, _ := tests.GoExecuteT(t, "gaiacli keys add foo --recover") - defer wc3.Close() - _, err = wc3.Write([]byte("1234567890\n")) - require.NoError(t, err) + cmd, wc3, _ := tests.GoExecuteT(t, "gaiacli keys add foo --recover") + password(t, wc3) _, err = wc3.Write([]byte(masterKey + "\n")) require.NoError(t, err) - time.Sleep(time.Second) + cmd.Wait() // add a secondary key - _, wc4, _ := tests.GoExecuteT(t, "gaiacli keys add bar") - time.Sleep(time.Second * 5) - _, err = wc4.Write([]byte("1234567890\n")) - require.NoError(t, err) - time.Sleep(time.Second * 5) + cmd, wc4, _ := tests.GoExecuteT(t, "gaiacli keys add bar") + password(t, wc4) + cmd.Wait() // get addresses out = tests.ExecuteT(t, "gaiacli keys show foo") fooAddr := strings.TrimLeft(out, "foo\t") out = tests.ExecuteT(t, "gaiacli keys show bar") barAddr := strings.TrimLeft(out, "bar\t") - fmt.Printf("debug barAddr: %v\n", barAddr) // send money from foo to bar - cmdStr := fmt.Sprintf("gaiacli send --sequence=0 --chain-id=%v --amount=10fermion --to=%v --name=foo", chainID, barAddr) - _, wc5, rc5 := tests.GoExecuteT(t, cmdStr) - _, err = wc5.Write([]byte("1234567890\n")) - require.NoError(t, err) - fmt.Printf("debug outCh: %v\n", out) - time.Sleep(time.Second) - bz := make([]byte, 1000000) - rc5.Read(bz) - fmt.Printf("debug ex: %v\n", string(bz)) + cmdStr := fmt.Sprintf("gaiacli send %v --sequence=0 --amount=10fermion --to=%v --name=foo", gaiacliFlags, barAddr) + cmd, wc5, _ := tests.GoExecuteT(t, cmdStr) + password(t, wc5) + cmd.Wait() + time.Sleep(time.Second * 3) // waiting for some blocks to pass // verify money sent to bar - time.Sleep(time.Second) - out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v", fooAddr)) - fmt.Printf("debug out: %v\n", out) - out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v", barAddr)) - require.Fail(t, "debug out: %v\n", out) + out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v %v", barAddr, gaiacliFlags)) + barAcc := unmarshalBaseAccount(t, out) + assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) + + out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, gaiacliFlags)) + fooAcc := unmarshalBaseAccount(t, out) + assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion")) +} + +func unmarshalBaseAccount(t *testing.T, raw string) auth.BaseAccount { + var initRes map[string]json.RawMessage + err := json.Unmarshal([]byte(raw), &initRes) + require.NoError(t, err, "raw %v, err %v", raw, err) + value := initRes["value"] + var acc auth.BaseAccount + _ = json.Unmarshal(value, &acc) //XXX pubkey can't be decoded go amino issue + require.NoError(t, err, "value %v, err %v", string(value), err) + return acc } diff --git a/tests/gobash.go b/tests/gobash.go index 8095a7d90..5a177db94 100644 --- a/tests/gobash.go +++ b/tests/gobash.go @@ -2,10 +2,10 @@ package tests import ( "io" - "os" "os/exec" "strings" "testing" + "time" "github.com/stretchr/testify/require" ) @@ -31,12 +31,13 @@ func ExecuteT(t *testing.T, command string) (out string) { bz, err := cmd.CombinedOutput() require.NoError(t, err, string(bz)) out = strings.Trim(string(bz), "\n") //trim any new lines + time.Sleep(time.Second) return out } // Asynchronously execute the command, return standard output and error -func GoExecuteT(t *testing.T, command string) (proc *os.Process, pipeIn io.WriteCloser, pipeOut io.ReadCloser) { - cmd := getCmd(t, command) +func GoExecuteT(t *testing.T, command string) (cmd *exec.Cmd, pipeIn io.WriteCloser, pipeOut io.ReadCloser) { + cmd = getCmd(t, command) pipeIn, err := cmd.StdinPipe() require.NoError(t, err) pipeOut, err = cmd.StdoutPipe() @@ -48,5 +49,6 @@ func GoExecuteT(t *testing.T, command string) (proc *os.Process, pipeIn io.Write //require.NoError(t, err, string(bz)) //outChan <- strings.Trim(string(bz), "\n") //trim any new lines }() - return nil, pipeIn, pipeOut + time.Sleep(time.Second) + return cmd, pipeIn, pipeOut } From 59f86b42516d3102459886608968f3a8b6a1ce92 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 14 Apr 2018 03:16:49 -0400 Subject: [PATCH 018/176] interim borken --- cmd/gaia/cmd/cli_test.go | 106 ++++++++++++++++++++------------------- tests/gobash.go | 8 +-- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go index 6d3e9db11..d2e86d7f7 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cmd/cli_test.go @@ -3,7 +3,6 @@ package common import ( "encoding/json" "fmt" - "io" "strings" "testing" "time" @@ -16,77 +15,82 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" ) -func password(t *testing.T, wc io.WriteCloser) { - _, err := wc.Write([]byte("1234567890\n")) - require.NoError(t, err) -} - func TestGaiaCLI(t *testing.T) { - // clear genesis/keys tests.ExecuteT(t, "gaiad unsafe_reset_all") - cmd, wc0, _ := tests.GoExecuteT(t, "gaiacli keys delete foo") - password(t, wc0) - cmd.Wait() - cmd, wc1, _ := tests.GoExecuteT(t, "gaiacli keys delete bar") - password(t, wc1) - cmd.Wait() - - // init genesis get master key - out := tests.ExecuteT(t, "gaiad init") - var initRes map[string]interface{} - outCut := "{" + strings.SplitN(out, "{", 2)[1] // weird I'm sorry - err := json.Unmarshal([]byte(outCut), &initRes) - require.NoError(t, err, "out %v outCut %v err %v", out, outCut, err) - masterKey := (initRes["secret"]).(string) - chainID := (initRes["chain_id"]).(string) + pass := "1234567890" + executeWrite(t, "gaiacli keys delete foo", pass) + executeWrite(t, "gaiacli keys delete bar", pass) + masterKey, chainID := executeInit(t, "gaiad init") + // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) - gaiacliFlags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) + flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) // start gaiad server - cmd, _, _ = tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) + cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() + time.Sleep(time.Second) // waiting for some blocks to pass - // add the master key + //executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) cmd, wc3, _ := tests.GoExecuteT(t, "gaiacli keys add foo --recover") - password(t, wc3) + time.Sleep(time.Second) // waiting for some blocks to pass + _, err := wc3.Write([]byte("1234567890\n")) + require.NoError(t, err) _, err = wc3.Write([]byte(masterKey + "\n")) require.NoError(t, err) cmd.Wait() + time.Sleep(time.Second * 5) // waiting for some blocks to pass + fooAddr := executeGetAddr(t, "gaiacli keys show foo") + panic(fmt.Sprintf("debug fooAddr: %v\n", fooAddr)) - // add a secondary key - cmd, wc4, _ := tests.GoExecuteT(t, "gaiacli keys add bar") - password(t, wc4) - cmd.Wait() - - // get addresses - out = tests.ExecuteT(t, "gaiacli keys show foo") - fooAddr := strings.TrimLeft(out, "foo\t") - out = tests.ExecuteT(t, "gaiacli keys show bar") - barAddr := strings.TrimLeft(out, "bar\t") - - // send money from foo to bar - cmdStr := fmt.Sprintf("gaiacli send %v --sequence=0 --amount=10fermion --to=%v --name=foo", gaiacliFlags, barAddr) - cmd, wc5, _ := tests.GoExecuteT(t, cmdStr) - password(t, wc5) - cmd.Wait() + executeWrite(t, "gaiacli keys add bar", pass) + barAddr := executeGetAddr(t, "gaiacli keys show bar") + executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass - // verify money sent to bar - out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v %v", barAddr, gaiacliFlags)) - barAcc := unmarshalBaseAccount(t, out) + barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) - - out = tests.ExecuteT(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, gaiacliFlags)) - fooAcc := unmarshalBaseAccount(t, out) + fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion")) + + // declare candidacy + //executeWrite(t, "gaiacli declare-candidacy -", pass) } -func unmarshalBaseAccount(t *testing.T, raw string) auth.BaseAccount { +func executeWrite(t *testing.T, cmdStr string, writes ...string) { + cmd, wc, _ := tests.GoExecuteT(t, cmdStr) + for _, write := range writes { + _, err := wc.Write([]byte(write + "\n")) + require.NoError(t, err) + } + cmd.Wait() +} + +func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { + tests.GoExecuteT(t, cmdStr) + out := tests.ExecuteT(t, cmdStr) + outCut := "{" + strings.SplitN(out, "{", 2)[1] // weird I'm sorry + var initRes map[string]json.RawMessage - err := json.Unmarshal([]byte(raw), &initRes) - require.NoError(t, err, "raw %v, err %v", raw, err) + err := json.Unmarshal([]byte(outCut), &initRes) + require.NoError(t, err, "out %v outCut %v err %v", out, outCut, err) + masterKey = string(initRes["secret"]) + chainID = string(initRes["chain_id"]) + return +} + +func executeGetAddr(t *testing.T, cmdStr string) (addr string) { + out := tests.ExecuteT(t, cmdStr) + name := strings.SplitN(cmdStr, " show ", 2)[1] + return strings.TrimLeft(out, name+"\t") +} + +func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { + out := tests.ExecuteT(t, cmdStr) + var initRes map[string]json.RawMessage + err := json.Unmarshal([]byte(out), &initRes) + require.NoError(t, err, "out %v, err %v", out, err) value := initRes["value"] var acc auth.BaseAccount _ = json.Unmarshal(value, &acc) //XXX pubkey can't be decoded go amino issue diff --git a/tests/gobash.go b/tests/gobash.go index 5a177db94..12b3da085 100644 --- a/tests/gobash.go +++ b/tests/gobash.go @@ -42,13 +42,7 @@ func GoExecuteT(t *testing.T, command string) (cmd *exec.Cmd, pipeIn io.WriteClo require.NoError(t, err) pipeOut, err = cmd.StdoutPipe() require.NoError(t, err) - - go func() { - cmd.Start() - //bz, _ := cmd.CombinedOutput() - //require.NoError(t, err, string(bz)) - //outChan <- strings.Trim(string(bz), "\n") //trim any new lines - }() + go cmd.Start() time.Sleep(time.Second) return cmd, pipeIn, pipeOut } From 158e9dd12d2e5b81a0dc88bd7bd525e9786b9915 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 14 Apr 2018 13:06:54 -0400 Subject: [PATCH 019/176] fixed cli tests --- cmd/gaia/cmd/cli_test.go | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go index d2e86d7f7..eb31aaad1 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cmd/cli_test.go @@ -30,21 +30,11 @@ func TestGaiaCLI(t *testing.T) { // start gaiad server cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - time.Sleep(time.Second) // waiting for some blocks to pass - - //executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) - cmd, wc3, _ := tests.GoExecuteT(t, "gaiacli keys add foo --recover") - time.Sleep(time.Second) // waiting for some blocks to pass - _, err := wc3.Write([]byte("1234567890\n")) - require.NoError(t, err) - _, err = wc3.Write([]byte(masterKey + "\n")) - require.NoError(t, err) - cmd.Wait() - time.Sleep(time.Second * 5) // waiting for some blocks to pass - fooAddr := executeGetAddr(t, "gaiacli keys show foo") - panic(fmt.Sprintf("debug fooAddr: %v\n", fooAddr)) + executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) executeWrite(t, "gaiacli keys add bar", pass) + + fooAddr := executeGetAddr(t, "gaiacli keys show foo") barAddr := executeGetAddr(t, "gaiacli keys show bar") executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass @@ -68,15 +58,16 @@ func executeWrite(t *testing.T, cmdStr string, writes ...string) { } func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { - tests.GoExecuteT(t, cmdStr) out := tests.ExecuteT(t, cmdStr) outCut := "{" + strings.SplitN(out, "{", 2)[1] // weird I'm sorry var initRes map[string]json.RawMessage err := json.Unmarshal([]byte(outCut), &initRes) - require.NoError(t, err, "out %v outCut %v err %v", out, outCut, err) - masterKey = string(initRes["secret"]) - chainID = string(initRes["chain_id"]) + require.NoError(t, err) + err = json.Unmarshal(initRes["secret"], &masterKey) + require.NoError(t, err) + err = json.Unmarshal(initRes["chain_id"], &chainID) + require.NoError(t, err) return } From e584d5acacc96108a1f028e69810946295a9aa10 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 14 Apr 2018 16:52:58 -0400 Subject: [PATCH 020/176] ci build -> install pubkey issue ... rebase fixes ... --- Makefile | 2 +- client/keys/wire.go | 6 ++++ cmd/gaia/app/app.go | 14 +++----- cmd/gaia/app/app_test.go | 19 ++++------- cmd/gaia/cmd/cli_test.go | 68 ++++++++++++++++++++++++++++++-------- cmd/gaia/cmd/gaiad/main.go | 2 +- x/stake/commands/tx.go | 4 ++- x/stake/types.go | 26 ++++++++++++--- 8 files changed, 98 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 78a5c9dcc..daa0361fc 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ all: check_tools get_vendor_deps build build_examples test ######################################## ### CI -ci: get_tools get_vendor_deps build test_cover +ci: get_tools get_vendor_deps install test_cover ######################################## ### Build diff --git a/client/keys/wire.go b/client/keys/wire.go index 225e60ae7..a163f995a 100644 --- a/client/keys/wire.go +++ b/client/keys/wire.go @@ -11,6 +11,12 @@ func init() { wire.RegisterCrypto(cdc) } +// marshal keys func MarshalJSON(o interface{}) ([]byte, error) { return cdc.MarshalJSON(o) } + +// unmarshal json +func UnmarshalJSON(bz []byte, ptr interface{}) error { + return cdc.UnmarshalJSON(bz, ptr) +} diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index eeb64a7a7..0c9ef8b55 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -39,10 +39,10 @@ type GaiaApp struct { stakeKeeper stake.Keeper } -func NewGaiaApp(logger log.Logger, dbs map[string]dbm.DB) *GaiaApp { +func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { // create your application object var app = &GaiaApp{ - BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]), + BaseApp: bam.NewBaseApp(appName, logger, db), cdc: MakeCodec(), capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyAccountStore: sdk.NewKVStoreKey("acc"), @@ -70,13 +70,7 @@ func NewGaiaApp(logger log.Logger, dbs map[string]dbm.DB) *GaiaApp { app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) - app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"]) - app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"]) - app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"]) - app.MountStoreWithDB(app.capKeyStakeStore, sdk.StoreTypeIAVL, dbs["stake"]) - - // NOTE: Broken until #532 lands - //app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakeStore) + app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyIBCStore, app.capKeyStakeStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { @@ -116,7 +110,7 @@ func (app *GaiaApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { } // StdTx.Msg is an interface. The concrete types - // are registered by MakeTxCodec in bank.RegisterWire. + // are registered by MakeTxCodec err := app.cdc.UnmarshalBinary(txBytes, &tx) if err != nil { return nil, sdk.ErrTxDecode("").TraceCause(err, "") diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index ea10cebc5..5c8450138 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -85,20 +85,15 @@ var ( } ) -func loggerAndDBs() (log.Logger, map[string]dbm.DB) { +func loggerAndDB() (log.Logger, dbm.DB) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - dbs := map[string]dbm.DB{ - "main": dbm.NewMemDB(), - "acc": dbm.NewMemDB(), - "ibc": dbm.NewMemDB(), - "stake": dbm.NewMemDB(), - } - return logger, dbs + db := dbm.NewMemDB() + return logger, db } func newGaiaApp() *GaiaApp { - logger, dbs := loggerAndDBs() - return NewGaiaApp(logger, dbs) + logger, db := loggerAndDB() + return NewGaiaApp(logger, db) } func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { @@ -144,7 +139,7 @@ func TestMsgs(t *testing.T) { } func TestSortGenesis(t *testing.T) { - logger, dbs := loggerAndDBs() + logger, dbs := loggerAndDB() gapp := NewGaiaApp(logger, dbs) // Note the order: the coins are unsorted! @@ -188,7 +183,7 @@ func TestSortGenesis(t *testing.T) { } func TestGenesis(t *testing.T) { - logger, dbs := loggerAndDBs() + logger, dbs := loggerAndDB() gapp := NewGaiaApp(logger, dbs) // Construct some genesis bytes to reflect GaiaAccount diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go index eb31aaad1..c537ae0a5 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cmd/cli_test.go @@ -1,6 +1,7 @@ package common import ( + "encoding/hex" "encoding/json" "fmt" "strings" @@ -10,17 +11,20 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" "github.com/cosmos/cosmos-sdk/x/auth" + crypto "github.com/tendermint/go-crypto" + crkeys "github.com/tendermint/go-crypto/keys" ) func TestGaiaCLI(t *testing.T) { tests.ExecuteT(t, "gaiad unsafe_reset_all") pass := "1234567890" - executeWrite(t, "gaiacli keys delete foo", pass) - executeWrite(t, "gaiacli keys delete bar", pass) + executeWrite(t, false, "gaiacli keys delete foo", pass) + executeWrite(t, false, "gaiacli keys delete bar", pass) masterKey, chainID := executeInit(t, "gaiad init") // get a free port, also setup some common flags @@ -31,25 +35,55 @@ func TestGaiaCLI(t *testing.T) { cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) - executeWrite(t, "gaiacli keys add bar", pass) + executeWrite(t, false, "gaiacli keys add foo --recover", pass, masterKey) + executeWrite(t, false, "gaiacli keys add bar", pass) - fooAddr := executeGetAddr(t, "gaiacli keys show foo") - barAddr := executeGetAddr(t, "gaiacli keys show bar") - executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) + fooAddr, fooPubKey := executeGetAddr(t, "gaiacli keys show foo --output=json") + barAddr, _ := executeGetAddr(t, "gaiacli keys show bar --output=json") + + fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) + + executeWrite(t, false, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) - fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion")) // declare candidacy - //executeWrite(t, "gaiacli declare-candidacy -", pass) + //--address-candidate string hex address of the validator/candidate + //--amount string Amount of coins to bond (default "1fermion") + //--chain-id string Chain ID of tendermint node + //--fee string Fee to pay along with transaction + //--keybase-sig string optional keybase signature + //--moniker string validator-candidate name + //--name string Name of private key with which to sign + //--node string : to tendermint rpc interface for this chain (default "tcp://localhost:46657") + //--pubkey string PubKey of the validator-candidate + //--sequence int Sequence number to sign the tx + //--website string optional website + _ = fooPubKey + //declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags) + //declStr += fmt.Sprintf(" --name=%v", "foo") + //declStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) + //declStr += fmt.Sprintf(" --pubkey=%v", fooPubKey) + //declStr += fmt.Sprintf(" --amount=%v", "3fermion") + //declStr += fmt.Sprintf(" --moniker=%v", "foo-vally") + //fmt.Printf("debug declStr: %v\n", declStr) + //executeWrite(t, true, declStr, pass) } -func executeWrite(t *testing.T, cmdStr string, writes ...string) { - cmd, wc, _ := tests.GoExecuteT(t, cmdStr) +func executeWrite(t *testing.T, print bool, cmdStr string, writes ...string) { + cmd, wc, rc := tests.GoExecuteT(t, cmdStr) + + if print { + bz := make([]byte, 100000) + rc.Read(bz) + fmt.Printf("debug read: %v\n", string(bz)) + } + for _, write := range writes { _, err := wc.Write([]byte(write + "\n")) require.NoError(t, err) @@ -71,10 +105,16 @@ func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { return } -func executeGetAddr(t *testing.T, cmdStr string) (addr string) { +func executeGetAddr(t *testing.T, cmdStr string) (addr, pubKey string) { out := tests.ExecuteT(t, cmdStr) - name := strings.SplitN(cmdStr, " show ", 2)[1] - return strings.TrimLeft(out, name+"\t") + var info crkeys.Info + keys.UnmarshalJSON([]byte(out), &info) + pubKey = hex.EncodeToString(info.PubKey.(crypto.PubKeyEd25519).Bytes()) + pubKey = strings.TrimLeft(pubKey, "1624de6220") + fmt.Printf("debug pubKey: %v\n", pubKey) + addr = info.PubKey.Address().String() + fmt.Printf("debug addr: %v\n", addr) + return } func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index b84a4e20d..91ea778f7 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -31,7 +31,7 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { if err != nil { return nil, err } - bapp := app.NewBasecoinApp(logger, db) + bapp := app.NewGaiaApp(logger, db) //dbAcc, err := dbm.NewGoLevelDB("gaia-acc", dataDir) //if err != nil { //return nil, err diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index 679e59b15..76220aeb6 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -269,9 +269,11 @@ func GetPubKey(pubKeyStr string) (pk crypto.PubKey, err error) { return } if len(pubKeyStr) != 64 { //if len(pkBytes) != 32 { - err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters long") + err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters, this pubkey is %v characters", len(pubKeyStr)) return } + + // TODO: bech32 ... var pkBytes []byte pkBytes, err = hex.DecodeString(pubKeyStr) if err != nil { diff --git a/x/stake/types.go b/x/stake/types.go index 240f3fe2a..14978ce35 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -1,6 +1,8 @@ package stake import ( + "encoding/hex" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" abci "github.com/tendermint/abci/types" @@ -131,12 +133,20 @@ type Validator struct { // abci validator from stake validator type func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator { - pkBytes, err := cdc.MarshalBinary(v.PubKey) + //pkBytes, err := cdc.MarshalBinary(v.PubKey) + //if err != nil { + //panic(err) + //} + //return abci.Validator{ + //PubKey: pkBytes, + //Power: v.Power.Evaluate(), + //} + TypeDistinguisher, err := hex.DecodeString("1624de6220") if err != nil { panic(err) } return abci.Validator{ - PubKey: pkBytes, + PubKey: append(TypeDistinguisher, v.PubKey.Bytes()...), Power: v.Power.Evaluate(), } } @@ -144,12 +154,20 @@ func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator { // abci validator from stake validator type // with zero power used for validator updates func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator { - pkBytes, err := cdc.MarshalBinary(v.PubKey) + //pkBytes, err := cdc.MarshalBinary(v.PubKey) + //if err != nil { + //panic(err) + //} + //return abci.Validator{ + //PubKey: pkBytes, + //Power: 0, + //} + TypeDistinguisher, err := hex.DecodeString("1624de6220") if err != nil { panic(err) } return abci.Validator{ - PubKey: pkBytes, + PubKey: append(TypeDistinguisher, v.PubKey.Bytes()...), Power: 0, } } From 265670297cf5864cd34893366f4310949c27a58b Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 16 Apr 2018 16:47:28 -0400 Subject: [PATCH 021/176] fix PK encodings --- cmd/gaia/cmd/cli_test.go | 42 ++++++++++++++++++++-------------------- x/stake/keeper_test.go | 20 +++++-------------- x/stake/types.go | 30 ++-------------------------- 3 files changed, 28 insertions(+), 64 deletions(-) diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go index c537ae0a5..a2bf5a3ca 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cmd/cli_test.go @@ -23,8 +23,8 @@ func TestGaiaCLI(t *testing.T) { tests.ExecuteT(t, "gaiad unsafe_reset_all") pass := "1234567890" - executeWrite(t, false, "gaiacli keys delete foo", pass) - executeWrite(t, false, "gaiacli keys delete bar", pass) + executeWrite(t, "gaiacli keys delete foo", pass) + executeWrite(t, "gaiacli keys delete bar", pass) masterKey, chainID := executeInit(t, "gaiad init") // get a free port, also setup some common flags @@ -35,8 +35,8 @@ func TestGaiaCLI(t *testing.T) { cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - executeWrite(t, false, "gaiacli keys add foo --recover", pass, masterKey) - executeWrite(t, false, "gaiacli keys add bar", pass) + executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) + executeWrite(t, "gaiacli keys add bar", pass) fooAddr, fooPubKey := executeGetAddr(t, "gaiacli keys show foo --output=json") barAddr, _ := executeGetAddr(t, "gaiacli keys show bar --output=json") @@ -44,7 +44,7 @@ func TestGaiaCLI(t *testing.T) { fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) - executeWrite(t, false, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) + executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) @@ -64,25 +64,25 @@ func TestGaiaCLI(t *testing.T) { //--pubkey string PubKey of the validator-candidate //--sequence int Sequence number to sign the tx //--website string optional website - _ = fooPubKey - //declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags) - //declStr += fmt.Sprintf(" --name=%v", "foo") - //declStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) - //declStr += fmt.Sprintf(" --pubkey=%v", fooPubKey) - //declStr += fmt.Sprintf(" --amount=%v", "3fermion") - //declStr += fmt.Sprintf(" --moniker=%v", "foo-vally") - //fmt.Printf("debug declStr: %v\n", declStr) - //executeWrite(t, true, declStr, pass) + //_ = fooPubKey + declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags) + declStr += fmt.Sprintf(" --name=%v", "foo") + declStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) + declStr += fmt.Sprintf(" --pubkey=%v", fooPubKey) + declStr += fmt.Sprintf(" --amount=%v", "3fermion") + declStr += fmt.Sprintf(" --moniker=%v", "foo-vally") + fmt.Printf("debug declStr: %v\n", declStr) + executeWrite(t, declStr, pass) } -func executeWrite(t *testing.T, print bool, cmdStr string, writes ...string) { - cmd, wc, rc := tests.GoExecuteT(t, cmdStr) +func executeWrite(t *testing.T, cmdStr string, writes ...string) { + cmd, wc, _ := tests.GoExecuteT(t, cmdStr) - if print { - bz := make([]byte, 100000) - rc.Read(bz) - fmt.Printf("debug read: %v\n", string(bz)) - } + //if print { + //bz := make([]byte, 100000) + //rc.Read(bz) + //fmt.Printf("debug read: %v\n", string(bz)) + //} for _, write := range writes { _, err := wc.Write([]byte(write + "\n")) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 9d6f69cc6..e01df1aae 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -5,7 +5,6 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" - crypto "github.com/tendermint/go-crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -315,15 +314,6 @@ func TestGetAccUpdateValidators(t *testing.T) { } } - // to compare pubkeys between abci pubkey and crypto.PubKey - wirePK := func(pk crypto.PubKey) []byte { - pkBytes, err := keeper.cdc.MarshalBinary(pk) - if err != nil { - panic(err) - } - return pkBytes - } - // test from nothing to something // candidate set: {} -> {c1, c3} // validator set: {} -> {c1, c3} @@ -478,7 +468,7 @@ func TestGetAccUpdateValidators(t *testing.T) { acc = keeper.getAccUpdateValidators(ctx) require.Equal(t, 2, len(acc), "%v", acc) - assert.Equal(t, wirePK(candidatesIn[0].PubKey), acc[0].PubKey) + assert.Equal(t, candidatesIn[0].PubKey.Bytes(), acc[0].PubKey) assert.Equal(t, int64(0), acc[0].Power) assert.Equal(t, vals[0].abciValidator(keeper.cdc), acc[1]) @@ -503,10 +493,10 @@ func TestGetAccUpdateValidators(t *testing.T) { require.Equal(t, 0, len(candidates)) acc = keeper.getAccUpdateValidators(ctx) require.Equal(t, 4, len(acc)) - assert.Equal(t, wirePK(candidatesIn[1].PubKey), acc[0].PubKey) - assert.Equal(t, wirePK(candidatesIn[2].PubKey), acc[1].PubKey) - assert.Equal(t, wirePK(candidatesIn[3].PubKey), acc[2].PubKey) - assert.Equal(t, wirePK(candidatesIn[4].PubKey), acc[3].PubKey) + assert.Equal(t, candidatesIn[1].PubKey.Bytes(), acc[0].PubKey) + assert.Equal(t, candidatesIn[2].PubKey.Bytes(), acc[1].PubKey) + assert.Equal(t, candidatesIn[3].PubKey.Bytes(), acc[2].PubKey) + assert.Equal(t, candidatesIn[4].PubKey.Bytes(), acc[3].PubKey) assert.Equal(t, int64(0), acc[0].Power) assert.Equal(t, int64(0), acc[1].Power) assert.Equal(t, int64(0), acc[2].Power) diff --git a/x/stake/types.go b/x/stake/types.go index 14978ce35..b0dbc0b1f 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -1,8 +1,6 @@ package stake import ( - "encoding/hex" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" abci "github.com/tendermint/abci/types" @@ -133,20 +131,8 @@ type Validator struct { // abci validator from stake validator type func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator { - //pkBytes, err := cdc.MarshalBinary(v.PubKey) - //if err != nil { - //panic(err) - //} - //return abci.Validator{ - //PubKey: pkBytes, - //Power: v.Power.Evaluate(), - //} - TypeDistinguisher, err := hex.DecodeString("1624de6220") - if err != nil { - panic(err) - } return abci.Validator{ - PubKey: append(TypeDistinguisher, v.PubKey.Bytes()...), + PubKey: v.PubKey.Bytes(), Power: v.Power.Evaluate(), } } @@ -154,20 +140,8 @@ func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator { // abci validator from stake validator type // with zero power used for validator updates func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator { - //pkBytes, err := cdc.MarshalBinary(v.PubKey) - //if err != nil { - //panic(err) - //} - //return abci.Validator{ - //PubKey: pkBytes, - //Power: 0, - //} - TypeDistinguisher, err := hex.DecodeString("1624de6220") - if err != nil { - panic(err) - } return abci.Validator{ - PubKey: append(TypeDistinguisher, v.PubKey.Bytes()...), + PubKey: v.PubKey.Bytes(), Power: 0, } } From 09fe4c0262cd9a8160e6dd31ee107411e98e507a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 16 Apr 2018 19:17:09 -0400 Subject: [PATCH 022/176] fix stake query keys --- cmd/gaia/cmd/cli_test.go | 72 +++++++++++++++++++++++++++----------- cmd/gaia/cmd/gaiad/main.go | 19 ---------- x/stake/commands/query.go | 16 +++------ x/stake/commands/tx.go | 8 ++--- 4 files changed, 61 insertions(+), 54 deletions(-) diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go index a2bf5a3ca..225c2bd07 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cmd/cli_test.go @@ -19,12 +19,45 @@ import ( crkeys "github.com/tendermint/go-crypto/keys" ) -func TestGaiaCLI(t *testing.T) { +//func TestGaiaCLISend(t *testing.T) { + +//tests.ExecuteT(t, "gaiad unsafe_reset_all") +//pass := "1234567890" +//executeWrite(t, "gaiacli keys delete foo", pass) +//executeWrite(t, "gaiacli keys delete bar", pass) +//masterKey, chainID := executeInit(t, "gaiad init") + +//// get a free port, also setup some common flags +//servAddr := server.FreeTCPAddr(t) +//flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) + +//// start gaiad server +//cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) +//defer cmd.Process.Kill() + +//executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) +//executeWrite(t, "gaiacli keys add bar", pass) + +//fooAddr, _ := executeGetAddr(t, "gaiacli keys show foo --output=json") +//barAddr, _ := executeGetAddr(t, "gaiacli keys show bar --output=json") + +//fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) +//assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) + +//executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) +//time.Sleep(time.Second * 3) // waiting for some blocks to pass + +//barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) +//assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) +//fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) +//assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion")) +//} + +func TestGaiaCLIDeclareCandidacy(t *testing.T) { tests.ExecuteT(t, "gaiad unsafe_reset_all") pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) - executeWrite(t, "gaiacli keys delete bar", pass) masterKey, chainID := executeInit(t, "gaiad init") // get a free port, also setup some common flags @@ -36,22 +69,10 @@ func TestGaiaCLI(t *testing.T) { defer cmd.Process.Kill() executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) - executeWrite(t, "gaiacli keys add bar", pass) - fooAddr, fooPubKey := executeGetAddr(t, "gaiacli keys show foo --output=json") - barAddr, _ := executeGetAddr(t, "gaiacli keys show bar --output=json") - fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) - executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) - time.Sleep(time.Second * 3) // waiting for some blocks to pass - - barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) - assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) - fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion")) - // declare candidacy //--address-candidate string hex address of the validator/candidate //--amount string Amount of coins to bond (default "1fermion") @@ -73,17 +94,14 @@ func TestGaiaCLI(t *testing.T) { declStr += fmt.Sprintf(" --moniker=%v", "foo-vally") fmt.Printf("debug declStr: %v\n", declStr) executeWrite(t, declStr, pass) + fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + time.Sleep(time.Second * 3) // waiting for some blocks to pass + assert.Equal(t, int64(99997), fooAcc.GetCoins().AmountOf("fermion")) } func executeWrite(t *testing.T, cmdStr string, writes ...string) { cmd, wc, _ := tests.GoExecuteT(t, cmdStr) - //if print { - //bz := make([]byte, 100000) - //rc.Read(bz) - //fmt.Printf("debug read: %v\n", string(bz)) - //} - for _, write := range writes { _, err := wc.Write([]byte(write + "\n")) require.NoError(t, err) @@ -91,6 +109,20 @@ func executeWrite(t *testing.T, cmdStr string, writes ...string) { cmd.Wait() } +func executeWritePrint(t *testing.T, cmdStr string, writes ...string) { + cmd, wc, rc := tests.GoExecuteT(t, cmdStr) + + for _, write := range writes { + _, err := wc.Write([]byte(write + "\n")) + require.NoError(t, err) + } + cmd.Wait() + + bz := make([]byte, 100000) + rc.Read(bz) + fmt.Printf("debug read: %v\n", string(bz)) +} + func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { out := tests.ExecuteT(t, cmdStr) outCut := "{" + strings.SplitN(out, "{", 2)[1] // weird I'm sorry diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 91ea778f7..199a06152 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -32,25 +32,6 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { return nil, err } bapp := app.NewGaiaApp(logger, db) - //dbAcc, err := dbm.NewGoLevelDB("gaia-acc", dataDir) - //if err != nil { - //return nil, err - //} - //dbIBC, err := dbm.NewGoLevelDB("gaia-ibc", dataDir) - //if err != nil { - //return nil, err - //} - //dbStake, err := dbm.NewGoLevelDB("gaia-stake", dataDir) - //if err != nil { - //return nil, err - //} - //dbs := map[string]dbm.DB{ - //"main": dbMain, - //"acc": dbAcc, - //"ibc": dbIBC, - //"stake": dbStake, - //} - //bapp := app.NewGaiaApp(logger, dbs) return bapp, nil } diff --git a/x/stake/commands/query.go b/x/stake/commands/query.go index 38e16f333..187de702c 100644 --- a/x/stake/commands/query.go +++ b/x/stake/commands/query.go @@ -16,12 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" ) -// XXX remove dependancy -func PrefixedKey(app string, key []byte) []byte { - prefix := append([]byte(app), byte(0)) - return append(prefix, key...) -} - //nolint var ( fsValAddr = flag.NewFlagSet("", flag.ContinueOnError) @@ -44,7 +38,7 @@ func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command { Short: "Query for the set of validator-candidates pubkeys", RunE: func(cmd *cobra.Command, args []string) error { - key := PrefixedKey(stake.MsgType, stake.CandidatesKey) + key := stake.CandidatesKey ctx := context.NewCoreContextFromViper() res, err := ctx.Query(key, storeName) @@ -54,7 +48,7 @@ func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command { // parse out the candidates candidates := new(stake.Candidates) - err = cdc.UnmarshalJSON(res, candidates) + err = cdc.UnmarshalBinary(res, candidates) if err != nil { return err } @@ -85,7 +79,7 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { return err } - key := PrefixedKey(stake.MsgType, stake.GetCandidateKey(addr)) + key := stake.GetCandidateKey(addr) ctx := context.NewCoreContextFromViper() @@ -133,7 +127,7 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command } delegator := crypto.Address(bz) - key := PrefixedKey(stake.MsgType, stake.GetDelegatorBondKey(delegator, addr, cdc)) + key := stake.GetDelegatorBondKey(delegator, addr, cdc) ctx := context.NewCoreContextFromViper() @@ -177,7 +171,7 @@ func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command } delegator := crypto.Address(bz) - key := PrefixedKey(stake.MsgType, stake.GetDelegatorBondsKey(delegator, cdc)) + key := stake.GetDelegatorBondsKey(delegator, cdc) ctx := context.NewCoreContextFromViper() diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index 76220aeb6..bc8f93e8f 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -268,10 +268,10 @@ func GetPubKey(pubKeyStr string) (pk crypto.PubKey, err error) { err = fmt.Errorf("must use --pubkey flag") return } - if len(pubKeyStr) != 64 { //if len(pkBytes) != 32 { - err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters, this pubkey is %v characters", len(pubKeyStr)) - return - } + //if len(pubKeyStr) != 64 { //if len(pkBytes) != 32 { + //err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters, this pubkey is %v characters", len(pubKeyStr)) + //return + //} // TODO: bech32 ... var pkBytes []byte From d344de3b629e11cf423c988cd06b8c069f97ba03 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 16 Apr 2018 19:49:00 -0400 Subject: [PATCH 023/176] stake test candidate query --- cmd/gaia/cmd/cli_test.go | 69 +++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go index 225c2bd07..8011d7a69 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cmd/cli_test.go @@ -12,46 +12,48 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/stake" crypto "github.com/tendermint/go-crypto" crkeys "github.com/tendermint/go-crypto/keys" ) -//func TestGaiaCLISend(t *testing.T) { +func TestGaiaCLISend(t *testing.T) { -//tests.ExecuteT(t, "gaiad unsafe_reset_all") -//pass := "1234567890" -//executeWrite(t, "gaiacli keys delete foo", pass) -//executeWrite(t, "gaiacli keys delete bar", pass) -//masterKey, chainID := executeInit(t, "gaiad init") + tests.ExecuteT(t, "gaiad unsafe_reset_all") + pass := "1234567890" + executeWrite(t, "gaiacli keys delete foo", pass) + executeWrite(t, "gaiacli keys delete bar", pass) + masterKey, chainID := executeInit(t, "gaiad init") -//// get a free port, also setup some common flags -//servAddr := server.FreeTCPAddr(t) -//flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) + // get a free port, also setup some common flags + servAddr := server.FreeTCPAddr(t) + flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID) -//// start gaiad server -//cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) -//defer cmd.Process.Kill() + // start gaiad server + cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) + defer cmd.Process.Kill() -//executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) -//executeWrite(t, "gaiacli keys add bar", pass) + executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) + executeWrite(t, "gaiacli keys add bar", pass) -//fooAddr, _ := executeGetAddr(t, "gaiacli keys show foo --output=json") -//barAddr, _ := executeGetAddr(t, "gaiacli keys show bar --output=json") + fooAddr, _ := executeGetAddr(t, "gaiacli keys show foo --output=json") + barAddr, _ := executeGetAddr(t, "gaiacli keys show bar --output=json") -//fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) -//assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) + fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) -//executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) -//time.Sleep(time.Second * 3) // waiting for some blocks to pass + executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) + time.Sleep(time.Second * 3) // waiting for some blocks to pass -//barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) -//assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) -//fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) -//assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion")) -//} + barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) + assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) + fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion")) +} func TestGaiaCLIDeclareCandidacy(t *testing.T) { @@ -94,9 +96,11 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { declStr += fmt.Sprintf(" --moniker=%v", "foo-vally") fmt.Printf("debug declStr: %v\n", declStr) executeWrite(t, declStr, pass) - fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) time.Sleep(time.Second * 3) // waiting for some blocks to pass + fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(99997), fooAcc.GetCoins().AmountOf("fermion")) + candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address=%v", flags, fooAddr)) + assert.Equal(t, candidate.Address.String(), fooAddr) } func executeWrite(t *testing.T, cmdStr string, writes ...string) { @@ -142,7 +146,11 @@ func executeGetAddr(t *testing.T, cmdStr string) (addr, pubKey string) { var info crkeys.Info keys.UnmarshalJSON([]byte(out), &info) pubKey = hex.EncodeToString(info.PubKey.(crypto.PubKeyEd25519).Bytes()) + + // TODO this is really wierd, also error that not 64 characters! pubKey = strings.TrimLeft(pubKey, "1624de6220") + pubKey = fmt.Sprintf("%064v", pubKey) + fmt.Printf("debug pubKey: %v\n", pubKey) addr = info.PubKey.Address().String() fmt.Printf("debug addr: %v\n", addr) @@ -160,3 +168,12 @@ func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { require.NoError(t, err, "value %v, err %v", string(value), err) return acc } + +func executeGetCandidate(t *testing.T, cmdStr string) stake.Candidate { + out := tests.ExecuteT(t, cmdStr) + var candidate stake.Candidate + cdc := app.MakeCodec() + err := cdc.UnmarshalJSON([]byte(out), &candidate) + require.NoError(t, err, "out %v, err %v", out, err) + return candidate +} From 45723733bcb58525e172ce47a4208ae77dcddfac Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 17 Apr 2018 13:38:14 -0400 Subject: [PATCH 024/176] fix staking flags --- x/stake/commands/tx.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index bc8f93e8f..55e009db0 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -49,6 +49,7 @@ func init() { fsCandidate.String(FlagIdentity, "", "optional keybase signature") fsCandidate.String(FlagWebsite, "", "optional website") fsCandidate.String(FlagAddressCandidate, "", "hex address of the validator/candidate") + fsDelegator.String(FlagAddressCandidate, "", "hex address of the delegator") fsDelegator.String(FlagAddressDelegator, "", "hex address of the delegator") } @@ -155,7 +156,6 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command { }, } - cmd.Flags().AddFlagSet(fsPk) cmd.Flags().AddFlagSet(fsCandidate) return cmd } @@ -198,7 +198,6 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { }, } - cmd.Flags().AddFlagSet(fsPk) cmd.Flags().AddFlagSet(fsAmount) cmd.Flags().AddFlagSet(fsDelegator) return cmd @@ -252,7 +251,6 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command { }, } - cmd.Flags().AddFlagSet(fsPk) cmd.Flags().AddFlagSet(fsShares) cmd.Flags().AddFlagSet(fsDelegator) return cmd @@ -268,10 +266,10 @@ func GetPubKey(pubKeyStr string) (pk crypto.PubKey, err error) { err = fmt.Errorf("must use --pubkey flag") return } - //if len(pubKeyStr) != 64 { //if len(pkBytes) != 32 { - //err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters, this pubkey is %v characters", len(pubKeyStr)) - //return - //} + if len(pubKeyStr) != 64 { //if len(pkBytes) != 32 { + err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters, this pubkey is %v characters", len(pubKeyStr)) + return + } // TODO: bech32 ... var pkBytes []byte From c80b9674cddbaa5c62e8c3c6b61f749fdc190ac3 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 18 Apr 2018 00:33:33 -0400 Subject: [PATCH 025/176] stake CLI various fixes, confirmed working --- cmd/gaia/cmd/cli_test.go | 43 +++++----- cmd/gaia/cmd/gaiacli/main.go | 4 +- server/init.go | 2 +- tests/gobash.go | 10 ++- x/stake/commands/flags.go | 41 +++++++++ x/stake/commands/query.go | 160 ++++++++++++++++------------------- x/stake/commands/tx.go | 52 +----------- x/stake/types.go | 2 +- 8 files changed, 153 insertions(+), 161 deletions(-) create mode 100644 x/stake/commands/flags.go diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cmd/cli_test.go index 8011d7a69..b1af5f7b7 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cmd/cli_test.go @@ -23,7 +23,7 @@ import ( func TestGaiaCLISend(t *testing.T) { - tests.ExecuteT(t, "gaiad unsafe_reset_all") + tests.ExecuteT(t, "gaiad unsafe_reset_all", 1) pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) executeWrite(t, "gaiacli keys delete bar", pass) @@ -57,7 +57,7 @@ func TestGaiaCLISend(t *testing.T) { func TestGaiaCLIDeclareCandidacy(t *testing.T) { - tests.ExecuteT(t, "gaiad unsafe_reset_all") + tests.ExecuteT(t, "gaiad unsafe_reset_all", 1) pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) masterKey, chainID := executeInit(t, "gaiad init") @@ -76,18 +76,6 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) // declare candidacy - //--address-candidate string hex address of the validator/candidate - //--amount string Amount of coins to bond (default "1fermion") - //--chain-id string Chain ID of tendermint node - //--fee string Fee to pay along with transaction - //--keybase-sig string optional keybase signature - //--moniker string validator-candidate name - //--name string Name of private key with which to sign - //--node string : to tendermint rpc interface for this chain (default "tcp://localhost:46657") - //--pubkey string PubKey of the validator-candidate - //--sequence int Sequence number to sign the tx - //--website string optional website - //_ = fooPubKey declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags) declStr += fmt.Sprintf(" --name=%v", "foo") declStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) @@ -99,8 +87,25 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { time.Sleep(time.Second * 3) // waiting for some blocks to pass fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(99997), fooAcc.GetCoins().AmountOf("fermion")) - candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address=%v", flags, fooAddr)) + candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr)) assert.Equal(t, candidate.Address.String(), fooAddr) + assert.Equal(t, int64(3), candidate.Assets.Evaluate()) + + // TODO figure out why this times out with connection refused errors in go-bash + // unbond a single share + //unbondStr := fmt.Sprintf("gaiacli unbond %v", flags) + //unbondStr += fmt.Sprintf(" --name=%v", "foo") + //unbondStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) + //unbondStr += fmt.Sprintf(" --address-delegator=%v", fooAddr) + //unbondStr += fmt.Sprintf(" --shares=%v", "1") + //unbondStr += fmt.Sprintf(" --sequence=%v", "1") + //fmt.Printf("debug unbondStr: %v\n", unbondStr) + //executeWrite(t, unbondStr, pass) + //time.Sleep(time.Second * 3) // waiting for some blocks to pass + //fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + //assert.Equal(t, int64(99998), fooAcc.GetCoins().AmountOf("fermion")) + //candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr)) + //assert.Equal(t, int64(2), candidate.Assets.Evaluate()) } func executeWrite(t *testing.T, cmdStr string, writes ...string) { @@ -128,7 +133,7 @@ func executeWritePrint(t *testing.T, cmdStr string, writes ...string) { } func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { - out := tests.ExecuteT(t, cmdStr) + out := tests.ExecuteT(t, cmdStr, 1) outCut := "{" + strings.SplitN(out, "{", 2)[1] // weird I'm sorry var initRes map[string]json.RawMessage @@ -142,7 +147,7 @@ func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { } func executeGetAddr(t *testing.T, cmdStr string) (addr, pubKey string) { - out := tests.ExecuteT(t, cmdStr) + out := tests.ExecuteT(t, cmdStr, 2) var info crkeys.Info keys.UnmarshalJSON([]byte(out), &info) pubKey = hex.EncodeToString(info.PubKey.(crypto.PubKeyEd25519).Bytes()) @@ -158,7 +163,7 @@ func executeGetAddr(t *testing.T, cmdStr string) (addr, pubKey string) { } func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { - out := tests.ExecuteT(t, cmdStr) + out := tests.ExecuteT(t, cmdStr, 2) var initRes map[string]json.RawMessage err := json.Unmarshal([]byte(out), &initRes) require.NoError(t, err, "out %v, err %v", out, err) @@ -170,7 +175,7 @@ func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { } func executeGetCandidate(t *testing.T, cmdStr string) stake.Candidate { - out := tests.ExecuteT(t, cmdStr) + out := tests.ExecuteT(t, cmdStr, 2) var candidate stake.Candidate cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &candidate) diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index c5c3190c3..1e5528308 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -48,10 +48,10 @@ func main() { rootCmd.AddCommand( client.GetCommands( authcmd.GetAccountCmd("main", cdc, authcmd.GetAccountDecoder(cdc)), - stakecmd.GetCmdQueryCandidates("stake", cdc), stakecmd.GetCmdQueryCandidate("stake", cdc), + //stakecmd.GetCmdQueryCandidates("stake", cdc), stakecmd.GetCmdQueryDelegatorBond("stake", cdc), - stakecmd.GetCmdQueryDelegatorBonds("stake", cdc), + //stakecmd.GetCmdQueryDelegatorBonds("stake", cdc), )...) rootCmd.AddCommand( client.PostCommands( diff --git a/server/init.go b/server/init.go index 8c82d2796..f2578cb19 100644 --- a/server/init.go +++ b/server/init.go @@ -70,7 +70,7 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error { return nil } - // generate secrete and address + // generate secret and address addr, secret, err := GenerateCoinKey() if err != nil { return err diff --git a/tests/gobash.go b/tests/gobash.go index 12b3da085..c106c1f3f 100644 --- a/tests/gobash.go +++ b/tests/gobash.go @@ -1,6 +1,7 @@ package tests import ( + "fmt" "io" "os/exec" "strings" @@ -25,10 +26,15 @@ func getCmd(t *testing.T, command string) *exec.Cmd { return cmd } -// Execute the command, return standard output and error -func ExecuteT(t *testing.T, command string) (out string) { +// Execute the command, return standard output and error, try a few times if requested +func ExecuteT(t *testing.T, command string, trials int) (out string) { cmd := getCmd(t, command) bz, err := cmd.CombinedOutput() + if err != nil && trials > 1 { + fmt.Printf("trial %v, retrying: %v\n", trials, command) + time.Sleep(time.Second * 10) + return ExecuteT(t, command, trials-1) + } require.NoError(t, err, string(bz)) out = strings.Trim(string(bz), "\n") //trim any new lines time.Sleep(time.Second) diff --git a/x/stake/commands/flags.go b/x/stake/commands/flags.go new file mode 100644 index 000000000..e5b97d62c --- /dev/null +++ b/x/stake/commands/flags.go @@ -0,0 +1,41 @@ +package commands + +import ( + flag "github.com/spf13/pflag" +) + +// nolint +const ( + FlagAddressDelegator = "address-delegator" + FlagAddressCandidate = "address-candidate" + FlagPubKey = "pubkey" + FlagAmount = "amount" + FlagShares = "shares" + + FlagMoniker = "moniker" + FlagIdentity = "keybase-sig" + FlagWebsite = "website" + FlagDetails = "details" +) + +// common flagsets to add to various functions +var ( + fsPk = flag.NewFlagSet("", flag.ContinueOnError) + fsAmount = flag.NewFlagSet("", flag.ContinueOnError) + fsShares = flag.NewFlagSet("", flag.ContinueOnError) + fsDescription = flag.NewFlagSet("", flag.ContinueOnError) + fsCandidate = flag.NewFlagSet("", flag.ContinueOnError) + fsDelegator = flag.NewFlagSet("", flag.ContinueOnError) +) + +func init() { + fsPk.String(FlagPubKey, "", "PubKey of the validator-candidate") + fsAmount.String(FlagAmount, "1fermion", "Amount of coins to bond") + fsShares.String(FlagShares, "", "Amount of shares to unbond, either in decimal or keyword MAX (ex. 1.23456789, 99, MAX)") + fsDescription.String(FlagMoniker, "", "validator-candidate name") + fsDescription.String(FlagIdentity, "", "optional keybase signature") + fsDescription.String(FlagWebsite, "", "optional website") + fsDescription.String(FlagDetails, "", "optional details") + fsCandidate.String(FlagAddressCandidate, "", "hex address of the validator/candidate") + fsDelegator.String(FlagAddressDelegator, "", "hex address of the delegator") +} diff --git a/x/stake/commands/query.go b/x/stake/commands/query.go index 187de702c..3bc2cffa7 100644 --- a/x/stake/commands/query.go +++ b/x/stake/commands/query.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/spf13/cobra" - flag "github.com/spf13/pflag" "github.com/spf13/viper" crypto "github.com/tendermint/go-crypto" @@ -16,56 +15,41 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" ) -//nolint -var ( - fsValAddr = flag.NewFlagSet("", flag.ContinueOnError) - fsDelAddr = flag.NewFlagSet("", flag.ContinueOnError) - FlagValidatorAddr = "address" - FlagDelegatorAddr = "delegator-address" -) +//// create command to query for all candidates +//func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command { +//cmd := &cobra.Command{ +//Use: "candidates", +//Short: "Query for the set of validator-candidates pubkeys", +//RunE: func(cmd *cobra.Command, args []string) error { -func init() { - //Add Flags - fsValAddr.String(FlagValidatorAddr, "", "Address of the validator/candidate") - fsDelAddr.String(FlagDelegatorAddr, "", "Delegator hex address") +//key := stake.CandidatesKey -} +//ctx := context.NewCoreContextFromViper() +//res, err := ctx.Query(key, storeName) +//if err != nil { +//return err +//} -// create command to query for all candidates -func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "candidates", - Short: "Query for the set of validator-candidates pubkeys", - RunE: func(cmd *cobra.Command, args []string) error { +//// parse out the candidates +//candidates := new(stake.Candidates) +//err = cdc.UnmarshalBinary(res, candidates) +//if err != nil { +//return err +//} +//output, err := wire.MarshalJSONIndent(cdc, candidates) +//if err != nil { +//return err +//} +//fmt.Println(string(output)) +//return nil - key := stake.CandidatesKey +//// TODO output with proofs / machine parseable etc. +//}, +//} - ctx := context.NewCoreContextFromViper() - res, err := ctx.Query(key, storeName) - if err != nil { - return err - } - - // parse out the candidates - candidates := new(stake.Candidates) - err = cdc.UnmarshalBinary(res, candidates) - if err != nil { - return err - } - output, err := wire.MarshalJSONIndent(cdc, candidates) - if err != nil { - return err - } - fmt.Println(string(output)) - return nil - - // TODO output with proofs / machine parseable etc. - }, - } - - cmd.Flags().AddFlagSet(fsDelAddr) - return cmd -} +//cmd.Flags().AddFlagSet(fsDelegator) +//return cmd +//} // get the command to query a candidate func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { @@ -74,7 +58,7 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { Short: "Query a validator-candidate account", RunE: func(cmd *cobra.Command, args []string) error { - addr, err := sdk.GetAddress(viper.GetString(FlagValidatorAddr)) + addr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate)) if err != nil { return err } @@ -105,7 +89,7 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { }, } - cmd.Flags().AddFlagSet(fsValAddr) + cmd.Flags().AddFlagSet(fsCandidate) return cmd } @@ -116,12 +100,12 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command Short: "Query a delegators bond based on address and candidate pubkey", RunE: func(cmd *cobra.Command, args []string) error { - addr, err := sdk.GetAddress(viper.GetString(FlagValidatorAddr)) + addr, err := sdk.GetAddress(viper.GetString(FlagAddressCandidate)) if err != nil { return err } - bz, err := hex.DecodeString(viper.GetString(FlagDelegatorAddr)) + bz, err := hex.DecodeString(viper.GetString(FlagAddressDelegator)) if err != nil { return err } @@ -137,7 +121,7 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command } // parse out the bond - var bond stake.DelegatorBond + bond := new(stake.DelegatorBond) err = cdc.UnmarshalBinary(res, bond) if err != nil { return err @@ -153,49 +137,49 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command }, } - cmd.Flags().AddFlagSet(fsValAddr) - cmd.Flags().AddFlagSet(fsDelAddr) + cmd.Flags().AddFlagSet(fsCandidate) + cmd.Flags().AddFlagSet(fsDelegator) return cmd } -// get the command to query all the candidates bonded to a delegator -func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "delegator-candidates", - Short: "Query all delegators candidates' pubkeys based on address", - RunE: func(cmd *cobra.Command, args []string) error { +//// get the command to query all the candidates bonded to a delegator +//func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command { +//cmd := &cobra.Command{ +//Use: "delegator-candidates", +//Short: "Query all delegators bond's candidate-addresses based on delegator-address", +//RunE: func(cmd *cobra.Command, args []string) error { - bz, err := hex.DecodeString(viper.GetString(FlagDelegatorAddr)) - if err != nil { - return err - } - delegator := crypto.Address(bz) +//bz, err := hex.DecodeString(viper.GetString(FlagAddressDelegator)) +//if err != nil { +//return err +//} +//delegator := crypto.Address(bz) - key := stake.GetDelegatorBondsKey(delegator, cdc) +//key := stake.GetDelegatorBondsKey(delegator, cdc) - ctx := context.NewCoreContextFromViper() +//ctx := context.NewCoreContextFromViper() - res, err := ctx.Query(key, storeName) - if err != nil { - return err - } +//res, err := ctx.Query(key, storeName) +//if err != nil { +//return err +//} - // parse out the candidates list - var candidates []crypto.PubKey - err = cdc.UnmarshalBinary(res, candidates) - if err != nil { - return err - } - output, err := wire.MarshalJSONIndent(cdc, candidates) - if err != nil { - return err - } - fmt.Println(string(output)) - return nil +//// parse out the candidates list +//var candidates []crypto.PubKey +//err = cdc.UnmarshalBinary(res, candidates) +//if err != nil { +//return err +//} +//output, err := wire.MarshalJSONIndent(cdc, candidates) +//if err != nil { +//return err +//} +//fmt.Println(string(output)) +//return nil - // TODO output with proofs / machine parseable etc. - }, - } - cmd.Flags().AddFlagSet(fsDelAddr) - return cmd -} +//// TODO output with proofs / machine parseable etc. +//}, +//} +//cmd.Flags().AddFlagSet(fsDelegator) +//return cmd +//} diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index 55e009db0..4a1983743 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -5,12 +5,10 @@ import ( "fmt" "github.com/spf13/cobra" - flag "github.com/spf13/pflag" "github.com/spf13/viper" crypto "github.com/tendermint/go-crypto" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" @@ -18,52 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" ) -// nolint -const ( - FlagAddressDelegator = "address-delegator" - FlagAddressCandidate = "address-candidate" - FlagPubKey = "pubkey" - FlagAmount = "amount" - FlagShares = "shares" - - FlagMoniker = "moniker" - FlagIdentity = "keybase-sig" - FlagWebsite = "website" - FlagDetails = "details" -) - -// common flagsets to add to various functions -var ( - fsPk = flag.NewFlagSet("", flag.ContinueOnError) - fsAmount = flag.NewFlagSet("", flag.ContinueOnError) - fsShares = flag.NewFlagSet("", flag.ContinueOnError) - fsCandidate = flag.NewFlagSet("", flag.ContinueOnError) - fsDelegator = flag.NewFlagSet("", flag.ContinueOnError) -) - -func init() { - fsPk.String(FlagPubKey, "", "PubKey of the validator-candidate") - fsAmount.String(FlagAmount, "1fermion", "Amount of coins to bond") - fsShares.String(FlagShares, "", "Amount of shares to unbond, either in decimal or keyword MAX (ex. 1.23456789, 99, MAX)") - fsCandidate.String(FlagMoniker, "", "validator-candidate name") - fsCandidate.String(FlagIdentity, "", "optional keybase signature") - fsCandidate.String(FlagWebsite, "", "optional website") - fsCandidate.String(FlagAddressCandidate, "", "hex address of the validator/candidate") - fsDelegator.String(FlagAddressCandidate, "", "hex address of the delegator") - fsDelegator.String(FlagAddressDelegator, "", "hex address of the delegator") -} - -//TODO refactor to common functionality -func getNamePassword() (name, passphrase string, err error) { - name = viper.GetString(client.FlagName) - buf := client.BufferStdin() - prompt := fmt.Sprintf("Password to sign with '%s':", name) - passphrase, err = client.GetPassword(prompt, buf) - return -} - -//_________________________________________________________________________________________ - // create declare candidacy command func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -114,6 +66,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { cmd.Flags().AddFlagSet(fsPk) cmd.Flags().AddFlagSet(fsAmount) + cmd.Flags().AddFlagSet(fsDescription) cmd.Flags().AddFlagSet(fsCandidate) return cmd } @@ -156,6 +109,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command { }, } + cmd.Flags().AddFlagSet(fsDescription) cmd.Flags().AddFlagSet(fsCandidate) return cmd } @@ -200,6 +154,7 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { cmd.Flags().AddFlagSet(fsAmount) cmd.Flags().AddFlagSet(fsDelegator) + cmd.Flags().AddFlagSet(fsCandidate) return cmd } @@ -253,6 +208,7 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command { cmd.Flags().AddFlagSet(fsShares) cmd.Flags().AddFlagSet(fsDelegator) + cmd.Flags().AddFlagSet(fsCandidate) return cmd } diff --git a/x/stake/types.go b/x/stake/types.go index b0dbc0b1f..9f7d97ae5 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -153,7 +153,7 @@ func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator { // pubKey. // TODO better way of managing space type DelegatorBond struct { - DelegatorAddr sdk.Address `json:"delegatoraddr"` + DelegatorAddr sdk.Address `json:"delegator_addr"` CandidateAddr sdk.Address `json:"candidate_addr"` Shares sdk.Rat `json:"shares"` } From 2994af56c9589711c192cf7ef8a4811567c84771 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 18 Apr 2018 12:36:55 -0400 Subject: [PATCH 026/176] gaia new error codetype --- cmd/gaia/app/app.go | 15 +++++++--- cmd/gaia/app/app_test.go | 64 ++++++++++++++-------------------------- x/stake/keeper.go | 2 +- x/stake/test_common.go | 2 +- 4 files changed, 35 insertions(+), 48 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 0c9ef8b55..57a5d672c 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -37,6 +37,9 @@ type GaiaApp struct { coinKeeper bank.CoinKeeper ibcMapper ibc.IBCMapper stakeKeeper stake.Keeper + + // Handle fees + feeHandler sdk.FeeHandler } func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { @@ -59,19 +62,23 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { // add handlers app.coinKeeper = bank.NewCoinKeeper(app.accountMapper) - app.ibcMapper = ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) - app.stakeKeeper = stake.NewKeeper(app.cdc, app.capKeyStakeStore, app.coinKeeper) + app.ibcMapper = ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) + app.stakeKeeper = stake.NewKeeper(app.cdc, app.capKeyStakeStore, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) + app.Router(). AddRoute("bank", bank.NewHandler(app.coinKeeper)). AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). AddRoute("stake", stake.NewHandler(app.stakeKeeper)) + // Define the feeHandler. + app.feeHandler = auth.BurnFeeHandler + // initialize BaseApp app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyIBCStore, app.capKeyStakeStore) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeHandler)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) @@ -113,7 +120,7 @@ func (app *GaiaApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { // are registered by MakeTxCodec err := app.cdc.UnmarshalBinary(txBytes, &tx) if err != nil { - return nil, sdk.ErrTxDecode("").TraceCause(err, "") + return nil, sdk.ErrTxDecode("").Trace(err.Error()) } return tx, nil } diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 5c8450138..bd339c75a 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/examples/basecoin/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" @@ -138,48 +139,27 @@ func TestMsgs(t *testing.T) { } } -func TestSortGenesis(t *testing.T) { - logger, dbs := loggerAndDB() - gapp := NewGaiaApp(logger, dbs) +func setGenesisAccounts(gapp *GaiaApp, accs ...auth.BaseAccount) error { + genaccs := make([]*types.GenesisAccount, len(accs)) + for i, acc := range accs { + genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) + } - // Note the order: the coins are unsorted! - coinDenom1, coinDenom2 := "foocoin", "barcoin" + genesisState := types.GenesisState{ + Accounts: genaccs, + } - str := `{ - "accounts": [{ - "address": "%s", - "coins": [ - { - "denom": "%s", - "amount": 10 - }, - { - "denom": "%s", - "amount": 20 - } - ] - }] - }` - genState := fmt.Sprintf(str, addr1.String(), coinDenom1, coinDenom2) + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + if err != nil { + return err + } // Initialize the chain vals := []abci.Validator{} - gapp.InitChain(abci.RequestInitChain{vals, []byte(genState)}) + gapp.InitChain(abci.RequestInitChain{vals, stateBytes}) gapp.Commit() - // Unsorted coins means invalid - err := sendMsg5.ValidateBasic() - require.Equal(t, sdk.CodeInvalidCoins, err.ABCICode(), err.ABCILog()) - - // Sort coins, should be valid - sendMsg5.Inputs[0].Coins.Sort() - sendMsg5.Outputs[0].Coins.Sort() - err = sendMsg5.ValidateBasic() - require.Nil(t, err) - - // Ensure we can send - require.Nil(t, setGenesis(gapp)) // initialize the pool - SignCheckDeliver(t, gapp, sendMsg5, []int64{0}, true, priv1) + return nil } func TestGenesis(t *testing.T) { @@ -247,7 +227,7 @@ func TestSendMsgWithAccounts(t *testing.T) { tx.Signatures[0].Sequence = 1 res := gapp.Deliver(tx) - assert.Equal(t, sdk.CodeUnauthorized, res.Code, res.Log) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) // resigning the tx with the bumped sequence should work SignCheckDeliver(t, gapp, sendMsg1, []int64{1}, true, priv1) @@ -498,18 +478,18 @@ func SignCheckDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, exp // Run a Check res := gapp.Check(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) } // Simulate a Block gapp.BeginBlock(abci.RequestBeginBlock{}) res = gapp.Deliver(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) } gapp.EndBlock(abci.RequestEndBlock{}) @@ -530,9 +510,9 @@ func SignDeliver(t *testing.T, gapp *GaiaApp, msg sdk.Msg, seq []int64, expPass gapp.BeginBlock(abci.RequestBeginBlock{}) res := gapp.Deliver(tx) if expPass { - require.Equal(t, sdk.CodeOK, res.Code, res.Log) + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } else { - require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) } gapp.EndBlock(abci.RequestEndBlock{}) } diff --git a/x/stake/keeper.go b/x/stake/keeper.go index c2b054eba..751b84017 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -23,7 +23,7 @@ type Keeper struct { codespace sdk.CodespaceType } -func NewKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { +func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { keeper := Keeper{ storeKey: key, cdc: cdc, diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 75781777a..1de86c912 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -140,7 +140,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context &auth.BaseAccount{}, // prototype ).Seal() ck := bank.NewCoinKeeper(accountMapper) - keeper := NewKeeper(ctx, cdc, keyStake, ck, DefaultCodespace) + keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace) keeper.setPool(ctx, initialPool()) keeper.setParams(ctx, defaultParams()) From 8c59ced191c96e51355aca0a79b20488f341b429 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 18 Apr 2018 12:39:59 -0400 Subject: [PATCH 027/176] changelog --- CHANGELOG.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cfbe82dd..d31ce6cbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,13 @@ FEATURES: * Add CacheContext * Add auto sequencing to client * Add FeeHandler to ante handler +* Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond +* MountStoreWithDB without providing a custom store works. BREAKING CHANGES * Remove go-wire, use go-amino +* Gaia simple-staking bond and unbond functions replaced * [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface * [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores * All module keepers now require a codespace, see basecoin or democoin for usage @@ -18,12 +21,6 @@ BREAKING CHANGES BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia -FEATURES: - -* Add CacheContext -* Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond -* MountStoreWithDB without providing a custom store works. - ## 0.14.1 (April 9, 2018) BUG FIXES From be93b760e779c21925dd4d76d0b081d9797ec1a6 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 18 Apr 2018 13:23:47 -0400 Subject: [PATCH 028/176] circle make install int --- .circleci/config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6754ebc05..c6cb56a1e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ jobs: name: binaries command: | export PATH="$GOBIN:$PATH" - make build + make install - persist_to_workspace: root: /tmp/workspace paths: @@ -59,6 +59,8 @@ jobs: - run: name: Run tests command: | + export PATH="$GOBIN:$PATH" + make install for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/ | circleci tests split --split-by=timings); do id=$(basename "$pkg") From 6f65867154f73051a53be6b8cc0cdd59282782e6 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 18 Apr 2018 14:06:49 -0400 Subject: [PATCH 029/176] comment out go-bash race condition --- .circleci/config.yml | 2 +- cmd/gaia/{cmd => cli_test}/cli_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename cmd/gaia/{cmd => cli_test}/cli_test.go (99%) diff --git a/.circleci/config.yml b/.circleci/config.yml index c6cb56a1e..47cb5661d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -61,7 +61,7 @@ jobs: command: | export PATH="$GOBIN:$PATH" make install - for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/ | circleci tests split --split-by=timings); do + for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/ | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | circleci tests split --split-by=timings); do id=$(basename "$pkg") go test -timeout 5m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" diff --git a/cmd/gaia/cmd/cli_test.go b/cmd/gaia/cli_test/cli_test.go similarity index 99% rename from cmd/gaia/cmd/cli_test.go rename to cmd/gaia/cli_test/cli_test.go index b1af5f7b7..4b4a17dcd 100644 --- a/cmd/gaia/cmd/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -1,4 +1,4 @@ -package common +package clitest import ( "encoding/hex" From d36efcd4171ab8c747e9672e87a06a9f6b9ecd97 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 18 Apr 2018 14:21:07 -0400 Subject: [PATCH 030/176] unbond in gaia cli test --- cmd/gaia/cli_test/cli_test.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 4b4a17dcd..0d9a89578 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -93,19 +93,19 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { // TODO figure out why this times out with connection refused errors in go-bash // unbond a single share - //unbondStr := fmt.Sprintf("gaiacli unbond %v", flags) - //unbondStr += fmt.Sprintf(" --name=%v", "foo") - //unbondStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) - //unbondStr += fmt.Sprintf(" --address-delegator=%v", fooAddr) - //unbondStr += fmt.Sprintf(" --shares=%v", "1") - //unbondStr += fmt.Sprintf(" --sequence=%v", "1") - //fmt.Printf("debug unbondStr: %v\n", unbondStr) - //executeWrite(t, unbondStr, pass) - //time.Sleep(time.Second * 3) // waiting for some blocks to pass - //fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - //assert.Equal(t, int64(99998), fooAcc.GetCoins().AmountOf("fermion")) - //candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr)) - //assert.Equal(t, int64(2), candidate.Assets.Evaluate()) + unbondStr := fmt.Sprintf("gaiacli unbond %v", flags) + unbondStr += fmt.Sprintf(" --name=%v", "foo") + unbondStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) + unbondStr += fmt.Sprintf(" --address-delegator=%v", fooAddr) + unbondStr += fmt.Sprintf(" --shares=%v", "1") + unbondStr += fmt.Sprintf(" --sequence=%v", "1") + fmt.Printf("debug unbondStr: %v\n", unbondStr) + executeWrite(t, unbondStr, pass) + time.Sleep(time.Second * 3) // waiting for some blocks to pass + fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + assert.Equal(t, int64(99998), fooAcc.GetCoins().AmountOf("fermion")) + candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr)) + assert.Equal(t, int64(2), candidate.Assets.Evaluate()) } func executeWrite(t *testing.T, cmdStr string, writes ...string) { From 0e8c3e4a5b3a806b0c3a200570a57e7258eb1239 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 18 Apr 2018 14:32:40 -0400 Subject: [PATCH 031/176] remove gaia basecoin reference --- cmd/gaia/app/app_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index bd339c75a..b3350b503 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -9,7 +9,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/examples/basecoin/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" @@ -139,14 +138,15 @@ func TestMsgs(t *testing.T) { } } -func setGenesisAccounts(gapp *GaiaApp, accs ...auth.BaseAccount) error { - genaccs := make([]*types.GenesisAccount, len(accs)) +func setGenesisAccounts(gapp *GaiaApp, accs ...*auth.BaseAccount) error { + genaccs := make([]GenesisAccount, len(accs)) for i, acc := range accs { - genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) + genaccs[i] = NewGenesisAccount(acc) } - genesisState := types.GenesisState{ - Accounts: genaccs, + genesisState := GenesisState{ + Accounts: genaccs, + StakeData: stake.GetDefaultGenesisState(), } stateBytes, err := json.MarshalIndent(genesisState, "", "\t") From 1f9184a24b91185a90240312389c980c94ddb188 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 18 Apr 2018 15:39:32 -0400 Subject: [PATCH 032/176] basic go-linting // moved corecontext --- baseapp/baseapp.go | 3 +-- baseapp/baseapp_test.go | 2 +- client/{core/core.go => context/helpers.go} | 10 +++++----- client/{core/context.go => context/types.go} | 3 ++- client/context/viper.go | 8 ++++---- client/lcd/helpers.go | 5 ++--- client/lcd/lcd_test.go | 4 ++-- 7 files changed, 17 insertions(+), 18 deletions(-) rename client/{core/core.go => context/helpers.go} (95%) rename client/{core/context.go => context/types.go} (96%) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 3eebb1eb4..827408b20 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -114,7 +114,6 @@ func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) { func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) { app.anteHandler = ah } - func (app *BaseApp) Router() Router { return app.router } // load latest application version @@ -337,7 +336,7 @@ func (app *BaseApp) DeliverTx(txBytes []byte) (res abci.ResponseDeliverTx) { } } -// Mostly for testing +// nolint- Mostly for testing func (app *BaseApp) Check(tx sdk.Tx) (result sdk.Result) { return app.runTx(true, nil, tx) } diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 78fd50464..f70521009 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -240,7 +240,7 @@ func TestDeliverTx(t *testing.T) { height := int64((counter / txPerHeight) + 1) assert.Equal(t, height, thisHeader.Height) - counter += 1 + counter++ return sdk.Result{} }) diff --git a/client/core/core.go b/client/context/helpers.go similarity index 95% rename from client/core/core.go rename to client/context/helpers.go index 2a1b2736a..509ec09dc 100644 --- a/client/core/core.go +++ b/client/context/helpers.go @@ -1,4 +1,4 @@ -package core +package context import ( "fmt" @@ -141,17 +141,17 @@ func (ctx CoreContext) SignBuildBroadcast(name string, msg sdk.Msg, cdc *wire.Co } // get the next sequence for the account address -func (c CoreContext) NextSequence(address []byte) (int64, error) { - if c.Decoder == nil { +func (ctx CoreContext) NextSequence(address []byte) (int64, error) { + if ctx.Decoder == nil { return 0, errors.New("AccountDecoder required but not provided") } - res, err := c.Query(address, c.AccountStore) + res, err := ctx.Query(address, ctx.AccountStore) if err != nil { return 0, err } - account, err := c.Decoder(res) + account, err := ctx.Decoder(res) if err != nil { panic(err) } diff --git a/client/core/context.go b/client/context/types.go similarity index 96% rename from client/core/context.go rename to client/context/types.go index fac60b553..e580027d6 100644 --- a/client/core/context.go +++ b/client/context/types.go @@ -1,4 +1,4 @@ -package core +package context import ( rpcclient "github.com/tendermint/tendermint/rpc/client" @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// typical context created in sdk modules for transactions/queries type CoreContext struct { ChainID string Height int64 diff --git a/client/context/viper.go b/client/context/viper.go index c3b0369d9..7e82f7ad9 100644 --- a/client/context/viper.go +++ b/client/context/viper.go @@ -2,6 +2,7 @@ package context import ( "fmt" + "github.com/spf13/viper" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" @@ -9,11 +10,10 @@ import ( tmtypes "github.com/tendermint/tendermint/types" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/core" ) // NewCoreContextFromViper - return a new context with parameters from the command line -func NewCoreContextFromViper() core.CoreContext { +func NewCoreContextFromViper() CoreContext { nodeURI := viper.GetString(client.FlagNode) var rpc rpcclient.Client if nodeURI != "" { @@ -27,7 +27,7 @@ func NewCoreContextFromViper() core.CoreContext { chainID = def } } - return core.CoreContext{ + return CoreContext{ ChainID: chainID, Height: viper.GetInt64(client.FlagHeight), TrustNode: viper.GetBool(client.FlagTrustNode), @@ -54,7 +54,7 @@ func defaultChainID() (string, error) { } // EnsureSequence - automatically set sequence number if none provided -func EnsureSequence(ctx core.CoreContext) (core.CoreContext, error) { +func EnsureSequence(ctx CoreContext) (CoreContext, error) { if viper.IsSet(client.FlagSequence) { return ctx, nil } diff --git a/client/lcd/helpers.go b/client/lcd/helpers.go index 64814a5fc..a64d44dfa 100644 --- a/client/lcd/helpers.go +++ b/client/lcd/helpers.go @@ -28,10 +28,9 @@ func waitForRPC() { _, err := client.Call("status", map[string]interface{}{}, result) if err == nil { return - } else { - fmt.Println("error", err) - time.Sleep(time.Millisecond) } + fmt.Println("error", err) + time.Sleep(time.Millisecond) } } diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index e84ff8e9b..0b5c6b064 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -42,9 +42,9 @@ var ( coinAmount = int64(10000000) // XXX bad globals + name = "test" + password = "0123456789" port string // XXX: but it's the int ... - name string = "test" - password string = "0123456789" seed string sendAddr string ) From d28efaac2784f3d13538bee75f1bc4ce29036899 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 19 Apr 2018 00:49:24 -0400 Subject: [PATCH 033/176] many renames / golint compliance --- client/context/helpers.go | 9 +- client/keys/add.go | 4 + client/keys/delete.go | 3 + client/keys/list.go | 4 +- client/keys/root.go | 1 + client/keys/show.go | 2 + client/keys/update.go | 3 + client/lcd/root.go | 2 +- client/rpc/block.go | 3 + client/rpc/root.go | 5 +- client/rpc/status.go | 2 + client/rpc/validators.go | 16 +- client/tx/broadcast.go | 2 + client/tx/query.go | 51 +++--- client/tx/root.go | 13 +- client/tx/search.go | 40 +++-- client/tx/sign.go | 3 + cmd/gaia/app/app.go | 36 ++--- cmd/gaia/app/app_test.go | 16 +- cmd/gaia/cmd/gaiacli/main.go | 1 - docs/guide.md | 18 +-- examples/basecoin/app/app.go | 12 +- examples/basecoin/app/app_test.go | 18 +-- examples/democoin/app/app.go | 22 +-- examples/democoin/app/app_test.go | 22 +-- examples/democoin/types/account.go | 4 +- examples/democoin/x/cool/commands/tx.go | 20 +-- examples/democoin/x/cool/errors.go | 1 + examples/democoin/x/cool/handler.go | 16 +- examples/democoin/x/cool/keeper.go | 6 +- examples/democoin/x/cool/types.go | 52 +++--- examples/democoin/x/pow/commands/tx.go | 13 +- examples/democoin/x/pow/errors.go | 31 ++-- examples/democoin/x/pow/handler.go | 7 +- examples/democoin/x/pow/handler_test.go | 10 +- examples/democoin/x/pow/keeper.go | 69 ++++---- examples/democoin/x/pow/keeper_test.go | 6 +- examples/democoin/x/pow/mine.go | 5 +- examples/democoin/x/pow/types.go | 29 ++-- examples/democoin/x/pow/types_test.go | 44 +++--- examples/kvstore/main.go | 7 +- server/init.go | 4 +- server/tm_cmds.go | 6 +- server/util.go | 2 + store/cachekvstore.go | 6 +- store/cachekvstore_test.go | 16 +- store/cachemergeiterator.go | 3 +- store/dbstoreadapter.go | 2 +- store/firstlast.go | 4 +- store/iavlstore.go | 1 + store/iavlstore_test.go | 24 +-- store/rootmultistore.go | 3 +- store/types.go | 1 + types/errors.go | 2 + version/command.go | 6 +- wire/wire.go | 3 + x/auth/commands/account.go | 1 + x/auth/context.go | 2 + x/auth/mapper.go | 15 +- x/auth/rest/query.go | 17 +- x/auth/rest/root.go | 11 -- x/bank/commands/sendtx.go | 87 +++++------ x/bank/errors.go | 2 +- x/bank/handler.go | 20 +-- x/bank/keeper.go | 200 ++++++++++++------------ x/bank/keeper_test.go | 8 +- x/bank/msgs.go | 65 +++----- x/bank/msgs_test.go | 107 +++++-------- x/bank/rest/root.go | 14 -- x/bank/rest/sendtx.go | 8 +- x/bank/wire.go | 4 +- x/ibc/commands/ibctx.go | 65 ++++---- x/ibc/commands/relay.go | 9 +- x/ibc/errors.go | 6 +- x/ibc/handler.go | 6 +- x/ibc/ibc_test.go | 12 +- x/ibc/mapper.go | 23 +-- x/ibc/rest/root.go | 14 -- x/ibc/rest/transfer.go | 9 +- x/ibc/types.go | 44 +++--- x/ibc/types_test.go | 3 +- x/simplestake/commands/commands.go | 113 ++++++------- x/simplestake/errors.go | 5 +- x/simplestake/handler.go | 12 +- x/simplestake/keeper.go | 7 +- x/simplestake/keeper_test.go | 4 +- x/simplestake/msgs.go | 66 +++----- x/simplestake/msgs_test.go | 8 +- x/stake/commands/tx.go | 32 +--- x/stake/keeper.go | 4 +- x/stake/msg.go | 15 -- x/stake/test_common.go | 6 +- 92 files changed, 792 insertions(+), 943 deletions(-) delete mode 100644 x/auth/rest/root.go delete mode 100644 x/bank/rest/root.go delete mode 100644 x/ibc/rest/root.go diff --git a/client/context/helpers.go b/client/context/helpers.go index 509ec09dc..ded70cb5c 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -126,7 +126,14 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w } // sign and build the transaction from the msg -func (ctx CoreContext) SignBuildBroadcast(name string, msg sdk.Msg, cdc *wire.Codec) (*ctypes.ResultBroadcastTxCommit, error) { +func (ctx CoreContext) EnsureSignBuildBroadcast(name string, msg sdk.Msg, cdc *wire.Codec) (res *ctypes.ResultBroadcastTxCommit, err error) { + + // default to next sequence number if none provided + ctx, err = EnsureSequence(ctx) + if err != nil { + return nil, err + } + passphrase, err := ctx.GetPassphraseFromStdin(name) if err != nil { return nil, err diff --git a/client/keys/add.go b/client/keys/add.go index d68983028..da368a3a6 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -135,14 +135,17 @@ func printCreate(info keys.Info, seed string) { } } +///////////////////////////// // REST +// new key request REST body type NewKeyBody struct { Name string `json:"name"` Password string `json:"password"` Seed string `json:"seed"` } +// add new key REST handler func AddNewKeyRequestHandler(w http.ResponseWriter, r *http.Request) { var kb keys.Keybase var m NewKeyBody @@ -208,6 +211,7 @@ func getSeed(algo keys.CryptoAlgo) string { return seed } +// Seed REST request handler func SeedRequestHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) algoType := vars["type"] diff --git a/client/keys/delete.go b/client/keys/delete.go index b0327771b..cd2016bd2 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -48,12 +48,15 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error { return nil } +//////////////////////// // REST +// delete key request REST body type DeleteKeyBody struct { Password string `json:"password"` } +// delete key REST handler func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) name := vars["name"] diff --git a/client/keys/list.go b/client/keys/list.go index 97ccf8a90..26e06d9da 100644 --- a/client/keys/list.go +++ b/client/keys/list.go @@ -31,8 +31,10 @@ func runListCmd(cmd *cobra.Command, args []string) error { return err } -//REST +///////////////////////// +// REST +// query key list REST handler func QueryKeysRequestHandler(w http.ResponseWriter, r *http.Request) { kb, err := GetKeyBase() if err != nil { diff --git a/client/keys/root.go b/client/keys/root.go index 48b50d5e9..c8f6aea69 100644 --- a/client/keys/root.go +++ b/client/keys/root.go @@ -29,6 +29,7 @@ func Commands() *cobra.Command { return cmd } +// resgister REST routes func RegisterRoutes(r *mux.Router) { r.HandleFunc("/keys", QueryKeysRequestHandler).Methods("GET") r.HandleFunc("/keys", AddNewKeyRequestHandler).Methods("POST") diff --git a/client/keys/show.go b/client/keys/show.go index bb60b5bc0..76966cd19 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -42,8 +42,10 @@ func runShowCmd(cmd *cobra.Command, args []string) error { return err } +/////////////////////////// // REST +// get key REST handler func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) name := vars["name"] diff --git a/client/keys/update.go b/client/keys/update.go index d95be78bf..c0edc5fe6 100644 --- a/client/keys/update.go +++ b/client/keys/update.go @@ -53,13 +53,16 @@ func runUpdateCmd(cmd *cobra.Command, args []string) error { return nil } +/////////////////////// // REST +// update key request REST body type UpdateKeyBody struct { NewPassword string `json:"new_password"` OldPassword string `json:"old_password"` } +// update key REST handler func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) name := vars["name"] diff --git a/client/lcd/root.go b/client/lcd/root.go index 9464081e0..81eca333e 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -66,7 +66,7 @@ func startRESTServerFn(cdc *wire.Codec) func(cmd *cobra.Command, args []string) func createHandler(cdc *wire.Codec) http.Handler { r := mux.NewRouter() - r.HandleFunc("/version", version.VersionRequestHandler).Methods("GET") + r.HandleFunc("/version", version.RequestHandler).Methods("GET") kb, err := keys.GetKeyBase() //XXX if err != nil { diff --git a/client/rpc/block.go b/client/rpc/block.go index 8df26edda..200dc668e 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -55,6 +55,7 @@ func getBlock(height *int64) ([]byte, error) { return output, nil } +// get the current blockchain height func GetChainHeight() (int64, error) { node, err := context.NewCoreContextFromViper().GetNode() if err != nil { @@ -94,6 +95,7 @@ func printBlock(cmd *cobra.Command, args []string) error { // REST +// REST handler to get a block func BlockRequestHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) height, err := strconv.ParseInt(vars["height"], 10, 64) @@ -117,6 +119,7 @@ func BlockRequestHandler(w http.ResponseWriter, r *http.Request) { w.Write(output) } +// REST handler to get the latest block func LatestBlockRequestHandler(w http.ResponseWriter, r *http.Request) { height, err := GetChainHeight() if err != nil { diff --git a/client/rpc/root.go b/client/rpc/root.go index 8b04c044f..43e9097f0 100644 --- a/client/rpc/root.go +++ b/client/rpc/root.go @@ -44,11 +44,12 @@ func initClientCommand() *cobra.Command { return cmd } +// Register REST endpoints func RegisterRoutes(r *mux.Router) { r.HandleFunc("/node_info", NodeInfoRequestHandler).Methods("GET") r.HandleFunc("/syncing", NodeSyncingRequestHandler).Methods("GET") r.HandleFunc("/blocks/latest", LatestBlockRequestHandler).Methods("GET") r.HandleFunc("/blocks/{height}", BlockRequestHandler).Methods("GET") - r.HandleFunc("/validatorsets/latest", LatestValidatorsetRequestHandler).Methods("GET") - r.HandleFunc("/validatorsets/{height}", ValidatorsetRequestHandler).Methods("GET") + r.HandleFunc("/validatorsets/latest", LatestValidatorSetRequestHandler).Methods("GET") + r.HandleFunc("/validatorsets/{height}", ValidatorSetRequestHandler).Methods("GET") } diff --git a/client/rpc/status.go b/client/rpc/status.go index 83fc01c56..3b143d9c5 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -51,6 +51,7 @@ func printNodeStatus(cmd *cobra.Command, args []string) error { // REST +// REST handler for node info func NodeInfoRequestHandler(w http.ResponseWriter, r *http.Request) { status, err := getNodeStatus() if err != nil { @@ -69,6 +70,7 @@ func NodeInfoRequestHandler(w http.ResponseWriter, r *http.Request) { w.Write(output) } +// REST handler for node syncing func NodeSyncingRequestHandler(w http.ResponseWriter, r *http.Request) { status, err := getNodeStatus() if err != nil { diff --git a/client/rpc/validators.go b/client/rpc/validators.go index cdaf3be93..6937e4a89 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -12,6 +12,8 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" ) +// TODO these next two functions feel kinda hacky based on their placement + func validatorCommand() *cobra.Command { cmd := &cobra.Command{ Use: "validatorset ", @@ -24,7 +26,7 @@ func validatorCommand() *cobra.Command { return cmd } -func GetValidators(height *int64) ([]byte, error) { +func getValidators(height *int64) ([]byte, error) { // get the node node, err := context.NewCoreContextFromViper().GetNode() if err != nil { @@ -59,7 +61,7 @@ func printValidators(cmd *cobra.Command, args []string) error { } } - output, err := GetValidators(height) + output, err := getValidators(height) if err != nil { return err } @@ -70,7 +72,8 @@ func printValidators(cmd *cobra.Command, args []string) error { // REST -func ValidatorsetRequestHandler(w http.ResponseWriter, r *http.Request) { +// Validator Set at a height REST handler +func ValidatorSetRequestHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) height, err := strconv.ParseInt(vars["height"], 10, 64) if err != nil { @@ -84,7 +87,7 @@ func ValidatorsetRequestHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("ERROR: Requested block height is bigger then the chain length.")) return } - output, err := GetValidators(&height) + output, err := getValidators(&height) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) @@ -93,14 +96,15 @@ func ValidatorsetRequestHandler(w http.ResponseWriter, r *http.Request) { w.Write(output) } -func LatestValidatorsetRequestHandler(w http.ResponseWriter, r *http.Request) { +// Latest Validator Set REST handler +func LatestValidatorSetRequestHandler(w http.ResponseWriter, r *http.Request) { height, err := GetChainHeight() if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) return } - output, err := GetValidators(&height) + output, err := getValidators(&height) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) diff --git a/client/tx/broadcast.go b/client/tx/broadcast.go index 998e2b0f1..9e9eaae70 100644 --- a/client/tx/broadcast.go +++ b/client/tx/broadcast.go @@ -7,10 +7,12 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" ) +// Tx Broadcast Body type BroadcastTxBody struct { TxBytes string `json="tx"` } +// BroadcastTx REST Handler func BroadcastTxRequestHandler(w http.ResponseWriter, r *http.Request) { var m BroadcastTxBody diff --git a/client/tx/query.go b/client/tx/query.go index 63ab2ff04..cc252bacc 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -21,19 +21,37 @@ import ( ) // Get the default command for a tx query -func QueryTxCmd(cmdr commander) *cobra.Command { +func QueryTxCmd(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "tx [hash]", Short: "Matches this txhash over all committed blocks", - RunE: cmdr.queryAndPrintTx, + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) != 1 || len(args[0]) == 0 { + return errors.New("You must provide a tx hash") + } + + // find the key to look up the account + hashHexStr := args[0] + trustNode := viper.GetBool(client.FlagTrustNode) + + output, err := queryTx(cdc, hashHexStr, trustNode) + if err != nil { + return err + } + fmt.Println(string(output)) + + return nil + }, } + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + // TODO: change this to false when we can cmd.Flags().Bool(client.FlagTrustNode, true, "Don't verify proofs for responses") return cmd } -func (c commander) queryTx(hashHexStr string, trustNode bool) ([]byte, error) { +func queryTx(cdc *wire.Codec, hashHexStr string, trustNode bool) ([]byte, error) { hash, err := hex.DecodeString(hashHexStr) if err != nil { return nil, err @@ -49,7 +67,7 @@ func (c commander) queryTx(hashHexStr string, trustNode bool) ([]byte, error) { if err != nil { return nil, err } - info, err := formatTxResult(c.cdc, res) + info, err := formatTxResult(cdc, res) if err != nil { return nil, err } @@ -88,31 +106,10 @@ func parseTx(cdc *wire.Codec, txBytes []byte) (sdk.Tx, error) { return tx, nil } -// CMD - -// command to query for a transaction -func (c commander) queryAndPrintTx(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a tx hash") - } - - // find the key to look up the account - hashHexStr := args[0] - trustNode := viper.GetBool(client.FlagTrustNode) - - output, err := c.queryTx(hashHexStr, trustNode) - if err != nil { - return err - } - fmt.Println(string(output)) - - return nil -} - // REST +// transaction query REST handler func QueryTxRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Request) { - c := commander{cdc} return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hashHexStr := vars["hash"] @@ -122,7 +119,7 @@ func QueryTxRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Requ trustNode = true } - output, err := c.queryTx(hashHexStr, trustNode) + output, err := queryTx(cdc, hashHexStr, trustNode) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) diff --git a/client/tx/root.go b/client/tx/root.go index f7d2cf945..2a87113b3 100644 --- a/client/tx/root.go +++ b/client/tx/root.go @@ -7,23 +7,18 @@ import ( "github.com/cosmos/cosmos-sdk/wire" ) -// type used to pass around the provided cdc -type commander struct { - cdc *wire.Codec -} - // AddCommands adds a number of tx-query related subcommands func AddCommands(cmd *cobra.Command, cdc *wire.Codec) { - cmdr := commander{cdc} cmd.AddCommand( - SearchTxCmd(cmdr), - QueryTxCmd(cmdr), + SearchTxCmd(cdc), + QueryTxCmd(cdc), ) } +// register REST routes func RegisterRoutes(r *mux.Router, cdc *wire.Codec) { - // r.HandleFunc("/txs", SearchTxRequestHandler(cdc)).Methods("GET") r.HandleFunc("/txs/{hash}", QueryTxRequestHandler(cdc)).Methods("GET") + // r.HandleFunc("/txs", SearchTxRequestHandler(cdc)).Methods("GET") // r.HandleFunc("/txs/sign", SignTxRequstHandler).Methods("POST") // r.HandleFunc("/txs/broadcast", BroadcastTxRequestHandler).Methods("POST") } diff --git a/client/tx/search.go b/client/tx/search.go index df3be5077..1687d3bbd 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -22,13 +22,24 @@ const ( ) // default client command to search through tagged transactions -func SearchTxCmd(cmdr commander) *cobra.Command { +func SearchTxCmd(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "txs", Short: "Search for all transactions that match the given tags", - RunE: cmdr.searchAndPrintTx, + RunE: func(cmd *cobra.Command, args []string) error { + tags := viper.GetStringSlice(flagTags) + + output, err := searchTx(cdc, tags) + if err != nil { + return err + } + fmt.Println(string(output)) + return nil + }, } + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + // TODO: change this to false once proofs built in cmd.Flags().Bool(client.FlagTrustNode, true, "Don't verify proofs for responses") cmd.Flags().StringSlice(flagTags, nil, "Tags that must match (may provide multiple)") @@ -36,7 +47,7 @@ func SearchTxCmd(cmdr commander) *cobra.Command { return cmd } -func (c commander) searchTx(tags []string) ([]byte, error) { +func searchTx(cdc *wire.Codec, tags []string) ([]byte, error) { if len(tags) == 0 { return nil, errors.New("Must declare at least one tag to search") } @@ -55,12 +66,12 @@ func (c commander) searchTx(tags []string) ([]byte, error) { return nil, err } - info, err := formatTxResults(c.cdc, res) + info, err := formatTxResults(cdc, res) if err != nil { return nil, err } - output, err := c.cdc.MarshalJSON(info) + output, err := cdc.MarshalJSON(info) if err != nil { return nil, err } @@ -79,24 +90,11 @@ func formatTxResults(cdc *wire.Codec, res []*ctypes.ResultTx) ([]txInfo, error) return out, nil } -// CMD - -func (c commander) searchAndPrintTx(cmd *cobra.Command, args []string) error { - tags := viper.GetStringSlice(flagTags) - - output, err := c.searchTx(tags) - if err != nil { - return err - } - - fmt.Println(string(output)) - return nil -} - +///////////////////////////////////////// // REST +// Search Tx REST Handler func SearchTxRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Request) { - c := commander{cdc} return func(w http.ResponseWriter, r *http.Request) { tag := r.FormValue("tag") if tag == "" { @@ -106,7 +104,7 @@ func SearchTxRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Req } tags := []string{tag} - output, err := c.searchTx(tags) + output, err := searchTx(cdc, tags) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) diff --git a/client/tx/sign.go b/client/tx/sign.go index 3a3fff4a0..2d885b049 100644 --- a/client/tx/sign.go +++ b/client/tx/sign.go @@ -8,12 +8,15 @@ import ( keys "github.com/tendermint/go-crypto/keys" ) +// REST request body +// TODO does this need to be exposed? type SignTxBody struct { Name string `json="name"` Password string `json="password"` TxBytes string `json="tx"` } +// sign transaction REST Handler func SignTxRequstHandler(w http.ResponseWriter, r *http.Request) { var kb keys.Keybase var m SignTxBody diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 57a5d672c..e780c08bf 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -27,15 +27,15 @@ type GaiaApp struct { cdc *wire.Codec // keys to access the substores - capKeyMainStore *sdk.KVStoreKey - capKeyAccountStore *sdk.KVStoreKey - capKeyIBCStore *sdk.KVStoreKey - capKeyStakeStore *sdk.KVStoreKey + keyMain *sdk.KVStoreKey + keyAccount *sdk.KVStoreKey + keyIBC *sdk.KVStoreKey + keyStake *sdk.KVStoreKey // Manage getting and setting accounts accountMapper sdk.AccountMapper - coinKeeper bank.CoinKeeper - ibcMapper ibc.IBCMapper + coinKeeper bank.Keeper + ibcMapper ibc.Mapper stakeKeeper stake.Keeper // Handle fees @@ -45,25 +45,25 @@ type GaiaApp struct { func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { // create your application object var app = &GaiaApp{ - BaseApp: bam.NewBaseApp(appName, logger, db), - cdc: MakeCodec(), - capKeyMainStore: sdk.NewKVStoreKey("main"), - capKeyAccountStore: sdk.NewKVStoreKey("acc"), - capKeyIBCStore: sdk.NewKVStoreKey("ibc"), - capKeyStakeStore: sdk.NewKVStoreKey("stake"), + BaseApp: bam.NewBaseApp(appName, logger, db), + cdc: MakeCodec(), + keyMain: sdk.NewKVStoreKey("main"), + keyAccount: sdk.NewKVStoreKey("acc"), + keyIBC: sdk.NewKVStoreKey("ibc"), + keyStake: sdk.NewKVStoreKey("stake"), } // define the accountMapper app.accountMapper = auth.NewAccountMapper( app.cdc, - app.capKeyMainStore, // target store + app.keyMain, // target store &auth.BaseAccount{}, // prototype ).Seal() // add handlers - app.coinKeeper = bank.NewCoinKeeper(app.accountMapper) - app.ibcMapper = ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) - app.stakeKeeper = stake.NewKeeper(app.cdc, app.capKeyStakeStore, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) + app.coinKeeper = bank.NewKeeper(app.accountMapper) + app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) + app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) app.Router(). AddRoute("bank", bank.NewHandler(app.coinKeeper)). @@ -77,9 +77,9 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) - app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyIBCStore, app.capKeyStakeStore) + app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeHandler)) - err := app.LoadLatestVersion(app.capKeyMainStore) + err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) } diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index b3350b503..721215999 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -42,12 +42,12 @@ var ( 0, } - sendMsg1 = bank.SendMsg{ + sendMsg1 = bank.MsgSend{ Inputs: []bank.Input{bank.NewInput(addr1, coins)}, Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, } - sendMsg2 = bank.SendMsg{ + sendMsg2 = bank.MsgSend{ Inputs: []bank.Input{bank.NewInput(addr1, coins)}, Outputs: []bank.Output{ bank.NewOutput(addr2, halfCoins), @@ -55,7 +55,7 @@ var ( }, } - sendMsg3 = bank.SendMsg{ + sendMsg3 = bank.MsgSend{ Inputs: []bank.Input{ bank.NewInput(addr1, coins), bank.NewInput(addr4, coins), @@ -66,7 +66,7 @@ var ( }, } - sendMsg4 = bank.SendMsg{ + sendMsg4 = bank.MsgSend{ Inputs: []bank.Input{ bank.NewInput(addr2, coins), }, @@ -75,7 +75,7 @@ var ( }, } - sendMsg5 = bank.SendMsg{ + sendMsg5 = bank.MsgSend{ Inputs: []bank.Input{ bank.NewInput(addr1, manyCoins), }, @@ -191,7 +191,7 @@ func TestGenesis(t *testing.T) { assert.Equal(t, baseAcc, res1) } -func TestSendMsgWithAccounts(t *testing.T) { +func TestMsgSendWithAccounts(t *testing.T) { gapp := newGaiaApp() // Construct some genesis bytes to reflect GaiaAccount @@ -233,7 +233,7 @@ func TestSendMsgWithAccounts(t *testing.T) { SignCheckDeliver(t, gapp, sendMsg1, []int64{1}, true, priv1) } -func TestSendMsgMultipleOut(t *testing.T) { +func TestMsgSendMultipleOut(t *testing.T) { gapp := newGaiaApp() genCoins, err := sdk.ParseCoins("42foocoin") @@ -293,7 +293,7 @@ func TestSengMsgMultipleInOut(t *testing.T) { CheckBalance(t, gapp, addr3, "10foocoin") } -func TestSendMsgDependent(t *testing.T) { +func TestMsgSendDependent(t *testing.T) { gapp := newGaiaApp() genCoins, err := sdk.ParseCoins("42foocoin") diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index 1e5528308..45818b36b 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -12,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/lcd" "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" diff --git a/docs/guide.md b/docs/guide.md index fe28a09cb..9f8329835 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -69,12 +69,12 @@ but this is mostly for convenience and not type-safe. For instance, the `Basecoin` message types are defined in `x/bank/tx.go`: ```go -type SendMsg struct { +type MsgSend struct { Inputs []Input `json:"inputs"` Outputs []Output `json:"outputs"` } -type IssueMsg struct { +type MsgIssue struct { Banker sdk.Address `json:"banker"` Outputs []Output `json:"outputs"` } @@ -83,7 +83,7 @@ type IssueMsg struct { Each specifies the addresses that must sign the message: ```go -func (msg SendMsg) GetSigners() []sdk.Address { +func (msg MsgSend) GetSigners() []sdk.Address { addrs := make([]sdk.Address, len(msg.Inputs)) for i, in := range msg.Inputs { addrs[i] = in.Address @@ -91,7 +91,7 @@ func (msg SendMsg) GetSigners() []sdk.Address { return addrs } -func (msg IssueMsg) GetSigners() []sdk.Address { +func (msg MsgIssue) GetSigners() []sdk.Address { return []sdk.Address{msg.Banker} } ``` @@ -174,13 +174,13 @@ property that it can unmarshal into interface types, but it requires the relevant types to be registered ahead of type. Registration happens on a `Codec` object, so as not to taint the global name space. -For instance, in `Basecoin`, we wish to register the `SendMsg` and `IssueMsg` +For instance, in `Basecoin`, we wish to register the `MsgSend` and `MsgIssue` types: ```go cdc.RegisterInterface((*sdk.Msg)(nil), nil) -cdc.RegisterConcrete(bank.SendMsg{}, "cosmos-sdk/SendMsg", nil) -cdc.RegisterConcrete(bank.IssueMsg{}, "cosmos-sdk/IssueMsg", nil) +cdc.RegisterConcrete(bank.MsgSend{}, "cosmos-sdk/MsgSend", nil) +cdc.RegisterConcrete(bank.MsgIssue{}, "cosmos-sdk/MsgIssue", nil) ``` Note how each concrete type is given a name - these name determine the type's @@ -319,8 +319,8 @@ func NewHandler(am sdk.AccountMapper) sdk.Handler { The quintessential SDK application is Basecoin - a simple multi-asset cryptocurrency. Basecoin consists of a set of accounts stored in a Merkle tree, where each account may have -many coins. There are two message types: SendMsg and IssueMsg. -SendMsg allows coins to be sent around, while IssueMsg allows a +many coins. There are two message types: MsgSend and MsgIssue. +MsgSend allows coins to be sent around, while MsgIssue allows a set of predefined users to issue new coins. ## Conclusion diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index bb3ef05ac..e9f5b6e5a 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -64,8 +64,8 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { ).Seal() // Add handlers. - coinKeeper := bank.NewCoinKeeper(app.accountMapper) - ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) + coinKeeper := bank.NewKeeper(app.accountMapper) + ibcMapper := ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). @@ -94,12 +94,12 @@ func MakeCodec() *wire.Codec { // Register Msgs cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.SendMsg{}, "basecoin/Send", nil) - cdc.RegisterConcrete(bank.IssueMsg{}, "basecoin/Issue", nil) + cdc.RegisterConcrete(bank.MsgSend{}, "basecoin/Send", nil) + cdc.RegisterConcrete(bank.MsgIssue{}, "basecoin/Issue", nil) cdc.RegisterConcrete(ibc.IBCTransferMsg{}, "basecoin/IBCTransferMsg", nil) cdc.RegisterConcrete(ibc.IBCReceiveMsg{}, "basecoin/IBCReceiveMsg", nil) - cdc.RegisterConcrete(simplestake.BondMsg{}, "basecoin/BondMsg", nil) - cdc.RegisterConcrete(simplestake.UnbondMsg{}, "basecoin/UnbondMsg", nil) + cdc.RegisterConcrete(simplestake.MsgBond{}, "basecoin/BondMsg", nil) + cdc.RegisterConcrete(simplestake.MsgUnbond{}, "basecoin/UnbondMsg", nil) // Register AppAccount cdc.RegisterInterface((*sdk.Account)(nil), nil) diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index bc1735dde..b502aae46 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -42,12 +42,12 @@ var ( 0, } - sendMsg1 = bank.SendMsg{ + sendMsg1 = bank.MsgSend{ Inputs: []bank.Input{bank.NewInput(addr1, coins)}, Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, } - sendMsg2 = bank.SendMsg{ + sendMsg2 = bank.MsgSend{ Inputs: []bank.Input{bank.NewInput(addr1, coins)}, Outputs: []bank.Output{ bank.NewOutput(addr2, halfCoins), @@ -55,7 +55,7 @@ var ( }, } - sendMsg3 = bank.SendMsg{ + sendMsg3 = bank.MsgSend{ Inputs: []bank.Input{ bank.NewInput(addr1, coins), bank.NewInput(addr4, coins), @@ -66,7 +66,7 @@ var ( }, } - sendMsg4 = bank.SendMsg{ + sendMsg4 = bank.MsgSend{ Inputs: []bank.Input{ bank.NewInput(addr2, coins), }, @@ -75,7 +75,7 @@ var ( }, } - sendMsg5 = bank.SendMsg{ + sendMsg5 = bank.MsgSend{ Inputs: []bank.Input{ bank.NewInput(addr1, manyCoins), }, @@ -208,7 +208,7 @@ func TestGenesis(t *testing.T) { assert.Equal(t, acc, res1) } -func TestSendMsgWithAccounts(t *testing.T) { +func TestMsgSendWithAccounts(t *testing.T) { bapp := newBasecoinApp() // Construct some genesis bytes to reflect basecoin/types/AppAccount @@ -249,7 +249,7 @@ func TestSendMsgWithAccounts(t *testing.T) { SignCheckDeliver(t, bapp, sendMsg1, []int64{1}, true, priv1) } -func TestSendMsgMultipleOut(t *testing.T) { +func TestMsgSendMultipleOut(t *testing.T) { bapp := newBasecoinApp() genCoins, err := sdk.ParseCoins("42foocoin") @@ -311,7 +311,7 @@ func TestSengMsgMultipleInOut(t *testing.T) { CheckBalance(t, bapp, addr3, "10foocoin") } -func TestSendMsgDependent(t *testing.T) { +func TestMsgSendDependent(t *testing.T) { bapp := newBasecoinApp() genCoins, err := sdk.ParseCoins("42foocoin") @@ -339,7 +339,7 @@ func TestSendMsgDependent(t *testing.T) { CheckBalance(t, bapp, addr1, "42foocoin") } -func TestQuizMsg(t *testing.T) { +func TestMsgQuiz(t *testing.T) { bapp := newBasecoinApp() // Construct genesis state diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 4e5e4e22f..290a04d66 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -69,10 +69,10 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { ).Seal() // Add handlers. - coinKeeper := bank.NewCoinKeeper(app.accountMapper) + coinKeeper := bank.NewKeeper(app.accountMapper) coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper, app.RegisterCodespace(cool.DefaultCodespace)) - powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewPowConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) - ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) + powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) + ibcMapper := ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). @@ -104,15 +104,15 @@ func MakeCodec() *wire.Codec { // Register Msgs cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.SendMsg{}, "democoin/Send", nil) - cdc.RegisterConcrete(bank.IssueMsg{}, "democoin/Issue", nil) - cdc.RegisterConcrete(cool.QuizMsg{}, "democoin/Quiz", nil) - cdc.RegisterConcrete(cool.SetTrendMsg{}, "democoin/SetTrend", nil) - cdc.RegisterConcrete(pow.MineMsg{}, "democoin/Mine", nil) + cdc.RegisterConcrete(bank.MsgSend{}, "democoin/Send", nil) + cdc.RegisterConcrete(bank.MsgIssue{}, "democoin/Issue", nil) + cdc.RegisterConcrete(cool.MsgQuiz{}, "democoin/Quiz", nil) + cdc.RegisterConcrete(cool.MsgSetTrend{}, "democoin/SetTrend", nil) + cdc.RegisterConcrete(pow.MsgMine{}, "democoin/Mine", nil) cdc.RegisterConcrete(ibc.IBCTransferMsg{}, "democoin/IBCTransferMsg", nil) cdc.RegisterConcrete(ibc.IBCReceiveMsg{}, "democoin/IBCReceiveMsg", nil) - cdc.RegisterConcrete(simplestake.BondMsg{}, "democoin/BondMsg", nil) - cdc.RegisterConcrete(simplestake.UnbondMsg{}, "democoin/UnbondMsg", nil) + cdc.RegisterConcrete(simplestake.MsgBond{}, "democoin/BondMsg", nil) + cdc.RegisterConcrete(simplestake.MsgUnbond{}, "democoin/UnbondMsg", nil) // Register AppAccount cdc.RegisterInterface((*sdk.Account)(nil), nil) @@ -169,7 +169,7 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep // return sdk.ErrGenesisParse("").TraceCause(err, "") } - err = powKeeper.InitGenesis(ctx, genesisState.PowGenesis) + err = powKeeper.InitGenesis(ctx, genesisState.POWGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index f17e2a9b0..c67782d92 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -36,32 +36,32 @@ var ( 0, } - sendMsg = bank.SendMsg{ + sendMsg = bank.MsgSend{ Inputs: []bank.Input{bank.NewInput(addr1, coins)}, Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, } - quizMsg1 = cool.QuizMsg{ + quizMsg1 = cool.MsgQuiz{ Sender: addr1, CoolAnswer: "icecold", } - quizMsg2 = cool.QuizMsg{ + quizMsg2 = cool.MsgQuiz{ Sender: addr1, CoolAnswer: "badvibesonly", } - setTrendMsg1 = cool.SetTrendMsg{ + setTrendMsg1 = cool.MsgSetTrend{ Sender: addr1, Cool: "icecold", } - setTrendMsg2 = cool.SetTrendMsg{ + setTrendMsg2 = cool.MsgSetTrend{ Sender: addr1, Cool: "badvibesonly", } - setTrendMsg3 = cool.SetTrendMsg{ + setTrendMsg3 = cool.MsgSetTrend{ Sender: addr1, Cool: "warmandkind", } @@ -157,7 +157,7 @@ func TestGenesis(t *testing.T) { assert.Equal(t, acc, res1) } -func TestSendMsgWithAccounts(t *testing.T) { +func TestMsgSendWithAccounts(t *testing.T) { bapp := newDemocoinApp() // Construct some genesis bytes to reflect democoin/types/AppAccount @@ -233,7 +233,7 @@ func TestSendMsgWithAccounts(t *testing.T) { assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) } -func TestMineMsg(t *testing.T) { +func TestMsgMine(t *testing.T) { bapp := newDemocoinApp() // Construct genesis state @@ -271,11 +271,11 @@ func TestMineMsg(t *testing.T) { assert.Equal(t, acc1, res1) // Mine and check for reward - mineMsg1 := pow.GenerateMineMsg(addr1, 1, 2) + mineMsg1 := pow.GenerateMsgMine(addr1, 1, 2) SignCheckDeliver(t, bapp, mineMsg1, 0, true) CheckBalance(t, bapp, "1pow") // Mine again and check for reward - mineMsg2 := pow.GenerateMineMsg(addr1, 2, 3) + mineMsg2 := pow.GenerateMsgMine(addr1, 2, 3) SignCheckDeliver(t, bapp, mineMsg2, 1, true) CheckBalance(t, bapp, "2pow") // Mine again - should be invalid @@ -284,7 +284,7 @@ func TestMineMsg(t *testing.T) { } -func TestQuizMsg(t *testing.T) { +func TestMsgQuiz(t *testing.T) { bapp := newDemocoinApp() // Construct genesis state diff --git a/examples/democoin/types/account.go b/examples/democoin/types/account.go index d90525f1d..8a744229a 100644 --- a/examples/democoin/types/account.go +++ b/examples/democoin/types/account.go @@ -45,8 +45,8 @@ func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { // State to Unmarshal type GenesisState struct { Accounts []*GenesisAccount `json:"accounts"` - PowGenesis pow.PowGenesis `json:"pow"` - CoolGenesis cool.CoolGenesis `json:"cool"` + POWGenesis pow.Genesis `json:"pow"` + CoolGenesis cool.Genesis `json:"cool"` } // GenesisAccount doesn't need pubkey or sequence diff --git a/examples/democoin/x/cool/commands/tx.go b/examples/democoin/x/cool/commands/tx.go index 88c5e4e68..90f31d283 100644 --- a/examples/democoin/x/cool/commands/tx.go +++ b/examples/democoin/x/cool/commands/tx.go @@ -34,19 +34,13 @@ func QuizTxCmd(cdc *wire.Codec) *cobra.Command { } // create the message - msg := cool.NewQuizMsg(from, args[0]) + msg := cool.NewMsgQuiz(from, args[0]) // get account name name := viper.GetString(client.FlagName) - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - // build and sign the transaction, then broadcast to Tendermint - res, err := ctx.SignBuildBroadcast(name, msg, cdc) + res, err := ctx.EnsureSignBuildBroadcast(name, msg, cdc) if err != nil { return err } @@ -78,17 +72,11 @@ func SetTrendTxCmd(cdc *wire.Codec) *cobra.Command { // get account name name := viper.GetString(client.FlagName) - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - // create the message - msg := cool.NewSetTrendMsg(from, args[0]) + msg := cool.NewMsgSetTrend(from, args[0]) // build and sign the transaction, then broadcast to Tendermint - res, err := ctx.SignBuildBroadcast(name, msg, cdc) + res, err := ctx.EnsureSignBuildBroadcast(name, msg, cdc) if err != nil { return err } diff --git a/examples/democoin/x/cool/errors.go b/examples/democoin/x/cool/errors.go index 4c28f94ba..7a5e62c5d 100644 --- a/examples/democoin/x/cool/errors.go +++ b/examples/democoin/x/cool/errors.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// Cool errors reserve 400 ~ 499. const ( DefaultCodespace sdk.CodespaceType = 6 diff --git a/examples/democoin/x/cool/handler.go b/examples/democoin/x/cool/handler.go index e2b36b218..c82fa4ae4 100644 --- a/examples/democoin/x/cool/handler.go +++ b/examples/democoin/x/cool/handler.go @@ -21,10 +21,10 @@ import ( func NewHandler(k Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { - case SetTrendMsg: - return handleSetTrendMsg(ctx, k, msg) - case QuizMsg: - return handleQuizMsg(ctx, k, msg) + case MsgSetTrend: + return handleMsgSetTrend(ctx, k, msg) + case MsgQuiz: + return handleMsgQuiz(ctx, k, msg) default: errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name()) return sdk.ErrUnknownRequest(errMsg).Result() @@ -32,14 +32,14 @@ func NewHandler(k Keeper) sdk.Handler { } } -// Handle QuizMsg This is the engine of your module -func handleSetTrendMsg(ctx sdk.Context, k Keeper, msg SetTrendMsg) sdk.Result { +// Handle MsgQuiz This is the engine of your module +func handleMsgSetTrend(ctx sdk.Context, k Keeper, msg MsgSetTrend) sdk.Result { k.setTrend(ctx, msg.Cool) return sdk.Result{} } -// Handle QuizMsg This is the engine of your module -func handleQuizMsg(ctx sdk.Context, k Keeper, msg QuizMsg) sdk.Result { +// Handle MsgQuiz This is the engine of your module +func handleMsgQuiz(ctx sdk.Context, k Keeper, msg MsgQuiz) sdk.Result { correct := k.CheckTrend(ctx, msg.CoolAnswer) diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index 3b6c8e9ae..b180cd23c 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -7,7 +7,7 @@ import ( // Keeper - handlers sets/gets of custom variables for your module type Keeper struct { - ck bank.CoinKeeper + ck bank.Keeper storeKey sdk.StoreKey // The (unexposed) key used to access the store from the Context. @@ -15,7 +15,7 @@ type Keeper struct { } // NewKeeper - Returns the Keeper -func NewKeeper(key sdk.StoreKey, bankKeeper bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { +func NewKeeper(key sdk.StoreKey, bankKeeper bank.Keeper, codespace sdk.CodespaceType) Keeper { return Keeper{bankKeeper, key, codespace} } @@ -44,7 +44,7 @@ func (k Keeper) CheckTrend(ctx sdk.Context, guessedTrend string) bool { } // InitGenesis - store the genesis trend -func (k Keeper) InitGenesis(ctx sdk.Context, data CoolGenesis) error { +func (k Keeper) InitGenesis(ctx sdk.Context, data Genesis) error { k.setTrend(ctx, data.Trend) return nil } diff --git a/examples/democoin/x/cool/types.go b/examples/democoin/x/cool/types.go index e24c363ac..caaf8610f 100644 --- a/examples/democoin/x/cool/types.go +++ b/examples/democoin/x/cool/types.go @@ -8,39 +8,39 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// A really cool msg type, these fields are can be entirely arbitrary and +// a really cool msg type, these fields are can be entirely arbitrary and // custom to your message -type SetTrendMsg struct { +type MsgSetTrend struct { Sender sdk.Address Cool string } -// Genesis state - specify genesis trend -type CoolGenesis struct { +// genesis state - specify genesis trend +type Genesis struct { Trend string `json:"trend"` } -// New cool message -func NewSetTrendMsg(sender sdk.Address, cool string) SetTrendMsg { - return SetTrendMsg{ +// new cool message +func NewMsgSetTrend(sender sdk.Address, cool string) MsgSetTrend { + return MsgSetTrend{ Sender: sender, Cool: cool, } } // enforce the msg type at compile time -var _ sdk.Msg = SetTrendMsg{} +var _ sdk.Msg = MsgSetTrend{} // nolint -func (msg SetTrendMsg) Type() string { return "cool" } -func (msg SetTrendMsg) Get(key interface{}) (value interface{}) { return nil } -func (msg SetTrendMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } -func (msg SetTrendMsg) String() string { - return fmt.Sprintf("SetTrendMsg{Sender: %v, Cool: %v}", msg.Sender, msg.Cool) +func (msg MsgSetTrend) Type() string { return "cool" } +func (msg MsgSetTrend) Get(key interface{}) (value interface{}) { return nil } +func (msg MsgSetTrend) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } +func (msg MsgSetTrend) String() string { + return fmt.Sprintf("MsgSetTrend{Sender: %v, Cool: %v}", msg.Sender, msg.Cool) } // Validate Basic is used to quickly disqualify obviously invalid messages quickly -func (msg SetTrendMsg) ValidateBasic() sdk.Error { +func (msg MsgSetTrend) ValidateBasic() sdk.Error { if len(msg.Sender) == 0 { return sdk.ErrUnknownAddress(msg.Sender.String()).Trace("") } @@ -54,7 +54,7 @@ func (msg SetTrendMsg) ValidateBasic() sdk.Error { } // Get the bytes for the message signer to sign on -func (msg SetTrendMsg) GetSignBytes() []byte { +func (msg MsgSetTrend) GetSignBytes() []byte { b, err := json.Marshal(msg) if err != nil { panic(err) @@ -66,32 +66,32 @@ func (msg SetTrendMsg) GetSignBytes() []byte { // A message type to quiz how cool you are. these fields are can be entirely // arbitrary and custom to your message -type QuizMsg struct { +type MsgQuiz struct { Sender sdk.Address CoolAnswer string } // New cool message -func NewQuizMsg(sender sdk.Address, coolerthancool string) QuizMsg { - return QuizMsg{ +func NewMsgQuiz(sender sdk.Address, coolerthancool string) MsgQuiz { + return MsgQuiz{ Sender: sender, CoolAnswer: coolerthancool, } } // enforce the msg type at compile time -var _ sdk.Msg = QuizMsg{} +var _ sdk.Msg = MsgQuiz{} // nolint -func (msg QuizMsg) Type() string { return "cool" } -func (msg QuizMsg) Get(key interface{}) (value interface{}) { return nil } -func (msg QuizMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } -func (msg QuizMsg) String() string { - return fmt.Sprintf("QuizMsg{Sender: %v, CoolAnswer: %v}", msg.Sender, msg.CoolAnswer) +func (msg MsgQuiz) Type() string { return "cool" } +func (msg MsgQuiz) Get(key interface{}) (value interface{}) { return nil } +func (msg MsgQuiz) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } +func (msg MsgQuiz) String() string { + return fmt.Sprintf("MsgQuiz{Sender: %v, CoolAnswer: %v}", msg.Sender, msg.CoolAnswer) } // Validate Basic is used to quickly disqualify obviously invalid messages quickly -func (msg QuizMsg) ValidateBasic() sdk.Error { +func (msg MsgQuiz) ValidateBasic() sdk.Error { if len(msg.Sender) == 0 { return sdk.ErrUnknownAddress(msg.Sender.String()).Trace("") } @@ -99,7 +99,7 @@ func (msg QuizMsg) ValidateBasic() sdk.Error { } // Get the bytes for the message signer to sign on -func (msg QuizMsg) GetSignBytes() []byte { +func (msg MsgQuiz) GetSignBytes() []byte { b, err := json.Marshal(msg) if err != nil { panic(err) diff --git a/examples/democoin/x/pow/commands/tx.go b/examples/democoin/x/pow/commands/tx.go index 5fa11a476..017047d08 100644 --- a/examples/democoin/x/pow/commands/tx.go +++ b/examples/democoin/x/pow/commands/tx.go @@ -14,6 +14,7 @@ import ( authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" ) +// command to mine some pow! func MineCmd(cdc *wire.Codec) *cobra.Command { return &cobra.Command{ Use: "mine [difficulty] [count] [nonce] [solution]", @@ -36,12 +37,10 @@ func MineCmd(cdc *wire.Codec) *cobra.Command { if err != nil { return err } - count, err := strconv.ParseUint(args[1], 0, 64) if err != nil { return err } - nonce, err := strconv.ParseUint(args[2], 0, 64) if err != nil { return err @@ -49,19 +48,13 @@ func MineCmd(cdc *wire.Codec) *cobra.Command { solution := []byte(args[3]) - msg := pow.NewMineMsg(from, difficulty, count, nonce, solution) + msg := pow.NewMsgMine(from, difficulty, count, nonce, solution) // get account name name := ctx.FromAddressName - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - // build and sign the transaction, then broadcast to Tendermint - res, err := ctx.SignBuildBroadcast(name, msg, cdc) + res, err := ctx.EnsureSignBuildBroadcast(name, msg, cdc) if err != nil { return err } diff --git a/examples/democoin/x/pow/errors.go b/examples/democoin/x/pow/errors.go index d387f9b9a..a499e0d9f 100644 --- a/examples/democoin/x/pow/errors.go +++ b/examples/democoin/x/pow/errors.go @@ -4,19 +4,20 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// TODO remove, seems hacky type CodeType = sdk.CodeType +// POW errors reserve 200 ~ 299 const ( - DefaultCodespace sdk.CodespaceType = 5 - - CodeInvalidDifficulty CodeType = 201 - CodeNonexistentDifficulty CodeType = 202 - CodeNonexistentReward CodeType = 203 - CodeNonexistentCount CodeType = 204 - CodeInvalidProof CodeType = 205 - CodeNotBelowTarget CodeType = 206 - CodeInvalidCount CodeType = 207 - CodeUnknownRequest CodeType = sdk.CodeUnknownRequest + DefaultCodespace sdk.CodespaceType = 5 + CodeInvalidDifficulty CodeType = 201 + CodeNonexistentDifficulty CodeType = 202 + CodeNonexistentReward CodeType = 203 + CodeNonexistentCount CodeType = 204 + CodeInvalidProof CodeType = 205 + CodeNotBelowTarget CodeType = 206 + CodeInvalidCount CodeType = 207 + CodeUnknownRequest CodeType = sdk.CodeUnknownRequest ) func codeToDefaultMsg(code CodeType) string { @@ -42,30 +43,25 @@ func codeToDefaultMsg(code CodeType) string { } } +// nolint func ErrInvalidDifficulty(codespace sdk.CodespaceType, msg string) sdk.Error { return newError(codespace, CodeInvalidDifficulty, msg) } - func ErrNonexistentDifficulty(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeNonexistentDifficulty, "") } - func ErrNonexistentReward(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeNonexistentReward, "") } - func ErrNonexistentCount(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeNonexistentCount, "") } - func ErrInvalidProof(codespace sdk.CodespaceType, msg string) sdk.Error { return newError(codespace, CodeInvalidProof, msg) } - func ErrNotBelowTarget(codespace sdk.CodespaceType, msg string) sdk.Error { return newError(codespace, CodeNotBelowTarget, msg) } - func ErrInvalidCount(codespace sdk.CodespaceType, msg string) sdk.Error { return newError(codespace, CodeInvalidCount, msg) } @@ -73,9 +69,8 @@ func ErrInvalidCount(codespace sdk.CodespaceType, msg string) sdk.Error { func msgOrDefaultMsg(msg string, code CodeType) string { if msg != "" { return msg - } else { - return codeToDefaultMsg(code) } + return codeToDefaultMsg(code) } func newError(codespace sdk.CodespaceType, code CodeType, msg string) sdk.Error { diff --git a/examples/democoin/x/pow/handler.go b/examples/democoin/x/pow/handler.go index d1a691139..2dd549bde 100644 --- a/examples/democoin/x/pow/handler.go +++ b/examples/democoin/x/pow/handler.go @@ -6,17 +6,18 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// POW handler func (pk Keeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { - case MineMsg: - return handleMineMsg(ctx, pk, msg) + case MsgMine: + return handleMsgMine(ctx, pk, msg) default: errMsg := "Unrecognized pow Msg type: " + reflect.TypeOf(msg).Name() return sdk.ErrUnknownRequest(errMsg).Result() } } -func handleMineMsg(ctx sdk.Context, pk Keeper, msg MineMsg) sdk.Result { +func handleMsgMine(ctx sdk.Context, pk Keeper, msg MsgMine) sdk.Result { // precondition: msg has passed ValidateBasic diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index 4b1a571f7..8a4f81de2 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -20,8 +20,8 @@ func TestPowHandler(t *testing.T) { am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - config := NewPowConfig("pow", int64(1)) - ck := bank.NewCoinKeeper(am) + config := NewConfig("pow", int64(1)) + ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, config, ck, DefaultCodespace) handler := keeper.Handler @@ -30,11 +30,11 @@ func TestPowHandler(t *testing.T) { count := uint64(1) difficulty := uint64(2) - err := keeper.InitGenesis(ctx, PowGenesis{uint64(1), uint64(0)}) + err := keeper.InitGenesis(ctx, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) nonce, proof := mine(addr, count, difficulty) - msg := NewMineMsg(addr, difficulty, count, nonce, proof) + msg := NewMsgMine(addr, difficulty, count, nonce, proof) result := handler(ctx, msg) assert.Equal(t, result, sdk.Result{}) @@ -51,7 +51,7 @@ func TestPowHandler(t *testing.T) { difficulty = uint64(4) nonce, proof = mine(addr, count, difficulty) - msg = NewMineMsg(addr, difficulty, count, nonce, proof) + msg = NewMsgMine(addr, difficulty, count, nonce, proof) result = handler(ctx, msg) assert.NotEqual(t, result, sdk.Result{}) diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 70453d6d6..9a5edf0b5 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -9,42 +9,45 @@ import ( ) // module users must specify coin denomination and reward (constant) per PoW solution -type PowConfig struct { +type Config struct { Denomination string Reward int64 } // genesis info must specify starting difficulty and starting count -type PowGenesis struct { +type Genesis struct { Difficulty uint64 `json:"difficulty"` Count uint64 `json:"count"` } +// POW Keeper type Keeper struct { key sdk.StoreKey - config PowConfig - ck bank.CoinKeeper + config Config + ck bank.Keeper codespace sdk.CodespaceType } -func NewPowConfig(denomination string, reward int64) PowConfig { - return PowConfig{denomination, reward} +func NewConfig(denomination string, reward int64) Config { + return Config{denomination, reward} } -func NewKeeper(key sdk.StoreKey, config PowConfig, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { +func NewKeeper(key sdk.StoreKey, config Config, ck bank.Keeper, codespace sdk.CodespaceType) Keeper { return Keeper{key, config, ck, codespace} } -func (pk Keeper) InitGenesis(ctx sdk.Context, genesis PowGenesis) error { - pk.SetLastDifficulty(ctx, genesis.Difficulty) - pk.SetLastCount(ctx, genesis.Count) +// Init Genessis for the POW module +func (k Keeper) InitGenesis(ctx sdk.Context, genesis Genesis) error { + k.SetLastDifficulty(ctx, genesis.Difficulty) + k.SetLastCount(ctx, genesis.Count) return nil } var lastDifficultyKey = []byte("lastDifficultyKey") -func (pk Keeper) GetLastDifficulty(ctx sdk.Context) (uint64, error) { - store := ctx.KVStore(pk.key) +// get the last mining difficulty +func (k Keeper) GetLastDifficulty(ctx sdk.Context) (uint64, error) { + store := ctx.KVStore(k.key) stored := store.Get(lastDifficultyKey) if stored == nil { panic("no stored difficulty") @@ -53,15 +56,17 @@ func (pk Keeper) GetLastDifficulty(ctx sdk.Context) (uint64, error) { } } -func (pk Keeper) SetLastDifficulty(ctx sdk.Context, diff uint64) { - store := ctx.KVStore(pk.key) +// set the last mining difficulty +func (k Keeper) SetLastDifficulty(ctx sdk.Context, diff uint64) { + store := ctx.KVStore(k.key) store.Set(lastDifficultyKey, []byte(strconv.FormatUint(diff, 16))) } var countKey = []byte("count") -func (pk Keeper) GetLastCount(ctx sdk.Context) (uint64, error) { - store := ctx.KVStore(pk.key) +// get the last count +func (k Keeper) GetLastCount(ctx sdk.Context) (uint64, error) { + store := ctx.KVStore(k.key) stored := store.Get(countKey) if stored == nil { panic("no stored count") @@ -70,45 +75,45 @@ func (pk Keeper) GetLastCount(ctx sdk.Context) (uint64, error) { } } -func (pk Keeper) SetLastCount(ctx sdk.Context, count uint64) { - store := ctx.KVStore(pk.key) +// set the last count +func (k Keeper) SetLastCount(ctx sdk.Context, count uint64) { + store := ctx.KVStore(k.key) store.Set(countKey, []byte(strconv.FormatUint(count, 16))) } -func (pk Keeper) CheckValid(ctx sdk.Context, difficulty uint64, count uint64) (uint64, uint64, sdk.Error) { +// Is the keeper state valid? +func (k Keeper) CheckValid(ctx sdk.Context, difficulty uint64, count uint64) (uint64, uint64, sdk.Error) { - lastDifficulty, err := pk.GetLastDifficulty(ctx) + lastDifficulty, err := k.GetLastDifficulty(ctx) if err != nil { - return 0, 0, ErrNonexistentDifficulty(pk.codespace) + return 0, 0, ErrNonexistentDifficulty(k.codespace) } newDifficulty := lastDifficulty + 1 - lastCount, err := pk.GetLastCount(ctx) + lastCount, err := k.GetLastCount(ctx) if err != nil { - return 0, 0, ErrNonexistentCount(pk.codespace) + return 0, 0, ErrNonexistentCount(k.codespace) } newCount := lastCount + 1 if count != newCount { - return 0, 0, ErrInvalidCount(pk.codespace, fmt.Sprintf("invalid count: was %d, should have been %d", count, newCount)) + return 0, 0, ErrInvalidCount(k.codespace, fmt.Sprintf("invalid count: was %d, should have been %d", count, newCount)) } - if difficulty != newDifficulty { - return 0, 0, ErrInvalidDifficulty(pk.codespace, fmt.Sprintf("invalid difficulty: was %d, should have been %d", difficulty, newDifficulty)) + return 0, 0, ErrInvalidDifficulty(k.codespace, fmt.Sprintf("invalid difficulty: was %d, should have been %d", difficulty, newDifficulty)) } - return newDifficulty, newCount, nil - } -func (pk Keeper) ApplyValid(ctx sdk.Context, sender sdk.Address, newDifficulty uint64, newCount uint64) sdk.Error { - _, ckErr := pk.ck.AddCoins(ctx, sender, []sdk.Coin{sdk.Coin{pk.config.Denomination, pk.config.Reward}}) +// Add some coins for a POW well done +func (k Keeper) ApplyValid(ctx sdk.Context, sender sdk.Address, newDifficulty uint64, newCount uint64) sdk.Error { + _, ckErr := k.ck.AddCoins(ctx, sender, []sdk.Coin{sdk.Coin{k.config.Denomination, k.config.Reward}}) if ckErr != nil { return ckErr } - pk.SetLastDifficulty(ctx, newDifficulty) - pk.SetLastCount(ctx, newCount) + k.SetLastDifficulty(ctx, newDifficulty) + k.SetLastCount(ctx, newCount) return nil } diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index d0b60fa17..4c01559f6 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -33,11 +33,11 @@ func TestPowKeeperGetSet(t *testing.T) { am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - config := NewPowConfig("pow", int64(1)) - ck := bank.NewCoinKeeper(am) + config := NewConfig("pow", int64(1)) + ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, config, ck, DefaultCodespace) - err := keeper.InitGenesis(ctx, PowGenesis{uint64(1), uint64(0)}) + err := keeper.InitGenesis(ctx, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) res, err := keeper.GetLastDifficulty(ctx) diff --git a/examples/democoin/x/pow/mine.go b/examples/democoin/x/pow/mine.go index ff2264aaa..21d389a1d 100644 --- a/examples/democoin/x/pow/mine.go +++ b/examples/democoin/x/pow/mine.go @@ -9,9 +9,10 @@ import ( crypto "github.com/tendermint/go-crypto" ) -func GenerateMineMsg(sender sdk.Address, count uint64, difficulty uint64) MineMsg { +// generate the mine message +func GenerateMsgMine(sender sdk.Address, count uint64, difficulty uint64) MsgMine { nonce, hash := mine(sender, count, difficulty) - return NewMineMsg(sender, difficulty, count, nonce, hash) + return NewMsgMine(sender, difficulty, count, nonce, hash) } func hash(sender sdk.Address, count uint64, nonce uint64) []byte { diff --git a/examples/democoin/x/pow/types.go b/examples/democoin/x/pow/types.go index 69d56e4f1..999dd4197 100644 --- a/examples/democoin/x/pow/types.go +++ b/examples/democoin/x/pow/types.go @@ -13,8 +13,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// MineMsg - mine some coins with PoW -type MineMsg struct { +// MsgMine - mine some coins with PoW +type MsgMine struct { Sender sdk.Address `json:"sender"` Difficulty uint64 `json:"difficulty"` Count uint64 `json:"count"` @@ -23,21 +23,23 @@ type MineMsg struct { } // enforce the msg type at compile time -var _ sdk.Msg = MineMsg{} +var _ sdk.Msg = MsgMine{} -// NewMineMsg - construct mine message -func NewMineMsg(sender sdk.Address, difficulty uint64, count uint64, nonce uint64, proof []byte) MineMsg { - return MineMsg{sender, difficulty, count, nonce, proof} +// NewMsgMine - construct mine message +func NewMsgMine(sender sdk.Address, difficulty uint64, count uint64, nonce uint64, proof []byte) MsgMine { + return MsgMine{sender, difficulty, count, nonce, proof} } -func (msg MineMsg) Type() string { return "pow" } -func (msg MineMsg) Get(key interface{}) (value interface{}) { return nil } -func (msg MineMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } -func (msg MineMsg) String() string { - return fmt.Sprintf("MineMsg{Sender: %v, Difficulty: %d, Count: %d, Nonce: %d, Proof: %s}", msg.Sender, msg.Difficulty, msg.Count, msg.Nonce, msg.Proof) +// nolint +func (msg MsgMine) Type() string { return "pow" } +func (msg MsgMine) Get(key interface{}) (value interface{}) { return nil } +func (msg MsgMine) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } +func (msg MsgMine) String() string { + return fmt.Sprintf("MsgMine{Sender: %v, Difficulty: %d, Count: %d, Nonce: %d, Proof: %s}", msg.Sender, msg.Difficulty, msg.Count, msg.Nonce, msg.Proof) } -func (msg MineMsg) ValidateBasic() sdk.Error { +// validate the mine message +func (msg MsgMine) ValidateBasic() sdk.Error { // check hash var data []byte // hash must include sender, so no other users can race the tx @@ -69,7 +71,8 @@ func (msg MineMsg) ValidateBasic() sdk.Error { return nil } -func (msg MineMsg) GetSignBytes() []byte { +// get the mine message sign bytes +func (msg MsgMine) GetSignBytes() []byte { b, err := json.Marshal(msg) if err != nil { panic(err) diff --git a/examples/democoin/x/pow/types_test.go b/examples/democoin/x/pow/types_test.go index 34ab8914e..bf2e9169b 100644 --- a/examples/democoin/x/pow/types_test.go +++ b/examples/democoin/x/pow/types_test.go @@ -9,70 +9,72 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func TestNewMineMsg(t *testing.T) { +func TestNewMsgMine(t *testing.T) { addr := sdk.Address([]byte("sender")) - msg := MineMsg{addr, 0, 0, 0, []byte("")} - equiv := NewMineMsg(addr, 0, 0, 0, []byte("")) + msg := MsgMine{addr, 0, 0, 0, []byte("")} + equiv := NewMsgMine(addr, 0, 0, 0, []byte("")) assert.Equal(t, msg, equiv, "%s != %s", msg, equiv) } -func TestMineMsgType(t *testing.T) { +func TestMsgMineType(t *testing.T) { addr := sdk.Address([]byte("sender")) - msg := MineMsg{addr, 0, 0, 0, []byte("")} + msg := MsgMine{addr, 0, 0, 0, []byte("")} assert.Equal(t, msg.Type(), "pow") } -func TestMineMsgValidation(t *testing.T) { +func TestMsgMineValidation(t *testing.T) { addr := sdk.Address([]byte("sender")) otherAddr := sdk.Address([]byte("another")) count := uint64(0) + for difficulty := uint64(1); difficulty < 1000; difficulty += 100 { - count += 1 + + count++ nonce, proof := mine(addr, count, difficulty) - msg := MineMsg{addr, difficulty, count, nonce, proof} + msg := MsgMine{addr, difficulty, count, nonce, proof} err := msg.ValidateBasic() assert.Nil(t, err, "error with difficulty %d - %+v", difficulty, err) - msg.Count += 1 + msg.Count++ err = msg.ValidateBasic() assert.NotNil(t, err, "count was wrong, should have thrown error with msg %s", msg) - msg.Count -= 1 - msg.Nonce += 1 + msg.Count-- + msg.Nonce++ err = msg.ValidateBasic() assert.NotNil(t, err, "nonce was wrong, should have thrown error with msg %s", msg) - msg.Nonce -= 1 + msg.Nonce-- msg.Sender = otherAddr err = msg.ValidateBasic() assert.NotNil(t, err, "sender was wrong, should have thrown error with msg %s", msg) } } -func TestMineMsgString(t *testing.T) { +func TestMsgMineString(t *testing.T) { addr := sdk.Address([]byte("sender")) - msg := MineMsg{addr, 0, 0, 0, []byte("abc")} + msg := MsgMine{addr, 0, 0, 0, []byte("abc")} res := msg.String() - assert.Equal(t, res, "MineMsg{Sender: 73656E646572, Difficulty: 0, Count: 0, Nonce: 0, Proof: abc}") + assert.Equal(t, res, "MsgMine{Sender: 73656E646572, Difficulty: 0, Count: 0, Nonce: 0, Proof: abc}") } -func TestMineMsgGet(t *testing.T) { +func TestMsgMineGet(t *testing.T) { addr := sdk.Address([]byte("sender")) - msg := MineMsg{addr, 0, 0, 0, []byte("")} + msg := MsgMine{addr, 0, 0, 0, []byte("")} res := msg.Get(nil) assert.Nil(t, res) } -func TestMineMsgGetSignBytes(t *testing.T) { +func TestMsgMineGetSignBytes(t *testing.T) { addr := sdk.Address([]byte("sender")) - msg := MineMsg{addr, 1, 1, 1, []byte("abc")} + msg := MsgMine{addr, 1, 1, 1, []byte("abc")} res := msg.GetSignBytes() assert.Equal(t, string(res), `{"sender":"73656E646572","difficulty":1,"count":1,"nonce":1,"proof":"YWJj"}`) } -func TestMineMsgGetSigners(t *testing.T) { +func TestMsgMineGetSigners(t *testing.T) { addr := sdk.Address([]byte("sender")) - msg := MineMsg{addr, 1, 1, 1, []byte("abc")} + msg := MsgMine{addr, 1, 1, 1, []byte("abc")} res := msg.GetSigners() assert.Equal(t, fmt.Sprintf("%v", res), "[73656E646572]") } diff --git a/examples/kvstore/main.go b/examples/kvstore/main.go index 0d80826ed..d6b71171d 100644 --- a/examples/kvstore/main.go +++ b/examples/kvstore/main.go @@ -41,7 +41,7 @@ func main() { baseApp.SetTxDecoder(decodeTx) // Set a handler Route. - baseApp.Router().AddRoute("kvstore", KVStoreHandler(capKeyMainStore)) + baseApp.Router().AddRoute("kvstore", Handler(capKeyMainStore)) // Load latest version. if err := baseApp.LoadLatestVersion(capKeyMainStore); err != nil { @@ -65,11 +65,12 @@ func main() { return } -func KVStoreHandler(storeKey sdk.StoreKey) sdk.Handler { +// KVStore Handler +func Handler(storeKey sdk.StoreKey) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { dTx, ok := msg.(kvstoreTx) if !ok { - panic("KVStoreHandler should only receive kvstoreTx") + panic("Handler should only receive kvstoreTx") } // tx is already unmarshalled diff --git a/server/init.go b/server/init.go index f2578cb19..a68566cdf 100644 --- a/server/init.go +++ b/server/init.go @@ -76,10 +76,10 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error { return err } - var DEFAULT_DENOM = "mycoin" + var defaultDenom = "mycoin" // Now, we want to add the custom app_state - appState, err := c.genAppState(args, addr, DEFAULT_DENOM) + appState, err := c.genAppState(args, addr, defaultDenom) if err != nil { return err } diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 2a9b680e5..67504fa6b 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -12,7 +12,7 @@ import ( // ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout func ShowNodeIDCmd(ctx *Context) *cobra.Command { - cmd := showNodeId{ctx} + cmd := showNodeID{ctx} return &cobra.Command{ Use: "show_node_id", Short: "Show this node's ID", @@ -20,11 +20,11 @@ func ShowNodeIDCmd(ctx *Context) *cobra.Command { } } -type showNodeId struct { +type showNodeID struct { context *Context } -func (s showNodeId) run(cmd *cobra.Command, args []string) error { +func (s showNodeID) run(cmd *cobra.Command, args []string) error { cfg := s.context.Config nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) if err != nil { diff --git a/server/util.go b/server/util.go index 95dc4b30d..cf37ec5cc 100644 --- a/server/util.go +++ b/server/util.go @@ -14,6 +14,7 @@ import ( "github.com/tendermint/tmlibs/log" ) +// server context type Context struct { Config *cfg.Config Logger log.Logger @@ -59,6 +60,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error } } +// add server commands func AddCommands( rootCmd *cobra.Command, appState GenAppState, appCreator AppCreator, diff --git a/store/cachekvstore.go b/store/cachekvstore.go index 6c5cc9542..772b59305 100644 --- a/store/cachekvstore.go +++ b/store/cachekvstore.go @@ -26,13 +26,12 @@ type cacheKVStore struct { var _ CacheKVStore = (*cacheKVStore)(nil) +// nolint func NewCacheKVStore(parent KVStore) *cacheKVStore { - ci := &cacheKVStore{ cache: make(map[string]cValue), parent: parent, } - return ci } @@ -170,9 +169,8 @@ func (ci *cacheKVStore) dirtyItems(ascending bool) []cmn.KVPair { sort.Slice(items, func(i, j int) bool { if ascending { return bytes.Compare(items[i].Key, items[j].Key) < 0 - } else { - return bytes.Compare(items[i].Key, items[j].Key) > 0 } + return bytes.Compare(items[i].Key, items[j].Key) > 0 }) return items } diff --git a/store/cachekvstore_test.go b/store/cachekvstore_test.go index e29cd6156..0c88ca27d 100644 --- a/store/cachekvstore_test.go +++ b/store/cachekvstore_test.go @@ -105,7 +105,7 @@ func TestCacheKVIteratorBounds(t *testing.T) { k, v := itr.Key(), itr.Value() assert.Equal(t, keyFmt(i), k) assert.Equal(t, valFmt(i), v) - i += 1 + i++ } assert.Equal(t, nItems, i) @@ -113,7 +113,7 @@ func TestCacheKVIteratorBounds(t *testing.T) { itr = st.Iterator(bz("money"), nil) i = 0 for ; itr.Valid(); itr.Next() { - i += 1 + i++ } assert.Equal(t, 0, i) @@ -124,7 +124,7 @@ func TestCacheKVIteratorBounds(t *testing.T) { k, v := itr.Key(), itr.Value() assert.Equal(t, keyFmt(i), k) assert.Equal(t, valFmt(i), v) - i += 1 + i++ } assert.Equal(t, 3, i) @@ -135,7 +135,7 @@ func TestCacheKVIteratorBounds(t *testing.T) { k, v := itr.Key(), itr.Value() assert.Equal(t, keyFmt(i), k) assert.Equal(t, valFmt(i), v) - i += 1 + i++ } assert.Equal(t, 4, i) } @@ -369,7 +369,7 @@ func assertIterateDomain(t *testing.T, st KVStore, expectedN int) { k, v := itr.Key(), itr.Value() assert.Equal(t, keyFmt(i), k) assert.Equal(t, valFmt(i), v) - i += 1 + i++ } assert.Equal(t, expectedN, i) } @@ -397,7 +397,7 @@ func assertIterateDomainCheck(t *testing.T, st KVStore, mem dbm.DB, r []keyRange itr.Next() itr2.Next() - i += 1 + i++ } assert.False(t, itr.Valid()) @@ -479,10 +479,10 @@ func (krc *keyRangeCounter) valid() bool { func (krc *keyRangeCounter) next() { thisKeyRange := krc.keyRanges[krc.rangeIdx] if krc.idx == thisKeyRange.len()-1 { - krc.rangeIdx += 1 + krc.rangeIdx++ krc.idx = 0 } else { - krc.idx += 1 + krc.idx++ } } diff --git a/store/cachemergeiterator.go b/store/cachemergeiterator.go index b6c50c42c..cd739500d 100644 --- a/store/cachemergeiterator.go +++ b/store/cachemergeiterator.go @@ -151,9 +151,8 @@ func (iter *cacheMergeIterator) Close() { func (iter *cacheMergeIterator) compare(a, b []byte) int { if iter.ascending { return bytes.Compare(a, b) - } else { - return bytes.Compare(a, b) * -1 } + return bytes.Compare(a, b) * -1 } // Skip all delete-items from the cache w/ `key < until`. After this function, diff --git a/store/dbstoreadapter.go b/store/dbstoreadapter.go index 10c175a99..7a299471f 100644 --- a/store/dbstoreadapter.go +++ b/store/dbstoreadapter.go @@ -10,7 +10,7 @@ type dbStoreAdapter struct { } // Implements Store. -func (_ dbStoreAdapter) GetStoreType() StoreType { +func (dbStoreAdapter) GetStoreType() StoreType { return sdk.StoreTypeDB } diff --git a/store/firstlast.go b/store/firstlast.go index e0c8b11bb..e6cb08432 100644 --- a/store/firstlast.go +++ b/store/firstlast.go @@ -2,6 +2,7 @@ package store import ( "bytes" + cmn "github.com/tendermint/tmlibs/common" ) @@ -22,9 +23,8 @@ func Last(st KVStore, start, end []byte) (kv cmn.KVPair, ok bool) { if !iter.Valid() { if v := st.Get(start); v != nil { return cmn.KVPair{cp(start), cp(v)}, true - } else { - return kv, false } + return kv, false } defer iter.Close() diff --git a/store/iavlstore.go b/store/iavlstore.go index 7d006d3c1..de32e27e1 100644 --- a/store/iavlstore.go +++ b/store/iavlstore.go @@ -17,6 +17,7 @@ const ( defaultIAVLNumHistory = 1<<53 - 1 // DEPRECATED ) +// load the iavl store func LoadIAVLStore(db dbm.DB, id CommitID) (CommitStore, error) { tree := iavl.NewVersionedTree(db, defaultIAVLCacheSize) _, err := tree.LoadVersion(id.Version) diff --git a/store/iavlstore_test.go b/store/iavlstore_test.go index 824617c26..4557dea06 100644 --- a/store/iavlstore_test.go +++ b/store/iavlstore_test.go @@ -80,7 +80,7 @@ func TestIAVLIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, treeData[expectedKey]) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -91,7 +91,7 @@ func TestIAVLIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, treeData[expectedKey]) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -102,7 +102,7 @@ func TestIAVLIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, treeData[expectedKey]) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -113,7 +113,7 @@ func TestIAVLIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, treeData[expectedKey]) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -124,7 +124,7 @@ func TestIAVLIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, treeData[expectedKey]) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -135,7 +135,7 @@ func TestIAVLIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, treeData[expectedKey]) - i += 1 + i++ } assert.Equal(t, len(expected), i) } @@ -164,7 +164,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, expectedKey) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -179,7 +179,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, []byte("test4")) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -194,7 +194,7 @@ func TestIAVLSubspaceIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, []byte("test4")) - i += 1 + i++ } assert.Equal(t, len(expected), i) } @@ -223,7 +223,7 @@ func TestIAVLReverseSubspaceIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, expectedKey) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -238,7 +238,7 @@ func TestIAVLReverseSubspaceIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, []byte("test4")) - i += 1 + i++ } assert.Equal(t, len(expected), i) @@ -253,7 +253,7 @@ func TestIAVLReverseSubspaceIterator(t *testing.T) { key, value := iter.Key(), iter.Value() assert.EqualValues(t, key, expectedKey) assert.EqualValues(t, value, []byte("test4")) - i += 1 + i++ } assert.Equal(t, len(expected), i) } diff --git a/store/rootmultistore.go b/store/rootmultistore.go index 3e094712b..217e8eb14 100644 --- a/store/rootmultistore.go +++ b/store/rootmultistore.go @@ -33,6 +33,7 @@ type rootMultiStore struct { var _ CommitMultiStore = (*rootMultiStore)(nil) var _ Queryable = (*rootMultiStore)(nil) +// nolint func NewCommitMultiStore(db dbm.DB) *rootMultiStore { return &rootMultiStore{ db: db, @@ -267,7 +268,7 @@ func (rs *rootMultiStore) loadCommitStoreFromParams(id CommitID, params storePar } func (rs *rootMultiStore) nameToKey(name string) StoreKey { - for key, _ := range rs.storesParams { + for key := range rs.storesParams { if key.Name() == name { return key } diff --git a/store/types.go b/store/types.go index fa27e94da..ca43dab6b 100644 --- a/store/types.go +++ b/store/types.go @@ -5,6 +5,7 @@ import ( ) // Import cosmos-sdk/types/store.go for convenience. +// nolint type Store = types.Store type Committer = types.Committer type CommitStore = types.CommitStore diff --git a/types/errors.go b/types/errors.go index c2fe726a2..059a0dd74 100644 --- a/types/errors.go +++ b/types/errors.go @@ -25,6 +25,7 @@ func (code ABCICodeType) IsOK() bool { return false } +// get the abci code from the local code and codespace func ToABCICode(space CodespaceType, code CodeType) ABCICodeType { // TODO: Make Tendermint more aware of codespaces. if space == CodespaceRoot && code == CodeOK { @@ -33,6 +34,7 @@ func ToABCICode(space CodespaceType, code CodeType) ABCICodeType { return ABCICodeType((uint32(space) << 16) | uint32(code)) } +// SDK error codes const ( // ABCI error codes ABCICodeOK ABCICodeType = 0 diff --git a/version/command.go b/version/command.go index e28cbe57e..b505414b1 100644 --- a/version/command.go +++ b/version/command.go @@ -25,15 +25,13 @@ func getVersion() string { } // CMD - func printVersion(cmd *cobra.Command, args []string) { v := getVersion() fmt.Println(v) } -// REST - -func VersionRequestHandler(w http.ResponseWriter, r *http.Request) { +// version REST handler endpoint +func RequestHandler(w http.ResponseWriter, r *http.Request) { v := getVersion() w.Write([]byte(v)) } diff --git a/wire/wire.go b/wire/wire.go index 32c82a676..0ee01939d 100644 --- a/wire/wire.go +++ b/wire/wire.go @@ -8,6 +8,7 @@ import ( "github.com/tendermint/go-crypto" ) +// amino codec to marshal/unmarshal type Codec = amino.Codec func NewCodec() *Codec { @@ -15,10 +16,12 @@ func NewCodec() *Codec { return cdc } +// Register the go-crypto to the codec func RegisterCrypto(cdc *Codec) { crypto.RegisterAmino(cdc) } +// attempt to make some pretty json func MarshalJSONIndent(cdc *Codec, obj interface{}) ([]byte, error) { bz, err := cdc.MarshalJSON(obj) if err != nil { diff --git a/x/auth/commands/account.go b/x/auth/commands/account.go index 56f441f35..4da601df8 100644 --- a/x/auth/commands/account.go +++ b/x/auth/commands/account.go @@ -17,6 +17,7 @@ func GetAccountCmdDefault(storeName string, cdc *wire.Codec) *cobra.Command { return GetAccountCmd(storeName, cdc, GetAccountDecoder(cdc)) } +// Get account decoder for auth.DefaultAccount func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { return func(accBytes []byte) (acct sdk.Account, err error) { // acct := new(auth.BaseAccount) diff --git a/x/auth/context.go b/x/auth/context.go index 91259d9e6..b233f1e86 100644 --- a/x/auth/context.go +++ b/x/auth/context.go @@ -33,10 +33,12 @@ const ( contextKeySigners contextKey = iota ) +// add the signers to the context func WithSigners(ctx types.Context, accounts []types.Account) types.Context { return ctx.WithValue(contextKeySigners, accounts) } +// get the signers from the context func GetSigners(ctx types.Context) []types.Account { v := ctx.Value(contextKeySigners) if v == nil { diff --git a/x/auth/mapper.go b/x/auth/mapper.go index 7bc23aee1..ed69034be 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -28,6 +28,7 @@ type accountMapper struct { // NewAccountMapper returns a new sdk.AccountMapper that // uses go-amino to (binary) encode and decode concrete sdk.Accounts. +// nolint func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto sdk.Account) accountMapper { return accountMapper{ key: key, @@ -107,14 +108,14 @@ func (am accountMapper) clonePrototype() sdk.Account { panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt)) } return clone - } else { - protoRv := reflect.New(protoRt).Elem() - clone, ok := protoRv.Interface().(sdk.Account) - if !ok { - panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt)) - } - return clone } + + protoRv := reflect.New(protoRt).Elem() + clone, ok := protoRv.Interface().(sdk.Account) + if !ok { + panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt)) + } + return clone } func (am accountMapper) encodeAccount(acc sdk.Account) []byte { diff --git a/x/auth/rest/query.go b/x/auth/rest/query.go index c401fe47f..b97f883f9 100644 --- a/x/auth/rest/query.go +++ b/x/auth/rest/query.go @@ -10,16 +10,19 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + auth "github.com/cosmos/cosmos-sdk/x/auth/commands" ) -type commander struct { - storeName string - cdc *wire.Codec - decoder sdk.AccountDecoder +// register REST routes +func RegisterRoutes(r *mux.Router, cdc *wire.Codec, storeName string) { + r.HandleFunc( + "/accounts/{address}", + QueryAccountRequestHandler(storeName, cdc, auth.GetAccountDecoder(cdc)), + ).Methods("GET") } +// query accountREST Handler func QueryAccountRequestHandler(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder) func(http.ResponseWriter, *http.Request) { - c := commander{storeName, cdc, decoder} ctx := context.NewCoreContextFromViper() return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -33,7 +36,7 @@ func QueryAccountRequestHandler(storeName string, cdc *wire.Codec, decoder sdk.A } key := sdk.Address(bz) - res, err := ctx.Query(key, c.storeName) + res, err := ctx.Query(key, storeName) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Could't query account. Error: %s", err.Error()))) @@ -47,7 +50,7 @@ func QueryAccountRequestHandler(storeName string, cdc *wire.Codec, decoder sdk.A } // decode the value - account, err := c.decoder(res) + account, err := decoder(res) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Could't parse query result. Result: %s. Error: %s", res, err.Error()))) diff --git a/x/auth/rest/root.go b/x/auth/rest/root.go deleted file mode 100644 index 5417cf868..000000000 --- a/x/auth/rest/root.go +++ /dev/null @@ -1,11 +0,0 @@ -package rest - -import ( - "github.com/cosmos/cosmos-sdk/wire" - auth "github.com/cosmos/cosmos-sdk/x/auth/commands" - "github.com/gorilla/mux" -) - -func RegisterRoutes(r *mux.Router, cdc *wire.Codec, storeName string) { - r.HandleFunc("/accounts/{address}", QueryAccountRequestHandler(storeName, cdc, auth.GetAccountDecoder(cdc))).Methods("GET") -} diff --git a/x/bank/commands/sendtx.go b/x/bank/commands/sendtx.go index 56048262d..dbf2bb3c9 100644 --- a/x/bank/commands/sendtx.go +++ b/x/bank/commands/sendtx.go @@ -20,68 +20,53 @@ const ( ) // SendTxCommand will create a send tx and sign it with the given key -func SendTxCmd(Cdc *wire.Codec) *cobra.Command { - cmdr := Commander{Cdc} +func SendTxCmd(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "send", Short: "Create and sign a send tx", - RunE: cmdr.sendTxCmd, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + + // get the from/to address + from, err := ctx.GetFromAddress() + if err != nil { + return err + } + + toStr := viper.GetString(flagTo) + bz, err := hex.DecodeString(toStr) + if err != nil { + return err + } + to := sdk.Address(bz) + + // parse coins + amount := viper.GetString(flagAmount) + coins, err := sdk.ParseCoins(amount) + if err != nil { + return err + } + + // build and sign the transaction, then broadcast to Tendermint + msg := BuildMsg(from, to, coins) + res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) + if err != nil { + return err + } + fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String()) + return nil + }, } + cmd.Flags().String(flagTo, "", "Address to send coins") cmd.Flags().String(flagAmount, "", "Amount of coins to send") return cmd } -type Commander struct { - Cdc *wire.Codec -} - -func (c Commander) sendTxCmd(cmd *cobra.Command, args []string) error { - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(c.Cdc)) - - // get the from address - from, err := ctx.GetFromAddress() - if err != nil { - return err - } - - // parse coins - amount := viper.GetString(flagAmount) - coins, err := sdk.ParseCoins(amount) - if err != nil { - return err - } - - // parse destination address - dest := viper.GetString(flagTo) - bz, err := hex.DecodeString(dest) - if err != nil { - return err - } - to := sdk.Address(bz) - - // build message - msg := BuildMsg(from, to, coins) - - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - - // build and sign the transaction, then broadcast to Tendermint - res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, c.Cdc) - if err != nil { - return err - } - - fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String()) - return nil -} - +// build the sendTx msg func BuildMsg(from sdk.Address, to sdk.Address, coins sdk.Coins) sdk.Msg { input := bank.NewInput(from, coins) output := bank.NewOutput(to, coins) - msg := bank.NewSendMsg([]bank.Input{input}, []bank.Output{output}) + msg := bank.NewMsgSend([]bank.Input{input}, []bank.Output{output}) return msg } diff --git a/x/bank/errors.go b/x/bank/errors.go index d7c7e9748..bf2a3ef26 100644 --- a/x/bank/errors.go +++ b/x/bank/errors.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// Coin errors reserve 100 ~ 199. +// Bank errors reserve 100 ~ 199. const ( DefaultCodespace sdk.CodespaceType = 2 diff --git a/x/bank/handler.go b/x/bank/handler.go index 8eca94a86..a50b0afcf 100644 --- a/x/bank/handler.go +++ b/x/bank/handler.go @@ -7,13 +7,13 @@ import ( ) // NewHandler returns a handler for "bank" type messages. -func NewHandler(ck CoinKeeper) sdk.Handler { +func NewHandler(k Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { - case SendMsg: - return handleSendMsg(ctx, ck, msg) - case IssueMsg: - return handleIssueMsg(ctx, ck, msg) + case MsgSend: + return handleMsgSend(ctx, k, msg) + case MsgIssue: + return handleMsgIssue(ctx, k, msg) default: errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name() return sdk.ErrUnknownRequest(errMsg).Result() @@ -21,11 +21,11 @@ func NewHandler(ck CoinKeeper) sdk.Handler { } } -// Handle SendMsg. -func handleSendMsg(ctx sdk.Context, ck CoinKeeper, msg SendMsg) sdk.Result { +// Handle MsgSend. +func handleMsgSend(ctx sdk.Context, k Keeper, msg MsgSend) sdk.Result { // NOTE: totalIn == totalOut should already have been checked - err := ck.InputOutputCoins(ctx, msg.Inputs, msg.Outputs) + err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs) if err != nil { return err.Result() } @@ -34,7 +34,7 @@ func handleSendMsg(ctx sdk.Context, ck CoinKeeper, msg SendMsg) sdk.Result { return sdk.Result{} // TODO } -// Handle IssueMsg. -func handleIssueMsg(ctx sdk.Context, ck CoinKeeper, msg IssueMsg) sdk.Result { +// Handle MsgIssue. +func handleMsgIssue(ctx sdk.Context, k Keeper, msg MsgIssue) sdk.Result { panic("not implemented yet") } diff --git a/x/bank/keeper.go b/x/bank/keeper.go index a5fabdbb0..d1fdeaea0 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -6,7 +6,106 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -const moduleName = "bank" +// Keeper manages transfers between accounts +type Keeper struct { + am sdk.AccountMapper +} + +// NewKeeper returns a new Keeper +func NewKeeper(am sdk.AccountMapper) Keeper { + return Keeper{am: am} +} + +// GetCoins returns the coins at the addr. +func (keeper Keeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { + return getCoins(ctx, keeper.am, addr) +} + +// SetCoins sets the coins at the addr. +func (keeper Keeper) SetCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) sdk.Error { + return setCoins(ctx, keeper.am, addr, amt) +} + +// HasCoins returns whether or not an account has at least amt coins. +func (keeper Keeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { + return hasCoins(ctx, keeper.am, addr, amt) +} + +// SubtractCoins subtracts amt from the coins at the addr. +func (keeper Keeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { + return subtractCoins(ctx, keeper.am, addr, amt) +} + +// AddCoins adds amt to the coins at the addr. +func (keeper Keeper) AddCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { + return addCoins(ctx, keeper.am, addr, amt) +} + +// SendCoins moves coins from one account to another +func (keeper Keeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { + return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt) +} + +// InputOutputCoins handles a list of inputs and outputs +func (keeper Keeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { + return inputOutputCoins(ctx, keeper.am, inputs, outputs) +} + +//______________________________________________________________________________________________ + +// SendKeeper only allows transfers between accounts, without the possibility of creating coins +type SendKeeper struct { + am sdk.AccountMapper +} + +// NewSendKeeper returns a new Keeper +func NewSendKeeper(am sdk.AccountMapper) SendKeeper { + return SendKeeper{am: am} +} + +// GetCoins returns the coins at the addr. +func (keeper SendKeeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { + return getCoins(ctx, keeper.am, addr) +} + +// HasCoins returns whether or not an account has at least amt coins. +func (keeper SendKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { + return hasCoins(ctx, keeper.am, addr, amt) +} + +// SendCoins moves coins from one account to another +func (keeper SendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { + return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt) +} + +// InputOutputCoins handles a list of inputs and outputs +func (keeper SendKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { + return inputOutputCoins(ctx, keeper.am, inputs, outputs) +} + +//______________________________________________________________________________________________ + +// ViewKeeper only allows reading of balances +type ViewKeeper struct { + am sdk.AccountMapper +} + +// NewViewKeeper returns a new Keeper +func NewViewKeeper(am sdk.AccountMapper) ViewKeeper { + return ViewKeeper{am: am} +} + +// GetCoins returns the coins at the addr. +func (keeper ViewKeeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { + return getCoins(ctx, keeper.am, addr) +} + +// HasCoins returns whether or not an account has at least amt coins. +func (keeper ViewKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { + return hasCoins(ctx, keeper.am, addr, amt) +} + +//______________________________________________________________________________________________ func getCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address) sdk.Coins { acc := am.GetAccount(ctx, addr) @@ -88,102 +187,3 @@ func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, out return nil } - -// CoinKeeper manages transfers between accounts -type CoinKeeper struct { - am sdk.AccountMapper -} - -// NewCoinKeeper returns a new CoinKeeper -func NewCoinKeeper(am sdk.AccountMapper) CoinKeeper { - return CoinKeeper{am: am} -} - -// GetCoins returns the coins at the addr. -func (keeper CoinKeeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { - return getCoins(ctx, keeper.am, addr) -} - -// SetCoins sets the coins at the addr. -func (keeper CoinKeeper) SetCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) sdk.Error { - return setCoins(ctx, keeper.am, addr, amt) -} - -// HasCoins returns whether or not an account has at least amt coins. -func (keeper CoinKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { - return hasCoins(ctx, keeper.am, addr, amt) -} - -// SubtractCoins subtracts amt from the coins at the addr. -func (keeper CoinKeeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { - return subtractCoins(ctx, keeper.am, addr, amt) -} - -// AddCoins adds amt to the coins at the addr. -func (keeper CoinKeeper) AddCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { - return addCoins(ctx, keeper.am, addr, amt) -} - -// SendCoins moves coins from one account to another -func (keeper CoinKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { - return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt) -} - -// InputOutputCoins handles a list of inputs and outputs -func (keeper CoinKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { - return inputOutputCoins(ctx, keeper.am, inputs, outputs) -} - -// -------------------------------------------------- - -// SendKeeper only allows transfers between accounts, without the possibility of creating coins -type SendKeeper struct { - am sdk.AccountMapper -} - -// NewSendKeeper returns a new CoinKeeper -func NewSendKeeper(am sdk.AccountMapper) SendKeeper { - return SendKeeper{am: am} -} - -// GetCoins returns the coins at the addr. -func (keeper SendKeeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { - return getCoins(ctx, keeper.am, addr) -} - -// HasCoins returns whether or not an account has at least amt coins. -func (keeper SendKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { - return hasCoins(ctx, keeper.am, addr, amt) -} - -// SendCoins moves coins from one account to another -func (keeper SendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { - return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt) -} - -// InputOutputCoins handles a list of inputs and outputs -func (keeper SendKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { - return inputOutputCoins(ctx, keeper.am, inputs, outputs) -} - -// -------------------------------------------------- - -// ViewKeeper only allows reading of balances -type ViewKeeper struct { - am sdk.AccountMapper -} - -// NewViewKeeper returns a new CoinKeeper -func NewViewKeeper(am sdk.AccountMapper) ViewKeeper { - return ViewKeeper{am: am} -} - -// GetCoins returns the coins at the addr. -func (keeper ViewKeeper) GetCoins(ctx sdk.Context, addr sdk.Address) sdk.Coins { - return getCoins(ctx, keeper.am, addr) -} - -// HasCoins returns whether or not an account has at least amt coins. -func (keeper ViewKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) bool { - return hasCoins(ctx, keeper.am, addr, amt) -} diff --git a/x/bank/keeper_test.go b/x/bank/keeper_test.go index 1e160d472..7db9c275d 100644 --- a/x/bank/keeper_test.go +++ b/x/bank/keeper_test.go @@ -24,7 +24,7 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { return ms, authKey } -func TestCoinKeeper(t *testing.T) { +func TestKeeper(t *testing.T) { ms, authKey := setupMultiStore() cdc := wire.NewCodec() @@ -32,7 +32,7 @@ func TestCoinKeeper(t *testing.T) { ctx := sdk.NewContext(ms, abci.Header{}, false, nil) accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) - coinKeeper := NewCoinKeeper(accountMapper) + coinKeeper := NewKeeper(accountMapper) addr := sdk.Address([]byte("addr1")) addr2 := sdk.Address([]byte("addr2")) @@ -118,7 +118,7 @@ func TestSendKeeper(t *testing.T) { ctx := sdk.NewContext(ms, abci.Header{}, false, nil) accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) - coinKeeper := NewCoinKeeper(accountMapper) + coinKeeper := NewKeeper(accountMapper) sendKeeper := NewSendKeeper(accountMapper) addr := sdk.Address([]byte("addr1")) @@ -187,7 +187,7 @@ func TestViewKeeper(t *testing.T) { ctx := sdk.NewContext(ms, abci.Header{}, false, nil) accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) - coinKeeper := NewCoinKeeper(accountMapper) + coinKeeper := NewKeeper(accountMapper) viewKeeper := NewViewKeeper(accountMapper) addr := sdk.Address([]byte("addr1")) diff --git a/x/bank/msgs.go b/x/bank/msgs.go index c0f2ad46a..0b0ea471e 100644 --- a/x/bank/msgs.go +++ b/x/bank/msgs.go @@ -2,29 +2,28 @@ package bank import ( "encoding/json" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" ) -// SendMsg - high level transaction of the coin module -type SendMsg struct { +// MsgSend - high level transaction of the coin module +type MsgSend struct { Inputs []Input `json:"inputs"` Outputs []Output `json:"outputs"` } -var _ sdk.Msg = SendMsg{} +var _ sdk.Msg = MsgSend{} -// NewSendMsg - construct arbitrary multi-in, multi-out send msg. -func NewSendMsg(in []Input, out []Output) SendMsg { - return SendMsg{Inputs: in, Outputs: out} +// NewMsgSend - construct arbitrary multi-in, multi-out send msg. +func NewMsgSend(in []Input, out []Output) MsgSend { + return MsgSend{Inputs: in, Outputs: out} } // Implements Msg. -func (msg SendMsg) Type() string { return "bank" } // TODO: "bank/send" +func (msg MsgSend) Type() string { return "bank" } // TODO: "bank/send" // Implements Msg. -func (msg SendMsg) ValidateBasic() sdk.Error { +func (msg MsgSend) ValidateBasic() sdk.Error { // this just makes sure all the inputs and outputs are properly formatted, // not that they actually have the money inside if len(msg.Inputs) == 0 { @@ -54,17 +53,13 @@ func (msg SendMsg) ValidateBasic() sdk.Error { return nil } -func (msg SendMsg) String() string { - return fmt.Sprintf("SendMsg{%v->%v}", msg.Inputs, msg.Outputs) -} - // Implements Msg. -func (msg SendMsg) Get(key interface{}) (value interface{}) { +func (msg MsgSend) Get(key interface{}) (value interface{}) { return nil } // Implements Msg. -func (msg SendMsg) GetSignBytes() []byte { +func (msg MsgSend) GetSignBytes() []byte { b, err := json.Marshal(msg) // XXX: ensure some canonical form if err != nil { panic(err) @@ -73,7 +68,7 @@ func (msg SendMsg) GetSignBytes() []byte { } // Implements Msg. -func (msg SendMsg) GetSigners() []sdk.Address { +func (msg MsgSend) GetSigners() []sdk.Address { addrs := make([]sdk.Address, len(msg.Inputs)) for i, in := range msg.Inputs { addrs[i] = in.Address @@ -82,24 +77,24 @@ func (msg SendMsg) GetSigners() []sdk.Address { } //---------------------------------------- -// IssueMsg +// MsgIssue -// IssueMsg - high level transaction of the coin module -type IssueMsg struct { +// MsgIssue - high level transaction of the coin module +type MsgIssue struct { Banker sdk.Address `json:"banker"` Outputs []Output `json:"outputs"` } -// NewIssueMsg - construct arbitrary multi-in, multi-out send msg. -func NewIssueMsg(banker sdk.Address, out []Output) IssueMsg { - return IssueMsg{Banker: banker, Outputs: out} +// NewMsgIssue - construct arbitrary multi-in, multi-out send msg. +func NewMsgIssue(banker sdk.Address, out []Output) MsgIssue { + return MsgIssue{Banker: banker, Outputs: out} } // Implements Msg. -func (msg IssueMsg) Type() string { return "bank" } // TODO: "bank/issue" +func (msg MsgIssue) Type() string { return "bank" } // TODO: "bank/issue" // Implements Msg. -func (msg IssueMsg) ValidateBasic() sdk.Error { +func (msg MsgIssue) ValidateBasic() sdk.Error { // XXX if len(msg.Outputs) == 0 { return ErrNoOutputs(DefaultCodespace).Trace("") @@ -112,17 +107,13 @@ func (msg IssueMsg) ValidateBasic() sdk.Error { return nil } -func (msg IssueMsg) String() string { - return fmt.Sprintf("IssueMsg{%v#%v}", msg.Banker, msg.Outputs) -} - // Implements Msg. -func (msg IssueMsg) Get(key interface{}) (value interface{}) { +func (msg MsgIssue) Get(key interface{}) (value interface{}) { return nil } // Implements Msg. -func (msg IssueMsg) GetSignBytes() []byte { +func (msg MsgIssue) GetSignBytes() []byte { b, err := json.Marshal(msg) // XXX: ensure some canonical form if err != nil { panic(err) @@ -131,7 +122,7 @@ func (msg IssueMsg) GetSignBytes() []byte { } // Implements Msg. -func (msg IssueMsg) GetSigners() []sdk.Address { +func (msg MsgIssue) GetSigners() []sdk.Address { return []sdk.Address{msg.Banker} } @@ -158,11 +149,7 @@ func (in Input) ValidateBasic() sdk.Error { return nil } -func (in Input) String() string { - return fmt.Sprintf("Input{%v,%v}", in.Address, in.Coins) -} - -// NewInput - create a transaction input, used with SendMsg +// NewInput - create a transaction input, used with MsgSend func NewInput(addr sdk.Address, coins sdk.Coins) Input { input := Input{ Address: addr, @@ -194,11 +181,7 @@ func (out Output) ValidateBasic() sdk.Error { return nil } -func (out Output) String() string { - return fmt.Sprintf("Output{%v,%v}", out.Address, out.Coins) -} - -// NewOutput - create a transaction output, used with SendMsg +// NewOutput - create a transaction output, used with MsgSend func NewOutput(addr sdk.Address, coins sdk.Coins) Output { output := Output{ Address: addr, diff --git a/x/bank/msgs_test.go b/x/bank/msgs_test.go index b158405d9..d3e1ef4f6 100644 --- a/x/bank/msgs_test.go +++ b/x/bank/msgs_test.go @@ -9,14 +9,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func TestNewSendMsg(t *testing.T) {} +func TestNewMsgSend(t *testing.T) {} -func TestSendMsgType(t *testing.T) { - // Construct a SendMsg +func TestMsgSendType(t *testing.T) { + // Construct a MsgSend addr1 := sdk.Address([]byte("input")) addr2 := sdk.Address([]byte("output")) coins := sdk.Coins{{"atom", 10}} - var msg = SendMsg{ + var msg = MsgSend{ Inputs: []Input{NewInput(addr1, coins)}, Outputs: []Output{NewOutput(addr2, coins)}, } @@ -109,7 +109,7 @@ func TestOutputValidation(t *testing.T) { } } -func TestSendMsgValidation(t *testing.T) { +func TestMsgSendValidation(t *testing.T) { addr1 := sdk.Address([]byte{1, 2}) addr2 := sdk.Address([]byte{7, 8}) atom123 := sdk.Coins{{"atom", 123}} @@ -128,40 +128,40 @@ func TestSendMsgValidation(t *testing.T) { cases := []struct { valid bool - tx SendMsg + tx MsgSend }{ - {false, SendMsg{}}, // no input or output - {false, SendMsg{Inputs: []Input{input1}}}, // just input - {false, SendMsg{Outputs: []Output{output1}}}, // just ouput - {false, SendMsg{ + {false, MsgSend{}}, // no input or output + {false, MsgSend{Inputs: []Input{input1}}}, // just input + {false, MsgSend{Outputs: []Output{output1}}}, // just ouput + {false, MsgSend{ Inputs: []Input{NewInput(emptyAddr, atom123)}, // invalid input Outputs: []Output{output1}}}, - {false, SendMsg{ + {false, MsgSend{ Inputs: []Input{input1}, Outputs: []Output{{emptyAddr, atom123}}}, // invalid ouput }, - {false, SendMsg{ + {false, MsgSend{ Inputs: []Input{input1}, Outputs: []Output{output2}}, // amounts dont match }, - {false, SendMsg{ + {false, MsgSend{ Inputs: []Input{input1}, Outputs: []Output{output3}}, // amounts dont match }, - {false, SendMsg{ + {false, MsgSend{ Inputs: []Input{input1}, Outputs: []Output{outputMulti}}, // amounts dont match }, - {false, SendMsg{ + {false, MsgSend{ Inputs: []Input{input2}, Outputs: []Output{output1}}, // amounts dont match }, - {true, SendMsg{ + {true, MsgSend{ Inputs: []Input{input1}, Outputs: []Output{output1}}, }, - {true, SendMsg{ + {true, MsgSend{ Inputs: []Input{input1, input2}, Outputs: []Output{outputMulti}}, }, @@ -177,29 +177,11 @@ func TestSendMsgValidation(t *testing.T) { } } -func TestSendMsgString(t *testing.T) { - // Construct a SendMsg - addr1String := "input" - addr2String := "output" - addr1 := sdk.Address([]byte(addr1String)) - addr2 := sdk.Address([]byte(addr2String)) - coins := sdk.Coins{{"atom", 10}} - var msg = SendMsg{ - Inputs: []Input{NewInput(addr1, coins)}, - Outputs: []Output{NewOutput(addr2, coins)}, - } - - res := msg.String() - expected := fmt.Sprintf("SendMsg{[Input{%X,10atom}]->[Output{%X,10atom}]}", addr1String, addr2String) - // TODO some failures for bad results - assert.Equal(t, expected, res) -} - -func TestSendMsgGet(t *testing.T) { +func TestMsgSendGet(t *testing.T) { addr1 := sdk.Address([]byte("input")) addr2 := sdk.Address([]byte("output")) coins := sdk.Coins{{"atom", 10}} - var msg = SendMsg{ + var msg = MsgSend{ Inputs: []Input{NewInput(addr1, coins)}, Outputs: []Output{NewOutput(addr2, coins)}, } @@ -207,11 +189,11 @@ func TestSendMsgGet(t *testing.T) { assert.Nil(t, res) } -func TestSendMsgGetSignBytes(t *testing.T) { +func TestMsgSendGetSignBytes(t *testing.T) { addr1 := sdk.Address([]byte("input")) addr2 := sdk.Address([]byte("output")) coins := sdk.Coins{{"atom", 10}} - var msg = SendMsg{ + var msg = MsgSend{ Inputs: []Input{NewInput(addr1, coins)}, Outputs: []Output{NewOutput(addr2, coins)}, } @@ -220,8 +202,8 @@ func TestSendMsgGetSignBytes(t *testing.T) { assert.Equal(t, string(res), `{"inputs":[{"address":"696E707574","coins":[{"denom":"atom","amount":10}]}],"outputs":[{"address":"6F7574707574","coins":[{"denom":"atom","amount":10}]}]}`) } -func TestSendMsgGetSigners(t *testing.T) { - var msg = SendMsg{ +func TestMsgSendGetSigners(t *testing.T) { + var msg = MsgSend{ Inputs: []Input{ NewInput(sdk.Address([]byte("input1")), nil), NewInput(sdk.Address([]byte("input2")), nil), @@ -235,7 +217,7 @@ func TestSendMsgGetSigners(t *testing.T) { /* // what to do w/ this test? -func TestSendMsgSigners(t *testing.T) { +func TestMsgSendSigners(t *testing.T) { signers := []sdk.Address{ {1, 2, 3}, {4, 5, 6}, @@ -247,24 +229,24 @@ func TestSendMsgSigners(t *testing.T) { for i, signer := range signers { inputs[i] = NewInput(signer, someCoins) } - tx := NewSendMsg(inputs, nil) + tx := NewMsgSend(inputs, nil) assert.Equal(t, signers, tx.Signers()) } */ // ---------------------------------------- -// IssueMsg Tests +// MsgIssue Tests -func TestNewIssueMsg(t *testing.T) { +func TestNewMsgIssue(t *testing.T) { // TODO } -func TestIssueMsgType(t *testing.T) { - // Construct an IssueMsg +func TestMsgIssueType(t *testing.T) { + // Construct an MsgIssue addr := sdk.Address([]byte("loan-from-bank")) coins := sdk.Coins{{"atom", 10}} - var msg = IssueMsg{ + var msg = MsgIssue{ Banker: sdk.Address([]byte("input")), Outputs: []Output{NewOutput(addr, coins)}, } @@ -273,29 +255,14 @@ func TestIssueMsgType(t *testing.T) { assert.Equal(t, msg.Type(), "bank") } -func TestIssueMsgValidation(t *testing.T) { +func TestMsgIssueValidation(t *testing.T) { // TODO } -func TestIssueMsgString(t *testing.T) { - addrString := "loan-from-bank" - bankerString := "input" - // Construct a IssueMsg - addr := sdk.Address([]byte(addrString)) - coins := sdk.Coins{{"atom", 10}} - var msg = IssueMsg{ - Banker: sdk.Address([]byte(bankerString)), - Outputs: []Output{NewOutput(addr, coins)}, - } - res := msg.String() - expected := fmt.Sprintf("IssueMsg{%X#[Output{%X,10atom}]}", bankerString, addrString) - assert.Equal(t, expected, res) -} - -func TestIssueMsgGet(t *testing.T) { +func TestMsgIssueGet(t *testing.T) { addr := sdk.Address([]byte("loan-from-bank")) coins := sdk.Coins{{"atom", 10}} - var msg = IssueMsg{ + var msg = MsgIssue{ Banker: sdk.Address([]byte("input")), Outputs: []Output{NewOutput(addr, coins)}, } @@ -303,10 +270,10 @@ func TestIssueMsgGet(t *testing.T) { assert.Nil(t, res) } -func TestIssueMsgGetSignBytes(t *testing.T) { +func TestMsgIssueGetSignBytes(t *testing.T) { addr := sdk.Address([]byte("loan-from-bank")) coins := sdk.Coins{{"atom", 10}} - var msg = IssueMsg{ + var msg = MsgIssue{ Banker: sdk.Address([]byte("input")), Outputs: []Output{NewOutput(addr, coins)}, } @@ -315,8 +282,8 @@ func TestIssueMsgGetSignBytes(t *testing.T) { assert.Equal(t, string(res), `{"banker":"696E707574","outputs":[{"address":"6C6F616E2D66726F6D2D62616E6B","coins":[{"denom":"atom","amount":10}]}]}`) } -func TestIssueMsgGetSigners(t *testing.T) { - var msg = IssueMsg{ +func TestMsgIssueGetSigners(t *testing.T) { + var msg = MsgIssue{ Banker: sdk.Address([]byte("onlyone")), } res := msg.GetSigners() diff --git a/x/bank/rest/root.go b/x/bank/rest/root.go deleted file mode 100644 index 4534482a9..000000000 --- a/x/bank/rest/root.go +++ /dev/null @@ -1,14 +0,0 @@ -package rest - -import ( - "github.com/gorilla/mux" - - keys "github.com/tendermint/go-crypto/keys" - - "github.com/cosmos/cosmos-sdk/wire" -) - -// RegisterRoutes - Central function to define routes that get registered by the main application -func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - r.HandleFunc("/accounts/{address}/send", SendRequestHandler(cdc, kb)).Methods("POST") -} diff --git a/x/bank/rest/sendtx.go b/x/bank/rest/sendtx.go index b1f8516f3..eec487a3d 100644 --- a/x/bank/rest/sendtx.go +++ b/x/bank/rest/sendtx.go @@ -15,6 +15,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank/commands" ) +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { + r.HandleFunc("/accounts/{address}/send", SendRequestHandler(cdc, kb)).Methods("POST") +} + type sendBody struct { // fees is not used currently // Fees sdk.Coin `json="fees"` @@ -27,7 +32,6 @@ type sendBody struct { // SendRequestHandler - http request handler to send coins to a address func SendRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.ResponseWriter, *http.Request) { - c := commands.Commander{cdc} ctx := context.NewCoreContextFromViper() return func(w http.ResponseWriter, r *http.Request) { // collect data @@ -73,7 +77,7 @@ func SendRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.ResponseWrit // sign ctx = ctx.WithSequence(m.Sequence) - txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, c.Cdc) + txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc) if err != nil { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(err.Error())) diff --git a/x/bank/wire.go b/x/bank/wire.go index c53f06564..fdb6c252b 100644 --- a/x/bank/wire.go +++ b/x/bank/wire.go @@ -6,6 +6,6 @@ import ( // Register concrete types on wire codec func RegisterWire(cdc *wire.Codec) { - cdc.RegisterConcrete(SendMsg{}, "cosmos-sdk/Send", nil) - cdc.RegisterConcrete(IssueMsg{}, "cosmos-sdk/Issue", nil) + cdc.RegisterConcrete(MsgSend{}, "cosmos-sdk/Send", nil) + cdc.RegisterConcrete(MsgIssue{}, "cosmos-sdk/Issue", nil) } diff --git a/x/ibc/commands/ibctx.go b/x/ibc/commands/ibctx.go index d17b40b21..1fc53b7e6 100644 --- a/x/ibc/commands/ibctx.go +++ b/x/ibc/commands/ibctx.go @@ -23,53 +23,42 @@ const ( flagChain = "chain" ) +// IBC transfer command func IBCTransferCmd(cdc *wire.Codec) *cobra.Command { - cmdr := sendCommander{cdc} cmd := &cobra.Command{ - Use: "transfer", - RunE: cmdr.sendIBCTransfer, + Use: "transfer", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + + // get the from address + from, err := ctx.GetFromAddress() + if err != nil { + return err + } + + // build the message + msg, err := buildMsg(from) + if err != nil { + return err + } + + // get password + res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) + if err != nil { + return err + } + + fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String()) + return nil + }, } + cmd.Flags().String(flagTo, "", "Address to send coins") cmd.Flags().String(flagAmount, "", "Amount of coins to send") cmd.Flags().String(flagChain, "", "Destination chain to send coins") return cmd } -type sendCommander struct { - cdc *wire.Codec -} - -func (c sendCommander) sendIBCTransfer(cmd *cobra.Command, args []string) error { - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(c.cdc)) - - // get the from address - from, err := ctx.GetFromAddress() - if err != nil { - return err - } - - // build the message - msg, err := buildMsg(from) - if err != nil { - return err - } - - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - - // get password - res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, c.cdc) - if err != nil { - return err - } - - fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String()) - return nil -} - func buildMsg(from sdk.Address) (sdk.Msg, error) { amount := viper.GetString(flagAmount) coins, err := sdk.ParseCoins(amount) diff --git a/x/ibc/commands/relay.go b/x/ibc/commands/relay.go index d652e306f..d772735bb 100644 --- a/x/ibc/commands/relay.go +++ b/x/ibc/commands/relay.go @@ -18,6 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc" ) +// flags const ( FlagFromChainID = "from-chain-id" FlagFromChainNode = "from-chain-node" @@ -35,6 +36,7 @@ type relayCommander struct { logger log.Logger } +// IBC relay command func IBCRelayCmd(cdc *wire.Codec) *cobra.Command { cmdr := relayCommander{ cdc: cdc, @@ -91,6 +93,7 @@ func (c relayCommander) loop(fromChainID, fromChainNode, toChainID, toChainNode } ingressKey := ibc.IngressSequenceKey(fromChainID) + OUTER: for { time.Sleep(5 * time.Second) @@ -111,7 +114,7 @@ OUTER: egressLengthbz, err := query(fromChainNode, lengthKey, c.ibcStore) if err != nil { c.logger.Error("Error querying outgoing packet list length", "err", err) - continue OUTER + continue OUTER //TODO replace with continue (I think it should just to the correct place where OUTER is now) } var egressLength int64 if egressLengthbz == nil { @@ -129,14 +132,14 @@ OUTER: egressbz, err := query(fromChainNode, ibc.EgressKey(toChainID, i), c.ibcStore) if err != nil { c.logger.Error("Error querying egress packet", "err", err) - continue OUTER + continue OUTER // TODO replace to break, will break first loop then send back to the beginning (aka OUTER) } err = c.broadcastTx(seq, toChainNode, c.refine(egressbz, i, passphrase)) seq++ if err != nil { c.logger.Error("Error broadcasting ingress packet", "err", err) - continue OUTER + continue OUTER // TODO replace to break, will break first loop then send back to the beginning (aka OUTER) } c.logger.Info("Relayed IBC packet", "number", i) diff --git a/x/ibc/errors.go b/x/ibc/errors.go index 3c52bed7b..60a141eba 100644 --- a/x/ibc/errors.go +++ b/x/ibc/errors.go @@ -4,6 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// IBC errors reserve 200 ~ 299. const ( DefaultCodespace sdk.CodespaceType = 3 @@ -24,10 +25,10 @@ func codeToDefaultMsg(code sdk.CodeType) string { } } +// nolint func ErrInvalidSequence(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeInvalidSequence, "") } - func ErrIdenticalChains(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeIdenticalChains, "") } @@ -43,7 +44,6 @@ func newError(codespace sdk.CodespaceType, code sdk.CodeType, msg string) sdk.Er func msgOrDefaultMsg(msg string, code sdk.CodeType) string { if msg != "" { return msg - } else { - return codeToDefaultMsg(code) } + return codeToDefaultMsg(code) } diff --git a/x/ibc/handler.go b/x/ibc/handler.go index dcd00359f..46cbf1e30 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" ) -func NewHandler(ibcm IBCMapper, ck bank.CoinKeeper) sdk.Handler { +func NewHandler(ibcm Mapper, ck bank.Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { case IBCTransferMsg: @@ -22,7 +22,7 @@ func NewHandler(ibcm IBCMapper, ck bank.CoinKeeper) sdk.Handler { } // IBCTransferMsg deducts coins from the account and creates an egress IBC packet. -func handleIBCTransferMsg(ctx sdk.Context, ibcm IBCMapper, ck bank.CoinKeeper, msg IBCTransferMsg) sdk.Result { +func handleIBCTransferMsg(ctx sdk.Context, ibcm Mapper, ck bank.Keeper, msg IBCTransferMsg) sdk.Result { packet := msg.IBCPacket _, err := ck.SubtractCoins(ctx, packet.SrcAddr, packet.Coins) @@ -39,7 +39,7 @@ func handleIBCTransferMsg(ctx sdk.Context, ibcm IBCMapper, ck bank.CoinKeeper, m } // IBCReceiveMsg adds coins to the destination address and creates an ingress IBC packet. -func handleIBCReceiveMsg(ctx sdk.Context, ibcm IBCMapper, ck bank.CoinKeeper, msg IBCReceiveMsg) sdk.Result { +func handleIBCReceiveMsg(ctx sdk.Context, ibcm Mapper, ck bank.Keeper, msg IBCReceiveMsg) sdk.Result { packet := msg.IBCPacket seq := ibcm.GetIngressSequence(ctx, packet.SrcChain) diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index 1fc724e54..61b9182f1 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -16,7 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" ) -// AccountMapper(/CoinKeeper) and IBCMapper should use different StoreKey later +// AccountMapper(/Keeper) and IBCMapper should use different StoreKey later func defaultContext(key sdk.StoreKey) sdk.Context { db := dbm.NewMemDB() @@ -31,7 +31,7 @@ func newAddress() crypto.Address { return crypto.GenPrivKeyEd25519().PubKey().Address() } -func getCoins(ck bank.CoinKeeper, ctx sdk.Context, addr crypto.Address) (sdk.Coins, sdk.Error) { +func getCoins(ck bank.Keeper, ctx sdk.Context, addr crypto.Address) (sdk.Coins, sdk.Error) { zero := sdk.Coins(nil) return ck.AddCoins(ctx, addr, zero) } @@ -41,8 +41,8 @@ func makeCodec() *wire.Codec { // Register Msgs cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.SendMsg{}, "test/ibc/Send", nil) - cdc.RegisterConcrete(bank.IssueMsg{}, "test/ibc/Issue", nil) + cdc.RegisterConcrete(bank.MsgSend{}, "test/ibc/Send", nil) + cdc.RegisterConcrete(bank.MsgIssue{}, "test/ibc/Issue", nil) cdc.RegisterConcrete(IBCTransferMsg{}, "test/ibc/IBCTransferMsg", nil) cdc.RegisterConcrete(IBCReceiveMsg{}, "test/ibc/IBCReceiveMsg", nil) @@ -61,7 +61,7 @@ func TestIBC(t *testing.T) { ctx := defaultContext(key) am := auth.NewAccountMapper(cdc, key, &auth.BaseAccount{}) - ck := bank.NewCoinKeeper(am) + ck := bank.NewKeeper(am) src := newAddress() dest := newAddress() @@ -73,7 +73,7 @@ func TestIBC(t *testing.T) { assert.Nil(t, err) assert.Equal(t, mycoins, coins) - ibcm := NewIBCMapper(cdc, key, DefaultCodespace) + ibcm := NewMapper(cdc, key, DefaultCodespace) h := NewHandler(ibcm, ck) packet := IBCPacket{ SrcAddr: src, diff --git a/x/ibc/mapper.go b/x/ibc/mapper.go index d3ecc779d..06631179b 100644 --- a/x/ibc/mapper.go +++ b/x/ibc/mapper.go @@ -7,17 +7,18 @@ import ( wire "github.com/cosmos/cosmos-sdk/wire" ) -type IBCMapper struct { +// IBC Mapper +type Mapper struct { key sdk.StoreKey cdc *wire.Codec codespace sdk.CodespaceType } -// XXX: The IBCMapper should not take a CoinKeeper. Rather have the CoinKeeper -// take an IBCMapper. -func NewIBCMapper(cdc *wire.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) IBCMapper { +// XXX: The Mapper should not take a CoinKeeper. Rather have the CoinKeeper +// take an Mapper. +func NewMapper(cdc *wire.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Mapper { // XXX: How are these codecs supposed to work? - return IBCMapper{ + return Mapper{ key: key, cdc: cdc, codespace: codespace, @@ -28,7 +29,7 @@ func NewIBCMapper(cdc *wire.Codec, key sdk.StoreKey, codespace sdk.CodespaceType // only be invoked from another module directly and not through a user // transaction. // TODO: Handle invalid IBC packets and return errors. -func (ibcm IBCMapper) PostIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error { +func (ibcm Mapper) PostIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error { // write everything into the state store := ctx.KVStore(ibcm.key) index := ibcm.getEgressLength(store, packet.DestChain) @@ -52,7 +53,7 @@ func (ibcm IBCMapper) PostIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error // to the appropriate callbacks. // XXX: For now this handles all interactions with the CoinKeeper. // XXX: This needs to do some authentication checking. -func (ibcm IBCMapper) ReceiveIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error { +func (ibcm Mapper) ReceiveIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error { return nil } @@ -74,7 +75,8 @@ func unmarshalBinaryPanic(cdc *wire.Codec, bz []byte, ptr interface{}) { } } -func (ibcm IBCMapper) GetIngressSequence(ctx sdk.Context, srcChain string) int64 { +// TODO add description +func (ibcm Mapper) GetIngressSequence(ctx sdk.Context, srcChain string) int64 { store := ctx.KVStore(ibcm.key) key := IngressSequenceKey(srcChain) @@ -90,7 +92,8 @@ func (ibcm IBCMapper) GetIngressSequence(ctx sdk.Context, srcChain string) int64 return res } -func (ibcm IBCMapper) SetIngressSequence(ctx sdk.Context, srcChain string, sequence int64) { +// TODO add description +func (ibcm Mapper) SetIngressSequence(ctx sdk.Context, srcChain string, sequence int64) { store := ctx.KVStore(ibcm.key) key := IngressSequenceKey(srcChain) @@ -99,7 +102,7 @@ func (ibcm IBCMapper) SetIngressSequence(ctx sdk.Context, srcChain string, seque } // Retrieves the index of the currently stored outgoing IBC packets. -func (ibcm IBCMapper) getEgressLength(store sdk.KVStore, destChain string) int64 { +func (ibcm Mapper) getEgressLength(store sdk.KVStore, destChain string) int64 { bz := store.Get(EgressLengthKey(destChain)) if bz == nil { zero := marshalBinaryPanic(ibcm.cdc, int64(0)) diff --git a/x/ibc/rest/root.go b/x/ibc/rest/root.go deleted file mode 100644 index 81e74d031..000000000 --- a/x/ibc/rest/root.go +++ /dev/null @@ -1,14 +0,0 @@ -package rest - -import ( - "github.com/gorilla/mux" - - keys "github.com/tendermint/go-crypto/keys" - - "github.com/cosmos/cosmos-sdk/wire" -) - -// RegisterRoutes - Central function to define routes that get registered by the main application -func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - r.HandleFunc("/ibc/{destchain}/{address}/send", TransferRequestHandler(cdc, kb)).Methods("POST") -} diff --git a/x/ibc/rest/transfer.go b/x/ibc/rest/transfer.go index 1317730e7..c0f70b517 100644 --- a/x/ibc/rest/transfer.go +++ b/x/ibc/rest/transfer.go @@ -11,10 +11,14 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/bank/commands" "github.com/cosmos/cosmos-sdk/x/ibc" ) +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { + r.HandleFunc("/ibc/{destchain}/{address}/send", TransferRequestHandler(cdc, kb)).Methods("POST") +} + type transferBody struct { // Fees sdk.Coin `json="fees"` Amount sdk.Coins `json:"amount"` @@ -27,7 +31,6 @@ type transferBody struct { // TransferRequestHandler - http request handler to transfer coins to a address // on a different chain via IBC func TransferRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.ResponseWriter, *http.Request) { - c := commands.Commander{cdc} ctx := context.NewCoreContextFromViper() return func(w http.ResponseWriter, r *http.Request) { // collect data @@ -70,7 +73,7 @@ func TransferRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.Response // sign ctx = ctx.WithSequence(m.Sequence) - txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, c.Cdc) + txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc) if err != nil { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(err.Error())) diff --git a/x/ibc/types.go b/x/ibc/types.go index 2bf2c4267..6102a2a9f 100644 --- a/x/ibc/types.go +++ b/x/ibc/types.go @@ -9,6 +9,7 @@ import ( // ------------------------------ // IBCPacket +// nolint - TODO rename to Packet as IBCPacket stutters (golint) // IBCPacket defines a piece of data that can be send between two separate // blockchains. type IBCPacket struct { @@ -31,6 +32,7 @@ func NewIBCPacket(srcAddr sdk.Address, destAddr sdk.Address, coins sdk.Coins, } } +// validator the ibc packey func (ibcp IBCPacket) ValidateBasic() sdk.Error { if ibcp.SrcChain == ibcp.DestChain { return ErrIdenticalChains(DefaultCodespace).Trace("") @@ -44,19 +46,20 @@ func (ibcp IBCPacket) ValidateBasic() sdk.Error { // ---------------------------------- // IBCTransferMsg +// nolint - TODO rename to TransferMsg as folks will reference with ibc.TransferMsg // IBCTransferMsg defines how another module can send an IBCPacket. type IBCTransferMsg struct { IBCPacket } -func (msg IBCTransferMsg) Type() string { - return "ibc" -} +// nolint +func (msg IBCTransferMsg) Type() string { return "ibc" } +func (msg IBCTransferMsg) Get(key interface{}) interface{} { return nil } -func (msg IBCTransferMsg) Get(key interface{}) interface{} { - return nil -} +// x/bank/tx.go MsgSend.GetSigners() +func (msg IBCTransferMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.SrcAddr} } +// get the sign bytes for ibc transfer message func (msg IBCTransferMsg) GetSignBytes() []byte { cdc := wire.NewCodec() bz, err := cdc.MarshalBinary(msg) @@ -66,18 +69,15 @@ func (msg IBCTransferMsg) GetSignBytes() []byte { return bz } +// validate ibc transfer message func (msg IBCTransferMsg) ValidateBasic() sdk.Error { return msg.IBCPacket.ValidateBasic() } -// x/bank/tx.go SendMsg.GetSigners() -func (msg IBCTransferMsg) GetSigners() []sdk.Address { - return []sdk.Address{msg.SrcAddr} -} - // ---------------------------------- // IBCReceiveMsg +// nolint - TODO rename to ReceiveMsg as folks will reference with ibc.ReceiveMsg // IBCReceiveMsg defines the message that a relayer uses to post an IBCPacket // to the destination chain. type IBCReceiveMsg struct { @@ -86,14 +86,15 @@ type IBCReceiveMsg struct { Sequence int64 } -func (msg IBCReceiveMsg) Type() string { - return "ibc" -} +// nolint +func (msg IBCReceiveMsg) Type() string { return "ibc" } +func (msg IBCReceiveMsg) Get(key interface{}) interface{} { return nil } +func (msg IBCReceiveMsg) ValidateBasic() sdk.Error { return msg.IBCPacket.ValidateBasic() } -func (msg IBCReceiveMsg) Get(key interface{}) interface{} { - return nil -} +// x/bank/tx.go MsgSend.GetSigners() +func (msg IBCReceiveMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Relayer} } +// get the sign bytes for ibc receive message func (msg IBCReceiveMsg) GetSignBytes() []byte { cdc := wire.NewCodec() bz, err := cdc.MarshalBinary(msg) @@ -102,12 +103,3 @@ func (msg IBCReceiveMsg) GetSignBytes() []byte { } return bz } - -func (msg IBCReceiveMsg) ValidateBasic() sdk.Error { - return msg.IBCPacket.ValidateBasic() -} - -// x/bank/tx.go SendMsg.GetSigners() -func (msg IBCReceiveMsg) GetSigners() []sdk.Address { - return []sdk.Address{msg.Relayer} -} diff --git a/x/ibc/types_test.go b/x/ibc/types_test.go index c16839ddc..199270b29 100644 --- a/x/ibc/types_test.go +++ b/x/ibc/types_test.go @@ -106,7 +106,6 @@ func constructIBCPacket(valid bool) IBCPacket { if valid { return NewIBCPacket(srcAddr, destAddr, coins, srcChain, destChain) - } else { - return NewIBCPacket(srcAddr, destAddr, coins, srcChain, srcChain) } + return NewIBCPacket(srcAddr, destAddr, coins, srcChain, srcChain) } diff --git a/x/simplestake/commands/commands.go b/x/simplestake/commands/commands.go index ba6602028..78144fdac 100644 --- a/x/simplestake/commands/commands.go +++ b/x/simplestake/commands/commands.go @@ -21,89 +21,72 @@ const ( flagValidator = "validator" ) +// simple bond tx func BondTxCmd(cdc *wire.Codec) *cobra.Command { - cmdr := commander{cdc} cmd := &cobra.Command{ Use: "bond", Short: "Bond to a validator", - RunE: cmdr.bondTxCmd, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper() + + from, err := ctx.GetFromAddress() + if err != nil { + return err + } + + stakeString := viper.GetString(flagStake) + if len(stakeString) == 0 { + return fmt.Errorf("specify coins to bond with --stake") + } + + valString := viper.GetString(flagValidator) + if len(valString) == 0 { + return fmt.Errorf("specify pubkey to bond to with --validator") + } + + stake, err := sdk.ParseCoin(stakeString) + if err != nil { + return err + } + + // TODO: bech32 ... + rawPubKey, err := hex.DecodeString(valString) + if err != nil { + return err + } + var pubKeyEd crypto.PubKeyEd25519 + copy(pubKeyEd[:], rawPubKey) + + msg := simplestake.NewMsgBond(from, stake, pubKeyEd) + + return sendMsg(cdc, msg) + }, } cmd.Flags().String(flagStake, "", "Amount of coins to stake") cmd.Flags().String(flagValidator, "", "Validator address to stake") return cmd } +// simple unbond tx func UnbondTxCmd(cdc *wire.Codec) *cobra.Command { - cmdr := commander{cdc} cmd := &cobra.Command{ Use: "unbond", Short: "Unbond from a validator", - RunE: cmdr.unbondTxCmd, + RunE: func(cmd *cobra.Command, args []string) error { + from, err := context.NewCoreContextFromViper().GetFromAddress() + if err != nil { + return err + } + msg := simplestake.NewMsgUnbond(from) + return sendMsg(cdc, msg) + }, } return cmd } -type commander struct { - cdc *wire.Codec -} - -func (co commander) bondTxCmd(cmd *cobra.Command, args []string) error { - ctx := context.NewCoreContextFromViper() - - from, err := ctx.GetFromAddress() - if err != nil { - return err - } - - stakeString := viper.GetString(flagStake) - if len(stakeString) == 0 { - return fmt.Errorf("specify coins to bond with --stake") - } - - valString := viper.GetString(flagValidator) - if len(valString) == 0 { - return fmt.Errorf("specify pubkey to bond to with --validator") - } - - stake, err := sdk.ParseCoin(stakeString) - if err != nil { - return err - } - - // TODO: bech32 ... - rawPubKey, err := hex.DecodeString(valString) - if err != nil { - return err - } - var pubKeyEd crypto.PubKeyEd25519 - copy(pubKeyEd[:], rawPubKey) - - msg := simplestake.NewBondMsg(from, stake, pubKeyEd) - - return co.sendMsg(msg) -} - -func (co commander) unbondTxCmd(cmd *cobra.Command, args []string) error { - from, err := context.NewCoreContextFromViper().GetFromAddress() - if err != nil { - return err - } - - msg := simplestake.NewUnbondMsg(from) - - return co.sendMsg(msg) -} - -func (co commander) sendMsg(msg sdk.Msg) error { - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(co.cdc)) - - // default to next sequence number if none provided - ctx, err := context.EnsureSequence(ctx) - if err != nil { - return err - } - - res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, co.cdc) +func sendMsg(cdc *wire.Codec, msg sdk.Msg) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err } diff --git a/x/simplestake/errors.go b/x/simplestake/errors.go index 0fb7eebce..0effba9c0 100644 --- a/x/simplestake/errors.go +++ b/x/simplestake/errors.go @@ -4,6 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// simple stake errors reserve 300 ~ 399. const ( DefaultCodespace sdk.CodespaceType = 4 @@ -14,18 +15,16 @@ const ( CodeIncorrectStakingToken sdk.CodeType = 303 ) +// nolint func ErrIncorrectStakingToken(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeIncorrectStakingToken, "") } - func ErrEmptyValidator(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeEmptyValidator, "") } - func ErrInvalidUnbond(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeInvalidUnbond, "") } - func ErrEmptyStake(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeEmptyStake, "") } diff --git a/x/simplestake/handler.go b/x/simplestake/handler.go index 894da04b2..a84e8b07b 100644 --- a/x/simplestake/handler.go +++ b/x/simplestake/handler.go @@ -10,17 +10,17 @@ import ( func NewHandler(k Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { - case BondMsg: - return handleBondMsg(ctx, k, msg) - case UnbondMsg: - return handleUnbondMsg(ctx, k, msg) + case MsgBond: + return handleMsgBond(ctx, k, msg) + case MsgUnbond: + return handleMsgUnbond(ctx, k, msg) default: return sdk.ErrUnknownRequest("No match for message type.").Result() } } } -func handleBondMsg(ctx sdk.Context, k Keeper, msg BondMsg) sdk.Result { +func handleMsgBond(ctx sdk.Context, k Keeper, msg MsgBond) sdk.Result { power, err := k.Bond(ctx, msg.Address, msg.PubKey, msg.Stake) if err != nil { return err.Result() @@ -37,7 +37,7 @@ func handleBondMsg(ctx sdk.Context, k Keeper, msg BondMsg) sdk.Result { } } -func handleUnbondMsg(ctx sdk.Context, k Keeper, msg UnbondMsg) sdk.Result { +func handleMsgUnbond(ctx sdk.Context, k Keeper, msg MsgUnbond) sdk.Result { pubKey, _, err := k.Unbond(ctx, msg.Address) if err != nil { return err.Result() diff --git a/x/simplestake/keeper.go b/x/simplestake/keeper.go index 934d0b5a0..7b61c3623 100644 --- a/x/simplestake/keeper.go +++ b/x/simplestake/keeper.go @@ -12,15 +12,16 @@ const stakingToken = "steak" const moduleName = "simplestake" +// simple stake keeper type Keeper struct { - ck bank.CoinKeeper + ck bank.Keeper key sdk.StoreKey cdc *wire.Codec codespace sdk.CodespaceType } -func NewKeeper(key sdk.StoreKey, coinKeeper bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { +func NewKeeper(key sdk.StoreKey, coinKeeper bank.Keeper, codespace sdk.CodespaceType) Keeper { cdc := wire.NewCodec() wire.RegisterCrypto(cdc) return Keeper{ @@ -59,6 +60,7 @@ func (k Keeper) deleteBondInfo(ctx sdk.Context, addr sdk.Address) { store.Delete(addr) } +// register a bond with the keeper func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) { if stake.Denom != stakingToken { return 0, ErrIncorrectStakingToken(k.codespace) @@ -83,6 +85,7 @@ func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, st return bi.Power, nil } +// register an unbond with the keeper func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) { bi := k.getBondInfo(ctx, addr) if bi.isEmpty() { diff --git a/x/simplestake/keeper_test.go b/x/simplestake/keeper_test.go index 833227968..75e9fcded 100644 --- a/x/simplestake/keeper_test.go +++ b/x/simplestake/keeper_test.go @@ -33,7 +33,7 @@ func TestKeeperGetSet(t *testing.T) { ms, _, capKey := setupMultiStore() ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil), DefaultCodespace) + stakeKeeper := NewKeeper(capKey, bank.NewKeeper(nil), DefaultCodespace) addr := sdk.Address([]byte("some-address")) bi := stakeKeeper.getBondInfo(ctx, addr) @@ -62,7 +62,7 @@ func TestBonding(t *testing.T) { ctx := sdk.NewContext(ms, abci.Header{}, false, nil) accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) - coinKeeper := bank.NewCoinKeeper(accountMapper) + coinKeeper := bank.NewKeeper(accountMapper) stakeKeeper := NewKeeper(capKey, coinKeeper, DefaultCodespace) addr := sdk.Address([]byte("some-address")) privKey := crypto.GenPrivKeyEd25519() diff --git a/x/simplestake/msgs.go b/x/simplestake/msgs.go index 963bfae7b..512d571c5 100644 --- a/x/simplestake/msgs.go +++ b/x/simplestake/msgs.go @@ -8,44 +8,43 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// ------------------------- -// BondMsg +//_________________________________________________________---- -type BondMsg struct { +// simple bond message +type MsgBond struct { Address sdk.Address `json:"address"` Stake sdk.Coin `json:"coins"` PubKey crypto.PubKey `json:"pub_key"` } -func NewBondMsg(addr sdk.Address, stake sdk.Coin, pubKey crypto.PubKey) BondMsg { - return BondMsg{ +func NewMsgBond(addr sdk.Address, stake sdk.Coin, pubKey crypto.PubKey) MsgBond { + return MsgBond{ Address: addr, Stake: stake, PubKey: pubKey, } } -func (msg BondMsg) Type() string { - return moduleName -} +//nolint +func (msg MsgBond) Type() string { return moduleName } //TODO update "stake/declarecandidacy" +func (msg MsgBond) Get(key interface{}) (value interface{}) { return nil } +func (msg MsgBond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} } -func (msg BondMsg) ValidateBasic() sdk.Error { +// basic validation of the bond message +func (msg MsgBond) ValidateBasic() sdk.Error { if msg.Stake.IsZero() { return ErrEmptyStake(DefaultCodespace) } if msg.PubKey == nil { - return sdk.ErrInvalidPubKey("BondMsg.PubKey must not be empty") + return sdk.ErrInvalidPubKey("MsgBond.PubKey must not be empty") } return nil } -func (msg BondMsg) Get(key interface{}) interface{} { - return nil -} - -func (msg BondMsg) GetSignBytes() []byte { +// get bond message sign bytes +func (msg MsgBond) GetSignBytes() []byte { bz, err := json.Marshal(msg) if err != nil { panic(err) @@ -53,43 +52,30 @@ func (msg BondMsg) GetSignBytes() []byte { return bz } -func (msg BondMsg) GetSigners() []sdk.Address { - return []sdk.Address{msg.Address} -} +//_______________________________________________________________ -// ------------------------- -// UnbondMsg - -type UnbondMsg struct { +// simple unbond message +type MsgUnbond struct { Address sdk.Address `json:"address"` } -func NewUnbondMsg(addr sdk.Address) UnbondMsg { - return UnbondMsg{ +func NewMsgUnbond(addr sdk.Address) MsgUnbond { + return MsgUnbond{ Address: addr, } } -func (msg UnbondMsg) Type() string { - return moduleName -} +//nolint +func (msg MsgUnbond) Type() string { return moduleName } //TODO update "stake/declarecandidacy" +func (msg MsgUnbond) Get(key interface{}) (value interface{}) { return nil } +func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} } +func (msg MsgUnbond) ValidateBasic() sdk.Error { return nil } -func (msg UnbondMsg) ValidateBasic() sdk.Error { - return nil -} - -func (msg UnbondMsg) Get(key interface{}) interface{} { - return nil -} - -func (msg UnbondMsg) GetSignBytes() []byte { +// get unbond message sign bytes +func (msg MsgUnbond) GetSignBytes() []byte { bz, err := json.Marshal(msg) if err != nil { panic(err) } return bz } - -func (msg UnbondMsg) GetSigners() []sdk.Address { - return []sdk.Address{msg.Address} -} diff --git a/x/simplestake/msgs_test.go b/x/simplestake/msgs_test.go index 49a8feec5..c71ebe7fc 100644 --- a/x/simplestake/msgs_test.go +++ b/x/simplestake/msgs_test.go @@ -14,14 +14,14 @@ func TestBondMsgValidation(t *testing.T) { privKey := crypto.GenPrivKeyEd25519() cases := []struct { valid bool - bondMsg BondMsg + msgBond MsgBond }{ - {true, NewBondMsg(sdk.Address{}, sdk.Coin{"mycoin", 5}, privKey.PubKey())}, - {false, NewBondMsg(sdk.Address{}, sdk.Coin{"mycoin", 0}, privKey.PubKey())}, + {true, NewMsgBond(sdk.Address{}, sdk.Coin{"mycoin", 5}, privKey.PubKey())}, + {false, NewMsgBond(sdk.Address{}, sdk.Coin{"mycoin", 0}, privKey.PubKey())}, } for i, tc := range cases { - err := tc.bondMsg.ValidateBasic() + err := tc.msgBond.ValidateBasic() if tc.valid { assert.Nil(t, err, "%d: %+v", i, err) } else { diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index 4a1983743..e04a81885 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -48,13 +48,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { // build and sign the transaction, then broadcast to Tendermint ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - - res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, cdc) + res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err } @@ -93,13 +87,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command { // build and sign the transaction, then broadcast to Tendermint ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - - res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, cdc) + res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err } @@ -136,13 +124,7 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command { // build and sign the transaction, then broadcast to Tendermint ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - - res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, cdc) + res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err } @@ -190,13 +172,7 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command { // build and sign the transaction, then broadcast to Tendermint ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - // default to next sequence number if none provided - ctx, err = context.EnsureSequence(ctx) - if err != nil { - return err - } - - res, err := ctx.SignBuildBroadcast(ctx.FromAddressName, msg, cdc) + res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err } diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 751b84017..49806f9b9 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -13,7 +13,7 @@ import ( type Keeper struct { storeKey sdk.StoreKey cdc *wire.Codec - coinKeeper bank.CoinKeeper + coinKeeper bank.Keeper // caches gs Pool @@ -23,7 +23,7 @@ type Keeper struct { codespace sdk.CodespaceType } -func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace sdk.CodespaceType) Keeper { +func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper { keeper := Keeper{ storeKey: key, cdc: cdc, diff --git a/x/stake/msg.go b/x/stake/msg.go index b5ba09b5a..10cea3fa8 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -2,7 +2,6 @@ package stake import ( "encoding/json" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" crypto "github.com/tendermint/go-crypto" @@ -44,9 +43,6 @@ func NewMsgDeclareCandidacy(candidateAddr sdk.Address, pubkey crypto.PubKey, func (msg MsgDeclareCandidacy) Type() string { return MsgType } //TODO update "stake/declarecandidacy" func (msg MsgDeclareCandidacy) Get(key interface{}) (value interface{}) { return nil } func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.CandidateAddr} } -func (msg MsgDeclareCandidacy) String() string { - return fmt.Sprintf("CandidateAddr{Address: %v}", msg.CandidateAddr) // XXX fix -} // get the bytes for the message signer to sign on func (msg MsgDeclareCandidacy) GetSignBytes() []byte { @@ -67,7 +63,6 @@ func (msg MsgDeclareCandidacy) ValidateBasic() sdk.Error { } if msg.Bond.Amount <= 0 { return ErrBadBondingAmount(DefaultCodespace) - // return sdk.ErrInvalidCoins(sdk.Coins{msg.Bond}.String()) } empty := Description{} if msg.Description == empty { @@ -95,9 +90,6 @@ func NewMsgEditCandidacy(candidateAddr sdk.Address, description Description) Msg func (msg MsgEditCandidacy) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" func (msg MsgEditCandidacy) Get(key interface{}) (value interface{}) { return nil } func (msg MsgEditCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.CandidateAddr} } -func (msg MsgEditCandidacy) String() string { - return fmt.Sprintf("CandidateAddr{Address: %v}", msg.CandidateAddr) // XXX fix -} // get the bytes for the message signer to sign on func (msg MsgEditCandidacy) GetSignBytes() []byte { @@ -141,9 +133,6 @@ func NewMsgDelegate(delegatorAddr, candidateAddr sdk.Address, bond sdk.Coin) Msg func (msg MsgDelegate) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" func (msg MsgDelegate) Get(key interface{}) (value interface{}) { return nil } func (msg MsgDelegate) GetSigners() []sdk.Address { return []sdk.Address{msg.DelegatorAddr} } -func (msg MsgDelegate) String() string { - return fmt.Sprintf("Addr{Address: %v}", msg.DelegatorAddr) // XXX fix -} // get the bytes for the message signer to sign on func (msg MsgDelegate) GetSignBytes() []byte { @@ -167,7 +156,6 @@ func (msg MsgDelegate) ValidateBasic() sdk.Error { } if msg.Bond.Amount <= 0 { return ErrBadBondingAmount(DefaultCodespace) - // return sdk.ErrInvalidCoins(sdk.Coins{msg.Bond}.String()) } return nil } @@ -193,9 +181,6 @@ func NewMsgUnbond(delegatorAddr, candidateAddr sdk.Address, shares string) MsgUn func (msg MsgUnbond) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" func (msg MsgUnbond) Get(key interface{}) (value interface{}) { return nil } func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.DelegatorAddr} } -func (msg MsgUnbond) String() string { - return fmt.Sprintf("Addr{Address: %v}", msg.DelegatorAddr) // XXX fix -} // get the bytes for the message signer to sign on func (msg MsgUnbond) GetSignBytes() []byte { diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 1de86c912..9d7b13e7c 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -96,8 +96,8 @@ func makeTestCodec() *wire.Codec { // Register Msgs cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.SendMsg{}, "test/stake/Send", nil) - cdc.RegisterConcrete(bank.IssueMsg{}, "test/stake/Issue", nil) + cdc.RegisterConcrete(bank.MsgSend{}, "test/stake/Send", nil) + cdc.RegisterConcrete(bank.MsgIssue{}, "test/stake/Issue", nil) cdc.RegisterConcrete(MsgDeclareCandidacy{}, "test/stake/DeclareCandidacy", nil) cdc.RegisterConcrete(MsgEditCandidacy{}, "test/stake/EditCandidacy", nil) cdc.RegisterConcrete(MsgUnbond{}, "test/stake/Unbond", nil) @@ -139,7 +139,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context keyMain, // target store &auth.BaseAccount{}, // prototype ).Seal() - ck := bank.NewCoinKeeper(accountMapper) + ck := bank.NewKeeper(accountMapper) keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace) keeper.setPool(ctx, initialPool()) keeper.setParams(ctx, defaultParams()) From b1c83f2edb8a0f7acd9d064c816d18bc200934fc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 6 Apr 2018 13:11:26 +0200 Subject: [PATCH 034/176] WIP: Track validator height (closes #582) --- x/stake/keeper.go | 6 +++--- x/stake/keeper_keys.go | 10 +++++++--- x/stake/types.go | 28 ++++++++++++++++------------ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 751b84017..2dcfd3caf 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -101,9 +101,9 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // update the list ordered by voting power if oldFound { - store.Delete(GetValidatorKey(address, oldCandidate.Assets, k.cdc)) + store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) } - store.Set(GetValidatorKey(address, validator.Power, k.cdc), bz) + store.Set(GetValidatorKey(address, validator.Power, validator.Height, k.cdc), bz) // add to the validators to update list if is already a validator // or is a new validator @@ -136,7 +136,7 @@ func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) { // delete the old candidate record store := ctx.KVStore(k.storeKey) store.Delete(GetCandidateKey(address)) - store.Delete(GetValidatorKey(address, candidate.Assets, k.cdc)) + store.Delete(GetValidatorKey(address, candidate.Assets, candidate.ValidatorHeight, k.cdc)) // delete from recent and power weighted validator groups if the validator // exists and add validator with zero power to the validator updates diff --git a/x/stake/keeper_keys.go b/x/stake/keeper_keys.go index 45e0570bc..ae8f9d733 100644 --- a/x/stake/keeper_keys.go +++ b/x/stake/keeper_keys.go @@ -1,6 +1,8 @@ package stake import ( + "encoding/binary" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" ) @@ -30,9 +32,11 @@ func GetCandidateKey(addr sdk.Address) []byte { } // get the key for the validator used in the power-store -func GetValidatorKey(addr sdk.Address, power sdk.Rat, cdc *wire.Codec) []byte { - powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount)) - return append(ValidatorsKey, append(powerBytes, addr.Bytes()...)...) +func GetValidatorKey(addr sdk.Address, power sdk.Rat, height uint64, cdc *wire.Codec) []byte { + powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) + heightBytes := make([]byte, 8) + binary.LittleEndian.PutUint64(heightBytes, height) // height little-endian (older validators first) + return append(ValidatorsKey, append(powerBytes, append(heightBytes, addr.Bytes()...)...)...) } // get the key for the accumulated update validators diff --git a/x/stake/types.go b/x/stake/types.go index 9f7d97ae5..7757566bf 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -59,12 +59,13 @@ const ( // exchange rate. Voting power can be calculated as total bonds multiplied by // exchange rate. type Candidate struct { - Status CandidateStatus `json:"status"` // Bonded status - Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here - PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate - Assets sdk.Rat `json:"assets"` // total shares of a global hold pools - Liabilities sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators - Description Description `json:"description"` // Description terms for the candidate + Status CandidateStatus `json:"status"` // Bonded status + Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here + PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate + Assets sdk.Rat `json:"assets"` // total shares of a global hold pools + Liabilities sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators + Description Description `json:"description"` // Description terms for the candidate + ValidatorHeight uint64 `json:"validator_height"` // If considered a validator, height when first considered a validator, else 0 } // Candidates - list of Candidates @@ -73,12 +74,13 @@ type Candidates []Candidate // NewCandidate - initialize a new candidate func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Description) Candidate { return Candidate{ - Status: Unbonded, - Address: address, - PubKey: pubKey, - Assets: sdk.ZeroRat, - Liabilities: sdk.ZeroRat, - Description: description, + Status: Unbonded, + Address: address, + PubKey: pubKey, + Assets: sdk.ZeroRat, + Liabilities: sdk.ZeroRat, + Description: description, + ValidatorHeight: uint64(0), } } @@ -114,6 +116,7 @@ func (c Candidate) validator() Validator { Address: c.Address, PubKey: c.PubKey, Power: c.Assets, + Height: c.ValidatorHeight, } } @@ -127,6 +130,7 @@ type Validator struct { Address sdk.Address `json:"address"` PubKey crypto.PubKey `json:"pub_key"` Power sdk.Rat `json:"voting_power"` + Height uint64 `json:"height"` // If considered a validator, height when first considered a validator, else 0 } // abci validator from stake validator type From 905a9eefb9b6113a5675bc7e095ef51d9bb1b797 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 9 Apr 2018 12:17:45 +0200 Subject: [PATCH 035/176] Cleanup implementation --- x/stake/keeper.go | 7 ++++++- x/stake/keeper_keys.go | 4 ++-- x/stake/types.go | 6 +++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 2dcfd3caf..a51877b3c 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -80,6 +80,9 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // retreive the old candidate record oldCandidate, oldFound := k.GetCandidate(ctx, address) + // update the validator block height (will only get written if stake has changed) + candidate.ValidatorHeight = ctx.BlockHeight() + // marshal the candidate record and add to the state bz, err := k.cdc.MarshalBinary(candidate) if err != nil { @@ -87,7 +90,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { } store.Set(GetCandidateKey(candidate.Address), bz) - // mashal the new validator record + // marshal the new validator record validator := candidate.validator() bz, err = k.cdc.MarshalBinary(validator) if err != nil { @@ -121,7 +124,9 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { panic(err) } store.Set(GetAccUpdateValidatorKey(validator.Address), bz) + } + return } diff --git a/x/stake/keeper_keys.go b/x/stake/keeper_keys.go index ae8f9d733..a8adc2a12 100644 --- a/x/stake/keeper_keys.go +++ b/x/stake/keeper_keys.go @@ -32,10 +32,10 @@ func GetCandidateKey(addr sdk.Address) []byte { } // get the key for the validator used in the power-store -func GetValidatorKey(addr sdk.Address, power sdk.Rat, height uint64, cdc *wire.Codec) []byte { +func GetValidatorKey(addr sdk.Address, power sdk.Rat, height int64, cdc *wire.Codec) []byte { powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) heightBytes := make([]byte, 8) - binary.LittleEndian.PutUint64(heightBytes, height) // height little-endian (older validators first) + binary.LittleEndian.PutUint64(heightBytes, uint64(height)) // height little-endian (older validators first) return append(ValidatorsKey, append(powerBytes, append(heightBytes, addr.Bytes()...)...)...) } diff --git a/x/stake/types.go b/x/stake/types.go index 7757566bf..052a50fa2 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -65,7 +65,7 @@ type Candidate struct { Assets sdk.Rat `json:"assets"` // total shares of a global hold pools Liabilities sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators Description Description `json:"description"` // Description terms for the candidate - ValidatorHeight uint64 `json:"validator_height"` // If considered a validator, height when first considered a validator, else 0 + ValidatorHeight int64 `json:"validator_height"` // Earliest height at current voting power } // Candidates - list of Candidates @@ -80,7 +80,7 @@ func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Descrip Assets: sdk.ZeroRat, Liabilities: sdk.ZeroRat, Description: description, - ValidatorHeight: uint64(0), + ValidatorHeight: int64(0), } } @@ -130,7 +130,7 @@ type Validator struct { Address sdk.Address `json:"address"` PubKey crypto.PubKey `json:"pub_key"` Power sdk.Rat `json:"voting_power"` - Height uint64 `json:"height"` // If considered a validator, height when first considered a validator, else 0 + Height int64 `json:"height"` // Earliest height at current voting power } // abci validator from stake validator type From 36f579766049e8cf2dd0c0b4a85944e12d53b0d6 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 9 Apr 2018 13:12:08 +0200 Subject: [PATCH 036/176] Ordering fixes, testcases --- x/stake/keeper.go | 32 ++++++++++++++++++++------------ x/stake/keeper_keys.go | 4 ++-- x/stake/keeper_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index a51877b3c..f6aa01c63 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -80,9 +80,6 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // retreive the old candidate record oldCandidate, oldFound := k.GetCandidate(ctx, address) - // update the validator block height (will only get written if stake has changed) - candidate.ValidatorHeight = ctx.BlockHeight() - // marshal the candidate record and add to the state bz, err := k.cdc.MarshalBinary(candidate) if err != nil { @@ -90,6 +87,26 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { } store.Set(GetCandidateKey(candidate.Address), bz) + // if the voting power is the same no need to update any of the other indexes + if oldFound && oldCandidate.Assets.Equal(candidate.Assets) { + return + } + + // update the list ordered by voting power + if oldFound { + store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) + } + + // update the validator block height + candidate.ValidatorHeight = ctx.BlockHeight() + + // update the candidate record + bz, err = k.cdc.MarshalBinary(candidate) + if err != nil { + panic(err) + } + store.Set(GetCandidateKey(candidate.Address), bz) + // marshal the new validator record validator := candidate.validator() bz, err = k.cdc.MarshalBinary(validator) @@ -97,15 +114,6 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { panic(err) } - // if the voting power is the same no need to update any of the other indexes - if oldFound && oldCandidate.Assets.Equal(candidate.Assets) { - return - } - - // update the list ordered by voting power - if oldFound { - store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) - } store.Set(GetValidatorKey(address, validator.Power, validator.Height, k.cdc), bz) // add to the validators to update list if is already a validator diff --git a/x/stake/keeper_keys.go b/x/stake/keeper_keys.go index a8adc2a12..e9db23c2c 100644 --- a/x/stake/keeper_keys.go +++ b/x/stake/keeper_keys.go @@ -34,8 +34,8 @@ func GetCandidateKey(addr sdk.Address) []byte { // get the key for the validator used in the power-store func GetValidatorKey(addr sdk.Address, power sdk.Rat, height int64, cdc *wire.Codec) []byte { powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) - heightBytes := make([]byte, 8) - binary.LittleEndian.PutUint64(heightBytes, uint64(height)) // height little-endian (older validators first) + heightBytes := make([]byte, binary.MaxVarintLen64) + binary.BigEndian.PutUint64(heightBytes, ^uint64(height)) // invert height (older validators first) return append(ValidatorsKey, append(powerBytes, append(heightBytes, addr.Bytes()...)...)...) } diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index e01df1aae..baaa2ec8c 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -243,6 +243,47 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, sdk.NewRat(300), validators[0].Power, "%v", validators) assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators) + // test equal voting power, different age + candidates[3].Assets = sdk.NewRat(200) + ctx = ctx.WithBlockHeight(10) + keeper.setCandidate(ctx, candidates[3]) + validators = keeper.GetValidators(ctx) + require.Equal(t, len(validators), n) + assert.Equal(t, sdk.NewRat(200), validators[0].Power, "%v", validators) + assert.Equal(t, sdk.NewRat(200), validators[1].Power, "%v", validators) + assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) + assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) + assert.Equal(t, int64(0), validators[0].Height, "%v", validators) + assert.Equal(t, int64(10), validators[1].Height, "%v", validators) + + // no change in voting power - no change in sort + ctx = ctx.WithBlockHeight(20) + keeper.setCandidate(ctx, candidates[4]) + validators = keeper.GetValidators(ctx) + require.Equal(t, len(validators), n) + assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) + assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) + + // change in voting power of both candidates, ages swapped + candidates[3].Assets = sdk.NewRat(300) + candidates[4].Assets = sdk.NewRat(300) + keeper.setCandidate(ctx, candidates[3]) + validators = keeper.GetValidators(ctx) + require.Equal(t, len(validators), n) + ctx = ctx.WithBlockHeight(30) + keeper.setCandidate(ctx, candidates[4]) + validators = keeper.GetValidators(ctx) + require.Equal(t, len(validators), n, "%v", validators) + assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators) + assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) + + // reset assets / heights + candidates[3].Assets = sdk.NewRat(300) + candidates[4].Assets = sdk.NewRat(200) + ctx = ctx.WithBlockHeight(0) + keeper.setCandidate(ctx, candidates[3]) + keeper.setCandidate(ctx, candidates[4]) + // test a swap in voting power candidates[0].Assets = sdk.NewRat(600) keeper.setCandidate(ctx, candidates[0]) From 91e850b568b244272b5503ecb9d74f02b0e81021 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 6 Apr 2018 13:11:26 +0200 Subject: [PATCH 037/176] WIP: Track validator height (closes #582) --- x/stake/keeper.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index f6aa01c63..7f35da1a9 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -96,24 +96,6 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { if oldFound { store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) } - - // update the validator block height - candidate.ValidatorHeight = ctx.BlockHeight() - - // update the candidate record - bz, err = k.cdc.MarshalBinary(candidate) - if err != nil { - panic(err) - } - store.Set(GetCandidateKey(candidate.Address), bz) - - // marshal the new validator record - validator := candidate.validator() - bz, err = k.cdc.MarshalBinary(validator) - if err != nil { - panic(err) - } - store.Set(GetValidatorKey(address, validator.Power, validator.Height, k.cdc), bz) // add to the validators to update list if is already a validator From 7fa634e772952cde9b0de68c8eff5fdc2228752a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 9 Apr 2018 12:17:45 +0200 Subject: [PATCH 038/176] Cleanup implementation --- x/stake/keeper.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 7f35da1a9..a51877b3c 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -80,6 +80,9 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // retreive the old candidate record oldCandidate, oldFound := k.GetCandidate(ctx, address) + // update the validator block height (will only get written if stake has changed) + candidate.ValidatorHeight = ctx.BlockHeight() + // marshal the candidate record and add to the state bz, err := k.cdc.MarshalBinary(candidate) if err != nil { @@ -87,6 +90,13 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { } store.Set(GetCandidateKey(candidate.Address), bz) + // marshal the new validator record + validator := candidate.validator() + bz, err = k.cdc.MarshalBinary(validator) + if err != nil { + panic(err) + } + // if the voting power is the same no need to update any of the other indexes if oldFound && oldCandidate.Assets.Equal(candidate.Assets) { return From 90d88114d9063bcec2dc2b0b459fe9b1f896116c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 9 Apr 2018 13:12:08 +0200 Subject: [PATCH 039/176] Ordering fixes, testcases --- x/stake/keeper.go | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index a51877b3c..f6aa01c63 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -80,9 +80,6 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // retreive the old candidate record oldCandidate, oldFound := k.GetCandidate(ctx, address) - // update the validator block height (will only get written if stake has changed) - candidate.ValidatorHeight = ctx.BlockHeight() - // marshal the candidate record and add to the state bz, err := k.cdc.MarshalBinary(candidate) if err != nil { @@ -90,6 +87,26 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { } store.Set(GetCandidateKey(candidate.Address), bz) + // if the voting power is the same no need to update any of the other indexes + if oldFound && oldCandidate.Assets.Equal(candidate.Assets) { + return + } + + // update the list ordered by voting power + if oldFound { + store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) + } + + // update the validator block height + candidate.ValidatorHeight = ctx.BlockHeight() + + // update the candidate record + bz, err = k.cdc.MarshalBinary(candidate) + if err != nil { + panic(err) + } + store.Set(GetCandidateKey(candidate.Address), bz) + // marshal the new validator record validator := candidate.validator() bz, err = k.cdc.MarshalBinary(validator) @@ -97,15 +114,6 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { panic(err) } - // if the voting power is the same no need to update any of the other indexes - if oldFound && oldCandidate.Assets.Equal(candidate.Assets) { - return - } - - // update the list ordered by voting power - if oldFound { - store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) - } store.Set(GetValidatorKey(address, validator.Power, validator.Height, k.cdc), bz) // add to the validators to update list if is already a validator From 166711742e0694d7e8fa24e2fed89a9f8769b6a7 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 12 Apr 2018 11:52:54 +0200 Subject: [PATCH 040/176] Rebase, test fix --- x/stake/keeper.go | 8 +++++--- x/stake/keeper_test.go | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index f6aa01c63..8cce331cf 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -94,12 +94,14 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // update the list ordered by voting power if oldFound { + // retain the old validator height, even though stake has changed + candidate.ValidatorHeight = oldCandidate.ValidatorHeight store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) + } else { + // update the validator block height + candidate.ValidatorHeight = ctx.BlockHeight() } - // update the validator block height - candidate.ValidatorHeight = ctx.BlockHeight() - // update the candidate record bz, err = k.cdc.MarshalBinary(candidate) if err != nil { diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index baaa2ec8c..85b2d72ba 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -254,7 +254,7 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) assert.Equal(t, int64(0), validators[0].Height, "%v", validators) - assert.Equal(t, int64(10), validators[1].Height, "%v", validators) + assert.Equal(t, int64(0), validators[1].Height, "%v", validators) // no change in voting power - no change in sort ctx = ctx.WithBlockHeight(20) @@ -274,8 +274,8 @@ func TestGetValidators(t *testing.T) { keeper.setCandidate(ctx, candidates[4]) validators = keeper.GetValidators(ctx) require.Equal(t, len(validators), n, "%v", validators) - assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators) - assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) + assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) + assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) // reset assets / heights candidates[3].Assets = sdk.NewRat(300) From 6424bb85ff1addd3ba13851840f2966e0f4d5914 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 12 Apr 2018 12:37:38 +0200 Subject: [PATCH 041/176] Update ordering logic --- x/stake/keeper.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 8cce331cf..88d82650a 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -94,11 +94,16 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // update the list ordered by voting power if oldFound { - // retain the old validator height, even though stake has changed - candidate.ValidatorHeight = oldCandidate.ValidatorHeight + if k.isNewValidator(ctx, store, candidate.Address) { + // already in the validator set - retain the old validator height + candidate.ValidatorHeight = oldCandidate.ValidatorHeight + } else { + // wasn't in the validator set, update the validator block height + candidate.ValidatorHeight = ctx.BlockHeight() + } store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) } else { - // update the validator block height + // wasn't a candidate, update the validator block height candidate.ValidatorHeight = ctx.BlockHeight() } From 4e72250dd1d936279403603ac6f8cd979d171b6d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 13 Apr 2018 13:28:41 +0200 Subject: [PATCH 042/176] Add testcases (ref #582 discussion) --- x/stake/keeper_test.go | 62 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 85b2d72ba..a137047e5 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -264,7 +264,7 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) - // change in voting power of both candidates, ages swapped + // change in voting power of both candidates, both still in v-set, no age change candidates[3].Assets = sdk.NewRat(300) candidates[4].Assets = sdk.NewRat(300) keeper.setCandidate(ctx, candidates[3]) @@ -277,10 +277,68 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) + // now 2 max validators + params := keeper.GetParams(ctx) + params.MaxValidators = 2 + keeper.setParams(ctx, params) + candidates[0].Assets = sdk.NewRat(500) + keeper.setCandidate(ctx, candidates[0]) + validators = keeper.GetValidators(ctx) + require.Equal(t, uint16(len(validators)), params.MaxValidators) + require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) + // candidate 4 was set before candidate 3 + require.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) + + // simulate scenario from https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-380757108 + ctx = ctx.WithBlockHeight(40) + // candidate 4 kicked out temporarily + candidates[4].Assets = sdk.NewRat(200) + keeper.setCandidate(ctx, candidates[4]) + validators = keeper.GetValidators(ctx) + require.Equal(t, uint16(len(validators)), params.MaxValidators) + require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) + require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) + // candidate 4 does not get spot back + candidates[4].Assets = sdk.NewRat(300) + keeper.setCandidate(ctx, candidates[4]) + validators = keeper.GetValidators(ctx) + require.Equal(t, uint16(len(validators)), params.MaxValidators) + require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) + require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) + candidate, exists := keeper.GetCandidate(ctx, candidates[4].Address) + require.Equal(t, exists, true) + require.Equal(t, candidate.ValidatorHeight, int64(40)) + + // first transaction wins + candidates[1].Assets = sdk.NewRat(1000) + candidates[2].Assets = sdk.NewRat(1000) + keeper.setCandidate(ctx, candidates[1]) + keeper.setCandidate(ctx, candidates[2]) + validators = keeper.GetValidators(ctx) + require.Equal(t, uint16(len(validators)), params.MaxValidators) + require.Equal(t, candidates[1].Address, validators[0].Address, "%v", validators) + require.Equal(t, candidates[2].Address, validators[1].Address, "%v", validators) + candidates[1].Assets = sdk.NewRat(1100) + candidates[2].Assets = sdk.NewRat(1100) + keeper.setCandidate(ctx, candidates[2]) + keeper.setCandidate(ctx, candidates[1]) + validators = keeper.GetValidators(ctx) + require.Equal(t, uint16(len(validators)), params.MaxValidators) + require.Equal(t, candidates[2].Address, validators[0].Address, "%v", validators) + require.Equal(t, candidates[1].Address, validators[1].Address, "%v", validators) + // reset assets / heights + params.MaxValidators = 100 + keeper.setParams(ctx, params) + candidates[0].Assets = sdk.NewRat(0) + candidates[1].Assets = sdk.NewRat(100) + candidates[2].Assets = sdk.NewRat(1) candidates[3].Assets = sdk.NewRat(300) candidates[4].Assets = sdk.NewRat(200) ctx = ctx.WithBlockHeight(0) + keeper.setCandidate(ctx, candidates[0]) + keeper.setCandidate(ctx, candidates[1]) + keeper.setCandidate(ctx, candidates[2]) keeper.setCandidate(ctx, candidates[3]) keeper.setCandidate(ctx, candidates[4]) @@ -295,7 +353,7 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) // test the max validators term - params := keeper.GetParams(ctx) + params = keeper.GetParams(ctx) n = 2 params.MaxValidators = uint16(n) keeper.setParams(ctx, params) From 7f38f3470935a5e1aacd1335e5602e992b032621 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 16 Apr 2018 13:22:05 +0200 Subject: [PATCH 043/176] Stake module block-local tx index counter --- x/stake/keeper.go | 68 +++++++++++++++++++++++++++++++++++------- x/stake/keeper_keys.go | 8 +++-- x/stake/keeper_test.go | 32 +++++++++++--------- x/stake/tick.go | 3 ++ x/stake/types.go | 34 +++++++++++---------- 5 files changed, 104 insertions(+), 41 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 88d82650a..935a0ab46 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -33,6 +33,42 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace return keeper } +// InitGenesis - store genesis parameters +func (k Keeper) InitGenesis(ctx sdk.Context, data json.RawMessage) error { + var state GenesisState + if err := json.Unmarshal(data, &state); err != nil { + return err + } + k.setPool(ctx, state.Pool) + k.setParams(ctx, state.Params) + return nil +} + +// get the current counter +func (k Keeper) getCounter(ctx sdk.Context) int64 { + store := ctx.KVStore(k.storeKey) + b := store.Get(CounterKey) + if b == nil { + return 0 + } + var counter int64 + err := k.cdc.UnmarshalBinary(b, &counter) + if err != nil { + panic(err) + } + return counter +} + +// set the current counter +func (k Keeper) setCounter(ctx sdk.Context, counter int64) { + store := ctx.KVStore(k.storeKey) + bz, err := k.cdc.MarshalBinary(counter) + if err != nil { + panic(err) + } + store.Set(CounterKey, bz) +} + //_________________________________________________________________________ // get a single candidate @@ -80,6 +116,12 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // retreive the old candidate record oldCandidate, oldFound := k.GetCandidate(ctx, address) + // if found, copy the old block height and counter + if oldFound { + candidate.ValidatorHeight = oldCandidate.ValidatorHeight + candidate.ValidatorCounter = oldCandidate.ValidatorCounter + } + // marshal the candidate record and add to the state bz, err := k.cdc.MarshalBinary(candidate) if err != nil { @@ -92,19 +134,25 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { return } + updateHeight := false + // update the list ordered by voting power if oldFound { - if k.isNewValidator(ctx, store, candidate.Address) { - // already in the validator set - retain the old validator height - candidate.ValidatorHeight = oldCandidate.ValidatorHeight - } else { - // wasn't in the validator set, update the validator block height - candidate.ValidatorHeight = ctx.BlockHeight() + if !k.isNewValidator(ctx, store, candidate.Address) { + updateHeight = true } - store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, k.cdc)) + // else already in the validator set - retain the old validator height and counter + store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, oldCandidate.ValidatorCounter, k.cdc)) } else { - // wasn't a candidate, update the validator block height + updateHeight = true + } + + if updateHeight { + // wasn't a candidate or wasn't in the validator set, update the validator block height and counter candidate.ValidatorHeight = ctx.BlockHeight() + counter := k.getCounter(ctx) + candidate.ValidatorCounter = counter + k.setCounter(ctx, counter+1) } // update the candidate record @@ -121,7 +169,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { panic(err) } - store.Set(GetValidatorKey(address, validator.Power, validator.Height, k.cdc), bz) + store.Set(GetValidatorKey(address, validator.Power, validator.Height, validator.Counter, k.cdc), bz) // add to the validators to update list if is already a validator // or is a new validator @@ -156,7 +204,7 @@ func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) { // delete the old candidate record store := ctx.KVStore(k.storeKey) store.Delete(GetCandidateKey(address)) - store.Delete(GetValidatorKey(address, candidate.Assets, candidate.ValidatorHeight, k.cdc)) + store.Delete(GetValidatorKey(address, candidate.Assets, candidate.ValidatorHeight, candidate.ValidatorCounter, k.cdc)) // delete from recent and power weighted validator groups if the validator // exists and add validator with zero power to the validator updates diff --git a/x/stake/keeper_keys.go b/x/stake/keeper_keys.go index e9db23c2c..c34d40480 100644 --- a/x/stake/keeper_keys.go +++ b/x/stake/keeper_keys.go @@ -22,6 +22,8 @@ var ( ToKickOutValidatorsKey = []byte{0x06} // prefix for each key to the last updated validator group DelegatorBondKeyPrefix = []byte{0x07} // prefix for each key to a delegator's bond + + CounterKey = []byte{0x08} // key for block-local tx index ) const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch @@ -32,11 +34,13 @@ func GetCandidateKey(addr sdk.Address) []byte { } // get the key for the validator used in the power-store -func GetValidatorKey(addr sdk.Address, power sdk.Rat, height int64, cdc *wire.Codec) []byte { +func GetValidatorKey(addr sdk.Address, power sdk.Rat, height int64, counter int64, cdc *wire.Codec) []byte { powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) heightBytes := make([]byte, binary.MaxVarintLen64) binary.BigEndian.PutUint64(heightBytes, ^uint64(height)) // invert height (older validators first) - return append(ValidatorsKey, append(powerBytes, append(heightBytes, addr.Bytes()...)...)...) + counterBytes := make([]byte, binary.MaxVarintLen64) + binary.BigEndian.PutUint64(counterBytes, ^uint64(counter)) // invert counter (first txns have priority) + return append(ValidatorsKey, append(powerBytes, append(heightBytes, append(counterBytes, addr.Bytes()...)...)...)...) } // get the key for the accumulated update validators diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index a137047e5..442bc2c5e 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -251,8 +251,8 @@ func TestGetValidators(t *testing.T) { require.Equal(t, len(validators), n) assert.Equal(t, sdk.NewRat(200), validators[0].Power, "%v", validators) assert.Equal(t, sdk.NewRat(200), validators[1].Power, "%v", validators) - assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) - assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) + assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators) + assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) assert.Equal(t, int64(0), validators[0].Height, "%v", validators) assert.Equal(t, int64(0), validators[1].Height, "%v", validators) @@ -261,8 +261,8 @@ func TestGetValidators(t *testing.T) { keeper.setCandidate(ctx, candidates[4]) validators = keeper.GetValidators(ctx) require.Equal(t, len(validators), n) - assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) - assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) + assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators) + assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) // change in voting power of both candidates, both still in v-set, no age change candidates[3].Assets = sdk.NewRat(300) @@ -274,8 +274,8 @@ func TestGetValidators(t *testing.T) { keeper.setCandidate(ctx, candidates[4]) validators = keeper.GetValidators(ctx) require.Equal(t, len(validators), n, "%v", validators) - assert.Equal(t, candidates[4].Address, validators[0].Address, "%v", validators) - assert.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) + assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators) + assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) // now 2 max validators params := keeper.GetParams(ctx) @@ -286,8 +286,8 @@ func TestGetValidators(t *testing.T) { validators = keeper.GetValidators(ctx) require.Equal(t, uint16(len(validators)), params.MaxValidators) require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) - // candidate 4 was set before candidate 3 - require.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) + // candidate 3 was set before candidate 4 + require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) // simulate scenario from https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-380757108 ctx = ctx.WithBlockHeight(40) @@ -309,23 +309,25 @@ func TestGetValidators(t *testing.T) { require.Equal(t, exists, true) require.Equal(t, candidate.ValidatorHeight, int64(40)) - // first transaction wins + // first transaction wins, https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-381250392 + candidates[0].Assets = sdk.NewRat(2000) + keeper.setCandidate(ctx, candidates[0]) candidates[1].Assets = sdk.NewRat(1000) candidates[2].Assets = sdk.NewRat(1000) keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[2]) validators = keeper.GetValidators(ctx) require.Equal(t, uint16(len(validators)), params.MaxValidators) - require.Equal(t, candidates[1].Address, validators[0].Address, "%v", validators) - require.Equal(t, candidates[2].Address, validators[1].Address, "%v", validators) + require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) + require.Equal(t, candidates[1].Address, validators[1].Address, "%v", validators) candidates[1].Assets = sdk.NewRat(1100) candidates[2].Assets = sdk.NewRat(1100) keeper.setCandidate(ctx, candidates[2]) keeper.setCandidate(ctx, candidates[1]) validators = keeper.GetValidators(ctx) require.Equal(t, uint16(len(validators)), params.MaxValidators) - require.Equal(t, candidates[2].Address, validators[0].Address, "%v", validators) - require.Equal(t, candidates[1].Address, validators[1].Address, "%v", validators) + require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) + require.Equal(t, candidates[2].Address, validators[1].Address, "%v", validators) // reset assets / heights params.MaxValidators = 100 @@ -627,7 +629,9 @@ func TestIsRecentValidator(t *testing.T) { validators = keeper.GetValidators(ctx) require.Equal(t, 2, len(validators)) assert.Equal(t, candidatesIn[0].validator(), validators[0]) - assert.Equal(t, candidatesIn[1].validator(), validators[1]) + c1ValWithCounter := candidatesIn[1].validator() + c1ValWithCounter.Counter = int64(1) + assert.Equal(t, c1ValWithCounter, validators[1]) // test a basic retrieve of something that should be a recent validator assert.True(t, keeper.IsRecentValidator(ctx, candidatesIn[0].Address)) diff --git a/x/stake/tick.go b/x/stake/tick.go index 129be58f0..0b3dd1c83 100644 --- a/x/stake/tick.go +++ b/x/stake/tick.go @@ -26,6 +26,9 @@ func (k Keeper) Tick(ctx sdk.Context) (change []abci.Validator) { // save the params k.setPool(ctx, p) + // reset the counter + k.setCounter(ctx, 0) + change = k.getAccUpdateValidators(ctx) return diff --git a/x/stake/types.go b/x/stake/types.go index 052a50fa2..64f1e3dc2 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -59,13 +59,14 @@ const ( // exchange rate. Voting power can be calculated as total bonds multiplied by // exchange rate. type Candidate struct { - Status CandidateStatus `json:"status"` // Bonded status - Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here - PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate - Assets sdk.Rat `json:"assets"` // total shares of a global hold pools - Liabilities sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators - Description Description `json:"description"` // Description terms for the candidate - ValidatorHeight int64 `json:"validator_height"` // Earliest height at current voting power + Status CandidateStatus `json:"status"` // Bonded status + Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here + PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate + Assets sdk.Rat `json:"assets"` // total shares of a global hold pools + Liabilities sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators + Description Description `json:"description"` // Description terms for the candidate + ValidatorHeight int64 `json:"validator_height"` // Earliest height at current voting power + ValidatorCounter int64 `json:"validator_counter"` // Block-local tx index of validator change } // Candidates - list of Candidates @@ -74,13 +75,14 @@ type Candidates []Candidate // NewCandidate - initialize a new candidate func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Description) Candidate { return Candidate{ - Status: Unbonded, - Address: address, - PubKey: pubKey, - Assets: sdk.ZeroRat, - Liabilities: sdk.ZeroRat, - Description: description, - ValidatorHeight: int64(0), + Status: Unbonded, + Address: address, + PubKey: pubKey, + Assets: sdk.ZeroRat, + Liabilities: sdk.ZeroRat, + Description: description, + ValidatorHeight: int64(0), + ValidatorCounter: int64(0), } } @@ -117,6 +119,7 @@ func (c Candidate) validator() Validator { PubKey: c.PubKey, Power: c.Assets, Height: c.ValidatorHeight, + Counter: c.ValidatorCounter, } } @@ -130,7 +133,8 @@ type Validator struct { Address sdk.Address `json:"address"` PubKey crypto.PubKey `json:"pub_key"` Power sdk.Rat `json:"voting_power"` - Height int64 `json:"height"` // Earliest height at current voting power + Height int64 `json:"height"` // Earliest height at current voting power + Counter int64 `json:"counter"` // Block-local tx index for resolving equal voting power & height } // abci validator from stake validator type From d2fa76aa3765e7fadcb379634ef249afe2aaa092 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 19 Apr 2018 13:52:57 +0200 Subject: [PATCH 044/176] Rebase onto develop --- x/stake/keeper.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 935a0ab46..ffb8ad80e 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -33,17 +33,6 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace return keeper } -// InitGenesis - store genesis parameters -func (k Keeper) InitGenesis(ctx sdk.Context, data json.RawMessage) error { - var state GenesisState - if err := json.Unmarshal(data, &state); err != nil { - return err - } - k.setPool(ctx, state.Pool) - k.setParams(ctx, state.Params) - return nil -} - // get the current counter func (k Keeper) getCounter(ctx sdk.Context) int64 { store := ctx.KVStore(k.storeKey) From 12336f249c3b2c3948f759b31269308f0a2774e6 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 19 Apr 2018 14:09:12 +0200 Subject: [PATCH 045/176] Address PR comments Clarify field names, explain testing scenarios in more depth --- x/stake/keeper.go | 22 +++++++++++----------- x/stake/keeper_keys.go | 6 +++--- x/stake/keeper_test.go | 25 +++++++++++++++++++++---- x/stake/types.go | 40 ++++++++++++++++++++-------------------- 4 files changed, 55 insertions(+), 38 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index ffb8ad80e..a3502960e 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -33,14 +33,14 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.CoinKeeper, codespace return keeper } -// get the current counter -func (k Keeper) getCounter(ctx sdk.Context) int64 { +// get the current in-block validator operation counter +func (k Keeper) getCounter(ctx sdk.Context) int16 { store := ctx.KVStore(k.storeKey) b := store.Get(CounterKey) if b == nil { return 0 } - var counter int64 + var counter int16 err := k.cdc.UnmarshalBinary(b, &counter) if err != nil { panic(err) @@ -48,8 +48,8 @@ func (k Keeper) getCounter(ctx sdk.Context) int64 { return counter } -// set the current counter -func (k Keeper) setCounter(ctx sdk.Context, counter int64) { +// set the current in-block validator operation counter +func (k Keeper) setCounter(ctx sdk.Context, counter int16) { store := ctx.KVStore(k.storeKey) bz, err := k.cdc.MarshalBinary(counter) if err != nil { @@ -107,8 +107,8 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // if found, copy the old block height and counter if oldFound { - candidate.ValidatorHeight = oldCandidate.ValidatorHeight - candidate.ValidatorCounter = oldCandidate.ValidatorCounter + candidate.ValidatorBondHeight = oldCandidate.ValidatorBondHeight + candidate.ValidatorBondCounter = oldCandidate.ValidatorBondCounter } // marshal the candidate record and add to the state @@ -131,16 +131,16 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { updateHeight = true } // else already in the validator set - retain the old validator height and counter - store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorHeight, oldCandidate.ValidatorCounter, k.cdc)) + store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorBondHeight, oldCandidate.ValidatorBondCounter, k.cdc)) } else { updateHeight = true } if updateHeight { // wasn't a candidate or wasn't in the validator set, update the validator block height and counter - candidate.ValidatorHeight = ctx.BlockHeight() + candidate.ValidatorBondHeight = ctx.BlockHeight() counter := k.getCounter(ctx) - candidate.ValidatorCounter = counter + candidate.ValidatorBondCounter = counter k.setCounter(ctx, counter+1) } @@ -193,7 +193,7 @@ func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) { // delete the old candidate record store := ctx.KVStore(k.storeKey) store.Delete(GetCandidateKey(address)) - store.Delete(GetValidatorKey(address, candidate.Assets, candidate.ValidatorHeight, candidate.ValidatorCounter, k.cdc)) + store.Delete(GetValidatorKey(address, candidate.Assets, candidate.ValidatorBondHeight, candidate.ValidatorBondCounter, k.cdc)) // delete from recent and power weighted validator groups if the validator // exists and add validator with zero power to the validator updates diff --git a/x/stake/keeper_keys.go b/x/stake/keeper_keys.go index c34d40480..eb641b883 100644 --- a/x/stake/keeper_keys.go +++ b/x/stake/keeper_keys.go @@ -34,12 +34,12 @@ func GetCandidateKey(addr sdk.Address) []byte { } // get the key for the validator used in the power-store -func GetValidatorKey(addr sdk.Address, power sdk.Rat, height int64, counter int64, cdc *wire.Codec) []byte { +func GetValidatorKey(addr sdk.Address, power sdk.Rat, height int64, counter int16, cdc *wire.Codec) []byte { powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) heightBytes := make([]byte, binary.MaxVarintLen64) binary.BigEndian.PutUint64(heightBytes, ^uint64(height)) // invert height (older validators first) - counterBytes := make([]byte, binary.MaxVarintLen64) - binary.BigEndian.PutUint64(counterBytes, ^uint64(counter)) // invert counter (first txns have priority) + counterBytes := make([]byte, 2) + binary.BigEndian.PutUint16(counterBytes, ^uint16(counter)) // invert counter (first txns have priority) return append(ValidatorsKey, append(powerBytes, append(heightBytes, append(counterBytes, addr.Bytes()...)...)...)...) } diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 442bc2c5e..c42f7182b 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -289,7 +289,19 @@ func TestGetValidators(t *testing.T) { // candidate 3 was set before candidate 4 require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) - // simulate scenario from https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-380757108 + /* + A candidate which leaves the validator set due to a decrease in voting power, + then increases to the original voting power, does not get its spot back in the + case of a tie. + + ref https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-380757108 + */ + candidates[4].Assets = sdk.NewRat(301) + keeper.setCandidate(ctx, candidates[4]) + validators = keeper.GetValidators(ctx) + require.Equal(t, uint16(len(validators)), params.MaxValidators) + require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) + require.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) ctx = ctx.WithBlockHeight(40) // candidate 4 kicked out temporarily candidates[4].Assets = sdk.NewRat(200) @@ -307,9 +319,14 @@ func TestGetValidators(t *testing.T) { require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) candidate, exists := keeper.GetCandidate(ctx, candidates[4].Address) require.Equal(t, exists, true) - require.Equal(t, candidate.ValidatorHeight, int64(40)) + require.Equal(t, candidate.ValidatorBondHeight, int64(40)) - // first transaction wins, https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-381250392 + /* + If two candidates both increase to the same voting power in the same block, + the one with the first transaction should take precedence (become a validator). + + ref https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-381250392 + */ candidates[0].Assets = sdk.NewRat(2000) keeper.setCandidate(ctx, candidates[0]) candidates[1].Assets = sdk.NewRat(1000) @@ -630,7 +647,7 @@ func TestIsRecentValidator(t *testing.T) { require.Equal(t, 2, len(validators)) assert.Equal(t, candidatesIn[0].validator(), validators[0]) c1ValWithCounter := candidatesIn[1].validator() - c1ValWithCounter.Counter = int64(1) + c1ValWithCounter.Counter = int16(1) assert.Equal(t, c1ValWithCounter, validators[1]) // test a basic retrieve of something that should be a recent validator diff --git a/x/stake/types.go b/x/stake/types.go index 64f1e3dc2..be48afe3e 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -59,14 +59,14 @@ const ( // exchange rate. Voting power can be calculated as total bonds multiplied by // exchange rate. type Candidate struct { - Status CandidateStatus `json:"status"` // Bonded status - Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here - PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate - Assets sdk.Rat `json:"assets"` // total shares of a global hold pools - Liabilities sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators - Description Description `json:"description"` // Description terms for the candidate - ValidatorHeight int64 `json:"validator_height"` // Earliest height at current voting power - ValidatorCounter int64 `json:"validator_counter"` // Block-local tx index of validator change + Status CandidateStatus `json:"status"` // Bonded status + Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here + PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate + Assets sdk.Rat `json:"assets"` // total shares of a global hold pools + Liabilities sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators + Description Description `json:"description"` // Description terms for the candidate + ValidatorBondHeight int64 `json:"validator_bond_height"` // Earliest height as a bonded validator + ValidatorBondCounter int16 `json:"validator_bond_counter"` // Block-local tx index of validator change } // Candidates - list of Candidates @@ -75,14 +75,14 @@ type Candidates []Candidate // NewCandidate - initialize a new candidate func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Description) Candidate { return Candidate{ - Status: Unbonded, - Address: address, - PubKey: pubKey, - Assets: sdk.ZeroRat, - Liabilities: sdk.ZeroRat, - Description: description, - ValidatorHeight: int64(0), - ValidatorCounter: int64(0), + Status: Unbonded, + Address: address, + PubKey: pubKey, + Assets: sdk.ZeroRat, + Liabilities: sdk.ZeroRat, + Description: description, + ValidatorBondHeight: int64(0), + ValidatorBondCounter: int16(0), } } @@ -118,8 +118,8 @@ func (c Candidate) validator() Validator { Address: c.Address, PubKey: c.PubKey, Power: c.Assets, - Height: c.ValidatorHeight, - Counter: c.ValidatorCounter, + Height: c.ValidatorBondHeight, + Counter: c.ValidatorBondCounter, } } @@ -133,8 +133,8 @@ type Validator struct { Address sdk.Address `json:"address"` PubKey crypto.PubKey `json:"pub_key"` Power sdk.Rat `json:"voting_power"` - Height int64 `json:"height"` // Earliest height at current voting power - Counter int64 `json:"counter"` // Block-local tx index for resolving equal voting power & height + Height int64 `json:"height"` // Earliest height as a validator + Counter int16 `json:"counter"` // Block-local tx index for resolving equal voting power & height } // abci validator from stake validator type From 46626745807906f6dc0fc2bb6b3d3a9c3e8a47aa Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 19 Apr 2018 14:30:14 +0200 Subject: [PATCH 046/176] Add Golint to CircleCI --- .circleci/config.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 47cb5661d..1dc5c1b53 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,6 +27,11 @@ jobs: command: | export PATH="$GOBIN:$PATH" make get_vendor_deps + - run: + name: linter + command: | + export PATH="$GOBIN:$PATH" + go get -u github.com/tendermint/lint/golint - run: name: binaries command: | @@ -46,6 +51,24 @@ jobs: paths: - /go/src/github.com/cosmos/cosmos-sdk + lint: + <<: *defaults + parallelism: 4 + steps: + - attach_workspace: + at: /tmp/workspace + - restore_cache: + key: v1-pkg-cache + - restore_cache: + key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Lint source + command: | + export PATH="$GOBIN:$PATH" + for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/); do + test -z "$(golint $pkg | tee /dev/stderr)" + done + test_cover: <<: *defaults parallelism: 4 @@ -96,10 +119,12 @@ workflows: test-suite: jobs: - setup_dependencies + - lint: + requires: + - setup_dependencies - test_cover: requires: - setup_dependencies - upload_coverage: requires: - test_cover - From 266ea5ce82a25963ac3bdee2e1e5abde22ef38e6 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 4 Mar 2018 00:37:01 -0500 Subject: [PATCH 047/176] docs cleanup --- docs/{ => old}/basecoin/basics.rst | 0 docs/{ => old}/basecoin/extensions.rst | 0 docs/{sdk => old}/glossary.rst | 0 docs/{ => old}/ibc.rst | 0 docs/{x => old}/replay-protection.rst | 0 docs/{ => old}/staking/intro.rst | 0 docs/{ => old}/staking/key-management.rst | 0 docs/{ => old}/staking/local-testnet.rst | 0 docs/{ => old}/staking/public-testnet.rst | 0 docs/{ => sdk}/apps.md | 2 +- docs/sdk/install.rst | 17 ++++++----------- 11 files changed, 7 insertions(+), 12 deletions(-) rename docs/{ => old}/basecoin/basics.rst (100%) rename docs/{ => old}/basecoin/extensions.rst (100%) rename docs/{sdk => old}/glossary.rst (100%) rename docs/{ => old}/ibc.rst (100%) rename docs/{x => old}/replay-protection.rst (100%) rename docs/{ => old}/staking/intro.rst (100%) rename docs/{ => old}/staking/key-management.rst (100%) rename docs/{ => old}/staking/local-testnet.rst (100%) rename docs/{ => old}/staking/public-testnet.rst (100%) rename docs/{ => sdk}/apps.md (97%) diff --git a/docs/basecoin/basics.rst b/docs/old/basecoin/basics.rst similarity index 100% rename from docs/basecoin/basics.rst rename to docs/old/basecoin/basics.rst diff --git a/docs/basecoin/extensions.rst b/docs/old/basecoin/extensions.rst similarity index 100% rename from docs/basecoin/extensions.rst rename to docs/old/basecoin/extensions.rst diff --git a/docs/sdk/glossary.rst b/docs/old/glossary.rst similarity index 100% rename from docs/sdk/glossary.rst rename to docs/old/glossary.rst diff --git a/docs/ibc.rst b/docs/old/ibc.rst similarity index 100% rename from docs/ibc.rst rename to docs/old/ibc.rst diff --git a/docs/x/replay-protection.rst b/docs/old/replay-protection.rst similarity index 100% rename from docs/x/replay-protection.rst rename to docs/old/replay-protection.rst diff --git a/docs/staking/intro.rst b/docs/old/staking/intro.rst similarity index 100% rename from docs/staking/intro.rst rename to docs/old/staking/intro.rst diff --git a/docs/staking/key-management.rst b/docs/old/staking/key-management.rst similarity index 100% rename from docs/staking/key-management.rst rename to docs/old/staking/key-management.rst diff --git a/docs/staking/local-testnet.rst b/docs/old/staking/local-testnet.rst similarity index 100% rename from docs/staking/local-testnet.rst rename to docs/old/staking/local-testnet.rst diff --git a/docs/staking/public-testnet.rst b/docs/old/staking/public-testnet.rst similarity index 100% rename from docs/staking/public-testnet.rst rename to docs/old/staking/public-testnet.rst diff --git a/docs/apps.md b/docs/sdk/apps.md similarity index 97% rename from docs/apps.md rename to docs/sdk/apps.md index 29fb905cb..01210cb66 100644 --- a/docs/apps.md +++ b/docs/sdk/apps.md @@ -15,7 +15,7 @@ while defining as little about that state machine as possible (staying true to t BaseApp requires stores to be mounted via capabilities keys - handlers can only access stores they're given the key for. The BaseApp ensures all stores are properly loaded, cached, and committed. One mounted store is considered the "main" - it holds the latest block header, from which we can find and load the -most recent state. +most recent state ([TODO](https://github.com/cosmos/cosmos-sdk/issues/522)). BaseApp distinguishes between two handler types - the `AnteHandler` and the `MsgHandler`. The former is a global validity check (checking nonces, sigs and sufficient balances to pay fees, diff --git a/docs/sdk/install.rst b/docs/sdk/install.rst index c5a82475a..b4c0ad5da 100644 --- a/docs/sdk/install.rst +++ b/docs/sdk/install.rst @@ -6,7 +6,8 @@ version of the code, please head to our `downloads `__ page to get a pre-compiled binary for your platform. -Usually, Cosmos SDK can be installed like a normal Go program: +Usually, Cosmos SDK can be installed to +`$GOPATH/src/github.com/cosmos/cosmos-sdk` like a normal Go program: :: @@ -23,13 +24,7 @@ repo, the correct way to install is: git pull origin master make all -This will create the ``basecoin`` binary in ``$GOPATH/bin``. -``make all`` implies ``make get_vendor_deps`` and uses ``dep`` to -install the correct version of all dependencies. It also tests the code, -including some cli tests to make sure your binary behaves properly. - -If you need another branch, make sure to run ``git checkout `` -before ``make all``. And if you switch branches a lot, especially -touching other tendermint repos, you may need to ``make fresh`` -sometimes so dep doesn't get confused with all the branches and -versions lying around. +This will create the ``basecoind`` and ``basecli`` binaries locally in +``./build/bin``. ``make all`` implies ``make get_vendor_deps`` and uses +``glide`` to install the correct version of all dependencies. It also tests the +code, including some cli tests to make sure your binary behaves properly. From f386946d4cae7da38bd06dc13618c42842f6769f Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Fri, 30 Mar 2018 11:30:25 -0700 Subject: [PATCH 048/176] docs update part 1 --- docs/old/staking/intro.rst | 171 ++++++++++++++++++++++++++++--------- 1 file changed, 132 insertions(+), 39 deletions(-) diff --git a/docs/old/staking/intro.rst b/docs/old/staking/intro.rst index ca1d002f5..a8f4ea078 100644 --- a/docs/old/staking/intro.rst +++ b/docs/old/staking/intro.rst @@ -1,77 +1,166 @@ -Using Gaia -========== +Using The Staking Module +======================== -This project is a demonstration of the Cosmos Hub with staking functionality; it is -designed to get validator acquianted with staking concepts and procedure. +This project is a demonstration of the Cosmos Hub staking functionality; it is +designed to get validator acquianted with staking concepts and procedures. Potential validators will be declaring their candidacy, after which users can delegate and, if they so wish, unbond. This can be practiced using a local or public testnet. +This example covers initial setup of a two-node testnet between a server in the cloud and a local machine. Begin this tutorial from a cloud machine that you've ``ssh``'d into. + Install ------- -The ``gaia`` tooling is an extension of the Cosmos-SDK; to install: +The ``basecoind`` and ``basecli`` binaries: :: - go get github.com/cosmos/gaia - cd $GOPATH/src/github.com/cosmos/gaia + go get github.com/cosmos/cosmos-sdk + cd $GOPATH/src/github.com/cosmos/cosmos-sdk make get_vendor_deps make install -It has three primary commands: +Let's jump right into it. First, we initialize some default files: :: - Available Commands: - node The Cosmos Network delegation-game blockchain test - rest-server REST client for gaia commands - client Gaia light client - - version Show version info - help Help about any command + basecoind init -and a handful of flags that are highlighted only as necessary. +which will output: -The ``gaia node`` command is a proxt for running a tendermint node. You'll be using -this command to either initialize a new node, or - using existing files - joining -the testnet. +:: -The ``gaia rest-server`` command is used by the `cosmos UI `__. + I[03-30|11:20:13.365] Found private validator module=main path=/root/.basecoind/config/priv_validator.json + I[03-30|11:20:13.365] Found genesis file module=main path=/root/.basecoind/config/genesis.json + Secret phrase to access coins: + citizen hungry tennis noise park hire glory exercise link glow dolphin labor design grit apple abandon -Lastly, the ``gaia client`` command is the workhorse of the staking module. It allows -for sending various transactions and other types of interaction with a running chain. -that you've setup or joined a testnet. +This tell us we have a ``priv_validator.json`` and ``genesis.json`` in the ``~/.basecoind/config`` directory. A ``config.toml`` was also created in the same directory. It is a good idea to get familiar with those files. Write down the seed. -Generating Keys ---------------- +The next thing we'll need to is add the key from ``priv_validator.json`` to the ``basecli`` key manager. For this we need a seed and a password: -Review the `key management tutorial <../key-management.html>`__ and create one key -if you'll be joining the public testnet, and three keys if you'll be trying out a local -testnet. +:: + + basecli keys add alice --recover + +which will give you three prompts: + +:: + + Enter a passphrase for your key: + Repeat the passphrase: + Enter your recovery seed phrase: + +create a password and copy in your seed phrase. The name and address of the key will be output: + +:: + + alice 67997DD03D527EB439B7193F2B813B05B219CC02 + +You can see all available keys with: + +:: + + basecli keys list + +See the `key management tutorial <../key-management.html>`__ for more information on managing keys. Setup Testnet ------------- -The first thing you'll want to do is either `create a local testnet <./local-testnet.html>`__ or -join a `public testnet <./public-testnet.html>`__. Either step is required before proceeding. +Next, we start the daemon (do this in another window): -The rest of this tutorial will assume a local testnet with three participants: ``alice`` will be -the initial validator, ``bob`` will first receives tokens from ``alice`` then declare candidacy -as a validator, and ``charlie`` will bond then unbond to ``bob``. If you're joining the public -testnet, the token amounts will need to be adjusted. +:: + + basecoind start + +and you'll see blocks start streaming through. + +For this example, we're doing the above on a cloud machine. The next steps should be done on your local machine or another server in the cloud, which will join the running testnet then bond/unbond. + +Accounts +-------- + +We have: + +- ``alice`` the initial validator (in the cloud) +- ``bob`` receives tokens from ``alice`` then declares candidacy (from local machine) +- ``charlie`` will bond and unbond to ``bob`` (from local machine) + +Remember that ``alice`` was already created. On your second machine, install the binaries and create two new keys: + +:: + + basecli keys add bob + basecli keys add charlie + +both of which will prompt you for a password. Now we need to copy the ``genesis.json`` and ``config.toml`` from the first machine (with ``alice``) to the second machine. This is a good time to look at both these files. + +The ``genesis.json`` should look something like: + +:: + + { + "app_hash": "", + "app_state": { + "accounts": [ + { + "address": "1FEADCDC8CCB22244769B9CC93C1F6D7489FC5AF", + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + } + ] + }, + "chain_id": "test-chain-EsYka3", + "genesis_time": "0001-01-01T00:00:00Z", + "validators": [ + { + "pub_key": { + "type": "ed25519", + "data": "57B89D41F18FE3FE69250B44693A7D68DE4E03EC563F54C27F9A86CE8B81A4B7" + }, + "power": 10, + "name": "" + } + ] + } + +To notice is that the ``accounts`` field has a an address and a whole bunch of "mycoin". This is ``alice``'s address (todo: dbl check). Under ``validators`` we see the ``pub_key.data`` field, which will match the same field in the ``priv_validator.json`` file. + +The ``config.toml`` is long so let's focus on one field: + +:: + + # Comma separated list of seed nodes to connect to + seeds = "" + +On the ``alice`` cloud machine, we don't need to do anything here. Instead, we need its IP address. After copying this file (and the ``genesis.json`` to your local machine, you'll want to put the IP in the ``seeds = "138.197.161.74"`` field, in this case, we have a made-up IP. For joining testnets with many nodes, you can add more comma-seperated IPs to the list. + + +Now that your files are all setup, it's time to join the network. On your local machine, run: + +:: + + basecoind start + +and your new node will connect to the running validator (``alice``). Sending Tokens -------------- -We'll have ``alice`` who is currently quite rich, send some ``fermions`` to ``bob``: +We'll have ``alice`` send some ``mycoin`` to ``bob``, who has now joined the network: :: - gaia client tx send --amount=1000fermion --sequence=1 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 + basecli send --amount=1000fermion --seq=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 -where the ``--sequence`` flag is to be incremented for each transaction, the ``--name`` flag names the sender, and the ``--to`` flag takes ``bob``'s address. You'll see something like: +where the ``--seq`` flag is to be incremented for each transaction, the ``--name`` flag names the sender, and the ``--to`` flag takes ``bob``'s address. You'll see something like: :: @@ -101,11 +190,13 @@ where the ``--sequence`` flag is to be incremented for each transaction, the ``- "height": 2963 } +TODO: check the above with current actual output. + Check out ``bob``'s account, which should now have 992 fermions: :: - gaia client query account 5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 + basecli account 5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 Adding a Second Validator ------------------------- @@ -114,6 +205,8 @@ Next, let's add the second node as a validator. First, we need the pub_key data: +** need to make bob a priv_Val above! + :: cat $HOME/.gaia2/priv_validator.json @@ -130,7 +223,7 @@ Now ``bob`` can declare candidacy to that pubkey: :: - gaia client tx declare-candidacy --amount=10fermion --name=bob --pubkey= --moniker=bobby + basecli declare-candidacy --amount=10mycoin --name=bob --pubkey= --moniker=bobby with an output like: From 6a7dc0966f2ca7676c61a51431319ef8dbf25c25 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Tue, 3 Apr 2018 05:09:24 -0700 Subject: [PATCH 049/176] docs: update binary --- docs/old/staking/intro.rst | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/old/staking/intro.rst b/docs/old/staking/intro.rst index a8f4ea078..3a8973df1 100644 --- a/docs/old/staking/intro.rst +++ b/docs/old/staking/intro.rst @@ -65,8 +65,6 @@ You can see all available keys with: basecli keys list -See the `key management tutorial <../key-management.html>`__ for more information on managing keys. - Setup Testnet ------------- @@ -158,9 +156,9 @@ We'll have ``alice`` send some ``mycoin`` to ``bob``, who has now joined the net :: - basecli send --amount=1000fermion --seq=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 + basecli send --amount=1000mycoin --seq=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 -where the ``--seq`` flag is to be incremented for each transaction, the ``--name`` flag names the sender, and the ``--to`` flag takes ``bob``'s address. You'll see something like: +where the ``--seq`` flag is to be incremented for each transaction, the ``--name`` flag is the sender (alice), and the ``--to`` flag takes ``bob``'s address. You'll see something like: :: @@ -192,12 +190,16 @@ where the ``--seq`` flag is to be incremented for each transaction, the ``--name TODO: check the above with current actual output. -Check out ``bob``'s account, which should now have 992 fermions: +Check out ``bob``'s account, which should now have 1000 mycoin: :: basecli account 5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 + + + + Adding a Second Validator ------------------------- @@ -205,7 +207,7 @@ Next, let's add the second node as a validator. First, we need the pub_key data: -** need to make bob a priv_Val above! +** need to make bob a priv_Val above? :: @@ -240,11 +242,11 @@ with an output like: } -We should see ``bob``'s account balance decrease by 10 fermions: +We should see ``bob``'s account balance decrease by 10 mycoin: :: - gaia client query account 5D93A6059B6592833CBC8FA3DA90EE0382198985 + basecli account 5D93A6059B6592833CBC8FA3DA90EE0382198985 To confirm for certain the new validator is active, ask the tendermint node: @@ -256,7 +258,7 @@ If you now kill either node, blocks will stop streaming in, because there aren't enough validators online. Turn it back on and they will start streaming again. -Now that ``bob`` has declared candidacy, which essentially bonded 10 fermions and made him a validator, we're going to get ``charlie`` to delegate some coins to ``bob``. +Now that ``bob`` has declared candidacy, which essentially bonded 10 mycoin and made him a validator, we're going to get ``charlie`` to delegate some coins to ``bob``. Delegating ---------- @@ -265,13 +267,13 @@ First let's have ``alice`` send some coins to ``charlie``: :: - gaia client tx send --amount=1000fermion --sequence=2 --name=alice --to=48F74F48281C89E5E4BE9092F735EA519768E8EF + basecli tx --amount=1000mycoin --sequence=2 --name=alice --to=48F74F48281C89E5E4BE9092F735EA519768E8EF -Then ``charlie`` will delegate some fermions to ``bob``: +Then ``charlie`` will delegate some mycoin to ``bob``: :: - gaia client tx delegate --amount=10fermion --name=charlie --pubkey= + basecli tx delegate --amount=10mycoin --name=charlie --pubkey= You'll see output like: @@ -287,13 +289,13 @@ You'll see output like: "height": 51585 } -And that's it. You can query ``charlie``'s account to see the decrease in fermions. +And that's it. You can query ``charlie``'s account to see the decrease in mycoin. To get more information about the candidate, try: :: - gaia client query candidate --pubkey= + basecli query candidate --pubkey= and you'll see output similar to: @@ -326,7 +328,7 @@ It's also possible the query the delegator's bond like so: :: - gaia client query delegator-bond --delegator-address 48F74F48281C89E5E4BE9092F735EA519768E8EF --pubkey 52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B + basecli query delegator-bond --delegator-address 48F74F48281C89E5E4BE9092F735EA519768E8EF --pubkey 52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B with an output similar to: @@ -355,9 +357,7 @@ your VotingPower reduce and your account balance increase. :: - gaia client tx unbond --amount=5fermion --name=charlie --pubkey= - gaia client query account 48F74F48281C89E5E4BE9092F735EA519768E8EF + basecli unbond --amount=5mycoin --name=charlie --pubkey= + basecli account 48F74F48281C89E5E4BE9092F735EA519768E8EF -See the bond decrease with ``gaia client query delegator-bond`` like above. - -That concludes an overview of the ``gaia`` tooling for local testing. +See the bond decrease with ``basecli query delegator-bond`` like above. From 15011eaf2277b14455866d2012d2a4f6ec16208d Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 11 Apr 2018 10:14:34 -0400 Subject: [PATCH 050/176] docs: use correct binary --- docs/old/staking/intro.rst | 52 ++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/docs/old/staking/intro.rst b/docs/old/staking/intro.rst index 3a8973df1..d6f046aba 100644 --- a/docs/old/staking/intro.rst +++ b/docs/old/staking/intro.rst @@ -13,7 +13,7 @@ This example covers initial setup of a two-node testnet between a server in the Install ------- -The ``basecoind`` and ``basecli`` binaries: +The ``gaiad`` and ``gaiacli`` binaries: :: @@ -26,24 +26,24 @@ Let's jump right into it. First, we initialize some default files: :: - basecoind init + gaiad init which will output: :: - I[03-30|11:20:13.365] Found private validator module=main path=/root/.basecoind/config/priv_validator.json - I[03-30|11:20:13.365] Found genesis file module=main path=/root/.basecoind/config/genesis.json + I[03-30|11:20:13.365] Found private validator module=main path=/root/.gaiad/config/priv_validator.json + I[03-30|11:20:13.365] Found genesis file module=main path=/root/.gaiad/config/genesis.json Secret phrase to access coins: citizen hungry tennis noise park hire glory exercise link glow dolphin labor design grit apple abandon -This tell us we have a ``priv_validator.json`` and ``genesis.json`` in the ``~/.basecoind/config`` directory. A ``config.toml`` was also created in the same directory. It is a good idea to get familiar with those files. Write down the seed. +This tell us we have a ``priv_validator.json`` and ``genesis.json`` in the ``~/.gaiad/config`` directory. A ``config.toml`` was also created in the same directory. It is a good idea to get familiar with those files. Write down the seed. -The next thing we'll need to is add the key from ``priv_validator.json`` to the ``basecli`` key manager. For this we need a seed and a password: +The next thing we'll need to is add the key from ``priv_validator.json`` to the ``gaiacli`` key manager. For this we need a seed and a password: :: - basecli keys add alice --recover + gaiacli keys add alice --recover which will give you three prompts: @@ -63,7 +63,7 @@ You can see all available keys with: :: - basecli keys list + gaiacli keys list Setup Testnet ------------- @@ -72,7 +72,7 @@ Next, we start the daemon (do this in another window): :: - basecoind start + gaiad start and you'll see blocks start streaming through. @@ -91,8 +91,8 @@ Remember that ``alice`` was already created. On your second machine, install the :: - basecli keys add bob - basecli keys add charlie + gaiacli keys add bob + gaiacli keys add charlie both of which will prompt you for a password. Now we need to copy the ``genesis.json`` and ``config.toml`` from the first machine (with ``alice``) to the second machine. This is a good time to look at both these files. @@ -145,7 +145,7 @@ Now that your files are all setup, it's time to join the network. On your local :: - basecoind start + gaiad start and your new node will connect to the running validator (``alice``). @@ -156,7 +156,7 @@ We'll have ``alice`` send some ``mycoin`` to ``bob``, who has now joined the net :: - basecli send --amount=1000mycoin --seq=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 + gaiacli send --amount=1000mycoin --seq=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 where the ``--seq`` flag is to be incremented for each transaction, the ``--name`` flag is the sender (alice), and the ``--to`` flag takes ``bob``'s address. You'll see something like: @@ -194,15 +194,13 @@ Check out ``bob``'s account, which should now have 1000 mycoin: :: - basecli account 5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 - - - - + gaiacli account 5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 Adding a Second Validator ------------------------- +**This section is wrong/needs to be updated** + Next, let's add the second node as a validator. First, we need the pub_key data: @@ -225,7 +223,7 @@ Now ``bob`` can declare candidacy to that pubkey: :: - basecli declare-candidacy --amount=10mycoin --name=bob --pubkey= --moniker=bobby + gaiacli declare-candidacy --amount=10mycoin --name=bob --pubkey= --moniker=bobby with an output like: @@ -246,7 +244,7 @@ We should see ``bob``'s account balance decrease by 10 mycoin: :: - basecli account 5D93A6059B6592833CBC8FA3DA90EE0382198985 + gaiacli account 5D93A6059B6592833CBC8FA3DA90EE0382198985 To confirm for certain the new validator is active, ask the tendermint node: @@ -267,13 +265,13 @@ First let's have ``alice`` send some coins to ``charlie``: :: - basecli tx --amount=1000mycoin --sequence=2 --name=alice --to=48F74F48281C89E5E4BE9092F735EA519768E8EF + gaiacli tx --amount=1000mycoin --sequence=2 --name=alice --to=48F74F48281C89E5E4BE9092F735EA519768E8EF Then ``charlie`` will delegate some mycoin to ``bob``: :: - basecli tx delegate --amount=10mycoin --name=charlie --pubkey= + gaiacli tx delegate --amount=10mycoin --name=charlie --pubkey= You'll see output like: @@ -295,7 +293,7 @@ To get more information about the candidate, try: :: - basecli query candidate --pubkey= + gaiacli query candidate --pubkey= and you'll see output similar to: @@ -328,7 +326,7 @@ It's also possible the query the delegator's bond like so: :: - basecli query delegator-bond --delegator-address 48F74F48281C89E5E4BE9092F735EA519768E8EF --pubkey 52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B + gaiacli query delegator-bond --delegator-address 48F74F48281C89E5E4BE9092F735EA519768E8EF --pubkey 52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B with an output similar to: @@ -357,7 +355,7 @@ your VotingPower reduce and your account balance increase. :: - basecli unbond --amount=5mycoin --name=charlie --pubkey= - basecli account 48F74F48281C89E5E4BE9092F735EA519768E8EF + gaiacli unbond --amount=5mycoin --name=charlie --pubkey= + gaiacli account 48F74F48281C89E5E4BE9092F735EA519768E8EF -See the bond decrease with ``basecli query delegator-bond`` like above. +See the bond decrease with ``gaiacli query delegator-bond`` like above. From d7d09f3feab5b7d6bfd4eccdcd2cef8f7d59cd8d Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 11 Apr 2018 10:47:55 -0400 Subject: [PATCH 051/176] docs: cleanup --- docs/conf.py | 2 +- docs/index.rst | 25 +++++++++---------------- docs/sdk/install.rst | 20 +++++++------------- 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 3af51ef95..f0fa0a634 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -47,7 +47,7 @@ master_doc = 'index' # General information about the project. project = u'Cosmos-SDK' -copyright = u'2017, The Authors' +copyright = u'2018, The Authors' author = u'The Authors' # The version info for the project you're documenting, acts as replacement for diff --git a/docs/index.rst b/docs/index.rst index 80d5dd48d..23dd1e87a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,7 +21,7 @@ SDK sdk/overview.rst sdk/install.rst - sdk/glossary.rst +.. old/glossary.rst # not completely up to date but has good content .. Basecoin .. -------- @@ -29,19 +29,17 @@ SDK .. .. toctree:: :maxdepth: 2 -.. basecoin/basics.rst -.. basecoin/extensions.rst +.. old/basecoin/basics.rst # has a decent getting-start tutorial that's relatively up to date, should be consolidated with the other getting started doc Extensions ---------- -Replay Protection -~~~~~~~~~~~~~~~~~ +.. old/basecoin/extensions.rst # probably not worth salvaging -.. toctree:: - :maxdepth: 1 +.. Replay Protection +.. ~~~~~~~~~~~~~~~~~ - x/replay-protection.rst +.. old/replay-protection.rst # not sure if worth salvaging Staking @@ -55,12 +53,7 @@ Staking staking/local-testnet.rst staking/public-testnet.rst -Extras ------- +.. IBC +.. --- -.. One maxdepth for now - -.. toctree:: - :maxdepth: 1 - - ibc.rst +.. old/ibc.rst # needs to be updated diff --git a/docs/sdk/install.rst b/docs/sdk/install.rst index b4c0ad5da..33c176913 100644 --- a/docs/sdk/install.rst +++ b/docs/sdk/install.rst @@ -1,17 +1,12 @@ Install ======= -If you aren't used to compile go programs and just want the released -version of the code, please head to our -`downloads `__ page to get a -pre-compiled binary for your platform. - -Usually, Cosmos SDK can be installed to +Cosmos SDK can be installed to `$GOPATH/src/github.com/cosmos/cosmos-sdk` like a normal Go program: :: - go get -u github.com/cosmos/cosmos-sdk + go get github.com/cosmos/cosmos-sdk If the dependencies have been updated with breaking changes, or if another branch is required, ``dep`` is used for dependency management. @@ -21,10 +16,9 @@ repo, the correct way to install is: :: cd $GOPATH/src/github.com/cosmos/cosmos-sdk - git pull origin master - make all + make get_vendor_deps + make install + make install_examples -This will create the ``basecoind`` and ``basecli`` binaries locally in -``./build/bin``. ``make all`` implies ``make get_vendor_deps`` and uses -``glide`` to install the correct version of all dependencies. It also tests the -code, including some cli tests to make sure your binary behaves properly. +This will install ``gaiad`` and ``gaiacli`` and four example binaries: +``basecoind``, ``basecli``, ``democoind``, and ``democli``. From 4c0a5a6c209fd28fe8349a6781c42e2a49916a3d Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 11 Apr 2018 10:53:50 -0400 Subject: [PATCH 052/176] docs: move back updated intro --- docs/{old => }/staking/intro.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{old => }/staking/intro.rst (100%) diff --git a/docs/old/staking/intro.rst b/docs/staking/intro.rst similarity index 100% rename from docs/old/staking/intro.rst rename to docs/staking/intro.rst From c3cabbf78622e1e50744946802b63b9c4072e849 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 11 Apr 2018 11:25:17 -0400 Subject: [PATCH 053/176] docs: add testnet doc from @kidinamoto01 --- docs/staking/testnet.rst | 211 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 docs/staking/testnet.rst diff --git a/docs/staking/testnet.rst b/docs/staking/testnet.rst new file mode 100644 index 000000000..b18adf5eb --- /dev/null +++ b/docs/staking/testnet.rst @@ -0,0 +1,211 @@ +# Cosmos Testnet Setup + +## Installment + +Requirement : + + [Go 1.9+](https://golang.org/dl/) + + [dep](https://github.com/golang/dep) + +### STEPS + +**Get Source Code** + +``` +go get github.com/cosmos/cosmos-sdk +``` + +Now we can fetch the correct versions of each dependency by running: + +``` +cd $GOPATH/src/github.com/cosmos/cosmos-sdk +git fetch --all +git checkout develop +make get_tools +make get_vendor_deps +make install +make install_examples +``` + +The latest cosmos-sdk should now be installed. Verify that everything is OK by running: + +``` +gaiad version +``` +You should see: + +``` +0.15.0-rc1-9d90c6b +``` + +And also: + +``` +basecli version +``` + +You should see: + +``` +0.15.0-rc1-9d90c6b +``` + +### Local-Test Example + +Here is a quick example to get you off your feet: + +First, generate a new key with a name, and save the address: +``` +MYNAME= +basecli keys new $MYNAME +basecli keys list +MYADDR= +``` +Now initialize a gaia chain: +``` +gaiad init --home=$HOME/.gaiad1 +``` + +you should see seed phrase for genesis account in the output & config & data folder int the home directory + +In the config folder, there will be the following file: config.toml , genesis.json, node_key.json ,priv_validator.json + +The genesis file should look like this: + +``` +{ + "genesis_time": "0001-01-01T00:00:00Z", + "chain_id": "test-chain-0TRiTa", + "validators": [ + { + "pub_key": { + "type": "AC26791624DE60", + "value": "" + }, + "power": 10, + "name": "" + } + ], + "app_hash": "", + "app_state": { + "accounts": [ + { + "address": "", + "coins": [ + { + "denom": "steak", + "amount": 9007199254740992 + } + ] + } + ] + } +} +``` + +**Note: ** We need to change the denomination of token from default to `steak` in genesis file. + +Then, recover the genesis account with `basecli` + +``` +basecli keys add --recover +``` + +By now, you have set up the first node. This is great! + +We can add a second node on our local machine by initiating a node in a new directory, and copying in the genesis. + +``` +gaiad init --home=$HOME/.gaiad2 +``` + +Replace the genesis file and toml file to another folder + +``` +cp $HOME/.gaiad/config/genesis.json $HOME/.gaiad2/config +cp $HOME/.gaiad/config/config.toml $HOME/.gaiad2/config +``` + +Get the node id of first node. +``` +gaiad show_node_id --home=$HOME/.gaiad1 +``` +We need to also modify $HOME/.gaiad2/config.toml to set new seeds and ports. It should look like: +``` +proxy_app = "tcp://127.0.0.1:46668" +moniker = "anonymous" +fast_sync = true +db_backend = "leveldb" +log_level = "state:info,*:error" + +[rpc] +laddr = "tcp://0.0.0.0:46667" + +[p2p] +laddr = "tcp://0.0.0.0:46666" +persistent_peers = "@0.0.0.0:46656" +``` +Great, now that we've initialized the chains, we can start both nodes in the background: +``` +gaiad start --home=$HOME/.gaiad1 &> gaia1.log & +NODE1_PID=$! +gaia start --home=$HOME/.gaiad2 &> gaia2.log & +NODE2_PID=$! +``` +Note we save the PID so we can later kill the processes. Of course, you can peak at your logs with tail gaia1.log, or follow them for a bit with tail -f gaia1.log. +Nice. We can also lookup the validator set: + +``` +basecli validatorset +``` +There is only **one** validator now. Let's add another one! +First, we need to create a new account: + +``` +basecli keys new +``` +Check that we now have two accounts: +``` +basecli keys list +``` +Then, we try to transfer some `strak` to another account: +``` +basecli send --amount=1000steak --to=$MYADDR2 --name=$NAME --chain-id= --node=tcp://localhost:46657 --sequence=0 +``` +**Note** We need to be careful with the `chain-id` & `sequence` + +Check the balance & sequence by : +``` +basecli account $MYADDR +``` +We can see the balance of $MYADDR2 is 1000 now. + +Findally, let's bind the validator in `$HOME/gaiad2`, get the pubkey first +``` +cat $HOME/.gaiad2/config/priv_validator.json | jq .pub_key.value +``` + +Go to [this website](http://tomeko.net/online_tools/base64.php?lang=en) to change pubkey from base64 to Hex. +Ok, now we can bond some coins to that pubkey: +``` +basecli bond --stake=1steak --validator= --sequence=0 --chain-id= --name=test +``` +Nice. We can see there are two validators: + +``` +basecli validatorset +``` +Check the balance of $MYADDR2 to see the difference: it has 1 less `steak`! +``` +basecli account $MYADDR2 +``` +To confirm for certain the new validator is active, check tendermint: +``` +curl localhost:46657/validators +``` +Finally, to relinquish all your power, unbond some coins. You should see your VotingPower reduce and your account balance increase. +``` +basecli unbond --sequence=# --chain-id= --name=test +``` + From 90d03a81b0a54032b64499bfb74697037aaed484 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 11 Apr 2018 11:44:44 -0400 Subject: [PATCH 054/176] docs: rst-ify testnet doc --- docs/sdk/install.rst | 24 +++ docs/staking/testnet.rst | 316 +++++++++++++++++++-------------------- 2 files changed, 175 insertions(+), 165 deletions(-) diff --git a/docs/sdk/install.rst b/docs/sdk/install.rst index 33c176913..213c49a37 100644 --- a/docs/sdk/install.rst +++ b/docs/sdk/install.rst @@ -22,3 +22,27 @@ repo, the correct way to install is: This will install ``gaiad`` and ``gaiacli`` and four example binaries: ``basecoind``, ``basecli``, ``democoind``, and ``democli``. + +Verify that everything is OK by running: + +:: + + gaiad version + +you should see: + +:: + + 0.15.0-rc1-9d90c6b + +then with: + +:: + + basecli version + +you should see: + +:: + + 0.15.0-rc1-9d90c6b diff --git a/docs/staking/testnet.rst b/docs/staking/testnet.rst index b18adf5eb..eabe18bb6 100644 --- a/docs/staking/testnet.rst +++ b/docs/staking/testnet.rst @@ -1,211 +1,197 @@ -# Cosmos Testnet Setup +Testnet Setup +============= -## Installment +Install +------- -Requirement : +See the `installation guide <../sdk/install.html>`__ for details on installation. - [Go 1.9+](https://golang.org/dl/) - - [dep](https://github.com/golang/dep) - -### STEPS - -**Get Source Code** - -``` -go get github.com/cosmos/cosmos-sdk -``` - -Now we can fetch the correct versions of each dependency by running: - -``` -cd $GOPATH/src/github.com/cosmos/cosmos-sdk -git fetch --all -git checkout develop -make get_tools -make get_vendor_deps -make install -make install_examples -``` - -The latest cosmos-sdk should now be installed. Verify that everything is OK by running: - -``` -gaiad version -``` -You should see: - -``` -0.15.0-rc1-9d90c6b -``` - -And also: - -``` -basecli version -``` - -You should see: - -``` -0.15.0-rc1-9d90c6b -``` ### Local-Test Example Here is a quick example to get you off your feet: First, generate a new key with a name, and save the address: -``` -MYNAME= -basecli keys new $MYNAME -basecli keys list -MYADDR= -``` + +:: + + MYNAME= + basecli keys new $MYNAME + basecli keys list + MYADDR= + + Now initialize a gaia chain: -``` -gaiad init --home=$HOME/.gaiad1 -``` -you should see seed phrase for genesis account in the output & config & data folder int the home directory +:: + gaiad init --home=$HOME/.gaiad1 -In the config folder, there will be the following file: config.toml , genesis.json, node_key.json ,priv_validator.json +you should see seed phrase for genesis account in the output & config & data folder in the home directory. + +In the config folder, there will be the following files: ``config.toml``, ``genesis.json``, ``node_key.json``, and ``priv_validator.json``. The genesis file should look like this: -``` -{ - "genesis_time": "0001-01-01T00:00:00Z", - "chain_id": "test-chain-0TRiTa", - "validators": [ +:: + { - "pub_key": { - "type": "AC26791624DE60", - "value": "" - }, - "power": 10, - "name": "" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "", - "coins": [ + "genesis_time": "0001-01-01T00:00:00Z", + "chain_id": "test-chain-0TRiTa", + "validators": [ + { + "pub_key": { + "type": "AC26791624DE60", + "value": "" + }, + "power": 10, + "name": "" + } + ], + "app_hash": "", + "app_state": { + "accounts": [ { - "denom": "steak", - "amount": 9007199254740992 + "address": "", + "coins": [ + { + "denom": "steak", + "amount": 9007199254740992 + } + ] } ] } - ] - } -} -``` + } -**Note: ** We need to change the denomination of token from default to `steak` in genesis file. -Then, recover the genesis account with `basecli` +**Note:** We need to change the denomination of token from default to ``steak`` in genesis file. -``` -basecli keys add --recover -``` +Then, recover the genesis account with ``basecli``: + +:: + + basecli keys add --recover By now, you have set up the first node. This is great! -We can add a second node on our local machine by initiating a node in a new directory, and copying in the genesis. +We can add a second node on our local machine by initiating a node in a new directory, and copying in the ``genesis.json``: -``` -gaiad init --home=$HOME/.gaiad2 -``` +:: -Replace the genesis file and toml file to another folder + gaiad init --home=$HOME/.gaiad2 -``` -cp $HOME/.gaiad/config/genesis.json $HOME/.gaiad2/config -cp $HOME/.gaiad/config/config.toml $HOME/.gaiad2/config -``` +and replace the ``genesis.json`` and ``config.toml`` file: + +:: + + cp $HOME/.gaiad/config/genesis.json $HOME/.gaiad2/config + cp $HOME/.gaiad/config/config.toml $HOME/.gaiad2/config + +then, get the node id of first node: + +:: + + gaiad show_node_id --home=$HOME/.gaiad1 -Get the node id of first node. -``` -gaiad show_node_id --home=$HOME/.gaiad1 -``` We need to also modify $HOME/.gaiad2/config.toml to set new seeds and ports. It should look like: -``` -proxy_app = "tcp://127.0.0.1:46668" -moniker = "anonymous" -fast_sync = true -db_backend = "leveldb" -log_level = "state:info,*:error" -[rpc] -laddr = "tcp://0.0.0.0:46667" +:: + + proxy_app = "tcp://127.0.0.1:46668" + moniker = "anonymous" + fast_sync = true + db_backend = "leveldb" + log_level = "state:info,*:error" + + [rpc] + laddr = "tcp://0.0.0.0:46667" + + [p2p] + laddr = "tcp://0.0.0.0:46666" + persistent_peers = "@0.0.0.0:46656" + -[p2p] -laddr = "tcp://0.0.0.0:46666" -persistent_peers = "@0.0.0.0:46656" -``` Great, now that we've initialized the chains, we can start both nodes in the background: -``` -gaiad start --home=$HOME/.gaiad1 &> gaia1.log & -NODE1_PID=$! -gaia start --home=$HOME/.gaiad2 &> gaia2.log & -NODE2_PID=$! -``` -Note we save the PID so we can later kill the processes. Of course, you can peak at your logs with tail gaia1.log, or follow them for a bit with tail -f gaia1.log. + +:: + + gaiad start --home=$HOME/.gaiad1 &> gaia1.log & + NODE1_PID=$! + gaia start --home=$HOME/.gaiad2 &> gaia2.log & + NODE2_PID=$! + +Note that we save the PID so we can later kill the processes. You can peak at your logs with ``tail gaia1.log``, or follow them for a bit with ``tail -f gaia1.log``. + Nice. We can also lookup the validator set: -``` -basecli validatorset -``` -There is only **one** validator now. Let's add another one! +:: + + basecli validatorset + +There is only **one** validator now. Let's add another one! + First, we need to create a new account: -``` -basecli keys new -``` +:: + + basecli keys new + Check that we now have two accounts: -``` -basecli keys list -``` -Then, we try to transfer some `strak` to another account: -``` -basecli send --amount=1000steak --to=$MYADDR2 --name=$NAME --chain-id= --node=tcp://localhost:46657 --sequence=0 -``` -**Note** We need to be careful with the `chain-id` & `sequence` -Check the balance & sequence by : -``` -basecli account $MYADDR -``` -We can see the balance of $MYADDR2 is 1000 now. +:: + basecli keys list -Findally, let's bind the validator in `$HOME/gaiad2`, get the pubkey first -``` -cat $HOME/.gaiad2/config/priv_validator.json | jq .pub_key.value -``` +Then, we try to transfer some ``steak`` to another account: + +:: + + basecli send --amount=1000steak --to=$MYADDR2 --name=$NAME --chain-id= --node=tcp://localhost:46657 --sequence=0 + +**Note** We need to be careful with the ``chain-id`` and ``sequence`` + +Check the balance & sequence with: + +:: + + basecli account $MYADDR + +We can see the balance of ``$MYADDR2`` is 1000 now. + +Finally, let's bond the validator in ``$HOME/gaiad2``. Get the pubkey first: + +:: + + cat $HOME/.gaiad2/config/priv_validator.json | jq .pub_key.value + +Go to [this website](http://tomeko.net/online_tools/base64.php?lang=en) to change pubkey from base64 to Hex. -Go to [this website](http://tomeko.net/online_tools/base64.php?lang=en) to change pubkey from base64 to Hex. Ok, now we can bond some coins to that pubkey: -``` -basecli bond --stake=1steak --validator= --sequence=0 --chain-id= --name=test -``` -Nice. We can see there are two validators: -``` -basecli validatorset -``` -Check the balance of $MYADDR2 to see the difference: it has 1 less `steak`! -``` -basecli account $MYADDR2 -``` +:: + + basecli bond --stake=1steak --validator= --sequence=0 --chain-id= --name=test + +Nice. We can see there are now two validators: + +:: + + basecli validatorset + +Check the balance of ``$MYADDR2`` to see the difference: it has 1 less ``steak``! + +:: + basecli account $MYADDR2 + To confirm for certain the new validator is active, check tendermint: -``` -curl localhost:46657/validators -``` -Finally, to relinquish all your power, unbond some coins. You should see your VotingPower reduce and your account balance increase. -``` -basecli unbond --sequence=# --chain-id= --name=test -``` +:: + + curl localhost:46657/validators + +Finally, to relinquish all your power, unbond some coins. You should see your VotingPower reduce and your account balance increase. + +:: + + basecli unbond --sequence=# --chain-id= --name=test + +That's it! From 9924b1cb11b5eaf8984de446bdaedd40289a2d0f Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 11 Apr 2018 11:46:50 -0400 Subject: [PATCH 055/176] docs: build fixes --- docs/conf.py | 2 +- docs/index.rst | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index f0fa0a634..73a0220fd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -69,7 +69,7 @@ language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'old'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' diff --git a/docs/index.rst b/docs/index.rst index 23dd1e87a..3bf1c06ad 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -49,9 +49,10 @@ Staking :maxdepth: 1 staking/intro.rst - staking/key-management.rst - staking/local-testnet.rst - staking/public-testnet.rst + staking/testnet.rst +.. staking/key-management.rst +.. staking/local-testnet.rst +.. staking/public-testnet.rst .. IBC .. --- From f9fc2e88d99701bbae40a07a42024aa871cce6d0 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 11 Apr 2018 11:55:22 -0400 Subject: [PATCH 056/176] lil fixes --- docs/index.rst | 10 ++++------ docs/sdk/install.rst | 2 +- docs/staking/testnet.rst | 18 +++++++----------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 3bf1c06ad..1dc8eb35f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,13 +14,11 @@ Welcome to the Cosmos SDK! SDK --- -.. One maxdepth for now - .. toctree:: :maxdepth: 1 - sdk/overview.rst sdk/install.rst +.. sdk/overview.rst # needs to be updated .. old/glossary.rst # not completely up to date but has good content .. Basecoin @@ -31,8 +29,8 @@ SDK .. old/basecoin/basics.rst # has a decent getting-start tutorial that's relatively up to date, should be consolidated with the other getting started doc -Extensions ----------- +.. Extensions +.. ---------- .. old/basecoin/extensions.rst # probably not worth salvaging @@ -48,8 +46,8 @@ Staking .. toctree:: :maxdepth: 1 - staking/intro.rst staking/testnet.rst +.. staking/intro.rst .. staking/key-management.rst .. staking/local-testnet.rst .. staking/public-testnet.rst diff --git a/docs/sdk/install.rst b/docs/sdk/install.rst index 213c49a37..d0e90b838 100644 --- a/docs/sdk/install.rst +++ b/docs/sdk/install.rst @@ -2,7 +2,7 @@ Install ======= Cosmos SDK can be installed to -`$GOPATH/src/github.com/cosmos/cosmos-sdk` like a normal Go program: +``$GOPATH/src/github.com/cosmos/cosmos-sdk`` like a normal Go program: :: diff --git a/docs/staking/testnet.rst b/docs/staking/testnet.rst index eabe18bb6..a04383690 100644 --- a/docs/staking/testnet.rst +++ b/docs/staking/testnet.rst @@ -1,14 +1,8 @@ Testnet Setup ============= -Install -------- - See the `installation guide <../sdk/install.html>`__ for details on installation. - -### Local-Test Example - Here is a quick example to get you off your feet: First, generate a new key with a name, and save the address: @@ -24,6 +18,7 @@ First, generate a new key with a name, and save the address: Now initialize a gaia chain: :: + gaiad init --home=$HOME/.gaiad1 you should see seed phrase for genesis account in the output & config & data folder in the home directory. @@ -63,8 +58,7 @@ The genesis file should look like this: } } - -**Note:** We need to change the denomination of token from default to ``steak`` in genesis file. +**Note:** We need to change the denomination of token from default to ``steak`` in the genesis file. Then, recover the genesis account with ``basecli``: @@ -80,7 +74,7 @@ We can add a second node on our local machine by initiating a node in a new dire gaiad init --home=$HOME/.gaiad2 -and replace the ``genesis.json`` and ``config.toml`` file: +and replace the ``genesis.json`` and ``config.toml`` files: :: @@ -139,6 +133,7 @@ First, we need to create a new account: Check that we now have two accounts: :: + basecli keys list Then, we try to transfer some ``steak`` to another account: @@ -147,7 +142,7 @@ Then, we try to transfer some ``steak`` to another account: basecli send --amount=1000steak --to=$MYADDR2 --name=$NAME --chain-id= --node=tcp://localhost:46657 --sequence=0 -**Note** We need to be careful with the ``chain-id`` and ``sequence`` +**Note:** We need to be careful with the ``chain-id`` and ``sequence`` Check the balance & sequence with: @@ -163,7 +158,7 @@ Finally, let's bond the validator in ``$HOME/gaiad2``. Get the pubkey first: cat $HOME/.gaiad2/config/priv_validator.json | jq .pub_key.value -Go to [this website](http://tomeko.net/online_tools/base64.php?lang=en) to change pubkey from base64 to Hex. +Go to `this website `__ to change pubkey from base64 to Hex. Ok, now we can bond some coins to that pubkey: @@ -180,6 +175,7 @@ Nice. We can see there are now two validators: Check the balance of ``$MYADDR2`` to see the difference: it has 1 less ``steak``! :: + basecli account $MYADDR2 To confirm for certain the new validator is active, check tendermint: From 0fd69d56ee7fc09af323416ca958d7f0b8731b48 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Thu, 19 Apr 2018 12:14:06 -0400 Subject: [PATCH 057/176] docs: PR comments --- docs/sdk/install.rst | 2 +- docs/staking/intro.rst | 65 ++++++++++++++++++++++++++++++++-------- docs/staking/testnet.rst | 26 ++++++++-------- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/docs/sdk/install.rst b/docs/sdk/install.rst index d0e90b838..03b219cb5 100644 --- a/docs/sdk/install.rst +++ b/docs/sdk/install.rst @@ -39,7 +39,7 @@ then with: :: - basecli version + gaiacli version you should see: diff --git a/docs/staking/intro.rst b/docs/staking/intro.rst index d6f046aba..68032c536 100644 --- a/docs/staking/intro.rst +++ b/docs/staking/intro.rst @@ -101,34 +101,75 @@ The ``genesis.json`` should look something like: :: { - "app_hash": "", "app_state": { "accounts": [ { - "address": "1FEADCDC8CCB22244769B9CC93C1F6D7489FC5AF", + "address": "1D9B2356CAADF46D3EE3488E3CCE3028B4283DEE", "coins": [ { - "denom": "mycoin", - "amount": 9007199254740992 + "denom": "fermion", + "amount": 100000 } ] } - ] + ], + "stake": { + "pool": { + "total_supply": 0, + "bonded_shares": { + "num": 0, + "denom": 1 + }, + "unbonded_shares": { + "num": 0, + "denom": 1 + }, + "bonded_pool": 0, + "unbonded_pool": 0, + "inflation_last_time": 0, + "inflation": { + "num": 7, + "denom": 100 + } + }, + "params": { + "inflation_rate_change": { + "num": 13, + "denom": 100 + }, + "inflation_max": { + "num": 20, + "denom": 100 + }, + "inflation_min": { + "num": 7, + "denom": 100 + }, + "goal_bonded": { + "num": 67, + "denom": 100 + }, + "max_validators": 100, + "bond_denom": "fermion" + } + } }, - "chain_id": "test-chain-EsYka3", - "genesis_time": "0001-01-01T00:00:00Z", "validators": [ { "pub_key": { - "type": "ed25519", - "data": "57B89D41F18FE3FE69250B44693A7D68DE4E03EC563F54C27F9A86CE8B81A4B7" + "type": "AC26791624DE60", + "value": "rgpc/ctVld6RpSfwN5yxGBF17R1PwMTdhQ9gKVUZp5g=" }, "power": 10, "name": "" } - ] + ], + "app_hash": "", + "genesis_time": "0001-01-01T00:00:00Z", + "chain_id": "test-chain-Uv1EVU" } + To notice is that the ``accounts`` field has a an address and a whole bunch of "mycoin". This is ``alice``'s address (todo: dbl check). Under ``validators`` we see the ``pub_key.data`` field, which will match the same field in the ``priv_validator.json`` file. The ``config.toml`` is long so let's focus on one field: @@ -156,9 +197,9 @@ We'll have ``alice`` send some ``mycoin`` to ``bob``, who has now joined the net :: - gaiacli send --amount=1000mycoin --seq=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 + gaiacli send --amount=1000mycoin --sequence=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 --chain-id=test-chain-Uv1EVU -where the ``--seq`` flag is to be incremented for each transaction, the ``--name`` flag is the sender (alice), and the ``--to`` flag takes ``bob``'s address. You'll see something like: +where the ``--sequence`` flag is to be incremented for each transaction, the ``--name`` flag is the sender (alice), and the ``--to`` flag takes ``bob``'s address. You'll see something like: :: diff --git a/docs/staking/testnet.rst b/docs/staking/testnet.rst index a04383690..484ec3b5d 100644 --- a/docs/staking/testnet.rst +++ b/docs/staking/testnet.rst @@ -10,8 +10,8 @@ First, generate a new key with a name, and save the address: :: MYNAME= - basecli keys new $MYNAME - basecli keys list + gaiacli keys new $MYNAME + gaiacli keys list MYADDR= @@ -60,11 +60,11 @@ The genesis file should look like this: **Note:** We need to change the denomination of token from default to ``steak`` in the genesis file. -Then, recover the genesis account with ``basecli``: +Then, recover the genesis account with ``gaiacli``: :: - basecli keys add --recover + gaiacli keys add --recover By now, you have set up the first node. This is great! @@ -120,7 +120,7 @@ Nice. We can also lookup the validator set: :: - basecli validatorset + gaiacli validatorset There is only **one** validator now. Let's add another one! @@ -128,19 +128,19 @@ First, we need to create a new account: :: - basecli keys new + gaiacli keys new Check that we now have two accounts: :: - basecli keys list + gaiacli keys list Then, we try to transfer some ``steak`` to another account: :: - basecli send --amount=1000steak --to=$MYADDR2 --name=$NAME --chain-id= --node=tcp://localhost:46657 --sequence=0 + gaiacli send --amount=1000steak --to=$MYADDR2 --name=$NAME --chain-id= --node=tcp://localhost:46657 --sequence=0 **Note:** We need to be careful with the ``chain-id`` and ``sequence`` @@ -148,7 +148,7 @@ Check the balance & sequence with: :: - basecli account $MYADDR + gaiacli account $MYADDR We can see the balance of ``$MYADDR2`` is 1000 now. @@ -164,19 +164,19 @@ Ok, now we can bond some coins to that pubkey: :: - basecli bond --stake=1steak --validator= --sequence=0 --chain-id= --name=test + gaiacli bond --stake=1steak --validator= --sequence=0 --chain-id= --name=test Nice. We can see there are now two validators: :: - basecli validatorset + gaiacli validatorset Check the balance of ``$MYADDR2`` to see the difference: it has 1 less ``steak``! :: - basecli account $MYADDR2 + gaiacli account $MYADDR2 To confirm for certain the new validator is active, check tendermint: @@ -188,6 +188,6 @@ Finally, to relinquish all your power, unbond some coins. You should see your Vo :: - basecli unbond --sequence=# --chain-id= --name=test + gaiacli unbond --sequence=# --chain-id= --name=test That's it! From 57b150960c226eaee761720cdd5bc14149ee795c Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Thu, 19 Apr 2018 12:25:00 -0400 Subject: [PATCH 058/176] docs: add key generation pseudo code --- docs/index.rst | 3 ++- docs/sdk/key-management.rst | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 docs/sdk/key-management.rst diff --git a/docs/index.rst b/docs/index.rst index 1dc8eb35f..66e3f7cb8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,8 +18,9 @@ SDK :maxdepth: 1 sdk/install.rst + sdk/key-management.rst .. sdk/overview.rst # needs to be updated -.. old/glossary.rst # not completely up to date but has good content +.. old/glossary.rst # not completely up to date but has good content .. Basecoin .. -------- diff --git a/docs/sdk/key-management.rst b/docs/sdk/key-management.rst new file mode 100644 index 000000000..d2b657729 --- /dev/null +++ b/docs/sdk/key-management.rst @@ -0,0 +1,18 @@ +Key Management +============== + +Here we cover many aspects of handling keys within the Cosmos SDK framework. + +Pseudo Code +----------- + +Generating an address for an ed25519 public key (in pseudo code): + +:: + + const TypeDistinguisher = HexToBytes("1624de6220") + + // prepend the TypeDistinguisher as Bytes + SerializedBytes = TypeDistinguisher ++ PubKey.asBytes() + + Address = ripemd160(SerializedBytes) From 5c78c382f9a80910a79076828eb06739d6deef84 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 19 Apr 2018 13:04:40 -0400 Subject: [PATCH 059/176] stdlib linting --- types/stdlib/stdlib.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/stdlib/stdlib.go b/types/stdlib/stdlib.go index dd9f4efad..acb786305 100644 --- a/types/stdlib/stdlib.go +++ b/types/stdlib/stdlib.go @@ -7,7 +7,8 @@ import ( wire "github.com/cosmos/cosmos-sdk/wire" ) -type ListMapper interface { // Solidity list like structure +// Solidity list like structure +type ListMapper interface { Len(sdk.Context) int64 Get(sdk.Context, int64, interface{}) Set(sdk.Context, int64, interface{}) @@ -90,6 +91,7 @@ func (lm listMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Conte } } +// mapper interface for queue type QueueMapper interface { Push(sdk.Context, interface{}) Peek(sdk.Context, interface{}) From e149d27f1c7333df52fb01f0c70700fb91373818 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 19 Apr 2018 13:16:09 -0400 Subject: [PATCH 060/176] lint changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d31ce6cbb..26f9d105a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ FEATURES: * Add FeeHandler to ante handler * Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond * MountStoreWithDB without providing a custom store works. +* Repo is now lint compliant / GoMetaLinter with tendermint-lint integrated into CI BREAKING CHANGES @@ -17,6 +18,9 @@ BREAKING CHANGES * [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface * [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores * All module keepers now require a codespace, see basecoin or democoin for usage +* Many changes to names throughout + * Type as a prefix naming convention applied (ex. BondMsg -> MsgBond) + * Removed redundancy in names (ex. stake.StakeKeeper -> stake.Keeper) BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia From 566563f666e1cbd4c556aa453edb15c0baaf7c1c Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 19 Apr 2018 13:20:45 -0400 Subject: [PATCH 061/176] ci gometalinter, also add linter failing function to test --- .circleci/config.yml | 5 ++--- x/stake/handler.go | 3 +++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1dc5c1b53..825d5e93f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -32,6 +32,7 @@ jobs: command: | export PATH="$GOBIN:$PATH" go get -u github.com/tendermint/lint/golint + go get -u github.com/alecthomas/gometalinter - run: name: binaries command: | @@ -65,9 +66,7 @@ jobs: name: Lint source command: | export PATH="$GOBIN:$PATH" - for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/); do - test -z "$(golint $pkg | tee /dev/stderr)" - done + gometalinter --disable-all --enable='golint' --vendor ./... test_cover: <<: *defaults diff --git a/x/stake/handler.go b/x/stake/handler.go index 84eeca3c4..6bdd4b140 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -48,6 +48,9 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ +func Bloop() { +} + // InitGenesis - store genesis parameters func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { k.setPool(ctx, data.Pool) From 2a796b6c7a126aa4020727cf7b85bf06a01ad15d Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 19 Apr 2018 13:23:59 -0400 Subject: [PATCH 062/176] remove test linter fail function --- x/stake/handler.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index 6bdd4b140..84eeca3c4 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -48,9 +48,6 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ -func Bloop() { -} - // InitGenesis - store genesis parameters func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { k.setPool(ctx, data.Pool) From 36c6f726909ec70dd381896f52fbbaa56caa24e8 Mon Sep 17 00:00:00 2001 From: mossid Date: Thu, 15 Mar 2018 18:39:55 +0100 Subject: [PATCH 063/176] add comment & write test for Iterate()s --- types/stdlib/stdlib.go | 24 ++++++++++++++++++------ types/stdlib/stdlib_test.go | 25 ++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/types/stdlib/stdlib.go b/types/stdlib/stdlib.go index dd9f4efad..71196fe0c 100644 --- a/types/stdlib/stdlib.go +++ b/types/stdlib/stdlib.go @@ -1,15 +1,21 @@ -package types +package stdlib import ( - "errors" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" ) -type ListMapper interface { // Solidity list like structure +// ListMapper is a Mapper interface that provides list-like functions +// It panics when the element type cannot be (un/)marshalled by the codec + +type ListMapper interface { + // ListMapper dosen't checks index out of range + // The user should check Len() before doing any actions Len(sdk.Context) int64 Get(sdk.Context, int64, interface{}) + // Setting element out of range is harmful; use Push() when adding new elements Set(sdk.Context, int64, interface{}) Push(sdk.Context, interface{}) Iterate(sdk.Context, interface{}, func(sdk.Context, int64)) @@ -53,7 +59,7 @@ func (lm listMapper) Len(ctx sdk.Context) int64 { func (lm listMapper) Get(ctx sdk.Context, index int64, ptr interface{}) { if index < 0 { - panic(errors.New("")) + panic(fmt.Errorf("Invalid index in ListMapper.Get(ctx, %d, ptr)", index)) } store := ctx.KVStore(lm.key) bz := store.Get(marshalInt64(lm.cdc, index)) @@ -64,7 +70,7 @@ func (lm listMapper) Get(ctx sdk.Context, index int64, ptr interface{}) { func (lm listMapper) Set(ctx sdk.Context, index int64, value interface{}) { if index < 0 { - panic(errors.New("")) + panic(fmt.Errorf("Invalid index in ListMapper.Set(ctx, %d, value)", index)) } store := ctx.KVStore(lm.key) bz, err := lm.cdc.MarshalBinary(value) @@ -90,11 +96,17 @@ func (lm listMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Conte } } +// QueueMapper is a Mapper interface that provides queue-like functions +// It panics when the element type cannot be (un/)marshalled by the codec + type QueueMapper interface { Push(sdk.Context, interface{}) + // Popping/Peeking on an empty queue will cause panic + // The user should check IsEmpty() before doing any actions Peek(sdk.Context, interface{}) Pop(sdk.Context) IsEmpty(sdk.Context) bool + // Iterate() removes elements it processed; return true in the continuation to break Iterate(sdk.Context, interface{}, func(sdk.Context) bool) } @@ -124,7 +136,7 @@ type queueInfo struct { func (info queueInfo) validateBasic() error { if info.End < info.Begin || info.Begin < 0 || info.End < 0 { - return errors.New("") + return fmt.Errorf("Invalid queue information: {Begin: %d, End: %d}", info.Begin, info.End) } return nil } diff --git a/types/stdlib/stdlib_test.go b/types/stdlib/stdlib_test.go index 7c871ccf3..25caa34fe 100644 --- a/types/stdlib/stdlib_test.go +++ b/types/stdlib/stdlib_test.go @@ -1,4 +1,4 @@ -package types +package stdlib import ( "testing" @@ -46,6 +46,12 @@ func TestListMapper(t *testing.T) { lm.Set(ctx, int64(0), val) lm.Get(ctx, int64(0), &res) assert.Equal(t, val, res) + + lm.Iterate(ctx, &res, func(ctx sdk.Context, index int64) { + lm.Set(ctx, index, S{res.I + 1, !res.B}) + }) + lm.Get(ctx, int64(0), &res) + assert.Equal(t, S{3, true}, res) } func TestQueueMapper(t *testing.T) { @@ -63,7 +69,20 @@ func TestQueueMapper(t *testing.T) { qm.Pop(ctx) empty := qm.IsEmpty(ctx) - assert.Equal(t, true, empty) - + assert.True(t, empty) assert.Panics(t, func() { qm.Peek(ctx, &res) }) + + qm.Push(ctx, S{1, true}) + qm.Push(ctx, S{2, true}) + qm.Push(ctx, S{3, true}) + qm.Iterate(ctx, &res, func(ctx sdk.Context) (brk bool) { + if res.I == 3 { + brk = true + } + return + }) + + assert.False(t, qm.IsEmpty(ctx)) + qm.Pop(ctx) + assert.True(t, qm.IsEmpty(ctx)) } From cc07dce8f2cb453dea37afe57b51146d514e0c4a Mon Sep 17 00:00:00 2001 From: mossid Date: Mon, 19 Mar 2018 14:01:49 +0100 Subject: [PATCH 064/176] mock store --- mock/store.go | 104 ++++++++++++++++++++++++++++++++++++ types/stdlib/stdlib_test.go | 2 +- 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 mock/store.go diff --git a/mock/store.go b/mock/store.go new file mode 100644 index 000000000..f7844e668 --- /dev/null +++ b/mock/store.go @@ -0,0 +1,104 @@ +package mock + +import ( + dbm "github.com/tendermint/tmlibs/db" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type multiStore struct { + kv map[sdk.StoreKey]kvStore +} + +func (ms multiStore) CacheMultiStore() sdk.CacheMultiStore { + panic("not implemented") +} + +func (ms multiStore) CacheWrap() sdk.CacheWrap { + panic("not implemented") +} + +func (ms multiStore) Commit() sdk.CommitID { + panic("not implemented") +} + +func (ms multiStore) LastCommitID() sdk.CommitID { + panic("not implemented") +} + +func (ms multiStore) GetCommitKVStore(key sdk.StoreKey) sdk.CommitKVStore { + panic("not implemented") +} + +func (ms multiStore) GetCommitStore(key sdk.StoreKey) sdk.CommitStore { + panic("not implemented") +} + +func (ms multiStore) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) { + ms.kv[key] = kvStore{store: make(map[string][]byte)} +} + +func (ms multiStore) LoadLatestVersion() error { + return nil +} + +func (md multiStore) LoadVersion(ver int64) error { + panic("not implemented") +} + +func (ms multiStore) GetKVStore(key sdk.StoreKey) sdk.KVStore { + return ms.kv[key] +} + +func (ms multiStore) GetStore(key sdk.StoreKey) sdk.Store { + panic("not implemented") +} + +func (ms multiStore) GetStoreType() sdk.StoreType { + panic("not implemented") +} + +type kvStore struct { + store map[string][]byte +} + +func (kv kvStore) CacheWrap() sdk.CacheWrap { + panic("not implemented") +} + +func (kv kvStore) GetStoreType() sdk.StoreType { + panic("not implemented") +} + +func (kv kvStore) Get(key []byte) []byte { + v, ok := kv.store[string(key)] + if !ok { + return nil + } + return v +} + +func (kv kvStore) Has(key []byte) bool { + _, ok := kv.store[string(key)] + return ok +} + +func (kv kvStore) Set(key, value []byte) { + kv.store[string(key)] = value +} + +func (kv kvStore) Delete(key []byte) { + delete(kv.store, string(key)) +} + +func (kv kvStore) Iterator(start, end []byte) sdk.Iterator { + panic("not implemented") +} + +func (kv kvStore) ReverseIterator(start, end []byte) sdk.Iterator { + panic("not implemented") +} + +func NewCommitMultiStore(db dbm.DB) sdk.CommitMultiStore { + return multiStore{kv: make(map[sdk.StoreKey]kvStore)} +} diff --git a/types/stdlib/stdlib_test.go b/types/stdlib/stdlib_test.go index 25caa34fe..a225f148e 100644 --- a/types/stdlib/stdlib_test.go +++ b/types/stdlib/stdlib_test.go @@ -9,7 +9,7 @@ import ( abci "github.com/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/store" + store "github.com/cosmos/cosmos-sdk/mock" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" ) From 380fa78eae9beaa798f6c05ec845783daca04782 Mon Sep 17 00:00:00 2001 From: mossid Date: Mon, 19 Mar 2018 14:27:39 +0100 Subject: [PATCH 065/176] add test for mock/store.go --- mock/store_test.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 mock/store_test.go diff --git a/mock/store_test.go b/mock/store_test.go new file mode 100644 index 000000000..e92060947 --- /dev/null +++ b/mock/store_test.go @@ -0,0 +1,33 @@ +package mock + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + dbm "github.com/tendermint/tmlibs/db" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestStore(t *testing.T) { + db := dbm.NewMemDB() + cms := NewCommitMultiStore(db) + + key := sdk.NewKVStoreKey("test") + cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db) + err := cms.LoadLatestVersion() + assert.Nil(t, err) + + store := cms.GetKVStore(key) + assert.NotNil(t, store) + + k := []byte("hello") + v := []byte("world") + assert.False(t, store.Has(k)) + store.Set(k, v) + assert.True(t, store.Has(k)) + assert.Equal(t, v, store.Get(k)) + store.Delete(k) + assert.False(t, store.Has(k)) +} From 2c10c868f423361e25e0ab9b639ea148cbbf5bc6 Mon Sep 17 00:00:00 2001 From: mossid Date: Thu, 12 Apr 2018 15:46:55 +0200 Subject: [PATCH 066/176] prefixed storekey --- types/stdlib/stdlib.go | 105 +++++++++++++++++++++--------------- types/stdlib/stdlib_test.go | 7 +-- 2 files changed, 66 insertions(+), 46 deletions(-) diff --git a/types/stdlib/stdlib.go b/types/stdlib/stdlib.go index 71196fe0c..97948b876 100644 --- a/types/stdlib/stdlib.go +++ b/types/stdlib/stdlib.go @@ -17,37 +17,40 @@ type ListMapper interface { Get(sdk.Context, int64, interface{}) // Setting element out of range is harmful; use Push() when adding new elements Set(sdk.Context, int64, interface{}) + Delete(sdk.Context, int64) Push(sdk.Context, interface{}) - Iterate(sdk.Context, interface{}, func(sdk.Context, int64)) + Iterate(sdk.Context, interface{}, func(sdk.Context, int64) bool) } type listMapper struct { - key sdk.StoreKey - cdc *wire.Codec - lk []byte + key sdk.StoreKey + cdc *wire.Codec + prefix string + lk []byte } -func NewListMapper(cdc *wire.Codec, key sdk.StoreKey) ListMapper { +func NewListMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) ListMapper { lk, err := cdc.MarshalBinary(int64(-1)) if err != nil { panic(err) } return listMapper{ - key: key, - cdc: cdc, - lk: lk, + key: key, + cdc: cdc, + prefix: prefix, + lk: lk, } } func (lm listMapper) Len(ctx sdk.Context) int64 { store := ctx.KVStore(lm.key) - bz := store.Get(lm.lk) + bz := store.Get(lm.LengthKey()) if bz == nil { zero, err := lm.cdc.MarshalBinary(0) if err != nil { panic(err) } - store.Set(lm.lk, zero) + store.Set(lm.LengthKey(), zero) return 0 } var res int64 @@ -62,7 +65,7 @@ func (lm listMapper) Get(ctx sdk.Context, index int64, ptr interface{}) { panic(fmt.Errorf("Invalid index in ListMapper.Get(ctx, %d, ptr)", index)) } store := ctx.KVStore(lm.key) - bz := store.Get(marshalInt64(lm.cdc, index)) + bz := store.Get(lm.ElemKey(index)) if err := lm.cdc.UnmarshalBinary(bz, ptr); err != nil { panic(err) } @@ -77,7 +80,15 @@ func (lm listMapper) Set(ctx sdk.Context, index int64, value interface{}) { if err != nil { panic(err) } - store.Set(marshalInt64(lm.cdc, index), bz) + store.Set(lm.ElemKey(index), bz) +} + +func (lm listMapper) Delete(ctx sdk.Context, index int64) { + if index < 0 { + panic(fmt.Errorf("Invalid index in ListMapper.Delete(ctx, %d)", index)) + } + store := ctx.KVStore(lm.key) + store.Delete(lm.ElemKey(index)) } func (lm listMapper) Push(ctx sdk.Context, value interface{}) { @@ -85,17 +96,27 @@ func (lm listMapper) Push(ctx sdk.Context, value interface{}) { lm.Set(ctx, length, value) store := ctx.KVStore(lm.key) - store.Set(lm.lk, marshalInt64(lm.cdc, length+1)) + store.Set(lm.LengthKey(), marshalInt64(lm.cdc, length+1)) } -func (lm listMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, int64)) { +func (lm listMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, int64) bool) { length := lm.Len(ctx) for i := int64(0); i < length; i++ { lm.Get(ctx, i, ptr) - fn(ctx, i) + if fn(ctx, i) { + break + } } } +func (lm listMapper) LengthKey() []byte { + return []byte(fmt.Sprintf("%s/%d", lm.prefix, lm.lk)) +} + +func (lm listMapper) ElemKey(i int64) []byte { + return []byte(fmt.Sprintf("%s/%d", lm.prefix, i)) +} + // QueueMapper is a Mapper interface that provides queue-like functions // It panics when the element type cannot be (un/)marshalled by the codec @@ -111,20 +132,24 @@ type QueueMapper interface { } type queueMapper struct { - key sdk.StoreKey - cdc *wire.Codec - ik []byte + key sdk.StoreKey + cdc *wire.Codec + prefix string + lm ListMapper + lk []byte + ik []byte } -func NewQueueMapper(cdc *wire.Codec, key sdk.StoreKey) QueueMapper { - ik, err := cdc.MarshalBinary(int64(-1)) - if err != nil { - panic(err) - } +func NewQueueMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) QueueMapper { + lk := []byte("list") + ik := []byte("info") return queueMapper{ - key: key, - cdc: cdc, - ik: ik, + key: key, + cdc: cdc, + prefix: prefix, + lm: NewListMapper(cdc, key, prefix+string(lk)), + lk: lk, + ik: ik, } } @@ -146,9 +171,9 @@ func (info queueInfo) isEmpty() bool { } func (qm queueMapper) getQueueInfo(store sdk.KVStore) queueInfo { - bz := store.Get(qm.ik) + bz := store.Get(qm.InfoKey()) if bz == nil { - store.Set(qm.ik, marshalQueueInfo(qm.cdc, queueInfo{0, 0})) + store.Set(qm.InfoKey(), marshalQueueInfo(qm.cdc, queueInfo{0, 0})) return queueInfo{0, 0} } var info queueInfo @@ -166,18 +191,14 @@ func (qm queueMapper) setQueueInfo(store sdk.KVStore, info queueInfo) { if err != nil { panic(err) } - store.Set(qm.ik, bz) + store.Set(qm.InfoKey(), bz) } func (qm queueMapper) Push(ctx sdk.Context, value interface{}) { store := ctx.KVStore(qm.key) info := qm.getQueueInfo(store) - bz, err := qm.cdc.MarshalBinary(value) - if err != nil { - panic(err) - } - store.Set(marshalInt64(qm.cdc, info.End), bz) + qm.lm.Set(ctx, info.End, value) info.End++ qm.setQueueInfo(store, info) @@ -186,16 +207,13 @@ func (qm queueMapper) Push(ctx sdk.Context, value interface{}) { func (qm queueMapper) Peek(ctx sdk.Context, ptr interface{}) { store := ctx.KVStore(qm.key) info := qm.getQueueInfo(store) - bz := store.Get(marshalInt64(qm.cdc, info.Begin)) - if err := qm.cdc.UnmarshalBinary(bz, ptr); err != nil { - panic(err) - } + qm.lm.Get(ctx, info.Begin, ptr) } func (qm queueMapper) Pop(ctx sdk.Context) { store := ctx.KVStore(qm.key) info := qm.getQueueInfo(store) - store.Delete(marshalInt64(qm.cdc, info.Begin)) + qm.lm.Delete(ctx, info.Begin) info.Begin++ qm.setQueueInfo(store, info) } @@ -212,11 +230,8 @@ func (qm queueMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Cont var i int64 for i = info.Begin; i < info.End; i++ { + qm.lm.Get(ctx, i, ptr) key := marshalInt64(qm.cdc, i) - bz := store.Get(key) - if err := qm.cdc.UnmarshalBinary(bz, ptr); err != nil { - panic(err) - } store.Delete(key) if fn(ctx) { break @@ -227,6 +242,10 @@ func (qm queueMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Cont qm.setQueueInfo(store, info) } +func (qm queueMapper) InfoKey() []byte { + return []byte(fmt.Sprintf("%s/%s", qm.prefix, qm.ik)) +} + func marshalQueueInfo(cdc *wire.Codec, info queueInfo) []byte { bz, err := cdc.MarshalBinary(info) if err != nil { diff --git a/types/stdlib/stdlib_test.go b/types/stdlib/stdlib_test.go index a225f148e..7cce1bdf6 100644 --- a/types/stdlib/stdlib_test.go +++ b/types/stdlib/stdlib_test.go @@ -32,7 +32,7 @@ func defaultComponents(key sdk.StoreKey) (sdk.Context, *wire.Codec) { func TestListMapper(t *testing.T) { key := sdk.NewKVStoreKey("list") ctx, cdc := defaultComponents(key) - lm := NewListMapper(cdc, key) + lm := NewListMapper(cdc, key, "data") val := S{1, true} var res S @@ -47,8 +47,9 @@ func TestListMapper(t *testing.T) { lm.Get(ctx, int64(0), &res) assert.Equal(t, val, res) - lm.Iterate(ctx, &res, func(ctx sdk.Context, index int64) { + lm.Iterate(ctx, &res, func(ctx sdk.Context, index int64) (brk bool) { lm.Set(ctx, index, S{res.I + 1, !res.B}) + return }) lm.Get(ctx, int64(0), &res) assert.Equal(t, S{3, true}, res) @@ -57,7 +58,7 @@ func TestListMapper(t *testing.T) { func TestQueueMapper(t *testing.T) { key := sdk.NewKVStoreKey("queue") ctx, cdc := defaultComponents(key) - qm := NewQueueMapper(cdc, key) + qm := NewQueueMapper(cdc, key, "data") val := S{1, true} var res S From 775668d12d4ce9b17a688a6f8c6cd625efda1a8b Mon Sep 17 00:00:00 2001 From: mossid Date: Thu, 12 Apr 2018 15:59:24 +0200 Subject: [PATCH 067/176] now pass ci --- mock/store.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mock/store.go b/mock/store.go index f7844e668..e518aa26a 100644 --- a/mock/store.go +++ b/mock/store.go @@ -99,6 +99,14 @@ func (kv kvStore) ReverseIterator(start, end []byte) sdk.Iterator { panic("not implemented") } +func (kv kvStore) SubspaceIterator(prefix []byte) sdk.Iterator { + panic("not implemented") +} + +func (kv kvStore) ReverseSubspaceIterator(prefix []byte) sdk.Iterator { + panic("not implemented") +} + func NewCommitMultiStore(db dbm.DB) sdk.CommitMultiStore { return multiStore{kv: make(map[sdk.StoreKey]kvStore)} } From fbfdbd4266e069e7e67911abea1dce830e072634 Mon Sep 17 00:00:00 2001 From: mossid Date: Thu, 12 Apr 2018 16:07:58 +0200 Subject: [PATCH 068/176] stdlib -> lib --- types/{stdlib => lib}/stdlib.go | 0 types/{stdlib => lib}/stdlib_test.go | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename types/{stdlib => lib}/stdlib.go (100%) rename types/{stdlib => lib}/stdlib_test.go (100%) diff --git a/types/stdlib/stdlib.go b/types/lib/stdlib.go similarity index 100% rename from types/stdlib/stdlib.go rename to types/lib/stdlib.go diff --git a/types/stdlib/stdlib_test.go b/types/lib/stdlib_test.go similarity index 100% rename from types/stdlib/stdlib_test.go rename to types/lib/stdlib_test.go From 373e408fadeb5fcf23d28bba282f4dd9e946278c Mon Sep 17 00:00:00 2001 From: mossid Date: Thu, 12 Apr 2018 18:19:28 +0200 Subject: [PATCH 069/176] expose QueueInfo --- types/lib/stdlib.go | 30 ++++++++++++++++++------------ types/lib/stdlib_test.go | 4 +++- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/types/lib/stdlib.go b/types/lib/stdlib.go index 97948b876..caf426585 100644 --- a/types/lib/stdlib.go +++ b/types/lib/stdlib.go @@ -1,4 +1,4 @@ -package stdlib +package lib import ( "fmt" @@ -129,6 +129,7 @@ type QueueMapper interface { IsEmpty(sdk.Context) bool // Iterate() removes elements it processed; return true in the continuation to break Iterate(sdk.Context, interface{}, func(sdk.Context) bool) + Info(sdk.Context) QueueInfo } type queueMapper struct { @@ -153,30 +154,30 @@ func NewQueueMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) QueueMappe } } -type queueInfo struct { +type QueueInfo struct { // begin <= elems < end Begin int64 End int64 } -func (info queueInfo) validateBasic() error { +func (info QueueInfo) validateBasic() error { if info.End < info.Begin || info.Begin < 0 || info.End < 0 { return fmt.Errorf("Invalid queue information: {Begin: %d, End: %d}", info.Begin, info.End) } return nil } -func (info queueInfo) isEmpty() bool { +func (info QueueInfo) isEmpty() bool { return info.Begin == info.End } -func (qm queueMapper) getQueueInfo(store sdk.KVStore) queueInfo { +func (qm queueMapper) getQueueInfo(store sdk.KVStore) QueueInfo { bz := store.Get(qm.InfoKey()) if bz == nil { - store.Set(qm.InfoKey(), marshalQueueInfo(qm.cdc, queueInfo{0, 0})) - return queueInfo{0, 0} + store.Set(qm.InfoKey(), marshalQueueInfo(qm.cdc, QueueInfo{0, 0})) + return QueueInfo{0, 0} } - var info queueInfo + var info QueueInfo if err := qm.cdc.UnmarshalBinary(bz, &info); err != nil { panic(err) } @@ -186,7 +187,7 @@ func (qm queueMapper) getQueueInfo(store sdk.KVStore) queueInfo { return info } -func (qm queueMapper) setQueueInfo(store sdk.KVStore, info queueInfo) { +func (qm queueMapper) setQueueInfo(store sdk.KVStore, info QueueInfo) { bz, err := qm.cdc.MarshalBinary(info) if err != nil { panic(err) @@ -231,8 +232,7 @@ func (qm queueMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Cont var i int64 for i = info.Begin; i < info.End; i++ { qm.lm.Get(ctx, i, ptr) - key := marshalInt64(qm.cdc, i) - store.Delete(key) + qm.lm.Delete(ctx, i) if fn(ctx) { break } @@ -242,11 +242,17 @@ func (qm queueMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Cont qm.setQueueInfo(store, info) } +func (qm queueMapper) Info(ctx sdk.Context) QueueInfo { + store := ctx.KVStore(qm.key) + + return qm.getQueueInfo(store) +} + func (qm queueMapper) InfoKey() []byte { return []byte(fmt.Sprintf("%s/%s", qm.prefix, qm.ik)) } -func marshalQueueInfo(cdc *wire.Codec, info queueInfo) []byte { +func marshalQueueInfo(cdc *wire.Codec, info QueueInfo) []byte { bz, err := cdc.MarshalBinary(info) if err != nil { panic(err) diff --git a/types/lib/stdlib_test.go b/types/lib/stdlib_test.go index 7cce1bdf6..197e6cbe4 100644 --- a/types/lib/stdlib_test.go +++ b/types/lib/stdlib_test.go @@ -1,4 +1,4 @@ -package stdlib +package lib import ( "testing" @@ -84,6 +84,8 @@ func TestQueueMapper(t *testing.T) { }) assert.False(t, qm.IsEmpty(ctx)) + assert.Equal(t, QueueInfo{3, 4}, qm.Info(ctx)) + qm.Pop(ctx) assert.True(t, qm.IsEmpty(ctx)) } From 1b72a6c40d6e8785af2008dd8d799527f87784d8 Mon Sep 17 00:00:00 2001 From: mossid Date: Fri, 13 Apr 2018 14:10:55 +0200 Subject: [PATCH 070/176] apply requests --- types/lib/stdlib.go | 224 ++++++++++++++++++--------------------- types/lib/stdlib_test.go | 40 +++++-- 2 files changed, 133 insertions(+), 131 deletions(-) diff --git a/types/lib/stdlib.go b/types/lib/stdlib.go index caf426585..f075ce3ff 100644 --- a/types/lib/stdlib.go +++ b/types/lib/stdlib.go @@ -2,6 +2,8 @@ package lib import ( "fmt" + "strconv" + "strings" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" @@ -11,38 +13,45 @@ import ( // It panics when the element type cannot be (un/)marshalled by the codec type ListMapper interface { - // ListMapper dosen't checks index out of range + // ListMapper dosen't check if an index is in bounds // The user should check Len() before doing any actions - Len(sdk.Context) int64 - Get(sdk.Context, int64, interface{}) - // Setting element out of range is harmful; use Push() when adding new elements - Set(sdk.Context, int64, interface{}) - Delete(sdk.Context, int64) + Len(sdk.Context) uint64 + + Get(sdk.Context, uint64, interface{}) error + + // Setting element out of range is harmful + // Use Push() instead of Set() to append a new element + Set(sdk.Context, uint64, interface{}) + + Delete(sdk.Context, uint64) + Push(sdk.Context, interface{}) - Iterate(sdk.Context, interface{}, func(sdk.Context, int64) bool) + + // Iterate*() is used to iterate over all existing elements in the list + // Return true in the continuation to break + + // CONTRACT: No writes may happen within a domain while an iterator exists over it. + IterateRead(sdk.Context, interface{}, func(sdk.Context, uint64) bool) + + // IterateWrite() is safe to write over the domain + IterateWrite(sdk.Context, interface{}, func(sdk.Context, uint64) bool) } type listMapper struct { key sdk.StoreKey cdc *wire.Codec prefix string - lk []byte } func NewListMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) ListMapper { - lk, err := cdc.MarshalBinary(int64(-1)) - if err != nil { - panic(err) - } return listMapper{ key: key, cdc: cdc, prefix: prefix, - lk: lk, } } -func (lm listMapper) Len(ctx sdk.Context) int64 { +func (lm listMapper) Len(ctx sdk.Context) uint64 { store := ctx.KVStore(lm.key) bz := store.Get(lm.LengthKey()) if bz == nil { @@ -53,28 +62,20 @@ func (lm listMapper) Len(ctx sdk.Context) int64 { store.Set(lm.LengthKey(), zero) return 0 } - var res int64 + var res uint64 if err := lm.cdc.UnmarshalBinary(bz, &res); err != nil { panic(err) } return res } -func (lm listMapper) Get(ctx sdk.Context, index int64, ptr interface{}) { - if index < 0 { - panic(fmt.Errorf("Invalid index in ListMapper.Get(ctx, %d, ptr)", index)) - } +func (lm listMapper) Get(ctx sdk.Context, index uint64, ptr interface{}) error { store := ctx.KVStore(lm.key) bz := store.Get(lm.ElemKey(index)) - if err := lm.cdc.UnmarshalBinary(bz, ptr); err != nil { - panic(err) - } + return lm.cdc.UnmarshalBinary(bz, ptr) } -func (lm listMapper) Set(ctx sdk.Context, index int64, value interface{}) { - if index < 0 { - panic(fmt.Errorf("Invalid index in ListMapper.Set(ctx, %d, value)", index)) - } +func (lm listMapper) Set(ctx sdk.Context, index uint64, value interface{}) { store := ctx.KVStore(lm.key) bz, err := lm.cdc.MarshalBinary(value) if err != nil { @@ -83,10 +84,7 @@ func (lm listMapper) Set(ctx sdk.Context, index int64, value interface{}) { store.Set(lm.ElemKey(index), bz) } -func (lm listMapper) Delete(ctx sdk.Context, index int64) { - if index < 0 { - panic(fmt.Errorf("Invalid index in ListMapper.Delete(ctx, %d)", index)) - } +func (lm listMapper) Delete(ctx sdk.Context, index uint64) { store := ctx.KVStore(lm.key) store.Delete(lm.ElemKey(index)) } @@ -96,13 +94,38 @@ func (lm listMapper) Push(ctx sdk.Context, value interface{}) { lm.Set(ctx, length, value) store := ctx.KVStore(lm.key) - store.Set(lm.LengthKey(), marshalInt64(lm.cdc, length+1)) + store.Set(lm.LengthKey(), marshalUint64(lm.cdc, length+1)) } -func (lm listMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, int64) bool) { +func (lm listMapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { + store := ctx.KVStore(lm.key) + start, end := subspace([]byte(fmt.Sprintf("%s/elem/", lm.prefix))) + iter := store.Iterator(start, end) + for ; iter.Valid(); iter.Next() { + v := iter.Value() + if err := lm.cdc.UnmarshalBinary(v, ptr); err != nil { + panic(err) + } + s := strings.Split(string(iter.Key()), "/") + index, err := strconv.ParseUint(s[len(s)-1], 10, 64) + if err != nil { + panic(err) + } + if fn(ctx, index) { + break + } + } + + iter.Close() +} + +func (lm listMapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { length := lm.Len(ctx) - for i := int64(0); i < length; i++ { - lm.Get(ctx, i, ptr) + + for i := uint64(0); i < length; i++ { + if err := lm.Get(ctx, i, ptr); err != nil { + continue + } if fn(ctx, i) { break } @@ -110,11 +133,11 @@ func (lm listMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Conte } func (lm listMapper) LengthKey() []byte { - return []byte(fmt.Sprintf("%s/%d", lm.prefix, lm.lk)) + return []byte(fmt.Sprintf("%s/length", lm.prefix)) } -func (lm listMapper) ElemKey(i int64) []byte { - return []byte(fmt.Sprintf("%s/%d", lm.prefix, i)) +func (lm listMapper) ElemKey(i uint64) []byte { + return []byte(fmt.Sprintf("%s/elem/%020d", lm.prefix, i)) } // QueueMapper is a Mapper interface that provides queue-like functions @@ -124,12 +147,14 @@ type QueueMapper interface { Push(sdk.Context, interface{}) // Popping/Peeking on an empty queue will cause panic // The user should check IsEmpty() before doing any actions - Peek(sdk.Context, interface{}) + Peek(sdk.Context, interface{}) error Pop(sdk.Context) IsEmpty(sdk.Context) bool - // Iterate() removes elements it processed; return true in the continuation to break - Iterate(sdk.Context, interface{}, func(sdk.Context) bool) - Info(sdk.Context) QueueInfo + // Iterate() removes elements it processed + // Return true in the continuation to break + // The interface{} is unmarshalled before the continuation is called + // Starts from the top(head) of the queue + Flush(sdk.Context, interface{}, func(sdk.Context) bool) } type queueMapper struct { @@ -137,100 +162,67 @@ type queueMapper struct { cdc *wire.Codec prefix string lm ListMapper - lk []byte - ik []byte } func NewQueueMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) QueueMapper { - lk := []byte("list") - ik := []byte("info") return queueMapper{ key: key, cdc: cdc, prefix: prefix, - lm: NewListMapper(cdc, key, prefix+string(lk)), - lk: lk, - ik: ik, + lm: NewListMapper(cdc, key, prefix+"list"), } } -type QueueInfo struct { - // begin <= elems < end - Begin int64 - End int64 -} - -func (info QueueInfo) validateBasic() error { - if info.End < info.Begin || info.Begin < 0 || info.End < 0 { - return fmt.Errorf("Invalid queue information: {Begin: %d, End: %d}", info.Begin, info.End) - } - return nil -} - -func (info QueueInfo) isEmpty() bool { - return info.Begin == info.End -} - -func (qm queueMapper) getQueueInfo(store sdk.KVStore) QueueInfo { - bz := store.Get(qm.InfoKey()) +func (qm queueMapper) getTop(store sdk.KVStore) (res uint64) { + bz := store.Get(qm.TopKey()) if bz == nil { - store.Set(qm.InfoKey(), marshalQueueInfo(qm.cdc, QueueInfo{0, 0})) - return QueueInfo{0, 0} + store.Set(qm.TopKey(), marshalUint64(qm.cdc, 0)) + return 0 } - var info QueueInfo - if err := qm.cdc.UnmarshalBinary(bz, &info); err != nil { + + if err := qm.cdc.UnmarshalBinary(bz, &res); err != nil { panic(err) } - if err := info.validateBasic(); err != nil { - panic(err) - } - return info + + return } -func (qm queueMapper) setQueueInfo(store sdk.KVStore, info QueueInfo) { - bz, err := qm.cdc.MarshalBinary(info) - if err != nil { - panic(err) - } - store.Set(qm.InfoKey(), bz) +func (qm queueMapper) setTop(store sdk.KVStore, top uint64) { + bz := marshalUint64(qm.cdc, top) + store.Set(qm.TopKey(), bz) } func (qm queueMapper) Push(ctx sdk.Context, value interface{}) { - store := ctx.KVStore(qm.key) - info := qm.getQueueInfo(store) - - qm.lm.Set(ctx, info.End, value) - - info.End++ - qm.setQueueInfo(store, info) + qm.lm.Push(ctx, value) } -func (qm queueMapper) Peek(ctx sdk.Context, ptr interface{}) { +func (qm queueMapper) Peek(ctx sdk.Context, ptr interface{}) error { store := ctx.KVStore(qm.key) - info := qm.getQueueInfo(store) - qm.lm.Get(ctx, info.Begin, ptr) + top := qm.getTop(store) + return qm.lm.Get(ctx, top, ptr) } func (qm queueMapper) Pop(ctx sdk.Context) { store := ctx.KVStore(qm.key) - info := qm.getQueueInfo(store) - qm.lm.Delete(ctx, info.Begin) - info.Begin++ - qm.setQueueInfo(store, info) + top := qm.getTop(store) + qm.lm.Delete(ctx, top) + qm.setTop(store, top+1) } func (qm queueMapper) IsEmpty(ctx sdk.Context) bool { store := ctx.KVStore(qm.key) - info := qm.getQueueInfo(store) - return info.isEmpty() + top := qm.getTop(store) + length := qm.lm.Len(ctx) + return top >= length } -func (qm queueMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Context) bool) { +func (qm queueMapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Context) bool) { store := ctx.KVStore(qm.key) - info := qm.getQueueInfo(store) + top := qm.getTop(store) + length := qm.lm.Len(ctx) - var i int64 - for i = info.Begin; i < info.End; i++ { + var i uint64 + for i = top; i < length; i++ { qm.lm.Get(ctx, i, ptr) qm.lm.Delete(ctx, i) if fn(ctx) { @@ -238,32 +230,24 @@ func (qm queueMapper) Iterate(ctx sdk.Context, ptr interface{}, fn func(sdk.Cont } } - info.Begin = i - qm.setQueueInfo(store, info) + qm.setTop(store, i) } -func (qm queueMapper) Info(ctx sdk.Context) QueueInfo { - store := ctx.KVStore(qm.key) - - return qm.getQueueInfo(store) +func (qm queueMapper) TopKey() []byte { + return []byte(fmt.Sprintf("%s/top", qm.prefix)) } -func (qm queueMapper) InfoKey() []byte { - return []byte(fmt.Sprintf("%s/%s", qm.prefix, qm.ik)) -} - -func marshalQueueInfo(cdc *wire.Codec, info QueueInfo) []byte { - bz, err := cdc.MarshalBinary(info) - if err != nil { - panic(err) - } - return bz -} - -func marshalInt64(cdc *wire.Codec, i int64) []byte { +func marshalUint64(cdc *wire.Codec, i uint64) []byte { bz, err := cdc.MarshalBinary(i) if err != nil { panic(err) } return bz } + +func subspace(prefix []byte) (start, end []byte) { + end = make([]byte, len(prefix)) + copy(end, prefix) + end[len(end)-1]++ + return prefix, end +} diff --git a/types/lib/stdlib_test.go b/types/lib/stdlib_test.go index 197e6cbe4..1058fed6e 100644 --- a/types/lib/stdlib_test.go +++ b/types/lib/stdlib_test.go @@ -9,13 +9,13 @@ import ( abci "github.com/tendermint/abci/types" - store "github.com/cosmos/cosmos-sdk/mock" + "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" ) type S struct { - I int64 + I uint64 B bool } @@ -38,20 +38,39 @@ func TestListMapper(t *testing.T) { var res S lm.Push(ctx, val) - assert.Equal(t, int64(1), lm.Len(ctx)) - lm.Get(ctx, int64(0), &res) + assert.Equal(t, uint64(1), lm.Len(ctx)) + lm.Get(ctx, uint64(0), &res) assert.Equal(t, val, res) val = S{2, false} - lm.Set(ctx, int64(0), val) - lm.Get(ctx, int64(0), &res) + lm.Set(ctx, uint64(0), val) + lm.Get(ctx, uint64(0), &res) assert.Equal(t, val, res) - lm.Iterate(ctx, &res, func(ctx sdk.Context, index int64) (brk bool) { + val = S{100, false} + lm.Push(ctx, val) + assert.Equal(t, uint64(2), lm.Len(ctx)) + lm.Get(ctx, uint64(1), &res) + assert.Equal(t, val, res) + + lm.Delete(ctx, uint64(1)) + assert.Equal(t, uint64(2), lm.Len(ctx)) + + lm.IterateRead(ctx, &res, func(ctx sdk.Context, index uint64) (brk bool) { + var temp S + lm.Get(ctx, index, &temp) + assert.Equal(t, temp, res) + + assert.True(t, index != 1) + return + }) + + lm.IterateWrite(ctx, &res, func(ctx sdk.Context, index uint64) (brk bool) { lm.Set(ctx, index, S{res.I + 1, !res.B}) return }) - lm.Get(ctx, int64(0), &res) + + lm.Get(ctx, uint64(0), &res) assert.Equal(t, S{3, true}, res) } @@ -71,12 +90,12 @@ func TestQueueMapper(t *testing.T) { empty := qm.IsEmpty(ctx) assert.True(t, empty) - assert.Panics(t, func() { qm.Peek(ctx, &res) }) + assert.NotNil(t, qm.Peek(ctx, &res)) qm.Push(ctx, S{1, true}) qm.Push(ctx, S{2, true}) qm.Push(ctx, S{3, true}) - qm.Iterate(ctx, &res, func(ctx sdk.Context) (brk bool) { + qm.Flush(ctx, &res, func(ctx sdk.Context) (brk bool) { if res.I == 3 { brk = true } @@ -84,7 +103,6 @@ func TestQueueMapper(t *testing.T) { }) assert.False(t, qm.IsEmpty(ctx)) - assert.Equal(t, QueueInfo{3, 4}, qm.Info(ctx)) qm.Pop(ctx) assert.True(t, qm.IsEmpty(ctx)) From e00d03aabde2cd84e169e3dada7f271c6129595e Mon Sep 17 00:00:00 2001 From: mossid Date: Wed, 18 Apr 2018 16:56:39 +0200 Subject: [PATCH 071/176] in progress --- types/lib/stdlib.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/types/lib/stdlib.go b/types/lib/stdlib.go index f075ce3ff..7f812033b 100644 --- a/types/lib/stdlib.go +++ b/types/lib/stdlib.go @@ -27,6 +27,10 @@ type ListMapper interface { Push(sdk.Context, interface{}) + // Getter/Setter for meta information - can be customized + GetMeta(sdk.Context, interface{}) error + SetMeta(sdk.Context, interface{}) + // Iterate*() is used to iterate over all existing elements in the list // Return true in the continuation to break @@ -97,6 +101,21 @@ func (lm listMapper) Push(ctx sdk.Context, value interface{}) { store.Set(lm.LengthKey(), marshalUint64(lm.cdc, length+1)) } +func (lm listMapper) GetMeta(ctx sdk.Context, ptr interface{}) error { + store := ctx.KVStore(lm.key) + bz := store.Get(lm.MetaKey()) + return lm.cdc.UnmarshalBinary(bz, ptr) +} + +func (lm listMapper) SetMeta(ctx sdk.Context, value interface{}) { + store := ctx.KVStore(lm.key) + bz, err := lm.cdc.MarshalBinary(value) + if err != nil { + panic(err) + } + store.Set(lm.MetaKey(), bz) +} + func (lm listMapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { store := ctx.KVStore(lm.key) start, end := subspace([]byte(fmt.Sprintf("%s/elem/", lm.prefix))) @@ -140,6 +159,8 @@ func (lm listMapper) ElemKey(i uint64) []byte { return []byte(fmt.Sprintf("%s/elem/%020d", lm.prefix, i)) } +func (lm listMapper) + // QueueMapper is a Mapper interface that provides queue-like functions // It panics when the element type cannot be (un/)marshalled by the codec From 91767fc6d30549b1876a9e431b7ade7f140be149 Mon Sep 17 00:00:00 2001 From: mossid Date: Wed, 18 Apr 2018 17:55:40 +0200 Subject: [PATCH 072/176] add GenericMapper --- types/lib/{stdlib.go => mapper.go} | 88 ++++++++++---------- types/lib/{stdlib_test.go => mapper_test.go} | 0 2 files changed, 45 insertions(+), 43 deletions(-) rename types/lib/{stdlib.go => mapper.go} (73%) rename types/lib/{stdlib_test.go => mapper_test.go} (100%) diff --git a/types/lib/stdlib.go b/types/lib/mapper.go similarity index 73% rename from types/lib/stdlib.go rename to types/lib/mapper.go index 7f812033b..e168eec2b 100644 --- a/types/lib/stdlib.go +++ b/types/lib/mapper.go @@ -9,6 +9,12 @@ import ( wire "github.com/cosmos/cosmos-sdk/wire" ) +type GenericMapper struct { + key sdk.StoreKey + cdc *wire.Codec + prefix string +} + // ListMapper is a Mapper interface that provides list-like functions // It panics when the element type cannot be (un/)marshalled by the codec @@ -39,23 +45,26 @@ type ListMapper interface { // IterateWrite() is safe to write over the domain IterateWrite(sdk.Context, interface{}, func(sdk.Context, uint64) bool) -} -type listMapper struct { - key sdk.StoreKey - cdc *wire.Codec - prefix string + // Key for the length of the list + LengthKey() []byte + + // Key for getting elements + ElemKey(uint64) []byte + + // Key for additional meta information of the list + MetaKey() []byte } func NewListMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) ListMapper { - return listMapper{ + return GenericMapper{ key: key, cdc: cdc, prefix: prefix, } } -func (lm listMapper) Len(ctx sdk.Context) uint64 { +func (lm GenericMapper) Len(ctx sdk.Context) uint64 { store := ctx.KVStore(lm.key) bz := store.Get(lm.LengthKey()) if bz == nil { @@ -73,13 +82,13 @@ func (lm listMapper) Len(ctx sdk.Context) uint64 { return res } -func (lm listMapper) Get(ctx sdk.Context, index uint64, ptr interface{}) error { +func (lm GenericMapper) Get(ctx sdk.Context, index uint64, ptr interface{}) error { store := ctx.KVStore(lm.key) bz := store.Get(lm.ElemKey(index)) return lm.cdc.UnmarshalBinary(bz, ptr) } -func (lm listMapper) Set(ctx sdk.Context, index uint64, value interface{}) { +func (lm GenericMapper) Set(ctx sdk.Context, index uint64, value interface{}) { store := ctx.KVStore(lm.key) bz, err := lm.cdc.MarshalBinary(value) if err != nil { @@ -88,12 +97,12 @@ func (lm listMapper) Set(ctx sdk.Context, index uint64, value interface{}) { store.Set(lm.ElemKey(index), bz) } -func (lm listMapper) Delete(ctx sdk.Context, index uint64) { +func (lm GenericMapper) Delete(ctx sdk.Context, index uint64) { store := ctx.KVStore(lm.key) store.Delete(lm.ElemKey(index)) } -func (lm listMapper) Push(ctx sdk.Context, value interface{}) { +func (lm GenericMapper) Push(ctx sdk.Context, value interface{}) { length := lm.Len(ctx) lm.Set(ctx, length, value) @@ -101,13 +110,13 @@ func (lm listMapper) Push(ctx sdk.Context, value interface{}) { store.Set(lm.LengthKey(), marshalUint64(lm.cdc, length+1)) } -func (lm listMapper) GetMeta(ctx sdk.Context, ptr interface{}) error { +func (lm GenericMapper) GetMeta(ctx sdk.Context, ptr interface{}) error { store := ctx.KVStore(lm.key) bz := store.Get(lm.MetaKey()) return lm.cdc.UnmarshalBinary(bz, ptr) } -func (lm listMapper) SetMeta(ctx sdk.Context, value interface{}) { +func (lm GenericMapper) SetMeta(ctx sdk.Context, value interface{}) { store := ctx.KVStore(lm.key) bz, err := lm.cdc.MarshalBinary(value) if err != nil { @@ -116,7 +125,7 @@ func (lm listMapper) SetMeta(ctx sdk.Context, value interface{}) { store.Set(lm.MetaKey(), bz) } -func (lm listMapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { +func (lm GenericMapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { store := ctx.KVStore(lm.key) start, end := subspace([]byte(fmt.Sprintf("%s/elem/", lm.prefix))) iter := store.Iterator(start, end) @@ -138,7 +147,7 @@ func (lm listMapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.C iter.Close() } -func (lm listMapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { +func (lm GenericMapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { length := lm.Len(ctx) for i := uint64(0); i < length; i++ { @@ -151,15 +160,17 @@ func (lm listMapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk. } } -func (lm listMapper) LengthKey() []byte { +func (lm GenericMapper) LengthKey() []byte { return []byte(fmt.Sprintf("%s/length", lm.prefix)) } -func (lm listMapper) ElemKey(i uint64) []byte { +func (lm GenericMapper) ElemKey(i uint64) []byte { return []byte(fmt.Sprintf("%s/elem/%020d", lm.prefix, i)) } -func (lm listMapper) +func (lm GenericMapper) MetaKey() []byte { + return []byte(fmt.Sprintf("%s/meta", lm.prefix)) +} // QueueMapper is a Mapper interface that provides queue-like functions // It panics when the element type cannot be (un/)marshalled by the codec @@ -176,25 +187,20 @@ type QueueMapper interface { // The interface{} is unmarshalled before the continuation is called // Starts from the top(head) of the queue Flush(sdk.Context, interface{}, func(sdk.Context) bool) -} -type queueMapper struct { - key sdk.StoreKey - cdc *wire.Codec - prefix string - lm ListMapper + // Key for the index of top element + TopKey() []byte } func NewQueueMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) QueueMapper { - return queueMapper{ + return GenericMapper{ key: key, cdc: cdc, prefix: prefix, - lm: NewListMapper(cdc, key, prefix+"list"), } } -func (qm queueMapper) getTop(store sdk.KVStore) (res uint64) { +func (qm GenericMapper) getTop(store sdk.KVStore) (res uint64) { bz := store.Get(qm.TopKey()) if bz == nil { store.Set(qm.TopKey(), marshalUint64(qm.cdc, 0)) @@ -208,44 +214,40 @@ func (qm queueMapper) getTop(store sdk.KVStore) (res uint64) { return } -func (qm queueMapper) setTop(store sdk.KVStore, top uint64) { +func (qm GenericMapper) setTop(store sdk.KVStore, top uint64) { bz := marshalUint64(qm.cdc, top) store.Set(qm.TopKey(), bz) } -func (qm queueMapper) Push(ctx sdk.Context, value interface{}) { - qm.lm.Push(ctx, value) -} - -func (qm queueMapper) Peek(ctx sdk.Context, ptr interface{}) error { +func (qm GenericMapper) Peek(ctx sdk.Context, ptr interface{}) error { store := ctx.KVStore(qm.key) top := qm.getTop(store) - return qm.lm.Get(ctx, top, ptr) + return qm.Get(ctx, top, ptr) } -func (qm queueMapper) Pop(ctx sdk.Context) { +func (qm GenericMapper) Pop(ctx sdk.Context) { store := ctx.KVStore(qm.key) top := qm.getTop(store) - qm.lm.Delete(ctx, top) + qm.Delete(ctx, top) qm.setTop(store, top+1) } -func (qm queueMapper) IsEmpty(ctx sdk.Context) bool { +func (qm GenericMapper) IsEmpty(ctx sdk.Context) bool { store := ctx.KVStore(qm.key) top := qm.getTop(store) - length := qm.lm.Len(ctx) + length := qm.Len(ctx) return top >= length } -func (qm queueMapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Context) bool) { +func (qm GenericMapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Context) bool) { store := ctx.KVStore(qm.key) top := qm.getTop(store) - length := qm.lm.Len(ctx) + length := qm.Len(ctx) var i uint64 for i = top; i < length; i++ { - qm.lm.Get(ctx, i, ptr) - qm.lm.Delete(ctx, i) + qm.Get(ctx, i, ptr) + qm.Delete(ctx, i) if fn(ctx) { break } @@ -254,7 +256,7 @@ func (qm queueMapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Contex qm.setTop(store, i) } -func (qm queueMapper) TopKey() []byte { +func (qm GenericMapper) TopKey() []byte { return []byte(fmt.Sprintf("%s/top", qm.prefix)) } diff --git a/types/lib/stdlib_test.go b/types/lib/mapper_test.go similarity index 100% rename from types/lib/stdlib_test.go rename to types/lib/mapper_test.go From ad0c776d943f90e8acd52a7367cc992b98c85ef9 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 19 Apr 2018 15:18:31 -0400 Subject: [PATCH 073/176] show_validator now displays HEX by default, declare-candidacy also takes go-amino encoded --- cmd/gaia/cli_test/cli_test.go | 17 ++----- server/tm_cmds.go | 88 ++++++++++++++++------------------- x/stake/commands/tx.go | 39 +++++----------- 3 files changed, 56 insertions(+), 88 deletions(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 0d9a89578..6bda6894b 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -40,8 +40,8 @@ func TestGaiaCLISend(t *testing.T) { executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) executeWrite(t, "gaiacli keys add bar", pass) - fooAddr, _ := executeGetAddr(t, "gaiacli keys show foo --output=json") - barAddr, _ := executeGetAddr(t, "gaiacli keys show bar --output=json") + fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") + barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json") fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) @@ -71,7 +71,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { defer cmd.Process.Kill() executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) - fooAddr, fooPubKey := executeGetAddr(t, "gaiacli keys show foo --output=json") + fooAddr, fooPubKey := executeGetAddrPK(t, "gaiacli keys show foo --output=json") fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) @@ -91,7 +91,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { assert.Equal(t, candidate.Address.String(), fooAddr) assert.Equal(t, int64(3), candidate.Assets.Evaluate()) - // TODO figure out why this times out with connection refused errors in go-bash + // TODO timeout issues if not connected to the internet // unbond a single share unbondStr := fmt.Sprintf("gaiacli unbond %v", flags) unbondStr += fmt.Sprintf(" --name=%v", "foo") @@ -146,19 +146,12 @@ func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { return } -func executeGetAddr(t *testing.T, cmdStr string) (addr, pubKey string) { +func executeGetAddrPK(t *testing.T, cmdStr string) (addr, pubKey string) { out := tests.ExecuteT(t, cmdStr, 2) var info crkeys.Info keys.UnmarshalJSON([]byte(out), &info) pubKey = hex.EncodeToString(info.PubKey.(crypto.PubKeyEd25519).Bytes()) - - // TODO this is really wierd, also error that not 64 characters! - pubKey = strings.TrimLeft(pubKey, "1624de6220") - pubKey = fmt.Sprintf("%064v", pubKey) - - fmt.Printf("debug pubKey: %v\n", pubKey) addr = info.PubKey.Address().String() - fmt.Printf("debug addr: %v\n", addr) return } diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 67504fa6b..dd826ba8c 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -1,9 +1,11 @@ package server import ( + "encoding/hex" "fmt" "github.com/spf13/cobra" + "github.com/spf13/viper" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/p2p" @@ -12,73 +14,63 @@ import ( // ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout func ShowNodeIDCmd(ctx *Context) *cobra.Command { - cmd := showNodeID{ctx} return &cobra.Command{ Use: "show_node_id", Short: "Show this node's ID", - RunE: cmd.run, + RunE: func(cmd *cobra.Command, args []string) error { + cfg := ctx.Config + nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) + if err != nil { + return err + } + fmt.Println(nodeKey.ID()) + return nil + }, } } -type showNodeID struct { - context *Context -} - -func (s showNodeID) run(cmd *cobra.Command, args []string) error { - cfg := s.context.Config - nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) - if err != nil { - return err - } - fmt.Println(nodeKey.ID()) - return nil -} - -//-------------------------------------------------------------------------------- +//________________________________________________________________________________ // ShowValidator - ported from Tendermint, show this node's validator info func ShowValidatorCmd(ctx *Context) *cobra.Command { - cmd := showValidator{ctx} - return &cobra.Command{ + flagJSON := "json" + cmd := cobra.Command{ Use: "show_validator", Short: "Show this node's validator info", - RunE: cmd.run, + RunE: func(cmd *cobra.Command, args []string) error { + + cfg := ctx.Config + privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorFile()) + pubKey := privValidator.PubKey + + if viper.GetBool(flagJSON) { + pubKeyJSONBytes, err := cdc.MarshalJSON(pubKey) + if err != nil { + return err + } + fmt.Println(string(pubKeyJSONBytes)) + return nil + } + pubKeyHex := hex.EncodeToString(pubKey.Bytes()) + fmt.Println(pubKeyHex) + return nil + }, } + cmd.Flags().Bool(flagJSON, false, "get machine parseable output") + return &cmd } -type showValidator struct { - context *Context -} - -func (s showValidator) run(cmd *cobra.Command, args []string) error { - cfg := s.context.Config - privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorFile()) - pubKeyJSONBytes, err := cdc.MarshalJSON(privValidator.PubKey) - if err != nil { - return err - } - fmt.Println(string(pubKeyJSONBytes)) - return nil -} - -//------------------------------------------------------------------------------ +//________________________________________________________________________________ // UnsafeResetAllCmd - extension of the tendermint command, resets initialization func UnsafeResetAllCmd(ctx *Context) *cobra.Command { - cmd := resetAll{ctx} return &cobra.Command{ Use: "unsafe_reset_all", Short: "Reset all blockchain data", - RunE: cmd.run, + RunE: func(cmd *cobra.Command, args []string) error { + cfg := ctx.Config + tcmd.ResetAll(cfg.DBDir(), cfg.PrivValidatorFile(), ctx.Logger) + return nil + }, } } - -type resetAll struct { - context *Context -} - -func (r resetAll) run(cmd *cobra.Command, args []string) error { - cfg := r.context.Config - tcmd.ResetAll(cfg.DBDir(), cfg.PrivValidatorFile(), r.context.Logger) - return nil -} diff --git a/x/stake/commands/tx.go b/x/stake/commands/tx.go index e04a81885..69fedba54 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/commands/tx.go @@ -30,10 +30,20 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { if err != nil { return err } - pk, err := GetPubKey(viper.GetString(FlagPubKey)) + + pkStr := viper.GetString(FlagPubKey) + if len(pkStr) == 0 { + return fmt.Errorf("must use --pubkey flag") + } + pkBytes, err := hex.DecodeString(pkStr) if err != nil { return err } + pk, err := crypto.PubKeyFromBytes(pkBytes) + if err != nil { + return err + } + if viper.GetString(FlagMoniker) == "" { return fmt.Errorf("please enter a moniker for the validator-candidate using --moniker") } @@ -187,30 +197,3 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command { cmd.Flags().AddFlagSet(fsCandidate) return cmd } - -//______________________________________________________________________________________ - -// create the pubkey from a pubkey string -// TODO move to a better reusable place -func GetPubKey(pubKeyStr string) (pk crypto.PubKey, err error) { - - if len(pubKeyStr) == 0 { - err = fmt.Errorf("must use --pubkey flag") - return - } - if len(pubKeyStr) != 64 { //if len(pkBytes) != 32 { - err = fmt.Errorf("pubkey must be Ed25519 hex encoded string which is 64 characters, this pubkey is %v characters", len(pubKeyStr)) - return - } - - // TODO: bech32 ... - var pkBytes []byte - pkBytes, err = hex.DecodeString(pubKeyStr) - if err != nil { - return - } - var pkEd crypto.PubKeyEd25519 - copy(pkEd[:], pkBytes[:]) - pk = pkEd - return -} From bce7bf6e79ed8784390f6798cdebec95b66ca8f5 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 19 Apr 2018 16:33:17 -0400 Subject: [PATCH 074/176] rm a couple comments --- server/tm_cmds.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/tm_cmds.go b/server/tm_cmds.go index dd826ba8c..648e3d80d 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -29,8 +29,6 @@ func ShowNodeIDCmd(ctx *Context) *cobra.Command { } } -//________________________________________________________________________________ - // ShowValidator - ported from Tendermint, show this node's validator info func ShowValidatorCmd(ctx *Context) *cobra.Command { flagJSON := "json" @@ -60,8 +58,6 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command { return &cmd } -//________________________________________________________________________________ - // UnsafeResetAllCmd - extension of the tendermint command, resets initialization func UnsafeResetAllCmd(ctx *Context) *cobra.Command { return &cobra.Command{ From 0ea1bc7918a7ef129e6c9b7264074a8b4044531d Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 19 Apr 2018 21:09:48 -0400 Subject: [PATCH 075/176] add prepend bytes comment to pubkey hex string --- x/stake/commands/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/stake/commands/flags.go b/x/stake/commands/flags.go index e5b97d62c..4bafd9c65 100644 --- a/x/stake/commands/flags.go +++ b/x/stake/commands/flags.go @@ -29,7 +29,7 @@ var ( ) func init() { - fsPk.String(FlagPubKey, "", "PubKey of the validator-candidate") + fsPk.String(FlagPubKey, "", "Go-Amino encoded hex PubKey of the validator-candidate. For Ed25519 the go-amino prepend hex is 1624de6220") fsAmount.String(FlagAmount, "1fermion", "Amount of coins to bond") fsShares.String(FlagShares, "", "Amount of shares to unbond, either in decimal or keyword MAX (ex. 1.23456789, 99, MAX)") fsDescription.String(FlagMoniker, "", "validator-candidate name") From ca3d3be3af0459782934cb99b9b639869c27d876 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 20 Apr 2018 12:51:47 -0400 Subject: [PATCH 076/176] better key output --- CHANGELOG.md | 1 + client/keys/utils.go | 70 +++++++++++++++++++++-------------- cmd/gaia/cli_test/cli_test.go | 11 ++---- server/tm_cmds.go | 3 +- 4 files changed, 48 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26f9d105a..e4c141631 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ FEATURES: * Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond * MountStoreWithDB without providing a custom store works. * Repo is now lint compliant / GoMetaLinter with tendermint-lint integrated into CI +* Better key output, pubkey go-amino hex bytes now output by default BREAKING CHANGES diff --git a/client/keys/utils.go b/client/keys/utils.go index d1b3d3f65..f86389a89 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -1,8 +1,11 @@ package keys import ( + "encoding/hex" + "encoding/json" "fmt" "path/filepath" + "strings" "github.com/spf13/viper" @@ -16,20 +19,10 @@ import ( // KeyDBName is the directory under root where we store the keys const KeyDBName = "keys" -var ( - // keybase is used to make GetKeyBase a singleton - keybase keys.Keybase -) +// keybase is used to make GetKeyBase a singleton +var keybase keys.Keybase -// used for outputting keys.Info over REST -type KeyOutput struct { - Name string `json:"name"` - Address string `json:"address"` - // TODO add pubkey? - // Pubkey string `json:"pubkey"` -} - -// GetKeyBase initializes a keybase based on the configuration +// initialize a keybase based on the configuration func GetKeyBase() (keys.Keybase, error) { if keybase == nil { rootDir := viper.GetString(cli.HomeFlag) @@ -47,36 +40,57 @@ func SetKeyBase(kb keys.Keybase) { keybase = kb } +// used for outputting keys.Info over REST +type KeyOutput struct { + Name string `json:"name"` + Address string `json:"address"` + PubKey string `json:"pub_key"` +} + +func NewKeyOutput(info keys.Info) KeyOutput { + return KeyOutput{ + Name: info.Name, + Address: info.PubKey.Address().String(), + PubKey: strings.ToUpper(hex.EncodeToString(info.PubKey.Bytes())), + } +} + +func NewKeyOutputs(infos []keys.Info) []KeyOutput { + kos := make([]KeyOutput, len(infos)) + for i, info := range infos { + kos[i] = NewKeyOutput(info) + } + return kos +} + func printInfo(info keys.Info) { + ko := NewKeyOutput(info) switch viper.Get(cli.OutputFlag) { case "text": - addr := info.PubKey.Address().String() - sep := "\t\t" - if len(info.Name) > 7 { - sep = "\t" - } - fmt.Printf("%s%s%s\n", info.Name, sep, addr) + fmt.Printf("NAME:\tADDRESS:\t\t\t\t\tPUBKEY:\n") + fmt.Printf("%s\t%s\t%s\n", ko.Name, ko.Address, ko.PubKey) case "json": - json, err := MarshalJSON(info) + out, err := json.MarshalIndent(ko, "", "\t") if err != nil { - panic(err) // really shouldn't happen... + panic(err) } - fmt.Println(string(json)) + fmt.Println(string(out)) } } func printInfos(infos []keys.Info) { + kos := NewKeyOutputs(infos) switch viper.Get(cli.OutputFlag) { case "text": - fmt.Println("All keys:") - for _, i := range infos { - printInfo(i) + fmt.Printf("NAME:\tADDRESS:\t\t\t\t\tPUBKEY:\n") + for _, ko := range kos { + fmt.Printf("%s\t%s\t%s\n", ko.Name, ko.Address, ko.PubKey) } case "json": - json, err := MarshalJSON(infos) + out, err := json.MarshalIndent(kos, "", "\t") if err != nil { - panic(err) // really shouldn't happen... + panic(err) } - fmt.Println(string(json)) + fmt.Println(string(out)) } } diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 6bda6894b..827c7116b 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -1,7 +1,6 @@ package clitest import ( - "encoding/hex" "encoding/json" "fmt" "strings" @@ -17,8 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/tests" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/stake" - crypto "github.com/tendermint/go-crypto" - crkeys "github.com/tendermint/go-crypto/keys" ) func TestGaiaCLISend(t *testing.T) { @@ -148,11 +145,9 @@ func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { func executeGetAddrPK(t *testing.T, cmdStr string) (addr, pubKey string) { out := tests.ExecuteT(t, cmdStr, 2) - var info crkeys.Info - keys.UnmarshalJSON([]byte(out), &info) - pubKey = hex.EncodeToString(info.PubKey.(crypto.PubKeyEd25519).Bytes()) - addr = info.PubKey.Address().String() - return + var ko keys.KeyOutput + keys.UnmarshalJSON([]byte(out), &ko) + return ko.Address, ko.PubKey } func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 648e3d80d..73dca6651 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -3,6 +3,7 @@ package server import ( "encoding/hex" "fmt" + "strings" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -49,7 +50,7 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command { fmt.Println(string(pubKeyJSONBytes)) return nil } - pubKeyHex := hex.EncodeToString(pubKey.Bytes()) + pubKeyHex := strings.ToUpper(hex.EncodeToString(pubKey.Bytes())) fmt.Println(pubKeyHex) return nil }, From 3e7481d00fce7cd13faef6241c0e41e2744d3540 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 20 Apr 2018 13:14:01 -0400 Subject: [PATCH 077/176] updated docs for new key work updated docs for new key work --- client/keys/README.md => docs/old/keys.md | 0 docs/staking/intro.rst | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename client/keys/README.md => docs/old/keys.md (100%) diff --git a/client/keys/README.md b/docs/old/keys.md similarity index 100% rename from client/keys/README.md rename to docs/old/keys.md diff --git a/docs/staking/intro.rst b/docs/staking/intro.rst index 68032c536..961136894 100644 --- a/docs/staking/intro.rst +++ b/docs/staking/intro.rst @@ -56,8 +56,8 @@ which will give you three prompts: create a password and copy in your seed phrase. The name and address of the key will be output: :: - - alice 67997DD03D527EB439B7193F2B813B05B219CC02 + NAME: ADDRESS: PUBKEY: + alice 67997DD03D527EB439B7193F2B813B05B219CC02 1624DE6220BB89786C1D597050438C728202436552C6226AB67453CDB2A4D2703402FB52B6 You can see all available keys with: From 88a11ec0bbc19aa27abbd58c3854f78ac574574b Mon Sep 17 00:00:00 2001 From: mossid Date: Fri, 20 Apr 2018 23:25:43 +0200 Subject: [PATCH 078/176] apply requests --- types/lib/mapper.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/types/lib/mapper.go b/types/lib/mapper.go index e168eec2b..18b3cf5fd 100644 --- a/types/lib/mapper.go +++ b/types/lib/mapper.go @@ -3,7 +3,6 @@ package lib import ( "fmt" "strconv" - "strings" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" @@ -25,24 +24,27 @@ type ListMapper interface { Get(sdk.Context, uint64, interface{}) error - // Setting element out of range is harmful + // Setting element out of range will break length counting // Use Push() instead of Set() to append a new element Set(sdk.Context, uint64, interface{}) + // Other elements' indices are preserved after deletion Delete(sdk.Context, uint64) Push(sdk.Context, interface{}) // Getter/Setter for meta information - can be customized + // Use this space for storing relevant information about the list GetMeta(sdk.Context, interface{}) error SetMeta(sdk.Context, interface{}) // Iterate*() is used to iterate over all existing elements in the list // Return true in the continuation to break - // CONTRACT: No writes may happen within a domain while an iterator exists over it. + // CONTRACT: No writes may happen within a domain while iterating over it. IterateRead(sdk.Context, interface{}, func(sdk.Context, uint64) bool) + // CONTRACT: No deletion may happend whihin a domain while iterating over it. // IterateWrite() is safe to write over the domain IterateWrite(sdk.Context, interface{}, func(sdk.Context, uint64) bool) @@ -134,8 +136,8 @@ func (lm GenericMapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sd if err := lm.cdc.UnmarshalBinary(v, ptr); err != nil { panic(err) } - s := strings.Split(string(iter.Key()), "/") - index, err := strconv.ParseUint(s[len(s)-1], 10, 64) + s := string(iter.Key()[len(lm.prefix)+6:]) + index, err := strconv.ParseUint(s, 10, 64) if err != nil { panic(err) } @@ -182,10 +184,12 @@ type QueueMapper interface { Peek(sdk.Context, interface{}) error Pop(sdk.Context) IsEmpty(sdk.Context) bool - // Iterate() removes elements it processed + + // Flush() removes elements it processed // Return true in the continuation to break // The interface{} is unmarshalled before the continuation is called // Starts from the top(head) of the queue + // CONTRACT: Pop() or Push() should not be performed while flushing Flush(sdk.Context, interface{}, func(sdk.Context) bool) // Key for the index of top element From fbfec1c9cfaa602812055c445263144674d4f453 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Sun, 8 Apr 2018 23:13:49 +0800 Subject: [PATCH 079/176] Start prep for IBC standard for Ethereum community --- docs/spec/ibc/ibc.md | 26 ++++++++++++++++++++------ x/ibc/commands/relay.go | 6 +++--- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/docs/spec/ibc/ibc.md b/docs/spec/ibc/ibc.md index dedbdc301..e3f6090f6 100644 --- a/docs/spec/ibc/ibc.md +++ b/docs/spec/ibc/ibc.md @@ -1,10 +1,17 @@ # IBC Specification -IBC(Inter-Blockchain Communication) protocol is used by multiple zones on Cosmos. Using IBC, the zones can send coins or arbitrary data to other zones. +The IBC (Inter Blockchain Communication) protocol specifies how tokens, +non-fungible assets and complex objects can be moved securely between different +zones (independent blockchains). IBC is conceptually similar to TCP/IP in the +sense that anyone can implement it in order to be able to establish IBC +connections with willing clients. + ## Terms -How IBC module treats incoming IBC packets is simillar with how BaseApp treats incoming transactions. Therefore, the components of IBC module have their corresponding pair in BaseApp. +How IBC module treats incoming IBC packets is similar to how BaseApp treats +incoming transactions. Therefore, the components of IBC module have their +corresponding pair in BaseApp. | BaseApp Terms | IBC Terms | | ------------- | ---------- | @@ -12,20 +19,27 @@ How IBC module treats incoming IBC packets is simillar with how BaseApp treats i | Tx | Packet | | Msg | Payload | + ## MVP Specifications ### [MVP1](./mvp1.md) -MVP1 will contain the basic functionalities, including packet generation and packet receivement. There will be no security check for incoming packets. +MVP1 will contain the basic functionalities, including packet generation and +incoming packet processing. There will be no security check for incoming +packets. ### [MVP2](./mvp2.md) -IBC module will be more modular in MVP2. Indivisual modules can register custom handlers to IBC module. +The IBC module will be more modular in MVP2. Individual modules can register +custom handlers on the IBC module. ### [MVP3](./mvp3.md) -Light client verification is added to verify the message from the other chain. Registering chains with their ROT(Root Of Trust) is needed. +Light client verification is added to verify an IBC packet from another chain. +Registering chains with their RoT(Root of Trust) is added as well. ### [MVP4](./mvp4.md) -ACK verification / timeout handler helper functions and messaging queue are implemented to make it failsafe. Callbacks will be registered to the dispatcher to handle failure when they register handlers. +ACK verification / timeout handler helper functions and messaging queues are +implemented to make it safe. Callbacks will be registered to the dispatcher to +handle failure when they register handlers. diff --git a/x/ibc/commands/relay.go b/x/ibc/commands/relay.go index d772735bb..6e4254926 100644 --- a/x/ibc/commands/relay.go +++ b/x/ibc/commands/relay.go @@ -10,10 +10,8 @@ import ( "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/client/context" - sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" "github.com/cosmos/cosmos-sdk/x/ibc" ) @@ -84,7 +82,9 @@ func (c relayCommander) runIBCRelay(cmd *cobra.Command, args []string) { c.loop(fromChainID, fromChainNode, toChainID, toChainNode) } -func (c relayCommander) loop(fromChainID, fromChainNode, toChainID, toChainNode string) { +func (c relayCommander) loop(fromChainID, fromChainNode, toChainID, + toChainNode string) { + ctx := context.NewCoreContextFromViper() // get password passphrase, err := ctx.GetPassphraseFromStdin(ctx.FromAddressName) From b500cfcf44cf10c940643001beacd0f6413b4836 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 14:47:12 -0700 Subject: [PATCH 080/176] added to Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index daa0361fc..4381eea82 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ PACKAGES=$(shell go list ./... | grep -v '/vendor/') COMMIT_HASH := $(shell git rev-parse --short HEAD) BUILD_FLAGS = -ldflags "-X github.com/cosmos/cosmos-sdk/version.GitCommit=${COMMIT_HASH}" -all: check_tools get_vendor_deps build build_examples test +all: check_tools get_vendor_deps build build_examples install install_examples test ######################################## ### CI From 016a1c8ec9adebc2fbc9dc87fc7c84943001a882 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 23:36:15 -0700 Subject: [PATCH 081/176] removed seal --- cmd/gaia/app/app.go | 2 +- examples/basecoin/app/app.go | 2 +- examples/democoin/app/app.go | 2 +- x/auth/mapper.go | 29 ----------------------------- x/auth/mapper_test.go | 14 -------------- x/stake/test_common.go | 2 +- 6 files changed, 4 insertions(+), 47 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index e780c08bf..fd981a3b5 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -58,7 +58,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { app.cdc, app.keyMain, // target store &auth.BaseAccount{}, // prototype - ).Seal() + ) // add handlers app.coinKeeper = bank.NewKeeper(app.accountMapper) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index e9f5b6e5a..b02f21669 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -61,7 +61,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { cdc, app.capKeyMainStore, // target store &types.AppAccount{}, // prototype - ).Seal() + ) // Add handlers. coinKeeper := bank.NewKeeper(app.accountMapper) diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 290a04d66..b70f51b5c 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -66,7 +66,7 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { cdc, app.capKeyMainStore, // target store &types.AppAccount{}, // prototype - ).Seal() + ) // Add handlers. coinKeeper := bank.NewKeeper(app.accountMapper) diff --git a/x/auth/mapper.go b/x/auth/mapper.go index ed69034be..b815fada7 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -9,7 +9,6 @@ import ( ) var _ sdk.AccountMapper = (*accountMapper)(nil) -var _ sdk.AccountMapper = (*sealedAccountMapper)(nil) // Implements sdk.AccountMapper. // This AccountMapper encodes/decodes accounts using the @@ -37,21 +36,6 @@ func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto sdk.Account) acco } } -// Returns the go-amino codec. You may need to register interfaces -// and concrete types here, if your app's sdk.Account -// implementation includes interface fields. -// NOTE: It is not secure to expose the codec, so check out -// .Seal(). -func (am accountMapper) WireCodec() *wire.Codec { - return am.cdc -} - -// Returns a "sealed" accountMapper. -// The codec is not accessible from a sealedAccountMapper. -func (am accountMapper) Seal() sealedAccountMapper { - return sealedAccountMapper{am} -} - // Implements sdk.AccountMapper. func (am accountMapper) NewAccountWithAddress(ctx sdk.Context, addr sdk.Address) sdk.Account { acc := am.clonePrototype() @@ -78,19 +62,6 @@ func (am accountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { store.Set(addr, bz) } -//---------------------------------------- -// sealedAccountMapper - -type sealedAccountMapper struct { - accountMapper -} - -// There's no way for external modules to mutate the -// sam.accountMapper.cdc from here, even with reflection. -func (sam sealedAccountMapper) WireCodec() *wire.Codec { - panic("accountMapper is sealed") -} - //---------------------------------------- // misc. diff --git a/x/auth/mapper_test.go b/x/auth/mapper_test.go index 030207db2..2912ddde8 100644 --- a/x/auth/mapper_test.go +++ b/x/auth/mapper_test.go @@ -57,17 +57,3 @@ func TestAccountMapperGetSet(t *testing.T) { assert.NotNil(t, acc) assert.Equal(t, newSequence, acc.GetSequence()) } - -func TestAccountMapperSealed(t *testing.T) { - _, capKey := setupMultiStore() - cdc := wire.NewCodec() - RegisterBaseAccount(cdc) - - // normal mapper exposes the wire codec - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - assert.NotNil(t, mapper.WireCodec()) - - // seal mapper, should panic when we try to get the codec - mapperSealed := mapper.Seal() - assert.Panics(t, func() { mapperSealed.WireCodec() }) -} diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 9d7b13e7c..4a36feb95 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -138,7 +138,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context cdc, // amino codec keyMain, // target store &auth.BaseAccount{}, // prototype - ).Seal() + ) ck := bank.NewKeeper(accountMapper) keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace) keeper.setPool(ctx, initialPool()) From b7c6713c5c51938768c349f8c66c75c6bd563891 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 23:40:43 -0700 Subject: [PATCH 082/176] updated Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4c141631..285c7ae8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ BREAKING CHANGES * Many changes to names throughout * Type as a prefix naming convention applied (ex. BondMsg -> MsgBond) * Removed redundancy in names (ex. stake.StakeKeeper -> stake.Keeper) +* Removed SealedAccountMapper BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia From 2672f4a1bbc4a8358dd595b62ccb9c42b5fac12a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Apr 2018 17:30:54 +0200 Subject: [PATCH 083/176] Add delegator bond query API endpoint --- x/stake/rest/query.go | 79 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 x/stake/rest/query.go diff --git a/x/stake/rest/query.go b/x/stake/rest/query.go new file mode 100644 index 000000000..240f68d96 --- /dev/null +++ b/x/stake/rest/query.go @@ -0,0 +1,79 @@ +package rest + +import ( + "encoding/hex" + "fmt" + "net/http" + + "github.com/gorilla/mux" + "github.com/tendermint/go-crypto/keys" + + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/stake" +) + +// RegisterRoutes - Central function to define routes that get registered by the main application +func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { + r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", BondingStatusHandler("stake", cdc, kb)).Methods("GET") +} + +// BondingStatusHandler - http request handler to query delegator bonding status +func BondingStatusHandler(storeName string, cdc *wire.Codec, kb keys.Keybase) func(http.ResponseWriter, *http.Request) { + ctx := context.NewCoreContextFromViper() + return func(w http.ResponseWriter, r *http.Request) { + // read parameters + vars := mux.Vars(r) + delegator := vars["delegator"] + validator := vars["validator"] + + bz, err := hex.DecodeString(delegator) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + delegatorAddr := sdk.Address(bz) + + bz, err = hex.DecodeString(validator) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + candidateAddr := sdk.Address(bz) + + key := stake.GetDelegatorBondKey(delegatorAddr, candidateAddr, cdc) + + res, err := ctx.Query(key, storeName) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("Couldn't query bond. Error: %s", err.Error()))) + return + } + + // the query will return empty if there is no data for this bond + if len(res) == 0 { + w.WriteHeader(http.StatusNoContent) + return + } + + var bond stake.DelegatorBond + err = cdc.UnmarshalBinary(res, &bond) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("Couldn't decode bond. Error: %s", err.Error()))) + return + } + + output, err := cdc.MarshalJSON(bond) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + w.Write(output) + } +} From 91b1ee393ce55550757d546dd3750908553ee37a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Apr 2018 18:17:21 +0200 Subject: [PATCH 084/176] Add ViewSlashKeeper --- x/stake/keeper.go | 2 +- x/stake/view_slash_keeper.go | 29 ++++++++++ x/stake/view_slash_keeper_test.go | 93 +++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 x/stake/view_slash_keeper.go create mode 100644 x/stake/view_slash_keeper_test.go diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 8bfefef84..f1b436314 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -354,7 +354,7 @@ func (k Keeper) clearAccUpdateValidators(ctx sdk.Context) { //_____________________________________________________________________ -// load a delegator bong +// load a delegator bond func (k Keeper) GetDelegatorBond(ctx sdk.Context, delegatorAddr, candidateAddr sdk.Address) (bond DelegatorBond, found bool) { diff --git a/x/stake/view_slash_keeper.go b/x/stake/view_slash_keeper.go new file mode 100644 index 000000000..375c7323b --- /dev/null +++ b/x/stake/view_slash_keeper.go @@ -0,0 +1,29 @@ +package stake + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// keeper to view information & slash validators +// will be used by governance module +type ViewSlashKeeper struct { + keeper Keeper +} + +// NewViewSlashKeeper creates a keeper restricted to +// viewing information & slashing validators +func NewViewSlashKeeper(k Keeper) ViewSlashKeeper { + return ViewSlashKeeper{k} +} + +// load a delegator bond +func (v ViewSlashKeeper) GetDelegatorBond(ctx sdk.Context, + delegatorAddr, candidateAddr sdk.Address) (bond DelegatorBond, found bool) { + return v.keeper.GetDelegatorBond(ctx, delegatorAddr, candidateAddr) +} + +// load n delegator bonds +func (v ViewSlashKeeper) GetDelegatorBonds(ctx sdk.Context, + delegator sdk.Address, maxRetrieve int16) (bonds []DelegatorBond) { + return v.keeper.GetDelegatorBonds(ctx, delegator, maxRetrieve) +} diff --git a/x/stake/view_slash_keeper_test.go b/x/stake/view_slash_keeper_test.go new file mode 100644 index 000000000..2e0e70d3b --- /dev/null +++ b/x/stake/view_slash_keeper_test.go @@ -0,0 +1,93 @@ +package stake + +import ( + "bytes" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// tests GetDelegatorBond, GetDelegatorBonds +func TestViewSlashBond(t *testing.T) { + ctx, _, keeper := createTestInput(t, false, 0) + + //construct the candidates + amts := []int64{9, 8, 7} + var candidates [3]Candidate + for i, amt := range amts { + candidates[i] = Candidate{ + Address: addrVals[i], + PubKey: pks[i], + Assets: sdk.NewRat(amt), + Liabilities: sdk.NewRat(amt), + } + } + + // first add a candidates[0] to delegate too + keeper.setCandidate(ctx, candidates[0]) + + bond1to1 := DelegatorBond{ + DelegatorAddr: addrDels[0], + CandidateAddr: addrVals[0], + Shares: sdk.NewRat(9), + } + + viewSlashKeeper := NewViewSlashKeeper(keeper) + + bondsEqual := func(b1, b2 DelegatorBond) bool { + return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) && + bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) && + b1.Shares == b2.Shares + } + + // check the empty keeper first + _, found := viewSlashKeeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) + assert.False(t, found) + + // set and retrieve a record + keeper.setDelegatorBond(ctx, bond1to1) + resBond, found := viewSlashKeeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) + assert.True(t, found) + assert.True(t, bondsEqual(bond1to1, resBond)) + + // modify a records, save, and retrieve + bond1to1.Shares = sdk.NewRat(99) + keeper.setDelegatorBond(ctx, bond1to1) + resBond, found = viewSlashKeeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) + assert.True(t, found) + assert.True(t, bondsEqual(bond1to1, resBond)) + + // add some more records + keeper.setCandidate(ctx, candidates[1]) + keeper.setCandidate(ctx, candidates[2]) + bond1to2 := DelegatorBond{addrDels[0], addrVals[1], sdk.NewRat(9)} + bond1to3 := DelegatorBond{addrDels[0], addrVals[2], sdk.NewRat(9)} + bond2to1 := DelegatorBond{addrDels[1], addrVals[0], sdk.NewRat(9)} + bond2to2 := DelegatorBond{addrDels[1], addrVals[1], sdk.NewRat(9)} + bond2to3 := DelegatorBond{addrDels[1], addrVals[2], sdk.NewRat(9)} + keeper.setDelegatorBond(ctx, bond1to2) + keeper.setDelegatorBond(ctx, bond1to3) + keeper.setDelegatorBond(ctx, bond2to1) + keeper.setDelegatorBond(ctx, bond2to2) + keeper.setDelegatorBond(ctx, bond2to3) + + // test all bond retrieve capabilities + resBonds := viewSlashKeeper.GetDelegatorBonds(ctx, addrDels[0], 5) + require.Equal(t, 3, len(resBonds)) + assert.True(t, bondsEqual(bond1to1, resBonds[0])) + assert.True(t, bondsEqual(bond1to2, resBonds[1])) + assert.True(t, bondsEqual(bond1to3, resBonds[2])) + resBonds = viewSlashKeeper.GetDelegatorBonds(ctx, addrDels[0], 3) + require.Equal(t, 3, len(resBonds)) + resBonds = viewSlashKeeper.GetDelegatorBonds(ctx, addrDels[0], 2) + require.Equal(t, 2, len(resBonds)) + resBonds = viewSlashKeeper.GetDelegatorBonds(ctx, addrDels[1], 5) + require.Equal(t, 3, len(resBonds)) + assert.True(t, bondsEqual(bond2to1, resBonds[0])) + assert.True(t, bondsEqual(bond2to2, resBonds[1])) + assert.True(t, bondsEqual(bond2to3, resBonds[2])) + +} From 5b1e2a3786df99ad39d98e52143e418042335456 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Apr 2018 18:32:55 +0200 Subject: [PATCH 085/176] Add Height field to DelegatorBond, update appropriately --- x/stake/handler.go | 5 +++++ x/stake/keeper_test.go | 20 +++++++++++++++----- x/stake/types.go | 1 + x/stake/view_slash_keeper_test.go | 11 ++++++----- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index 84eeca3c4..d9f718fe5 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -158,6 +158,9 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, pool, candidate, newShares := pool.candidateAddTokens(candidate, bondAmt.Amount) bond.Shares = bond.Shares.Add(newShares) + // Update bond height + bond.Height = ctx.BlockHeight() + k.setDelegatorBond(ctx, bond) k.setCandidate(ctx, candidate) k.setPool(ctx, pool) @@ -226,6 +229,8 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { k.removeDelegatorBond(ctx, bond) } else { + // Update bond height + bond.Height = ctx.BlockHeight() k.setDelegatorBond(ctx, bond) } diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index c42f7182b..03431a403 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -122,6 +122,7 @@ func TestBond(t *testing.T) { bondsEqual := func(b1, b2 DelegatorBond) bool { return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) && bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) && + b1.Height == b2.Height && b1.Shares == b2.Shares } @@ -142,14 +143,23 @@ func TestBond(t *testing.T) { assert.True(t, found) assert.True(t, bondsEqual(bond1to1, resBond)) + // test height + ctx = ctx.WithBlockHeight(10) + keeper.setDelegatorBond(ctx, bond1to1) + resBond, found = keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) + assert.True(t, found) + assert.Equal(t, resBond.Height, 10) + ctx = ctx.WithBlockHeight(0) + keeper.setDelegatorBond(ctx, bond1to1) + // add some more records keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[2]) - bond1to2 := DelegatorBond{addrDels[0], addrVals[1], sdk.NewRat(9)} - bond1to3 := DelegatorBond{addrDels[0], addrVals[2], sdk.NewRat(9)} - bond2to1 := DelegatorBond{addrDels[1], addrVals[0], sdk.NewRat(9)} - bond2to2 := DelegatorBond{addrDels[1], addrVals[1], sdk.NewRat(9)} - bond2to3 := DelegatorBond{addrDels[1], addrVals[2], sdk.NewRat(9)} + bond1to2 := DelegatorBond{addrDels[0], addrVals[1], sdk.NewRat(9), 0} + bond1to3 := DelegatorBond{addrDels[0], addrVals[2], sdk.NewRat(9), 1} + bond2to1 := DelegatorBond{addrDels[1], addrVals[0], sdk.NewRat(9), 2} + bond2to2 := DelegatorBond{addrDels[1], addrVals[1], sdk.NewRat(9), 3} + bond2to3 := DelegatorBond{addrDels[1], addrVals[2], sdk.NewRat(9), 4} keeper.setDelegatorBond(ctx, bond1to2) keeper.setDelegatorBond(ctx, bond1to3) keeper.setDelegatorBond(ctx, bond2to1) diff --git a/x/stake/types.go b/x/stake/types.go index be48afe3e..8f9e87cbb 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -164,4 +164,5 @@ type DelegatorBond struct { DelegatorAddr sdk.Address `json:"delegator_addr"` CandidateAddr sdk.Address `json:"candidate_addr"` Shares sdk.Rat `json:"shares"` + Height int64 `json:"height"` // Last height bond updated } diff --git a/x/stake/view_slash_keeper_test.go b/x/stake/view_slash_keeper_test.go index 2e0e70d3b..a8b0e1071 100644 --- a/x/stake/view_slash_keeper_test.go +++ b/x/stake/view_slash_keeper_test.go @@ -40,6 +40,7 @@ func TestViewSlashBond(t *testing.T) { bondsEqual := func(b1, b2 DelegatorBond) bool { return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) && bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) && + b1.Height == b2.Height && b1.Shares == b2.Shares } @@ -63,11 +64,11 @@ func TestViewSlashBond(t *testing.T) { // add some more records keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[2]) - bond1to2 := DelegatorBond{addrDels[0], addrVals[1], sdk.NewRat(9)} - bond1to3 := DelegatorBond{addrDels[0], addrVals[2], sdk.NewRat(9)} - bond2to1 := DelegatorBond{addrDels[1], addrVals[0], sdk.NewRat(9)} - bond2to2 := DelegatorBond{addrDels[1], addrVals[1], sdk.NewRat(9)} - bond2to3 := DelegatorBond{addrDels[1], addrVals[2], sdk.NewRat(9)} + bond1to2 := DelegatorBond{addrDels[0], addrVals[1], sdk.NewRat(9), 0} + bond1to3 := DelegatorBond{addrDels[0], addrVals[2], sdk.NewRat(9), 1} + bond2to1 := DelegatorBond{addrDels[1], addrVals[0], sdk.NewRat(9), 2} + bond2to2 := DelegatorBond{addrDels[1], addrVals[1], sdk.NewRat(9), 3} + bond2to3 := DelegatorBond{addrDels[1], addrVals[2], sdk.NewRat(9), 4} keeper.setDelegatorBond(ctx, bond1to2) keeper.setDelegatorBond(ctx, bond1to3) keeper.setDelegatorBond(ctx, bond2to1) From 86b79b9c842a9062cf5da17ccde5f01e482dd305 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Apr 2018 18:41:36 +0200 Subject: [PATCH 086/176] Fix testcases & update changelog --- CHANGELOG.md | 1 + x/stake/handler_test.go | 5 +++++ x/stake/keeper_test.go | 9 --------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4c141631..4de7af20a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ BREAKING CHANGES * Remove go-wire, use go-amino * Gaia simple-staking bond and unbond functions replaced +* [stake] Delegator bonds now store the height at which they were updated * [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface * [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores * All module keepers now require a codespace, see basecoin or democoin for usage diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 538c664e9..1240e4e6c 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -76,7 +76,10 @@ func TestIncrementsMsgDelegate(t *testing.T) { // just send the same msgbond multiple times msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, bondAmount) + for i := 0; i < 5; i++ { + ctx = ctx.WithBlockHeight(int64(i)) + got := handleMsgDelegate(ctx, msgDelegate, keeper) require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) @@ -90,6 +93,8 @@ func TestIncrementsMsgDelegate(t *testing.T) { expLiabilities := int64(i+2) * bondAmount // (1 self delegation) expDelegatorAcc := initBond - expBond + require.Equal(t, bond.Height, int64(i), "Incorrect bond height") + gotBond := bond.Shares.Evaluate() gotLiabilities := candidate.Liabilities.Evaluate() gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 03431a403..e3edfbf9e 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -143,15 +143,6 @@ func TestBond(t *testing.T) { assert.True(t, found) assert.True(t, bondsEqual(bond1to1, resBond)) - // test height - ctx = ctx.WithBlockHeight(10) - keeper.setDelegatorBond(ctx, bond1to1) - resBond, found = keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) - assert.True(t, found) - assert.Equal(t, resBond.Height, 10) - ctx = ctx.WithBlockHeight(0) - keeper.setDelegatorBond(ctx, bond1to1) - // add some more records keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[2]) From 87edaa80d4d55305e11c631982b9edf61eb05e9b Mon Sep 17 00:00:00 2001 From: mossid Date: Wed, 25 Apr 2018 13:44:29 +0200 Subject: [PATCH 087/176] add comments, clarify Iterate() --- types/lib/mapper.go | 71 +++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/types/lib/mapper.go b/types/lib/mapper.go index 18b3cf5fd..428691778 100644 --- a/types/lib/mapper.go +++ b/types/lib/mapper.go @@ -8,7 +8,7 @@ import ( wire "github.com/cosmos/cosmos-sdk/wire" ) -type GenericMapper struct { +type Mapper struct { key sdk.StoreKey cdc *wire.Codec prefix string @@ -29,22 +29,21 @@ type ListMapper interface { Set(sdk.Context, uint64, interface{}) // Other elements' indices are preserved after deletion + // Panics when the index is out of range Delete(sdk.Context, uint64) + // Push will increase the length when it is called + // The other methods does not modify the length Push(sdk.Context, interface{}) - // Getter/Setter for meta information - can be customized - // Use this space for storing relevant information about the list - GetMeta(sdk.Context, interface{}) error - SetMeta(sdk.Context, interface{}) - // Iterate*() is used to iterate over all existing elements in the list // Return true in the continuation to break + // The second element of the continuation will indicate the position of the element + // Using it with Get() will return the same one with the provided element // CONTRACT: No writes may happen within a domain while iterating over it. IterateRead(sdk.Context, interface{}, func(sdk.Context, uint64) bool) - // CONTRACT: No deletion may happend whihin a domain while iterating over it. // IterateWrite() is safe to write over the domain IterateWrite(sdk.Context, interface{}, func(sdk.Context, uint64) bool) @@ -53,20 +52,17 @@ type ListMapper interface { // Key for getting elements ElemKey(uint64) []byte - - // Key for additional meta information of the list - MetaKey() []byte } func NewListMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) ListMapper { - return GenericMapper{ + return Mapper{ key: key, cdc: cdc, prefix: prefix, } } -func (lm GenericMapper) Len(ctx sdk.Context) uint64 { +func (lm Mapper) Len(ctx sdk.Context) uint64 { store := ctx.KVStore(lm.key) bz := store.Get(lm.LengthKey()) if bz == nil { @@ -84,13 +80,13 @@ func (lm GenericMapper) Len(ctx sdk.Context) uint64 { return res } -func (lm GenericMapper) Get(ctx sdk.Context, index uint64, ptr interface{}) error { +func (lm Mapper) Get(ctx sdk.Context, index uint64, ptr interface{}) error { store := ctx.KVStore(lm.key) bz := store.Get(lm.ElemKey(index)) return lm.cdc.UnmarshalBinary(bz, ptr) } -func (lm GenericMapper) Set(ctx sdk.Context, index uint64, value interface{}) { +func (lm Mapper) Set(ctx sdk.Context, index uint64, value interface{}) { store := ctx.KVStore(lm.key) bz, err := lm.cdc.MarshalBinary(value) if err != nil { @@ -99,12 +95,12 @@ func (lm GenericMapper) Set(ctx sdk.Context, index uint64, value interface{}) { store.Set(lm.ElemKey(index), bz) } -func (lm GenericMapper) Delete(ctx sdk.Context, index uint64) { +func (lm Mapper) Delete(ctx sdk.Context, index uint64) { store := ctx.KVStore(lm.key) store.Delete(lm.ElemKey(index)) } -func (lm GenericMapper) Push(ctx sdk.Context, value interface{}) { +func (lm Mapper) Push(ctx sdk.Context, value interface{}) { length := lm.Len(ctx) lm.Set(ctx, length, value) @@ -112,22 +108,7 @@ func (lm GenericMapper) Push(ctx sdk.Context, value interface{}) { store.Set(lm.LengthKey(), marshalUint64(lm.cdc, length+1)) } -func (lm GenericMapper) GetMeta(ctx sdk.Context, ptr interface{}) error { - store := ctx.KVStore(lm.key) - bz := store.Get(lm.MetaKey()) - return lm.cdc.UnmarshalBinary(bz, ptr) -} - -func (lm GenericMapper) SetMeta(ctx sdk.Context, value interface{}) { - store := ctx.KVStore(lm.key) - bz, err := lm.cdc.MarshalBinary(value) - if err != nil { - panic(err) - } - store.Set(lm.MetaKey(), bz) -} - -func (lm GenericMapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { +func (lm Mapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { store := ctx.KVStore(lm.key) start, end := subspace([]byte(fmt.Sprintf("%s/elem/", lm.prefix))) iter := store.Iterator(start, end) @@ -149,7 +130,7 @@ func (lm GenericMapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sd iter.Close() } -func (lm GenericMapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { +func (lm Mapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { length := lm.Len(ctx) for i := uint64(0); i < length; i++ { @@ -162,18 +143,14 @@ func (lm GenericMapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(s } } -func (lm GenericMapper) LengthKey() []byte { +func (lm Mapper) LengthKey() []byte { return []byte(fmt.Sprintf("%s/length", lm.prefix)) } -func (lm GenericMapper) ElemKey(i uint64) []byte { +func (lm Mapper) ElemKey(i uint64) []byte { return []byte(fmt.Sprintf("%s/elem/%020d", lm.prefix, i)) } -func (lm GenericMapper) MetaKey() []byte { - return []byte(fmt.Sprintf("%s/meta", lm.prefix)) -} - // QueueMapper is a Mapper interface that provides queue-like functions // It panics when the element type cannot be (un/)marshalled by the codec @@ -197,14 +174,14 @@ type QueueMapper interface { } func NewQueueMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) QueueMapper { - return GenericMapper{ + return Mapper{ key: key, cdc: cdc, prefix: prefix, } } -func (qm GenericMapper) getTop(store sdk.KVStore) (res uint64) { +func (qm Mapper) getTop(store sdk.KVStore) (res uint64) { bz := store.Get(qm.TopKey()) if bz == nil { store.Set(qm.TopKey(), marshalUint64(qm.cdc, 0)) @@ -218,32 +195,32 @@ func (qm GenericMapper) getTop(store sdk.KVStore) (res uint64) { return } -func (qm GenericMapper) setTop(store sdk.KVStore, top uint64) { +func (qm Mapper) setTop(store sdk.KVStore, top uint64) { bz := marshalUint64(qm.cdc, top) store.Set(qm.TopKey(), bz) } -func (qm GenericMapper) Peek(ctx sdk.Context, ptr interface{}) error { +func (qm Mapper) Peek(ctx sdk.Context, ptr interface{}) error { store := ctx.KVStore(qm.key) top := qm.getTop(store) return qm.Get(ctx, top, ptr) } -func (qm GenericMapper) Pop(ctx sdk.Context) { +func (qm Mapper) Pop(ctx sdk.Context) { store := ctx.KVStore(qm.key) top := qm.getTop(store) qm.Delete(ctx, top) qm.setTop(store, top+1) } -func (qm GenericMapper) IsEmpty(ctx sdk.Context) bool { +func (qm Mapper) IsEmpty(ctx sdk.Context) bool { store := ctx.KVStore(qm.key) top := qm.getTop(store) length := qm.Len(ctx) return top >= length } -func (qm GenericMapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Context) bool) { +func (qm Mapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Context) bool) { store := ctx.KVStore(qm.key) top := qm.getTop(store) length := qm.Len(ctx) @@ -260,7 +237,7 @@ func (qm GenericMapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Cont qm.setTop(store, i) } -func (qm GenericMapper) TopKey() []byte { +func (qm Mapper) TopKey() []byte { return []byte(fmt.Sprintf("%s/top", qm.prefix)) } From 06d47bebedb8bd739ac5952f469040d2185b5959 Mon Sep 17 00:00:00 2001 From: mossid Date: Wed, 25 Apr 2018 14:45:22 +0200 Subject: [PATCH 088/176] add comments for golint --- mock/store.go | 2 +- types/lib/mapper.go | 163 ++++++++++++++++++++++++++------------------ 2 files changed, 97 insertions(+), 68 deletions(-) diff --git a/mock/store.go b/mock/store.go index e518aa26a..329eb250b 100644 --- a/mock/store.go +++ b/mock/store.go @@ -42,7 +42,7 @@ func (ms multiStore) LoadLatestVersion() error { return nil } -func (md multiStore) LoadVersion(ver int64) error { +func (ms multiStore) LoadVersion(ver int64) error { panic("not implemented") } diff --git a/types/lib/mapper.go b/types/lib/mapper.go index 428691778..ca9020077 100644 --- a/types/lib/mapper.go +++ b/types/lib/mapper.go @@ -8,6 +8,7 @@ import ( wire "github.com/cosmos/cosmos-sdk/wire" ) +// Mapper defines a primitive mapper type type Mapper struct { key sdk.StoreKey cdc *wire.Codec @@ -16,24 +17,29 @@ type Mapper struct { // ListMapper is a Mapper interface that provides list-like functions // It panics when the element type cannot be (un/)marshalled by the codec - type ListMapper interface { + + // Len() returns the length of the list + // The length is only increased by Push() and not decreased // ListMapper dosen't check if an index is in bounds // The user should check Len() before doing any actions Len(sdk.Context) uint64 + // Get() returns the element by its index Get(sdk.Context, uint64, interface{}) error + // Set() stores the element to the given position // Setting element out of range will break length counting // Use Push() instead of Set() to append a new element Set(sdk.Context, uint64, interface{}) + // Delete() deletes the element in the given position // Other elements' indices are preserved after deletion // Panics when the index is out of range Delete(sdk.Context, uint64) - // Push will increase the length when it is called - // The other methods does not modify the length + // Push() inserts the element to the end of the list + // It will increase the length when it is called Push(sdk.Context, interface{}) // Iterate*() is used to iterate over all existing elements in the list @@ -54,6 +60,7 @@ type ListMapper interface { ElemKey(uint64) []byte } +// NewListMapper constructs new ListMapper func NewListMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) ListMapper { return Mapper{ key: key, @@ -62,62 +69,68 @@ func NewListMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) ListMapper } } -func (lm Mapper) Len(ctx sdk.Context) uint64 { - store := ctx.KVStore(lm.key) - bz := store.Get(lm.LengthKey()) +// Len implements ListMapper +func (m Mapper) Len(ctx sdk.Context) uint64 { + store := ctx.KVStore(m.key) + bz := store.Get(m.LengthKey()) if bz == nil { - zero, err := lm.cdc.MarshalBinary(0) + zero, err := m.cdc.MarshalBinary(0) if err != nil { panic(err) } - store.Set(lm.LengthKey(), zero) + store.Set(m.LengthKey(), zero) return 0 } var res uint64 - if err := lm.cdc.UnmarshalBinary(bz, &res); err != nil { + if err := m.cdc.UnmarshalBinary(bz, &res); err != nil { panic(err) } return res } -func (lm Mapper) Get(ctx sdk.Context, index uint64, ptr interface{}) error { - store := ctx.KVStore(lm.key) - bz := store.Get(lm.ElemKey(index)) - return lm.cdc.UnmarshalBinary(bz, ptr) +// Get implements ListMapper +func (m Mapper) Get(ctx sdk.Context, index uint64, ptr interface{}) error { + store := ctx.KVStore(m.key) + bz := store.Get(m.ElemKey(index)) + return m.cdc.UnmarshalBinary(bz, ptr) } -func (lm Mapper) Set(ctx sdk.Context, index uint64, value interface{}) { - store := ctx.KVStore(lm.key) - bz, err := lm.cdc.MarshalBinary(value) +// Set implements ListMapper +func (m Mapper) Set(ctx sdk.Context, index uint64, value interface{}) { + store := ctx.KVStore(m.key) + bz, err := m.cdc.MarshalBinary(value) if err != nil { panic(err) } - store.Set(lm.ElemKey(index), bz) + store.Set(m.ElemKey(index), bz) } -func (lm Mapper) Delete(ctx sdk.Context, index uint64) { - store := ctx.KVStore(lm.key) - store.Delete(lm.ElemKey(index)) +// Delete implements ListMapper +func (m Mapper) Delete(ctx sdk.Context, index uint64) { + store := ctx.KVStore(m.key) + store.Delete(m.ElemKey(index)) } -func (lm Mapper) Push(ctx sdk.Context, value interface{}) { - length := lm.Len(ctx) - lm.Set(ctx, length, value) +// Push implements ListMapper +func (m Mapper) Push(ctx sdk.Context, value interface{}) { + length := m.Len(ctx) + m.Set(ctx, length, value) - store := ctx.KVStore(lm.key) - store.Set(lm.LengthKey(), marshalUint64(lm.cdc, length+1)) + store := ctx.KVStore(m.key) + store.Set(m.LengthKey(), marshalUint64(m.cdc, length+1)) } -func (lm Mapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { - store := ctx.KVStore(lm.key) - start, end := subspace([]byte(fmt.Sprintf("%s/elem/", lm.prefix))) +// IterateRead implements ListMapper +func (m Mapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { + store := ctx.KVStore(m.key) + start, end := subspace([]byte(fmt.Sprintf("%s/elem/", m.prefix))) iter := store.Iterator(start, end) for ; iter.Valid(); iter.Next() { v := iter.Value() - if err := lm.cdc.UnmarshalBinary(v, ptr); err != nil { + if err := m.cdc.UnmarshalBinary(v, ptr); err != nil { panic(err) } - s := string(iter.Key()[len(lm.prefix)+6:]) + s := string(iter.Key()[len(m.prefix)+6:]) index, err := strconv.ParseUint(s, 10, 64) if err != nil { panic(err) @@ -130,11 +143,12 @@ func (lm Mapper) IterateRead(ctx sdk.Context, ptr interface{}, fn func(sdk.Conte iter.Close() } -func (lm Mapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { - length := lm.Len(ctx) +// IterateWrite implements ListMapper +func (m Mapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk.Context, uint64) bool) { + length := m.Len(ctx) for i := uint64(0); i < length; i++ { - if err := lm.Get(ctx, i, ptr); err != nil { + if err := m.Get(ctx, i, ptr); err != nil { continue } if fn(ctx, i) { @@ -143,23 +157,32 @@ func (lm Mapper) IterateWrite(ctx sdk.Context, ptr interface{}, fn func(sdk.Cont } } -func (lm Mapper) LengthKey() []byte { - return []byte(fmt.Sprintf("%s/length", lm.prefix)) +// LengthKey implements ListMapper +func (m Mapper) LengthKey() []byte { + return []byte(fmt.Sprintf("%s/length", m.prefix)) } -func (lm Mapper) ElemKey(i uint64) []byte { - return []byte(fmt.Sprintf("%s/elem/%020d", lm.prefix, i)) +// ElemKey implements ListMapper +func (m Mapper) ElemKey(i uint64) []byte { + return []byte(fmt.Sprintf("%s/elem/%020d", m.prefix, i)) } // QueueMapper is a Mapper interface that provides queue-like functions // It panics when the element type cannot be (un/)marshalled by the codec - type QueueMapper interface { + // Push() inserts the elements to the rear of the queue Push(sdk.Context, interface{}) + // Popping/Peeking on an empty queue will cause panic // The user should check IsEmpty() before doing any actions + + // Peek() returns the element at the front of the queue without removing it Peek(sdk.Context, interface{}) error + + // Pop() returns the element at the front of the queue and removes it Pop(sdk.Context) + + // IsEmpty() checks if the queue is empty IsEmpty(sdk.Context) bool // Flush() removes elements it processed @@ -173,6 +196,7 @@ type QueueMapper interface { TopKey() []byte } +// NewQueueMapper constructs new QueueMapper func NewQueueMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) QueueMapper { return Mapper{ key: key, @@ -181,64 +205,69 @@ func NewQueueMapper(cdc *wire.Codec, key sdk.StoreKey, prefix string) QueueMappe } } -func (qm Mapper) getTop(store sdk.KVStore) (res uint64) { - bz := store.Get(qm.TopKey()) +func (m Mapper) getTop(store sdk.KVStore) (res uint64) { + bz := store.Get(m.TopKey()) if bz == nil { - store.Set(qm.TopKey(), marshalUint64(qm.cdc, 0)) + store.Set(m.TopKey(), marshalUint64(m.cdc, 0)) return 0 } - if err := qm.cdc.UnmarshalBinary(bz, &res); err != nil { + if err := m.cdc.UnmarshalBinary(bz, &res); err != nil { panic(err) } return } -func (qm Mapper) setTop(store sdk.KVStore, top uint64) { - bz := marshalUint64(qm.cdc, top) - store.Set(qm.TopKey(), bz) +func (m Mapper) setTop(store sdk.KVStore, top uint64) { + bz := marshalUint64(m.cdc, top) + store.Set(m.TopKey(), bz) } -func (qm Mapper) Peek(ctx sdk.Context, ptr interface{}) error { - store := ctx.KVStore(qm.key) - top := qm.getTop(store) - return qm.Get(ctx, top, ptr) +// Peek implements QueueMapper +func (m Mapper) Peek(ctx sdk.Context, ptr interface{}) error { + store := ctx.KVStore(m.key) + top := m.getTop(store) + return m.Get(ctx, top, ptr) } -func (qm Mapper) Pop(ctx sdk.Context) { - store := ctx.KVStore(qm.key) - top := qm.getTop(store) - qm.Delete(ctx, top) - qm.setTop(store, top+1) +// Pop implements QueueMapper +func (m Mapper) Pop(ctx sdk.Context) { + store := ctx.KVStore(m.key) + top := m.getTop(store) + m.Delete(ctx, top) + m.setTop(store, top+1) } -func (qm Mapper) IsEmpty(ctx sdk.Context) bool { - store := ctx.KVStore(qm.key) - top := qm.getTop(store) - length := qm.Len(ctx) +// IsEmpty implements QueueMapper +func (m Mapper) IsEmpty(ctx sdk.Context) bool { + store := ctx.KVStore(m.key) + top := m.getTop(store) + length := m.Len(ctx) return top >= length } -func (qm Mapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Context) bool) { - store := ctx.KVStore(qm.key) - top := qm.getTop(store) - length := qm.Len(ctx) +// Flush implements QueueMapper +func (m Mapper) Flush(ctx sdk.Context, ptr interface{}, fn func(sdk.Context) bool) { + store := ctx.KVStore(m.key) + top := m.getTop(store) + length := m.Len(ctx) var i uint64 for i = top; i < length; i++ { - qm.Get(ctx, i, ptr) - qm.Delete(ctx, i) + m.Get(ctx, i, ptr) + m.Delete(ctx, i) if fn(ctx) { break } } - qm.setTop(store, i) + m.setTop(store, i) } -func (qm Mapper) TopKey() []byte { - return []byte(fmt.Sprintf("%s/top", qm.prefix)) +// TopKey implements QueueMapper +func (m Mapper) TopKey() []byte { + return []byte(fmt.Sprintf("%s/top", m.prefix)) } func marshalUint64(cdc *wire.Codec, i uint64) []byte { From 56ac948dc6949fc84d66fc92debef2e1bedd4e2e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 25 Apr 2018 16:18:06 +0200 Subject: [PATCH 089/176] REST folder restructure & cleanup --- client/lcd/root.go | 6 +++--- cmd/gaia/cmd/gaiacli/main.go | 8 ++++---- examples/basecoin/cmd/basecli/main.go | 8 ++++---- examples/democoin/cmd/democli/main.go | 12 ++++++------ .../x/cool/{commands => client/cli}/tx.go | 4 ++-- .../x/pow/{commands => client/cli}/tx.go | 4 ++-- x/auth/{commands => client/cli}/account.go | 2 +- x/auth/{ => client}/rest/query.go | 9 +++++---- x/bank/{commands => client/cli}/sendtx.go | 16 ++++------------ x/bank/{ => client}/rest/sendtx.go | 11 ++++++----- x/bank/client/util.go | 14 ++++++++++++++ x/ibc/{commands => client/cli}/README.md | 0 x/ibc/{commands => client/cli}/ibctx.go | 4 ++-- x/ibc/{commands => client/cli}/relay.go | 4 ++-- x/ibc/{ => client}/rest/transfer.go | 7 ++++--- .../{commands => client/cli}/commands.go | 4 ++-- x/stake/{commands => client/cli}/flags.go | 2 +- x/stake/{commands => client/cli}/query.go | 2 +- x/stake/{commands => client/cli}/tx.go | 4 ++-- x/stake/{ => client}/rest/query.go | 7 ++++--- 20 files changed, 69 insertions(+), 59 deletions(-) rename examples/democoin/x/cool/{commands => client/cli}/tx.go (96%) rename examples/democoin/x/pow/{commands => client/cli}/tx.go (95%) rename x/auth/{commands => client/cli}/account.go (99%) rename x/auth/{ => client}/rest/query.go (90%) rename x/bank/{commands => client/cli}/sendtx.go (77%) rename x/bank/{ => client}/rest/sendtx.go (90%) create mode 100644 x/bank/client/util.go rename x/ibc/{commands => client/cli}/README.md (100%) rename x/ibc/{commands => client/cli}/ibctx.go (96%) rename x/ibc/{commands => client/cli}/relay.go (98%) rename x/ibc/{ => client}/rest/transfer.go (93%) rename x/simplestake/{commands => client/cli}/commands.go (96%) rename x/stake/{commands => client/cli}/flags.go (98%) rename x/stake/{commands => client/cli}/query.go (99%) rename x/stake/{commands => client/cli}/tx.go (98%) rename x/stake/{ => client}/rest/query.go (93%) diff --git a/client/lcd/root.go b/client/lcd/root.go index 81eca333e..a607504cd 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -18,9 +18,9 @@ import ( tx "github.com/cosmos/cosmos-sdk/client/tx" version "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/wire" - auth "github.com/cosmos/cosmos-sdk/x/auth/rest" - bank "github.com/cosmos/cosmos-sdk/x/bank/rest" - ibc "github.com/cosmos/cosmos-sdk/x/ibc/rest" + auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" + bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" + ibc "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" ) const ( diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index 45818b36b..8efb9f4dd 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -13,10 +13,10 @@ import ( "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/version" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" - bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" - ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands" - stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" + ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" ) diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 6271adcec..c2a6145aa 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -14,10 +14,10 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/version" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" - bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" - ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands" - simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" + ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/client/cli" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" diff --git a/examples/democoin/cmd/democli/main.go b/examples/democoin/cmd/democli/main.go index 2b71db710..534b88ca2 100644 --- a/examples/democoin/cmd/democli/main.go +++ b/examples/democoin/cmd/democli/main.go @@ -14,15 +14,15 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/version" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" - bankcmd "github.com/cosmos/cosmos-sdk/x/bank/commands" - ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/commands" - simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" + ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/client/cli" "github.com/cosmos/cosmos-sdk/examples/democoin/app" "github.com/cosmos/cosmos-sdk/examples/democoin/types" - coolcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool/commands" - powcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow/commands" + coolcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool/client/cli" + powcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow/client/cli" ) // rootCmd is the entry point for this binary diff --git a/examples/democoin/x/cool/commands/tx.go b/examples/democoin/x/cool/client/cli/tx.go similarity index 96% rename from examples/democoin/x/cool/commands/tx.go rename to examples/democoin/x/cool/client/cli/tx.go index 90f31d283..9abcfd630 100644 --- a/examples/democoin/x/cool/commands/tx.go +++ b/examples/democoin/x/cool/client/cli/tx.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "fmt" @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/wire" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" ) diff --git a/examples/democoin/x/pow/commands/tx.go b/examples/democoin/x/pow/client/cli/tx.go similarity index 95% rename from examples/democoin/x/pow/commands/tx.go rename to examples/democoin/x/pow/client/cli/tx.go index 017047d08..62ee4db69 100644 --- a/examples/democoin/x/pow/commands/tx.go +++ b/examples/democoin/x/pow/client/cli/tx.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "fmt" @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow" "github.com/cosmos/cosmos-sdk/wire" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" ) // command to mine some pow! diff --git a/x/auth/commands/account.go b/x/auth/client/cli/account.go similarity index 99% rename from x/auth/commands/account.go rename to x/auth/client/cli/account.go index 4da601df8..c6c8c6c54 100644 --- a/x/auth/commands/account.go +++ b/x/auth/client/cli/account.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "encoding/hex" diff --git a/x/auth/rest/query.go b/x/auth/client/rest/query.go similarity index 90% rename from x/auth/rest/query.go rename to x/auth/client/rest/query.go index b97f883f9..e16884fc6 100644 --- a/x/auth/rest/query.go +++ b/x/auth/client/rest/query.go @@ -10,20 +10,21 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - auth "github.com/cosmos/cosmos-sdk/x/auth/commands" + auth "github.com/cosmos/cosmos-sdk/x/auth/client/cli" ) // register REST routes func RegisterRoutes(r *mux.Router, cdc *wire.Codec, storeName string) { + ctx := context.NewCoreContextFromViper() + r.HandleFunc( "/accounts/{address}", - QueryAccountRequestHandler(storeName, cdc, auth.GetAccountDecoder(cdc)), + QueryAccountRequestHandler(storeName, cdc, auth.GetAccountDecoder(cdc), ctx), ).Methods("GET") } // query accountREST Handler -func QueryAccountRequestHandler(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder) func(http.ResponseWriter, *http.Request) { - ctx := context.NewCoreContextFromViper() +func QueryAccountRequestHandler(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) addr := vars["address"] diff --git a/x/bank/commands/sendtx.go b/x/bank/client/cli/sendtx.go similarity index 77% rename from x/bank/commands/sendtx.go rename to x/bank/client/cli/sendtx.go index dbf2bb3c9..910984288 100644 --- a/x/bank/commands/sendtx.go +++ b/x/bank/client/cli/sendtx.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "encoding/hex" @@ -10,8 +10,8 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" - "github.com/cosmos/cosmos-sdk/x/bank" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + "github.com/cosmos/cosmos-sdk/x/bank/client" ) const ( @@ -48,7 +48,7 @@ func SendTxCmd(cdc *wire.Codec) *cobra.Command { } // build and sign the transaction, then broadcast to Tendermint - msg := BuildMsg(from, to, coins) + msg := client.BuildMsg(from, to, coins) res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err @@ -62,11 +62,3 @@ func SendTxCmd(cdc *wire.Codec) *cobra.Command { cmd.Flags().String(flagAmount, "", "Amount of coins to send") return cmd } - -// build the sendTx msg -func BuildMsg(from sdk.Address, to sdk.Address, coins sdk.Coins) sdk.Msg { - input := bank.NewInput(from, coins) - output := bank.NewOutput(to, coins) - msg := bank.NewMsgSend([]bank.Input{input}, []bank.Output{output}) - return msg -} diff --git a/x/bank/rest/sendtx.go b/x/bank/client/rest/sendtx.go similarity index 90% rename from x/bank/rest/sendtx.go rename to x/bank/client/rest/sendtx.go index eec487a3d..83b62d03d 100644 --- a/x/bank/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -12,12 +12,14 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/bank/commands" + "github.com/cosmos/cosmos-sdk/x/bank/client" ) // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - r.HandleFunc("/accounts/{address}/send", SendRequestHandler(cdc, kb)).Methods("POST") + ctx := context.NewCoreContextFromViper() + + r.HandleFunc("/accounts/{address}/send", SendRequestHandler(cdc, kb, ctx)).Methods("POST") } type sendBody struct { @@ -31,8 +33,7 @@ type sendBody struct { } // SendRequestHandler - http request handler to send coins to a address -func SendRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.ResponseWriter, *http.Request) { - ctx := context.NewCoreContextFromViper() +func SendRequestHandler(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { // collect data vars := mux.Vars(r) @@ -68,7 +69,7 @@ func SendRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.ResponseWrit to := sdk.Address(bz) // build message - msg := commands.BuildMsg(info.PubKey.Address(), to, m.Amount) + msg := client.BuildMsg(info.PubKey.Address(), to, m.Amount) if err != nil { // XXX rechecking same error ? w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) diff --git a/x/bank/client/util.go b/x/bank/client/util.go new file mode 100644 index 000000000..4d461b34f --- /dev/null +++ b/x/bank/client/util.go @@ -0,0 +1,14 @@ +package client + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + bank "github.com/cosmos/cosmos-sdk/x/bank" +) + +// build the sendTx msg +func BuildMsg(from sdk.Address, to sdk.Address, coins sdk.Coins) sdk.Msg { + input := bank.NewInput(from, coins) + output := bank.NewOutput(to, coins) + msg := bank.NewMsgSend([]bank.Input{input}, []bank.Output{output}) + return msg +} diff --git a/x/ibc/commands/README.md b/x/ibc/client/cli/README.md similarity index 100% rename from x/ibc/commands/README.md rename to x/ibc/client/cli/README.md diff --git a/x/ibc/commands/ibctx.go b/x/ibc/client/cli/ibctx.go similarity index 96% rename from x/ibc/commands/ibctx.go rename to x/ibc/client/cli/ibctx.go index 1fc53b7e6..906758dd7 100644 --- a/x/ibc/commands/ibctx.go +++ b/x/ibc/client/cli/ibctx.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "encoding/hex" @@ -13,7 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc" ) diff --git a/x/ibc/commands/relay.go b/x/ibc/client/cli/relay.go similarity index 98% rename from x/ibc/commands/relay.go rename to x/ibc/client/cli/relay.go index 6e4254926..86e8b1dbf 100644 --- a/x/ibc/commands/relay.go +++ b/x/ibc/client/cli/relay.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "os" @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc" ) diff --git a/x/ibc/rest/transfer.go b/x/ibc/client/rest/transfer.go similarity index 93% rename from x/ibc/rest/transfer.go rename to x/ibc/client/rest/transfer.go index c0f70b517..9e567df01 100644 --- a/x/ibc/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -16,7 +16,9 @@ import ( // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - r.HandleFunc("/ibc/{destchain}/{address}/send", TransferRequestHandler(cdc, kb)).Methods("POST") + ctx := context.NewCoreContextFromViper() + + r.HandleFunc("/ibc/{destchain}/{address}/send", TransferRequestHandler(cdc, kb, ctx)).Methods("POST") } type transferBody struct { @@ -30,8 +32,7 @@ type transferBody struct { // TransferRequestHandler - http request handler to transfer coins to a address // on a different chain via IBC -func TransferRequestHandler(cdc *wire.Codec, kb keys.Keybase) func(http.ResponseWriter, *http.Request) { - ctx := context.NewCoreContextFromViper() +func TransferRequestHandler(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { // collect data vars := mux.Vars(r) diff --git a/x/simplestake/commands/commands.go b/x/simplestake/client/cli/commands.go similarity index 96% rename from x/simplestake/commands/commands.go rename to x/simplestake/client/cli/commands.go index 78144fdac..54ef73ac4 100644 --- a/x/simplestake/commands/commands.go +++ b/x/simplestake/client/cli/commands.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "encoding/hex" @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/simplestake" ) diff --git a/x/stake/commands/flags.go b/x/stake/client/cli/flags.go similarity index 98% rename from x/stake/commands/flags.go rename to x/stake/client/cli/flags.go index 4bafd9c65..bf8246b34 100644 --- a/x/stake/commands/flags.go +++ b/x/stake/client/cli/flags.go @@ -1,4 +1,4 @@ -package commands +package cli import ( flag "github.com/spf13/pflag" diff --git a/x/stake/commands/query.go b/x/stake/client/cli/query.go similarity index 99% rename from x/stake/commands/query.go rename to x/stake/client/cli/query.go index 3bc2cffa7..145333e48 100644 --- a/x/stake/commands/query.go +++ b/x/stake/client/cli/query.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "encoding/hex" diff --git a/x/stake/commands/tx.go b/x/stake/client/cli/tx.go similarity index 98% rename from x/stake/commands/tx.go rename to x/stake/client/cli/tx.go index 69fedba54..188dba867 100644 --- a/x/stake/commands/tx.go +++ b/x/stake/client/cli/tx.go @@ -1,4 +1,4 @@ -package commands +package cli import ( "encoding/hex" @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/commands" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/stake" ) diff --git a/x/stake/rest/query.go b/x/stake/client/rest/query.go similarity index 93% rename from x/stake/rest/query.go rename to x/stake/client/rest/query.go index 240f68d96..0e148345b 100644 --- a/x/stake/rest/query.go +++ b/x/stake/client/rest/query.go @@ -16,12 +16,13 @@ import ( // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", BondingStatusHandler("stake", cdc, kb)).Methods("GET") + ctx := context.NewCoreContextFromViper() + + r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", BondingStatusHandler("stake", cdc, kb, ctx)).Methods("GET") } // BondingStatusHandler - http request handler to query delegator bonding status -func BondingStatusHandler(storeName string, cdc *wire.Codec, kb keys.Keybase) func(http.ResponseWriter, *http.Request) { - ctx := context.NewCoreContextFromViper() +func BondingStatusHandler(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { // read parameters vars := mux.Vars(r) From 228bc4add9147c26b8f42232c941f6f9dde4e3c2 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 25 Apr 2018 16:19:21 +0200 Subject: [PATCH 090/176] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37dbedf37..076129dbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ FEATURES: BREAKING CHANGES * Remove go-wire, use go-amino +* Move module REST/CLI packages to x/[module]/client/rest and x/[module]/client/cli * Gaia simple-staking bond and unbond functions replaced * [stake] Delegator bonds now store the height at which they were updated * [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface From fd40d39556da9c4e702a6654aa64cb5df3a6b73a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 25 Apr 2018 16:49:31 +0200 Subject: [PATCH 091/176] Only one CoreContext for all REST commands --- client/lcd/root.go | 13 +++--- client/rpc/block.go | 79 ++++++++++++++++++----------------- client/rpc/root.go | 15 +++---- client/rpc/status.go | 64 +++++++++++++++------------- client/rpc/validators.go | 76 +++++++++++++++++---------------- client/tx/broadcast.go | 36 ++++++++-------- client/tx/query.go | 10 ++--- client/tx/root.go | 5 ++- client/tx/search.go | 10 ++--- x/auth/client/rest/query.go | 4 +- x/bank/client/rest/sendtx.go | 4 +- x/ibc/client/rest/transfer.go | 4 +- x/stake/client/rest/query.go | 4 +- 13 files changed, 167 insertions(+), 157 deletions(-) diff --git a/client/lcd/root.go b/client/lcd/root.go index a607504cd..b166d4ce4 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -13,6 +13,7 @@ import ( cmn "github.com/tendermint/tmlibs/common" client "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" keys "github.com/cosmos/cosmos-sdk/client/keys" rpc "github.com/cosmos/cosmos-sdk/client/rpc" tx "github.com/cosmos/cosmos-sdk/client/tx" @@ -73,12 +74,14 @@ func createHandler(cdc *wire.Codec) http.Handler { panic(err) } + ctx := context.NewCoreContextFromViper() + // TODO make more functional? aka r = keys.RegisterRoutes(r) keys.RegisterRoutes(r) - rpc.RegisterRoutes(r) - tx.RegisterRoutes(r, cdc) - auth.RegisterRoutes(r, cdc, "main") - bank.RegisterRoutes(r, cdc, kb) - ibc.RegisterRoutes(r, cdc, kb) + rpc.RegisterRoutes(ctx, r) + tx.RegisterRoutes(ctx, r, cdc) + auth.RegisterRoutes(ctx, r, cdc, "main") + bank.RegisterRoutes(ctx, r, cdc, kb) + ibc.RegisterRoutes(ctx, r, cdc, kb) return r } diff --git a/client/rpc/block.go b/client/rpc/block.go index 200dc668e..46f6cdbd8 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -29,9 +29,8 @@ func blockCommand() *cobra.Command { return cmd } -func getBlock(height *int64) ([]byte, error) { +func getBlock(ctx context.CoreContext, height *int64) ([]byte, error) { // get the node - ctx := context.NewCoreContextFromViper() node, err := ctx.GetNode() if err != nil { return nil, err @@ -56,8 +55,8 @@ func getBlock(height *int64) ([]byte, error) { } // get the current blockchain height -func GetChainHeight() (int64, error) { - node, err := context.NewCoreContextFromViper().GetNode() +func GetChainHeight(ctx context.CoreContext) (int64, error) { + node, err := ctx.GetNode() if err != nil { return -1, err } @@ -85,7 +84,7 @@ func printBlock(cmd *cobra.Command, args []string) error { } } - output, err := getBlock(height) + output, err := getBlock(context.NewCoreContextFromViper(), height) if err != nil { return err } @@ -96,42 +95,46 @@ func printBlock(cmd *cobra.Command, args []string) error { // REST // REST handler to get a block -func BlockRequestHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - height, err := strconv.ParseInt(vars["height"], 10, 64) - if err != nil { - w.WriteHeader(400) - w.Write([]byte("ERROR: Couldn't parse block height. Assumed format is '/block/{height}'.")) - return +func BlockRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + height, err := strconv.ParseInt(vars["height"], 10, 64) + if err != nil { + w.WriteHeader(400) + w.Write([]byte("ERROR: Couldn't parse block height. Assumed format is '/block/{height}'.")) + return + } + chainHeight, err := GetChainHeight(ctx) + if height > chainHeight { + w.WriteHeader(404) + w.Write([]byte("ERROR: Requested block height is bigger then the chain length.")) + return + } + output, err := getBlock(ctx, &height) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + w.Write(output) } - chainHeight, err := GetChainHeight() - if height > chainHeight { - w.WriteHeader(404) - w.Write([]byte("ERROR: Requested block height is bigger then the chain length.")) - return - } - output, err := getBlock(&height) - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return - } - w.Write(output) } // REST handler to get the latest block -func LatestBlockRequestHandler(w http.ResponseWriter, r *http.Request) { - height, err := GetChainHeight() - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return +func LatestBlockRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + height, err := GetChainHeight(ctx) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + output, err := getBlock(ctx, &height) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + w.Write(output) } - output, err := getBlock(&height) - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return - } - w.Write(output) } diff --git a/client/rpc/root.go b/client/rpc/root.go index 43e9097f0..81be7ddf4 100644 --- a/client/rpc/root.go +++ b/client/rpc/root.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" ) const ( @@ -45,11 +46,11 @@ func initClientCommand() *cobra.Command { } // Register REST endpoints -func RegisterRoutes(r *mux.Router) { - r.HandleFunc("/node_info", NodeInfoRequestHandler).Methods("GET") - r.HandleFunc("/syncing", NodeSyncingRequestHandler).Methods("GET") - r.HandleFunc("/blocks/latest", LatestBlockRequestHandler).Methods("GET") - r.HandleFunc("/blocks/{height}", BlockRequestHandler).Methods("GET") - r.HandleFunc("/validatorsets/latest", LatestValidatorSetRequestHandler).Methods("GET") - r.HandleFunc("/validatorsets/{height}", ValidatorSetRequestHandler).Methods("GET") +func RegisterRoutes(ctx context.CoreContext, r *mux.Router) { + r.HandleFunc("/node_info", NodeInfoRequestHandler(ctx)).Methods("GET") + r.HandleFunc("/syncing", NodeSyncingRequestHandler(ctx)).Methods("GET") + r.HandleFunc("/blocks/latest", LatestBlockRequestHandler(ctx)).Methods("GET") + r.HandleFunc("/blocks/{height}", BlockRequestHandler(ctx)).Methods("GET") + r.HandleFunc("/validatorsets/latest", LatestValidatorSetRequestHandler(ctx)).Methods("GET") + r.HandleFunc("/validatorsets/{height}", ValidatorSetRequestHandler(ctx)).Methods("GET") } diff --git a/client/rpc/status.go b/client/rpc/status.go index 3b143d9c5..919fea4ce 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -22,9 +22,9 @@ func statusCommand() *cobra.Command { return cmd } -func getNodeStatus() (*ctypes.ResultStatus, error) { +func getNodeStatus(ctx context.CoreContext) (*ctypes.ResultStatus, error) { // get the node - node, err := context.NewCoreContextFromViper().GetNode() + node, err := ctx.GetNode() if err != nil { return &ctypes.ResultStatus{}, err } @@ -34,7 +34,7 @@ func getNodeStatus() (*ctypes.ResultStatus, error) { // CMD func printNodeStatus(cmd *cobra.Command, args []string) error { - status, err := getNodeStatus() + status, err := getNodeStatus(context.NewCoreContextFromViper()) if err != nil { return err } @@ -52,38 +52,42 @@ func printNodeStatus(cmd *cobra.Command, args []string) error { // REST // REST handler for node info -func NodeInfoRequestHandler(w http.ResponseWriter, r *http.Request) { - status, err := getNodeStatus() - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return - } +func NodeInfoRequestHandler(ctx context.CoreContext) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + status, err := getNodeStatus(ctx) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } - nodeInfo := status.NodeInfo - output, err := cdc.MarshalJSON(nodeInfo) - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return + nodeInfo := status.NodeInfo + output, err := cdc.MarshalJSON(nodeInfo) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + w.Write(output) } - w.Write(output) } // REST handler for node syncing -func NodeSyncingRequestHandler(w http.ResponseWriter, r *http.Request) { - status, err := getNodeStatus() - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return - } +func NodeSyncingRequestHandler(ctx context.CoreContext) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + status, err := getNodeStatus(ctx) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } - syncing := status.SyncInfo.Syncing - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return + syncing := status.SyncInfo.Syncing + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + w.Write([]byte(strconv.FormatBool(syncing))) } - w.Write([]byte(strconv.FormatBool(syncing))) } diff --git a/client/rpc/validators.go b/client/rpc/validators.go index 6937e4a89..768cad7bc 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -26,9 +26,9 @@ func validatorCommand() *cobra.Command { return cmd } -func getValidators(height *int64) ([]byte, error) { +func getValidators(ctx context.CoreContext, height *int64) ([]byte, error) { // get the node - node, err := context.NewCoreContextFromViper().GetNode() + node, err := ctx.GetNode() if err != nil { return nil, err } @@ -61,7 +61,7 @@ func printValidators(cmd *cobra.Command, args []string) error { } } - output, err := getValidators(height) + output, err := getValidators(context.NewCoreContextFromViper(), height) if err != nil { return err } @@ -73,42 +73,46 @@ func printValidators(cmd *cobra.Command, args []string) error { // REST // Validator Set at a height REST handler -func ValidatorSetRequestHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - height, err := strconv.ParseInt(vars["height"], 10, 64) - if err != nil { - w.WriteHeader(400) - w.Write([]byte("ERROR: Couldn't parse block height. Assumed format is '/validatorsets/{height}'.")) - return +func ValidatorSetRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + height, err := strconv.ParseInt(vars["height"], 10, 64) + if err != nil { + w.WriteHeader(400) + w.Write([]byte("ERROR: Couldn't parse block height. Assumed format is '/validatorsets/{height}'.")) + return + } + chainHeight, err := GetChainHeight(ctx) + if height > chainHeight { + w.WriteHeader(404) + w.Write([]byte("ERROR: Requested block height is bigger then the chain length.")) + return + } + output, err := getValidators(ctx, &height) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + w.Write(output) } - chainHeight, err := GetChainHeight() - if height > chainHeight { - w.WriteHeader(404) - w.Write([]byte("ERROR: Requested block height is bigger then the chain length.")) - return - } - output, err := getValidators(&height) - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return - } - w.Write(output) } // Latest Validator Set REST handler -func LatestValidatorSetRequestHandler(w http.ResponseWriter, r *http.Request) { - height, err := GetChainHeight() - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return +func LatestValidatorSetRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + height, err := GetChainHeight(ctx) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + output, err := getValidators(ctx, &height) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + w.Write(output) } - output, err := getValidators(&height) - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return - } - w.Write(output) } diff --git a/client/tx/broadcast.go b/client/tx/broadcast.go index 9e9eaae70..d325ff15b 100644 --- a/client/tx/broadcast.go +++ b/client/tx/broadcast.go @@ -13,23 +13,25 @@ type BroadcastTxBody struct { } // BroadcastTx REST Handler -func BroadcastTxRequestHandler(w http.ResponseWriter, r *http.Request) { - var m BroadcastTxBody +func BroadcastTxRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + var m BroadcastTxBody - decoder := json.NewDecoder(r.Body) - err := decoder.Decode(&m) - if err != nil { - w.WriteHeader(400) - w.Write([]byte(err.Error())) - return + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&m) + if err != nil { + w.WriteHeader(400) + w.Write([]byte(err.Error())) + return + } + + res, err := ctx.BroadcastTx([]byte(m.TxBytes)) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + + w.Write([]byte(string(res.Height))) } - - res, err := context.NewCoreContextFromViper().BroadcastTx([]byte(m.TxBytes)) - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return - } - - w.Write([]byte(string(res.Height))) } diff --git a/client/tx/query.go b/client/tx/query.go index cc252bacc..2c53622e1 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -34,7 +34,7 @@ func QueryTxCmd(cdc *wire.Codec) *cobra.Command { hashHexStr := args[0] trustNode := viper.GetBool(client.FlagTrustNode) - output, err := queryTx(cdc, hashHexStr, trustNode) + output, err := queryTx(context.NewCoreContextFromViper(), cdc, hashHexStr, trustNode) if err != nil { return err } @@ -51,14 +51,14 @@ func QueryTxCmd(cdc *wire.Codec) *cobra.Command { return cmd } -func queryTx(cdc *wire.Codec, hashHexStr string, trustNode bool) ([]byte, error) { +func queryTx(ctx context.CoreContext, cdc *wire.Codec, hashHexStr string, trustNode bool) ([]byte, error) { hash, err := hex.DecodeString(hashHexStr) if err != nil { return nil, err } // get the node - node, err := context.NewCoreContextFromViper().GetNode() + node, err := ctx.GetNode() if err != nil { return nil, err } @@ -109,7 +109,7 @@ func parseTx(cdc *wire.Codec, txBytes []byte) (sdk.Tx, error) { // REST // transaction query REST handler -func QueryTxRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Request) { +func QueryTxRequestHandler(cdc *wire.Codec, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hashHexStr := vars["hash"] @@ -119,7 +119,7 @@ func QueryTxRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Requ trustNode = true } - output, err := queryTx(cdc, hashHexStr, trustNode) + output, err := queryTx(ctx, cdc, hashHexStr, trustNode) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) diff --git a/client/tx/root.go b/client/tx/root.go index 2a87113b3..caae53620 100644 --- a/client/tx/root.go +++ b/client/tx/root.go @@ -4,6 +4,7 @@ import ( "github.com/gorilla/mux" "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/wire" ) @@ -16,8 +17,8 @@ func AddCommands(cmd *cobra.Command, cdc *wire.Codec) { } // register REST routes -func RegisterRoutes(r *mux.Router, cdc *wire.Codec) { - r.HandleFunc("/txs/{hash}", QueryTxRequestHandler(cdc)).Methods("GET") +func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec) { + r.HandleFunc("/txs/{hash}", QueryTxRequestHandler(cdc, ctx)).Methods("GET") // r.HandleFunc("/txs", SearchTxRequestHandler(cdc)).Methods("GET") // r.HandleFunc("/txs/sign", SignTxRequstHandler).Methods("POST") // r.HandleFunc("/txs/broadcast", BroadcastTxRequestHandler).Methods("POST") diff --git a/client/tx/search.go b/client/tx/search.go index 1687d3bbd..29b330a30 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -29,7 +29,7 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { tags := viper.GetStringSlice(flagTags) - output, err := searchTx(cdc, tags) + output, err := searchTx(context.NewCoreContextFromViper(), cdc, tags) if err != nil { return err } @@ -47,7 +47,7 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command { return cmd } -func searchTx(cdc *wire.Codec, tags []string) ([]byte, error) { +func searchTx(ctx context.CoreContext, cdc *wire.Codec, tags []string) ([]byte, error) { if len(tags) == 0 { return nil, errors.New("Must declare at least one tag to search") } @@ -55,7 +55,7 @@ func searchTx(cdc *wire.Codec, tags []string) ([]byte, error) { query := strings.Join(tags, " AND ") // get the node - node, err := context.NewCoreContextFromViper().GetNode() + node, err := ctx.GetNode() if err != nil { return nil, err } @@ -94,7 +94,7 @@ func formatTxResults(cdc *wire.Codec, res []*ctypes.ResultTx) ([]txInfo, error) // REST // Search Tx REST Handler -func SearchTxRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Request) { +func SearchTxRequestHandler(ctx context.CoreContext, cdc *wire.Codec) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { tag := r.FormValue("tag") if tag == "" { @@ -104,7 +104,7 @@ func SearchTxRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Req } tags := []string{tag} - output, err := searchTx(cdc, tags) + output, err := searchTx(ctx, cdc, tags) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index e16884fc6..fd51789c1 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -14,9 +14,7 @@ import ( ) // register REST routes -func RegisterRoutes(r *mux.Router, cdc *wire.Codec, storeName string) { - ctx := context.NewCoreContextFromViper() - +func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, storeName string) { r.HandleFunc( "/accounts/{address}", QueryAccountRequestHandler(storeName, cdc, auth.GetAccountDecoder(cdc), ctx), diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index 83b62d03d..15256ce09 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -16,9 +16,7 @@ import ( ) // RegisterRoutes - Central function to define routes that get registered by the main application -func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - ctx := context.NewCoreContextFromViper() - +func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { r.HandleFunc("/accounts/{address}/send", SendRequestHandler(cdc, kb, ctx)).Methods("POST") } diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index 9e567df01..033ef6be5 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -15,9 +15,7 @@ import ( ) // RegisterRoutes - Central function to define routes that get registered by the main application -func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - ctx := context.NewCoreContextFromViper() - +func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { r.HandleFunc("/ibc/{destchain}/{address}/send", TransferRequestHandler(cdc, kb, ctx)).Methods("POST") } diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 0e148345b..96bdcc95d 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -15,9 +15,7 @@ import ( ) // RegisterRoutes - Central function to define routes that get registered by the main application -func RegisterRoutes(r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - ctx := context.NewCoreContextFromViper() - +func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", BondingStatusHandler("stake", cdc, kb, ctx)).Methods("GET") } From 5b4fb85f7ecd0f382eeff58daabbacd99900bcec Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 25 Apr 2018 22:32:22 +0200 Subject: [PATCH 092/176] Fn suffix & http.HandlerFunc --- client/rpc/block.go | 4 ++-- client/rpc/root.go | 12 ++++++------ client/rpc/status.go | 4 ++-- client/rpc/validators.go | 4 ++-- client/tx/broadcast.go | 2 +- client/tx/query.go | 8 ++++---- client/tx/root.go | 2 +- client/tx/search.go | 2 +- x/auth/client/rest/query.go | 4 ++-- x/bank/client/rest/sendtx.go | 6 +++--- x/ibc/client/rest/transfer.go | 4 ++-- x/stake/client/rest/query.go | 6 +++--- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/client/rpc/block.go b/client/rpc/block.go index 46f6cdbd8..12c65fa70 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -95,7 +95,7 @@ func printBlock(cmd *cobra.Command, args []string) error { // REST // REST handler to get a block -func BlockRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +func BlockRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) height, err := strconv.ParseInt(vars["height"], 10, 64) @@ -121,7 +121,7 @@ func BlockRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *htt } // REST handler to get the latest block -func LatestBlockRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +func LatestBlockRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { height, err := GetChainHeight(ctx) if err != nil { diff --git a/client/rpc/root.go b/client/rpc/root.go index 81be7ddf4..f779bd729 100644 --- a/client/rpc/root.go +++ b/client/rpc/root.go @@ -47,10 +47,10 @@ func initClientCommand() *cobra.Command { // Register REST endpoints func RegisterRoutes(ctx context.CoreContext, r *mux.Router) { - r.HandleFunc("/node_info", NodeInfoRequestHandler(ctx)).Methods("GET") - r.HandleFunc("/syncing", NodeSyncingRequestHandler(ctx)).Methods("GET") - r.HandleFunc("/blocks/latest", LatestBlockRequestHandler(ctx)).Methods("GET") - r.HandleFunc("/blocks/{height}", BlockRequestHandler(ctx)).Methods("GET") - r.HandleFunc("/validatorsets/latest", LatestValidatorSetRequestHandler(ctx)).Methods("GET") - r.HandleFunc("/validatorsets/{height}", ValidatorSetRequestHandler(ctx)).Methods("GET") + r.HandleFunc("/node_info", NodeInfoRequestHandlerFn(ctx)).Methods("GET") + r.HandleFunc("/syncing", NodeSyncingRequestHandlerFn(ctx)).Methods("GET") + r.HandleFunc("/blocks/latest", LatestBlockRequestHandlerFn(ctx)).Methods("GET") + r.HandleFunc("/blocks/{height}", BlockRequestHandlerFn(ctx)).Methods("GET") + r.HandleFunc("/validatorsets/latest", LatestValidatorSetRequestHandlerFn(ctx)).Methods("GET") + r.HandleFunc("/validatorsets/{height}", ValidatorSetRequestHandlerFn(ctx)).Methods("GET") } diff --git a/client/rpc/status.go b/client/rpc/status.go index 919fea4ce..70d6628e4 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -52,7 +52,7 @@ func printNodeStatus(cmd *cobra.Command, args []string) error { // REST // REST handler for node info -func NodeInfoRequestHandler(ctx context.CoreContext) func(w http.ResponseWriter, r *http.Request) { +func NodeInfoRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { status, err := getNodeStatus(ctx) if err != nil { @@ -73,7 +73,7 @@ func NodeInfoRequestHandler(ctx context.CoreContext) func(w http.ResponseWriter, } // REST handler for node syncing -func NodeSyncingRequestHandler(ctx context.CoreContext) func(w http.ResponseWriter, r *http.Request) { +func NodeSyncingRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { status, err := getNodeStatus(ctx) if err != nil { diff --git a/client/rpc/validators.go b/client/rpc/validators.go index 768cad7bc..f9b1f6f8f 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -73,7 +73,7 @@ func printValidators(cmd *cobra.Command, args []string) error { // REST // Validator Set at a height REST handler -func ValidatorSetRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +func ValidatorSetRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) height, err := strconv.ParseInt(vars["height"], 10, 64) @@ -99,7 +99,7 @@ func ValidatorSetRequestHandler(ctx context.CoreContext) func(http.ResponseWrite } // Latest Validator Set REST handler -func LatestValidatorSetRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +func LatestValidatorSetRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { height, err := GetChainHeight(ctx) if err != nil { diff --git a/client/tx/broadcast.go b/client/tx/broadcast.go index d325ff15b..7f55e97d7 100644 --- a/client/tx/broadcast.go +++ b/client/tx/broadcast.go @@ -13,7 +13,7 @@ type BroadcastTxBody struct { } // BroadcastTx REST Handler -func BroadcastTxRequestHandler(ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +func BroadcastTxRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var m BroadcastTxBody diff --git a/client/tx/query.go b/client/tx/query.go index 2c53622e1..0583f94f5 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -34,7 +34,7 @@ func QueryTxCmd(cdc *wire.Codec) *cobra.Command { hashHexStr := args[0] trustNode := viper.GetBool(client.FlagTrustNode) - output, err := queryTx(context.NewCoreContextFromViper(), cdc, hashHexStr, trustNode) + output, err := queryTx(cdc, context.NewCoreContextFromViper(), hashHexStr, trustNode) if err != nil { return err } @@ -51,7 +51,7 @@ func QueryTxCmd(cdc *wire.Codec) *cobra.Command { return cmd } -func queryTx(ctx context.CoreContext, cdc *wire.Codec, hashHexStr string, trustNode bool) ([]byte, error) { +func queryTx(cdc *wire.Codec, ctx context.CoreContext, hashHexStr string, trustNode bool) ([]byte, error) { hash, err := hex.DecodeString(hashHexStr) if err != nil { return nil, err @@ -109,7 +109,7 @@ func parseTx(cdc *wire.Codec, txBytes []byte) (sdk.Tx, error) { // REST // transaction query REST handler -func QueryTxRequestHandler(cdc *wire.Codec, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +func QueryTxRequestHandlerFn(cdc *wire.Codec, ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) hashHexStr := vars["hash"] @@ -119,7 +119,7 @@ func QueryTxRequestHandler(cdc *wire.Codec, ctx context.CoreContext) func(http.R trustNode = true } - output, err := queryTx(ctx, cdc, hashHexStr, trustNode) + output, err := queryTx(cdc, ctx, hashHexStr, trustNode) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) diff --git a/client/tx/root.go b/client/tx/root.go index caae53620..e8abf3318 100644 --- a/client/tx/root.go +++ b/client/tx/root.go @@ -18,7 +18,7 @@ func AddCommands(cmd *cobra.Command, cdc *wire.Codec) { // register REST routes func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec) { - r.HandleFunc("/txs/{hash}", QueryTxRequestHandler(cdc, ctx)).Methods("GET") + r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cdc, ctx)).Methods("GET") // r.HandleFunc("/txs", SearchTxRequestHandler(cdc)).Methods("GET") // r.HandleFunc("/txs/sign", SignTxRequstHandler).Methods("POST") // r.HandleFunc("/txs/broadcast", BroadcastTxRequestHandler).Methods("POST") diff --git a/client/tx/search.go b/client/tx/search.go index 29b330a30..3e3b1daa6 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -94,7 +94,7 @@ func formatTxResults(cdc *wire.Codec, res []*ctypes.ResultTx) ([]txInfo, error) // REST // Search Tx REST Handler -func SearchTxRequestHandler(ctx context.CoreContext, cdc *wire.Codec) func(http.ResponseWriter, *http.Request) { +func SearchTxRequestHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { tag := r.FormValue("tag") if tag == "" { diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index fd51789c1..52244fec9 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -17,12 +17,12 @@ import ( func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, storeName string) { r.HandleFunc( "/accounts/{address}", - QueryAccountRequestHandler(storeName, cdc, auth.GetAccountDecoder(cdc), ctx), + QueryAccountRequestHandlerFn(storeName, cdc, auth.GetAccountDecoder(cdc), ctx), ).Methods("GET") } // query accountREST Handler -func QueryAccountRequestHandler(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder, ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) addr := vars["address"] diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index 15256ce09..6ce472b6f 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -17,7 +17,7 @@ import ( // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - r.HandleFunc("/accounts/{address}/send", SendRequestHandler(cdc, kb, ctx)).Methods("POST") + r.HandleFunc("/accounts/{address}/send", SendRequestHandlerFn(cdc, kb, ctx)).Methods("POST") } type sendBody struct { @@ -30,8 +30,8 @@ type sendBody struct { Sequence int64 `json:"sequence"` } -// SendRequestHandler - http request handler to send coins to a address -func SendRequestHandler(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +// SendRequestHandlerFn - http request handler to send coins to a address +func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // collect data vars := mux.Vars(r) diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index 033ef6be5..48a29ee80 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -16,7 +16,7 @@ import ( // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - r.HandleFunc("/ibc/{destchain}/{address}/send", TransferRequestHandler(cdc, kb, ctx)).Methods("POST") + r.HandleFunc("/ibc/{destchain}/{address}/send", TransferRequestHandlerFn(cdc, kb, ctx)).Methods("POST") } type transferBody struct { @@ -30,7 +30,7 @@ type transferBody struct { // TransferRequestHandler - http request handler to transfer coins to a address // on a different chain via IBC -func TransferRequestHandler(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // collect data vars := mux.Vars(r) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 96bdcc95d..8eb0e03ce 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -16,11 +16,11 @@ import ( // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { - r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", BondingStatusHandler("stake", cdc, kb, ctx)).Methods("GET") + r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", BondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET") } -// BondingStatusHandler - http request handler to query delegator bonding status -func BondingStatusHandler(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) func(http.ResponseWriter, *http.Request) { +// BondingStatusHandlerFn - http request handler to query delegator bonding status +func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // read parameters vars := mux.Vars(r) From f3fffcb7a27574b58c62ba1e7a2ef09ddffc878d Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 20 Apr 2018 17:42:56 -0400 Subject: [PATCH 093/176] more versatile init --- server/init.go | 88 +++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/server/init.go b/server/init.go index a68566cdf..c432149be 100644 --- a/server/init.go +++ b/server/init.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/spf13/cobra" + "github.com/spf13/pflag" "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/words" @@ -19,28 +20,15 @@ import ( dbm "github.com/tendermint/tmlibs/db" ) -// testnetInformation contains the info necessary -// to setup a testnet including this account and validator. -type testnetInformation struct { - Secret string `json:"secret"` - - ChainID string `json:"chain_id"` - Account string `json:"account"` - Validator tmtypes.GenesisValidator `json:"validator"` - NodeID p2p.ID `json:"node_id"` -} - type initCmd struct { genAppState GenAppState context *Context } -// InitCmd will initialize all files for tendermint, -// along with proper app_state. -// The application can pass in a function to generate -// proper state. And may want to use GenerateCoinKey -// to create default account(s). -func InitCmd(gen GenAppState, ctx *Context) *cobra.Command { +// InitCmd will initialize all files for tendermint, along with proper +// app_state. The application can pass in a function to generate proper state. +// And may want to use GenerateCoinKey to create default account(s). +func InitCmd(gen GenAppState, fs pflag.FlagSet, ctx *Context) *cobra.Command { cmd := initCmd{ genAppState: gen, context: ctx, @@ -50,12 +38,23 @@ func InitCmd(gen GenAppState, ctx *Context) *cobra.Command { Short: "Initialize genesis files", RunE: cmd.run, } + cobraCmd.Flags().AddFlagSet(fs) return &cobraCmd } +// defaultPrint contains the info necessary +// to setup a testnet including this account and validator. +type defaultPrint struct { + Secret string `json:"secret"` + ChainID string `json:"chain_id"` + Account string `json:"account"` + Validator tmtypes.GenesisValidator `json:"validator"` + NodeID string `json:"node_id"` +} + func (c initCmd) run(cmd *cobra.Command, args []string) error { // Store testnet information as we go - var testnetInfo testnetInformation + var testnetInfo defaultPrint // Run the basic tendermint initialization, // set up a default genesis with no app_options @@ -71,15 +70,13 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error { } // generate secret and address - addr, secret, err := GenerateCoinKey() - if err != nil { - return err - } - - var defaultDenom = "mycoin" + //addr, secret, err := GenerateCoinKey() + //if err != nil { + //return err + //} // Now, we want to add the custom app_state - appState, err := c.genAppState(args, addr, defaultDenom) + appState, err := c.genAppState() if err != nil { return err } @@ -98,6 +95,8 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error { return err } testnetInfo.NodeID = nodeKey.ID() + + // print the output out, err := wire.MarshalJSONIndent(cdc, testnetInfo) if err != nil { return err @@ -108,7 +107,7 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error { // This was copied from tendermint/cmd/tendermint/commands/init.go // so we could pass in the config and the logger. -func (c initCmd) initTendermintFiles(config *cfg.Config, info *testnetInformation) error { +func (c initCmd) initTendermintFiles(config *cfg.Config, info *defaultPrint) error { // private validator privValFile := config.PrivValidatorFile() var privValidator *pvm.FilePV @@ -157,28 +156,31 @@ func (c initCmd) initTendermintFiles(config *cfg.Config, info *testnetInformatio //------------------------------------------------------------------- -// GenAppState takes the command line args, as well -// as an address and coin denomination. -// It returns a default app_state to be included in -// in the genesis file. -// This is application-specific -type GenAppState func(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) +// GenAppState takes the command line args, as well as an address and coin +// denomination. It returns a default app_state to be included in in the +// genesis file. This is application-specific +type GenAppState func() (json.RawMessage, error) -// DefaultGenAppState expects two args: an account address -// and a coin denomination, and gives lots of coins to that address. -func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) { - opts := fmt.Sprintf(`{ +// Create one account with a whole bunch of mycoin in it +func DefaultGenAppState(args []string) (json.RawMessage, error) { + + addr, secret, err := GenerateCoinKey() + if err != nil { + return err + } + + genesisState := fmt.Sprintf(`{ "accounts": [{ "address": "%s", "coins": [ { - "denom": "%s", + "denom": "mycoin", "amount": 9007199254740992 } ] }] - }`, addr.String(), coinDenom) - return json.RawMessage(opts), nil + }`, addr.String()) + return json.RawMessage(genesisState), nil } //------------------------------------------------------------------- @@ -209,12 +211,10 @@ func addGenesisState(filename string, appState json.RawMessage) error { return ioutil.WriteFile(filename, out, 0600) } -//------------------------------------------------------------------- +//_____________________________________________________________________ -// GenerateCoinKey returns the address of a public key, -// along with the secret phrase to recover the private key. -// You can give coins to this address and return the recovery -// phrase to the user to access them. +// GenerateCoinKey returns the address of a public key, along with the secret +// phrase to recover the private key. func GenerateCoinKey() (sdk.Address, string, error) { // construct an in-memory key store codec, err := words.LoadCodec("english") From 6748aa7bc6a4b1f6162e30af6f50d8f564e9108a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 20 Apr 2018 19:55:22 -0400 Subject: [PATCH 094/176] first stab init refactor --- cmd/gaia/app/app.go | 31 +++-- cmd/gaia/cmd/gaiad/main.go | 2 +- mock/app.go | 24 ++-- server/init.go | 251 ++++++++++++++----------------------- server/test_helpers.go | 2 +- server/util.go | 2 +- 6 files changed, 140 insertions(+), 172 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index fd981a3b5..6819b67b2 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -2,13 +2,17 @@ package app import ( "encoding/json" + "fmt" abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + tmtypes "github.com/tendermint/tendermint/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" bam "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" @@ -177,9 +181,24 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { } } -// DefaultGenAppState expects two args: an account address +// GaiaGenAppState expects two args: an account address // and a coin denomination, and gives lots of coins to that address. -func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) { +func GaiaGenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage, err error) { + + var addr sdk.Address + var secret string + addr, secret, err = server.GenerateCoinKey() + if err != nil { + return + } + fmt.Printf("secret recovery key:\n%s\n", secret) + + chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) + + validators = []tmtypes.GenesisValidator{{ + PubKey: pubKey, + Power: 10, + }} accAuth := auth.NewBaseAccountWithAddress(addr) accAuth.Coins = sdk.Coins{{"fermion", 100000}} @@ -191,10 +210,6 @@ func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json StakeData: stake.GetDefaultGenesisState(), } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - if err != nil { - return nil, err - } - - return stateBytes, nil + appState, err = json.MarshalIndent(genesisState, "", "\t") + return } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 199a06152..63485433f 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -36,7 +36,7 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { } func main() { - server.AddCommands(rootCmd, app.DefaultGenAppState, generateApp, context) + server.AddCommands(rootCmd, app.GaiaGenAppState, generateApp, context) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.gaiad") diff --git a/mock/app.go b/mock/app.go index 631cc3c31..462c5564f 100644 --- a/mock/app.go +++ b/mock/app.go @@ -6,6 +6,9 @@ import ( "path/filepath" abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + tmtypes "github.com/tendermint/tendermint/types" + cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -103,11 +106,18 @@ func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci } } -// GenInitOptions can be passed into InitCmd, -// returns a static string of a few key-values that can be parsed -// by InitChainer -func GenInitOptions(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) { - opts := []byte(`{ +// GenAppState can be passed into InitCmd, returns a static string of a few +// key-values that can be parsed by InitChainer +func GenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage, err error) { + + chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) + + validators = []tmtypes.GenesisValidator{{ + PubKey: pubKey, + Power: 10, + }} + + appState = json.RawMessage(fmt.Sprintf(`{ "values": [ { "key": "hello", @@ -118,6 +128,6 @@ func GenInitOptions(args []string, addr sdk.Address, coinDenom string) (json.Raw "value": "bar" } ] -}`) - return opts, nil +}`)) + return } diff --git a/server/init.go b/server/init.go index c432149be..7669e5bc5 100644 --- a/server/init.go +++ b/server/init.go @@ -8,8 +8,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/spf13/cobra" - "github.com/spf13/pflag" + crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" "github.com/tendermint/go-crypto/keys/words" cfg "github.com/tendermint/tendermint/config" @@ -20,183 +20,91 @@ import ( dbm "github.com/tendermint/tmlibs/db" ) -type initCmd struct { - genAppState GenAppState - context *Context -} - -// InitCmd will initialize all files for tendermint, along with proper -// app_state. The application can pass in a function to generate proper state. -// And may want to use GenerateCoinKey to create default account(s). -func InitCmd(gen GenAppState, fs pflag.FlagSet, ctx *Context) *cobra.Command { - cmd := initCmd{ - genAppState: gen, - context: ctx, - } +// get cmd to initialize all files for tendermint and application +func InitCmd(gen GenAppParams, ctx *Context) *cobra.Command { cobraCmd := cobra.Command{ Use: "init", Short: "Initialize genesis files", - RunE: cmd.run, + RunE: func(cmd *cobra.Command, args []string) error { + + config := ctx.Config + pubkey := ReadOrCreatePrivValidator(config) + + chainID, validators, appState, err := gen(pubkey) + if err != nil { + return err + } + + err = CreateGenesisFile(config, chainID, validators, appState) + if err != nil { + return err + } + + nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) + if err != nil { + return err + } + + // print out some key information + toPrint := struct { + ChainID string `json:"chain_id"` + NodeID string `json:"node_id"` + }{ + chainID, + string(nodeKey.ID()), + } + out, err := wire.MarshalJSONIndent(cdc, toPrint) + if err != nil { + return err + } + fmt.Println(string(out)) + return nil + }, } - cobraCmd.Flags().AddFlagSet(fs) return &cobraCmd } -// defaultPrint contains the info necessary -// to setup a testnet including this account and validator. -type defaultPrint struct { - Secret string `json:"secret"` - ChainID string `json:"chain_id"` - Account string `json:"account"` - Validator tmtypes.GenesisValidator `json:"validator"` - NodeID string `json:"node_id"` -} - -func (c initCmd) run(cmd *cobra.Command, args []string) error { - // Store testnet information as we go - var testnetInfo defaultPrint - - // Run the basic tendermint initialization, - // set up a default genesis with no app_options - config := c.context.Config - err := c.initTendermintFiles(config, &testnetInfo) - if err != nil { - return err - } - - // no app_options, leave like tendermint - if c.genAppState == nil { - return nil - } - - // generate secret and address - //addr, secret, err := GenerateCoinKey() - //if err != nil { - //return err - //} - - // Now, we want to add the custom app_state - appState, err := c.genAppState() - if err != nil { - return err - } - - testnetInfo.Secret = secret - testnetInfo.Account = addr.String() - - // And add them to the genesis file - genFile := config.GenesisFile() - if err := addGenesisState(genFile, appState); err != nil { - return err - } - - nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) - if err != nil { - return err - } - testnetInfo.NodeID = nodeKey.ID() - - // print the output - out, err := wire.MarshalJSONIndent(cdc, testnetInfo) - if err != nil { - return err - } - fmt.Println(string(out)) - return nil -} - -// This was copied from tendermint/cmd/tendermint/commands/init.go -// so we could pass in the config and the logger. -func (c initCmd) initTendermintFiles(config *cfg.Config, info *defaultPrint) error { +// read of create the private key file for this config +func ReadOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { // private validator - privValFile := config.PrivValidatorFile() + privValFile := tmConfig.PrivValidatorFile() var privValidator *pvm.FilePV if cmn.FileExists(privValFile) { privValidator = pvm.LoadFilePV(privValFile) - c.context.Logger.Info("Found private validator", "path", privValFile) } else { privValidator = pvm.GenFilePV(privValFile) privValidator.Save() - c.context.Logger.Info("Generated private validator", "path", privValFile) } + return privValidator.GetPubKey() +} - // genesis file - genFile := config.GenesisFile() +// create the genesis file +func CreateGenesisFile(tmConfig *cfg.Config, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { + genFile := tmConfig.GenesisFile() if cmn.FileExists(genFile) { - c.context.Logger.Info("Found genesis file", "path", genFile) - } else { - genDoc := tmtypes.GenesisDoc{ - ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), - } - genDoc.Validators = []tmtypes.GenesisValidator{{ - PubKey: privValidator.GetPubKey(), - Power: 10, - }} - - if err := genDoc.SaveAs(genFile); err != nil { - return err - } - c.context.Logger.Info("Generated genesis file", "path", genFile) + return fmt.Errorf("genesis config file already exists: %v", genFile) } - - // reload the config file and find our validator info - loadedDoc, err := tmtypes.GenesisDocFromFile(genFile) - if err != nil { + genDoc := tmtypes.GenesisDoc{ + ChainID: chainID, + Validators: validators, + } + if err := genDoc.ValidateAndComplete(); err != nil { return err } - for _, validator := range loadedDoc.Validators { - if validator.PubKey == privValidator.GetPubKey() { - info.Validator = validator - } + if err := genDoc.SaveAs(genFile); err != nil { + return err } - info.ChainID = loadedDoc.ChainID - - return nil + return addAppStateToGenesis(genFile, appState) } -//------------------------------------------------------------------- - -// GenAppState takes the command line args, as well as an address and coin -// denomination. It returns a default app_state to be included in in the -// genesis file. This is application-specific -type GenAppState func() (json.RawMessage, error) - -// Create one account with a whole bunch of mycoin in it -func DefaultGenAppState(args []string) (json.RawMessage, error) { - - addr, secret, err := GenerateCoinKey() +// Add one line to the genesis file +func addAppStateToGenesis(genesisConfigPath string, appState json.RawMessage) error { + bz, err := ioutil.ReadFile(genesisConfigPath) if err != nil { return err } - genesisState := fmt.Sprintf(`{ - "accounts": [{ - "address": "%s", - "coins": [ - { - "denom": "mycoin", - "amount": 9007199254740992 - } - ] - }] - }`, addr.String()) - return json.RawMessage(genesisState), nil -} - -//------------------------------------------------------------------- - -// GenesisDoc involves some tendermint-specific structures we don't -// want to parse, so we just grab it into a raw object format, -// so we can add one line. -type GenesisDoc map[string]json.RawMessage - -func addGenesisState(filename string, appState json.RawMessage) error { - bz, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - - var doc GenesisDoc + var doc map[string]json.RawMessage err = cdc.UnmarshalJSON(bz, &doc) if err != nil { return err @@ -207,15 +115,51 @@ func addGenesisState(filename string, appState json.RawMessage) error { if err != nil { return err } - - return ioutil.WriteFile(filename, out, 0600) + return ioutil.WriteFile(genesisConfigPath, out, 0600) } //_____________________________________________________________________ +// GenAppParams creates the core parameters initialization. It takes in a +// pubkey meant to represent the pubkey of the validator of this machine. +type GenAppParams func(crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage, err error) + +// Create one account with a whole bunch of mycoin in it +func SimpleGenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage, err error) { + + var addr sdk.Address + var secret string + addr, secret, err = GenerateCoinKey() + if err != nil { + return + } + fmt.Printf("secret recovery key:\n%s\n", secret) + + chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) + + validators = []tmtypes.GenesisValidator{{ + PubKey: pubKey, + Power: 10, + }} + + appState = json.RawMessage(fmt.Sprintf(`{ + "accounts": [{ + "address": "%s", + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + }] +}`, addr.String())) + return +} + // GenerateCoinKey returns the address of a public key, along with the secret // phrase to recover the private key. func GenerateCoinKey() (sdk.Address, string, error) { + // construct an in-memory key store codec, err := words.LoadCodec("english") if err != nil { @@ -231,7 +175,6 @@ func GenerateCoinKey() (sdk.Address, string, error) { if err != nil { return nil, "", err } - addr := info.PubKey.Address() return addr, secret, nil } diff --git a/server/test_helpers.go b/server/test_helpers.go index f226ba1b1..01a093f47 100644 --- a/server/test_helpers.go +++ b/server/test_helpers.go @@ -50,7 +50,7 @@ func StartServer(t *testing.T) chan error { // init server ctx := NewContext(cfg, log.NewNopLogger()) - initCmd := InitCmd(mock.GenInitOptions, ctx) + initCmd := InitCmd(mock.GenAppState, ctx) err = initCmd.RunE(nil, nil) require.NoError(t, err) diff --git a/server/util.go b/server/util.go index cf37ec5cc..83f22db82 100644 --- a/server/util.go +++ b/server/util.go @@ -63,7 +63,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error // add server commands func AddCommands( rootCmd *cobra.Command, - appState GenAppState, appCreator AppCreator, + appState GenAppParams, appCreator AppCreator, context *Context) { rootCmd.PersistentFlags().String("log_level", context.Config.LogLevel, "Log level") From 55c1e1dcfc4c38fa997fcb184f85f272e100f784 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 21 Apr 2018 22:26:46 -0400 Subject: [PATCH 095/176] init refactor --- cmd/gaia/app/app.go | 8 +++-- cmd/gaia/cmd/gaiad/main.go | 20 +++++------ examples/basecoin/cmd/basecoind/main.go | 29 ++++++++------- examples/democoin/cmd/democoind/main.go | 46 +++++++++++------------- mock/app.go | 14 ++++---- mock/app_test.go | 9 +++-- server/init.go | 37 +++++++++---------- server/init_test.go | 2 +- server/start.go | 47 ++++++++++--------------- server/start_test.go | 6 ++-- server/test_helpers.go | 37 +++++++++---------- server/util.go | 34 +++++++++++++----- server/util_test.go | 43 ++++++++++++++++++++++ 13 files changed, 187 insertions(+), 145 deletions(-) create mode 100644 server/util_test.go diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 6819b67b2..b09bd7159 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -2,7 +2,6 @@ package app import ( "encoding/json" - "fmt" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" @@ -183,7 +182,7 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { // GaiaGenAppState expects two args: an account address // and a coin denomination, and gives lots of coins to that address. -func GaiaGenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage, err error) { +func GaiaGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { var addr sdk.Address var secret string @@ -191,7 +190,10 @@ func GaiaGenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtypes if err != nil { return } - fmt.Printf("secret recovery key:\n%s\n", secret) + + mm := map[string]string{"secret": secret} + bz, err := cdc.MarshalJSON(mm) + message = json.RawMessage(bz) chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 63485433f..8231c4d42 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -15,16 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/server" ) -// rootCmd is the entry point for this binary -var ( - context = server.NewDefaultContext() - rootCmd = &cobra.Command{ - Use: "gaiad", - Short: "Gaia Daemon (server)", - PersistentPreRunE: server.PersistentPreRunEFn(context), - } -) - func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { dataDir := filepath.Join(rootDir, "data") db, err := dbm.NewGoLevelDB("gaia", dataDir) @@ -36,7 +26,15 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { } func main() { - server.AddCommands(rootCmd, app.GaiaGenAppState, generateApp, context) + cdc := app.MakeCodec() + ctx := server.NewDefaultContext() + rootCmd := &cobra.Command{ + Use: "gaiad", + Short: "Gaia Daemon (server)", + PersistentPreRunE: server.PersistentPreRunEFn(ctx), + } + + server.AddCommands(ctx, cdc, rootCmd, app.GaiaGenAppState, generateApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.gaiad") diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 37eb7d58f..7d7447300 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -15,15 +15,23 @@ import ( "github.com/cosmos/cosmos-sdk/server" ) -// rootCmd is the entry point for this binary -var ( - context = server.NewDefaultContext() - rootCmd = &cobra.Command{ +func main() { + cdc := app.MakeCodec() + ctx := server.NewDefaultContext() + + rootCmd := &cobra.Command{ Use: "basecoind", Short: "Basecoin Daemon (server)", - PersistentPreRunE: server.PersistentPreRunEFn(context), + PersistentPreRunE: server.PersistentPreRunEFn(ctx), } -) + + server.AddCommands(ctx, cdc, rootCmd, server.SimpleGenAppState, generateApp) + + // prepare and add flags + rootDir := os.ExpandEnv("$HOME/.basecoind") + executor := cli.PrepareBaseCmd(rootCmd, "BC", rootDir) + executor.Execute() +} func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { dataDir := filepath.Join(rootDir, "data") @@ -34,12 +42,3 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { bapp := app.NewBasecoinApp(logger, db) return bapp, nil } - -func main() { - server.AddCommands(rootCmd, server.DefaultGenAppState, generateApp, context) - - // prepare and add flags - rootDir := os.ExpandEnv("$HOME/.basecoind") - executor := cli.PrepareBaseCmd(rootCmd, "BC", rootDir) - executor.Execute() -} diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 8f8bb5a90..025515629 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -8,42 +8,29 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + tmtypes "github.com/tendermint/tendermint/types" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/examples/democoin/app" "github.com/cosmos/cosmos-sdk/server" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) -// rootCmd is the entry point for this binary -var ( - context = server.NewDefaultContext() - rootCmd = &cobra.Command{ - Use: "democoind", - Short: "Democoin Daemon (server)", - PersistentPreRunE: server.PersistentPreRunEFn(context), - } -) - -// defaultAppState sets up the app_state for the -// default genesis file -func defaultAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) { - baseJSON, err := server.DefaultGenAppState(args, addr, coinDenom) +// coolGenAppState sets up the app_state and appends the cool app state +func CoolGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { + chainID, validators, appState, message, err = server.SimpleGenAppState(cdc, pubKey) if err != nil { - return nil, err + return } - var jsonMap map[string]json.RawMessage - err = json.Unmarshal(baseJSON, &jsonMap) - if err != nil { - return nil, err - } - jsonMap["cool"] = json.RawMessage(`{ + key := "cool" + value := json.RawMessage(`{ "trend": "ice-cold" }`) - bz, err := json.Marshal(jsonMap) - return json.RawMessage(bz), err + appState, err = server.AppendJSON(cdc, appState, key, value) + return } func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { @@ -56,7 +43,16 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { } func main() { - server.AddCommands(rootCmd, defaultAppState, generateApp, context) + cdc := app.MakeCodec() + ctx := server.NewDefaultContext() + + rootCmd := &cobra.Command{ + Use: "democoind", + Short: "Democoin Daemon (server)", + PersistentPreRunE: server.PersistentPreRunEFn(ctx), + } + + server.AddCommands(ctx, cdc, rootCmd, CoolGenAppState, generateApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/mock/app.go b/mock/app.go index 462c5564f..c687d6d4b 100644 --- a/mock/app.go +++ b/mock/app.go @@ -14,11 +14,11 @@ import ( bam "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) -// NewApp creates a simple mock kvstore app for testing. -// It should work similar to a real app. -// Make sure rootDir is empty before running the test, +// NewApp creates a simple mock kvstore app for testing. It should work +// similar to a real app. Make sure rootDir is empty before running the test, // in order to guarantee consistent results func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { db, err := dbm.NewGoLevelDB("mock", filepath.Join(rootDir, "data")) @@ -108,16 +108,16 @@ func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci // GenAppState can be passed into InitCmd, returns a static string of a few // key-values that can be parsed by InitChainer -func GenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage, err error) { +func GenAppState(_ *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { - chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) + chainID = fmt.Sprintf("test-chain-%v", cmn.RandStr(6)) validators = []tmtypes.GenesisValidator{{ PubKey: pubKey, Power: 10, }} - appState = json.RawMessage(fmt.Sprintf(`{ + appState = json.RawMessage(`{ "values": [ { "key": "hello", @@ -128,6 +128,6 @@ func GenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtypes.Gen "value": "bar" } ] -}`)) +}`) return } diff --git a/mock/app_test.go b/mock/app_test.go index 18449631c..099808ee2 100644 --- a/mock/app_test.go +++ b/mock/app_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" ) // TestInitApp makes sure we can initialize this thing without an error @@ -21,9 +22,13 @@ func TestInitApp(t *testing.T) { require.NoError(t, err) // initialize it future-way - opts, err := GenInitOptions(nil, nil, "") + pubKey := crypto.GenPrivKeyEd25519().PubKey() + _, _, appState, _, err := GenAppState(nil, pubKey) require.NoError(t, err) - req := abci.RequestInitChain{AppStateBytes: opts} + //TODO test validators in the init chain? + req := abci.RequestInitChain{ + AppStateBytes: appState, + } app.InitChain(req) app.Commit() diff --git a/server/init.go b/server/init.go index 7669e5bc5..139a9937d 100644 --- a/server/init.go +++ b/server/init.go @@ -21,7 +21,7 @@ import ( ) // get cmd to initialize all files for tendermint and application -func InitCmd(gen GenAppParams, ctx *Context) *cobra.Command { +func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams) *cobra.Command { cobraCmd := cobra.Command{ Use: "init", Short: "Initialize genesis files", @@ -30,12 +30,12 @@ func InitCmd(gen GenAppParams, ctx *Context) *cobra.Command { config := ctx.Config pubkey := ReadOrCreatePrivValidator(config) - chainID, validators, appState, err := gen(pubkey) + chainID, validators, appState, message, err := gen(cdc, pubkey) if err != nil { return err } - err = CreateGenesisFile(config, chainID, validators, appState) + err = CreateGenesisFile(config, cdc, chainID, validators, appState) if err != nil { return err } @@ -47,11 +47,13 @@ func InitCmd(gen GenAppParams, ctx *Context) *cobra.Command { // print out some key information toPrint := struct { - ChainID string `json:"chain_id"` - NodeID string `json:"node_id"` + ChainID string `json:"chain_id"` + NodeID string `json:"node_id"` + Message json.RawMessage `json:"message"` }{ chainID, string(nodeKey.ID()), + message, } out, err := wire.MarshalJSONIndent(cdc, toPrint) if err != nil { @@ -79,7 +81,7 @@ func ReadOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { } // create the genesis file -func CreateGenesisFile(tmConfig *cfg.Config, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { +func CreateGenesisFile(tmConfig *cfg.Config, cdc *wire.Codec, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { genFile := tmConfig.GenesisFile() if cmn.FileExists(genFile) { return fmt.Errorf("genesis config file already exists: %v", genFile) @@ -94,24 +96,16 @@ func CreateGenesisFile(tmConfig *cfg.Config, chainID string, validators []tmtype if err := genDoc.SaveAs(genFile); err != nil { return err } - return addAppStateToGenesis(genFile, appState) + return addAppStateToGenesis(cdc, genFile, appState) } // Add one line to the genesis file -func addAppStateToGenesis(genesisConfigPath string, appState json.RawMessage) error { +func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState json.RawMessage) error { bz, err := ioutil.ReadFile(genesisConfigPath) if err != nil { return err } - - var doc map[string]json.RawMessage - err = cdc.UnmarshalJSON(bz, &doc) - if err != nil { - return err - } - - doc["app_state"] = appState - out, err := wire.MarshalJSONIndent(cdc, doc) + out, err := AppendJSON(cdc, bz, "app_state", appState) if err != nil { return err } @@ -122,10 +116,10 @@ func addAppStateToGenesis(genesisConfigPath string, appState json.RawMessage) er // GenAppParams creates the core parameters initialization. It takes in a // pubkey meant to represent the pubkey of the validator of this machine. -type GenAppParams func(crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage, err error) +type GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) // Create one account with a whole bunch of mycoin in it -func SimpleGenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage, err error) { +func SimpleGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { var addr sdk.Address var secret string @@ -133,7 +127,10 @@ func SimpleGenAppState(pubKey crypto.PubKey) (chainID string, validators []tmtyp if err != nil { return } - fmt.Printf("secret recovery key:\n%s\n", secret) + + mm := map[string]string{"secret": secret} + bz, err := cdc.MarshalJSON(mm) + message = json.RawMessage(bz) chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) diff --git a/server/init_test.go b/server/init_test.go index 19e669519..a035a3077 100644 --- a/server/init_test.go +++ b/server/init_test.go @@ -18,7 +18,7 @@ func TestInit(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - cmd := InitCmd(mock.GenInitOptions, ctx) + cmd := InitCmd(ctx, cdc, mock.GenAppState) err = cmd.RunE(nil, nil) require.NoError(t, err) } diff --git a/server/start.go b/server/start.go index a4ff9852e..c9a38abdf 100644 --- a/server/start.go +++ b/server/start.go @@ -27,45 +27,34 @@ type AppCreator func(string, log.Logger) (abci.Application, error) // StartCmd runs the service passed in, either // stand-alone, or in-process with tendermint -func StartCmd(app AppCreator, ctx *Context) *cobra.Command { - start := startCmd{ - appCreator: app, - context: ctx, - } +func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { cmd := &cobra.Command{ Use: "start", Short: "Run the full node", - RunE: start.run, + RunE: func(cmd *cobra.Command, args []string) error { + if !viper.GetBool(flagWithTendermint) { + ctx.Logger.Info("Starting ABCI without Tendermint") + return startStandAlone(ctx, appCreator) + } + ctx.Logger.Info("Starting ABCI with Tendermint") + return startInProcess(ctx, appCreator) + }, } + // basic flags for abci app cmd.Flags().Bool(flagWithTendermint, true, "run abci app embedded in-process with tendermint") cmd.Flags().String(flagAddress, "tcp://0.0.0.0:46658", "Listen address") - // AddNodeFlags adds support for all - // tendermint-specific command line options + // AddNodeFlags adds support for all tendermint-specific command line options tcmd.AddNodeFlags(cmd) return cmd } -type startCmd struct { - appCreator AppCreator - context *Context -} - -func (s startCmd) run(cmd *cobra.Command, args []string) error { - if !viper.GetBool(flagWithTendermint) { - s.context.Logger.Info("Starting ABCI without Tendermint") - return s.startStandAlone() - } - s.context.Logger.Info("Starting ABCI with Tendermint") - return s.startInProcess() -} - -func (s startCmd) startStandAlone() error { +func startStandAlone(ctx *Context, appCreator AppCreator) error { // Generate the app in the proper dir addr := viper.GetString(flagAddress) home := viper.GetString("home") - app, err := s.appCreator(home, s.context.Logger) + app, err := appCreator(home, ctx.Logger) if err != nil { return err } @@ -74,7 +63,7 @@ func (s startCmd) startStandAlone() error { if err != nil { return errors.Errorf("Error creating listener: %v\n", err) } - svr.SetLogger(s.context.Logger.With("module", "abci-server")) + svr.SetLogger(ctx.Logger.With("module", "abci-server")) svr.Start() // Wait forever @@ -85,10 +74,10 @@ func (s startCmd) startStandAlone() error { return nil } -func (s startCmd) startInProcess() error { - cfg := s.context.Config +func startInProcess(ctx *Context, appCreator AppCreator) error { + cfg := ctx.Config home := cfg.RootDir - app, err := s.appCreator(home, s.context.Logger) + app, err := appCreator(home, ctx.Logger) if err != nil { return err } @@ -99,7 +88,7 @@ func (s startCmd) startInProcess() error { proxy.NewLocalClientCreator(app), node.DefaultGenesisDocProviderFunc(cfg), node.DefaultDBProvider, - s.context.Logger.With("module", "node")) + ctx.Logger.With("module", "node")) if err != nil { return err } diff --git a/server/start_test.go b/server/start_test.go index ec6c886b1..f8ac5f709 100644 --- a/server/start_test.go +++ b/server/start_test.go @@ -25,7 +25,7 @@ func TestStartStandAlone(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - initCmd := InitCmd(mock.GenInitOptions, ctx) + initCmd := InitCmd(ctx, cdc, mock.GenAppState) err = initCmd.RunE(nil, nil) require.NoError(t, err) @@ -51,13 +51,13 @@ func TestStartWithTendermint(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - initCmd := InitCmd(mock.GenInitOptions, ctx) + initCmd := InitCmd(ctx, cdc, mock.GenAppState) err = initCmd.RunE(nil, nil) require.NoError(t, err) // set up app and start up viper.Set(flagWithTendermint, true) - startCmd := StartCmd(mock.NewApp, ctx) + startCmd := StartCmd(ctx, mock.NewApp) startCmd.Flags().Set(flagAddress, FreeTCPAddr(t)) // set to a new free address timeout := time.Duration(5) * time.Second diff --git a/server/test_helpers.go b/server/test_helpers.go index 01a093f47..6855f0e92 100644 --- a/server/test_helpers.go +++ b/server/test_helpers.go @@ -8,13 +8,10 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/mock" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/require" - tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tmlibs/cli" - "github.com/tendermint/tmlibs/log" ) // Get a free address for a test tendermint server @@ -42,27 +39,27 @@ func setupViper(t *testing.T) func() { // Begin the server pass up the channel to close // NOTE pass up the channel so it can be closed at the end of the process -func StartServer(t *testing.T) chan error { - defer setupViper(t)() +//func StartServer(t *testing.T, cdc *wire.Codec) chan error { +//defer setupViper(t)() - cfg, err := tcmd.ParseConfig() - require.Nil(t, err) +//cfg, err := tcmd.ParseConfig() +//require.Nil(t, err) - // init server - ctx := NewContext(cfg, log.NewNopLogger()) - initCmd := InitCmd(mock.GenAppState, ctx) - err = initCmd.RunE(nil, nil) - require.NoError(t, err) +//// init server +//ctx := NewContext(cfg, log.NewNopLogger()) +//initCmd := InitCmd(ctx, cdc, mock.GenAppState) +//err = initCmd.RunE(nil, nil) +//require.NoError(t, err) - // start server - viper.Set(flagWithTendermint, true) - startCmd := StartCmd(mock.NewApp, ctx) - startCmd.Flags().Set(flagAddress, FreeTCPAddr(t)) // set to a new free address - startCmd.Flags().Set("rpc.laddr", FreeTCPAddr(t)) // set to a new free address - timeout := time.Duration(3) * time.Second +//// start server +//viper.Set(flagWithTendermint, true) +//startCmd := StartCmd(mock.NewApp, ctx) +//startCmd.Flags().Set(flagAddress, FreeTCPAddr(t)) // set to a new free address +//startCmd.Flags().Set("rpc.laddr", FreeTCPAddr(t)) // set to a new free address +//timeout := time.Duration(3) * time.Second - return RunOrTimeout(startCmd, timeout, t) -} +//return RunOrTimeout(startCmd, timeout, t) +//} // Run or Timout RunE of command passed in func RunOrTimeout(cmd *cobra.Command, timeout time.Duration, t *testing.T) chan error { diff --git a/server/util.go b/server/util.go index 83f22db82..1d60428b5 100644 --- a/server/util.go +++ b/server/util.go @@ -1,12 +1,14 @@ package server import ( + "encoding/json" "os" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/cosmos-sdk/wire" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tmlibs/cli" @@ -31,7 +33,7 @@ func NewContext(config *cfg.Config, logger log.Logger) *Context { return &Context{config, logger} } -//-------------------------------------------------------------------- +//___________________________________________________________________________________ // PersistentPreRunEFn returns a PersistentPreRunE function for cobra // that initailizes the passed in context with a properly configured @@ -62,18 +64,32 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error // add server commands func AddCommands( + ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, - appState GenAppParams, appCreator AppCreator, - context *Context) { + appState GenAppParams, appCreator AppCreator) { - rootCmd.PersistentFlags().String("log_level", context.Config.LogLevel, "Log level") + rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") rootCmd.AddCommand( - InitCmd(appState, context), - StartCmd(appCreator, context), - UnsafeResetAllCmd(context), - ShowNodeIDCmd(context), - ShowValidatorCmd(context), + InitCmd(ctx, cdc, appState), + StartCmd(ctx, appCreator), + UnsafeResetAllCmd(ctx), + ShowNodeIDCmd(ctx), + ShowValidatorCmd(ctx), version.VersionCmd, ) } + +//___________________________________________________________________________________ + +// append a new json field to existing json message +func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMessage) (appended []byte, err error) { + var jsonMap map[string]json.RawMessage + err = cdc.UnmarshalJSON(baseJSON, &jsonMap) + if err != nil { + return nil, err + } + jsonMap[key] = value + bz, err := wire.MarshalJSONIndent(cdc, jsonMap) + return json.RawMessage(bz), err +} diff --git a/server/util_test.go b/server/util_test.go new file mode 100644 index 000000000..5345b0f8f --- /dev/null +++ b/server/util_test.go @@ -0,0 +1,43 @@ +package server + +import ( + "encoding/json" + "testing" + + "github.com/cosmos/cosmos-sdk/wire" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +//func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMessage) (appended []byte, err error) { + +func TestAppendJSON(t *testing.T) { + + foo := map[string]string{"foo": "foofoo"} + bar := map[string]string{"barInner": "barbar"} + + // create raw messages + bz, err := cdc.MarshalJSON(foo) + require.NoError(t, err) + fooRaw := json.RawMessage(bz) + + bz, err = cdc.MarshalJSON(bar) + require.NoError(t, err) + barRaw := json.RawMessage(bz) + + // make the append + cdc := wire.NewCodec() + appBz, err := AppendJSON(cdc, fooRaw, "barOuter", barRaw) + require.NoError(t, err) + + // test the append + var appended map[string]json.RawMessage + err = cdc.UnmarshalJSON(appBz, &appended) + require.NoError(t, err) + + var resBar map[string]string + err = cdc.UnmarshalJSON(appended["barOuter"], &resBar) + require.NoError(t, err) + + assert.Equal(t, bar, resBar, "appended: %v", appended) +} From d4c2d6fd4cea11ec2b67f30f77fb6f02c8e66a3a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sun, 22 Apr 2018 00:57:53 -0400 Subject: [PATCH 096/176] fix cli tests --- cmd/gaia/cli_test/cli_test.go | 44 ++++++++++++++----------- examples/basecoin/cmd/basecoind/main.go | 2 +- examples/democoin/cmd/democoind/main.go | 2 +- server/init.go | 36 +++++++++++--------- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 827c7116b..07028ba16 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -3,7 +3,6 @@ package clitest import ( "encoding/json" "fmt" - "strings" "testing" "time" @@ -24,7 +23,7 @@ func TestGaiaCLISend(t *testing.T) { pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) executeWrite(t, "gaiacli keys delete bar", pass) - masterKey, chainID := executeInit(t, "gaiad init") + masterKey, chainID := executeInit(t, "gaiad init -o") // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) @@ -57,7 +56,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { tests.ExecuteT(t, "gaiad unsafe_reset_all", 1) pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) - masterKey, chainID := executeInit(t, "gaiad init") + masterKey, chainID := executeInit(t, "gaiad init -o") // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) @@ -90,19 +89,19 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { // TODO timeout issues if not connected to the internet // unbond a single share - unbondStr := fmt.Sprintf("gaiacli unbond %v", flags) - unbondStr += fmt.Sprintf(" --name=%v", "foo") - unbondStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) - unbondStr += fmt.Sprintf(" --address-delegator=%v", fooAddr) - unbondStr += fmt.Sprintf(" --shares=%v", "1") - unbondStr += fmt.Sprintf(" --sequence=%v", "1") - fmt.Printf("debug unbondStr: %v\n", unbondStr) - executeWrite(t, unbondStr, pass) - time.Sleep(time.Second * 3) // waiting for some blocks to pass - fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(99998), fooAcc.GetCoins().AmountOf("fermion")) - candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr)) - assert.Equal(t, int64(2), candidate.Assets.Evaluate()) + //unbondStr := fmt.Sprintf("gaiacli unbond %v", flags) + //unbondStr += fmt.Sprintf(" --name=%v", "foo") + //unbondStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) + //unbondStr += fmt.Sprintf(" --address-delegator=%v", fooAddr) + //unbondStr += fmt.Sprintf(" --shares=%v", "1") + //unbondStr += fmt.Sprintf(" --sequence=%v", "1") + //fmt.Printf("debug unbondStr: %v\n", unbondStr) + //executeWrite(t, unbondStr, pass) + //time.Sleep(time.Second * 3) // waiting for some blocks to pass + //fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + //assert.Equal(t, int64(99998), fooAcc.GetCoins().AmountOf("fermion")) + //candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr)) + //assert.Equal(t, int64(2), candidate.Assets.Evaluate()) } func executeWrite(t *testing.T, cmdStr string, writes ...string) { @@ -131,15 +130,20 @@ func executeWritePrint(t *testing.T, cmdStr string, writes ...string) { func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { out := tests.ExecuteT(t, cmdStr, 1) - outCut := "{" + strings.SplitN(out, "{", 2)[1] // weird I'm sorry var initRes map[string]json.RawMessage - err := json.Unmarshal([]byte(outCut), &initRes) - require.NoError(t, err) - err = json.Unmarshal(initRes["secret"], &masterKey) + err := json.Unmarshal([]byte(out), &initRes) require.NoError(t, err) + err = json.Unmarshal(initRes["chain_id"], &chainID) require.NoError(t, err) + + var appMessageRes map[string]json.RawMessage + err = json.Unmarshal(initRes["app_message"], &appMessageRes) + require.NoError(t, err) + + err = json.Unmarshal(appMessageRes["secret"], &masterKey) + require.NoError(t, err) return } diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 7d7447300..02f2c8065 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -25,7 +25,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, server.SimpleGenAppState, generateApp) + server.AddCommands(ctx, cdc, rootCmd, server.SimpleGenAppParams, generateApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 025515629..93602023a 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -21,7 +21,7 @@ import ( // coolGenAppState sets up the app_state and appends the cool app state func CoolGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { - chainID, validators, appState, message, err = server.SimpleGenAppState(cdc, pubKey) + chainID, validators, appState, message, err = server.SimpleGenAppParams(cdc, pubKey) if err != nil { return } diff --git a/server/init.go b/server/init.go index 139a9937d..fc80b495f 100644 --- a/server/init.go +++ b/server/init.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/spf13/cobra" + "github.com/spf13/viper" crypto "github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto/keys" @@ -22,6 +23,8 @@ import ( // get cmd to initialize all files for tendermint and application func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams) *cobra.Command { + flagOverwrite := "overwrite" + cobraCmd := cobra.Command{ Use: "init", Short: "Initialize genesis files", @@ -30,12 +33,17 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams) *cobra.Command { config := ctx.Config pubkey := ReadOrCreatePrivValidator(config) - chainID, validators, appState, message, err := gen(cdc, pubkey) + chainID, validators, appState, cliPrint, err := gen(cdc, pubkey) if err != nil { return err } - err = CreateGenesisFile(config, cdc, chainID, validators, appState) + genFile := config.GenesisFile() + if !viper.GetBool(flagOverwrite) && cmn.FileExists(genFile) { + return fmt.Errorf("genesis config file already exists: %v", genFile) + } + + err = WriteGenesisFile(cdc, genFile, chainID, validators, appState) if err != nil { return err } @@ -47,13 +55,13 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams) *cobra.Command { // print out some key information toPrint := struct { - ChainID string `json:"chain_id"` - NodeID string `json:"node_id"` - Message json.RawMessage `json:"message"` + ChainID string `json:"chain_id"` + NodeID string `json:"node_id"` + AppMessage json.RawMessage `json:"app_message"` }{ chainID, string(nodeKey.ID()), - message, + cliPrint, } out, err := wire.MarshalJSONIndent(cdc, toPrint) if err != nil { @@ -63,6 +71,8 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams) *cobra.Command { return nil }, } + + cobraCmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") return &cobraCmd } @@ -81,11 +91,7 @@ func ReadOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { } // create the genesis file -func CreateGenesisFile(tmConfig *cfg.Config, cdc *wire.Codec, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { - genFile := tmConfig.GenesisFile() - if cmn.FileExists(genFile) { - return fmt.Errorf("genesis config file already exists: %v", genFile) - } +func WriteGenesisFile(cdc *wire.Codec, genesisFile, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { genDoc := tmtypes.GenesisDoc{ ChainID: chainID, Validators: validators, @@ -93,10 +99,10 @@ func CreateGenesisFile(tmConfig *cfg.Config, cdc *wire.Codec, chainID string, va if err := genDoc.ValidateAndComplete(); err != nil { return err } - if err := genDoc.SaveAs(genFile); err != nil { + if err := genDoc.SaveAs(genesisFile); err != nil { return err } - return addAppStateToGenesis(cdc, genFile, appState) + return addAppStateToGenesis(cdc, genesisFile, appState) } // Add one line to the genesis file @@ -119,7 +125,7 @@ func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState js type GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) // Create one account with a whole bunch of mycoin in it -func SimpleGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { +func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { var addr sdk.Address var secret string @@ -130,7 +136,7 @@ func SimpleGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, v mm := map[string]string{"secret": secret} bz, err := cdc.MarshalJSON(mm) - message = json.RawMessage(bz) + cliPrint = json.RawMessage(bz) chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) From 246e4bdac3432e3f730ead6219bf2cc480c10bfb Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sun, 22 Apr 2018 01:32:47 -0400 Subject: [PATCH 097/176] renames --- CHANGELOG.md | 2 +- cmd/gaia/app/app.go | 15 +++++++++++---- cmd/gaia/cmd/gaiad/main.go | 22 +++++++++++----------- examples/democoin/cmd/democoind/main.go | 8 ++++---- mock/app.go | 4 ++-- mock/app_test.go | 2 +- server/init.go | 2 +- server/init_test.go | 2 +- server/start_test.go | 4 ++-- server/test_helpers.go | 2 +- server/tm_cmds.go | 4 ++++ server/wire.go | 12 ------------ 12 files changed, 39 insertions(+), 40 deletions(-) delete mode 100644 server/wire.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 076129dbc..618db746a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,7 +74,7 @@ BREAKING CHANGES to allow mounting multiple stores with their own DB until they can share one * [x/staking] Renamed to `simplestake` * [builder] Functions don't take `passphrase` as argument -* [server] GenAppState returns generated seed and address +* [server] GenAppParams returns generated seed and address * [basecoind] `init` command outputs JSON of everything necessary for testnet * [basecoind] `basecoin.db -> data/basecoin.db` * [basecli] `data/keys.db -> keys/keys.db` diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index b09bd7159..1ab0c7c19 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -180,9 +180,16 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { } } -// GaiaGenAppState expects two args: an account address -// and a coin denomination, and gives lots of coins to that address. -func GaiaGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { +// XXX func GeneratePiece +// XXX func AddPiece + +// Create the core parameters for genesis initialization for gaia +func GaiaGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { + + // XXX what's the best way to pass around this information? have special flagset defined here? + // add keys to accounts (flag) + // generate X accounts each with X money + // generate X number of validators each bonded with X amount of token var addr sdk.Address var secret string @@ -193,7 +200,7 @@ func GaiaGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, val mm := map[string]string{"secret": secret} bz, err := cdc.MarshalJSON(mm) - message = json.RawMessage(bz) + cliPrint = json.RawMessage(bz) chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 8231c4d42..1637a8085 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -15,16 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/server" ) -func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("gaia", dataDir) - if err != nil { - return nil, err - } - bapp := app.NewGaiaApp(logger, db) - return bapp, nil -} - func main() { cdc := app.MakeCodec() ctx := server.NewDefaultContext() @@ -34,10 +24,20 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, app.GaiaGenAppState, generateApp) + server.AddCommands(ctx, cdc, rootCmd, app.GaiaGenAppParams, generateApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.gaiad") executor := cli.PrepareBaseCmd(rootCmd, "GA", rootDir) executor.Execute() } + +func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB("gaia", dataDir) + if err != nil { + return nil, err + } + bapp := app.NewGaiaApp(logger, db) + return bapp, nil +} diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 93602023a..7cfd55e91 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -19,9 +19,9 @@ import ( "github.com/cosmos/cosmos-sdk/wire" ) -// coolGenAppState sets up the app_state and appends the cool app state -func CoolGenAppState(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { - chainID, validators, appState, message, err = server.SimpleGenAppParams(cdc, pubKey) +// coolGenAppParams sets up the app_state and appends the cool app state +func CoolGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { + chainID, validators, appState, cliPrint, err = server.SimpleGenAppParams(cdc, pubKey) if err != nil { return } @@ -52,7 +52,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, CoolGenAppState, generateApp) + server.AddCommands(ctx, cdc, rootCmd, CoolGenAppParams, generateApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/mock/app.go b/mock/app.go index c687d6d4b..09f09b830 100644 --- a/mock/app.go +++ b/mock/app.go @@ -106,9 +106,9 @@ func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci } } -// GenAppState can be passed into InitCmd, returns a static string of a few +// GenAppParams can be passed into InitCmd, returns a static string of a few // key-values that can be parsed by InitChainer -func GenAppState(_ *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) { +func GenAppParams(_ *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { chainID = fmt.Sprintf("test-chain-%v", cmn.RandStr(6)) diff --git a/mock/app_test.go b/mock/app_test.go index 099808ee2..fe0948a84 100644 --- a/mock/app_test.go +++ b/mock/app_test.go @@ -23,7 +23,7 @@ func TestInitApp(t *testing.T) { // initialize it future-way pubKey := crypto.GenPrivKeyEd25519().PubKey() - _, _, appState, _, err := GenAppState(nil, pubKey) + _, _, appState, _, err := GenAppParams(nil, pubKey) require.NoError(t, err) //TODO test validators in the init chain? req := abci.RequestInitChain{ diff --git a/server/init.go b/server/init.go index fc80b495f..14635a941 100644 --- a/server/init.go +++ b/server/init.go @@ -122,7 +122,7 @@ func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState js // GenAppParams creates the core parameters initialization. It takes in a // pubkey meant to represent the pubkey of the validator of this machine. -type GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, message json.RawMessage, err error) +type GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) // Create one account with a whole bunch of mycoin in it func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { diff --git a/server/init_test.go b/server/init_test.go index a035a3077..e4bf8c016 100644 --- a/server/init_test.go +++ b/server/init_test.go @@ -18,7 +18,7 @@ func TestInit(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - cmd := InitCmd(ctx, cdc, mock.GenAppState) + cmd := InitCmd(ctx, cdc, mock.GenAppParams) err = cmd.RunE(nil, nil) require.NoError(t, err) } diff --git a/server/start_test.go b/server/start_test.go index f8ac5f709..9cbd45661 100644 --- a/server/start_test.go +++ b/server/start_test.go @@ -25,7 +25,7 @@ func TestStartStandAlone(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - initCmd := InitCmd(ctx, cdc, mock.GenAppState) + initCmd := InitCmd(ctx, cdc, mock.GenAppParams) err = initCmd.RunE(nil, nil) require.NoError(t, err) @@ -51,7 +51,7 @@ func TestStartWithTendermint(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - initCmd := InitCmd(ctx, cdc, mock.GenAppState) + initCmd := InitCmd(ctx, cdc, mock.GenAppParams) err = initCmd.RunE(nil, nil) require.NoError(t, err) diff --git a/server/test_helpers.go b/server/test_helpers.go index 6855f0e92..55b6caf43 100644 --- a/server/test_helpers.go +++ b/server/test_helpers.go @@ -47,7 +47,7 @@ func setupViper(t *testing.T) func() { //// init server //ctx := NewContext(cfg, log.NewNopLogger()) -//initCmd := InitCmd(ctx, cdc, mock.GenAppState) +//initCmd := InitCmd(ctx, cdc, mock.GenAppParams) //err = initCmd.RunE(nil, nil) //require.NoError(t, err) diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 73dca6651..a876d1bcd 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/cosmos/cosmos-sdk/wire" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -43,6 +44,9 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command { pubKey := privValidator.PubKey if viper.GetBool(flagJSON) { + + cdc := wire.NewCodec() + wire.RegisterCrypto(cdc) pubKeyJSONBytes, err := cdc.MarshalJSON(pubKey) if err != nil { return err diff --git a/server/wire.go b/server/wire.go deleted file mode 100644 index 261e7cfe1..000000000 --- a/server/wire.go +++ /dev/null @@ -1,12 +0,0 @@ -package server - -import ( - "github.com/cosmos/cosmos-sdk/wire" -) - -var cdc *wire.Codec - -func init() { - cdc = wire.NewCodec() - wire.RegisterCrypto(cdc) -} From 867d0e502ca5c7d605230189e58da8dcecc505fc Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sun, 22 Apr 2018 13:36:35 -0400 Subject: [PATCH 098/176] working genesis pieces --- cmd/gaia/app/app.go | 1 - server/init.go | 112 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 104 insertions(+), 9 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 1ab0c7c19..61242b039 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -180,7 +180,6 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { } } -// XXX func GeneratePiece // XXX func AddPiece // Create the core parameters for genesis initialization for gaia diff --git a/server/init.go b/server/init.go index 14635a941..de2bc9428 100644 --- a/server/init.go +++ b/server/init.go @@ -4,6 +4,9 @@ import ( "encoding/json" "fmt" "io/ioutil" + "os" + "path" + "path/filepath" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" @@ -21,14 +24,14 @@ import ( dbm "github.com/tendermint/tmlibs/db" ) +// TODO flag to retrieve genesis file / config file from a URL? // get cmd to initialize all files for tendermint and application -func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams) *cobra.Command { - flagOverwrite := "overwrite" - - cobraCmd := cobra.Command{ +func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState AppendAppState) *cobra.Command { + flagOverwrite, flagAppendFile := "overwrite", "piece-file" + cmd := &cobra.Command{ Use: "init", - Short: "Initialize genesis files", - RunE: func(cmd *cobra.Command, args []string) error { + Short: "Initialize genesis config, priv-validator file, and p2p-node file", + RunE: func(_ *cobra.Command, _ []string) error { config := ctx.Config pubkey := ReadOrCreatePrivValidator(config) @@ -72,10 +75,100 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams) *cobra.Command { }, } - cobraCmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") - return &cobraCmd + cmd.AddCommand(FromPiecesCmd(ctx, cdc, appendState)) + cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") + cmd.Flags().BoolP(flagAppendFile, "a", false, "create an append file for others to import") + return cmd } +// genesis piece structure for creating combined genesis +type GenesisPiece struct { + ChainID string `json:"chain_id"` + NodeID string `json:"node_id"` + AppState json.RawMessage `json:"app_state"` + Validators []tmtypes.GenesisValidator `json:"validators"` +} + +// get cmd to initialize all files for tendermint and application +func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *cobra.Command { + return &cobra.Command{ + Use: "from-pieces [directory]", + Short: "Create genesis from directory of genesis pieces", + Args: cobra.ExactArgs(1), + RunE: func(_ *cobra.Command, args []string) error { + pieceDir := args[0] + + // ensure that the privVal and nodeKey file already exist + config := ctx.Config + privValFile := config.PrivValidatorFile() + nodeKeyFile := config.NodeKeyFile() + genFile := config.GenesisFile() + if !cmn.FileExists(privValFile) { + return fmt.Errorf("privVal file must already exist, please initialize with init cmd: %v", privValFile) + } + if !cmn.FileExists(nodeKeyFile) { + return fmt.Errorf("nodeKey file must already exist, please initialize with init cmd: %v", nodeKeyFile) + } + cmn.FileExists(genFile) + + // XXX remove the existing gen config file + + // deterministically walk the directory for genesis-piece files to import + filepath.Walk(pieceDir, appendPiece(cdc, appendState, nodeKeyFile, genFile)) + + return nil + }, + } +} + +// append a genesis-piece +func appendPiece(cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFile string) filepath.WalkFunc { + return func(filePath string, _ os.FileInfo, err error) error { + if err != nil { + return err + } + if path.Ext(filePath) != "json" { + return nil + } + + // XXX get the file bytes + var bz []byte + + // get the piece + var piece GenesisPiece + err = cdc.UnmarshalJSON(bz, &piece) + if err != nil { + return err + } + + // if the first file, create the genesis from scratch with piece inputs + if !cmn.FileExists(genFile) { + return WriteGenesisFile(cdc, genFile, piece.chainID, piece.validators, piece.appState) + } + + // XXX read in the genFile + + // XXX verify chain-ids are the same + // XXX combine the validator set + var validators []tmtypes.GenesisValidator + + // combine the app state + appState, err := appendState(appState, piece.AppState) + if err != nil { + return err + } + + // write the appended genesis file + return WriteGenesisFile(cdc, genFile, piece.chainID, validators, appState) + + // XXX read in nodeKey and combine new nodeID file + + return nil + } +} + +//________________________________________________________________________________________ + // read of create the private key file for this config func ReadOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { // private validator @@ -124,6 +217,9 @@ func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState js // pubkey meant to represent the pubkey of the validator of this machine. type GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) +// append appState1 with appState2 +type AppendAppState func(cdc *wire.Codec, appState1, appState2 json.RawMesssage) (appState json.RawMessage, err error) + // Create one account with a whole bunch of mycoin in it func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { From 556896679a49c0aeecce02f41fe36409a82b332a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 23 Apr 2018 11:47:39 -0400 Subject: [PATCH 099/176] ... --- client/tx/query.go | 5 +-- server/init.go | 60 ++++++++++++++++++-------- server/util.go | 2 +- x/auth/client/cli/account.go | 83 ++++++++++++++---------------------- 4 files changed, 77 insertions(+), 73 deletions(-) diff --git a/client/tx/query.go b/client/tx/query.go index 0583f94f5..2078b7883 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -8,7 +8,6 @@ import ( "strconv" "github.com/gorilla/mux" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" abci "github.com/tendermint/abci/types" @@ -25,10 +24,8 @@ func QueryTxCmd(cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "tx [hash]", Short: "Matches this txhash over all committed blocks", + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a tx hash") - } // find the key to look up the account hashHexStr := args[0] diff --git a/server/init.go b/server/init.go index de2bc9428..0ce6ad50b 100644 --- a/server/init.go +++ b/server/init.go @@ -31,6 +31,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append cmd := &cobra.Command{ Use: "init", Short: "Initialize genesis config, priv-validator file, and p2p-node file", + Args: cobra.NoArgs, RunE: func(_ *cobra.Command, _ []string) error { config := ctx.Config @@ -74,10 +75,11 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append return nil }, } - - cmd.AddCommand(FromPiecesCmd(ctx, cdc, appendState)) + if appendState != nil { + cmd.AddCommand(FromPiecesCmd(ctx, cdc, appendState)) + cmd.Flags().BoolP(flagAppendFile, "a", false, "create an append file for others to import") + } cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") - cmd.Flags().BoolP(flagAppendFile, "a", false, "create an append file for others to import") return cmd } @@ -102,16 +104,16 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *c config := ctx.Config privValFile := config.PrivValidatorFile() nodeKeyFile := config.NodeKeyFile() - genFile := config.GenesisFile() if !cmn.FileExists(privValFile) { return fmt.Errorf("privVal file must already exist, please initialize with init cmd: %v", privValFile) } if !cmn.FileExists(nodeKeyFile) { return fmt.Errorf("nodeKey file must already exist, please initialize with init cmd: %v", nodeKeyFile) } - cmn.FileExists(genFile) - // XXX remove the existing gen config file + // remove genFile for creation + genFile := config.GenesisFile() + os.Remove(genFile) // deterministically walk the directory for genesis-piece files to import filepath.Walk(pieceDir, appendPiece(cdc, appendState, nodeKeyFile, genFile)) @@ -123,16 +125,19 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *c // append a genesis-piece func appendPiece(cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFile string) filepath.WalkFunc { - return func(filePath string, _ os.FileInfo, err error) error { + return func(pieceFile string, _ os.FileInfo, err error) error { if err != nil { return err } - if path.Ext(filePath) != "json" { + if path.Ext(pieceFile) != "json" { return nil } - // XXX get the file bytes - var bz []byte + // get the piece file bytes + bz, err := ioutil.ReadFile(pieceFile) + if err != nil { + return err + } // get the piece var piece GenesisPiece @@ -143,25 +148,44 @@ func appendPiece(cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFi // if the first file, create the genesis from scratch with piece inputs if !cmn.FileExists(genFile) { - return WriteGenesisFile(cdc, genFile, piece.chainID, piece.validators, piece.appState) + return WriteGenesisFile(cdc, genFile, piece.ChainID, piece.Validators, piece.AppState) } - // XXX read in the genFile + // read in the genFile + bz, err = ioutil.ReadFile(genFile) + if err != nil { + return err + } + var genMap map[string]json.RawMessage + err = cdc.UnmarshalJSON(bz, &genMap) + if err != nil { + return err + } + appState := genMap["app_state"] - // XXX verify chain-ids are the same - // XXX combine the validator set + // verify chain-ids are the same + if piece.ChainID != string(genMap["chain_id"]) { + return fmt.Errorf("piece chain id's are mismatched, %s != %s", piece.ChainID, genMap["chain_id"]) + } + + // combine the validator set var validators []tmtypes.GenesisValidator + err = cdc.UnmarshalJSON(genMap["validators"], &validators) + if err != nil { + return err + } + validators = append(validators, piece.Validators...) // combine the app state - appState, err := appendState(appState, piece.AppState) + appState, err = appendState(cdc, appState, piece.AppState) if err != nil { return err } // write the appended genesis file - return WriteGenesisFile(cdc, genFile, piece.chainID, validators, appState) + return WriteGenesisFile(cdc, genFile, piece.ChainID, validators, appState) - // XXX read in nodeKey and combine new nodeID file + // XXX XXX XXX read in configTOMBL and combine new nodeID file return nil } @@ -218,7 +242,7 @@ func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState js type GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) // append appState1 with appState2 -type AppendAppState func(cdc *wire.Codec, appState1, appState2 json.RawMesssage) (appState json.RawMessage, err error) +type AppendAppState func(cdc *wire.Codec, appState1, appState2 json.RawMessage) (appState json.RawMessage, err error) // Create one account with a whole bunch of mycoin in it func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { diff --git a/server/util.go b/server/util.go index 1d60428b5..4b34d0383 100644 --- a/server/util.go +++ b/server/util.go @@ -71,7 +71,7 @@ func AddCommands( rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") rootCmd.AddCommand( - InitCmd(ctx, cdc, appState), + InitCmd(ctx, cdc, appState, nil), StartCmd(ctx, appCreator), UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), diff --git a/x/auth/client/cli/account.go b/x/auth/client/cli/account.go index c6c8c6c54..b45cb12dd 100644 --- a/x/auth/client/cli/account.go +++ b/x/auth/client/cli/account.go @@ -4,7 +4,6 @@ import ( "encoding/hex" "fmt" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client/context" @@ -32,56 +31,40 @@ func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { // GetAccountCmd returns a query account that will display the // state of the account at a given address func GetAccountCmd(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder) *cobra.Command { - cmdr := commander{ - storeName, - cdc, - decoder, - } return &cobra.Command{ - Use: "account
", + Use: "account [address]", Short: "Query account balance", - RunE: cmdr.getAccountCmd, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + + // find the key to look up the account + addr := args[0] + bz, err := hex.DecodeString(addr) + if err != nil { + return err + } + key := sdk.Address(bz) + + // perform query + ctx := context.NewCoreContextFromViper() + res, err := ctx.Query(key, storeName) + if err != nil { + return err + } + + // decode the value + account, err := decoder(res) + if err != nil { + return err + } + + // print out whole account + output, err := wire.MarshalJSONIndent(cdc, account) + if err != nil { + return err + } + fmt.Println(string(output)) + return nil + }, } } - -type commander struct { - storeName string - cdc *wire.Codec - decoder sdk.AccountDecoder -} - -func (c commander) getAccountCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide an account name") - } - - // find the key to look up the account - addr := args[0] - bz, err := hex.DecodeString(addr) - if err != nil { - return err - } - key := sdk.Address(bz) - - ctx := context.NewCoreContextFromViper() - - res, err := ctx.Query(key, c.storeName) - if err != nil { - return err - } - - // decode the value - account, err := c.decoder(res) - if err != nil { - return err - } - - // print out whole account - output, err := wire.MarshalJSONIndent(c.cdc, account) - if err != nil { - return err - } - fmt.Println(string(output)) - - return nil -} From c8f5fcb27b26d2a4132d6871ccfbf670b09f4fef Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 23 Apr 2018 15:15:50 -0400 Subject: [PATCH 100/176] init append functionality complete --- server/init.go | 48 ++++++++++++++++++++++++++++++++++++++------ server/init_test.go | 4 +++- server/start_test.go | 7 +++++-- server/util.go | 41 +++++++++++++++++++++++++++++++++++++ server/util_test.go | 2 +- 5 files changed, 92 insertions(+), 10 deletions(-) diff --git a/server/init.go b/server/init.go index 0ce6ad50b..3e8e0da4a 100644 --- a/server/init.go +++ b/server/init.go @@ -27,7 +27,7 @@ import ( // TODO flag to retrieve genesis file / config file from a URL? // get cmd to initialize all files for tendermint and application func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState AppendAppState) *cobra.Command { - flagOverwrite, flagAppendFile := "overwrite", "piece-file" + flagOverwrite, flagPieceFile := "overwrite", "piece-file" cmd := &cobra.Command{ Use: "init", Short: "Initialize genesis config, priv-validator file, and p2p-node file", @@ -56,15 +56,17 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append if err != nil { return err } + nodeID := string(nodeKey.ID()) // print out some key information + toPrint := struct { ChainID string `json:"chain_id"` NodeID string `json:"node_id"` AppMessage json.RawMessage `json:"app_message"` }{ chainID, - string(nodeKey.ID()), + nodeID, cliPrint, } out, err := wire.MarshalJSONIndent(cdc, toPrint) @@ -72,12 +74,35 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append return err } fmt.Println(string(out)) + + // write the piece file is path specified + pieceFile := viper.GetString(flagPieceFile) + if len(pieceFile) > 0 { + //create the piece + ip, err := externalIP() + if err != nil { + return err + } + piece := GenesisPiece{ + ChainID: chainID, + NodeID: nodeID, + IP: ip, + AppState: appState, + Validators: validators, + } + bz, err := cdc.MarshalJSON(piece) + if err != nil { + return err + } + return cmn.WriteFile(pieceFile, bz, 0644) + } + return nil }, } if appendState != nil { cmd.AddCommand(FromPiecesCmd(ctx, cdc, appendState)) - cmd.Flags().BoolP(flagAppendFile, "a", false, "create an append file for others to import") + cmd.Flags().StringP(flagPieceFile, "a", "", "create an append file for others to import") } cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") return cmd @@ -87,6 +112,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append type GenesisPiece struct { ChainID string `json:"chain_id"` NodeID string `json:"node_id"` + IP string `json:"ip"` AppState json.RawMessage `json:"app_state"` Validators []tmtypes.GenesisValidator `json:"validators"` } @@ -116,7 +142,7 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *c os.Remove(genFile) // deterministically walk the directory for genesis-piece files to import - filepath.Walk(pieceDir, appendPiece(cdc, appendState, nodeKeyFile, genFile)) + filepath.Walk(pieceDir, appendPiece(ctx, cdc, appendState, nodeKeyFile, genFile)) return nil }, @@ -124,7 +150,7 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *c } // append a genesis-piece -func appendPiece(cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFile string) filepath.WalkFunc { +func appendPiece(ctx *Context, cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFile string) filepath.WalkFunc { return func(pieceFile string, _ os.FileInfo, err error) error { if err != nil { return err @@ -185,7 +211,17 @@ func appendPiece(cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFi // write the appended genesis file return WriteGenesisFile(cdc, genFile, piece.ChainID, validators, appState) - // XXX XXX XXX read in configTOMBL and combine new nodeID file + // Add a persistent peer if the config (if it's not me) + myIP, err := externalIP() + if err != nil { + return err + } + if myIP == piece.IP { + return nil + } + ctx.Config.P2P.PersistentPeers += fmt.Sprintf(",%s@%s", piece.NodeID, piece.IP) + configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get + cfg.WriteConfigFile(configFilePath, ctx.Config) return nil } diff --git a/server/init_test.go b/server/init_test.go index e4bf8c016..b13fb4789 100644 --- a/server/init_test.go +++ b/server/init_test.go @@ -8,6 +8,7 @@ import ( "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/mock" + "github.com/cosmos/cosmos-sdk/wire" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" ) @@ -18,7 +19,8 @@ func TestInit(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - cmd := InitCmd(ctx, cdc, mock.GenAppParams) + cdc := wire.NewCodec() + cmd := InitCmd(ctx, cdc, mock.GenAppParams, nil) err = cmd.RunE(nil, nil) require.NoError(t, err) } diff --git a/server/start_test.go b/server/start_test.go index 9cbd45661..d933d19f1 100644 --- a/server/start_test.go +++ b/server/start_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/mock" + "github.com/cosmos/cosmos-sdk/wire" "github.com/tendermint/abci/server" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tmlibs/log" @@ -25,7 +26,8 @@ func TestStartStandAlone(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - initCmd := InitCmd(ctx, cdc, mock.GenAppParams) + cdc := wire.NewCodec() + initCmd := InitCmd(ctx, cdc, mock.GenAppParams, nil) err = initCmd.RunE(nil, nil) require.NoError(t, err) @@ -51,7 +53,8 @@ func TestStartWithTendermint(t *testing.T) { cfg, err := tcmd.ParseConfig() require.Nil(t, err) ctx := NewContext(cfg, logger) - initCmd := InitCmd(ctx, cdc, mock.GenAppParams) + cdc := wire.NewCodec() + initCmd := InitCmd(ctx, cdc, mock.GenAppParams, nil) err = initCmd.RunE(nil, nil) require.NoError(t, err) diff --git a/server/util.go b/server/util.go index 4b34d0383..3f24d5987 100644 --- a/server/util.go +++ b/server/util.go @@ -2,8 +2,10 @@ package server import ( "encoding/json" + "net" "os" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -93,3 +95,42 @@ func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMess bz, err := wire.MarshalJSONIndent(cdc, jsonMap) return json.RawMessage(bz), err } + +// https://stackoverflow.com/questions/23558425/how-do-i-get-the-local-ip-address-in-go +// TODO there must be a better way to get external IP +func externalIP() (string, error) { + ifaces, err := net.Interfaces() + if err != nil { + return "", err + } + for _, iface := range ifaces { + if iface.Flags&net.FlagUp == 0 { + continue // interface down + } + if iface.Flags&net.FlagLoopback != 0 { + continue // loopback interface + } + addrs, err := iface.Addrs() + if err != nil { + return "", err + } + for _, addr := range addrs { + var ip net.IP + switch v := addr.(type) { + case *net.IPNet: + ip = v.IP + case *net.IPAddr: + ip = v.IP + } + if ip == nil || ip.IsLoopback() { + continue + } + ip = ip.To4() + if ip == nil { + continue // not an ipv4 address + } + return ip.String(), nil + } + } + return "", errors.New("are you connected to the network?") +} diff --git a/server/util_test.go b/server/util_test.go index 5345b0f8f..a21fe3882 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -12,6 +12,7 @@ import ( //func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMessage) (appended []byte, err error) { func TestAppendJSON(t *testing.T) { + cdc := wire.NewCodec() foo := map[string]string{"foo": "foofoo"} bar := map[string]string{"barInner": "barbar"} @@ -26,7 +27,6 @@ func TestAppendJSON(t *testing.T) { barRaw := json.RawMessage(bz) // make the append - cdc := wire.NewCodec() appBz, err := AppendJSON(cdc, fooRaw, "barOuter", barRaw) require.NoError(t, err) From 201908949affa1ed4a104a3108101a47fb29e2fc Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 23 Apr 2018 20:05:58 -0400 Subject: [PATCH 101/176] stake init overhaul --- cmd/gaia/app/app.go | 146 +++++++++++++++++++----- cmd/gaia/cli_test/cli_test.go | 21 ++-- cmd/gaia/cmd/gaiad/main.go | 2 +- examples/basecoin/app/app.go | 4 +- examples/basecoin/cmd/basecoind/main.go | 2 +- examples/democoin/app/app.go | 4 +- examples/democoin/cmd/democoind/main.go | 7 +- server/init.go | 41 ++++--- server/init_test.go | 5 +- server/start_test.go | 10 +- server/util.go | 6 +- x/stake/handler.go | 3 + x/stake/types.go | 5 +- 13 files changed, 189 insertions(+), 67 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 61242b039..3eda293d3 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -2,7 +2,11 @@ package app import ( "encoding/json" + "errors" + "strings" + "github.com/spf13/pflag" + "github.com/spf13/viper" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" tmtypes "github.com/tendermint/tendermint/types" @@ -133,7 +137,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci stateJSON := req.AppStateBytes genesisState := new(GenesisState) - err := json.Unmarshal(stateJSON, genesisState) + err := app.cdc.UnmarshalJSON(stateJSON, genesisState) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") @@ -151,7 +155,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci return abci.ResponseInitChain{} } -//__________________________________________________________ +//________________________________________________________________________________________ // State to Unmarshal type GenesisState struct { @@ -172,7 +176,7 @@ func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { } } -// convert GenesisAccount to GaiaAccount +// convert GenesisAccount to auth.BaseAccount func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { return &auth.BaseAccount{ Address: ga.Address, @@ -180,44 +184,126 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { } } -// XXX func AddPiece +var ( + flagAccounts = "accounts" + flagOWK = "overwrite-keys" +) + +// get app init parameters for server init command +func GaiaAppInit() server.AppInit { + fs := pflag.NewFlagSet("", pflag.ContinueOnError) + fs.String(flagAccounts, "foobar-10fermion,10baz-true", "genesis accounts in form: name1-coins-isval;name2-coins-isval;...") + fs.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail") + return server.AppInit{ + Flags: fs, + GenAppParams: GaiaGenAppParams, + AppendAppState: GaiaAppendAppState, + } +} // Create the core parameters for genesis initialization for gaia +// note that the pubkey input is this machines pubkey func GaiaGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { - // XXX what's the best way to pass around this information? have special flagset defined here? - // add keys to accounts (flag) - // generate X accounts each with X money - // generate X number of validators each bonded with X amount of token - - var addr sdk.Address - var secret string - addr, secret, err = server.GenerateCoinKey() - if err != nil { - return - } - - mm := map[string]string{"secret": secret} - bz, err := cdc.MarshalJSON(mm) - cliPrint = json.RawMessage(bz) - + printMap := make(map[string]string) + var candidates []stake.Candidate + poolAssets := int64(0) chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) - validators = []tmtypes.GenesisValidator{{ - PubKey: pubKey, - Power: 10, - }} + // get genesis flag account information + accountsStr := viper.GetString(flagAccounts) + accounts := strings.Split(accountsStr, ";") + genaccs := make([]GenesisAccount, len(accounts)) + for i, account := range accounts { + p := strings.Split(account, "-") + if len(p) != 3 { + err = errors.New("input account has bad form, each account must be in form name-coins-isval, for example: foobar-10fermion,10baz-true") + return + } + name := p[0] + var coins sdk.Coins + coins, err = sdk.ParseCoins(p[1]) + if err != nil { + return + } + isValidator := false + if p[2] == "true" { + isValidator = true + } - accAuth := auth.NewBaseAccountWithAddress(addr) - accAuth.Coins = sdk.Coins{{"fermion", 100000}} - acc := NewGenesisAccount(&accAuth) - genaccs := []GenesisAccount{acc} + var addr sdk.Address + var secret string + addr, secret, err = server.GenerateCoinKey() + if err != nil { + return + } + + printMap["secret-"+name] = secret + + // create the genesis account + accAuth := auth.NewBaseAccountWithAddress(addr) + accAuth.Coins = coins + acc := NewGenesisAccount(&accAuth) + genaccs[i] = acc + + // add the validator + if isValidator { + + // only use this machines pubkey the first time, all others are dummies + var pk crypto.PubKey + if i == 0 { + pk = pubKey + } else { + pk = crypto.GenPrivKeyEd25519().PubKey() + } + + freePower := int64(100) + validator := tmtypes.GenesisValidator{ + PubKey: pk, + Power: freePower, + } + desc := stake.NewDescription(name, "", "", "") + candidate := stake.NewCandidate(addr, pk, desc) + candidate.Assets = sdk.NewRat(freePower) + poolAssets += freePower + validators = append(validators, validator) + candidates = append(candidates, candidate) + } + } + + // create the print message + bz, err := cdc.MarshalJSON(printMap) + cliPrint = json.RawMessage(bz) + + stakeData := stake.GetDefaultGenesisState() + stakeData.Candidates = candidates + + // assume everything is bonded from the get-go + stakeData.Pool.TotalSupply = poolAssets + stakeData.Pool.BondedShares = sdk.NewRat(poolAssets) genesisState := GenesisState{ Accounts: genaccs, - StakeData: stake.GetDefaultGenesisState(), + StakeData: stakeData, } - appState, err = json.MarshalIndent(genesisState, "", "\t") + appState, err = wire.MarshalJSONIndent(cdc, genesisState) return } + +// append gaia app_state together, stitch the accounts together take the +// staking parameters from the first appState +func GaiaAppendAppState(cdc *wire.Codec, appState1, appState2 json.RawMessage) (appState json.RawMessage, err error) { + var genState1, genState2 GenesisState + err = cdc.UnmarshalJSON(appState1, &genState1) + if err != nil { + panic(err) + } + err = cdc.UnmarshalJSON(appState2, &genState2) + if err != nil { + panic(err) + } + genState1.Accounts = append(genState1.Accounts, genState2.Accounts...) + + return cdc.MarshalJSON(genState1) +} diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 07028ba16..0d4443879 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -23,7 +23,8 @@ func TestGaiaCLISend(t *testing.T) { pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) executeWrite(t, "gaiacli keys delete bar", pass) - masterKey, chainID := executeInit(t, "gaiad init -o") + keys, chainID := executeInit(t, "gaiad init -o --accounts=foo-100000fermion-true", "foo") + require.Equal(t, 1, len(keys)) // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) @@ -33,7 +34,7 @@ func TestGaiaCLISend(t *testing.T) { cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) + executeWrite(t, "gaiacli keys add foo --recover", pass, keys[0]) executeWrite(t, "gaiacli keys add bar", pass) fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") @@ -56,7 +57,8 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { tests.ExecuteT(t, "gaiad unsafe_reset_all", 1) pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) - masterKey, chainID := executeInit(t, "gaiad init -o") + keys, chainID := executeInit(t, "gaiad init -o --accounts=bar-100000fermion-true;foo-100000fermion-true", "bar", "foo") + require.Equal(t, 2, len(keys)) // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) @@ -66,7 +68,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey) + executeWrite(t, "gaiacli keys add foo --recover", pass, keys[1]) fooAddr, fooPubKey := executeGetAddrPK(t, "gaiacli keys show foo --output=json") fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) @@ -128,7 +130,7 @@ func executeWritePrint(t *testing.T, cmdStr string, writes ...string) { fmt.Printf("debug read: %v\n", string(bz)) } -func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { +func executeInit(t *testing.T, cmdStr string, names ...string) (keys []string, chainID string) { out := tests.ExecuteT(t, cmdStr, 1) var initRes map[string]json.RawMessage @@ -142,8 +144,13 @@ func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) { err = json.Unmarshal(initRes["app_message"], &appMessageRes) require.NoError(t, err) - err = json.Unmarshal(appMessageRes["secret"], &masterKey) - require.NoError(t, err) + for _, name := range names { + var key string + err = json.Unmarshal(appMessageRes["secret-"+name], &key) + require.NoError(t, err) + keys = append(keys, key) + } + return } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 1637a8085..565cf5ac2 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -24,7 +24,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, app.GaiaGenAppParams, generateApp) + server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.gaiad") diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index b02f21669..ead9c78e3 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -1,8 +1,6 @@ package app import ( - "encoding/json" - abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" @@ -133,7 +131,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) stateJSON := req.AppStateBytes genesisState := new(types.GenesisState) - err := json.Unmarshal(stateJSON, genesisState) + err := app.cdc.UnmarshalJSON(stateJSON, genesisState) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 02f2c8065..8d14821c6 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -25,7 +25,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, server.SimpleGenAppParams, generateApp) + server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, generateApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index b70f51b5c..8266b2b9b 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -1,8 +1,6 @@ package app import ( - "encoding/json" - abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" @@ -147,7 +145,7 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep stateJSON := req.AppStateBytes genesisState := new(types.GenesisState) - err := json.Unmarshal(stateJSON, genesisState) + err := app.cdc.UnmarshalJSON(stateJSON, genesisState) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 7cfd55e91..0eb378005 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -19,6 +19,11 @@ import ( "github.com/cosmos/cosmos-sdk/wire" ) +// init parameters +var CoolAppInit = server.AppInit{ + GenAppParams: CoolGenAppParams, +} + // coolGenAppParams sets up the app_state and appends the cool app state func CoolGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { chainID, validators, appState, cliPrint, err = server.SimpleGenAppParams(cdc, pubKey) @@ -52,7 +57,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, CoolGenAppParams, generateApp) + server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, generateApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/server/init.go b/server/init.go index 3e8e0da4a..7e7d895a1 100644 --- a/server/init.go +++ b/server/init.go @@ -11,6 +11,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/spf13/cobra" + "github.com/spf13/pflag" "github.com/spf13/viper" crypto "github.com/tendermint/go-crypto" @@ -26,7 +27,7 @@ import ( // TODO flag to retrieve genesis file / config file from a URL? // get cmd to initialize all files for tendermint and application -func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState AppendAppState) *cobra.Command { +func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { flagOverwrite, flagPieceFile := "overwrite", "piece-file" cmd := &cobra.Command{ Use: "init", @@ -37,7 +38,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append config := ctx.Config pubkey := ReadOrCreatePrivValidator(config) - chainID, validators, appState, cliPrint, err := gen(cdc, pubkey) + chainID, validators, appState, cliPrint, err := appInit.GenAppParams(cdc, pubkey) if err != nil { return err } @@ -100,11 +101,12 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append return nil }, } - if appendState != nil { - cmd.AddCommand(FromPiecesCmd(ctx, cdc, appendState)) + if appInit.AppendAppState != nil { + cmd.AddCommand(FromPiecesCmd(ctx, cdc, appInit)) cmd.Flags().StringP(flagPieceFile, "a", "", "create an append file for others to import") } cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") + cmd.Flags().AddFlagSet(appInit.Flags) return cmd } @@ -118,7 +120,7 @@ type GenesisPiece struct { } // get cmd to initialize all files for tendermint and application -func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *cobra.Command { +func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { return &cobra.Command{ Use: "from-pieces [directory]", Short: "Create genesis from directory of genesis pieces", @@ -142,7 +144,7 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *c os.Remove(genFile) // deterministically walk the directory for genesis-piece files to import - filepath.Walk(pieceDir, appendPiece(ctx, cdc, appendState, nodeKeyFile, genFile)) + filepath.Walk(pieceDir, appendPiece(ctx, cdc, appInit, nodeKeyFile, genFile)) return nil }, @@ -150,7 +152,7 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *c } // append a genesis-piece -func appendPiece(ctx *Context, cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFile string) filepath.WalkFunc { +func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, genFile string) filepath.WalkFunc { return func(pieceFile string, _ os.FileInfo, err error) error { if err != nil { return err @@ -203,7 +205,7 @@ func appendPiece(ctx *Context, cdc *wire.Codec, appendState AppendAppState, node validators = append(validators, piece.Validators...) // combine the app state - appState, err = appendState(cdc, appState, piece.AppState) + appState, err = appInit.AppendAppState(cdc, appState, piece.AppState) if err != nil { return err } @@ -273,17 +275,30 @@ func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState js //_____________________________________________________________________ -// GenAppParams creates the core parameters initialization. It takes in a -// pubkey meant to represent the pubkey of the validator of this machine. -type GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) +// Core functionality passed from the application to the server init command +type AppInit struct { -// append appState1 with appState2 -type AppendAppState func(cdc *wire.Codec, appState1, appState2 json.RawMessage) (appState json.RawMessage, err error) + // flags required for GenAppParams + Flags *pflag.FlagSet + + // GenAppParams creates the core parameters initialization. It takes in a + // pubkey meant to represent the pubkey of the validator of this machine. + GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) + + // append appState1 with appState2 + AppendAppState func(cdc *wire.Codec, appState1, appState2 json.RawMessage) (appState json.RawMessage, err error) +} + +// simple default application init +var DefaultAppInit = AppInit{ + GenAppParams: SimpleGenAppParams, +} // Create one account with a whole bunch of mycoin in it func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { var addr sdk.Address + var secret string addr, secret, err = GenerateCoinKey() if err != nil { diff --git a/server/init_test.go b/server/init_test.go index b13fb4789..5db483516 100644 --- a/server/init_test.go +++ b/server/init_test.go @@ -20,7 +20,10 @@ func TestInit(t *testing.T) { require.Nil(t, err) ctx := NewContext(cfg, logger) cdc := wire.NewCodec() - cmd := InitCmd(ctx, cdc, mock.GenAppParams, nil) + appInit := AppInit{ + GenAppParams: mock.GenAppParams, + } + cmd := InitCmd(ctx, cdc, appInit) err = cmd.RunE(nil, nil) require.NoError(t, err) } diff --git a/server/start_test.go b/server/start_test.go index d933d19f1..85f1a7135 100644 --- a/server/start_test.go +++ b/server/start_test.go @@ -27,7 +27,10 @@ func TestStartStandAlone(t *testing.T) { require.Nil(t, err) ctx := NewContext(cfg, logger) cdc := wire.NewCodec() - initCmd := InitCmd(ctx, cdc, mock.GenAppParams, nil) + appInit := AppInit{ + GenAppParams: mock.GenAppParams, + } + initCmd := InitCmd(ctx, cdc, appInit) err = initCmd.RunE(nil, nil) require.NoError(t, err) @@ -54,7 +57,10 @@ func TestStartWithTendermint(t *testing.T) { require.Nil(t, err) ctx := NewContext(cfg, logger) cdc := wire.NewCodec() - initCmd := InitCmd(ctx, cdc, mock.GenAppParams, nil) + appInit := AppInit{ + GenAppParams: mock.GenAppParams, + } + initCmd := InitCmd(ctx, cdc, appInit) err = initCmd.RunE(nil, nil) require.NoError(t, err) diff --git a/server/util.go b/server/util.go index 3f24d5987..ed91f3048 100644 --- a/server/util.go +++ b/server/util.go @@ -67,13 +67,13 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error // add server commands func AddCommands( ctx *Context, cdc *wire.Codec, - rootCmd *cobra.Command, - appState GenAppParams, appCreator AppCreator) { + rootCmd *cobra.Command, appInit AppInit, + appCreator AppCreator) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") rootCmd.AddCommand( - InitCmd(ctx, cdc, appState, nil), + InitCmd(ctx, cdc, appInit), StartCmd(ctx, appCreator), UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), diff --git a/x/stake/handler.go b/x/stake/handler.go index d9f718fe5..e39720385 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -52,6 +52,9 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { k.setPool(ctx, data.Pool) k.setParams(ctx, data.Params) + for _, candidate := range data.Candidates { + k.setCandidate(ctx, candidate) + } } //_____________________________________________________________________ diff --git a/x/stake/types.go b/x/stake/types.go index 8f9e87cbb..634b51186 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -9,8 +9,9 @@ import ( // GenesisState - all staking state that must be provided at genesis type GenesisState struct { - Pool Pool `json:"pool"` - Params Params `json:"params"` + Pool Pool `json:"pool"` + Params Params `json:"params"` + Candidates []Candidate `json:"candidates"` } //_________________________________________________________________________ From 3aa47527375f38a4b76cfdcf74e9dc84c6cb994a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 23 Apr 2018 20:26:28 -0400 Subject: [PATCH 102/176] stake cli init fixes --- cmd/gaia/app/app.go | 4 ++-- cmd/gaia/cli_test/cli_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 3eda293d3..c0a91afc8 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -192,7 +192,7 @@ var ( // get app init parameters for server init command func GaiaAppInit() server.AppInit { fs := pflag.NewFlagSet("", pflag.ContinueOnError) - fs.String(flagAccounts, "foobar-10fermion,10baz-true", "genesis accounts in form: name1-coins-isval;name2-coins-isval;...") + fs.String(flagAccounts, "foobar-10fermion,10baz-true", "genesis accounts in form: name1-coins-isval:name2-coins-isval:...") fs.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail") return server.AppInit{ Flags: fs, @@ -212,7 +212,7 @@ func GaiaGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, va // get genesis flag account information accountsStr := viper.GetString(flagAccounts) - accounts := strings.Split(accountsStr, ";") + accounts := strings.Split(accountsStr, ":") genaccs := make([]GenesisAccount, len(accounts)) for i, account := range accounts { p := strings.Split(account, "-") diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 0d4443879..b3b2c4e7e 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -57,7 +57,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { tests.ExecuteT(t, "gaiad unsafe_reset_all", 1) pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) - keys, chainID := executeInit(t, "gaiad init -o --accounts=bar-100000fermion-true;foo-100000fermion-true", "bar", "foo") + keys, chainID := executeInit(t, "gaiad init -o --accounts=bar-100000fermion-true:foo-100000fermion-false", "bar", "foo") require.Equal(t, 2, len(keys)) // get a free port, also setup some common flags From 525a852b0172a5c44ee152e38d686557d9f33270 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 23 Apr 2018 21:32:43 -0400 Subject: [PATCH 103/176] bug fixes to init from-pieces command --- cmd/gaia/app/app.go | 18 +++++++++++++++++- server/init.go | 34 +++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index c0a91afc8..37c062595 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -186,6 +186,7 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { var ( flagAccounts = "accounts" + flagChainID = "chain-id" flagOWK = "overwrite-keys" ) @@ -193,6 +194,7 @@ var ( func GaiaAppInit() server.AppInit { fs := pflag.NewFlagSet("", pflag.ContinueOnError) fs.String(flagAccounts, "foobar-10fermion,10baz-true", "genesis accounts in form: name1-coins-isval:name2-coins-isval:...") + fs.String(flagChainID, "", "genesis file chain-id, if left blank will be randomly created") fs.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail") return server.AppInit{ Flags: fs, @@ -208,7 +210,11 @@ func GaiaGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, va printMap := make(map[string]string) var candidates []stake.Candidate poolAssets := int64(0) - chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) + + chainID = viper.GetString(flagChainID) + if len(chainID) == 0 { + chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) + } // get genesis flag account information accountsStr := viper.GetString(flagAccounts) @@ -280,6 +286,7 @@ func GaiaGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, va // assume everything is bonded from the get-go stakeData.Pool.TotalSupply = poolAssets + stakeData.Pool.BondedPool = poolAssets stakeData.Pool.BondedShares = sdk.NewRat(poolAssets) genesisState := GenesisState{ @@ -304,6 +311,15 @@ func GaiaAppendAppState(cdc *wire.Codec, appState1, appState2 json.RawMessage) ( panic(err) } genState1.Accounts = append(genState1.Accounts, genState2.Accounts...) + genState1.StakeData.Candidates = append(genState1.StakeData.Candidates, genState2.StakeData.Candidates...) + + // pool logic + CombinedSupply := genState1.StakeData.Pool.TotalSupply + genState2.StakeData.Pool.TotalSupply + CombinedBondedPool := genState1.StakeData.Pool.BondedPool + genState2.StakeData.Pool.BondedPool + CombinedBondedShares := genState1.StakeData.Pool.BondedShares.Add(genState2.StakeData.Pool.BondedShares) + genState1.StakeData.Pool.TotalSupply = CombinedSupply + genState1.StakeData.Pool.BondedPool = CombinedBondedPool + genState1.StakeData.Pool.BondedShares = CombinedBondedShares return cdc.MarshalJSON(genState1) } diff --git a/server/init.go b/server/init.go index 7e7d895a1..68eb7f738 100644 --- a/server/init.go +++ b/server/init.go @@ -77,8 +77,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { fmt.Println(string(out)) // write the piece file is path specified - pieceFile := viper.GetString(flagPieceFile) - if len(pieceFile) > 0 { + if viper.GetBool(flagPieceFile) { //create the piece ip, err := externalIP() if err != nil { @@ -95,7 +94,9 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { if err != nil { return err } - return cmn.WriteFile(pieceFile, bz, 0644) + name := fmt.Sprintf("piece%v.json", nodeID) + file := filepath.Join(viper.GetString("home"), name) + return cmn.WriteFile(file, bz, 0644) } return nil @@ -103,7 +104,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { } if appInit.AppendAppState != nil { cmd.AddCommand(FromPiecesCmd(ctx, cdc, appInit)) - cmd.Flags().StringP(flagPieceFile, "a", "", "create an append file for others to import") + cmd.Flags().BoolP(flagPieceFile, "a", false, "create an append file (under [--home]/[nodeID]piece.json) for others to import") } cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") cmd.Flags().AddFlagSet(appInit.Flags) @@ -144,7 +145,10 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Comman os.Remove(genFile) // deterministically walk the directory for genesis-piece files to import - filepath.Walk(pieceDir, appendPiece(ctx, cdc, appInit, nodeKeyFile, genFile)) + err := filepath.Walk(pieceDir, appendPiece(ctx, cdc, appInit, nodeKeyFile, genFile)) + if err != nil { + return err + } return nil }, @@ -157,7 +161,7 @@ func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, ge if err != nil { return err } - if path.Ext(pieceFile) != "json" { + if path.Ext(pieceFile) != ".json" { return nil } @@ -192,7 +196,12 @@ func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, ge appState := genMap["app_state"] // verify chain-ids are the same - if piece.ChainID != string(genMap["chain_id"]) { + var genChainID string + err = cdc.UnmarshalJSON(genMap["chain_id"], &genChainID) + if err != nil { + return err + } + if piece.ChainID != genChainID { return fmt.Errorf("piece chain id's are mismatched, %s != %s", piece.ChainID, genMap["chain_id"]) } @@ -211,7 +220,10 @@ func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, ge } // write the appended genesis file - return WriteGenesisFile(cdc, genFile, piece.ChainID, validators, appState) + err = WriteGenesisFile(cdc, genFile, piece.ChainID, validators, appState) + if err != nil { + return err + } // Add a persistent peer if the config (if it's not me) myIP, err := externalIP() @@ -221,7 +233,11 @@ func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, ge if myIP == piece.IP { return nil } - ctx.Config.P2P.PersistentPeers += fmt.Sprintf(",%s@%s", piece.NodeID, piece.IP) + comma := "," + if len(ctx.Config.P2P.PersistentPeers) == 0 { + comma = "" + } + ctx.Config.P2P.PersistentPeers += fmt.Sprintf("%s%s@%s", comma, piece.NodeID, piece.IP) configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get cfg.WriteConfigFile(configFilePath, ctx.Config) From 4049c5d24fb5be7d5904fb580ea7b7bea4a3fd95 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 24 Apr 2018 19:46:39 -0400 Subject: [PATCH 104/176] cwgoes comments, bug fix --- server/init.go | 21 +++++++++++++-------- server/test_helpers.go | 24 ------------------------ server/util_test.go | 2 -- 3 files changed, 13 insertions(+), 34 deletions(-) diff --git a/server/init.go b/server/init.go index 68eb7f738..4420bdf01 100644 --- a/server/init.go +++ b/server/init.go @@ -25,10 +25,9 @@ import ( dbm "github.com/tendermint/tmlibs/db" ) -// TODO flag to retrieve genesis file / config file from a URL? // get cmd to initialize all files for tendermint and application func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { - flagOverwrite, flagPieceFile := "overwrite", "piece-file" + flagOverwrite, flagPieceFile, flagIP := "overwrite", "piece-file", "ip" cmd := &cobra.Command{ Use: "init", Short: "Initialize genesis config, priv-validator file, and p2p-node file", @@ -79,9 +78,12 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { // write the piece file is path specified if viper.GetBool(flagPieceFile) { //create the piece - ip, err := externalIP() - if err != nil { - return err + ip := viper.GetString(flagIP) + if len(ip) == 0 { + ip, err = externalIP() + if err != nil { + return err + } } piece := GenesisPiece{ ChainID: chainID, @@ -90,7 +92,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { AppState: appState, Validators: validators, } - bz, err := cdc.MarshalJSON(piece) + bz, err := wire.MarshalJSONIndent(cdc, piece) if err != nil { return err } @@ -107,6 +109,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { cmd.Flags().BoolP(flagPieceFile, "a", false, "create an append file (under [--home]/[nodeID]piece.json) for others to import") } cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") + cmd.Flags().String(flagIP, "", "external facing IP to use if left blank IP will be retrieved from this machine") cmd.Flags().AddFlagSet(appInit.Flags) return cmd } @@ -158,6 +161,7 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Comman // append a genesis-piece func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, genFile string) filepath.WalkFunc { return func(pieceFile string, _ os.FileInfo, err error) error { + fmt.Printf("debug pieceFile: %v\n", pieceFile) if err != nil { return err } @@ -202,7 +206,7 @@ func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, ge return err } if piece.ChainID != genChainID { - return fmt.Errorf("piece chain id's are mismatched, %s != %s", piece.ChainID, genMap["chain_id"]) + return fmt.Errorf("piece chain id's are mismatched, %s != %s", piece.ChainID, genChainID) } // combine the validator set @@ -237,7 +241,8 @@ func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, ge if len(ctx.Config.P2P.PersistentPeers) == 0 { comma = "" } - ctx.Config.P2P.PersistentPeers += fmt.Sprintf("%s%s@%s", comma, piece.NodeID, piece.IP) + //newPeer := fmt.Sprintf("%s%s@%s:46656", comma, piece.NodeID, piece.IP) + ctx.Config.P2P.PersistentPeers += fmt.Sprintf("%s%s@%s:46656", comma, piece.NodeID, piece.IP) configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get cfg.WriteConfigFile(configFilePath, ctx.Config) diff --git a/server/test_helpers.go b/server/test_helpers.go index 55b6caf43..382c77878 100644 --- a/server/test_helpers.go +++ b/server/test_helpers.go @@ -37,30 +37,6 @@ func setupViper(t *testing.T) func() { } } -// Begin the server pass up the channel to close -// NOTE pass up the channel so it can be closed at the end of the process -//func StartServer(t *testing.T, cdc *wire.Codec) chan error { -//defer setupViper(t)() - -//cfg, err := tcmd.ParseConfig() -//require.Nil(t, err) - -//// init server -//ctx := NewContext(cfg, log.NewNopLogger()) -//initCmd := InitCmd(ctx, cdc, mock.GenAppParams) -//err = initCmd.RunE(nil, nil) -//require.NoError(t, err) - -//// start server -//viper.Set(flagWithTendermint, true) -//startCmd := StartCmd(mock.NewApp, ctx) -//startCmd.Flags().Set(flagAddress, FreeTCPAddr(t)) // set to a new free address -//startCmd.Flags().Set("rpc.laddr", FreeTCPAddr(t)) // set to a new free address -//timeout := time.Duration(3) * time.Second - -//return RunOrTimeout(startCmd, timeout, t) -//} - // Run or Timout RunE of command passed in func RunOrTimeout(cmd *cobra.Command, timeout time.Duration, t *testing.T) chan error { done := make(chan error) diff --git a/server/util_test.go b/server/util_test.go index a21fe3882..13f8ad5db 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -9,8 +9,6 @@ import ( "github.com/stretchr/testify/require" ) -//func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMessage) (appended []byte, err error) { - func TestAppendJSON(t *testing.T) { cdc := wire.NewCodec() From d1402f4e922414e83206f622051a51a04cffa18f Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 24 Apr 2018 20:55:15 -0400 Subject: [PATCH 105/176] move waitForXxx funcs from lcd to tests.WaitForXxx --- client/lcd/helpers.go | 19 -------- client/lcd/lcd_test.go | 82 +++---------------------------- tests/util.go | 107 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 94 deletions(-) create mode 100644 tests/util.go diff --git a/client/lcd/helpers.go b/client/lcd/helpers.go index a64d44dfa..367e1a53d 100644 --- a/client/lcd/helpers.go +++ b/client/lcd/helpers.go @@ -7,33 +7,14 @@ import ( "os" "path/filepath" "strings" - "time" cmn "github.com/tendermint/tmlibs/common" cfg "github.com/tendermint/tendermint/config" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - rpcclient "github.com/tendermint/tendermint/rpc/lib/client" ) var globalConfig *cfg.Config -func waitForRPC() { - laddr := GetConfig().RPC.ListenAddress - fmt.Println("LADDR", laddr) - client := rpcclient.NewJSONRPCClient(laddr) - ctypes.RegisterAmino(client.Codec()) - result := new(ctypes.ResultStatus) - for { - _, err := client.Call("status", map[string]interface{}{}, result) - if err == nil { - return - } - fmt.Println("error", err) - time.Sleep(time.Millisecond) - } -} - // f**ing long, but unique for each test func makePathname() string { // get path diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 0b5c6b064..66a8a4085 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -10,7 +10,6 @@ import ( "os" "regexp" "testing" - "time" "github.com/spf13/viper" "github.com/stretchr/testify/assert" @@ -34,6 +33,7 @@ import ( keys "github.com/cosmos/cosmos-sdk/client/keys" bapp "github.com/cosmos/cosmos-sdk/examples/basecoin/app" btypes "github.com/cosmos/cosmos-sdk/examples/basecoin/types" + tests "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -157,7 +157,7 @@ func TestNodeStatus(t *testing.T) { func TestBlock(t *testing.T) { - waitForHeight(2) + tests.WaitForHeight(2, port) var resultBlock ctypes.ResultBlock @@ -224,7 +224,7 @@ func TestCoinSend(t *testing.T) { // create TX receiveAddr, resultTx := doSend(t, port, seed) - waitForHeight(resultTx.Height + 1) + tests.WaitForHeight(resultTx.Height+1, port) // check if tx was commited assert.Equal(t, uint32(0), resultTx.CheckTx.Code) @@ -253,7 +253,7 @@ func TestIBCTransfer(t *testing.T) { // create TX resultTx := doIBCTransfer(t, port, seed) - waitForHeight(resultTx.Height + 1) + tests.WaitForHeight(resultTx.Height+1, port) // check if tx was commited assert.Equal(t, uint32(0), resultTx.CheckTx.Code) @@ -286,7 +286,7 @@ func TestTxs(t *testing.T) { // create TX _, resultTx := doSend(t, port, seed) - waitForHeight(resultTx.Height + 1) + tests.WaitForHeight(resultTx.Height+1, port) // check if tx is findable res, body := request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil) @@ -380,7 +380,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { return nil, nil, err } - waitForStart() + tests.WaitForStart(port) return node, lcd, nil } @@ -407,7 +407,7 @@ func startTM(cfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc, p } // wait for rpc - waitForRPC() + tests.WaitForRPC(GetConfig().RPC.ListenAddress) logger.Info("Tendermint running!") return n, err @@ -490,71 +490,3 @@ func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroad return resultTx } - -func waitForHeight(height int64) { - for { - var resultBlock ctypes.ResultBlock - - url := fmt.Sprintf("http://localhost:%v%v", port, "/blocks/latest") - res, err := http.Get(url) - if err != nil { - panic(err) - } - - body, err := ioutil.ReadAll(res.Body) - if err != nil { - panic(err) - } - res.Body.Close() - - err = cdc.UnmarshalJSON([]byte(body), &resultBlock) - if err != nil { - fmt.Println("RES", res) - fmt.Println("BODY", string(body)) - panic(err) - } - - if resultBlock.Block.Height >= height { - return - } - time.Sleep(time.Millisecond * 100) - } -} - -// wait for 2 blocks -func waitForStart() { - waitHeight := int64(2) - for { - time.Sleep(time.Second) - - url := fmt.Sprintf("http://localhost:%v%v", port, "/blocks/latest") - res, err := http.Get(url) - if err != nil { - panic(err) - } - - // waiting for server to start ... - if res.StatusCode != http.StatusOK { - res.Body.Close() - continue - } - - body, err := ioutil.ReadAll(res.Body) - if err != nil { - panic(err) - } - res.Body.Close() - - resultBlock := new(ctypes.ResultBlock) - err = cdc.UnmarshalJSON([]byte(body), &resultBlock) - if err != nil { - fmt.Println("RES", res) - fmt.Println("BODY", string(body)) - panic(err) - } - - if resultBlock.Block.Height >= waitHeight { - return - } - } -} diff --git a/tests/util.go b/tests/util.go new file mode 100644 index 000000000..a6f026f24 --- /dev/null +++ b/tests/util.go @@ -0,0 +1,107 @@ +package tests + +import ( + "fmt" + "io/ioutil" + "net/http" + "time" + + amino "github.com/tendermint/go-amino" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + rpcclient "github.com/tendermint/tendermint/rpc/lib/client" +) + +// TODO: these functions just print to Stdout. +// consider using the logger. + +// Uses localhost +func WaitForHeight(height int64, port string) { + for { + var resultBlock ctypes.ResultBlock + + url := fmt.Sprintf("http://localhost:%v%v", port, "/blocks/latest") + res, err := http.Get(url) + if err != nil { + panic(err) + } + + body, err := ioutil.ReadAll(res.Body) + if err != nil { + panic(err) + } + res.Body.Close() + + err = cdc.UnmarshalJSON([]byte(body), &resultBlock) + if err != nil { + fmt.Println("RES", res) + fmt.Println("BODY", string(body)) + panic(err) + } + + if resultBlock.Block.Height >= height { + return + } + time.Sleep(time.Millisecond * 100) + } +} + +// wait for 2 blocks. +// uses localhost +func WaitForStart(port string) { + waitHeight := int64(2) + for { + time.Sleep(time.Second) + + url := fmt.Sprintf("http://localhost:%v%v", port, "/blocks/latest") + res, err := http.Get(url) + if err != nil { + panic(err) + } + + // waiting for server to start ... + if res.StatusCode != http.StatusOK { + res.Body.Close() + continue + } + + body, err := ioutil.ReadAll(res.Body) + if err != nil { + panic(err) + } + res.Body.Close() + + resultBlock := new(ctypes.ResultBlock) + err = cdc.UnmarshalJSON([]byte(body), &resultBlock) + if err != nil { + fmt.Println("RES", res) + fmt.Println("BODY", string(body)) + panic(err) + } + + if resultBlock.Block.Height >= waitHeight { + return + } + } +} + +// Wait for the RPC server to respond to /status +func WaitForRPC(laddr string) { + fmt.Println("LADDR", laddr) + client := rpcclient.NewJSONRPCClient(laddr) + ctypes.RegisterAmino(client.Codec()) + result := new(ctypes.ResultStatus) + for { + _, err := client.Call("status", map[string]interface{}{}, result) + if err == nil { + return + } + fmt.Printf("Waiting for RPC server to start on %s:%v\n", laddr, err) + time.Sleep(time.Millisecond) + } +} + +var cdc = amino.NewCodec() + +func init() { + ctypes.RegisterAmino(cdc) +} From 12f20d160a3096813254e6cbc4f634ee083e859e Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 25 Apr 2018 01:37:46 -0400 Subject: [PATCH 106/176] interim gen app tx refactor --- server/init.go | 326 ++++++++++++++++++++++--------------------------- 1 file changed, 147 insertions(+), 179 deletions(-) diff --git a/server/init.go b/server/init.go index 4420bdf01..edb256f8e 100644 --- a/server/init.go +++ b/server/init.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "io/ioutil" - "os" "path" "path/filepath" @@ -25,9 +24,82 @@ import ( dbm "github.com/tendermint/tmlibs/db" ) +// genesis piece structure for creating combined genesis +type GenesisTx struct { + NodeID string `json:"node_id"` + IP string `json:"ip"` + Validator tmtypes.GenesisValidator `json:"validator"` + AppGenTx json.RawMessage `json:"app_gen_tx"` +} + +var ( + flagOverwrite = "overwrite" + flagGenTxs = "gen-txs" + flagIP = "ip" + flagChainID = "ip" +) + +// get cmd to initialize all files for tendermint and application +func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { + cmd := &cobra.Command{ + Use: "gen-tx", + Short: "Create genesis transaction file (under [--home]/gentx-[nodeID].json)", + Args: cobra.NoArgs, + RunE: func(_ *cobra.Command, args []string) error { + + config := ctx.Config + nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) + if err != nil { + return err + } + nodeID := string(nodeKey.ID()) + pubKey := ReadOrCreatePrivValidator(config) + + appGenTx, toPrint, validator, err := appInit.GenAppTx(cdc, pubKey) + if err != nil { + return err + } + + ip := viper.GetString(flagIP) + if len(ip) == 0 { + ip, err = externalIP() + if err != nil { + return err + } + } + + tx := GenesisTx{ + NodeID: nodeID, + IP: ip, + Validator: validator, + AppGenTx: appGenTx, + } + bz, err := wire.MarshalJSONIndent(cdc, tx) + if err != nil { + return err + } + name := fmt.Sprintf("gentx-%v.json", nodeID) + file := filepath.Join(viper.GetString("home"), name) + if err != nil { + return err + err = cmn.WriteFile(file, bz, 0644) + } + + out, err := wire.MarshalJSONIndent(cdc, toPrint) + if err != nil { + return err + } + fmt.Println(string(out)) + return nil + }, + } + cmd.Flags().String(flagIP, "", "external facing IP to use if left blank IP will be retrieved from this machine") + cmd.Flags().AddFlagSet(appInit.FlagsAppTx) + return cmd +} + // get cmd to initialize all files for tendermint and application func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { - flagOverwrite, flagPieceFile, flagIP := "overwrite", "piece-file", "ip" cmd := &cobra.Command{ Use: "init", Short: "Initialize genesis config, priv-validator file, and p2p-node file", @@ -35,16 +107,46 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { RunE: func(_ *cobra.Command, _ []string) error { config := ctx.Config - pubkey := ReadOrCreatePrivValidator(config) - - chainID, validators, appState, cliPrint, err := appInit.GenAppParams(cdc, pubkey) + nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) if err != nil { return err } + nodeID := string(nodeKey.ID()) + pubKey := ReadOrCreatePrivValidator(config) + + chainID := viper.GetString(flagChainID) + if chainID == "" { + chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) + } genFile := config.GenesisFile() if !viper.GetBool(flagOverwrite) && cmn.FileExists(genFile) { - return fmt.Errorf("genesis config file already exists: %v", genFile) + return fmt.Errorf("genesis.json file already exists: %v", genFile) + } + + // process genesis transactions, or otherwise create one for defaults + var appGenTxs, cliPrints []json.RawMessage + var validators []tmtypes.GenesisValidator + var persistentPeers string + genTxsDir := viper.GetString(flagGenTxs) + if genTxsDir != "" { + validators, persistentPeers, appGenTxs, cliPrints = processGenTxs(genTxsDir, cdc, appInit) + config.P2P.PersistentPeers = persistentPeers + configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get + cfg.WriteConfigFile(configFilePath, config) + } else { + appTx, cliPrint, validator, err := appInit.GenAppTx(cdc, pubKey) + if err != nil { + return err + } + validators = []tmtypes.GenesisValidator{validator} + appGenTxs = []json.RawMessage{appTx} + cliPrints = []json.RawMessage{cliPrint} + } + + appState, err := appInit.GenAppParams(cdc, appGenTxs) + if err != nil { + return err } err = WriteGenesisFile(cdc, genFile, chainID, validators, appState) @@ -52,22 +154,15 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { return err } - nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) - if err != nil { - return err - } - nodeID := string(nodeKey.ID()) - // print out some key information - toPrint := struct { - ChainID string `json:"chain_id"` - NodeID string `json:"node_id"` - AppMessage json.RawMessage `json:"app_message"` + ChainID string `json:"chain_id"` + NodeID string `json:"node_id"` + AppMessage []json.RawMessage `json:"app_messages"` }{ chainID, nodeID, - cliPrint, + cliPrints, } out, err := wire.MarshalJSONIndent(cdc, toPrint) if err != nil { @@ -75,179 +170,51 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { } fmt.Println(string(out)) - // write the piece file is path specified - if viper.GetBool(flagPieceFile) { - //create the piece - ip := viper.GetString(flagIP) - if len(ip) == 0 { - ip, err = externalIP() - if err != nil { - return err - } - } - piece := GenesisPiece{ - ChainID: chainID, - NodeID: nodeID, - IP: ip, - AppState: appState, - Validators: validators, - } - bz, err := wire.MarshalJSONIndent(cdc, piece) - if err != nil { - return err - } - name := fmt.Sprintf("piece%v.json", nodeID) - file := filepath.Join(viper.GetString("home"), name) - return cmn.WriteFile(file, bz, 0644) - } - return nil }, } - if appInit.AppendAppState != nil { - cmd.AddCommand(FromPiecesCmd(ctx, cdc, appInit)) - cmd.Flags().BoolP(flagPieceFile, "a", false, "create an append file (under [--home]/[nodeID]piece.json) for others to import") - } - cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file") - cmd.Flags().String(flagIP, "", "external facing IP to use if left blank IP will be retrieved from this machine") - cmd.Flags().AddFlagSet(appInit.Flags) + cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file") + cmd.Flags().String(flagChainID, "", "designated chain-id for the genesis") + cmd.Flags().AddFlagSet(appInit.FlagsAppParams) return cmd } -// genesis piece structure for creating combined genesis -type GenesisPiece struct { - ChainID string `json:"chain_id"` - NodeID string `json:"node_id"` - IP string `json:"ip"` - AppState json.RawMessage `json:"app_state"` - Validators []tmtypes.GenesisValidator `json:"validators"` -} - -// get cmd to initialize all files for tendermint and application -func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { - return &cobra.Command{ - Use: "from-pieces [directory]", - Short: "Create genesis from directory of genesis pieces", - Args: cobra.ExactArgs(1), - RunE: func(_ *cobra.Command, args []string) error { - pieceDir := args[0] - - // ensure that the privVal and nodeKey file already exist - config := ctx.Config - privValFile := config.PrivValidatorFile() - nodeKeyFile := config.NodeKeyFile() - if !cmn.FileExists(privValFile) { - return fmt.Errorf("privVal file must already exist, please initialize with init cmd: %v", privValFile) - } - if !cmn.FileExists(nodeKeyFile) { - return fmt.Errorf("nodeKey file must already exist, please initialize with init cmd: %v", nodeKeyFile) - } - - // remove genFile for creation - genFile := config.GenesisFile() - os.Remove(genFile) - - // deterministically walk the directory for genesis-piece files to import - err := filepath.Walk(pieceDir, appendPiece(ctx, cdc, appInit, nodeKeyFile, genFile)) - if err != nil { - return err - } - - return nil - }, - } -} - // append a genesis-piece -func appendPiece(ctx *Context, cdc *wire.Codec, appInit AppInit, nodeKeyFile, genFile string) filepath.WalkFunc { - return func(pieceFile string, _ os.FileInfo, err error) error { - fmt.Printf("debug pieceFile: %v\n", pieceFile) - if err != nil { - return err - } - if path.Ext(pieceFile) != ".json" { +func processGenTxs(genTxsDir string, cdc *wire.Codec, appInit AppInit) ( + validators []tmtypes.GenesisValidator, appGenTxs, cliPrints []json.RawMessage, persistentPeers string, err error) { + + fos, err := ioutil.ReadDir(genTxsDir) + for _, fo := range fos { + filename := fo.Name() + if !fo.IsDir() && (path.Ext(filename) != ".json") { return nil } - // get the piece file bytes - bz, err := ioutil.ReadFile(pieceFile) + // get the genTx + bz, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + var genTx GenesisTx + err = cdc.UnmarshalJSON(bz, &genTx) if err != nil { return err } - // get the piece - var piece GenesisPiece - err = cdc.UnmarshalJSON(bz, &piece) - if err != nil { - return err - } + // combine some stuff + validators = append(validators, genTx.Validator) + appGenTxs = append(appGenTxs, genTx.AppGenTxs) + cliPrints = append(cliPrints, genTx.CliPrints) - // if the first file, create the genesis from scratch with piece inputs - if !cmn.FileExists(genFile) { - return WriteGenesisFile(cdc, genFile, piece.ChainID, piece.Validators, piece.AppState) - } - - // read in the genFile - bz, err = ioutil.ReadFile(genFile) - if err != nil { - return err - } - var genMap map[string]json.RawMessage - err = cdc.UnmarshalJSON(bz, &genMap) - if err != nil { - return err - } - appState := genMap["app_state"] - - // verify chain-ids are the same - var genChainID string - err = cdc.UnmarshalJSON(genMap["chain_id"], &genChainID) - if err != nil { - return err - } - if piece.ChainID != genChainID { - return fmt.Errorf("piece chain id's are mismatched, %s != %s", piece.ChainID, genChainID) - } - - // combine the validator set - var validators []tmtypes.GenesisValidator - err = cdc.UnmarshalJSON(genMap["validators"], &validators) - if err != nil { - return err - } - validators = append(validators, piece.Validators...) - - // combine the app state - appState, err = appInit.AppendAppState(cdc, appState, piece.AppState) - if err != nil { - return err - } - - // write the appended genesis file - err = WriteGenesisFile(cdc, genFile, piece.ChainID, validators, appState) - if err != nil { - return err - } - - // Add a persistent peer if the config (if it's not me) - myIP, err := externalIP() - if err != nil { - return err - } - if myIP == piece.IP { - return nil - } + // Add a persistent peer comma := "," - if len(ctx.Config.P2P.PersistentPeers) == 0 { + if len(persistentPeers) == 0 { comma = "" } - //newPeer := fmt.Sprintf("%s%s@%s:46656", comma, piece.NodeID, piece.IP) - ctx.Config.P2P.PersistentPeers += fmt.Sprintf("%s%s@%s:46656", comma, piece.NodeID, piece.IP) - configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get - cfg.WriteConfigFile(configFilePath, ctx.Config) - - return nil + persistentPeers += fmt.Sprintf("%s%s@%s:46656", comma, piece.NodeID, piece.IP) } + + return nil } //________________________________________________________________________________________ @@ -299,15 +266,17 @@ func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState js // Core functionality passed from the application to the server init command type AppInit struct { - // flags required for GenAppParams - Flags *pflag.FlagSet + // flags required for application init functions + FlagsAppParams *pflag.FlagSet + FlagsAppTx *pflag.FlagSet // GenAppParams creates the core parameters initialization. It takes in a // pubkey meant to represent the pubkey of the validator of this machine. - GenAppParams func(*wire.Codec, crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) + GenAppParams func(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) - // append appState1 with appState2 - AppendAppState func(cdc *wire.Codec, appState1, appState2 json.RawMessage) (appState json.RawMessage, err error) + // create the application genesis tx + GenAppTx func(cdc *wire.Codec, pk crypto.PubKey) ( + appTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) } // simple default application init @@ -316,7 +285,8 @@ var DefaultAppInit = AppInit{ } // Create one account with a whole bunch of mycoin in it -func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { +func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey, _ json.RawMessage) ( + validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { var addr sdk.Address @@ -330,8 +300,6 @@ func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, bz, err := cdc.MarshalJSON(mm) cliPrint = json.RawMessage(bz) - chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) - validators = []tmtypes.GenesisValidator{{ PubKey: pubKey, Power: 10, From b9477ecbbec2a537a57db5c6d95839e07ccc0b4b Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 25 Apr 2018 16:12:14 -0400 Subject: [PATCH 107/176] init refactor uses genesis transaction now --- cmd/gaia/app/app.go | 183 +++++++++++------------- cmd/gaia/cli_test/cli_test.go | 61 ++++---- examples/democoin/cmd/democoind/main.go | 9 +- mock/app.go | 24 ++-- mock/app_test.go | 5 +- server/init.go | 149 ++++++++++++------- server/init_test.go | 3 +- server/start_test.go | 6 +- 8 files changed, 237 insertions(+), 203 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 37c062595..eb63c6f1a 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -3,7 +3,6 @@ package app import ( "encoding/json" "errors" - "strings" "github.com/spf13/pflag" "github.com/spf13/viper" @@ -185,141 +184,123 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { } var ( - flagAccounts = "accounts" - flagChainID = "chain-id" - flagOWK = "overwrite-keys" + flagName = "name" + //flagOWK = "overwrite-keys" ) // get app init parameters for server init command func GaiaAppInit() server.AppInit { - fs := pflag.NewFlagSet("", pflag.ContinueOnError) - fs.String(flagAccounts, "foobar-10fermion,10baz-true", "genesis accounts in form: name1-coins-isval:name2-coins-isval:...") - fs.String(flagChainID, "", "genesis file chain-id, if left blank will be randomly created") - fs.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail") + fsAppGenState := pflag.NewFlagSet("", pflag.ContinueOnError) + //fsAppGenState.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail") + + fsAppGenTx := pflag.NewFlagSet("", pflag.ContinueOnError) + fsAppGenTx.String(flagName, "", "validator moniker, if left blank, do not add validator") + return server.AppInit{ - Flags: fs, - GenAppParams: GaiaGenAppParams, - AppendAppState: GaiaAppendAppState, + FlagsAppGenState: fsAppGenState, + FlagsAppGenTx: fsAppGenTx, + AppGenState: GaiaAppGenState, + AppGenTx: GaiaAppGenTx, } } +// simple genesis tx +type GaiaGenTx struct { + Name string `json:"name"` + Address sdk.Address `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` +} + +// power given to validators in gaia init functions +var FreePower = int64(100) + // Create the core parameters for genesis initialization for gaia // note that the pubkey input is this machines pubkey -func GaiaGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { +func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { - printMap := make(map[string]string) - var candidates []stake.Candidate - poolAssets := int64(0) - - chainID = viper.GetString(flagChainID) - if len(chainID) == 0 { - chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6)) + if len(appGenTxs) == 0 { + err = errors.New("must provide at least genesis transaction") + return } + // start with the default staking genesis state + stakeData := stake.GetDefaultGenesisState() + // get genesis flag account information - accountsStr := viper.GetString(flagAccounts) - accounts := strings.Split(accountsStr, ":") - genaccs := make([]GenesisAccount, len(accounts)) - for i, account := range accounts { - p := strings.Split(account, "-") - if len(p) != 3 { - err = errors.New("input account has bad form, each account must be in form name-coins-isval, for example: foobar-10fermion,10baz-true") - return - } - name := p[0] - var coins sdk.Coins - coins, err = sdk.ParseCoins(p[1]) - if err != nil { - return - } - isValidator := false - if p[2] == "true" { - isValidator = true - } + genaccs := make([]GenesisAccount, len(appGenTxs)) + for i, appGenTx := range appGenTxs { - var addr sdk.Address - var secret string - addr, secret, err = server.GenerateCoinKey() + var genTx GaiaGenTx + err = cdc.UnmarshalJSON(appGenTx, &genTx) if err != nil { return } - printMap["secret-"+name] = secret - - // create the genesis account - accAuth := auth.NewBaseAccountWithAddress(addr) - accAuth.Coins = coins + // create the genesis account, give'm few fermions and a buncha token with there name + accAuth := auth.NewBaseAccountWithAddress(genTx.Address) + accAuth.Coins = sdk.Coins{ + {genTx.Name + "Token", 1000}, + {"fermion", 50}, + } acc := NewGenesisAccount(&accAuth) genaccs[i] = acc // add the validator - if isValidator { + if len(genTx.Name) > 0 { + desc := stake.NewDescription(genTx.Name, "", "", "") + candidate := stake.NewCandidate(genTx.Address, genTx.PubKey, desc) + candidate.Assets = sdk.NewRat(FreePower) + stakeData.Candidates = append(stakeData.Candidates, candidate) - // only use this machines pubkey the first time, all others are dummies - var pk crypto.PubKey - if i == 0 { - pk = pubKey - } else { - pk = crypto.GenPrivKeyEd25519().PubKey() - } - - freePower := int64(100) - validator := tmtypes.GenesisValidator{ - PubKey: pk, - Power: freePower, - } - desc := stake.NewDescription(name, "", "", "") - candidate := stake.NewCandidate(addr, pk, desc) - candidate.Assets = sdk.NewRat(freePower) - poolAssets += freePower - validators = append(validators, validator) - candidates = append(candidates, candidate) + // pool logic + stakeData.Pool.TotalSupply += FreePower + stakeData.Pool.BondedPool += FreePower + stakeData.Pool.BondedShares = sdk.NewRat(stakeData.Pool.BondedPool) } } - // create the print message - bz, err := cdc.MarshalJSON(printMap) - cliPrint = json.RawMessage(bz) - - stakeData := stake.GetDefaultGenesisState() - stakeData.Candidates = candidates - - // assume everything is bonded from the get-go - stakeData.Pool.TotalSupply = poolAssets - stakeData.Pool.BondedPool = poolAssets - stakeData.Pool.BondedShares = sdk.NewRat(poolAssets) - + // create the final app state genesisState := GenesisState{ Accounts: genaccs, StakeData: stakeData, } - appState, err = wire.MarshalJSONIndent(cdc, genesisState) return } -// append gaia app_state together, stitch the accounts together take the -// staking parameters from the first appState -func GaiaAppendAppState(cdc *wire.Codec, appState1, appState2 json.RawMessage) (appState json.RawMessage, err error) { - var genState1, genState2 GenesisState - err = cdc.UnmarshalJSON(appState1, &genState1) - if err != nil { - panic(err) - } - err = cdc.UnmarshalJSON(appState2, &genState2) - if err != nil { - panic(err) - } - genState1.Accounts = append(genState1.Accounts, genState2.Accounts...) - genState1.StakeData.Candidates = append(genState1.StakeData.Candidates, genState2.StakeData.Candidates...) +// Generate a gaia genesis transaction +func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { - // pool logic - CombinedSupply := genState1.StakeData.Pool.TotalSupply + genState2.StakeData.Pool.TotalSupply - CombinedBondedPool := genState1.StakeData.Pool.BondedPool + genState2.StakeData.Pool.BondedPool - CombinedBondedShares := genState1.StakeData.Pool.BondedShares.Add(genState2.StakeData.Pool.BondedShares) - genState1.StakeData.Pool.TotalSupply = CombinedSupply - genState1.StakeData.Pool.BondedPool = CombinedBondedPool - genState1.StakeData.Pool.BondedShares = CombinedBondedShares + var addr sdk.Address + var secret string + addr, secret, err = server.GenerateCoinKey() + if err != nil { + return + } - return cdc.MarshalJSON(genState1) + var bz []byte + gaiaGenTx := GaiaGenTx{ + Name: viper.GetString(flagName), + Address: addr, + PubKey: pk, + } + bz, err = wire.MarshalJSONIndent(cdc, gaiaGenTx) + 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: FreePower, + } + return } diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index b3b2c4e7e..b70d25551 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -23,8 +23,7 @@ func TestGaiaCLISend(t *testing.T) { pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) executeWrite(t, "gaiacli keys delete bar", pass) - keys, chainID := executeInit(t, "gaiad init -o --accounts=foo-100000fermion-true", "foo") - require.Equal(t, 1, len(keys)) + key, chainID := executeInit(t, "gaiad init -o --name=foo") // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) @@ -34,14 +33,14 @@ func TestGaiaCLISend(t *testing.T) { cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - executeWrite(t, "gaiacli keys add foo --recover", pass, keys[0]) + executeWrite(t, "gaiacli keys add foo --recover", pass, key) executeWrite(t, "gaiacli keys add bar", pass) fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json") fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("fermion")) executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass @@ -49,7 +48,7 @@ func TestGaiaCLISend(t *testing.T) { barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("fermion")) } func TestGaiaCLIDeclareCandidacy(t *testing.T) { @@ -57,8 +56,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { tests.ExecuteT(t, "gaiad unsafe_reset_all", 1) pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) - keys, chainID := executeInit(t, "gaiad init -o --accounts=bar-100000fermion-true:foo-100000fermion-false", "bar", "foo") - require.Equal(t, 2, len(keys)) + key, chainID := executeInit(t, "gaiad init -o --name=foo") // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) @@ -68,41 +66,46 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - executeWrite(t, "gaiacli keys add foo --recover", pass, keys[1]) - fooAddr, fooPubKey := executeGetAddrPK(t, "gaiacli keys show foo --output=json") + executeWrite(t, "gaiacli keys add foo --recover", pass, key) + executeWrite(t, "gaiacli keys add bar", pass) + fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") + barAddr, barPubKey := executeGetAddrPK(t, "gaiacli keys show bar --output=json") + time.Sleep(time.Second * 3) // waiting for some blocks to pass + barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) + assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("fermion")) // declare candidacy declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags) - declStr += fmt.Sprintf(" --name=%v", "foo") - declStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) - declStr += fmt.Sprintf(" --pubkey=%v", fooPubKey) + declStr += fmt.Sprintf(" --name=%v", "bar") + declStr += fmt.Sprintf(" --address-candidate=%v", barAddr) + declStr += fmt.Sprintf(" --pubkey=%v", barPubKey) declStr += fmt.Sprintf(" --amount=%v", "3fermion") - declStr += fmt.Sprintf(" --moniker=%v", "foo-vally") + declStr += fmt.Sprintf(" --moniker=%v", "bar-vally") fmt.Printf("debug declStr: %v\n", declStr) executeWrite(t, declStr, pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass - fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(99997), fooAcc.GetCoins().AmountOf("fermion")) - candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr)) - assert.Equal(t, candidate.Address.String(), fooAddr) + barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) + assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("fermion")) + candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) + assert.Equal(t, candidate.Address.String(), barAddr) assert.Equal(t, int64(3), candidate.Assets.Evaluate()) // TODO timeout issues if not connected to the internet // unbond a single share //unbondStr := fmt.Sprintf("gaiacli unbond %v", flags) - //unbondStr += fmt.Sprintf(" --name=%v", "foo") - //unbondStr += fmt.Sprintf(" --address-candidate=%v", fooAddr) - //unbondStr += fmt.Sprintf(" --address-delegator=%v", fooAddr) + //unbondStr += fmt.Sprintf(" --name=%v", "bar") + //unbondStr += fmt.Sprintf(" --address-candidate=%v", barAddr) + //unbondStr += fmt.Sprintf(" --address-delegator=%v", barAddr) //unbondStr += fmt.Sprintf(" --shares=%v", "1") //unbondStr += fmt.Sprintf(" --sequence=%v", "1") //fmt.Printf("debug unbondStr: %v\n", unbondStr) //executeWrite(t, unbondStr, pass) //time.Sleep(time.Second * 3) // waiting for some blocks to pass - //fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - //assert.Equal(t, int64(99998), fooAcc.GetCoins().AmountOf("fermion")) - //candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr)) + //barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) + //assert.Equal(t, int64(99998), barAcc.GetCoins().AmountOf("fermion")) + //candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) //assert.Equal(t, int64(2), candidate.Assets.Evaluate()) } @@ -130,7 +133,7 @@ func executeWritePrint(t *testing.T, cmdStr string, writes ...string) { fmt.Printf("debug read: %v\n", string(bz)) } -func executeInit(t *testing.T, cmdStr string, names ...string) (keys []string, chainID string) { +func executeInit(t *testing.T, cmdStr string) (key, chainID string) { out := tests.ExecuteT(t, cmdStr, 1) var initRes map[string]json.RawMessage @@ -144,12 +147,8 @@ func executeInit(t *testing.T, cmdStr string, names ...string) (keys []string, c err = json.Unmarshal(initRes["app_message"], &appMessageRes) require.NoError(t, err) - for _, name := range names { - var key string - err = json.Unmarshal(appMessageRes["secret-"+name], &key) - require.NoError(t, err) - keys = append(keys, key) - } + err = json.Unmarshal(appMessageRes["secret"], &key) + require.NoError(t, err) return } diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 0eb378005..afca80bce 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -8,8 +8,6 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" - tmtypes "github.com/tendermint/tendermint/types" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -21,12 +19,13 @@ import ( // init parameters var CoolAppInit = server.AppInit{ - GenAppParams: CoolGenAppParams, + AppGenState: CoolAppGenState, + AppGenTx: server.SimpleAppGenTx, } // coolGenAppParams sets up the app_state and appends the cool app state -func CoolGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { - chainID, validators, appState, cliPrint, err = server.SimpleGenAppParams(cdc, pubKey) +func CoolAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { + appState, err = server.SimpleAppGenState(cdc, appGenTxs) if err != nil { return } diff --git a/mock/app.go b/mock/app.go index 09f09b830..84f762db0 100644 --- a/mock/app.go +++ b/mock/app.go @@ -8,7 +8,6 @@ import ( abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" tmtypes "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -106,17 +105,9 @@ func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci } } -// GenAppParams can be passed into InitCmd, returns a static string of a few +// AppGenState can be passed into InitCmd, returns a static string of a few // key-values that can be parsed by InitChainer -func GenAppParams(_ *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { - - chainID = fmt.Sprintf("test-chain-%v", cmn.RandStr(6)) - - validators = []tmtypes.GenesisValidator{{ - PubKey: pubKey, - Power: 10, - }} - +func AppGenState(_ *wire.Codec, _ []json.RawMessage) (appState json.RawMessage, err error) { appState = json.RawMessage(`{ "values": [ { @@ -131,3 +122,14 @@ func GenAppParams(_ *wire.Codec, pubKey crypto.PubKey) (chainID string, validato }`) return } + +// Return a validator, not much else +func AppGenTx(_ *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { + + validator = tmtypes.GenesisValidator{ + PubKey: pk, + Power: 10, + } + return +} diff --git a/mock/app_test.go b/mock/app_test.go index fe0948a84..7c84f9a1d 100644 --- a/mock/app_test.go +++ b/mock/app_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" ) // TestInitApp makes sure we can initialize this thing without an error @@ -22,9 +21,9 @@ func TestInitApp(t *testing.T) { require.NoError(t, err) // initialize it future-way - pubKey := crypto.GenPrivKeyEd25519().PubKey() - _, _, appState, _, err := GenAppParams(nil, pubKey) + appState, err := AppGenState(nil, nil) require.NoError(t, err) + //TODO test validators in the init chain? req := abci.RequestInitChain{ AppStateBytes: appState, diff --git a/server/init.go b/server/init.go index edb256f8e..5916e3834 100644 --- a/server/init.go +++ b/server/init.go @@ -4,11 +4,13 @@ import ( "encoding/json" "fmt" "io/ioutil" + "os" "path" "path/filepath" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" @@ -30,13 +32,14 @@ type GenesisTx struct { IP string `json:"ip"` Validator tmtypes.GenesisValidator `json:"validator"` AppGenTx json.RawMessage `json:"app_gen_tx"` + CLIPrint json.RawMessage `json:"cli_print"` } var ( flagOverwrite = "overwrite" flagGenTxs = "gen-txs" flagIP = "ip" - flagChainID = "ip" + flagChainID = "chain-id" ) // get cmd to initialize all files for tendermint and application @@ -55,7 +58,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { nodeID := string(nodeKey.ID()) pubKey := ReadOrCreatePrivValidator(config) - appGenTx, toPrint, validator, err := appInit.GenAppTx(cdc, pubKey) + appGenTx, cliPrint, validator, err := appInit.AppGenTx(cdc, pubKey) if err != nil { return err } @@ -73,6 +76,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { IP: ip, Validator: validator, AppGenTx: appGenTx, + CLIPrint: cliPrint, } bz, err := wire.MarshalJSONIndent(cdc, tx) if err != nil { @@ -85,7 +89,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { err = cmn.WriteFile(file, bz, 0644) } - out, err := wire.MarshalJSONIndent(cdc, toPrint) + out, err := wire.MarshalJSONIndent(cdc, cliPrint) if err != nil { return err } @@ -94,7 +98,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { }, } cmd.Flags().String(flagIP, "", "external facing IP to use if left blank IP will be retrieved from this machine") - cmd.Flags().AddFlagSet(appInit.FlagsAppTx) + cmd.Flags().AddFlagSet(appInit.FlagsAppGenTx) return cmd } @@ -125,26 +129,31 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { } // process genesis transactions, or otherwise create one for defaults - var appGenTxs, cliPrints []json.RawMessage + var appMessage json.RawMessage + var appGenTxs []json.RawMessage var validators []tmtypes.GenesisValidator var persistentPeers string + genTxsDir := viper.GetString(flagGenTxs) if genTxsDir != "" { - validators, persistentPeers, appGenTxs, cliPrints = processGenTxs(genTxsDir, cdc, appInit) + validators, appGenTxs, persistentPeers, err = processGenTxs(genTxsDir, cdc, appInit) + if err != nil { + return err + } config.P2P.PersistentPeers = persistentPeers configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get cfg.WriteConfigFile(configFilePath, config) } else { - appTx, cliPrint, validator, err := appInit.GenAppTx(cdc, pubKey) + appGenTx, am, validator, err := appInit.AppGenTx(cdc, pubKey) + appMessage = am if err != nil { return err } validators = []tmtypes.GenesisValidator{validator} - appGenTxs = []json.RawMessage{appTx} - cliPrints = []json.RawMessage{cliPrint} + appGenTxs = []json.RawMessage{appGenTx} } - appState, err := appInit.GenAppParams(cdc, appGenTxs) + appState, err := appInit.AppGenState(cdc, appGenTxs) if err != nil { return err } @@ -156,13 +165,13 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { // print out some key information toPrint := struct { - ChainID string `json:"chain_id"` - NodeID string `json:"node_id"` - AppMessage []json.RawMessage `json:"app_messages"` + ChainID string `json:"chain_id"` + NodeID string `json:"node_id"` + AppMessage json.RawMessage `json:"app_message"` }{ chainID, nodeID, - cliPrints, + appMessage, } out, err := wire.MarshalJSONIndent(cdc, toPrint) if err != nil { @@ -174,47 +183,55 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { }, } cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file") - cmd.Flags().String(flagChainID, "", "designated chain-id for the genesis") - cmd.Flags().AddFlagSet(appInit.FlagsAppParams) + cmd.Flags().String(flagChainID, "", "genesis file chain-id, if left blank will be randomly created") + cmd.Flags().String(flagGenTxs, "", "directory containing the genesis transactions") + cmd.Flags().AddFlagSet(appInit.FlagsAppGenState) + cmd.Flags().AddFlagSet(appInit.FlagsAppGenTx) // need to add this flagset for when no GenTx's provided + cmd.AddCommand(GenTxCmd(ctx, cdc, appInit)) return cmd } // append a genesis-piece func processGenTxs(genTxsDir string, cdc *wire.Codec, appInit AppInit) ( - validators []tmtypes.GenesisValidator, appGenTxs, cliPrints []json.RawMessage, persistentPeers string, err error) { + validators []tmtypes.GenesisValidator, appGenTxs []json.RawMessage, persistentPeers string, err error) { - fos, err := ioutil.ReadDir(genTxsDir) + // XXX sort the files by contents just incase people renamed their files + var fos []os.FileInfo + fos, err = ioutil.ReadDir(genTxsDir) + if err != nil { + return + } for _, fo := range fos { filename := fo.Name() if !fo.IsDir() && (path.Ext(filename) != ".json") { - return nil + return } // get the genTx - bz, err := ioutil.ReadFile(filename) + var bz []byte + bz, err = ioutil.ReadFile(filename) if err != nil { - return err + return } var genTx GenesisTx err = cdc.UnmarshalJSON(bz, &genTx) if err != nil { - return err + return } // combine some stuff validators = append(validators, genTx.Validator) - appGenTxs = append(appGenTxs, genTx.AppGenTxs) - cliPrints = append(cliPrints, genTx.CliPrints) + appGenTxs = append(appGenTxs, genTx.AppGenTx) // Add a persistent peer comma := "," if len(persistentPeers) == 0 { comma = "" } - persistentPeers += fmt.Sprintf("%s%s@%s:46656", comma, piece.NodeID, piece.IP) + persistentPeers += fmt.Sprintf("%s%s@%s:46656", comma, genTx.NodeID, genTx.IP) } - return nil + return } //________________________________________________________________________________________ @@ -267,43 +284,44 @@ func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState js type AppInit struct { // flags required for application init functions - FlagsAppParams *pflag.FlagSet - FlagsAppTx *pflag.FlagSet + FlagsAppGenState *pflag.FlagSet + FlagsAppGenTx *pflag.FlagSet - // GenAppParams creates the core parameters initialization. It takes in a + // AppGenState creates the core parameters initialization. It takes in a // pubkey meant to represent the pubkey of the validator of this machine. - GenAppParams func(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) + AppGenState func(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) // create the application genesis tx - GenAppTx func(cdc *wire.Codec, pk crypto.PubKey) ( - appTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) + AppGenTx func(cdc *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) } +//_____________________________________________________________________ + // simple default application init var DefaultAppInit = AppInit{ - GenAppParams: SimpleGenAppParams, + AppGenState: SimpleAppGenState, + AppGenTx: SimpleAppGenTx, } -// Create one account with a whole bunch of mycoin in it -func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey, _ json.RawMessage) ( - validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) { +// simple genesis tx +type SimpleGenTx struct { + Addr sdk.Address `json:"addr"` +} - var addr sdk.Address +// create the genesis app state +func SimpleAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { - var secret string - addr, secret, err = GenerateCoinKey() - if err != nil { + if len(appGenTxs) != 1 { + err = errors.New("must provide a single genesis transaction") return } - mm := map[string]string{"secret": secret} - bz, err := cdc.MarshalJSON(mm) - cliPrint = json.RawMessage(bz) - - validators = []tmtypes.GenesisValidator{{ - PubKey: pubKey, - Power: 10, - }} + var genTx SimpleGenTx + err = cdc.UnmarshalJSON(appGenTxs[0], &genTx) + if err != nil { + return + } appState = json.RawMessage(fmt.Sprintf(`{ "accounts": [{ @@ -315,7 +333,40 @@ func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey, _ json.RawMessage } ] }] -}`, addr.String())) +}`, genTx.Addr.String())) + return +} + +// Generate a genesis transaction +func SimpleAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { + + var addr sdk.Address + var secret string + addr, secret, err = GenerateCoinKey() + if err != nil { + return + } + + var bz []byte + simpleGenTx := SimpleGenTx{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 } diff --git a/server/init_test.go b/server/init_test.go index 5db483516..1bdf0a085 100644 --- a/server/init_test.go +++ b/server/init_test.go @@ -21,7 +21,8 @@ func TestInit(t *testing.T) { ctx := NewContext(cfg, logger) cdc := wire.NewCodec() appInit := AppInit{ - GenAppParams: mock.GenAppParams, + AppGenState: mock.AppGenState, + AppGenTx: mock.AppGenTx, } cmd := InitCmd(ctx, cdc, appInit) err = cmd.RunE(nil, nil) diff --git a/server/start_test.go b/server/start_test.go index 85f1a7135..3bf2eac7e 100644 --- a/server/start_test.go +++ b/server/start_test.go @@ -28,7 +28,8 @@ func TestStartStandAlone(t *testing.T) { ctx := NewContext(cfg, logger) cdc := wire.NewCodec() appInit := AppInit{ - GenAppParams: mock.GenAppParams, + AppGenState: mock.AppGenState, + AppGenTx: mock.AppGenTx, } initCmd := InitCmd(ctx, cdc, appInit) err = initCmd.RunE(nil, nil) @@ -58,7 +59,8 @@ func TestStartWithTendermint(t *testing.T) { ctx := NewContext(cfg, logger) cdc := wire.NewCodec() appInit := AppInit{ - GenAppParams: mock.GenAppParams, + AppGenState: mock.AppGenState, + AppGenTx: mock.AppGenTx, } initCmd := InitCmd(ctx, cdc, appInit) err = initCmd.RunE(nil, nil) From 7e2ac801377fb8947540c3b19be037cecdfc0683 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 25 Apr 2018 16:38:13 -0400 Subject: [PATCH 108/176] cli testing fix --- cmd/gaia/cli_test/cli_test.go | 29 +++++++++++++++++++---------- tests/gobash.go | 11 ++++------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index b70d25551..00d94861d 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -13,13 +13,14 @@ import ( "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/tests" + "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/stake" ) func TestGaiaCLISend(t *testing.T) { - tests.ExecuteT(t, "gaiad unsafe_reset_all", 1) + tests.ExecuteT(t, "gaiad unsafe_reset_all") pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) executeWrite(t, "gaiacli keys delete bar", pass) @@ -53,9 +54,10 @@ func TestGaiaCLISend(t *testing.T) { func TestGaiaCLIDeclareCandidacy(t *testing.T) { - tests.ExecuteT(t, "gaiad unsafe_reset_all", 1) + tests.ExecuteT(t, "gaiad unsafe_reset_all") pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) + executeWrite(t, "gaiacli keys delete bar", pass) key, chainID := executeInit(t, "gaiad init -o --name=foo") // get a free port, also setup some common flags @@ -70,11 +72,14 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { executeWrite(t, "gaiacli keys add bar", pass) fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") barAddr, barPubKey := executeGetAddrPK(t, "gaiacli keys show bar --output=json") + + executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass - barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) - assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) + fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("fermion")) + barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) + assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) // declare candidacy declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags) @@ -85,7 +90,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { declStr += fmt.Sprintf(" --moniker=%v", "bar-vally") fmt.Printf("debug declStr: %v\n", declStr) executeWrite(t, declStr, pass) - time.Sleep(time.Second * 3) // waiting for some blocks to pass + time.Sleep(time.Second) // waiting for some blocks to pass barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("fermion")) candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) @@ -116,6 +121,7 @@ func executeWrite(t *testing.T, cmdStr string, writes ...string) { _, err := wc.Write([]byte(write + "\n")) require.NoError(t, err) } + fmt.Printf("debug waiting cmdStr: %v\n", cmdStr) cmd.Wait() } @@ -126,6 +132,7 @@ func executeWritePrint(t *testing.T, cmdStr string, writes ...string) { _, err := wc.Write([]byte(write + "\n")) require.NoError(t, err) } + fmt.Printf("debug waiting cmdStr: %v\n", cmdStr) cmd.Wait() bz := make([]byte, 100000) @@ -134,7 +141,7 @@ func executeWritePrint(t *testing.T, cmdStr string, writes ...string) { } func executeInit(t *testing.T, cmdStr string) (key, chainID string) { - out := tests.ExecuteT(t, cmdStr, 1) + out := tests.ExecuteT(t, cmdStr) var initRes map[string]json.RawMessage err := json.Unmarshal([]byte(out), &initRes) @@ -154,26 +161,28 @@ func executeInit(t *testing.T, cmdStr string) (key, chainID string) { } func executeGetAddrPK(t *testing.T, cmdStr string) (addr, pubKey string) { - out := tests.ExecuteT(t, cmdStr, 2) + out := tests.ExecuteT(t, cmdStr) var ko keys.KeyOutput keys.UnmarshalJSON([]byte(out), &ko) return ko.Address, ko.PubKey } func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { - out := tests.ExecuteT(t, cmdStr, 2) + out := tests.ExecuteT(t, cmdStr) var initRes map[string]json.RawMessage err := json.Unmarshal([]byte(out), &initRes) require.NoError(t, err, "out %v, err %v", out, err) value := initRes["value"] var acc auth.BaseAccount - _ = json.Unmarshal(value, &acc) //XXX pubkey can't be decoded go amino issue + cdc := wire.NewCodec() + wire.RegisterCrypto(cdc) + err = cdc.UnmarshalJSON(value, &acc) require.NoError(t, err, "value %v, err %v", string(value), err) return acc } func executeGetCandidate(t *testing.T, cmdStr string) stake.Candidate { - out := tests.ExecuteT(t, cmdStr, 2) + out := tests.ExecuteT(t, cmdStr) var candidate stake.Candidate cdc := app.MakeCodec() err := cdc.UnmarshalJSON([]byte(out), &candidate) diff --git a/tests/gobash.go b/tests/gobash.go index c106c1f3f..baa84f417 100644 --- a/tests/gobash.go +++ b/tests/gobash.go @@ -1,7 +1,6 @@ package tests import ( - "fmt" "io" "os/exec" "strings" @@ -27,13 +26,11 @@ func getCmd(t *testing.T, command string) *exec.Cmd { } // Execute the command, return standard output and error, try a few times if requested -func ExecuteT(t *testing.T, command string, trials int) (out string) { +func ExecuteT(t *testing.T, command string) (out string) { cmd := getCmd(t, command) bz, err := cmd.CombinedOutput() - if err != nil && trials > 1 { - fmt.Printf("trial %v, retrying: %v\n", trials, command) - time.Sleep(time.Second * 10) - return ExecuteT(t, command, trials-1) + if err != nil { + panic(err) } require.NoError(t, err, string(bz)) out = strings.Trim(string(bz), "\n") //trim any new lines @@ -48,7 +45,7 @@ func GoExecuteT(t *testing.T, command string) (cmd *exec.Cmd, pipeIn io.WriteClo require.NoError(t, err) pipeOut, err = cmd.StdoutPipe() require.NoError(t, err) - go cmd.Start() + cmd.Start() time.Sleep(time.Second) return cmd, pipeIn, pipeOut } From d1c6216c0f554525a6cd2ed4349b5acdc4e556b0 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 25 Apr 2018 17:17:40 -0400 Subject: [PATCH 109/176] gen-tx fix --- server/init.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/server/init.go b/server/init.go index 5916e3834..98b724caf 100644 --- a/server/init.go +++ b/server/init.go @@ -32,7 +32,6 @@ type GenesisTx struct { IP string `json:"ip"` Validator tmtypes.GenesisValidator `json:"validator"` AppGenTx json.RawMessage `json:"app_gen_tx"` - CLIPrint json.RawMessage `json:"cli_print"` } var ( @@ -76,20 +75,28 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { IP: ip, Validator: validator, AppGenTx: appGenTx, - CLIPrint: cliPrint, } bz, err := wire.MarshalJSONIndent(cdc, tx) if err != nil { return err } + genTxFile := json.RawMessage(bz) name := fmt.Sprintf("gentx-%v.json", nodeID) file := filepath.Join(viper.GetString("home"), name) + err = cmn.WriteFile(file, bz, 0644) if err != nil { return err - err = cmn.WriteFile(file, bz, 0644) } - out, err := wire.MarshalJSONIndent(cdc, cliPrint) + // print out some key information + toPrint := struct { + AppMessage json.RawMessage `json:"app_message"` + GenTxFile json.RawMessage `json:"gen_tx_file"` + }{ + cliPrint, + genTxFile, + } + out, err := wire.MarshalJSONIndent(cdc, toPrint) if err != nil { return err } @@ -202,7 +209,7 @@ func processGenTxs(genTxsDir string, cdc *wire.Codec, appInit AppInit) ( return } for _, fo := range fos { - filename := fo.Name() + filename := path.Join(genTxsDir, fo.Name()) if !fo.IsDir() && (path.Ext(filename) != ".json") { return } From 05c5809bae10a858b36457366d47395d69168850 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 00:27:40 -0400 Subject: [PATCH 110/176] gaia init automatic key processing --- client/keys/utils.go | 7 +- cmd/gaia/app/app.go | 165 ++------------------------------ cmd/gaia/app/genesis.go | 175 ++++++++++++++++++++++++++++++++++ cmd/gaia/cli_test/cli_test.go | 20 +--- cmd/gaia/cmd/gaiacli/main.go | 4 +- cmd/gaia/cmd/gaiad/main.go | 4 +- server/init.go | 42 ++++++-- server/tm_cmds.go | 4 +- 8 files changed, 233 insertions(+), 188 deletions(-) create mode 100644 cmd/gaia/app/genesis.go diff --git a/client/keys/utils.go b/client/keys/utils.go index f86389a89..013aa1848 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -24,8 +24,13 @@ var keybase keys.Keybase // initialize a keybase based on the configuration func GetKeyBase() (keys.Keybase, error) { + rootDir := viper.GetString(cli.HomeFlag) + return GetKeyBaseFromDir(rootDir) +} + +// initialize a keybase based on the configuration +func GetKeyBaseFromDir(rootDir string) (keys.Keybase, error) { if keybase == nil { - rootDir := viper.GetString(cli.HomeFlag) db, err := dbm.NewGoLevelDB(KeyDBName, filepath.Join(rootDir, "keys")) if err != nil { return nil, err diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index eb63c6f1a..9ece80ea7 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -1,20 +1,14 @@ package app import ( - "encoding/json" - "errors" + "os" - "github.com/spf13/pflag" - "github.com/spf13/viper" abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" - tmtypes "github.com/tendermint/tendermint/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" bam "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" @@ -27,6 +21,12 @@ const ( appName = "GaiaApp" ) +// default home directories for expected binaries +var ( + DefaultCLIHome = os.ExpandEnv("$HOME/.gaiacli") + DefaultNodeHome = os.ExpandEnv("$HOME/.gaiad") +) + // Extended ABCI application type GaiaApp struct { *bam.BaseApp @@ -153,154 +153,3 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci return abci.ResponseInitChain{} } - -//________________________________________________________________________________________ - -// State to Unmarshal -type GenesisState struct { - Accounts []GenesisAccount `json:"accounts"` - StakeData stake.GenesisState `json:"stake"` -} - -// GenesisAccount doesn't need pubkey or sequence -type GenesisAccount struct { - Address sdk.Address `json:"address"` - Coins sdk.Coins `json:"coins"` -} - -func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { - return GenesisAccount{ - Address: acc.Address, - Coins: acc.Coins, - } -} - -// convert GenesisAccount to auth.BaseAccount -func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { - return &auth.BaseAccount{ - Address: ga.Address, - Coins: ga.Coins.Sort(), - } -} - -var ( - flagName = "name" - //flagOWK = "overwrite-keys" -) - -// get app init parameters for server init command -func GaiaAppInit() server.AppInit { - fsAppGenState := pflag.NewFlagSet("", pflag.ContinueOnError) - //fsAppGenState.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail") - - fsAppGenTx := pflag.NewFlagSet("", pflag.ContinueOnError) - fsAppGenTx.String(flagName, "", "validator moniker, if left blank, do not add validator") - - return server.AppInit{ - FlagsAppGenState: fsAppGenState, - FlagsAppGenTx: fsAppGenTx, - AppGenState: GaiaAppGenState, - AppGenTx: GaiaAppGenTx, - } -} - -// simple genesis tx -type GaiaGenTx struct { - Name string `json:"name"` - Address sdk.Address `json:"address"` - PubKey crypto.PubKey `json:"pub_key"` -} - -// power given to validators in gaia init functions -var FreePower = int64(100) - -// Create the core parameters for genesis initialization for gaia -// note that the pubkey input is this machines pubkey -func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { - - if len(appGenTxs) == 0 { - err = errors.New("must provide at least genesis transaction") - return - } - - // start with the default staking genesis state - stakeData := stake.GetDefaultGenesisState() - - // get genesis flag account information - genaccs := make([]GenesisAccount, len(appGenTxs)) - for i, appGenTx := range appGenTxs { - - var genTx GaiaGenTx - err = cdc.UnmarshalJSON(appGenTx, &genTx) - if err != nil { - return - } - - // create the genesis account, give'm few fermions and a buncha token with there name - accAuth := auth.NewBaseAccountWithAddress(genTx.Address) - accAuth.Coins = sdk.Coins{ - {genTx.Name + "Token", 1000}, - {"fermion", 50}, - } - acc := NewGenesisAccount(&accAuth) - genaccs[i] = acc - - // add the validator - if len(genTx.Name) > 0 { - desc := stake.NewDescription(genTx.Name, "", "", "") - candidate := stake.NewCandidate(genTx.Address, genTx.PubKey, desc) - candidate.Assets = sdk.NewRat(FreePower) - stakeData.Candidates = append(stakeData.Candidates, candidate) - - // pool logic - stakeData.Pool.TotalSupply += FreePower - stakeData.Pool.BondedPool += FreePower - stakeData.Pool.BondedShares = sdk.NewRat(stakeData.Pool.BondedPool) - } - } - - // create the final app state - genesisState := GenesisState{ - Accounts: genaccs, - StakeData: stakeData, - } - appState, err = wire.MarshalJSONIndent(cdc, genesisState) - return -} - -// Generate a gaia genesis transaction -func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( - appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { - - var addr sdk.Address - var secret string - addr, secret, err = server.GenerateCoinKey() - if err != nil { - return - } - - var bz []byte - gaiaGenTx := GaiaGenTx{ - Name: viper.GetString(flagName), - Address: addr, - PubKey: pk, - } - bz, err = wire.MarshalJSONIndent(cdc, gaiaGenTx) - 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: FreePower, - } - return -} diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go new file mode 100644 index 000000000..66fd1f98d --- /dev/null +++ b/cmd/gaia/app/genesis.go @@ -0,0 +1,175 @@ +package app + +import ( + "encoding/json" + "errors" + + "github.com/spf13/pflag" + "github.com/spf13/viper" + crypto "github.com/tendermint/go-crypto" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/stake" +) + +// State to Unmarshal +type GenesisState struct { + Accounts []GenesisAccount `json:"accounts"` + StakeData stake.GenesisState `json:"stake"` +} + +// GenesisAccount doesn't need pubkey or sequence +type GenesisAccount struct { + Address sdk.Address `json:"address"` + Coins sdk.Coins `json:"coins"` +} + +func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { + return GenesisAccount{ + Address: acc.Address, + Coins: acc.Coins, + } +} + +// convert GenesisAccount to auth.BaseAccount +func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { + return &auth.BaseAccount{ + Address: ga.Address, + Coins: ga.Coins.Sort(), + } +} + +var ( + flagName = "name" + flagClientHome = "home-client" + flagOWK = "owk" + + // bonded tokens given to genesis validators/accounts + freeFermionVal = int64(100) + freeFermionsAcc = int64(50) +) + +// get app init parameters for server init command +func GaiaAppInit() server.AppInit { + fsAppGenState := pflag.NewFlagSet("", pflag.ContinueOnError) + + fsAppGenTx := pflag.NewFlagSet("", pflag.ContinueOnError) + fsAppGenTx.String(flagName, "", "validator moniker, if left blank, do not add validator") + fsAppGenTx.String(flagClientHome, DefaultCLIHome, "home directory for the client, used for key generation") + fsAppGenTx.Bool(flagOWK, false, "overwrite the for the accounts created") + + return server.AppInit{ + FlagsAppGenState: fsAppGenState, + FlagsAppGenTx: fsAppGenTx, + AppGenState: GaiaAppGenState, + AppGenTx: GaiaAppGenTx, + } +} + +// simple genesis tx +type GaiaGenTx struct { + Name string `json:"name"` + Address sdk.Address `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` +} + +// power given to validators in gaia init functions + +// Create the core parameters for genesis initialization for gaia +// note that the pubkey input is this machines pubkey +func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { + + if len(appGenTxs) == 0 { + err = errors.New("must provide at least genesis transaction") + return + } + + // start with the default staking genesis state + stakeData := stake.GetDefaultGenesisState() + + // get genesis flag account information + genaccs := make([]GenesisAccount, len(appGenTxs)) + for i, appGenTx := range appGenTxs { + + var genTx GaiaGenTx + err = cdc.UnmarshalJSON(appGenTx, &genTx) + if err != nil { + return + } + + // create the genesis account, give'm few fermions and a buncha token with there name + accAuth := auth.NewBaseAccountWithAddress(genTx.Address) + accAuth.Coins = sdk.Coins{ + {genTx.Name + "Token", 1000}, + {"fermion", freeFermionsAcc}, + } + acc := NewGenesisAccount(&accAuth) + genaccs[i] = acc + stakeData.Pool.TotalSupply += freeFermionsAcc // increase the supply + + // add the validator + if len(genTx.Name) > 0 { + desc := stake.NewDescription(genTx.Name, "", "", "") + candidate := stake.NewCandidate(genTx.Address, genTx.PubKey, desc) + candidate.Assets = sdk.NewRat(freeFermionVal) + stakeData.Candidates = append(stakeData.Candidates, candidate) + + // pool logic + stakeData.Pool.TotalSupply += freeFermionVal + stakeData.Pool.BondedPool += freeFermionVal + stakeData.Pool.BondedShares = sdk.NewRat(stakeData.Pool.BondedPool) + } + } + + // create the final app state + genesisState := GenesisState{ + Accounts: genaccs, + StakeData: stakeData, + } + appState, err = wire.MarshalJSONIndent(cdc, genesisState) + return +} + +// Generate a gaia genesis transaction +func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { + + var addr sdk.Address + var secret string + clientRoot := viper.GetString(flagClientHome) + overwrite := viper.GetBool(flagOWK) + name := viper.GetString(flagName) + addr, secret, err = server.GenerateSaveCoinKey(clientRoot, name, "1234567890", overwrite) + if err != nil { + return + } + + var bz []byte + gaiaGenTx := GaiaGenTx{ + Name: name, + Address: addr, + PubKey: pk, + } + bz, err = wire.MarshalJSONIndent(cdc, gaiaGenTx) + 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: freeFermionVal, + } + return +} diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 00d94861d..01f2e1563 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -24,7 +24,8 @@ func TestGaiaCLISend(t *testing.T) { pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) executeWrite(t, "gaiacli keys delete bar", pass) - key, chainID := executeInit(t, "gaiad init -o --name=foo") + chainID := executeInit(t, "gaiad init -o --name=foo") + executeWrite(t, "gaiacli keys add bar", pass) // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) @@ -34,9 +35,6 @@ func TestGaiaCLISend(t *testing.T) { cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - executeWrite(t, "gaiacli keys add foo --recover", pass, key) - executeWrite(t, "gaiacli keys add bar", pass) - fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json") @@ -58,7 +56,8 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { pass := "1234567890" executeWrite(t, "gaiacli keys delete foo", pass) executeWrite(t, "gaiacli keys delete bar", pass) - key, chainID := executeInit(t, "gaiad init -o --name=foo") + chainID := executeInit(t, "gaiad init -o --name=foo") + executeWrite(t, "gaiacli keys add bar", pass) // get a free port, also setup some common flags servAddr := server.FreeTCPAddr(t) @@ -68,8 +67,6 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr)) defer cmd.Process.Kill() - executeWrite(t, "gaiacli keys add foo --recover", pass, key) - executeWrite(t, "gaiacli keys add bar", pass) fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") barAddr, barPubKey := executeGetAddrPK(t, "gaiacli keys show bar --output=json") @@ -140,7 +137,7 @@ func executeWritePrint(t *testing.T, cmdStr string, writes ...string) { fmt.Printf("debug read: %v\n", string(bz)) } -func executeInit(t *testing.T, cmdStr string) (key, chainID string) { +func executeInit(t *testing.T, cmdStr string) (chainID string) { out := tests.ExecuteT(t, cmdStr) var initRes map[string]json.RawMessage @@ -150,13 +147,6 @@ func executeInit(t *testing.T, cmdStr string) (key, chainID string) { err = json.Unmarshal(initRes["chain_id"], &chainID) require.NoError(t, err) - var appMessageRes map[string]json.RawMessage - err = json.Unmarshal(initRes["app_message"], &appMessageRes) - require.NoError(t, err) - - err = json.Unmarshal(appMessageRes["secret"], &key) - require.NoError(t, err) - return } diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index 8efb9f4dd..ab0a98c69 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -1,8 +1,6 @@ package main import ( - "os" - "github.com/spf13/cobra" "github.com/tendermint/tmlibs/cli" @@ -73,6 +71,6 @@ func main() { ) // prepare and add flags - executor := cli.PrepareMainCmd(rootCmd, "GA", os.ExpandEnv("$HOME/.gaiacli")) + executor := cli.PrepareMainCmd(rootCmd, "GA", app.DefaultCLIHome) executor.Execute() } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 565cf5ac2..0417671a2 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -1,7 +1,6 @@ package main import ( - "os" "path/filepath" "github.com/spf13/cobra" @@ -27,8 +26,7 @@ func main() { server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp) // prepare and add flags - rootDir := os.ExpandEnv("$HOME/.gaiad") - executor := cli.PrepareBaseCmd(rootCmd, "GA", rootDir) + executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome) executor.Execute() } diff --git a/server/init.go b/server/init.go index 98b724caf..d23d78b81 100644 --- a/server/init.go +++ b/server/init.go @@ -8,8 +8,6 @@ import ( "path" "path/filepath" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -22,8 +20,13 @@ import ( "github.com/tendermint/tendermint/p2p" tmtypes "github.com/tendermint/tendermint/types" pvm "github.com/tendermint/tendermint/types/priv_validator" + tmcli "github.com/tendermint/tmlibs/cli" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" + + clkeys "github.com/cosmos/cosmos-sdk/client/keys" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) // genesis piece structure for creating combined genesis @@ -82,7 +85,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { } genTxFile := json.RawMessage(bz) name := fmt.Sprintf("gentx-%v.json", nodeID) - file := filepath.Join(viper.GetString("home"), name) + file := filepath.Join(viper.GetString(tmcli.HomeFlag), name) err = cmn.WriteFile(file, bz, 0644) if err != nil { return err @@ -148,7 +151,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { return err } config.P2P.PersistentPeers = persistentPeers - configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get + configFilePath := filepath.Join(viper.GetString(tmcli.HomeFlag), "config", "config.toml") //TODO this is annoying should be easier to get cfg.WriteConfigFile(configFilePath, config) } else { appGenTx, am, validator, err := appInit.AppGenTx(cdc, pubKey) @@ -165,7 +168,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { return err } - err = WriteGenesisFile(cdc, genFile, chainID, validators, appState) + err = writeGenesisFile(cdc, genFile, chainID, validators, appState) if err != nil { return err } @@ -258,7 +261,7 @@ func ReadOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { } // create the genesis file -func WriteGenesisFile(cdc *wire.Codec, genesisFile, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { +func writeGenesisFile(cdc *wire.Codec, genesisFile, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error { genDoc := tmtypes.GenesisDoc{ ChainID: chainID, Validators: validators, @@ -399,3 +402,30 @@ func GenerateCoinKey() (sdk.Address, string, error) { addr := info.PubKey.Address() return 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.Address, string, error) { + + // get the keystore from the client + keybase, err := clkeys.GetKeyBaseFromDir(clientRoot) + if err != nil { + return nil, "", err + } + + // ensure no overwrite + if !overwrite { + _, err := keybase.Get(keyName) + if err == nil { + return nil, "", errors.New("key already exists, overwrite is disabled") + } + } + + // generate a private key, with recovery phrase + info, secret, err := keybase.Create(keyName, keyPass, keys.AlgoEd25519) + if err != nil { + return nil, "", err + } + addr := info.PubKey.Address() + return addr, secret, nil +} diff --git a/server/tm_cmds.go b/server/tm_cmds.go index a876d1bcd..d581ca5f7 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -36,7 +36,7 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command { flagJSON := "json" cmd := cobra.Command{ Use: "show_validator", - Short: "Show this node's validator info", + Short: "Show this node's tendermint validator info", RunE: func(cmd *cobra.Command, args []string) error { cfg := ctx.Config @@ -67,7 +67,7 @@ func ShowValidatorCmd(ctx *Context) *cobra.Command { func UnsafeResetAllCmd(ctx *Context) *cobra.Command { return &cobra.Command{ Use: "unsafe_reset_all", - Short: "Reset all blockchain data", + Short: "Reset blockchain database, priv_validator.json file, and the logger", RunE: func(cmd *cobra.Command, args []string) error { cfg := ctx.Config tcmd.ResetAll(cfg.DBDir(), cfg.PrivValidatorFile(), ctx.Logger) From ade42e74b7d3b6b700e9de05b3d95f34b67f345a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 00:49:53 -0400 Subject: [PATCH 111/176] better init test --- cmd/gaia/app/genesis.go | 82 ++++++++++++++++++------------------ cmd/gaia/app/genesis_test.go | 33 +++++++++++++++ server/init.go | 74 ++++++++++++++++---------------- server/init_test.go | 15 ++++++- 4 files changed, 125 insertions(+), 79 deletions(-) create mode 100644 cmd/gaia/app/genesis_test.go diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 66fd1f98d..513430ec9 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -65,8 +65,8 @@ func GaiaAppInit() server.AppInit { return server.AppInit{ FlagsAppGenState: fsAppGenState, FlagsAppGenTx: fsAppGenTx, - AppGenState: GaiaAppGenState, AppGenTx: GaiaAppGenTx, + AppGenState: GaiaAppGenState, } } @@ -77,7 +77,45 @@ type GaiaGenTx struct { PubKey crypto.PubKey `json:"pub_key"` } -// power given to validators in gaia init functions +// Generate a gaia genesis transaction +func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { + + var addr sdk.Address + var secret string + clientRoot := viper.GetString(flagClientHome) + overwrite := viper.GetBool(flagOWK) + name := viper.GetString(flagName) + addr, secret, err = server.GenerateSaveCoinKey(clientRoot, name, "1234567890", overwrite) + if err != nil { + return + } + + var bz []byte + gaiaGenTx := GaiaGenTx{ + Name: name, + Address: addr, + PubKey: pk, + } + bz, err = wire.MarshalJSONIndent(cdc, gaiaGenTx) + 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: freeFermionVal, + } + return +} // Create the core parameters for genesis initialization for gaia // note that the pubkey input is this machines pubkey @@ -133,43 +171,3 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso appState, err = wire.MarshalJSONIndent(cdc, genesisState) return } - -// Generate a gaia genesis transaction -func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( - appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { - - var addr sdk.Address - var secret string - clientRoot := viper.GetString(flagClientHome) - overwrite := viper.GetBool(flagOWK) - name := viper.GetString(flagName) - addr, secret, err = server.GenerateSaveCoinKey(clientRoot, name, "1234567890", overwrite) - if err != nil { - return - } - - var bz []byte - gaiaGenTx := GaiaGenTx{ - Name: name, - Address: addr, - PubKey: pk, - } - bz, err = wire.MarshalJSONIndent(cdc, gaiaGenTx) - 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: freeFermionVal, - } - return -} diff --git a/cmd/gaia/app/genesis_test.go b/cmd/gaia/app/genesis_test.go new file mode 100644 index 000000000..94bcdd0df --- /dev/null +++ b/cmd/gaia/app/genesis_test.go @@ -0,0 +1,33 @@ +package app + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/stretchr/testify/assert" + crypto "github.com/tendermint/go-crypto" +) + +func TestToAccount(t *testing.T) { + priv = crypto.GenPrivKeyEd25519() + addr = priv.PubKey().Address() + authAcc := auth.NewBaseAccountWithAddress(addr) + genAcc := NewGenesisAccount(authAcc) + assert.Equal(t, authAcc, genAcc.ToAccount()) +} + +func TestGaiaAppGenTx(t *testing.T) { + cdc := MakeCodec() + + //TODO test that key overwrite flags work / no overwrites if set off + //TODO test validator created has provided pubkey + //TODO test the account created has the correct pubkey +} + +func TestGaiaAppGenState(t *testing.T) { + cdc := MakeCodec() + + // TODO test must provide at least genesis transaction + // TODO test with both one and two genesis transactions: + // TODO correct: genesis account created, canididates created, pool token variance +} diff --git a/server/init.go b/server/init.go index d23d78b81..af735f092 100644 --- a/server/init.go +++ b/server/init.go @@ -58,7 +58,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { return err } nodeID := string(nodeKey.ID()) - pubKey := ReadOrCreatePrivValidator(config) + pubKey := readOrCreatePrivValidator(config) appGenTx, cliPrint, validator, err := appInit.AppGenTx(cdc, pubKey) if err != nil { @@ -126,7 +126,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { return err } nodeID := string(nodeKey.ID()) - pubKey := ReadOrCreatePrivValidator(config) + pubKey := readOrCreatePrivValidator(config) chainID := viper.GetString(flagChainID) if chainID == "" { @@ -247,7 +247,7 @@ func processGenTxs(genTxsDir string, cdc *wire.Codec, appInit AppInit) ( //________________________________________________________________________________________ // read of create the private key file for this config -func ReadOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { +func readOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey { // private validator privValFile := tmConfig.PrivValidatorFile() var privValidator *pvm.FilePV @@ -297,21 +297,21 @@ type AppInit struct { FlagsAppGenState *pflag.FlagSet FlagsAppGenTx *pflag.FlagSet - // 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 *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) - // create the application genesis tx AppGenTx func(cdc *wire.Codec, pk crypto.PubKey) ( appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) + + // 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 *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) } //_____________________________________________________________________ // simple default application init var DefaultAppInit = AppInit{ - AppGenState: SimpleAppGenState, AppGenTx: SimpleAppGenTx, + AppGenState: SimpleAppGenState, } // simple genesis tx @@ -319,34 +319,6 @@ type SimpleGenTx struct { Addr sdk.Address `json:"addr"` } -// create the genesis app state -func SimpleAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { - - if len(appGenTxs) != 1 { - err = errors.New("must provide a single genesis transaction") - return - } - - var genTx SimpleGenTx - err = cdc.UnmarshalJSON(appGenTxs[0], &genTx) - if err != nil { - return - } - - appState = json.RawMessage(fmt.Sprintf(`{ - "accounts": [{ - "address": "%s", - "coins": [ - { - "denom": "mycoin", - "amount": 9007199254740992 - } - ] - }] -}`, genTx.Addr.String())) - return -} - // Generate a genesis transaction func SimpleAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { @@ -380,6 +352,36 @@ func SimpleAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( return } +// create the genesis app state +func SimpleAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { + + if len(appGenTxs) != 1 { + err = errors.New("must provide a single genesis transaction") + return + } + + var genTx SimpleGenTx + err = cdc.UnmarshalJSON(appGenTxs[0], &genTx) + if err != nil { + return + } + + appState = json.RawMessage(fmt.Sprintf(`{ + "accounts": [{ + "address": "%s", + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + }] +}`, genTx.Addr.String())) + return +} + +//___________________________________________________________________________________________ + // GenerateCoinKey returns the address of a public key, along with the secret // phrase to recover the private key. func GenerateCoinKey() (sdk.Address, string, error) { diff --git a/server/init_test.go b/server/init_test.go index 1bdf0a085..eca529505 100644 --- a/server/init_test.go +++ b/server/init_test.go @@ -12,7 +12,8 @@ import ( tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" ) -func TestInit(t *testing.T) { +// TODO update +func TestInitCmd(t *testing.T) { defer setupViper(t)() logger := log.NewNopLogger() @@ -28,3 +29,15 @@ func TestInit(t *testing.T) { err = cmd.RunE(nil, nil) require.NoError(t, err) } + +func TestGenTxCmd(t *testing.T) { + // TODO +} + +func TestSimpleAppGenTx(t *testing.T) { + // TODO +} + +func TestSimpleAppGenState(t *testing.T) { + // TODO +} From 514b3fba4ebebfd609e28e357c2e8844bbe76e9a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 14:16:17 -0400 Subject: [PATCH 112/176] fix genesis tests --- cmd/gaia/app/genesis_test.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cmd/gaia/app/genesis_test.go b/cmd/gaia/app/genesis_test.go index 94bcdd0df..03ff46e50 100644 --- a/cmd/gaia/app/genesis_test.go +++ b/cmd/gaia/app/genesis_test.go @@ -3,21 +3,23 @@ package app import ( "testing" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/assert" crypto "github.com/tendermint/go-crypto" ) func TestToAccount(t *testing.T) { - priv = crypto.GenPrivKeyEd25519() - addr = priv.PubKey().Address() + priv := crypto.GenPrivKeyEd25519() + addr := sdk.Address(priv.PubKey().Address()) authAcc := auth.NewBaseAccountWithAddress(addr) - genAcc := NewGenesisAccount(authAcc) - assert.Equal(t, authAcc, genAcc.ToAccount()) + genAcc := NewGenesisAccount(&authAcc) + assert.Equal(t, authAcc, *genAcc.ToAccount()) } func TestGaiaAppGenTx(t *testing.T) { cdc := MakeCodec() + _ = cdc //TODO test that key overwrite flags work / no overwrites if set off //TODO test validator created has provided pubkey @@ -26,6 +28,7 @@ func TestGaiaAppGenTx(t *testing.T) { func TestGaiaAppGenState(t *testing.T) { cdc := MakeCodec() + _ = cdc // TODO test must provide at least genesis transaction // TODO test with both one and two genesis transactions: From 3a4813ff01b25b4a2b67bbd089cd70af256092db Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 14:20:20 -0400 Subject: [PATCH 113/176] added test_nocli for fast non-cli tests --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 4381eea82..855d96357 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,9 @@ godocs: test: test_unit # test_cli +test_nocli: + go test `go list ./... | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test` + # Must be run in each package seperately for the visualization # Added here for easy reference # coverage: From 9b645836e36389466a5e088b9a3c240963e4bc8c Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 14:33:02 -0400 Subject: [PATCH 114/176] changelog for better init --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 618db746a..539c99735 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ FEATURES: * MountStoreWithDB without providing a custom store works. * Repo is now lint compliant / GoMetaLinter with tendermint-lint integrated into CI * Better key output, pubkey go-amino hex bytes now output by default +* gaiad init overhaul + * Create genesis transactions with `gaiad init gen-tx` + * New genesis account keys are automatically added to the client keybase (introduce `--client-home` flag) + * Initialize with genesis txs using `--gen-txs` flag BREAKING CHANGES @@ -25,6 +29,7 @@ BREAKING CHANGES * Type as a prefix naming convention applied (ex. BondMsg -> MsgBond) * Removed redundancy in names (ex. stake.StakeKeeper -> stake.Keeper) * Removed SealedAccountMapper +* gaiad init now requires use of `--name` flag BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia From 0f28f6738ab6aa772b29ea5b54596e57288a0b70 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 15:52:20 -0400 Subject: [PATCH 115/176] updated some testnet docs, gen-txs now in the config folder --- docs/staking/testnet.rst | 161 ++++++--------------------------------- server/init.go | 17 +++-- 2 files changed, 36 insertions(+), 142 deletions(-) diff --git a/docs/staking/testnet.rst b/docs/staking/testnet.rst index 484ec3b5d..027146893 100644 --- a/docs/staking/testnet.rst +++ b/docs/staking/testnet.rst @@ -1,109 +1,33 @@ Testnet Setup ============= +**Note:** THIS DOCUMENT IS OUT OF DATE + See the `installation guide <../sdk/install.html>`__ for details on installation. Here is a quick example to get you off your feet: -First, generate a new key with a name, and save the address: +First, generate a couple of genesis transactions to be incorparated into the genesis file, this will create two keys with the password ``1234567890`` :: - MYNAME= - gaiacli keys new $MYNAME + gaiad init gen-tx --name=foo --home=$HOME/.gaiad1 + gaiad init gen-tx --name=bar --home=$HOME/.gaiad2 gaiacli keys list - MYADDR= - -Now initialize a gaia chain: +**Note:** If you've already run these tests you may need to overwrite keys using the ``--OWK`` flag +When you list the keys you should see two addresses, we'll need these later so take note. +Now let's actually create the genesis files for both nodes: :: - gaiad init --home=$HOME/.gaiad1 - -you should see seed phrase for genesis account in the output & config & data folder in the home directory. - -In the config folder, there will be the following files: ``config.toml``, ``genesis.json``, ``node_key.json``, and ``priv_validator.json``. - -The genesis file should look like this: - -:: - - { - "genesis_time": "0001-01-01T00:00:00Z", - "chain_id": "test-chain-0TRiTa", - "validators": [ - { - "pub_key": { - "type": "AC26791624DE60", - "value": "" - }, - "power": 10, - "name": "" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "", - "coins": [ - { - "denom": "steak", - "amount": 9007199254740992 - } - ] - } - ] - } - } - -**Note:** We need to change the denomination of token from default to ``steak`` in the genesis file. - -Then, recover the genesis account with ``gaiacli``: - -:: - - gaiacli keys add --recover - -By now, you have set up the first node. This is great! - -We can add a second node on our local machine by initiating a node in a new directory, and copying in the ``genesis.json``: - -:: - - gaiad init --home=$HOME/.gaiad2 - -and replace the ``genesis.json`` and ``config.toml`` files: - -:: - - cp $HOME/.gaiad/config/genesis.json $HOME/.gaiad2/config - cp $HOME/.gaiad/config/config.toml $HOME/.gaiad2/config - -then, get the node id of first node: - -:: - - gaiad show_node_id --home=$HOME/.gaiad1 - -We need to also modify $HOME/.gaiad2/config.toml to set new seeds and ports. It should look like: - -:: - - proxy_app = "tcp://127.0.0.1:46668" - moniker = "anonymous" - fast_sync = true - db_backend = "leveldb" - log_level = "state:info,*:error" - - [rpc] - laddr = "tcp://0.0.0.0:46667" - - [p2p] - laddr = "tcp://0.0.0.0:46666" - persistent_peers = "@0.0.0.0:46656" + cp -a ~/.gaiad2/config/gentx/. ~/.gaiad1/config/gentx/ + cp -a ~/.gaiad1/config/gentx/. ~/.gaiad2/config/gentx/ + gaiad init --gen-txs --home=$HOME/.gaiad1 --chain-id=test-chain + gaiad init --gen-txs --home=$HOME/.gaiad2 --chain-id=test-chain +**Note:** If you've already run these tests you may need to overwrite genesis using the ``-o`` flag +What we just did is copy the genesis transactions between each of the nodes so there is a common genesis transaction set; then we created both genesis files independantly from each home directory. Importantly both nodes have independantly created their ``genesis.json`` and ``config.toml`` files, which should be identical between nodes. Great, now that we've initialized the chains, we can start both nodes in the background: @@ -122,25 +46,13 @@ Nice. We can also lookup the validator set: gaiacli validatorset -There is only **one** validator now. Let's add another one! - -First, we need to create a new account: +Then, we try to transfer some ``fermion`` to another account: :: - gaiacli keys new - -Check that we now have two accounts: - -:: - - gaiacli keys list - -Then, we try to transfer some ``steak`` to another account: - -:: - - gaiacli send --amount=1000steak --to=$MYADDR2 --name=$NAME --chain-id= --node=tcp://localhost:46657 --sequence=0 + gaiacli account + gaiacli account + gaiacli send --amount=10fermion --to= --name=foo --chain-id=test-chain --node=tcp://localhost:46657 --sequence=0 **Note:** We need to be careful with the ``chain-id`` and ``sequence`` @@ -148,35 +60,7 @@ Check the balance & sequence with: :: - gaiacli account $MYADDR - -We can see the balance of ``$MYADDR2`` is 1000 now. - -Finally, let's bond the validator in ``$HOME/gaiad2``. Get the pubkey first: - -:: - - cat $HOME/.gaiad2/config/priv_validator.json | jq .pub_key.value - -Go to `this website `__ to change pubkey from base64 to Hex. - -Ok, now we can bond some coins to that pubkey: - -:: - - gaiacli bond --stake=1steak --validator= --sequence=0 --chain-id= --name=test - -Nice. We can see there are now two validators: - -:: - - gaiacli validatorset - -Check the balance of ``$MYADDR2`` to see the difference: it has 1 less ``steak``! - -:: - - gaiacli account $MYADDR2 + gaiacli account To confirm for certain the new validator is active, check tendermint: @@ -188,6 +72,11 @@ Finally, to relinquish all your power, unbond some coins. You should see your Vo :: - gaiacli unbond --sequence=# --chain-id= --name=test + gaiacli unbond --sequence=1 --chain-id= --name=test That's it! + +**Note:** TODO demonstrate edit-candidacy +**Note:** TODO demonstrate delegation +**Note:** TODO demonstrate unbond of delegation +**Note:** TODO demonstrate unbond candidate diff --git a/server/init.go b/server/init.go index af735f092..2d8be85f8 100644 --- a/server/init.go +++ b/server/init.go @@ -48,7 +48,7 @@ var ( func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { cmd := &cobra.Command{ Use: "gen-tx", - Short: "Create genesis transaction file (under [--home]/gentx-[nodeID].json)", + Short: "Create genesis transaction file (under [--home]/config/gentx/gentx-[nodeID].json)", Args: cobra.NoArgs, RunE: func(_ *cobra.Command, args []string) error { @@ -85,7 +85,12 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { } genTxFile := json.RawMessage(bz) name := fmt.Sprintf("gentx-%v.json", nodeID) - file := filepath.Join(viper.GetString(tmcli.HomeFlag), name) + writePath := filepath.Join(viper.GetString(tmcli.HomeFlag), "config", "gentx") + file := filepath.Join(writePath, name) + err = cmn.EnsureDir(writePath, 0700) + if err != nil { + return err + } err = cmn.WriteFile(file, bz, 0644) if err != nil { return err @@ -144,14 +149,14 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { var validators []tmtypes.GenesisValidator var persistentPeers string - genTxsDir := viper.GetString(flagGenTxs) - if genTxsDir != "" { + if viper.GetBool(flagGenTxs) { + genTxsDir := filepath.Join(viper.GetString(tmcli.HomeFlag), "config", "gentx") validators, appGenTxs, persistentPeers, err = processGenTxs(genTxsDir, cdc, appInit) if err != nil { return err } config.P2P.PersistentPeers = persistentPeers - configFilePath := filepath.Join(viper.GetString(tmcli.HomeFlag), "config", "config.toml") //TODO this is annoying should be easier to get + configFilePath := filepath.Join(viper.GetString(tmcli.HomeFlag), "config", "config.toml") cfg.WriteConfigFile(configFilePath, config) } else { appGenTx, am, validator, err := appInit.AppGenTx(cdc, pubKey) @@ -194,7 +199,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command { } cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file") cmd.Flags().String(flagChainID, "", "genesis file chain-id, if left blank will be randomly created") - cmd.Flags().String(flagGenTxs, "", "directory containing the genesis transactions") + cmd.Flags().Bool(flagGenTxs, false, "apply genesis transactions from [--home]/config/gentx/") cmd.Flags().AddFlagSet(appInit.FlagsAppGenState) cmd.Flags().AddFlagSet(appInit.FlagsAppGenTx) // need to add this flagset for when no GenTx's provided cmd.AddCommand(GenTxCmd(ctx, cdc, appInit)) From f9b5d8c648905b6cbf033da6d758fc2f710dea71 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 22:03:25 +0200 Subject: [PATCH 116/176] Minor README updates --- docs/staking/testnet.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/staking/testnet.rst b/docs/staking/testnet.rst index 027146893..ab8c1644d 100644 --- a/docs/staking/testnet.rst +++ b/docs/staking/testnet.rst @@ -1,7 +1,7 @@ Testnet Setup ============= -**Note:** THIS DOCUMENT IS OUT OF DATE +**Note:** This document is incomplete and may not be up-to-date with the state of the code. See the `installation guide <../sdk/install.html>`__ for details on installation. @@ -27,7 +27,7 @@ Now let's actually create the genesis files for both nodes: gaiad init --gen-txs --home=$HOME/.gaiad2 --chain-id=test-chain **Note:** If you've already run these tests you may need to overwrite genesis using the ``-o`` flag -What we just did is copy the genesis transactions between each of the nodes so there is a common genesis transaction set; then we created both genesis files independantly from each home directory. Importantly both nodes have independantly created their ``genesis.json`` and ``config.toml`` files, which should be identical between nodes. +What we just did is copy the genesis transactions between each of the nodes so there is a common genesis transaction set; then we created both genesis files independently from each home directory. Importantly both nodes have independently created their ``genesis.json`` and ``config.toml`` files, which should be identical between nodes. Great, now that we've initialized the chains, we can start both nodes in the background: @@ -52,7 +52,7 @@ Then, we try to transfer some ``fermion`` to another account: gaiacli account gaiacli account - gaiacli send --amount=10fermion --to= --name=foo --chain-id=test-chain --node=tcp://localhost:46657 --sequence=0 + gaiacli send --amount=10fermion --to= --name=foo --chain-id=test-chain **Note:** We need to be careful with the ``chain-id`` and ``sequence`` @@ -72,7 +72,7 @@ Finally, to relinquish all your power, unbond some coins. You should see your Vo :: - gaiacli unbond --sequence=1 --chain-id= --name=test + gaiacli unbond --chain-id= --name=test That's it! From 54a5869efde87bf397be6d176d4634ce134cd1a0 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 17:32:20 -0400 Subject: [PATCH 117/176] added used of cobra arg constraints --- client/keys/delete.go | 5 +---- client/keys/show.go | 26 ++++++++--------------- client/keys/update.go | 5 +---- client/rpc/block.go | 1 + client/rpc/validators.go | 3 ++- examples/democoin/x/cool/client/cli/tx.go | 11 ++-------- examples/democoin/x/pow/client/cli/tx.go | 8 +------ 7 files changed, 17 insertions(+), 42 deletions(-) diff --git a/client/keys/delete.go b/client/keys/delete.go index cd2016bd2..e9f3c1abe 100644 --- a/client/keys/delete.go +++ b/client/keys/delete.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/gorilla/mux" - "github.com/pkg/errors" keys "github.com/tendermint/go-crypto/keys" "github.com/spf13/cobra" @@ -18,14 +17,12 @@ func deleteKeyCommand() *cobra.Command { Use: "delete ", Short: "Delete the given key", RunE: runDeleteCmd, + Args: cobra.ExactArgs(1), } return cmd } func runDeleteCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } name := args[0] buf := client.BufferStdin() diff --git a/client/keys/show.go b/client/keys/show.go index 76966cd19..d0555764d 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -5,7 +5,6 @@ import ( "net/http" "github.com/gorilla/mux" - "github.com/pkg/errors" keys "github.com/tendermint/go-crypto/keys" "github.com/spf13/cobra" @@ -15,7 +14,15 @@ var showKeysCmd = &cobra.Command{ Use: "show ", Short: "Show key info for the given name", Long: `Return public details of one local key.`, - RunE: runShowCmd, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + name := args[0] + info, err := getKey(name) + if err == nil { + printInfo(info) + } + return err + }, } func getKey(name string) (keys.Info, error) { @@ -27,21 +34,6 @@ func getKey(name string) (keys.Info, error) { return kb.Get(name) } -// CMD - -func runShowCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } - name := args[0] - - info, err := getKey(name) - if err == nil { - printInfo(info) - } - return err -} - /////////////////////////// // REST diff --git a/client/keys/update.go b/client/keys/update.go index c0edc5fe6..f3db82c3f 100644 --- a/client/keys/update.go +++ b/client/keys/update.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/gorilla/mux" - "github.com/pkg/errors" keys "github.com/tendermint/go-crypto/keys" "github.com/spf13/cobra" @@ -18,14 +17,12 @@ func updateKeyCommand() *cobra.Command { Use: "update ", Short: "Change the password used to protect private key", RunE: runUpdateCmd, + Args: cobra.ExactArgs(1), } return cmd } func runUpdateCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") - } name := args[0] buf := client.BufferStdin() diff --git a/client/rpc/block.go b/client/rpc/block.go index 12c65fa70..354727019 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -20,6 +20,7 @@ func blockCommand() *cobra.Command { cmd := &cobra.Command{ Use: "block [height]", Short: "Get verified data for a the block at given height", + Args: cobra.MaximumNArgs(1), RunE: printBlock, } cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") diff --git a/client/rpc/validators.go b/client/rpc/validators.go index f9b1f6f8f..892d131ac 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -16,8 +16,9 @@ import ( func validatorCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "validatorset ", + Use: "validatorset [height]", Short: "Get the full validator set at given height", + Args: cobra.MaximumNArgs(1), RunE: printValidators, } cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") diff --git a/examples/democoin/x/cool/client/cli/tx.go b/examples/democoin/x/cool/client/cli/tx.go index 9abcfd630..f502f09e1 100644 --- a/examples/democoin/x/cool/client/cli/tx.go +++ b/examples/democoin/x/cool/client/cli/tx.go @@ -3,7 +3,6 @@ package cli import ( "fmt" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -20,11 +19,8 @@ func QuizTxCmd(cdc *wire.Codec) *cobra.Command { return &cobra.Command{ Use: "cool [answer]", Short: "What's cooler than being cool?", + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide an answer") - } - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) // get the from address from the name flag @@ -56,11 +52,8 @@ func SetTrendTxCmd(cdc *wire.Codec) *cobra.Command { return &cobra.Command{ Use: "setcool [answer]", Short: "You're so cool, tell us what is cool!", + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide an answer") - } - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) // get the from address from the name flag diff --git a/examples/democoin/x/pow/client/cli/tx.go b/examples/democoin/x/pow/client/cli/tx.go index 62ee4db69..92f97d4e0 100644 --- a/examples/democoin/x/pow/client/cli/tx.go +++ b/examples/democoin/x/pow/client/cli/tx.go @@ -4,7 +4,6 @@ import ( "fmt" "strconv" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client/context" @@ -19,13 +18,8 @@ func MineCmd(cdc *wire.Codec) *cobra.Command { return &cobra.Command{ Use: "mine [difficulty] [count] [nonce] [solution]", Short: "Mine some coins with proof-of-work!", + Args: cobra.ExactArgs(4), RunE: func(cmd *cobra.Command, args []string) error { - if len(args) != 4 { - return errors.New("You must provide a difficulty, a count, a solution, and a nonce (in that order)") - } - - // get from address and parse arguments - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) from, err := ctx.GetFromAddress() From 260ab69e4f6780e8171698ffd2c5df35eae12e19 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 22:59:30 -0400 Subject: [PATCH 118/176] cleanup, move simplestaking to democoin --- baseapp/baseapp.go | 29 +++++- baseapp/baseapp_test.go | 10 +- cmd/gaia/app/app.go | 56 ++--------- examples/basecoin/app/app.go | 94 +++++++------------ examples/basecoin/cmd/basecli/main.go | 23 +---- examples/democoin/app/app.go | 54 ++--------- examples/democoin/cmd/democli/main.go | 2 +- examples/democoin/x/cool/wire.go | 11 +++ examples/democoin/x/pow/wire.go | 10 ++ .../x}/simplestake/client/cli/commands.go | 3 +- .../democoin/x}/simplestake/errors.go | 0 .../democoin/x}/simplestake/handler.go | 0 .../democoin/x}/simplestake/keeper.go | 0 .../democoin/x}/simplestake/keeper_test.go | 0 .../democoin/x}/simplestake/msgs.go | 0 .../democoin/x}/simplestake/msgs_test.go | 0 .../democoin/x}/simplestake/types.go | 0 examples/democoin/x/simplestake/wire.go | 11 +++ examples/kvstore/main.go | 2 +- mock/app.go | 2 +- types/wire.go | 8 ++ x/auth/wire.go | 12 +++ x/stake/fee_distribution.go | 9 ++ 23 files changed, 155 insertions(+), 181 deletions(-) create mode 100644 examples/democoin/x/cool/wire.go create mode 100644 examples/democoin/x/pow/wire.go rename {x => examples/democoin/x}/simplestake/client/cli/commands.go (97%) rename {x => examples/democoin/x}/simplestake/errors.go (100%) rename {x => examples/democoin/x}/simplestake/handler.go (100%) rename {x => examples/democoin/x}/simplestake/keeper.go (100%) rename {x => examples/democoin/x}/simplestake/keeper_test.go (100%) rename {x => examples/democoin/x}/simplestake/msgs.go (100%) rename {x => examples/democoin/x}/simplestake/msgs_test.go (100%) rename {x => examples/democoin/x}/simplestake/types.go (100%) create mode 100644 examples/democoin/x/simplestake/wire.go create mode 100644 types/wire.go create mode 100644 x/auth/wire.go create mode 100644 x/stake/fee_distribution.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 827408b20..210900d61 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) // Key to store the header in the DB itself. @@ -56,7 +57,7 @@ var _ abci.Application = (*BaseApp)(nil) // Create and name new BaseApp // NOTE: The db is used to store the version number for now. -func NewBaseApp(name string, logger log.Logger, db dbm.DB) *BaseApp { +func NewBaseApp(name string, cdc *wire.Codec, logger log.Logger, db dbm.DB) *BaseApp { app := &BaseApp{ Logger: logger, name: name, @@ -64,6 +65,7 @@ func NewBaseApp(name string, logger log.Logger, db dbm.DB) *BaseApp { cms: store.NewCommitMultiStore(db), router: NewRouter(), codespacer: sdk.NewCodespacer(), + txDecoder: defaultTxDecoder(cdc), } // Register the undefined & root codespaces, which should not be used by any modules app.codespacer.RegisterOrPanic(sdk.CodespaceUndefined) @@ -98,10 +100,31 @@ func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) { app.cms.MountStoreWithDB(key, typ, nil) } -// nolint - Set functions +// Set the txDecoder function func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) { app.txDecoder = txDecoder } + +// default custom logic for transaction decoding +func defaultTxDecoder(cdc *wire.Codec) sdk.TxDecoder { + return func(txBytes []byte) (sdk.Tx, sdk.Error) { + var tx = sdk.StdTx{} + + if len(txBytes) == 0 { + return nil, sdk.ErrTxDecode("txBytes are empty") + } + + // StdTx.Msg is an interface. The concrete types + // are registered by MakeTxCodec + err := cdc.UnmarshalBinary(txBytes, &tx) + if err != nil { + return nil, sdk.ErrTxDecode("").Trace(err.Error()) + } + return tx, nil + } +} + +// nolint - Set functions func (app *BaseApp) SetInitChainer(initChainer sdk.InitChainer) { app.initChainer = initChainer } @@ -217,7 +240,7 @@ func (app *BaseApp) setDeliverState(header abci.Header) { } } -//---------------------------------------- +//______________________________________________________________________________ // ABCI // Implements ABCI diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index f70521009..fe061622c 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -25,7 +25,7 @@ func defaultLogger() log.Logger { func newBaseApp(name string) *BaseApp { logger := defaultLogger() db := dbm.NewMemDB() - return NewBaseApp(name, logger, db) + return NewBaseApp(name, nil, logger, db) } func TestMountStores(t *testing.T) { @@ -59,7 +59,7 @@ func TestLoadVersion(t *testing.T) { logger := defaultLogger() db := dbm.NewMemDB() name := t.Name() - app := NewBaseApp(name, logger, db) + app := NewBaseApp(name, nil, logger, db) // make a cap key and mount the store capKey := sdk.NewKVStoreKey("main") @@ -81,7 +81,7 @@ func TestLoadVersion(t *testing.T) { commitID := sdk.CommitID{1, res.Data} // reload - app = NewBaseApp(name, logger, db) + app = NewBaseApp(name, nil, logger, db) app.MountStoresIAVL(capKey) err = app.LoadLatestVersion(capKey) // needed to make stores non-nil assert.Nil(t, err) @@ -147,7 +147,7 @@ func TestInitChainer(t *testing.T) { name := t.Name() db := dbm.NewMemDB() logger := defaultLogger() - app := NewBaseApp(name, logger, db) + app := NewBaseApp(name, nil, logger, db) // make cap keys and mount the stores // NOTE/TODO: mounting multiple stores is broken // see https://github.com/cosmos/cosmos-sdk/issues/532 @@ -184,7 +184,7 @@ func TestInitChainer(t *testing.T) { assert.Equal(t, value, res.Value) // reload app - app = NewBaseApp(name, logger, db) + app = NewBaseApp(name, nil, logger, db) app.MountStoresIAVL(capKey, capKey2) err = app.LoadLatestVersion(capKey) // needed to make stores non-nil assert.Nil(t, err) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 9ece80ea7..690dafe53 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -43,48 +43,38 @@ type GaiaApp struct { coinKeeper bank.Keeper ibcMapper ibc.Mapper stakeKeeper stake.Keeper - - // Handle fees - feeHandler sdk.FeeHandler } func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { + cdc := MakeCodec() + // create your application object var app = &GaiaApp{ - BaseApp: bam.NewBaseApp(appName, logger, db), - cdc: MakeCodec(), + BaseApp: bam.NewBaseApp(appName, cdc, logger, db), + cdc: cdc, keyMain: sdk.NewKVStoreKey("main"), keyAccount: sdk.NewKVStoreKey("acc"), keyIBC: sdk.NewKVStoreKey("ibc"), keyStake: sdk.NewKVStoreKey("stake"), } - // define the accountMapper - app.accountMapper = auth.NewAccountMapper( - app.cdc, - app.keyMain, // target store - &auth.BaseAccount{}, // prototype - ) - - // add handlers + // add accountMapper/handlers + app.accountMapper = auth.NewAccountMapper(app.cdc, app.keyMain, &auth.BaseAccount{}) app.coinKeeper = bank.NewKeeper(app.accountMapper) app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) + // register message routes app.Router(). AddRoute("bank", bank.NewHandler(app.coinKeeper)). AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). AddRoute("stake", stake.NewHandler(app.stakeKeeper)) - // Define the feeHandler. - app.feeHandler = auth.BurnFeeHandler - // initialize BaseApp - app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeHandler)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, stake.FeeHandler)) err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) @@ -96,41 +86,15 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { // custom tx codec func MakeCodec() *wire.Codec { var cdc = wire.NewCodec() - - // Register Msgs - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - ibc.RegisterWire(cdc) bank.RegisterWire(cdc) stake.RegisterWire(cdc) - - // Register AppAccount - cdc.RegisterInterface((*sdk.Account)(nil), nil) - cdc.RegisterConcrete(&auth.BaseAccount{}, "gaia/Account", nil) - - // Register crypto. + auth.RegisterWire(cdc) + sdk.RegisterWire(cdc) wire.RegisterCrypto(cdc) - return cdc } -// custom logic for transaction decoding -func (app *GaiaApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { - var tx = sdk.StdTx{} - - if len(txBytes) == 0 { - return nil, sdk.ErrTxDecode("txBytes are empty") - } - - // StdTx.Msg is an interface. The concrete types - // are registered by MakeTxCodec - err := app.cdc.UnmarshalBinary(txBytes, &tx) - if err != nil { - return nil, sdk.ErrTxDecode("").Trace(err.Error()) - } - return tx, nil -} - // custom logic for gaia initialization func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.AppStateBytes diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index ead9c78e3..a1ec9a38b 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" - "github.com/cosmos/cosmos-sdk/x/simplestake" + "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" ) @@ -27,16 +27,16 @@ type BasecoinApp struct { cdc *wire.Codec // keys to access the substores - capKeyMainStore *sdk.KVStoreKey - capKeyAccountStore *sdk.KVStoreKey - capKeyIBCStore *sdk.KVStoreKey - capKeyStakingStore *sdk.KVStoreKey + keyMain *sdk.KVStoreKey + keyAccount *sdk.KVStoreKey + keyIBC *sdk.KVStoreKey + keyStake *sdk.KVStoreKey // Manage getting and setting accounts accountMapper sdk.AccountMapper - - // Handle fees - feeHandler sdk.FeeHandler + coinKeeper bank.Keeper + ibcMapper ibc.Mapper + stakeKeeper stake.Keeper } func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { @@ -46,86 +46,58 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // Create your application object. var app = &BasecoinApp{ - BaseApp: bam.NewBaseApp(appName, logger, db), - cdc: cdc, - capKeyMainStore: sdk.NewKVStoreKey("main"), - capKeyAccountStore: sdk.NewKVStoreKey("acc"), - capKeyIBCStore: sdk.NewKVStoreKey("ibc"), - capKeyStakingStore: sdk.NewKVStoreKey("stake"), + BaseApp: bam.NewBaseApp(appName, cdc, logger, db), + cdc: cdc, + keyMain: sdk.NewKVStoreKey("main"), + keyAccount: sdk.NewKVStoreKey("acc"), + keyIBC: sdk.NewKVStoreKey("ibc"), + keyStake: sdk.NewKVStoreKey("stake"), } // Define the accountMapper. app.accountMapper = auth.NewAccountMapper( cdc, - app.capKeyMainStore, // target store + app.keyMain, // target store &types.AppAccount{}, // prototype ) - // Add handlers. - coinKeeper := bank.NewKeeper(app.accountMapper) - ibcMapper := ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) - stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) - app.Router(). - AddRoute("bank", bank.NewHandler(coinKeeper)). - AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). - AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) + // add accountMapper/handlers + app.coinKeeper = bank.NewKeeper(app.accountMapper) + app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) + app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) - // Define the feeHandler. - app.feeHandler = auth.BurnFeeHandler + // register message routes + app.Router(). + AddRoute("bank", bank.NewHandler(app.coinKeeper)). + AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). + AddRoute("stake", stake.NewHandler(app.stakeKeeper)) // Initialize BaseApp. - app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainer) - app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyIBCStore, app.capKeyStakingStore) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeHandler)) - err := app.LoadLatestVersion(app.capKeyMainStore) + app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, auth.BurnFeeHandler)) + err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) } - return app } // Custom tx codec func MakeCodec() *wire.Codec { var cdc = wire.NewCodec() + wire.RegisterCrypto(cdc) // Register crypto. + sdk.RegisterWire(cdc) // Register Msgs + bank.RegisterWire(cdc) + stake.RegisterWire(cdc) + ibc.RegisterWire(cdc) - // Register Msgs - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.MsgSend{}, "basecoin/Send", nil) - cdc.RegisterConcrete(bank.MsgIssue{}, "basecoin/Issue", nil) - cdc.RegisterConcrete(ibc.IBCTransferMsg{}, "basecoin/IBCTransferMsg", nil) - cdc.RegisterConcrete(ibc.IBCReceiveMsg{}, "basecoin/IBCReceiveMsg", nil) - cdc.RegisterConcrete(simplestake.MsgBond{}, "basecoin/BondMsg", nil) - cdc.RegisterConcrete(simplestake.MsgUnbond{}, "basecoin/UnbondMsg", nil) - - // Register AppAccount + // register custom AppAccount cdc.RegisterInterface((*sdk.Account)(nil), nil) cdc.RegisterConcrete(&types.AppAccount{}, "basecoin/Account", nil) - - // Register crypto. - wire.RegisterCrypto(cdc) - return cdc } -// Custom logic for transaction decoding -func (app *BasecoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { - var tx = sdk.StdTx{} - - if len(txBytes) == 0 { - return nil, sdk.ErrTxDecode("txBytes are empty") - } - - // StdTx.Msg is an interface. The concrete types - // are registered by MakeTxCodec in bank.RegisterAmino. - err := app.cdc.UnmarshalBinary(txBytes, &tx) - if err != nil { - return nil, sdk.ErrTxDecode("").Trace(err.Error()) - } - return tx, nil -} - // Custom logic for basecoin initialization func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.AppStateBytes diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index c2a6145aa..50800450f 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -14,13 +14,11 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/version" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" - simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/client/cli" + stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" - "github.com/cosmos/cosmos-sdk/examples/basecoin/types" ) // rootCmd is the entry point for this binary @@ -49,26 +47,15 @@ func main() { rootCmd.AddCommand(client.LineBreak) // add query/post commands (custom to binary) - rootCmd.AddCommand( - client.GetCommands( - authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)), - )...) rootCmd.AddCommand( client.PostCommands( bankcmd.SendTxCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( ibccmd.IBCTransferCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( ibccmd.IBCRelayCmd(cdc), - simplestakingcmd.BondTxCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( - simplestakingcmd.UnbondTxCmd(cdc), + stakecmd.GetCmdDeclareCandidacy(cdc), + stakecmd.GetCmdEditCandidacy(cdc), + stakecmd.GetCmdDelegate(cdc), + stakecmd.GetCmdUnbond(cdc), )...) // add proxy, version and key info diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 8266b2b9b..aabd4c41c 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -12,11 +12,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" - "github.com/cosmos/cosmos-sdk/x/simplestake" "github.com/cosmos/cosmos-sdk/examples/democoin/types" "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool" "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow" + "github.com/cosmos/cosmos-sdk/examples/democoin/x/simplestake" "github.com/cosmos/cosmos-sdk/examples/democoin/x/sketchy" ) @@ -38,9 +38,6 @@ type DemocoinApp struct { // Manage getting and setting accounts accountMapper sdk.AccountMapper - - // Handle fees - feeHandler sdk.FeeHandler } func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { @@ -50,7 +47,7 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { // Create your application object. var app = &DemocoinApp{ - BaseApp: bam.NewBaseApp(appName, logger, db), + BaseApp: bam.NewBaseApp(appName, cdc, logger, db), cdc: cdc, capKeyMainStore: sdk.NewKVStoreKey("main"), capKeyAccountStore: sdk.NewKVStoreKey("acc"), @@ -80,65 +77,34 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) - // Define the feeHandler. - app.feeHandler = auth.BurnFeeHandler - // Initialize BaseApp. - app.SetTxDecoder(app.txDecoder) app.SetInitChainer(app.initChainerFn(coolKeeper, powKeeper)) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeHandler)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, auth.BurnFeeHandler)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) } - return app } // custom tx codec func MakeCodec() *wire.Codec { var cdc = wire.NewCodec() - - // Register Msgs - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.MsgSend{}, "democoin/Send", nil) - cdc.RegisterConcrete(bank.MsgIssue{}, "democoin/Issue", nil) - cdc.RegisterConcrete(cool.MsgQuiz{}, "democoin/Quiz", nil) - cdc.RegisterConcrete(cool.MsgSetTrend{}, "democoin/SetTrend", nil) - cdc.RegisterConcrete(pow.MsgMine{}, "democoin/Mine", nil) - cdc.RegisterConcrete(ibc.IBCTransferMsg{}, "democoin/IBCTransferMsg", nil) - cdc.RegisterConcrete(ibc.IBCReceiveMsg{}, "democoin/IBCReceiveMsg", nil) - cdc.RegisterConcrete(simplestake.MsgBond{}, "democoin/BondMsg", nil) - cdc.RegisterConcrete(simplestake.MsgUnbond{}, "democoin/UnbondMsg", nil) + wire.RegisterCrypto(cdc) // Register crypto. + sdk.RegisterWire(cdc) // Register Msgs + cool.RegisterWire(cdc) + pow.RegisterWire(cdc) + bank.RegisterWire(cdc) + ibc.RegisterWire(cdc) + simplestake.RegisterWire(cdc) // Register AppAccount cdc.RegisterInterface((*sdk.Account)(nil), nil) cdc.RegisterConcrete(&types.AppAccount{}, "democoin/Account", nil) - - // Register crypto. - wire.RegisterCrypto(cdc) - return cdc } -// custom logic for transaction decoding -func (app *DemocoinApp) txDecoder(txBytes []byte) (sdk.Tx, sdk.Error) { - var tx = sdk.StdTx{} - - if len(txBytes) == 0 { - return nil, sdk.ErrTxDecode("txBytes are empty") - } - - // StdTx.Msg is an interface. The concrete types - // are registered by MakeTxCodec in bank.RegisterWire. - err := app.cdc.UnmarshalBinary(txBytes, &tx) - if err != nil { - return nil, sdk.ErrTxDecode("").Trace(err.Error()) - } - return tx, nil -} - // custom logic for democoin initialization func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keeper) sdk.InitChainer { return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { diff --git a/examples/democoin/cmd/democli/main.go b/examples/democoin/cmd/democli/main.go index 534b88ca2..45a448c2e 100644 --- a/examples/democoin/cmd/democli/main.go +++ b/examples/democoin/cmd/democli/main.go @@ -17,12 +17,12 @@ import ( authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" - simplestakingcmd "github.com/cosmos/cosmos-sdk/x/simplestake/client/cli" "github.com/cosmos/cosmos-sdk/examples/democoin/app" "github.com/cosmos/cosmos-sdk/examples/democoin/types" coolcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/cool/client/cli" powcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow/client/cli" + simplestakingcmd "github.com/cosmos/cosmos-sdk/examples/democoin/x/simplestake/client/cli" ) // rootCmd is the entry point for this binary diff --git a/examples/democoin/x/cool/wire.go b/examples/democoin/x/cool/wire.go new file mode 100644 index 000000000..63666888a --- /dev/null +++ b/examples/democoin/x/cool/wire.go @@ -0,0 +1,11 @@ +package cool + +import ( + "github.com/cosmos/cosmos-sdk/wire" +) + +// Register concrete types on wire codec +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterConcrete(MsgQuiz{}, "cool/Quiz", nil) + cdc.RegisterConcrete(MsgSetTrend{}, "cool/SetTrend", nil) +} diff --git a/examples/democoin/x/pow/wire.go b/examples/democoin/x/pow/wire.go new file mode 100644 index 000000000..3d7f61486 --- /dev/null +++ b/examples/democoin/x/pow/wire.go @@ -0,0 +1,10 @@ +package pow + +import ( + "github.com/cosmos/cosmos-sdk/wire" +) + +// Register concrete types on wire codec +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterConcrete(MsgMine{}, "pow/Mine", nil) +} diff --git a/x/simplestake/client/cli/commands.go b/examples/democoin/x/simplestake/client/cli/commands.go similarity index 97% rename from x/simplestake/client/cli/commands.go rename to examples/democoin/x/simplestake/client/cli/commands.go index 54ef73ac4..ede1efc75 100644 --- a/x/simplestake/client/cli/commands.go +++ b/examples/democoin/x/simplestake/client/cli/commands.go @@ -13,7 +13,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" - "github.com/cosmos/cosmos-sdk/x/simplestake" + + "github.com/cosmos/cosmos-sdk/examples/democoin/x/simplestake" ) const ( diff --git a/x/simplestake/errors.go b/examples/democoin/x/simplestake/errors.go similarity index 100% rename from x/simplestake/errors.go rename to examples/democoin/x/simplestake/errors.go diff --git a/x/simplestake/handler.go b/examples/democoin/x/simplestake/handler.go similarity index 100% rename from x/simplestake/handler.go rename to examples/democoin/x/simplestake/handler.go diff --git a/x/simplestake/keeper.go b/examples/democoin/x/simplestake/keeper.go similarity index 100% rename from x/simplestake/keeper.go rename to examples/democoin/x/simplestake/keeper.go diff --git a/x/simplestake/keeper_test.go b/examples/democoin/x/simplestake/keeper_test.go similarity index 100% rename from x/simplestake/keeper_test.go rename to examples/democoin/x/simplestake/keeper_test.go diff --git a/x/simplestake/msgs.go b/examples/democoin/x/simplestake/msgs.go similarity index 100% rename from x/simplestake/msgs.go rename to examples/democoin/x/simplestake/msgs.go diff --git a/x/simplestake/msgs_test.go b/examples/democoin/x/simplestake/msgs_test.go similarity index 100% rename from x/simplestake/msgs_test.go rename to examples/democoin/x/simplestake/msgs_test.go diff --git a/x/simplestake/types.go b/examples/democoin/x/simplestake/types.go similarity index 100% rename from x/simplestake/types.go rename to examples/democoin/x/simplestake/types.go diff --git a/examples/democoin/x/simplestake/wire.go b/examples/democoin/x/simplestake/wire.go new file mode 100644 index 000000000..4ef971b44 --- /dev/null +++ b/examples/democoin/x/simplestake/wire.go @@ -0,0 +1,11 @@ +package simplestake + +import ( + "github.com/cosmos/cosmos-sdk/wire" +) + +// Register concrete types on wire codec +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterConcrete(MsgBond{}, "simplestake/BondMsg", nil) + cdc.RegisterConcrete(MsgUnbond{}, "simplestake/UnbondMsg", nil) +} diff --git a/examples/kvstore/main.go b/examples/kvstore/main.go index d6b71171d..856538f63 100644 --- a/examples/kvstore/main.go +++ b/examples/kvstore/main.go @@ -32,7 +32,7 @@ func main() { var capKeyMainStore = sdk.NewKVStoreKey("main") // Create BaseApp. - var baseApp = bam.NewBaseApp("kvstore", logger, db) + var baseApp = bam.NewBaseApp("kvstore", nil, logger, db) // Set mounts for BaseApp's MultiStore. baseApp.MountStoresIAVL(capKeyMainStore) diff --git a/mock/app.go b/mock/app.go index 84f762db0..ab1a8447a 100644 --- a/mock/app.go +++ b/mock/app.go @@ -29,7 +29,7 @@ func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { capKeyMainStore := sdk.NewKVStoreKey("main") // Create BaseApp. - baseApp := bam.NewBaseApp("kvstore", logger, db) + baseApp := bam.NewBaseApp("kvstore", nil, logger, db) // Set mounts for BaseApp's MultiStore. baseApp.MountStoresIAVL(capKeyMainStore) diff --git a/types/wire.go b/types/wire.go new file mode 100644 index 000000000..245b3677c --- /dev/null +++ b/types/wire.go @@ -0,0 +1,8 @@ +package types + +import wire "github.com/cosmos/cosmos-sdk/wire" + +// Register the sdk message type +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterInterface((*Msg)(nil), nil) +} diff --git a/x/auth/wire.go b/x/auth/wire.go new file mode 100644 index 000000000..9db1b85cc --- /dev/null +++ b/x/auth/wire.go @@ -0,0 +1,12 @@ +package auth + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" +) + +// Register concrete types on wire codec for default AppAccount +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterConcrete(&BaseAccount{}, "auth/Account", nil) +} diff --git a/x/stake/fee_distribution.go b/x/stake/fee_distribution.go new file mode 100644 index 000000000..cff42c706 --- /dev/null +++ b/x/stake/fee_distribution.go @@ -0,0 +1,9 @@ +package stake + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func FeeHandler(ctx sdk.Context, tx sdk.Tx, fee sdk.Coins) { + +} From bffb0132a519bb3183584cb0090aa0b341bc45f1 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 27 Apr 2018 15:20:12 -0400 Subject: [PATCH 119/176] lint fix, add make test_lint --- Makefile | 5 ++++- x/stake/fee_distribution.go | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 855d96357..acbfba951 100644 --- a/Makefile +++ b/Makefile @@ -99,6 +99,9 @@ test_unit: test_cover: @bash tests/test_cover.sh +test_lint: + gometalinter --disable-all --enable='golint' --vendor ./... + benchmark: @go test -bench=. $(PACKAGES) @@ -130,4 +133,4 @@ devdoc_update: # To avoid unintended conflicts with file names, always add to .PHONY # unless there is a reason not to. # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: build build_examples install install_examples dist check_tools get_tools get_vendor_deps draw_deps test test_unit test_tutorial benchmark devdoc_init devdoc devdoc_save devdoc_update +.PHONY: build build_examples install install_examples dist check_tools get_tools get_vendor_deps draw_deps test test_nocli test_unit test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update diff --git a/x/stake/fee_distribution.go b/x/stake/fee_distribution.go index cff42c706..940a66e38 100644 --- a/x/stake/fee_distribution.go +++ b/x/stake/fee_distribution.go @@ -4,6 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// Handle fee distribution to the validators and delegators func FeeHandler(ctx sdk.Context, tx sdk.Tx, fee sdk.Coins) { } From ff66629b68ac5fd2592dbd351670c14afedf3156 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Apr 2018 14:51:35 +0200 Subject: [PATCH 120/176] Example WriteGenesis implementation --- examples/democoin/x/pow/keeper.go | 18 +++++++++++++++++- examples/democoin/x/pow/keeper_test.go | 4 ++++ types/initgenesis.go | 10 ---------- 3 files changed, 21 insertions(+), 11 deletions(-) delete mode 100644 types/initgenesis.go diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 9a5edf0b5..4d95840b7 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -36,13 +36,29 @@ func NewKeeper(key sdk.StoreKey, config Config, ck bank.Keeper, codespace sdk.Co return Keeper{key, config, ck, codespace} } -// Init Genessis for the POW module +// InitGenesis for the POW module func (k Keeper) InitGenesis(ctx sdk.Context, genesis Genesis) error { k.SetLastDifficulty(ctx, genesis.Difficulty) k.SetLastCount(ctx, genesis.Count) return nil } +// WriteGenesis for the PoW module +func (k Keeper) WriteGenesis(ctx sdk.Context) Genesis { + difficulty, err := k.GetLastDifficulty(ctx) + if err != nil { + panic(err) + } + count, err := k.GetLastCount(ctx) + if err != nil { + panic(err) + } + return Genesis{ + difficulty, + count, + } +} + var lastDifficultyKey = []byte("lastDifficultyKey") // get the last mining difficulty diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index 4c01559f6..015f98556 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -40,6 +40,10 @@ func TestPowKeeperGetSet(t *testing.T) { err := keeper.InitGenesis(ctx, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) + genesis := keeper.WriteGenesis(ctx) + assert.Nil(t, err) + assert.Equal(t, genesis, Genesis{uint64(1), uint64(0)}) + res, err := keeper.GetLastDifficulty(ctx) assert.Nil(t, err) assert.Equal(t, res, uint64(1)) diff --git a/types/initgenesis.go b/types/initgenesis.go deleted file mode 100644 index ff3c03cf4..000000000 --- a/types/initgenesis.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import ( - "encoding/json" -) - -// Run only once on chain initialization, should write genesis state to store -// or throw an error if some required information was not provided, in which case -// the application will panic. -type InitGenesis func(ctx Context, data json.RawMessage) error From f71191e402a2045a65b7166e72545178016ba766 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 24 Apr 2018 12:49:37 +0200 Subject: [PATCH 121/176] Add simple WriteGenesis for stake & cool modules --- cmd/gaia/app/app.go | 2 +- examples/democoin/x/cool/keeper.go | 6 ++++++ x/stake/handler.go | 9 ++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 690dafe53..46e8e3a2f 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -113,7 +113,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + app.stakeKeeper.InitGenesis(ctx, genesisState.StakeData) return abci.ResponseInitChain{} } diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index b180cd23c..6a1f8da6d 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -48,3 +48,9 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data Genesis) error { k.setTrend(ctx, data.Trend) return nil } + +// WriteGenesis - output the genesis trend +func (k Keeper) WriteGenesis(ctx sdk.Context) Genesis { + trend := k.GetTrend(ctx) + return Genesis{trend} +} diff --git a/x/stake/handler.go b/x/stake/handler.go index e39720385..a04bdf862 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -49,7 +49,7 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ // InitGenesis - store genesis parameters -func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { +func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { k.setPool(ctx, data.Pool) k.setParams(ctx, data.Params) for _, candidate := range data.Candidates { @@ -57,6 +57,13 @@ func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { } } +// WriteGenesis - output genesis parameters +func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { + pool := k.GetPool(ctx) + params := k.GetParams(ctx) + return GenesisState{pool, params} +} + //_____________________________________________________________________ // These functions assume everything has been authenticated, From 0436d890c7dd9d273f6fa49226e7461e259bf714 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 24 Apr 2018 15:05:19 +0200 Subject: [PATCH 122/176] Add candidates & bonds to stake module genesis --- x/stake/handler.go | 12 +++++++++++- x/stake/keeper.go | 28 ++++++++++++++++++++++++++-- x/stake/types.go | 7 ++++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index a04bdf862..d7b7ef86e 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -55,13 +55,23 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { for _, candidate := range data.Candidates { k.setCandidate(ctx, candidate) } + for _, bond := range data.Bonds { + k.setDelegatorBond(ctx, bond) + } } // WriteGenesis - output genesis parameters func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) - return GenesisState{pool, params} + candidates := k.GetCandidates(ctx, -1) + bonds := k.GetBonds(ctx, -1) + return GenesisState{ + pool, + params, + candidates, + bonds, + } } //_____________________________________________________________________ diff --git a/x/stake/keeper.go b/x/stake/keeper.go index f1b436314..d30d7b46e 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -74,7 +74,7 @@ func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candi return candidate, true } -// Get the set of all candidates, retrieve a maxRetrieve number of records +// Get the set of all candidates, retrieve a maxRetrieve number of records, -1 maxRetrieve = no limit func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Candidates) { store := ctx.KVStore(k.storeKey) iterator := store.Iterator(subspace(CandidatesKey)) @@ -82,7 +82,7 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca candidates = make([]Candidate, maxRetrieve) i := 0 for ; ; i++ { - if !iterator.Valid() || i > int(maxRetrieve-1) { + if !iterator.Valid() || (maxRetrieve >= 0 && i > int(maxRetrieve-1)) { iterator.Close() break } @@ -371,6 +371,30 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context, return bond, true } +// load all bonds, -1 maxRetrieve = no limit +func (k Keeper) GetBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorBond) { + store := ctx.KVStore(k.storeKey) + iterator := store.Iterator(subspace(DelegatorBondKeyPrefix)) + + bonds = make([]DelegatorBond, maxRetrieve) + i := 0 + for ; ; i++ { + if !iterator.Valid() || (maxRetrieve >= 0 && i > int(maxRetrieve-1)) { + iterator.Close() + break + } + bondBytes := iterator.Value() + var bond DelegatorBond + err := k.cdc.UnmarshalBinary(bondBytes, &bond) + if err != nil { + panic(err) + } + bonds[i] = bond + iterator.Next() + } + return bonds[:i] // trim +} + // load all bonds of a delegator func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (bonds []DelegatorBond) { store := ctx.KVStore(k.storeKey) diff --git a/x/stake/types.go b/x/stake/types.go index 634b51186..6e15acd96 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -9,9 +9,10 @@ import ( // GenesisState - all staking state that must be provided at genesis type GenesisState struct { - Pool Pool `json:"pool"` - Params Params `json:"params"` - Candidates []Candidate `json:"candidates"` + Pool Pool `json:"pool"` + Params Params `json:"params"` + Candidates []Candidate `json:"candidates"` + Bonds []DelegatorBond `json:"bonds"` } //_________________________________________________________________________ From 203d2c19ccf95a48ffa0dd939bfed7b1d6fae756 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 24 Apr 2018 15:26:28 +0200 Subject: [PATCH 123/176] Add export command to stake module --- x/stake/commands/export.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 x/stake/commands/export.go diff --git a/x/stake/commands/export.go b/x/stake/commands/export.go new file mode 100644 index 000000000..f3d1516d5 --- /dev/null +++ b/x/stake/commands/export.go @@ -0,0 +1,30 @@ +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" // XXX fix + "github.com/cosmos/cosmos-sdk/x/stake" +) + +// get the command to export state +func GetCmdExport(load func() (stake.Keeper, sdk.Context), cdc *wire.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "export", + Short: "Export stake module state as JSON to stdout", + RunE: func(cmd *cobra.Command, args []string) error { + keeper, ctx := load() + genesis := keeper.WriteGenesis(ctx) + output, err := wire.MarshalJSONIndent(cdc, genesis) + if err != nil { + return err + } + fmt.Println(string(output)) + return nil + }, + } + return cmd +} From 55c82e44a2c3ab5623a2826e26dacd51b9713115 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 24 Apr 2018 15:46:39 +0200 Subject: [PATCH 124/176] export-stake command works --- cmd/gaia/app/app.go | 5 +++++ cmd/gaia/cmd/gaiad/main.go | 2 ++ x/stake/commands/export.go | 11 ++++++----- x/stake/handler.go | 4 ++-- x/stake/keeper.go | 8 ++++---- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 46e8e3a2f..9c7eb5180 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -117,3 +117,8 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci return abci.ResponseInitChain{} } + +// custom logic for export +func (app *GaiaApp) ExportStake() stake.GenesisState { + return app.stakeKeeper.WriteGenesis(app.NewContext(true, abci.Header{})) +} diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 0417671a2..ca9b72cdf 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -12,6 +12,8 @@ import ( "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" + stake "github.com/cosmos/cosmos-sdk/x/stake" + stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands" ) func main() { diff --git a/x/stake/commands/export.go b/x/stake/commands/export.go index f3d1516d5..679aa5d1a 100644 --- a/x/stake/commands/export.go +++ b/x/stake/commands/export.go @@ -5,19 +5,20 @@ import ( "github.com/spf13/cobra" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" // XXX fix "github.com/cosmos/cosmos-sdk/x/stake" ) // get the command to export state -func GetCmdExport(load func() (stake.Keeper, sdk.Context), cdc *wire.Codec) *cobra.Command { +func GetCmdExport(export func() (stake.GenesisState, error), cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ - Use: "export", + Use: "export-stake", Short: "Export stake module state as JSON to stdout", RunE: func(cmd *cobra.Command, args []string) error { - keeper, ctx := load() - genesis := keeper.WriteGenesis(ctx) + genesis, err := export() + if err != nil { + return err + } output, err := wire.MarshalJSONIndent(cdc, genesis) if err != nil { return err diff --git a/x/stake/handler.go b/x/stake/handler.go index d7b7ef86e..36e1110d8 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -64,8 +64,8 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) - candidates := k.GetCandidates(ctx, -1) - bonds := k.GetBonds(ctx, -1) + candidates := k.GetCandidates(ctx, 32767) + bonds := k.GetBonds(ctx, 32767) return GenesisState{ pool, params, diff --git a/x/stake/keeper.go b/x/stake/keeper.go index d30d7b46e..6bb3f054f 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -74,7 +74,7 @@ func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candi return candidate, true } -// Get the set of all candidates, retrieve a maxRetrieve number of records, -1 maxRetrieve = no limit +// Get the set of all candidates, retrieve a maxRetrieve number of records func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Candidates) { store := ctx.KVStore(k.storeKey) iterator := store.Iterator(subspace(CandidatesKey)) @@ -82,7 +82,7 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca candidates = make([]Candidate, maxRetrieve) i := 0 for ; ; i++ { - if !iterator.Valid() || (maxRetrieve >= 0 && i > int(maxRetrieve-1)) { + if !iterator.Valid() || i > int(maxRetrieve-1) { iterator.Close() break } @@ -371,7 +371,7 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context, return bond, true } -// load all bonds, -1 maxRetrieve = no limit +// load all bonds func (k Keeper) GetBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorBond) { store := ctx.KVStore(k.storeKey) iterator := store.Iterator(subspace(DelegatorBondKeyPrefix)) @@ -379,7 +379,7 @@ func (k Keeper) GetBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorB bonds = make([]DelegatorBond, maxRetrieve) i := 0 for ; ; i++ { - if !iterator.Valid() || (maxRetrieve >= 0 && i > int(maxRetrieve-1)) { + if !iterator.Valid() || i > int(maxRetrieve-1) { iterator.Close() break } From f92e83d2e07c85495978e5720a6b72f73639e3f0 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 17:53:07 +0200 Subject: [PATCH 125/176] Swap to general `export` command --- cmd/gaia/app/app.go | 7 ++-- cmd/gaia/cmd/gaiad/main.go | 17 +++++++-- examples/basecoin/app/app.go | 5 +++ examples/basecoin/cmd/basecoind/main.go | 13 ++++++- examples/democoin/app/app.go | 19 ++++++++-- examples/democoin/cmd/democoind/main.go | 18 +++++++++- server/export.go | 48 +++++++++++++++++++++++++ server/util.go | 5 ++- x/stake/commands/export.go | 31 ---------------- 9 files changed, 122 insertions(+), 41 deletions(-) create mode 100644 server/export.go delete mode 100644 x/stake/commands/export.go diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 9c7eb5180..fe4782689 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -119,6 +119,9 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // custom logic for export -func (app *GaiaApp) ExportStake() stake.GenesisState { - return app.stakeKeeper.WriteGenesis(app.NewContext(true, abci.Header{})) +func (app *GaiaApp) ExportGenesis() GenesisState { + return GenesisState{ + Accounts: []GenesisAccount{}, + StakeData: app.stakeKeeper.WriteGenesis(app.NewContext(true, abci.Header{})), + } } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index ca9b72cdf..36b709952 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -12,8 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" - stake "github.com/cosmos/cosmos-sdk/x/stake" - stakecmd "github.com/cosmos/cosmos-sdk/x/stake/commands" + "github.com/cosmos/cosmos-sdk/wire" ) func main() { @@ -26,6 +25,7 @@ func main() { } server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp) + server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp, exportApp) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome) @@ -41,3 +41,16 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { bapp := app.NewGaiaApp(logger, db) return bapp, nil } + +func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB("gaia", dataDir) + if err != nil { + return nil, nil, err + } + bapp := app.NewGaiaApp(log.NewNopLogger(), db) + if err != nil { + return nil, nil, err + } + return bapp.ExportGenesis(), app.MakeCodec(), nil +} diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index a1ec9a38b..c85ff4441 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -119,3 +119,8 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) } return abci.ResponseInitChain{} } + +// Custom logic for state export +func (app *BasecoinApp) ExportGenesis() types.GenesisState { + return types.GenesisState{} +} diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 8d14821c6..5a165735e 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/wire" ) func main() { @@ -25,7 +26,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, generateApp) + server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, generateApp, exportApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") @@ -42,3 +43,13 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { bapp := app.NewBasecoinApp(logger, db) return bapp, nil } + +func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB("basecoin", dataDir) + if err != nil { + return nil, nil, err + } + bapp := app.NewBasecoinApp(logger, db) + return bapp.ExportGenesis(), nil, nil +} diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index aabd4c41c..516e3b675 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -36,6 +36,9 @@ type DemocoinApp struct { capKeyIBCStore *sdk.KVStoreKey capKeyStakingStore *sdk.KVStoreKey + // keepers + powKeeper pow.Keeper + // Manage getting and setting accounts accountMapper sdk.AccountMapper } @@ -66,19 +69,19 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { // Add handlers. coinKeeper := bank.NewKeeper(app.accountMapper) coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper, app.RegisterCodespace(cool.DefaultCodespace)) - powKeeper := pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) + app.powKeeper = pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) ibcMapper := ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). AddRoute("cool", cool.NewHandler(coolKeeper)). - AddRoute("pow", powKeeper.Handler). + AddRoute("pow", app.powKeeper.Handler). AddRoute("sketchy", sketchy.NewHandler()). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) // Initialize BaseApp. - app.SetInitChainer(app.initChainerFn(coolKeeper, powKeeper)) + app.SetInitChainer(app.initChainerFn(coolKeeper, app.powKeeper)) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, auth.BurnFeeHandler)) err := app.LoadLatestVersion(app.capKeyMainStore) @@ -142,3 +145,13 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep return abci.ResponseInitChain{} } } + +// Custom logic for state export +func (app *DemocoinApp) ExportGenesis() types.GenesisState { + ctx := app.NewContext(true, abci.Header{}) + return types.GenesisState{ + Accounts: []*types.GenesisAccount{}, + POWGenesis: app.powKeeper.WriteGenesis(ctx), + CoolGenesis: cool.Genesis{}, + } +} diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index afca80bce..738420e8d 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -32,6 +32,12 @@ func CoolAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso key := "cool" value := json.RawMessage(`{ "trend": "ice-cold" + }`) + appState, err = server.AppendJSON(cdc, appState, key, value) + key = "pow" + value = json.RawMessage(`{ + "difficulty": 1, + "count": 0 }`) appState, err = server.AppendJSON(cdc, appState, key, value) return @@ -46,6 +52,16 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { return bapp, nil } +func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB("democoin", dataDir) + if err != nil { + return nil, nil, err + } + bapp := app.NewDemocoinApp(logger, db) + return bapp.ExportGenesis(), nil, nil +} + func main() { cdc := app.MakeCodec() ctx := server.NewDefaultContext() @@ -56,7 +72,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, generateApp) + server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, generateApp, exportApp) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/server/export.go b/server/export.go new file mode 100644 index 000000000..9430eeb48 --- /dev/null +++ b/server/export.go @@ -0,0 +1,48 @@ +package server + +import ( + "fmt" + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/tendermint/tmlibs/log" + + "github.com/cosmos/cosmos-sdk/wire" +) + +// AppExporter dumps all app state to JSON-serializable structure +type AppExporter func(home string, log log.Logger) (interface{}, *wire.Codec, error) + +// ExportCmd dumps app state to JSON +func ExportCmd(app AppExporter, ctx *Context) *cobra.Command { + export := exportCmd{ + appExporter: app, + context: ctx, + } + cmd := &cobra.Command{ + Use: "export", + Short: "Export state to JSON", + RunE: export.run, + } + return cmd +} + +type exportCmd struct { + appExporter AppExporter + context *Context +} + +func (e exportCmd) run(cmd *cobra.Command, args []string) error { + home := viper.GetString("home") + genesis, cdc, err := e.appExporter(home, e.context.Logger) + if err != nil { + return errors.Errorf("Error exporting state: %v\n", err) + } + output, err := wire.MarshalJSONIndent(cdc, genesis) + if err != nil { + return errors.Errorf("Error marshalling state: %v\n", err) + } + fmt.Println(string(output)) + return nil +} diff --git a/server/util.go b/server/util.go index ed91f3048..6e7c56af0 100644 --- a/server/util.go +++ b/server/util.go @@ -68,7 +68,8 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator AppCreator) { + appCreator AppCreator, appExporter AppExporter, + context *Context) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") @@ -78,6 +79,8 @@ func AddCommands( UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), ShowValidatorCmd(ctx), + ExportCmd(appExporter, context), + UnsafeResetAllCmd(context), version.VersionCmd, ) } diff --git a/x/stake/commands/export.go b/x/stake/commands/export.go deleted file mode 100644 index 679aa5d1a..000000000 --- a/x/stake/commands/export.go +++ /dev/null @@ -1,31 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/wire" // XXX fix - "github.com/cosmos/cosmos-sdk/x/stake" -) - -// get the command to export state -func GetCmdExport(export func() (stake.GenesisState, error), cdc *wire.Codec) *cobra.Command { - cmd := &cobra.Command{ - Use: "export-stake", - Short: "Export stake module state as JSON to stdout", - RunE: func(cmd *cobra.Command, args []string) error { - genesis, err := export() - if err != nil { - return err - } - output, err := wire.MarshalJSONIndent(cdc, genesis) - if err != nil { - return err - } - fmt.Println(string(output)) - return nil - }, - } - return cmd -} From 724c1eced5869300d265c0cec9b5eeb114844e60 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 18:07:13 +0200 Subject: [PATCH 126/176] Minor cleanup --- examples/basecoin/app/app.go | 10 +++++++++- examples/democoin/app/app.go | 28 ++++++++++++++++------------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index c85ff4441..529bb99d7 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" + "github.com/cosmos/cosmos-sdk/examples/democoin/x/simplestake" ) const ( @@ -32,6 +33,11 @@ type BasecoinApp struct { keyIBC *sdk.KVStoreKey keyStake *sdk.KVStoreKey + // keepers + coinKeeper bank.Keeper + ibcMapper ibc.Mapper + stakeKeeper simplestake.Keeper + // Manage getting and setting accounts accountMapper sdk.AccountMapper coinKeeper bank.Keeper @@ -122,5 +128,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) // Custom logic for state export func (app *BasecoinApp) ExportGenesis() types.GenesisState { - return types.GenesisState{} + return types.GenesisState{ + Accounts: []*types.GenesisAccount{}, + } } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 516e3b675..c0b8dd092 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -37,7 +37,11 @@ type DemocoinApp struct { capKeyStakingStore *sdk.KVStoreKey // keepers - powKeeper pow.Keeper + coinKeeper bank.Keeper + coolKeeper cool.Keeper + powKeeper pow.Keeper + ibcMapper ibc.Mapper + stakeKeeper simplestake.Keeper // Manage getting and setting accounts accountMapper sdk.AccountMapper @@ -67,21 +71,21 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { ) // Add handlers. - coinKeeper := bank.NewKeeper(app.accountMapper) - coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper, app.RegisterCodespace(cool.DefaultCodespace)) - app.powKeeper = pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) - ibcMapper := ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) - stakeKeeper := simplestake.NewKeeper(app.capKeyStakingStore, coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) + app.coinKeeper = bank.NewKeeper(app.accountMapper) + app.coolKeeper = cool.NewKeeper(app.capKeyMainStore, app.coinKeeper, app.RegisterCodespace(cool.DefaultCodespace)) + app.powKeeper = pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), app.coinKeeper, app.RegisterCodespace(pow.DefaultCodespace)) + app.ibcMapper = ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace)) + app.stakeKeeper = simplestake.NewKeeper(app.capKeyStakingStore, app.coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace)) app.Router(). - AddRoute("bank", bank.NewHandler(coinKeeper)). - AddRoute("cool", cool.NewHandler(coolKeeper)). + AddRoute("bank", bank.NewHandler(app.coinKeeper)). + AddRoute("cool", cool.NewHandler(app.coolKeeper)). AddRoute("pow", app.powKeeper.Handler). AddRoute("sketchy", sketchy.NewHandler()). - AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). - AddRoute("simplestake", simplestake.NewHandler(stakeKeeper)) + AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). + AddRoute("simplestake", simplestake.NewHandler(app.stakeKeeper)) // Initialize BaseApp. - app.SetInitChainer(app.initChainerFn(coolKeeper, app.powKeeper)) + app.SetInitChainer(app.initChainerFn(app.coolKeeper, app.powKeeper)) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, auth.BurnFeeHandler)) err := app.LoadLatestVersion(app.capKeyMainStore) @@ -152,6 +156,6 @@ func (app *DemocoinApp) ExportGenesis() types.GenesisState { return types.GenesisState{ Accounts: []*types.GenesisAccount{}, POWGenesis: app.powKeeper.WriteGenesis(ctx), - CoolGenesis: cool.Genesis{}, + CoolGenesis: app.coolKeeper.WriteGenesis(ctx), } } From 9746260d1d30440e8af61753e196bc3704727d89 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 18:34:25 +0200 Subject: [PATCH 127/176] Add testcases --- examples/democoin/x/cool/keeper_test.go | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 examples/democoin/x/cool/keeper_test.go diff --git a/examples/democoin/x/cool/keeper_test.go b/examples/democoin/x/cool/keeper_test.go new file mode 100644 index 000000000..470efea0a --- /dev/null +++ b/examples/democoin/x/cool/keeper_test.go @@ -0,0 +1,50 @@ +package cool + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + abci "github.com/tendermint/abci/types" + dbm "github.com/tendermint/tmlibs/db" + + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + auth "github.com/cosmos/cosmos-sdk/x/auth" + bank "github.com/cosmos/cosmos-sdk/x/bank" +) + +func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { + db := dbm.NewMemDB() + capKey := sdk.NewKVStoreKey("capkey") + ms := store.NewCommitMultiStore(db) + ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db) + ms.LoadLatestVersion() + return ms, capKey +} + +func TestCoolKeeper(t *testing.T) { + ms, capKey := setupMultiStore() + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) + + am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ck := bank.NewKeeper(am) + keeper := NewKeeper(capKey, ck, DefaultCodespace) + + err := keeper.InitGenesis(ctx, Genesis{"icy"}) + assert.Nil(t, err) + + genesis := keeper.WriteGenesis(ctx) + assert.Nil(t, err) + assert.Equal(t, genesis, Genesis{"icy"}) + + res := keeper.GetTrend(ctx) + assert.Equal(t, res, "icy") + + keeper.setTrend(ctx, "fiery") + res = keeper.GetTrend(ctx) + assert.Equal(t, res, "fiery") +} From 88b364d5a01e98eb2e5547fd98f433a2788e74cc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 18:44:26 +0200 Subject: [PATCH 128/176] Minor bugfix --- examples/basecoin/cmd/basecoind/main.go | 2 +- examples/democoin/cmd/democoind/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 5a165735e..164ef6865 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -51,5 +51,5 @@ func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, err return nil, nil, err } bapp := app.NewBasecoinApp(logger, db) - return bapp.ExportGenesis(), nil, nil + return bapp.ExportGenesis(), app.MakeCodec(), nil } diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 738420e8d..92e4af70f 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -59,7 +59,7 @@ func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, err return nil, nil, err } bapp := app.NewDemocoinApp(logger, db) - return bapp.ExportGenesis(), nil, nil + return bapp.ExportGenesis(), app.MakeCodec(), nil } func main() { From dbdf6aae0e54026037ac9a64e93d99556dde1d47 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 18:49:08 +0200 Subject: [PATCH 129/176] Test GetBonds --- x/stake/keeper_test.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index e3edfbf9e..61737def7 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -94,7 +94,7 @@ func TestCandidate(t *testing.T) { assert.False(t, found) } -// tests GetDelegatorBond, GetDelegatorBonds, SetDelegatorBond, removeDelegatorBond +// tests GetDelegatorBond, GetDelegatorBonds, SetDelegatorBond, removeDelegatorBond, GetBonds func TestBond(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) @@ -172,6 +172,14 @@ func TestBond(t *testing.T) { assert.True(t, bondsEqual(bond2to1, resBonds[0])) assert.True(t, bondsEqual(bond2to2, resBonds[1])) assert.True(t, bondsEqual(bond2to3, resBonds[2])) + allBonds := keeper.GetBonds(ctx, 1000) + require.Equal(t, 6, len(allBonds)) + assert.True(t, bondsEqual(bond1to1, allBonds[0])) + assert.True(t, bondsEqual(bond1to2, allBonds[1])) + assert.True(t, bondsEqual(bond1to3, allBonds[2])) + assert.True(t, bondsEqual(bond2to1, allBonds[3])) + assert.True(t, bondsEqual(bond2to2, allBonds[4])) + assert.True(t, bondsEqual(bond2to3, allBonds[5])) // delete a record keeper.removeDelegatorBond(ctx, bond2to3) From c788c3e5330a07e194765fdef541d506645fdc5c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 20:13:16 +0200 Subject: [PATCH 130/176] GetBonds => getBonds --- x/stake/handler.go | 2 +- x/stake/keeper.go | 2 +- x/stake/keeper_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index 36e1110d8..6c09b8d7c 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -65,7 +65,7 @@ func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) candidates := k.GetCandidates(ctx, 32767) - bonds := k.GetBonds(ctx, 32767) + bonds := k.getBonds(ctx, 32767) return GenesisState{ pool, params, diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 6bb3f054f..e53d5ce09 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -372,7 +372,7 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context, } // load all bonds -func (k Keeper) GetBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorBond) { +func (k Keeper) getBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorBond) { store := ctx.KVStore(k.storeKey) iterator := store.Iterator(subspace(DelegatorBondKeyPrefix)) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 61737def7..3878b7bbb 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -172,7 +172,7 @@ func TestBond(t *testing.T) { assert.True(t, bondsEqual(bond2to1, resBonds[0])) assert.True(t, bondsEqual(bond2to2, resBonds[1])) assert.True(t, bondsEqual(bond2to3, resBonds[2])) - allBonds := keeper.GetBonds(ctx, 1000) + allBonds := keeper.getBonds(ctx, 1000) require.Equal(t, 6, len(allBonds)) assert.True(t, bondsEqual(bond1to1, allBonds[0])) assert.True(t, bondsEqual(bond1to2, allBonds[1])) From 9450779bba49f129ab6fa0314d0621e1e42d86d5 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 20:19:02 +0200 Subject: [PATCH 131/176] InitGenesis & WriteGenesis no longer functions of keepers --- cmd/gaia/app/app.go | 4 ++-- examples/democoin/app/app.go | 8 ++++---- examples/democoin/x/cool/keeper.go | 4 ++-- examples/democoin/x/cool/keeper_test.go | 4 ++-- examples/democoin/x/pow/handler_test.go | 2 +- examples/democoin/x/pow/keeper.go | 4 ++-- examples/democoin/x/pow/keeper_test.go | 4 ++-- x/stake/handler.go | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index fe4782689..59fb3a209 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -113,7 +113,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - app.stakeKeeper.InitGenesis(ctx, genesisState.StakeData) + stake.InitGenesis(app.stakeKeeper, ctx, genesisState.StakeData) return abci.ResponseInitChain{} } @@ -122,6 +122,6 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci func (app *GaiaApp) ExportGenesis() GenesisState { return GenesisState{ Accounts: []GenesisAccount{}, - StakeData: app.stakeKeeper.WriteGenesis(app.NewContext(true, abci.Header{})), + StakeData: stake.WriteGenesis(app.stakeKeeper, app.NewContext(true, abci.Header{})), } } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index c0b8dd092..d4c2a2ba3 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -134,13 +134,13 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Application specific genesis handling - err = coolKeeper.InitGenesis(ctx, genesisState.CoolGenesis) + err = cool.InitGenesis(app.coolKeeper, ctx, genesisState.CoolGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") } - err = powKeeper.InitGenesis(ctx, genesisState.POWGenesis) + err = pow.InitGenesis(app.powKeeper, ctx, genesisState.POWGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") @@ -155,7 +155,7 @@ func (app *DemocoinApp) ExportGenesis() types.GenesisState { ctx := app.NewContext(true, abci.Header{}) return types.GenesisState{ Accounts: []*types.GenesisAccount{}, - POWGenesis: app.powKeeper.WriteGenesis(ctx), - CoolGenesis: app.coolKeeper.WriteGenesis(ctx), + POWGenesis: pow.WriteGenesis(app.powKeeper, ctx), + CoolGenesis: cool.WriteGenesis(app.coolKeeper, ctx), } } diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index 6a1f8da6d..d594e29af 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -44,13 +44,13 @@ func (k Keeper) CheckTrend(ctx sdk.Context, guessedTrend string) bool { } // InitGenesis - store the genesis trend -func (k Keeper) InitGenesis(ctx sdk.Context, data Genesis) error { +func InitGenesis(k Keeper, ctx sdk.Context, data Genesis) error { k.setTrend(ctx, data.Trend) return nil } // WriteGenesis - output the genesis trend -func (k Keeper) WriteGenesis(ctx sdk.Context) Genesis { +func WriteGenesis(k Keeper, ctx sdk.Context) Genesis { trend := k.GetTrend(ctx) return Genesis{trend} } diff --git a/examples/democoin/x/cool/keeper_test.go b/examples/democoin/x/cool/keeper_test.go index 470efea0a..7fa8009fd 100644 --- a/examples/democoin/x/cool/keeper_test.go +++ b/examples/democoin/x/cool/keeper_test.go @@ -34,10 +34,10 @@ func TestCoolKeeper(t *testing.T) { ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, ck, DefaultCodespace) - err := keeper.InitGenesis(ctx, Genesis{"icy"}) + err := InitGenesis(keeper, ctx, Genesis{"icy"}) assert.Nil(t, err) - genesis := keeper.WriteGenesis(ctx) + genesis := WriteGenesis(keeper, ctx) assert.Nil(t, err) assert.Equal(t, genesis, Genesis{"icy"}) diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index 8a4f81de2..b6f568ee1 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -30,7 +30,7 @@ func TestPowHandler(t *testing.T) { count := uint64(1) difficulty := uint64(2) - err := keeper.InitGenesis(ctx, Genesis{uint64(1), uint64(0)}) + err := InitGenesis(keeper, ctx, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) nonce, proof := mine(addr, count, difficulty) diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 4d95840b7..398009a13 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -37,14 +37,14 @@ func NewKeeper(key sdk.StoreKey, config Config, ck bank.Keeper, codespace sdk.Co } // InitGenesis for the POW module -func (k Keeper) InitGenesis(ctx sdk.Context, genesis Genesis) error { +func InitGenesis(k Keeper, ctx sdk.Context, genesis Genesis) error { k.SetLastDifficulty(ctx, genesis.Difficulty) k.SetLastCount(ctx, genesis.Count) return nil } // WriteGenesis for the PoW module -func (k Keeper) WriteGenesis(ctx sdk.Context) Genesis { +func WriteGenesis(k Keeper, ctx sdk.Context) Genesis { difficulty, err := k.GetLastDifficulty(ctx) if err != nil { panic(err) diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index 015f98556..23cad93f7 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -37,10 +37,10 @@ func TestPowKeeperGetSet(t *testing.T) { ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, config, ck, DefaultCodespace) - err := keeper.InitGenesis(ctx, Genesis{uint64(1), uint64(0)}) + err := InitGenesis(keeper, ctx, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) - genesis := keeper.WriteGenesis(ctx) + genesis := WriteGenesis(keeper, ctx) assert.Nil(t, err) assert.Equal(t, genesis, Genesis{uint64(1), uint64(0)}) diff --git a/x/stake/handler.go b/x/stake/handler.go index 6c09b8d7c..b1d58bf13 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -49,7 +49,7 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ // InitGenesis - store genesis parameters -func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { +func InitGenesis(k Keeper, ctx sdk.Context, data GenesisState) { k.setPool(ctx, data.Pool) k.setParams(ctx, data.Params) for _, candidate := range data.Candidates { @@ -61,7 +61,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data GenesisState) { } // WriteGenesis - output genesis parameters -func (k Keeper) WriteGenesis(ctx sdk.Context) GenesisState { +func WriteGenesis(k Keeper, ctx sdk.Context) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) candidates := k.GetCandidates(ctx, 32767) From df4fdb3642d620018b44f355bb293aae84ab6f70 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 21:34:32 +0200 Subject: [PATCH 132/176] Rebase & merge changes --- cmd/gaia/cmd/gaiad/main.go | 1 - server/util.go | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 36b709952..d791ef59f 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -24,7 +24,6 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp) server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp, exportApp) // prepare and add flags diff --git a/server/util.go b/server/util.go index 6e7c56af0..e77d50039 100644 --- a/server/util.go +++ b/server/util.go @@ -68,8 +68,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator AppCreator, appExporter AppExporter, - context *Context) { + appCreator AppCreator, appExporter AppExporter) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") @@ -79,8 +78,8 @@ func AddCommands( UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), ShowValidatorCmd(ctx), - ExportCmd(appExporter, context), - UnsafeResetAllCmd(context), + ExportCmd(appExporter, ctx), + UnsafeResetAllCmd(ctx), version.VersionCmd, ) } From f6cef029046f7629b4f02052c15b187c639b6fcc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 22:52:35 +0200 Subject: [PATCH 133/176] Reorder parameters & remove redundant check --- cmd/gaia/app/app.go | 4 ++-- cmd/gaia/cmd/gaiad/main.go | 11 ++++------- examples/democoin/app/app.go | 8 ++++---- examples/democoin/x/cool/keeper.go | 4 ++-- examples/democoin/x/cool/keeper_test.go | 4 ++-- examples/democoin/x/pow/handler_test.go | 2 +- examples/democoin/x/pow/keeper.go | 4 ++-- examples/democoin/x/pow/keeper_test.go | 4 ++-- x/stake/handler.go | 4 ++-- 9 files changed, 21 insertions(+), 24 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 59fb3a209..a60c03851 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -113,7 +113,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - stake.InitGenesis(app.stakeKeeper, ctx, genesisState.StakeData) + stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) return abci.ResponseInitChain{} } @@ -122,6 +122,6 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci func (app *GaiaApp) ExportGenesis() GenesisState { return GenesisState{ Accounts: []GenesisAccount{}, - StakeData: stake.WriteGenesis(app.stakeKeeper, app.NewContext(true, abci.Header{})), + StakeData: stake.WriteGenesis(app.NewContext(true, abci.Header{}), app.stakeKeeper), } } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index d791ef59f..0e456453e 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -37,8 +37,8 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { if err != nil { return nil, err } - bapp := app.NewGaiaApp(logger, db) - return bapp, nil + gapp := app.NewGaiaApp(logger, db) + return gapp, nil } func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { @@ -47,9 +47,6 @@ func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, err if err != nil { return nil, nil, err } - bapp := app.NewGaiaApp(log.NewNopLogger(), db) - if err != nil { - return nil, nil, err - } - return bapp.ExportGenesis(), app.MakeCodec(), nil + gapp := app.NewGaiaApp(log.NewNopLogger(), db) + return gapp.ExportGenesis(), app.MakeCodec(), nil } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index d4c2a2ba3..cb16c53d7 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -134,13 +134,13 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Application specific genesis handling - err = cool.InitGenesis(app.coolKeeper, ctx, genesisState.CoolGenesis) + err = cool.InitGenesis(ctx, app.coolKeeper, genesisState.CoolGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") } - err = pow.InitGenesis(app.powKeeper, ctx, genesisState.POWGenesis) + err = pow.InitGenesis(ctx, app.powKeeper, genesisState.POWGenesis) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") @@ -155,7 +155,7 @@ func (app *DemocoinApp) ExportGenesis() types.GenesisState { ctx := app.NewContext(true, abci.Header{}) return types.GenesisState{ Accounts: []*types.GenesisAccount{}, - POWGenesis: pow.WriteGenesis(app.powKeeper, ctx), - CoolGenesis: cool.WriteGenesis(app.coolKeeper, ctx), + POWGenesis: pow.WriteGenesis(ctx, app.powKeeper), + CoolGenesis: cool.WriteGenesis(ctx, app.coolKeeper), } } diff --git a/examples/democoin/x/cool/keeper.go b/examples/democoin/x/cool/keeper.go index d594e29af..fef93b954 100644 --- a/examples/democoin/x/cool/keeper.go +++ b/examples/democoin/x/cool/keeper.go @@ -44,13 +44,13 @@ func (k Keeper) CheckTrend(ctx sdk.Context, guessedTrend string) bool { } // InitGenesis - store the genesis trend -func InitGenesis(k Keeper, ctx sdk.Context, data Genesis) error { +func InitGenesis(ctx sdk.Context, k Keeper, data Genesis) error { k.setTrend(ctx, data.Trend) return nil } // WriteGenesis - output the genesis trend -func WriteGenesis(k Keeper, ctx sdk.Context) Genesis { +func WriteGenesis(ctx sdk.Context, k Keeper) Genesis { trend := k.GetTrend(ctx) return Genesis{trend} } diff --git a/examples/democoin/x/cool/keeper_test.go b/examples/democoin/x/cool/keeper_test.go index 7fa8009fd..9aca3cc2a 100644 --- a/examples/democoin/x/cool/keeper_test.go +++ b/examples/democoin/x/cool/keeper_test.go @@ -34,10 +34,10 @@ func TestCoolKeeper(t *testing.T) { ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, ck, DefaultCodespace) - err := InitGenesis(keeper, ctx, Genesis{"icy"}) + err := InitGenesis(ctx, keeper, Genesis{"icy"}) assert.Nil(t, err) - genesis := WriteGenesis(keeper, ctx) + genesis := WriteGenesis(ctx, keeper) assert.Nil(t, err) assert.Equal(t, genesis, Genesis{"icy"}) diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index b6f568ee1..0fffb8f5b 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -30,7 +30,7 @@ func TestPowHandler(t *testing.T) { count := uint64(1) difficulty := uint64(2) - err := InitGenesis(keeper, ctx, Genesis{uint64(1), uint64(0)}) + err := InitGenesis(ctx, keeper, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) nonce, proof := mine(addr, count, difficulty) diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 398009a13..931e41a32 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -37,14 +37,14 @@ func NewKeeper(key sdk.StoreKey, config Config, ck bank.Keeper, codespace sdk.Co } // InitGenesis for the POW module -func InitGenesis(k Keeper, ctx sdk.Context, genesis Genesis) error { +func InitGenesis(ctx sdk.Context, k Keeper, genesis Genesis) error { k.SetLastDifficulty(ctx, genesis.Difficulty) k.SetLastCount(ctx, genesis.Count) return nil } // WriteGenesis for the PoW module -func WriteGenesis(k Keeper, ctx sdk.Context) Genesis { +func WriteGenesis(ctx sdk.Context, k Keeper) Genesis { difficulty, err := k.GetLastDifficulty(ctx) if err != nil { panic(err) diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index 23cad93f7..cb021eb16 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -37,10 +37,10 @@ func TestPowKeeperGetSet(t *testing.T) { ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, config, ck, DefaultCodespace) - err := InitGenesis(keeper, ctx, Genesis{uint64(1), uint64(0)}) + err := InitGenesis(ctx, keeper, Genesis{uint64(1), uint64(0)}) assert.Nil(t, err) - genesis := WriteGenesis(keeper, ctx) + genesis := WriteGenesis(ctx, keeper) assert.Nil(t, err) assert.Equal(t, genesis, Genesis{uint64(1), uint64(0)}) diff --git a/x/stake/handler.go b/x/stake/handler.go index b1d58bf13..2b55ba3b1 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -49,7 +49,7 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker { //_____________________________________________________________________ // InitGenesis - store genesis parameters -func InitGenesis(k Keeper, ctx sdk.Context, data GenesisState) { +func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) { k.setPool(ctx, data.Pool) k.setParams(ctx, data.Params) for _, candidate := range data.Candidates { @@ -61,7 +61,7 @@ func InitGenesis(k Keeper, ctx sdk.Context, data GenesisState) { } // WriteGenesis - output genesis parameters -func WriteGenesis(k Keeper, ctx sdk.Context) GenesisState { +func WriteGenesis(ctx sdk.Context, k Keeper) GenesisState { pool := k.GetPool(ctx) params := k.GetParams(ctx) candidates := k.GetCandidates(ctx, 32767) From 10d2e5ae403fecc5780b19401163bb6ea537f21b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 27 Apr 2018 13:38:11 +0200 Subject: [PATCH 134/176] Move generateApp & exportApp to baseapp/helpers --- baseapp/baseapp.go | 7 +++++ baseapp/helpers.go | 38 +++++++++++++++++++++++++ cmd/gaia/app/app.go | 2 +- cmd/gaia/cmd/gaiad/main.go | 28 ++++++------------ examples/basecoin/app/app.go | 2 +- examples/basecoin/cmd/basecoind/main.go | 25 ++++++---------- examples/democoin/app/app.go | 2 +- examples/democoin/cmd/democoind/main.go | 26 ++++++----------- server/export.go | 10 ++----- server/start.go | 13 +++------ server/util.go | 3 +- 11 files changed, 83 insertions(+), 73 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 210900d61..515970d04 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -241,6 +241,13 @@ func (app *BaseApp) setDeliverState(header abci.Header) { } //______________________________________________________________________________ + +// ExportGenesis returns the genesis state in a wire-serializable format +// should be overridden by applications extending baseapp +func (app *BaseApp) ExportGenesis() interface{} { + return nil +} + // ABCI // Implements ABCI diff --git a/baseapp/helpers.go b/baseapp/helpers.go index 43bd654d6..e2007a1f5 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -1,9 +1,14 @@ package baseapp import ( + "path/filepath" + + "github.com/cosmos/cosmos-sdk/wire" "github.com/tendermint/abci/server" abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" ) // RunForever - BasecoinApp execution and cleanup @@ -22,3 +27,36 @@ func RunForever(app abci.Application) { srv.Stop() }) } + +// AppCreator lets us lazily initialize app, using home dir +// and other flags (?) to start +type AppCreator func(string, log.Logger) (abci.Application, error) + +// AppExporter dumps all app state to JSON-serializable structure +type AppExporter func(home string, log log.Logger) (interface{}, *wire.Codec, error) + +// GenerateFn returns an application generation function +func GenerateFn(appFn func(log.Logger, dbm.DB) abci.Application, name string) AppCreator { + return func(rootDir string, logger log.Logger) (abci.Application, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB(name, dataDir) + if err != nil { + return nil, err + } + app := appFn(logger, db) + return app, nil + } +} + +// ExportFn returns an application export function +func ExportFn(appFn func(log.Logger, dbm.DB) (interface{}, *wire.Codec), name string) AppExporter { + return func(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB(name, dataDir) + if err != nil { + return nil, nil, err + } + genesis, codec := appFn(logger, db) + return genesis, codec, nil + } +} diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index a60c03851..126422e2c 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -119,7 +119,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // custom logic for export -func (app *GaiaApp) ExportGenesis() GenesisState { +func (app *GaiaApp) ExportGenesis() interface{} { return GenesisState{ Accounts: []GenesisAccount{}, StakeData: stake.WriteGenesis(app.NewContext(true, abci.Header{}), app.stakeKeeper), diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 0e456453e..9e6dfff05 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -1,8 +1,6 @@ package main import ( - "path/filepath" - "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" @@ -10,6 +8,7 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/wire" @@ -24,29 +23,20 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp, exportApp) + server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), + baseapp.GenerateFn(newApp, "gaia"), + baseapp.ExportFn(exportApp, "gaia")) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome) executor.Execute() } -func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("gaia", dataDir) - if err != nil { - return nil, err - } - gapp := app.NewGaiaApp(logger, db) - return gapp, nil +func newApp(logger log.Logger, db dbm.DB) abci.Application { + return app.NewGaiaApp(logger, db) } -func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("gaia", dataDir) - if err != nil { - return nil, nil, err - } - gapp := app.NewGaiaApp(log.NewNopLogger(), db) - return gapp.ExportGenesis(), app.MakeCodec(), nil +func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { + gapp := app.NewGaiaApp(logger, db) + return gapp.ExportGenesis(), app.MakeCodec() } diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 529bb99d7..eb5076942 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -127,7 +127,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) } // Custom logic for state export -func (app *BasecoinApp) ExportGenesis() types.GenesisState { +func (app *BasecoinApp) ExportGenesis() interface{} { return types.GenesisState{ Accounts: []*types.GenesisAccount{}, } diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 164ef6865..4aa04a914 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -2,7 +2,6 @@ package main import ( "os" - "path/filepath" "github.com/spf13/cobra" @@ -11,6 +10,7 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/wire" @@ -26,7 +26,9 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, generateApp, exportApp) + server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, + baseapp.GenerateFn(newApp, "basecoin"), + baseapp.ExportFn(exportApp, "basecoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") @@ -34,22 +36,11 @@ func main() { executor.Execute() } -func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("basecoin", dataDir) - if err != nil { - return nil, err - } - bapp := app.NewBasecoinApp(logger, db) - return bapp, nil +func newApp(logger log.Logger, db dbm.DB) abci.Application { + return app.NewBasecoinApp(logger, db) } -func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("basecoin", dataDir) - if err != nil { - return nil, nil, err - } +func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { bapp := app.NewBasecoinApp(logger, db) - return bapp.ExportGenesis(), app.MakeCodec(), nil + return bapp.ExportGenesis(), app.MakeCodec() } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index cb16c53d7..3b383bef8 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -151,7 +151,7 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Custom logic for state export -func (app *DemocoinApp) ExportGenesis() types.GenesisState { +func (app *DemocoinApp) ExportGenesis() interface{} { ctx := app.NewContext(true, abci.Header{}) return types.GenesisState{ Accounts: []*types.GenesisAccount{}, diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 92e4af70f..8dc01faaf 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "os" - "path/filepath" "github.com/spf13/cobra" @@ -12,6 +11,7 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/examples/democoin/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/wire" @@ -43,23 +43,13 @@ func CoolAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso return } -func generateApp(rootDir string, logger log.Logger) (abci.Application, error) { - db, err := dbm.NewGoLevelDB("democoin", filepath.Join(rootDir, "data")) - if err != nil { - return nil, err - } - bapp := app.NewDemocoinApp(logger, db) - return bapp, nil +func newApp(logger log.Logger, db dbm.DB) abci.Application { + return app.NewDemocoinApp(logger, db) } -func exportApp(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB("democoin", dataDir) - if err != nil { - return nil, nil, err - } - bapp := app.NewDemocoinApp(logger, db) - return bapp.ExportGenesis(), app.MakeCodec(), nil +func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { + dapp := app.NewDemocoinApp(logger, db) + return dapp.ExportGenesis(), app.MakeCodec() } func main() { @@ -72,7 +62,9 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, generateApp, exportApp) + server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, + baseapp.GenerateFn(newApp, "democoin"), + baseapp.ExportFn(exportApp, "democoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/server/export.go b/server/export.go index 9430eeb48..3ca71217b 100644 --- a/server/export.go +++ b/server/export.go @@ -6,16 +6,12 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/tendermint/tmlibs/log" - + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/wire" ) -// AppExporter dumps all app state to JSON-serializable structure -type AppExporter func(home string, log log.Logger) (interface{}, *wire.Codec, error) - // ExportCmd dumps app state to JSON -func ExportCmd(app AppExporter, ctx *Context) *cobra.Command { +func ExportCmd(app baseapp.AppExporter, ctx *Context) *cobra.Command { export := exportCmd{ appExporter: app, context: ctx, @@ -29,7 +25,7 @@ func ExportCmd(app AppExporter, ctx *Context) *cobra.Command { } type exportCmd struct { - appExporter AppExporter + appExporter baseapp.AppExporter context *Context } diff --git a/server/start.go b/server/start.go index c9a38abdf..79f5e3980 100644 --- a/server/start.go +++ b/server/start.go @@ -6,14 +6,13 @@ import ( "github.com/spf13/viper" "github.com/tendermint/abci/server" - abci "github.com/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/baseapp" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/proxy" pvm "github.com/tendermint/tendermint/types/priv_validator" cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" ) const ( @@ -21,13 +20,9 @@ const ( flagAddress = "address" ) -// AppCreator lets us lazily initialize app, using home dir -// and other flags (?) to start -type AppCreator func(string, log.Logger) (abci.Application, error) - // StartCmd runs the service passed in, either // stand-alone, or in-process with tendermint -func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { +func StartCmd(ctx *Context, appCreator baseapp.AppCreator) *cobra.Command { cmd := &cobra.Command{ Use: "start", Short: "Run the full node", @@ -50,7 +45,7 @@ func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { return cmd } -func startStandAlone(ctx *Context, appCreator AppCreator) error { +func startStandAlone(ctx *Context, appCreator baseapp.AppCreator) error { // Generate the app in the proper dir addr := viper.GetString(flagAddress) home := viper.GetString("home") @@ -74,7 +69,7 @@ func startStandAlone(ctx *Context, appCreator AppCreator) error { return nil } -func startInProcess(ctx *Context, appCreator AppCreator) error { +func startInProcess(ctx *Context, appCreator baseapp.AppCreator) error { cfg := ctx.Config home := cfg.RootDir app, err := appCreator(home, ctx.Logger) diff --git a/server/util.go b/server/util.go index e77d50039..31e472839 100644 --- a/server/util.go +++ b/server/util.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/wire" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" @@ -68,7 +69,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator AppCreator, appExporter AppExporter) { + appCreator baseapp.AppCreator, appExporter baseapp.AppExporter) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") From ad77affb53096e1017bfdba28da8ac7f9547705d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 27 Apr 2018 16:59:47 +0200 Subject: [PATCH 135/176] Add IterateAccounts & account export --- cmd/gaia/app/app.go | 13 +++++++++++-- examples/basecoin/app/app.go | 11 ++++++++++- examples/democoin/app/app.go | 10 +++++++++- types/account.go | 1 + x/auth/mapper.go | 17 +++++++++++++++++ 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 126422e2c..532a1e095 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -120,8 +120,17 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci // custom logic for export func (app *GaiaApp) ExportGenesis() interface{} { + ctx := app.NewContext(true, abci.Header{}) + accounts := []GenesisAccount{} + app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { + accounts = append(accounts, GenesisAccount{ + Address: a.GetAddress(), + Coins: a.GetCoins(), + }) + return false + }) return GenesisState{ - Accounts: []GenesisAccount{}, - StakeData: stake.WriteGenesis(app.NewContext(true, abci.Header{}), app.stakeKeeper), + Accounts: accounts, + StakeData: stake.WriteGenesis(ctx, app.stakeKeeper), } } diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index eb5076942..532c25f76 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -128,7 +128,16 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) // Custom logic for state export func (app *BasecoinApp) ExportGenesis() interface{} { + ctx := app.NewContext(true, abci.Header{}) + accounts := []*types.GenesisAccount{} + app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { + accounts = append(accounts, &types.GenesisAccount{ + Address: a.GetAddress(), + Coins: a.GetCoins(), + }) + return false + }) return types.GenesisState{ - Accounts: []*types.GenesisAccount{}, + Accounts: accounts, } } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 3b383bef8..5f2cd32d8 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -153,8 +153,16 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep // Custom logic for state export func (app *DemocoinApp) ExportGenesis() interface{} { ctx := app.NewContext(true, abci.Header{}) + accounts := []*types.GenesisAccount{} + app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { + accounts = append(accounts, &types.GenesisAccount{ + Address: a.GetAddress(), + Coins: a.GetCoins(), + }) + return false + }) return types.GenesisState{ - Accounts: []*types.GenesisAccount{}, + Accounts: accounts, POWGenesis: pow.WriteGenesis(ctx, app.powKeeper), CoolGenesis: cool.WriteGenesis(ctx, app.coolKeeper), } diff --git a/types/account.go b/types/account.go index 91ad49979..33332867c 100644 --- a/types/account.go +++ b/types/account.go @@ -48,6 +48,7 @@ type AccountMapper interface { NewAccountWithAddress(ctx Context, addr Address) Account GetAccount(ctx Context, addr Address) Account SetAccount(ctx Context, acc Account) + IterateAccounts(ctx Context, cont func(Account) bool) } // AccountDecoder unmarshals account bytes diff --git a/x/auth/mapper.go b/x/auth/mapper.go index b815fada7..fea98876d 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -62,6 +62,23 @@ func (am accountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { store.Set(addr, bz) } +// Implements sdk.AccountMapper. +func (am accountMapper) IterateAccounts(ctx sdk.Context, cont func(sdk.Account) bool) { + store := ctx.KVStore(am.key) + iter := store.Iterator(nil, nil) + for { + if !iter.Valid() { + return + } + val := iter.Value() + acc := am.decodeAccount(val) + if cont(acc) { + return + } + iter.Next() + } +} + //---------------------------------------- // misc. From 5759f6ab6037d5aa79cf0c45beae43917d8af963 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 27 Apr 2018 17:06:55 +0200 Subject: [PATCH 136/176] Use account store key --- cmd/gaia/app/app.go | 10 ++++++++-- examples/democoin/app/app.go | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 532a1e095..b9a77cfc5 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -58,8 +58,14 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { keyStake: sdk.NewKVStoreKey("stake"), } - // add accountMapper/handlers - app.accountMapper = auth.NewAccountMapper(app.cdc, app.keyMain, &auth.BaseAccount{}) + // define the accountMapper + app.accountMapper = auth.NewAccountMapper( + app.cdc, + app.keyAccount, // target store + &auth.BaseAccount{}, // prototype + ) + + // add handlers app.coinKeeper = bank.NewKeeper(app.accountMapper) app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 5f2cd32d8..f7da19f72 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -66,8 +66,8 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { // Define the accountMapper. app.accountMapper = auth.NewAccountMapper( cdc, - app.capKeyMainStore, // target store - &types.AppAccount{}, // prototype + app.capKeyAccountStore, // target store + &types.AppAccount{}, // prototype ) // Add handlers. From 67961476b460b4d6672f8c99034a1e440876c1a7 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 27 Apr 2018 17:14:08 +0200 Subject: [PATCH 137/176] Fix testsuite --- client/lcd/root.go | 2 +- cmd/gaia/cmd/gaiacli/main.go | 2 +- examples/basecoin/cmd/basecli/main.go | 6 ++++++ examples/democoin/cmd/democli/main.go | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/client/lcd/root.go b/client/lcd/root.go index b166d4ce4..a7be5079b 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -80,7 +80,7 @@ func createHandler(cdc *wire.Codec) http.Handler { keys.RegisterRoutes(r) rpc.RegisterRoutes(ctx, r) tx.RegisterRoutes(ctx, r, cdc) - auth.RegisterRoutes(ctx, r, cdc, "main") + auth.RegisterRoutes(ctx, r, cdc, "acc") bank.RegisterRoutes(ctx, r, cdc, kb) ibc.RegisterRoutes(ctx, r, cdc, kb) return r diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index ab0a98c69..93d6b57b9 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -44,7 +44,7 @@ func main() { // add query/post commands (custom to binary) rootCmd.AddCommand( client.GetCommands( - authcmd.GetAccountCmd("main", cdc, authcmd.GetAccountDecoder(cdc)), + authcmd.GetAccountCmd("acc", cdc, authcmd.GetAccountDecoder(cdc)), stakecmd.GetCmdQueryCandidate("stake", cdc), //stakecmd.GetCmdQueryCandidates("stake", cdc), stakecmd.GetCmdQueryDelegatorBond("stake", cdc), diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 50800450f..1cc440995 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -19,6 +19,7 @@ import ( stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" + "github.com/cosmos/cosmos-sdk/examples/basecoin/types" ) // rootCmd is the entry point for this binary @@ -47,6 +48,11 @@ func main() { rootCmd.AddCommand(client.LineBreak) // add query/post commands (custom to binary) + rootCmd.AddCommand( + client.GetCommands( + authcmd.GetAccountCmd("acc", cdc, types.GetAccountDecoder(cdc)), + )...) + rootCmd.AddCommand( client.PostCommands( bankcmd.SendTxCmd(cdc), diff --git a/examples/democoin/cmd/democli/main.go b/examples/democoin/cmd/democli/main.go index 45a448c2e..cdf9396d6 100644 --- a/examples/democoin/cmd/democli/main.go +++ b/examples/democoin/cmd/democli/main.go @@ -54,7 +54,7 @@ func main() { // start with commands common to basecoin rootCmd.AddCommand( client.GetCommands( - authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)), + authcmd.GetAccountCmd("acc", cdc, types.GetAccountDecoder(cdc)), )...) rootCmd.AddCommand( client.PostCommands( From 10ddd7a3d32ea1b9b4a1e797afcc6e9290002560 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 27 Apr 2018 20:00:33 -0400 Subject: [PATCH 138/176] refactor export function, working --- baseapp/helpers.go | 7 ++++--- cmd/gaia/app/app.go | 22 +++++++++++++--------- cmd/gaia/app/genesis.go | 7 +++++++ server/export.go | 39 ++++++++++++--------------------------- server/util.go | 5 ++--- types/account.go | 2 +- x/auth/mapper.go | 4 ++-- 7 files changed, 41 insertions(+), 45 deletions(-) diff --git a/baseapp/helpers.go b/baseapp/helpers.go index e2007a1f5..7a7884677 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -1,6 +1,7 @@ package baseapp import ( + "encoding/json" "path/filepath" "github.com/cosmos/cosmos-sdk/wire" @@ -49,14 +50,14 @@ func GenerateFn(appFn func(log.Logger, dbm.DB) abci.Application, name string) Ap } // ExportFn returns an application export function -func ExportFn(appFn func(log.Logger, dbm.DB) (interface{}, *wire.Codec), name string) AppExporter { - return func(rootDir string, logger log.Logger) (interface{}, *wire.Codec, error) { +func ExportFn(appFn func(log.Logger, dbm.DB) json.RawMessage, name string) AppExporter { + return func(rootDir string, logger log.Logger) (interface{}, error) { dataDir := filepath.Join(rootDir, "data") db, err := dbm.NewGoLevelDB(name, dataDir) if err != nil { return nil, nil, err } - genesis, codec := appFn(logger, db) + genesis := appFn(logger, db) return genesis, codec, nil } } diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index b9a77cfc5..66f16e7ad 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -1,6 +1,7 @@ package app import ( + "encoding/json" "os" abci "github.com/tendermint/abci/types" @@ -124,19 +125,22 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci return abci.ResponseInitChain{} } -// custom logic for export -func (app *GaiaApp) ExportGenesis() interface{} { +// export the state of gaia for a genesis f +func (app *GaiaApp) ExportAppStateJSON() (appState json.RawGenesis, err error) { ctx := app.NewContext(true, abci.Header{}) + + // iterate to get the accounts accounts := []GenesisAccount{} - app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { - accounts = append(accounts, GenesisAccount{ - Address: a.GetAddress(), - Coins: a.GetCoins(), - }) + appendAccount := func(acc sdk.Account) (stop bool) { + account := NewGenesisAccountI(acc) + accounts = append(accounts, account) return false - }) - return GenesisState{ + } + app.accountMapper.IterateAccounts(ctx, appendAccount) + + genState := GenesisState{ Accounts: accounts, StakeData: stake.WriteGenesis(ctx, app.stakeKeeper), } + return wire.MarshalJSONIndent(cdc, genState) } diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 513430ec9..7d0fb01d0 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -35,6 +35,13 @@ func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { } } +func NewGenesisAccountI(acc sdk.Account) GenesisAccount { + return GenesisAccount{ + Address: acc.GetAddress(), + Coins: acc.GetCoins(), + } +} + // convert GenesisAccount to auth.BaseAccount func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { return &auth.BaseAccount{ diff --git a/server/export.go b/server/export.go index 3ca71217b..8d464b3b1 100644 --- a/server/export.go +++ b/server/export.go @@ -2,6 +2,7 @@ package server import ( "fmt" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -11,34 +12,18 @@ import ( ) // ExportCmd dumps app state to JSON -func ExportCmd(app baseapp.AppExporter, ctx *Context) *cobra.Command { - export := exportCmd{ - appExporter: app, - context: ctx, - } - cmd := &cobra.Command{ +func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter baseapp.AppExporter) *cobra.Command { + return &cobra.Command{ Use: "export", Short: "Export state to JSON", - RunE: export.run, + RunE: func(cmd *cobra.Command, args []string) error { + home := viper.GetString("home") + appState, err := appExporter(home, ctx.Logger) + if err != nil { + return errors.Errorf("Error exporting state: %v\n", err) + } + fmt.Println(string(output)) + return nil + }, } - return cmd -} - -type exportCmd struct { - appExporter baseapp.AppExporter - context *Context -} - -func (e exportCmd) run(cmd *cobra.Command, args []string) error { - home := viper.GetString("home") - genesis, cdc, err := e.appExporter(home, e.context.Logger) - if err != nil { - return errors.Errorf("Error exporting state: %v\n", err) - } - output, err := wire.MarshalJSONIndent(cdc, genesis) - if err != nil { - return errors.Errorf("Error marshalling state: %v\n", err) - } - fmt.Println(string(output)) - return nil } diff --git a/server/util.go b/server/util.go index 31e472839..54377547d 100644 --- a/server/util.go +++ b/server/util.go @@ -9,7 +9,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/wire" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" @@ -69,7 +68,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator baseapp.AppCreator, appExporter baseapp.AppExporter) { + appCreator AppCreator) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") @@ -79,7 +78,7 @@ func AddCommands( UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), ShowValidatorCmd(ctx), - ExportCmd(appExporter, ctx), + ExportCmd(cts, cdc, appCreator), UnsafeResetAllCmd(ctx), version.VersionCmd, ) diff --git a/types/account.go b/types/account.go index 33332867c..b47aea28a 100644 --- a/types/account.go +++ b/types/account.go @@ -48,7 +48,7 @@ type AccountMapper interface { NewAccountWithAddress(ctx Context, addr Address) Account GetAccount(ctx Context, addr Address) Account SetAccount(ctx Context, acc Account) - IterateAccounts(ctx Context, cont func(Account) bool) + IterateAccounts(ctx Context, process func(sdk.Account) (stop bool)) } // AccountDecoder unmarshals account bytes diff --git a/x/auth/mapper.go b/x/auth/mapper.go index fea98876d..f9e202c8a 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -63,7 +63,7 @@ func (am accountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { } // Implements sdk.AccountMapper. -func (am accountMapper) IterateAccounts(ctx sdk.Context, cont func(sdk.Account) bool) { +func (am accountMapper) IterateAccounts(ctx sdk.Context, process func(sdk.Account) (stop bool)) { store := ctx.KVStore(am.key) iter := store.Iterator(nil, nil) for { @@ -72,7 +72,7 @@ func (am accountMapper) IterateAccounts(ctx sdk.Context, cont func(sdk.Account) } val := iter.Value() acc := am.decodeAccount(val) - if cont(acc) { + if process(acc) { return } iter.Next() From 318e92414528d87d06700caad71462024f315819 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 27 Apr 2018 20:36:11 -0400 Subject: [PATCH 139/176] refactor --- baseapp/baseapp.go | 6 ---- baseapp/helpers.go | 39 ----------------------- cmd/gaia/app/app.go | 4 +-- cmd/gaia/cmd/gaiad/main.go | 12 +++---- examples/basecoin/app/app.go | 13 +++----- examples/basecoin/cmd/basecli/main.go | 1 + examples/basecoin/cmd/basecoind/main.go | 11 +++---- examples/democoin/app/app.go | 24 +++++++++----- examples/democoin/cmd/democoind/main.go | 9 +++--- server/constructors.go | 42 +++++++++++++++++++++++++ server/export.go | 5 ++- server/start.go | 7 ++--- server/util.go | 4 +-- types/account.go | 2 +- 14 files changed, 89 insertions(+), 90 deletions(-) create mode 100644 server/constructors.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 515970d04..84a18aa06 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -242,12 +242,6 @@ func (app *BaseApp) setDeliverState(header abci.Header) { //______________________________________________________________________________ -// ExportGenesis returns the genesis state in a wire-serializable format -// should be overridden by applications extending baseapp -func (app *BaseApp) ExportGenesis() interface{} { - return nil -} - // ABCI // Implements ABCI diff --git a/baseapp/helpers.go b/baseapp/helpers.go index 7a7884677..43bd654d6 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -1,15 +1,9 @@ package baseapp import ( - "encoding/json" - "path/filepath" - - "github.com/cosmos/cosmos-sdk/wire" "github.com/tendermint/abci/server" abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" ) // RunForever - BasecoinApp execution and cleanup @@ -28,36 +22,3 @@ func RunForever(app abci.Application) { srv.Stop() }) } - -// AppCreator lets us lazily initialize app, using home dir -// and other flags (?) to start -type AppCreator func(string, log.Logger) (abci.Application, error) - -// AppExporter dumps all app state to JSON-serializable structure -type AppExporter func(home string, log log.Logger) (interface{}, *wire.Codec, error) - -// GenerateFn returns an application generation function -func GenerateFn(appFn func(log.Logger, dbm.DB) abci.Application, name string) AppCreator { - return func(rootDir string, logger log.Logger) (abci.Application, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB(name, dataDir) - if err != nil { - return nil, err - } - app := appFn(logger, db) - return app, nil - } -} - -// ExportFn returns an application export function -func ExportFn(appFn func(log.Logger, dbm.DB) json.RawMessage, name string) AppExporter { - return func(rootDir string, logger log.Logger) (interface{}, error) { - dataDir := filepath.Join(rootDir, "data") - db, err := dbm.NewGoLevelDB(name, dataDir) - if err != nil { - return nil, nil, err - } - genesis := appFn(logger, db) - return genesis, codec, nil - } -} diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 66f16e7ad..a9cf248e1 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -126,7 +126,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // export the state of gaia for a genesis f -func (app *GaiaApp) ExportAppStateJSON() (appState json.RawGenesis, err error) { +func (app *GaiaApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) // iterate to get the accounts @@ -142,5 +142,5 @@ func (app *GaiaApp) ExportAppStateJSON() (appState json.RawGenesis, err error) { Accounts: accounts, StakeData: stake.WriteGenesis(ctx, app.stakeKeeper), } - return wire.MarshalJSONIndent(cdc, genState) + return wire.MarshalJSONIndent(app.cdc, genState) } diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 9e6dfff05..f64498d85 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -1,6 +1,8 @@ package main import ( + "encoding/json" + "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" @@ -8,10 +10,8 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/wire" ) func main() { @@ -24,8 +24,8 @@ func main() { } server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), - baseapp.GenerateFn(newApp, "gaia"), - baseapp.ExportFn(exportApp, "gaia")) + server.ConstructAppCreator(newApp, "gaia"), + server.ConstructAppExporter(exportAppState, "gaia")) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome) @@ -36,7 +36,7 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewGaiaApp(logger, db) } -func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { +func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { gapp := app.NewGaiaApp(logger, db) - return gapp.ExportGenesis(), app.MakeCodec() + return gapp.ExportAppStateJSON() } diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 532c25f76..b8f5346cd 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -1,6 +1,8 @@ package app import ( + "encoding/json" + abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" @@ -15,7 +17,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/examples/basecoin/types" - "github.com/cosmos/cosmos-sdk/examples/democoin/x/simplestake" ) const ( @@ -33,11 +34,6 @@ type BasecoinApp struct { keyIBC *sdk.KVStoreKey keyStake *sdk.KVStoreKey - // keepers - coinKeeper bank.Keeper - ibcMapper ibc.Mapper - stakeKeeper simplestake.Keeper - // Manage getting and setting accounts accountMapper sdk.AccountMapper coinKeeper bank.Keeper @@ -127,7 +123,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) } // Custom logic for state export -func (app *BasecoinApp) ExportGenesis() interface{} { +func (app *BasecoinApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) accounts := []*types.GenesisAccount{} app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { @@ -137,7 +133,8 @@ func (app *BasecoinApp) ExportGenesis() interface{} { }) return false }) - return types.GenesisState{ + genState := types.GenesisState{ Accounts: accounts, } + return wire.MarshalJSONIndent(app.cdc, genState) } diff --git a/examples/basecoin/cmd/basecli/main.go b/examples/basecoin/cmd/basecli/main.go index 1cc440995..f5385b559 100644 --- a/examples/basecoin/cmd/basecli/main.go +++ b/examples/basecoin/cmd/basecli/main.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/version" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 4aa04a914..4e6a30a08 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "os" "github.com/spf13/cobra" @@ -10,10 +11,8 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/wire" ) func main() { @@ -27,8 +26,8 @@ func main() { } server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, - baseapp.GenerateFn(newApp, "basecoin"), - baseapp.ExportFn(exportApp, "basecoin")) + server.ConstructAppCreator(newApp, "basecoin"), + server.ConstructAppExporter(exportAppState, "basecoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") @@ -40,7 +39,7 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewBasecoinApp(logger, db) } -func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { +func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { bapp := app.NewBasecoinApp(logger, db) - return bapp.ExportGenesis(), app.MakeCodec() + return bapp.ExportAppStateJSON() } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index f7da19f72..7c8250b18 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -1,6 +1,8 @@ package app import ( + "encoding/json" + abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" @@ -151,19 +153,25 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Custom logic for state export -func (app *DemocoinApp) ExportGenesis() interface{} { +func (app *DemocoinApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) + + // iterate to get the accounts accounts := []*types.GenesisAccount{} - app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { - accounts = append(accounts, &types.GenesisAccount{ - Address: a.GetAddress(), - Coins: a.GetCoins(), - }) + appendAccount := func(acc sdk.Account) (stop bool) { + account := &types.GenesisAccount{ + Address: acc.GetAddress(), + Coins: acc.GetCoins(), + } + accounts = append(accounts, account) return false - }) - return types.GenesisState{ + } + app.accountMapper.IterateAccounts(ctx, appendAccount) + + genState := types.GenesisState{ Accounts: accounts, POWGenesis: pow.WriteGenesis(ctx, app.powKeeper), CoolGenesis: cool.WriteGenesis(ctx, app.coolKeeper), } + return wire.MarshalJSONIndent(app.cdc, genState) } diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 8dc01faaf..3283da58a 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -11,7 +11,6 @@ import ( dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/examples/democoin/app" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/wire" @@ -47,9 +46,9 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewDemocoinApp(logger, db) } -func exportApp(logger log.Logger, db dbm.DB) (interface{}, *wire.Codec) { +func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { dapp := app.NewDemocoinApp(logger, db) - return dapp.ExportGenesis(), app.MakeCodec() + return dapp.ExportAppStateJSON() } func main() { @@ -63,8 +62,8 @@ func main() { } server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, - baseapp.GenerateFn(newApp, "democoin"), - baseapp.ExportFn(exportApp, "democoin")) + server.ConstructAppCreator(newApp, "democoin"), + server.ConstructAppExporter(exportAppState, "democoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/server/constructors.go b/server/constructors.go new file mode 100644 index 000000000..3d6950062 --- /dev/null +++ b/server/constructors.go @@ -0,0 +1,42 @@ +package server + +import ( + "encoding/json" + "path/filepath" + + abci "github.com/tendermint/abci/types" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" +) + +// AppCreator lets us lazily initialize app, using home dir +// and other flags (?) to start +type AppCreator func(string, log.Logger) (abci.Application, error) + +// AppExporter dumps all app state to JSON-serializable structure +type AppExporter func(home string, log log.Logger) (json.RawMessage, error) + +// ConstructAppCreator returns an application generation function +func ConstructAppCreator(appFn func(log.Logger, dbm.DB) abci.Application, name string) AppCreator { + return func(rootDir string, logger log.Logger) (abci.Application, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB(name, dataDir) + if err != nil { + return nil, err + } + app := appFn(logger, db) + return app, nil + } +} + +// ConstructAppExporter returns an application export function +func ConstructAppExporter(appFn func(log.Logger, dbm.DB) (json.RawMessage, error), name string) AppExporter { + return func(rootDir string, logger log.Logger) (json.RawMessage, error) { + dataDir := filepath.Join(rootDir, "data") + db, err := dbm.NewGoLevelDB(name, dataDir) + if err != nil { + return nil, err + } + return appFn(logger, db) + } +} diff --git a/server/export.go b/server/export.go index 8d464b3b1..3d0e49a12 100644 --- a/server/export.go +++ b/server/export.go @@ -7,12 +7,11 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/wire" ) // ExportCmd dumps app state to JSON -func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter baseapp.AppExporter) *cobra.Command { +func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter AppExporter) *cobra.Command { return &cobra.Command{ Use: "export", Short: "Export state to JSON", @@ -22,7 +21,7 @@ func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter baseapp.AppExporter) * if err != nil { return errors.Errorf("Error exporting state: %v\n", err) } - fmt.Println(string(output)) + fmt.Println(string(appState)) return nil }, } diff --git a/server/start.go b/server/start.go index 79f5e3980..23e38749b 100644 --- a/server/start.go +++ b/server/start.go @@ -7,7 +7,6 @@ import ( "github.com/tendermint/abci/server" - "github.com/cosmos/cosmos-sdk/baseapp" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/proxy" @@ -22,7 +21,7 @@ const ( // StartCmd runs the service passed in, either // stand-alone, or in-process with tendermint -func StartCmd(ctx *Context, appCreator baseapp.AppCreator) *cobra.Command { +func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { cmd := &cobra.Command{ Use: "start", Short: "Run the full node", @@ -45,7 +44,7 @@ func StartCmd(ctx *Context, appCreator baseapp.AppCreator) *cobra.Command { return cmd } -func startStandAlone(ctx *Context, appCreator baseapp.AppCreator) error { +func startStandAlone(ctx *Context, appCreator AppCreator) error { // Generate the app in the proper dir addr := viper.GetString(flagAddress) home := viper.GetString("home") @@ -69,7 +68,7 @@ func startStandAlone(ctx *Context, appCreator baseapp.AppCreator) error { return nil } -func startInProcess(ctx *Context, appCreator baseapp.AppCreator) error { +func startInProcess(ctx *Context, appCreator AppCreator) error { cfg := ctx.Config home := cfg.RootDir app, err := appCreator(home, ctx.Logger) diff --git a/server/util.go b/server/util.go index 54377547d..313d4fc5b 100644 --- a/server/util.go +++ b/server/util.go @@ -68,7 +68,7 @@ func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error func AddCommands( ctx *Context, cdc *wire.Codec, rootCmd *cobra.Command, appInit AppInit, - appCreator AppCreator) { + appCreator AppCreator, appExport AppExporter) { rootCmd.PersistentFlags().String("log_level", ctx.Config.LogLevel, "Log level") @@ -78,7 +78,7 @@ func AddCommands( UnsafeResetAllCmd(ctx), ShowNodeIDCmd(ctx), ShowValidatorCmd(ctx), - ExportCmd(cts, cdc, appCreator), + ExportCmd(ctx, cdc, appExport), UnsafeResetAllCmd(ctx), version.VersionCmd, ) diff --git a/types/account.go b/types/account.go index b47aea28a..7f4de12d3 100644 --- a/types/account.go +++ b/types/account.go @@ -48,7 +48,7 @@ type AccountMapper interface { NewAccountWithAddress(ctx Context, addr Address) Account GetAccount(ctx Context, addr Address) Account SetAccount(ctx Context, acc Account) - IterateAccounts(ctx Context, process func(sdk.Account) (stop bool)) + IterateAccounts(ctx Context, process func(Account) (stop bool)) } // AccountDecoder unmarshals account bytes From f7587f784704e0919b67e4b0cd459d855d3c932c Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 27 Apr 2018 20:47:35 -0400 Subject: [PATCH 140/176] export refactor, lcd tests borken --- examples/basecoin/app/app.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index b8f5346cd..f5122c130 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -125,14 +125,19 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) // Custom logic for state export func (app *BasecoinApp) ExportAppStateJSON() (appState json.RawMessage, err error) { ctx := app.NewContext(true, abci.Header{}) + + // iterate to get the accounts accounts := []*types.GenesisAccount{} - app.accountMapper.IterateAccounts(ctx, func(a sdk.Account) bool { - accounts = append(accounts, &types.GenesisAccount{ - Address: a.GetAddress(), - Coins: a.GetCoins(), - }) + appendAccount := func(acc sdk.Account) (stop bool) { + account := &types.GenesisAccount{ + Address: acc.GetAddress(), + Coins: acc.GetCoins(), + } + accounts = append(accounts, account) return false - }) + } + app.accountMapper.IterateAccounts(ctx, appendAccount) + genState := types.GenesisState{ Accounts: accounts, } From 81ac153e7d95856c217189135b283bbf1d82c4fd Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Sat, 28 Apr 2018 02:50:54 +0200 Subject: [PATCH 141/176] Fix testcase --- examples/basecoin/app/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index f5122c130..d3eae85c0 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -59,7 +59,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // Define the accountMapper. app.accountMapper = auth.NewAccountMapper( cdc, - app.keyMain, // target store + app.keyAccount, // target store &types.AppAccount{}, // prototype ) From d3fd71a3688670962fe426cb060ef822628bc23e Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 28 Apr 2018 21:59:47 -0400 Subject: [PATCH 142/176] version and changelog --- CHANGELOG.md | 2 +- version/version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1612f083f..1e70c13cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.15.0 (TBD) +## 0.15.0 (April 29, 2018) FEATURES: diff --git a/version/version.go b/version/version.go index ded399a03..957af26af 100644 --- a/version/version.go +++ b/version/version.go @@ -9,7 +9,7 @@ const Maj = "0" const Min = "15" const Fix = "0" -const Version = "0.15.0-rc0" +const Version = "0.15.0" // GitCommit set by build flags var GitCommit = "" From 59a5da4f3a8af7b8228a5d078897bf05ce6587f8 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 28 Apr 2018 22:04:29 -0400 Subject: [PATCH 143/176] update tendermint to v0.19.1 --- CHANGELOG.md | 6 ++++++ Gopkg.lock | 25 +++++++++++++------------ Gopkg.toml | 4 ++-- version/version.go | 4 ++-- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e70c13cf..7857441de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.15.1 (April 29, 2018) + +IMPROVEMENTS: + +* Update Tendermint to v0.19.1 (includes many rpc fixes) + ## 0.15.0 (April 29, 2018) FEATURES: diff --git a/Gopkg.lock b/Gopkg.lock index eb2a1c8ca..d773b4d7a 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -11,7 +11,7 @@ branch = "master" name = "github.com/btcsuite/btcd" packages = ["btcec"] - revision = "2be2f12b358dc57d70b8f501b00be450192efbc3" + revision = "675abc5df3c5531bc741b56a765e35623459da6d" [[projects]] name = "github.com/davecgh/go-spew" @@ -277,8 +277,8 @@ [[projects]] name = "github.com/tendermint/go-amino" packages = ["."] - revision = "42246108ff925a457fb709475070a03dfd3e2b5c" - version = "0.9.6" + revision = "3668c02a8feace009f80754a5e5a8541e5d7b996" + version = "0.9.8" [[projects]] name = "github.com/tendermint/go-crypto" @@ -342,8 +342,8 @@ "types/priv_validator", "version" ] - revision = "d0beaba7e8a5652506a34b5fab299cc2dc274c02" - version = "v0.19.0" + revision = "26f633ed48441f72895b710f0e87b7b6c6791066" + version = "v0.19.1" [[projects]] name = "github.com/tendermint/tmlibs" @@ -360,8 +360,8 @@ "pubsub", "pubsub/query" ] - revision = "737154202faf75c70437f59ba5303f2eb09f5636" - version = "0.8.2-rc1" + revision = "d94e312673e16a11ea55d742cefb3e331228f898" + version = "v0.8.2" [[projects]] branch = "master" @@ -377,13 +377,14 @@ "ripemd160", "salsa20/salsa" ] - revision = "d6449816ce06963d9d136eee5a56fca5b0616e7e" + revision = "b49d69b5da943f7ef3c9cf91c8777c1f78a0cc3c" [[projects]] branch = "master" name = "golang.org/x/net" packages = [ "context", + "http/httpguts", "http2", "http2/hpack", "idna", @@ -391,13 +392,13 @@ "lex/httplex", "trace" ] - revision = "61147c48b25b599e5b561d2e9c4f3e1ef489ca41" + revision = "5f9ae10d9af5b1c89ae6904293b14b064d4ada23" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "3b87a42e500a6dc65dae1a55d0b641295971163e" + revision = "cbbc999da32df943dac6cd71eb3ee39e1d7838b9" [[projects]] name = "golang.org/x/text" @@ -424,7 +425,7 @@ branch = "master" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] - revision = "51d0944304c3cbce4afe9e5247e21100037bff78" + revision = "86e600f69ee4704c6efbf6a2a40a5c10700e76c2" [[projects]] name = "google.golang.org/grpc" @@ -459,6 +460,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "b6b2d696a242e715ddb8b25c93b3c8f7e7cabc9292eab29dffe935eddbd35fb8" + inputs-digest = "48f831a7ccc2c0fd3b790c16ca99ec864b89253d087ff4190d821c01c13e635a" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 86de8ca21..1e71e68e2 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -62,7 +62,7 @@ [[constraint]] name = "github.com/tendermint/go-amino" - version = "~0.9.6" + version = "~0.9.8" [[constraint]] name = "github.com/tendermint/iavl" @@ -70,7 +70,7 @@ [[constraint]] name = "github.com/tendermint/tendermint" - version = "0.19.0" + version = "0.19.1" [[override]] name = "github.com/tendermint/tmlibs" diff --git a/version/version.go b/version/version.go index 957af26af..1f85bdf62 100644 --- a/version/version.go +++ b/version/version.go @@ -7,9 +7,9 @@ package version const Maj = "0" const Min = "15" -const Fix = "0" +const Fix = "1" -const Version = "0.15.0" +const Version = "0.15.1" // GitCommit set by build flags var GitCommit = "" From ce321173990c1f12a12fbdd5327588ffbc8358c7 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 30 Apr 2018 17:21:14 -0400 Subject: [PATCH 144/176] rational embedes bigRat --- baseapp/baseapp.go | 2 - cmd/gaia/app/app.go | 4 +- types/rational.go | 147 ++++++++++-------------------- types/rational_test.go | 76 +++++++-------- x/stake/client/cli/tx.go | 2 +- x/stake/handler.go | 6 +- x/stake/keeper.go | 56 ++++++------ x/stake/keeper_test.go | 25 +---- x/stake/msg.go | 2 +- x/stake/pool.go | 10 +- x/stake/pool_test.go | 85 +++++++++-------- x/stake/test_common.go | 35 ++++++- x/stake/tick.go | 2 +- x/stake/tick_test.go | 21 ++--- x/stake/types.go | 25 ++++- x/stake/view_slash_keeper_test.go | 8 -- 16 files changed, 231 insertions(+), 275 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 84a18aa06..51e96ae20 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -265,7 +265,6 @@ func (app *BaseApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOp // InitChain runs the initialization logic directly on the CommitMultiStore and commits it. func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) { if app.initChainer == nil { - // TODO: should we have some default handling of validators? return } @@ -275,7 +274,6 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC // NOTE: we don't commit, but BeginBlock for block 1 // starts from this deliverState - return } diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index a9cf248e1..5ff532bff 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -106,8 +106,8 @@ func MakeCodec() *wire.Codec { func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.AppStateBytes - genesisState := new(GenesisState) - err := app.cdc.UnmarshalJSON(stateJSON, genesisState) + var genesisState GenesisState + err := app.cdc.UnmarshalJSON(stateJSON, &genesisState) if err != nil { panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") diff --git a/types/rational.go b/types/rational.go index 9199520b2..2276ab4f2 100644 --- a/types/rational.go +++ b/types/rational.go @@ -1,6 +1,7 @@ package types import ( + "bytes" "fmt" "math/big" "strconv" @@ -13,68 +14,24 @@ import ( // __ /___...._____ _\o // __| |_ |_ -// Rat - extend big.Rat // NOTE: never use new(Rat) or else // we will panic unmarshalling into the // nil embedded big.Rat type Rat struct { - Num int64 `json:"num"` - Denom int64 `json:"denom"` - //*big.Rat `json:"rat"` + big.Rat `json:"rat"` } -// RatInterface - big Rat with additional functionality -// NOTE: we only have one implementation of this interface -// and don't use it anywhere, but it might come in handy -// if we want to provide Rat types that include -// the units of the value in the type system. -//type RatInterface interface { -//GetRat() *big.Rat -//Num() int64 -//Denom() int64 -//GT(Rat) bool -//LT(Rat) bool -//Equal(Rat) bool -//IsZero() bool -//Inv() Rat -//Mul(Rat) Rat -//Quo(Rat) Rat -//Add(Rat) Rat -//Sub(Rat) Rat -//Round(int64) Rat -//Evaluate() int64 -//} -//var _ Rat = Rat{} // enforce at compile time - // nolint - common values -var ( - ZeroRat = NewRat(0) // Rat{big.NewRat(0, 1)} - OneRat = NewRat(1) // Rat{big.NewRat(1, 1)} -) +func ZeroRat() Rat { return Rat{*big.NewRat(0, 1)} } +func OneRat() Rat { return Rat{*big.NewRat(1, 1)} } // New - create a new Rat from integers -//func NewRat(Numerator int64, Denominator ...int64) Rat { -//switch len(Denominator) { -//case 0: -//return Rat{big.NewRat(Numerator, 1)} -//case 1: -//return Rat{big.NewRat(Numerator, Denominator[0])} -//default: -//panic("improper use of New, can only have one denominator") -//} -//} -func NewRat(num int64, denom ...int64) Rat { - switch len(denom) { +func NewRat(Numerator int64, Denominator ...int64) Rat { + switch len(Denominator) { case 0: - return Rat{ - Num: num, - Denom: 1, - } + return Rat{*big.NewRat(Numerator, 1)} case 1: - return Rat{ - Num: num, - Denom: denom[0], - } + return Rat{*big.NewRat(Numerator, Denominator[0])} default: panic("improper use of New, can only have one denominator") } @@ -124,30 +81,17 @@ func NewRatFromDecimal(decimalStr string) (f Rat, err Error) { } //nolint -func ToRat(r *big.Rat) Rat { return NewRat(r.Num().Int64(), r.Denom().Int64()) } // GetRat - get big.Rat -func (r Rat) GetRat() *big.Rat { return big.NewRat(r.Num, r.Denom) } // GetRat - get big.Rat -func (r Rat) IsZero() bool { return r.Num == 0 } // IsZero - Is the Rat equal to zero -func (r Rat) Equal(r2 Rat) bool { return r.GetRat().Cmp(r2.GetRat()) == 0 } // Equal - rationals are equal -func (r Rat) GT(r2 Rat) bool { return r.GetRat().Cmp(r2.GetRat()) == 1 } // GT - greater than -func (r Rat) LT(r2 Rat) bool { return r.GetRat().Cmp(r2.GetRat()) == -1 } // LT - less than -func (r Rat) Inv() Rat { return ToRat(new(big.Rat).Inv(r.GetRat())) } // Inv - inverse -func (r Rat) Mul(r2 Rat) Rat { return ToRat(new(big.Rat).Mul(r.GetRat(), r2.GetRat())) } // Mul - multiplication -func (r Rat) Quo(r2 Rat) Rat { return ToRat(new(big.Rat).Quo(r.GetRat(), r2.GetRat())) } // Quo - quotient -func (r Rat) Add(r2 Rat) Rat { return ToRat(new(big.Rat).Add(r.GetRat(), r2.GetRat())) } // Add - addition -func (r Rat) Sub(r2 Rat) Rat { return ToRat(new(big.Rat).Sub(r.GetRat(), r2.GetRat())) } // Sub - subtraction -//func (r Rat) GetRat() *big.Rat { return r.Rat } // GetRat - get big.Rat -//func (r Rat) Num() int64 { return r.Rat.Num().Int64() } // Num - return the numerator -//func (r Rat) Denom() int64 { return r.Rat.Denom().Int64() } // Denom - return the denominator -//func (r Rat) IsZero() bool { return r.Num() == 0 } // IsZero - Is the Rat equal to zero -//func (r Rat) Equal(r2 Rat) bool { return r.Rat.Cmp(r2.GetRat()) == 0 } // Equal - rationals are equal -//func (r Rat) GT(r2 Rat) bool { return r.Rat.Cmp(r2.GetRat()) == 1 } // GT - greater than -//func (r Rat) LT(r2 Rat) bool { return r.Rat.Cmp(r2.GetRat()) == -1 } // LT - less than -//func (r Rat) Inv() Rat { return Rat{new(big.Rat).Inv(r.Rat)} } // Inv - inverse -//func (r Rat) Mul(r2 Rat) Rat { return Rat{new(big.Rat).Mul(r.Rat, r2.GetRat())} } // Mul - multiplication -//func (r Rat) Quo(r2 Rat) Rat { return Rat{new(big.Rat).Quo(r.Rat, r2.GetRat())} } // Quo - quotient -//func (r Rat) Add(r2 Rat) Rat { return Rat{new(big.Rat).Add(r.Rat, r2.GetRat())} } // Add - addition -//func (r Rat) Sub(r2 Rat) Rat { return Rat{new(big.Rat).Sub(r.Rat, r2.GetRat())} } // Sub - subtraction -//func (r Rat) String() string { return fmt.Sprintf("%v/%v", r.Num(), r.Denom()) } // Sub - subtraction +func (r Rat) Num() int64 { return r.Rat.Num().Int64() } // Num - return the numerator +func (r Rat) Denom() int64 { return r.Rat.Denom().Int64() } // Denom - return the denominator +func (r Rat) IsZero() bool { return r.Num() == 0 } // IsZero - Is the Rat equal to zero +func (r Rat) Equal(r2 Rat) bool { return (&(r.Rat)).Cmp(&(r2.Rat)) == 0 } // Equal - rationals are equal +func (r Rat) GT(r2 Rat) bool { return (&(r.Rat)).Cmp(&(r2.Rat)) == 1 } // Equal - rationals are equal +func (r Rat) LT(r2 Rat) bool { return (&(r.Rat)).Cmp(&(r2.Rat)) == -1 } // Equal - rationals are equal +func (r Rat) Mul(r2 Rat) Rat { return Rat{*new(big.Rat).Mul(&(r.Rat), &(r2.Rat))} } // Mul - multiplication +func (r Rat) Quo(r2 Rat) Rat { return Rat{*new(big.Rat).Quo(&(r.Rat), &(r2.Rat))} } // Quo - quotient +func (r Rat) Add(r2 Rat) Rat { return Rat{*new(big.Rat).Add(&(r.Rat), &(r2.Rat))} } // Add - addition +func (r Rat) Sub(r2 Rat) Rat { return Rat{*new(big.Rat).Sub(&(r.Rat), &(r2.Rat))} } // Sub - subtraction +func (r Rat) String() string { return fmt.Sprintf("%v/%v", r.Num(), r.Denom()) } // Sub - subtraction var ( zero = big.NewInt(0) @@ -161,8 +105,8 @@ var ( // evaluate the rational using bankers rounding func (r Rat) EvaluateBig() *big.Int { - num := r.GetRat().Num() - denom := r.GetRat().Denom() + num := r.Rat.Num() + denom := r.Rat.Denom() d, rem := new(big.Int), new(big.Int) d.QuoRem(num, denom, rem) @@ -195,8 +139,8 @@ func (r Rat) Evaluate() int64 { // round Rat with the provided precisionFactor func (r Rat) Round(precisionFactor int64) Rat { - rTen := ToRat(new(big.Rat).Mul(r.GetRat(), big.NewRat(precisionFactor, 1))) - return ToRat(big.NewRat(rTen.Evaluate(), precisionFactor)) + rTen := Rat{*new(big.Rat).Mul(&(r.Rat), big.NewRat(precisionFactor, 1))} + return Rat{*big.NewRat(rTen.Evaluate(), precisionFactor)} } // TODO panic if negative or if totalDigits < len(initStr)??? @@ -212,26 +156,33 @@ func (r Rat) ToLeftPadded(totalDigits int8) string { // Hack to just use json.Marshal for everything until // we update for amino //type JSONCodec struct{} +//nolint //func (jc JSONCodec) MarshalJSON(o interface{}) ([]byte, error) { return json.Marshal(o) } //func (jc JSONCodec) UnmarshalJSON(bz []byte, o interface{}) error { return json.Unmarshal(bz, o) } -// Wraps r.MarshalText() in quotes to make it a valid JSON string. -//func (r Rat) MarshalAmino() (string, error) { -//bz, err := r.MarshalText() -//if err != nil { -//return "", err -//} -//return fmt.Sprintf(`%s`, bz), nil -//} +//Wraps r.MarshalText() in quotes to make it a valid JSON string. +func (r Rat) MarshalJSON() ([]byte, error) { + bz, err := (&(r.Rat)).MarshalText() + if err != nil { + return nil, err + } + return []byte(fmt.Sprintf("\"%s\"", bz)), nil +} -//// Requires a valid JSON string - strings quotes and calls UnmarshalText -//func (r *Rat) UnmarshalAmino(data string) (err error) { -////quote := []byte(`"`) -////if len(data) < 2 || -////!bytes.HasPrefix(data, quote) || -////!bytes.HasSuffix(data, quote) { -////return fmt.Errorf("JSON encoded Rat must be a quote-delimitted string") -////} -////data = bytes.Trim(data, `"`) -//return r.UnmarshalText([]byte(data)) -//} +// Requires a valid JSON string - strings quotes and calls UnmarshalText +func (r *Rat) UnmarshalJSON(data []byte) (err error) { + quote := []byte(`"`) + if len(data) < 2 || + !bytes.HasPrefix(data, quote) || + !bytes.HasSuffix(data, quote) { + return fmt.Errorf("JSON encoded Rat must be a quote-delimitted string, have %v", string(data)) + } + data = bytes.Trim(data, `"`) + tempRat := big.NewRat(0, 1) + err = tempRat.UnmarshalText(data) + if err != nil { + return err + } + r.Rat = *tempRat + return nil +} diff --git a/types/rational_test.go b/types/rational_test.go index 5af63e8ec..2625db064 100644 --- a/types/rational_test.go +++ b/types/rational_test.go @@ -129,14 +129,14 @@ func TestArithmatic(t *testing.T) { } for _, tc := range tests { - assert.True(t, tc.resMul.Equal(tc.r1.Mul(tc.r2)), "r1 %v, r2 %v", tc.r1.GetRat(), tc.r2.GetRat()) - assert.True(t, tc.resAdd.Equal(tc.r1.Add(tc.r2)), "r1 %v, r2 %v", tc.r1.GetRat(), tc.r2.GetRat()) - assert.True(t, tc.resSub.Equal(tc.r1.Sub(tc.r2)), "r1 %v, r2 %v", tc.r1.GetRat(), tc.r2.GetRat()) + assert.True(t, tc.resMul.Equal(tc.r1.Mul(tc.r2)), "r1 %v, r2 %v", tc.r1.Rat, tc.r2.Rat) + assert.True(t, tc.resAdd.Equal(tc.r1.Add(tc.r2)), "r1 %v, r2 %v", tc.r1.Rat, tc.r2.Rat) + assert.True(t, tc.resSub.Equal(tc.r1.Sub(tc.r2)), "r1 %v, r2 %v", tc.r1.Rat, tc.r2.Rat) - if tc.r2.Num == 0 { // panic for divide by zero + if tc.r2.Num() == 0 { // panic for divide by zero assert.Panics(t, func() { tc.r1.Quo(tc.r2) }) } else { - assert.True(t, tc.resDiv.Equal(tc.r1.Quo(tc.r2)), "r1 %v, r2 %v", tc.r1.GetRat(), tc.r2.GetRat()) + assert.True(t, tc.resDiv.Equal(tc.r1.Quo(tc.r2)), "r1 %v, r2 %v", tc.r1.Rat, tc.r2.Rat) } } } @@ -180,8 +180,8 @@ func TestRound(t *testing.T) { precFactor int64 }{ {NewRat(333, 777), NewRat(429, 1000), 1000}, - {ToRat(new(big.Rat).SetFrac(big3, big7)), NewRat(429, 1000), 1000}, - {ToRat(new(big.Rat).SetFrac(big3, big7)), ToRat(big.NewRat(4285714286, 10000000000)), 10000000000}, + {Rat{*new(big.Rat).SetFrac(big3, big7)}, NewRat(429, 1000), 1000}, + {Rat{*new(big.Rat).SetFrac(big3, big7)}, Rat{*big.NewRat(4285714286, 10000000000)}, 10000000000}, {NewRat(1, 2), NewRat(1, 2), 1000}, } @@ -209,47 +209,40 @@ func TestToLeftPadded(t *testing.T) { } } -//func TestZeroSerializationJSON(t *testing.T) { -//r := NewRat(0, 1) -//err := r.UnmarshalJSON([]byte(`"0/1"`)) -//assert.Nil(t, err) -//err = r.UnmarshalJSON([]byte(`"0/0"`)) -//assert.NotNil(t, err) -//err = r.UnmarshalJSON([]byte(`"1/0"`)) -//assert.NotNil(t, err) -//err = r.UnmarshalJSON([]byte(`"{}"`)) -//assert.NotNil(t, err) -//} +func TestZeroSerializationJSON(t *testing.T) { + r := NewRat(0, 1) + err := r.UnmarshalJSON([]byte(`"0/1"`)) + assert.Nil(t, err) + err = r.UnmarshalJSON([]byte(`"0/0"`)) + assert.NotNil(t, err) + err = r.UnmarshalJSON([]byte(`"1/0"`)) + assert.NotNil(t, err) + err = r.UnmarshalJSON([]byte(`"{}"`)) + assert.NotNil(t, err) +} -//func TestSerializationJSON(t *testing.T) { -//r := NewRat(1, 3) +func TestSerializationText(t *testing.T) { + r := NewRat(1, 3) -//bz, err := r.MarshalText() -//require.Nil(t, err) + bz, err := r.MarshalText() + require.NoError(t, err) -//r2 := NewRat(0, 1) -//err = r2.UnmarshalText(bz) -//require.Nil(t, err) - -//assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) -//} + r2 := NewRat(0, 1) + err = r2.UnmarshalText(bz) + require.NoError(t, err) + assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) +} var cdc = wire.NewCodec() //var jsonCdc JSONCodec // TODO wire.Codec func TestSerializationGoWire(t *testing.T) { r := NewRat(1, 3) - - bz, err := cdc.MarshalBinary(r) - require.Nil(t, err) - - //str, err := r.MarshalJSON() - //require.Nil(t, err) + bz, err := cdc.MarshalJSON(r) + require.NoError(t, err) r2 := NewRat(0, 1) - err = cdc.UnmarshalBinary([]byte(bz), &r2) - //panic(fmt.Sprintf("debug bz: %v\n", string(bz))) - require.Nil(t, err) - + err = cdc.UnmarshalJSON(bz, &r2) + require.NoError(t, err) assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) } @@ -261,17 +254,14 @@ type testEmbedStruct struct { func TestEmbeddedStructSerializationGoWire(t *testing.T) { obj := testEmbedStruct{"foo", 10, NewRat(1, 3)} - - bz, err := cdc.MarshalBinary(obj) + bz, err := cdc.MarshalJSON(obj) require.Nil(t, err) var obj2 testEmbedStruct - obj2.Field3 = NewRat(0, 1) // ... needs to be initialized - err = cdc.UnmarshalBinary(bz, &obj2) + err = cdc.UnmarshalJSON(bz, &obj2) require.Nil(t, err) assert.Equal(t, obj.Field1, obj2.Field1) assert.Equal(t, obj.Field2, obj2.Field2) assert.True(t, obj.Field3.Equal(obj2.Field3), "original: %v, unmarshalled: %v", obj, obj2) - } diff --git a/x/stake/client/cli/tx.go b/x/stake/client/cli/tx.go index 188dba867..091701a70 100644 --- a/x/stake/client/cli/tx.go +++ b/x/stake/client/cli/tx.go @@ -166,7 +166,7 @@ func GetCmdUnbond(cdc *wire.Codec) *cobra.Command { if err != nil { return err } - if !shares.GT(sdk.ZeroRat) { + if !shares.GT(sdk.ZeroRat()) { return fmt.Errorf("shares must be positive integer or decimal (ex. 123, 1.23456789)") } } diff --git a/x/stake/handler.go b/x/stake/handler.go index 2b55ba3b1..1408c5bb1 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -165,7 +165,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, bond = DelegatorBond{ DelegatorAddr: delegatorAddr, CandidateAddr: candidate.Address, - Shares: sdk.ZeroRat, + Shares: sdk.ZeroRat(), } } @@ -194,7 +194,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { if !found { return ErrNoDelegatorForAddress(k.codespace).Result() } - if !bond.Shares.GT(sdk.ZeroRat) { // bond shares < msg shares + if !bond.Shares.GT(sdk.ZeroRat()) { // bond shares < msg shares return ErrInsufficientFunds(k.codespace).Result() } @@ -202,7 +202,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { // test that there are enough shares to unbond if msg.Shares == "MAX" { - if !bond.Shares.GT(sdk.ZeroRat) { + if !bond.Shares.GT(sdk.ZeroRat()) { return ErrNotEnoughBondShares(k.codespace, msg.Shares).Result() } } else { diff --git a/x/stake/keeper.go b/x/stake/keeper.go index e53d5ce09..d9fa293f5 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -16,7 +16,7 @@ type Keeper struct { coinKeeper bank.Keeper // caches - gs Pool + pool Pool params Params // codespace @@ -41,7 +41,7 @@ func (k Keeper) getCounter(ctx sdk.Context) int16 { return 0 } var counter int16 - err := k.cdc.UnmarshalBinary(b, &counter) + err := k.cdc.UnmarshalJSON(b, &counter) if err != nil { panic(err) } @@ -51,7 +51,7 @@ func (k Keeper) getCounter(ctx sdk.Context) int16 { // set the current in-block validator operation counter func (k Keeper) setCounter(ctx sdk.Context, counter int16) { store := ctx.KVStore(k.storeKey) - bz, err := k.cdc.MarshalBinary(counter) + bz, err := k.cdc.MarshalJSON(counter) if err != nil { panic(err) } @@ -67,7 +67,7 @@ func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candi if b == nil { return candidate, false } - err := k.cdc.UnmarshalBinary(b, &candidate) + err := k.cdc.UnmarshalJSON(b, &candidate) if err != nil { panic(err) } @@ -88,7 +88,7 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca } bz := iterator.Value() var candidate Candidate - err := k.cdc.UnmarshalBinary(bz, &candidate) + err := k.cdc.UnmarshalJSON(bz, &candidate) if err != nil { panic(err) } @@ -112,7 +112,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { } // marshal the candidate record and add to the state - bz, err := k.cdc.MarshalBinary(candidate) + bz, err := k.cdc.MarshalJSON(candidate) if err != nil { panic(err) } @@ -145,7 +145,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { } // update the candidate record - bz, err = k.cdc.MarshalBinary(candidate) + bz, err = k.cdc.MarshalJSON(candidate) if err != nil { panic(err) } @@ -153,7 +153,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // marshal the new validator record validator := candidate.validator() - bz, err = k.cdc.MarshalBinary(validator) + bz, err = k.cdc.MarshalJSON(validator) if err != nil { panic(err) } @@ -171,7 +171,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { setAcc = true } if setAcc { - bz, err = k.cdc.MarshalBinary(validator.abciValidator(k.cdc)) + bz, err = k.cdc.MarshalJSON(validator.abciValidator(k.cdc)) if err != nil { panic(err) } @@ -200,7 +200,7 @@ func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) { if store.Get(GetRecentValidatorKey(address)) == nil { return } - bz, err := k.cdc.MarshalBinary(candidate.validator().abciValidatorZero(k.cdc)) + bz, err := k.cdc.MarshalJSON(candidate.validator().abciValidatorZero(k.cdc)) if err != nil { panic(err) } @@ -242,7 +242,7 @@ func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) { } bz := iterator.Value() var validator Validator - err := k.cdc.UnmarshalBinary(bz, &validator) + err := k.cdc.UnmarshalJSON(bz, &validator) if err != nil { panic(err) } @@ -266,11 +266,11 @@ func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) { // get the zero abci validator from the ToKickOut iterator value bz := iterator.Value() var validator Validator - err := k.cdc.UnmarshalBinary(bz, &validator) + err := k.cdc.UnmarshalJSON(bz, &validator) if err != nil { panic(err) } - bz, err = k.cdc.MarshalBinary(validator.abciValidatorZero(k.cdc)) + bz, err = k.cdc.MarshalJSON(validator.abciValidatorZero(k.cdc)) if err != nil { panic(err) } @@ -297,7 +297,7 @@ func (k Keeper) isNewValidator(ctx sdk.Context, store sdk.KVStore, address sdk.A } bz := iterator.Value() var val Validator - err := k.cdc.UnmarshalBinary(bz, &val) + err := k.cdc.UnmarshalJSON(bz, &val) if err != nil { panic(err) } @@ -330,7 +330,7 @@ func (k Keeper) getAccUpdateValidators(ctx sdk.Context) (updates []abci.Validato for ; iterator.Valid(); iterator.Next() { valBytes := iterator.Value() var val abci.Validator - err := k.cdc.UnmarshalBinary(valBytes, &val) + err := k.cdc.UnmarshalJSON(valBytes, &val) if err != nil { panic(err) } @@ -364,7 +364,7 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context, return bond, false } - err := k.cdc.UnmarshalBinary(delegatorBytes, &bond) + err := k.cdc.UnmarshalJSON(delegatorBytes, &bond) if err != nil { panic(err) } @@ -385,7 +385,7 @@ func (k Keeper) getBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorB } bondBytes := iterator.Value() var bond DelegatorBond - err := k.cdc.UnmarshalBinary(bondBytes, &bond) + err := k.cdc.UnmarshalJSON(bondBytes, &bond) if err != nil { panic(err) } @@ -410,7 +410,7 @@ func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRet } bondBytes := iterator.Value() var bond DelegatorBond - err := k.cdc.UnmarshalBinary(bondBytes, &bond) + err := k.cdc.UnmarshalJSON(bondBytes, &bond) if err != nil { panic(err) } @@ -422,7 +422,7 @@ func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRet func (k Keeper) setDelegatorBond(ctx sdk.Context, bond DelegatorBond) { store := ctx.KVStore(k.storeKey) - b, err := k.cdc.MarshalBinary(bond) + b, err := k.cdc.MarshalJSON(bond) if err != nil { panic(err) } @@ -439,7 +439,7 @@ func (k Keeper) removeDelegatorBond(ctx sdk.Context, bond DelegatorBond) { // load/save the global staking params func (k Keeper) GetParams(ctx sdk.Context) (params Params) { // check if cached before anything - if k.params != (Params{}) { + if !k.params.equal(Params{}) { return k.params } store := ctx.KVStore(k.storeKey) @@ -448,7 +448,7 @@ func (k Keeper) GetParams(ctx sdk.Context) (params Params) { panic("Stored params should not have been nil") } - err := k.cdc.UnmarshalBinary(b, ¶ms) + err := k.cdc.UnmarshalJSON(b, ¶ms) if err != nil { panic(err) } @@ -456,7 +456,7 @@ func (k Keeper) GetParams(ctx sdk.Context) (params Params) { } func (k Keeper) setParams(ctx sdk.Context, params Params) { store := ctx.KVStore(k.storeKey) - b, err := k.cdc.MarshalBinary(params) + b, err := k.cdc.MarshalJSON(params) if err != nil { panic(err) } @@ -467,17 +467,17 @@ func (k Keeper) setParams(ctx sdk.Context, params Params) { //_______________________________________________________________________ // load/save the pool -func (k Keeper) GetPool(ctx sdk.Context) (gs Pool) { +func (k Keeper) GetPool(ctx sdk.Context) (pool Pool) { // check if cached before anything - if k.gs != (Pool{}) { - return k.gs + if !k.pool.equal(Pool{}) { + return k.pool } store := ctx.KVStore(k.storeKey) b := store.Get(PoolKey) if b == nil { panic("Stored pool should not have been nil") } - err := k.cdc.UnmarshalBinary(b, &gs) + err := k.cdc.UnmarshalJSON(b, &pool) if err != nil { panic(err) // This error should never occur big problem if does } @@ -486,10 +486,10 @@ func (k Keeper) GetPool(ctx sdk.Context) (gs Pool) { func (k Keeper) setPool(ctx sdk.Context, p Pool) { store := ctx.KVStore(k.storeKey) - b, err := k.cdc.MarshalBinary(p) + b, err := k.cdc.MarshalJSON(p) if err != nil { panic(err) } store.Set(PoolKey, b) - k.gs = Pool{} // clear the cache + k.pool = Pool{} //clear the cache } diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 3878b7bbb..8156071f1 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -1,7 +1,6 @@ package stake import ( - "bytes" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -40,15 +39,6 @@ func TestCandidate(t *testing.T) { } } - candidatesEqual := func(c1, c2 Candidate) bool { - return c1.Status == c2.Status && - c1.PubKey.Equals(c2.PubKey) && - bytes.Equal(c1.Address, c2.Address) && - c1.Assets.Equal(c2.Assets) && - c1.Liabilities.Equal(c2.Liabilities) && - c1.Description == c2.Description - } - // check the empty keeper first _, found := keeper.GetCandidate(ctx, addrVals[0]) assert.False(t, found) @@ -119,13 +109,6 @@ func TestBond(t *testing.T) { Shares: sdk.NewRat(9), } - bondsEqual := func(b1, b2 DelegatorBond) bool { - return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) && - bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) && - b1.Height == b2.Height && - b1.Shares == b2.Shares - } - // check the empty keeper first _, found := keeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) assert.False(t, found) @@ -460,8 +443,8 @@ func TestGetAccUpdateValidators(t *testing.T) { require.Equal(t, 2, len(candidates)) assert.Equal(t, candidates[0].validator().abciValidator(keeper.cdc), acc[0]) assert.Equal(t, candidates[1].validator().abciValidator(keeper.cdc), acc[1]) - assert.Equal(t, candidates[0].validator(), vals[1]) - assert.Equal(t, candidates[1].validator(), vals[0]) + assert.True(t, validatorsEqual(candidates[0].validator(), vals[1])) + assert.True(t, validatorsEqual(candidates[1].validator(), vals[0])) // test identical, // candidate set: {c1, c3} -> {c1, c3} @@ -654,10 +637,10 @@ func TestIsRecentValidator(t *testing.T) { keeper.setCandidate(ctx, candidatesIn[1]) validators = keeper.GetValidators(ctx) require.Equal(t, 2, len(validators)) - assert.Equal(t, candidatesIn[0].validator(), validators[0]) + assert.True(t, validatorsEqual(candidatesIn[0].validator(), validators[0])) c1ValWithCounter := candidatesIn[1].validator() c1ValWithCounter.Counter = int16(1) - assert.Equal(t, c1ValWithCounter, validators[1]) + assert.True(t, validatorsEqual(c1ValWithCounter, validators[1])) // test a basic retrieve of something that should be a recent validator assert.True(t, keeper.IsRecentValidator(ctx, candidatesIn[0].Address)) diff --git a/x/stake/msg.go b/x/stake/msg.go index 10cea3fa8..6e8101f96 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -204,7 +204,7 @@ func (msg MsgUnbond) ValidateBasic() sdk.Error { if err != nil { return ErrBadShares(DefaultCodespace) } - if rat.IsZero() || rat.LT(sdk.ZeroRat) { + if rat.IsZero() || rat.LT(sdk.ZeroRat()) { return ErrBadShares(DefaultCodespace) } } diff --git a/x/stake/pool.go b/x/stake/pool.go index 1e58fe28e..f0c7bfae5 100644 --- a/x/stake/pool.go +++ b/x/stake/pool.go @@ -9,13 +9,13 @@ func (p Pool) bondedRatio() sdk.Rat { if p.TotalSupply > 0 { return sdk.NewRat(p.BondedPool, p.TotalSupply) } - return sdk.ZeroRat + return sdk.ZeroRat() } // get the exchange rate of bonded token per issued share func (p Pool) bondedShareExRate() sdk.Rat { if p.BondedShares.IsZero() { - return sdk.OneRat + return sdk.OneRat() } return sdk.NewRat(p.BondedPool).Quo(p.BondedShares) } @@ -23,7 +23,7 @@ func (p Pool) bondedShareExRate() sdk.Rat { // get the exchange rate of unbonded tokens held in candidates per issued share func (p Pool) unbondedShareExRate() sdk.Rat { if p.UnbondedShares.IsZero() { - return sdk.OneRat + return sdk.OneRat() } return sdk.NewRat(p.UnbondedPool).Quo(p.UnbondedShares) } @@ -51,7 +51,7 @@ func (p Pool) unbondedToBondedPool(candidate Candidate) (Pool, Candidate) { //_______________________________________________________________________ func (p Pool) addTokensBonded(amount int64) (p2 Pool, issuedShares sdk.Rat) { - issuedShares = sdk.NewRat(amount).Quo(p.bondedShareExRate()) // (tokens/shares)^-1 * tokens + issuedShares = sdk.NewRat(amount).Quo(p.bondedShareExRate()) // tokens * (shares/tokens) p.BondedPool += amount p.BondedShares = p.BondedShares.Add(issuedShares) return p, issuedShares @@ -65,7 +65,7 @@ func (p Pool) removeSharesBonded(shares sdk.Rat) (p2 Pool, removedTokens int64) } func (p Pool) addTokensUnbonded(amount int64) (p2 Pool, issuedShares sdk.Rat) { - issuedShares = p.unbondedShareExRate().Inv().Mul(sdk.NewRat(amount)) // (tokens/shares)^-1 * tokens + issuedShares = sdk.NewRat(amount).Quo(p.unbondedShareExRate()) // tokens * (shares/tokens) p.UnbondedShares = p.UnbondedShares.Add(issuedShares) p.UnbondedPool += amount return p, issuedShares diff --git a/x/stake/pool_test.go b/x/stake/pool_test.go index cf1cd7ca2..316d57b96 100644 --- a/x/stake/pool_test.go +++ b/x/stake/pool_test.go @@ -22,7 +22,7 @@ func TestBondedRatio(t *testing.T) { pool.TotalSupply = 0 // avoids divide-by-zero - require.Equal(t, pool.bondedRatio(), sdk.ZeroRat) + require.Equal(t, pool.bondedRatio(), sdk.ZeroRat()) } func TestBondedShareExRate(t *testing.T) { @@ -33,10 +33,10 @@ func TestBondedShareExRate(t *testing.T) { // bonded pool / bonded shares require.Equal(t, pool.bondedShareExRate(), sdk.NewRat(3).Quo(sdk.NewRat(10))) - pool.BondedShares = sdk.ZeroRat + pool.BondedShares = sdk.ZeroRat() // avoids divide-by-zero - require.Equal(t, pool.bondedShareExRate(), sdk.OneRat) + require.Equal(t, pool.bondedShareExRate(), sdk.OneRat()) } func TestUnbondedShareExRate(t *testing.T) { @@ -47,24 +47,24 @@ func TestUnbondedShareExRate(t *testing.T) { // unbonded pool / unbonded shares require.Equal(t, pool.unbondedShareExRate(), sdk.NewRat(3).Quo(sdk.NewRat(10))) - pool.UnbondedShares = sdk.ZeroRat + pool.UnbondedShares = sdk.ZeroRat() // avoids divide-by-zero - require.Equal(t, pool.unbondedShareExRate(), sdk.OneRat) + require.Equal(t, pool.unbondedShareExRate(), sdk.OneRat()) } func TestBondedToUnbondedPool(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) - assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) - assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) + assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) candA := Candidate{ Status: Bonded, Address: addrs[0], PubKey: pks[0], - Assets: sdk.OneRat, - Liabilities: sdk.OneRat, + Assets: sdk.OneRat(), + Liabilities: sdk.OneRat(), } poolB, candB := poolA.bondedToUnbondedPool(candA) @@ -84,14 +84,14 @@ func TestUnbonbedtoBondedPool(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) - assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) - assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) + assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) candA := Candidate{ Status: Bonded, Address: addrs[0], PubKey: pks[0], - Assets: sdk.OneRat, - Liabilities: sdk.OneRat, + Assets: sdk.OneRat(), + Liabilities: sdk.OneRat(), } candA.Status = Unbonded poolB, candB := poolA.unbondedToBondedPool(candA) @@ -112,65 +112,64 @@ func TestAddTokensBonded(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) - assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) poolB, sharesB := poolA.addTokensBonded(10) - assert.Equal(t, poolB.bondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolB.bondedShareExRate(), sdk.OneRat()) // correct changes to bonded shares and bonded pool assert.Equal(t, poolB.BondedShares, poolA.BondedShares.Add(sharesB)) assert.Equal(t, poolB.BondedPool, poolA.BondedPool+10) // same number of bonded shares / tokens when exchange rate is one - assert.Equal(t, poolB.BondedShares, sdk.NewRat(poolB.BondedPool)) + assert.True(t, poolB.BondedShares.Equal(sdk.NewRat(poolB.BondedPool))) } func TestRemoveSharesBonded(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) - assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) poolB, tokensB := poolA.removeSharesBonded(sdk.NewRat(10)) - assert.Equal(t, poolB.bondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolB.bondedShareExRate(), sdk.OneRat()) // correct changes to bonded shares and bonded pool assert.Equal(t, poolB.BondedShares, poolA.BondedShares.Sub(sdk.NewRat(10))) assert.Equal(t, poolB.BondedPool, poolA.BondedPool-tokensB) // same number of bonded shares / tokens when exchange rate is one - assert.Equal(t, poolB.BondedShares, sdk.NewRat(poolB.BondedPool)) - + assert.True(t, poolB.BondedShares.Equal(sdk.NewRat(poolB.BondedPool))) } func TestAddTokensUnbonded(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) - assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) poolB, sharesB := poolA.addTokensUnbonded(10) - assert.Equal(t, poolB.unbondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolB.unbondedShareExRate(), sdk.OneRat()) // correct changes to unbonded shares and unbonded pool assert.Equal(t, poolB.UnbondedShares, poolA.UnbondedShares.Add(sharesB)) assert.Equal(t, poolB.UnbondedPool, poolA.UnbondedPool+10) // same number of unbonded shares / tokens when exchange rate is one - assert.Equal(t, poolB.UnbondedShares, sdk.NewRat(poolB.UnbondedPool)) + assert.True(t, poolB.UnbondedShares.Equal(sdk.NewRat(poolB.UnbondedPool))) } func TestRemoveSharesUnbonded(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) poolA := keeper.GetPool(ctx) - assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) poolB, tokensB := poolA.removeSharesUnbonded(sdk.NewRat(10)) - assert.Equal(t, poolB.unbondedShareExRate(), sdk.OneRat) + assert.Equal(t, poolB.unbondedShareExRate(), sdk.OneRat()) // correct changes to unbonded shares and bonded pool assert.Equal(t, poolB.UnbondedShares, poolA.UnbondedShares.Sub(sdk.NewRat(10))) assert.Equal(t, poolB.UnbondedPool, poolA.UnbondedPool-tokensB) // same number of unbonded shares / tokens when exchange rate is one - assert.Equal(t, poolB.UnbondedShares, sdk.NewRat(poolB.UnbondedPool)) + assert.True(t, poolB.UnbondedShares.Equal(sdk.NewRat(poolB.UnbondedPool))) } func TestCandidateAddTokens(t *testing.T) { @@ -186,9 +185,9 @@ func TestCandidateAddTokens(t *testing.T) { } poolA.BondedPool = candA.Assets.Evaluate() poolA.BondedShares = candA.Assets - assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat) - assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) - assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat) + assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat()) + assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) + assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) poolB, candB, sharesB := poolA.candidateAddTokens(candA, 10) // shares were issued @@ -212,9 +211,9 @@ func TestCandidateRemoveShares(t *testing.T) { } poolA.BondedPool = candA.Assets.Evaluate() poolA.BondedShares = candA.Assets - assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat) - assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat) - assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat) + assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat()) + assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) + assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) poolB, candB, coinsB := poolA.candidateRemoveShares(candA, sdk.NewRat(10)) // coins were created @@ -280,8 +279,8 @@ func randomCandidate(r *rand.Rand) Candidate { func randomSetup(r *rand.Rand, numCandidates int) (Pool, Candidates) { pool := Pool{ TotalSupply: 0, - BondedShares: sdk.ZeroRat, - UnbondedShares: sdk.ZeroRat, + BondedShares: sdk.ZeroRat(), + UnbondedShares: sdk.ZeroRat(), BondedPool: 0, UnbondedPool: 0, InflationLastTime: 0, @@ -380,29 +379,29 @@ func assertInvariants(t *testing.T, msg string, pMod.UnbondedPool, pMod.BondedPool, tokens) // nonnegative bonded shares - require.False(t, pMod.BondedShares.LT(sdk.ZeroRat), + require.False(t, pMod.BondedShares.LT(sdk.ZeroRat()), "Negative bonded shares - msg: %v\npOrig: %#v\npMod: %#v\ntokens: %v\n", msg, pOrig, pMod, tokens) // nonnegative unbonded shares - require.False(t, pMod.UnbondedShares.LT(sdk.ZeroRat), + require.False(t, pMod.UnbondedShares.LT(sdk.ZeroRat()), "Negative unbonded shares - msg: %v\npOrig: %#v\npMod: %#v\ntokens: %v\n", msg, pOrig, pMod, tokens) // nonnegative bonded ex rate - require.False(t, pMod.bondedShareExRate().LT(sdk.ZeroRat), + require.False(t, pMod.bondedShareExRate().LT(sdk.ZeroRat()), "Applying operation \"%s\" resulted in negative bondedShareExRate: %d", msg, pMod.bondedShareExRate().Evaluate()) // nonnegative unbonded ex rate - require.False(t, pMod.unbondedShareExRate().LT(sdk.ZeroRat), + require.False(t, pMod.unbondedShareExRate().LT(sdk.ZeroRat()), "Applying operation \"%s\" resulted in negative unbondedShareExRate: %d", msg, pMod.unbondedShareExRate().Evaluate()) for _, cMod := range cMods { // nonnegative ex rate - require.False(t, cMod.delegatorShareExRate().LT(sdk.ZeroRat), + require.False(t, cMod.delegatorShareExRate().LT(sdk.ZeroRat()), "Applying operation \"%s\" resulted in negative candidate.delegatorShareExRate(): %v (candidate.Address: %s)", msg, cMod.delegatorShareExRate(), @@ -410,7 +409,7 @@ func assertInvariants(t *testing.T, msg string, ) // nonnegative assets - require.False(t, cMod.Assets.LT(sdk.ZeroRat), + require.False(t, cMod.Assets.LT(sdk.ZeroRat()), "Applying operation \"%s\" resulted in negative candidate.Assets: %v (candidate.Liabilities: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)", msg, cMod.Assets, @@ -420,7 +419,7 @@ func assertInvariants(t *testing.T, msg string, ) // nonnegative liabilities - require.False(t, cMod.Liabilities.LT(sdk.ZeroRat), + require.False(t, cMod.Liabilities.LT(sdk.ZeroRat()), "Applying operation \"%s\" resulted in negative candidate.Liabilities: %v (candidate.Assets: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)", msg, cMod.Liabilities, @@ -449,7 +448,7 @@ func TestPossibleOverflow(t *testing.T) { pool := Pool{ TotalSupply: 0, BondedShares: assets, - UnbondedShares: sdk.ZeroRat, + UnbondedShares: sdk.ZeroRat(), BondedPool: assets.Evaluate(), UnbondedPool: 0, InflationLastTime: 0, @@ -461,7 +460,7 @@ func TestPossibleOverflow(t *testing.T) { _, newCandidate, _ := pool.candidateAddTokens(cand, tokens) msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg) - require.False(t, newCandidate.delegatorShareExRate().LT(sdk.ZeroRat), + require.False(t, newCandidate.delegatorShareExRate().LT(sdk.ZeroRat()), "Applying operation \"%s\" resulted in negative delegatorShareExRate(): %v", msg, newCandidate.delegatorShareExRate()) } diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 4a36feb95..4d11ea937 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -1,6 +1,7 @@ package stake import ( + "bytes" "encoding/hex" "testing" @@ -50,6 +51,30 @@ var ( emptyPubkey crypto.PubKey ) +func validatorsEqual(b1, b2 Validator) bool { + return bytes.Equal(b1.Address, b2.Address) && + b1.PubKey.Equals(b2.PubKey) && + b1.Power.Equal(b2.Power) && + b1.Height == b2.Height && + b1.Counter == b2.Counter +} + +func candidatesEqual(c1, c2 Candidate) bool { + return c1.Status == c2.Status && + c1.PubKey.Equals(c2.PubKey) && + bytes.Equal(c1.Address, c2.Address) && + c1.Assets.Equal(c2.Assets) && + c1.Liabilities.Equal(c2.Liabilities) && + c1.Description == c2.Description +} + +func bondsEqual(b1, b2 DelegatorBond) bool { + return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) && + bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) && + b1.Height == b2.Height && + b1.Shares.Equal(b2.Shares) +} + // default params for testing func defaultParams() Params { return Params{ @@ -66,8 +91,8 @@ func defaultParams() Params { func initialPool() Pool { return Pool{ TotalSupply: 0, - BondedShares: sdk.ZeroRat, - UnbondedShares: sdk.ZeroRat, + BondedShares: sdk.ZeroRat(), + UnbondedShares: sdk.ZeroRat(), BondedPool: 0, UnbondedPool: 0, InflationLastTime: 0, @@ -112,9 +137,9 @@ func makeTestCodec() *wire.Codec { func paramsNoInflation() Params { return Params{ - InflationRateChange: sdk.ZeroRat, - InflationMax: sdk.ZeroRat, - InflationMin: sdk.ZeroRat, + InflationRateChange: sdk.ZeroRat(), + InflationMax: sdk.ZeroRat(), + InflationMin: sdk.ZeroRat(), GoalBonded: sdk.NewRat(67, 100), MaxValidators: 100, BondDenom: "fermion", diff --git a/x/stake/tick.go b/x/stake/tick.go index 0b3dd1c83..9ca484061 100644 --- a/x/stake/tick.go +++ b/x/stake/tick.go @@ -62,7 +62,7 @@ func (k Keeper) nextInflation(ctx sdk.Context) (inflation sdk.Rat) { // 7% and 20%. // (1 - bondedRatio/GoalBonded) * InflationRateChange - inflationRateChangePerYear := sdk.OneRat.Sub(pool.bondedRatio().Quo(params.GoalBonded)).Mul(params.InflationRateChange) + inflationRateChangePerYear := sdk.OneRat().Sub(pool.bondedRatio().Quo(params.GoalBonded)).Mul(params.InflationRateChange) inflationRateChange := inflationRateChangePerYear.Quo(hrsPerYrRat) // increase the new annual inflation for this next cycle diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index 105ee8981..f75cf65b5 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -29,22 +29,22 @@ func TestGetInflation(t *testing.T) { // 100% bonded, starting at 20% inflation and being reduced // (1 - (1/0.67))*(0.13/8667) {"test 2", 1, 1, sdk.NewRat(20, 100), - sdk.OneRat.Sub(sdk.OneRat.Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)}, + sdk.OneRat().Sub(sdk.OneRat().Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)}, // 50% bonded, starting at 10% inflation and being increased {"test 3", 1, 2, sdk.NewRat(10, 100), - sdk.OneRat.Sub(sdk.NewRat(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)}, + sdk.OneRat().Sub(sdk.NewRat(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)}, // test 7% minimum stop (testing with 100% bonded) - {"test 4", 1, 1, sdk.NewRat(7, 100), sdk.ZeroRat}, + {"test 4", 1, 1, sdk.NewRat(7, 100), sdk.ZeroRat()}, {"test 5", 1, 1, sdk.NewRat(70001, 1000000), sdk.NewRat(-1, 1000000).Round(precision)}, // test 20% maximum stop (testing with 0% bonded) - {"test 6", 0, 0, sdk.NewRat(20, 100), sdk.ZeroRat}, + {"test 6", 0, 0, sdk.NewRat(20, 100), sdk.ZeroRat()}, {"test 7", 0, 0, sdk.NewRat(199999, 1000000), sdk.NewRat(1, 1000000).Round(precision)}, // perfect balance shouldn't change inflation - {"test 8", 67, 100, sdk.NewRat(15, 100), sdk.ZeroRat}, + {"test 8", 67, 100, sdk.NewRat(15, 100), sdk.ZeroRat()}, } for _, tc := range tests { pool.BondedPool, pool.TotalSupply = tc.setBondedPool, tc.setTotalSupply @@ -97,7 +97,7 @@ func TestProcessProvisions(t *testing.T) { assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(bondedShares, totalSupply)), "%v", pool.bondedRatio()) // test the value of candidate shares - assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat), "%v", pool.bondedShareExRate()) + assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate()) initialSupply := pool.TotalSupply initialUnbonded := pool.TotalSupply - pool.BondedPool @@ -121,14 +121,13 @@ func TestProcessProvisions(t *testing.T) { //panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", p.TotalSupply, p.BondedPool, pool.TotalSupply-pool.BondedPool)) // initial bonded ratio ~ from 27% to 40% increase for bonded holders ownership of total supply - assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(271734723, 671734723)), "%v", pool.bondedRatio()) + assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(211813022, 611813022)), "%v", pool.bondedRatio()) // global supply - assert.Equal(t, int64(671734723), pool.TotalSupply) - assert.Equal(t, int64(271734723), pool.BondedPool) + assert.Equal(t, int64(611813022), pool.TotalSupply) + assert.Equal(t, int64(211813022), pool.BondedPool) assert.Equal(t, unbondedShares, pool.UnbondedPool) // test the value of candidate shares - assert.True(t, pool.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(271734723)), "%v", pool.bondedShareExRate()) - + assert.True(t, pool.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(211813022)), "%v", pool.bondedShareExRate()) } diff --git a/x/stake/types.go b/x/stake/types.go index 6e15acd96..741783fa1 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -28,6 +28,15 @@ type Params struct { BondDenom string `json:"bond_denom"` // bondable coin denomination } +func (p Params) equal(p2 Params) bool { + return p.InflationRateChange.Equal(p2.InflationRateChange) && + p.InflationMax.Equal(p2.InflationMax) && + p.InflationMin.Equal(p2.InflationMin) && + p.GoalBonded.Equal(p2.GoalBonded) && + p.MaxValidators == p2.MaxValidators && + p.BondDenom == p2.BondDenom +} + //_________________________________________________________________________ // Pool - dynamic parameters of the current state @@ -41,6 +50,16 @@ type Pool struct { Inflation sdk.Rat `json:"inflation"` // current annual inflation rate } +func (p Pool) equal(p2 Pool) bool { + return p.BondedShares.Equal(p2.BondedShares) && + p.UnbondedShares.Equal(p2.UnbondedShares) && + p.Inflation.Equal(p2.Inflation) && + p.TotalSupply == p2.TotalSupply && + p.BondedPool == p2.BondedPool && + p.UnbondedPool == p2.UnbondedPool && + p.InflationLastTime == p2.InflationLastTime +} + //_________________________________________________________________________ // CandidateStatus - status of a validator-candidate @@ -80,8 +99,8 @@ func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Descrip Status: Unbonded, Address: address, PubKey: pubKey, - Assets: sdk.ZeroRat, - Liabilities: sdk.ZeroRat, + Assets: sdk.ZeroRat(), + Liabilities: sdk.ZeroRat(), Description: description, ValidatorBondHeight: int64(0), ValidatorBondCounter: int16(0), @@ -108,7 +127,7 @@ func NewDescription(moniker, identity, website, details string) Description { // get the exchange rate of global pool shares over delegator shares func (c Candidate) delegatorShareExRate() sdk.Rat { if c.Liabilities.IsZero() { - return sdk.OneRat + return sdk.OneRat() } return c.Assets.Quo(c.Liabilities) } diff --git a/x/stake/view_slash_keeper_test.go b/x/stake/view_slash_keeper_test.go index a8b0e1071..738085910 100644 --- a/x/stake/view_slash_keeper_test.go +++ b/x/stake/view_slash_keeper_test.go @@ -1,7 +1,6 @@ package stake import ( - "bytes" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -37,13 +36,6 @@ func TestViewSlashBond(t *testing.T) { viewSlashKeeper := NewViewSlashKeeper(keeper) - bondsEqual := func(b1, b2 DelegatorBond) bool { - return bytes.Equal(b1.DelegatorAddr, b2.DelegatorAddr) && - bytes.Equal(b1.CandidateAddr, b2.CandidateAddr) && - b1.Height == b2.Height && - b1.Shares == b2.Shares - } - // check the empty keeper first _, found := viewSlashKeeper.GetDelegatorBond(ctx, addrDels[0], addrVals[0]) assert.False(t, found) From 437a5b711a1fc01b744b3a6e074d74c3400006d0 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 30 Apr 2018 17:26:12 -0400 Subject: [PATCH 145/176] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e6228410..e52cfcfee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## UNRELEASED + +BREAKING CHANGES + +* types/rational now extends big.Rat + ## 0.15.1 (April 29, 2018) IMPROVEMENTS: From cb4463e5f128854218b60cbcc243d03929bfb060 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 30 Apr 2018 17:30:34 -0400 Subject: [PATCH 146/176] reenable TestPossibleOverflow --- x/stake/pool_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x/stake/pool_test.go b/x/stake/pool_test.go index 316d57b96..e5dc66058 100644 --- a/x/stake/pool_test.go +++ b/x/stake/pool_test.go @@ -432,9 +432,6 @@ func assertInvariants(t *testing.T, msg string, } -// TODO Re-enable once the overflow bug is fixed! -// ref https://github.com/cosmos/cosmos-sdk/issues/753 -/* func TestPossibleOverflow(t *testing.T) { assets := sdk.NewRat(2159) liabilities := sdk.NewRat(391432570689183511).Quo(sdk.NewRat(40113011844664)) @@ -464,7 +461,6 @@ func TestPossibleOverflow(t *testing.T) { "Applying operation \"%s\" resulted in negative delegatorShareExRate(): %v", msg, newCandidate.delegatorShareExRate()) } -*/ // run random operations in a random order on a random single-candidate state, assert invariants hold func TestSingleCandidateIntegrationInvariants(t *testing.T) { From 4a834ae9c5417c0ebf1aa35fa6cd3c62af1ed46d Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 30 Apr 2018 17:39:13 -0400 Subject: [PATCH 147/176] rational cleanup --- types/rational.go | 7 ------- types/rational_test.go | 12 ++++++------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/types/rational.go b/types/rational.go index 2276ab4f2..550c96825 100644 --- a/types/rational.go +++ b/types/rational.go @@ -153,13 +153,6 @@ func (r Rat) ToLeftPadded(totalDigits int8) string { //___________________________________________________________________________________ -// Hack to just use json.Marshal for everything until -// we update for amino -//type JSONCodec struct{} -//nolint -//func (jc JSONCodec) MarshalJSON(o interface{}) ([]byte, error) { return json.Marshal(o) } -//func (jc JSONCodec) UnmarshalJSON(bz []byte, o interface{}) error { return json.Unmarshal(bz, o) } - //Wraps r.MarshalText() in quotes to make it a valid JSON string. func (r Rat) MarshalJSON() ([]byte, error) { bz, err := (&(r.Rat)).MarshalText() diff --git a/types/rational_test.go b/types/rational_test.go index 2625db064..39207034c 100644 --- a/types/rational_test.go +++ b/types/rational_test.go @@ -209,15 +209,17 @@ func TestToLeftPadded(t *testing.T) { } } +var cdc = wire.NewCodec() //var jsonCdc JSONCodec // TODO wire.Codec + func TestZeroSerializationJSON(t *testing.T) { r := NewRat(0, 1) - err := r.UnmarshalJSON([]byte(`"0/1"`)) + err := cdc.UnmarshalJSON([]byte(`"0/1"`), &r) assert.Nil(t, err) - err = r.UnmarshalJSON([]byte(`"0/0"`)) + err = cdc.UnmarshalJSON([]byte(`"0/0"`), &r) assert.NotNil(t, err) - err = r.UnmarshalJSON([]byte(`"1/0"`)) + err = cdc.UnmarshalJSON([]byte(`"1/0"`), &r) assert.NotNil(t, err) - err = r.UnmarshalJSON([]byte(`"{}"`)) + err = cdc.UnmarshalJSON([]byte(`"{}"`), &r) assert.NotNil(t, err) } @@ -233,8 +235,6 @@ func TestSerializationText(t *testing.T) { assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) } -var cdc = wire.NewCodec() //var jsonCdc JSONCodec // TODO wire.Codec - func TestSerializationGoWire(t *testing.T) { r := NewRat(1, 3) bz, err := cdc.MarshalJSON(r) From 24dffd0c987c4afa82c0585cc16493366ebd9a5b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 1 May 2018 00:06:20 +0200 Subject: [PATCH 148/176] Reenable random testcase iterations --- x/stake/pool_test.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/x/stake/pool_test.go b/x/stake/pool_test.go index e5dc66058..6d70a85af 100644 --- a/x/stake/pool_test.go +++ b/x/stake/pool_test.go @@ -475,9 +475,7 @@ func TestSingleCandidateIntegrationInvariants(t *testing.T) { poolOrig, candidatesOrig, poolOrig, candidatesOrig, 0) - // TODO Increase iteration count once overflow bug is fixed - // ref https://github.com/cosmos/cosmos-sdk/issues/753 - for j := 0; j < 4; j++ { + for j := 0; j < 5; j++ { poolMod, candidateMod, tokens, msg := randomOperation(r)(r, poolOrig, candidatesOrig[0]) candidatesMod := make([]Candidate, len(candidatesOrig)) @@ -507,9 +505,7 @@ func TestMultiCandidateIntegrationInvariants(t *testing.T) { poolOrig, candidatesOrig, poolOrig, candidatesOrig, 0) - // TODO Increase iteration count once overflow bug is fixed - // ref https://github.com/cosmos/cosmos-sdk/issues/753 - for j := 0; j < 3; j++ { + for j := 0; j < 5; j++ { index := int(r.Int31n(int32(len(candidatesOrig)))) poolMod, candidateMod, tokens, msg := randomOperation(r)(r, poolOrig, candidatesOrig[index]) candidatesMod := make([]Candidate, len(candidatesOrig)) From af0e71fa0d674cad0540349400c6b943b6b23659 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 15:05:28 -0700 Subject: [PATCH 149/176] got rid of Get on Msg interface --- examples/democoin/x/cool/types.go | 10 ++++------ examples/democoin/x/pow/types.go | 5 ++--- examples/democoin/x/pow/types_test.go | 7 ------- examples/democoin/x/simplestake/msgs.go | 7 +++---- types/tx_msg.go | 3 --- x/auth/baseaccount.go | 1 - x/bank/msgs.go | 10 ---------- x/bank/msgs_test.go | 23 ----------------------- x/ibc/types.go | 8 +++----- x/stake/msg.go | 20 ++++++++------------ 10 files changed, 20 insertions(+), 74 deletions(-) diff --git a/examples/democoin/x/cool/types.go b/examples/democoin/x/cool/types.go index caaf8610f..b8640b211 100644 --- a/examples/democoin/x/cool/types.go +++ b/examples/democoin/x/cool/types.go @@ -32,9 +32,8 @@ func NewMsgSetTrend(sender sdk.Address, cool string) MsgSetTrend { var _ sdk.Msg = MsgSetTrend{} // nolint -func (msg MsgSetTrend) Type() string { return "cool" } -func (msg MsgSetTrend) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgSetTrend) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } +func (msg MsgSetTrend) Type() string { return "cool" } +func (msg MsgSetTrend) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } func (msg MsgSetTrend) String() string { return fmt.Sprintf("MsgSetTrend{Sender: %v, Cool: %v}", msg.Sender, msg.Cool) } @@ -83,9 +82,8 @@ func NewMsgQuiz(sender sdk.Address, coolerthancool string) MsgQuiz { var _ sdk.Msg = MsgQuiz{} // nolint -func (msg MsgQuiz) Type() string { return "cool" } -func (msg MsgQuiz) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgQuiz) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } +func (msg MsgQuiz) Type() string { return "cool" } +func (msg MsgQuiz) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } func (msg MsgQuiz) String() string { return fmt.Sprintf("MsgQuiz{Sender: %v, CoolAnswer: %v}", msg.Sender, msg.CoolAnswer) } diff --git a/examples/democoin/x/pow/types.go b/examples/democoin/x/pow/types.go index 999dd4197..039f57d44 100644 --- a/examples/democoin/x/pow/types.go +++ b/examples/democoin/x/pow/types.go @@ -31,9 +31,8 @@ func NewMsgMine(sender sdk.Address, difficulty uint64, count uint64, nonce uint6 } // nolint -func (msg MsgMine) Type() string { return "pow" } -func (msg MsgMine) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgMine) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } +func (msg MsgMine) Type() string { return "pow" } +func (msg MsgMine) GetSigners() []sdk.Address { return []sdk.Address{msg.Sender} } func (msg MsgMine) String() string { return fmt.Sprintf("MsgMine{Sender: %v, Difficulty: %d, Count: %d, Nonce: %d, Proof: %s}", msg.Sender, msg.Difficulty, msg.Count, msg.Nonce, msg.Proof) } diff --git a/examples/democoin/x/pow/types_test.go b/examples/democoin/x/pow/types_test.go index bf2e9169b..e69e59559 100644 --- a/examples/democoin/x/pow/types_test.go +++ b/examples/democoin/x/pow/types_test.go @@ -58,13 +58,6 @@ func TestMsgMineString(t *testing.T) { assert.Equal(t, res, "MsgMine{Sender: 73656E646572, Difficulty: 0, Count: 0, Nonce: 0, Proof: abc}") } -func TestMsgMineGet(t *testing.T) { - addr := sdk.Address([]byte("sender")) - msg := MsgMine{addr, 0, 0, 0, []byte("")} - res := msg.Get(nil) - assert.Nil(t, res) -} - func TestMsgMineGetSignBytes(t *testing.T) { addr := sdk.Address([]byte("sender")) msg := MsgMine{addr, 1, 1, 1, []byte("abc")} diff --git a/examples/democoin/x/simplestake/msgs.go b/examples/democoin/x/simplestake/msgs.go index 512d571c5..0a7707003 100644 --- a/examples/democoin/x/simplestake/msgs.go +++ b/examples/democoin/x/simplestake/msgs.go @@ -66,10 +66,9 @@ func NewMsgUnbond(addr sdk.Address) MsgUnbond { } //nolint -func (msg MsgUnbond) Type() string { return moduleName } //TODO update "stake/declarecandidacy" -func (msg MsgUnbond) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} } -func (msg MsgUnbond) ValidateBasic() sdk.Error { return nil } +func (msg MsgUnbond) Type() string { return moduleName } //TODO update "stake/declarecandidacy" +func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} } +func (msg MsgUnbond) ValidateBasic() sdk.Error { return nil } // get unbond message sign bytes func (msg MsgUnbond) GetSignBytes() []byte { diff --git a/types/tx_msg.go b/types/tx_msg.go index 25d35512d..7ac7b9bb2 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -11,9 +11,6 @@ type Msg interface { // Must be alphanumeric or empty. Type() string - // Get some property of the Msg. - Get(key interface{}) (value interface{}) - // Get the canonical byte representation of the Msg. GetSignBytes() []byte diff --git a/x/auth/baseaccount.go b/x/auth/baseaccount.go index a5f33c81d..d7cffcd06 100644 --- a/x/auth/baseaccount.go +++ b/x/auth/baseaccount.go @@ -30,7 +30,6 @@ func NewBaseAccountWithAddress(addr sdk.Address) BaseAccount { } } -// Implements sdk.Account. func (acc BaseAccount) Get(key interface{}) (value interface{}, err error) { panic("not implemented yet") } diff --git a/x/bank/msgs.go b/x/bank/msgs.go index 0b0ea471e..f37f720f1 100644 --- a/x/bank/msgs.go +++ b/x/bank/msgs.go @@ -53,11 +53,6 @@ func (msg MsgSend) ValidateBasic() sdk.Error { return nil } -// Implements Msg. -func (msg MsgSend) Get(key interface{}) (value interface{}) { - return nil -} - // Implements Msg. func (msg MsgSend) GetSignBytes() []byte { b, err := json.Marshal(msg) // XXX: ensure some canonical form @@ -107,11 +102,6 @@ func (msg MsgIssue) ValidateBasic() sdk.Error { return nil } -// Implements Msg. -func (msg MsgIssue) Get(key interface{}) (value interface{}) { - return nil -} - // Implements Msg. func (msg MsgIssue) GetSignBytes() []byte { b, err := json.Marshal(msg) // XXX: ensure some canonical form diff --git a/x/bank/msgs_test.go b/x/bank/msgs_test.go index d3e1ef4f6..78de01f40 100644 --- a/x/bank/msgs_test.go +++ b/x/bank/msgs_test.go @@ -177,18 +177,6 @@ func TestMsgSendValidation(t *testing.T) { } } -func TestMsgSendGet(t *testing.T) { - addr1 := sdk.Address([]byte("input")) - addr2 := sdk.Address([]byte("output")) - coins := sdk.Coins{{"atom", 10}} - var msg = MsgSend{ - Inputs: []Input{NewInput(addr1, coins)}, - Outputs: []Output{NewOutput(addr2, coins)}, - } - res := msg.Get(nil) - assert.Nil(t, res) -} - func TestMsgSendGetSignBytes(t *testing.T) { addr1 := sdk.Address([]byte("input")) addr2 := sdk.Address([]byte("output")) @@ -259,17 +247,6 @@ func TestMsgIssueValidation(t *testing.T) { // TODO } -func TestMsgIssueGet(t *testing.T) { - addr := sdk.Address([]byte("loan-from-bank")) - coins := sdk.Coins{{"atom", 10}} - var msg = MsgIssue{ - Banker: sdk.Address([]byte("input")), - Outputs: []Output{NewOutput(addr, coins)}, - } - res := msg.Get(nil) - assert.Nil(t, res) -} - func TestMsgIssueGetSignBytes(t *testing.T) { addr := sdk.Address([]byte("loan-from-bank")) coins := sdk.Coins{{"atom", 10}} diff --git a/x/ibc/types.go b/x/ibc/types.go index 6102a2a9f..09a853b20 100644 --- a/x/ibc/types.go +++ b/x/ibc/types.go @@ -53,8 +53,7 @@ type IBCTransferMsg struct { } // nolint -func (msg IBCTransferMsg) Type() string { return "ibc" } -func (msg IBCTransferMsg) Get(key interface{}) interface{} { return nil } +func (msg IBCTransferMsg) Type() string { return "ibc" } // x/bank/tx.go MsgSend.GetSigners() func (msg IBCTransferMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.SrcAddr} } @@ -87,9 +86,8 @@ type IBCReceiveMsg struct { } // nolint -func (msg IBCReceiveMsg) Type() string { return "ibc" } -func (msg IBCReceiveMsg) Get(key interface{}) interface{} { return nil } -func (msg IBCReceiveMsg) ValidateBasic() sdk.Error { return msg.IBCPacket.ValidateBasic() } +func (msg IBCReceiveMsg) Type() string { return "ibc" } +func (msg IBCReceiveMsg) ValidateBasic() sdk.Error { return msg.IBCPacket.ValidateBasic() } // x/bank/tx.go MsgSend.GetSigners() func (msg IBCReceiveMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.Relayer} } diff --git a/x/stake/msg.go b/x/stake/msg.go index 10cea3fa8..5d8e1f58f 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -40,9 +40,8 @@ func NewMsgDeclareCandidacy(candidateAddr sdk.Address, pubkey crypto.PubKey, } //nolint -func (msg MsgDeclareCandidacy) Type() string { return MsgType } //TODO update "stake/declarecandidacy" -func (msg MsgDeclareCandidacy) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.CandidateAddr} } +func (msg MsgDeclareCandidacy) Type() string { return MsgType } //TODO update "stake/declarecandidacy" +func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.CandidateAddr} } // get the bytes for the message signer to sign on func (msg MsgDeclareCandidacy) GetSignBytes() []byte { @@ -87,9 +86,8 @@ func NewMsgEditCandidacy(candidateAddr sdk.Address, description Description) Msg } //nolint -func (msg MsgEditCandidacy) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" -func (msg MsgEditCandidacy) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgEditCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.CandidateAddr} } +func (msg MsgEditCandidacy) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" +func (msg MsgEditCandidacy) GetSigners() []sdk.Address { return []sdk.Address{msg.CandidateAddr} } // get the bytes for the message signer to sign on func (msg MsgEditCandidacy) GetSignBytes() []byte { @@ -130,9 +128,8 @@ func NewMsgDelegate(delegatorAddr, candidateAddr sdk.Address, bond sdk.Coin) Msg } //nolint -func (msg MsgDelegate) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" -func (msg MsgDelegate) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgDelegate) GetSigners() []sdk.Address { return []sdk.Address{msg.DelegatorAddr} } +func (msg MsgDelegate) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" +func (msg MsgDelegate) GetSigners() []sdk.Address { return []sdk.Address{msg.DelegatorAddr} } // get the bytes for the message signer to sign on func (msg MsgDelegate) GetSignBytes() []byte { @@ -178,9 +175,8 @@ func NewMsgUnbond(delegatorAddr, candidateAddr sdk.Address, shares string) MsgUn } //nolint -func (msg MsgUnbond) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" -func (msg MsgUnbond) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.DelegatorAddr} } +func (msg MsgUnbond) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy" +func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.DelegatorAddr} } // get the bytes for the message signer to sign on func (msg MsgUnbond) GetSignBytes() []byte { From a7d7257802068247df28fd9a1c0c6478fcdeccca Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 15:08:12 -0700 Subject: [PATCH 150/176] added to Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e6228410..378e9377b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ BREAKING CHANGES * Removed redundancy in names (ex. stake.StakeKeeper -> stake.Keeper) * Removed SealedAccountMapper * gaiad init now requires use of `--name` flag +* Removed Get from Msg interface BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia From 52478de857687a726fb2fcf8fa3c1f9a00f18f4c Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 15:13:45 -0700 Subject: [PATCH 151/176] updated documentation --- docs/sdk/overview.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/sdk/overview.rst b/docs/sdk/overview.rst index 1356d7dc1..8a1350906 100644 --- a/docs/sdk/overview.rst +++ b/docs/sdk/overview.rst @@ -143,9 +143,6 @@ implementing the ``Msg`` interface: // Must be alphanumeric or empty. Type() string - // Get some property of the Msg. - Get(key interface{}) (value interface{}) - // Get the canonical byte representation of the Msg. GetSignBytes() []byte @@ -175,9 +172,6 @@ Messages can specify basic self-consistency checks using the ``ValidateBasic()`` method to enforce that message contents are well formed before any actual logic begins. -Finally, messages can provide generic access to their contents via ``Get(key)``, -but this is mostly for convenience and not type-safe. - For instance, the ``Basecoin`` message types are defined in ``x/bank/tx.go``: :: From ee2800ff6daecb1b42056e9c66cebde16ecd96d3 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 15:16:16 -0700 Subject: [PATCH 152/176] updated documentation --- x/auth/baseaccount.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/auth/baseaccount.go b/x/auth/baseaccount.go index d7cffcd06..a5f33c81d 100644 --- a/x/auth/baseaccount.go +++ b/x/auth/baseaccount.go @@ -30,6 +30,7 @@ func NewBaseAccountWithAddress(addr sdk.Address) BaseAccount { } } +// Implements sdk.Account. func (acc BaseAccount) Get(key interface{}) (value interface{}, err error) { panic("not implemented yet") } From 754481af2c90045eb2e1a22c9cc3eb8763bde647 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 15:05:28 -0700 Subject: [PATCH 153/176] got rid of Get on Msg interface --- x/auth/baseaccount.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/auth/baseaccount.go b/x/auth/baseaccount.go index a5f33c81d..d7cffcd06 100644 --- a/x/auth/baseaccount.go +++ b/x/auth/baseaccount.go @@ -30,7 +30,6 @@ func NewBaseAccountWithAddress(addr sdk.Address) BaseAccount { } } -// Implements sdk.Account. func (acc BaseAccount) Get(key interface{}) (value interface{}, err error) { panic("not implemented yet") } From fdb610bea7ae37ab3ae1f9742f811cb317c7d8c6 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 22 Apr 2018 15:16:16 -0700 Subject: [PATCH 154/176] updated documentation --- x/auth/baseaccount.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/auth/baseaccount.go b/x/auth/baseaccount.go index d7cffcd06..a5f33c81d 100644 --- a/x/auth/baseaccount.go +++ b/x/auth/baseaccount.go @@ -30,6 +30,7 @@ func NewBaseAccountWithAddress(addr sdk.Address) BaseAccount { } } +// Implements sdk.Account. func (acc BaseAccount) Get(key interface{}) (value interface{}, err error) { panic("not implemented yet") } From 9f4f35a6dbd6fd462d3959738c0b72035ed106f7 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 29 Apr 2018 20:03:22 -0700 Subject: [PATCH 155/176] removed Get from account --- types/account.go | 3 --- x/auth/baseaccount.go | 10 ---------- x/auth/baseaccount_test.go | 9 --------- 3 files changed, 22 deletions(-) diff --git a/types/account.go b/types/account.go index 7f4de12d3..74cd87f38 100644 --- a/types/account.go +++ b/types/account.go @@ -37,9 +37,6 @@ type Account interface { GetCoins() Coins SetCoins(Coins) error - - Get(key interface{}) (value interface{}, err error) - Set(key interface{}, value interface{}) error } // AccountMapper stores and retrieves accounts from stores diff --git a/x/auth/baseaccount.go b/x/auth/baseaccount.go index a5f33c81d..6a612689d 100644 --- a/x/auth/baseaccount.go +++ b/x/auth/baseaccount.go @@ -30,16 +30,6 @@ func NewBaseAccountWithAddress(addr sdk.Address) BaseAccount { } } -// Implements sdk.Account. -func (acc BaseAccount) Get(key interface{}) (value interface{}, err error) { - panic("not implemented yet") -} - -// Implements sdk.Account. -func (acc *BaseAccount) Set(key interface{}, value interface{}) error { - panic("not implemented yet") -} - // Implements sdk.Account. func (acc BaseAccount) GetAddress() sdk.Address { return acc.Address diff --git a/x/auth/baseaccount_test.go b/x/auth/baseaccount_test.go index 24b3e3673..8b69b6dfc 100644 --- a/x/auth/baseaccount_test.go +++ b/x/auth/baseaccount_test.go @@ -106,12 +106,3 @@ func TestBaseAccountMarshal(t *testing.T) { assert.NotNil(t, err) } - -func TestBaseAccountGetSet(t *testing.T) { - _, _, addr := keyPubAddr() - acc := NewBaseAccountWithAddress(addr) - - // Get/Set are not yet defined - all values cause a panic. - assert.Panics(t, func() { acc.Get("key") }) - assert.Panics(t, func() { acc.Set("key", "value") }) -} From 339c02af27a48bc2c74194ab384727c2d9374575 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 29 Apr 2018 20:06:00 -0700 Subject: [PATCH 156/176] docs/guide.md --- docs/guide.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/guide.md b/docs/guide.md index 9f8329835..db5ba392e 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -29,9 +29,6 @@ type Msg interface { // Must be alphanumeric or empty. Type() string - // Get some property of the Msg. - Get(key interface{}) (value interface{}) - // Get the canonical byte representation of the Msg. GetSignBytes() []byte @@ -63,9 +60,6 @@ Messages can specify basic self-consistency checks using the `ValidateBasic()` method to enforce that message contents are well formed before any actual logic begins. -Finally, messages can provide generic access to their contents via `Get(key)`, -but this is mostly for convenience and not type-safe. - For instance, the `Basecoin` message types are defined in `x/bank/tx.go`: ```go From a6589949fb87f27728e478b5bd665d3807c54d5c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 1 May 2018 00:19:28 +0200 Subject: [PATCH 157/176] Remove unnecessary code --- baseapp/baseapp_test.go | 13 ++++++------- examples/democoin/x/simplestake/msgs.go | 5 ++--- examples/kvstore/tx.go | 13 ------------- mock/tx.go | 13 ------------- types/tx_msg.go | 3 +-- 5 files changed, 9 insertions(+), 38 deletions(-) diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index fe061622c..aab64fc20 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -318,13 +318,12 @@ type testUpdatePowerTx struct { const msgType = "testUpdatePowerTx" -func (tx testUpdatePowerTx) Type() string { return msgType } -func (tx testUpdatePowerTx) Get(key interface{}) (value interface{}) { return nil } -func (tx testUpdatePowerTx) GetMsg() sdk.Msg { return tx } -func (tx testUpdatePowerTx) GetSignBytes() []byte { return nil } -func (tx testUpdatePowerTx) ValidateBasic() sdk.Error { return nil } -func (tx testUpdatePowerTx) GetSigners() []sdk.Address { return nil } -func (tx testUpdatePowerTx) GetSignatures() []sdk.StdSignature { return nil } +func (tx testUpdatePowerTx) Type() string { return msgType } +func (tx testUpdatePowerTx) GetMsg() sdk.Msg { return tx } +func (tx testUpdatePowerTx) GetSignBytes() []byte { return nil } +func (tx testUpdatePowerTx) ValidateBasic() sdk.Error { return nil } +func (tx testUpdatePowerTx) GetSigners() []sdk.Address { return nil } +func (tx testUpdatePowerTx) GetSignatures() []sdk.StdSignature { return nil } func TestValidatorChange(t *testing.T) { diff --git a/examples/democoin/x/simplestake/msgs.go b/examples/democoin/x/simplestake/msgs.go index 0a7707003..01797a65b 100644 --- a/examples/democoin/x/simplestake/msgs.go +++ b/examples/democoin/x/simplestake/msgs.go @@ -26,9 +26,8 @@ func NewMsgBond(addr sdk.Address, stake sdk.Coin, pubKey crypto.PubKey) MsgBond } //nolint -func (msg MsgBond) Type() string { return moduleName } //TODO update "stake/declarecandidacy" -func (msg MsgBond) Get(key interface{}) (value interface{}) { return nil } -func (msg MsgBond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} } +func (msg MsgBond) Type() string { return moduleName } //TODO update "stake/declarecandidacy" +func (msg MsgBond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} } // basic validation of the bond message func (msg MsgBond) ValidateBasic() sdk.Error { diff --git a/examples/kvstore/tx.go b/examples/kvstore/tx.go index c084925b7..12bce0736 100644 --- a/examples/kvstore/tx.go +++ b/examples/kvstore/tx.go @@ -13,19 +13,6 @@ type kvstoreTx struct { bytes []byte } -func (tx kvstoreTx) Get(key interface{}) (value interface{}) { - switch k := key.(type) { - case string: - switch k { - case "key": - return tx.key - case "value": - return tx.value - } - } - return nil -} - func (tx kvstoreTx) Type() string { return "kvstore" } diff --git a/mock/tx.go b/mock/tx.go index cc79b1172..81dea4571 100644 --- a/mock/tx.go +++ b/mock/tx.go @@ -26,19 +26,6 @@ func NewTx(key, value string) kvstoreTx { } } -func (tx kvstoreTx) Get(key interface{}) (value interface{}) { - switch k := key.(type) { - case string: - switch k { - case "key": - return tx.key - case "value": - return tx.value - } - } - return nil -} - func (tx kvstoreTx) Type() string { return "kvstore" } diff --git a/types/tx_msg.go b/types/tx_msg.go index 7ac7b9bb2..c3a22b60f 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -171,8 +171,7 @@ func NewTestMsg(addrs ...Address) *TestMsg { } //nolint -func (msg *TestMsg) Type() string { return "TestMsg" } -func (msg *TestMsg) Get(key interface{}) (value interface{}) { return nil } +func (msg *TestMsg) Type() string { return "TestMsg" } func (msg *TestMsg) GetSignBytes() []byte { bz, err := json.Marshal(msg.signers) if err != nil { From d52d74582aef73f22f35d2ae12042d9f11b77ab2 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Mon, 30 Apr 2018 16:24:46 -0700 Subject: [PATCH 158/176] Change fermion to steak --- cmd/gaia/app/app_test.go | 4 ++-- cmd/gaia/app/genesis.go | 4 ++-- cmd/gaia/cli_test/cli_test.go | 20 ++++++++++---------- docs/old/staking/public-testnet.rst | 4 ++-- docs/sdk/lcd-rest-api.yaml | 2 +- docs/staking/intro.rst | 4 ++-- docs/staking/testnet.rst | 4 ++-- x/stake/client/cli/flags.go | 2 +- x/stake/handler_test.go | 4 ++-- x/stake/msg.go | 2 +- x/stake/msg_test.go | 6 +++--- x/stake/test_common.go | 4 ++-- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 721215999..25c6b2d97 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -369,9 +369,9 @@ func TestIBCMsgs(t *testing.T) { func TestStakeMsgs(t *testing.T) { gapp := newGaiaApp() - genCoins, err := sdk.ParseCoins("42fermion") + genCoins, err := sdk.ParseCoins("42steak") require.Nil(t, err) - bondCoin, err := sdk.ParseCoin("10fermion") + bondCoin, err := sdk.ParseCoin("10steak") require.Nil(t, err) acc1 := &auth.BaseAccount{ diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 7d0fb01d0..9d88953cf 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -146,11 +146,11 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso return } - // create the genesis account, give'm few fermions and a buncha token with there name + // create the genesis account, give'm few steaks and a buncha token with there name accAuth := auth.NewBaseAccountWithAddress(genTx.Address) accAuth.Coins = sdk.Coins{ {genTx.Name + "Token", 1000}, - {"fermion", freeFermionsAcc}, + {"steak", freeFermionsAcc}, } acc := NewGenesisAccount(&accAuth) genaccs[i] = acc diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 01f2e1563..102c4ada9 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -39,15 +39,15 @@ func TestGaiaCLISend(t *testing.T) { barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json") fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak")) - executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) + executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) - assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak")) fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak")) } func TestGaiaCLIDeclareCandidacy(t *testing.T) { @@ -70,26 +70,26 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json") barAddr, barPubKey := executeGetAddrPK(t, "gaiacli keys show bar --output=json") - executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass) + executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass) time.Sleep(time.Second * 3) // waiting for some blocks to pass fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) - assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak")) barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) - assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak")) // declare candidacy declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags) declStr += fmt.Sprintf(" --name=%v", "bar") declStr += fmt.Sprintf(" --address-candidate=%v", barAddr) declStr += fmt.Sprintf(" --pubkey=%v", barPubKey) - declStr += fmt.Sprintf(" --amount=%v", "3fermion") + declStr += fmt.Sprintf(" --amount=%v", "3steak") declStr += fmt.Sprintf(" --moniker=%v", "bar-vally") fmt.Printf("debug declStr: %v\n", declStr) executeWrite(t, declStr, pass) time.Sleep(time.Second) // waiting for some blocks to pass barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) - assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("fermion")) + assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("steak")) candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) assert.Equal(t, candidate.Address.String(), barAddr) assert.Equal(t, int64(3), candidate.Assets.Evaluate()) @@ -106,7 +106,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { //executeWrite(t, unbondStr, pass) //time.Sleep(time.Second * 3) // waiting for some blocks to pass //barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) - //assert.Equal(t, int64(99998), barAcc.GetCoins().AmountOf("fermion")) + //assert.Equal(t, int64(99998), barAcc.GetCoins().AmountOf("steak")) //candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) //assert.Equal(t, int64(2), candidate.Assets.Evaluate()) } diff --git a/docs/old/staking/public-testnet.rst b/docs/old/staking/public-testnet.rst index 440a08449..640163642 100644 --- a/docs/old/staking/public-testnet.rst +++ b/docs/old/staking/public-testnet.rst @@ -12,7 +12,7 @@ Get Tokens If you haven't already `created a key <../key-management.html>`__, do so now. Copy your key's address and enter it into `this utility `__ which will send you -some ``fermion`` testnet tokens. +some ``steak`` testnet tokens. Get Files --------- @@ -59,6 +59,6 @@ and check our balance: Where ``$MYADDR`` is the address originally generated by ``gaia keys new bob``. -You are now ready to declare candidacy or delegate some fermions. See the +You are now ready to declare candidacy or delegate some steaks. See the `staking module overview <./staking-module.html>`__ for more information on using the ``gaia client``. diff --git a/docs/sdk/lcd-rest-api.yaml b/docs/sdk/lcd-rest-api.yaml index eb9ec714b..7d38274c0 100644 --- a/docs/sdk/lcd-rest-api.yaml +++ b/docs/sdk/lcd-rest-api.yaml @@ -547,7 +547,7 @@ components: properties: denom: type: string - example: fermion + example: steak amount: type: number example: 50 diff --git a/docs/staking/intro.rst b/docs/staking/intro.rst index 961136894..7b5acb986 100644 --- a/docs/staking/intro.rst +++ b/docs/staking/intro.rst @@ -107,7 +107,7 @@ The ``genesis.json`` should look something like: "address": "1D9B2356CAADF46D3EE3488E3CCE3028B4283DEE", "coins": [ { - "denom": "fermion", + "denom": "steak", "amount": 100000 } ] @@ -150,7 +150,7 @@ The ``genesis.json`` should look something like: "denom": 100 }, "max_validators": 100, - "bond_denom": "fermion" + "bond_denom": "steak" } } }, diff --git a/docs/staking/testnet.rst b/docs/staking/testnet.rst index ab8c1644d..92aa93eb2 100644 --- a/docs/staking/testnet.rst +++ b/docs/staking/testnet.rst @@ -46,13 +46,13 @@ Nice. We can also lookup the validator set: gaiacli validatorset -Then, we try to transfer some ``fermion`` to another account: +Then, we try to transfer some ``steak`` to another account: :: gaiacli account gaiacli account - gaiacli send --amount=10fermion --to= --name=foo --chain-id=test-chain + gaiacli send --amount=10steak --to= --name=foo --chain-id=test-chain **Note:** We need to be careful with the ``chain-id`` and ``sequence`` diff --git a/x/stake/client/cli/flags.go b/x/stake/client/cli/flags.go index bf8246b34..98ea3bcce 100644 --- a/x/stake/client/cli/flags.go +++ b/x/stake/client/cli/flags.go @@ -30,7 +30,7 @@ var ( func init() { fsPk.String(FlagPubKey, "", "Go-Amino encoded hex PubKey of the validator-candidate. For Ed25519 the go-amino prepend hex is 1624de6220") - fsAmount.String(FlagAmount, "1fermion", "Amount of coins to bond") + fsAmount.String(FlagAmount, "1steak", "Amount of coins to bond") fsShares.String(FlagShares, "", "Amount of shares to unbond, either in decimal or keyword MAX (ex. 1.23456789, 99, MAX)") fsDescription.String(FlagMoniker, "", "validator-candidate name") fsDescription.String(FlagIdentity, "", "optional keybase signature") diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 1240e4e6c..b4db952f0 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -18,7 +18,7 @@ func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt i return MsgDeclareCandidacy{ Description: Description{}, CandidateAddr: address, - Bond: sdk.Coin{"fermion", amt}, + Bond: sdk.Coin{"steak", amt}, PubKey: pubKey, } } @@ -27,7 +27,7 @@ func newTestMsgDelegate(delegatorAddr, candidateAddr sdk.Address, amt int64) Msg return MsgDelegate{ DelegatorAddr: delegatorAddr, CandidateAddr: candidateAddr, - Bond: sdk.Coin{"fermion", amt}, + Bond: sdk.Coin{"steak", amt}, } } diff --git a/x/stake/msg.go b/x/stake/msg.go index 6e8101f96..28e02bea7 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -14,7 +14,7 @@ const MsgType = "stake" // initialize at genesis - to allow for the same tests we should should make // the ValidateBasic() function a return from an initializable function // ValidateBasic(bondDenom string) function -const StakingToken = "fermion" +const StakingToken = "steak" //Verify interface at compile time var _, _, _, _ sdk.Msg = &MsgDeclareCandidacy{}, &MsgEditCandidacy{}, &MsgDelegate{}, &MsgUnbond{} diff --git a/x/stake/msg_test.go b/x/stake/msg_test.go index b3e2bbe3a..19e8335be 100644 --- a/x/stake/msg_test.go +++ b/x/stake/msg_test.go @@ -10,9 +10,9 @@ import ( ) var ( - coinPos = sdk.Coin{"fermion", 1000} - coinZero = sdk.Coin{"fermion", 0} - coinNeg = sdk.Coin{"fermion", -10000} + coinPos = sdk.Coin{"steak", 1000} + coinZero = sdk.Coin{"steak", 0} + coinNeg = sdk.Coin{"steak", -10000} coinPosNotAtoms = sdk.Coin{"foo", 10000} coinZeroNotAtoms = sdk.Coin{"foo", 0} coinNegNotAtoms = sdk.Coin{"foo", -10000} diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 4d11ea937..189deeff0 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -83,7 +83,7 @@ func defaultParams() Params { InflationMin: sdk.NewRat(7, 100), GoalBonded: sdk.NewRat(67, 100), MaxValidators: 100, - BondDenom: "fermion", + BondDenom: "steak", } } @@ -142,7 +142,7 @@ func paramsNoInflation() Params { InflationMin: sdk.ZeroRat(), GoalBonded: sdk.NewRat(67, 100), MaxValidators: 100, - BondDenom: "fermion", + BondDenom: "steak", } } From 05c4bbb9972672c43b28e03c774720e3ee0273a4 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Mon, 30 Apr 2018 19:30:00 -0400 Subject: [PATCH 159/176] staking cli UnmarshalBinary -> UnmarshalJSON --- x/stake/client/cli/query.go | 4 ++-- x/stake/client/rest/query.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index 145333e48..bb2a2b8db 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -74,7 +74,7 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { // parse out the candidate candidate := new(stake.Candidate) - err = cdc.UnmarshalBinary(res, candidate) + err = cdc.UnmarshalJSON(res, candidate) if err != nil { return err } @@ -122,7 +122,7 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command // parse out the bond bond := new(stake.DelegatorBond) - err = cdc.UnmarshalBinary(res, bond) + err = cdc.UnmarshalJSON(res, bond) if err != nil { return err } diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 8eb0e03ce..22175d75a 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -59,7 +59,7 @@ func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, } var bond stake.DelegatorBond - err = cdc.UnmarshalBinary(res, &bond) + err = cdc.UnmarshalJSON(res, &bond) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Couldn't decode bond. Error: %s", err.Error()))) From 44140a8d9e09bdb53b8ee5716a24ae863ee1b58c Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 26 Apr 2018 17:41:06 -0400 Subject: [PATCH 160/176] re-enable race check for cli test --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 825d5e93f..95f879392 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -83,7 +83,7 @@ jobs: command: | export PATH="$GOBIN:$PATH" make install - for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/ | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | circleci tests split --split-by=timings); do + for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/ | circleci tests split --split-by=timings); do id=$(basename "$pkg") go test -timeout 5m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" From 62fc3e2c497d983a6266221985e52ff56ad74ed1 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Apr 2018 12:35:09 +0200 Subject: [PATCH 161/176] Context-accessible logger field --- CHANGELOG.md | 1 + baseapp/baseapp.go | 8 ++++---- examples/democoin/x/pow/handler_test.go | 3 ++- examples/democoin/x/pow/keeper_test.go | 3 ++- examples/democoin/x/simplestake/keeper_test.go | 5 +++-- types/context.go | 13 ++++++++++--- types/context_test.go | 5 +++-- x/auth/ante_test.go | 11 ++++++----- x/auth/context_test.go | 3 ++- x/auth/mapper_test.go | 3 ++- x/bank/keeper_test.go | 7 ++++--- x/ibc/ibc_test.go | 3 ++- x/stake/test_common.go | 3 ++- 13 files changed, 43 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fe6c4cf2..a1799ea5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ FEATURES: * Create genesis transactions with `gaiad init gen-tx` * New genesis account keys are automatically added to the client keybase (introduce `--client-home` flag) * Initialize with genesis txs using `--gen-txs` flag +* Context now has access to the applicaiton logger BREAKING CHANGES diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 51e96ae20..21b45e0af 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -210,9 +210,9 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error { // NewContext returns a new Context with the correct store, the given header, and nil txBytes. func (app *BaseApp) NewContext(isCheckTx bool, header abci.Header) sdk.Context { if isCheckTx { - return sdk.NewContext(app.checkState.ms, header, true, nil) + return sdk.NewContext(app.checkState.ms, header, true, nil, log.NewNopLogger()) } - return sdk.NewContext(app.deliverState.ms, header, false, nil) + return sdk.NewContext(app.deliverState.ms, header, false, nil, log.NewNopLogger()) } type state struct { @@ -228,7 +228,7 @@ func (app *BaseApp) setCheckState(header abci.Header) { ms := app.cms.CacheMultiStore() app.checkState = &state{ ms: ms, - ctx: sdk.NewContext(ms, header, true, nil), + ctx: sdk.NewContext(ms, header, true, nil, log.NewNopLogger()), } } @@ -236,7 +236,7 @@ func (app *BaseApp) setDeliverState(header abci.Header) { ms := app.cms.CacheMultiStore() app.deliverState = &state{ ms: ms, - ctx: sdk.NewContext(ms, header, false, nil), + ctx: sdk.NewContext(ms, header, false, nil, log.NewNopLogger()), } } diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index 0fffb8f5b..30aeafa2a 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" abci "github.com/tendermint/abci/types" + "github.com/tendermint/tmlibs/log" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" @@ -19,7 +20,7 @@ func TestPowHandler(t *testing.T) { auth.RegisterBaseAccount(cdc) am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) config := NewConfig("pow", int64(1)) ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, config, ck, DefaultCodespace) diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index cb021eb16..a4afb876a 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -7,6 +7,7 @@ import ( abci "github.com/tendermint/abci/types" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" @@ -32,7 +33,7 @@ func TestPowKeeperGetSet(t *testing.T) { auth.RegisterBaseAccount(cdc) am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) config := NewConfig("pow", int64(1)) ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, config, ck, DefaultCodespace) diff --git a/examples/democoin/x/simplestake/keeper_test.go b/examples/democoin/x/simplestake/keeper_test.go index 75e9fcded..302a2e58b 100644 --- a/examples/democoin/x/simplestake/keeper_test.go +++ b/examples/democoin/x/simplestake/keeper_test.go @@ -10,6 +10,7 @@ import ( abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" @@ -32,7 +33,7 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) { func TestKeeperGetSet(t *testing.T) { ms, _, capKey := setupMultiStore() - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) stakeKeeper := NewKeeper(capKey, bank.NewKeeper(nil), DefaultCodespace) addr := sdk.Address([]byte("some-address")) @@ -59,7 +60,7 @@ func TestBonding(t *testing.T) { cdc := wire.NewCodec() auth.RegisterBaseAccount(cdc) - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := bank.NewKeeper(accountMapper) diff --git a/types/context.go b/types/context.go index 8c91175bc..e28523ebe 100644 --- a/types/context.go +++ b/types/context.go @@ -7,10 +7,9 @@ import ( "github.com/golang/protobuf/proto" abci "github.com/tendermint/abci/types" + "github.com/tendermint/tmlibs/log" ) -// TODO: Add a default logger. - /* The intent of Context is for it to be an immutable object that can be cloned and updated cheaply with WithValue() and passed forward to the @@ -31,7 +30,7 @@ type Context struct { } // create a new context -func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, txBytes []byte) Context { +func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, txBytes []byte, logger log.Logger) Context { c := Context{ Context: context.Background(), pst: newThePast(), @@ -43,6 +42,7 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, txBytes []byt c = c.WithChainID(header.ChainID) c = c.WithIsCheckTx(isCheckTx) c = c.WithTxBytes(txBytes) + c = c.WithLogger(logger) return c } @@ -126,6 +126,7 @@ const ( contextKeyChainID contextKeyIsCheckTx contextKeyTxBytes + contextKeyLogger ) // NOTE: Do not expose MultiStore. @@ -151,6 +152,9 @@ func (c Context) IsCheckTx() bool { func (c Context) TxBytes() []byte { return c.Value(contextKeyTxBytes).([]byte) } +func (c Context) Logger() log.Logger { + return c.Value(contextKeyLogger).(log.Logger) +} func (c Context) WithMultiStore(ms MultiStore) Context { return c.withValue(contextKeyMultiStore, ms) } @@ -170,6 +174,9 @@ func (c Context) WithIsCheckTx(isCheckTx bool) Context { func (c Context) WithTxBytes(txBytes []byte) Context { return c.withValue(contextKeyTxBytes, txBytes) } +func (c Context) WithLogger(logger log.Logger) Context { + return c.withValue(contextKeyLogger, logger) +} // Cache the multistore and return a new cached context. The cached context is // written to the context when writeCache is called. diff --git a/types/context_test.go b/types/context_test.go index b40e79dc2..ebed046ce 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/store" "github.com/cosmos/cosmos-sdk/types" @@ -14,7 +15,7 @@ import ( func TestContextGetOpShouldNeverPanic(t *testing.T) { var ms types.MultiStore - ctx := types.NewContext(ms, abci.Header{}, false, nil) + ctx := types.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) indices := []int64{ -10, 1, 0, 10, 20, } @@ -29,7 +30,7 @@ func defaultContext(key types.StoreKey) types.Context { cms := store.NewCommitMultiStore(db) cms.MountStoreWithDB(key, types.StoreTypeIAVL, db) cms.LoadLatestVersion() - ctx := types.NewContext(cms, abci.Header{}, false, nil) + ctx := types.NewContext(cms, abci.Header{}, false, nil, log.NewNopLogger()) return ctx } diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index 3baf8ee71..ec296b12b 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/tmlibs/log" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" @@ -73,7 +74,7 @@ func TestAnteHandlerSigErrors(t *testing.T) { RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) anteHandler := NewAnteHandler(mapper, BurnFeeHandler) - ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses priv1, addr1 := privAndAddr() @@ -114,7 +115,7 @@ func TestAnteHandlerSequences(t *testing.T) { RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) anteHandler := NewAnteHandler(mapper, BurnFeeHandler) - ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses priv1, addr1 := privAndAddr() @@ -180,7 +181,7 @@ func TestAnteHandlerFees(t *testing.T) { RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) anteHandler := NewAnteHandler(mapper, BurnFeeHandler) - ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses priv1, addr1 := privAndAddr() @@ -217,7 +218,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) anteHandler := NewAnteHandler(mapper, BurnFeeHandler) - ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses priv1, addr1 := privAndAddr() @@ -292,7 +293,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) anteHandler := NewAnteHandler(mapper, BurnFeeHandler) - ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses priv1, addr1 := privAndAddr() diff --git a/x/auth/context_test.go b/x/auth/context_test.go index 0e4db8b08..89e318e0a 100644 --- a/x/auth/context_test.go +++ b/x/auth/context_test.go @@ -6,13 +6,14 @@ import ( "github.com/stretchr/testify/assert" abci "github.com/tendermint/abci/types" + "github.com/tendermint/tmlibs/log" sdk "github.com/cosmos/cosmos-sdk/types" ) func TestContextWithSigners(t *testing.T) { ms, _ := setupMultiStore() - ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) _, _, addr1 := keyPubAddr() _, _, addr2 := keyPubAddr() diff --git a/x/auth/mapper_test.go b/x/auth/mapper_test.go index 2912ddde8..cdd418990 100644 --- a/x/auth/mapper_test.go +++ b/x/auth/mapper_test.go @@ -7,6 +7,7 @@ import ( abci "github.com/tendermint/abci/types" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" @@ -28,7 +29,7 @@ func TestAccountMapperGetSet(t *testing.T) { RegisterBaseAccount(cdc) // make context and mapper - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) addr := sdk.Address([]byte("some-address")) diff --git a/x/bank/keeper_test.go b/x/bank/keeper_test.go index 7db9c275d..4394392dd 100644 --- a/x/bank/keeper_test.go +++ b/x/bank/keeper_test.go @@ -7,6 +7,7 @@ import ( abci "github.com/tendermint/abci/types" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" @@ -30,7 +31,7 @@ func TestKeeper(t *testing.T) { cdc := wire.NewCodec() auth.RegisterBaseAccount(cdc) - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := NewKeeper(accountMapper) @@ -116,7 +117,7 @@ func TestSendKeeper(t *testing.T) { cdc := wire.NewCodec() auth.RegisterBaseAccount(cdc) - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := NewKeeper(accountMapper) sendKeeper := NewSendKeeper(accountMapper) @@ -185,7 +186,7 @@ func TestViewKeeper(t *testing.T) { cdc := wire.NewCodec() auth.RegisterBaseAccount(cdc) - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) coinKeeper := NewKeeper(accountMapper) viewKeeper := NewViewKeeper(accountMapper) diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index 61b9182f1..d0019002f 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -8,6 +8,7 @@ import ( abci "github.com/tendermint/abci/types" "github.com/tendermint/go-crypto" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" @@ -23,7 +24,7 @@ func defaultContext(key sdk.StoreKey) sdk.Context { cms := store.NewCommitMultiStore(db) cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db) cms.LoadLatestVersion() - ctx := sdk.NewContext(cms, abci.Header{}, false, nil) + ctx := sdk.NewContext(cms, abci.Header{}, false, nil, log.NewNopLogger()) return ctx } diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 189deeff0..27acebe08 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -10,6 +10,7 @@ import ( abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" @@ -157,7 +158,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context err := ms.LoadLatestVersion() require.Nil(t, err) - ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil) + ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil, log.NewNopLogger()) cdc := makeTestCodec() accountMapper := auth.NewAccountMapper( cdc, // amino codec From c7cd21955a9ea7ac5bf030b5b640959934480efc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 23 Apr 2018 13:22:07 +0200 Subject: [PATCH 162/176] Add MemLogger --- types/logger.go | 49 ++++++++++++++++++++++++++++++++++++++++++++ types/logger_test.go | 17 +++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 types/logger.go create mode 100644 types/logger_test.go diff --git a/types/logger.go b/types/logger.go new file mode 100644 index 000000000..f736b0120 --- /dev/null +++ b/types/logger.go @@ -0,0 +1,49 @@ +package types + +import ( + "github.com/tendermint/tmlibs/log" +) + +// MemLogger logs to memory +type MemLogger interface { + log.Logger + Logs() []LogEntry +} + +// LogEntry is an entry in a log +type LogEntry struct { + Level string + Message string + Keyvals []interface{} +} + +type memLogger struct { + entries *[]LogEntry +} + +func (l memLogger) Debug(msg string, keyvals ...interface{}) { + *l.entries = append(*l.entries, LogEntry{"debug", msg, keyvals}) +} + +func (l memLogger) Info(msg string, keyvals ...interface{}) { + *l.entries = append(*l.entries, LogEntry{"info", msg, keyvals}) +} + +func (l memLogger) Error(msg string, keyvals ...interface{}) { + *l.entries = append(*l.entries, LogEntry{"error", msg, keyvals}) +} + +func (l memLogger) With(keyvals ...interface{}) log.Logger { + panic("not implemented") +} + +func (l memLogger) Logs() []LogEntry { + return *l.entries +} + +func NewMemLogger() MemLogger { + entries := make([]LogEntry, 0) + return &memLogger{ + entries: &entries, + } +} diff --git a/types/logger_test.go b/types/logger_test.go new file mode 100644 index 000000000..e8cb51e11 --- /dev/null +++ b/types/logger_test.go @@ -0,0 +1,17 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMemLogger(t *testing.T) { + logger := NewMemLogger() + logger.Info("msg") + require.Equal(t, logger.Logs(), []LogEntry{LogEntry{"info", "msg", nil}}) + logger.Debug("msg2") + require.Equal(t, logger.Logs(), []LogEntry{LogEntry{"info", "msg", nil}, LogEntry{"debug", "msg2", nil}}) + logger.Error("msg3", 2) + require.Equal(t, logger.Logs(), []LogEntry{LogEntry{"info", "msg", nil}, LogEntry{"debug", "msg2", nil}, LogEntry{"error", "msg3", []interface{}{2}}}) +} From ad6c7f0be45a58f2f6d63d83defe908cd44fa058 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 25 Apr 2018 13:28:04 +0200 Subject: [PATCH 163/176] Remove MemLogger, update baseapp --- baseapp/baseapp.go | 8 ++++---- types/logger.go | 49 -------------------------------------------- types/logger_test.go | 17 --------------- 3 files changed, 4 insertions(+), 70 deletions(-) delete mode 100644 types/logger.go delete mode 100644 types/logger_test.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 21b45e0af..d3bf85fe8 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -210,9 +210,9 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error { // NewContext returns a new Context with the correct store, the given header, and nil txBytes. func (app *BaseApp) NewContext(isCheckTx bool, header abci.Header) sdk.Context { if isCheckTx { - return sdk.NewContext(app.checkState.ms, header, true, nil, log.NewNopLogger()) + return sdk.NewContext(app.checkState.ms, header, true, nil, app.Logger) } - return sdk.NewContext(app.deliverState.ms, header, false, nil, log.NewNopLogger()) + return sdk.NewContext(app.deliverState.ms, header, false, nil, app.Logger) } type state struct { @@ -228,7 +228,7 @@ func (app *BaseApp) setCheckState(header abci.Header) { ms := app.cms.CacheMultiStore() app.checkState = &state{ ms: ms, - ctx: sdk.NewContext(ms, header, true, nil, log.NewNopLogger()), + ctx: sdk.NewContext(ms, header, true, nil, app.Logger), } } @@ -236,7 +236,7 @@ func (app *BaseApp) setDeliverState(header abci.Header) { ms := app.cms.CacheMultiStore() app.deliverState = &state{ ms: ms, - ctx: sdk.NewContext(ms, header, false, nil, log.NewNopLogger()), + ctx: sdk.NewContext(ms, header, false, nil, app.Logger), } } diff --git a/types/logger.go b/types/logger.go deleted file mode 100644 index f736b0120..000000000 --- a/types/logger.go +++ /dev/null @@ -1,49 +0,0 @@ -package types - -import ( - "github.com/tendermint/tmlibs/log" -) - -// MemLogger logs to memory -type MemLogger interface { - log.Logger - Logs() []LogEntry -} - -// LogEntry is an entry in a log -type LogEntry struct { - Level string - Message string - Keyvals []interface{} -} - -type memLogger struct { - entries *[]LogEntry -} - -func (l memLogger) Debug(msg string, keyvals ...interface{}) { - *l.entries = append(*l.entries, LogEntry{"debug", msg, keyvals}) -} - -func (l memLogger) Info(msg string, keyvals ...interface{}) { - *l.entries = append(*l.entries, LogEntry{"info", msg, keyvals}) -} - -func (l memLogger) Error(msg string, keyvals ...interface{}) { - *l.entries = append(*l.entries, LogEntry{"error", msg, keyvals}) -} - -func (l memLogger) With(keyvals ...interface{}) log.Logger { - panic("not implemented") -} - -func (l memLogger) Logs() []LogEntry { - return *l.entries -} - -func NewMemLogger() MemLogger { - entries := make([]LogEntry, 0) - return &memLogger{ - entries: &entries, - } -} diff --git a/types/logger_test.go b/types/logger_test.go deleted file mode 100644 index e8cb51e11..000000000 --- a/types/logger_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestMemLogger(t *testing.T) { - logger := NewMemLogger() - logger.Info("msg") - require.Equal(t, logger.Logs(), []LogEntry{LogEntry{"info", "msg", nil}}) - logger.Debug("msg2") - require.Equal(t, logger.Logs(), []LogEntry{LogEntry{"info", "msg", nil}, LogEntry{"debug", "msg2", nil}}) - logger.Error("msg3", 2) - require.Equal(t, logger.Logs(), []LogEntry{LogEntry{"info", "msg", nil}, LogEntry{"debug", "msg2", nil}, LogEntry{"error", "msg3", []interface{}{2}}}) -} From db3a82fc97fe22a40ac253fc0f200d5f0acd499d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 25 Apr 2018 13:30:58 +0200 Subject: [PATCH 164/176] Update changelog, add simple testcase --- CHANGELOG.md | 2 +- types/context_test.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1799ea5a..98eef848d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ FEATURES: * Create genesis transactions with `gaiad init gen-tx` * New genesis account keys are automatically added to the client keybase (introduce `--client-home` flag) * Initialize with genesis txs using `--gen-txs` flag -* Context now has access to the applicaiton logger +* Context now has access to the application-configured logger BREAKING CHANGES diff --git a/types/context_test.go b/types/context_test.go index ebed046ce..d813516f0 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -60,3 +60,11 @@ func TestCacheContext(t *testing.T) { assert.Equal(t, v2, store.Get(k2)) } + +func TestLogContext(t *testing.T) { + key := types.NewKVStoreKey(t.Name()) + ctx := defaultContext(key) + ctx.Logger().Debug("debug") + ctx.Logger().Info("info") + ctx.Logger().Error("error") +} From 36e096d4bb163a639aab6e35a51815cb24b4956e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 25 Apr 2018 22:03:45 +0200 Subject: [PATCH 165/176] Update testcase after rebase --- types/lib/mapper_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/types/lib/mapper_test.go b/types/lib/mapper_test.go index 1058fed6e..e1759b06a 100644 --- a/types/lib/mapper_test.go +++ b/types/lib/mapper_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" abci "github.com/tendermint/abci/types" @@ -24,7 +25,7 @@ func defaultComponents(key sdk.StoreKey) (sdk.Context, *wire.Codec) { cms := store.NewCommitMultiStore(db) cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db) cms.LoadLatestVersion() - ctx := sdk.NewContext(cms, abci.Header{}, false, nil) + ctx := sdk.NewContext(cms, abci.Header{}, false, nil, log.NewNopLogger()) cdc := wire.NewCodec() return ctx, cdc } From 2376f231c21563775d71e952c05af8fc4bb71c75 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 1 May 2018 14:00:23 +0200 Subject: [PATCH 166/176] Rebase, update changelog & testcase --- CHANGELOG.md | 5 +++- examples/democoin/x/cool/keeper_test.go | 2 +- types/context_test.go | 31 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98eef848d..2f6c756c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## UNRELEASED +FEATURES + +* Context now has access to the application-configured logger + BREAKING CHANGES * types/rational now extends big.Rat @@ -27,7 +31,6 @@ FEATURES: * Create genesis transactions with `gaiad init gen-tx` * New genesis account keys are automatically added to the client keybase (introduce `--client-home` flag) * Initialize with genesis txs using `--gen-txs` flag -* Context now has access to the application-configured logger BREAKING CHANGES diff --git a/examples/democoin/x/cool/keeper_test.go b/examples/democoin/x/cool/keeper_test.go index 9aca3cc2a..d497dee69 100644 --- a/examples/democoin/x/cool/keeper_test.go +++ b/examples/democoin/x/cool/keeper_test.go @@ -30,7 +30,7 @@ func TestCoolKeeper(t *testing.T) { auth.RegisterBaseAccount(cdc) am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) - ctx := sdk.NewContext(ms, abci.Header{}, false, nil) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, nil) ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, ck, DefaultCodespace) diff --git a/types/context_test.go b/types/context_test.go index d813516f0..ec5faab44 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -13,6 +14,33 @@ import ( abci "github.com/tendermint/abci/types" ) +type MockLogger struct { + logs *[]string +} + +func NewMockLogger() MockLogger { + logs := make([]string, 0) + return MockLogger{ + &logs, + } +} + +func (l MockLogger) Debug(msg string, kvs ...interface{}) { + *l.logs = append(*l.logs, msg) +} + +func (l MockLogger) Info(msg string, kvs ...interface{}) { + *l.logs = append(*l.logs, msg) +} + +func (l MockLogger) Error(msg string, kvs ...interface{}) { + *l.logs = append(*l.logs, msg) +} + +func (l MockLogger) With(kvs ...interface{}) log.Logger { + panic("not implemented") +} + func TestContextGetOpShouldNeverPanic(t *testing.T) { var ms types.MultiStore ctx := types.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) @@ -64,7 +92,10 @@ func TestCacheContext(t *testing.T) { func TestLogContext(t *testing.T) { key := types.NewKVStoreKey(t.Name()) ctx := defaultContext(key) + logger := NewMockLogger() + ctx = ctx.WithLogger(logger) ctx.Logger().Debug("debug") ctx.Logger().Info("info") ctx.Logger().Error("error") + require.Equal(t, *logger.logs, []string{"debug", "info", "error"}) } From 7ef5e90fa557fed1f50a08519317834f2bbc1f66 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 1 May 2018 13:58:50 -0400 Subject: [PATCH 167/176] update changelog and version --- CHANGELOG.md | 69 ++++++++++++++++++++++++++-------------------- version/version.go | 6 ++-- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f6c756c9..e6fd48959 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,36 @@ # Changelog -## UNRELEASED - -FEATURES - -* Context now has access to the application-configured logger +## 0.16.0 (TBD) BREAKING CHANGES +* Move module REST/CLI packages to x/[module]/client/rest and x/[module]/client/cli +* Gaia simple-staking bond and unbond functions replaced +* [stake] Delegator bonds now store the height at which they were updated +* All module keepers now require a codespace, see basecoin or democoin for usage +* Many changes to names throughout + * Type as a prefix naming convention applied (ex. BondMsg -> MsgBond) + * Removed redundancy in names (ex. stake.StakeKeeper -> stake.Keeper) +* Removed SealedAccountMapper +* gaiad init now requires use of `--name` flag +* Removed Get from Msg interface * types/rational now extends big.Rat +FEATURES: + +* Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond +* MountStoreWithDB without providing a custom store works. +* Repo is now lint compliant / GoMetaLinter with tendermint-lint integrated into CI +* Better key output, pubkey go-amino hex bytes now output by default +* gaiad init overhaul + * Create genesis transactions with `gaiad init gen-tx` + * New genesis account keys are automatically added to the client keybase (introduce `--client-home` flag) + * Initialize with genesis txs using `--gen-txs` flag +* Context now has access to the application-configured logger + +BUG FIXES +* Gaia now uses stake, ported from github.com/cosmos/gaia + ## 0.15.1 (April 29, 2018) IMPROVEMENTS: @@ -18,38 +39,26 @@ IMPROVEMENTS: ## 0.15.0 (April 29, 2018) +NOTE: v0.15.0 is a large breaking change that updates the encoding scheme to use +[Amino](github.com/tendermint/go-amino). + +For details on how this changes encoding for public keys and addresses, +see the [docs](https://github.com/tendermint/tendermint/blob/v0.19.1/docs/specification/new-spec/encoding.md#public-key-cryptography). + +BREAKING CHANGES + +* Remove go-wire, use go-amino +* [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface +* [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores + FEATURES: * Add CacheContext * Add auto sequencing to client * Add FeeHandler to ante handler -* Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond -* MountStoreWithDB without providing a custom store works. -* Repo is now lint compliant / GoMetaLinter with tendermint-lint integrated into CI -* Better key output, pubkey go-amino hex bytes now output by default -* gaiad init overhaul - * Create genesis transactions with `gaiad init gen-tx` - * New genesis account keys are automatically added to the client keybase (introduce `--client-home` flag) - * Initialize with genesis txs using `--gen-txs` flag - -BREAKING CHANGES - -* Remove go-wire, use go-amino -* Move module REST/CLI packages to x/[module]/client/rest and x/[module]/client/cli -* Gaia simple-staking bond and unbond functions replaced -* [stake] Delegator bonds now store the height at which they were updated -* [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface -* [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores -* All module keepers now require a codespace, see basecoin or democoin for usage -* Many changes to names throughout - * Type as a prefix naming convention applied (ex. BondMsg -> MsgBond) - * Removed redundancy in names (ex. stake.StakeKeeper -> stake.Keeper) -* Removed SealedAccountMapper -* gaiad init now requires use of `--name` flag -* Removed Get from Msg interface BUG FIXES -* Gaia now uses stake, ported from github.com/cosmos/gaia +* MountStoreWithDB without providing a custom store works. ## 0.14.1 (April 9, 2018) diff --git a/version/version.go b/version/version.go index 1f85bdf62..d315bfea1 100644 --- a/version/version.go +++ b/version/version.go @@ -6,10 +6,10 @@ package version // TODO improve const Maj = "0" -const Min = "15" -const Fix = "1" +const Min = "16" +const Fix = "0" -const Version = "0.15.1" +const Version = "0.16.0-dev" // GitCommit set by build flags var GitCommit = "" From cb2491bbb87f056e9be396c23e2aa1e60f98840f Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 1 May 2018 11:31:56 -0700 Subject: [PATCH 168/176] Use GoAmino 0.9.9 and change impl of Rational.MarshalAmino --- Gopkg.lock | 6 +++--- Gopkg.toml | 2 +- types/rational.go | 21 +++++---------------- types/rational_test.go | 13 ++++++++++++- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index d773b4d7a..f474e7756 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -277,8 +277,8 @@ [[projects]] name = "github.com/tendermint/go-amino" packages = ["."] - revision = "3668c02a8feace009f80754a5e5a8541e5d7b996" - version = "0.9.8" + revision = "ed62928576cfcaf887209dc96142cd79cdfff389" + version = "0.9.9" [[projects]] name = "github.com/tendermint/go-crypto" @@ -460,6 +460,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "48f831a7ccc2c0fd3b790c16ca99ec864b89253d087ff4190d821c01c13e635a" + inputs-digest = "fad966346d3b6042faf2bf793168b6ce9a8ff59ae207b7ad57008ead0f3ff7d4" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 1e71e68e2..d2d4ee2ff 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -62,7 +62,7 @@ [[constraint]] name = "github.com/tendermint/go-amino" - version = "~0.9.8" + version = "~0.9.9" [[constraint]] name = "github.com/tendermint/iavl" diff --git a/types/rational.go b/types/rational.go index 550c96825..7e0a09107 100644 --- a/types/rational.go +++ b/types/rational.go @@ -1,7 +1,6 @@ package types import ( - "bytes" "fmt" "math/big" "strconv" @@ -153,26 +152,16 @@ func (r Rat) ToLeftPadded(totalDigits int8) string { //___________________________________________________________________________________ -//Wraps r.MarshalText() in quotes to make it a valid JSON string. -func (r Rat) MarshalJSON() ([]byte, error) { +//Wraps r.MarshalText(). +func (r Rat) MarshalAmino() (string, error) { bz, err := (&(r.Rat)).MarshalText() - if err != nil { - return nil, err - } - return []byte(fmt.Sprintf("\"%s\"", bz)), nil + return string(bz), err } // Requires a valid JSON string - strings quotes and calls UnmarshalText -func (r *Rat) UnmarshalJSON(data []byte) (err error) { - quote := []byte(`"`) - if len(data) < 2 || - !bytes.HasPrefix(data, quote) || - !bytes.HasSuffix(data, quote) { - return fmt.Errorf("JSON encoded Rat must be a quote-delimitted string, have %v", string(data)) - } - data = bytes.Trim(data, `"`) +func (r *Rat) UnmarshalAmino(text string) (err error) { tempRat := big.NewRat(0, 1) - err = tempRat.UnmarshalText(data) + err = tempRat.UnmarshalText([]byte(text)) if err != nil { return err } diff --git a/types/rational_test.go b/types/rational_test.go index 39207034c..a69c94195 100644 --- a/types/rational_test.go +++ b/types/rational_test.go @@ -235,7 +235,7 @@ func TestSerializationText(t *testing.T) { assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) } -func TestSerializationGoWire(t *testing.T) { +func TestSerializationGoWireJSON(t *testing.T) { r := NewRat(1, 3) bz, err := cdc.MarshalJSON(r) require.NoError(t, err) @@ -246,6 +246,17 @@ func TestSerializationGoWire(t *testing.T) { assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) } +func TestSerializationGoWireBinary(t *testing.T) { + r := NewRat(1, 3) + bz, err := cdc.MarshalBinary(r) + require.NoError(t, err) + + r2 := NewRat(0, 1) + err = cdc.UnmarshalBinary(bz, &r2) + require.NoError(t, err) + assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) +} + type testEmbedStruct struct { Field1 string `json:"f1"` Field2 int `json:"f2"` From dd9b5e78f709ead717353c61d5e1694cdf6583a5 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 1 May 2018 16:41:04 -0400 Subject: [PATCH 169/176] cleanup stake marshalJson -> marshalBinary --- cmd/gaia/app/app_test.go | 3 ++- types/rational_test.go | 6 ++--- x/stake/client/cli/query.go | 4 ++-- x/stake/client/rest/query.go | 2 +- x/stake/keeper.go | 44 ++++++++++++++++++------------------ 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 25c6b2d97..3bca2654b 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/ibc" @@ -107,7 +108,7 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { StakeData: stake.GetDefaultGenesisState(), } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + stateBytes, err := wire.MarshalJSONIndent(gapp.cdc, genesisState) if err != nil { return err } diff --git a/types/rational_test.go b/types/rational_test.go index a69c94195..e59545bfc 100644 --- a/types/rational_test.go +++ b/types/rational_test.go @@ -229,7 +229,7 @@ func TestSerializationText(t *testing.T) { bz, err := r.MarshalText() require.NoError(t, err) - r2 := NewRat(0, 1) + var r2 Rat err = r2.UnmarshalText(bz) require.NoError(t, err) assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) @@ -240,7 +240,7 @@ func TestSerializationGoWireJSON(t *testing.T) { bz, err := cdc.MarshalJSON(r) require.NoError(t, err) - r2 := NewRat(0, 1) + var r2 Rat err = cdc.UnmarshalJSON(bz, &r2) require.NoError(t, err) assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) @@ -251,7 +251,7 @@ func TestSerializationGoWireBinary(t *testing.T) { bz, err := cdc.MarshalBinary(r) require.NoError(t, err) - r2 := NewRat(0, 1) + var r2 Rat err = cdc.UnmarshalBinary(bz, &r2) require.NoError(t, err) assert.True(t, r.Equal(r2), "original: %v, unmarshalled: %v", r, r2) diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index bb2a2b8db..145333e48 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -74,7 +74,7 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { // parse out the candidate candidate := new(stake.Candidate) - err = cdc.UnmarshalJSON(res, candidate) + err = cdc.UnmarshalBinary(res, candidate) if err != nil { return err } @@ -122,7 +122,7 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command // parse out the bond bond := new(stake.DelegatorBond) - err = cdc.UnmarshalJSON(res, bond) + err = cdc.UnmarshalBinary(res, bond) if err != nil { return err } diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 22175d75a..8eb0e03ce 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -59,7 +59,7 @@ func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, } var bond stake.DelegatorBond - err = cdc.UnmarshalJSON(res, &bond) + err = cdc.UnmarshalBinary(res, &bond) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Couldn't decode bond. Error: %s", err.Error()))) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index d9fa293f5..605f675db 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -41,7 +41,7 @@ func (k Keeper) getCounter(ctx sdk.Context) int16 { return 0 } var counter int16 - err := k.cdc.UnmarshalJSON(b, &counter) + err := k.cdc.UnmarshalBinary(b, &counter) if err != nil { panic(err) } @@ -51,7 +51,7 @@ func (k Keeper) getCounter(ctx sdk.Context) int16 { // set the current in-block validator operation counter func (k Keeper) setCounter(ctx sdk.Context, counter int16) { store := ctx.KVStore(k.storeKey) - bz, err := k.cdc.MarshalJSON(counter) + bz, err := k.cdc.MarshalBinary(counter) if err != nil { panic(err) } @@ -67,7 +67,7 @@ func (k Keeper) GetCandidate(ctx sdk.Context, addr sdk.Address) (candidate Candi if b == nil { return candidate, false } - err := k.cdc.UnmarshalJSON(b, &candidate) + err := k.cdc.UnmarshalBinary(b, &candidate) if err != nil { panic(err) } @@ -88,7 +88,7 @@ func (k Keeper) GetCandidates(ctx sdk.Context, maxRetrieve int16) (candidates Ca } bz := iterator.Value() var candidate Candidate - err := k.cdc.UnmarshalJSON(bz, &candidate) + err := k.cdc.UnmarshalBinary(bz, &candidate) if err != nil { panic(err) } @@ -112,7 +112,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { } // marshal the candidate record and add to the state - bz, err := k.cdc.MarshalJSON(candidate) + bz, err := k.cdc.MarshalBinary(candidate) if err != nil { panic(err) } @@ -145,7 +145,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { } // update the candidate record - bz, err = k.cdc.MarshalJSON(candidate) + bz, err = k.cdc.MarshalBinary(candidate) if err != nil { panic(err) } @@ -153,7 +153,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // marshal the new validator record validator := candidate.validator() - bz, err = k.cdc.MarshalJSON(validator) + bz, err = k.cdc.MarshalBinary(validator) if err != nil { panic(err) } @@ -171,7 +171,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { setAcc = true } if setAcc { - bz, err = k.cdc.MarshalJSON(validator.abciValidator(k.cdc)) + bz, err = k.cdc.MarshalBinary(validator.abciValidator(k.cdc)) if err != nil { panic(err) } @@ -200,7 +200,7 @@ func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) { if store.Get(GetRecentValidatorKey(address)) == nil { return } - bz, err := k.cdc.MarshalJSON(candidate.validator().abciValidatorZero(k.cdc)) + bz, err := k.cdc.MarshalBinary(candidate.validator().abciValidatorZero(k.cdc)) if err != nil { panic(err) } @@ -242,7 +242,7 @@ func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) { } bz := iterator.Value() var validator Validator - err := k.cdc.UnmarshalJSON(bz, &validator) + err := k.cdc.UnmarshalBinary(bz, &validator) if err != nil { panic(err) } @@ -266,11 +266,11 @@ func (k Keeper) GetValidators(ctx sdk.Context) (validators []Validator) { // get the zero abci validator from the ToKickOut iterator value bz := iterator.Value() var validator Validator - err := k.cdc.UnmarshalJSON(bz, &validator) + err := k.cdc.UnmarshalBinary(bz, &validator) if err != nil { panic(err) } - bz, err = k.cdc.MarshalJSON(validator.abciValidatorZero(k.cdc)) + bz, err = k.cdc.MarshalBinary(validator.abciValidatorZero(k.cdc)) if err != nil { panic(err) } @@ -297,7 +297,7 @@ func (k Keeper) isNewValidator(ctx sdk.Context, store sdk.KVStore, address sdk.A } bz := iterator.Value() var val Validator - err := k.cdc.UnmarshalJSON(bz, &val) + err := k.cdc.UnmarshalBinary(bz, &val) if err != nil { panic(err) } @@ -330,7 +330,7 @@ func (k Keeper) getAccUpdateValidators(ctx sdk.Context) (updates []abci.Validato for ; iterator.Valid(); iterator.Next() { valBytes := iterator.Value() var val abci.Validator - err := k.cdc.UnmarshalJSON(valBytes, &val) + err := k.cdc.UnmarshalBinary(valBytes, &val) if err != nil { panic(err) } @@ -364,7 +364,7 @@ func (k Keeper) GetDelegatorBond(ctx sdk.Context, return bond, false } - err := k.cdc.UnmarshalJSON(delegatorBytes, &bond) + err := k.cdc.UnmarshalBinary(delegatorBytes, &bond) if err != nil { panic(err) } @@ -385,7 +385,7 @@ func (k Keeper) getBonds(ctx sdk.Context, maxRetrieve int16) (bonds []DelegatorB } bondBytes := iterator.Value() var bond DelegatorBond - err := k.cdc.UnmarshalJSON(bondBytes, &bond) + err := k.cdc.UnmarshalBinary(bondBytes, &bond) if err != nil { panic(err) } @@ -410,7 +410,7 @@ func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRet } bondBytes := iterator.Value() var bond DelegatorBond - err := k.cdc.UnmarshalJSON(bondBytes, &bond) + err := k.cdc.UnmarshalBinary(bondBytes, &bond) if err != nil { panic(err) } @@ -422,7 +422,7 @@ func (k Keeper) GetDelegatorBonds(ctx sdk.Context, delegator sdk.Address, maxRet func (k Keeper) setDelegatorBond(ctx sdk.Context, bond DelegatorBond) { store := ctx.KVStore(k.storeKey) - b, err := k.cdc.MarshalJSON(bond) + b, err := k.cdc.MarshalBinary(bond) if err != nil { panic(err) } @@ -448,7 +448,7 @@ func (k Keeper) GetParams(ctx sdk.Context) (params Params) { panic("Stored params should not have been nil") } - err := k.cdc.UnmarshalJSON(b, ¶ms) + err := k.cdc.UnmarshalBinary(b, ¶ms) if err != nil { panic(err) } @@ -456,7 +456,7 @@ func (k Keeper) GetParams(ctx sdk.Context) (params Params) { } func (k Keeper) setParams(ctx sdk.Context, params Params) { store := ctx.KVStore(k.storeKey) - b, err := k.cdc.MarshalJSON(params) + b, err := k.cdc.MarshalBinary(params) if err != nil { panic(err) } @@ -477,7 +477,7 @@ func (k Keeper) GetPool(ctx sdk.Context) (pool Pool) { if b == nil { panic("Stored pool should not have been nil") } - err := k.cdc.UnmarshalJSON(b, &pool) + err := k.cdc.UnmarshalBinary(b, &pool) if err != nil { panic(err) // This error should never occur big problem if does } @@ -486,7 +486,7 @@ func (k Keeper) GetPool(ctx sdk.Context) (pool Pool) { func (k Keeper) setPool(ctx sdk.Context, p Pool) { store := ctx.KVStore(k.storeKey) - b, err := k.cdc.MarshalJSON(p) + b, err := k.cdc.MarshalBinary(p) if err != nil { panic(err) } From 9ccee0770fe366b6664d080272259a752c679b16 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 1 May 2018 23:33:23 -0400 Subject: [PATCH 170/176] switched test to test_nopcli --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index acbfba951..d6d1fa289 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ PACKAGES=$(shell go list ./... | grep -v '/vendor/') COMMIT_HASH := $(shell git rev-parse --short HEAD) BUILD_FLAGS = -ldflags "-X github.com/cosmos/cosmos-sdk/version.GitCommit=${COMMIT_HASH}" -all: check_tools get_vendor_deps build build_examples install install_examples test +all: check_tools get_vendor_deps build build_examples install install_examples test_nocli ######################################## ### CI From e970dce841f5fc4130cc9363ab5ddeb83aab0cc8 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 2 May 2018 23:07:05 -0400 Subject: [PATCH 171/176] circle/makefile upgraaade --- .circleci/config.yml | 38 ++++++++++++++++++++++++++++++++++++++ Makefile | 22 +++++++++------------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 95f879392..122827afd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -67,6 +67,38 @@ jobs: command: | export PATH="$GOBIN:$PATH" gometalinter --disable-all --enable='golint' --vendor ./... + + test_unit: + <<: *defaults + parallelism: 4 + steps: + - attach_workspace: + at: /tmp/workspace + - restore_cache: + key: v1-pkg-cache + - restore_cache: + key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Test unit + command: | + export PATH="$GOBIN:$PATH" + make test_unit + + test_cli: + <<: *defaults + parallelism: 1 + steps: + - attach_workspace: + at: /tmp/workspace + - restore_cache: + key: v1-pkg-cache + - restore_cache: + key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Test cli + command: | + export PATH="$GOBIN:$PATH" + make test_cli test_cover: <<: *defaults @@ -121,6 +153,12 @@ workflows: - lint: requires: - setup_dependencies + - test_unit: + requires: + - setup_dependencies + - test_cli: + requires: + - setup_dependencies - test_cover: requires: - setup_dependencies diff --git a/Makefile b/Makefile index d6d1fa289..abcdc5756 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ PACKAGES=$(shell go list ./... | grep -v '/vendor/') +PACKAGES_NOCLITEST=$(shell go list ./... | grep -v '/vendor/' | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test) COMMIT_HASH := $(shell git rev-parse --short HEAD) BUILD_FLAGS = -ldflags "-X github.com/cosmos/cosmos-sdk/version.GitCommit=${COMMIT_HASH}" -all: check_tools get_vendor_deps build build_examples install install_examples test_nocli +all: check_tools get_vendor_deps install install_examples test_lint test ######################################## ### CI -ci: get_tools get_vendor_deps install test_cover +ci: get_tools get_vendor_deps install test_cover test_lint test ######################################## ### Build @@ -83,18 +84,13 @@ godocs: ######################################## ### Testing -test: test_unit # test_cli +test: test_unit test_cli -test_nocli: - go test `go list ./... | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test` - -# Must be run in each package seperately for the visualization -# Added here for easy reference -# coverage: -# go test -coverprofile=c.out && go tool cover -html=c.out +test_cli: + @go test -count 1 -p 1 `go list github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test` test_unit: - @go test $(PACKAGES) + @go test $(PACKAGES_NOCLITEST) test_cover: @bash tests/test_cover.sh @@ -103,7 +99,7 @@ test_lint: gometalinter --disable-all --enable='golint' --vendor ./... benchmark: - @go test -bench=. $(PACKAGES) + @go test -bench=. $(PACKAGES_NOCLITEST) ######################################## @@ -133,4 +129,4 @@ devdoc_update: # To avoid unintended conflicts with file names, always add to .PHONY # unless there is a reason not to. # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html -.PHONY: build build_examples install install_examples dist check_tools get_tools get_vendor_deps draw_deps test test_nocli test_unit test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update +.PHONY: build build_examples install install_examples dist check_tools get_tools get_vendor_deps draw_deps test test_cli test_unit test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update From 4911db850dd8232e7b8f701f81535d37c24a9b8d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 3 May 2018 18:35:12 +0200 Subject: [PATCH 172/176] Fix auto-sequencing (closes #950) --- client/context/viper.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/context/viper.go b/client/context/viper.go index 7e82f7ad9..4b3007f12 100644 --- a/client/context/viper.go +++ b/client/context/viper.go @@ -36,7 +36,7 @@ func NewCoreContextFromViper() CoreContext { Sequence: viper.GetInt64(client.FlagSequence), Client: rpc, Decoder: nil, - AccountStore: "main", + AccountStore: "acc", } } @@ -55,7 +55,8 @@ func defaultChainID() (string, error) { // EnsureSequence - automatically set sequence number if none provided func EnsureSequence(ctx CoreContext) (CoreContext, error) { - if viper.IsSet(client.FlagSequence) { + // Should be viper.IsSet, but this does not work - https://github.com/spf13/viper/pull/331 + if viper.GetInt64(client.FlagSequence) != 0 { return ctx, nil } from, err := ctx.GetFromAddress() From 05988623af728301aec667b8ee3f955d8c2e1a6d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 3 May 2018 18:36:37 +0200 Subject: [PATCH 173/176] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6fd48959..0b1e67bee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ FEATURES: BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia +* Auto-sequencing now works correctly ## 0.15.1 (April 29, 2018) From 10540e38db9ee7e155d370284c98c61b13875edd Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 3 May 2018 23:19:56 +0200 Subject: [PATCH 174/176] Handle case of empty (new) account --- client/context/helpers.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/context/helpers.go b/client/context/helpers.go index ded70cb5c..233dbcc2b 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -158,6 +158,11 @@ func (ctx CoreContext) NextSequence(address []byte) (int64, error) { return 0, err } + if len(res) == 0 { + fmt.Printf("No account found, defaulting to sequence 0\n") + return 0, err + } + account, err := ctx.Decoder(res) if err != nil { panic(err) From 23c9e2fb6f04a26f1b7bb4a46b946fa18e25acdd Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 4 May 2018 05:43:29 +0200 Subject: [PATCH 175/176] Update CLI tests to test auto-sequencing --- cmd/gaia/cli_test/cli_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 102c4ada9..b4529efd8 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -48,6 +48,15 @@ func TestGaiaCLISend(t *testing.T) { assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak")) fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak")) + + // test autosequencing + executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass) + time.Sleep(time.Second * 3) // waiting for some blocks to pass + + barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) + assert.Equal(t, int64(20), barAcc.GetCoins().AmountOf("steak")) + fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags)) + assert.Equal(t, int64(30), fooAcc.GetCoins().AmountOf("steak")) } func TestGaiaCLIDeclareCandidacy(t *testing.T) { From bf178ba041d40c503fd2c5e0693b8ec7f96397ff Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 7 May 2018 09:47:17 -0400 Subject: [PATCH 176/176] spec/ibc -> spec/ibc/mvp --- docs/spec/ibc/{ => mvp}/ibc.md | 0 docs/spec/ibc/{ => mvp}/mvp1.md | 0 docs/spec/ibc/{ => mvp}/mvp2.md | 0 docs/spec/ibc/{ => mvp}/mvp3.md | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename docs/spec/ibc/{ => mvp}/ibc.md (100%) rename docs/spec/ibc/{ => mvp}/mvp1.md (100%) rename docs/spec/ibc/{ => mvp}/mvp2.md (100%) rename docs/spec/ibc/{ => mvp}/mvp3.md (100%) diff --git a/docs/spec/ibc/ibc.md b/docs/spec/ibc/mvp/ibc.md similarity index 100% rename from docs/spec/ibc/ibc.md rename to docs/spec/ibc/mvp/ibc.md diff --git a/docs/spec/ibc/mvp1.md b/docs/spec/ibc/mvp/mvp1.md similarity index 100% rename from docs/spec/ibc/mvp1.md rename to docs/spec/ibc/mvp/mvp1.md diff --git a/docs/spec/ibc/mvp2.md b/docs/spec/ibc/mvp/mvp2.md similarity index 100% rename from docs/spec/ibc/mvp2.md rename to docs/spec/ibc/mvp/mvp2.md diff --git a/docs/spec/ibc/mvp3.md b/docs/spec/ibc/mvp/mvp3.md similarity index 100% rename from docs/spec/ibc/mvp3.md rename to docs/spec/ibc/mvp/mvp3.md