From 5b2a5c948ce6142ec2262886aafdc2a6a982cc54 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 24 May 2018 18:00:59 -0400 Subject: [PATCH 01/89] update to tm v0.19.6 --- CHANGELOG.md | 6 ++++++ Gopkg.lock | 20 ++++++++++---------- Gopkg.toml | 4 ++-- version/version.go | 4 ++-- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b0853dc0..1075450e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.17.3 + +*May 29, 2018* + +Update to Tendermint v0.19.6 (fix fast-sync halt) + ## 0.17.2 *May 20, 2018* diff --git a/Gopkg.lock b/Gopkg.lock index 37a32820c..3216a0f79 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -11,7 +11,7 @@ branch = "master" name = "github.com/btcsuite/btcd" packages = ["btcec"] - revision = "1432d294a5b055c297457c25434efbf13384cc46" + revision = "bc0944904505aab55e089371a892be2f87883161" [[projects]] name = "github.com/davecgh/go-spew" @@ -250,7 +250,7 @@ "leveldb/table", "leveldb/util" ] - revision = "e6d6b529196422703d54ff5c40e79809ec2020b3" + revision = "5d6fca44a948d2be89a9702de7717f0168403d3d" [[projects]] name = "github.com/tendermint/abci" @@ -341,8 +341,8 @@ "types/priv_validator", "version" ] - revision = "018e096748bafe1d2d1e69b909e4158f3b26f6b2" - version = "v0.19.5-rc1" + revision = "fd6021876b017cbf45cdf6dd55a0d6cdf431e826" + version = "v0.19.6-rc2" [[projects]] name = "github.com/tendermint/tmlibs" @@ -359,8 +359,8 @@ "pubsub", "pubsub/query" ] - revision = "cc5f287c4798ffe88c04d02df219ecb6932080fd" - version = "v0.8.3-rc0" + revision = "d970af87248a4e162590300dbb74e102183a417d" + version = "v0.8.3" [[projects]] branch = "master" @@ -376,7 +376,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "1a580b3eff7814fc9b40602fd35256c63b50f491" + revision = "ab813273cd59e1333f7ae7bff5d027d4aadf528c" [[projects]] branch = "master" @@ -390,13 +390,13 @@ "internal/timeseries", "trace" ] - revision = "57065200b4b034a1c8ad54ff77069408c2218ae6" + revision = "dfa909b99c79129e1100513e5cd36307665e5723" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "7c87d13f8e835d2fb3a70a2912c811ed0c1d241b" + revision = "c11f84a56e43e20a78cee75a7c034031ecf57d1f" [[projects]] name = "golang.org/x/text" @@ -457,6 +457,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "7540d2ecdb5d7d5084ab4e6132e929bbd501bd6add3006d8f08a6b2c127e0c7d" + inputs-digest = "2e868c5ad771cb647fd85a357375c559287602e886b7a040ddde0fac7f4f3365" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 5480bc03f..3a7ee9cfc 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -66,7 +66,7 @@ [[constraint]] name = "github.com/tendermint/go-amino" - version = "~0.9.9" + version = "=0.9.9" [[constraint]] name = "github.com/tendermint/iavl" @@ -74,7 +74,7 @@ [[constraint]] name = "github.com/tendermint/tendermint" - version = "0.19.5-rc1" + version = "0.19.6-rc2" [[override]] name = "github.com/tendermint/tmlibs" diff --git a/version/version.go b/version/version.go index ea365bda9..ae9433bcd 100644 --- a/version/version.go +++ b/version/version.go @@ -7,9 +7,9 @@ package version const Maj = "0" const Min = "17" -const Fix = "2" +const Fix = "3" -const Version = "0.17.2" +const Version = "0.17.3" // GitCommit set by build flags var GitCommit = "" From 36b3e530abb706c85f5373116d80850972c58324 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Thu, 31 May 2018 09:31:42 -0400 Subject: [PATCH 02/89] update tm to 0.17.4 --- CHANGELOG.md | 6 ++++++ Gopkg.lock | 17 +++++++++-------- Gopkg.toml | 2 +- version/version.go | 4 ++-- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1075450e2..271be8fb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.17.4 + +*May 31, 2018* + +Update to Tendermint v0.19.7 (WAL fixes and more) + ## 0.17.3 *May 29, 2018* diff --git a/Gopkg.lock b/Gopkg.lock index 3216a0f79..3873b9155 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -11,7 +11,7 @@ branch = "master" name = "github.com/btcsuite/btcd" packages = ["btcec"] - revision = "bc0944904505aab55e089371a892be2f87883161" + revision = "86fed781132ac890ee03e906e4ecd5d6fa180c64" [[projects]] name = "github.com/davecgh/go-spew" @@ -313,6 +313,9 @@ "consensus", "consensus/types", "evidence", + "libs/events", + "libs/pubsub", + "libs/pubsub/query", "lite", "lite/client", "lite/errors", @@ -341,8 +344,8 @@ "types/priv_validator", "version" ] - revision = "fd6021876b017cbf45cdf6dd55a0d6cdf431e826" - version = "v0.19.6-rc2" + revision = "a017f2fdd41496a81e04a2216630a405189da6e2" + version = "v0.19.7-rc0" [[projects]] name = "github.com/tendermint/tmlibs" @@ -355,9 +358,7 @@ "db", "flowrate", "log", - "merkle", - "pubsub", - "pubsub/query" + "merkle" ] revision = "d970af87248a4e162590300dbb74e102183a417d" version = "v0.8.3" @@ -390,7 +391,7 @@ "internal/timeseries", "trace" ] - revision = "dfa909b99c79129e1100513e5cd36307665e5723" + revision = "1e491301e022f8f977054da4c2d852decd59571f" [[projects]] branch = "master" @@ -457,6 +458,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "2e868c5ad771cb647fd85a357375c559287602e886b7a040ddde0fac7f4f3365" + inputs-digest = "a3a75136fb6921c4c4d413e4c8366f203b77367762763c97b8669ea854fbd62d" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 3a7ee9cfc..b8838920a 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -74,7 +74,7 @@ [[constraint]] name = "github.com/tendermint/tendermint" - version = "0.19.6-rc2" + version = "0.19.7-rc0" [[override]] name = "github.com/tendermint/tmlibs" diff --git a/version/version.go b/version/version.go index ae9433bcd..0871aee00 100644 --- a/version/version.go +++ b/version/version.go @@ -7,9 +7,9 @@ package version const Maj = "0" const Min = "17" -const Fix = "3" +const Fix = "4" -const Version = "0.17.3" +const Version = "0.17.4" // GitCommit set by build flags var GitCommit = "" From 7b4c632066459795f8ff39ca52a71723b40a47e5 Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Fri, 1 Jun 2018 10:51:38 +0100 Subject: [PATCH 03/89] autogenerate testaddrs func created --- x/stake/keeper_test.go | 4 ++-- x/stake/test_common.go | 34 ++++++++++++++++++++++++++++++++++ x/stake/tick.go | 6 +++--- x/stake/tick_test.go | 2 +- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index f28a2cf68..6e232d4f9 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -115,8 +115,8 @@ func TestValidatorBasics(t *testing.T) { resVals = keeper.GetValidatorsBonded(ctx) require.Equal(t, 3, len(resVals)) - assert.True(ValEq(t, validators[0], resVals[2])) // order doesn't matter here - assert.True(ValEq(t, validators[1], resVals[0])) + assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here + assert.True(ValEq(t, validators[1], resVals[2])) assert.True(ValEq(t, validators[2], resVals[1])) // remove a record diff --git a/x/stake/test_common.go b/x/stake/test_common.go index bf3e66551..2c5785910 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -3,6 +3,7 @@ package stake import ( "bytes" "encoding/hex" + "strconv" "testing" "github.com/stretchr/testify/require" @@ -162,3 +163,36 @@ func testAddr(addr string, bech string) sdk.Address { return res } + +func createTestAddrs(numAddrs int) []sdk.Address { + var addresses []sdk.Address + var buffer bytes.Buffer + + //start at 10 to avoid changing 1 to 01, 2 to 02, etc + for i := 10; i < numAddrs; i++ { + numString := strconv.Itoa(i) + buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA61") //base address string + + buffer.WriteString(numString) //adding on final two digits to make addresses unique + res, _ := sdk.GetAccAddressHex(buffer.String()) + bech, _ := sdk.Bech32CosmosifyAcc(res) + addresses = append(addresses, testAddr(buffer.String(), bech)) + buffer.Reset() + } + return addresses +} + +func createTestPubKeys(numPubKeys int) []crypto.PubKey { + var publicKeys []crypto.PubKey + var buffer bytes.Buffer + + //start at 10 to avoid changing 1 to 01, 2 to 02, etc + for i := 10; i < numPubKeys; i++ { + numString := strconv.Itoa(i) + buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB") //base pubkey string + buffer.WriteString(numString) //adding on final two digits to make pubkeys unique + publicKeys = append(publicKeys, newPubKey(buffer.String())) + buffer.Reset() + } + return publicKeys +} diff --git a/x/stake/tick.go b/x/stake/tick.go index a8d945734..70076c691 100644 --- a/x/stake/tick.go +++ b/x/stake/tick.go @@ -6,8 +6,8 @@ import ( ) const ( - hrsPerYr = 8766 // as defined by a julian year of 365.25 days - precision = 1000000000 + hrsPerYr = 8766 // as defined by a julian year of 365.25 days + precision = 100000000000 // increased to this precision for accuracy with tests on tick_test.go ) var hrsPerYrRat = sdk.NewRat(hrsPerYr) // as defined by a julian year of 365.25 days @@ -57,7 +57,7 @@ func (k Keeper) nextInflation(ctx sdk.Context) (inflation sdk.Rat) { params := k.GetParams(ctx) pool := k.GetPool(ctx) // The target annual inflation rate is recalculated for each previsions cycle. The - // inflation is also subject to a rate change (positive of negative) depending or + // inflation is also subject to a rate change (positive or negative) depending on // the distance from the desired ratio (67%). The maximum rate change possible is // defined to be 13% per year, however the annual inflation is capped as between // 7% and 20%. diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index 4f0f6dc06..6be3cd59f 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -112,7 +112,7 @@ func TestProcessProvisions(t *testing.T) { // process the provisions a year for hr := 0; hr < 8766; hr++ { pool := keeper.GetPool(ctx) - expInflation := keeper.nextInflation(ctx).Round(1000000000) + expInflation := keeper.nextInflation(ctx) expProvisions := (expInflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat)).Evaluate() startBondedTokens := pool.BondedTokens startTotalSupply := pool.TokenSupply() From 424ce545ef408aad80b1fb96eb153aa64d41a4f0 Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Fri, 1 Jun 2018 11:39:23 +0100 Subject: [PATCH 04/89] autogen addr func updated for 999 addrs if needed --- x/stake/keeper_test.go | 6 +++--- x/stake/test_common.go | 41 ++++++++------------------------------- x/stake/validator_test.go | 8 ++++---- 3 files changed, 15 insertions(+), 40 deletions(-) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 6e232d4f9..0e62f0936 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -115,9 +115,9 @@ func TestValidatorBasics(t *testing.T) { resVals = keeper.GetValidatorsBonded(ctx) require.Equal(t, 3, len(resVals)) - assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here - assert.True(ValEq(t, validators[1], resVals[2])) - assert.True(ValEq(t, validators[2], resVals[1])) + assert.True(ValEq(t, validators[0], resVals[2])) // order doesn't matter here + assert.True(ValEq(t, validators[1], resVals[1])) + assert.True(ValEq(t, validators[2], resVals[0])) // remove a record keeper.removeValidator(ctx, validators[1].Owner) diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 2c5785910..109112086 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -22,33 +22,8 @@ import ( // dummy addresses used for testing var ( - addrs = []sdk.Address{ - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctqyxjnwh"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctpesxxn9"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6162", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctzhrnsa6"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6163", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctr2489qg"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6164", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctytvs4pd"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6165", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ct9k6yqul"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6166", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctxcf3kjq"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6167", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ct89l9r0j"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6168", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctg6jkls2"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6169", "cosmosaccaddr:5ky9du8a2wlstz6fpx3p4mqpjyrm5ctf8yz2dc"), - } - - // dummy pubkeys used for testing - pks = []crypto.PubKey{ - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB50"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB51"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB52"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB53"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB54"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB55"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB56"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB57"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB58"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB59"), - } - + addrs = createTestAddrs(100) + pks = createTestPubKeys(100) emptyAddr sdk.Address emptyPubkey crypto.PubKey ) @@ -168,10 +143,10 @@ func createTestAddrs(numAddrs int) []sdk.Address { var addresses []sdk.Address var buffer bytes.Buffer - //start at 10 to avoid changing 1 to 01, 2 to 02, etc - for i := 10; i < numAddrs; i++ { + // start at 100 so we can make up to 999 test addresses with valid test addresses + for i := 100; i < (numAddrs + 100); i++ { numString := strconv.Itoa(i) - buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA61") //base address string + buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string buffer.WriteString(numString) //adding on final two digits to make addresses unique res, _ := sdk.GetAccAddressHex(buffer.String()) @@ -187,10 +162,10 @@ func createTestPubKeys(numPubKeys int) []crypto.PubKey { var buffer bytes.Buffer //start at 10 to avoid changing 1 to 01, 2 to 02, etc - for i := 10; i < numPubKeys; i++ { + for i := 100; i < (numPubKeys + 100); i++ { numString := strconv.Itoa(i) - buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB") //base pubkey string - buffer.WriteString(numString) //adding on final two digits to make pubkeys unique + buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") //base pubkey string + buffer.WriteString(numString) //adding on final two digits to make pubkeys unique publicKeys = append(publicKeys, newPubKey(buffer.String())) buffer.Reset() } diff --git a/x/stake/validator_test.go b/x/stake/validator_test.go index 1ca5ba2f7..98a82d1dc 100644 --- a/x/stake/validator_test.go +++ b/x/stake/validator_test.go @@ -148,7 +148,7 @@ func TestUpdateStatus(t *testing.T) { // TODO refactor this random setup // generate a random validator -func randomValidator(r *rand.Rand) Validator { +func randomValidator(r *rand.Rand, i int) Validator { poolSharesAmt := sdk.NewRat(int64(r.Int31n(10000))) delShares := sdk.NewRat(int64(r.Int31n(10000))) @@ -160,8 +160,8 @@ func randomValidator(r *rand.Rand) Validator { pShares = NewUnbondedShares(poolSharesAmt) } return Validator{ - Owner: addrs[0], - PubKey: pks[0], + Owner: addrs[i], + PubKey: pks[i], PoolShares: pShares, DelegatorShares: delShares, } @@ -173,7 +173,7 @@ func randomSetup(r *rand.Rand, numValidators int) (Pool, Validators) { validators := make([]Validator, numValidators) for i := 0; i < numValidators; i++ { - validator := randomValidator(r) + validator := randomValidator(r, i) if validator.Status() == sdk.Bonded { pool.BondedShares = pool.BondedShares.Add(validator.PoolShares.Bonded()) pool.BondedTokens += validator.PoolShares.Bonded().Evaluate() From f3f2729b117677977ce6740813d0d737e238d848 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 5 Jun 2018 18:04:16 -0700 Subject: [PATCH 05/89] update for tm v0.19.9 --- CHANGELOG.md | 7 +++++++ Gopkg.lock | 18 +++++++++--------- Gopkg.toml | 4 ++-- client/lcd/lcd_test.go | 2 +- server/init.go | 2 +- server/start.go | 2 +- server/tm_cmds.go | 2 +- version/version.go | 4 ++-- 8 files changed, 24 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 271be8fb9..c017ca91a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.17.5 + +*June 5, 2018* + +Update to Tendermint v0.19.9 (Fix evidence reactor, mempool deadlock, WAL panic, +memory leak) + ## 0.17.4 *May 31, 2018* diff --git a/Gopkg.lock b/Gopkg.lock index 3873b9155..a08427042 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -164,8 +164,8 @@ [[projects]] name = "github.com/pelletier/go-toml" packages = ["."] - revision = "acdc4509485b587f5e675510c4f2c63e90ff68a8" - version = "v1.1.0" + revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" + version = "v1.2.0" [[projects]] name = "github.com/pkg/errors" @@ -327,6 +327,7 @@ "p2p/conn", "p2p/pex", "p2p/upnp", + "privval", "proxy", "rpc/client", "rpc/core", @@ -341,11 +342,10 @@ "state/txindex/kv", "state/txindex/null", "types", - "types/priv_validator", "version" ] - revision = "a017f2fdd41496a81e04a2216630a405189da6e2" - version = "v0.19.7-rc0" + revision = "775fef31c2b8fb7ea36f0d57bae3bfa74d353100" + version = "v0.19.9-rc0" [[projects]] name = "github.com/tendermint/tmlibs" @@ -360,8 +360,8 @@ "log", "merkle" ] - revision = "d970af87248a4e162590300dbb74e102183a417d" - version = "v0.8.3" + revision = "692f1d86a6e2c0efa698fd1e4541b68c74ffaf38" + version = "v0.8.4" [[projects]] branch = "master" @@ -377,7 +377,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "ab813273cd59e1333f7ae7bff5d027d4aadf528c" + revision = "78e79280f680f7dd6b8e48c751887111ebdbcbd8" [[projects]] branch = "master" @@ -458,6 +458,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "a3a75136fb6921c4c4d413e4c8366f203b77367762763c97b8669ea854fbd62d" + inputs-digest = "71d11bd2a8f3f46ba3fd16759b501ad5b6b48037717d82020ebb25e021b67117" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index b8838920a..c25623bba 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -74,11 +74,11 @@ [[constraint]] name = "github.com/tendermint/tendermint" - version = "0.19.7-rc0" + version = "0.19.9-rc0" [[override]] name = "github.com/tendermint/tmlibs" - version = "~0.8.3-rc0" + version = "~0.8.4" # this got updated and broke, so locked to an old working commit ... [[override]] diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 66a8a4085..73f5ad2c5 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -24,7 +24,7 @@ import ( ctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmtypes "github.com/tendermint/tendermint/types" - pvm "github.com/tendermint/tendermint/types/priv_validator" + pvm "github.com/tendermint/tendermint/privval" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" diff --git a/server/init.go b/server/init.go index 68a1709bc..512751bed 100644 --- a/server/init.go +++ b/server/init.go @@ -20,7 +20,7 @@ import ( cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/p2p" tmtypes "github.com/tendermint/tendermint/types" - pvm "github.com/tendermint/tendermint/types/priv_validator" + pvm "github.com/tendermint/tendermint/privval" tmcli "github.com/tendermint/tmlibs/cli" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" diff --git a/server/start.go b/server/start.go index 23e38749b..9bf2d30cd 100644 --- a/server/start.go +++ b/server/start.go @@ -10,7 +10,7 @@ import ( 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" + pvm "github.com/tendermint/tendermint/privval" cmn "github.com/tendermint/tmlibs/common" ) diff --git a/server/tm_cmds.go b/server/tm_cmds.go index d581ca5f7..4d8edacab 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -11,7 +11,7 @@ import ( tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/p2p" - pvm "github.com/tendermint/tendermint/types/priv_validator" + pvm "github.com/tendermint/tendermint/privval" ) // ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout diff --git a/version/version.go b/version/version.go index 0871aee00..be9f7858b 100644 --- a/version/version.go +++ b/version/version.go @@ -7,9 +7,9 @@ package version const Maj = "0" const Min = "17" -const Fix = "4" +const Fix = "5" -const Version = "0.17.4" +const Version = "0.17.5" // GitCommit set by build flags var GitCommit = "" From 89d6264587f7e8216ed75d5a08b91b3e0cc49b8f Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Tue, 5 Jun 2018 23:02:31 -0400 Subject: [PATCH 06/89] simplified TestProcessProvisions into 4 repeatable funcs. fixed a small bug in it --- x/stake/tick_test.go | 165 +++++++++++++++++++++++++------------------ 1 file changed, 98 insertions(+), 67 deletions(-) diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index 6be3cd59f..1264814a7 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -61,80 +61,111 @@ func TestGetInflation(t *testing.T) { func TestProcessProvisions(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) - params := defaultParams() - params.MaxValidators = 2 - keeper.setParams(ctx, params) pool := keeper.GetPool(ctx) - var tokenSupply int64 = 550000000 - var bondedShares int64 = 150000000 - var unbondedShares int64 = 400000000 + var ( + initialTotalTokens int64 = 550000000 + initialBondedTokens int64 = 250000000 + initialUnbondedTokens int64 = 300000000 + cumulativeExpProvs int64 + initialBondedShares = sdk.NewRat(250000000, 1) + initialUnbondedShares = sdk.NewRat(300000000, 1) + tokensForValidators = []int64{150000000, 100000000, 100000000, 100000000, 100000000} + bondedValidators uint16 = 2 + ) // create some validators some bonded, some unbonded - var validators [5]Validator - validators[0] = NewValidator(addrs[0], pks[0], Description{}) - validators[0], pool, _ = validators[0].addTokensFromDel(pool, 150000000) - keeper.setPool(ctx, pool) - validators[0] = keeper.updateValidator(ctx, validators[0]) - pool = keeper.GetPool(ctx) - require.Equal(t, bondedShares, pool.BondedTokens, "%v", pool) + _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) + checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) - validators[1] = NewValidator(addrs[1], pks[1], Description{}) - validators[1], pool, _ = validators[1].addTokensFromDel(pool, 100000000) - keeper.setPool(ctx, pool) - validators[1] = keeper.updateValidator(ctx, validators[1]) - validators[2] = NewValidator(addrs[2], pks[2], Description{}) - validators[2], pool, _ = validators[2].addTokensFromDel(pool, 100000000) - keeper.setPool(ctx, pool) - validators[2] = keeper.updateValidator(ctx, validators[2]) - validators[3] = NewValidator(addrs[3], pks[3], Description{}) - validators[3], pool, _ = validators[3].addTokensFromDel(pool, 100000000) - keeper.setPool(ctx, pool) - validators[3] = keeper.updateValidator(ctx, validators[3]) - validators[4] = NewValidator(addrs[4], pks[4], Description{}) - validators[4], pool, _ = validators[4].addTokensFromDel(pool, 100000000) - keeper.setPool(ctx, pool) - validators[4] = keeper.updateValidator(ctx, validators[4]) - - assert.Equal(t, tokenSupply, pool.TokenSupply()) - assert.Equal(t, bondedShares, pool.BondedTokens) - assert.Equal(t, unbondedShares, pool.UnbondedTokens) - - // initial bonded ratio ~ 27% - assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(bondedShares, tokenSupply)), "%v", pool.bondedRatio()) - - // test the value of validator shares - assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate()) - - initialSupply := pool.TokenSupply() - initialUnbonded := pool.TokenSupply() - pool.BondedTokens - - // process the provisions a year + // process the provisions for a year for hr := 0; hr < 8766; hr++ { pool := keeper.GetPool(ctx) - expInflation := keeper.nextInflation(ctx) - expProvisions := (expInflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat)).Evaluate() - startBondedTokens := pool.BondedTokens - startTotalSupply := pool.TokenSupply() - pool = keeper.processProvisions(ctx) - keeper.setPool(ctx, pool) - //fmt.Printf("hr %v, startBondedTokens %v, expProvisions %v, pool.BondedTokens %v\n", hr, startBondedTokens, expProvisions, pool.BondedTokens) - require.Equal(t, startBondedTokens+expProvisions, pool.BondedTokens, "hr %v", hr) - require.Equal(t, startTotalSupply+expProvisions, pool.TokenSupply()) + _, expProvisions, _ := checkAndProcessProvisions(t, keeper, pool, ctx, hr) + cumulativeExpProvs = cumulativeExpProvs + expProvisions } + + //get the pool and do the final value checks from checkFinalPoolValues pool = keeper.GetPool(ctx) - assert.NotEqual(t, initialSupply, pool.TokenSupply()) - assert.Equal(t, initialUnbonded, pool.UnbondedTokens) - //panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", p.TotalSupply, p.BondedTokens, pool.TokenSupply()-pool.BondedTokens)) - - // initial bonded ratio ~ from 27% to 40% increase for bonded holders ownership of total supply - assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(211813022, 611813022)), "%v", pool.bondedRatio()) - - // global supply - assert.Equal(t, int64(611813022), pool.TokenSupply()) - assert.Equal(t, int64(211813022), pool.BondedTokens) - assert.Equal(t, unbondedShares, pool.UnbondedTokens) - - // test the value of validator shares - assert.True(t, pool.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(211813022)), "%v", pool.bondedShareExRate()) + checkFinalPoolValues(t, pool, initialTotalTokens, + initialUnbondedTokens, cumulativeExpProvs, + 0, 0, initialBondedShares, initialUnbondedShares) +} + +////////////////////////////////HELPER FUNCTIONS BELOW///////////////////////////////////// + +// Final check on the global pool values for what the total tokens accumulated from each hour of provisions and other functions +// bondedAdjustment and unbondedAdjustment are the accumulated changes for the operations of the test (i.e. if three unbonds happened, their total value would be passed as unbondedAdjustment) +func checkFinalPoolValues(t *testing.T, pool Pool, initialTotalTokens, initialUnbondedTokens, + cumulativeExpProvs, bondedAdjustment, unbondedAdjustment int64, bondedShares, unbondedShares sdk.Rat) { + + initialBonded := initialTotalTokens - initialUnbondedTokens + calculatedTotalTokens := initialTotalTokens + cumulativeExpProvs + calculatedBondedTokens := initialBonded + cumulativeExpProvs + bondedAdjustment + calculatedUnbondedTokens := initialUnbondedTokens + unbondedAdjustment + + // test that the bonded ratio the pool has is equal to what we calculated for tokens + assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(calculatedBondedTokens, calculatedTotalTokens)), "%v", pool.bondedRatio()) + + // test global supply + assert.Equal(t, calculatedTotalTokens, pool.TokenSupply()) + assert.Equal(t, calculatedBondedTokens, pool.BondedTokens) + assert.Equal(t, calculatedUnbondedTokens, pool.UnbondedTokens) + + // test the value of candidate shares + assert.True(t, pool.bondedShareExRate().Mul(bondedShares).Equal(sdk.NewRat(calculatedBondedTokens)), "%v", pool.bondedShareExRate()) + assert.True(t, pool.unbondedShareExRate().Mul(unbondedShares).Equal(sdk.NewRat(calculatedUnbondedTokens)), "%v", pool.unbondedShareExRate()) +} + +// Checks provisions are added to the pool correctly every hour +// Returns expected Provisions, expected Inflation, and pool, to help with cumulative calculations back in main Tests +func checkAndProcessProvisions(t *testing.T, keeper Keeper, pool Pool, ctx sdk.Context, hr int) (sdk.Rat, int64, Pool) { + + //If we are not doing a random operation, just check that normal provisions are working for each hour + expInflation := keeper.nextInflation(ctx) + expProvisions := (expInflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat)).Evaluate() + startBondedPool := pool.BondedTokens + startTotalSupply := pool.TokenSupply() + pool = keeper.processProvisions(ctx) + keeper.setPool(ctx, pool) + + //check provisions were added to pool + require.Equal(t, startBondedPool+expProvisions, pool.BondedTokens, "hr %v", hr) + require.Equal(t, startTotalSupply+expProvisions, pool.TokenSupply()) + + return expInflation, expProvisions, pool +} + +// Deterministic setup of validators, which updates the pool and choose maxValidators to be bonded +// Allows you to decide how many validators to setup, and which ones you want bonded +// You choose bonded validators by setting params.MaxValidators. If you choose 2, the first 2 Validators in the arrray will be bonded, the rest unbonded +func setupTestValidators(pool Pool, keeper Keeper, ctx sdk.Context, validatorTokens []int64, maxValidators uint16) ([]Validator, Keeper, Pool) { + params := defaultParams() + params.MaxValidators = maxValidators //set to limit the amount of validators we want bonded + keeper.setParams(ctx, params) + numValidators := len(validatorTokens) + validators := make([]Validator, numValidators) + + for i := 0; i < numValidators; i++ { + validators[i] = NewValidator(addrs[i], pks[i], Description{}) + validators[i], pool, _ = validators[i].addTokensFromDel(pool, validatorTokens[i]) + keeper.setPool(ctx, pool) + validators[i] = keeper.updateValidator(ctx, validators[i]) + pool = keeper.GetPool(ctx) + } + + return validators, keeper, pool +} + +// Checks that the deterministic candidate setup you wanted matches the values in the pool +func checkValidatorSetup(t *testing.T, pool Pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens int64) { + + assert.Equal(t, initialTotalTokens, pool.TokenSupply()) + assert.Equal(t, initialBondedTokens, pool.BondedTokens) + assert.Equal(t, initialUnbondedTokens, pool.UnbondedTokens) + + // test initial bonded ratio + assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(initialBondedTokens, initialTotalTokens)), "%v", pool.bondedRatio()) + // test the value of candidate shares + assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate()) } From 8d470e5410a04c374c38adbeee537316212d30d1 Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Tue, 5 Jun 2018 23:12:28 -0400 Subject: [PATCH 07/89] TestHourlyInflationRateOfChange() added, checks 11.4 years of inflation --- x/stake/tick_test.go | 77 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index 1264814a7..6bed352f5 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -1,6 +1,7 @@ package stake import ( + "strconv" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -92,6 +93,47 @@ func TestProcessProvisions(t *testing.T) { 0, 0, initialBondedShares, initialUnbondedShares) } +// Tests that the hourly rate of change will be positive, negative, or zero, depending on bonded ratio and inflation rate +// Cycles through the whole gambit of starting at 7% inflation, up to 20%, back down to 7% (it takes ~11.4 years) +func TestHourlyInflationRateOfChange(t *testing.T) { + ctx, _, keeper := createTestInput(t, false, 0) + // params := defaultParams() + // keeper.setParams(ctx, params) + pool := keeper.GetPool(ctx) + + // test setUpCandidates returned the token values by passing these vars into checkCandidateSetup() + var ( + initialTotalTokens int64 = 550000000 + initialBondedTokens int64 = 150000000 + initialUnbondedTokens int64 = 400000000 + cumulativeExpProvs int64 + bondedShares = sdk.NewRat(150000000, 1) + unbondedShares = sdk.NewRat(400000000, 1) + tokensForValidators = []int64{150000000, 100000000, 100000000, 100000000, 100000000} + bondedValidators uint16 = 1 + ) + + // create some candidates some bonded, some unbonded + _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) + checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) + + // ~11.4 years to go from 7%, up to 20%, back down to 7% + for hr := 0; hr < 100000; hr++ { + pool := keeper.GetPool(ctx) + previousInflation := pool.Inflation + updatedInflation, expProvisions, pool := checkAndProcessProvisions(t, keeper, pool, ctx, hr) + cumulativeExpProvs = cumulativeExpProvs + expProvisions + msg := strconv.Itoa(hr) + checkInflation(t, pool, previousInflation, updatedInflation, msg) + } + + // Final check that the pool equals initial values + cumulative provisions and adjustments we recorded + pool = keeper.GetPool(ctx) + checkFinalPoolValues(t, pool, initialTotalTokens, + initialUnbondedTokens, cumulativeExpProvs, + 0, 0, bondedShares, unbondedShares) +} + ////////////////////////////////HELPER FUNCTIONS BELOW///////////////////////////////////// // Final check on the global pool values for what the total tokens accumulated from each hour of provisions and other functions @@ -169,3 +211,38 @@ func checkValidatorSetup(t *testing.T, pool Pool, initialTotalTokens, initialBon // test the value of candidate shares assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate()) } + +// Checks that The inflation will correctly increase or decrease after an update to the pool +func checkInflation(t *testing.T, pool Pool, previousInflation, updatedInflation sdk.Rat, msg string) { + + inflationChange := updatedInflation.Sub(previousInflation) + + switch { + //BELOW 67% - Rate of change positive and increasing, while we are between 7% <= and < 20% inflation + case pool.bondedRatio().LT(sdk.NewRat(67, 100)) && updatedInflation.LT(sdk.NewRat(20, 100)): + assert.Equal(t, true, inflationChange.GT(sdk.ZeroRat()), msg) + + //BELOW 67% - Rate of change should be 0 while inflation continually stays at 20% until we reach 67% bonded ratio + case pool.bondedRatio().LT(sdk.NewRat(67, 100)) && updatedInflation.Equal(sdk.NewRat(20, 100)): + if previousInflation.Equal(sdk.NewRat(20, 100)) { + assert.Equal(t, true, inflationChange.IsZero(), msg) + //This else statement covers the one off case where we first hit 20%, but we still needed a positive ROC to get to 67% bonded ratio (i.e. we went from 19.99999% to 20%) + } else { + assert.Equal(t, true, inflationChange.GT(sdk.ZeroRat()), msg) + } + + //ABOVE 67% - Rate of change should be negative while the bond is above 67, and should stay negative until we reach inflation of 7% + case pool.bondedRatio().GT(sdk.NewRat(67, 100)) && updatedInflation.LT(sdk.NewRat(20, 100)) && updatedInflation.GT(sdk.NewRat(7, 100)): + assert.Equal(t, true, inflationChange.LT(sdk.ZeroRat()), msg) + + //ABOVE 67% - Rate of change should be 0 while inflation continually stays at 7%. + case pool.bondedRatio().GT(sdk.NewRat(67, 100)) && updatedInflation.Equal(sdk.NewRat(7, 100)): + if previousInflation.Equal(sdk.NewRat(7, 100)) { + assert.Equal(t, true, inflationChange.IsZero(), msg) + //This else statement covers the one off case where we first hit 7%, but we still needed a negative ROC to continue to get down to 67%. (i.e. we went from 7.00001% to 7%) + } else { + assert.Equal(t, true, inflationChange.LT(sdk.ZeroRat()), msg) + } + } + +} From af15f89531600b89f807399420b5ede83833efe5 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Tue, 5 Jun 2018 21:34:19 -0700 Subject: [PATCH 08/89] Update changelog for 0.18.0 (#1149) --- CHANGELOG.md | 72 +++++++++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22969a403..cf2ac21b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,49 +1,8 @@ # Changelog -## Pending - -BREAKING CHANGES -* [cli] rearranged commands under subcommands -* [stake] remove Tick and add EndBlocker - -FEATURES - -IMPROVEMENTS -* bank module uses go-wire codec instead of 'encoding/json' -* auth module uses go-wire codec instead of 'encoding/json' -* revised use of endblock and beginblock - -FIXES -* [cli] fixed cli-bash tests -* [ci] added cli-bash tests -* [basecoin] updated basecoin for stake and slashing -* [docs] fixed references to old cli commands - -## 0.18.1 - -BREAKING CHANGES - -* [x/auth] move stuff specific to auth anteHandler to the auth module rather than the types folder. This includes: - * StdTx (and its related stuff i.e. StdSignDoc, etc) - * StdFee - * StdSignature - * Account interface - * Related to this organization, I also: -* [x/auth] got rid of AccountMapper interface (in favor of the struct already in auth module) -* [x/auth] removed the FeeHandler function from the AnteHandler, Replaced with FeeKeeper -* [x/auth] Removed GetSignatures() from Tx interface (as different Tx styles might use something different than StdSignature) -* [store] Removed SubspaceIterator and ReverseSubspaceIterator from KVStore interface and replaced them with helper functions in /types -* Switch to bech32cosmos on all human readable inputs and outputs - -BUG FIXES - -* auto-sequencing transactions correctly -* query sequence via account store -* fixed duplicate pub_key in stake.Validator - ## 0.18.0 -_TBD_ +_2018-06-05_ BREAKING CHANGES @@ -62,6 +21,20 @@ BREAKING CHANGES * Introduction of Unbonding fields, lowlevel logic throughout (not fully implemented with queue) * Introduction of PoolShares type within validators, replaces three rational fields (BondedShares, UnbondingShares, UnbondedShares +* [x/auth] move stuff specific to auth anteHandler to the auth module rather than the types folder. This includes: + * StdTx (and its related stuff i.e. StdSignDoc, etc) + * StdFee + * StdSignature + * Account interface + * Related to this organization, I also: +* [x/auth] got rid of AccountMapper interface (in favor of the struct already in auth module) +* [x/auth] removed the FeeHandler function from the AnteHandler, Replaced with FeeKeeper +* [x/auth] Removed GetSignatures() from Tx interface (as different Tx styles might use something different than StdSignature) +* [store] Removed SubspaceIterator and ReverseSubspaceIterator from KVStore interface and replaced them with helper functions in /types +* [cli] rearranged commands under subcommands +* [stake] remove Tick and add EndBlocker +* Switch to bech32cosmos on all human readable inputs and outputs + FEATURES @@ -78,12 +51,22 @@ FEATURES * [stake] Added REST API * [Makefile] Added terraform/ansible playbooks to easily create remote testnets on Digital Ocean + BUG FIXES -* Auto-sequencing now works correctly * [stake] staking delegator shares exchange rate now relative to equivalent-bonded-tokens the validator has instead of bonded tokens ^ this is important for unbonded validators in the power store! +* [cli] fixed cli-bash tests +* [ci] added cli-bash tests +* [basecoin] updated basecoin for stake and slashing +* [docs] fixed references to old cli commands * [docs] Downgraded Swagger to v2 for downstream compatibility +* auto-sequencing transactions correctly +* query sequence via account store +* fixed duplicate pub_key in stake.Validator +* Auto-sequencing now works correctly + + ## 0.17.2 @@ -123,6 +106,7 @@ BUG FIXES * Auto-sequencing now works correctly + ## 0.16.0 (May 14th, 2018) BREAKING CHANGES @@ -157,12 +141,14 @@ BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia + ## 0.15.1 (April 29, 2018) IMPROVEMENTS: * Update Tendermint to v0.19.1 (includes many rpc fixes) + ## 0.15.0 (April 29, 2018) NOTE: v0.15.0 is a large breaking change that updates the encoding scheme to use From 5f409ce83247cce37ef34adeff2503f11a1903ee Mon Sep 17 00:00:00 2001 From: Fabian Date: Wed, 6 Jun 2018 06:53:04 +0200 Subject: [PATCH 09/89] Merge PR #1086: Bech32Cosmos output/input for the LCD * refactored bech32ization * updated keys endpoints for bech32 * bech32 for sending and querying * trying to change output of validator addresses * fixed validator output * linted * fixed merge conflict * added bech32 to staking endpoints * removed some logging statements * added GetAccPubKeyBech32Cosmos * fixed cli tests * updated swagger * merged standard bech32 change * renamed bech32cosmos to bech32 * bech32ify json output for key add * readded changelog * fixed changelog merge issue * Update CHANGELOG.md --- CHANGELOG.md | 4 ++ client/keys/add.go | 11 ++--- client/keys/list.go | 9 ++-- client/keys/show.go | 8 +++- client/keys/utils.go | 64 +++++++++++++++++------------ client/lcd/lcd_test.go | 69 +++++++++++++++++-------------- client/rpc/validators.go | 50 ++++++++++++++++++++++- cmd/gaia/cli_test/cli_test.go | 8 +++- docs/sdk/lcd-rest-api.yaml | 77 ++++++++++++++++++----------------- types/account.go | 17 +++++++- x/auth/client/rest/query.go | 8 ++-- x/bank/client/rest/sendtx.go | 11 ++++- x/ibc/client/rest/transfer.go | 11 ++++- x/stake/client/rest/query.go | 75 ++++++++++++++++++++++++++++++---- x/stake/client/rest/tx.go | 64 ++++++++++++++++++++++++----- 15 files changed, 348 insertions(+), 138 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf2ac21b0..731f3c14a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +BREAKING CHANGES + +* [lcd] Switch to bech32 for addresses on all human readable inputs and outputs + ## 0.18.0 _2018-06-05_ diff --git a/client/keys/add.go b/client/keys/add.go index da368a3a6..7ad9474ce 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -102,12 +102,6 @@ func runAddCmd(cmd *cobra.Command, args []string) error { return nil } -// addOutput lets us json format the data -type addOutput struct { - Key keys.Info `json:"key"` - Seed string `json:"seed"` -} - func printCreate(info keys.Info, seed string) { output := viper.Get(cli.OutputFlag) switch output { @@ -121,7 +115,10 @@ func printCreate(info keys.Info, seed string) { fmt.Println(seed) } case "json": - out := addOutput{Key: info} + out, err := Bech32KeyOutput(info) + if err != nil { + panic(err) + } if !viper.GetBool(flagNoBackup) { out.Seed = seed } diff --git a/client/keys/list.go b/client/keys/list.go index 9af511e5c..22f163f1d 100644 --- a/client/keys/list.go +++ b/client/keys/list.go @@ -4,7 +4,6 @@ import ( "encoding/json" "net/http" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" ) @@ -54,9 +53,11 @@ func QueryKeysRequestHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("[]")) return } - keysOutput := make([]KeyOutput, len(infos)) - for i, info := range infos { - keysOutput[i] = KeyOutput{Name: info.Name, Address: sdk.Address(info.PubKey.Address().Bytes())} + keysOutput, err := Bech32KeysOutput(infos) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return } output, err := json.MarshalIndent(keysOutput, "", " ") if err != nil { diff --git a/client/keys/show.go b/client/keys/show.go index c7be9cc9d..9051aba16 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -4,7 +4,6 @@ import ( "encoding/json" "net/http" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gorilla/mux" keys "github.com/tendermint/go-crypto/keys" @@ -51,7 +50,12 @@ func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) { return } - keyOutput := KeyOutput{Name: info.Name, Address: sdk.Address(info.PubKey.Address())} + keyOutput, err := Bech32KeyOutput(info) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } output, err := json.MarshalIndent(keyOutput, "", " ") if err != nil { w.WriteHeader(500) diff --git a/client/keys/utils.go b/client/keys/utils.go index 1c1fd0979..d810dfa1f 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -6,7 +6,6 @@ import ( "github.com/spf13/viper" - crypto "github.com/tendermint/go-crypto" keys "github.com/tendermint/go-crypto/keys" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" @@ -47,29 +46,47 @@ func SetKeyBase(kb keys.Keybase) { // used for outputting keys.Info over REST type KeyOutput struct { - Name string `json:"name"` - Address sdk.Address `json:"address"` - PubKey crypto.PubKey `json:"pub_key"` + Name string `json:"name"` + Address string `json:"address"` + PubKey string `json:"pub_key"` + Seed string `json:"seed,omitempty"` } -func NewKeyOutput(info keys.Info) KeyOutput { - return KeyOutput{ - Name: info.Name, - Address: sdk.Address(info.PubKey.Address().Bytes()), - PubKey: info.PubKey, - } -} - -func NewKeyOutputs(infos []keys.Info) []KeyOutput { +// create a list of KeyOutput in bech32 format +func Bech32KeysOutput(infos []keys.Info) ([]KeyOutput, error) { kos := make([]KeyOutput, len(infos)) for i, info := range infos { - kos[i] = NewKeyOutput(info) + ko, err := Bech32KeyOutput(info) + if err != nil { + return nil, err + } + kos[i] = ko } - return kos + return kos, nil +} + +// create a KeyOutput in bech32 format +func Bech32KeyOutput(info keys.Info) (KeyOutput, error) { + bechAccount, err := sdk.Bech32ifyAcc(sdk.Address(info.PubKey.Address().Bytes())) + if err != nil { + return KeyOutput{}, err + } + bechPubKey, err := sdk.Bech32ifyAccPub(info.PubKey) + if err != nil { + return KeyOutput{}, err + } + return KeyOutput{ + Name: info.Name, + Address: bechAccount, + PubKey: bechPubKey, + }, nil } func printInfo(info keys.Info) { - ko := NewKeyOutput(info) + ko, err := Bech32KeyOutput(info) + if err != nil { + panic(err) + } switch viper.Get(cli.OutputFlag) { case "text": fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n") @@ -84,7 +101,10 @@ func printInfo(info keys.Info) { } func printInfos(infos []keys.Info) { - kos := NewKeyOutputs(infos) + kos, err := Bech32KeysOutput(infos) + if err != nil { + panic(err) + } switch viper.Get(cli.OutputFlag) { case "text": fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n") @@ -101,13 +121,5 @@ func printInfos(infos []keys.Info) { } func printKeyOutput(ko KeyOutput) { - bechAccount, err := sdk.Bech32ifyAcc(ko.Address) - if err != nil { - panic(err) - } - bechPubKey, err := sdk.Bech32ifyAccPub(ko.PubKey) - if err != nil { - panic(err) - } - fmt.Printf("%s\t%s\t%s\n", ko.Name, bechAccount, bechPubKey) + fmt.Printf("%s\t%s\t%s\n", ko.Name, ko.Address, ko.PubKey) } diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 7a9cdbc25..47df51e7e 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -33,6 +33,7 @@ import ( client "github.com/cosmos/cosmos-sdk/client" keys "github.com/cosmos/cosmos-sdk/client/keys" + rpc "github.com/cosmos/cosmos-sdk/client/rpc" gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/server" tests "github.com/cosmos/cosmos-sdk/tests" @@ -40,14 +41,17 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/stake" + stakerest "github.com/cosmos/cosmos-sdk/x/stake/client/rest" ) var ( coinDenom = "steak" coinAmount = int64(10000000) - validatorAddr1 = "" - validatorAddr2 = "" + validatorAddr1Hx = "" + validatorAddr2Hx = "" + validatorAddr1 = "" + validatorAddr2 = "" // XXX bad globals name = "test" @@ -99,13 +103,13 @@ func TestKeys(t *testing.T) { err = cdc.UnmarshalJSON([]byte(body), &m) require.Nil(t, err) - sendAddrAcc, _ := sdk.GetAccAddressHex(sendAddr) addrAcc, _ := sdk.GetAccAddressHex(addr) + addrBech32, _ := sdk.Bech32ifyAcc(addrAcc) - assert.Equal(t, m[0].Name, name, "Did not serve keys name correctly") - assert.Equal(t, m[0].Address, sendAddrAcc, "Did not serve keys Address correctly") - assert.Equal(t, m[1].Name, newName, "Did not serve keys name correctly") - assert.Equal(t, m[1].Address, addrAcc, "Did not serve keys Address correctly") + assert.Equal(t, name, m[0].Name, "Did not serve keys name correctly") + assert.Equal(t, sendAddr, m[0].Address, "Did not serve keys Address correctly") + assert.Equal(t, newName, m[1].Name, "Did not serve keys name correctly") + assert.Equal(t, addrBech32, m[1].Address, "Did not serve keys Address correctly") // select key keyEndpoint := fmt.Sprintf("/keys/%s", newName) @@ -116,7 +120,7 @@ func TestKeys(t *testing.T) { require.Nil(t, err) assert.Equal(t, newName, m2.Name, "Did not serve keys name correctly") - assert.Equal(t, addrAcc, m2.Address, "Did not serve keys Address correctly") + assert.Equal(t, addrBech32, m2.Address, "Did not serve keys Address correctly") // update key jsonStr = []byte(fmt.Sprintf(`{"old_password":"%s", "new_password":"12345678901"}`, newPassword)) @@ -198,7 +202,7 @@ func TestBlock(t *testing.T) { func TestValidators(t *testing.T) { - var resultVals ctypes.ResultValidators + var resultVals rpc.ResultValidatorsOutput res, body := request(t, port, "GET", "/validatorsets/latest", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -206,7 +210,10 @@ func TestValidators(t *testing.T) { err := cdc.UnmarshalJSON([]byte(body), &resultVals) require.Nil(t, err, "Couldn't parse validatorset") - assert.NotEqual(t, ctypes.ResultValidators{}, resultVals) + assert.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals) + + assert.Contains(t, resultVals.Validators[0].Address, "cosmosvaladdr") + assert.Contains(t, resultVals.Validators[0].PubKey, "cosmosvalpub") // -- @@ -216,7 +223,7 @@ func TestValidators(t *testing.T) { err = cdc.UnmarshalJSON([]byte(body), &resultVals) require.Nil(t, err, "Couldn't parse validatorset") - assert.NotEqual(t, ctypes.ResultValidators{}, resultVals) + assert.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals) // -- @@ -225,10 +232,11 @@ func TestValidators(t *testing.T) { } func TestCoinSend(t *testing.T) { + bz, _ := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6") + someFakeAddr, _ := sdk.Bech32ifyAcc(bz) // query empty - //res, body := request(t, port, "GET", "/accounts/8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6", nil) - res, body := request(t, port, "GET", "/accounts/8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6", nil) + res, body := request(t, port, "GET", "/accounts/"+someFakeAddr, nil) require.Equal(t, http.StatusNoContent, res.StatusCode, body) acc := getAccount(t, sendAddr) @@ -323,15 +331,14 @@ func TestValidatorsQuery(t *testing.T) { // make sure all the validators were found (order unknown because sorted by owner addr) foundVal1, foundVal2 := false, false - res1, res2 := hex.EncodeToString(validators[0].Owner), hex.EncodeToString(validators[1].Owner) - if res1 == validatorAddr1 || res2 == validatorAddr1 { + if validators[0].Owner == validatorAddr1 || validators[1].Owner == validatorAddr1 { foundVal1 = true } - if res1 == validatorAddr2 || res2 == validatorAddr2 { + if validators[0].Owner == validatorAddr2 || validators[1].Owner == validatorAddr2 { foundVal2 = true } - assert.True(t, foundVal1, "validatorAddr1 %v, res1 %v, res2 %v", validatorAddr1, res1, res2) - assert.True(t, foundVal2, "validatorAddr2 %v, res1 %v, res2 %v", validatorAddr2, res1, res2) + assert.True(t, foundVal1, "validatorAddr1 %v, owner1 %v, owner2 %v", validatorAddr1, validators[0].Owner, validators[1].Owner) + assert.True(t, foundVal2, "validatorAddr2 %v, owner1 %v, owner2 %v", validatorAddr2, validators[0].Owner, validators[1].Owner) } func TestBond(t *testing.T) { @@ -418,8 +425,10 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { pk1 := genDoc.Validators[0].PubKey pk2 := genDoc.Validators[1].PubKey - validatorAddr1 = hex.EncodeToString(pk1.Address()) - validatorAddr2 = hex.EncodeToString(pk2.Address()) + validatorAddr1Hx = hex.EncodeToString(pk1.Address()) + validatorAddr2Hx = hex.EncodeToString(pk2.Address()) + validatorAddr1, _ = sdk.Bech32ifyVal(pk1.Address()) + validatorAddr2, _ = sdk.Bech32ifyVal(pk2.Address()) // NOTE it's bad practice to reuse pk address for the owner address but doing in the // test for simplicity @@ -444,7 +453,8 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { if err != nil { return nil, nil, err } - sendAddr = info.PubKey.Address().String() // XXX global + sendAddrHex, _ := sdk.GetAccAddressHex(info.PubKey.Address().String()) + sendAddr, _ = sdk.Bech32ifyAcc(sendAddrHex) // XXX global accAuth := auth.NewBaseAccountWithAddress(info.PubKey.Address()) accAuth.Coins = sdk.Coins{{"steak", 100}} acc := gapp.NewGenesisAccount(&accAuth) @@ -548,7 +558,7 @@ func doSend(t *testing.T, port, seed string) (receiveAddr string, resultTx ctype kb := client.MockKeyBase() receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519")) require.Nil(t, err) - receiveAddr = receiveInfo.PubKey.Address().String() + receiveAddr, _ = sdk.Bech32ifyAcc(receiveInfo.PubKey.Address()) acc := getAccount(t, sendAddr) sequence := acc.GetSequence() @@ -565,12 +575,11 @@ func doSend(t *testing.T, port, seed string) (receiveAddr string, resultTx ctype } func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxCommit) { - // create receive address kb := client.MockKeyBase() receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519")) require.Nil(t, err) - receiveAddr := receiveInfo.PubKey.Address().String() + receiveAddr, _ := sdk.Bech32ifyAcc(receiveInfo.PubKey.Address()) // get the account to get the sequence acc := getAccount(t, sendAddr) @@ -609,13 +618,13 @@ func doBond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxC "sequence": %d, "delegate": [ { - "delegator_addr": "%x", + "delegator_addr": "%s", "validator_addr": "%s", "bond": { "denom": "%s", "amount": 10 } } ], "unbond": [] - }`, name, password, sequence, acc.GetAddress(), validatorAddr1, coinDenom)) + }`, name, password, sequence, sendAddr, validatorAddr1, coinDenom)) res, body := request(t, port, "POST", "/stake/delegations", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -639,12 +648,12 @@ func doUnbond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastT "bond": [], "unbond": [ { - "delegator_addr": "%x", + "delegator_addr": "%s", "validator_addr": "%s", "shares": "1" } ] - }`, name, password, sequence, acc.GetAddress(), validatorAddr1)) + }`, name, password, sequence, sendAddr, validatorAddr1)) res, body := request(t, port, "POST", "/stake/delegations", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -655,11 +664,11 @@ func doUnbond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastT return results[0] } -func getValidators(t *testing.T) []stake.Validator { +func getValidators(t *testing.T) []stakerest.StakeValidatorOutput { // get the account to get the sequence res, body := request(t, port, "GET", "/stake/validators", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var validators stake.Validators + var validators []stakerest.StakeValidatorOutput err := cdc.UnmarshalJSON([]byte(body), &validators) require.Nil(t, err) return validators diff --git a/client/rpc/validators.go b/client/rpc/validators.go index d1aa6c9c1..f8835d737 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -10,6 +10,8 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + tmtypes "github.com/tendermint/tendermint/types" ) // TODO these next two functions feel kinda hacky based on their placement @@ -28,6 +30,38 @@ func ValidatorCommand() *cobra.Command { return cmd } +// Validator output in bech32 format +type ValidatorOutput struct { + Address string `json:"address"` // in bech32 + PubKey string `json:"pub_key"` // in bech32 + Accum int64 `json:"accum"` + VotingPower int64 `json:"voting_power"` +} + +// Validators at a certain height output in bech32 format +type ResultValidatorsOutput struct { + BlockHeight int64 `json:"block_height"` + Validators []ValidatorOutput `json:"validators"` +} + +func bech32ValidatorOutput(validator *tmtypes.Validator) (ValidatorOutput, error) { + bechAddress, err := sdk.Bech32ifyVal(validator.Address) + if err != nil { + return ValidatorOutput{}, err + } + bechValPubkey, err := sdk.Bech32ifyValPub(validator.PubKey) + if err != nil { + return ValidatorOutput{}, err + } + + return ValidatorOutput{ + Address: bechAddress, + PubKey: bechValPubkey, + Accum: validator.Accum, + VotingPower: validator.VotingPower, + }, nil +} + func getValidators(ctx context.CoreContext, height *int64) ([]byte, error) { // get the node node, err := ctx.GetNode() @@ -35,12 +69,23 @@ func getValidators(ctx context.CoreContext, height *int64) ([]byte, error) { return nil, err } - res, err := node.Validators(height) + validatorsRes, err := node.Validators(height) if err != nil { return nil, err } - output, err := cdc.MarshalJSON(res) + outputValidatorsRes := ResultValidatorsOutput{ + BlockHeight: validatorsRes.BlockHeight, + Validators: make([]ValidatorOutput, len(validatorsRes.Validators)), + } + for i := 0; i < len(validatorsRes.Validators); i++ { + outputValidatorsRes.Validators[i], err = bech32ValidatorOutput(validatorsRes.Validators[i]) + if err != nil { + return nil, err + } + } + + output, err := cdc.MarshalJSON(outputValidatorsRes) if err != nil { return nil, err } @@ -96,6 +141,7 @@ func ValidatorSetRequestHandlerFn(ctx context.CoreContext) http.HandlerFunc { w.Write([]byte(err.Error())) return } + w.Write(output) } } diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index ae46a623c..1868452a6 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -170,7 +170,13 @@ func executeGetAddrPK(t *testing.T, cmdStr string) (sdk.Address, crypto.PubKey) var ko keys.KeyOutput keys.UnmarshalJSON([]byte(out), &ko) - return ko.Address, ko.PubKey + address, err := sdk.GetAccAddressBech32(ko.Address) + require.NoError(t, err) + + pk, err := sdk.GetAccPubKeyBech32(ko.PubKey) + require.NoError(t, err) + + return address, pk } func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { diff --git a/docs/sdk/lcd-rest-api.yaml b/docs/sdk/lcd-rest-api.yaml index 408b2a792..3008d7f73 100644 --- a/docs/sdk/lcd-rest-api.yaml +++ b/docs/sdk/lcd-rest-api.yaml @@ -102,7 +102,7 @@ paths: - application/json responses: 200: - description: 12 word Seed + description: 16 word Seed schema: type: string /keys/{name}: @@ -204,7 +204,7 @@ paths: parameters: - in: path name: address - description: Account address + description: Account address in bech32 format required: true type: string get: @@ -222,7 +222,7 @@ paths: parameters: - in: path name: address - description: Account address + description: Account address in bech32 format required: true type: string post: @@ -255,18 +255,6 @@ paths: description: Tx was send and will probably be added to the next block 400: description: The Tx was malformated - /accounts/{address}/nonce: - parameters: - - in: path - name: address - description: Account address - required: true - type: string - get: - summary: Get the nonce for a certain account - responses: - 200: - description: Plaintext nonce i.e. "4" defaults to "0" /blocks/latest: get: summary: Get the latest block @@ -304,9 +292,14 @@ paths: 200: description: The validator set at the latest block height schema: - type: array - items: - $ref: "#/definitions/Delegate" + type: object + properties: + block_height: + type: number + validators: + type: array + items: + $ref: "#/definitions/Validator" /validatorsets/{height}: parameters: - in: path @@ -322,9 +315,14 @@ paths: 200: description: The validator set at a specific block height schema: - type: array - items: - $ref: "#/definitions/Delegate" + type: object + properties: + block_height: + type: number + validators: + type: array + items: + $ref: "#/definitions/Validator" 404: description: Block at height not available # /txs: @@ -549,7 +547,20 @@ paths: definitions: Address: type: string - example: DF096FDE8D380FA5B2AD20DB2962C82DDEA1ED9B + description: bech32 encoded addres + example: cosmosaccaddr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + ValidatorAddress: + type: string + description: bech32 encoded addres + example: cosmosvaladdr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + PubKey: + type: string + description: bech32 encoded public key + example: cosmosaccpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + ValidatorPubKey: + type: string + description: bech32 encoded public key + example: cosmosvalpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq Coins: type: object properties: @@ -652,16 +663,6 @@ definitions: example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 Pubkey: $ref: "#/definitions/PubKey" - PubKey: - type: object - properties: - type: - type: string - enum: - - ed25519 - data: - type: string - example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 Account: type: object properties: @@ -753,17 +754,19 @@ definitions: type: array items: type: object - Delegate: + Validator: type: object properties: + address: + $ref: '#/definitions/ValidatorAddress' pub_key: - $ref: "#/definitions/PubKey" + $ref: "#/definitions/ValidatorPubKey" power: type: number example: 1000 - name: - type: string - example: "159.89.3.34" + accum: + type: number + example: 1000 # Added by API Auto Mocking Plugin host: virtserver.swaggerhub.com basePath: /faboweb1/Cosmos-LCD-2/1.0.0 diff --git a/types/account.go b/types/account.go index ad0c58231..00d180a1c 100644 --- a/types/account.go +++ b/types/account.go @@ -32,7 +32,7 @@ func Bech32ifyAccPub(pub crypto.PubKey) (string, error) { } // Bech32ifyVal returns the bech32 encoded string for a validator address -func bech32ifyVal(addr Address) (string, error) { +func Bech32ifyVal(addr Address) (string, error) { return bech32.ConvertAndEncode(Bech32PrefixValAddr, addr.Bytes()) } @@ -62,6 +62,21 @@ func GetAccAddressBech32(address string) (addr Address, err error) { return Address(bz), nil } +// create a Pubkey from a string +func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) { + bz, err := getFromBech32(address, Bech32PrefixAccPub) + if err != nil { + return nil, err + } + + pk, err = crypto.PubKeyFromBytes(bz) + if err != nil { + return nil, err + } + + return pk, nil +} + // create an Address from a hex string func GetValAddressHex(address string) (addr Address, err error) { if len(address) == 0 { diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index a60ce5cdb..bcae59c20 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -1,7 +1,6 @@ package rest import ( - "encoding/hex" "fmt" "net/http" @@ -26,17 +25,16 @@ func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, sto func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder, ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - addr := vars["address"] + bech32addr := vars["address"] - bz, err := hex.DecodeString(addr) + addr, err := sdk.GetAccAddressBech32(bech32addr) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } - key := sdk.Address(bz) - res, err := ctx.Query(key, storeName) + res, err := ctx.Query(addr, storeName) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Could't query account. Error: %s", err.Error()))) diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index defed3f14..83ab3b843 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -41,7 +41,14 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreCont return func(w http.ResponseWriter, r *http.Request) { // collect data vars := mux.Vars(r) - address := vars["address"] + bech32addr := vars["address"] + + address, err := sdk.GetAccAddressBech32(bech32addr) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } var m sendBody body, err := ioutil.ReadAll(r.Body) @@ -64,7 +71,7 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreCont return } - to, err := sdk.GetAccAddressHex(address) + to, err := sdk.GetAccAddressHex(address.String()) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index 48a29ee80..d897c6e4f 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -35,7 +35,14 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.Core // collect data vars := mux.Vars(r) destChainID := vars["destchain"] - address := vars["address"] + bech32addr := vars["address"] + + address, err := sdk.GetAccAddressBech32(bech32addr) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } var m transferBody body, err := ioutil.ReadAll(r.Body) @@ -58,7 +65,7 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.Core return } - bz, err := hex.DecodeString(address) + bz, err := hex.DecodeString(address.String()) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 3e439c2b4..0da3260cb 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -1,7 +1,6 @@ package rest import ( - "encoding/hex" "fmt" "net/http" @@ -30,24 +29,22 @@ func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire // read parameters vars := mux.Vars(r) - delegator := vars["delegator"] - validator := vars["validator"] + bech32delegator := vars["delegator"] + bech32validator := vars["validator"] - bz, err := hex.DecodeString(delegator) + delegatorAddr, err := sdk.GetAccAddressBech32(bech32delegator) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } - delegatorAddr := sdk.Address(bz) - bz, err = hex.DecodeString(validator) + validatorAddr, err := sdk.GetValAddressBech32(bech32validator) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } - validatorAddr := sdk.Address(bz) key := stake.GetDelegationKey(delegatorAddr, validatorAddr, cdc) @@ -83,6 +80,62 @@ func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire } } +// TODO inherit from Validator +type StakeValidatorOutput struct { + Owner string `json:"owner"` // in bech32 + PubKey string `json:"pub_key"` // in bech32 + Revoked bool `json:"revoked"` // has the validator been revoked from bonded status? + + PoolShares stake.PoolShares `json:"pool_shares"` // total shares for tokens held in the pool + DelegatorShares sdk.Rat `json:"delegator_shares"` // total shares issued to a validator's delegators + + Description stake.Description `json:"description"` // description terms for the validator + BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator + BondIntraTxCounter int16 `json:"bond_intra_tx_counter"` // block-local tx index of validator change + ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer + + Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators + CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this validator can ever charge + CommissionChangeRate sdk.Rat `json:"commission_change_rate"` // XXX maximum daily increase of the validator commission + CommissionChangeToday sdk.Rat `json:"commission_change_today"` // XXX commission rate change today, reset each day (UTC time) + + // fee related + PrevBondedShares sdk.Rat `json:"prev_bonded_shares"` // total shares of a global hold pools +} + +func bech32StakeValidatorOutput(validator stake.Validator) (StakeValidatorOutput, error) { + bechOwner, err := sdk.Bech32ifyVal(validator.Owner) + if err != nil { + return StakeValidatorOutput{}, err + } + bechValPubkey, err := sdk.Bech32ifyValPub(validator.PubKey) + if err != nil { + return StakeValidatorOutput{}, err + } + + return StakeValidatorOutput{ + Owner: bechOwner, + PubKey: bechValPubkey, + Revoked: validator.Revoked, + + PoolShares: validator.PoolShares, + DelegatorShares: validator.DelegatorShares, + + Description: validator.Description, + BondHeight: validator.BondHeight, + BondIntraTxCounter: validator.BondIntraTxCounter, + ProposerRewardPool: validator.ProposerRewardPool, + + Commission: validator.Commission, + CommissionMax: validator.CommissionMax, + CommissionChangeRate: validator.CommissionChangeRate, + CommissionChangeToday: validator.CommissionChangeToday, + + PrevBondedShares: validator.PrevBondedShares, + }, nil +} + +// TODO bech32 // http request handler to query list of validators func validatorsHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -100,16 +153,20 @@ func validatorsHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Co } // parse out the validators - validators := make([]stake.Validator, len(kvs)) + validators := make([]StakeValidatorOutput, len(kvs)) for i, kv := range kvs { var validator stake.Validator + var bech32Validator StakeValidatorOutput err = cdc.UnmarshalBinary(kv.Value, &validator) + if err == nil { + bech32Validator, err = bech32StakeValidatorOutput(validator) + } if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))) return } - validators[i] = validator + validators[i] = bech32Validator } output, err := cdc.MarshalJSON(validators) diff --git a/x/stake/client/rest/tx.go b/x/stake/client/rest/tx.go index eaf206bf6..33fe73c69 100644 --- a/x/stake/client/rest/tx.go +++ b/x/stake/client/rest/tx.go @@ -3,6 +3,7 @@ package rest import ( "bytes" "encoding/json" + "fmt" "io/ioutil" "net/http" @@ -23,13 +24,24 @@ func registerTxRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, k ).Methods("POST") } +type msgDelegateInput struct { + DelegatorAddr string `json:"delegator_addr"` // in bech32 + ValidatorAddr string `json:"validator_addr"` // in bech32 + Bond sdk.Coin `json:"bond"` +} +type msgUnbondInput struct { + DelegatorAddr string `json:"delegator_addr"` // in bech32 + ValidatorAddr string `json:"validator_addr"` // in bech32 + Shares string `json:"shares"` +} + type editDelegationsBody struct { - LocalAccountName string `json:"name"` - Password string `json:"password"` - ChainID string `json:"chain_id"` - Sequence int64 `json:"sequence"` - Delegate []stake.MsgDelegate `json:"delegate"` - Unbond []stake.MsgUnbond `json:"unbond"` + LocalAccountName string `json:"name"` + Password string `json:"password"` + ChainID string `json:"chain_id"` + Sequence int64 `json:"sequence"` + Delegate []msgDelegateInput `json:"delegate"` + Unbond []msgUnbondInput `json:"unbond"` } func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc { @@ -59,21 +71,53 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx conte messages := make([]sdk.Msg, len(m.Delegate)+len(m.Unbond)) i := 0 for _, msg := range m.Delegate { - if !bytes.Equal(info.Address(), msg.DelegatorAddr) { + delegatorAddr, err := sdk.GetAccAddressBech32(msg.DelegatorAddr) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error()))) + return + } + validatorAddr, err := sdk.GetValAddressBech32(msg.ValidatorAddr) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))) + return + } + if !bytes.Equal(info.Address(), delegatorAddr) { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Must use own delegator address")) return } - messages[i] = msg + messages[i] = stake.MsgDelegate{ + DelegatorAddr: delegatorAddr, + ValidatorAddr: validatorAddr, + Bond: msg.Bond, + } i++ } for _, msg := range m.Unbond { - if !bytes.Equal(info.Address(), msg.DelegatorAddr) { + delegatorAddr, err := sdk.GetAccAddressBech32(msg.DelegatorAddr) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error()))) + return + } + validatorAddr, err := sdk.GetValAddressBech32(msg.ValidatorAddr) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))) + return + } + if !bytes.Equal(info.Address(), delegatorAddr) { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Must use own delegator address")) return } - messages[i] = msg + messages[i] = stake.MsgUnbond{ + DelegatorAddr: delegatorAddr, + ValidatorAddr: validatorAddr, + Shares: msg.Shares, + } i++ } From 7cb404d578df12d3d2af921c16e9c9453f0c3131 Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Wed, 6 Jun 2018 09:55:34 -0400 Subject: [PATCH 10/89] created a test to check large unbonds lower bonded ratio --- x/stake/tick_test.go | 67 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index 6bed352f5..fb3177f0a 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -1,6 +1,7 @@ package stake import ( + "math/rand" "strconv" "testing" @@ -9,6 +10,9 @@ import ( "github.com/stretchr/testify/require" ) +//change the int in NewSource to generate random input for tests that use r for randomization +var r = rand.New(rand.NewSource(505)) + func TestGetInflation(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) pool := keeper.GetPool(ctx) @@ -97,11 +101,8 @@ func TestProcessProvisions(t *testing.T) { // Cycles through the whole gambit of starting at 7% inflation, up to 20%, back down to 7% (it takes ~11.4 years) func TestHourlyInflationRateOfChange(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) - // params := defaultParams() - // keeper.setParams(ctx, params) pool := keeper.GetPool(ctx) - // test setUpCandidates returned the token values by passing these vars into checkCandidateSetup() var ( initialTotalTokens int64 = 550000000 initialBondedTokens int64 = 150000000 @@ -113,7 +114,7 @@ func TestHourlyInflationRateOfChange(t *testing.T) { bondedValidators uint16 = 1 ) - // create some candidates some bonded, some unbonded + // create some validators some bonded, some unbonded _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) @@ -134,6 +135,58 @@ func TestHourlyInflationRateOfChange(t *testing.T) { 0, 0, bondedShares, unbondedShares) } +//Test that a large unbonding will significantly lower the bonded ratio +func TestLargeUnbond(t *testing.T) { + ctx, _, keeper := createTestInput(t, false, 0) + // params := defaultParams() + // keeper.setParams(ctx, params) + pool := keeper.GetPool(ctx) + + var ( + initialTotalTokens int64 = 1200000000 + initialBondedTokens int64 = 900000000 + initialUnbondedTokens int64 = 300000000 + val0UnbondedTokens int64 + bondedShares = sdk.NewRat(900000000, 1) + unbondedShares = sdk.NewRat(300000000, 1) + bondSharesVal0 = sdk.NewRat(300000000, 1) + tokensForValidators = []int64{300000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000} + bondedValidators uint16 = 7 + ) + + _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) + checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) + + pool = keeper.GetPool(ctx) + validator, found := keeper.GetValidator(ctx, addrs[0]) + assert.True(t, found) + + // initialBondedRatio that we can use to compare to the new values after the unbond + initialBondedRatio := pool.bondedRatio() + // validator[0] will be unbonded, bringing us from 75% to ~50% + // This func will unbond 300,000,000 tokens that were previously bonded + pool, validator, _, _ = OpBondOrUnbond(r, pool, validator) + keeper.setPool(ctx, pool) + + // process provisions after the bonding, to compare the difference in expProvisions and expInflation + _, expProvisionsAfter, pool := checkAndProcessProvisions(t, keeper, pool, ctx, 0) + + bondedShares = bondedShares.Sub(bondSharesVal0) + val0UnbondedTokens = pool.unbondedShareExRate().Mul(validator.PoolShares.Unbonded()).Evaluate() + unbondedShares = unbondedShares.Add(sdk.NewRat(val0UnbondedTokens, 1).Mul(pool.unbondedShareExRate())) + + // unbonded shares should increase + assert.True(t, unbondedShares.GT(sdk.NewRat(150000000, 1))) + // Ensure that new bonded ratio is less than old bonded ratio , because before they were increasing (i.e. 55 < 72) + assert.True(t, (pool.bondedRatio().LT(initialBondedRatio))) + + // Final check that the pool equals initial values + provisions and adjustments we recorded + pool = keeper.GetPool(ctx) + checkFinalPoolValues(t, pool, initialTotalTokens, + initialUnbondedTokens, expProvisionsAfter, + -val0UnbondedTokens, val0UnbondedTokens, bondedShares, unbondedShares) +} + ////////////////////////////////HELPER FUNCTIONS BELOW///////////////////////////////////// // Final check on the global pool values for what the total tokens accumulated from each hour of provisions and other functions @@ -154,7 +207,7 @@ func checkFinalPoolValues(t *testing.T, pool Pool, initialTotalTokens, initialUn assert.Equal(t, calculatedBondedTokens, pool.BondedTokens) assert.Equal(t, calculatedUnbondedTokens, pool.UnbondedTokens) - // test the value of candidate shares + // test the value of validator shares assert.True(t, pool.bondedShareExRate().Mul(bondedShares).Equal(sdk.NewRat(calculatedBondedTokens)), "%v", pool.bondedShareExRate()) assert.True(t, pool.unbondedShareExRate().Mul(unbondedShares).Equal(sdk.NewRat(calculatedUnbondedTokens)), "%v", pool.unbondedShareExRate()) } @@ -199,7 +252,7 @@ func setupTestValidators(pool Pool, keeper Keeper, ctx sdk.Context, validatorTok return validators, keeper, pool } -// Checks that the deterministic candidate setup you wanted matches the values in the pool +// Checks that the deterministic validator setup you wanted matches the values in the pool func checkValidatorSetup(t *testing.T, pool Pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens int64) { assert.Equal(t, initialTotalTokens, pool.TokenSupply()) @@ -208,7 +261,7 @@ func checkValidatorSetup(t *testing.T, pool Pool, initialTotalTokens, initialBon // test initial bonded ratio assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(initialBondedTokens, initialTotalTokens)), "%v", pool.bondedRatio()) - // test the value of candidate shares + // test the value of validator shares assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate()) } From 3fbee11ccc5a504c925cdb42f7c6a1edd1be6d92 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 6 Jun 2018 18:38:13 +0200 Subject: [PATCH 11/89] Merge PR #1142: Export validators to genesis * Validator export skeleton * Update export command, add tests, update CHANGELOG * Rename exportAppState to exportAppStateAndTMValidators --- CHANGELOG.md | 6 +++++ cmd/gaia/app/app.go | 10 +++++-- cmd/gaia/app/app_test.go | 36 +++++++++++++++++++++++++ cmd/gaia/cmd/gaiad/main.go | 7 ++--- examples/basecoin/app/app.go | 10 +++++-- examples/basecoin/cmd/basecoind/main.go | 7 ++--- examples/democoin/app/app.go | 9 +++++-- examples/democoin/cmd/democoind/main.go | 7 ++--- server/constructors.go | 11 ++++---- server/export.go | 3 ++- types/stake.go | 1 + x/stake/genesis.go | 19 ++++++++++++- x/stake/validator.go | 1 + 13 files changed, 105 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 731f3c14a..6d6541691 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ BREAKING CHANGES +FEATURES + +IMPROVEMENTS +* export command now writes current validator set for Tendermint + +FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs ## 0.18.0 diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 8f8ed281e..f06ed2be3 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -5,6 +5,7 @@ import ( "os" abci "github.com/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -153,7 +154,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // export the state of gaia for a genesis file -func (app *GaiaApp) ExportAppStateJSON() (appState json.RawMessage, err error) { +func (app *GaiaApp) ExportAppStateAndValidators() (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) { ctx := app.NewContext(true, abci.Header{}) // iterate to get the accounts @@ -169,5 +170,10 @@ func (app *GaiaApp) ExportAppStateJSON() (appState json.RawMessage, err error) { Accounts: accounts, StakeData: stake.WriteGenesis(ctx, app.stakeKeeper), } - return wire.MarshalJSONIndent(app.cdc, genState) + appState, err = wire.MarshalJSONIndent(app.cdc, genState) + if err != nil { + return nil, nil, err + } + validators = stake.WriteValidators(ctx, app.stakeKeeper) + return appState, validators, nil } diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index b6fffac32..0fe1cfe5b 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -430,6 +430,42 @@ func TestStakeMsgs(t *testing.T) { require.False(t, found) } +func TestExportValidators(t *testing.T) { + gapp := newGaiaApp() + + genCoins, err := sdk.ParseCoins("42steak") + require.Nil(t, err) + bondCoin, err := sdk.ParseCoin("10steak") + 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) + + // Create Validator + description := stake.NewDescription("foo_moniker", "", "", "") + createValidatorMsg := stake.NewMsgCreateValidator( + addr1, priv1.PubKey(), bondCoin, description, + ) + SignCheckDeliver(t, gapp, createValidatorMsg, []int64{0}, true, priv1) + gapp.Commit() + + // Export validator set + _, validators, err := gapp.ExportAppStateAndValidators() + require.Nil(t, err) + require.Equal(t, 1, len(validators)) // 1 validator + require.Equal(t, priv1.PubKey(), validators[0].PubKey) + require.Equal(t, int64(10), validators[0].Power) +} + //____________________________________________________________________________________ func CheckBalance(t *testing.T, gapp *GaiaApp, addr sdk.Address, balExpected string) { diff --git a/cmd/gaia/cmd/gaiad/main.go b/cmd/gaia/cmd/gaiad/main.go index 30cb276ee..5d0eb9030 100644 --- a/cmd/gaia/cmd/gaiad/main.go +++ b/cmd/gaia/cmd/gaiad/main.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -26,7 +27,7 @@ func main() { server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), server.ConstructAppCreator(newApp, "gaia"), - server.ConstructAppExporter(exportAppState, "gaia")) + server.ConstructAppExporter(exportAppStateAndTMValidators, "gaia")) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome) @@ -37,7 +38,7 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewGaiaApp(logger, db) } -func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { +func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB) (json.RawMessage, []tmtypes.GenesisValidator, error) { gapp := app.NewGaiaApp(logger, db) - return gapp.ExportAppStateJSON() + return gapp.ExportAppStateAndValidators() } diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 1718b8be2..fdb0638b6 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -4,6 +4,7 @@ import ( "encoding/json" abci "github.com/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -155,7 +156,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) } // Custom logic for state export -func (app *BasecoinApp) ExportAppStateJSON() (appState json.RawMessage, err error) { +func (app *BasecoinApp) ExportAppStateAndValidators() (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) { ctx := app.NewContext(true, abci.Header{}) // iterate to get the accounts @@ -173,5 +174,10 @@ func (app *BasecoinApp) ExportAppStateJSON() (appState json.RawMessage, err erro genState := types.GenesisState{ Accounts: accounts, } - return wire.MarshalJSONIndent(app.cdc, genState) + appState, err = wire.MarshalJSONIndent(app.cdc, genState) + if err != nil { + return nil, nil, err + } + validators = stake.WriteValidators(ctx, app.stakeKeeper) + return appState, validators, err } diff --git a/examples/basecoin/cmd/basecoind/main.go b/examples/basecoin/cmd/basecoind/main.go index 4e6a30a08..4a6498e1b 100644 --- a/examples/basecoin/cmd/basecoind/main.go +++ b/examples/basecoin/cmd/basecoind/main.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -27,7 +28,7 @@ func main() { server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, server.ConstructAppCreator(newApp, "basecoin"), - server.ConstructAppExporter(exportAppState, "basecoin")) + server.ConstructAppExporter(exportAppStateAndTMValidators, "basecoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.basecoind") @@ -39,7 +40,7 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewBasecoinApp(logger, db) } -func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { +func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB) (json.RawMessage, []tmtypes.GenesisValidator, error) { bapp := app.NewBasecoinApp(logger, db) - return bapp.ExportAppStateJSON() + return bapp.ExportAppStateAndValidators() } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 2075a64da..dc7c3c9d8 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -4,6 +4,7 @@ import ( "encoding/json" abci "github.com/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -154,7 +155,7 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep } // Custom logic for state export -func (app *DemocoinApp) ExportAppStateJSON() (appState json.RawMessage, err error) { +func (app *DemocoinApp) ExportAppStateAndValidators() (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) { ctx := app.NewContext(true, abci.Header{}) // iterate to get the accounts @@ -174,5 +175,9 @@ func (app *DemocoinApp) ExportAppStateJSON() (appState json.RawMessage, err erro POWGenesis: pow.WriteGenesis(ctx, app.powKeeper), CoolGenesis: cool.WriteGenesis(ctx, app.coolKeeper), } - return wire.MarshalJSONIndent(app.cdc, genState) + appState, err = wire.MarshalJSONIndent(app.cdc, genState) + if err != nil { + return nil, nil, err + } + return appState, validators, nil } diff --git a/examples/democoin/cmd/democoind/main.go b/examples/democoin/cmd/democoind/main.go index 3283da58a..76d29075e 100644 --- a/examples/democoin/cmd/democoind/main.go +++ b/examples/democoin/cmd/democoind/main.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -46,9 +47,9 @@ func newApp(logger log.Logger, db dbm.DB) abci.Application { return app.NewDemocoinApp(logger, db) } -func exportAppState(logger log.Logger, db dbm.DB) (json.RawMessage, error) { +func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB) (json.RawMessage, []tmtypes.GenesisValidator, error) { dapp := app.NewDemocoinApp(logger, db) - return dapp.ExportAppStateJSON() + return dapp.ExportAppStateAndValidators() } func main() { @@ -63,7 +64,7 @@ func main() { server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, server.ConstructAppCreator(newApp, "democoin"), - server.ConstructAppExporter(exportAppState, "democoin")) + server.ConstructAppExporter(exportAppStateAndTMValidators, "democoin")) // prepare and add flags rootDir := os.ExpandEnv("$HOME/.democoind") diff --git a/server/constructors.go b/server/constructors.go index 3d6950062..c91c67a18 100644 --- a/server/constructors.go +++ b/server/constructors.go @@ -5,6 +5,7 @@ import ( "path/filepath" abci "github.com/tendermint/abci/types" + tmtypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" ) @@ -13,8 +14,8 @@ import ( // 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) +// AppExporter dumps all app state to JSON-serializable structure and returns the current validator set +type AppExporter func(home string, log log.Logger) (json.RawMessage, []tmtypes.GenesisValidator, error) // ConstructAppCreator returns an application generation function func ConstructAppCreator(appFn func(log.Logger, dbm.DB) abci.Application, name string) AppCreator { @@ -30,12 +31,12 @@ func ConstructAppCreator(appFn func(log.Logger, dbm.DB) abci.Application, name s } // 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) { +func ConstructAppExporter(appFn func(log.Logger, dbm.DB) (json.RawMessage, []tmtypes.GenesisValidator, error), name string) AppExporter { + return func(rootDir string, logger log.Logger) (json.RawMessage, []tmtypes.GenesisValidator, error) { dataDir := filepath.Join(rootDir, "data") db, err := dbm.NewGoLevelDB(name, dataDir) if err != nil { - return nil, err + return nil, nil, err } return appFn(logger, db) } diff --git a/server/export.go b/server/export.go index dad2df9cc..794235f62 100644 --- a/server/export.go +++ b/server/export.go @@ -18,7 +18,7 @@ func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter AppExporter) *cobra.Co Short: "Export state to JSON", RunE: func(cmd *cobra.Command, args []string) error { home := viper.GetString("home") - appState, err := appExporter(home, ctx.Logger) + appState, validators, err := appExporter(home, ctx.Logger) if err != nil { return errors.Errorf("Error exporting state: %v\n", err) } @@ -27,6 +27,7 @@ func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter AppExporter) *cobra.Co return err } doc.AppStateJSON = appState + doc.Validators = validators encoded, err := wire.MarshalJSONIndent(cdc, doc) if err != nil { return err diff --git a/types/stake.go b/types/stake.go index 6a620db76..7484295cc 100644 --- a/types/stake.go +++ b/types/stake.go @@ -32,6 +32,7 @@ func BondStatusToString(b BondStatus) string { // validator for a delegated proof of stake system type Validator interface { + GetMoniker() string // moniker of the validator GetStatus() BondStatus // status of the validator GetOwner() Address // owner address to receive/return validators coins GetPubKey() crypto.PubKey // validation pubkey diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 0a7c528bf..43ea61d8b 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -1,6 +1,10 @@ package stake -import sdk "github.com/cosmos/cosmos-sdk/types" +import ( + tmtypes "github.com/tendermint/tendermint/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) // GenesisState - all staking state that must be provided at genesis type GenesisState struct { @@ -63,3 +67,16 @@ func WriteGenesis(ctx sdk.Context, k Keeper) GenesisState { bonds, } } + +// WriteValidators - output current validator set +func WriteValidators(ctx sdk.Context, k Keeper) (vals []tmtypes.GenesisValidator) { + k.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) (stop bool) { + vals = append(vals, tmtypes.GenesisValidator{ + PubKey: validator.GetPubKey(), + Power: validator.GetPower().Evaluate(), + Name: validator.GetMoniker(), + }) + return false + }) + return +} diff --git a/x/stake/validator.go b/x/stake/validator.go index a0b484d71..3b135c12b 100644 --- a/x/stake/validator.go +++ b/x/stake/validator.go @@ -251,6 +251,7 @@ func (v Validator) DelegatorShareExRate(pool Pool) sdk.Rat { var _ sdk.Validator = Validator{} // nolint - for sdk.Validator +func (v Validator) GetMoniker() string { return v.Description.Moniker } func (v Validator) GetStatus() sdk.BondStatus { return v.Status() } func (v Validator) GetOwner() sdk.Address { return v.Owner } func (v Validator) GetPubKey() crypto.PubKey { return v.PubKey } From 5aa6c96cb6316f2d914bee32f8e6ded788c798ab Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Wed, 6 Jun 2018 13:11:36 -0400 Subject: [PATCH 12/89] added Large Bond test for provisions --- x/stake/tick_test.go | 63 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index fb3177f0a..27b3072f9 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -138,8 +138,6 @@ func TestHourlyInflationRateOfChange(t *testing.T) { //Test that a large unbonding will significantly lower the bonded ratio func TestLargeUnbond(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) - // params := defaultParams() - // keeper.setParams(ctx, params) pool := keeper.GetPool(ctx) var ( @@ -176,7 +174,7 @@ func TestLargeUnbond(t *testing.T) { unbondedShares = unbondedShares.Add(sdk.NewRat(val0UnbondedTokens, 1).Mul(pool.unbondedShareExRate())) // unbonded shares should increase - assert.True(t, unbondedShares.GT(sdk.NewRat(150000000, 1))) + assert.True(t, unbondedShares.GT(sdk.NewRat(300000000, 1))) // Ensure that new bonded ratio is less than old bonded ratio , because before they were increasing (i.e. 55 < 72) assert.True(t, (pool.bondedRatio().LT(initialBondedRatio))) @@ -187,6 +185,63 @@ func TestLargeUnbond(t *testing.T) { -val0UnbondedTokens, val0UnbondedTokens, bondedShares, unbondedShares) } +//Test that a large bonding will significantly increase the bonded ratio +func TestLargeBond(t *testing.T) { + ctx, _, keeper := createTestInput(t, false, 0) + pool := keeper.GetPool(ctx) + + var ( + initialTotalTokens int64 = 1600000000 + initialBondedTokens int64 = 400000000 + initialUnbondedTokens int64 = 1200000000 + val9UnbondedTokens int64 = 400000000 + val9BondedTokens int64 + bondedShares = sdk.NewRat(400000000, 1) + unbondedShares = sdk.NewRat(1200000000, 1) + unbondedSharesVal9 = sdk.NewRat(400000000, 1) + tokensForValidators = []int64{400000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 400000000} + bondedValidators uint16 = 1 + ) + + _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) + checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) + + pool = keeper.GetPool(ctx) + validator, found := keeper.GetValidator(ctx, addrs[9]) + assert.True(t, found) + + // initialBondedRatio that we can use to compare to the new values after the unbond + initialBondedRatio := pool.bondedRatio() + + params := defaultParams() + params.MaxValidators = bondedValidators + 1 //must do this to allow for an extra validator to bond + keeper.setParams(ctx, params) + + // validator[9] will be bonded, bringing us from 25% to ~50% + // This func will bond 400,000,000 tokens that were previously unbonded + pool, validator, _, _ = OpBondOrUnbond(r, pool, validator) + keeper.setPool(ctx, pool) + + // process provisions after the bonding, to compare the difference in expProvisions and expInflation + _, expProvisionsAfter, pool := checkAndProcessProvisions(t, keeper, pool, ctx, 0) + unbondedShares = unbondedShares.Sub(unbondedSharesVal9) + val9BondedTokens = val9UnbondedTokens + val9UnbondedTokens = 0 + bondedTokens := initialBondedTokens + val9BondedTokens + expProvisionsAfter + bondedShares = sdk.NewRat(bondedTokens, 1).Quo(pool.bondedShareExRate()) + + // unbonded shares should decrease + assert.True(t, unbondedShares.LT(sdk.NewRat(1200000000, 1))) + // Ensure that new bonded ratio is greater than old bonded ratio (i.e. 50% > 25%) + assert.True(t, (pool.bondedRatio().GT(initialBondedRatio))) + // Final check that the pool equals initial values + provisions and adjustments we recorded + pool = keeper.GetPool(ctx) + + checkFinalPoolValues(t, pool, initialTotalTokens, + initialUnbondedTokens, expProvisionsAfter, + val9BondedTokens, -val9BondedTokens, bondedShares, unbondedShares) +} + ////////////////////////////////HELPER FUNCTIONS BELOW///////////////////////////////////// // Final check on the global pool values for what the total tokens accumulated from each hour of provisions and other functions @@ -245,7 +300,7 @@ func setupTestValidators(pool Pool, keeper Keeper, ctx sdk.Context, validatorTok validators[i] = NewValidator(addrs[i], pks[i], Description{}) validators[i], pool, _ = validators[i].addTokensFromDel(pool, validatorTokens[i]) keeper.setPool(ctx, pool) - validators[i] = keeper.updateValidator(ctx, validators[i]) + validators[i] = keeper.updateValidator(ctx, validators[i]) //will kick out lower power validators. must keep in mind when setting up the test validators order pool = keeper.GetPool(ctx) } From 5352b650787fffe7f6302983305ee6201149f79c Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Wed, 6 Jun 2018 14:05:51 -0400 Subject: [PATCH 13/89] Added TestInflationWithRandomOperations --- x/stake/tick_test.go | 119 +++++++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 33 deletions(-) diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index 27b3072f9..8096119f4 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -10,8 +10,8 @@ import ( "github.com/stretchr/testify/require" ) -//change the int in NewSource to generate random input for tests that use r for randomization -var r = rand.New(rand.NewSource(505)) +//changing the int in NewSource will allow you to test different, deterministic, sets of operations +var r = rand.New(rand.NewSource(6595)) func TestGetInflation(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) @@ -64,6 +64,7 @@ func TestGetInflation(t *testing.T) { } } +// Test that provisions are correctly added to the pool and validators each hour for 1 year func TestProcessProvisions(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) pool := keeper.GetPool(ctx) @@ -75,18 +76,18 @@ func TestProcessProvisions(t *testing.T) { cumulativeExpProvs int64 initialBondedShares = sdk.NewRat(250000000, 1) initialUnbondedShares = sdk.NewRat(300000000, 1) - tokensForValidators = []int64{150000000, 100000000, 100000000, 100000000, 100000000} + validatorTokens = []int64{150000000, 100000000, 100000000, 100000000, 100000000} bondedValidators uint16 = 2 ) // create some validators some bonded, some unbonded - _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) + _, keeper, pool = setupTestValidators(pool, keeper, ctx, validatorTokens, bondedValidators) checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) // process the provisions for a year for hr := 0; hr < 8766; hr++ { pool := keeper.GetPool(ctx) - _, expProvisions, _ := checkAndProcessProvisions(t, keeper, pool, ctx, hr) + _, expProvisions, _ := updateProvisions(t, keeper, pool, ctx, hr) cumulativeExpProvs = cumulativeExpProvs + expProvisions } @@ -97,8 +98,8 @@ func TestProcessProvisions(t *testing.T) { 0, 0, initialBondedShares, initialUnbondedShares) } -// Tests that the hourly rate of change will be positive, negative, or zero, depending on bonded ratio and inflation rate -// Cycles through the whole gambit of starting at 7% inflation, up to 20%, back down to 7% (it takes ~11.4 years) +// Tests that the hourly rate of change of inflation will be positive, negative, or zero, depending on bonded ratio and inflation rate +// Cycles through the whole gambit of inflation possibilities, starting at 7% inflation, up to 20%, back down to 7% (it takes ~11.4 years) func TestHourlyInflationRateOfChange(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) pool := keeper.GetPool(ctx) @@ -110,19 +111,19 @@ func TestHourlyInflationRateOfChange(t *testing.T) { cumulativeExpProvs int64 bondedShares = sdk.NewRat(150000000, 1) unbondedShares = sdk.NewRat(400000000, 1) - tokensForValidators = []int64{150000000, 100000000, 100000000, 100000000, 100000000} + validatorTokens = []int64{150000000, 100000000, 100000000, 100000000, 100000000} bondedValidators uint16 = 1 ) // create some validators some bonded, some unbonded - _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) + _, keeper, pool = setupTestValidators(pool, keeper, ctx, validatorTokens, bondedValidators) checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) // ~11.4 years to go from 7%, up to 20%, back down to 7% for hr := 0; hr < 100000; hr++ { pool := keeper.GetPool(ctx) previousInflation := pool.Inflation - updatedInflation, expProvisions, pool := checkAndProcessProvisions(t, keeper, pool, ctx, hr) + updatedInflation, expProvisions, pool := updateProvisions(t, keeper, pool, ctx, hr) cumulativeExpProvs = cumulativeExpProvs + expProvisions msg := strconv.Itoa(hr) checkInflation(t, pool, previousInflation, updatedInflation, msg) @@ -148,11 +149,11 @@ func TestLargeUnbond(t *testing.T) { bondedShares = sdk.NewRat(900000000, 1) unbondedShares = sdk.NewRat(300000000, 1) bondSharesVal0 = sdk.NewRat(300000000, 1) - tokensForValidators = []int64{300000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000} + validatorTokens = []int64{300000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000} bondedValidators uint16 = 7 ) - _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) + _, keeper, pool = setupTestValidators(pool, keeper, ctx, validatorTokens, bondedValidators) checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) pool = keeper.GetPool(ctx) @@ -161,13 +162,13 @@ func TestLargeUnbond(t *testing.T) { // initialBondedRatio that we can use to compare to the new values after the unbond initialBondedRatio := pool.bondedRatio() - // validator[0] will be unbonded, bringing us from 75% to ~50% - // This func will unbond 300,000,000 tokens that were previously bonded + + // validator[0] will be unbonded, bringing us from 75% bonded ratio to ~50% (unbonding 300,000,000) pool, validator, _, _ = OpBondOrUnbond(r, pool, validator) keeper.setPool(ctx, pool) // process provisions after the bonding, to compare the difference in expProvisions and expInflation - _, expProvisionsAfter, pool := checkAndProcessProvisions(t, keeper, pool, ctx, 0) + _, expProvisionsAfter, pool := updateProvisions(t, keeper, pool, ctx, 0) bondedShares = bondedShares.Sub(bondSharesVal0) val0UnbondedTokens = pool.unbondedShareExRate().Mul(validator.PoolShares.Unbonded()).Evaluate() @@ -175,7 +176,7 @@ func TestLargeUnbond(t *testing.T) { // unbonded shares should increase assert.True(t, unbondedShares.GT(sdk.NewRat(300000000, 1))) - // Ensure that new bonded ratio is less than old bonded ratio , because before they were increasing (i.e. 55 < 72) + // Ensure that new bonded ratio is less than old bonded ratio , because before they were increasing (i.e. 50% < 75) assert.True(t, (pool.bondedRatio().LT(initialBondedRatio))) // Final check that the pool equals initial values + provisions and adjustments we recorded @@ -199,11 +200,11 @@ func TestLargeBond(t *testing.T) { bondedShares = sdk.NewRat(400000000, 1) unbondedShares = sdk.NewRat(1200000000, 1) unbondedSharesVal9 = sdk.NewRat(400000000, 1) - tokensForValidators = []int64{400000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 400000000} + validatorTokens = []int64{400000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 400000000} bondedValidators uint16 = 1 ) - _, keeper, pool = setupTestValidators(pool, keeper, ctx, tokensForValidators, bondedValidators) + _, keeper, pool = setupTestValidators(pool, keeper, ctx, validatorTokens, bondedValidators) checkValidatorSetup(t, pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens) pool = keeper.GetPool(ctx) @@ -217,13 +218,12 @@ func TestLargeBond(t *testing.T) { params.MaxValidators = bondedValidators + 1 //must do this to allow for an extra validator to bond keeper.setParams(ctx, params) - // validator[9] will be bonded, bringing us from 25% to ~50% - // This func will bond 400,000,000 tokens that were previously unbonded + // validator[9] will be bonded, bringing us from 25% to ~50% (bonding 400,000,000 tokens) pool, validator, _, _ = OpBondOrUnbond(r, pool, validator) keeper.setPool(ctx, pool) // process provisions after the bonding, to compare the difference in expProvisions and expInflation - _, expProvisionsAfter, pool := checkAndProcessProvisions(t, keeper, pool, ctx, 0) + _, expProvisionsAfter, pool := updateProvisions(t, keeper, pool, ctx, 0) unbondedShares = unbondedShares.Sub(unbondedSharesVal9) val9BondedTokens = val9UnbondedTokens val9UnbondedTokens = 0 @@ -242,10 +242,65 @@ func TestLargeBond(t *testing.T) { val9BondedTokens, -val9BondedTokens, bondedShares, unbondedShares) } +// Tests that inflation increases or decreases as expected when we do a random operation on 20 different validators +func TestInflationWithRandomOperations(t *testing.T) { + ctx, _, keeper := createTestInput(t, false, 0) + params := defaultParams() + keeper.setParams(ctx, params) + numValidators := 20 + + // start off by randomly setting up 20 validators + pool, validators := randomSetup(r, numValidators) + require.Equal(t, numValidators, len(validators)) + + for i := 0; i < len(validators); i++ { + keeper.setValidator(ctx, validators[i]) + } + keeper.setPool(ctx, pool) + + // Used to rotate validators so each random operation is applied to a different validator + validatorCounter := 0 + + // Loop through 20 random operations, and check the inflation after each operation + for i := 0; i < numValidators; i++ { + pool := keeper.GetPool(ctx) + + // Get inflation before randomOperation, for comparison later + previousInflation := pool.Inflation + + // Perform the random operation, and record how validators are modified + poolMod, validatorMod, tokens, msg := randomOperation(r)(r, pool, validators[validatorCounter]) + validatorsMod := make([]Validator, len(validators)) + copy(validatorsMod[:], validators[:]) + require.Equal(t, numValidators, len(validators), "i %v", validatorCounter) + require.Equal(t, numValidators, len(validatorsMod), "i %v", validatorCounter) + validatorsMod[validatorCounter] = validatorMod + + assertInvariants(t, msg, + pool, validators, + poolMod, validatorsMod, tokens) + + // set pool and validators after the random operation + pool = poolMod + keeper.setPool(ctx, pool) + validators = validatorsMod + + // Must set inflation here manually, as opposed to most other tests in this suite, where we call keeper.processProvisions(), which updates pool.Inflation + updatedInflation := keeper.nextInflation(ctx) + pool.Inflation = updatedInflation + keeper.setPool(ctx, pool) + + // Ensure inflation changes as expected when random operations are applied. + checkInflation(t, pool, previousInflation, updatedInflation, msg) + validatorCounter++ + } +} + ////////////////////////////////HELPER FUNCTIONS BELOW///////////////////////////////////// // Final check on the global pool values for what the total tokens accumulated from each hour of provisions and other functions -// bondedAdjustment and unbondedAdjustment are the accumulated changes for the operations of the test (i.e. if three unbonds happened, their total value would be passed as unbondedAdjustment) +// bondedAdjustment and unbondedAdjustment are the accumulated changes for the operations of the test +// (i.e. if three unbond operations happened, their total value would be passed as unbondedAdjustment) func checkFinalPoolValues(t *testing.T, pool Pool, initialTotalTokens, initialUnbondedTokens, cumulativeExpProvs, bondedAdjustment, unbondedAdjustment int64, bondedShares, unbondedShares sdk.Rat) { @@ -267,11 +322,9 @@ func checkFinalPoolValues(t *testing.T, pool Pool, initialTotalTokens, initialUn assert.True(t, pool.unbondedShareExRate().Mul(unbondedShares).Equal(sdk.NewRat(calculatedUnbondedTokens)), "%v", pool.unbondedShareExRate()) } -// Checks provisions are added to the pool correctly every hour +// Processes provisions are added to the pool correctly every hour // Returns expected Provisions, expected Inflation, and pool, to help with cumulative calculations back in main Tests -func checkAndProcessProvisions(t *testing.T, keeper Keeper, pool Pool, ctx sdk.Context, hr int) (sdk.Rat, int64, Pool) { - - //If we are not doing a random operation, just check that normal provisions are working for each hour +func updateProvisions(t *testing.T, keeper Keeper, pool Pool, ctx sdk.Context, hr int) (sdk.Rat, int64, Pool) { expInflation := keeper.nextInflation(ctx) expProvisions := (expInflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat)).Evaluate() startBondedPool := pool.BondedTokens @@ -286,12 +339,12 @@ func checkAndProcessProvisions(t *testing.T, keeper Keeper, pool Pool, ctx sdk.C return expInflation, expProvisions, pool } -// Deterministic setup of validators, which updates the pool and choose maxValidators to be bonded -// Allows you to decide how many validators to setup, and which ones you want bonded -// You choose bonded validators by setting params.MaxValidators. If you choose 2, the first 2 Validators in the arrray will be bonded, the rest unbonded +// Deterministic setup of validators and pool +// Allows you to decide how many validators to setup +// Allows you to pick which validators are bonded by adjusting the MaxValidators of params func setupTestValidators(pool Pool, keeper Keeper, ctx sdk.Context, validatorTokens []int64, maxValidators uint16) ([]Validator, Keeper, Pool) { params := defaultParams() - params.MaxValidators = maxValidators //set to limit the amount of validators we want bonded + params.MaxValidators = maxValidators keeper.setParams(ctx, params) numValidators := len(validatorTokens) validators := make([]Validator, numValidators) @@ -300,7 +353,7 @@ func setupTestValidators(pool Pool, keeper Keeper, ctx sdk.Context, validatorTok validators[i] = NewValidator(addrs[i], pks[i], Description{}) validators[i], pool, _ = validators[i].addTokensFromDel(pool, validatorTokens[i]) keeper.setPool(ctx, pool) - validators[i] = keeper.updateValidator(ctx, validators[i]) //will kick out lower power validators. must keep in mind when setting up the test validators order + validators[i] = keeper.updateValidator(ctx, validators[i]) //will kick out lower power validators. Keep this in mind when setting up the test validators order pool = keeper.GetPool(ctx) } @@ -309,7 +362,6 @@ func setupTestValidators(pool Pool, keeper Keeper, ctx sdk.Context, validatorTok // Checks that the deterministic validator setup you wanted matches the values in the pool func checkValidatorSetup(t *testing.T, pool Pool, initialTotalTokens, initialBondedTokens, initialUnbondedTokens int64) { - assert.Equal(t, initialTotalTokens, pool.TokenSupply()) assert.Equal(t, initialBondedTokens, pool.BondedTokens) assert.Equal(t, initialUnbondedTokens, pool.UnbondedTokens) @@ -322,7 +374,6 @@ func checkValidatorSetup(t *testing.T, pool Pool, initialTotalTokens, initialBon // Checks that The inflation will correctly increase or decrease after an update to the pool func checkInflation(t *testing.T, pool Pool, previousInflation, updatedInflation sdk.Rat, msg string) { - inflationChange := updatedInflation.Sub(previousInflation) switch { @@ -334,6 +385,7 @@ func checkInflation(t *testing.T, pool Pool, previousInflation, updatedInflation case pool.bondedRatio().LT(sdk.NewRat(67, 100)) && updatedInflation.Equal(sdk.NewRat(20, 100)): if previousInflation.Equal(sdk.NewRat(20, 100)) { assert.Equal(t, true, inflationChange.IsZero(), msg) + //This else statement covers the one off case where we first hit 20%, but we still needed a positive ROC to get to 67% bonded ratio (i.e. we went from 19.99999% to 20%) } else { assert.Equal(t, true, inflationChange.GT(sdk.ZeroRat()), msg) @@ -347,6 +399,7 @@ func checkInflation(t *testing.T, pool Pool, previousInflation, updatedInflation case pool.bondedRatio().GT(sdk.NewRat(67, 100)) && updatedInflation.Equal(sdk.NewRat(7, 100)): if previousInflation.Equal(sdk.NewRat(7, 100)) { assert.Equal(t, true, inflationChange.IsZero(), msg) + //This else statement covers the one off case where we first hit 7%, but we still needed a negative ROC to continue to get down to 67%. (i.e. we went from 7.00001% to 7%) } else { assert.Equal(t, true, inflationChange.LT(sdk.ZeroRat()), msg) From 78703f027d77cb881a5f1eec4575f689fa06b270 Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Wed, 6 Jun 2018 15:49:22 -0400 Subject: [PATCH 14/89] fixed small breaking changes from pulling in develop --- x/stake/inflation_test.go | 6 +++--- x/stake/test_common.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x/stake/inflation_test.go b/x/stake/inflation_test.go index 8096119f4..7fa393edc 100644 --- a/x/stake/inflation_test.go +++ b/x/stake/inflation_test.go @@ -214,7 +214,7 @@ func TestLargeBond(t *testing.T) { // initialBondedRatio that we can use to compare to the new values after the unbond initialBondedRatio := pool.bondedRatio() - params := defaultParams() + params := DefaultParams() params.MaxValidators = bondedValidators + 1 //must do this to allow for an extra validator to bond keeper.setParams(ctx, params) @@ -245,7 +245,7 @@ func TestLargeBond(t *testing.T) { // Tests that inflation increases or decreases as expected when we do a random operation on 20 different validators func TestInflationWithRandomOperations(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) - params := defaultParams() + params := DefaultParams() keeper.setParams(ctx, params) numValidators := 20 @@ -343,7 +343,7 @@ func updateProvisions(t *testing.T, keeper Keeper, pool Pool, ctx sdk.Context, h // Allows you to decide how many validators to setup // Allows you to pick which validators are bonded by adjusting the MaxValidators of params func setupTestValidators(pool Pool, keeper Keeper, ctx sdk.Context, validatorTokens []int64, maxValidators uint16) ([]Validator, Keeper, Pool) { - params := defaultParams() + params := DefaultParams() params.MaxValidators = maxValidators keeper.setParams(ctx, params) numValidators := len(validatorTokens) diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 50d8dc37e..3cea0b281 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -150,7 +150,7 @@ func createTestAddrs(numAddrs int) []sdk.Address { buffer.WriteString(numString) //adding on final two digits to make addresses unique res, _ := sdk.GetAccAddressHex(buffer.String()) - bech, _ := sdk.Bech32CosmosifyAcc(res) + bech, _ := sdk.Bech32ifyAcc(res) addresses = append(addresses, testAddr(buffer.String(), bech)) buffer.Reset() } From 04d6ce68989e3e270a4c9386361c8c27211143b8 Mon Sep 17 00:00:00 2001 From: mossid Date: Wed, 6 Jun 2018 18:25:00 -0700 Subject: [PATCH 15/89] add revoked prefix to key, add condition in getbypower --- x/stake/keeper.go | 6 ++++++ x/stake/keeper_keys.go | 13 ++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 9f554c764..fad1f86ef 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -167,6 +167,12 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []Validator { if !found { panic(fmt.Sprintf("validator record not found for address: %v\n", address)) } + + // Reached to revoked validators, stop iterating + if validator.Revoked { + iterator.Close() + break + } if validator.Status() == sdk.Bonded { validators[i] = validator i++ diff --git a/x/stake/keeper_keys.go b/x/stake/keeper_keys.go index 632a86ec3..20062f00e 100644 --- a/x/stake/keeper_keys.go +++ b/x/stake/keeper_keys.go @@ -51,15 +51,22 @@ func GetValidatorsByPowerKey(validator Validator, pool Pool) []byte { powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) // TODO ensure that the key will be a readable string.. probably should add seperators and have + revokedBytes := make([]byte, 1) + if validator.Revoked { + revokedBytes[0] = byte(0x01) + } else { + revokedBytes[0] = byte(0x00) + } // heightBytes and counterBytes represent strings like powerBytes does heightBytes := make([]byte, binary.MaxVarintLen64) binary.BigEndian.PutUint64(heightBytes, ^uint64(validator.BondHeight)) // invert height (older validators first) counterBytes := make([]byte, 2) binary.BigEndian.PutUint16(counterBytes, ^uint16(validator.BondIntraTxCounter)) // invert counter (first txns have priority) return append(ValidatorsByPowerKey, - append(powerBytes, - append(heightBytes, - append(counterBytes, validator.Owner.Bytes()...)...)...)...) // TODO don't technically need to store owner + append(revokedBytes, + append(powerBytes, + append(heightBytes, + append(counterBytes, validator.Owner.Bytes()...)...)...)...)...) // TODO don't technically need to store owner } // get the key for the accumulated update validators From 7baed6d3619d0bd912a27393420f8a3ac466a987 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 7 Jun 2018 21:36:03 +0200 Subject: [PATCH 16/89] Add MustUnBech32() functions --- types/account.go | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/types/account.go b/types/account.go index 00d180a1c..fa471ab49 100644 --- a/types/account.go +++ b/types/account.go @@ -62,6 +62,15 @@ func GetAccAddressBech32(address string) (addr Address, err error) { return Address(bz), nil } +// must create an Address from a string +func MustGetAccAddressBech32(address string) Address { + addr, err := GetAccAddressBech32(address) + if err != nil { + panic(err) + } + return addr +} + // create a Pubkey from a string func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) { bz, err := getFromBech32(address, Bech32PrefixAccPub) @@ -77,6 +86,15 @@ func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) { return pk, nil } +// must create a Pubkey from a string +func MustGetAccPubkeyBec32(address string) crypto.PubKey { + pk, err := GetAccPubKeyBech32(address) + if err != nil { + panic(err) + } + return pk +} + // create an Address from a hex string func GetValAddressHex(address string) (addr Address, err error) { if len(address) == 0 { @@ -98,7 +116,16 @@ func GetValAddressBech32(address string) (addr Address, err error) { return Address(bz), nil } -//Decode a validator publickey into a public key +// must create an Address from a bech32 string +func MustGetValAddressBech32(address string) Address { + addr, err := GetValAddressBech32(address) + if err != nil { + panic(err) + } + return addr +} + +// decode a validator public key into a PubKey func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) { bz, err := getFromBech32(pubkey, Bech32PrefixValPub) if err != nil { @@ -113,6 +140,15 @@ func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) { return pk, nil } +// must decode a validator public key into a PubKey +func MustGetValPubKeyBech32(pubkey string) crypto.PubKey { + pk, err := GetValPubKeyBech32(pubkey) + if err != nil { + panic(err) + } + return pk +} + func getFromBech32(bech32str, prefix string) ([]byte, error) { if len(bech32str) == 0 { return nil, errors.New("must provide non-empty string") From cabb6e68fc7b1afe0693865cb4e4d0278e2f0735 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 7 Jun 2018 23:42:37 +0200 Subject: [PATCH 17/89] bech32ify x/bank/MsgSend --- x/bank/msgs.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/x/bank/msgs.go b/x/bank/msgs.go index 7836056de..ff91ba40f 100644 --- a/x/bank/msgs.go +++ b/x/bank/msgs.go @@ -1,6 +1,8 @@ package bank import ( + "encoding/json" + sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -53,7 +55,20 @@ func (msg MsgSend) ValidateBasic() sdk.Error { // Implements Msg. func (msg MsgSend) GetSignBytes() []byte { - b, err := msgCdc.MarshalJSON(msg) // XXX: ensure some canonical form + var inputs, outputs []json.RawMessage + for _, input := range msg.Inputs { + inputs = append(inputs, input.GetSignBytes()) + } + for _, output := range msg.Outputs { + outputs = append(outputs, output.GetSignBytes()) + } + b, err := msgCdc.MarshalJSON(struct { + Inputs []json.RawMessage `json:"inputs"` + Outputs []json.RawMessage `json:"outputs"` + }{ + Inputs: inputs, + Outputs: outputs, + }) if err != nil { panic(err) } @@ -123,6 +138,24 @@ type Input struct { Coins sdk.Coins `json:"coins"` } +func (in Input) GetSignBytes() []byte { + addr, err := sdk.Bech32ifyAcc(in.Address) + if err != nil { + panic(err) + } + bin, err := msgCdc.MarshalJSON(struct { + Address string `json:"address"` + Coins sdk.Coins `json:"coins"` + }{ + Address: addr, + Coins: in.Coins, + }) + if err != nil { + panic(err) + } + return bin +} + // ValidateBasic - validate transaction input func (in Input) ValidateBasic() sdk.Error { if len(in.Address) == 0 { @@ -155,6 +188,24 @@ type Output struct { Coins sdk.Coins `json:"coins"` } +func (out Output) GetSignBytes() []byte { + addr, err := sdk.Bech32ifyAcc(out.Address) + if err != nil { + panic(err) + } + bin, err := msgCdc.MarshalJSON(struct { + Address string `json:"address"` + Coins sdk.Coins `json:"coins"` + }{ + Address: addr, + Coins: out.Coins, + }) + if err != nil { + panic(err) + } + return bin +} + // ValidateBasic - validate transaction output func (out Output) ValidateBasic() sdk.Error { if len(out.Address) == 0 { From f8896ee7aa374a4e5acf8584618fe990bc0166af Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 7 Jun 2018 23:47:23 +0200 Subject: [PATCH 18/89] Fix x/bank Msg testcases --- x/bank/msgs_test.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/x/bank/msgs_test.go b/x/bank/msgs_test.go index 8f9791c8d..82d61c765 100644 --- a/x/bank/msgs_test.go +++ b/x/bank/msgs_test.go @@ -187,12 +187,14 @@ func TestMsgSendGetSignBytes(t *testing.T) { } res := msg.GetSignBytes() - unmarshaledMsg := &MsgSend{} - msgCdc.UnmarshalJSON(res, unmarshaledMsg) - assert.Equal(t, &msg, unmarshaledMsg) + // TODO Why did we assert this? + /* + unmarshaledMsg := &MsgSend{} + msgCdc.UnmarshalJSON(res, unmarshaledMsg) + assert.Equal(t, &msg, unmarshaledMsg) + */ - // TODO bad results - expected := `{"type":"EAFDE32A2C87F8","value":{"inputs":[{"address":"696E707574","coins":[{"denom":"atom","amount":10}]}],"outputs":[{"address":"6F7574707574","coins":[{"denom":"atom","amount":10}]}]}}` + expected := `{"inputs":[{"address":"cosmosaccaddr1d9h8qat5e4ehc5","coins":[{"denom":"atom","amount":10}]}],"outputs":[{"address":"cosmosaccaddr1da6hgur4wse3jx32","coins":[{"denom":"atom","amount":10}]}]}` assert.Equal(t, expected, string(res)) } From a6c0db71e5d68a71499bb23e3aa01286506a70a9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 8 Jun 2018 00:32:14 +0200 Subject: [PATCH 19/89] Bech32ify GetSignBytes() for x/bank --- types/account.go | 36 ++++++++++++++++++++++++++++++++++++ x/bank/msgs.go | 26 +++++++++++++++----------- x/bank/msgs_test.go | 7 ------- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/types/account.go b/types/account.go index fa471ab49..2c35ca77d 100644 --- a/types/account.go +++ b/types/account.go @@ -26,21 +26,57 @@ func Bech32ifyAcc(addr Address) (string, error) { return bech32.ConvertAndEncode(Bech32PrefixAccAddr, addr.Bytes()) } +// MustBech32ifyAcc panics on bech32-encoding failure +func MustBech32ifyAcc(addr Address) string { + enc, err := Bech32ifyAcc(addr) + if err != nil { + panic(err) + } + return enc +} + // Bech32ifyAccPub takes AccountPubKey and returns the bech32 encoded string func Bech32ifyAccPub(pub crypto.PubKey) (string, error) { return bech32.ConvertAndEncode(Bech32PrefixAccPub, pub.Bytes()) } +// MustBech32ifyAccPub panics on bech32-encoding failure +func MustBech32ifyAccPub(pub crypto.PubKey) string { + enc, err := Bech32ifyAccPub(pub) + if err != nil { + panic(err) + } + return enc +} + // Bech32ifyVal returns the bech32 encoded string for a validator address func Bech32ifyVal(addr Address) (string, error) { return bech32.ConvertAndEncode(Bech32PrefixValAddr, addr.Bytes()) } +// MustBech32ifyVal panics on bech32-encoding failure +func MustBech32ifyVal(addr Address) string { + enc, err := Bech32ifyVal(addr) + if err != nil { + panic(err) + } + return enc +} + // Bech32ifyValPub returns the bech32 encoded string for a validator pubkey func Bech32ifyValPub(pub crypto.PubKey) (string, error) { return bech32.ConvertAndEncode(Bech32PrefixValPub, pub.Bytes()) } +// MustBech32ifyValPub pancis on bech32-encoding failure +func MustBech32ifyValPub(pub crypto.PubKey) string { + enc, err := Bech32ifyValPub(pub) + if err != nil { + panic(err) + } + return enc +} + // create an Address from a string func GetAccAddressHex(address string) (addr Address, err error) { if len(address) == 0 { diff --git a/x/bank/msgs.go b/x/bank/msgs.go index ff91ba40f..e0d73bf08 100644 --- a/x/bank/msgs.go +++ b/x/bank/msgs.go @@ -93,6 +93,8 @@ type MsgIssue struct { Outputs []Output `json:"outputs"` } +var _ sdk.Msg = MsgIssue{} + // NewMsgIssue - construct arbitrary multi-in, multi-out send msg. func NewMsgIssue(banker sdk.Address, out []Output) MsgIssue { return MsgIssue{Banker: banker, Outputs: out} @@ -117,7 +119,17 @@ func (msg MsgIssue) ValidateBasic() sdk.Error { // Implements Msg. func (msg MsgIssue) GetSignBytes() []byte { - b, err := msgCdc.MarshalJSON(msg) // XXX: ensure some canonical form + var outputs []json.RawMessage + for _, output := range msg.Outputs { + outputs = append(outputs, output.GetSignBytes()) + } + b, err := msgCdc.MarshalJSON(struct { + Banker string `json:"banker"` + Outputs []json.RawMessage `json:"outputs"` + }{ + Banker: sdk.MustBech32ifyAcc(msg.Banker), + Outputs: outputs, + }) if err != nil { panic(err) } @@ -139,15 +151,11 @@ type Input struct { } func (in Input) GetSignBytes() []byte { - addr, err := sdk.Bech32ifyAcc(in.Address) - if err != nil { - panic(err) - } bin, err := msgCdc.MarshalJSON(struct { Address string `json:"address"` Coins sdk.Coins `json:"coins"` }{ - Address: addr, + Address: sdk.MustBech32ifyAcc(in.Address), Coins: in.Coins, }) if err != nil { @@ -189,15 +197,11 @@ type Output struct { } func (out Output) GetSignBytes() []byte { - addr, err := sdk.Bech32ifyAcc(out.Address) - if err != nil { - panic(err) - } bin, err := msgCdc.MarshalJSON(struct { Address string `json:"address"` Coins sdk.Coins `json:"coins"` }{ - Address: addr, + Address: sdk.MustBech32ifyAcc(out.Address), Coins: out.Coins, }) if err != nil { diff --git a/x/bank/msgs_test.go b/x/bank/msgs_test.go index 82d61c765..06adad1ef 100644 --- a/x/bank/msgs_test.go +++ b/x/bank/msgs_test.go @@ -187,13 +187,6 @@ func TestMsgSendGetSignBytes(t *testing.T) { } res := msg.GetSignBytes() - // TODO Why did we assert this? - /* - unmarshaledMsg := &MsgSend{} - msgCdc.UnmarshalJSON(res, unmarshaledMsg) - assert.Equal(t, &msg, unmarshaledMsg) - */ - expected := `{"inputs":[{"address":"cosmosaccaddr1d9h8qat5e4ehc5","coins":[{"denom":"atom","amount":10}]}],"outputs":[{"address":"cosmosaccaddr1da6hgur4wse3jx32","coins":[{"denom":"atom","amount":10}]}]}` assert.Equal(t, expected, string(res)) } From b166cc237faabab225a76fce7e692a794b390f10 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 8 Jun 2018 00:35:13 +0200 Subject: [PATCH 20/89] Testcase/linter fixes --- x/bank/msgs.go | 2 ++ x/bank/msgs_test.go | 7 +------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/x/bank/msgs.go b/x/bank/msgs.go index e0d73bf08..48e62d835 100644 --- a/x/bank/msgs.go +++ b/x/bank/msgs.go @@ -150,6 +150,7 @@ type Input struct { Coins sdk.Coins `json:"coins"` } +// Return bytes to sign for Input func (in Input) GetSignBytes() []byte { bin, err := msgCdc.MarshalJSON(struct { Address string `json:"address"` @@ -196,6 +197,7 @@ type Output struct { Coins sdk.Coins `json:"coins"` } +// Return bytes to sign for Output func (out Output) GetSignBytes() []byte { bin, err := msgCdc.MarshalJSON(struct { Address string `json:"address"` diff --git a/x/bank/msgs_test.go b/x/bank/msgs_test.go index 06adad1ef..90b4869db 100644 --- a/x/bank/msgs_test.go +++ b/x/bank/msgs_test.go @@ -257,12 +257,7 @@ func TestMsgIssueGetSignBytes(t *testing.T) { } res := msg.GetSignBytes() - unmarshaledMsg := &MsgIssue{} - msgCdc.UnmarshalJSON(res, unmarshaledMsg) - assert.Equal(t, &msg, unmarshaledMsg) - - // TODO bad results - expected := `{"type":"72E617C06ABAD0","value":{"banker":"696E707574","outputs":[{"address":"6C6F616E2D66726F6D2D62616E6B","coins":[{"denom":"atom","amount":10}]}]}}` + expected := `{"banker":"cosmosaccaddr1d9h8qat5e4ehc5","outputs":[{"address":"cosmosaccaddr1d3hkzm3dveex7mfdvfsku6cwsauqd","coins":[{"denom":"atom","amount":10}]}]}` assert.Equal(t, expected, string(res)) } From f58b454985a146d1aebcf53588d56cbf8c08d273 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 7 Jun 2018 16:13:11 -0700 Subject: [PATCH 21/89] mock application framework compiling --- tests/mock/app.go | 85 +++++++++++++++++++++++++++++ tests/mock/simulate_block.go | 100 +++++++++++++++++++++++++++++++++++ x/bank/app_test.go | 96 +++++++++++++++++++++++++++++++++ 3 files changed, 281 insertions(+) create mode 100644 tests/mock/app.go create mode 100644 tests/mock/simulate_block.go create mode 100644 x/bank/app_test.go diff --git a/tests/mock/app.go b/tests/mock/app.go new file mode 100644 index 000000000..f7b7a0a34 --- /dev/null +++ b/tests/mock/app.go @@ -0,0 +1,85 @@ +package mock + +import ( + "testing" + + "os" + + "github.com/stretchr/testify/require" + abci "github.com/tendermint/abci/types" + 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" +) + +// Extended ABCI application +type App struct { + *bam.BaseApp + Cdc *wire.Codec // public since the codec is passed into the module anyways. + KeyMain *sdk.KVStoreKey + KeyAccount *sdk.KVStoreKey + + // TODO: Abstract this out from not needing to be auth specifically + AccountMapper auth.AccountMapper + FeeCollectionKeeper auth.FeeCollectionKeeper + + GenesisAccounts []auth.Account +} + +// NewApp is used for testing the server. For the internal mock app stuff, it uses code in helpers.go +func NewApp() *App { + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") + db := dbm.NewMemDB() + + // create the cdc with some standard codecs + cdc := wire.NewCodec() + sdk.RegisterWire(cdc) + wire.RegisterCrypto(cdc) + + // create your application object + app := &App{ + BaseApp: bam.NewBaseApp("mock", cdc, logger, db), + Cdc: cdc, + KeyMain: sdk.NewKVStoreKey("main"), + KeyAccount: sdk.NewKVStoreKey("acc"), + } + + // define the accountMapper + app.AccountMapper = auth.NewAccountMapper( + app.Cdc, + app.KeyAccount, // target store + &auth.BaseAccount{}, // prototype + ) + + // initialize the app, the chainers and blockers can be overwritten before calling complete setup + app.SetInitChainer(app.initChainer) + + app.SetAnteHandler(auth.NewAnteHandler(app.AccountMapper, app.FeeCollectionKeeper)) + + return app +} + +// complete the application setup after the routes have been registered +func (app App) CompleteSetup(t *testing.T, newKeys []*sdk.KVStoreKey) { + + newKeys = append(newKeys, app.KeyMain) + newKeys = append(newKeys, app.KeyAccount) + app.MountStoresIAVL(newKeys...) + err := app.LoadLatestVersion(app.KeyMain) + require.NoError(t, err) +} + +// custom logic for initialization +func (app App) initChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain { + + // load the accounts + for _, acc := range app.GenesisAccounts { + app.AccountMapper.SetAccount(ctx, acc) + } + + return abci.ResponseInitChain{} +} diff --git a/tests/mock/simulate_block.go b/tests/mock/simulate_block.go new file mode 100644 index 000000000..fa1000af7 --- /dev/null +++ b/tests/mock/simulate_block.go @@ -0,0 +1,100 @@ +package mock + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + crypto "github.com/tendermint/go-crypto" + + abci "github.com/tendermint/abci/types" +) + +var chainID = "" // TODO + +// set the mock app genesis +func SetGenesis(app *App, accs []auth.Account) { + + // pass the accounts in via the application (lazy) instead of through RequestInitChain + app.GenesisAccounts = accs + + app.InitChain(abci.RequestInitChain{}) + app.Commit() +} + +// check an account balance +func CheckBalance(t *testing.T, app *App, addr sdk.Address, exp sdk.Coins) { + ctxDeliver := app.BaseApp.NewContext(false, abci.Header{}) + res := app.AccountMapper.GetAccount(ctxDeliver, addr) + assert.Equal(t, exp, res.GetCoins()) +} + +// generate a signed transaction +func GenTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { + + // make the transaction free + fee := auth.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 100000, + } + + sigs := make([]auth.StdSignature, len(priv)) + for i, p := range priv { + sigs[i] = auth.StdSignature{ + PubKey: p.PubKey(), + Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), + Sequence: seq[i], + } + } + return auth.NewStdTx(msg, fee, sigs) +} + +// simulate a block +func SignCheckDeliver(t *testing.T, app *App, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { + + // Sign the tx + tx := GenTx(msg, seq, priv...) + + // Run a Check + res := app.Check(tx) + if expPass { + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) + } + + // Simulate a Block + app.BeginBlock(abci.RequestBeginBlock{}) + res = app.Deliver(tx) + if expPass { + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) + } + app.EndBlock(abci.RequestEndBlock{}) + + // XXX fix code or add explaination as to why using commit breaks a bunch of these tests + //app.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, app App, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { + + // Sign the tx + tx := GenTx(msg, seq, priv...) + + // Simulate a Block + app.BeginBlock(abci.RequestBeginBlock{}) + res := app.Deliver(tx) + if expPass { + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) + } + app.EndBlock(abci.RequestEndBlock{}) +} diff --git a/x/bank/app_test.go b/x/bank/app_test.go new file mode 100644 index 000000000..3dcf37c22 --- /dev/null +++ b/x/bank/app_test.go @@ -0,0 +1,96 @@ +package bank + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/tests/mock" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +// test bank module in a mock application +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 = auth.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 100000, + } + + sendMsg1 = MsgSend{ + Inputs: []Input{NewInput(addr1, coins)}, + Outputs: []Output{NewOutput(addr2, coins)}, + } +) + +func TestMsgSendWithAccounts(t *testing.T) { + + // initialize the mock application + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + coinKeeper := NewKeeper(mapp.AccountMapper) + mapp.Router().AddRoute("bank", NewHandler(coinKeeper)) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{}) + + // Add an account at genesis + coins, err := sdk.ParseCoins("77foocoin") + require.Nil(t, err) + //acc := auth.NewAccountWithAddress(addr1) + //acc.SetCoins(coins) + //accs := []auth.Account{acc} + + baseAcc := &auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + baseAccs := []auth.Account{baseAcc} + + // Construct genesis state + mock.SetGenesis(mapp, baseAccs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + require.NotNil(t, res1) + assert.Equal(t, baseAcc, res1.(*auth.BaseAccount)) + + // Run a CheckDeliver + mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, true, priv1) + + // Check balances + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 67}}) + mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) + + // Delivering again should cause replay error + mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, false, priv1) + + // bumping the txnonce number without resigning should be an auth error + tx := mock.GenTx(sendMsg1, []int64{0}, priv1) + tx.Signatures[0].Sequence = 1 + res := mapp.Deliver(tx) + + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) + + // resigning the tx with the bumped sequence should work + mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{1}, true, priv1) +} From 971e1489b21214a05ef7ce5623eaf5ec3c12adac Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 8 Jun 2018 01:24:08 +0200 Subject: [PATCH 22/89] Bech32ify msg.GetSignBytes() for x/slashing & x/stake --- x/slashing/msg.go | 6 +++++- x/stake/msg.go | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/x/slashing/msg.go b/x/slashing/msg.go index d2676af81..acf5f9d93 100644 --- a/x/slashing/msg.go +++ b/x/slashing/msg.go @@ -30,7 +30,11 @@ func (msg MsgUnrevoke) GetSigners() []sdk.Address { return []sdk.Address{msg.Val // get the bytes for the message signer to sign on func (msg MsgUnrevoke) GetSignBytes() []byte { - b, err := cdc.MarshalJSON(msg) + b, err := cdc.MarshalJSON(struct { + ValidatorAddr string `json:"address"` + }{ + ValidatorAddr: sdk.MustBech32ifyAcc(msg.ValidatorAddr), + }) if err != nil { panic(err) } diff --git a/x/stake/msg.go b/x/stake/msg.go index 40bf609ee..a0922bb87 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -45,7 +45,20 @@ func (msg MsgCreateValidator) GetSigners() []sdk.Address { // get the bytes for the message signer to sign on func (msg MsgCreateValidator) GetSignBytes() []byte { - return msgCdc.MustMarshalBinary(msg) + b, err := msgCdc.MarshalJSON(struct { + Description + ValidatorAddr string `json:"address"` + PubKey string `json:"pubkey"` + Bond sdk.Coin `json:"bond"` + }{ + Description: msg.Description, + ValidatorAddr: sdk.MustBech32ifyVal(msg.ValidatorAddr), + PubKey: sdk.MustBech32ifyValPub(msg.PubKey), + }) + if err != nil { + panic(err) + } + return b } // quick validity check @@ -89,7 +102,13 @@ func (msg MsgEditValidator) GetSigners() []sdk.Address { // get the bytes for the message signer to sign on func (msg MsgEditValidator) GetSignBytes() []byte { - b, err := msgCdc.MarshalJSON(msg) + b, err := msgCdc.MarshalJSON(struct { + Description + ValidatorAddr string `json:"address"` + }{ + Description: msg.Description, + ValidatorAddr: sdk.MustBech32ifyVal(msg.ValidatorAddr), + }) if err != nil { panic(err) } @@ -133,7 +152,15 @@ func (msg MsgDelegate) GetSigners() []sdk.Address { // get the bytes for the message signer to sign on func (msg MsgDelegate) GetSignBytes() []byte { - b, err := msgCdc.MarshalJSON(msg) + b, err := msgCdc.MarshalJSON(struct { + DelegatorAddr string `json:"delegator_addr"` + ValidatorAddr string `json:"validator_addr"` + Bond sdk.Coin `json:"bond"` + }{ + DelegatorAddr: sdk.MustBech32ifyAcc(msg.DelegatorAddr), + ValidatorAddr: sdk.MustBech32ifyVal(msg.ValidatorAddr), + Bond: msg.Bond, + }) if err != nil { panic(err) } @@ -180,7 +207,15 @@ func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.Deleg // get the bytes for the message signer to sign on func (msg MsgUnbond) GetSignBytes() []byte { - b, err := msgCdc.MarshalJSON(msg) + b, err := msgCdc.MarshalJSON(struct { + DelegatorAddr string `json:"delegator_addr"` + ValidatorAddr string `json:"validator_addr"` + Shares string `json:"shares"` + }{ + DelegatorAddr: sdk.MustBech32ifyAcc(msg.DelegatorAddr), + ValidatorAddr: sdk.MustBech32ifyVal(msg.ValidatorAddr), + Shares: msg.Shares, + }) if err != nil { panic(err) } From cbc6989ed60036e99ec74b02333a891bbabc50fc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 8 Jun 2018 01:49:37 +0200 Subject: [PATCH 23/89] Bech32ify msg.GetSignBytes() for x/ibc --- x/ibc/types.go | 51 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/x/ibc/types.go b/x/ibc/types.go index 09a853b20..76239102a 100644 --- a/x/ibc/types.go +++ b/x/ibc/types.go @@ -1,11 +1,20 @@ package ibc import ( - sdk "github.com/cosmos/cosmos-sdk/types" + "encoding/json" + sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" ) +var ( + msgCdc *wire.Codec +) + +func init() { + msgCdc = wire.NewCodec() +} + // ------------------------------ // IBCPacket @@ -32,6 +41,26 @@ func NewIBCPacket(srcAddr sdk.Address, destAddr sdk.Address, coins sdk.Coins, } } +func (p IBCPacket) GetSignBytes() []byte { + b, err := msgCdc.MarshalJSON(struct { + SrcAddr string + DestAddr string + Coins sdk.Coins + SrcChain string + DestChain string + }{ + SrcAddr: sdk.MustBech32ifyAcc(p.SrcAddr), + DestAddr: sdk.MustBech32ifyAcc(p.DestAddr), + Coins: p.Coins, + SrcChain: p.SrcChain, + DestChain: p.DestChain, + }) + if err != nil { + panic(err) + } + return b +} + // validator the ibc packey func (ibcp IBCPacket) ValidateBasic() sdk.Error { if ibcp.SrcChain == ibcp.DestChain { @@ -60,12 +89,7 @@ func (msg IBCTransferMsg) GetSigners() []sdk.Address { return []sdk.Address{msg. // get the sign bytes for ibc transfer message func (msg IBCTransferMsg) GetSignBytes() []byte { - cdc := wire.NewCodec() - bz, err := cdc.MarshalBinary(msg) - if err != nil { - panic(err) - } - return bz + return msg.IBCPacket.GetSignBytes() } // validate ibc transfer message @@ -94,10 +118,17 @@ func (msg IBCReceiveMsg) GetSigners() []sdk.Address { return []sdk.Address{msg.R // get the sign bytes for ibc receive message func (msg IBCReceiveMsg) GetSignBytes() []byte { - cdc := wire.NewCodec() - bz, err := cdc.MarshalBinary(msg) + b, err := msgCdc.MarshalJSON(struct { + IBCPacket json.RawMessage + Relayer string + Sequence int64 + }{ + IBCPacket: json.RawMessage(msg.IBCPacket.GetSignBytes()), + Relayer: sdk.MustBech32ifyAcc(msg.Relayer), + Sequence: msg.Sequence, + }) if err != nil { panic(err) } - return bz + return b } From 34ec53a76139d8f76b485d9b6d808d75338dc17b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 8 Jun 2018 01:50:59 +0200 Subject: [PATCH 24/89] Update CHANGELOG.md, update x/auth to avoid base64 --- CHANGELOG.md | 1 + x/auth/stdtx.go | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d6541691..e34a1468b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog BREAKING CHANGES +* msg.GetSignBytes() now returns bech32-encoded addresses in all cases FEATURES diff --git a/x/auth/stdtx.go b/x/auth/stdtx.go index 4858ae0b4..e08f77ee4 100644 --- a/x/auth/stdtx.go +++ b/x/auth/stdtx.go @@ -1,6 +1,8 @@ package auth import ( + "encoding/json" + sdk "github.com/cosmos/cosmos-sdk/types" crypto "github.com/tendermint/go-crypto" ) @@ -83,11 +85,11 @@ func (fee StdFee) Bytes() []byte { // and the Sequence numbers for each signature (prevent // inchain replay and enforce tx ordering per account). type StdSignDoc struct { - ChainID string `json:"chain_id"` - Sequences []int64 `json:"sequences"` - FeeBytes []byte `json:"fee_bytes"` - MsgBytes []byte `json:"msg_bytes"` - AltBytes []byte `json:"alt_bytes"` + ChainID string `json:"chain_id"` + Sequences []int64 `json:"sequences"` + FeeBytes json.RawMessage `json:"fee_bytes"` + MsgBytes json.RawMessage `json:"msg_bytes"` + AltBytes json.RawMessage `json:"alt_bytes"` } // StdSignBytes returns the bytes to sign for a transaction. @@ -96,8 +98,8 @@ func StdSignBytes(chainID string, sequences []int64, fee StdFee, msg sdk.Msg) [] bz, err := msgCdc.MarshalJSON(StdSignDoc{ ChainID: chainID, Sequences: sequences, - FeeBytes: fee.Bytes(), - MsgBytes: msg.GetSignBytes(), + FeeBytes: json.RawMessage(fee.Bytes()), + MsgBytes: json.RawMessage(msg.GetSignBytes()), }) if err != nil { panic(err) From a583a70b7c5c09ef10b381affbfb465c91a85e77 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 8 Jun 2018 01:59:10 +0200 Subject: [PATCH 25/89] Fix address type for x/slashing/MsgUnrevoke --- x/slashing/msg.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/slashing/msg.go b/x/slashing/msg.go index acf5f9d93..561c92266 100644 --- a/x/slashing/msg.go +++ b/x/slashing/msg.go @@ -33,7 +33,7 @@ func (msg MsgUnrevoke) GetSignBytes() []byte { b, err := cdc.MarshalJSON(struct { ValidatorAddr string `json:"address"` }{ - ValidatorAddr: sdk.MustBech32ifyAcc(msg.ValidatorAddr), + ValidatorAddr: sdk.MustBech32ifyVal(msg.ValidatorAddr), }) if err != nil { panic(err) From 496d4681c2d0167713effc34b4a580ae267cee28 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 8 Jun 2018 02:05:34 +0200 Subject: [PATCH 26/89] Add MsgUnrevoke.GetSignBytes() testcase, remove unused functions --- types/account.go | 36 ------------------------------------ x/slashing/msg_test.go | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 36 deletions(-) create mode 100644 x/slashing/msg_test.go diff --git a/types/account.go b/types/account.go index 2c35ca77d..381fb7af8 100644 --- a/types/account.go +++ b/types/account.go @@ -98,15 +98,6 @@ func GetAccAddressBech32(address string) (addr Address, err error) { return Address(bz), nil } -// must create an Address from a string -func MustGetAccAddressBech32(address string) Address { - addr, err := GetAccAddressBech32(address) - if err != nil { - panic(err) - } - return addr -} - // create a Pubkey from a string func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) { bz, err := getFromBech32(address, Bech32PrefixAccPub) @@ -122,15 +113,6 @@ func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) { return pk, nil } -// must create a Pubkey from a string -func MustGetAccPubkeyBec32(address string) crypto.PubKey { - pk, err := GetAccPubKeyBech32(address) - if err != nil { - panic(err) - } - return pk -} - // create an Address from a hex string func GetValAddressHex(address string) (addr Address, err error) { if len(address) == 0 { @@ -152,15 +134,6 @@ func GetValAddressBech32(address string) (addr Address, err error) { return Address(bz), nil } -// must create an Address from a bech32 string -func MustGetValAddressBech32(address string) Address { - addr, err := GetValAddressBech32(address) - if err != nil { - panic(err) - } - return addr -} - // decode a validator public key into a PubKey func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) { bz, err := getFromBech32(pubkey, Bech32PrefixValPub) @@ -176,15 +149,6 @@ func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) { return pk, nil } -// must decode a validator public key into a PubKey -func MustGetValPubKeyBech32(pubkey string) crypto.PubKey { - pk, err := GetValPubKeyBech32(pubkey) - if err != nil { - panic(err) - } - return pk -} - func getFromBech32(bech32str, prefix string) ([]byte, error) { if len(bech32str) == 0 { return nil, errors.New("must provide non-empty string") diff --git a/x/slashing/msg_test.go b/x/slashing/msg_test.go new file mode 100644 index 000000000..be7797107 --- /dev/null +++ b/x/slashing/msg_test.go @@ -0,0 +1,16 @@ +package slashing + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestMsgUnrevokeGetSignBytes(t *testing.T) { + addr := sdk.Address("abcd") + msg := NewMsgUnrevoke(addr) + bytes := msg.GetSignBytes() + assert.Equal(t, string(bytes), `{"address":"cosmosvaladdr1v93xxeqamr0mv"}`) +} From 1e6776848552fa90d63519d50042edf7c8e07dfb Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 7 Jun 2018 17:20:35 -0700 Subject: [PATCH 27/89] ported ibc tests --- cmd/gaia/app/app_test.go | 213 --------------------------------------- tests/mock/app.go | 5 +- x/bank/app_test.go | 149 +++++++++++++++++++++++---- x/ibc/app_test.go | 79 +++++++++++++++ 4 files changed, 213 insertions(+), 233 deletions(-) create mode 100644 x/ibc/app_test.go diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 0fe1cfe5b..1ec24d017 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -12,7 +12,6 @@ import ( "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" abci "github.com/tendermint/abci/types" @@ -46,43 +45,6 @@ var ( Inputs: []bank.Input{bank.NewInput(addr1, coins)}, Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, } - - sendMsg2 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{ - bank.NewOutput(addr2, halfCoins), - bank.NewOutput(addr3, halfCoins), - }, - } - - sendMsg3 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, coins), - bank.NewInput(addr4, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, coins), - bank.NewOutput(addr3, coins), - }, - } - - sendMsg4 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr2, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr1, coins), - }, - } - - sendMsg5 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, manyCoins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, manyCoins), - }, - } ) func loggerAndDB() (log.Logger, dbm.DB) { @@ -167,181 +129,6 @@ func TestGenesis(t *testing.T) { assert.Equal(t, baseAcc, res1) } -func TestMsgSendWithAccounts(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 = setGenesis(gapp, baseAcc) - require.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.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) -} - -func TestMsgSendMultipleOut(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 = setGenesis(gapp, acc1, acc2) - require.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 = setGenesis(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 TestMsgSendDependent(t *testing.T) { - gapp := newGaiaApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := &auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - err = setGenesis(gapp, acc1) - require.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 := setGenesis(gapp, baseAcc) - require.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 TestStakeMsgs(t *testing.T) { gapp := newGaiaApp() diff --git a/tests/mock/app.go b/tests/mock/app.go index f7b7a0a34..6a3933005 100644 --- a/tests/mock/app.go +++ b/tests/mock/app.go @@ -39,6 +39,7 @@ func NewApp() *App { cdc := wire.NewCodec() sdk.RegisterWire(cdc) wire.RegisterCrypto(cdc) + auth.RegisterWire(cdc) // create your application object app := &App{ @@ -64,7 +65,7 @@ func NewApp() *App { } // complete the application setup after the routes have been registered -func (app App) CompleteSetup(t *testing.T, newKeys []*sdk.KVStoreKey) { +func (app *App) CompleteSetup(t *testing.T, newKeys []*sdk.KVStoreKey) { newKeys = append(newKeys, app.KeyMain) newKeys = append(newKeys, app.KeyAccount) @@ -74,7 +75,7 @@ func (app App) CompleteSetup(t *testing.T, newKeys []*sdk.KVStoreKey) { } // custom logic for initialization -func (app App) initChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain { +func (app *App) initChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain { // load the accounts for _, acc := range app.GenesisAccounts { diff --git a/x/bank/app_test.go b/x/bank/app_test.go index 3dcf37c22..ecbb66145 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -18,8 +18,6 @@ import ( var ( chainID = "" // TODO - accName = "foobart" - priv1 = crypto.GenPrivKeyEd25519() addr1 = priv1.PubKey().Address() priv2 = crypto.GenPrivKeyEd25519() @@ -30,7 +28,8 @@ var ( coins = sdk.Coins{{"foocoin", 10}} halfCoins = sdk.Coins{{"foocoin", 5}} manyCoins = sdk.Coins{{"foocoin", 1}, {"barcoin", 1}} - fee = auth.StdFee{ + + freeFee = auth.StdFee{ // no fees for a buncha gas sdk.Coins{{"foocoin", 0}}, 100000, } @@ -39,11 +38,47 @@ var ( Inputs: []Input{NewInput(addr1, coins)}, Outputs: []Output{NewOutput(addr2, coins)}, } + + sendMsg2 = MsgSend{ + Inputs: []Input{NewInput(addr1, coins)}, + Outputs: []Output{ + NewOutput(addr2, halfCoins), + NewOutput(addr3, halfCoins), + }, + } + + sendMsg3 = MsgSend{ + Inputs: []Input{ + NewInput(addr1, coins), + NewInput(addr4, coins), + }, + Outputs: []Output{ + NewOutput(addr2, coins), + NewOutput(addr3, coins), + }, + } + + sendMsg4 = MsgSend{ + Inputs: []Input{ + NewInput(addr2, coins), + }, + Outputs: []Output{ + NewOutput(addr1, coins), + }, + } + + sendMsg5 = MsgSend{ + Inputs: []Input{ + NewInput(addr1, manyCoins), + }, + Outputs: []Output{ + NewOutput(addr2, manyCoins), + }, + } ) -func TestMsgSendWithAccounts(t *testing.T) { - - // initialize the mock application +// initialize the mock application for this module +func getMockApp(t *testing.T) *mock.App { mapp := mock.NewApp() RegisterWire(mapp.Cdc) @@ -51,34 +86,33 @@ func TestMsgSendWithAccounts(t *testing.T) { mapp.Router().AddRoute("bank", NewHandler(coinKeeper)) mapp.CompleteSetup(t, []*sdk.KVStoreKey{}) + return mapp +} + +func TestMsgSendWithAccounts(t *testing.T) { + mapp := getMockApp(t) // Add an account at genesis - coins, err := sdk.ParseCoins("77foocoin") - require.Nil(t, err) - //acc := auth.NewAccountWithAddress(addr1) - //acc.SetCoins(coins) - //accs := []auth.Account{acc} - - baseAcc := &auth.BaseAccount{ + acc := &auth.BaseAccount{ Address: addr1, - Coins: coins, + Coins: sdk.Coins{{"foocoin", 67}}, } - baseAccs := []auth.Account{baseAcc} + accs := []auth.Account{acc} // Construct genesis state - mock.SetGenesis(mapp, baseAccs) + mock.SetGenesis(mapp, accs) // A checkTx context (true) ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) require.NotNil(t, res1) - assert.Equal(t, baseAcc, res1.(*auth.BaseAccount)) + assert.Equal(t, acc, res1.(*auth.BaseAccount)) // Run a CheckDeliver mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, true, priv1) // Check balances - mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 67}}) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 57}}) mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) // Delivering again should cause replay error @@ -94,3 +128,82 @@ func TestMsgSendWithAccounts(t *testing.T) { // resigning the tx with the bumped sequence should work mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{1}, true, priv1) } + +func TestMsgSendMultipleOut(t *testing.T) { + mapp := getMockApp(t) + + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: sdk.Coins{{"foocoin", 42}}, + } + + acc2 := &auth.BaseAccount{ + Address: addr2, + Coins: sdk.Coins{{"foocoin", 42}}, + } + accs := []auth.Account{acc1, acc2} + + mock.SetGenesis(mapp, accs) + + // Simulate a Block + mock.SignCheckDeliver(t, mapp, sendMsg2, []int64{0}, true, priv1) + + // Check balances + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) + mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 47}}) + mock.CheckBalance(t, mapp, addr3, sdk.Coins{{"foocoin", 5}}) +} + +func TestSengMsgMultipleInOut(t *testing.T) { + mapp := getMockApp(t) + + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: sdk.Coins{{"foocoin", 42}}, + } + acc2 := &auth.BaseAccount{ + Address: addr2, + Coins: sdk.Coins{{"foocoin", 42}}, + } + acc4 := &auth.BaseAccount{ + Address: addr4, + Coins: sdk.Coins{{"foocoin", 42}}, + } + accs := []auth.Account{acc1, acc2, acc4} + + mock.SetGenesis(mapp, accs) + + // CheckDeliver + mock.SignCheckDeliver(t, mapp, sendMsg3, []int64{0, 0}, true, priv1, priv4) + + // Check balances + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) + mock.CheckBalance(t, mapp, addr4, sdk.Coins{{"foocoin", 32}}) + mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 52}}) + mock.CheckBalance(t, mapp, addr3, sdk.Coins{{"foocoin", 10}}) +} + +func TestMsgSendDependent(t *testing.T) { + mapp := getMockApp(t) + + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: sdk.Coins{{"foocoin", 42}}, + } + accs := []auth.Account{acc1} + + mock.SetGenesis(mapp, accs) + + // CheckDeliver + mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, true, priv1) + + // Check balances + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) + mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) + + // Simulate a Block + mock.SignCheckDeliver(t, mapp, sendMsg4, []int64{0}, true, priv2) + + // Check balances + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 42}}) +} diff --git a/x/ibc/app_test.go b/x/ibc/app_test.go new file mode 100644 index 000000000..0124e417e --- /dev/null +++ b/x/ibc/app_test.go @@ -0,0 +1,79 @@ +package ibc + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/cosmos/cosmos-sdk/tests/mock" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) *mock.App { + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + keyIBC := sdk.NewKVStoreKey("ibc") + ibcMapper := NewMapper(mapp.Cdc, keyIBC, mapp.RegisterCodespace(DefaultCodespace)) + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + mapp.Router().AddRoute("ibc", NewHandler(ibcMapper, coinKeeper)) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{keyIBC}) + return mapp +} + +func TestIBCMsgs(t *testing.T) { + gapp := getMockApp(t) + + sourceChain := "source-chain" + destChain := "dest-chain" + + priv1 := crypto.GenPrivKeyEd25519() + addr1 := priv1.PubKey().Address() + coins := sdk.Coins{{"foocoin", 10}} + var emptyCoins sdk.Coins + + acc := &auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + accs := []auth.Account{acc} + + mock.SetGenesis(gapp, accs) + + // A checkTx context (true) + ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) + res1 := gapp.AccountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc, res1) + + packet := IBCPacket{ + SrcAddr: addr1, + DestAddr: addr1, + Coins: coins, + SrcChain: sourceChain, + DestChain: destChain, + } + + transferMsg := IBCTransferMsg{ + IBCPacket: packet, + } + + receiveMsg := IBCReceiveMsg{ + IBCPacket: packet, + Relayer: addr1, + Sequence: 0, + } + + mock.SignCheckDeliver(t, gapp, transferMsg, []int64{0}, true, priv1) + mock.CheckBalance(t, gapp, addr1, emptyCoins) + mock.SignCheckDeliver(t, gapp, transferMsg, []int64{1}, false, priv1) + mock.SignCheckDeliver(t, gapp, receiveMsg, []int64{2}, true, priv1) + mock.CheckBalance(t, gapp, addr1, coins) + mock.SignCheckDeliver(t, gapp, receiveMsg, []int64{3}, false, priv1) +} From 946f952de1cf3d7fee2bbae5c0180814671ec799 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 8 Jun 2018 03:28:40 +0200 Subject: [PATCH 28/89] Linter fixes --- x/ibc/types.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x/ibc/types.go b/x/ibc/types.go index 76239102a..4924aec4b 100644 --- a/x/ibc/types.go +++ b/x/ibc/types.go @@ -41,6 +41,7 @@ func NewIBCPacket(srcAddr sdk.Address, destAddr sdk.Address, coins sdk.Coins, } } +//nolint func (p IBCPacket) GetSignBytes() []byte { b, err := msgCdc.MarshalJSON(struct { SrcAddr string @@ -62,11 +63,11 @@ func (p IBCPacket) GetSignBytes() []byte { } // validator the ibc packey -func (ibcp IBCPacket) ValidateBasic() sdk.Error { - if ibcp.SrcChain == ibcp.DestChain { +func (p IBCPacket) ValidateBasic() sdk.Error { + if p.SrcChain == p.DestChain { return ErrIdenticalChains(DefaultCodespace).Trace("") } - if !ibcp.Coins.IsValid() { + if !p.Coins.IsValid() { return sdk.ErrInvalidCoins("") } return nil From abab7c2e42eb694147879b755faae8534274f94a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 7 Jun 2018 20:55:14 -0700 Subject: [PATCH 29/89] modules test within mock application --- cmd/gaia/app/app_test.go | 212 +--------- examples/basecoin/app/app_test.go | 473 +---------------------- examples/democoin/app/app_test.go | 368 +----------------- examples/democoin/x/cool/app_test.go | 105 +++++ examples/democoin/x/pow/app_test.go | 83 ++++ {tests => x/auth}/mock/app.go | 4 +- x/auth/mock/auth_app_test.go | 111 ++++++ {tests => x/auth}/mock/simulate_block.go | 5 +- x/bank/app_test.go | 18 +- x/ibc/app_test.go | 22 +- x/stake/app_test.go | 152 ++++++++ 11 files changed, 497 insertions(+), 1056 deletions(-) create mode 100644 examples/democoin/x/cool/app_test.go create mode 100644 examples/democoin/x/pow/app_test.go rename {tests => x/auth}/mock/app.go (95%) create mode 100644 x/auth/mock/auth_app_test.go rename {tests => x/auth}/mock/simulate_block.go (89%) create mode 100644 x/stake/app_test.go diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 1ec24d017..0f6bab134 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -1,17 +1,16 @@ package app import ( - "fmt" "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/x/auth/mock" 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/stake" abci "github.com/tendermint/abci/types" @@ -20,31 +19,13 @@ import ( "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 = auth.StdFee{ - sdk.Coins{{"foocoin", 0}}, - 100000, - } - - sendMsg1 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + priv2 = crypto.GenPrivKeyEd25519() + addr2 = priv2.PubKey().Address() ) func loggerAndDB() (log.Logger, dbm.DB) { @@ -53,11 +34,6 @@ func loggerAndDB() (log.Logger, dbm.DB) { return logger, db } -func newGaiaApp() *GaiaApp { - logger, db := loggerAndDB() - return NewGaiaApp(logger, db) -} - func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { genaccs := make([]GenesisAccount, len(accs)) for i, acc := range accs { @@ -84,22 +60,6 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { //_______________________________________________________________________ -func TestMsgs(t *testing.T) { - gapp := newGaiaApp() - require.Nil(t, setGenesis(gapp)) - - 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 TestGenesis(t *testing.T) { logger, dbs := loggerAndDB() gapp := NewGaiaApp(logger, dbs) @@ -129,96 +89,9 @@ func TestGenesis(t *testing.T) { assert.Equal(t, baseAcc, res1) } -func TestStakeMsgs(t *testing.T) { - gapp := newGaiaApp() - - genCoins, err := sdk.ParseCoins("42steak") - require.Nil(t, err) - bondCoin, err := sdk.ParseCoin("10steak") - 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) - - // Create Validator - - description := stake.NewDescription("foo_moniker", "", "", "") - createValidatorMsg := stake.NewMsgCreateValidator( - addr1, priv1.PubKey(), bondCoin, description, - ) - SignCheckDeliver(t, gapp, createValidatorMsg, []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()) - validator, found := gapp.stakeKeeper.GetValidator(ctxDeliver, addr1) - require.True(t, found) - require.Equal(t, addr1, validator.Owner) - require.Equal(t, sdk.Bonded, validator.Status()) - require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) - - // check the bond that should have been created as well - bond, found := gapp.stakeKeeper.GetDelegation(ctxDeliver, addr1, addr1) - require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) - - // Edit Validator - - description = stake.NewDescription("bar_moniker", "", "", "") - editValidatorMsg := stake.NewMsgEditValidator( - addr1, description, - ) - SignDeliver(t, gapp, editValidatorMsg, []int64{1}, true, priv1) - - validator, found = gapp.stakeKeeper.GetValidator(ctxDeliver, addr1) - require.True(t, found) - require.Equal(t, description, validator.Description) - - // Delegate - - delegateMsg := stake.NewMsgDelegate( - addr2, addr1, bondCoin, - ) - SignDeliver(t, gapp, delegateMsg, []int64{0}, true, priv2) - - res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) - require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res2.GetCoins()) - bond, found = gapp.stakeKeeper.GetDelegation(ctxDeliver, addr2, addr1) - require.True(t, found) - require.Equal(t, addr2, bond.DelegatorAddr) - require.Equal(t, addr1, bond.ValidatorAddr) - require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) - - // Unbond - - unbondMsg := stake.NewMsgUnbond( - addr2, addr1, "MAX", - ) - SignDeliver(t, gapp, unbondMsg, []int64{1}, true, priv2) - - res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) - require.Equal(t, genCoins, res2.GetCoins()) - _, found = gapp.stakeKeeper.GetDelegation(ctxDeliver, addr2, addr1) - require.False(t, found) -} - func TestExportValidators(t *testing.T) { - gapp := newGaiaApp() + logger, dbs := loggerAndDB() + gapp := NewGaiaApp(logger, dbs) genCoins, err := sdk.ParseCoins("42steak") require.Nil(t, err) @@ -242,7 +115,7 @@ func TestExportValidators(t *testing.T) { createValidatorMsg := stake.NewMsgCreateValidator( addr1, priv1.PubKey(), bondCoin, description, ) - SignCheckDeliver(t, gapp, createValidatorMsg, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, gapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) gapp.Commit() // Export validator set @@ -252,72 +125,3 @@ func TestExportValidators(t *testing.T) { require.Equal(t, priv1.PubKey(), validators[0].PubKey) require.Equal(t, int64(10), validators[0].Power) } - -//____________________________________________________________________________________ - -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) auth.StdTx { - sigs := make([]auth.StdSignature, len(priv)) - for i, p := range priv { - sigs[i] = auth.StdSignature{ - PubKey: p.PubKey(), - Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), - Sequence: seq[i], - } - } - - return auth.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.ABCICodeOK, res.Code, res.Log) - } else { - 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.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, 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.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - gapp.EndBlock(abci.RequestEndBlock{}) -} diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 3027a8470..a1f7d5370 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -1,26 +1,23 @@ package app import ( - "encoding/json" - "fmt" "os" "testing" "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/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" - 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/examples/basecoin/types" + + 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" ) // Construct some global addrs and txs for tests. @@ -28,66 +25,9 @@ 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 = auth.StdFee{ - sdk.Coins{{"foocoin", 0}}, - 100000, - } - - sendMsg1 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } - - sendMsg2 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{ - bank.NewOutput(addr2, halfCoins), - bank.NewOutput(addr3, halfCoins), - }, - } - - sendMsg3 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, coins), - bank.NewInput(addr4, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, coins), - bank.NewOutput(addr3, coins), - }, - } - - sendMsg4 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr2, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr1, coins), - }, - } - - sendMsg5 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, manyCoins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, manyCoins), - }, - } ) -func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { +func setGenesis(t *testing.T, bapp *BasecoinApp, accs ...auth.BaseAccount) error { genaccs := make([]*types.GenesisAccount, len(accs)) for i, acc := range accs { genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) @@ -99,9 +39,7 @@ func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { } stateBytes, err := wire.MarshalJSONIndent(bapp.cdc, genesisState) - if err != nil { - return err - } + require.NoError(t, err) // Initialize the chain vals := []abci.Validator{} @@ -111,94 +49,24 @@ func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { return nil } -func loggerAndDB() (log.Logger, dbm.DB) { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - db := dbm.NewMemDB() - return logger, db -} - -func newBasecoinApp() *BasecoinApp { - logger, db := loggerAndDB() - return NewBasecoinApp(logger, db) -} - //_______________________________________________________________________ -func TestMsgs(t *testing.T) { - bapp := newBasecoinApp() - require.Nil(t, setGenesis(bapp)) - - msgs := []struct { - msg sdk.Msg - }{ - {sendMsg1}, - } - - for i, m := range msgs { - // Run a CheckDeliver - SignCheckDeliver(t, bapp, m.msg, []int64{int64(i)}, false, priv1) - } -} - -func TestSortGenesis(t *testing.T) { - logger, db := loggerAndDB() - bapp := NewBasecoinApp(logger, db) - - // Note the order: the coins are unsorted! - coinDenom1, coinDenom2 := "foocoin", "barcoin" - - genState := fmt.Sprintf(`{ - "accounts": [{ - "address": "%s", - "coins": [ - { - "denom": "%s", - "amount": 10 - }, - { - "denom": "%s", - "amount": 20 - } - ] - }] - }`, addr1.String(), coinDenom1, coinDenom2) - - // Initialize the chain - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: []byte(genState)}) - bapp.Commit() - - // Unsorted coins means invalid - err := sendMsg5.ValidateBasic() - require.Equal(t, sdk.CodeInvalidCoins, err.Code(), 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, bapp, sendMsg5, []int64{0}, true, priv1) -} - func TestGenesis(t *testing.T) { - logger, db := loggerAndDB() + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") + db := dbm.NewMemDB() bapp := NewBasecoinApp(logger, db) // Construct some genesis bytes to reflect basecoin/types/AppAccount pk := crypto.GenPrivKeyEd25519().PubKey() addr := pk.Address() - coins, err := sdk.ParseCoins("77foocoin,99barcoin") - require.Nil(t, err) + coins := sdk.Coins{{"foocoin", 77}, {"barcoin", 99}} baseAcc := auth.BaseAccount{ Address: addr, Coins: coins, } acc := &types.AppAccount{baseAcc, "foobart"} - err = setGenesis(bapp, baseAcc) - require.Nil(t, err) + setGenesis(t, bapp, baseAcc) // A checkTx context ctx := bapp.BaseApp.NewContext(true, abci.Header{}) @@ -211,318 +79,3 @@ func TestGenesis(t *testing.T) { res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) } - -func TestMsgChangePubKey(t *testing.T) { - - bapp := newBasecoinApp() - - // Construct some genesis bytes to reflect basecoin/types/AppAccount - // 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 = setGenesis(bapp, baseAcc) - require.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, baseAcc, res1.(*types.AppAccount).BaseAccount) - - // Run a CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "67foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - changePubKeyMsg := auth.MsgChangeKey{ - Address: addr1, - NewPubKey: priv2.PubKey(), - } - - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - acc := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - - // send a MsgChangePubKey - SignCheckDeliver(t, bapp, changePubKeyMsg, []int64{1}, true, priv1) - acc = bapp.accountMapper.GetAccount(ctxDeliver, addr1) - - assert.True(t, priv2.PubKey().Equals(acc.GetPubKey())) - - // signing a SendMsg with the old privKey should be an auth error - tx := genTx(sendMsg1, []int64{2}, priv1) - res := bapp.Deliver(tx) - assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) - - // resigning the tx with the new correct priv key should work - SignCheckDeliver(t, bapp, sendMsg1, []int64{2}, true, priv2) - - // Check balances - CheckBalance(t, bapp, addr1, "57foocoin") - CheckBalance(t, bapp, addr2, "20foocoin") -} - -func TestMsgSendWithAccounts(t *testing.T) { - bapp := newBasecoinApp() - - // Construct some genesis bytes to reflect basecoin/types/AppAccount - // 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 = setGenesis(bapp, baseAcc) - require.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, baseAcc, res1.(*types.AppAccount).BaseAccount) - - // Run a CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "67foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - // Delivering again should cause replay error - SignCheckDeliver(t, bapp, 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 := bapp.Deliver(tx) - - 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) -} - -func TestMsgSendMultipleOut(t *testing.T) { - bapp := newBasecoinApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - acc2 := auth.BaseAccount{ - Address: addr2, - Coins: genCoins, - } - - // Construct genesis state - err = setGenesis(bapp, acc1, acc2) - require.Nil(t, err) - - // Simulate a Block - SignCheckDeliver(t, bapp, sendMsg2, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr2, "47foocoin") - CheckBalance(t, bapp, addr3, "5foocoin") -} - -func TestSengMsgMultipleInOut(t *testing.T) { - bapp := newBasecoinApp() - - 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 = setGenesis(bapp, acc1, acc2, acc4) - assert.Nil(t, err) - - // CheckDeliver - SignCheckDeliver(t, bapp, sendMsg3, []int64{0, 0}, true, priv1, priv4) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr4, "32foocoin") - CheckBalance(t, bapp, addr2, "52foocoin") - CheckBalance(t, bapp, addr3, "10foocoin") -} - -func TestMsgSendDependent(t *testing.T) { - bapp := newBasecoinApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - // Construct genesis state - err = setGenesis(bapp, acc1) - require.Nil(t, err) - - err = setGenesis(bapp, acc1) - assert.Nil(t, err) - - // CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - // Simulate a Block - SignCheckDeliver(t, bapp, sendMsg4, []int64{0}, true, priv2) - - // Check balances - CheckBalance(t, bapp, addr1, "42foocoin") -} - -func TestMsgQuiz(t *testing.T) { - bapp := newBasecoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect basecoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - -} - -func TestIBCMsgs(t *testing.T) { - bapp := newBasecoinApp() - - sourceChain := "source-chain" - destChain := "dest-chain" - - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - err := setGenesis(bapp, baseAcc) - assert.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, 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, bapp, transferMsg, []int64{0}, true, priv1) - CheckBalance(t, bapp, addr1, "") - SignCheckDeliver(t, bapp, transferMsg, []int64{1}, false, priv1) - SignCheckDeliver(t, bapp, receiveMsg, []int64{2}, true, priv1) - CheckBalance(t, bapp, addr1, "10foocoin") - SignCheckDeliver(t, bapp, receiveMsg, []int64{3}, false, priv1) -} - -func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { - sigs := make([]auth.StdSignature, len(priv)) - for i, p := range priv { - sigs[i] = auth.StdSignature{ - PubKey: p.PubKey(), - Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), - Sequence: seq[i], - } - } - - return auth.NewStdTx(msg, fee, sigs) - -} - -func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { - - // Sign the tx - tx := genTx(msg, seq, priv...) - // Run a Check - res := bapp.Check(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - 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.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - bapp.EndBlock(abci.RequestEndBlock{}) - //bapp.Commit() -} - -func CheckBalance(t *testing.T, bapp *BasecoinApp, addr sdk.Address, balExpected string) { - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr) - assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) -} diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index ba041bcff..01264399a 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -2,7 +2,6 @@ package app import ( "encoding/json" - "fmt" "os" "testing" @@ -10,12 +9,8 @@ import ( "github.com/stretchr/testify/require" "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" 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" @@ -23,101 +18,9 @@ import ( "github.com/tendermint/tmlibs/log" ) -// Construct some global addrs and txs for tests. -var ( - chainID = "" // TODO - - priv1 = crypto.GenPrivKeyEd25519() - addr1 = priv1.PubKey().Address() - addr2 = crypto.GenPrivKeyEd25519().PubKey().Address() - coins = sdk.Coins{{"foocoin", 10}} - fee = auth.StdFee{ - sdk.Coins{{"foocoin", 0}}, - 1000000, - } - - sendMsg = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } - - quizMsg1 = cool.MsgQuiz{ - Sender: addr1, - CoolAnswer: "icecold", - } - - quizMsg2 = cool.MsgQuiz{ - Sender: addr1, - CoolAnswer: "badvibesonly", - } - - setTrendMsg1 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "icecold", - } - - setTrendMsg2 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "badvibesonly", - } - - setTrendMsg3 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "warmandkind", - } -) - -func loggerAndDB() (log.Logger, dbm.DB) { +func TestGenesis(t *testing.T) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") db := dbm.NewMemDB() - return logger, db -} - -func newDemocoinApp() *DemocoinApp { - logger, db := loggerAndDB() - return NewDemocoinApp(logger, db) -} - -//_______________________________________________________________________ - -func TestMsgs(t *testing.T) { - bapp := newDemocoinApp() - - msgs := []struct { - msg sdk.Msg - }{ - {sendMsg}, - {quizMsg1}, - {setTrendMsg1}, - } - - sequences := []int64{0} - for i, m := range msgs { - sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, m.msg)) - tx := auth.NewStdTx(m.msg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: sig, - }}) - - // just marshal/unmarshal! - txBytes, err := bapp.cdc.MarshalBinary(tx) - require.NoError(t, err, "i: %v", i) - - // Run a Check - cres := bapp.CheckTx(txBytes) - assert.Equal(t, sdk.CodeUnknownAddress, - sdk.CodeType(cres.Code), "i: %v, log: %v", i, cres.Log) - - // Simulate a Block - bapp.BeginBlock(abci.RequestBeginBlock{}) - dres := bapp.DeliverTx(txBytes) - assert.Equal(t, sdk.CodeUnknownAddress, - sdk.CodeType(dres.Code), "i: %v, log: %v", i, dres.Log) - } -} - -func TestGenesis(t *testing.T) { - logger, db := loggerAndDB() bapp := NewDemocoinApp(logger, db) // Construct some genesis bytes to reflect democoin/types/AppAccount @@ -156,272 +59,3 @@ func TestGenesis(t *testing.T) { res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) } - -func TestMsgSendWithAccounts(t *testing.T) { - bapp := newDemocoinApp() - - // Construct some genesis bytes to reflect democoin/types/AppAccount - // Give 77 foocoin to the first key - coins, err := sdk.ParseCoins("77foocoin") - require.Nil(t, err) - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Sign the tx - sequences := []int64{0} - sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, sendMsg)) - tx := auth.NewStdTx(sendMsg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: sig, - }}) - - // Run a Check - res := bapp.Check(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - - // Simulate a Block - bapp.BeginBlock(abci.RequestBeginBlock{}) - res = bapp.Deliver(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - - // Check balances - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - res3 := bapp.accountMapper.GetAccount(ctxDeliver, addr2) - assert.Equal(t, fmt.Sprintf("%v", res2.GetCoins()), "67foocoin") - assert.Equal(t, fmt.Sprintf("%v", res3.GetCoins()), "10foocoin") - - // Delivering again should cause replay error - res = bapp.Deliver(tx) - 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.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(auth.StdSignBytes(chainID, sequences, fee, tx.Msg)) - tx.Signatures[0].Signature = sig - res = bapp.Deliver(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) -} - -func TestMsgMine(t *testing.T) { - bapp := newDemocoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect democoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - "pow": map[string]uint64{ - "difficulty": 1, - "count": 0, - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Mine and check for reward - mineMsg1 := pow.GenerateMsgMine(addr1, 1, 2) - SignCheckDeliver(t, bapp, mineMsg1, 0, true) - CheckBalance(t, bapp, "1pow") - // Mine again and check for reward - mineMsg2 := pow.GenerateMsgMine(addr1, 2, 3) - SignCheckDeliver(t, bapp, mineMsg2, 1, true) - CheckBalance(t, bapp, "2pow") - // Mine again - should be invalid - SignCheckDeliver(t, bapp, mineMsg2, 1, false) - CheckBalance(t, bapp, "2pow") - -} - -func TestMsgQuiz(t *testing.T) { - bapp := newDemocoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect democoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Set the trend, submit a really cool quiz and check for reward - SignCheckDeliver(t, bapp, setTrendMsg1, 0, true) - SignCheckDeliver(t, bapp, quizMsg1, 1, true) - CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg2, 2, false) // result without reward - CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg1, 3, true) - CheckBalance(t, bapp, "138icecold") - SignCheckDeliver(t, bapp, setTrendMsg2, 4, true) // reset the trend - SignCheckDeliver(t, bapp, quizMsg1, 5, false) // the same answer will nolonger do! - CheckBalance(t, bapp, "138icecold") - SignCheckDeliver(t, bapp, quizMsg2, 6, true) // earlier answer now relavent again - CheckBalance(t, bapp, "69badvibesonly,138icecold") - SignCheckDeliver(t, bapp, setTrendMsg3, 7, false) // expect to fail to set the trend to something which is not cool - -} - -func TestHandler(t *testing.T) { - bapp := newDemocoinApp() - - sourceChain := "source-chain" - destChain := "dest-chain" - - vals := []abci.Validator{} - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, 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, bapp, transferMsg, 0, true) - CheckBalance(t, bapp, "") - SignCheckDeliver(t, bapp, transferMsg, 1, false) - SignCheckDeliver(t, bapp, receiveMsg, 2, true) - CheckBalance(t, bapp, "10foocoin") - SignCheckDeliver(t, bapp, receiveMsg, 3, false) -} - -// TODO describe the use of this function -func SignCheckDeliver(t *testing.T, bapp *DemocoinApp, msg sdk.Msg, seq int64, expPass bool) { - - // Sign the tx - tx := auth.NewStdTx(msg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: priv1.Sign(auth.StdSignBytes(chainID, []int64{seq}, fee, msg)), - Sequence: seq, - }}) - - // Run a Check - res := bapp.Check(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - 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.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - bapp.EndBlock(abci.RequestEndBlock{}) - //bapp.Commit() -} - -func CheckBalance(t *testing.T, bapp *DemocoinApp, balExpected string) { - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) -} diff --git a/examples/democoin/x/cool/app_test.go b/examples/democoin/x/cool/app_test.go new file mode 100644 index 000000000..d41c8ea82 --- /dev/null +++ b/examples/democoin/x/cool/app_test.go @@ -0,0 +1,105 @@ +package cool + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" + bank "github.com/cosmos/cosmos-sdk/x/bank" +) + +var ( + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + + quizMsg1 = MsgQuiz{ + Sender: addr1, + CoolAnswer: "icecold", + } + + quizMsg2 = MsgQuiz{ + Sender: addr1, + CoolAnswer: "badvibesonly", + } + + setTrendMsg1 = MsgSetTrend{ + Sender: addr1, + Cool: "icecold", + } + + setTrendMsg2 = MsgSetTrend{ + Sender: addr1, + Cool: "badvibesonly", + } + + setTrendMsg3 = MsgSetTrend{ + Sender: addr1, + Cool: "warmandkind", + } +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) *mock.App { + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + keyCool := sdk.NewKVStoreKey("cool") + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + keeper := NewKeeper(keyCool, coinKeeper, mapp.RegisterCodespace(DefaultCodespace)) + mapp.Router().AddRoute("cool", NewHandler(keeper)) + + mapp.SetInitChainer(getInitChainer(mapp, keeper, "ice-cold")) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{keyCool}) + return mapp +} + +// overwrite the mock init chainer +func getInitChainer(mapp *mock.App, keeper Keeper, newTrend string) sdk.InitChainer { + return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + mapp.InitChainer(ctx, req) + keeper.setTrend(ctx, newTrend) + + return abci.ResponseInitChain{} + } +} + +func TestMsgQuiz(t *testing.T) { + mapp := getMockApp(t) + + // Construct genesis state + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: nil, + } + accs := []auth.Account{acc1} + + // Initialize the chain (nil) + mock.SetGenesis(mapp, accs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + // Set the trend, submit a really cool quiz and check for reward + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{1}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 69}}) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg2, []int64{2}, false, priv1) // result without reward + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 69}}) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{3}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 138}}) + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg2, []int64{4}, true, priv1) // reset the trend + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{5}, false, priv1) // the same answer will nolonger do! + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 138}}) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg2, []int64{6}, true, priv1) // earlier answer now relavent again + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"badvibesonly", 69}, {"icecold", 138}}) + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg3, []int64{7}, false, priv1) // expect to fail to set the trend to something which is not cool +} diff --git a/examples/democoin/x/pow/app_test.go b/examples/democoin/x/pow/app_test.go new file mode 100644 index 000000000..0539df556 --- /dev/null +++ b/examples/democoin/x/pow/app_test.go @@ -0,0 +1,83 @@ +package pow + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" + "github.com/cosmos/cosmos-sdk/x/bank" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +var ( + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) *mock.App { + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + keyPOW := sdk.NewKVStoreKey("pow") + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + config := Config{"pow", 1} + keeper := NewKeeper(keyPOW, config, coinKeeper, mapp.RegisterCodespace(DefaultCodespace)) + mapp.Router().AddRoute("pow", keeper.Handler) + + mapp.SetInitChainer(getInitChainer(mapp, keeper)) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{keyPOW}) + return mapp +} + +// overwrite the mock init chainer +func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer { + return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + mapp.InitChainer(ctx, req) + + genesis := Genesis{ + Difficulty: 1, + Count: 0, + } + InitGenesis(ctx, keeper, genesis) + + return abci.ResponseInitChain{} + } +} + +func TestMsgMine(t *testing.T) { + mapp := getMockApp(t) + + // Construct genesis state + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: nil, + } + accs := []auth.Account{acc1} + + // Initialize the chain (nil) + mock.SetGenesis(mapp, accs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + // Mine and check for reward + mineMsg1 := GenerateMsgMine(addr1, 1, 2) + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg1, []int64{0}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 1}}) + // Mine again and check for reward + mineMsg2 := GenerateMsgMine(addr1, 2, 3) + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg2, []int64{1}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 2}}) + // Mine again - should be invalid + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg2, []int64{1}, false, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 2}}) +} diff --git a/tests/mock/app.go b/x/auth/mock/app.go similarity index 95% rename from tests/mock/app.go rename to x/auth/mock/app.go index 6a3933005..6ceff482b 100644 --- a/tests/mock/app.go +++ b/x/auth/mock/app.go @@ -57,7 +57,7 @@ func NewApp() *App { ) // initialize the app, the chainers and blockers can be overwritten before calling complete setup - app.SetInitChainer(app.initChainer) + app.SetInitChainer(app.InitChainer) app.SetAnteHandler(auth.NewAnteHandler(app.AccountMapper, app.FeeCollectionKeeper)) @@ -75,7 +75,7 @@ func (app *App) CompleteSetup(t *testing.T, newKeys []*sdk.KVStoreKey) { } // custom logic for initialization -func (app *App) initChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain { +func (app *App) InitChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain { // load the accounts for _, acc := range app.GenesisAccounts { diff --git a/x/auth/mock/auth_app_test.go b/x/auth/mock/auth_app_test.go new file mode 100644 index 000000000..a3ff6710e --- /dev/null +++ b/x/auth/mock/auth_app_test.go @@ -0,0 +1,111 @@ +package mock + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +// test auth module messages + +var ( + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + priv2 = crypto.GenPrivKeyEd25519() + addr2 = priv2.PubKey().Address() + + coins = sdk.Coins{{"foocoin", 10}} + sendMsg1 = bank.MsgSend{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, + } +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) *App { + mapp := NewApp() + + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + mapp.Router().AddRoute("bank", bank.NewHandler(coinKeeper)) + mapp.Router().AddRoute("auth", auth.NewHandler(mapp.AccountMapper)) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{}) + return mapp +} + +func TestMsgChangePubKey(t *testing.T) { + fmt.Println("wackydebugoutput TestMsgChangePubKey 0") + mapp := getMockApp(t) + + // Construct some genesis bytes to reflect basecoin/types/AppAccount + // Give 77 foocoin to the first key + coins := sdk.Coins{{"foocoin", 77}} + fmt.Println("wackydebugoutput TestMsgChangePubKey 1") + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + fmt.Println("wackydebugoutput TestMsgChangePubKey 3") + accs := []auth.Account{acc1} + fmt.Println("wackydebugoutput TestMsgChangePubKey 4") + + // Construct genesis state + SetGenesis(mapp, accs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 5") + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1.(*auth.BaseAccount)) + + // Run a CheckDeliver + SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) + fmt.Println("wackydebugoutput TestMsgChangePubKey 6") + + // Check balances + CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 67}}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 7") + CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 8") + + changePubKeyMsg := auth.MsgChangeKey{ + Address: addr1, + NewPubKey: priv2.PubKey(), + } + fmt.Println("wackydebugoutput TestMsgChangePubKey 10") + + ctxDeliver := mapp.BaseApp.NewContext(false, abci.Header{}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 11") + acc2 := mapp.AccountMapper.GetAccount(ctxDeliver, addr1) + + // send a MsgChangePubKey + SignCheckDeliver(t, mapp.BaseApp, changePubKeyMsg, []int64{1}, true, priv1) + fmt.Println("wackydebugoutput TestMsgChangePubKey 12") + acc2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr1) + + assert.True(t, priv2.PubKey().Equals(acc2.GetPubKey())) + + // signing a SendMsg with the old privKey should be an auth error + tx := GenTx(sendMsg1, []int64{2}, priv1) + fmt.Println("wackydebugoutput TestMsgChangePubKey 13") + res := mapp.Deliver(tx) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) + + // resigning the tx with the new correct priv key should work + SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{2}, true, priv2) + fmt.Println("wackydebugoutput TestMsgChangePubKey 14") + + // Check balances + CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 57}}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 15") + CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 20}}) + fmt.Println("wackydebugoutput TestMsgChangePubKey 16") +} diff --git a/tests/mock/simulate_block.go b/x/auth/mock/simulate_block.go similarity index 89% rename from tests/mock/simulate_block.go rename to x/auth/mock/simulate_block.go index fa1000af7..cf0c303a3 100644 --- a/tests/mock/simulate_block.go +++ b/x/auth/mock/simulate_block.go @@ -3,6 +3,7 @@ package mock import ( "testing" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/stretchr/testify/assert" @@ -52,7 +53,7 @@ func GenTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { } // simulate a block -func SignCheckDeliver(t *testing.T, app *App, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { +func SignCheckDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { // Sign the tx tx := GenTx(msg, seq, priv...) @@ -83,7 +84,7 @@ func SignCheckDeliver(t *testing.T, app *App, msg sdk.Msg, seq []int64, expPass // 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, app App, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { +func SignDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { // Sign the tx tx := GenTx(msg, seq, priv...) diff --git a/x/bank/app_test.go b/x/bank/app_test.go index ecbb66145..507f9e3f8 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/tests/mock" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" abci "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" @@ -16,8 +16,6 @@ import ( // test bank module in a mock application var ( - chainID = "" // TODO - priv1 = crypto.GenPrivKeyEd25519() addr1 = priv1.PubKey().Address() priv2 = crypto.GenPrivKeyEd25519() @@ -109,14 +107,14 @@ func TestMsgSendWithAccounts(t *testing.T) { assert.Equal(t, acc, res1.(*auth.BaseAccount)) // Run a CheckDeliver - mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 57}}) mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) // Delivering again should cause replay error - mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, false, priv1) // bumping the txnonce number without resigning should be an auth error tx := mock.GenTx(sendMsg1, []int64{0}, priv1) @@ -126,7 +124,7 @@ func TestMsgSendWithAccounts(t *testing.T) { assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) // resigning the tx with the bumped sequence should work - mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{1}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{1}, true, priv1) } func TestMsgSendMultipleOut(t *testing.T) { @@ -146,7 +144,7 @@ func TestMsgSendMultipleOut(t *testing.T) { mock.SetGenesis(mapp, accs) // Simulate a Block - mock.SignCheckDeliver(t, mapp, sendMsg2, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg2, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) @@ -174,7 +172,7 @@ func TestSengMsgMultipleInOut(t *testing.T) { mock.SetGenesis(mapp, accs) // CheckDeliver - mock.SignCheckDeliver(t, mapp, sendMsg3, []int64{0, 0}, true, priv1, priv4) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg3, []int64{0, 0}, true, priv1, priv4) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) @@ -195,14 +193,14 @@ func TestMsgSendDependent(t *testing.T) { mock.SetGenesis(mapp, accs) // CheckDeliver - mock.SignCheckDeliver(t, mapp, sendMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) // Simulate a Block - mock.SignCheckDeliver(t, mapp, sendMsg4, []int64{0}, true, priv2) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg4, []int64{0}, true, priv2) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 42}}) diff --git a/x/ibc/app_test.go b/x/ibc/app_test.go index 0124e417e..9e4b4bf56 100644 --- a/x/ibc/app_test.go +++ b/x/ibc/app_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/cosmos/cosmos-sdk/tests/mock" + "github.com/cosmos/cosmos-sdk/x/auth/mock" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" @@ -29,7 +29,7 @@ func getMockApp(t *testing.T) *mock.App { } func TestIBCMsgs(t *testing.T) { - gapp := getMockApp(t) + mapp := getMockApp(t) sourceChain := "source-chain" destChain := "dest-chain" @@ -45,11 +45,11 @@ func TestIBCMsgs(t *testing.T) { } accs := []auth.Account{acc} - mock.SetGenesis(gapp, accs) + mock.SetGenesis(mapp, accs) // A checkTx context (true) - ctxCheck := gapp.BaseApp.NewContext(true, abci.Header{}) - res1 := gapp.AccountMapper.GetAccount(ctxCheck, addr1) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) assert.Equal(t, acc, res1) packet := IBCPacket{ @@ -70,10 +70,10 @@ func TestIBCMsgs(t *testing.T) { Sequence: 0, } - mock.SignCheckDeliver(t, gapp, transferMsg, []int64{0}, true, priv1) - mock.CheckBalance(t, gapp, addr1, emptyCoins) - mock.SignCheckDeliver(t, gapp, transferMsg, []int64{1}, false, priv1) - mock.SignCheckDeliver(t, gapp, receiveMsg, []int64{2}, true, priv1) - mock.CheckBalance(t, gapp, addr1, coins) - mock.SignCheckDeliver(t, gapp, receiveMsg, []int64{3}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, transferMsg, []int64{0}, true, priv1) + mock.CheckBalance(t, mapp, addr1, emptyCoins) + mock.SignCheckDeliver(t, mapp.BaseApp, transferMsg, []int64{1}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, receiveMsg, []int64{2}, true, priv1) + mock.CheckBalance(t, mapp, addr1, coins) + mock.SignCheckDeliver(t, mapp.BaseApp, receiveMsg, []int64{3}, false, priv1) } diff --git a/x/stake/app_test.go b/x/stake/app_test.go new file mode 100644 index 000000000..4e3d1f422 --- /dev/null +++ b/x/stake/app_test.go @@ -0,0 +1,152 @@ +package stake + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +var ( + 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}} + fee = auth.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 100000, + } +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) (*mock.App, Keeper) { + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + keyStake := sdk.NewKVStoreKey("stake") + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + keeper := NewKeeper(mapp.Cdc, keyStake, coinKeeper, mapp.RegisterCodespace(DefaultCodespace)) + mapp.Router().AddRoute("stake", NewHandler(keeper)) + + mapp.SetEndBlocker(getEndBlocker(keeper)) + mapp.SetInitChainer(getInitChainer(mapp, keeper)) + + mapp.CompleteSetup(t, []*sdk.KVStoreKey{keyStake}) + return mapp, keeper +} + +// stake endblocker +func getEndBlocker(keeper Keeper) sdk.EndBlocker { + return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + validatorUpdates := EndBlocker(ctx, keeper) + return abci.ResponseEndBlock{ + ValidatorUpdates: validatorUpdates, + } + } +} + +// overwrite the mock init chainer +func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer { + return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + mapp.InitChainer(ctx, req) + InitGenesis(ctx, keeper, DefaultGenesisState()) + + return abci.ResponseInitChain{} + } +} + +func TestStakeMsgs(t *testing.T) { + mapp, keeper := getMockApp(t) + + genCoin := sdk.Coin{"steak", 42} + bondCoin := sdk.Coin{"steak", 10} + + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: sdk.Coins{genCoin}, + } + acc2 := &auth.BaseAccount{ + Address: addr2, + Coins: sdk.Coins{genCoin}, + } + accs := []auth.Account{acc1, acc2} + + mock.SetGenesis(mapp, accs) + + // A checkTx context (true) + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) + res2 := mapp.AccountMapper.GetAccount(ctxCheck, addr2) + require.Equal(t, acc1, res1) + require.Equal(t, acc2, res2) + + // Create Validator + + description := NewDescription("foo_moniker", "", "", "") + createValidatorMsg := NewMsgCreateValidator( + addr1, priv1.PubKey(), bondCoin, description, + ) + mock.SignCheckDeliver(t, mapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) + + ctxDeliver := mapp.BaseApp.NewContext(false, abci.Header{}) + res1 = mapp.AccountMapper.GetAccount(ctxDeliver, addr1) + require.Equal(t, sdk.Coins{genCoin.Minus(bondCoin)}, res1.GetCoins()) + validator, found := keeper.GetValidator(ctxDeliver, addr1) + require.True(t, found) + require.Equal(t, addr1, validator.Owner) + require.Equal(t, sdk.Bonded, validator.Status()) + require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) + + // check the bond that should have been created as well + bond, found := keeper.GetDelegation(ctxDeliver, addr1, addr1) + require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) + + // Edit Validator + + description = NewDescription("bar_moniker", "", "", "") + editValidatorMsg := NewMsgEditValidator( + addr1, description, + ) + mock.SignDeliver(t, mapp.BaseApp, editValidatorMsg, []int64{1}, true, priv1) + + validator, found = keeper.GetValidator(ctxDeliver, addr1) + require.True(t, found) + require.Equal(t, description, validator.Description) + + // Delegate + + delegateMsg := NewMsgDelegate( + addr2, addr1, bondCoin, + ) + mock.SignDeliver(t, mapp.BaseApp, delegateMsg, []int64{0}, true, priv2) + + res2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr2) + require.Equal(t, sdk.Coins{genCoin.Minus(bondCoin)}, res2.GetCoins()) + bond, found = keeper.GetDelegation(ctxDeliver, addr2, addr1) + require.True(t, found) + require.Equal(t, addr2, bond.DelegatorAddr) + require.Equal(t, addr1, bond.ValidatorAddr) + require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) + + // Unbond + + unbondMsg := NewMsgUnbond( + addr2, addr1, "MAX", + ) + mock.SignDeliver(t, mapp.BaseApp, unbondMsg, []int64{1}, true, priv2) + + res2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr2) + require.Equal(t, sdk.Coins{genCoin}, res2.GetCoins()) + _, found = keeper.GetDelegation(ctxDeliver, addr2, addr1) + require.False(t, found) +} From 40f5928898d4c8d019d92f09f73d6b41aa2c1e2c Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 7 Jun 2018 20:59:35 -0700 Subject: [PATCH 30/89] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d6541691..f8157594a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ FEATURES IMPROVEMENTS * export command now writes current validator set for Tendermint +* [tests] Application module tests now use a mock application FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs From b5d847288d8c0faa5504a0cfa116f7bd230f39b0 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 7 Jun 2018 21:33:06 -0700 Subject: [PATCH 31/89] move original mock into server --- CHANGELOG.md | 1 - cmd/gaia/app/app_test.go | 425 ++++++++++++++++++++++++- examples/basecoin/app/app_test.go | 475 +++++++++++++++++++++++++++- examples/democoin/app/app_test.go | 368 ++++++++++++++++++++- server/init_test.go | 2 +- {mock => server/mock}/app.go | 0 {mock => server/mock}/app_test.go | 0 {mock => server/mock}/helpers.go | 0 {mock => server/mock}/store.go | 0 {mock => server/mock}/store_test.go | 0 {mock => server/mock}/tx.go | 0 server/start_test.go | 2 +- x/auth/mock/app.go | 2 +- 13 files changed, 1248 insertions(+), 27 deletions(-) rename {mock => server/mock}/app.go (100%) rename {mock => server/mock}/app_test.go (100%) rename {mock => server/mock}/helpers.go (100%) rename {mock => server/mock}/store.go (100%) rename {mock => server/mock}/store_test.go (100%) rename {mock => server/mock}/tx.go (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8157594a..6d6541691 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,6 @@ FEATURES IMPROVEMENTS * export command now writes current validator set for Tendermint -* [tests] Application module tests now use a mock application FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 0f6bab134..0fe1cfe5b 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -1,16 +1,18 @@ package app import ( + "fmt" "os" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/x/auth/mock" 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" abci "github.com/tendermint/abci/types" @@ -19,13 +21,68 @@ import ( "github.com/tendermint/tmlibs/log" ) +// Construct some global addrs and txs for tests. var ( chainID = "" // TODO - priv1 = crypto.GenPrivKeyEd25519() - addr1 = priv1.PubKey().Address() - priv2 = crypto.GenPrivKeyEd25519() - addr2 = priv2.PubKey().Address() + 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 = auth.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 100000, + } + + sendMsg1 = bank.MsgSend{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, + } + + sendMsg2 = bank.MsgSend{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{ + bank.NewOutput(addr2, halfCoins), + bank.NewOutput(addr3, halfCoins), + }, + } + + sendMsg3 = bank.MsgSend{ + Inputs: []bank.Input{ + bank.NewInput(addr1, coins), + bank.NewInput(addr4, coins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr2, coins), + bank.NewOutput(addr3, coins), + }, + } + + sendMsg4 = bank.MsgSend{ + Inputs: []bank.Input{ + bank.NewInput(addr2, coins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr1, coins), + }, + } + + sendMsg5 = bank.MsgSend{ + Inputs: []bank.Input{ + bank.NewInput(addr1, manyCoins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr2, manyCoins), + }, + } ) func loggerAndDB() (log.Logger, dbm.DB) { @@ -34,6 +91,11 @@ func loggerAndDB() (log.Logger, dbm.DB) { return logger, db } +func newGaiaApp() *GaiaApp { + logger, db := loggerAndDB() + return NewGaiaApp(logger, db) +} + func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { genaccs := make([]GenesisAccount, len(accs)) for i, acc := range accs { @@ -60,6 +122,22 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { //_______________________________________________________________________ +func TestMsgs(t *testing.T) { + gapp := newGaiaApp() + require.Nil(t, setGenesis(gapp)) + + 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 TestGenesis(t *testing.T) { logger, dbs := loggerAndDB() gapp := NewGaiaApp(logger, dbs) @@ -89,9 +167,271 @@ func TestGenesis(t *testing.T) { assert.Equal(t, baseAcc, res1) } +func TestMsgSendWithAccounts(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 = setGenesis(gapp, baseAcc) + require.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.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) +} + +func TestMsgSendMultipleOut(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 = setGenesis(gapp, acc1, acc2) + require.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 = setGenesis(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 TestMsgSendDependent(t *testing.T) { + gapp := newGaiaApp() + + genCoins, err := sdk.ParseCoins("42foocoin") + require.Nil(t, err) + + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: genCoins, + } + + err = setGenesis(gapp, acc1) + require.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 := setGenesis(gapp, baseAcc) + require.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 TestStakeMsgs(t *testing.T) { + gapp := newGaiaApp() + + genCoins, err := sdk.ParseCoins("42steak") + require.Nil(t, err) + bondCoin, err := sdk.ParseCoin("10steak") + 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) + + // Create Validator + + description := stake.NewDescription("foo_moniker", "", "", "") + createValidatorMsg := stake.NewMsgCreateValidator( + addr1, priv1.PubKey(), bondCoin, description, + ) + SignCheckDeliver(t, gapp, createValidatorMsg, []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()) + validator, found := gapp.stakeKeeper.GetValidator(ctxDeliver, addr1) + require.True(t, found) + require.Equal(t, addr1, validator.Owner) + require.Equal(t, sdk.Bonded, validator.Status()) + require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) + + // check the bond that should have been created as well + bond, found := gapp.stakeKeeper.GetDelegation(ctxDeliver, addr1, addr1) + require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) + + // Edit Validator + + description = stake.NewDescription("bar_moniker", "", "", "") + editValidatorMsg := stake.NewMsgEditValidator( + addr1, description, + ) + SignDeliver(t, gapp, editValidatorMsg, []int64{1}, true, priv1) + + validator, found = gapp.stakeKeeper.GetValidator(ctxDeliver, addr1) + require.True(t, found) + require.Equal(t, description, validator.Description) + + // Delegate + + delegateMsg := stake.NewMsgDelegate( + addr2, addr1, bondCoin, + ) + SignDeliver(t, gapp, delegateMsg, []int64{0}, true, priv2) + + res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) + require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res2.GetCoins()) + bond, found = gapp.stakeKeeper.GetDelegation(ctxDeliver, addr2, addr1) + require.True(t, found) + require.Equal(t, addr2, bond.DelegatorAddr) + require.Equal(t, addr1, bond.ValidatorAddr) + require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) + + // Unbond + + unbondMsg := stake.NewMsgUnbond( + addr2, addr1, "MAX", + ) + SignDeliver(t, gapp, unbondMsg, []int64{1}, true, priv2) + + res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) + require.Equal(t, genCoins, res2.GetCoins()) + _, found = gapp.stakeKeeper.GetDelegation(ctxDeliver, addr2, addr1) + require.False(t, found) +} + func TestExportValidators(t *testing.T) { - logger, dbs := loggerAndDB() - gapp := NewGaiaApp(logger, dbs) + gapp := newGaiaApp() genCoins, err := sdk.ParseCoins("42steak") require.Nil(t, err) @@ -115,7 +455,7 @@ func TestExportValidators(t *testing.T) { createValidatorMsg := stake.NewMsgCreateValidator( addr1, priv1.PubKey(), bondCoin, description, ) - mock.SignCheckDeliver(t, gapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) + SignCheckDeliver(t, gapp, createValidatorMsg, []int64{0}, true, priv1) gapp.Commit() // Export validator set @@ -125,3 +465,72 @@ func TestExportValidators(t *testing.T) { require.Equal(t, priv1.PubKey(), validators[0].PubKey) require.Equal(t, int64(10), validators[0].Power) } + +//____________________________________________________________________________________ + +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) auth.StdTx { + sigs := make([]auth.StdSignature, len(priv)) + for i, p := range priv { + sigs[i] = auth.StdSignature{ + PubKey: p.PubKey(), + Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), + Sequence: seq[i], + } + } + + return auth.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.ABCICodeOK, res.Code, res.Log) + } else { + 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.ABCICodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.ABCICodeOK, 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.ABCICodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) + } + gapp.EndBlock(abci.RequestEndBlock{}) +} diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index a1f7d5370..3027a8470 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -1,23 +1,26 @@ package app import ( + "encoding/json" + "fmt" "os" "testing" "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/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" + 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/examples/basecoin/types" - - 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" ) // Construct some global addrs and txs for tests. @@ -25,9 +28,66 @@ 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 = auth.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 100000, + } + + sendMsg1 = bank.MsgSend{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, + } + + sendMsg2 = bank.MsgSend{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{ + bank.NewOutput(addr2, halfCoins), + bank.NewOutput(addr3, halfCoins), + }, + } + + sendMsg3 = bank.MsgSend{ + Inputs: []bank.Input{ + bank.NewInput(addr1, coins), + bank.NewInput(addr4, coins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr2, coins), + bank.NewOutput(addr3, coins), + }, + } + + sendMsg4 = bank.MsgSend{ + Inputs: []bank.Input{ + bank.NewInput(addr2, coins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr1, coins), + }, + } + + sendMsg5 = bank.MsgSend{ + Inputs: []bank.Input{ + bank.NewInput(addr1, manyCoins), + }, + Outputs: []bank.Output{ + bank.NewOutput(addr2, manyCoins), + }, + } ) -func setGenesis(t *testing.T, bapp *BasecoinApp, accs ...auth.BaseAccount) error { +func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { genaccs := make([]*types.GenesisAccount, len(accs)) for i, acc := range accs { genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) @@ -39,7 +99,9 @@ func setGenesis(t *testing.T, bapp *BasecoinApp, accs ...auth.BaseAccount) error } stateBytes, err := wire.MarshalJSONIndent(bapp.cdc, genesisState) - require.NoError(t, err) + if err != nil { + return err + } // Initialize the chain vals := []abci.Validator{} @@ -49,24 +111,94 @@ func setGenesis(t *testing.T, bapp *BasecoinApp, accs ...auth.BaseAccount) error return nil } -//_______________________________________________________________________ - -func TestGenesis(t *testing.T) { +func loggerAndDB() (log.Logger, dbm.DB) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") db := dbm.NewMemDB() + return logger, db +} + +func newBasecoinApp() *BasecoinApp { + logger, db := loggerAndDB() + return NewBasecoinApp(logger, db) +} + +//_______________________________________________________________________ + +func TestMsgs(t *testing.T) { + bapp := newBasecoinApp() + require.Nil(t, setGenesis(bapp)) + + msgs := []struct { + msg sdk.Msg + }{ + {sendMsg1}, + } + + for i, m := range msgs { + // Run a CheckDeliver + SignCheckDeliver(t, bapp, m.msg, []int64{int64(i)}, false, priv1) + } +} + +func TestSortGenesis(t *testing.T) { + logger, db := loggerAndDB() + bapp := NewBasecoinApp(logger, db) + + // Note the order: the coins are unsorted! + coinDenom1, coinDenom2 := "foocoin", "barcoin" + + genState := fmt.Sprintf(`{ + "accounts": [{ + "address": "%s", + "coins": [ + { + "denom": "%s", + "amount": 10 + }, + { + "denom": "%s", + "amount": 20 + } + ] + }] + }`, addr1.String(), coinDenom1, coinDenom2) + + // Initialize the chain + vals := []abci.Validator{} + bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: []byte(genState)}) + bapp.Commit() + + // Unsorted coins means invalid + err := sendMsg5.ValidateBasic() + require.Equal(t, sdk.CodeInvalidCoins, err.Code(), 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, bapp, sendMsg5, []int64{0}, true, priv1) +} + +func TestGenesis(t *testing.T) { + logger, db := loggerAndDB() bapp := NewBasecoinApp(logger, db) // Construct some genesis bytes to reflect basecoin/types/AppAccount pk := crypto.GenPrivKeyEd25519().PubKey() addr := pk.Address() - coins := sdk.Coins{{"foocoin", 77}, {"barcoin", 99}} + coins, err := sdk.ParseCoins("77foocoin,99barcoin") + require.Nil(t, err) baseAcc := auth.BaseAccount{ Address: addr, Coins: coins, } acc := &types.AppAccount{baseAcc, "foobart"} - setGenesis(t, bapp, baseAcc) + err = setGenesis(bapp, baseAcc) + require.Nil(t, err) // A checkTx context ctx := bapp.BaseApp.NewContext(true, abci.Header{}) @@ -79,3 +211,318 @@ func TestGenesis(t *testing.T) { res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) } + +func TestMsgChangePubKey(t *testing.T) { + + bapp := newBasecoinApp() + + // Construct some genesis bytes to reflect basecoin/types/AppAccount + // 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 = setGenesis(bapp, baseAcc) + require.Nil(t, err) + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, baseAcc, res1.(*types.AppAccount).BaseAccount) + + // Run a CheckDeliver + SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) + + // Check balances + CheckBalance(t, bapp, addr1, "67foocoin") + CheckBalance(t, bapp, addr2, "10foocoin") + + changePubKeyMsg := auth.MsgChangeKey{ + Address: addr1, + NewPubKey: priv2.PubKey(), + } + + ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) + acc := bapp.accountMapper.GetAccount(ctxDeliver, addr1) + + // send a MsgChangePubKey + SignCheckDeliver(t, bapp, changePubKeyMsg, []int64{1}, true, priv1) + acc = bapp.accountMapper.GetAccount(ctxDeliver, addr1) + + assert.True(t, priv2.PubKey().Equals(acc.GetPubKey())) + + // signing a SendMsg with the old privKey should be an auth error + tx := genTx(sendMsg1, []int64{2}, priv1) + res := bapp.Deliver(tx) + assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) + + // resigning the tx with the new correct priv key should work + SignCheckDeliver(t, bapp, sendMsg1, []int64{2}, true, priv2) + + // Check balances + CheckBalance(t, bapp, addr1, "57foocoin") + CheckBalance(t, bapp, addr2, "20foocoin") +} + +func TestMsgSendWithAccounts(t *testing.T) { + bapp := newBasecoinApp() + + // Construct some genesis bytes to reflect basecoin/types/AppAccount + // 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 = setGenesis(bapp, baseAcc) + require.Nil(t, err) + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, baseAcc, res1.(*types.AppAccount).BaseAccount) + + // Run a CheckDeliver + SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) + + // Check balances + CheckBalance(t, bapp, addr1, "67foocoin") + CheckBalance(t, bapp, addr2, "10foocoin") + + // Delivering again should cause replay error + SignCheckDeliver(t, bapp, 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 := bapp.Deliver(tx) + + 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) +} + +func TestMsgSendMultipleOut(t *testing.T) { + bapp := newBasecoinApp() + + genCoins, err := sdk.ParseCoins("42foocoin") + require.Nil(t, err) + + acc1 := auth.BaseAccount{ + Address: addr1, + Coins: genCoins, + } + + acc2 := auth.BaseAccount{ + Address: addr2, + Coins: genCoins, + } + + // Construct genesis state + err = setGenesis(bapp, acc1, acc2) + require.Nil(t, err) + + // Simulate a Block + SignCheckDeliver(t, bapp, sendMsg2, []int64{0}, true, priv1) + + // Check balances + CheckBalance(t, bapp, addr1, "32foocoin") + CheckBalance(t, bapp, addr2, "47foocoin") + CheckBalance(t, bapp, addr3, "5foocoin") +} + +func TestSengMsgMultipleInOut(t *testing.T) { + bapp := newBasecoinApp() + + 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 = setGenesis(bapp, acc1, acc2, acc4) + assert.Nil(t, err) + + // CheckDeliver + SignCheckDeliver(t, bapp, sendMsg3, []int64{0, 0}, true, priv1, priv4) + + // Check balances + CheckBalance(t, bapp, addr1, "32foocoin") + CheckBalance(t, bapp, addr4, "32foocoin") + CheckBalance(t, bapp, addr2, "52foocoin") + CheckBalance(t, bapp, addr3, "10foocoin") +} + +func TestMsgSendDependent(t *testing.T) { + bapp := newBasecoinApp() + + genCoins, err := sdk.ParseCoins("42foocoin") + require.Nil(t, err) + + acc1 := auth.BaseAccount{ + Address: addr1, + Coins: genCoins, + } + + // Construct genesis state + err = setGenesis(bapp, acc1) + require.Nil(t, err) + + err = setGenesis(bapp, acc1) + assert.Nil(t, err) + + // CheckDeliver + SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) + + // Check balances + CheckBalance(t, bapp, addr1, "32foocoin") + CheckBalance(t, bapp, addr2, "10foocoin") + + // Simulate a Block + SignCheckDeliver(t, bapp, sendMsg4, []int64{0}, true, priv2) + + // Check balances + CheckBalance(t, bapp, addr1, "42foocoin") +} + +func TestMsgQuiz(t *testing.T) { + bapp := newBasecoinApp() + + // Construct genesis state + // Construct some genesis bytes to reflect basecoin/types/AppAccount + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: nil, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + + // Construct genesis state + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc1), + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + require.Nil(t, err) + + // Initialize the chain (nil) + vals := []abci.Validator{} + bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) + bapp.Commit() + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + +} + +func TestIBCMsgs(t *testing.T) { + bapp := newBasecoinApp() + + sourceChain := "source-chain" + destChain := "dest-chain" + + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + + err := setGenesis(bapp, baseAcc) + assert.Nil(t, err) + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, 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, bapp, transferMsg, []int64{0}, true, priv1) + CheckBalance(t, bapp, addr1, "") + SignCheckDeliver(t, bapp, transferMsg, []int64{1}, false, priv1) + SignCheckDeliver(t, bapp, receiveMsg, []int64{2}, true, priv1) + CheckBalance(t, bapp, addr1, "10foocoin") + SignCheckDeliver(t, bapp, receiveMsg, []int64{3}, false, priv1) +} + +func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { + sigs := make([]auth.StdSignature, len(priv)) + for i, p := range priv { + sigs[i] = auth.StdSignature{ + PubKey: p.PubKey(), + Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), + Sequence: seq[i], + } + } + + return auth.NewStdTx(msg, fee, sigs) + +} + +func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { + + // Sign the tx + tx := genTx(msg, seq, priv...) + // Run a Check + res := bapp.Check(tx) + if expPass { + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) + } else { + 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.ABCICodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) + } + bapp.EndBlock(abci.RequestEndBlock{}) + //bapp.Commit() +} + +func CheckBalance(t *testing.T, bapp *BasecoinApp, addr sdk.Address, balExpected string) { + ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) + res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr) + assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) +} diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index 01264399a..ba041bcff 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -2,6 +2,7 @@ package app import ( "encoding/json" + "fmt" "os" "testing" @@ -9,8 +10,12 @@ import ( "github.com/stretchr/testify/require" "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" 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" @@ -18,9 +23,101 @@ import ( "github.com/tendermint/tmlibs/log" ) -func TestGenesis(t *testing.T) { +// Construct some global addrs and txs for tests. +var ( + chainID = "" // TODO + + priv1 = crypto.GenPrivKeyEd25519() + addr1 = priv1.PubKey().Address() + addr2 = crypto.GenPrivKeyEd25519().PubKey().Address() + coins = sdk.Coins{{"foocoin", 10}} + fee = auth.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 1000000, + } + + sendMsg = bank.MsgSend{ + Inputs: []bank.Input{bank.NewInput(addr1, coins)}, + Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, + } + + quizMsg1 = cool.MsgQuiz{ + Sender: addr1, + CoolAnswer: "icecold", + } + + quizMsg2 = cool.MsgQuiz{ + Sender: addr1, + CoolAnswer: "badvibesonly", + } + + setTrendMsg1 = cool.MsgSetTrend{ + Sender: addr1, + Cool: "icecold", + } + + setTrendMsg2 = cool.MsgSetTrend{ + Sender: addr1, + Cool: "badvibesonly", + } + + setTrendMsg3 = cool.MsgSetTrend{ + Sender: addr1, + Cool: "warmandkind", + } +) + +func loggerAndDB() (log.Logger, dbm.DB) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") db := dbm.NewMemDB() + return logger, db +} + +func newDemocoinApp() *DemocoinApp { + logger, db := loggerAndDB() + return NewDemocoinApp(logger, db) +} + +//_______________________________________________________________________ + +func TestMsgs(t *testing.T) { + bapp := newDemocoinApp() + + msgs := []struct { + msg sdk.Msg + }{ + {sendMsg}, + {quizMsg1}, + {setTrendMsg1}, + } + + sequences := []int64{0} + for i, m := range msgs { + sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, m.msg)) + tx := auth.NewStdTx(m.msg, fee, []auth.StdSignature{{ + PubKey: priv1.PubKey(), + Signature: sig, + }}) + + // just marshal/unmarshal! + txBytes, err := bapp.cdc.MarshalBinary(tx) + require.NoError(t, err, "i: %v", i) + + // Run a Check + cres := bapp.CheckTx(txBytes) + assert.Equal(t, sdk.CodeUnknownAddress, + sdk.CodeType(cres.Code), "i: %v, log: %v", i, cres.Log) + + // Simulate a Block + bapp.BeginBlock(abci.RequestBeginBlock{}) + dres := bapp.DeliverTx(txBytes) + assert.Equal(t, sdk.CodeUnknownAddress, + sdk.CodeType(dres.Code), "i: %v, log: %v", i, dres.Log) + } +} + +func TestGenesis(t *testing.T) { + logger, db := loggerAndDB() bapp := NewDemocoinApp(logger, db) // Construct some genesis bytes to reflect democoin/types/AppAccount @@ -59,3 +156,272 @@ func TestGenesis(t *testing.T) { res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) } + +func TestMsgSendWithAccounts(t *testing.T) { + bapp := newDemocoinApp() + + // Construct some genesis bytes to reflect democoin/types/AppAccount + // Give 77 foocoin to the first key + coins, err := sdk.ParseCoins("77foocoin") + require.Nil(t, err) + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + + // Construct genesis state + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc1), + }, + "cool": map[string]string{ + "trend": "ice-cold", + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + require.Nil(t, err) + + // Initialize the chain + vals := []abci.Validator{} + bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) + bapp.Commit() + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + // Sign the tx + sequences := []int64{0} + sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, sendMsg)) + tx := auth.NewStdTx(sendMsg, fee, []auth.StdSignature{{ + PubKey: priv1.PubKey(), + Signature: sig, + }}) + + // Run a Check + res := bapp.Check(tx) + assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) + + // Simulate a Block + bapp.BeginBlock(abci.RequestBeginBlock{}) + res = bapp.Deliver(tx) + assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) + + // Check balances + ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) + res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) + res3 := bapp.accountMapper.GetAccount(ctxDeliver, addr2) + assert.Equal(t, fmt.Sprintf("%v", res2.GetCoins()), "67foocoin") + assert.Equal(t, fmt.Sprintf("%v", res3.GetCoins()), "10foocoin") + + // Delivering again should cause replay error + res = bapp.Deliver(tx) + 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.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(auth.StdSignBytes(chainID, sequences, fee, tx.Msg)) + tx.Signatures[0].Signature = sig + res = bapp.Deliver(tx) + assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) +} + +func TestMsgMine(t *testing.T) { + bapp := newDemocoinApp() + + // Construct genesis state + // Construct some genesis bytes to reflect democoin/types/AppAccount + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: nil, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + + // Construct genesis state + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc1), + }, + "cool": map[string]string{ + "trend": "ice-cold", + }, + "pow": map[string]uint64{ + "difficulty": 1, + "count": 0, + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + require.Nil(t, err) + + // Initialize the chain (nil) + vals := []abci.Validator{} + bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) + bapp.Commit() + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + // Mine and check for reward + mineMsg1 := pow.GenerateMsgMine(addr1, 1, 2) + SignCheckDeliver(t, bapp, mineMsg1, 0, true) + CheckBalance(t, bapp, "1pow") + // Mine again and check for reward + mineMsg2 := pow.GenerateMsgMine(addr1, 2, 3) + SignCheckDeliver(t, bapp, mineMsg2, 1, true) + CheckBalance(t, bapp, "2pow") + // Mine again - should be invalid + SignCheckDeliver(t, bapp, mineMsg2, 1, false) + CheckBalance(t, bapp, "2pow") + +} + +func TestMsgQuiz(t *testing.T) { + bapp := newDemocoinApp() + + // Construct genesis state + // Construct some genesis bytes to reflect democoin/types/AppAccount + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: nil, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + + // Construct genesis state + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc1), + }, + "cool": map[string]string{ + "trend": "ice-cold", + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + require.Nil(t, err) + + // Initialize the chain (nil) + vals := []abci.Validator{} + bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) + bapp.Commit() + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, res1) + + // Set the trend, submit a really cool quiz and check for reward + SignCheckDeliver(t, bapp, setTrendMsg1, 0, true) + SignCheckDeliver(t, bapp, quizMsg1, 1, true) + CheckBalance(t, bapp, "69icecold") + SignCheckDeliver(t, bapp, quizMsg2, 2, false) // result without reward + CheckBalance(t, bapp, "69icecold") + SignCheckDeliver(t, bapp, quizMsg1, 3, true) + CheckBalance(t, bapp, "138icecold") + SignCheckDeliver(t, bapp, setTrendMsg2, 4, true) // reset the trend + SignCheckDeliver(t, bapp, quizMsg1, 5, false) // the same answer will nolonger do! + CheckBalance(t, bapp, "138icecold") + SignCheckDeliver(t, bapp, quizMsg2, 6, true) // earlier answer now relavent again + CheckBalance(t, bapp, "69badvibesonly,138icecold") + SignCheckDeliver(t, bapp, setTrendMsg3, 7, false) // expect to fail to set the trend to something which is not cool + +} + +func TestHandler(t *testing.T) { + bapp := newDemocoinApp() + + sourceChain := "source-chain" + destChain := "dest-chain" + + vals := []abci.Validator{} + baseAcc := auth.BaseAccount{ + Address: addr1, + Coins: coins, + } + acc1 := &types.AppAccount{baseAcc, "foobart"} + genesisState := map[string]interface{}{ + "accounts": []*types.GenesisAccount{ + types.NewGenesisAccount(acc1), + }, + "cool": map[string]string{ + "trend": "ice-cold", + }, + } + stateBytes, err := json.MarshalIndent(genesisState, "", "\t") + require.Nil(t, err) + bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) + bapp.Commit() + + // A checkTx context (true) + ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) + res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) + assert.Equal(t, acc1, 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, bapp, transferMsg, 0, true) + CheckBalance(t, bapp, "") + SignCheckDeliver(t, bapp, transferMsg, 1, false) + SignCheckDeliver(t, bapp, receiveMsg, 2, true) + CheckBalance(t, bapp, "10foocoin") + SignCheckDeliver(t, bapp, receiveMsg, 3, false) +} + +// TODO describe the use of this function +func SignCheckDeliver(t *testing.T, bapp *DemocoinApp, msg sdk.Msg, seq int64, expPass bool) { + + // Sign the tx + tx := auth.NewStdTx(msg, fee, []auth.StdSignature{{ + PubKey: priv1.PubKey(), + Signature: priv1.Sign(auth.StdSignBytes(chainID, []int64{seq}, fee, msg)), + Sequence: seq, + }}) + + // Run a Check + res := bapp.Check(tx) + if expPass { + require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) + } else { + 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.ABCICodeOK, res.Code, res.Log) + } else { + require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) + } + bapp.EndBlock(abci.RequestEndBlock{}) + //bapp.Commit() +} + +func CheckBalance(t *testing.T, bapp *DemocoinApp, balExpected string) { + ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) + res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) + assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) +} diff --git a/server/init_test.go b/server/init_test.go index eca529505..300decf33 100644 --- a/server/init_test.go +++ b/server/init_test.go @@ -7,7 +7,7 @@ import ( "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/mock" + "github.com/cosmos/cosmos-sdk/server/mock" "github.com/cosmos/cosmos-sdk/wire" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" ) diff --git a/mock/app.go b/server/mock/app.go similarity index 100% rename from mock/app.go rename to server/mock/app.go diff --git a/mock/app_test.go b/server/mock/app_test.go similarity index 100% rename from mock/app_test.go rename to server/mock/app_test.go diff --git a/mock/helpers.go b/server/mock/helpers.go similarity index 100% rename from mock/helpers.go rename to server/mock/helpers.go diff --git a/mock/store.go b/server/mock/store.go similarity index 100% rename from mock/store.go rename to server/mock/store.go diff --git a/mock/store_test.go b/server/mock/store_test.go similarity index 100% rename from mock/store_test.go rename to server/mock/store_test.go diff --git a/mock/tx.go b/server/mock/tx.go similarity index 100% rename from mock/tx.go rename to server/mock/tx.go diff --git a/server/start_test.go b/server/start_test.go index 454f2d492..1c1ad671e 100644 --- a/server/start_test.go +++ b/server/start_test.go @@ -9,7 +9,7 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/mock" + "github.com/cosmos/cosmos-sdk/server/mock" "github.com/cosmos/cosmos-sdk/wire" "github.com/tendermint/abci/server" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" diff --git a/x/auth/mock/app.go b/x/auth/mock/app.go index 6ceff482b..fcd130b44 100644 --- a/x/auth/mock/app.go +++ b/x/auth/mock/app.go @@ -30,7 +30,7 @@ type App struct { GenesisAccounts []auth.Account } -// NewApp is used for testing the server. For the internal mock app stuff, it uses code in helpers.go +// partially construct a new app on the memstore for module and genesis testing func NewApp() *App { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") db := dbm.NewMemDB() From 61a510ed08d6eaddc391676fffe8b9b04c5742ec Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Thu, 7 Jun 2018 21:46:27 -0700 Subject: [PATCH 32/89] ... --- CHANGELOG.md | 1 + cmd/gaia/app/app_test.go | 471 +----------------------------- examples/basecoin/app/app_test.go | 455 +---------------------------- examples/democoin/app/app_test.go | 368 +---------------------- 4 files changed, 9 insertions(+), 1286 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d6541691..bcdcf7302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ IMPROVEMENTS FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs +* [lcd] Switch to bech32 for addresses on all human readable inputs and outputs ## 0.18.0 diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 0fe1cfe5b..f79703fef 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -1,7 +1,6 @@ package app import ( - "fmt" "os" "testing" @@ -11,8 +10,6 @@ import ( 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" abci "github.com/tendermint/abci/types" @@ -21,81 +18,6 @@ import ( "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 = auth.StdFee{ - sdk.Coins{{"foocoin", 0}}, - 100000, - } - - sendMsg1 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } - - sendMsg2 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{ - bank.NewOutput(addr2, halfCoins), - bank.NewOutput(addr3, halfCoins), - }, - } - - sendMsg3 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, coins), - bank.NewInput(addr4, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, coins), - bank.NewOutput(addr3, coins), - }, - } - - sendMsg4 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr2, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr1, coins), - }, - } - - sendMsg5 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, manyCoins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, manyCoins), - }, - } -) - -func loggerAndDB() (log.Logger, dbm.DB) { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - db := dbm.NewMemDB() - return logger, db -} - -func newGaiaApp() *GaiaApp { - logger, db := loggerAndDB() - return NewGaiaApp(logger, db) -} - func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { genaccs := make([]GenesisAccount, len(accs)) for i, acc := range accs { @@ -120,27 +42,10 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { return nil } -//_______________________________________________________________________ - -func TestMsgs(t *testing.T) { - gapp := newGaiaApp() - require.Nil(t, setGenesis(gapp)) - - 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 TestGenesis(t *testing.T) { - logger, dbs := loggerAndDB() - gapp := NewGaiaApp(logger, dbs) + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") + db := dbm.NewMemDB() + gapp := NewGaiaApp(logger, db) // Construct some genesis bytes to reflect GaiaAccount pk := crypto.GenPrivKeyEd25519().PubKey() @@ -161,376 +66,8 @@ func TestGenesis(t *testing.T) { assert.Equal(t, baseAcc, res1) // reload app and ensure the account is still there - gapp = NewGaiaApp(logger, dbs) + gapp = NewGaiaApp(logger, db) ctx = gapp.BaseApp.NewContext(true, abci.Header{}) res1 = gapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, baseAcc, res1) } - -func TestMsgSendWithAccounts(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 = setGenesis(gapp, baseAcc) - require.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.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) -} - -func TestMsgSendMultipleOut(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 = setGenesis(gapp, acc1, acc2) - require.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 = setGenesis(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 TestMsgSendDependent(t *testing.T) { - gapp := newGaiaApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := &auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - err = setGenesis(gapp, acc1) - require.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 := setGenesis(gapp, baseAcc) - require.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 TestStakeMsgs(t *testing.T) { - gapp := newGaiaApp() - - genCoins, err := sdk.ParseCoins("42steak") - require.Nil(t, err) - bondCoin, err := sdk.ParseCoin("10steak") - 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) - - // Create Validator - - description := stake.NewDescription("foo_moniker", "", "", "") - createValidatorMsg := stake.NewMsgCreateValidator( - addr1, priv1.PubKey(), bondCoin, description, - ) - SignCheckDeliver(t, gapp, createValidatorMsg, []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()) - validator, found := gapp.stakeKeeper.GetValidator(ctxDeliver, addr1) - require.True(t, found) - require.Equal(t, addr1, validator.Owner) - require.Equal(t, sdk.Bonded, validator.Status()) - require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) - - // check the bond that should have been created as well - bond, found := gapp.stakeKeeper.GetDelegation(ctxDeliver, addr1, addr1) - require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) - - // Edit Validator - - description = stake.NewDescription("bar_moniker", "", "", "") - editValidatorMsg := stake.NewMsgEditValidator( - addr1, description, - ) - SignDeliver(t, gapp, editValidatorMsg, []int64{1}, true, priv1) - - validator, found = gapp.stakeKeeper.GetValidator(ctxDeliver, addr1) - require.True(t, found) - require.Equal(t, description, validator.Description) - - // Delegate - - delegateMsg := stake.NewMsgDelegate( - addr2, addr1, bondCoin, - ) - SignDeliver(t, gapp, delegateMsg, []int64{0}, true, priv2) - - res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) - require.Equal(t, genCoins.Minus(sdk.Coins{bondCoin}), res2.GetCoins()) - bond, found = gapp.stakeKeeper.GetDelegation(ctxDeliver, addr2, addr1) - require.True(t, found) - require.Equal(t, addr2, bond.DelegatorAddr) - require.Equal(t, addr1, bond.ValidatorAddr) - require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) - - // Unbond - - unbondMsg := stake.NewMsgUnbond( - addr2, addr1, "MAX", - ) - SignDeliver(t, gapp, unbondMsg, []int64{1}, true, priv2) - - res2 = gapp.accountMapper.GetAccount(ctxDeliver, addr2) - require.Equal(t, genCoins, res2.GetCoins()) - _, found = gapp.stakeKeeper.GetDelegation(ctxDeliver, addr2, addr1) - require.False(t, found) -} - -func TestExportValidators(t *testing.T) { - gapp := newGaiaApp() - - genCoins, err := sdk.ParseCoins("42steak") - require.Nil(t, err) - bondCoin, err := sdk.ParseCoin("10steak") - 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) - - // Create Validator - description := stake.NewDescription("foo_moniker", "", "", "") - createValidatorMsg := stake.NewMsgCreateValidator( - addr1, priv1.PubKey(), bondCoin, description, - ) - SignCheckDeliver(t, gapp, createValidatorMsg, []int64{0}, true, priv1) - gapp.Commit() - - // Export validator set - _, validators, err := gapp.ExportAppStateAndValidators() - require.Nil(t, err) - require.Equal(t, 1, len(validators)) // 1 validator - require.Equal(t, priv1.PubKey(), validators[0].PubKey) - require.Equal(t, int64(10), validators[0].Power) -} - -//____________________________________________________________________________________ - -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) auth.StdTx { - sigs := make([]auth.StdSignature, len(priv)) - for i, p := range priv { - sigs[i] = auth.StdSignature{ - PubKey: p.PubKey(), - Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), - Sequence: seq[i], - } - } - - return auth.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.ABCICodeOK, res.Code, res.Log) - } else { - 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.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, 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.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - gapp.EndBlock(abci.RequestEndBlock{}) -} diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 3027a8470..521516d47 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -1,8 +1,6 @@ package app import ( - "encoding/json" - "fmt" "os" "testing" @@ -13,8 +11,6 @@ import ( 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" abci "github.com/tendermint/abci/types" @@ -23,69 +19,7 @@ import ( "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 = auth.StdFee{ - sdk.Coins{{"foocoin", 0}}, - 100000, - } - - sendMsg1 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } - - sendMsg2 = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{ - bank.NewOutput(addr2, halfCoins), - bank.NewOutput(addr3, halfCoins), - }, - } - - sendMsg3 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, coins), - bank.NewInput(addr4, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, coins), - bank.NewOutput(addr3, coins), - }, - } - - sendMsg4 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr2, coins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr1, coins), - }, - } - - sendMsg5 = bank.MsgSend{ - Inputs: []bank.Input{ - bank.NewInput(addr1, manyCoins), - }, - Outputs: []bank.Output{ - bank.NewOutput(addr2, manyCoins), - }, - } -) +var accName = "foobart" func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { genaccs := make([]*types.GenesisAccount, len(accs)) @@ -111,79 +45,11 @@ func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { return nil } -func loggerAndDB() (log.Logger, dbm.DB) { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - db := dbm.NewMemDB() - return logger, db -} - -func newBasecoinApp() *BasecoinApp { - logger, db := loggerAndDB() - return NewBasecoinApp(logger, db) -} - //_______________________________________________________________________ -func TestMsgs(t *testing.T) { - bapp := newBasecoinApp() - require.Nil(t, setGenesis(bapp)) - - msgs := []struct { - msg sdk.Msg - }{ - {sendMsg1}, - } - - for i, m := range msgs { - // Run a CheckDeliver - SignCheckDeliver(t, bapp, m.msg, []int64{int64(i)}, false, priv1) - } -} - -func TestSortGenesis(t *testing.T) { - logger, db := loggerAndDB() - bapp := NewBasecoinApp(logger, db) - - // Note the order: the coins are unsorted! - coinDenom1, coinDenom2 := "foocoin", "barcoin" - - genState := fmt.Sprintf(`{ - "accounts": [{ - "address": "%s", - "coins": [ - { - "denom": "%s", - "amount": 10 - }, - { - "denom": "%s", - "amount": 20 - } - ] - }] - }`, addr1.String(), coinDenom1, coinDenom2) - - // Initialize the chain - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: []byte(genState)}) - bapp.Commit() - - // Unsorted coins means invalid - err := sendMsg5.ValidateBasic() - require.Equal(t, sdk.CodeInvalidCoins, err.Code(), 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, bapp, sendMsg5, []int64{0}, true, priv1) -} - func TestGenesis(t *testing.T) { - logger, db := loggerAndDB() + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") + db := dbm.NewMemDB() bapp := NewBasecoinApp(logger, db) // Construct some genesis bytes to reflect basecoin/types/AppAccount @@ -211,318 +77,3 @@ func TestGenesis(t *testing.T) { res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) } - -func TestMsgChangePubKey(t *testing.T) { - - bapp := newBasecoinApp() - - // Construct some genesis bytes to reflect basecoin/types/AppAccount - // 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 = setGenesis(bapp, baseAcc) - require.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, baseAcc, res1.(*types.AppAccount).BaseAccount) - - // Run a CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "67foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - changePubKeyMsg := auth.MsgChangeKey{ - Address: addr1, - NewPubKey: priv2.PubKey(), - } - - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - acc := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - - // send a MsgChangePubKey - SignCheckDeliver(t, bapp, changePubKeyMsg, []int64{1}, true, priv1) - acc = bapp.accountMapper.GetAccount(ctxDeliver, addr1) - - assert.True(t, priv2.PubKey().Equals(acc.GetPubKey())) - - // signing a SendMsg with the old privKey should be an auth error - tx := genTx(sendMsg1, []int64{2}, priv1) - res := bapp.Deliver(tx) - assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) - - // resigning the tx with the new correct priv key should work - SignCheckDeliver(t, bapp, sendMsg1, []int64{2}, true, priv2) - - // Check balances - CheckBalance(t, bapp, addr1, "57foocoin") - CheckBalance(t, bapp, addr2, "20foocoin") -} - -func TestMsgSendWithAccounts(t *testing.T) { - bapp := newBasecoinApp() - - // Construct some genesis bytes to reflect basecoin/types/AppAccount - // 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 = setGenesis(bapp, baseAcc) - require.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, baseAcc, res1.(*types.AppAccount).BaseAccount) - - // Run a CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "67foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - // Delivering again should cause replay error - SignCheckDeliver(t, bapp, 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 := bapp.Deliver(tx) - - 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) -} - -func TestMsgSendMultipleOut(t *testing.T) { - bapp := newBasecoinApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - acc2 := auth.BaseAccount{ - Address: addr2, - Coins: genCoins, - } - - // Construct genesis state - err = setGenesis(bapp, acc1, acc2) - require.Nil(t, err) - - // Simulate a Block - SignCheckDeliver(t, bapp, sendMsg2, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr2, "47foocoin") - CheckBalance(t, bapp, addr3, "5foocoin") -} - -func TestSengMsgMultipleInOut(t *testing.T) { - bapp := newBasecoinApp() - - 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 = setGenesis(bapp, acc1, acc2, acc4) - assert.Nil(t, err) - - // CheckDeliver - SignCheckDeliver(t, bapp, sendMsg3, []int64{0, 0}, true, priv1, priv4) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr4, "32foocoin") - CheckBalance(t, bapp, addr2, "52foocoin") - CheckBalance(t, bapp, addr3, "10foocoin") -} - -func TestMsgSendDependent(t *testing.T) { - bapp := newBasecoinApp() - - genCoins, err := sdk.ParseCoins("42foocoin") - require.Nil(t, err) - - acc1 := auth.BaseAccount{ - Address: addr1, - Coins: genCoins, - } - - // Construct genesis state - err = setGenesis(bapp, acc1) - require.Nil(t, err) - - err = setGenesis(bapp, acc1) - assert.Nil(t, err) - - // CheckDeliver - SignCheckDeliver(t, bapp, sendMsg1, []int64{0}, true, priv1) - - // Check balances - CheckBalance(t, bapp, addr1, "32foocoin") - CheckBalance(t, bapp, addr2, "10foocoin") - - // Simulate a Block - SignCheckDeliver(t, bapp, sendMsg4, []int64{0}, true, priv2) - - // Check balances - CheckBalance(t, bapp, addr1, "42foocoin") -} - -func TestMsgQuiz(t *testing.T) { - bapp := newBasecoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect basecoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - -} - -func TestIBCMsgs(t *testing.T) { - bapp := newBasecoinApp() - - sourceChain := "source-chain" - destChain := "dest-chain" - - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - err := setGenesis(bapp, baseAcc) - assert.Nil(t, err) - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, 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, bapp, transferMsg, []int64{0}, true, priv1) - CheckBalance(t, bapp, addr1, "") - SignCheckDeliver(t, bapp, transferMsg, []int64{1}, false, priv1) - SignCheckDeliver(t, bapp, receiveMsg, []int64{2}, true, priv1) - CheckBalance(t, bapp, addr1, "10foocoin") - SignCheckDeliver(t, bapp, receiveMsg, []int64{3}, false, priv1) -} - -func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { - sigs := make([]auth.StdSignature, len(priv)) - for i, p := range priv { - sigs[i] = auth.StdSignature{ - PubKey: p.PubKey(), - Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), - Sequence: seq[i], - } - } - - return auth.NewStdTx(msg, fee, sigs) - -} - -func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { - - // Sign the tx - tx := genTx(msg, seq, priv...) - // Run a Check - res := bapp.Check(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - 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.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - bapp.EndBlock(abci.RequestEndBlock{}) - //bapp.Commit() -} - -func CheckBalance(t *testing.T, bapp *BasecoinApp, addr sdk.Address, balExpected string) { - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr) - assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) -} diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index ba041bcff..01264399a 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -2,7 +2,6 @@ package app import ( "encoding/json" - "fmt" "os" "testing" @@ -10,12 +9,8 @@ import ( "github.com/stretchr/testify/require" "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" 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" @@ -23,101 +18,9 @@ import ( "github.com/tendermint/tmlibs/log" ) -// Construct some global addrs and txs for tests. -var ( - chainID = "" // TODO - - priv1 = crypto.GenPrivKeyEd25519() - addr1 = priv1.PubKey().Address() - addr2 = crypto.GenPrivKeyEd25519().PubKey().Address() - coins = sdk.Coins{{"foocoin", 10}} - fee = auth.StdFee{ - sdk.Coins{{"foocoin", 0}}, - 1000000, - } - - sendMsg = bank.MsgSend{ - Inputs: []bank.Input{bank.NewInput(addr1, coins)}, - Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, - } - - quizMsg1 = cool.MsgQuiz{ - Sender: addr1, - CoolAnswer: "icecold", - } - - quizMsg2 = cool.MsgQuiz{ - Sender: addr1, - CoolAnswer: "badvibesonly", - } - - setTrendMsg1 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "icecold", - } - - setTrendMsg2 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "badvibesonly", - } - - setTrendMsg3 = cool.MsgSetTrend{ - Sender: addr1, - Cool: "warmandkind", - } -) - -func loggerAndDB() (log.Logger, dbm.DB) { +func TestGenesis(t *testing.T) { logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") db := dbm.NewMemDB() - return logger, db -} - -func newDemocoinApp() *DemocoinApp { - logger, db := loggerAndDB() - return NewDemocoinApp(logger, db) -} - -//_______________________________________________________________________ - -func TestMsgs(t *testing.T) { - bapp := newDemocoinApp() - - msgs := []struct { - msg sdk.Msg - }{ - {sendMsg}, - {quizMsg1}, - {setTrendMsg1}, - } - - sequences := []int64{0} - for i, m := range msgs { - sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, m.msg)) - tx := auth.NewStdTx(m.msg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: sig, - }}) - - // just marshal/unmarshal! - txBytes, err := bapp.cdc.MarshalBinary(tx) - require.NoError(t, err, "i: %v", i) - - // Run a Check - cres := bapp.CheckTx(txBytes) - assert.Equal(t, sdk.CodeUnknownAddress, - sdk.CodeType(cres.Code), "i: %v, log: %v", i, cres.Log) - - // Simulate a Block - bapp.BeginBlock(abci.RequestBeginBlock{}) - dres := bapp.DeliverTx(txBytes) - assert.Equal(t, sdk.CodeUnknownAddress, - sdk.CodeType(dres.Code), "i: %v, log: %v", i, dres.Log) - } -} - -func TestGenesis(t *testing.T) { - logger, db := loggerAndDB() bapp := NewDemocoinApp(logger, db) // Construct some genesis bytes to reflect democoin/types/AppAccount @@ -156,272 +59,3 @@ func TestGenesis(t *testing.T) { res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address) assert.Equal(t, acc, res1) } - -func TestMsgSendWithAccounts(t *testing.T) { - bapp := newDemocoinApp() - - // Construct some genesis bytes to reflect democoin/types/AppAccount - // Give 77 foocoin to the first key - coins, err := sdk.ParseCoins("77foocoin") - require.Nil(t, err) - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Sign the tx - sequences := []int64{0} - sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, sendMsg)) - tx := auth.NewStdTx(sendMsg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: sig, - }}) - - // Run a Check - res := bapp.Check(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - - // Simulate a Block - bapp.BeginBlock(abci.RequestBeginBlock{}) - res = bapp.Deliver(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - - // Check balances - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - res3 := bapp.accountMapper.GetAccount(ctxDeliver, addr2) - assert.Equal(t, fmt.Sprintf("%v", res2.GetCoins()), "67foocoin") - assert.Equal(t, fmt.Sprintf("%v", res3.GetCoins()), "10foocoin") - - // Delivering again should cause replay error - res = bapp.Deliver(tx) - 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.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(auth.StdSignBytes(chainID, sequences, fee, tx.Msg)) - tx.Signatures[0].Signature = sig - res = bapp.Deliver(tx) - assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) -} - -func TestMsgMine(t *testing.T) { - bapp := newDemocoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect democoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - "pow": map[string]uint64{ - "difficulty": 1, - "count": 0, - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Mine and check for reward - mineMsg1 := pow.GenerateMsgMine(addr1, 1, 2) - SignCheckDeliver(t, bapp, mineMsg1, 0, true) - CheckBalance(t, bapp, "1pow") - // Mine again and check for reward - mineMsg2 := pow.GenerateMsgMine(addr1, 2, 3) - SignCheckDeliver(t, bapp, mineMsg2, 1, true) - CheckBalance(t, bapp, "2pow") - // Mine again - should be invalid - SignCheckDeliver(t, bapp, mineMsg2, 1, false) - CheckBalance(t, bapp, "2pow") - -} - -func TestMsgQuiz(t *testing.T) { - bapp := newDemocoinApp() - - // Construct genesis state - // Construct some genesis bytes to reflect democoin/types/AppAccount - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: nil, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - - // Construct genesis state - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - - // Initialize the chain (nil) - vals := []abci.Validator{} - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, res1) - - // Set the trend, submit a really cool quiz and check for reward - SignCheckDeliver(t, bapp, setTrendMsg1, 0, true) - SignCheckDeliver(t, bapp, quizMsg1, 1, true) - CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg2, 2, false) // result without reward - CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg1, 3, true) - CheckBalance(t, bapp, "138icecold") - SignCheckDeliver(t, bapp, setTrendMsg2, 4, true) // reset the trend - SignCheckDeliver(t, bapp, quizMsg1, 5, false) // the same answer will nolonger do! - CheckBalance(t, bapp, "138icecold") - SignCheckDeliver(t, bapp, quizMsg2, 6, true) // earlier answer now relavent again - CheckBalance(t, bapp, "69badvibesonly,138icecold") - SignCheckDeliver(t, bapp, setTrendMsg3, 7, false) // expect to fail to set the trend to something which is not cool - -} - -func TestHandler(t *testing.T) { - bapp := newDemocoinApp() - - sourceChain := "source-chain" - destChain := "dest-chain" - - vals := []abci.Validator{} - baseAcc := auth.BaseAccount{ - Address: addr1, - Coins: coins, - } - acc1 := &types.AppAccount{baseAcc, "foobart"} - genesisState := map[string]interface{}{ - "accounts": []*types.GenesisAccount{ - types.NewGenesisAccount(acc1), - }, - "cool": map[string]string{ - "trend": "ice-cold", - }, - } - stateBytes, err := json.MarshalIndent(genesisState, "", "\t") - require.Nil(t, err) - bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) - bapp.Commit() - - // A checkTx context (true) - ctxCheck := bapp.BaseApp.NewContext(true, abci.Header{}) - res1 := bapp.accountMapper.GetAccount(ctxCheck, addr1) - assert.Equal(t, acc1, 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, bapp, transferMsg, 0, true) - CheckBalance(t, bapp, "") - SignCheckDeliver(t, bapp, transferMsg, 1, false) - SignCheckDeliver(t, bapp, receiveMsg, 2, true) - CheckBalance(t, bapp, "10foocoin") - SignCheckDeliver(t, bapp, receiveMsg, 3, false) -} - -// TODO describe the use of this function -func SignCheckDeliver(t *testing.T, bapp *DemocoinApp, msg sdk.Msg, seq int64, expPass bool) { - - // Sign the tx - tx := auth.NewStdTx(msg, fee, []auth.StdSignature{{ - PubKey: priv1.PubKey(), - Signature: priv1.Sign(auth.StdSignBytes(chainID, []int64{seq}, fee, msg)), - Sequence: seq, - }}) - - // Run a Check - res := bapp.Check(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - 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.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - bapp.EndBlock(abci.RequestEndBlock{}) - //bapp.Commit() -} - -func CheckBalance(t *testing.T, bapp *DemocoinApp, balExpected string) { - ctxDeliver := bapp.BaseApp.NewContext(false, abci.Header{}) - res2 := bapp.accountMapper.GetAccount(ctxDeliver, addr1) - assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) -} From 42def02ae93b5a6d2c9af0b4e244a43723e78534 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 8 Jun 2018 10:03:37 -0700 Subject: [PATCH 33/89] pr comments --- CHANGELOG.md | 2 +- examples/basecoin/app/app_test.go | 4 +--- x/auth/mock/auth_app_test.go | 16 ---------------- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcdcf7302..f8157594a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,10 @@ FEATURES IMPROVEMENTS * export command now writes current validator set for Tendermint +* [tests] Application module tests now use a mock application FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs -* [lcd] Switch to bech32 for addresses on all human readable inputs and outputs ## 0.18.0 diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 521516d47..23bc531c0 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -19,12 +19,10 @@ import ( "github.com/tendermint/tmlibs/log" ) -var accName = "foobart" - func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error { genaccs := make([]*types.GenesisAccount, len(accs)) for i, acc := range accs { - genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, accName}) + genaccs[i] = types.NewGenesisAccount(&types.AppAccount{acc, "foobart"}) } genesisState := types.GenesisState{ diff --git a/x/auth/mock/auth_app_test.go b/x/auth/mock/auth_app_test.go index a3ff6710e..641c8a366 100644 --- a/x/auth/mock/auth_app_test.go +++ b/x/auth/mock/auth_app_test.go @@ -1,7 +1,6 @@ package mock import ( - "fmt" "testing" "github.com/stretchr/testify/assert" @@ -42,70 +41,55 @@ func getMockApp(t *testing.T) *App { } func TestMsgChangePubKey(t *testing.T) { - fmt.Println("wackydebugoutput TestMsgChangePubKey 0") mapp := getMockApp(t) // Construct some genesis bytes to reflect basecoin/types/AppAccount // Give 77 foocoin to the first key coins := sdk.Coins{{"foocoin", 77}} - fmt.Println("wackydebugoutput TestMsgChangePubKey 1") acc1 := &auth.BaseAccount{ Address: addr1, Coins: coins, } - fmt.Println("wackydebugoutput TestMsgChangePubKey 3") accs := []auth.Account{acc1} - fmt.Println("wackydebugoutput TestMsgChangePubKey 4") // Construct genesis state SetGenesis(mapp, accs) // A checkTx context (true) ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) - fmt.Println("wackydebugoutput TestMsgChangePubKey 5") res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) assert.Equal(t, acc1, res1.(*auth.BaseAccount)) // Run a CheckDeliver SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) - fmt.Println("wackydebugoutput TestMsgChangePubKey 6") // Check balances CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 67}}) - fmt.Println("wackydebugoutput TestMsgChangePubKey 7") CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) - fmt.Println("wackydebugoutput TestMsgChangePubKey 8") changePubKeyMsg := auth.MsgChangeKey{ Address: addr1, NewPubKey: priv2.PubKey(), } - fmt.Println("wackydebugoutput TestMsgChangePubKey 10") ctxDeliver := mapp.BaseApp.NewContext(false, abci.Header{}) - fmt.Println("wackydebugoutput TestMsgChangePubKey 11") acc2 := mapp.AccountMapper.GetAccount(ctxDeliver, addr1) // send a MsgChangePubKey SignCheckDeliver(t, mapp.BaseApp, changePubKeyMsg, []int64{1}, true, priv1) - fmt.Println("wackydebugoutput TestMsgChangePubKey 12") acc2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr1) assert.True(t, priv2.PubKey().Equals(acc2.GetPubKey())) // signing a SendMsg with the old privKey should be an auth error tx := GenTx(sendMsg1, []int64{2}, priv1) - fmt.Println("wackydebugoutput TestMsgChangePubKey 13") res := mapp.Deliver(tx) assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) // resigning the tx with the new correct priv key should work SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{2}, true, priv2) - fmt.Println("wackydebugoutput TestMsgChangePubKey 14") // Check balances CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 57}}) - fmt.Println("wackydebugoutput TestMsgChangePubKey 15") CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 20}}) - fmt.Println("wackydebugoutput TestMsgChangePubKey 16") } From 17948ccf0411f9ea685651d68a6f21cbfe6e56b2 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 8 Jun 2018 11:28:07 -0700 Subject: [PATCH 34/89] auth-mock simulate block now commits, stake app_test cleanup --- baseapp/baseapp.go | 5 +- x/auth/mock/auth_app_test.go | 2 + x/auth/mock/simulate_block.go | 32 ++++++------- x/bank/app_test.go | 1 + x/stake/app_test.go | 89 ++++++++++++++++++----------------- 5 files changed, 70 insertions(+), 59 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 4d32b92f5..0664f18eb 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -237,7 +237,10 @@ func (app *BaseApp) NewContext(isCheckTx bool, header abci.Header) sdk.Context { if isCheckTx { return sdk.NewContext(app.checkState.ms, header, true, nil, app.Logger) } - return sdk.NewContext(app.deliverState.ms, header, false, nil, app.Logger) + aa := app.deliverState + a := aa.ms + b := app.Logger + return sdk.NewContext(a, header, false, nil, b) } type state struct { diff --git a/x/auth/mock/auth_app_test.go b/x/auth/mock/auth_app_test.go index 641c8a366..716037d60 100644 --- a/x/auth/mock/auth_app_test.go +++ b/x/auth/mock/auth_app_test.go @@ -72,6 +72,7 @@ func TestMsgChangePubKey(t *testing.T) { NewPubKey: priv2.PubKey(), } + mapp.BeginBlock(abci.RequestBeginBlock{}) ctxDeliver := mapp.BaseApp.NewContext(false, abci.Header{}) acc2 := mapp.AccountMapper.GetAccount(ctxDeliver, addr1) @@ -82,6 +83,7 @@ func TestMsgChangePubKey(t *testing.T) { assert.True(t, priv2.PubKey().Equals(acc2.GetPubKey())) // signing a SendMsg with the old privKey should be an auth error + mapp.BeginBlock(abci.RequestBeginBlock{}) tx := GenTx(sendMsg1, []int64{2}, priv1) res := mapp.Deliver(tx) assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) diff --git a/x/auth/mock/simulate_block.go b/x/auth/mock/simulate_block.go index cf0c303a3..f8be0c65a 100644 --- a/x/auth/mock/simulate_block.go +++ b/x/auth/mock/simulate_block.go @@ -27,8 +27,8 @@ func SetGenesis(app *App, accs []auth.Account) { // check an account balance func CheckBalance(t *testing.T, app *App, addr sdk.Address, exp sdk.Coins) { - ctxDeliver := app.BaseApp.NewContext(false, abci.Header{}) - res := app.AccountMapper.GetAccount(ctxDeliver, addr) + ctxCheck := app.BaseApp.NewContext(true, abci.Header{}) + res := app.AccountMapper.GetAccount(ctxCheck, addr) assert.Equal(t, exp, res.GetCoins()) } @@ -77,25 +77,25 @@ func SignCheckDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int app.EndBlock(abci.RequestEndBlock{}) // XXX fix code or add explaination as to why using commit breaks a bunch of these tests - //app.Commit() + app.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, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { +//func SignDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { - // Sign the tx - tx := GenTx(msg, seq, priv...) +//// Sign the tx +//tx := GenTx(msg, seq, priv...) - // Simulate a Block - app.BeginBlock(abci.RequestBeginBlock{}) - res := app.Deliver(tx) - if expPass { - require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) - } else { - require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) - } - app.EndBlock(abci.RequestEndBlock{}) -} +//// Simulate a Block +//app.BeginBlock(abci.RequestBeginBlock{}) +//res := app.Deliver(tx) +//if expPass { +//require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) +//} else { +//require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) +//} +//app.EndBlock(abci.RequestEndBlock{}) +//} diff --git a/x/bank/app_test.go b/x/bank/app_test.go index 507f9e3f8..21d7d03a0 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -117,6 +117,7 @@ func TestMsgSendWithAccounts(t *testing.T) { mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, false, priv1) // bumping the txnonce number without resigning should be an auth error + mapp.BeginBlock(abci.RequestBeginBlock{}) tx := mock.GenTx(sendMsg1, []int64{0}, priv1) tx.Signatures[0].Sequence = 1 res := mapp.Deliver(tx) diff --git a/x/stake/app_test.go b/x/stake/app_test.go index 4e3d1f422..8e20633a0 100644 --- a/x/stake/app_test.go +++ b/x/stake/app_test.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/mock" "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" @@ -65,6 +66,30 @@ func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer { } } +//__________________________________________________________________________________________ + +func checkValidator(t *testing.T, mapp *mock.App, keeper Keeper, + addr sdk.Address, expFound bool) Validator { + + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + validator, found := keeper.GetValidator(ctxCheck, addr1) + assert.Equal(t, expFound, found) + return validator +} + +func checkDelegation(t *testing.T, mapp *mock.App, keeper Keeper, delegatorAddr, + validatorAddr sdk.Address, expFound bool, expShares sdk.Rat) { + + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + delegation, found := keeper.GetDelegation(ctxCheck, delegatorAddr, validatorAddr) + if expFound { + assert.True(t, found) + assert.True(sdk.RatEq(t, expShares, delegation.Shares)) + return + } + assert.False(t, found) +} + func TestStakeMsgs(t *testing.T) { mapp, keeper := getMockApp(t) @@ -82,14 +107,10 @@ func TestStakeMsgs(t *testing.T) { accs := []auth.Account{acc1, acc2} mock.SetGenesis(mapp, accs) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{genCoin}) + mock.CheckBalance(t, mapp, addr2, sdk.Coins{genCoin}) - // A checkTx context (true) - ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) - res1 := mapp.AccountMapper.GetAccount(ctxCheck, addr1) - res2 := mapp.AccountMapper.GetAccount(ctxCheck, addr2) - require.Equal(t, acc1, res1) - require.Equal(t, acc2, res2) - + //////////////////// // Create Validator description := NewDescription("foo_moniker", "", "", "") @@ -97,56 +118,40 @@ func TestStakeMsgs(t *testing.T) { addr1, priv1.PubKey(), bondCoin, description, ) mock.SignCheckDeliver(t, mapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{genCoin.Minus(bondCoin)}) + mapp.BeginBlock(abci.RequestBeginBlock{}) - ctxDeliver := mapp.BaseApp.NewContext(false, abci.Header{}) - res1 = mapp.AccountMapper.GetAccount(ctxDeliver, addr1) - require.Equal(t, sdk.Coins{genCoin.Minus(bondCoin)}, res1.GetCoins()) - validator, found := keeper.GetValidator(ctxDeliver, addr1) - require.True(t, found) + validator := checkValidator(t, mapp, keeper, addr1, true) require.Equal(t, addr1, validator.Owner) require.Equal(t, sdk.Bonded, validator.Status()) require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) // check the bond that should have been created as well - bond, found := keeper.GetDelegation(ctxDeliver, addr1, addr1) - require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) + checkDelegation(t, mapp, keeper, addr1, addr1, true, sdk.NewRat(10)) + //////////////////// // Edit Validator description = NewDescription("bar_moniker", "", "", "") - editValidatorMsg := NewMsgEditValidator( - addr1, description, - ) - mock.SignDeliver(t, mapp.BaseApp, editValidatorMsg, []int64{1}, true, priv1) - - validator, found = keeper.GetValidator(ctxDeliver, addr1) - require.True(t, found) + editValidatorMsg := NewMsgEditValidator(addr1, description) + mock.SignCheckDeliver(t, mapp.BaseApp, editValidatorMsg, []int64{1}, true, priv1) + validator = checkValidator(t, mapp, keeper, addr1, true) require.Equal(t, description, validator.Description) + //////////////////// // Delegate - delegateMsg := NewMsgDelegate( - addr2, addr1, bondCoin, - ) - mock.SignDeliver(t, mapp.BaseApp, delegateMsg, []int64{0}, true, priv2) - - res2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr2) - require.Equal(t, sdk.Coins{genCoin.Minus(bondCoin)}, res2.GetCoins()) - bond, found = keeper.GetDelegation(ctxDeliver, addr2, addr1) - require.True(t, found) - require.Equal(t, addr2, bond.DelegatorAddr) - require.Equal(t, addr1, bond.ValidatorAddr) - require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares)) + mock.CheckBalance(t, mapp, addr2, sdk.Coins{genCoin}) + delegateMsg := NewMsgDelegate(addr2, addr1, bondCoin) + mock.SignCheckDeliver(t, mapp.BaseApp, delegateMsg, []int64{0}, true, priv2) + mock.CheckBalance(t, mapp, addr2, sdk.Coins{genCoin.Minus(bondCoin)}) + checkDelegation(t, mapp, keeper, addr2, addr1, true, sdk.NewRat(10)) + //////////////////// // Unbond - unbondMsg := NewMsgUnbond( - addr2, addr1, "MAX", - ) - mock.SignDeliver(t, mapp.BaseApp, unbondMsg, []int64{1}, true, priv2) - - res2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr2) - require.Equal(t, sdk.Coins{genCoin}, res2.GetCoins()) - _, found = keeper.GetDelegation(ctxDeliver, addr2, addr1) - require.False(t, found) + unbondMsg := NewMsgUnbond(addr2, addr1, "MAX") + mock.SignCheckDeliver(t, mapp.BaseApp, unbondMsg, []int64{1}, true, priv2) + mock.CheckBalance(t, mapp, addr2, sdk.Coins{genCoin}) + checkDelegation(t, mapp, keeper, addr2, addr1, false, sdk.Rat{}) } From 6af81fc62e54246b7ad45ca30b5b6d1fdd3baa51 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Fri, 8 Jun 2018 13:13:51 -0700 Subject: [PATCH 35/89] cleanup --- baseapp/baseapp.go | 5 +---- x/auth/mock/simulate_block.go | 21 --------------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 0664f18eb..4d32b92f5 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -237,10 +237,7 @@ func (app *BaseApp) NewContext(isCheckTx bool, header abci.Header) sdk.Context { if isCheckTx { return sdk.NewContext(app.checkState.ms, header, true, nil, app.Logger) } - aa := app.deliverState - a := aa.ms - b := app.Logger - return sdk.NewContext(a, header, false, nil, b) + return sdk.NewContext(app.deliverState.ms, header, false, nil, app.Logger) } type state struct { diff --git a/x/auth/mock/simulate_block.go b/x/auth/mock/simulate_block.go index f8be0c65a..72ec8411f 100644 --- a/x/auth/mock/simulate_block.go +++ b/x/auth/mock/simulate_block.go @@ -76,26 +76,5 @@ func SignCheckDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int } app.EndBlock(abci.RequestEndBlock{}) - // XXX fix code or add explaination as to why using commit breaks a bunch of these tests app.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, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { - -//// Sign the tx -//tx := GenTx(msg, seq, priv...) - -//// Simulate a Block -//app.BeginBlock(abci.RequestBeginBlock{}) -//res := app.Deliver(tx) -//if expPass { -//require.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) -//} else { -//require.NotEqual(t, sdk.ABCICodeOK, res.Code, res.Log) -//} -//app.EndBlock(abci.RequestEndBlock{}) -//} From 5ddcf23aca71a2adb13051c900b3dd6c65559b26 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 8 Jun 2018 21:34:26 -0700 Subject: [PATCH 36/89] update godep --- Gopkg.lock | 38 +++++++++----------------------------- Gopkg.toml | 6 +----- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 0e6279300..612e8e3b3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -256,7 +256,7 @@ "leveldb/table", "leveldb/util" ] - revision = "5d6fca44a948d2be89a9702de7717f0168403d3d" + revision = "e2150783cd35f5b607daca48afd8c57ec54cc995" [[projects]] name = "github.com/tendermint/abci" @@ -267,8 +267,8 @@ "server", "types" ] - revision = "9af8b7a7c87478869f8c280ed9539470b8f470b4" - version = "v0.11.0-rc4" + revision = "ebee2fe114020aa49c70bbbae50b7079fc7e7b90" + version = "v0.11.0" [[projects]] branch = "master" @@ -347,13 +347,8 @@ "types", "version" ] -<<<<<<< HEAD - revision = "b5baab0238c9ec26e3b2d229b0243f9ff9220bdb" - version = "v0.20.0-rc3" -======= - revision = "775fef31c2b8fb7ea36f0d57bae3bfa74d353100" - version = "v0.19.9-rc0" ->>>>>>> master + revision = "27bd1deabe4ba6a2d9b463b8f3e3f1e31b993e61" + version = "v0.20.0" [[projects]] branch = "develop" @@ -368,17 +363,10 @@ "db", "flowrate", "log", -<<<<<<< HEAD "merkle", "merkle/tmhash" ] - revision = "44f1bdb0d55cc6527e38d0a7aab406e2580f56a4" -======= - "merkle" - ] - revision = "692f1d86a6e2c0efa698fd1e4541b68c74ffaf38" - version = "v0.8.4" ->>>>>>> master + revision = "640af0205d98d1f45fb2f912f9c35c8bf816adc9" [[projects]] branch = "master" @@ -394,11 +382,7 @@ "ripemd160", "salsa20/salsa" ] -<<<<<<< HEAD - revision = "5ba7f63082460102a45837dbd1827e10f9479ac0" -======= - revision = "78e79280f680f7dd6b8e48c751887111ebdbcbd8" ->>>>>>> master + revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9" [[projects]] branch = "master" @@ -418,7 +402,7 @@ branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "c11f84a56e43e20a78cee75a7c034031ecf57d1f" + revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" [[projects]] name = "golang.org/x/text" @@ -479,10 +463,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 -<<<<<<< HEAD - inputs-digest = "ccb2ab7644a38c2d0326280582f758256e37fc98c3ef0403581e3b85cff42188" -======= - inputs-digest = "71d11bd2a8f3f46ba3fd16759b501ad5b6b48037717d82020ebb25e021b67117" ->>>>>>> master + inputs-digest = "31f69b235b2d8f879a215c9e8ca0919adc62d21f6830b17931a3a0efb058721f" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 141371304..77de1b78d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -54,7 +54,7 @@ [[constraint]] name = "github.com/tendermint/abci" - version = "=0.11.0-rc4" + version = "=0.11.0" [[constraint]] name = "github.com/tendermint/go-crypto" @@ -76,10 +76,6 @@ name = "github.com/tendermint/tmlibs" branch = "develop" -[[override]] - name = "github.com/tendermint/tmlibs" - version = "~0.8.4" - # this got updated and broke, so locked to an old working commit ... [[override]] name = "google.golang.org/genproto" From a277ba91c712d5df20e1d9e91e4e5ba0e84d0f4f Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 8 Jun 2018 21:34:27 -0700 Subject: [PATCH 37/89] Merge PR #1178: Merge master (Tendermint updates) * update to tm v0.19.6 * update tm to 0.17.4 * update for tm v0.19.9 * update godep --- CHANGELOG.md | 19 +++++++++++++++++++ Gopkg.lock | 24 ++++++++++++------------ Gopkg.toml | 4 ++-- client/lcd/lcd_test.go | 2 +- server/init.go | 2 +- server/start.go | 2 +- server/tm_cmds.go | 2 +- 7 files changed, 37 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7a4ae409..7da9d60d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,25 @@ BUG FIXES +## 0.17.5 + +*June 5, 2018* + +Update to Tendermint v0.19.9 (Fix evidence reactor, mempool deadlock, WAL panic, +memory leak) + +## 0.17.4 + +*May 31, 2018* + +Update to Tendermint v0.19.7 (WAL fixes and more) + +## 0.17.3 + +*May 29, 2018* + +Update to Tendermint v0.19.6 (fix fast-sync halt) + ## 0.17.2 _May 20, 2018_ diff --git a/Gopkg.lock b/Gopkg.lock index 3e7d8c9d9..612e8e3b3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -170,8 +170,8 @@ [[projects]] name = "github.com/pelletier/go-toml" packages = ["."] - revision = "acdc4509485b587f5e675510c4f2c63e90ff68a8" - version = "v1.1.0" + revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" + version = "v1.2.0" [[projects]] name = "github.com/pkg/errors" @@ -256,7 +256,7 @@ "leveldb/table", "leveldb/util" ] - revision = "5d6fca44a948d2be89a9702de7717f0168403d3d" + revision = "e2150783cd35f5b607daca48afd8c57ec54cc995" [[projects]] name = "github.com/tendermint/abci" @@ -267,8 +267,8 @@ "server", "types" ] - revision = "9af8b7a7c87478869f8c280ed9539470b8f470b4" - version = "v0.11.0-rc4" + revision = "ebee2fe114020aa49c70bbbae50b7079fc7e7b90" + version = "v0.11.0" [[projects]] branch = "master" @@ -330,6 +330,7 @@ "p2p/conn", "p2p/pex", "p2p/upnp", + "privval", "proxy", "rpc/client", "rpc/core", @@ -344,11 +345,10 @@ "state/txindex/kv", "state/txindex/null", "types", - "types/priv_validator", "version" ] - revision = "b5baab0238c9ec26e3b2d229b0243f9ff9220bdb" - version = "v0.20.0-rc3" + revision = "27bd1deabe4ba6a2d9b463b8f3e3f1e31b993e61" + version = "v0.20.0" [[projects]] branch = "develop" @@ -366,7 +366,7 @@ "merkle", "merkle/tmhash" ] - revision = "44f1bdb0d55cc6527e38d0a7aab406e2580f56a4" + revision = "640af0205d98d1f45fb2f912f9c35c8bf816adc9" [[projects]] branch = "master" @@ -382,7 +382,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "5ba7f63082460102a45837dbd1827e10f9479ac0" + revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9" [[projects]] branch = "master" @@ -402,7 +402,7 @@ branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "c11f84a56e43e20a78cee75a7c034031ecf57d1f" + revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" [[projects]] name = "golang.org/x/text" @@ -463,6 +463,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "ccb2ab7644a38c2d0326280582f758256e37fc98c3ef0403581e3b85cff42188" + inputs-digest = "31f69b235b2d8f879a215c9e8ca0919adc62d21f6830b17931a3a0efb058721f" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 05b14be60..77de1b78d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -54,7 +54,7 @@ [[constraint]] name = "github.com/tendermint/abci" - version = "=0.11.0-rc4" + version = "=0.11.0" [[constraint]] name = "github.com/tendermint/go-crypto" @@ -70,7 +70,7 @@ [[constraint]] name = "github.com/tendermint/tendermint" - version = "=0.20.0-rc3" + version = "=0.20.0" [[override]] name = "github.com/tendermint/tmlibs" diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 47df51e7e..076b42262 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -26,7 +26,7 @@ import ( ctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmtypes "github.com/tendermint/tendermint/types" - pvm "github.com/tendermint/tendermint/types/priv_validator" + pvm "github.com/tendermint/tendermint/privval" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" diff --git a/server/init.go b/server/init.go index 68a1709bc..512751bed 100644 --- a/server/init.go +++ b/server/init.go @@ -20,7 +20,7 @@ import ( cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/p2p" tmtypes "github.com/tendermint/tendermint/types" - pvm "github.com/tendermint/tendermint/types/priv_validator" + pvm "github.com/tendermint/tendermint/privval" tmcli "github.com/tendermint/tmlibs/cli" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" diff --git a/server/start.go b/server/start.go index 23e38749b..9bf2d30cd 100644 --- a/server/start.go +++ b/server/start.go @@ -10,7 +10,7 @@ import ( 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" + pvm "github.com/tendermint/tendermint/privval" cmn "github.com/tendermint/tmlibs/common" ) diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 60eb5a2fa..7dccaf531 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -10,7 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/p2p" - pvm "github.com/tendermint/tendermint/types/priv_validator" + pvm "github.com/tendermint/tendermint/privval" ) // ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout From 9c4bbf7dfda0a80e6bced24294985e6dd0ae5717 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Fri, 8 Jun 2018 23:40:22 -0700 Subject: [PATCH 38/89] Merge PR #1195: gaiacli - Add error message for when account isn't found --- CHANGELOG.md | 1 + x/auth/client/cli/account.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da9d60d7..79432a971 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ FEATURES IMPROVEMENTS * export command now writes current validator set for Tendermint * [tests] Application module tests now use a mock application +* [gaiacli] Fix error message when account isn't found when running gaiacli account FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs diff --git a/x/auth/client/cli/account.go b/x/auth/client/cli/account.go index b5af6a686..e82b07414 100644 --- a/x/auth/client/cli/account.go +++ b/x/auth/client/cli/account.go @@ -52,6 +52,12 @@ func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecode return err } + // Check if account was found + if res == nil { + return sdk.ErrUnknownAddress("No account with address " + addr + + " was found in the state.\nAre you sure there has been a transaction involving it?") + } + // decode the value account, err := decoder(res) if err != nil { From d47b7cf5fa822daca1f0a4afcdbd372a4d8348dc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Sat, 9 Jun 2018 06:44:08 +0200 Subject: [PATCH 39/89] Add --gas flag to specify gas limit for a transaction --- CHANGELOG.md | 1 + client/context/helpers.go | 2 +- client/context/types.go | 7 +++++++ client/context/viper.go | 1 + client/flags.go | 2 ++ client/lcd/lcd_test.go | 3 ++- 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79432a971..71a8faa62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ IMPROVEMENTS FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs +* [cli] Added `--gas` flag to specify transaction gas limit ## 0.18.0 diff --git a/client/context/helpers.go b/client/context/helpers.go index f47cc7ff4..880c4adb3 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -114,7 +114,7 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w ChainID: chainID, Sequences: []int64{sequence}, Msg: msg, - Fee: auth.NewStdFee(10000, sdk.Coin{}), // TODO run simulate to estimate gas? + Fee: auth.NewStdFee(ctx.Gas, sdk.Coin{}), // TODO run simulate to estimate gas? } keybase, err := keys.GetKeyBase() diff --git a/client/context/types.go b/client/context/types.go index da15b3293..e9c97ffbc 100644 --- a/client/context/types.go +++ b/client/context/types.go @@ -10,6 +10,7 @@ import ( type CoreContext struct { ChainID string Height int64 + Gas int64 TrustNode bool NodeURI string FromAddressName string @@ -31,6 +32,12 @@ func (c CoreContext) WithHeight(height int64) CoreContext { return c } +// WithGas - return a copy of the context with an updated gas +func (c CoreContext) WithGas(gas int64) CoreContext { + c.Gas = gas + return c +} + // WithTrustNode - return a copy of the context with an updated TrustNode flag func (c CoreContext) WithTrustNode(trustNode bool) CoreContext { c.TrustNode = trustNode diff --git a/client/context/viper.go b/client/context/viper.go index 4b3007f12..081c9f5c2 100644 --- a/client/context/viper.go +++ b/client/context/viper.go @@ -30,6 +30,7 @@ func NewCoreContextFromViper() CoreContext { return CoreContext{ ChainID: chainID, Height: viper.GetInt64(client.FlagHeight), + Gas: viper.GetInt64(client.FlagGas), TrustNode: viper.GetBool(client.FlagTrustNode), FromAddressName: viper.GetString(client.FlagName), NodeURI: nodeURI, diff --git a/client/flags.go b/client/flags.go index ceaf5a3a9..aacd4ba1d 100644 --- a/client/flags.go +++ b/client/flags.go @@ -7,6 +7,7 @@ const ( FlagChainID = "chain-id" FlagNode = "node" FlagHeight = "height" + FlagGas = "gas" FlagTrustNode = "trust-node" FlagName = "name" FlagSequence = "sequence" @@ -25,6 +26,7 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command { c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") c.Flags().String(FlagNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") c.Flags().Int64(FlagHeight, 0, "block height to query, omit to get most recent provable block") + c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction") } return cmds } diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 076b42262..59f5b2464 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -22,11 +22,11 @@ import ( tmcfg "github.com/tendermint/tendermint/config" nm "github.com/tendermint/tendermint/node" p2p "github.com/tendermint/tendermint/p2p" + pvm "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/proxy" ctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmtypes "github.com/tendermint/tendermint/types" - pvm "github.com/tendermint/tendermint/privval" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -392,6 +392,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { return nil, nil, err } viper.Set(cli.HomeFlag, dir) + viper.Set(client.FlagGas, 200000) kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( if err != nil { return nil, nil, err From c08a3fec04b1b931153c4db2b3da3481ace8b4c6 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 9 Jun 2018 01:04:40 -0700 Subject: [PATCH 40/89] lawl viper --- client/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/flags.go b/client/flags.go index aacd4ba1d..2d68d3146 100644 --- a/client/flags.go +++ b/client/flags.go @@ -26,7 +26,6 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command { c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") c.Flags().String(FlagNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") c.Flags().Int64(FlagHeight, 0, "block height to query, omit to get most recent provable block") - c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction") } return cmds } @@ -39,6 +38,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command { c.Flags().String(FlagFee, "", "Fee to pay along with transaction") c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") c.Flags().String(FlagNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") + c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction") } return cmds } From aaaa0e16a294269ea4c9799443c39a0627715432 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Fri, 8 Jun 2018 23:40:22 -0700 Subject: [PATCH 41/89] Merge PR #1195: gaiacli - Add error message for when account isn't found --- CHANGELOG.md | 14 +++++++++++++- x/auth/client/cli/account.go | 6 ++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0ed96190..f8629ea1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +BREAKING CHANGES +* msg.GetSignBytes() now returns bech32-encoded addresses in all cases + +FEATURES + +IMPROVEMENTS +* export command now writes current validator set for Tendermint +* [tests] Application module tests now use a mock application + +FIXES +* [lcd] Switch to bech32 for addresses on all human readable inputs and outputs + ## 0.18.0 _2018-06-05_ @@ -65,7 +77,7 @@ BUG FIXES * query sequence via account store * fixed duplicate pub_key in stake.Validator * Auto-sequencing now works correctly - +* [gaiacli] Fix error message when account isn't found when running gaiacli account ## 0.17.5 diff --git a/x/auth/client/cli/account.go b/x/auth/client/cli/account.go index b5af6a686..e82b07414 100644 --- a/x/auth/client/cli/account.go +++ b/x/auth/client/cli/account.go @@ -52,6 +52,12 @@ func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecode return err } + // Check if account was found + if res == nil { + return sdk.ErrUnknownAddress("No account with address " + addr + + " was found in the state.\nAre you sure there has been a transaction involving it?") + } + // decode the value account, err := decoder(res) if err != nil { From d84296ed3731304e579ef339826740cc534a83f3 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 9 Jun 2018 01:04:40 -0700 Subject: [PATCH 42/89] lawl viper --- client/flags.go | 1 + 1 file changed, 1 insertion(+) diff --git a/client/flags.go b/client/flags.go index ceaf5a3a9..0b907604a 100644 --- a/client/flags.go +++ b/client/flags.go @@ -37,6 +37,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command { c.Flags().String(FlagFee, "", "Fee to pay along with transaction") c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") c.Flags().String(FlagNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") + c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction") } return cmds } From c6796b8fba067ae1b1ff4dc3f6a7c5614e2de947 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Sat, 9 Jun 2018 06:44:08 +0200 Subject: [PATCH 43/89] Add --gas flag to specify gas limit for a transaction --- CHANGELOG.md | 1 + client/context/helpers.go | 2 +- client/context/types.go | 7 +++++++ client/context/viper.go | 1 + client/flags.go | 2 ++ client/lcd/lcd_test.go | 3 ++- 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8629ea1a..5c3190842 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ IMPROVEMENTS FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs +* [cli] Added `--gas` flag to specify transaction gas limit ## 0.18.0 diff --git a/client/context/helpers.go b/client/context/helpers.go index f47cc7ff4..880c4adb3 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -114,7 +114,7 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w ChainID: chainID, Sequences: []int64{sequence}, Msg: msg, - Fee: auth.NewStdFee(10000, sdk.Coin{}), // TODO run simulate to estimate gas? + Fee: auth.NewStdFee(ctx.Gas, sdk.Coin{}), // TODO run simulate to estimate gas? } keybase, err := keys.GetKeyBase() diff --git a/client/context/types.go b/client/context/types.go index da15b3293..e9c97ffbc 100644 --- a/client/context/types.go +++ b/client/context/types.go @@ -10,6 +10,7 @@ import ( type CoreContext struct { ChainID string Height int64 + Gas int64 TrustNode bool NodeURI string FromAddressName string @@ -31,6 +32,12 @@ func (c CoreContext) WithHeight(height int64) CoreContext { return c } +// WithGas - return a copy of the context with an updated gas +func (c CoreContext) WithGas(gas int64) CoreContext { + c.Gas = gas + return c +} + // WithTrustNode - return a copy of the context with an updated TrustNode flag func (c CoreContext) WithTrustNode(trustNode bool) CoreContext { c.TrustNode = trustNode diff --git a/client/context/viper.go b/client/context/viper.go index 4b3007f12..081c9f5c2 100644 --- a/client/context/viper.go +++ b/client/context/viper.go @@ -30,6 +30,7 @@ func NewCoreContextFromViper() CoreContext { return CoreContext{ ChainID: chainID, Height: viper.GetInt64(client.FlagHeight), + Gas: viper.GetInt64(client.FlagGas), TrustNode: viper.GetBool(client.FlagTrustNode), FromAddressName: viper.GetString(client.FlagName), NodeURI: nodeURI, diff --git a/client/flags.go b/client/flags.go index 0b907604a..f4ee4279b 100644 --- a/client/flags.go +++ b/client/flags.go @@ -7,6 +7,7 @@ const ( FlagChainID = "chain-id" FlagNode = "node" FlagHeight = "height" + FlagGas = "gas" FlagTrustNode = "trust-node" FlagName = "name" FlagSequence = "sequence" @@ -25,6 +26,7 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command { c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") c.Flags().String(FlagNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") c.Flags().Int64(FlagHeight, 0, "block height to query, omit to get most recent provable block") + c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction") } return cmds } diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 19eff52c4..1b1257f34 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -22,11 +22,11 @@ import ( tmcfg "github.com/tendermint/tendermint/config" nm "github.com/tendermint/tendermint/node" p2p "github.com/tendermint/tendermint/p2p" + pvm "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/proxy" ctypes "github.com/tendermint/tendermint/rpc/core/types" tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmtypes "github.com/tendermint/tendermint/types" - pvm "github.com/tendermint/tendermint/privval" "github.com/tendermint/tmlibs/cli" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -385,6 +385,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { return nil, nil, err } viper.Set(cli.HomeFlag, dir) + viper.Set(client.FlagGas, 200000) kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( if err != nil { return nil, nil, err From cb6534a8f89ad227c9d73b5edc6ecdbb26aa8fed Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 9 Jun 2018 09:32:59 -0700 Subject: [PATCH 44/89] 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 5c3190842..e2c7a09c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ FIXES ## 0.18.0 -_2018-06-05_ +*June 9, 2018* BREAKING CHANGES diff --git a/version/version.go b/version/version.go index 116f1ff28..20074c7bc 100644 --- a/version/version.go +++ b/version/version.go @@ -9,7 +9,7 @@ const Maj = "0" const Min = "18" const Fix = "0" -const Version = "0.18.0-dev" +const Version = "0.18.0" // GitCommit set by build flags var GitCommit = "" From d309abb4b9bdb01272e54e048063502110c801fa Mon Sep 17 00:00:00 2001 From: Rigel Date: Sat, 9 Jun 2018 21:11:27 -0700 Subject: [PATCH 45/89] Merge PR #1195: PR template improvement --- .github/PULL_REQUEST_TEMPLATE.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9d234c326..caa541510 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,8 +1,12 @@ - + * [ ] Updated all relevant documentation in docs * [ ] Updated all code comments where relevant * [ ] Wrote tests * [ ] Updated CHANGELOG.md -* [ ] Updated Basecoin / other examples -* [ ] Squashed related commits and prefixed with PR number per [coding standards](https://github.com/tendermint/coding/blob/master/README.md#merging-a-pr) +* [ ] Updated Gaia/Examples +* [ ] Squashed all commits, uses message "Merge pull request #XYZ: [title]" ([coding standards](https://github.com/tendermint/coding/blob/master/README.md#merging-a-pr)) From e699e251f5ee1680a9d4246d1c57bc94b15dd75a Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 10 Jun 2018 10:41:37 -0700 Subject: [PATCH 46/89] add cmd/gaia/testnets folder to deprecate cosmos/testnets repo --- cmd/gaia/testnets/README.md | 296 +++++ cmd/gaia/testnets/STATUS.md | 38 + cmd/gaia/testnets/gaia-5001/adrian.json | 20 + cmd/gaia/testnets/gaia-5001/anton.json | 20 + cmd/gaia/testnets/gaia-5001/aurel.json | 20 + cmd/gaia/testnets/gaia-5001/bucky.json | 20 + cmd/gaia/testnets/gaia-5001/cwgoes.json | 20 + cmd/gaia/testnets/gaia-5001/iris.json | 20 + cmd/gaia/testnets/gaia-5001/lino.json | 20 + cmd/gaia/testnets/gaia-5001/pbostrom.json | 20 + cmd/gaia/testnets/gaia-5001/poldsam.json | 20 + cmd/gaia/testnets/gaia-5001/staked.json | 20 + cmd/gaia/testnets/gaia-5001/zach.json | 20 + cmd/gaia/testnets/gaia-5001/zaki.json | 20 + cmd/gaia/testnets/gaia-6000/genesis.json | 1459 +++++++++++++++++++++ cmd/gaia/testnets/gaia-6001/genesis.json | 1459 +++++++++++++++++++++ 16 files changed, 3492 insertions(+) create mode 100644 cmd/gaia/testnets/README.md create mode 100644 cmd/gaia/testnets/STATUS.md create mode 100644 cmd/gaia/testnets/gaia-5001/adrian.json create mode 100644 cmd/gaia/testnets/gaia-5001/anton.json create mode 100644 cmd/gaia/testnets/gaia-5001/aurel.json create mode 100644 cmd/gaia/testnets/gaia-5001/bucky.json create mode 100644 cmd/gaia/testnets/gaia-5001/cwgoes.json create mode 100644 cmd/gaia/testnets/gaia-5001/iris.json create mode 100644 cmd/gaia/testnets/gaia-5001/lino.json create mode 100644 cmd/gaia/testnets/gaia-5001/pbostrom.json create mode 100644 cmd/gaia/testnets/gaia-5001/poldsam.json create mode 100644 cmd/gaia/testnets/gaia-5001/staked.json create mode 100644 cmd/gaia/testnets/gaia-5001/zach.json create mode 100644 cmd/gaia/testnets/gaia-5001/zaki.json create mode 100644 cmd/gaia/testnets/gaia-6000/genesis.json create mode 100644 cmd/gaia/testnets/gaia-6001/genesis.json diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md new file mode 100644 index 000000000..e5c652279 --- /dev/null +++ b/cmd/gaia/testnets/README.md @@ -0,0 +1,296 @@ +# Connect to a Testnet + +This document explains how to connect to the Testnet of a [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk/) based blockchain. It can be used to connect to the latest Testnet for the Cosmos Hub. + +## Software Setup (Manual Installation) + +Follow these instructions to install the Cosmos-SDK and connect to the latest Testnet. This instructions work for both a local machine and a VM in a cloud server. + +If you want to run a non-validator full-node, installing the SDK on a Cloud server is a good option. However, if you are want to become a validator for the Hub's `mainnet` you should look at more complex setups, including [Sentry Node Architecture](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#how-can-validators-protect-themselves-from-denial-of-service-attacks), to protect your node from DDOS and ensure high-availability (see the [technical requirements](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#technical-requirements)). You can find more information on validators in our [website](https://cosmos.network/validators), in the [Validator FAQ](https://cosmos.network/resources/validator-faq) and in the [Validator Chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org). + +### Install [Go](https://golang.org/) + +Install `go` following the [instructions](https://golang.org/doc/install) in the official golang website. +You will require **Go 1.10+** for this tutorial. + +#### Set GOPATH + +First, you will need to set up your `GOPATH`. Make sure that the location `$HOME` is something like `/Users/`, you can corroborate it by typing `echo $HOME` in your terminal. + +Go to `$HOME` with the command `cd $HOME` and open the the hidden file `.bashrc` with a code editor and paste the following lines \(or `.bash_profile` if your're using OS X\). + +``` +export GOPATH=$HOME/go +export PATH=$PATH:$GOROOT/bin:$GOPATH/bin +``` + +Save and restart the terminal. + +_Note_: If you can't see the hidden file, use the shortcut `Command + Shift + .` in Finder. + + +### Install [GNU Wget](https://www.gnu.org/software/wget/) + +**MacOS** + +``` +brew install wget +``` + +**Linux** + +``` +sudo apt-get install wget +``` + +Note: You can check other available options for downloading `wget` [here](https://www.gnu.org/software/wget/faq.html#download). + +### Install Gaia + +Now we can fetch the correct versions of each dependency by running: + +``` +mkdir -p $GOPATH/src/github.com/cosmos/cosmos-sdk +git clone https://github.com/cosmos/cosmos-sdk.git +git checkout v0.18.0-rc0 +make get_tools // run $ make update_tools if already installed +make get_vendor_deps +make install +``` + +This will install the `gaiad` and `gaiacli` binaries. Verify that everything is OK by running: + +``` +gaiad version +``` + +You should see: + +``` +0.18.0-dev-af15f89 +``` + +And also: + +``` +gaiacli version +``` + +You should see: + +``` +0.18.0-dev-af15f89 +``` + +## Full Node Setup + +Clone the testnet repo. + +``` +git clone https://github.com/cosmos/testnets + +mkdir -p $HOME/.gaiad/config +cp -a testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json +gaiad unsafe_reset_all +``` + +Add a seed node by changing `seed = ""` in `config.toml` to `seed = "80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656"`. + +Lastly change the `moniker` string in the`config.toml`to identify your node. + +``` +# A custom human readable name for this node +moniker = "" +``` + +## Upgrading from a previous network + +These instructions are for anyone that ran a previous network and would like to upgrade to a newer version. + +Remove the ephemeral files and reset the data. +``` +rm $HOME/.gaiad/config/addrbook.json $HOME/.gaiad/config/genesis.json +gaiad unsafe_reset_all +``` + +Now your node is in a prestine state without changing your validator key. If you had any +sentry nodes or full nodes setup correctly previously they should work. + +**Make sure that every node has a unique `priv_validator.json`. Do not copy the `priv_validator.json` from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign.**\ + + +Now it is time to upgrade the software. +``` +cd $GOPATH/src/github.com/cosmos/cosmos-sdk +git fetch --all +git checkout v0.18.0-rc0 +make update_tools +make get_vendor_deps +make install +``` + +The next step is to obtain the new genesis file from `https://github.com/cosmos/testnets`. +``` +cd $HOME/testnets +git pull origin master + +cp -a gaia-6001/genesis.json $HOME/.gaiad/config +``` + +The last step is the adjust the `config.toml`. Make sure that you are connected to healthy peers or seed nodes. +These are some seeds nodes and they can be put into the config under the `seeds` key. Alternatively you can also +ask user validators directly for a persistent peer and add it under the `persisent_peers` key. +``` +80a35a46ce09cfb31ee220c8141a25e73e0b239b@cosmos.cryptium.ch:46656 +``` + +## Run a Full Node + +Start the full node: + +``` +gaiad start +``` + +Check the everything is running smoothly: + +``` +gaiacli status +``` + +## Generate keys + +You'll need a private and public key pair \(a.k.a. `sk, pk` respectively\) to be able to receive funds, send txs, bond tx, etc. + +To generate your a new key \(default _ed25519_ elliptic curve\): + +``` +gaiacli keys add +``` + +Next, you will have to enter a passphrase for your key twice. Save the _seed_ _phrase_ in a safe place in case you forget the password. + +Now if you check your private keys you will see the `` key among them: + +``` +gaiacli keys show +``` + +You can see all your other available keys by typing: + +``` +gaiacli keys list +``` + +The validator pubkey from your node should be the same as the one printed with the command: + +``` +gaiad tendermint show_validator +``` + +Finally, save your address and pubkey into a variable to use them afterwards. + +``` +MYADDR= +MYPUBKEY= +``` + +**IMPORTANT:** We strongly recommend to **NOT** use the same passphrase for your different keys. The Tendermint team and the Interchain Foundation will not be responsible for the lost of funds. + +### Get coins + +The best way to get coins at the moment is to ask in Riot chat. We plan to have a reliable faucet in future testnets. + +## Send tokens + +``` +gaiacli send --amount=1000fermion --chain-id= --sequence=0 --name= --to= +``` + +The `--amount` flag defines the corresponding amount of the coin in the format `--amount=` + +The `--sequence` flag corresponds to the sequence number to sign the tx. + +Now check the destination account and your own account to check the updated balances \(by default the latest block\): + +``` +gaiacli account +gaiacli account +``` + +You can also check your balance at a given block by using the `--block` flag: + +``` +gaiacli account --block= +``` + +## Run a Validator Node + +[Validators](https://cosmos.network/validators) are actors from the network that are responsible from committing new blocks to the blockchain by submitting their votes. In terms of security, validators' stake is slashed in all the zones they belong if they become unavailable, double sign a transaction, or don't cast their votes. We strongly recommend entities intending to run validators in the Cosmos Hub's `mainnet` to check the [technical requirements](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#technical-requirements) and take the necessary precautions to ensure high-availability, such as setting a Sentry Node architecture. If you have any question about validators, read the [Validator FAQ](https://cosmos.network/resources/validator-faq) and join the [Validator Chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org). + +This section covers the instructions necessary to stake tokens to become a testnet validator candidate. + +Your `pubkey` can be used to create a new validator candidate by staking some tokens: + +You can find your node pubkey by running +``` +gaiad tendermint show_validator +``` + +and this returns your public key for the declare-candidate command + + +``` +gaiacli stake create-validator --amount=500steak --pubkey= --address-candidate= --moniker=satoshi --chain-id= --sequence=1 --name= +``` + +You can add more information of the validator candidate such as`--website`, `--keybase-sig `or additional `--details`. If you want to edit the candidate info: + +``` +gaiacli stake edit-validator --details="To the cosmos !" --website="https://cosmos.network" +``` + +Finally, you can check all the candidate information by typing: + +``` +gaiacli stake validator --address-candidate= --chain-id= +``` + +To check that the validator is active you can find it on the validator set list: + +``` +gaiacli advanced tendermint validator-set +``` + +**Note:** Remember that to be in the validator set you need to have more total power than the Xnd validator, where X is the assigned size for the validator set \(by default _`X = 100`_\). + +## Delegate your tokens + +You can delegate \(_i.e._ bind\) **Atoms** to a validator to become a [delegator](https://cosmos.network/resources/delegators) and obtain a part of its fee revenue in **Photons**. For more information about the Cosmos Token Model, refer to our [whitepaper](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf). + +### Bond your tokens + +Bond your tokens to a validator candidate with the following command: + +``` +gaiacli stake delegate --amount=10steak --address-delegator= --address-candidate= --name= --chain-id= --sequence=2 +``` + +When tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain shares that represent their stake in this pool. + +### Unbond + +If for any reason the validator misbehaves or you just want to unbond a certain amount of the bonded tokens: + +``` +gaiacli stake unbond --address-delegator= --address-candidate= --shares=MAX --name= --chain-id= --sequence=3 +``` + +You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\). + +You should now see the unbonded tokens reflected in your balance and in your delegator bond: + +``` +gaiacli account +gaiacli stake delegation --address-delegator= --address-candidate= --chain-id= +``` diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md new file mode 100644 index 000000000..fb21ff9a4 --- /dev/null +++ b/cmd/gaia/testnets/STATUS.md @@ -0,0 +1,38 @@ +# TESTNET STATUS + +## *June 5, 2018, 21:00 EST* - New Release + +- Released gaia + [v0.17.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.17.5) + with update for Tendermint + [v0.19.9](https://github.com/tendermint/tendermint/releases/tag/v0.19.9) +- Fixes many bugs! + - evidence gossipping + - mempool deadlock + - WAL panic + - memory leak +- Please update to this to put a stop to the rampant invalid evidence gossiping + :) + +## *May 31, 2018, 14:00 EST* - New Release + +- Released gaia + [v0.17.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.17.4) with update for Tendermint v0.19.7 +- Fixes a WAL bug and some more +- Please update to this if you have trouble restarting a node + +## *May 31, 2018, 2:00 EST* - Testnet Halt + +- A validator equivocated last week and Evidence is being rampantly gossipped +- Peers that can't process the evidence (either too far behind or too far ahead) are disconnecting from the peers that + sent it, causing high peer turn-over +- The high peer turn-over may be causing a memory-leak, resulting in some nodes + crashing and the testnet halting +- We need to fix some issues in the EvidenceReactor to address this and also + investigate the possible memory-leak + +## *May 29, 2018* - New Release + +- Released v0.17.3 with update for Tendermint v0.19.6 +- Fixes fast-sync bug +- Please update to this to sync with the testnet diff --git a/cmd/gaia/testnets/gaia-5001/adrian.json b/cmd/gaia/testnets/gaia-5001/adrian.json new file mode 100644 index 000000000..7ca99cb1e --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/adrian.json @@ -0,0 +1,20 @@ +{ + "node_id": "1ebc5ca705b3ae1c06a0888ff1287ada82149dc3", + "ip": "138.68.77.24", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "power": 100, + "name": "adrian" + }, + "app_gen_tx": { + "name": "default", + "address": "D9C12CB5186FE0018179742FD3110EE534C63460", + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/anton.json b/cmd/gaia/testnets/gaia-5001/anton.json new file mode 100644 index 000000000..701e85887 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/anton.json @@ -0,0 +1,20 @@ +{ + "node_id": "c272ae3cff7558db2c6195eea38fd43fd08406dc", + "ip": "206.189.31.178", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "tJlZJWjOpYvRitYFTWNPTaUtvQVf+hoNjlfI84VPqvI=" + }, + "power": 100, + "name": "anton" + }, + "app_gen_tx": { + "name": "default", + "address": "E766088FD171906289617F60BF0014C46F0F85EC", + "pub_key": { + "type": "AC26791624DE60", + "value": "tJlZJWjOpYvRitYFTWNPTaUtvQVf+hoNjlfI84VPqvI=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/aurel.json b/cmd/gaia/testnets/gaia-5001/aurel.json new file mode 100644 index 000000000..0c2ea8166 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/aurel.json @@ -0,0 +1,20 @@ +{ + "node_id": "aef085c4bfed0c1ffc6705f2e1e3bf85e5164600", + "ip": "45.77.53.208", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "power": 100, + "name": "aurel" + }, + "app_gen_tx": { + "name": "aurel", + "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/bucky.json b/cmd/gaia/testnets/gaia-5001/bucky.json new file mode 100644 index 000000000..fc4bb51cd --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/bucky.json @@ -0,0 +1,20 @@ +{ + "node_id": "b0dd378c3fbc4c156cd6d302a799f0d2e4227201", + "ip": "159.89.121.174", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "power": 100, + "name": "bucky" + }, + "app_gen_tx": { + "name": "bucky", + "address": "935E48ED79F1006ED135553768E1D9A768747CF6", + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/cwgoes.json b/cmd/gaia/testnets/gaia-5001/cwgoes.json new file mode 100644 index 000000000..dce7e20c9 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/cwgoes.json @@ -0,0 +1,20 @@ +{ + "node_id": "e25603602d8cf8542570ad0e311d50f55f497f85", + "ip": "158.69.63.13", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "power": 100, + "name": "cwgoes" + }, + "app_gen_tx": { + "name": "cwgoes", + "address": "328FBB8EA315D070DF908982A5F91A3618001D20", + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/iris.json b/cmd/gaia/testnets/gaia-5001/iris.json new file mode 100644 index 000000000..1a1019672 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/iris.json @@ -0,0 +1,20 @@ +{ + "node_id": "aabf05a67b2f399807dc602d05bf97b0ed283ac2", + "ip": "116.62.62.39", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "power": 100, + "name": "iris" + }, + "app_gen_tx": { + "name": "=suyu", + "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + } + } +} \ No newline at end of file diff --git a/cmd/gaia/testnets/gaia-5001/lino.json b/cmd/gaia/testnets/gaia-5001/lino.json new file mode 100644 index 000000000..5bc98bb6e --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/lino.json @@ -0,0 +1,20 @@ +{ + "node_id": "79466a03e9d4b4648a7dd8cead1fa7121ce76ee3", + "ip": "34.235.130.1", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "power": 100, + "name": "lino" + }, + "app_gen_tx": { + "name": "lino", + "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/pbostrom.json b/cmd/gaia/testnets/gaia-5001/pbostrom.json new file mode 100644 index 000000000..59cd46950 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/pbostrom.json @@ -0,0 +1,20 @@ +{ + "node_id": "adb290585a2753bf1a520c76802b0dab3dffa895", + "ip": "34.201.21.179", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "power": 100, + "name": "pbostrom" + }, + "app_gen_tx": { + "name": "default", + "address": "109720515B4F8C0858DA3521E448262334534FFD", + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/poldsam.json b/cmd/gaia/testnets/gaia-5001/poldsam.json new file mode 100644 index 000000000..8149a9259 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/poldsam.json @@ -0,0 +1,20 @@ +{ + "node_id": "678503e6c8f50db7279c7da3cb9b072aac4bc0d5", + "ip": "35.193.188.125", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "power": 100, + "name": "polsdam" + }, + "app_gen_tx": { + "name": "poldsam", + "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/staked.json b/cmd/gaia/testnets/gaia-5001/staked.json new file mode 100644 index 000000000..f39cced6b --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/staked.json @@ -0,0 +1,20 @@ +{ + "node_id": "3519f05985394107e0b2e285361b7e012adb1113", + "ip": "54.209.118.64", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "vq0V0BjpmIh6WyNnFpMaO5LyUK2FamkNt65eJYa5AaQ=" + }, + "power": 100, + "name": "staked" + }, + "app_gen_tx": { + "name": "default", + "address": "935E04662697134905706A4CCDB822AC6FC11C2E", + "pub_key": { + "type": "AC26791624DE60", + "value": "vq0V0BjpmIh6WyNnFpMaO5LyUK2FamkNt65eJYa5AaQ=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/zach.json b/cmd/gaia/testnets/gaia-5001/zach.json new file mode 100644 index 000000000..76a08cc92 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/zach.json @@ -0,0 +1,20 @@ +{ + "node_id": "8a2802fb25d352f3e7e277559a4f683780c3ef22", + "ip": "167.99.191.184", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "power": 100, + "name": "" + }, + "app_gen_tx": { + "name": "zach", + "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/zaki.json b/cmd/gaia/testnets/gaia-5001/zaki.json new file mode 100644 index 000000000..956f2bf8c --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/zaki.json @@ -0,0 +1,20 @@ +{ + "node_id": "30b45459e4881680c0ef1750fde136fefa6c3b98", + "ip": "35.184.182.143", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "power": 100, + "name": "zaki" + }, + "app_gen_tx": { + "name": "zaki", + "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-6000/genesis.json b/cmd/gaia/testnets/gaia-6000/genesis.json new file mode 100644 index 000000000..aefab9286 --- /dev/null +++ b/cmd/gaia/testnets/gaia-6000/genesis.json @@ -0,0 +1,1459 @@ +{ + "genesis_time": "2018-05-15T18:29:12.38288148Z", + "chain_id": "gaia-6000", + "consensus_params": { + "block_size_params": { + "max_bytes": 22020096, + "max_txs": 100000, + "max_gas": -1 + }, + "tx_size_params": { + "max_bytes": 10240, + "max_gas": -1 + }, + "block_gossip_params": { + "block_part_size_bytes": 65536 + }, + "evidence_params": { + "max_age": 100000 + } + }, + "validators": [ + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "power": 1000, + "name": "adrian" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "power": 1000, + "name": "zaki" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "power": 100, + "name": "staked" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "power": 1000, + "name": "polsdam" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "power": 1000, + "name": "lino" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "power": 100, + "name": "" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "power": 1000, + "name": "iris" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "power": 1000, + "name": "pbostrom" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "power": 1000, + "name": "aurel" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "power": 1000, + "name": "bucky" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "power": 100, + "name": "cwgoes" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "power": 1000, + "name": "bdnet" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "power": 1000, + "name": "melea-trust" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "power": 1000, + "name": "naruemon" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "power": 1000, + "name": "idoor" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "power": 1000, + "name": "ATEAM1" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "power": 1000, + "name": "figmatt" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "power": 1000, + "name": "jla-bsd" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "power": 1000, + "name": "Gold" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "power": 1000, + "name": "nylira" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "power": 1000, + "name": "BKCM" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "power": 1000, + "name": "Dev's Validator" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "power": 1000, + "name": "Staking Facilities" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "power": 1000, + "name": "nuevax" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "power": 1000, + "name": "vultr.guest" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "power": 1000, + "name": "forebole" + } + ], + "app_hash": "", + "app_state": { + "accounts": [ + { + "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "coins": [ + { + "denom": "devToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "coins": [ + { + "denom": "adrianToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "109720515B4F8C0858DA3521E448262334534FFD", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "coins": [ + { + "denom": "aurelToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "328FBB8EA315D070DF908982A5F91A3618001D20", + "coins": [ + { + "denom": "cwgoesToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "coins": [ + { + "denom": "BKCMToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "coins": [ + { + "denom": "BDToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "coins": [ + { + "denom": "suyuToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "coins": [ + { + "denom": "linoToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "coins": [ + { + "denom": "stakingToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E04662697134905706A4CCDB822AC6FC11C2E", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E48ED79F1006ED135553768E1D9A768747CF6", + "coins": [ + { + "denom": "buckyToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", + "coins": [ + { + "denom": "kwunyeungToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zachToken", + "amount": 1000 + } + ] + }, + { + "address": "A323EC45243D600204BA3D298E3C20322D08C84C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "nuevaxToken", + "amount": 1000 + } + ] + }, + { + "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "dokiaToken", + "amount": 1000 + } + ] + }, + { + "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "forboleToken", + "amount": 1000 + } + ] + }, + { + "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "coins": [ + { + "denom": "steak", + "amount": 100 + }, + { + "denom": "pengToken", + "amount": 1000 + } + ] + }, + { + "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", + "coins": [ + { + "denom": "steak", + "amount": 900 + }, + { + "denom": "faucetToken", + "amount": 10000000 + } + ] + }, + { + "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "goldToken", + "amount": 100 + } + ] + }, + { + "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "jlaToken", + "amount": 100 + } + ] + }, + { + "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "figmattToken", + "amount": 100 + } + ] + }, + { + "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "ATEAM1Token", + "amount": 100 + } + ] + }, + { + "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "idoorToken", + "amount": 100 + } + ] + }, + { + "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "naruemonToken", + "amount": 100 + } + ] + }, + { + "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zakiToken", + "amount": 1000 + } + ] + }, + { + "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "trustToken", + "amount": 1000 + } + ] + }, + { + "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "coins": [ + { + "denom": "poldsamToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + } + ], + "stake": { + "pool": { + "loose_unbonded_tokens": 2350, + "unbonded_tokens": 0, + "unbonding_tokens": 0, + "bonded_tokens": 25200, + "unbonded_shares": "0", + "unbonding_shares": "0", + "bonded_shares": "25200", + "inflation_last_time": 0, + "inflation": "9012837/100000000", + "date_last_commission_reset": 0, + "prev_bonded_shares": "0" + }, + "params": { + "inflation_rate_change": "13/100", + "inflation_max": "1/5", + "inflation_min": "7/100", + "goal_bonded": "67/100", + "max_validators": 100, + "bond_denom": "steak" + }, + "bonds": [ + { + "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "shares": "1000", + "height": 0 + } + ], + "validators": [ + { + "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "description": { + "moniker": "Dev's Validator", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "109720515B4F8C0858DA3521E448262334534FFD", + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "description": { + "moniker": "", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "description": { + "moniker": "aurel", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "description": { + "moniker": "cwgoes", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "description": { + "moniker": "BKCM", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "description": { + "moniker": "bdnet", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "description": { + "moniker": "suyu", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "description": { + "moniker": "lino", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "description": { + "moniker": "Staking Facilities", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "description": { + "moniker": "default", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "description": { + "moniker": "bucky", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "description": { + "moniker": "zach", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "description": { + "moniker": "nuevax", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "description": { + "moniker": "vultr.guest", + "identity": "", + "website": "https://ion.dokia.capital/", + "details": "DokiaValidator" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "description": { + "moniker": "forbole", + "identity": "", + "website": "https://www.forbole.com", + "details": "Recommend. Refer. Reward" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "description": { + "moniker": "nylira", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "description": { + "moniker": "Gold", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "description": { + "moniker": "jla-bsd", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "description": { + "moniker": "figmatt", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "description": { + "moniker": "ATEAM1", + "identity": "", + "website": "", + "details": "ATEAM1" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "description": { + "moniker": "idoor", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "description": { + "moniker": "naruemon", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "description": { + "moniker": "Adrian Brink - Cryptium Labs", + "identity": "", + "website": "https://cryptium.ch", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "description": { + "moniker": "zaki", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "description": { + "moniker": "trust", + "identity": "", + "website": "http://cosmos-trust.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "description": { + "moniker": "proof-of-audit", + "identity": "", + "website": "https://proof-of-audit.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + } + ] + } + } +} diff --git a/cmd/gaia/testnets/gaia-6001/genesis.json b/cmd/gaia/testnets/gaia-6001/genesis.json new file mode 100644 index 000000000..512d761be --- /dev/null +++ b/cmd/gaia/testnets/gaia-6001/genesis.json @@ -0,0 +1,1459 @@ +{ + "genesis_time": "2018-05-15T18:29:12.38288148Z", + "chain_id": "gaia-6001", + "consensus_params": { + "block_size_params": { + "max_bytes": 22020096, + "max_txs": 100000, + "max_gas": -1 + }, + "tx_size_params": { + "max_bytes": 10240, + "max_gas": -1 + }, + "block_gossip_params": { + "block_part_size_bytes": 65536 + }, + "evidence_params": { + "max_age": 100000 + } + }, + "validators": [ + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "power": 1000, + "name": "adrian" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "power": 1000, + "name": "zaki" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "power": 100, + "name": "staked" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "power": 1000, + "name": "polsdam" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "power": 1000, + "name": "lino" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "power": 100, + "name": "" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "power": 1000, + "name": "iris" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "power": 1000, + "name": "pbostrom" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "power": 1000, + "name": "aurel" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "power": 1000, + "name": "bucky" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "power": 100, + "name": "cwgoes" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "power": 1000, + "name": "bdnet" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "power": 1000, + "name": "melea-trust" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "power": 1000, + "name": "naruemon" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "power": 1000, + "name": "idoor" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "power": 1000, + "name": "ATEAM1" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "power": 1000, + "name": "figmatt" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "power": 1000, + "name": "jla-bsd" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "power": 1000, + "name": "Gold" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "power": 1000, + "name": "nylira" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "power": 1000, + "name": "BKCM" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "power": 1000, + "name": "Dev's Validator" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "power": 1000, + "name": "Staking Facilities" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "power": 1000, + "name": "nuevax" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "power": 1000, + "name": "vultr.guest" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "power": 1000, + "name": "forebole" + } + ], + "app_hash": "", + "app_state": { + "accounts": [ + { + "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "coins": [ + { + "denom": "devToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "coins": [ + { + "denom": "adrianToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "109720515B4F8C0858DA3521E448262334534FFD", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "coins": [ + { + "denom": "aurelToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "328FBB8EA315D070DF908982A5F91A3618001D20", + "coins": [ + { + "denom": "cwgoesToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "coins": [ + { + "denom": "BKCMToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "coins": [ + { + "denom": "BDToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "coins": [ + { + "denom": "suyuToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "coins": [ + { + "denom": "linoToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "coins": [ + { + "denom": "stakingToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E04662697134905706A4CCDB822AC6FC11C2E", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E48ED79F1006ED135553768E1D9A768747CF6", + "coins": [ + { + "denom": "buckyToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", + "coins": [ + { + "denom": "kwunyeungToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zachToken", + "amount": 1000 + } + ] + }, + { + "address": "A323EC45243D600204BA3D298E3C20322D08C84C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "nuevaxToken", + "amount": 1000 + } + ] + }, + { + "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "dokiaToken", + "amount": 1000 + } + ] + }, + { + "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "forboleToken", + "amount": 1000 + } + ] + }, + { + "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "coins": [ + { + "denom": "steak", + "amount": 100 + }, + { + "denom": "pengToken", + "amount": 1000 + } + ] + }, + { + "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", + "coins": [ + { + "denom": "steak", + "amount": 900 + }, + { + "denom": "faucetToken", + "amount": 10000000 + } + ] + }, + { + "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "goldToken", + "amount": 100 + } + ] + }, + { + "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "jlaToken", + "amount": 100 + } + ] + }, + { + "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "figmattToken", + "amount": 100 + } + ] + }, + { + "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "ATEAM1Token", + "amount": 100 + } + ] + }, + { + "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "idoorToken", + "amount": 100 + } + ] + }, + { + "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "naruemonToken", + "amount": 100 + } + ] + }, + { + "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zakiToken", + "amount": 1000 + } + ] + }, + { + "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "trustToken", + "amount": 1000 + } + ] + }, + { + "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "coins": [ + { + "denom": "poldsamToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + } + ], + "stake": { + "pool": { + "loose_unbonded_tokens": 2300, + "unbonded_tokens": 0, + "unbonding_tokens": 0, + "bonded_tokens": 23300, + "unbonded_shares": "0", + "unbonding_shares": "0", + "bonded_shares": "23300", + "inflation_last_time": 0, + "inflation": "9012837/100000000", + "date_last_commission_reset": 0, + "prev_bonded_shares": "0" + }, + "params": { + "inflation_rate_change": "13/100", + "inflation_max": "1/5", + "inflation_min": "7/100", + "goal_bonded": "67/100", + "max_validators": 100, + "bond_denom": "steak" + }, + "bonds": [ + { + "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "shares": "1000", + "height": 0 + } + ], + "validators": [ + { + "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "description": { + "moniker": "Dev's Validator", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "109720515B4F8C0858DA3521E448262334534FFD", + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "description": { + "moniker": "", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "description": { + "moniker": "aurel", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "description": { + "moniker": "cwgoes", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "description": { + "moniker": "BKCM", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "description": { + "moniker": "bdnet", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "description": { + "moniker": "suyu", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "description": { + "moniker": "lino", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "description": { + "moniker": "Staking Facilities", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "description": { + "moniker": "default", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "description": { + "moniker": "bucky", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "description": { + "moniker": "zach", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "description": { + "moniker": "nuevax", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "description": { + "moniker": "vultr.guest", + "identity": "", + "website": "https://ion.dokia.capital/", + "details": "DokiaValidator" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "description": { + "moniker": "forbole", + "identity": "", + "website": "https://www.forbole.com", + "details": "Recommend. Refer. Reward" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "description": { + "moniker": "nylira", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "description": { + "moniker": "Gold", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "description": { + "moniker": "jla-bsd", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "description": { + "moniker": "figmatt", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "description": { + "moniker": "ATEAM1", + "identity": "", + "website": "", + "details": "ATEAM1" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "description": { + "moniker": "idoor", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "description": { + "moniker": "naruemon", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "description": { + "moniker": "Adrian Brink - Cryptium Labs", + "identity": "", + "website": "https://cryptium.ch", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "description": { + "moniker": "zaki", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "description": { + "moniker": "trust", + "identity": "", + "website": "http://cosmos-trust.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "description": { + "moniker": "proof-of-audit", + "identity": "", + "website": "https://proof-of-audit.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + } + ] + } + } +} From eceb56b709e6d2fb1ec9a401af4d2c0e82a33a18 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 10 Jun 2018 10:51:18 -0700 Subject: [PATCH 47/89] cmd/gaia/testnets: update status.md with recent history --- cmd/gaia/testnets/STATUS.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md index fb21ff9a4..d53c49e09 100644 --- a/cmd/gaia/testnets/STATUS.md +++ b/cmd/gaia/testnets/STATUS.md @@ -1,5 +1,41 @@ # TESTNET STATUS +## *June 10, 2018, 8:30 EST* - Gaia-6001 consensus failure + +- Validator unbonding and revocation activity caused a consensus failure +- There is a bug in the staking module that must be fixed +- The team is taking its time to look into this and release a fix following a + proper protocol for hotfix upgrades to the testnet +- Please stay tuned! + +## *June 9, 2018, 14:00 EST* - New Release + +- Released gaia + [v0.18.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.18.0) with + update for Tendermint + [v0.20.0](https://github.com/tendermint/tendermint/releases/tag/v0.20.0) +- Includes bug fix for declaring candidacy from the command line + +## *June 8, 2018, 23:30 EST* - Gaia-6001 is making blocks + +- +2/3 of the voting power is finally online for Gaia-6001 and it is making + blocks! +- This is a momentous achievement - a successful asynchronous decentralized + testnet launch +- Congrats everyone! + +## *June 8, 2018, 12:00 EST* - New Testnet Gaia-6001 + +- After some confusion around testnet deployment and a contention testnet + hardfork, a new genesis file and network was released for `gaia-6001` + +## *June 7, 2018, 9:00 EST* - New Testnet Gaia-6000 + +- Released a new `genesis.json` file for `gaia-6000` +- Initial validators include those that were most active in + the gaia-5001 testnet +- Join the network via gaia `v0.18.0-rc0` + ## *June 5, 2018, 21:00 EST* - New Release - Released gaia From 9430ba1baa3001c2686be2b2ff2991d18a0ca4bf Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 10 Jun 2018 11:02:19 -0700 Subject: [PATCH 48/89] cmd/gaia/testnets: update versions, use a working seed --- cmd/gaia/testnets/README.md | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md index e5c652279..a6f6bbb5e 100644 --- a/cmd/gaia/testnets/README.md +++ b/cmd/gaia/testnets/README.md @@ -2,6 +2,12 @@ This document explains how to connect to the Testnet of a [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk/) based blockchain. It can be used to connect to the latest Testnet for the Cosmos Hub. +NOTE: We are aware this documentation is sub-par and are actively working to +improve both the tooling and the documentation to make this as painless as +possible. In the meantime, join the +[chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org) for technical support. Thanks very +much for your patience :) + ## Software Setup (Manual Installation) Follow these instructions to install the Cosmos-SDK and connect to the latest Testnet. This instructions work for both a local machine and a VM in a cloud server. @@ -52,7 +58,7 @@ Now we can fetch the correct versions of each dependency by running: ``` mkdir -p $GOPATH/src/github.com/cosmos/cosmos-sdk git clone https://github.com/cosmos/cosmos-sdk.git -git checkout v0.18.0-rc0 +git checkout v0.18.0 make get_tools // run $ make update_tools if already installed make get_vendor_deps make install @@ -67,7 +73,7 @@ gaiad version You should see: ``` -0.18.0-dev-af15f89 +0.18.0-eceb56b7 ``` And also: @@ -79,22 +85,20 @@ gaiacli version You should see: ``` -0.18.0-dev-af15f89 +0.18.0-eceb56b7 ``` ## Full Node Setup -Clone the testnet repo. +Copy the testnet initialization files to a new data directory: ``` -git clone https://github.com/cosmos/testnets - mkdir -p $HOME/.gaiad/config -cp -a testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json +cp -a cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json gaiad unsafe_reset_all ``` -Add a seed node by changing `seed = ""` in `config.toml` to `seed = "80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656"`. +Add a seed node by changing `seed = ""` in `config.toml` to `seed = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656" Lastly change the `moniker` string in the`config.toml`to identify your node. @@ -123,25 +127,24 @@ Now it is time to upgrade the software. ``` cd $GOPATH/src/github.com/cosmos/cosmos-sdk git fetch --all -git checkout v0.18.0-rc0 +git checkout v0.18.0 make update_tools make get_vendor_deps make install ``` -The next step is to obtain the new genesis file from `https://github.com/cosmos/testnets`. -``` -cd $HOME/testnets -git pull origin master +The next step is to copy the new genesis file: -cp -a gaia-6001/genesis.json $HOME/.gaiad/config +``` +cp -a cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json ``` The last step is the adjust the `config.toml`. Make sure that you are connected to healthy peers or seed nodes. These are some seeds nodes and they can be put into the config under the `seeds` key. Alternatively you can also ask user validators directly for a persistent peer and add it under the `persisent_peers` key. + ``` -80a35a46ce09cfb31ee220c8141a25e73e0b239b@cosmos.cryptium.ch:46656 +38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656" ``` ## Run a Full Node From 3bea85abb367e1c7bd3d17ef7bda70aebcf37f25 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 11 Jun 2018 02:55:54 +0200 Subject: [PATCH 49/89] Register slashing keeper, set startHeight, testcases --- cmd/gaia/app/app.go | 3 +- x/slashing/app_test.go | 124 ++++++++++++++++++++++++++++++++++++++ x/slashing/keeper.go | 6 +- x/slashing/keeper_test.go | 30 +++++++++ 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 x/slashing/app_test.go diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index f06ed2be3..717d64c39 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -82,7 +82,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { app.Router(). AddRoute("bank", bank.NewHandler(app.coinKeeper)). AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). - AddRoute("stake", stake.NewHandler(app.stakeKeeper)) + AddRoute("stake", stake.NewHandler(app.stakeKeeper)). + AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)) // initialize BaseApp app.SetInitChainer(app.initChainer) diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go new file mode 100644 index 000000000..f0f1f7247 --- /dev/null +++ b/x/slashing/app_test.go @@ -0,0 +1,124 @@ +package slashing + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/x/stake" + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" +) + +var ( + 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}} + fee = auth.StdFee{ + sdk.Coins{{"foocoin", 0}}, + 100000, + } +) + +// initialize the mock application for this module +func getMockApp(t *testing.T) (*mock.App, stake.Keeper, Keeper) { + mapp := mock.NewApp() + + RegisterWire(mapp.Cdc) + keyStake := sdk.NewKVStoreKey("stake") + keySlashing := sdk.NewKVStoreKey("slashing") + coinKeeper := bank.NewKeeper(mapp.AccountMapper) + stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, coinKeeper, mapp.RegisterCodespace(DefaultCodespace)) + keeper := NewKeeper(mapp.Cdc, keySlashing, stakeKeeper, mapp.RegisterCodespace(DefaultCodespace)) + mapp.Router().AddRoute("stake", stake.NewHandler(stakeKeeper)) + mapp.Router().AddRoute("slashing", NewHandler(keeper)) + + mapp.SetEndBlocker(getEndBlocker(stakeKeeper)) + mapp.SetInitChainer(getInitChainer(mapp, stakeKeeper)) + mapp.CompleteSetup(t, []*sdk.KVStoreKey{keyStake, keySlashing}) + + return mapp, stakeKeeper, keeper +} + +// stake endblocker +func getEndBlocker(keeper stake.Keeper) sdk.EndBlocker { + return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + validatorUpdates := stake.EndBlocker(ctx, keeper) + return abci.ResponseEndBlock{ + ValidatorUpdates: validatorUpdates, + } + } +} + +// overwrite the mock init chainer +func getInitChainer(mapp *mock.App, keeper stake.Keeper) sdk.InitChainer { + return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + mapp.InitChainer(ctx, req) + stake.InitGenesis(ctx, keeper, stake.DefaultGenesisState()) + return abci.ResponseInitChain{} + } +} + +func checkValidator(t *testing.T, mapp *mock.App, keeper stake.Keeper, + addr sdk.Address, expFound bool) stake.Validator { + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + validator, found := keeper.GetValidator(ctxCheck, addr1) + assert.Equal(t, expFound, found) + return validator +} + +func checkValidatorSigningInfo(t *testing.T, mapp *mock.App, keeper Keeper, + addr sdk.Address, expFound bool) ValidatorSigningInfo { + ctxCheck := mapp.BaseApp.NewContext(true, abci.Header{}) + signingInfo, found := keeper.getValidatorSigningInfo(ctxCheck, addr) + assert.Equal(t, expFound, found) + return signingInfo +} + +func TestSlashingMsgs(t *testing.T) { + mapp, stakeKeeper, keeper := getMockApp(t) + + genCoin := sdk.Coin{"steak", 42} + bondCoin := sdk.Coin{"steak", 10} + + acc1 := &auth.BaseAccount{ + Address: addr1, + Coins: sdk.Coins{genCoin}, + } + acc2 := &auth.BaseAccount{ + Address: addr2, + Coins: sdk.Coins{genCoin}, + } + accs := []auth.Account{acc1, acc2} + + mock.SetGenesis(mapp, accs) + description := stake.NewDescription("foo_moniker", "", "", "") + createValidatorMsg := stake.NewMsgCreateValidator( + addr1, priv1.PubKey(), bondCoin, description, + ) + mock.SignCheckDeliver(t, mapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) + mock.CheckBalance(t, mapp, addr1, sdk.Coins{genCoin.Minus(bondCoin)}) + mapp.BeginBlock(abci.RequestBeginBlock{}) + + validator := checkValidator(t, mapp, stakeKeeper, addr1, true) + require.Equal(t, addr1, validator.Owner) + require.Equal(t, sdk.Bonded, validator.Status()) + require.True(sdk.RatEq(t, sdk.NewRat(10), validator.PoolShares.Bonded())) + unrevokeMsg := MsgUnrevoke{ValidatorAddr: validator.PubKey.Address()} + + // no signing info yet + checkValidatorSigningInfo(t, mapp, keeper, addr1, false) + + // unrevoke should fail + mock.SignCheckDeliver(t, mapp.BaseApp, unrevokeMsg, []int64{1}, false, priv1) +} diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index d558cc04b..89faf64ed 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -56,7 +56,11 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey, // Local index, so counts blocks validator *should* have signed // Will use the 0-value default signing info if not present - signInfo, _ := k.getValidatorSigningInfo(ctx, address) + signInfo, found := k.getValidatorSigningInfo(ctx, address) + if !found { + // If this validator has never been seen before, set the start height + signInfo.StartHeight = height + } index := signInfo.IndexOffset % SignedBlocksWindow signInfo.IndexOffset++ diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 25ae1686d..3d49b65c4 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -129,3 +129,33 @@ func TestHandleAbsentValidator(t *testing.T) { validator, _ = sk.GetValidatorByPubKey(ctx, val) require.Equal(t, sdk.Unbonded, validator.GetStatus()) } + +func TestHandleNewValidator(t *testing.T) { + // initial setup + ctx, ck, sk, keeper := createTestInput(t) + addr, val, amt := addrs[0], pks[0], int64(100) + sh := stake.NewHandler(sk) + got := sh(ctx, newTestMsgCreateValidator(addr, val, amt)) + require.True(t, got.IsOK()) + stake.EndBlocker(ctx, sk) + require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins - amt}}) + require.Equal(t, sdk.NewRat(amt), sk.Validator(ctx, addr).GetPower()) + + // 1000 first blocks not a validator + ctx = ctx.WithBlockHeight(1001) + + // Now a validator + keeper.handleValidatorSignature(ctx, val, true) + info, found := keeper.getValidatorSigningInfo(ctx, val.Address()) + require.True(t, found) + require.Equal(t, int64(1001), info.StartHeight) + require.Equal(t, int64(1), info.IndexOffset) + require.Equal(t, int64(1), info.SignedBlocksCounter) + require.Equal(t, int64(0), info.JailedUntil) + + // validator should be bonded still, should not have been revoked or slashed + validator, _ := sk.GetValidatorByPubKey(ctx, val) + require.Equal(t, sdk.Bonded, validator.GetStatus()) + pool := sk.GetPool(ctx) + require.Equal(t, int64(100), pool.BondedTokens) +} From 2d2b57261c004aa1555b9f54470687e3e3420135 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 11 Jun 2018 02:59:36 +0200 Subject: [PATCH 50/89] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71a8faa62..f6768cff9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ IMPROVEMENTS FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs * [cli] Added `--gas` flag to specify transaction gas limit +* [gaia] Registered slashing message handler +* [x/slashing] Set signInfo.StartHeight correctly for newly bonded validators ## 0.18.0 From f6a30afbf4f1501ec9edb1801adab3bc94b90413 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 11 Jun 2018 03:03:52 +0200 Subject: [PATCH 51/89] Improve testcase, add comment --- x/slashing/keeper.go | 2 +- x/slashing/keeper_test.go | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 89faf64ed..c7cf06369 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -55,7 +55,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey, address := pubkey.Address() // Local index, so counts blocks validator *should* have signed - // Will use the 0-value default signing info if not present + // Will use the 0-value default signing info if not present, except for start height signInfo, found := k.getValidatorSigningInfo(ctx, address) if !found { // If this validator has never been seen before, set the start height diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 3d49b65c4..3e78d939d 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -144,12 +144,15 @@ func TestHandleNewValidator(t *testing.T) { // 1000 first blocks not a validator ctx = ctx.WithBlockHeight(1001) - // Now a validator + // Now a validator, for two blocks keeper.handleValidatorSignature(ctx, val, true) + ctx = ctx.WithBlockHeight(1002) + keeper.handleValidatorSignature(ctx, val, false) + info, found := keeper.getValidatorSigningInfo(ctx, val.Address()) require.True(t, found) require.Equal(t, int64(1001), info.StartHeight) - require.Equal(t, int64(1), info.IndexOffset) + require.Equal(t, int64(2), info.IndexOffset) require.Equal(t, int64(1), info.SignedBlocksCounter) require.Equal(t, int64(0), info.JailedUntil) From a4865ef6aa8b1fd4db193171ec7bc6f40561fcf3 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 11 Jun 2018 03:14:20 +0200 Subject: [PATCH 52/89] Add mock.SignCheck, update testcase to assert error code --- x/auth/mock/simulate_block.go | 6 ++++++ x/slashing/app_test.go | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/x/auth/mock/simulate_block.go b/x/auth/mock/simulate_block.go index 72ec8411f..4db7bf630 100644 --- a/x/auth/mock/simulate_block.go +++ b/x/auth/mock/simulate_block.go @@ -52,6 +52,12 @@ func GenTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { return auth.NewStdTx(msg, fee, sigs) } +func SignCheck(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.Result { + tx := GenTx(msg, seq, priv...) + res := app.Check(tx) + return res +} + // simulate a block func SignCheckDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index f0f1f7247..9253765d5 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -38,7 +38,7 @@ func getMockApp(t *testing.T) (*mock.App, stake.Keeper, Keeper) { keyStake := sdk.NewKVStoreKey("stake") keySlashing := sdk.NewKVStoreKey("slashing") coinKeeper := bank.NewKeeper(mapp.AccountMapper) - stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, coinKeeper, mapp.RegisterCodespace(DefaultCodespace)) + stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, coinKeeper, mapp.RegisterCodespace(stake.DefaultCodespace)) keeper := NewKeeper(mapp.Cdc, keySlashing, stakeKeeper, mapp.RegisterCodespace(DefaultCodespace)) mapp.Router().AddRoute("stake", stake.NewHandler(stakeKeeper)) mapp.Router().AddRoute("slashing", NewHandler(keeper)) @@ -119,6 +119,7 @@ func TestSlashingMsgs(t *testing.T) { // no signing info yet checkValidatorSigningInfo(t, mapp, keeper, addr1, false) - // unrevoke should fail - mock.SignCheckDeliver(t, mapp.BaseApp, unrevokeMsg, []int64{1}, false, priv1) + // unrevoke should fail with unknown validator + res := mock.SignCheck(t, mapp.BaseApp, unrevokeMsg, []int64{1}, priv1) + require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeInvalidValidator), res.Code) } From c9a977beae4b1262e5087e49bfb9520e37334870 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 11 Jun 2018 03:15:48 +0200 Subject: [PATCH 53/89] Cleanup testcase --- x/slashing/app_test.go | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index 9253765d5..3d33f53e7 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -18,16 +18,7 @@ import ( var ( 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}} - fee = auth.StdFee{ - sdk.Coins{{"foocoin", 0}}, - 100000, - } ) // initialize the mock application for this module @@ -95,12 +86,7 @@ func TestSlashingMsgs(t *testing.T) { Address: addr1, Coins: sdk.Coins{genCoin}, } - acc2 := &auth.BaseAccount{ - Address: addr2, - Coins: sdk.Coins{genCoin}, - } - accs := []auth.Account{acc1, acc2} - + accs := []auth.Account{acc1} mock.SetGenesis(mapp, accs) description := stake.NewDescription("foo_moniker", "", "", "") createValidatorMsg := stake.NewMsgCreateValidator( From b9c1bcbd74ffbaaa0e9294ea76ed0337b1888a33 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 11 Jun 2018 03:22:38 +0200 Subject: [PATCH 54/89] Tiny linter fix --- x/auth/mock/simulate_block.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/auth/mock/simulate_block.go b/x/auth/mock/simulate_block.go index 4db7bf630..16b250f4c 100644 --- a/x/auth/mock/simulate_block.go +++ b/x/auth/mock/simulate_block.go @@ -52,6 +52,7 @@ func GenTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { return auth.NewStdTx(msg, fee, sigs) } +// check a transaction result func SignCheck(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.Result { tx := GenTx(msg, seq, priv...) res := app.Check(tx) From 74f5b26666b893bb22a679a732c3c0563afeff47 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 11 Jun 2018 11:35:12 -0700 Subject: [PATCH 55/89] readme points to testnet folder --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 3faf2c8af..7713633d0 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,14 @@ master | [![CircleCI](https://circleci.com/gh/cosmos/cosmos-sdk/tree/master.s **Note**: Requires [Go 1.10+](https://golang.org/dl/) +## Testnet + +For more information on connecting to the testnet, see +[cmd/gaia/testnets](/cmd/gaia/testnets) + +For the latest status of the testnet, see the [status +file](/cmd/gaia/testnets/status.md). + ## Overview From 5e975fc675cf780de5019427f1e9d9c5cea09d59 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 11 Jun 2018 11:35:18 -0700 Subject: [PATCH 56/89] add fixes from billy --- cmd/gaia/testnets/README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md index a6f6bbb5e..891cffdfd 100644 --- a/cmd/gaia/testnets/README.md +++ b/cmd/gaia/testnets/README.md @@ -98,9 +98,13 @@ cp -a cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json gaiad unsafe_reset_all ``` -Add a seed node by changing `seed = ""` in `config.toml` to `seed = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656" +Add a seed node by changing `seed = ""` in `$HOME/.gaiad/config/config.toml` to -Lastly change the `moniker` string in the`config.toml`to identify your node. +``` +seed = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" +``` + +Lastly change the `moniker` string in the `$HOME/.gaiad/config/config.toml`to identify your node. ``` # A custom human readable name for this node @@ -139,12 +143,12 @@ The next step is to copy the new genesis file: cp -a cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json ``` -The last step is the adjust the `config.toml`. Make sure that you are connected to healthy peers or seed nodes. +The last step is the adjust the `$HOME/.gaiad/config/config.toml`. Make sure that you are connected to healthy peers or seed nodes. These are some seeds nodes and they can be put into the config under the `seeds` key. Alternatively you can also ask user validators directly for a persistent peer and add it under the `persisent_peers` key. ``` -38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656" +38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656 ``` ## Run a Full Node From f07573708316b429e8e070ae7f03a418861e57a7 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 11 Jun 2018 11:37:05 -0700 Subject: [PATCH 57/89] fix status.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7713633d0..3af98fb4f 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ For more information on connecting to the testnet, see [cmd/gaia/testnets](/cmd/gaia/testnets) For the latest status of the testnet, see the [status -file](/cmd/gaia/testnets/status.md). +file](/cmd/gaia/testnets/STATUS.md). ## Overview From 4dcf41df4b4f64c243a45c389abe0ba897d9c5fb Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 11 Jun 2018 11:40:38 -0700 Subject: [PATCH 58/89] seed->seeds --- cmd/gaia/testnets/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md index 891cffdfd..42484c599 100644 --- a/cmd/gaia/testnets/README.md +++ b/cmd/gaia/testnets/README.md @@ -98,10 +98,10 @@ cp -a cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json gaiad unsafe_reset_all ``` -Add a seed node by changing `seed = ""` in `$HOME/.gaiad/config/config.toml` to +Add a seed node by changing `seeds = ""` in `$HOME/.gaiad/config/config.toml` to ``` -seed = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" +seeds = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" ``` Lastly change the `moniker` string in the `$HOME/.gaiad/config/config.toml`to identify your node. From ee17b7c9cc7e5167bf4d2eea95c8ef3b25f0ba6a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 11 Jun 2018 21:47:35 +0200 Subject: [PATCH 59/89] Address PR comments: test descriptions & NewValidatorSigningInfo --- x/slashing/keeper.go | 4 ++-- x/slashing/keeper_test.go | 7 +++++++ x/slashing/signing_info.go | 10 ++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index c7cf06369..d5ae09ef2 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -58,8 +58,8 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey, // Will use the 0-value default signing info if not present, except for start height signInfo, found := k.getValidatorSigningInfo(ctx, address) if !found { - // If this validator has never been seen before, set the start height - signInfo.StartHeight = height + // If this validator has never been seen before, construct a new SigningInfo with the correct start height + signInfo = NewValidatorSigningInfo(height, 0, 0, 0) } index := signInfo.IndexOffset % SignedBlocksWindow signInfo.IndexOffset++ diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 3e78d939d..1f8f9db07 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -11,6 +11,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" ) +// Test that a validator is slashed correctly +// when we discover evidence of equivocation func TestHandleDoubleSign(t *testing.T) { // initial setup @@ -32,6 +34,8 @@ func TestHandleDoubleSign(t *testing.T) { require.Equal(t, sdk.NewRat(amt).Mul(sdk.NewRat(19).Quo(sdk.NewRat(20))), sk.Validator(ctx, addr).GetPower()) } +// Test a validator through uptime, downtime, revocation, +// unrevocation, starting height reset, and revocation again func TestHandleAbsentValidator(t *testing.T) { // initial setup @@ -130,6 +134,9 @@ func TestHandleAbsentValidator(t *testing.T) { require.Equal(t, sdk.Unbonded, validator.GetStatus()) } +// Test a new validator entering the validator set +// Ensure that SigningInfo.StartHeight is set correctly +// and that they are not immediately revoked func TestHandleNewValidator(t *testing.T) { // initial setup ctx, ck, sk, keeper := createTestInput(t) diff --git a/x/slashing/signing_info.go b/x/slashing/signing_info.go index a2df0505a..acbe1738b 100644 --- a/x/slashing/signing_info.go +++ b/x/slashing/signing_info.go @@ -47,6 +47,16 @@ func (k Keeper) setValidatorSigningBitArray(ctx sdk.Context, address sdk.Address store.Set(GetValidatorSigningBitArrayKey(address, index), bz) } +// Construct a new `ValidatorSigningInfo` struct +func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil int64, signedBlocksCounter int64) ValidatorSigningInfo { + return ValidatorSigningInfo{ + StartHeight: startHeight, + IndexOffset: indexOffset, + JailedUntil: jailedUntil, + SignedBlocksCounter: signedBlocksCounter, + } +} + // Signing info for a validator type ValidatorSigningInfo struct { StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unrevoked From 8ece8073019f92d0de1d1a4fa67de248ed36dbbd Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 11 Jun 2018 13:09:29 -0700 Subject: [PATCH 60/89] Merge PR #1085: Re-enable tx history in LCD * reenable tx search * removed not needed argument * register types for decoding * trying to fix indexing tests * added tx hash query test * Fix x/bank tagging * remove dead code * remove print * extended tests for tx querying * changelog * added txs address querying * linted * rename * use prefix for bech32 addresses in tags * changed error message * Fix tiny linter issue --- CHANGELOG.md | 1 + client/lcd/helpers.go | 1 - client/lcd/lcd_test.go | 61 +++++++++++++++++++++++++++--------------- client/tx/root.go | 2 +- client/tx/search.go | 49 +++++++++++++++++++++++++-------- types/account.go | 11 ++++---- types/wire.go | 1 + x/auth/wire.go | 1 + x/bank/keeper.go | 4 +-- 9 files changed, 90 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71a8faa62..16346def3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ IMPROVEMENTS FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs +* fixed tx indexing/querying * [cli] Added `--gas` flag to specify transaction gas limit ## 0.18.0 diff --git a/client/lcd/helpers.go b/client/lcd/helpers.go index 367e1a53d..14cd5c16c 100644 --- a/client/lcd/helpers.go +++ b/client/lcd/helpers.go @@ -48,7 +48,6 @@ func GetConfig() *cfg.Config { tm, rpc, _ := makeAddrs() globalConfig.P2P.ListenAddress = tm globalConfig.RPC.ListenAddress = rpc - globalConfig.TxIndex.IndexTags = "app.creator" // see kvstore application } return globalConfig } diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 59f5b2464..3565d99c3 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -243,7 +243,7 @@ func TestCoinSend(t *testing.T) { initialBalance := acc.GetCoins() // create TX - receiveAddr, resultTx := doSend(t, port, seed) + receiveAddr, resultTx := doSend(t, port) tests.WaitForHeight(resultTx.Height+1, port) // check if tx was commited @@ -290,39 +290,57 @@ func TestIBCTransfer(t *testing.T) { } func TestTxs(t *testing.T) { - - // TODO: re-enable once we can get txs by tag - // query wrong - // res, body := request(t, port, "GET", "/txs", nil) - // require.Equal(t, http.StatusBadRequest, res.StatusCode, body) + res, body := request(t, port, "GET", "/txs", nil) + require.Equal(t, http.StatusBadRequest, res.StatusCode, body) // query empty - // res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=coin.sender='%s'", "8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6"), nil) - // require.Equal(t, http.StatusOK, res.StatusCode, body) - - // assert.Equal(t, "[]", body) + res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", "cosmosaccaddr1jawd35d9aq4u76sr3fjalmcqc8hqygs9gtnmv3"), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + assert.Equal(t, "[]", body) // create TX - _, resultTx := doSend(t, port, seed) + receiveAddr, resultTx := doSend(t, port) tests.WaitForHeight(resultTx.Height+1, port) // check if tx is findable - res, body := request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil) + res, body = request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - // // query sender - // res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=coin.sender='%s'", addr), nil) - // require.Equal(t, http.StatusOK, res.StatusCode, body) + type txInfo struct { + Height int64 `json:"height"` + Tx sdk.Tx `json:"tx"` + Result abci.ResponseDeliverTx `json:"result"` + } + var indexedTxs []txInfo - // assert.NotEqual(t, "[]", body) + // check if tx is queryable + res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=tx.hash='%s'", resultTx.Hash), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + assert.NotEqual(t, "[]", body) - // // query receiver - // res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=coin.receiver='%s'", receiveAddr), nil) - // require.Equal(t, http.StatusOK, res.StatusCode, body) + err := cdc.UnmarshalJSON([]byte(body), &indexedTxs) + require.NoError(t, err) + assert.Equal(t, len(indexedTxs), 1) - // assert.NotEqual(t, "[]", body) + // query sender + res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", sendAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + err = cdc.UnmarshalJSON([]byte(body), &indexedTxs) + require.NoError(t, err) + assert.Equal(t, 2, len(indexedTxs)) // there are 2 txs created with doSend + assert.Equal(t, resultTx.Height, indexedTxs[1].Height) + + // query recipient + res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=recipient_bech32='%s'", receiveAddr), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + err = cdc.UnmarshalJSON([]byte(body), &indexedTxs) + require.NoError(t, err) + assert.Equal(t, 1, len(indexedTxs)) + assert.Equal(t, resultTx.Height, indexedTxs[0].Height) } func TestValidatorsQuery(t *testing.T) { @@ -401,6 +419,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) { config := GetConfig() config.Consensus.TimeoutCommit = 1000 config.Consensus.SkipTimeoutCommit = false + config.TxIndex.IndexAllTags = true logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) logger = log.NewFilter(logger, log.AllowError()) @@ -553,7 +572,7 @@ func getAccount(t *testing.T, sendAddr string) auth.Account { return acc } -func doSend(t *testing.T, port, seed string) (receiveAddr string, resultTx ctypes.ResultBroadcastTxCommit) { +func doSend(t *testing.T, port string) (receiveAddr string, resultTx ctypes.ResultBroadcastTxCommit) { // create receive address kb := client.MockKeyBase() diff --git a/client/tx/root.go b/client/tx/root.go index e8abf3318..5def5a544 100644 --- a/client/tx/root.go +++ b/client/tx/root.go @@ -19,7 +19,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}", QueryTxRequestHandlerFn(cdc, ctx)).Methods("GET") - // r.HandleFunc("/txs", SearchTxRequestHandler(cdc)).Methods("GET") + r.HandleFunc("/txs", SearchTxRequestHandlerFn(ctx, 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 527661626..3ab3a3df1 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -13,6 +13,7 @@ import ( "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" ) @@ -29,7 +30,11 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { tags := viper.GetStringSlice(flagTags) - output, err := searchTx(context.NewCoreContextFromViper(), cdc, tags) + txs, err := searchTxs(context.NewCoreContextFromViper(), cdc, tags) + if err != nil { + return err + } + output, err := cdc.MarshalJSON(txs) if err != nil { return err } @@ -47,13 +52,12 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command { return cmd } -func searchTx(ctx context.CoreContext, cdc *wire.Codec, tags []string) ([]byte, error) { +func searchTxs(ctx context.CoreContext, cdc *wire.Codec, tags []string) ([]txInfo, error) { if len(tags) == 0 { return nil, errors.New("Must declare at least one tag to search") } // XXX: implement ANY query := strings.Join(tags, " AND ") - // get the node node, err := ctx.GetNode() if err != nil { @@ -74,11 +78,7 @@ func searchTx(ctx context.CoreContext, cdc *wire.Codec, tags []string) ([]byte, return nil, err } - output, err := cdc.MarshalJSON(info) - if err != nil { - return nil, err - } - return output, nil + return info, nil } func formatTxResults(cdc *wire.Codec, res []*ctypes.ResultTx) ([]txInfo, error) { @@ -102,17 +102,44 @@ func SearchTxRequestHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.Han tag := r.FormValue("tag") if tag == "" { w.WriteHeader(400) - w.Write([]byte("You need to provide a tag to search for.")) + w.Write([]byte("You need to provide at least a tag as a key=value pair to search for. Postfix the key with _bech32 to search bech32-encoded addresses or public keys")) return } + keyValue := strings.Split(tag, "=") + key := keyValue[0] + value := keyValue[1] + if strings.HasSuffix(key, "_bech32") { + bech32address := strings.Trim(value, "'") + prefix := strings.Split(bech32address, "1")[0] + bz, err := sdk.GetFromBech32(bech32address, prefix) + if err != nil { + w.WriteHeader(400) + w.Write([]byte(err.Error())) + return + } - tags := []string{tag} - output, err := searchTx(ctx, cdc, tags) + tag = strings.TrimRight(key, "_bech32") + "='" + sdk.Address(bz).String() + "'" + } + + txs, err := searchTxs(ctx, cdc, []string{tag}) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) return } + + if len(txs) == 0 { + w.Write([]byte("[]")) + return + } + + output, err := cdc.MarshalJSON(txs) + if err != nil { + w.WriteHeader(500) + w.Write([]byte(err.Error())) + return + } + w.Write(output) } } diff --git a/types/account.go b/types/account.go index 381fb7af8..a7dd50ead 100644 --- a/types/account.go +++ b/types/account.go @@ -91,7 +91,7 @@ func GetAccAddressHex(address string) (addr Address, err error) { // create an Address from a string func GetAccAddressBech32(address string) (addr Address, err error) { - bz, err := getFromBech32(address, Bech32PrefixAccAddr) + bz, err := GetFromBech32(address, Bech32PrefixAccAddr) if err != nil { return nil, err } @@ -100,7 +100,7 @@ func GetAccAddressBech32(address string) (addr Address, err error) { // create a Pubkey from a string func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) { - bz, err := getFromBech32(address, Bech32PrefixAccPub) + bz, err := GetFromBech32(address, Bech32PrefixAccPub) if err != nil { return nil, err } @@ -127,7 +127,7 @@ func GetValAddressHex(address string) (addr Address, err error) { // create an Address from a bech32 string func GetValAddressBech32(address string) (addr Address, err error) { - bz, err := getFromBech32(address, Bech32PrefixValAddr) + bz, err := GetFromBech32(address, Bech32PrefixValAddr) if err != nil { return nil, err } @@ -136,7 +136,7 @@ func GetValAddressBech32(address string) (addr Address, err error) { // decode a validator public key into a PubKey func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) { - bz, err := getFromBech32(pubkey, Bech32PrefixValPub) + bz, err := GetFromBech32(pubkey, Bech32PrefixValPub) if err != nil { return nil, err } @@ -149,7 +149,8 @@ func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) { return pk, nil } -func getFromBech32(bech32str, prefix string) ([]byte, error) { +// decode a bytestring from a bech32-encoded string +func GetFromBech32(bech32str, prefix string) ([]byte, error) { if len(bech32str) == 0 { return nil, errors.New("must provide non-empty string") } diff --git a/types/wire.go b/types/wire.go index 245b3677c..2ef28820d 100644 --- a/types/wire.go +++ b/types/wire.go @@ -5,4 +5,5 @@ import wire "github.com/cosmos/cosmos-sdk/wire" // Register the sdk message type func RegisterWire(cdc *wire.Codec) { cdc.RegisterInterface((*Msg)(nil), nil) + cdc.RegisterInterface((*Tx)(nil), nil) } diff --git a/x/auth/wire.go b/x/auth/wire.go index 309464c86..6e430be4c 100644 --- a/x/auth/wire.go +++ b/x/auth/wire.go @@ -9,6 +9,7 @@ func RegisterWire(cdc *wire.Codec) { cdc.RegisterInterface((*Account)(nil), nil) cdc.RegisterConcrete(&BaseAccount{}, "auth/Account", nil) cdc.RegisterConcrete(MsgChangeKey{}, "auth/ChangeKey", nil) + cdc.RegisterConcrete(StdTx{}, "auth/StdTx", nil) } var msgCdc = wire.NewCodec() diff --git a/x/bank/keeper.go b/x/bank/keeper.go index b14da4d81..71c884ffe 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -151,7 +151,7 @@ func subtractCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt return amt, nil, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) } err := setCoins(ctx, am, addr, newCoins) - tags := sdk.NewTags("sender", addr.Bytes()) + tags := sdk.NewTags("sender", []byte(addr.String())) return newCoins, tags, err } @@ -164,7 +164,7 @@ func addCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk. return amt, nil, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) } err := setCoins(ctx, am, addr, newCoins) - tags := sdk.NewTags("recipient", addr.Bytes()) + tags := sdk.NewTags("recipient", []byte(addr.String())) return newCoins, tags, err } From 1b20adcd22a51b7efc551807e4532ca6b382b72b Mon Sep 17 00:00:00 2001 From: Rigel Date: Mon, 11 Jun 2018 18:12:37 -0700 Subject: [PATCH 61/89] Merge PR #1191: LCD cleanup / add LCD gas field * remove global variables from lcd * added make race, fix lcd race condition * cleanup * Five-character changelog update --- .gitignore | 3 +- CHANGELOG.md | 4 +- Makefile | 3 + client/keys/utils.go | 2 + client/lcd/helpers.go | 53 ---- client/lcd/lcd_test.go | 495 +++++++++++++--------------------- client/lcd/main_test.go | 38 --- client/lcd/root.go | 48 ++-- client/lcd/test_helpers.go | 234 ++++++++++++++++ x/bank/client/rest/sendtx.go | 4 + x/ibc/client/rest/transfer.go | 4 + x/stake/client/rest/query.go | 2 +- x/stake/client/rest/tx.go | 4 + 13 files changed, 464 insertions(+), 430 deletions(-) delete mode 100644 client/lcd/helpers.go delete mode 100644 client/lcd/main_test.go create mode 100644 client/lcd/test_helpers.go diff --git a/.gitignore b/.gitignore index 494e72452..da467c151 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ docs/_build # Data - ideally these don't exist examples/basecoin/app/data baseapp/data/* +client/lcd/keys/* # Testing coverage.txt @@ -26,4 +27,4 @@ profile.out vagrant # Graphviz -dependency-graph.png \ No newline at end of file +dependency-graph.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 16346def3..248509389 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ BREAKING CHANGES * msg.GetSignBytes() now returns bech32-encoded addresses in all cases +* [lcd] REST end-points now include gas FEATURES @@ -9,10 +10,11 @@ IMPROVEMENTS * export command now writes current validator set for Tendermint * [tests] Application module tests now use a mock application * [gaiacli] Fix error message when account isn't found when running gaiacli account +* [lcd] refactored to eliminate use of global variables, and interdependent tests FIXES * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs -* fixed tx indexing/querying +* [lcd] fixed tx indexing/querying * [cli] Added `--gas` flag to specify transaction gas limit ## 0.18.0 diff --git a/Makefile b/Makefile index f7e2083c7..d6444b0b6 100644 --- a/Makefile +++ b/Makefile @@ -92,6 +92,9 @@ test_cli: test_unit: @go test $(PACKAGES_NOCLITEST) +test_race: + @go test -race $(PACKAGES_NOCLITEST) + test_cover: @bash tests/test_cover.sh diff --git a/client/keys/utils.go b/client/keys/utils.go index d810dfa1f..8b6cfcb35 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -21,6 +21,8 @@ const KeyDBName = "keys" // keybase is used to make GetKeyBase a singleton var keybase keys.Keybase +// TODO make keybase take a database not load from the directory + // initialize a keybase based on the configuration func GetKeyBase() (keys.Keybase, error) { rootDir := viper.GetString(cli.HomeFlag) diff --git a/client/lcd/helpers.go b/client/lcd/helpers.go deleted file mode 100644 index 14cd5c16c..000000000 --- a/client/lcd/helpers.go +++ /dev/null @@ -1,53 +0,0 @@ -package lcd - -// NOTE: COPIED VERBATIM FROM tendermint/tendermint/rpc/test/helpers.go - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - cmn "github.com/tendermint/tmlibs/common" - - cfg "github.com/tendermint/tendermint/config" -) - -var globalConfig *cfg.Config - -// f**ing long, but unique for each test -func makePathname() string { - // get path - p, err := os.Getwd() - if err != nil { - panic(err) - } - // fmt.Println(p) - sep := string(filepath.Separator) - return strings.Replace(p, sep, "_", -1) -} - -func randPort() int { - return int(cmn.RandUint16()/2 + 10000) -} - -func makeAddrs() (string, string, string) { - start := randPort() - return fmt.Sprintf("tcp://0.0.0.0:%d", start), - fmt.Sprintf("tcp://0.0.0.0:%d", start+1), - fmt.Sprintf("tcp://0.0.0.0:%d", start+2) -} - -// GetConfig returns a config for the test cases as a singleton -func GetConfig() *cfg.Config { - if globalConfig == nil { - pathname := makePathname() - globalConfig = cfg.ResetTestRoot(pathname) - - // and we use random ports to run in parallel - tm, rpc, _ := makeAddrs() - globalConfig.P2P.ListenAddress = tm - globalConfig.RPC.ListenAddress = rpc - } - return globalConfig -} diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 3565d99c3..48e2ad0a2 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -1,146 +1,115 @@ package lcd import ( - "bytes" "encoding/hex" "encoding/json" "fmt" - "io/ioutil" - "net" "net/http" - "os" "regexp" "testing" - "github.com/spf13/viper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" cryptoKeys "github.com/tendermint/go-crypto/keys" - tmcfg "github.com/tendermint/tendermint/config" - nm "github.com/tendermint/tendermint/node" p2p "github.com/tendermint/tendermint/p2p" - pvm "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/proxy" ctypes "github.com/tendermint/tendermint/rpc/core/types" - tmrpc "github.com/tendermint/tendermint/rpc/lib/server" - tmtypes "github.com/tendermint/tendermint/types" - "github.com/tendermint/tmlibs/cli" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" client "github.com/cosmos/cosmos-sdk/client" keys "github.com/cosmos/cosmos-sdk/client/keys" rpc "github.com/cosmos/cosmos-sdk/client/rpc" - gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/server" tests "github.com/cosmos/cosmos-sdk/tests" 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" stakerest "github.com/cosmos/cosmos-sdk/x/stake/client/rest" ) -var ( - coinDenom = "steak" - coinAmount = int64(10000000) - - validatorAddr1Hx = "" - validatorAddr2Hx = "" - validatorAddr1 = "" - validatorAddr2 = "" - - // XXX bad globals - name = "test" - password = "0123456789" - port string - seed string - sendAddr string -) - func TestKeys(t *testing.T) { - - // empty keys - // XXX: the test comes with a key setup - /* - res, body := request(t, port, "GET", "/keys", nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - assert.Equal(t, "[]", body, "Expected an empty array") - */ + name, password := "test", "1234567890" + addr, seed := CreateAddr(t, "test", password, GetKB(t)) + cleanup, _, port := InitializeTestLCD(t, 2, []sdk.Address{addr}) + defer cleanup() // get seed - res, body := request(t, port, "GET", "/keys/seed", nil) + res, body := Request(t, port, "GET", "/keys/seed", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) newSeed := body reg, err := regexp.Compile(`([a-z]+ ){12}`) require.Nil(t, err) match := reg.MatchString(seed) - assert.True(t, match, "Returned seed has wrong foramt", seed) + assert.True(t, match, "Returned seed has wrong format", seed) newName := "test_newname" newPassword := "0987654321" // add key var jsonStr = []byte(fmt.Sprintf(`{"name":"test_fail", "password":"%s"}`, password)) - res, body = request(t, port, "POST", "/keys", jsonStr) + res, body = Request(t, port, "POST", "/keys", jsonStr) assert.Equal(t, http.StatusBadRequest, res.StatusCode, "Account creation should require a seed") jsonStr = []byte(fmt.Sprintf(`{"name":"%s", "password":"%s", "seed": "%s"}`, newName, newPassword, newSeed)) - res, body = request(t, port, "POST", "/keys", jsonStr) + res, body = Request(t, port, "POST", "/keys", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) - addr := body - assert.Len(t, addr, 40, "Returned address has wrong format", addr) + addr2 := body + assert.Len(t, addr2, 40, "Returned address has wrong format", addr2) // existing keys - res, body = request(t, port, "GET", "/keys", nil) + res, body = Request(t, port, "GET", "/keys", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var m [2]keys.KeyOutput err = cdc.UnmarshalJSON([]byte(body), &m) require.Nil(t, err) - addrAcc, _ := sdk.GetAccAddressHex(addr) - addrBech32, _ := sdk.Bech32ifyAcc(addrAcc) + addr2Acc, err := sdk.GetAccAddressHex(addr2) + require.Nil(t, err) + addr2Bech32 := sdk.MustBech32ifyAcc(addr2Acc) + addrBech32 := sdk.MustBech32ifyAcc(addr) assert.Equal(t, name, m[0].Name, "Did not serve keys name correctly") - assert.Equal(t, sendAddr, m[0].Address, "Did not serve keys Address correctly") + assert.Equal(t, addrBech32, m[0].Address, "Did not serve keys Address correctly") assert.Equal(t, newName, m[1].Name, "Did not serve keys name correctly") - assert.Equal(t, addrBech32, m[1].Address, "Did not serve keys Address correctly") + assert.Equal(t, addr2Bech32, m[1].Address, "Did not serve keys Address correctly") // select key keyEndpoint := fmt.Sprintf("/keys/%s", newName) - res, body = request(t, port, "GET", keyEndpoint, nil) + res, body = Request(t, port, "GET", keyEndpoint, nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var m2 keys.KeyOutput err = cdc.UnmarshalJSON([]byte(body), &m2) require.Nil(t, err) assert.Equal(t, newName, m2.Name, "Did not serve keys name correctly") - assert.Equal(t, addrBech32, m2.Address, "Did not serve keys Address correctly") + assert.Equal(t, addr2Bech32, m2.Address, "Did not serve keys Address correctly") // update key - jsonStr = []byte(fmt.Sprintf(`{"old_password":"%s", "new_password":"12345678901"}`, newPassword)) - res, body = request(t, port, "PUT", keyEndpoint, jsonStr) + jsonStr = []byte(fmt.Sprintf(`{ + "old_password":"%s", + "new_password":"12345678901" + }`, newPassword)) + + res, body = Request(t, port, "PUT", keyEndpoint, jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) // here it should say unauthorized as we changed the password before - res, body = request(t, port, "PUT", keyEndpoint, jsonStr) + res, body = Request(t, port, "PUT", keyEndpoint, jsonStr) require.Equal(t, http.StatusUnauthorized, res.StatusCode, body) // delete key jsonStr = []byte(`{"password":"12345678901"}`) - res, body = request(t, port, "DELETE", keyEndpoint, jsonStr) + res, body = Request(t, port, "DELETE", keyEndpoint, jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) } func TestVersion(t *testing.T) { + cleanup, _, port := InitializeTestLCD(t, 1, []sdk.Address{}) + defer cleanup() // node info - res, body := request(t, port, "GET", "/version", nil) + res, body := Request(t, port, "GET", "/version", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) reg, err := regexp.Compile(`\d+\.\d+\.\d+(-dev)?`) @@ -150,9 +119,11 @@ func TestVersion(t *testing.T) { } func TestNodeStatus(t *testing.T) { + cleanup, _, port := InitializeTestLCD(t, 1, []sdk.Address{}) + defer cleanup() // node info - res, body := request(t, port, "GET", "/node_info", nil) + res, body := Request(t, port, "GET", "/node_info", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var nodeInfo p2p.NodeInfo @@ -162,21 +133,20 @@ func TestNodeStatus(t *testing.T) { assert.NotEqual(t, p2p.NodeInfo{}, nodeInfo, "res: %v", res) // syncing - res, body = request(t, port, "GET", "/syncing", nil) + res, body = Request(t, port, "GET", "/syncing", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) // we expect that there is no other node running so the syncing state is "false" - // we c assert.Equal(t, "false", body) } func TestBlock(t *testing.T) { - - tests.WaitForHeight(2, port) + cleanup, _, port := InitializeTestLCD(t, 1, []sdk.Address{}) + defer cleanup() var resultBlock ctypes.ResultBlock - res, body := request(t, port, "GET", "/blocks/latest", nil) + res, body := Request(t, port, "GET", "/blocks/latest", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) err := cdc.UnmarshalJSON([]byte(body), &resultBlock) @@ -186,7 +156,7 @@ func TestBlock(t *testing.T) { // -- - res, body = request(t, port, "GET", "/blocks/1", nil) + res, body = Request(t, port, "GET", "/blocks/1", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) err = json.Unmarshal([]byte(body), &resultBlock) @@ -196,15 +166,17 @@ func TestBlock(t *testing.T) { // -- - res, body = request(t, port, "GET", "/blocks/1000000000", nil) + res, body = Request(t, port, "GET", "/blocks/1000000000", nil) require.Equal(t, http.StatusNotFound, res.StatusCode, body) } func TestValidators(t *testing.T) { + cleanup, _, port := InitializeTestLCD(t, 1, []sdk.Address{}) + defer cleanup() var resultVals rpc.ResultValidatorsOutput - res, body := request(t, port, "GET", "/validatorsets/latest", nil) + res, body := Request(t, port, "GET", "/validatorsets/latest", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) err := cdc.UnmarshalJSON([]byte(body), &resultVals) @@ -217,7 +189,7 @@ func TestValidators(t *testing.T) { // -- - res, body = request(t, port, "GET", "/validatorsets/1", nil) + res, body = Request(t, port, "GET", "/validatorsets/1", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) err = cdc.UnmarshalJSON([]byte(body), &resultVals) @@ -227,23 +199,29 @@ func TestValidators(t *testing.T) { // -- - res, body = request(t, port, "GET", "/validatorsets/1000000000", nil) + res, body = Request(t, port, "GET", "/validatorsets/1000000000", nil) require.Equal(t, http.StatusNotFound, res.StatusCode) } func TestCoinSend(t *testing.T) { - bz, _ := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6") - someFakeAddr, _ := sdk.Bech32ifyAcc(bz) + name, password := "test", "1234567890" + addr, seed := CreateAddr(t, "test", password, GetKB(t)) + cleanup, _, port := InitializeTestLCD(t, 2, []sdk.Address{addr}) + defer cleanup() + + bz, err := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6") + require.NoError(t, err) + someFakeAddr := sdk.MustBech32ifyAcc(bz) // query empty - res, body := request(t, port, "GET", "/accounts/"+someFakeAddr, nil) + res, body := Request(t, port, "GET", "/accounts/"+someFakeAddr, nil) require.Equal(t, http.StatusNoContent, res.StatusCode, body) - acc := getAccount(t, sendAddr) + acc := getAccount(t, port, addr) initialBalance := acc.GetCoins() // create TX - receiveAddr, resultTx := doSend(t, port) + receiveAddr, resultTx := doSend(t, port, seed, name, password, addr) tests.WaitForHeight(resultTx.Height+1, port) // check if tx was commited @@ -251,27 +229,31 @@ func TestCoinSend(t *testing.T) { assert.Equal(t, uint32(0), resultTx.DeliverTx.Code) // query sender - acc = getAccount(t, sendAddr) + acc = getAccount(t, port, addr) coins := acc.GetCoins() mycoins := coins[0] - assert.Equal(t, coinDenom, mycoins.Denom) + assert.Equal(t, "steak", mycoins.Denom) assert.Equal(t, initialBalance[0].Amount-1, mycoins.Amount) // query receiver - acc = getAccount(t, receiveAddr) + acc = getAccount(t, port, receiveAddr) coins = acc.GetCoins() mycoins = coins[0] - assert.Equal(t, coinDenom, mycoins.Denom) + assert.Equal(t, "steak", mycoins.Denom) assert.Equal(t, int64(1), mycoins.Amount) } func TestIBCTransfer(t *testing.T) { + name, password := "test", "1234567890" + addr, seed := CreateAddr(t, "test", password, GetKB(t)) + cleanup, _, port := InitializeTestLCD(t, 2, []sdk.Address{addr}) + defer cleanup() - acc := getAccount(t, sendAddr) + acc := getAccount(t, port, addr) initialBalance := acc.GetCoins() // create TX - resultTx := doIBCTransfer(t, port, seed) + resultTx := doIBCTransfer(t, port, seed, name, password, addr) tests.WaitForHeight(resultTx.Height+1, port) @@ -280,32 +262,37 @@ func TestIBCTransfer(t *testing.T) { assert.Equal(t, uint32(0), resultTx.DeliverTx.Code) // query sender - acc = getAccount(t, sendAddr) + acc = getAccount(t, port, addr) coins := acc.GetCoins() mycoins := coins[0] - assert.Equal(t, coinDenom, mycoins.Denom) + assert.Equal(t, "steak", mycoins.Denom) assert.Equal(t, initialBalance[0].Amount-1, mycoins.Amount) // TODO: query ibc egress packet state } func TestTxs(t *testing.T) { + name, password := "test", "1234567890" + addr, seed := CreateAddr(t, "test", password, GetKB(t)) + cleanup, _, port := InitializeTestLCD(t, 2, []sdk.Address{addr}) + defer cleanup() + // query wrong - res, body := request(t, port, "GET", "/txs", nil) + res, body := Request(t, port, "GET", "/txs", nil) require.Equal(t, http.StatusBadRequest, res.StatusCode, body) // query empty - res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", "cosmosaccaddr1jawd35d9aq4u76sr3fjalmcqc8hqygs9gtnmv3"), nil) + res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", "cosmosaccaddr1jawd35d9aq4u76sr3fjalmcqc8hqygs9gtnmv3"), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) assert.Equal(t, "[]", body) // create TX - receiveAddr, resultTx := doSend(t, port) + receiveAddr, resultTx := doSend(t, port, seed, name, password, addr) tests.WaitForHeight(resultTx.Height+1, port) // check if tx is findable - res, body = request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil) + res, body = Request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) type txInfo struct { @@ -316,53 +303,67 @@ func TestTxs(t *testing.T) { var indexedTxs []txInfo // check if tx is queryable - res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=tx.hash='%s'", resultTx.Hash), nil) + res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=tx.hash='%s'", resultTx.Hash), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) assert.NotEqual(t, "[]", body) err := cdc.UnmarshalJSON([]byte(body), &indexedTxs) require.NoError(t, err) - assert.Equal(t, len(indexedTxs), 1) + assert.Equal(t, 1, len(indexedTxs)) // query sender - res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", sendAddr), nil) + addrBech := sdk.MustBech32ifyAcc(addr) + res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", addrBech), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) err = cdc.UnmarshalJSON([]byte(body), &indexedTxs) require.NoError(t, err) - assert.Equal(t, 2, len(indexedTxs)) // there are 2 txs created with doSend - assert.Equal(t, resultTx.Height, indexedTxs[1].Height) + require.Equal(t, 1, len(indexedTxs), "%v", indexedTxs) // there are 2 txs created with doSend + assert.Equal(t, resultTx.Height, indexedTxs[0].Height) // query recipient - res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=recipient_bech32='%s'", receiveAddr), nil) + receiveAddrBech := sdk.MustBech32ifyAcc(receiveAddr) + res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=recipient_bech32='%s'", receiveAddrBech), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) err = cdc.UnmarshalJSON([]byte(body), &indexedTxs) require.NoError(t, err) - assert.Equal(t, 1, len(indexedTxs)) + require.Equal(t, 1, len(indexedTxs)) assert.Equal(t, resultTx.Height, indexedTxs[0].Height) } func TestValidatorsQuery(t *testing.T) { - validators := getValidators(t) + cleanup, pks, port := InitializeTestLCD(t, 2, []sdk.Address{}) + require.Equal(t, 2, len(pks)) + defer cleanup() + + validators := getValidators(t, port) assert.Equal(t, len(validators), 2) // make sure all the validators were found (order unknown because sorted by owner addr) foundVal1, foundVal2 := false, false - if validators[0].Owner == validatorAddr1 || validators[1].Owner == validatorAddr1 { + pk1Bech := sdk.MustBech32ifyValPub(pks[0]) + pk2Bech := sdk.MustBech32ifyValPub(pks[1]) + if validators[0].PubKey == pk1Bech || validators[1].PubKey == pk1Bech { foundVal1 = true } - if validators[0].Owner == validatorAddr2 || validators[1].Owner == validatorAddr2 { + if validators[0].PubKey == pk2Bech || validators[1].PubKey == pk2Bech { foundVal2 = true } - assert.True(t, foundVal1, "validatorAddr1 %v, owner1 %v, owner2 %v", validatorAddr1, validators[0].Owner, validators[1].Owner) - assert.True(t, foundVal2, "validatorAddr2 %v, owner1 %v, owner2 %v", validatorAddr2, validators[0].Owner, validators[1].Owner) + assert.True(t, foundVal1, "pk1Bech %v, owner1 %v, owner2 %v", pk1Bech, validators[0].Owner, validators[1].Owner) + assert.True(t, foundVal2, "pk2Bech %v, owner1 %v, owner2 %v", pk2Bech, validators[0].Owner, validators[1].Owner) } -func TestBond(t *testing.T) { +func TestBonding(t *testing.T) { + name, password, denom := "test", "1234567890", "steak" + addr, seed := CreateAddr(t, "test", password, GetKB(t)) + cleanup, pks, port := InitializeTestLCD(t, 2, []sdk.Address{addr}) + defer cleanup() + + validator1Owner := pks[0].Address() // create bond TX - resultTx := doBond(t, port, seed) + resultTx := doBond(t, port, seed, name, password, addr, validator1Owner) tests.WaitForHeight(resultTx.Height+1, port) // check if tx was commited @@ -370,201 +371,41 @@ func TestBond(t *testing.T) { assert.Equal(t, uint32(0), resultTx.DeliverTx.Code) // query sender - acc := getAccount(t, sendAddr) + acc := getAccount(t, port, addr) coins := acc.GetCoins() - assert.Equal(t, int64(87), coins.AmountOf(coinDenom)) + assert.Equal(t, int64(40), coins.AmountOf(denom)) - // query candidate - bond := getDelegation(t, sendAddr, validatorAddr1) - assert.Equal(t, "10/1", bond.Shares.String()) -} + // query validator + bond := getDelegation(t, port, addr, validator1Owner) + assert.Equal(t, "60/1", bond.Shares.String()) -func TestUnbond(t *testing.T) { + ////////////////////// + // testing unbonding // create unbond TX - resultTx := doUnbond(t, port, seed) + resultTx = doUnbond(t, port, seed, name, password, addr, validator1Owner) tests.WaitForHeight(resultTx.Height+1, port) + // query validator + bond = getDelegation(t, port, addr, validator1Owner) + assert.Equal(t, "30/1", bond.Shares.String()) + // check if tx was commited assert.Equal(t, uint32(0), resultTx.CheckTx.Code) assert.Equal(t, uint32(0), resultTx.DeliverTx.Code) + // TODO fix shares fn in staking // query sender - acc := getAccount(t, sendAddr) - coins := acc.GetCoins() - assert.Equal(t, int64(98), coins.AmountOf(coinDenom)) - - // query candidate - bond := getDelegation(t, sendAddr, validatorAddr1) - assert.Equal(t, "9/1", bond.Shares.String()) + //acc = getAccount(t, port, addr) + //coins = acc.GetCoins() + //assert.Equal(t, int64(70), coins.AmountOf(denom)) } -//__________________________________________________________ -// helpers - -// strt TM and the LCD in process, listening on their respective sockets -func startTMAndLCD() (*nm.Node, net.Listener, error) { - - dir, err := ioutil.TempDir("", "lcd_test") - if err != nil { - return nil, nil, err - } - viper.Set(cli.HomeFlag, dir) - viper.Set(client.FlagGas, 200000) - kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( - if err != nil { - return nil, nil, err - } - - config := GetConfig() - config.Consensus.TimeoutCommit = 1000 - config.Consensus.SkipTimeoutCommit = false - config.TxIndex.IndexAllTags = true - - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - logger = log.NewFilter(logger, log.AllowError()) - privValidatorFile := config.PrivValidatorFile() - privVal := pvm.LoadOrGenFilePV(privValidatorFile) - db := dbm.NewMemDB() - app := gapp.NewGaiaApp(logger, db) - cdc = gapp.MakeCodec() // XXX - - genesisFile := config.GenesisFile() - genDoc, err := tmtypes.GenesisDocFromFile(genesisFile) - if err != nil { - return nil, nil, err - } - - genDoc.Validators = append(genDoc.Validators, - tmtypes.GenesisValidator{ - PubKey: crypto.GenPrivKeyEd25519().PubKey(), - Power: 1, - Name: "val", - }, - ) - - pk1 := genDoc.Validators[0].PubKey - pk2 := genDoc.Validators[1].PubKey - validatorAddr1Hx = hex.EncodeToString(pk1.Address()) - validatorAddr2Hx = hex.EncodeToString(pk2.Address()) - validatorAddr1, _ = sdk.Bech32ifyVal(pk1.Address()) - validatorAddr2, _ = sdk.Bech32ifyVal(pk2.Address()) - - // NOTE it's bad practice to reuse pk address for the owner address but doing in the - // test for simplicity - var appGenTxs [2]json.RawMessage - appGenTxs[0], _, _, err = gapp.GaiaAppGenTxNF(cdc, pk1, pk1.Address(), "test_val1", true) - if err != nil { - return nil, nil, err - } - appGenTxs[1], _, _, err = gapp.GaiaAppGenTxNF(cdc, pk2, pk2.Address(), "test_val2", true) - if err != nil { - return nil, nil, err - } - - genesisState, err := gapp.GaiaAppGenState(cdc, appGenTxs[:]) - if err != nil { - return nil, nil, err - } - - // add the sendAddr to genesis - var info cryptoKeys.Info - info, seed, err = kb.Create(name, password, cryptoKeys.AlgoEd25519) // XXX global seed - if err != nil { - return nil, nil, err - } - sendAddrHex, _ := sdk.GetAccAddressHex(info.PubKey.Address().String()) - sendAddr, _ = sdk.Bech32ifyAcc(sendAddrHex) // XXX global - accAuth := auth.NewBaseAccountWithAddress(info.PubKey.Address()) - accAuth.Coins = sdk.Coins{{"steak", 100}} - acc := gapp.NewGenesisAccount(&accAuth) - genesisState.Accounts = append(genesisState.Accounts, acc) - - appState, err := wire.MarshalJSONIndent(cdc, genesisState) - if err != nil { - return nil, nil, err - } - genDoc.AppStateJSON = appState - - // LCD listen address - var listenAddr string - listenAddr, port, err = server.FreeTCPAddr() - if err != nil { - return nil, nil, err - } - - // XXX: need to set this so LCD knows the tendermint node address! - viper.Set(client.FlagNode, config.RPC.ListenAddress) - viper.Set(client.FlagChainID, genDoc.ChainID) - - node, err := startTM(config, logger, genDoc, privVal, app) - if err != nil { - return nil, nil, err - } - lcd, err := startLCD(logger, listenAddr, cdc) - if err != nil { - return nil, nil, err - } - - tests.WaitForStart(port) - - return node, lcd, nil -} - -// Create & start in-process tendermint node with memdb -// and in-process abci application. -// TODO: need to clean up the WAL dir or enable it to be not persistent -func startTM(cfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc, privVal tmtypes.PrivValidator, app abci.Application) (*nm.Node, error) { - genDocProvider := func() (*tmtypes.GenesisDoc, error) { return genDoc, nil } - dbProvider := func(*nm.DBContext) (dbm.DB, error) { return dbm.NewMemDB(), nil } - n, err := nm.NewNode(cfg, - privVal, - proxy.NewLocalClientCreator(app), - genDocProvider, - dbProvider, - logger.With("module", "node")) - if err != nil { - return nil, err - } - - err = n.Start() - if err != nil { - return nil, err - } - - // wait for rpc - tests.WaitForRPC(GetConfig().RPC.ListenAddress) - - logger.Info("Tendermint running!") - return n, err -} - -// start the LCD. note this blocks! -func startLCD(logger log.Logger, listenAddr string, cdc *wire.Codec) (net.Listener, error) { - handler := createHandler(cdc) - return tmrpc.StartHTTPServer(listenAddr, handler, logger) -} - -func request(t *testing.T, port, method, path string, payload []byte) (*http.Response, string) { - var res *http.Response - var err error - url := fmt.Sprintf("http://localhost:%v%v", port, path) - req, err := http.NewRequest(method, url, bytes.NewBuffer(payload)) - require.Nil(t, err) - res, err = http.DefaultClient.Do(req) - // res, err = http.Post(url, "application/json", bytes.NewBuffer(payload)) - require.Nil(t, err) - - output, err := ioutil.ReadAll(res.Body) - res.Body.Close() - require.Nil(t, err) - - return res, string(output) -} - -func getAccount(t *testing.T, sendAddr string) auth.Account { - // get the account to get the sequence - res, body := request(t, port, "GET", "/accounts/"+sendAddr, nil) +//_____________________________________________________________________________ +// get the account to get the sequence +func getAccount(t *testing.T, port string, addr sdk.Address) auth.Account { + addrBech32 := sdk.MustBech32ifyAcc(addr) + res, body := Request(t, port, "GET", "/accounts/"+addrBech32, nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var acc auth.Account err := cdc.UnmarshalJSON([]byte(body), &acc) @@ -572,20 +413,32 @@ func getAccount(t *testing.T, sendAddr string) auth.Account { return acc } -func doSend(t *testing.T, port string) (receiveAddr string, resultTx ctypes.ResultBroadcastTxCommit) { +func doSend(t *testing.T, port, seed, name, password string, addr sdk.Address) (receiveAddr sdk.Address, resultTx ctypes.ResultBroadcastTxCommit) { // create receive address kb := client.MockKeyBase() receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519")) require.Nil(t, err) - receiveAddr, _ = sdk.Bech32ifyAcc(receiveInfo.PubKey.Address()) + receiveAddr = receiveInfo.PubKey.Address() + receiveAddrBech := sdk.MustBech32ifyAcc(receiveAddr) - acc := getAccount(t, sendAddr) + acc := getAccount(t, port, addr) sequence := acc.GetSequence() // send - jsonStr := []byte(fmt.Sprintf(`{ "name":"%s", "password":"%s", "sequence":%d, "amount":[{ "denom": "%s", "amount": 1 }] }`, name, password, sequence, coinDenom)) - res, body := request(t, port, "POST", "/accounts/"+receiveAddr+"/send", jsonStr) + jsonStr := []byte(fmt.Sprintf(`{ + "name":"%s", + "password":"%s", + "sequence":%d, + "gas": 10000, + "amount":[ + { + "denom": "%s", + "amount": 1 + } + ] + }`, name, password, sequence, "steak")) + res, body := Request(t, port, "POST", "/accounts/"+receiveAddrBech+"/send", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) err = cdc.UnmarshalJSON([]byte(body), &resultTx) @@ -594,20 +447,32 @@ func doSend(t *testing.T, port string) (receiveAddr string, resultTx ctypes.Resu return receiveAddr, resultTx } -func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxCommit) { +func doIBCTransfer(t *testing.T, port, seed, name, password string, addr sdk.Address) (resultTx ctypes.ResultBroadcastTxCommit) { // create receive address kb := client.MockKeyBase() receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519")) require.Nil(t, err) - receiveAddr, _ := sdk.Bech32ifyAcc(receiveInfo.PubKey.Address()) + receiveAddr := receiveInfo.PubKey.Address() + receiveAddrBech := sdk.MustBech32ifyAcc(receiveAddr) // get the account to get the sequence - acc := getAccount(t, sendAddr) + acc := getAccount(t, port, addr) sequence := acc.GetSequence() // send - jsonStr := []byte(fmt.Sprintf(`{ "name":"%s", "password":"%s", "sequence":%d, "amount":[{ "denom": "%s", "amount": 1 }] }`, name, password, sequence, coinDenom)) - res, body := request(t, port, "POST", "/ibc/testchain/"+receiveAddr+"/send", jsonStr) + jsonStr := []byte(fmt.Sprintf(`{ + "name":"%s", + "password": "%s", + "sequence": %d, + "gas": 100000, + "amount":[ + { + "denom": "%s", + "amount": 1 + } + ] + }`, name, password, sequence, "steak")) + res, body := Request(t, port, "POST", "/ibc/testchain/"+receiveAddrBech+"/send", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) err = cdc.UnmarshalJSON([]byte(body), &resultTx) @@ -616,9 +481,13 @@ func doIBCTransfer(t *testing.T, port, seed string) (resultTx ctypes.ResultBroad return resultTx } -func getDelegation(t *testing.T, delegatorAddr, candidateAddr string) stake.Delegation { +func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.Address) stake.Delegation { + + delegatorAddrBech := sdk.MustBech32ifyAcc(delegatorAddr) + validatorAddrBech := sdk.MustBech32ifyVal(validatorAddr) + // get the account to get the sequence - res, body := request(t, port, "GET", "/stake/"+delegatorAddr+"/bonding_status/"+candidateAddr, nil) + res, body := Request(t, port, "GET", "/stake/"+delegatorAddrBech+"/bonding_status/"+validatorAddrBech, nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var bond stake.Delegation err := cdc.UnmarshalJSON([]byte(body), &bond) @@ -626,26 +495,30 @@ func getDelegation(t *testing.T, delegatorAddr, candidateAddr string) stake.Dele return bond } -func doBond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxCommit) { +func doBond(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.Address) (resultTx ctypes.ResultBroadcastTxCommit) { // get the account to get the sequence - acc := getAccount(t, sendAddr) + acc := getAccount(t, port, delegatorAddr) sequence := acc.GetSequence() + delegatorAddrBech := sdk.MustBech32ifyAcc(delegatorAddr) + validatorAddrBech := sdk.MustBech32ifyVal(validatorAddr) + // send jsonStr := []byte(fmt.Sprintf(`{ "name": "%s", "password": "%s", "sequence": %d, + "gas": 10000, "delegate": [ { "delegator_addr": "%s", "validator_addr": "%s", - "bond": { "denom": "%s", "amount": 10 } + "bond": { "denom": "%s", "amount": 60 } } ], "unbond": [] - }`, name, password, sequence, sendAddr, validatorAddr1, coinDenom)) - res, body := request(t, port, "POST", "/stake/delegations", jsonStr) + }`, name, password, sequence, delegatorAddrBech, validatorAddrBech, "steak")) + res, body := Request(t, port, "POST", "/stake/delegations", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) var results []ctypes.ResultBroadcastTxCommit @@ -655,26 +528,30 @@ func doBond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxC return results[0] } -func doUnbond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastTxCommit) { +func doUnbond(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.Address) (resultTx ctypes.ResultBroadcastTxCommit) { // get the account to get the sequence - acc := getAccount(t, sendAddr) + acc := getAccount(t, port, delegatorAddr) sequence := acc.GetSequence() + delegatorAddrBech := sdk.MustBech32ifyAcc(delegatorAddr) + validatorAddrBech := sdk.MustBech32ifyVal(validatorAddr) + // send jsonStr := []byte(fmt.Sprintf(`{ "name": "%s", "password": "%s", "sequence": %d, - "bond": [], + "gas": 10000, + "delegate": [], "unbond": [ { "delegator_addr": "%s", "validator_addr": "%s", - "shares": "1" + "shares": "30" } ] - }`, name, password, sequence, sendAddr, validatorAddr1)) - res, body := request(t, port, "POST", "/stake/delegations", jsonStr) + }`, name, password, sequence, delegatorAddrBech, validatorAddrBech)) + res, body := Request(t, port, "POST", "/stake/delegations", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) var results []ctypes.ResultBroadcastTxCommit @@ -684,9 +561,9 @@ func doUnbond(t *testing.T, port, seed string) (resultTx ctypes.ResultBroadcastT return results[0] } -func getValidators(t *testing.T) []stakerest.StakeValidatorOutput { +func getValidators(t *testing.T, port string) []stakerest.StakeValidatorOutput { // get the account to get the sequence - res, body := request(t, port, "GET", "/stake/validators", nil) + res, body := Request(t, port, "GET", "/stake/validators", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var validators []stakerest.StakeValidatorOutput err := cdc.UnmarshalJSON([]byte(body), &validators) diff --git a/client/lcd/main_test.go b/client/lcd/main_test.go deleted file mode 100644 index 9f0e2bd4f..000000000 --- a/client/lcd/main_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package lcd - -import ( - "fmt" - "os" - "testing" - - nm "github.com/tendermint/tendermint/node" -) - -var node *nm.Node - -// See https://golang.org/pkg/testing/#hdr-Main -// for more details -func TestMain(m *testing.M) { - // start a basecoind node and LCD server in the background to test against - - // run all the tests against a single server instance - node, lcd, err := startTMAndLCD() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - code := m.Run() - - // tear down - // TODO: cleanup - // TODO: it would be great if TM could run without - // persiting anything in the first place - node.Stop() - node.Wait() - - // just a listener ... - lcd.Close() - - os.Exit(code) -} diff --git a/client/lcd/root.go b/client/lcd/root.go index 507134302..c3ec75c96 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -25,19 +25,34 @@ import ( stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest" ) -const ( - flagListenAddr = "laddr" - flagCORS = "cors" -) - // ServeCommand will generate a long-running rest server // (aka Light Client Daemon) that exposes functionality similar // to the cli, but over rest func ServeCommand(cdc *wire.Codec) *cobra.Command { + flagListenAddr := "laddr" + flagCORS := "cors" + cmd := &cobra.Command{ Use: "rest-server", Short: "Start LCD (light-client daemon), a local REST server", - RunE: startRESTServerFn(cdc), + RunE: func(cmd *cobra.Command, args []string) error { + listenAddr := viper.GetString(flagListenAddr) + handler := createHandler(cdc) + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)). + With("module", "rest-server") + listener, err := tmserver.StartHTTPServer(listenAddr, handler, logger) + if err != nil { + return err + } + logger.Info("REST server started") + + // Wait forever and cleanup + cmn.TrapSignal(func() { + err := listener.Close() + logger.Error("Error closing listener", "err", err) + }) + return nil + }, } cmd.Flags().StringP(flagListenAddr, "a", "tcp://localhost:1317", "Address for server to listen on") cmd.Flags().String(flagCORS, "", "Set to domains that can make CORS requests (* for all)") @@ -46,27 +61,6 @@ func ServeCommand(cdc *wire.Codec) *cobra.Command { return cmd } -func startRESTServerFn(cdc *wire.Codec) func(cmd *cobra.Command, args []string) error { - return func(cmd *cobra.Command, args []string) error { - listenAddr := viper.GetString(flagListenAddr) - handler := createHandler(cdc) - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)). - With("module", "rest-server") - listener, err := tmserver.StartHTTPServer(listenAddr, handler, logger) - if err != nil { - return err - } - logger.Info("REST server started") - - // Wait forever and cleanup - cmn.TrapSignal(func() { - err := listener.Close() - logger.Error("Error closing listener", "err", err) - }) - return nil - } -} - func createHandler(cdc *wire.Codec) http.Handler { r := mux.NewRouter() r.HandleFunc("/version", version.RequestHandler).Methods("GET") diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go new file mode 100644 index 000000000..c1898ff81 --- /dev/null +++ b/client/lcd/test_helpers.go @@ -0,0 +1,234 @@ +package lcd + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net" + "net/http" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + crkeys "github.com/tendermint/go-crypto/keys" + tmcfg "github.com/tendermint/tendermint/config" + nm "github.com/tendermint/tendermint/node" + pvm "github.com/tendermint/tendermint/privval" + "github.com/tendermint/tendermint/proxy" + tmrpc "github.com/tendermint/tendermint/rpc/lib/server" + 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/client" + keys "github.com/cosmos/cosmos-sdk/client/keys" + gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/tests" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" +) + +// f**ing long, but unique for each test +func makePathname() string { + // get path + p, err := os.Getwd() + if err != nil { + panic(err) + } + sep := string(filepath.Separator) + return strings.Replace(p, sep, "_", -1) +} + +// GetConfig returns a config for the test cases as a singleton +func GetConfig() *tmcfg.Config { + pathname := makePathname() + config := tmcfg.ResetTestRoot(pathname) + + tmAddr, _, err := server.FreeTCPAddr() + if err != nil { + panic(err) + } + rcpAddr, _, err := server.FreeTCPAddr() + if err != nil { + panic(err) + } + + config.P2P.ListenAddress = tmAddr + config.RPC.ListenAddress = rcpAddr + return config +} + +// get the lcd test keybase +// note can't use a memdb because the request is expecting to interact with the default location +func GetKB(t *testing.T) crkeys.Keybase { + dir, err := ioutil.TempDir("", "lcd_test") + require.NoError(t, err) + viper.Set(cli.HomeFlag, dir) + keybase, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( + require.NoError(t, err) + return keybase +} + +// add an address to the store return name and password +func CreateAddr(t *testing.T, name, password string, kb crkeys.Keybase) (addr sdk.Address, seed string) { + var info crkeys.Info + var err error + info, seed, err = kb.Create(name, password, crkeys.AlgoEd25519) + require.NoError(t, err) + addr = info.PubKey.Address() + return +} + +// strt TM and the LCD in process, listening on their respective sockets +// nValidators = number of validators +// initAddrs = accounts to initialize with some steaks +func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.Address) (cleanup func(), validatorsPKs []crypto.PubKey, port string) { + + config := GetConfig() + config.Consensus.TimeoutCommit = 1000 + config.Consensus.SkipTimeoutCommit = false + config.TxIndex.IndexAllTags = true + + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewFilter(logger, log.AllowError()) + privValidatorFile := config.PrivValidatorFile() + privVal := pvm.LoadOrGenFilePV(privValidatorFile) + privVal.Reset() + db := dbm.NewMemDB() + app := gapp.NewGaiaApp(logger, db) + cdc = gapp.MakeCodec() // XXX + + genesisFile := config.GenesisFile() + genDoc, err := tmtypes.GenesisDocFromFile(genesisFile) + require.NoError(t, err) + + // add more validators + if nValidators < 1 { + panic("InitializeTestLCD must use at least one validator") + } + for i := 1; i < nValidators; i++ { + genDoc.Validators = append(genDoc.Validators, + tmtypes.GenesisValidator{ + PubKey: crypto.GenPrivKeyEd25519().PubKey(), + Power: 1, + Name: "val", + }, + ) + } + + // NOTE it's bad practice to reuse pk address for the owner address but doing in the + // test for simplicity + var appGenTxs []json.RawMessage + for _, gdValidator := range genDoc.Validators { + pk := gdValidator.PubKey + validatorsPKs = append(validatorsPKs, pk) // append keys for output + appGenTx, _, _, err := gapp.GaiaAppGenTxNF(cdc, pk, pk.Address(), "test_val1", true) + require.NoError(t, err) + appGenTxs = append(appGenTxs, appGenTx) + } + + genesisState, err := gapp.GaiaAppGenState(cdc, appGenTxs[:]) + require.NoError(t, err) + + // add some tokens to init accounts + for _, addr := range initAddrs { + accAuth := auth.NewBaseAccountWithAddress(addr) + accAuth.Coins = sdk.Coins{{"steak", 100}} + acc := gapp.NewGenesisAccount(&accAuth) + genesisState.Accounts = append(genesisState.Accounts, acc) + } + + appState, err := wire.MarshalJSONIndent(cdc, genesisState) + require.NoError(t, err) + genDoc.AppStateJSON = appState + + // LCD listen address + var listenAddr string + listenAddr, port, err = server.FreeTCPAddr() + require.NoError(t, err) + + // XXX: need to set this so LCD knows the tendermint node address! + viper.Set(client.FlagNode, config.RPC.ListenAddress) + viper.Set(client.FlagChainID, genDoc.ChainID) + + node, err := startTM(config, logger, genDoc, privVal, app) + require.NoError(t, err) + lcd, err := startLCD(logger, listenAddr, cdc) + require.NoError(t, err) + + //time.Sleep(time.Second) + //tests.WaitForHeight(2, port) + tests.WaitForStart(port) + tests.WaitForHeight(1, port) + + // for use in defer + cleanup = func() { + node.Stop() + node.Wait() + lcd.Close() + } + + return +} + +// Create & start in-process tendermint node with memdb +// and in-process abci application. +// TODO: need to clean up the WAL dir or enable it to be not persistent +func startTM(tmcfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc, privVal tmtypes.PrivValidator, app abci.Application) (*nm.Node, error) { + genDocProvider := func() (*tmtypes.GenesisDoc, error) { return genDoc, nil } + dbProvider := func(*nm.DBContext) (dbm.DB, error) { return dbm.NewMemDB(), nil } + n, err := nm.NewNode(tmcfg, + privVal, + proxy.NewLocalClientCreator(app), + genDocProvider, + dbProvider, + logger.With("module", "node")) + if err != nil { + return nil, err + } + + err = n.Start() + if err != nil { + return nil, err + } + + // wait for rpc + tests.WaitForRPC(tmcfg.RPC.ListenAddress) + + logger.Info("Tendermint running!") + return n, err +} + +// start the LCD. note this blocks! +func startLCD(logger log.Logger, listenAddr string, cdc *wire.Codec) (net.Listener, error) { + handler := createHandler(cdc) + return tmrpc.StartHTTPServer(listenAddr, handler, logger) +} + +// make a test lcd test request +func Request(t *testing.T, port, method, path string, payload []byte) (*http.Response, string) { + var res *http.Response + var err error + url := fmt.Sprintf("http://localhost:%v%v", port, path) + req, err := http.NewRequest(method, url, bytes.NewBuffer(payload)) + require.Nil(t, err) + res, err = http.DefaultClient.Do(req) + // res, err = http.Post(url, "application/json", bytes.NewBuffer(payload)) + require.Nil(t, err) + + output, err := ioutil.ReadAll(res.Body) + res.Body.Close() + require.Nil(t, err) + + return res, string(output) +} diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index 83ab3b843..28a294617 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -28,6 +28,7 @@ type sendBody struct { Password string `json:"password"` ChainID string `json:"chain_id"` Sequence int64 `json:"sequence"` + Gas int64 `json:"gas"` } var msgCdc = wire.NewCodec() @@ -86,6 +87,9 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreCont return } + // add gas to context + ctx = ctx.WithGas(m.Gas) + // sign ctx = ctx.WithSequence(m.Sequence) txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc) diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index d897c6e4f..2b26b9f01 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -26,6 +26,7 @@ type transferBody struct { Password string `json:"password"` SrcChainID string `json:"src_chain_id"` Sequence int64 `json:"sequence"` + Gas int64 `json:"gas"` } // TransferRequestHandler - http request handler to transfer coins to a address @@ -77,6 +78,9 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.Core packet := ibc.NewIBCPacket(info.PubKey.Address(), to, m.Amount, m.SrcChainID, destChainID) msg := ibc.IBCTransferMsg{packet} + // add gas to context + ctx = ctx.WithGas(m.Gas) + // sign ctx = ctx.WithSequence(m.Sequence) txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 0da3260cb..f8a2f00e5 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -80,7 +80,7 @@ func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire } } -// TODO inherit from Validator +// TODO move exist next to validator struct for maintainability type StakeValidatorOutput struct { Owner string `json:"owner"` // in bech32 PubKey string `json:"pub_key"` // in bech32 diff --git a/x/stake/client/rest/tx.go b/x/stake/client/rest/tx.go index 33fe73c69..19eca4c44 100644 --- a/x/stake/client/rest/tx.go +++ b/x/stake/client/rest/tx.go @@ -40,6 +40,7 @@ type editDelegationsBody struct { Password string `json:"password"` ChainID string `json:"chain_id"` Sequence int64 `json:"sequence"` + Gas int64 `json:"gas"` Delegate []msgDelegateInput `json:"delegate"` Unbond []msgUnbondInput `json:"unbond"` } @@ -121,6 +122,9 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx conte i++ } + // add gas to context + ctx = ctx.WithGas(m.Gas) + // sign messages signedTxs := make([][]byte, len(messages[:])) for i, msg := range messages { From 161cb474d4e224f158d7fee62cc6b76f759c43ed Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Mon, 11 Jun 2018 19:30:54 -0700 Subject: [PATCH 62/89] Account Numbers for Replay Protection with Account Pruning (#1077) * in progress * passes current tests * added tests and got working * changelog and docs * removed prints * oops * works! * issue in test_cli * number 9 number 9 number 9 * at least it does only the 9 issue now * hallelujah it works! * removed print statement * rebased * gah --- CHANGELOG.md | 1 + client/context/helpers.go | 48 +++++++-- client/context/types.go | 7 ++ client/context/viper.go | 20 ++++ client/flags.go | 18 ++-- client/lcd/lcd_test.go | 18 +++- cmd/gaia/app/app.go | 1 + cmd/gaia/app/app_test.go | 40 -------- docs/sdk/overview.rst | 10 +- examples/basecoin/app/app.go | 1 + examples/democoin/x/cool/app_test.go | 16 +-- examples/democoin/x/pow/app_test.go | 6 +- x/auth/account.go | 23 ++++- x/auth/ante.go | 17 +++- x/auth/ante_test.go | 139 +++++++++++++++++++-------- x/auth/client/cli/account.go | 2 +- x/auth/client/rest/query.go | 2 +- x/auth/mapper.go | 40 +++++++- x/auth/mock/app.go | 4 +- x/auth/mock/auth_app_test.go | 8 +- x/auth/mock/simulate_block.go | 13 +-- x/auth/stdtx.go | 36 ++++--- x/bank/app_test.go | 16 +-- x/bank/client/rest/sendtx.go | 2 + x/ibc/app_test.go | 10 +- x/ibc/client/rest/transfer.go | 2 + x/stake/app_test.go | 8 +- x/stake/client/rest/tx.go | 2 + 28 files changed, 337 insertions(+), 173 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 248509389..d1ce2cb72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ BREAKING CHANGES * [lcd] REST end-points now include gas FEATURES +* [x/auth] Added AccountNumbers to BaseAccount and StdTxs to allow for replay protection with account pruning IMPROVEMENTS * export command now writes current validator set for Tendermint diff --git a/client/context/helpers.go b/client/context/helpers.go index 880c4adb3..0229827fe 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -109,12 +109,15 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w if chainID == "" { return nil, errors.Errorf("Chain ID required but not specified") } + accnum := ctx.AccountNumber sequence := ctx.Sequence + signMsg := auth.StdSignMsg{ - ChainID: chainID, - Sequences: []int64{sequence}, - Msg: msg, - Fee: auth.NewStdFee(ctx.Gas, sdk.Coin{}), // TODO run simulate to estimate gas? + ChainID: chainID, + AccountNumbers: []int64{accnum}, + Sequences: []int64{sequence}, + Msg: msg, + Fee: auth.NewStdFee(ctx.Gas, sdk.Coin{}), // TODO run simulate to estimate gas? } keybase, err := keys.GetKeyBase() @@ -130,9 +133,10 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w return nil, err } sigs := []auth.StdSignature{{ - PubKey: pubkey, - Signature: sig, - Sequence: sequence, + PubKey: pubkey, + Signature: sig, + AccountNumber: accnum, + Sequence: sequence, }} // marshal bytes @@ -144,6 +148,10 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w // sign and build the transaction from the msg func (ctx CoreContext) EnsureSignBuildBroadcast(name string, msg sdk.Msg, cdc *wire.Codec) (res *ctypes.ResultBroadcastTxCommit, err error) { + ctx, err = EnsureAccountNumber(ctx) + if err != nil { + return nil, err + } // default to next sequence number if none provided ctx, err = EnsureSequence(ctx) if err != nil { @@ -163,13 +171,37 @@ func (ctx CoreContext) EnsureSignBuildBroadcast(name string, msg sdk.Msg, cdc *w return ctx.BroadcastTx(txBytes) } +// get the next sequence for the account address +func (ctx CoreContext) GetAccountNumber(address []byte) (int64, error) { + if ctx.Decoder == nil { + return 0, errors.New("AccountDecoder required but not provided") + } + + res, err := ctx.Query(auth.AddressStoreKey(address), ctx.AccountStore) + if err != nil { + return 0, err + } + + if len(res) == 0 { + fmt.Printf("No account found. Returning 0.\n") + return 0, err + } + + account, err := ctx.Decoder(res) + if err != nil { + panic(err) + } + + return account.GetAccountNumber(), nil +} + // get the next sequence for the account address func (ctx CoreContext) NextSequence(address []byte) (int64, error) { if ctx.Decoder == nil { return 0, errors.New("AccountDecoder required but not provided") } - res, err := ctx.Query(address, ctx.AccountStore) + res, err := ctx.Query(auth.AddressStoreKey(address), ctx.AccountStore) if err != nil { return 0, err } diff --git a/client/context/types.go b/client/context/types.go index e9c97ffbc..791ffb23a 100644 --- a/client/context/types.go +++ b/client/context/types.go @@ -14,6 +14,7 @@ type CoreContext struct { TrustNode bool NodeURI string FromAddressName string + AccountNumber int64 Sequence int64 Client rpcclient.Client Decoder auth.AccountDecoder @@ -57,6 +58,12 @@ func (c CoreContext) WithFromAddressName(fromAddressName string) CoreContext { return c } +// WithSequence - return a copy of the context with an account number +func (c CoreContext) WithAccountNumber(accnum int64) CoreContext { + c.AccountNumber = accnum + return c +} + // WithSequence - return a copy of the context with an updated sequence number func (c CoreContext) WithSequence(sequence int64) CoreContext { c.Sequence = sequence diff --git a/client/context/viper.go b/client/context/viper.go index 081c9f5c2..5f262d56f 100644 --- a/client/context/viper.go +++ b/client/context/viper.go @@ -34,6 +34,7 @@ func NewCoreContextFromViper() CoreContext { TrustNode: viper.GetBool(client.FlagTrustNode), FromAddressName: viper.GetString(client.FlagName), NodeURI: nodeURI, + AccountNumber: viper.GetInt64(client.FlagAccountNumber), Sequence: viper.GetInt64(client.FlagSequence), Client: rpc, Decoder: nil, @@ -54,6 +55,25 @@ func defaultChainID() (string, error) { return doc.ChainID, nil } +// EnsureSequence - automatically set sequence number if none provided +func EnsureAccountNumber(ctx CoreContext) (CoreContext, error) { + // Should be viper.IsSet, but this does not work - https://github.com/spf13/viper/pull/331 + if viper.GetInt64(client.FlagAccountNumber) != 0 { + return ctx, nil + } + from, err := ctx.GetFromAddress() + if err != nil { + return ctx, err + } + accnum, err := ctx.GetAccountNumber(from) + if err != nil { + return ctx, err + } + fmt.Printf("Defaulting to account number: %d\n", accnum) + ctx = ctx.WithAccountNumber(accnum) + return ctx, nil +} + // EnsureSequence - automatically set sequence number if none provided func EnsureSequence(ctx CoreContext) (CoreContext, error) { // Should be viper.IsSet, but this does not work - https://github.com/spf13/viper/pull/331 diff --git a/client/flags.go b/client/flags.go index 2d68d3146..4991b9a77 100644 --- a/client/flags.go +++ b/client/flags.go @@ -4,14 +4,15 @@ import "github.com/spf13/cobra" // nolint const ( - FlagChainID = "chain-id" - FlagNode = "node" - FlagHeight = "height" - FlagGas = "gas" - FlagTrustNode = "trust-node" - FlagName = "name" - FlagSequence = "sequence" - FlagFee = "fee" + FlagChainID = "chain-id" + FlagNode = "node" + FlagHeight = "height" + FlagGas = "gas" + FlagTrustNode = "trust-node" + FlagName = "name" + FlagAccountNumber = "account-number" + FlagSequence = "sequence" + FlagFee = "fee" ) // LineBreak can be included in a command list to provide a blank line @@ -34,6 +35,7 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command { func PostCommands(cmds ...*cobra.Command) []*cobra.Command { for _, c := range cmds { c.Flags().String(FlagName, "", "Name of private key with which to sign") + c.Flags().Int64(FlagAccountNumber, 0, "AccountNumber number to sign the tx") c.Flags().Int64(FlagSequence, 0, "Sequence number to sign the tx") c.Flags().String(FlagFee, "", "Fee to pay along with transaction") c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 48e2ad0a2..946f70bbc 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -423,12 +423,14 @@ func doSend(t *testing.T, port, seed, name, password string, addr sdk.Address) ( receiveAddrBech := sdk.MustBech32ifyAcc(receiveAddr) acc := getAccount(t, port, addr) + accnum := acc.GetAccountNumber() sequence := acc.GetSequence() // send jsonStr := []byte(fmt.Sprintf(`{ "name":"%s", - "password":"%s", + "password":"%s", + "account_number":%d, "sequence":%d, "gas": 10000, "amount":[ @@ -437,7 +439,7 @@ func doSend(t *testing.T, port, seed, name, password string, addr sdk.Address) ( "amount": 1 } ] - }`, name, password, sequence, "steak")) + }`, name, password, accnum, sequence, "steak")) res, body := Request(t, port, "POST", "/accounts/"+receiveAddrBech+"/send", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -457,12 +459,14 @@ func doIBCTransfer(t *testing.T, port, seed, name, password string, addr sdk.Add // get the account to get the sequence acc := getAccount(t, port, addr) + accnum := acc.GetAccountNumber() sequence := acc.GetSequence() // send jsonStr := []byte(fmt.Sprintf(`{ "name":"%s", "password": "%s", + "account_number":%d, "sequence": %d, "gas": 100000, "amount":[ @@ -471,7 +475,7 @@ func doIBCTransfer(t *testing.T, port, seed, name, password string, addr sdk.Add "amount": 1 } ] - }`, name, password, sequence, "steak")) + }`, name, password, accnum, sequence, "steak")) res, body := Request(t, port, "POST", "/ibc/testchain/"+receiveAddrBech+"/send", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -498,6 +502,7 @@ func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.A func doBond(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.Address) (resultTx ctypes.ResultBroadcastTxCommit) { // get the account to get the sequence acc := getAccount(t, port, delegatorAddr) + accnum := acc.GetAccountNumber() sequence := acc.GetSequence() delegatorAddrBech := sdk.MustBech32ifyAcc(delegatorAddr) @@ -507,6 +512,7 @@ func doBond(t *testing.T, port, seed, name, password string, delegatorAddr, vali jsonStr := []byte(fmt.Sprintf(`{ "name": "%s", "password": "%s", + "account_number": %d, "sequence": %d, "gas": 10000, "delegate": [ @@ -517,7 +523,7 @@ func doBond(t *testing.T, port, seed, name, password string, delegatorAddr, vali } ], "unbond": [] - }`, name, password, sequence, delegatorAddrBech, validatorAddrBech, "steak")) + }`, name, password, accnum, sequence, delegatorAddrBech, validatorAddrBech, "steak")) res, body := Request(t, port, "POST", "/stake/delegations", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -531,6 +537,7 @@ func doBond(t *testing.T, port, seed, name, password string, delegatorAddr, vali func doUnbond(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.Address) (resultTx ctypes.ResultBroadcastTxCommit) { // get the account to get the sequence acc := getAccount(t, port, delegatorAddr) + accnum := acc.GetAccountNumber() sequence := acc.GetSequence() delegatorAddrBech := sdk.MustBech32ifyAcc(delegatorAddr) @@ -540,6 +547,7 @@ func doUnbond(t *testing.T, port, seed, name, password string, delegatorAddr, va jsonStr := []byte(fmt.Sprintf(`{ "name": "%s", "password": "%s", + "account_number": %d, "sequence": %d, "gas": 10000, "delegate": [], @@ -550,7 +558,7 @@ func doUnbond(t *testing.T, port, seed, name, password string, delegatorAddr, va "shares": "30" } ] - }`, name, password, sequence, delegatorAddrBech, validatorAddrBech)) + }`, name, password, accnum, sequence, delegatorAddrBech, validatorAddrBech)) res, body := Request(t, port, "POST", "/stake/delegations", jsonStr) require.Equal(t, http.StatusOK, res.StatusCode, body) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index f06ed2be3..fb614f372 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -144,6 +144,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci // load the accounts for _, gacc := range genesisState.Accounts { acc := gacc.ToAccount() + acc.AccountNumber = app.accountMapper.GetNextAccountNumber(ctx) app.accountMapper.SetAccount(ctx, acc) } diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index f79703fef..0523c5499 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -1,21 +1,11 @@ package app import ( - "os" - "testing" - - "github.com/stretchr/testify/assert" - "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/stake" abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" ) func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { @@ -41,33 +31,3 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { return nil } - -func TestGenesis(t *testing.T) { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") - db := dbm.NewMemDB() - gapp := NewGaiaApp(logger, db) - - // 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 = setGenesis(gapp, baseAcc) - require.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, db) - ctx = gapp.BaseApp.NewContext(true, abci.Header{}) - res1 = gapp.accountMapper.GetAccount(ctx, baseAcc.Address) - assert.Equal(t, baseAcc, res1) -} diff --git a/docs/sdk/overview.rst b/docs/sdk/overview.rst index 8a1350906..0cb7e7304 100644 --- a/docs/sdk/overview.rst +++ b/docs/sdk/overview.rst @@ -232,12 +232,14 @@ a standard form: type StdSignature struct { crypto.PubKey // optional crypto.Signature - Sequence int64 + AccountNumber int64 + Sequence int64 } -It contains the signature itself, as well as the corresponding account's -sequence number. The sequence number is expected to increment every time a -message is signed by a given account. This prevents "replay attacks", where +It contains the signature itself, as well as the corresponding account's account and +sequence numbers. The sequence number is expected to increment every time a +message is signed by a given account. The account number stays the same and is assigned +when the account is first generated. These prevent "replay attacks", where the same message could be executed over and over again. The ``StdSignature`` can also optionally include the public key for verifying the diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index fdb0638b6..f654ba05e 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -146,6 +146,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") } + acc.AccountNumber = app.accountMapper.GetNextAccountNumber(ctx) app.accountMapper.SetAccount(ctx, acc) } diff --git a/examples/democoin/x/cool/app_test.go b/examples/democoin/x/cool/app_test.go index d41c8ea82..8d3f347b3 100644 --- a/examples/democoin/x/cool/app_test.go +++ b/examples/democoin/x/cool/app_test.go @@ -89,17 +89,17 @@ func TestMsgQuiz(t *testing.T) { assert.Equal(t, acc1, res1) // Set the trend, submit a really cool quiz and check for reward - mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg1, []int64{0}, true, priv1) - mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{1}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg1, []int64{0}, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{0}, []int64{1}, true, priv1) mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 69}}) - mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg2, []int64{2}, false, priv1) // result without reward + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg2, []int64{0}, []int64{2}, false, priv1) // result without reward mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 69}}) - mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{3}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{0}, []int64{3}, true, priv1) mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 138}}) - mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg2, []int64{4}, true, priv1) // reset the trend - mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{5}, false, priv1) // the same answer will nolonger do! + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg2, []int64{0}, []int64{4}, true, priv1) // reset the trend + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg1, []int64{0}, []int64{5}, false, priv1) // the same answer will nolonger do! mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"icecold", 138}}) - mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg2, []int64{6}, true, priv1) // earlier answer now relavent again + mock.SignCheckDeliver(t, mapp.BaseApp, quizMsg2, []int64{0}, []int64{6}, true, priv1) // earlier answer now relavent again mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"badvibesonly", 69}, {"icecold", 138}}) - mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg3, []int64{7}, false, priv1) // expect to fail to set the trend to something which is not cool + mock.SignCheckDeliver(t, mapp.BaseApp, setTrendMsg3, []int64{0}, []int64{7}, false, priv1) // expect to fail to set the trend to something which is not cool } diff --git a/examples/democoin/x/pow/app_test.go b/examples/democoin/x/pow/app_test.go index 0539df556..aa71fb080 100644 --- a/examples/democoin/x/pow/app_test.go +++ b/examples/democoin/x/pow/app_test.go @@ -71,13 +71,13 @@ func TestMsgMine(t *testing.T) { // Mine and check for reward mineMsg1 := GenerateMsgMine(addr1, 1, 2) - mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg1, []int64{0}, []int64{0}, true, priv1) mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 1}}) // Mine again and check for reward mineMsg2 := GenerateMsgMine(addr1, 2, 3) - mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg2, []int64{1}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg2, []int64{0}, []int64{1}, true, priv1) mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 2}}) // Mine again - should be invalid - mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg2, []int64{1}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, mineMsg2, []int64{0}, []int64{1}, false, priv1) mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"pow", 2}}) } diff --git a/x/auth/account.go b/x/auth/account.go index 0ae72a8a6..77966b8e7 100644 --- a/x/auth/account.go +++ b/x/auth/account.go @@ -17,6 +17,9 @@ type Account interface { GetPubKey() crypto.PubKey // can return nil. SetPubKey(crypto.PubKey) error + GetAccountNumber() int64 + SetAccountNumber(int64) error + GetSequence() int64 SetSequence(int64) error @@ -36,10 +39,11 @@ var _ Account = (*BaseAccount)(nil) // Extend this by embedding this in your AppAccount. // See the examples/basecoin/types/account.go for an example. type BaseAccount struct { - Address sdk.Address `json:"address"` - Coins sdk.Coins `json:"coins"` - PubKey crypto.PubKey `json:"public_key"` - Sequence int64 `json:"sequence"` + Address sdk.Address `json:"address"` + Coins sdk.Coins `json:"coins"` + PubKey crypto.PubKey `json:"public_key"` + AccountNumber int64 `json:"account_number"` + Sequence int64 `json:"sequence"` } func NewBaseAccountWithAddress(addr sdk.Address) BaseAccount { @@ -84,6 +88,17 @@ func (acc *BaseAccount) SetCoins(coins sdk.Coins) error { return nil } +// Implements Account +func (acc *BaseAccount) GetAccountNumber() int64 { + return acc.AccountNumber +} + +// Implements Account +func (acc *BaseAccount) SetAccountNumber(accNumber int64) error { + acc.AccountNumber = accNumber + return nil +} + // Implements sdk.Account. func (acc *BaseAccount) GetSequence() int64 { return acc.Sequence diff --git a/x/auth/ante.go b/x/auth/ante.go index 9663bcfe4..c50da0c32 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -14,7 +14,7 @@ const ( ) // NewAnteHandler returns an AnteHandler that checks -// and increments sequence numbers, checks signatures, +// and increments sequence numbers, checks signatures & account numbers, // and deducts fees from the first signer. func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler { @@ -46,11 +46,15 @@ func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler { true } - // Get the sign bytes (requires all sequence numbers and the fee) + // Get the sign bytes (requires all account & sequence numbers and the fee) sequences := make([]int64, len(signerAddrs)) for i := 0; i < len(signerAddrs); i++ { sequences[i] = sigs[i].Sequence } + accNums := make([]int64, len(signerAddrs)) + for i := 0; i < len(signerAddrs); i++ { + accNums[i] = sigs[i].AccountNumber + } fee := stdTx.Fee chainID := ctx.ChainID() // XXX: major hack; need to get ChainID @@ -58,7 +62,7 @@ func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler { if chainID == "" { chainID = viper.GetString("chain-id") } - signBytes := StdSignBytes(ctx.ChainID(), sequences, fee, msg) + signBytes := StdSignBytes(ctx.ChainID(), accNums, sequences, fee, msg) // Check sig and nonce and collect signer accounts. var signerAccs = make([]Account, len(signerAddrs)) @@ -117,6 +121,13 @@ func processSig( return nil, sdk.ErrUnknownAddress(addr.String()).Result() } + // Check account number. + accnum := acc.GetAccountNumber() + if accnum != sig.AccountNumber { + return nil, sdk.ErrInvalidSequence( + fmt.Sprintf("Invalid account number. Got %d, expected %d", sig.AccountNumber, accnum)).Result() + } + // Check and increment sequence number. seq := acc.GetSequence() if seq != sig.Sequence { diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index b7f22e5d5..aff80cb59 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -52,15 +52,15 @@ func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, code), result.Code) } -func newTestTx(ctx sdk.Context, msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, fee StdFee) sdk.Tx { - signBytes := StdSignBytes(ctx.ChainID(), seqs, fee, msg) - return newTestTxWithSignBytes(msg, privs, seqs, fee, signBytes) +func newTestTx(ctx sdk.Context, msg sdk.Msg, privs []crypto.PrivKey, accNums []int64, seqs []int64, fee StdFee) sdk.Tx { + signBytes := StdSignBytes(ctx.ChainID(), accNums, seqs, fee, msg) + return newTestTxWithSignBytes(msg, privs, accNums, seqs, fee, signBytes) } -func newTestTxWithSignBytes(msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, fee StdFee, signBytes []byte) sdk.Tx { +func newTestTxWithSignBytes(msg sdk.Msg, privs []crypto.PrivKey, accNums []int64, seqs []int64, fee StdFee, signBytes []byte) sdk.Tx { sigs := make([]StdSignature, len(privs)) for i, priv := range privs { - sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: priv.Sign(signBytes), Sequence: seqs[i]} + sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: priv.Sign(signBytes), AccountNumber: accNums[i], Sequence: seqs[i]} } tx := NewStdTx(msg, fee, sigs) return tx @@ -87,18 +87,18 @@ func TestAnteHandlerSigErrors(t *testing.T) { fee := newStdFee() // test no signatures - privs, seqs := []crypto.PrivKey{}, []int64{} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accNums, seqs := []crypto.PrivKey{}, []int64{}, []int64{} + tx = newTestTx(ctx, msg, privs, accNums, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnauthorized) // test num sigs dont match GetSigners - privs, seqs = []crypto.PrivKey{priv1}, []int64{0} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accNums, seqs = []crypto.PrivKey{priv1}, []int64{0}, []int64{0} + tx = newTestTx(ctx, msg, privs, accNums, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnauthorized) // test an unrecognized account - privs, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 0} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accNums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{0, 0} + tx = newTestTx(ctx, msg, privs, accNums, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnknownAddress) // save the first account, but second is still unrecognized @@ -108,6 +108,61 @@ func TestAnteHandlerSigErrors(t *testing.T) { checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnknownAddress) } +// Test logic around account number checking with one signer and many signers. +func TestAnteHandlerAccountNumbers(t *testing.T) { + // setup + ms, capKey, capKey2 := setupMultiStore() + cdc := wire.NewCodec() + RegisterBaseAccount(cdc) + mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + feeCollector := NewFeeCollectionKeeper(cdc, capKey2) + anteHandler := NewAnteHandler(mapper, feeCollector) + ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) + + // keys and addresses + priv1, addr1 := privAndAddr() + priv2, addr2 := privAndAddr() + + // set the accounts + acc1 := mapper.NewAccountWithAddress(ctx, addr1) + acc1.SetCoins(newCoins()) + mapper.SetAccount(ctx, acc1) + acc2 := mapper.NewAccountWithAddress(ctx, addr2) + acc2.SetCoins(newCoins()) + mapper.SetAccount(ctx, acc2) + + // msg and signatures + var tx sdk.Tx + msg := newTestMsg(addr1) + fee := newStdFee() + + // test good tx from one signer + privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) + checkValidTx(t, anteHandler, ctx, tx) + + // new tx from wrong account number + seqs = []int64{1} + tx = newTestTx(ctx, msg, privs, []int64{1}, seqs, fee) + checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidSequence) + + // from correct account number + seqs = []int64{1} + tx = newTestTx(ctx, msg, privs, []int64{0}, seqs, fee) + checkValidTx(t, anteHandler, ctx, tx) + + // new tx with another signer and incorrect account numbers + msg = newTestMsg(addr1, addr2) + privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{1, 0}, []int64{2, 0} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) + checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidSequence) + + // correct account numbers + privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{2, 0} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) + checkValidTx(t, anteHandler, ctx, tx) +} + // Test logic around sequence checking with one signer and many signers. func TestAnteHandlerSequences(t *testing.T) { // setup @@ -137,8 +192,8 @@ func TestAnteHandlerSequences(t *testing.T) { fee := newStdFee() // test good tx from one signer - privs, seqs := []crypto.PrivKey{priv1}, []int64{0} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkValidTx(t, anteHandler, ctx, tx) // test sending it again fails (replay protection) @@ -146,13 +201,13 @@ func TestAnteHandlerSequences(t *testing.T) { // fix sequence, should pass seqs = []int64{1} - tx = newTestTx(ctx, msg, privs, seqs, fee) + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkValidTx(t, anteHandler, ctx, tx) // new tx with another signer and correct sequences msg = newTestMsg(addr1, addr2) - privs, seqs = []crypto.PrivKey{priv1, priv2}, []int64{2, 0} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{2, 0} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkValidTx(t, anteHandler, ctx, tx) // replay fails @@ -160,18 +215,18 @@ func TestAnteHandlerSequences(t *testing.T) { // tx from just second signer with incorrect sequence fails msg = newTestMsg(addr2) - privs, seqs = []crypto.PrivKey{priv2}, []int64{0} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accnums, seqs = []crypto.PrivKey{priv2}, []int64{1}, []int64{0} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidSequence) // fix the sequence and it passes - tx = newTestTx(ctx, msg, []crypto.PrivKey{priv2}, []int64{1}, fee) + tx = newTestTx(ctx, msg, []crypto.PrivKey{priv2}, []int64{1}, []int64{1}, fee) checkValidTx(t, anteHandler, ctx, tx) // another tx from both of them that passes msg = newTestMsg(addr1, addr2) - privs, seqs = []crypto.PrivKey{priv1, priv2}, []int64{3, 2} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{3, 2} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkValidTx(t, anteHandler, ctx, tx) } @@ -196,13 +251,13 @@ func TestAnteHandlerFees(t *testing.T) { // msg and signatures var tx sdk.Tx msg := newTestMsg(addr1) - privs, seqs := []crypto.PrivKey{priv1}, []int64{0} + privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0} fee := NewStdFee(100, sdk.Coin{"atom", 150}, ) // signer does not have enough funds to pay the fee - tx = newTestTx(ctx, msg, privs, seqs, fee) + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInsufficientFunds) acc1.SetCoins(sdk.Coins{{"atom", 149}}) @@ -249,8 +304,8 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { fee3.Amount[0].Amount += 100 // test good tx and signBytes - privs, seqs := []crypto.PrivKey{priv1}, []int64{0} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkValidTx(t, anteHandler, ctx, tx) chainID := ctx.ChainID() @@ -259,37 +314,39 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { cases := []struct { chainID string + accnums []int64 seqs []int64 fee StdFee msg sdk.Msg code sdk.CodeType }{ - {chainID2, []int64{1}, fee, msg, codeUnauth}, // test wrong chain_id - {chainID, []int64{2}, fee, msg, codeUnauth}, // test wrong seqs - {chainID, []int64{1, 2}, fee, msg, codeUnauth}, // test wrong seqs - {chainID, []int64{1}, fee, newTestMsg(addr2), codeUnauth}, // test wrong msg - {chainID, []int64{1}, fee2, newTestMsg(addr2), codeUnauth}, // test wrong fee - {chainID, []int64{1}, fee3, newTestMsg(addr2), codeUnauth}, // test wrong fee + {chainID2, []int64{0}, []int64{1}, fee, msg, codeUnauth}, // test wrong chain_id + {chainID, []int64{0}, []int64{2}, fee, msg, codeUnauth}, // test wrong seqs + {chainID, []int64{0}, []int64{1, 2}, fee, msg, codeUnauth}, // test wrong seqs + {chainID, []int64{1}, []int64{1}, fee, msg, codeUnauth}, // test wrong accnum + {chainID, []int64{0}, []int64{1}, fee, newTestMsg(addr2), codeUnauth}, // test wrong msg + {chainID, []int64{0}, []int64{1}, fee2, msg, codeUnauth}, // test wrong fee + {chainID, []int64{0}, []int64{1}, fee3, msg, codeUnauth}, // test wrong fee } privs, seqs = []crypto.PrivKey{priv1}, []int64{1} for _, cs := range cases { tx := newTestTxWithSignBytes( - msg, privs, seqs, fee, - StdSignBytes(cs.chainID, cs.seqs, cs.fee, cs.msg), + msg, privs, accnums, seqs, fee, + StdSignBytes(cs.chainID, cs.accnums, cs.seqs, cs.fee, cs.msg), ) checkInvalidTx(t, anteHandler, ctx, tx, cs.code) } // test wrong signer if public key exist - privs, seqs = []crypto.PrivKey{priv2}, []int64{1} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accnums, seqs = []crypto.PrivKey{priv2}, []int64{0}, []int64{1} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnauthorized) // test wrong signer if public doesn't exist msg = newTestMsg(addr2) - privs, seqs = []crypto.PrivKey{priv1}, []int64{0} - tx = newTestTx(ctx, msg, privs, seqs, fee) + privs, accnums, seqs = []crypto.PrivKey{priv1}, []int64{1}, []int64{0} + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey) } @@ -320,9 +377,9 @@ func TestAnteHandlerSetPubKey(t *testing.T) { // test good tx and set public key msg := newTestMsg(addr1) - privs, seqs := []crypto.PrivKey{priv1}, []int64{0} + privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0} fee := newStdFee() - tx = newTestTx(ctx, msg, privs, seqs, fee) + tx = newTestTx(ctx, msg, privs, accnums, seqs, fee) checkValidTx(t, anteHandler, ctx, tx) acc1 = mapper.GetAccount(ctx, addr1) @@ -330,7 +387,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { // test public key not found msg = newTestMsg(addr2) - tx = newTestTx(ctx, msg, privs, seqs, fee) + tx = newTestTx(ctx, msg, privs, []int64{1}, seqs, fee) sigs := tx.(StdTx).GetSignatures() sigs[0].PubKey = nil checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey) @@ -339,7 +396,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { assert.Nil(t, acc2.GetPubKey()) // test invalid signature and public key - tx = newTestTx(ctx, msg, privs, seqs, fee) + tx = newTestTx(ctx, msg, privs, []int64{1}, seqs, fee) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey) acc2 = mapper.GetAccount(ctx, addr2) diff --git a/x/auth/client/cli/account.go b/x/auth/client/cli/account.go index e82b07414..a3265a78c 100644 --- a/x/auth/client/cli/account.go +++ b/x/auth/client/cli/account.go @@ -47,7 +47,7 @@ func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecode // perform query ctx := context.NewCoreContextFromViper() - res, err := ctx.Query(key, storeName) + res, err := ctx.Query(auth.AddressStoreKey(key), storeName) if err != nil { return err } diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index bcae59c20..9ccbe8e14 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -34,7 +34,7 @@ func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder aut return } - res, err := ctx.Query(addr, storeName) + res, err := ctx.Query(auth.AddressStoreKey(addr), storeName) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(fmt.Sprintf("Could't query account. Error: %s", err.Error()))) diff --git a/x/auth/mapper.go b/x/auth/mapper.go index cdab2480e..b4364f768 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -9,6 +9,8 @@ import ( crypto "github.com/tendermint/go-crypto" ) +var globalAccountNumberKey = []byte("globalAccountNumber") + // This AccountMapper encodes/decodes accounts using the // go-amino (binary) encoding/decoding library. type AccountMapper struct { @@ -38,13 +40,25 @@ func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto Account) AccountM func (am AccountMapper) NewAccountWithAddress(ctx sdk.Context, addr sdk.Address) Account { acc := am.clonePrototype() acc.SetAddress(addr) + acc.SetAccountNumber(am.GetNextAccountNumber(ctx)) return acc } +// New Account +func (am AccountMapper) NewAccount(ctx sdk.Context, acc Account) Account { + acc.SetAccountNumber(am.GetNextAccountNumber(ctx)) + return acc +} + +// Turn an address to key used to get it from the account store +func AddressStoreKey(addr sdk.Address) []byte { + return append([]byte("account:"), addr.Bytes()...) +} + // Implements sdk.AccountMapper. func (am AccountMapper) GetAccount(ctx sdk.Context, addr sdk.Address) Account { store := ctx.KVStore(am.key) - bz := store.Get(addr) + bz := store.Get(AddressStoreKey(addr)) if bz == nil { return nil } @@ -57,13 +71,13 @@ func (am AccountMapper) SetAccount(ctx sdk.Context, acc Account) { addr := acc.GetAddress() store := ctx.KVStore(am.key) bz := am.encodeAccount(acc) - store.Set(addr, bz) + store.Set(AddressStoreKey(addr), bz) } // Implements sdk.AccountMapper. func (am AccountMapper) IterateAccounts(ctx sdk.Context, process func(Account) (stop bool)) { store := ctx.KVStore(am.key) - iter := store.Iterator(nil, nil) + iter := sdk.KVStorePrefixIterator(store, []byte("account:")) for { if !iter.Valid() { return @@ -116,6 +130,26 @@ func (am AccountMapper) setSequence(ctx sdk.Context, addr sdk.Address, newSequen return nil } +// Returns and increments the global account number counter +func (am AccountMapper) GetNextAccountNumber(ctx sdk.Context) int64 { + var accNumber int64 + store := ctx.KVStore(am.key) + bz := store.Get(globalAccountNumberKey) + if bz == nil { + accNumber = 0 + } else { + err := am.cdc.UnmarshalBinary(bz, &accNumber) + if err != nil { + panic(err) + } + } + + bz = am.cdc.MustMarshalBinary(accNumber + 1) + store.Set(globalAccountNumberKey, bz) + + return accNumber +} + //---------------------------------------- // misc. diff --git a/x/auth/mock/app.go b/x/auth/mock/app.go index fcd130b44..953008807 100644 --- a/x/auth/mock/app.go +++ b/x/auth/mock/app.go @@ -78,7 +78,9 @@ func (app *App) CompleteSetup(t *testing.T, newKeys []*sdk.KVStoreKey) { func (app *App) InitChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain { // load the accounts - for _, acc := range app.GenesisAccounts { + for _, genacc := range app.GenesisAccounts { + acc := app.AccountMapper.NewAccountWithAddress(ctx, genacc.GetAddress()) + acc.SetCoins(genacc.GetCoins()) app.AccountMapper.SetAccount(ctx, acc) } diff --git a/x/auth/mock/auth_app_test.go b/x/auth/mock/auth_app_test.go index 716037d60..bb4d7007b 100644 --- a/x/auth/mock/auth_app_test.go +++ b/x/auth/mock/auth_app_test.go @@ -61,7 +61,7 @@ func TestMsgChangePubKey(t *testing.T) { assert.Equal(t, acc1, res1.(*auth.BaseAccount)) // Run a CheckDeliver - SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) + SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, []int64{0}, true, priv1) // Check balances CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 67}}) @@ -77,19 +77,19 @@ func TestMsgChangePubKey(t *testing.T) { acc2 := mapp.AccountMapper.GetAccount(ctxDeliver, addr1) // send a MsgChangePubKey - SignCheckDeliver(t, mapp.BaseApp, changePubKeyMsg, []int64{1}, true, priv1) + SignCheckDeliver(t, mapp.BaseApp, changePubKeyMsg, []int64{0}, []int64{1}, true, priv1) acc2 = mapp.AccountMapper.GetAccount(ctxDeliver, addr1) assert.True(t, priv2.PubKey().Equals(acc2.GetPubKey())) // signing a SendMsg with the old privKey should be an auth error mapp.BeginBlock(abci.RequestBeginBlock{}) - tx := GenTx(sendMsg1, []int64{2}, priv1) + tx := GenTx(sendMsg1, []int64{0}, []int64{2}, priv1) res := mapp.Deliver(tx) assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) // resigning the tx with the new correct priv key should work - SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{2}, true, priv2) + SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, []int64{2}, true, priv2) // Check balances CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 57}}) diff --git a/x/auth/mock/simulate_block.go b/x/auth/mock/simulate_block.go index 72ec8411f..b8e9e94f8 100644 --- a/x/auth/mock/simulate_block.go +++ b/x/auth/mock/simulate_block.go @@ -33,7 +33,7 @@ func CheckBalance(t *testing.T, app *App, addr sdk.Address, exp sdk.Coins) { } // generate a signed transaction -func GenTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { +func GenTx(msg sdk.Msg, accnums []int64, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { // make the transaction free fee := auth.StdFee{ @@ -44,19 +44,20 @@ func GenTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { sigs := make([]auth.StdSignature, len(priv)) for i, p := range priv { sigs[i] = auth.StdSignature{ - PubKey: p.PubKey(), - Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), - Sequence: seq[i], + PubKey: p.PubKey(), + Signature: p.Sign(auth.StdSignBytes(chainID, accnums, seq, fee, msg)), + AccountNumber: accnums[i], + Sequence: seq[i], } } return auth.NewStdTx(msg, fee, sigs) } // simulate a block -func SignCheckDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { +func SignCheckDeliver(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, accnums []int64, seq []int64, expPass bool, priv ...crypto.PrivKeyEd25519) { // Sign the tx - tx := GenTx(msg, seq, priv...) + tx := GenTx(msg, accnums, seq, priv...) // Run a Check res := app.Check(tx) diff --git a/x/auth/stdtx.go b/x/auth/stdtx.go index e08f77ee4..5c43a3717 100644 --- a/x/auth/stdtx.go +++ b/x/auth/stdtx.go @@ -85,21 +85,23 @@ func (fee StdFee) Bytes() []byte { // and the Sequence numbers for each signature (prevent // inchain replay and enforce tx ordering per account). type StdSignDoc struct { - ChainID string `json:"chain_id"` - Sequences []int64 `json:"sequences"` - FeeBytes json.RawMessage `json:"fee_bytes"` - MsgBytes json.RawMessage `json:"msg_bytes"` - AltBytes json.RawMessage `json:"alt_bytes"` + ChainID string `json:"chain_id"` + AccountNumbers []int64 `json:"account_numbers"` + Sequences []int64 `json:"sequences"` + FeeBytes []byte `json:"fee_bytes"` + MsgBytes []byte `json:"msg_bytes"` + AltBytes []byte `json:"alt_bytes"` } // StdSignBytes returns the bytes to sign for a transaction. // TODO: change the API to just take a chainID and StdTx ? -func StdSignBytes(chainID string, sequences []int64, fee StdFee, msg sdk.Msg) []byte { - bz, err := msgCdc.MarshalJSON(StdSignDoc{ - ChainID: chainID, - Sequences: sequences, - FeeBytes: json.RawMessage(fee.Bytes()), - MsgBytes: json.RawMessage(msg.GetSignBytes()), +func StdSignBytes(chainID string, accnums []int64, sequences []int64, fee StdFee, msg sdk.Msg) []byte { + bz, err := json.Marshal(StdSignDoc{ + ChainID: chainID, + AccountNumbers: accnums, + Sequences: sequences, + FeeBytes: fee.Bytes(), + MsgBytes: msg.GetSignBytes(), }) if err != nil { panic(err) @@ -111,21 +113,23 @@ func StdSignBytes(chainID string, sequences []int64, fee StdFee, msg sdk.Msg) [] // a Msg with the other requirements for a StdSignDoc before // it is signed. For use in the CLI. type StdSignMsg struct { - ChainID string - Sequences []int64 - Fee StdFee - Msg sdk.Msg + ChainID string + AccountNumbers []int64 + Sequences []int64 + Fee StdFee + Msg sdk.Msg // XXX: Alt } // get message bytes func (msg StdSignMsg) Bytes() []byte { - return StdSignBytes(msg.ChainID, msg.Sequences, msg.Fee, msg.Msg) + return StdSignBytes(msg.ChainID, msg.AccountNumbers, msg.Sequences, msg.Fee, msg.Msg) } // Standard Signature type StdSignature struct { crypto.PubKey `json:"pub_key"` // optional crypto.Signature `json:"signature"` + AccountNumber int64 `json:"account_number"` Sequence int64 `json:"sequence"` } diff --git a/x/bank/app_test.go b/x/bank/app_test.go index 21d7d03a0..d0c112b3d 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -107,25 +107,25 @@ func TestMsgSendWithAccounts(t *testing.T) { assert.Equal(t, acc, res1.(*auth.BaseAccount)) // Run a CheckDeliver - mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 57}}) mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) // Delivering again should cause replay error - mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, []int64{0}, false, priv1) // bumping the txnonce number without resigning should be an auth error mapp.BeginBlock(abci.RequestBeginBlock{}) - tx := mock.GenTx(sendMsg1, []int64{0}, priv1) + tx := mock.GenTx(sendMsg1, []int64{0}, []int64{0}, priv1) tx.Signatures[0].Sequence = 1 res := mapp.Deliver(tx) assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeUnauthorized), res.Code, res.Log) // resigning the tx with the bumped sequence should work - mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{1}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, []int64{1}, true, priv1) } func TestMsgSendMultipleOut(t *testing.T) { @@ -145,7 +145,7 @@ func TestMsgSendMultipleOut(t *testing.T) { mock.SetGenesis(mapp, accs) // Simulate a Block - mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg2, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg2, []int64{0}, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) @@ -173,7 +173,7 @@ func TestSengMsgMultipleInOut(t *testing.T) { mock.SetGenesis(mapp, accs) // CheckDeliver - mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg3, []int64{0, 0}, true, priv1, priv4) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg3, []int64{0, 2}, []int64{0, 0}, true, priv1, priv4) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) @@ -194,14 +194,14 @@ func TestMsgSendDependent(t *testing.T) { mock.SetGenesis(mapp, accs) // CheckDeliver - mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg1, []int64{0}, []int64{0}, true, priv1) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 32}}) mock.CheckBalance(t, mapp, addr2, sdk.Coins{{"foocoin", 10}}) // Simulate a Block - mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg4, []int64{0}, true, priv2) + mock.SignCheckDeliver(t, mapp.BaseApp, sendMsg4, []int64{1}, []int64{0}, true, priv2) // Check balances mock.CheckBalance(t, mapp, addr1, sdk.Coins{{"foocoin", 42}}) diff --git a/x/bank/client/rest/sendtx.go b/x/bank/client/rest/sendtx.go index 28a294617..2639d2788 100644 --- a/x/bank/client/rest/sendtx.go +++ b/x/bank/client/rest/sendtx.go @@ -27,6 +27,7 @@ type sendBody struct { LocalAccountName string `json:"name"` Password string `json:"password"` ChainID string `json:"chain_id"` + AccountNumber int64 `json:"account_number"` Sequence int64 `json:"sequence"` Gas int64 `json:"gas"` } @@ -91,6 +92,7 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreCont ctx = ctx.WithGas(m.Gas) // sign + ctx = ctx.WithAccountNumber(m.AccountNumber) ctx = ctx.WithSequence(m.Sequence) txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc) if err != nil { diff --git a/x/ibc/app_test.go b/x/ibc/app_test.go index 9e4b4bf56..90d426882 100644 --- a/x/ibc/app_test.go +++ b/x/ibc/app_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/cosmos/cosmos-sdk/x/auth/mock" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/mock" "github.com/cosmos/cosmos-sdk/x/bank" abci "github.com/tendermint/abci/types" @@ -70,10 +70,10 @@ func TestIBCMsgs(t *testing.T) { Sequence: 0, } - mock.SignCheckDeliver(t, mapp.BaseApp, transferMsg, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, transferMsg, []int64{0},[]int64{0}, true, priv1) mock.CheckBalance(t, mapp, addr1, emptyCoins) - mock.SignCheckDeliver(t, mapp.BaseApp, transferMsg, []int64{1}, false, priv1) - mock.SignCheckDeliver(t, mapp.BaseApp, receiveMsg, []int64{2}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, transferMsg, []int64{0}, []int64{1}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, receiveMsg, []int64{0}, []int64{2}, true, priv1) mock.CheckBalance(t, mapp, addr1, coins) - mock.SignCheckDeliver(t, mapp.BaseApp, receiveMsg, []int64{3}, false, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, receiveMsg, []int64{0}, []int64{3}, false, priv1) } diff --git a/x/ibc/client/rest/transfer.go b/x/ibc/client/rest/transfer.go index 2b26b9f01..b77a6f5eb 100644 --- a/x/ibc/client/rest/transfer.go +++ b/x/ibc/client/rest/transfer.go @@ -25,6 +25,7 @@ type transferBody struct { LocalAccountName string `json:"name"` Password string `json:"password"` SrcChainID string `json:"src_chain_id"` + AccountNumber int64 `json:"account_number"` Sequence int64 `json:"sequence"` Gas int64 `json:"gas"` } @@ -82,6 +83,7 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.Core ctx = ctx.WithGas(m.Gas) // sign + ctx = ctx.WithAccountNumber(m.AccountNumber) ctx = ctx.WithSequence(m.Sequence) txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc) if err != nil { diff --git a/x/stake/app_test.go b/x/stake/app_test.go index 8e20633a0..940d4db2b 100644 --- a/x/stake/app_test.go +++ b/x/stake/app_test.go @@ -117,7 +117,7 @@ func TestStakeMsgs(t *testing.T) { createValidatorMsg := NewMsgCreateValidator( addr1, priv1.PubKey(), bondCoin, description, ) - mock.SignCheckDeliver(t, mapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, createValidatorMsg, []int64{0}, []int64{0}, true, priv1) mock.CheckBalance(t, mapp, addr1, sdk.Coins{genCoin.Minus(bondCoin)}) mapp.BeginBlock(abci.RequestBeginBlock{}) @@ -134,7 +134,7 @@ func TestStakeMsgs(t *testing.T) { description = NewDescription("bar_moniker", "", "", "") editValidatorMsg := NewMsgEditValidator(addr1, description) - mock.SignCheckDeliver(t, mapp.BaseApp, editValidatorMsg, []int64{1}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, editValidatorMsg, []int64{0}, []int64{1}, true, priv1) validator = checkValidator(t, mapp, keeper, addr1, true) require.Equal(t, description, validator.Description) @@ -143,7 +143,7 @@ func TestStakeMsgs(t *testing.T) { mock.CheckBalance(t, mapp, addr2, sdk.Coins{genCoin}) delegateMsg := NewMsgDelegate(addr2, addr1, bondCoin) - mock.SignCheckDeliver(t, mapp.BaseApp, delegateMsg, []int64{0}, true, priv2) + mock.SignCheckDeliver(t, mapp.BaseApp, delegateMsg, []int64{1}, []int64{0}, true, priv2) mock.CheckBalance(t, mapp, addr2, sdk.Coins{genCoin.Minus(bondCoin)}) checkDelegation(t, mapp, keeper, addr2, addr1, true, sdk.NewRat(10)) @@ -151,7 +151,7 @@ func TestStakeMsgs(t *testing.T) { // Unbond unbondMsg := NewMsgUnbond(addr2, addr1, "MAX") - mock.SignCheckDeliver(t, mapp.BaseApp, unbondMsg, []int64{1}, true, priv2) + mock.SignCheckDeliver(t, mapp.BaseApp, unbondMsg, []int64{1}, []int64{1}, true, priv2) mock.CheckBalance(t, mapp, addr2, sdk.Coins{genCoin}) checkDelegation(t, mapp, keeper, addr2, addr1, false, sdk.Rat{}) } diff --git a/x/stake/client/rest/tx.go b/x/stake/client/rest/tx.go index 19eca4c44..77a6540ee 100644 --- a/x/stake/client/rest/tx.go +++ b/x/stake/client/rest/tx.go @@ -39,6 +39,7 @@ type editDelegationsBody struct { LocalAccountName string `json:"name"` Password string `json:"password"` ChainID string `json:"chain_id"` + AccountNumber int64 `json:"account_number"` Sequence int64 `json:"sequence"` Gas int64 `json:"gas"` Delegate []msgDelegateInput `json:"delegate"` @@ -129,6 +130,7 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx conte signedTxs := make([][]byte, len(messages[:])) for i, msg := range messages { // increment sequence for each message + ctx = ctx.WithAccountNumber(m.AccountNumber) ctx = ctx.WithSequence(m.Sequence) m.Sequence++ From 5bf58ee444a6bd3ff8a4254bca322a9e03d7af15 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 12 Jun 2018 09:47:59 +0200 Subject: [PATCH 63/89] Merge PR #1210: Fix testcases (another fast-forward merge issue) --- Gopkg.lock | 14 +++++++------- x/auth/mock/simulate_block.go | 4 ++-- x/slashing/app_test.go | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 612e8e3b3..07a3c6d5b 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -197,8 +197,8 @@ ".", "mem" ] - revision = "63644898a8da0bc22138abf860edaf5277b6102e" - version = "v1.1.0" + revision = "787d034dfe70e44075ccc060d346146ef53270ad" + version = "v1.1.1" [[projects]] name = "github.com/spf13/cast" @@ -236,8 +236,8 @@ "assert", "require" ] - revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" - version = "v1.2.1" + revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" + version = "v1.2.2" [[projects]] branch = "master" @@ -366,7 +366,7 @@ "merkle", "merkle/tmhash" ] - revision = "640af0205d98d1f45fb2f912f9c35c8bf816adc9" + revision = "0c98d10b4ffbd87978d79c160e835b3d3df241ec" [[projects]] branch = "master" @@ -396,13 +396,13 @@ "internal/timeseries", "trace" ] - revision = "1e491301e022f8f977054da4c2d852decd59571f" + revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" + revision = "bff228c7b664c5fce602223a05fb708fd8654986" [[projects]] name = "golang.org/x/text" diff --git a/x/auth/mock/simulate_block.go b/x/auth/mock/simulate_block.go index e93ac3cea..7a77e0f09 100644 --- a/x/auth/mock/simulate_block.go +++ b/x/auth/mock/simulate_block.go @@ -54,8 +54,8 @@ func GenTx(msg sdk.Msg, accnums []int64, seq []int64, priv ...crypto.PrivKeyEd25 } // check a transaction result -func SignCheck(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.Result { - tx := GenTx(msg, seq, priv...) +func SignCheck(t *testing.T, app *baseapp.BaseApp, msg sdk.Msg, accnums []int64, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.Result { + tx := GenTx(msg, accnums, seq, priv...) res := app.Check(tx) return res } diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index 3d33f53e7..2a99795c6 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -92,7 +92,7 @@ func TestSlashingMsgs(t *testing.T) { createValidatorMsg := stake.NewMsgCreateValidator( addr1, priv1.PubKey(), bondCoin, description, ) - mock.SignCheckDeliver(t, mapp.BaseApp, createValidatorMsg, []int64{0}, true, priv1) + mock.SignCheckDeliver(t, mapp.BaseApp, createValidatorMsg, []int64{0}, []int64{0}, true, priv1) mock.CheckBalance(t, mapp, addr1, sdk.Coins{genCoin.Minus(bondCoin)}) mapp.BeginBlock(abci.RequestBeginBlock{}) @@ -106,6 +106,6 @@ func TestSlashingMsgs(t *testing.T) { checkValidatorSigningInfo(t, mapp, keeper, addr1, false) // unrevoke should fail with unknown validator - res := mock.SignCheck(t, mapp.BaseApp, unrevokeMsg, []int64{1}, priv1) + res := mock.SignCheck(t, mapp.BaseApp, unrevokeMsg, []int64{0}, []int64{1}, priv1) require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeInvalidValidator), res.Code) } From 3b9cb4949782f21dc28eedd6858aaaf2d2e60ed1 Mon Sep 17 00:00:00 2001 From: Peng Zhong <172531+nylira@users.noreply.github.com> Date: Tue, 12 Jun 2018 13:50:49 +0800 Subject: [PATCH 64/89] readme improvements add link to official faucet, remove sequence from cmds readme improvements wording improvements and simplifications add link to cosmos explorer remove instances of candidate add apostrophe small fixes improve the installing software section fixes based on feedback add note about querying an empty account remove panic note update introduction add full cp path for copying genesis.json update moniker warning remove redundant sections add error message when querying empty account don't need a link to golang.org link to sections, better section names fix section link reorganize sections add h3s remove & symbol add whitespace update h3 to h2 add note about explorer not connecting to every node --- cmd/gaia/testnets/README.md | 247 +++++++++++++++--------------------- 1 file changed, 99 insertions(+), 148 deletions(-) diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md index 42484c599..8ea2d43fc 100644 --- a/cmd/gaia/testnets/README.md +++ b/cmd/gaia/testnets/README.md @@ -1,228 +1,185 @@ -# Connect to a Testnet +# Connect to the `gaia-6001` Testnet -This document explains how to connect to the Testnet of a [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk/) based blockchain. It can be used to connect to the latest Testnet for the Cosmos Hub. - -NOTE: We are aware this documentation is sub-par and are actively working to -improve both the tooling and the documentation to make this as painless as +Note: We are aware this documentation is sub-par. We are working to +improve the tooling and the documentation to make this process as painless as possible. In the meantime, join the -[chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org) for technical support. Thanks very -much for your patience :) +[Validator Chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org) +for technical support. Thanks very much for your patience. :) -## Software Setup (Manual Installation) +## Setting Up a New Node -Follow these instructions to install the Cosmos-SDK and connect to the latest Testnet. This instructions work for both a local machine and a VM in a cloud server. +These instructions are for setting up a brand new full node from scratch. If you ran a full node on a previous testnet, please skip to [Upgrading From Previous Testnet](#upgrading-from-previous-testnet). -If you want to run a non-validator full-node, installing the SDK on a Cloud server is a good option. However, if you are want to become a validator for the Hub's `mainnet` you should look at more complex setups, including [Sentry Node Architecture](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#how-can-validators-protect-themselves-from-denial-of-service-attacks), to protect your node from DDOS and ensure high-availability (see the [technical requirements](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#technical-requirements)). You can find more information on validators in our [website](https://cosmos.network/validators), in the [Validator FAQ](https://cosmos.network/resources/validator-faq) and in the [Validator Chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org). +### Install Go -### Install [Go](https://golang.org/) +Install `go` by following the [official docs](https://golang.org/doc/install). +**Go 1.10+** is required for the Cosmos SDK. -Install `go` following the [instructions](https://golang.org/doc/install) in the official golang website. -You will require **Go 1.10+** for this tutorial. +### Install Cosmos SDK -#### Set GOPATH - -First, you will need to set up your `GOPATH`. Make sure that the location `$HOME` is something like `/Users/`, you can corroborate it by typing `echo $HOME` in your terminal. - -Go to `$HOME` with the command `cd $HOME` and open the the hidden file `.bashrc` with a code editor and paste the following lines \(or `.bash_profile` if your're using OS X\). +Next, let's install the testnet's version of the Cosmos SDK. ``` -export GOPATH=$HOME/go -export PATH=$PATH:$GOROOT/bin:$GOPATH/bin +go get github.com/cosmos/cosmos-sdk +cd $GOPATH/src/github.com/cosmos/cosmos-sdk && git checkout v0.18.0 +make get_tools && make get_vendor_deps && make install ``` -Save and restart the terminal. - -_Note_: If you can't see the hidden file, use the shortcut `Command + Shift + .` in Finder. - - -### Install [GNU Wget](https://www.gnu.org/software/wget/) - -**MacOS** - -``` -brew install wget -``` - -**Linux** - -``` -sudo apt-get install wget -``` - -Note: You can check other available options for downloading `wget` [here](https://www.gnu.org/software/wget/faq.html#download). - -### Install Gaia - -Now we can fetch the correct versions of each dependency by running: - -``` -mkdir -p $GOPATH/src/github.com/cosmos/cosmos-sdk -git clone https://github.com/cosmos/cosmos-sdk.git -git checkout v0.18.0 -make get_tools // run $ make update_tools if already installed -make get_vendor_deps -make install -``` - -This will install the `gaiad` and `gaiacli` binaries. Verify that everything is OK by running: +That will install the `gaiad` and `gaiacli` binaries. Verify that everything is OK: ``` gaiad version -``` - -You should see: - -``` 0.18.0-eceb56b7 ``` -And also: +### Node Setup + +Create the required configuration files: ``` -gaiacli version +gaiad init ``` -You should see: - -``` -0.18.0-eceb56b7 -``` - -## Full Node Setup - -Copy the testnet initialization files to a new data directory: - -``` -mkdir -p $HOME/.gaiad/config -cp -a cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json -gaiad unsafe_reset_all -``` - -Add a seed node by changing `seeds = ""` in `$HOME/.gaiad/config/config.toml` to - -``` -seeds = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" -``` - -Lastly change the `moniker` string in the `$HOME/.gaiad/config/config.toml`to identify your node. +Name your node by editing the `moniker` in `$HOME/.gaiad/config/config.toml`. Note that only ASCII characters are supported. Using Unicode renders your node unconnectable. ``` # A custom human readable name for this node moniker = "" ``` -## Upgrading from a previous network +Your full node has been initialized! Please skip to [Genesis & Seeds](#genesis--seeds). -These instructions are for anyone that ran a previous network and would like to upgrade to a newer version. +## Upgrading From Previous Testnet + +These instructions are for full nodes that have ran on previous testnets and would like to upgrade to the latest testnet. + +### Reset Data + +First, remove the outdated files and reset the data. -Remove the ephemeral files and reset the data. ``` rm $HOME/.gaiad/config/addrbook.json $HOME/.gaiad/config/genesis.json gaiad unsafe_reset_all ``` -Now your node is in a prestine state without changing your validator key. If you had any -sentry nodes or full nodes setup correctly previously they should work. +Your node is now in a pristine state while keeping the original `priv_validator.json`. If you had any sentry nodes or full nodes setup before, they should continue to work. -**Make sure that every node has a unique `priv_validator.json`. Do not copy the `priv_validator.json` from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign.**\ +**WARNING:** Make sure that every node has a unique `priv_validator.json`. Do not copy the `priv_validator.json` from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign. +### Software Upgrade + +Now it is time to upgrade the software: -Now it is time to upgrade the software. ``` cd $GOPATH/src/github.com/cosmos/cosmos-sdk -git fetch --all -git checkout v0.18.0 -make update_tools -make get_vendor_deps -make install +git fetch --all && git checkout v0.18.0 +make update_tools && make get_vendor_deps && make install ``` -The next step is to copy the new genesis file: +Your full node has been cleanly upgraded! + +## Genesis & Seeds + +### Copy the Genesis File + +Copy the testnet's `genesis.json` file and place it in `gaiad`'s config directory. ``` -cp -a cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json +mkdir -p $HOME/.gaiad/config +cp -a $GOPATH/src/github.com/cosmos/cosmos-sdk/cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json ``` -The last step is the adjust the `$HOME/.gaiad/config/config.toml`. Make sure that you are connected to healthy peers or seed nodes. -These are some seeds nodes and they can be put into the config under the `seeds` key. Alternatively you can also -ask user validators directly for a persistent peer and add it under the `persisent_peers` key. +### Add Seed Nodes + +Your node needs to know how to find peers. You'll need to add healthy seed nodes to `$HOME/.gaiad/config/config.toml`. Here are some seed nodes you can use: ``` -38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656 +# Comma separated list of seed nodes to connect to +seeds = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" ``` +You can also [ask other validators](https://riot.im/app/#/room/#cosmos_validators:matrix.org) for a persistent peer and add it under the `persistent_peers` key. For more information on seeds and peers, [read this](https://github.com/tendermint/tendermint/blob/develop/docs/using-tendermint.md#peers). + ## Run a Full Node -Start the full node: +Start the full node with this command: ``` gaiad start ``` -Check the everything is running smoothly: +Check that everything is running smoothly: ``` gaiacli status ``` -## Generate keys +View the status of the network with the [Cosmos Explorer](https://explorecosmos.network). Once your full node syncs up to the current block height, you should see it appear on the [list of full nodes](https://explorecosmos.network/validators). If it doesn't show up, that's ok--the Explorer does not connect to every node. + +## Generate Keys You'll need a private and public key pair \(a.k.a. `sk, pk` respectively\) to be able to receive funds, send txs, bond tx, etc. -To generate your a new key \(default _ed25519_ elliptic curve\): +To generate a new key \(default _ed25519_ elliptic curve\): ``` gaiacli keys add ``` -Next, you will have to enter a passphrase for your key twice. Save the _seed_ _phrase_ in a safe place in case you forget the password. +Next, you will have to create a passphrase. Save the _seed_ _phrase_ in a safe place in case you forget the password. -Now if you check your private keys you will see the `` key among them: +If you check your private keys, you'll now see ``: ``` gaiacli keys show ``` -You can see all your other available keys by typing: +You can see all your available keys by typing: ``` gaiacli keys list ``` -The validator pubkey from your node should be the same as the one printed with the command: +View the validator pubkey for your node by typing: ``` gaiad tendermint show_validator ``` -Finally, save your address and pubkey into a variable to use them afterwards. +Save your address and pubkey to environment variables for later use: ``` MYADDR= MYPUBKEY= ``` -**IMPORTANT:** We strongly recommend to **NOT** use the same passphrase for your different keys. The Tendermint team and the Interchain Foundation will not be responsible for the lost of funds. +**WARNING:** We strongly recommend NOT using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. -### Get coins +## Get Tokens -The best way to get coins at the moment is to ask in Riot chat. We plan to have a reliable faucet in future testnets. +The best way to get tokens is from the [Cosmos Testnet Faucet](https://faucetcosmos.network). If the faucet is not working for you, try asking [#cosmos-validators](https://riot.im/app/#/room/#cosmos-validators:matrix.org). -## Send tokens +After receiving tokens to your address, you can view your account's balance by typing: ``` -gaiacli send --amount=1000fermion --chain-id= --sequence=0 --name= --to= +gaiacli account ``` -The `--amount` flag defines the corresponding amount of the coin in the format `--amount=` +Note: When you query an account balance with zero tokens, you will get this error: `No account with address was found in the state.` This is expected! We're working on improving our error messages. -The `--sequence` flag corresponds to the sequence number to sign the tx. - -Now check the destination account and your own account to check the updated balances \(by default the latest block\): +## Send Tokens ``` +gaiacli send --amount=10faucetToken --chain-id= --name= --to= +``` + +Note: The `--amount` flag accepts the format `--amount=`. + +Now, view the updated balances of the origin and destination accounts: + +``` +gaiacli account gaiacli account -gaiacli account ``` You can also check your balance at a given block by using the `--block` flag: @@ -233,71 +190,65 @@ gaiacli account --block= ## Run a Validator Node -[Validators](https://cosmos.network/validators) are actors from the network that are responsible from committing new blocks to the blockchain by submitting their votes. In terms of security, validators' stake is slashed in all the zones they belong if they become unavailable, double sign a transaction, or don't cast their votes. We strongly recommend entities intending to run validators in the Cosmos Hub's `mainnet` to check the [technical requirements](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#technical-requirements) and take the necessary precautions to ensure high-availability, such as setting a Sentry Node architecture. If you have any question about validators, read the [Validator FAQ](https://cosmos.network/resources/validator-faq) and join the [Validator Chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org). +[Validators](https://cosmos.network/validators) are responsible for committing new blocks to the blockchain through voting. A validator's stake is slashed if they become unavailable, double sign a transaction, or don't cast their votes. If you only want to run a full node, a VM in the cloud is fine. However, if you are want to become a validator for the Hub's `mainnet`, you should research hardened setups. Please read [Sentry Node Architecture](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#how-can-validators-protect-themselves-from-denial-of-service-attacks) to protect your node from DDOS and ensure high-availability. Also see the [technical requirements](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#technical-requirements)). There's also more info on our [website](https://cosmos.network/validators). -This section covers the instructions necessary to stake tokens to become a testnet validator candidate. +Your `pubkey` can be used to create a new validator by staking tokens. You can find your validator pubkey by running: -Your `pubkey` can be used to create a new validator candidate by staking some tokens: - -You can find your node pubkey by running ``` gaiad tendermint show_validator ``` -and this returns your public key for the declare-candidate command - +Next, craft your `gaiacli stake create-validator` command: ``` -gaiacli stake create-validator --amount=500steak --pubkey= --address-candidate= --moniker=satoshi --chain-id= --sequence=1 --name= +gaiacli stake create-validator --amount=5steak --pubkey= --address-validator= --moniker=satoshi --chain-id= --name= ``` -You can add more information of the validator candidate such as`--website`, `--keybase-sig `or additional `--details`. If you want to edit the candidate info: +You can add more information to the validator, such as`--website`, `--keybase-sig`, or `--details`. Here's how: ``` gaiacli stake edit-validator --details="To the cosmos !" --website="https://cosmos.network" ``` -Finally, you can check all the candidate information by typing: +View the validator's information with this command: ``` -gaiacli stake validator --address-candidate= --chain-id= +gaiacli stake validator --address-validator= --chain-id= ``` -To check that the validator is active you can find it on the validator set list: +To check that the validator is active, look for it here: ``` gaiacli advanced tendermint validator-set ``` -**Note:** Remember that to be in the validator set you need to have more total power than the Xnd validator, where X is the assigned size for the validator set \(by default _`X = 100`_\). +**Note:** To be in the validator set, you need to have more total voting power than the 100th validator. -## Delegate your tokens +## Delegating to a Validator -You can delegate \(_i.e._ bind\) **Atoms** to a validator to become a [delegator](https://cosmos.network/resources/delegators) and obtain a part of its fee revenue in **Photons**. For more information about the Cosmos Token Model, refer to our [whitepaper](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf). +On the upcoming mainnet, you can delegate `atom` to a validator. These [delegators](https://cosmos.network/resources/delegators) can receive part of the validator's fee revenue in `photon`. Read more more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf). -### Bond your tokens +### Bond Tokens -Bond your tokens to a validator candidate with the following command: +On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator: ``` -gaiacli stake delegate --amount=10steak --address-delegator= --address-candidate= --name= --chain-id= --sequence=2 +gaiacli stake delegate --amount=10steak --address-delegator= --address-validator= --name= --chain-id= ``` -When tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain shares that represent their stake in this pool. +While tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain a percentage of shares that equal their stake in this pool. -### Unbond +### Unbond Tokens -If for any reason the validator misbehaves or you just want to unbond a certain amount of the bonded tokens: +If for any reason the validator misbehaves, or you want to unbond a certain amount of tokens, use this following command. You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\). ``` -gaiacli stake unbond --address-delegator= --address-candidate= --shares=MAX --name= --chain-id= --sequence=3 +gaiacli stake unbond --address-delegator= --address-validator= --shares=MAX --name= --chain-id= ``` -You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\). - -You should now see the unbonded tokens reflected in your balance and in your delegator bond: +You can check your balance and your stake delegation to see that the unbonding went through successfully. ``` gaiacli account -gaiacli stake delegation --address-delegator= --address-candidate= --chain-id= +gaiacli stake delegation --address-delegator= --address-validator= --chain-id= ``` From a03770d73d2a0035f49a7fc5d575be5d7edfdad9 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Jun 2018 21:13:28 -0700 Subject: [PATCH 65/89] testnets: minor readme update --- cmd/gaia/testnets/README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md index 8ea2d43fc..b34926aed 100644 --- a/cmd/gaia/testnets/README.md +++ b/cmd/gaia/testnets/README.md @@ -20,8 +20,10 @@ Install `go` by following the [official docs](https://golang.org/doc/install). Next, let's install the testnet's version of the Cosmos SDK. ``` -go get github.com/cosmos/cosmos-sdk -cd $GOPATH/src/github.com/cosmos/cosmos-sdk && git checkout v0.18.0 +mkdir -p $GOPATH/src/github.com/cosmos +cd $GOPATH/src/github.com/cosmos +git clone https://github.com/cosmos/cosmos-sdk +cd cosmos-sdk && git checkout v0.18.0 make get_tools && make get_vendor_deps && make install ``` @@ -62,7 +64,9 @@ rm $HOME/.gaiad/config/addrbook.json $HOME/.gaiad/config/genesis.json gaiad unsafe_reset_all ``` -Your node is now in a pristine state while keeping the original `priv_validator.json`. If you had any sentry nodes or full nodes setup before, they should continue to work. +Your node is now in a pristine state while keeping the original `priv_validator.json` and `config.toml`. If you had any sentry nodes or full nodes setup before, +your node will still try to connect to them, but may fail if they haven't also +been upgraded. **WARNING:** Make sure that every node has a unique `priv_validator.json`. Do not copy the `priv_validator.json` from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign. @@ -226,7 +230,7 @@ gaiacli advanced tendermint validator-set ## Delegating to a Validator -On the upcoming mainnet, you can delegate `atom` to a validator. These [delegators](https://cosmos.network/resources/delegators) can receive part of the validator's fee revenue in `photon`. Read more more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf). +On the upcoming mainnet, you can delegate `atom` to a validator. These [delegators](https://cosmos.network/resources/delegators) can receive part of the validator's fee revenue. Read more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf). ### Bond Tokens From 1c8dbd1087fbc6e93332ec8dd25f4277d57a0b92 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Tue, 12 Jun 2018 21:42:52 -0700 Subject: [PATCH 66/89] Merge PR #1228: Update to Tendermint develop --- Gopkg.lock | 9 ++++----- Gopkg.toml | 4 ++-- server/tm_cmds.go | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 07a3c6d5b..515c4dc4f 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -267,8 +267,8 @@ "server", "types" ] - revision = "ebee2fe114020aa49c70bbbae50b7079fc7e7b90" - version = "v0.11.0" + revision = "198dccf0ddfd1bb176f87657e3286a05a6ed9540" + version = "v0.12.0" [[projects]] branch = "master" @@ -347,8 +347,7 @@ "types", "version" ] - revision = "27bd1deabe4ba6a2d9b463b8f3e3f1e31b993e61" - version = "v0.20.0" + revision = "fa32dc51819c5eb85a51a239b785c930ac8ad5f0" [[projects]] branch = "develop" @@ -463,6 +462,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "31f69b235b2d8f879a215c9e8ca0919adc62d21f6830b17931a3a0efb058721f" + inputs-digest = "4f488b27a585db0df82292eb72740bee8b6c1e50e7d593bf1e45785195d09938" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 77de1b78d..5428e7421 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -54,7 +54,7 @@ [[constraint]] name = "github.com/tendermint/abci" - version = "=0.11.0" + version = "=0.12.0" [[constraint]] name = "github.com/tendermint/go-crypto" @@ -70,7 +70,7 @@ [[constraint]] name = "github.com/tendermint/tendermint" - version = "=0.20.0" + revision = "fa32dc51819c5eb85a51a239b785c930ac8ad5f0" [[override]] name = "github.com/tendermint/tmlibs" diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 7dccaf531..25d417a66 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -72,7 +72,7 @@ func UnsafeResetAllCmd(ctx *Context) *cobra.Command { 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) + tcmd.ResetAll(cfg.DBDir(), cfg.P2P.AddrBookFile(), cfg.PrivValidatorFile(), ctx.Logger) return nil }, } From 8753d6d59a569e1d8949a5e068d4b6dfc555b429 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 13 Jun 2018 07:25:14 +0200 Subject: [PATCH 67/89] Revert "Merge PR #1228: Update to Tendermint develop" (#1231) This reverts commit 1c8dbd1087fbc6e93332ec8dd25f4277d57a0b92. --- Gopkg.lock | 9 +++++---- Gopkg.toml | 4 ++-- server/tm_cmds.go | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 515c4dc4f..07a3c6d5b 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -267,8 +267,8 @@ "server", "types" ] - revision = "198dccf0ddfd1bb176f87657e3286a05a6ed9540" - version = "v0.12.0" + revision = "ebee2fe114020aa49c70bbbae50b7079fc7e7b90" + version = "v0.11.0" [[projects]] branch = "master" @@ -347,7 +347,8 @@ "types", "version" ] - revision = "fa32dc51819c5eb85a51a239b785c930ac8ad5f0" + revision = "27bd1deabe4ba6a2d9b463b8f3e3f1e31b993e61" + version = "v0.20.0" [[projects]] branch = "develop" @@ -462,6 +463,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "4f488b27a585db0df82292eb72740bee8b6c1e50e7d593bf1e45785195d09938" + inputs-digest = "31f69b235b2d8f879a215c9e8ca0919adc62d21f6830b17931a3a0efb058721f" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 5428e7421..77de1b78d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -54,7 +54,7 @@ [[constraint]] name = "github.com/tendermint/abci" - version = "=0.12.0" + version = "=0.11.0" [[constraint]] name = "github.com/tendermint/go-crypto" @@ -70,7 +70,7 @@ [[constraint]] name = "github.com/tendermint/tendermint" - revision = "fa32dc51819c5eb85a51a239b785c930ac8ad5f0" + version = "=0.20.0" [[override]] name = "github.com/tendermint/tmlibs" diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 25d417a66..7dccaf531 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -72,7 +72,7 @@ func UnsafeResetAllCmd(ctx *Context) *cobra.Command { 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.P2P.AddrBookFile(), cfg.PrivValidatorFile(), ctx.Logger) + tcmd.ResetAll(cfg.DBDir(), cfg.PrivValidatorFile(), ctx.Logger) return nil }, } From ef2e7a5129d0848e99daa14357b6be8f3f9907c3 Mon Sep 17 00:00:00 2001 From: suyuhuang Date: Wed, 13 Jun 2018 13:27:24 +0800 Subject: [PATCH 68/89] Merge PR #1229: Fix 'gaiad init gen-tx' not showing seed --- cmd/gaia/app/genesis.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 813796c0d..558bca38a 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -108,7 +108,8 @@ func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( return } cliPrint = json.RawMessage(bz) - return GaiaAppGenTxNF(cdc, pk, addr, name, overwrite) + appGenTx,_,validator,err = GaiaAppGenTxNF(cdc, pk, addr, name, overwrite) + return } // Generate a gaia genesis transaction without flags From 522042fd1200fbdbf49c76e55b4bceeebb80a0f9 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Jun 2018 22:17:11 -0700 Subject: [PATCH 69/89] gaiadebug tool --- Makefile | 5 +- cmd/gaia/cmd/gaiadebug/main.go | 122 +++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 cmd/gaia/cmd/gaiadebug/main.go diff --git a/Makefile b/Makefile index d6444b0b6..c0d18c4a3 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,9 @@ install_examples: go install $(BUILD_FLAGS) ./examples/democoin/cmd/democoind go install $(BUILD_FLAGS) ./examples/democoin/cmd/democli +install_debug: + go install $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiadebug + dist: @bash publish/dist.sh @bash publish/publish.sh @@ -157,4 +160,4 @@ remotenet-status: # 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_cli test_unit test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update remotenet-start remotenet-stop remotenet-status +.PHONY: build build_examples install install_examples install_debug 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 remotenet-start remotenet-stop remotenet-status diff --git a/cmd/gaia/cmd/gaiadebug/main.go b/cmd/gaia/cmd/gaiadebug/main.go new file mode 100644 index 000000000..ed5344bdd --- /dev/null +++ b/cmd/gaia/cmd/gaiadebug/main.go @@ -0,0 +1,122 @@ +package main + +import ( + "bytes" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "os" + + gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/spf13/cobra" + crypto "github.com/tendermint/go-crypto" +) + +func init() { + rootCmd.AddCommand(txCmd) + rootCmd.AddCommand(pubkeyCmd) +} + +var rootCmd = &cobra.Command{ + Use: "gaiadebug", + Short: "Gaia debug tool", + SilenceUsage: true, +} + +var txCmd = &cobra.Command{ + Use: "tx", + Short: "Decode a gaia tx from hex or base64", + RunE: runTxCmd, +} + +var pubkeyCmd = &cobra.Command{ + Use: "pubkey", + Short: "Decode a pubkey from hex or base64", + RunE: runPubKeyCmd, +} + +func runPubKeyCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("Expected single arg") + } + + pubkeyString := args[0] + + // try hex, then base64 + pubkeyBytes, err := hex.DecodeString(pubkeyString) + if err != nil { + var err2 error + pubkeyBytes, err2 = base64.StdEncoding.DecodeString(pubkeyString) + if err2 != nil { + return fmt.Errorf(`Expected hex or base64. Got errors: + hex: %v, + base64: %v + `, err, err2) + } + } + + cdc := gaia.MakeCodec() + var pubKey crypto.PubKeyEd25519 + copy(pubKey[:], pubkeyBytes) + pubKeyJSONBytes, err := cdc.MarshalJSON(pubKey) + if err != nil { + return err + } + fmt.Println("Address:", pubKey.Address()) + fmt.Printf("Hex: %X\n", pubkeyBytes) + fmt.Println("JSON (base64):", string(pubKeyJSONBytes)) + return nil +} + +func runTxCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("Expected single arg") + } + + txString := args[0] + + // try hex, then base64 + txBytes, err := hex.DecodeString(txString) + if err != nil { + var err2 error + txBytes, err2 = base64.StdEncoding.DecodeString(txString) + if err2 != nil { + return fmt.Errorf(`Expected hex or base64. Got errors: + hex: %v, + base64: %v + `, err, err2) + } + } + + var tx = auth.StdTx{} + cdc := gaia.MakeCodec() + + err = cdc.UnmarshalBinary(txBytes, &tx) + if err != nil { + return err + } + + bz, err := cdc.MarshalJSON(tx) + if err != nil { + return err + } + + buf := bytes.NewBuffer([]byte{}) + err = json.Indent(buf, bz, "", " ") + if err != nil { + return err + } + + fmt.Println(buf.String()) + return nil +} + +func main() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } + os.Exit(0) +} From cb93cbee3d138bb7199f84d226fd850967a19126 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Jun 2018 22:27:13 -0700 Subject: [PATCH 70/89] gaiadebug: add hack command --- cmd/gaia/cmd/gaiadebug/hack.go | 243 +++++++++++++++++++++++++++++++++ cmd/gaia/cmd/gaiadebug/main.go | 7 + 2 files changed, 250 insertions(+) create mode 100644 cmd/gaia/cmd/gaiadebug/hack.go diff --git a/cmd/gaia/cmd/gaiadebug/hack.go b/cmd/gaia/cmd/gaiadebug/hack.go new file mode 100644 index 000000000..2c84184bf --- /dev/null +++ b/cmd/gaia/cmd/gaiadebug/hack.go @@ -0,0 +1,243 @@ +package main + +import ( + "encoding/base64" + "encoding/hex" + "fmt" + "os" + "path" + + "github.com/spf13/cobra" + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + 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/slashing" + "github.com/cosmos/cosmos-sdk/x/stake" + + gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" +) + +func runHackCmd(cmd *cobra.Command, args []string) error { + + if len(args) != 1 { + return fmt.Errorf("Expected 1 arg") + } + + // ".gaiad" + dataDir := args[0] + dataDir = path.Join(dataDir, "data") + + // load the app + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + db, err := dbm.NewGoLevelDB("gaia", dataDir) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + app := NewGaiaApp(logger, db) + + // print some info + id := app.LastCommitID() + lastBlockHeight := app.LastBlockHeight() + fmt.Println("ID", id) + fmt.Println("LastBlockHeight", lastBlockHeight) + + //---------------------------------------------------- + // XXX: start hacking! + //---------------------------------------------------- + // eg. gaia-6001 testnet bug + // We paniced when iterating through the "bypower" keys. + // The following powerKey was there, but the corresponding "trouble" validator did not exist. + // So here we do a binary search on the past states to find when the powerKey first showed up ... + + // owner of the validator the bonds, gets revoked, later unbonds, and then later is still found in the bypower store + trouble := hexToBytes("D3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") + // this is his "bypower" key + powerKey := hexToBytes("05303030303030303030303033FFFFFFFFFFFF4C0C0000FFFED3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") + + topHeight := lastBlockHeight + bottomHeight := int64(0) + checkHeight := topHeight + for { + // load the given version of the state + err = app.LoadVersion(checkHeight, app.keyMain) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + ctx := app.NewContext(true, abci.Header{}) + + // check for the powerkey and the validator from the store + store := ctx.KVStore(app.keyStake) + res := store.Get(powerKey) + val, _ := app.stakeKeeper.GetValidator(ctx, trouble) + fmt.Println("checking height", checkHeight, res, val) + if res == nil { + bottomHeight = checkHeight + } else { + topHeight = checkHeight + } + checkHeight = (topHeight + bottomHeight) / 2 + } +} + +func base64ToPub(b64 string) crypto.PubKeyEd25519 { + data, _ := base64.StdEncoding.DecodeString(b64) + var pubKey crypto.PubKeyEd25519 + copy(pubKey[:], data) + return pubKey + +} + +func hexToBytes(h string) []byte { + trouble, _ := hex.DecodeString(h) + return trouble + +} + +//-------------------------------------------------------------------------------- +// NOTE: This is all copied from gaia/app/app.go +// so we can access internal fields! + +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 + cdc *wire.Codec + + // keys to access the substores + keyMain *sdk.KVStoreKey + keyAccount *sdk.KVStoreKey + keyIBC *sdk.KVStoreKey + keyStake *sdk.KVStoreKey + keySlashing *sdk.KVStoreKey + + // Manage getting and setting accounts + accountMapper auth.AccountMapper + feeCollectionKeeper auth.FeeCollectionKeeper + coinKeeper bank.Keeper + ibcMapper ibc.Mapper + stakeKeeper stake.Keeper + slashingKeeper slashing.Keeper +} + +func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { + cdc := MakeCodec() + + // create your application object + var app = &GaiaApp{ + 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"), + keySlashing: sdk.NewKVStoreKey("slashing"), + } + + // 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)) + app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.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)) + + // initialize BaseApp + app.SetInitChainer(app.initChainer) + app.SetBeginBlocker(app.BeginBlocker) + app.SetEndBlocker(app.EndBlocker) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) + app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing) + 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() + ibc.RegisterWire(cdc) + bank.RegisterWire(cdc) + stake.RegisterWire(cdc) + slashing.RegisterWire(cdc) + auth.RegisterWire(cdc) + sdk.RegisterWire(cdc) + wire.RegisterCrypto(cdc) + return cdc +} + +// application updates every end block +func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) + + return abci.ResponseBeginBlock{ + Tags: tags.ToKVPairs(), + } +} + +// application updates every end block +func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) + + return abci.ResponseEndBlock{ + ValidatorUpdates: validatorUpdates, + } +} + +// custom logic for gaia initialization +func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + stateJSON := req.AppStateBytes + // TODO is this now the whole genesis file? + + var genesisState gaia.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, "") + } + + // load the accounts + for _, gacc := range genesisState.Accounts { + acc := gacc.ToAccount() + app.accountMapper.SetAccount(ctx, acc) + } + + // load the initial stake information + stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + return abci.ResponseInitChain{} + +} diff --git a/cmd/gaia/cmd/gaiadebug/main.go b/cmd/gaia/cmd/gaiadebug/main.go index ed5344bdd..914746dbd 100644 --- a/cmd/gaia/cmd/gaiadebug/main.go +++ b/cmd/gaia/cmd/gaiadebug/main.go @@ -17,6 +17,7 @@ import ( func init() { rootCmd.AddCommand(txCmd) rootCmd.AddCommand(pubkeyCmd) + rootCmd.AddCommand(hackCmd) } var rootCmd = &cobra.Command{ @@ -37,6 +38,12 @@ var pubkeyCmd = &cobra.Command{ RunE: runPubKeyCmd, } +var hackCmd = &cobra.Command{ + Use: "hack", + Short: "Boilerplate to Hack on an existing state by scripting some Go...", + RunE: runHackCmd, +} + func runPubKeyCmd(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("Expected single arg") From 2219548d0e538cd5652e83253bf6102f1b5f96a5 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Jun 2018 22:45:51 -0700 Subject: [PATCH 71/89] fix from merge --- client/lcd/lcd_test.go | 186 +---------------------------------------- 1 file changed, 3 insertions(+), 183 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index f0d5d80e8..ba2937e05 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -1,44 +1,26 @@ package lcd import ( - "bytes" "encoding/hex" "encoding/json" "fmt" - "io/ioutil" - "net" "net/http" - "os" "regexp" "testing" - "github.com/spf13/viper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" cryptoKeys "github.com/tendermint/go-crypto/keys" - tmcfg "github.com/tendermint/tendermint/config" - nm "github.com/tendermint/tendermint/node" p2p "github.com/tendermint/tendermint/p2p" - pvm "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/proxy" ctypes "github.com/tendermint/tendermint/rpc/core/types" - tmrpc "github.com/tendermint/tendermint/rpc/lib/server" - tmtypes "github.com/tendermint/tendermint/types" - "github.com/tendermint/tmlibs/cli" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" client "github.com/cosmos/cosmos-sdk/client" keys "github.com/cosmos/cosmos-sdk/client/keys" rpc "github.com/cosmos/cosmos-sdk/client/rpc" - gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/server" tests "github.com/cosmos/cosmos-sdk/tests" 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" stakerest "github.com/cosmos/cosmos-sdk/x/stake/client/rest" @@ -414,172 +396,10 @@ func TestBonding(t *testing.T) { // TODO fix shares fn in staking // query sender - acc := getAccount(t, sendAddr) - coins := acc.GetCoins() - assert.Equal(t, int64(98), coins.AmountOf(coinDenom)) + //acc := getAccount(t, sendAddr) + //coins := acc.GetCoins() + //assert.Equal(t, int64(98), coins.AmountOf(coinDenom)) - // query candidate - bond := getDelegation(t, sendAddr, validatorAddr1) - assert.Equal(t, "9/1", bond.Shares.String()) -} - -//__________________________________________________________ -// helpers - -// strt TM and the LCD in process, listening on their respective sockets -func startTMAndLCD() (*nm.Node, net.Listener, error) { - - dir, err := ioutil.TempDir("", "lcd_test") - if err != nil { - return nil, nil, err - } - viper.Set(cli.HomeFlag, dir) - viper.Set(client.FlagGas, 200000) - kb, err := keys.GetKeyBase() // dbm.NewMemDB()) // :( - if err != nil { - return nil, nil, err - } - - config := GetConfig() - config.Consensus.TimeoutCommit = 1000 - config.Consensus.SkipTimeoutCommit = false - - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - logger = log.NewFilter(logger, log.AllowError()) - privValidatorFile := config.PrivValidatorFile() - privVal := pvm.LoadOrGenFilePV(privValidatorFile) - db := dbm.NewMemDB() - app := gapp.NewGaiaApp(logger, db) - cdc = gapp.MakeCodec() // XXX - - genesisFile := config.GenesisFile() - genDoc, err := tmtypes.GenesisDocFromFile(genesisFile) - if err != nil { - return nil, nil, err - } - - genDoc.Validators = append(genDoc.Validators, - tmtypes.GenesisValidator{ - PubKey: crypto.GenPrivKeyEd25519().PubKey(), - Power: 1, - Name: "val", - }, - ) - - pk1 := genDoc.Validators[0].PubKey - pk2 := genDoc.Validators[1].PubKey - validatorAddr1 = hex.EncodeToString(pk1.Address()) - validatorAddr2 = hex.EncodeToString(pk2.Address()) - - // NOTE it's bad practice to reuse pk address for the owner address but doing in the - // test for simplicity - var appGenTxs [2]json.RawMessage - appGenTxs[0], _, _, err = gapp.GaiaAppGenTxNF(cdc, pk1, pk1.Address(), "test_val1", true) - if err != nil { - return nil, nil, err - } - appGenTxs[1], _, _, err = gapp.GaiaAppGenTxNF(cdc, pk2, pk2.Address(), "test_val2", true) - if err != nil { - return nil, nil, err - } - - genesisState, err := gapp.GaiaAppGenState(cdc, appGenTxs[:]) - if err != nil { - return nil, nil, err - } - - // add the sendAddr to genesis - var info cryptoKeys.Info - info, seed, err = kb.Create(name, password, cryptoKeys.AlgoEd25519) // XXX global seed - if err != nil { - return nil, nil, err - } - sendAddr = info.PubKey.Address().String() // XXX global - accAuth := auth.NewBaseAccountWithAddress(info.PubKey.Address()) - accAuth.Coins = sdk.Coins{{"steak", 100}} - acc := gapp.NewGenesisAccount(&accAuth) - genesisState.Accounts = append(genesisState.Accounts, acc) - - appState, err := wire.MarshalJSONIndent(cdc, genesisState) - if err != nil { - return nil, nil, err - } - genDoc.AppStateJSON = appState - - // LCD listen address - var listenAddr string - listenAddr, port, err = server.FreeTCPAddr() - if err != nil { - return nil, nil, err - } - - // XXX: need to set this so LCD knows the tendermint node address! - viper.Set(client.FlagNode, config.RPC.ListenAddress) - viper.Set(client.FlagChainID, genDoc.ChainID) - - node, err := startTM(config, logger, genDoc, privVal, app) - if err != nil { - return nil, nil, err - } - lcd, err := startLCD(logger, listenAddr, cdc) - if err != nil { - return nil, nil, err - } - - tests.WaitForStart(port) - - return node, lcd, nil -} - -// Create & start in-process tendermint node with memdb -// and in-process abci application. -// TODO: need to clean up the WAL dir or enable it to be not persistent -func startTM(cfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc, privVal tmtypes.PrivValidator, app abci.Application) (*nm.Node, error) { - genDocProvider := func() (*tmtypes.GenesisDoc, error) { return genDoc, nil } - dbProvider := func(*nm.DBContext) (dbm.DB, error) { return dbm.NewMemDB(), nil } - n, err := nm.NewNode(cfg, - privVal, - proxy.NewLocalClientCreator(app), - genDocProvider, - dbProvider, - logger.With("module", "node")) - if err != nil { - return nil, err - } - - err = n.Start() - if err != nil { - return nil, err - } - - // wait for rpc - tests.WaitForRPC(GetConfig().RPC.ListenAddress) - - logger.Info("Tendermint running!") - return n, err -} - -// start the LCD. note this blocks! -func startLCD(logger log.Logger, listenAddr string, cdc *wire.Codec) (net.Listener, error) { - handler := createHandler(cdc) - return tmrpc.StartHTTPServer(listenAddr, handler, logger) -} - -func request(t *testing.T, port, method, path string, payload []byte) (*http.Response, string) { - var res *http.Response - var err error - url := fmt.Sprintf("http://localhost:%v%v", port, path) - req, err := http.NewRequest(method, url, bytes.NewBuffer(payload)) - require.Nil(t, err) - res, err = http.DefaultClient.Do(req) - // res, err = http.Post(url, "application/json", bytes.NewBuffer(payload)) - require.Nil(t, err) - - output, err := ioutil.ReadAll(res.Body) - res.Body.Close() - require.Nil(t, err) - - return res, string(output) } //_____________________________________________________________________________ From 47cc91e8e5f3ad5b4eb1983fae7bf3acd09a131d Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Jun 2018 22:59:33 -0700 Subject: [PATCH 72/89] gaiadebug: raw-bytes command --- cmd/gaia/cmd/gaiadebug/main.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cmd/gaia/cmd/gaiadebug/main.go b/cmd/gaia/cmd/gaiadebug/main.go index 914746dbd..79045c07b 100644 --- a/cmd/gaia/cmd/gaiadebug/main.go +++ b/cmd/gaia/cmd/gaiadebug/main.go @@ -7,6 +7,8 @@ import ( "encoding/json" "fmt" "os" + "strconv" + "strings" gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/x/auth" @@ -18,6 +20,7 @@ func init() { rootCmd.AddCommand(txCmd) rootCmd.AddCommand(pubkeyCmd) rootCmd.AddCommand(hackCmd) + rootCmd.AddCommand(rawBytesCmd) } var rootCmd = &cobra.Command{ @@ -44,6 +47,33 @@ var hackCmd = &cobra.Command{ RunE: runHackCmd, } +var rawBytesCmd = &cobra.Command{ + Use: "raw-bytes", + Short: "Convert raw bytes output (eg. [10 21 13 255]) to hex", + RunE: runRawBytesCmd, +} + +func runRawBytesCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("Expected single arg") + } + stringBytes := args[0] + stringBytes = strings.Trim(stringBytes, "[") + stringBytes = strings.Trim(stringBytes, "]") + spl := strings.Split(stringBytes, " ") + + byteArray := []byte{} + for _, s := range spl { + b, err := strconv.Atoi(s) + if err != nil { + return err + } + byteArray = append(byteArray, byte(b)) + } + fmt.Printf("%X\n", byteArray) + return nil +} + func runPubKeyCmd(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("Expected single arg") From 1cd3a6255a863b4c83c72f14f30293592360c461 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Jun 2018 23:12:55 -0700 Subject: [PATCH 73/89] fix from merge --- client/flags.go | 1 - 1 file changed, 1 deletion(-) diff --git a/client/flags.go b/client/flags.go index 96ea5efd5..4991b9a77 100644 --- a/client/flags.go +++ b/client/flags.go @@ -27,7 +27,6 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command { c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") c.Flags().String(FlagNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") c.Flags().Int64(FlagHeight, 0, "block height to query, omit to get most recent provable block") - c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction") } return cmds } From 35a3c1491875a6f4731c93d6e4cd6a7f627a356f Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 12 Jun 2018 23:18:37 -0700 Subject: [PATCH 74/89] update status.md --- cmd/gaia/testnets/STATUS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md index d53c49e09..6f2140c26 100644 --- a/cmd/gaia/testnets/STATUS.md +++ b/cmd/gaia/testnets/STATUS.md @@ -1,5 +1,11 @@ # TESTNET STATUS +## *June 13, 2018, 2:30 EST* - Published Postmortem of Gaia-6001 failure + +- A bug in the design of the staking data model caused a sanity check to fail +- Full writeup + [here](https://github.com/cosmos/cosmos-sdk/issues/1197#issuecomment-396823021) + ## *June 10, 2018, 8:30 EST* - Gaia-6001 consensus failure - Validator unbonding and revocation activity caused a consensus failure From 83c1183e25a8bccc980a158be750c8e060f99f00 Mon Sep 17 00:00:00 2001 From: Rigel Date: Wed, 13 Jun 2018 00:12:57 -0700 Subject: [PATCH 75/89] Merge PR #1233: Inflation now unbonded working debug fix add broken test fix testnet bug updated provision test changelog cwgoes comments --- CHANGELOG.md | 2 ++ x/stake/handler_test.go | 73 +++++++++++++++++++++++++++++++++++++++ x/stake/inflation.go | 4 ++- x/stake/inflation_test.go | 59 ++++++------------------------- x/stake/keeper.go | 6 ++++ x/stake/keeper_test.go | 41 ++++++++++++++++++++++ x/stake/shares.go | 5 +-- 7 files changed, 138 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3123bef82..300b71fb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,10 @@ IMPROVEMENTS * [tests] Application module tests now use a mock application * [gaiacli] Fix error message when account isn't found when running gaiacli account * [lcd] refactored to eliminate use of global variables, and interdependent tests +* [x/stake] More stake tests added to test ByPower index FIXES +* [x/stake] bonded inflation removed, non-bonded inflation partially implemented * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs * [lcd] fixed tx indexing/querying * [cli] Added `--gas` flag to specify transaction gas limit diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 0c086f06d..6dcf3e66d 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -33,6 +33,78 @@ func newTestMsgDelegate(delegatorAddr, validatorAddr sdk.Address, amt int64) Msg //______________________________________________________________________ +func TestValidatorByPowerIndex(t *testing.T) { + validatorAddr, validatorAddr3 := addrs[0], addrs[1] + + initBond := int64(1000000) + initBondStr := "1000" + ctx, _, keeper := createTestInput(t, false, initBond) + + // create validator + msgCreateValidator := newTestMsgCreateValidator(validatorAddr, pks[0], initBond) + got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + assert.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + + // verify the self-delegation exists + bond, found := keeper.GetDelegation(ctx, validatorAddr, validatorAddr) + require.True(t, found) + gotBond := bond.Shares.Evaluate() + require.Equal(t, initBond, gotBond, + "initBond: %v\ngotBond: %v\nbond: %v\n", + initBond, gotBond, bond) + + // verify that the by power index exists + validator, found := keeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + pool := keeper.GetPool(ctx) + power := GetValidatorsByPowerKey(validator, pool) + require.True(t, keeper.validatorByPowerIndexExists(ctx, power)) + + // create a second validator keep it bonded + msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, pks[2], int64(1000000)) + got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) + assert.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + + // slash and revoke the first validator + keeper.Slash(ctx, pks[0], 0, sdk.NewRat(1, 2)) + keeper.Revoke(ctx, pks[0]) + validator, found = keeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + require.Equal(t, sdk.Unbonded, validator.PoolShares.Status) // ensure is unbonded + require.Equal(t, int64(500000), validator.PoolShares.Amount.Evaluate()) // ensure is unbonded + + // the old power record should have been deleted as the power changed + assert.False(t, keeper.validatorByPowerIndexExists(ctx, power)) + + // but the new power record should have been created + validator, found = keeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + pool = keeper.GetPool(ctx) + power2 := GetValidatorsByPowerKey(validator, pool) + require.True(t, keeper.validatorByPowerIndexExists(ctx, power2)) + + // inflate a bunch + for i := 0; i < 20000; i++ { + pool = keeper.processProvisions(ctx) + keeper.setPool(ctx, pool) + } + + // now the new record power index should be the same as the original record + power3 := GetValidatorsByPowerKey(validator, pool) + assert.Equal(t, power2, power3) + + // unbond self-delegation + msgUnbond := NewMsgUnbond(validatorAddr, validatorAddr, "MAX") + got = handleMsgUnbond(ctx, msgUnbond, keeper) + assert.True(t, got.IsOK(), + "got: %v\nmsgUnbond: %v\ninitBondStr: %v\n", got, msgUnbond, initBondStr) + + // verify that by power key nolonger exists + _, found = keeper.GetValidator(ctx, validatorAddr) + require.False(t, found) + assert.False(t, keeper.validatorByPowerIndexExists(ctx, power3)) +} + func TestDuplicatesMsgCreateValidator(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 1000) @@ -42,6 +114,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) assert.True(t, got.IsOK(), "%v", got) validator, found := keeper.GetValidator(ctx, validatorAddr) + require.True(t, found) assert.Equal(t, sdk.Bonded, validator.Status()) assert.Equal(t, validatorAddr, validator.Owner) diff --git a/x/stake/inflation.go b/x/stake/inflation.go index d613a478a..fe3f59435 100644 --- a/x/stake/inflation.go +++ b/x/stake/inflation.go @@ -22,7 +22,9 @@ func (k Keeper) processProvisions(ctx sdk.Context) Pool { // which needs to be updated is the `BondedPool`. So for each previsions cycle: provisions := pool.Inflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat).Evaluate() - pool.BondedTokens += provisions + + // TODO add to the fees provisions + pool.LooseUnbondedTokens += provisions return pool } diff --git a/x/stake/inflation_test.go b/x/stake/inflation_test.go index 7fa393edc..0d5183f4c 100644 --- a/x/stake/inflation_test.go +++ b/x/stake/inflation_test.go @@ -74,8 +74,6 @@ func TestProcessProvisions(t *testing.T) { initialBondedTokens int64 = 250000000 initialUnbondedTokens int64 = 300000000 cumulativeExpProvs int64 - initialBondedShares = sdk.NewRat(250000000, 1) - initialUnbondedShares = sdk.NewRat(300000000, 1) validatorTokens = []int64{150000000, 100000000, 100000000, 100000000, 100000000} bondedValidators uint16 = 2 ) @@ -93,9 +91,7 @@ func TestProcessProvisions(t *testing.T) { //get the pool and do the final value checks from checkFinalPoolValues pool = keeper.GetPool(ctx) - checkFinalPoolValues(t, pool, initialTotalTokens, - initialUnbondedTokens, cumulativeExpProvs, - 0, 0, initialBondedShares, initialUnbondedShares) + checkFinalPoolValues(t, pool, initialTotalTokens, cumulativeExpProvs) } // Tests that the hourly rate of change of inflation will be positive, negative, or zero, depending on bonded ratio and inflation rate @@ -109,8 +105,6 @@ func TestHourlyInflationRateOfChange(t *testing.T) { initialBondedTokens int64 = 150000000 initialUnbondedTokens int64 = 400000000 cumulativeExpProvs int64 - bondedShares = sdk.NewRat(150000000, 1) - unbondedShares = sdk.NewRat(400000000, 1) validatorTokens = []int64{150000000, 100000000, 100000000, 100000000, 100000000} bondedValidators uint16 = 1 ) @@ -131,9 +125,7 @@ func TestHourlyInflationRateOfChange(t *testing.T) { // Final check that the pool equals initial values + cumulative provisions and adjustments we recorded pool = keeper.GetPool(ctx) - checkFinalPoolValues(t, pool, initialTotalTokens, - initialUnbondedTokens, cumulativeExpProvs, - 0, 0, bondedShares, unbondedShares) + checkFinalPoolValues(t, pool, initialTotalTokens, cumulativeExpProvs) } //Test that a large unbonding will significantly lower the bonded ratio @@ -181,9 +173,7 @@ func TestLargeUnbond(t *testing.T) { // Final check that the pool equals initial values + provisions and adjustments we recorded pool = keeper.GetPool(ctx) - checkFinalPoolValues(t, pool, initialTotalTokens, - initialUnbondedTokens, expProvisionsAfter, - -val0UnbondedTokens, val0UnbondedTokens, bondedShares, unbondedShares) + checkFinalPoolValues(t, pool, initialTotalTokens, expProvisionsAfter) } //Test that a large bonding will significantly increase the bonded ratio @@ -192,12 +182,9 @@ func TestLargeBond(t *testing.T) { pool := keeper.GetPool(ctx) var ( - initialTotalTokens int64 = 1600000000 - initialBondedTokens int64 = 400000000 - initialUnbondedTokens int64 = 1200000000 - val9UnbondedTokens int64 = 400000000 - val9BondedTokens int64 - bondedShares = sdk.NewRat(400000000, 1) + initialTotalTokens int64 = 1600000000 + initialBondedTokens int64 = 400000000 + initialUnbondedTokens int64 = 1200000000 unbondedShares = sdk.NewRat(1200000000, 1) unbondedSharesVal9 = sdk.NewRat(400000000, 1) validatorTokens = []int64{400000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 400000000} @@ -225,10 +212,6 @@ func TestLargeBond(t *testing.T) { // process provisions after the bonding, to compare the difference in expProvisions and expInflation _, expProvisionsAfter, pool := updateProvisions(t, keeper, pool, ctx, 0) unbondedShares = unbondedShares.Sub(unbondedSharesVal9) - val9BondedTokens = val9UnbondedTokens - val9UnbondedTokens = 0 - bondedTokens := initialBondedTokens + val9BondedTokens + expProvisionsAfter - bondedShares = sdk.NewRat(bondedTokens, 1).Quo(pool.bondedShareExRate()) // unbonded shares should decrease assert.True(t, unbondedShares.LT(sdk.NewRat(1200000000, 1))) @@ -237,9 +220,7 @@ func TestLargeBond(t *testing.T) { // Final check that the pool equals initial values + provisions and adjustments we recorded pool = keeper.GetPool(ctx) - checkFinalPoolValues(t, pool, initialTotalTokens, - initialUnbondedTokens, expProvisionsAfter, - val9BondedTokens, -val9BondedTokens, bondedShares, unbondedShares) + checkFinalPoolValues(t, pool, initialTotalTokens, expProvisionsAfter) } // Tests that inflation increases or decreases as expected when we do a random operation on 20 different validators @@ -296,30 +277,13 @@ func TestInflationWithRandomOperations(t *testing.T) { } } +//_________________________________________________________________________________________ ////////////////////////////////HELPER FUNCTIONS BELOW///////////////////////////////////// -// Final check on the global pool values for what the total tokens accumulated from each hour of provisions and other functions -// bondedAdjustment and unbondedAdjustment are the accumulated changes for the operations of the test -// (i.e. if three unbond operations happened, their total value would be passed as unbondedAdjustment) -func checkFinalPoolValues(t *testing.T, pool Pool, initialTotalTokens, initialUnbondedTokens, - cumulativeExpProvs, bondedAdjustment, unbondedAdjustment int64, bondedShares, unbondedShares sdk.Rat) { - - initialBonded := initialTotalTokens - initialUnbondedTokens +// Final check on the global pool values for what the total tokens accumulated from each hour of provisions +func checkFinalPoolValues(t *testing.T, pool Pool, initialTotalTokens, cumulativeExpProvs int64) { calculatedTotalTokens := initialTotalTokens + cumulativeExpProvs - calculatedBondedTokens := initialBonded + cumulativeExpProvs + bondedAdjustment - calculatedUnbondedTokens := initialUnbondedTokens + unbondedAdjustment - - // test that the bonded ratio the pool has is equal to what we calculated for tokens - assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(calculatedBondedTokens, calculatedTotalTokens)), "%v", pool.bondedRatio()) - - // test global supply assert.Equal(t, calculatedTotalTokens, pool.TokenSupply()) - assert.Equal(t, calculatedBondedTokens, pool.BondedTokens) - assert.Equal(t, calculatedUnbondedTokens, pool.UnbondedTokens) - - // test the value of validator shares - assert.True(t, pool.bondedShareExRate().Mul(bondedShares).Equal(sdk.NewRat(calculatedBondedTokens)), "%v", pool.bondedShareExRate()) - assert.True(t, pool.unbondedShareExRate().Mul(unbondedShares).Equal(sdk.NewRat(calculatedUnbondedTokens)), "%v", pool.unbondedShareExRate()) } // Processes provisions are added to the pool correctly every hour @@ -327,13 +291,11 @@ func checkFinalPoolValues(t *testing.T, pool Pool, initialTotalTokens, initialUn func updateProvisions(t *testing.T, keeper Keeper, pool Pool, ctx sdk.Context, hr int) (sdk.Rat, int64, Pool) { expInflation := keeper.nextInflation(ctx) expProvisions := (expInflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat)).Evaluate() - startBondedPool := pool.BondedTokens startTotalSupply := pool.TokenSupply() pool = keeper.processProvisions(ctx) keeper.setPool(ctx, pool) //check provisions were added to pool - require.Equal(t, startBondedPool+expProvisions, pool.BondedTokens, "hr %v", hr) require.Equal(t, startTotalSupply+expProvisions, pool.TokenSupply()) return expInflation, expProvisions, pool @@ -405,5 +367,4 @@ func checkInflation(t *testing.T, pool Pool, previousInflation, updatedInflation assert.Equal(t, true, inflationChange.LT(sdk.ZeroRat()), msg) } } - } diff --git a/x/stake/keeper.go b/x/stake/keeper.go index fad1f86ef..4a2e6ff4b 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -78,6 +78,12 @@ func (k Keeper) setValidatorByPowerIndex(ctx sdk.Context, validator Validator, p store.Set(GetValidatorsByPowerKey(validator, pool), validator.Owner) } +// used in testing +func (k Keeper) validatorByPowerIndexExists(ctx sdk.Context, power []byte) bool { + store := ctx.KVStore(k.storeKey) + return store.Get(power) != nil +} + // Get the set of all validators with no limits, used during genesis dump func (k Keeper) getAllValidators(ctx sdk.Context) (validators Validators) { store := ctx.KVStore(k.storeKey) diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 2868853e0..76bfc507a 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -24,6 +24,47 @@ var ( } ) +func TestUpdateValidatorByPowerIndex(t *testing.T) { + ctx, _, keeper := createTestInput(t, false, 0) + pool := keeper.GetPool(ctx) + + // create a random pool + pool.BondedTokens = 1234 + pool.BondedShares = sdk.NewRat(124) + pool.UnbondingTokens = 13934 + pool.UnbondingShares = sdk.NewRat(145) + pool.UnbondedTokens = 154 + pool.UnbondedShares = sdk.NewRat(1333) + keeper.setPool(ctx, pool) + + // add a validator + validator := NewValidator(addrVals[0], pks[0], Description{}) + validator, pool, delSharesCreated := validator.addTokensFromDel(pool, 100) + require.Equal(t, sdk.Unbonded, validator.Status()) + assert.Equal(t, int64(100), validator.PoolShares.Tokens(pool).Evaluate()) + keeper.setPool(ctx, pool) + keeper.updateValidator(ctx, validator) + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + assert.Equal(t, int64(100), validator.PoolShares.Tokens(pool).Evaluate(), "\nvalidator %v\npool %v", validator, pool) + + pool = keeper.GetPool(ctx) + power := GetValidatorsByPowerKey(validator, pool) + assert.True(t, keeper.validatorByPowerIndexExists(ctx, power)) + + // burn half the delegator shares + validator, pool, burned := validator.removeDelShares(pool, delSharesCreated.Quo(sdk.NewRat(2))) + assert.Equal(t, int64(50), burned) + keeper.setPool(ctx, pool) // update the pool + keeper.updateValidator(ctx, validator) // update the validator, possibly kicking it out + assert.False(t, keeper.validatorByPowerIndexExists(ctx, power)) + + pool = keeper.GetPool(ctx) + validator, found = keeper.GetValidator(ctx, addrVals[0]) + power = GetValidatorsByPowerKey(validator, pool) + assert.True(t, keeper.validatorByPowerIndexExists(ctx, power)) +} + func TestSetValidator(t *testing.T) { ctx, _, keeper := createTestInput(t, false, 0) pool := keeper.GetPool(ctx) diff --git a/x/stake/shares.go b/x/stake/shares.go index d5fe93844..e30fa3738 100644 --- a/x/stake/shares.go +++ b/x/stake/shares.go @@ -118,13 +118,14 @@ func (s PoolShares) ToBonded(p Pool) PoolShares { //_________________________________________________________________________________________________________ +// TODO better tests // get the equivalent amount of tokens contained by the shares func (s PoolShares) Tokens(p Pool) sdk.Rat { switch s.Status { case sdk.Bonded: - return p.unbondedShareExRate().Mul(s.Amount) // (tokens/shares) * shares + return p.bondedShareExRate().Mul(s.Amount) // (tokens/shares) * shares case sdk.Unbonding: - return p.unbondedShareExRate().Mul(s.Amount) + return p.unbondingShareExRate().Mul(s.Amount) case sdk.Unbonded: return p.unbondedShareExRate().Mul(s.Amount) default: From 37bba35c91e7ade8f7a160ceb2c37b322fed42f1 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 13 Jun 2018 00:44:46 -0700 Subject: [PATCH 76/89] Merge PR #1232: Bucky/gaiadebug * update to tm v0.19.6 * update tm to 0.17.4 * update for tm v0.19.9 * update godep * Merge PR #1195: gaiacli - Add error message for when account isn't found * Add --gas flag to specify gas limit for a transaction * lawl viper * version and changelog * add cmd/gaia/testnets folder to deprecate cosmos/testnets repo * cmd/gaia/testnets: update status.md with recent history * cmd/gaia/testnets: update versions, use a working seed * readme points to testnet folder * add fixes from billy * fix status.md * seed->seeds * readme improvements add link to official faucet, remove sequence from cmds readme improvements wording improvements and simplifications add link to cosmos explorer remove instances of candidate add apostrophe small fixes improve the installing software section fixes based on feedback add note about querying an empty account remove panic note update introduction add full cp path for copying genesis.json update moniker warning remove redundant sections add error message when querying empty account don't need a link to golang.org link to sections, better section names fix section link reorganize sections add h3s remove & symbol add whitespace update h3 to h2 add note about explorer not connecting to every node * testnets: minor readme update * gaiadebug tool * gaiadebug: add hack command * fix from merge * gaiadebug: raw-bytes command * fix from merge --- CHANGELOG.md | 21 +- Makefile | 5 +- README.md | 8 + client/lcd/lcd_test.go | 7 +- cmd/gaia/cmd/gaiadebug/hack.go | 243 ++++ cmd/gaia/cmd/gaiadebug/main.go | 159 +++ cmd/gaia/testnets/README.md | 258 ++++ cmd/gaia/testnets/STATUS.md | 74 ++ cmd/gaia/testnets/gaia-5001/adrian.json | 20 + cmd/gaia/testnets/gaia-5001/anton.json | 20 + cmd/gaia/testnets/gaia-5001/aurel.json | 20 + cmd/gaia/testnets/gaia-5001/bucky.json | 20 + cmd/gaia/testnets/gaia-5001/cwgoes.json | 20 + cmd/gaia/testnets/gaia-5001/iris.json | 20 + cmd/gaia/testnets/gaia-5001/lino.json | 20 + cmd/gaia/testnets/gaia-5001/pbostrom.json | 20 + cmd/gaia/testnets/gaia-5001/poldsam.json | 20 + cmd/gaia/testnets/gaia-5001/staked.json | 20 + cmd/gaia/testnets/gaia-5001/zach.json | 20 + cmd/gaia/testnets/gaia-5001/zaki.json | 20 + cmd/gaia/testnets/gaia-6000/genesis.json | 1459 +++++++++++++++++++++ cmd/gaia/testnets/gaia-6001/genesis.json | 1459 +++++++++++++++++++++ version/version.go | 2 +- 23 files changed, 3929 insertions(+), 6 deletions(-) create mode 100644 cmd/gaia/cmd/gaiadebug/hack.go create mode 100644 cmd/gaia/cmd/gaiadebug/main.go create mode 100644 cmd/gaia/testnets/README.md create mode 100644 cmd/gaia/testnets/STATUS.md create mode 100644 cmd/gaia/testnets/gaia-5001/adrian.json create mode 100644 cmd/gaia/testnets/gaia-5001/anton.json create mode 100644 cmd/gaia/testnets/gaia-5001/aurel.json create mode 100644 cmd/gaia/testnets/gaia-5001/bucky.json create mode 100644 cmd/gaia/testnets/gaia-5001/cwgoes.json create mode 100644 cmd/gaia/testnets/gaia-5001/iris.json create mode 100644 cmd/gaia/testnets/gaia-5001/lino.json create mode 100644 cmd/gaia/testnets/gaia-5001/pbostrom.json create mode 100644 cmd/gaia/testnets/gaia-5001/poldsam.json create mode 100644 cmd/gaia/testnets/gaia-5001/staked.json create mode 100644 cmd/gaia/testnets/gaia-5001/zach.json create mode 100644 cmd/gaia/testnets/gaia-5001/zaki.json create mode 100644 cmd/gaia/testnets/gaia-6000/genesis.json create mode 100644 cmd/gaia/testnets/gaia-6001/genesis.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 300b71fb6..f40117f82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ FIXES ## 0.18.0 -_2018-06-05_ +*June 9, 2018* BREAKING CHANGES @@ -87,8 +87,27 @@ BUG FIXES * query sequence via account store * fixed duplicate pub_key in stake.Validator * Auto-sequencing now works correctly +* [gaiacli] Fix error message when account isn't found when running gaiacli account +## 0.17.5 + +*June 5, 2018* + +Update to Tendermint v0.19.9 (Fix evidence reactor, mempool deadlock, WAL panic, +memory leak) + +## 0.17.4 + +*May 31, 2018* + +Update to Tendermint v0.19.7 (WAL fixes and more) + +## 0.17.3 + +*May 29, 2018* + +Update to Tendermint v0.19.6 (fix fast-sync halt) ## 0.17.5 diff --git a/Makefile b/Makefile index d6444b0b6..c0d18c4a3 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,9 @@ install_examples: go install $(BUILD_FLAGS) ./examples/democoin/cmd/democoind go install $(BUILD_FLAGS) ./examples/democoin/cmd/democli +install_debug: + go install $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiadebug + dist: @bash publish/dist.sh @bash publish/publish.sh @@ -157,4 +160,4 @@ remotenet-status: # 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_cli test_unit test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update remotenet-start remotenet-stop remotenet-status +.PHONY: build build_examples install install_examples install_debug 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 remotenet-start remotenet-stop remotenet-status diff --git a/README.md b/README.md index 3faf2c8af..3af98fb4f 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,14 @@ master | [![CircleCI](https://circleci.com/gh/cosmos/cosmos-sdk/tree/master.s **Note**: Requires [Go 1.10+](https://golang.org/dl/) +## Testnet + +For more information on connecting to the testnet, see +[cmd/gaia/testnets](/cmd/gaia/testnets) + +For the latest status of the testnet, see the [status +file](/cmd/gaia/testnets/STATUS.md). + ## Overview diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 946f70bbc..ba2937e05 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -396,9 +396,10 @@ func TestBonding(t *testing.T) { // TODO fix shares fn in staking // query sender - //acc = getAccount(t, port, addr) - //coins = acc.GetCoins() - //assert.Equal(t, int64(70), coins.AmountOf(denom)) + //acc := getAccount(t, sendAddr) + //coins := acc.GetCoins() + //assert.Equal(t, int64(98), coins.AmountOf(coinDenom)) + } //_____________________________________________________________________________ diff --git a/cmd/gaia/cmd/gaiadebug/hack.go b/cmd/gaia/cmd/gaiadebug/hack.go new file mode 100644 index 000000000..2c84184bf --- /dev/null +++ b/cmd/gaia/cmd/gaiadebug/hack.go @@ -0,0 +1,243 @@ +package main + +import ( + "encoding/base64" + "encoding/hex" + "fmt" + "os" + "path" + + "github.com/spf13/cobra" + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + 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/slashing" + "github.com/cosmos/cosmos-sdk/x/stake" + + gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" +) + +func runHackCmd(cmd *cobra.Command, args []string) error { + + if len(args) != 1 { + return fmt.Errorf("Expected 1 arg") + } + + // ".gaiad" + dataDir := args[0] + dataDir = path.Join(dataDir, "data") + + // load the app + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + db, err := dbm.NewGoLevelDB("gaia", dataDir) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + app := NewGaiaApp(logger, db) + + // print some info + id := app.LastCommitID() + lastBlockHeight := app.LastBlockHeight() + fmt.Println("ID", id) + fmt.Println("LastBlockHeight", lastBlockHeight) + + //---------------------------------------------------- + // XXX: start hacking! + //---------------------------------------------------- + // eg. gaia-6001 testnet bug + // We paniced when iterating through the "bypower" keys. + // The following powerKey was there, but the corresponding "trouble" validator did not exist. + // So here we do a binary search on the past states to find when the powerKey first showed up ... + + // owner of the validator the bonds, gets revoked, later unbonds, and then later is still found in the bypower store + trouble := hexToBytes("D3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") + // this is his "bypower" key + powerKey := hexToBytes("05303030303030303030303033FFFFFFFFFFFF4C0C0000FFFED3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") + + topHeight := lastBlockHeight + bottomHeight := int64(0) + checkHeight := topHeight + for { + // load the given version of the state + err = app.LoadVersion(checkHeight, app.keyMain) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + ctx := app.NewContext(true, abci.Header{}) + + // check for the powerkey and the validator from the store + store := ctx.KVStore(app.keyStake) + res := store.Get(powerKey) + val, _ := app.stakeKeeper.GetValidator(ctx, trouble) + fmt.Println("checking height", checkHeight, res, val) + if res == nil { + bottomHeight = checkHeight + } else { + topHeight = checkHeight + } + checkHeight = (topHeight + bottomHeight) / 2 + } +} + +func base64ToPub(b64 string) crypto.PubKeyEd25519 { + data, _ := base64.StdEncoding.DecodeString(b64) + var pubKey crypto.PubKeyEd25519 + copy(pubKey[:], data) + return pubKey + +} + +func hexToBytes(h string) []byte { + trouble, _ := hex.DecodeString(h) + return trouble + +} + +//-------------------------------------------------------------------------------- +// NOTE: This is all copied from gaia/app/app.go +// so we can access internal fields! + +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 + cdc *wire.Codec + + // keys to access the substores + keyMain *sdk.KVStoreKey + keyAccount *sdk.KVStoreKey + keyIBC *sdk.KVStoreKey + keyStake *sdk.KVStoreKey + keySlashing *sdk.KVStoreKey + + // Manage getting and setting accounts + accountMapper auth.AccountMapper + feeCollectionKeeper auth.FeeCollectionKeeper + coinKeeper bank.Keeper + ibcMapper ibc.Mapper + stakeKeeper stake.Keeper + slashingKeeper slashing.Keeper +} + +func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { + cdc := MakeCodec() + + // create your application object + var app = &GaiaApp{ + 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"), + keySlashing: sdk.NewKVStoreKey("slashing"), + } + + // 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)) + app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.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)) + + // initialize BaseApp + app.SetInitChainer(app.initChainer) + app.SetBeginBlocker(app.BeginBlocker) + app.SetEndBlocker(app.EndBlocker) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) + app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing) + 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() + ibc.RegisterWire(cdc) + bank.RegisterWire(cdc) + stake.RegisterWire(cdc) + slashing.RegisterWire(cdc) + auth.RegisterWire(cdc) + sdk.RegisterWire(cdc) + wire.RegisterCrypto(cdc) + return cdc +} + +// application updates every end block +func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) + + return abci.ResponseBeginBlock{ + Tags: tags.ToKVPairs(), + } +} + +// application updates every end block +func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) + + return abci.ResponseEndBlock{ + ValidatorUpdates: validatorUpdates, + } +} + +// custom logic for gaia initialization +func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + stateJSON := req.AppStateBytes + // TODO is this now the whole genesis file? + + var genesisState gaia.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, "") + } + + // load the accounts + for _, gacc := range genesisState.Accounts { + acc := gacc.ToAccount() + app.accountMapper.SetAccount(ctx, acc) + } + + // load the initial stake information + stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + return abci.ResponseInitChain{} + +} diff --git a/cmd/gaia/cmd/gaiadebug/main.go b/cmd/gaia/cmd/gaiadebug/main.go new file mode 100644 index 000000000..79045c07b --- /dev/null +++ b/cmd/gaia/cmd/gaiadebug/main.go @@ -0,0 +1,159 @@ +package main + +import ( + "bytes" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "os" + "strconv" + "strings" + + gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/spf13/cobra" + crypto "github.com/tendermint/go-crypto" +) + +func init() { + rootCmd.AddCommand(txCmd) + rootCmd.AddCommand(pubkeyCmd) + rootCmd.AddCommand(hackCmd) + rootCmd.AddCommand(rawBytesCmd) +} + +var rootCmd = &cobra.Command{ + Use: "gaiadebug", + Short: "Gaia debug tool", + SilenceUsage: true, +} + +var txCmd = &cobra.Command{ + Use: "tx", + Short: "Decode a gaia tx from hex or base64", + RunE: runTxCmd, +} + +var pubkeyCmd = &cobra.Command{ + Use: "pubkey", + Short: "Decode a pubkey from hex or base64", + RunE: runPubKeyCmd, +} + +var hackCmd = &cobra.Command{ + Use: "hack", + Short: "Boilerplate to Hack on an existing state by scripting some Go...", + RunE: runHackCmd, +} + +var rawBytesCmd = &cobra.Command{ + Use: "raw-bytes", + Short: "Convert raw bytes output (eg. [10 21 13 255]) to hex", + RunE: runRawBytesCmd, +} + +func runRawBytesCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("Expected single arg") + } + stringBytes := args[0] + stringBytes = strings.Trim(stringBytes, "[") + stringBytes = strings.Trim(stringBytes, "]") + spl := strings.Split(stringBytes, " ") + + byteArray := []byte{} + for _, s := range spl { + b, err := strconv.Atoi(s) + if err != nil { + return err + } + byteArray = append(byteArray, byte(b)) + } + fmt.Printf("%X\n", byteArray) + return nil +} + +func runPubKeyCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("Expected single arg") + } + + pubkeyString := args[0] + + // try hex, then base64 + pubkeyBytes, err := hex.DecodeString(pubkeyString) + if err != nil { + var err2 error + pubkeyBytes, err2 = base64.StdEncoding.DecodeString(pubkeyString) + if err2 != nil { + return fmt.Errorf(`Expected hex or base64. Got errors: + hex: %v, + base64: %v + `, err, err2) + } + } + + cdc := gaia.MakeCodec() + var pubKey crypto.PubKeyEd25519 + copy(pubKey[:], pubkeyBytes) + pubKeyJSONBytes, err := cdc.MarshalJSON(pubKey) + if err != nil { + return err + } + fmt.Println("Address:", pubKey.Address()) + fmt.Printf("Hex: %X\n", pubkeyBytes) + fmt.Println("JSON (base64):", string(pubKeyJSONBytes)) + return nil +} + +func runTxCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return fmt.Errorf("Expected single arg") + } + + txString := args[0] + + // try hex, then base64 + txBytes, err := hex.DecodeString(txString) + if err != nil { + var err2 error + txBytes, err2 = base64.StdEncoding.DecodeString(txString) + if err2 != nil { + return fmt.Errorf(`Expected hex or base64. Got errors: + hex: %v, + base64: %v + `, err, err2) + } + } + + var tx = auth.StdTx{} + cdc := gaia.MakeCodec() + + err = cdc.UnmarshalBinary(txBytes, &tx) + if err != nil { + return err + } + + bz, err := cdc.MarshalJSON(tx) + if err != nil { + return err + } + + buf := bytes.NewBuffer([]byte{}) + err = json.Indent(buf, bz, "", " ") + if err != nil { + return err + } + + fmt.Println(buf.String()) + return nil +} + +func main() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } + os.Exit(0) +} diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md new file mode 100644 index 000000000..b34926aed --- /dev/null +++ b/cmd/gaia/testnets/README.md @@ -0,0 +1,258 @@ +# Connect to the `gaia-6001` Testnet + +Note: We are aware this documentation is sub-par. We are working to +improve the tooling and the documentation to make this process as painless as +possible. In the meantime, join the +[Validator Chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org) +for technical support. Thanks very much for your patience. :) + +## Setting Up a New Node + +These instructions are for setting up a brand new full node from scratch. If you ran a full node on a previous testnet, please skip to [Upgrading From Previous Testnet](#upgrading-from-previous-testnet). + +### Install Go + +Install `go` by following the [official docs](https://golang.org/doc/install). +**Go 1.10+** is required for the Cosmos SDK. + +### Install Cosmos SDK + +Next, let's install the testnet's version of the Cosmos SDK. + +``` +mkdir -p $GOPATH/src/github.com/cosmos +cd $GOPATH/src/github.com/cosmos +git clone https://github.com/cosmos/cosmos-sdk +cd cosmos-sdk && git checkout v0.18.0 +make get_tools && make get_vendor_deps && make install +``` + +That will install the `gaiad` and `gaiacli` binaries. Verify that everything is OK: + +``` +gaiad version +0.18.0-eceb56b7 +``` + +### Node Setup + +Create the required configuration files: + +``` +gaiad init +``` + +Name your node by editing the `moniker` in `$HOME/.gaiad/config/config.toml`. Note that only ASCII characters are supported. Using Unicode renders your node unconnectable. + +``` +# A custom human readable name for this node +moniker = "" +``` + +Your full node has been initialized! Please skip to [Genesis & Seeds](#genesis--seeds). + +## Upgrading From Previous Testnet + +These instructions are for full nodes that have ran on previous testnets and would like to upgrade to the latest testnet. + +### Reset Data + +First, remove the outdated files and reset the data. + +``` +rm $HOME/.gaiad/config/addrbook.json $HOME/.gaiad/config/genesis.json +gaiad unsafe_reset_all +``` + +Your node is now in a pristine state while keeping the original `priv_validator.json` and `config.toml`. If you had any sentry nodes or full nodes setup before, +your node will still try to connect to them, but may fail if they haven't also +been upgraded. + +**WARNING:** Make sure that every node has a unique `priv_validator.json`. Do not copy the `priv_validator.json` from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign. + +### Software Upgrade + +Now it is time to upgrade the software: + +``` +cd $GOPATH/src/github.com/cosmos/cosmos-sdk +git fetch --all && git checkout v0.18.0 +make update_tools && make get_vendor_deps && make install +``` + +Your full node has been cleanly upgraded! + +## Genesis & Seeds + +### Copy the Genesis File + +Copy the testnet's `genesis.json` file and place it in `gaiad`'s config directory. + +``` +mkdir -p $HOME/.gaiad/config +cp -a $GOPATH/src/github.com/cosmos/cosmos-sdk/cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json +``` + +### Add Seed Nodes + +Your node needs to know how to find peers. You'll need to add healthy seed nodes to `$HOME/.gaiad/config/config.toml`. Here are some seed nodes you can use: + +``` +# Comma separated list of seed nodes to connect to +seeds = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" +``` + +You can also [ask other validators](https://riot.im/app/#/room/#cosmos_validators:matrix.org) for a persistent peer and add it under the `persistent_peers` key. For more information on seeds and peers, [read this](https://github.com/tendermint/tendermint/blob/develop/docs/using-tendermint.md#peers). + +## Run a Full Node + +Start the full node with this command: + +``` +gaiad start +``` + +Check that everything is running smoothly: + +``` +gaiacli status +``` + +View the status of the network with the [Cosmos Explorer](https://explorecosmos.network). Once your full node syncs up to the current block height, you should see it appear on the [list of full nodes](https://explorecosmos.network/validators). If it doesn't show up, that's ok--the Explorer does not connect to every node. + +## Generate Keys + +You'll need a private and public key pair \(a.k.a. `sk, pk` respectively\) to be able to receive funds, send txs, bond tx, etc. + +To generate a new key \(default _ed25519_ elliptic curve\): + +``` +gaiacli keys add +``` + +Next, you will have to create a passphrase. Save the _seed_ _phrase_ in a safe place in case you forget the password. + +If you check your private keys, you'll now see ``: + +``` +gaiacli keys show +``` + +You can see all your available keys by typing: + +``` +gaiacli keys list +``` + +View the validator pubkey for your node by typing: + +``` +gaiad tendermint show_validator +``` + +Save your address and pubkey to environment variables for later use: + +``` +MYADDR= +MYPUBKEY= +``` + +**WARNING:** We strongly recommend NOT using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. + +## Get Tokens + +The best way to get tokens is from the [Cosmos Testnet Faucet](https://faucetcosmos.network). If the faucet is not working for you, try asking [#cosmos-validators](https://riot.im/app/#/room/#cosmos-validators:matrix.org). + +After receiving tokens to your address, you can view your account's balance by typing: + +``` +gaiacli account +``` + +Note: When you query an account balance with zero tokens, you will get this error: `No account with address was found in the state.` This is expected! We're working on improving our error messages. + +## Send Tokens + +``` +gaiacli send --amount=10faucetToken --chain-id= --name= --to= +``` + +Note: The `--amount` flag accepts the format `--amount=`. + +Now, view the updated balances of the origin and destination accounts: + +``` +gaiacli account +gaiacli account +``` + +You can also check your balance at a given block by using the `--block` flag: + +``` +gaiacli account --block= +``` + +## Run a Validator Node + +[Validators](https://cosmos.network/validators) are responsible for committing new blocks to the blockchain through voting. A validator's stake is slashed if they become unavailable, double sign a transaction, or don't cast their votes. If you only want to run a full node, a VM in the cloud is fine. However, if you are want to become a validator for the Hub's `mainnet`, you should research hardened setups. Please read [Sentry Node Architecture](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#how-can-validators-protect-themselves-from-denial-of-service-attacks) to protect your node from DDOS and ensure high-availability. Also see the [technical requirements](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#technical-requirements)). There's also more info on our [website](https://cosmos.network/validators). + +Your `pubkey` can be used to create a new validator by staking tokens. You can find your validator pubkey by running: + +``` +gaiad tendermint show_validator +``` + +Next, craft your `gaiacli stake create-validator` command: + +``` +gaiacli stake create-validator --amount=5steak --pubkey= --address-validator= --moniker=satoshi --chain-id= --name= +``` + +You can add more information to the validator, such as`--website`, `--keybase-sig`, or `--details`. Here's how: + +``` +gaiacli stake edit-validator --details="To the cosmos !" --website="https://cosmos.network" +``` + +View the validator's information with this command: + +``` +gaiacli stake validator --address-validator= --chain-id= +``` + +To check that the validator is active, look for it here: + +``` +gaiacli advanced tendermint validator-set +``` + +**Note:** To be in the validator set, you need to have more total voting power than the 100th validator. + +## Delegating to a Validator + +On the upcoming mainnet, you can delegate `atom` to a validator. These [delegators](https://cosmos.network/resources/delegators) can receive part of the validator's fee revenue. Read more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf). + +### Bond Tokens + +On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator: + +``` +gaiacli stake delegate --amount=10steak --address-delegator= --address-validator= --name= --chain-id= +``` + +While tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain a percentage of shares that equal their stake in this pool. + +### Unbond Tokens + +If for any reason the validator misbehaves, or you want to unbond a certain amount of tokens, use this following command. You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\). + +``` +gaiacli stake unbond --address-delegator= --address-validator= --shares=MAX --name= --chain-id= +``` + +You can check your balance and your stake delegation to see that the unbonding went through successfully. + +``` +gaiacli account +gaiacli stake delegation --address-delegator= --address-validator= --chain-id= +``` diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md new file mode 100644 index 000000000..d53c49e09 --- /dev/null +++ b/cmd/gaia/testnets/STATUS.md @@ -0,0 +1,74 @@ +# TESTNET STATUS + +## *June 10, 2018, 8:30 EST* - Gaia-6001 consensus failure + +- Validator unbonding and revocation activity caused a consensus failure +- There is a bug in the staking module that must be fixed +- The team is taking its time to look into this and release a fix following a + proper protocol for hotfix upgrades to the testnet +- Please stay tuned! + +## *June 9, 2018, 14:00 EST* - New Release + +- Released gaia + [v0.18.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.18.0) with + update for Tendermint + [v0.20.0](https://github.com/tendermint/tendermint/releases/tag/v0.20.0) +- Includes bug fix for declaring candidacy from the command line + +## *June 8, 2018, 23:30 EST* - Gaia-6001 is making blocks + +- +2/3 of the voting power is finally online for Gaia-6001 and it is making + blocks! +- This is a momentous achievement - a successful asynchronous decentralized + testnet launch +- Congrats everyone! + +## *June 8, 2018, 12:00 EST* - New Testnet Gaia-6001 + +- After some confusion around testnet deployment and a contention testnet + hardfork, a new genesis file and network was released for `gaia-6001` + +## *June 7, 2018, 9:00 EST* - New Testnet Gaia-6000 + +- Released a new `genesis.json` file for `gaia-6000` +- Initial validators include those that were most active in + the gaia-5001 testnet +- Join the network via gaia `v0.18.0-rc0` + +## *June 5, 2018, 21:00 EST* - New Release + +- Released gaia + [v0.17.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.17.5) + with update for Tendermint + [v0.19.9](https://github.com/tendermint/tendermint/releases/tag/v0.19.9) +- Fixes many bugs! + - evidence gossipping + - mempool deadlock + - WAL panic + - memory leak +- Please update to this to put a stop to the rampant invalid evidence gossiping + :) + +## *May 31, 2018, 14:00 EST* - New Release + +- Released gaia + [v0.17.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.17.4) with update for Tendermint v0.19.7 +- Fixes a WAL bug and some more +- Please update to this if you have trouble restarting a node + +## *May 31, 2018, 2:00 EST* - Testnet Halt + +- A validator equivocated last week and Evidence is being rampantly gossipped +- Peers that can't process the evidence (either too far behind or too far ahead) are disconnecting from the peers that + sent it, causing high peer turn-over +- The high peer turn-over may be causing a memory-leak, resulting in some nodes + crashing and the testnet halting +- We need to fix some issues in the EvidenceReactor to address this and also + investigate the possible memory-leak + +## *May 29, 2018* - New Release + +- Released v0.17.3 with update for Tendermint v0.19.6 +- Fixes fast-sync bug +- Please update to this to sync with the testnet diff --git a/cmd/gaia/testnets/gaia-5001/adrian.json b/cmd/gaia/testnets/gaia-5001/adrian.json new file mode 100644 index 000000000..7ca99cb1e --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/adrian.json @@ -0,0 +1,20 @@ +{ + "node_id": "1ebc5ca705b3ae1c06a0888ff1287ada82149dc3", + "ip": "138.68.77.24", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "power": 100, + "name": "adrian" + }, + "app_gen_tx": { + "name": "default", + "address": "D9C12CB5186FE0018179742FD3110EE534C63460", + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/anton.json b/cmd/gaia/testnets/gaia-5001/anton.json new file mode 100644 index 000000000..701e85887 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/anton.json @@ -0,0 +1,20 @@ +{ + "node_id": "c272ae3cff7558db2c6195eea38fd43fd08406dc", + "ip": "206.189.31.178", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "tJlZJWjOpYvRitYFTWNPTaUtvQVf+hoNjlfI84VPqvI=" + }, + "power": 100, + "name": "anton" + }, + "app_gen_tx": { + "name": "default", + "address": "E766088FD171906289617F60BF0014C46F0F85EC", + "pub_key": { + "type": "AC26791624DE60", + "value": "tJlZJWjOpYvRitYFTWNPTaUtvQVf+hoNjlfI84VPqvI=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/aurel.json b/cmd/gaia/testnets/gaia-5001/aurel.json new file mode 100644 index 000000000..0c2ea8166 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/aurel.json @@ -0,0 +1,20 @@ +{ + "node_id": "aef085c4bfed0c1ffc6705f2e1e3bf85e5164600", + "ip": "45.77.53.208", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "power": 100, + "name": "aurel" + }, + "app_gen_tx": { + "name": "aurel", + "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/bucky.json b/cmd/gaia/testnets/gaia-5001/bucky.json new file mode 100644 index 000000000..fc4bb51cd --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/bucky.json @@ -0,0 +1,20 @@ +{ + "node_id": "b0dd378c3fbc4c156cd6d302a799f0d2e4227201", + "ip": "159.89.121.174", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "power": 100, + "name": "bucky" + }, + "app_gen_tx": { + "name": "bucky", + "address": "935E48ED79F1006ED135553768E1D9A768747CF6", + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/cwgoes.json b/cmd/gaia/testnets/gaia-5001/cwgoes.json new file mode 100644 index 000000000..dce7e20c9 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/cwgoes.json @@ -0,0 +1,20 @@ +{ + "node_id": "e25603602d8cf8542570ad0e311d50f55f497f85", + "ip": "158.69.63.13", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "power": 100, + "name": "cwgoes" + }, + "app_gen_tx": { + "name": "cwgoes", + "address": "328FBB8EA315D070DF908982A5F91A3618001D20", + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/iris.json b/cmd/gaia/testnets/gaia-5001/iris.json new file mode 100644 index 000000000..1a1019672 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/iris.json @@ -0,0 +1,20 @@ +{ + "node_id": "aabf05a67b2f399807dc602d05bf97b0ed283ac2", + "ip": "116.62.62.39", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "power": 100, + "name": "iris" + }, + "app_gen_tx": { + "name": "=suyu", + "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + } + } +} \ No newline at end of file diff --git a/cmd/gaia/testnets/gaia-5001/lino.json b/cmd/gaia/testnets/gaia-5001/lino.json new file mode 100644 index 000000000..5bc98bb6e --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/lino.json @@ -0,0 +1,20 @@ +{ + "node_id": "79466a03e9d4b4648a7dd8cead1fa7121ce76ee3", + "ip": "34.235.130.1", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "power": 100, + "name": "lino" + }, + "app_gen_tx": { + "name": "lino", + "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/pbostrom.json b/cmd/gaia/testnets/gaia-5001/pbostrom.json new file mode 100644 index 000000000..59cd46950 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/pbostrom.json @@ -0,0 +1,20 @@ +{ + "node_id": "adb290585a2753bf1a520c76802b0dab3dffa895", + "ip": "34.201.21.179", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "power": 100, + "name": "pbostrom" + }, + "app_gen_tx": { + "name": "default", + "address": "109720515B4F8C0858DA3521E448262334534FFD", + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/poldsam.json b/cmd/gaia/testnets/gaia-5001/poldsam.json new file mode 100644 index 000000000..8149a9259 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/poldsam.json @@ -0,0 +1,20 @@ +{ + "node_id": "678503e6c8f50db7279c7da3cb9b072aac4bc0d5", + "ip": "35.193.188.125", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "power": 100, + "name": "polsdam" + }, + "app_gen_tx": { + "name": "poldsam", + "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/staked.json b/cmd/gaia/testnets/gaia-5001/staked.json new file mode 100644 index 000000000..f39cced6b --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/staked.json @@ -0,0 +1,20 @@ +{ + "node_id": "3519f05985394107e0b2e285361b7e012adb1113", + "ip": "54.209.118.64", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "vq0V0BjpmIh6WyNnFpMaO5LyUK2FamkNt65eJYa5AaQ=" + }, + "power": 100, + "name": "staked" + }, + "app_gen_tx": { + "name": "default", + "address": "935E04662697134905706A4CCDB822AC6FC11C2E", + "pub_key": { + "type": "AC26791624DE60", + "value": "vq0V0BjpmIh6WyNnFpMaO5LyUK2FamkNt65eJYa5AaQ=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/zach.json b/cmd/gaia/testnets/gaia-5001/zach.json new file mode 100644 index 000000000..76a08cc92 --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/zach.json @@ -0,0 +1,20 @@ +{ + "node_id": "8a2802fb25d352f3e7e277559a4f683780c3ef22", + "ip": "167.99.191.184", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "power": 100, + "name": "" + }, + "app_gen_tx": { + "name": "zach", + "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-5001/zaki.json b/cmd/gaia/testnets/gaia-5001/zaki.json new file mode 100644 index 000000000..956f2bf8c --- /dev/null +++ b/cmd/gaia/testnets/gaia-5001/zaki.json @@ -0,0 +1,20 @@ +{ + "node_id": "30b45459e4881680c0ef1750fde136fefa6c3b98", + "ip": "35.184.182.143", + "validator": { + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "power": 100, + "name": "zaki" + }, + "app_gen_tx": { + "name": "zaki", + "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + } + } +} diff --git a/cmd/gaia/testnets/gaia-6000/genesis.json b/cmd/gaia/testnets/gaia-6000/genesis.json new file mode 100644 index 000000000..aefab9286 --- /dev/null +++ b/cmd/gaia/testnets/gaia-6000/genesis.json @@ -0,0 +1,1459 @@ +{ + "genesis_time": "2018-05-15T18:29:12.38288148Z", + "chain_id": "gaia-6000", + "consensus_params": { + "block_size_params": { + "max_bytes": 22020096, + "max_txs": 100000, + "max_gas": -1 + }, + "tx_size_params": { + "max_bytes": 10240, + "max_gas": -1 + }, + "block_gossip_params": { + "block_part_size_bytes": 65536 + }, + "evidence_params": { + "max_age": 100000 + } + }, + "validators": [ + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "power": 1000, + "name": "adrian" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "power": 1000, + "name": "zaki" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "power": 100, + "name": "staked" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "power": 1000, + "name": "polsdam" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "power": 1000, + "name": "lino" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "power": 100, + "name": "" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "power": 1000, + "name": "iris" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "power": 1000, + "name": "pbostrom" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "power": 1000, + "name": "aurel" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "power": 1000, + "name": "bucky" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "power": 100, + "name": "cwgoes" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "power": 1000, + "name": "bdnet" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "power": 1000, + "name": "melea-trust" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "power": 1000, + "name": "naruemon" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "power": 1000, + "name": "idoor" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "power": 1000, + "name": "ATEAM1" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "power": 1000, + "name": "figmatt" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "power": 1000, + "name": "jla-bsd" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "power": 1000, + "name": "Gold" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "power": 1000, + "name": "nylira" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "power": 1000, + "name": "BKCM" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "power": 1000, + "name": "Dev's Validator" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "power": 1000, + "name": "Staking Facilities" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "power": 1000, + "name": "nuevax" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "power": 1000, + "name": "vultr.guest" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "power": 1000, + "name": "forebole" + } + ], + "app_hash": "", + "app_state": { + "accounts": [ + { + "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "coins": [ + { + "denom": "devToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "coins": [ + { + "denom": "adrianToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "109720515B4F8C0858DA3521E448262334534FFD", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "coins": [ + { + "denom": "aurelToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "328FBB8EA315D070DF908982A5F91A3618001D20", + "coins": [ + { + "denom": "cwgoesToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "coins": [ + { + "denom": "BKCMToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "coins": [ + { + "denom": "BDToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "coins": [ + { + "denom": "suyuToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "coins": [ + { + "denom": "linoToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "coins": [ + { + "denom": "stakingToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E04662697134905706A4CCDB822AC6FC11C2E", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E48ED79F1006ED135553768E1D9A768747CF6", + "coins": [ + { + "denom": "buckyToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", + "coins": [ + { + "denom": "kwunyeungToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zachToken", + "amount": 1000 + } + ] + }, + { + "address": "A323EC45243D600204BA3D298E3C20322D08C84C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "nuevaxToken", + "amount": 1000 + } + ] + }, + { + "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "dokiaToken", + "amount": 1000 + } + ] + }, + { + "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "forboleToken", + "amount": 1000 + } + ] + }, + { + "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "coins": [ + { + "denom": "steak", + "amount": 100 + }, + { + "denom": "pengToken", + "amount": 1000 + } + ] + }, + { + "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", + "coins": [ + { + "denom": "steak", + "amount": 900 + }, + { + "denom": "faucetToken", + "amount": 10000000 + } + ] + }, + { + "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "goldToken", + "amount": 100 + } + ] + }, + { + "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "jlaToken", + "amount": 100 + } + ] + }, + { + "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "figmattToken", + "amount": 100 + } + ] + }, + { + "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "ATEAM1Token", + "amount": 100 + } + ] + }, + { + "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "idoorToken", + "amount": 100 + } + ] + }, + { + "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "naruemonToken", + "amount": 100 + } + ] + }, + { + "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zakiToken", + "amount": 1000 + } + ] + }, + { + "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "trustToken", + "amount": 1000 + } + ] + }, + { + "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "coins": [ + { + "denom": "poldsamToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + } + ], + "stake": { + "pool": { + "loose_unbonded_tokens": 2350, + "unbonded_tokens": 0, + "unbonding_tokens": 0, + "bonded_tokens": 25200, + "unbonded_shares": "0", + "unbonding_shares": "0", + "bonded_shares": "25200", + "inflation_last_time": 0, + "inflation": "9012837/100000000", + "date_last_commission_reset": 0, + "prev_bonded_shares": "0" + }, + "params": { + "inflation_rate_change": "13/100", + "inflation_max": "1/5", + "inflation_min": "7/100", + "goal_bonded": "67/100", + "max_validators": 100, + "bond_denom": "steak" + }, + "bonds": [ + { + "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "shares": "1000", + "height": 0 + } + ], + "validators": [ + { + "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "description": { + "moniker": "Dev's Validator", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "109720515B4F8C0858DA3521E448262334534FFD", + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "description": { + "moniker": "", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "description": { + "moniker": "aurel", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "description": { + "moniker": "cwgoes", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "description": { + "moniker": "BKCM", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "description": { + "moniker": "bdnet", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "description": { + "moniker": "suyu", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "description": { + "moniker": "lino", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "description": { + "moniker": "Staking Facilities", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "description": { + "moniker": "default", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "description": { + "moniker": "bucky", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "description": { + "moniker": "zach", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "description": { + "moniker": "nuevax", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "description": { + "moniker": "vultr.guest", + "identity": "", + "website": "https://ion.dokia.capital/", + "details": "DokiaValidator" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "description": { + "moniker": "forbole", + "identity": "", + "website": "https://www.forbole.com", + "details": "Recommend. Refer. Reward" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "description": { + "moniker": "nylira", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "description": { + "moniker": "Gold", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "description": { + "moniker": "jla-bsd", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "description": { + "moniker": "figmatt", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "description": { + "moniker": "ATEAM1", + "identity": "", + "website": "", + "details": "ATEAM1" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "description": { + "moniker": "idoor", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "description": { + "moniker": "naruemon", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "description": { + "moniker": "Adrian Brink - Cryptium Labs", + "identity": "", + "website": "https://cryptium.ch", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "description": { + "moniker": "zaki", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "description": { + "moniker": "trust", + "identity": "", + "website": "http://cosmos-trust.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "description": { + "moniker": "proof-of-audit", + "identity": "", + "website": "https://proof-of-audit.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + } + ] + } + } +} diff --git a/cmd/gaia/testnets/gaia-6001/genesis.json b/cmd/gaia/testnets/gaia-6001/genesis.json new file mode 100644 index 000000000..512d761be --- /dev/null +++ b/cmd/gaia/testnets/gaia-6001/genesis.json @@ -0,0 +1,1459 @@ +{ + "genesis_time": "2018-05-15T18:29:12.38288148Z", + "chain_id": "gaia-6001", + "consensus_params": { + "block_size_params": { + "max_bytes": 22020096, + "max_txs": 100000, + "max_gas": -1 + }, + "tx_size_params": { + "max_bytes": 10240, + "max_gas": -1 + }, + "block_gossip_params": { + "block_part_size_bytes": 65536 + }, + "evidence_params": { + "max_age": 100000 + } + }, + "validators": [ + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "power": 1000, + "name": "adrian" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "power": 1000, + "name": "zaki" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "power": 100, + "name": "staked" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "power": 1000, + "name": "polsdam" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "power": 1000, + "name": "lino" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "power": 100, + "name": "" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "power": 1000, + "name": "iris" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "power": 1000, + "name": "pbostrom" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "power": 1000, + "name": "aurel" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "power": 1000, + "name": "bucky" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "power": 100, + "name": "cwgoes" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "power": 1000, + "name": "bdnet" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "power": 1000, + "name": "melea-trust" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "power": 1000, + "name": "naruemon" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "power": 1000, + "name": "idoor" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "power": 1000, + "name": "ATEAM1" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "power": 1000, + "name": "figmatt" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "power": 1000, + "name": "jla-bsd" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "power": 1000, + "name": "Gold" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "power": 1000, + "name": "nylira" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "power": 1000, + "name": "BKCM" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "power": 1000, + "name": "Dev's Validator" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "power": 1000, + "name": "Staking Facilities" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "power": 1000, + "name": "nuevax" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "power": 1000, + "name": "vultr.guest" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "power": 1000, + "name": "forebole" + } + ], + "app_hash": "", + "app_state": { + "accounts": [ + { + "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "coins": [ + { + "denom": "devToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "coins": [ + { + "denom": "adrianToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "109720515B4F8C0858DA3521E448262334534FFD", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "coins": [ + { + "denom": "aurelToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "328FBB8EA315D070DF908982A5F91A3618001D20", + "coins": [ + { + "denom": "cwgoesToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "coins": [ + { + "denom": "BKCMToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "coins": [ + { + "denom": "BDToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "coins": [ + { + "denom": "suyuToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "coins": [ + { + "denom": "linoToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "coins": [ + { + "denom": "stakingToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E04662697134905706A4CCDB822AC6FC11C2E", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E48ED79F1006ED135553768E1D9A768747CF6", + "coins": [ + { + "denom": "buckyToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", + "coins": [ + { + "denom": "kwunyeungToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zachToken", + "amount": 1000 + } + ] + }, + { + "address": "A323EC45243D600204BA3D298E3C20322D08C84C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "nuevaxToken", + "amount": 1000 + } + ] + }, + { + "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "dokiaToken", + "amount": 1000 + } + ] + }, + { + "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "forboleToken", + "amount": 1000 + } + ] + }, + { + "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "coins": [ + { + "denom": "steak", + "amount": 100 + }, + { + "denom": "pengToken", + "amount": 1000 + } + ] + }, + { + "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", + "coins": [ + { + "denom": "steak", + "amount": 900 + }, + { + "denom": "faucetToken", + "amount": 10000000 + } + ] + }, + { + "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "goldToken", + "amount": 100 + } + ] + }, + { + "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "jlaToken", + "amount": 100 + } + ] + }, + { + "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "figmattToken", + "amount": 100 + } + ] + }, + { + "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "ATEAM1Token", + "amount": 100 + } + ] + }, + { + "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "idoorToken", + "amount": 100 + } + ] + }, + { + "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "naruemonToken", + "amount": 100 + } + ] + }, + { + "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zakiToken", + "amount": 1000 + } + ] + }, + { + "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "trustToken", + "amount": 1000 + } + ] + }, + { + "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "coins": [ + { + "denom": "poldsamToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + } + ], + "stake": { + "pool": { + "loose_unbonded_tokens": 2300, + "unbonded_tokens": 0, + "unbonding_tokens": 0, + "bonded_tokens": 23300, + "unbonded_shares": "0", + "unbonding_shares": "0", + "bonded_shares": "23300", + "inflation_last_time": 0, + "inflation": "9012837/100000000", + "date_last_commission_reset": 0, + "prev_bonded_shares": "0" + }, + "params": { + "inflation_rate_change": "13/100", + "inflation_max": "1/5", + "inflation_min": "7/100", + "goal_bonded": "67/100", + "max_validators": 100, + "bond_denom": "steak" + }, + "bonds": [ + { + "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "shares": "1000", + "height": 0 + } + ], + "validators": [ + { + "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "description": { + "moniker": "Dev's Validator", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "109720515B4F8C0858DA3521E448262334534FFD", + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "description": { + "moniker": "", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "description": { + "moniker": "aurel", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "description": { + "moniker": "cwgoes", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "description": { + "moniker": "BKCM", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "description": { + "moniker": "bdnet", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "description": { + "moniker": "suyu", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "description": { + "moniker": "lino", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "description": { + "moniker": "Staking Facilities", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "description": { + "moniker": "default", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "description": { + "moniker": "bucky", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "description": { + "moniker": "zach", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "description": { + "moniker": "nuevax", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "description": { + "moniker": "vultr.guest", + "identity": "", + "website": "https://ion.dokia.capital/", + "details": "DokiaValidator" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "description": { + "moniker": "forbole", + "identity": "", + "website": "https://www.forbole.com", + "details": "Recommend. Refer. Reward" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "description": { + "moniker": "nylira", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "description": { + "moniker": "Gold", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "description": { + "moniker": "jla-bsd", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "description": { + "moniker": "figmatt", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "description": { + "moniker": "ATEAM1", + "identity": "", + "website": "", + "details": "ATEAM1" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "description": { + "moniker": "idoor", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "description": { + "moniker": "naruemon", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "description": { + "moniker": "Adrian Brink - Cryptium Labs", + "identity": "", + "website": "https://cryptium.ch", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "description": { + "moniker": "zaki", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "description": { + "moniker": "trust", + "identity": "", + "website": "http://cosmos-trust.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "description": { + "moniker": "proof-of-audit", + "identity": "", + "website": "https://proof-of-audit.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + } + ] + } + } +} diff --git a/version/version.go b/version/version.go index 116f1ff28..20074c7bc 100644 --- a/version/version.go +++ b/version/version.go @@ -9,7 +9,7 @@ const Maj = "0" const Min = "18" const Fix = "0" -const Version = "0.18.0-dev" +const Version = "0.18.0" // GitCommit set by build flags var GitCommit = "" From 219a16c6de8641c59785688fdb9099acd4437bd6 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 13 Jun 2018 09:57:54 +0200 Subject: [PATCH 77/89] Revert "Merge PR #1232: Bucky/gaiadebug" This reverts commit 37bba35c91e7ade8f7a160ceb2c37b322fed42f1. --- CHANGELOG.md | 21 +- Makefile | 5 +- README.md | 8 - client/lcd/lcd_test.go | 7 +- cmd/gaia/cmd/gaiadebug/hack.go | 243 ---- cmd/gaia/cmd/gaiadebug/main.go | 159 --- cmd/gaia/testnets/README.md | 258 ---- cmd/gaia/testnets/STATUS.md | 74 -- cmd/gaia/testnets/gaia-5001/adrian.json | 20 - cmd/gaia/testnets/gaia-5001/anton.json | 20 - cmd/gaia/testnets/gaia-5001/aurel.json | 20 - cmd/gaia/testnets/gaia-5001/bucky.json | 20 - cmd/gaia/testnets/gaia-5001/cwgoes.json | 20 - cmd/gaia/testnets/gaia-5001/iris.json | 20 - cmd/gaia/testnets/gaia-5001/lino.json | 20 - cmd/gaia/testnets/gaia-5001/pbostrom.json | 20 - cmd/gaia/testnets/gaia-5001/poldsam.json | 20 - cmd/gaia/testnets/gaia-5001/staked.json | 20 - cmd/gaia/testnets/gaia-5001/zach.json | 20 - cmd/gaia/testnets/gaia-5001/zaki.json | 20 - cmd/gaia/testnets/gaia-6000/genesis.json | 1459 --------------------- cmd/gaia/testnets/gaia-6001/genesis.json | 1459 --------------------- version/version.go | 2 +- 23 files changed, 6 insertions(+), 3929 deletions(-) delete mode 100644 cmd/gaia/cmd/gaiadebug/hack.go delete mode 100644 cmd/gaia/cmd/gaiadebug/main.go delete mode 100644 cmd/gaia/testnets/README.md delete mode 100644 cmd/gaia/testnets/STATUS.md delete mode 100644 cmd/gaia/testnets/gaia-5001/adrian.json delete mode 100644 cmd/gaia/testnets/gaia-5001/anton.json delete mode 100644 cmd/gaia/testnets/gaia-5001/aurel.json delete mode 100644 cmd/gaia/testnets/gaia-5001/bucky.json delete mode 100644 cmd/gaia/testnets/gaia-5001/cwgoes.json delete mode 100644 cmd/gaia/testnets/gaia-5001/iris.json delete mode 100644 cmd/gaia/testnets/gaia-5001/lino.json delete mode 100644 cmd/gaia/testnets/gaia-5001/pbostrom.json delete mode 100644 cmd/gaia/testnets/gaia-5001/poldsam.json delete mode 100644 cmd/gaia/testnets/gaia-5001/staked.json delete mode 100644 cmd/gaia/testnets/gaia-5001/zach.json delete mode 100644 cmd/gaia/testnets/gaia-5001/zaki.json delete mode 100644 cmd/gaia/testnets/gaia-6000/genesis.json delete mode 100644 cmd/gaia/testnets/gaia-6001/genesis.json diff --git a/CHANGELOG.md b/CHANGELOG.md index f40117f82..300b71fb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ FIXES ## 0.18.0 -*June 9, 2018* +_2018-06-05_ BREAKING CHANGES @@ -87,27 +87,8 @@ BUG FIXES * query sequence via account store * fixed duplicate pub_key in stake.Validator * Auto-sequencing now works correctly -* [gaiacli] Fix error message when account isn't found when running gaiacli account -## 0.17.5 - -*June 5, 2018* - -Update to Tendermint v0.19.9 (Fix evidence reactor, mempool deadlock, WAL panic, -memory leak) - -## 0.17.4 - -*May 31, 2018* - -Update to Tendermint v0.19.7 (WAL fixes and more) - -## 0.17.3 - -*May 29, 2018* - -Update to Tendermint v0.19.6 (fix fast-sync halt) ## 0.17.5 diff --git a/Makefile b/Makefile index c0d18c4a3..d6444b0b6 100644 --- a/Makefile +++ b/Makefile @@ -46,9 +46,6 @@ install_examples: go install $(BUILD_FLAGS) ./examples/democoin/cmd/democoind go install $(BUILD_FLAGS) ./examples/democoin/cmd/democli -install_debug: - go install $(BUILD_FLAGS) ./cmd/gaia/cmd/gaiadebug - dist: @bash publish/dist.sh @bash publish/publish.sh @@ -160,4 +157,4 @@ remotenet-status: # 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 install_debug 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 remotenet-start remotenet-stop remotenet-status +.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 remotenet-start remotenet-stop remotenet-status diff --git a/README.md b/README.md index 3af98fb4f..3faf2c8af 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,6 @@ master | [![CircleCI](https://circleci.com/gh/cosmos/cosmos-sdk/tree/master.s **Note**: Requires [Go 1.10+](https://golang.org/dl/) -## Testnet - -For more information on connecting to the testnet, see -[cmd/gaia/testnets](/cmd/gaia/testnets) - -For the latest status of the testnet, see the [status -file](/cmd/gaia/testnets/STATUS.md). - ## Overview diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index ba2937e05..946f70bbc 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -396,10 +396,9 @@ func TestBonding(t *testing.T) { // TODO fix shares fn in staking // query sender - //acc := getAccount(t, sendAddr) - //coins := acc.GetCoins() - //assert.Equal(t, int64(98), coins.AmountOf(coinDenom)) - + //acc = getAccount(t, port, addr) + //coins = acc.GetCoins() + //assert.Equal(t, int64(70), coins.AmountOf(denom)) } //_____________________________________________________________________________ diff --git a/cmd/gaia/cmd/gaiadebug/hack.go b/cmd/gaia/cmd/gaiadebug/hack.go deleted file mode 100644 index 2c84184bf..000000000 --- a/cmd/gaia/cmd/gaiadebug/hack.go +++ /dev/null @@ -1,243 +0,0 @@ -package main - -import ( - "encoding/base64" - "encoding/hex" - "fmt" - "os" - "path" - - "github.com/spf13/cobra" - abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" - 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/slashing" - "github.com/cosmos/cosmos-sdk/x/stake" - - gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" -) - -func runHackCmd(cmd *cobra.Command, args []string) error { - - if len(args) != 1 { - return fmt.Errorf("Expected 1 arg") - } - - // ".gaiad" - dataDir := args[0] - dataDir = path.Join(dataDir, "data") - - // load the app - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - db, err := dbm.NewGoLevelDB("gaia", dataDir) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - app := NewGaiaApp(logger, db) - - // print some info - id := app.LastCommitID() - lastBlockHeight := app.LastBlockHeight() - fmt.Println("ID", id) - fmt.Println("LastBlockHeight", lastBlockHeight) - - //---------------------------------------------------- - // XXX: start hacking! - //---------------------------------------------------- - // eg. gaia-6001 testnet bug - // We paniced when iterating through the "bypower" keys. - // The following powerKey was there, but the corresponding "trouble" validator did not exist. - // So here we do a binary search on the past states to find when the powerKey first showed up ... - - // owner of the validator the bonds, gets revoked, later unbonds, and then later is still found in the bypower store - trouble := hexToBytes("D3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") - // this is his "bypower" key - powerKey := hexToBytes("05303030303030303030303033FFFFFFFFFFFF4C0C0000FFFED3DC0FF59F7C3B548B7AFA365561B87FD0208AF8") - - topHeight := lastBlockHeight - bottomHeight := int64(0) - checkHeight := topHeight - for { - // load the given version of the state - err = app.LoadVersion(checkHeight, app.keyMain) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - ctx := app.NewContext(true, abci.Header{}) - - // check for the powerkey and the validator from the store - store := ctx.KVStore(app.keyStake) - res := store.Get(powerKey) - val, _ := app.stakeKeeper.GetValidator(ctx, trouble) - fmt.Println("checking height", checkHeight, res, val) - if res == nil { - bottomHeight = checkHeight - } else { - topHeight = checkHeight - } - checkHeight = (topHeight + bottomHeight) / 2 - } -} - -func base64ToPub(b64 string) crypto.PubKeyEd25519 { - data, _ := base64.StdEncoding.DecodeString(b64) - var pubKey crypto.PubKeyEd25519 - copy(pubKey[:], data) - return pubKey - -} - -func hexToBytes(h string) []byte { - trouble, _ := hex.DecodeString(h) - return trouble - -} - -//-------------------------------------------------------------------------------- -// NOTE: This is all copied from gaia/app/app.go -// so we can access internal fields! - -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 - cdc *wire.Codec - - // keys to access the substores - keyMain *sdk.KVStoreKey - keyAccount *sdk.KVStoreKey - keyIBC *sdk.KVStoreKey - keyStake *sdk.KVStoreKey - keySlashing *sdk.KVStoreKey - - // Manage getting and setting accounts - accountMapper auth.AccountMapper - feeCollectionKeeper auth.FeeCollectionKeeper - coinKeeper bank.Keeper - ibcMapper ibc.Mapper - stakeKeeper stake.Keeper - slashingKeeper slashing.Keeper -} - -func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { - cdc := MakeCodec() - - // create your application object - var app = &GaiaApp{ - 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"), - keySlashing: sdk.NewKVStoreKey("slashing"), - } - - // 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)) - app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.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)) - - // initialize BaseApp - app.SetInitChainer(app.initChainer) - app.SetBeginBlocker(app.BeginBlocker) - app.SetEndBlocker(app.EndBlocker) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) - app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing) - 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() - ibc.RegisterWire(cdc) - bank.RegisterWire(cdc) - stake.RegisterWire(cdc) - slashing.RegisterWire(cdc) - auth.RegisterWire(cdc) - sdk.RegisterWire(cdc) - wire.RegisterCrypto(cdc) - return cdc -} - -// application updates every end block -func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) - - return abci.ResponseBeginBlock{ - Tags: tags.ToKVPairs(), - } -} - -// application updates every end block -func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) - - return abci.ResponseEndBlock{ - ValidatorUpdates: validatorUpdates, - } -} - -// custom logic for gaia initialization -func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { - stateJSON := req.AppStateBytes - // TODO is this now the whole genesis file? - - var genesisState gaia.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, "") - } - - // load the accounts - for _, gacc := range genesisState.Accounts { - acc := gacc.ToAccount() - app.accountMapper.SetAccount(ctx, acc) - } - - // load the initial stake information - stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) - return abci.ResponseInitChain{} - -} diff --git a/cmd/gaia/cmd/gaiadebug/main.go b/cmd/gaia/cmd/gaiadebug/main.go deleted file mode 100644 index 79045c07b..000000000 --- a/cmd/gaia/cmd/gaiadebug/main.go +++ /dev/null @@ -1,159 +0,0 @@ -package main - -import ( - "bytes" - "encoding/base64" - "encoding/hex" - "encoding/json" - "fmt" - "os" - "strconv" - "strings" - - gaia "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/spf13/cobra" - crypto "github.com/tendermint/go-crypto" -) - -func init() { - rootCmd.AddCommand(txCmd) - rootCmd.AddCommand(pubkeyCmd) - rootCmd.AddCommand(hackCmd) - rootCmd.AddCommand(rawBytesCmd) -} - -var rootCmd = &cobra.Command{ - Use: "gaiadebug", - Short: "Gaia debug tool", - SilenceUsage: true, -} - -var txCmd = &cobra.Command{ - Use: "tx", - Short: "Decode a gaia tx from hex or base64", - RunE: runTxCmd, -} - -var pubkeyCmd = &cobra.Command{ - Use: "pubkey", - Short: "Decode a pubkey from hex or base64", - RunE: runPubKeyCmd, -} - -var hackCmd = &cobra.Command{ - Use: "hack", - Short: "Boilerplate to Hack on an existing state by scripting some Go...", - RunE: runHackCmd, -} - -var rawBytesCmd = &cobra.Command{ - Use: "raw-bytes", - Short: "Convert raw bytes output (eg. [10 21 13 255]) to hex", - RunE: runRawBytesCmd, -} - -func runRawBytesCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("Expected single arg") - } - stringBytes := args[0] - stringBytes = strings.Trim(stringBytes, "[") - stringBytes = strings.Trim(stringBytes, "]") - spl := strings.Split(stringBytes, " ") - - byteArray := []byte{} - for _, s := range spl { - b, err := strconv.Atoi(s) - if err != nil { - return err - } - byteArray = append(byteArray, byte(b)) - } - fmt.Printf("%X\n", byteArray) - return nil -} - -func runPubKeyCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("Expected single arg") - } - - pubkeyString := args[0] - - // try hex, then base64 - pubkeyBytes, err := hex.DecodeString(pubkeyString) - if err != nil { - var err2 error - pubkeyBytes, err2 = base64.StdEncoding.DecodeString(pubkeyString) - if err2 != nil { - return fmt.Errorf(`Expected hex or base64. Got errors: - hex: %v, - base64: %v - `, err, err2) - } - } - - cdc := gaia.MakeCodec() - var pubKey crypto.PubKeyEd25519 - copy(pubKey[:], pubkeyBytes) - pubKeyJSONBytes, err := cdc.MarshalJSON(pubKey) - if err != nil { - return err - } - fmt.Println("Address:", pubKey.Address()) - fmt.Printf("Hex: %X\n", pubkeyBytes) - fmt.Println("JSON (base64):", string(pubKeyJSONBytes)) - return nil -} - -func runTxCmd(cmd *cobra.Command, args []string) error { - if len(args) != 1 { - return fmt.Errorf("Expected single arg") - } - - txString := args[0] - - // try hex, then base64 - txBytes, err := hex.DecodeString(txString) - if err != nil { - var err2 error - txBytes, err2 = base64.StdEncoding.DecodeString(txString) - if err2 != nil { - return fmt.Errorf(`Expected hex or base64. Got errors: - hex: %v, - base64: %v - `, err, err2) - } - } - - var tx = auth.StdTx{} - cdc := gaia.MakeCodec() - - err = cdc.UnmarshalBinary(txBytes, &tx) - if err != nil { - return err - } - - bz, err := cdc.MarshalJSON(tx) - if err != nil { - return err - } - - buf := bytes.NewBuffer([]byte{}) - err = json.Indent(buf, bz, "", " ") - if err != nil { - return err - } - - fmt.Println(buf.String()) - return nil -} - -func main() { - err := rootCmd.Execute() - if err != nil { - os.Exit(1) - } - os.Exit(0) -} diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md deleted file mode 100644 index b34926aed..000000000 --- a/cmd/gaia/testnets/README.md +++ /dev/null @@ -1,258 +0,0 @@ -# Connect to the `gaia-6001` Testnet - -Note: We are aware this documentation is sub-par. We are working to -improve the tooling and the documentation to make this process as painless as -possible. In the meantime, join the -[Validator Chat](https://riot.im/app/#/room/#cosmos_validators:matrix.org) -for technical support. Thanks very much for your patience. :) - -## Setting Up a New Node - -These instructions are for setting up a brand new full node from scratch. If you ran a full node on a previous testnet, please skip to [Upgrading From Previous Testnet](#upgrading-from-previous-testnet). - -### Install Go - -Install `go` by following the [official docs](https://golang.org/doc/install). -**Go 1.10+** is required for the Cosmos SDK. - -### Install Cosmos SDK - -Next, let's install the testnet's version of the Cosmos SDK. - -``` -mkdir -p $GOPATH/src/github.com/cosmos -cd $GOPATH/src/github.com/cosmos -git clone https://github.com/cosmos/cosmos-sdk -cd cosmos-sdk && git checkout v0.18.0 -make get_tools && make get_vendor_deps && make install -``` - -That will install the `gaiad` and `gaiacli` binaries. Verify that everything is OK: - -``` -gaiad version -0.18.0-eceb56b7 -``` - -### Node Setup - -Create the required configuration files: - -``` -gaiad init -``` - -Name your node by editing the `moniker` in `$HOME/.gaiad/config/config.toml`. Note that only ASCII characters are supported. Using Unicode renders your node unconnectable. - -``` -# A custom human readable name for this node -moniker = "" -``` - -Your full node has been initialized! Please skip to [Genesis & Seeds](#genesis--seeds). - -## Upgrading From Previous Testnet - -These instructions are for full nodes that have ran on previous testnets and would like to upgrade to the latest testnet. - -### Reset Data - -First, remove the outdated files and reset the data. - -``` -rm $HOME/.gaiad/config/addrbook.json $HOME/.gaiad/config/genesis.json -gaiad unsafe_reset_all -``` - -Your node is now in a pristine state while keeping the original `priv_validator.json` and `config.toml`. If you had any sentry nodes or full nodes setup before, -your node will still try to connect to them, but may fail if they haven't also -been upgraded. - -**WARNING:** Make sure that every node has a unique `priv_validator.json`. Do not copy the `priv_validator.json` from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign. - -### Software Upgrade - -Now it is time to upgrade the software: - -``` -cd $GOPATH/src/github.com/cosmos/cosmos-sdk -git fetch --all && git checkout v0.18.0 -make update_tools && make get_vendor_deps && make install -``` - -Your full node has been cleanly upgraded! - -## Genesis & Seeds - -### Copy the Genesis File - -Copy the testnet's `genesis.json` file and place it in `gaiad`'s config directory. - -``` -mkdir -p $HOME/.gaiad/config -cp -a $GOPATH/src/github.com/cosmos/cosmos-sdk/cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json -``` - -### Add Seed Nodes - -Your node needs to know how to find peers. You'll need to add healthy seed nodes to `$HOME/.gaiad/config/config.toml`. Here are some seed nodes you can use: - -``` -# Comma separated list of seed nodes to connect to -seeds = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" -``` - -You can also [ask other validators](https://riot.im/app/#/room/#cosmos_validators:matrix.org) for a persistent peer and add it under the `persistent_peers` key. For more information on seeds and peers, [read this](https://github.com/tendermint/tendermint/blob/develop/docs/using-tendermint.md#peers). - -## Run a Full Node - -Start the full node with this command: - -``` -gaiad start -``` - -Check that everything is running smoothly: - -``` -gaiacli status -``` - -View the status of the network with the [Cosmos Explorer](https://explorecosmos.network). Once your full node syncs up to the current block height, you should see it appear on the [list of full nodes](https://explorecosmos.network/validators). If it doesn't show up, that's ok--the Explorer does not connect to every node. - -## Generate Keys - -You'll need a private and public key pair \(a.k.a. `sk, pk` respectively\) to be able to receive funds, send txs, bond tx, etc. - -To generate a new key \(default _ed25519_ elliptic curve\): - -``` -gaiacli keys add -``` - -Next, you will have to create a passphrase. Save the _seed_ _phrase_ in a safe place in case you forget the password. - -If you check your private keys, you'll now see ``: - -``` -gaiacli keys show -``` - -You can see all your available keys by typing: - -``` -gaiacli keys list -``` - -View the validator pubkey for your node by typing: - -``` -gaiad tendermint show_validator -``` - -Save your address and pubkey to environment variables for later use: - -``` -MYADDR= -MYPUBKEY= -``` - -**WARNING:** We strongly recommend NOT using the same passphrase for multiple keys. The Tendermint team and the Interchain Foundation will not be responsible for the loss of funds. - -## Get Tokens - -The best way to get tokens is from the [Cosmos Testnet Faucet](https://faucetcosmos.network). If the faucet is not working for you, try asking [#cosmos-validators](https://riot.im/app/#/room/#cosmos-validators:matrix.org). - -After receiving tokens to your address, you can view your account's balance by typing: - -``` -gaiacli account -``` - -Note: When you query an account balance with zero tokens, you will get this error: `No account with address was found in the state.` This is expected! We're working on improving our error messages. - -## Send Tokens - -``` -gaiacli send --amount=10faucetToken --chain-id= --name= --to= -``` - -Note: The `--amount` flag accepts the format `--amount=`. - -Now, view the updated balances of the origin and destination accounts: - -``` -gaiacli account -gaiacli account -``` - -You can also check your balance at a given block by using the `--block` flag: - -``` -gaiacli account --block= -``` - -## Run a Validator Node - -[Validators](https://cosmos.network/validators) are responsible for committing new blocks to the blockchain through voting. A validator's stake is slashed if they become unavailable, double sign a transaction, or don't cast their votes. If you only want to run a full node, a VM in the cloud is fine. However, if you are want to become a validator for the Hub's `mainnet`, you should research hardened setups. Please read [Sentry Node Architecture](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#how-can-validators-protect-themselves-from-denial-of-service-attacks) to protect your node from DDOS and ensure high-availability. Also see the [technical requirements](https://github.com/cosmos/cosmos/blob/master/VALIDATORS_FAQ.md#technical-requirements)). There's also more info on our [website](https://cosmos.network/validators). - -Your `pubkey` can be used to create a new validator by staking tokens. You can find your validator pubkey by running: - -``` -gaiad tendermint show_validator -``` - -Next, craft your `gaiacli stake create-validator` command: - -``` -gaiacli stake create-validator --amount=5steak --pubkey= --address-validator= --moniker=satoshi --chain-id= --name= -``` - -You can add more information to the validator, such as`--website`, `--keybase-sig`, or `--details`. Here's how: - -``` -gaiacli stake edit-validator --details="To the cosmos !" --website="https://cosmos.network" -``` - -View the validator's information with this command: - -``` -gaiacli stake validator --address-validator= --chain-id= -``` - -To check that the validator is active, look for it here: - -``` -gaiacli advanced tendermint validator-set -``` - -**Note:** To be in the validator set, you need to have more total voting power than the 100th validator. - -## Delegating to a Validator - -On the upcoming mainnet, you can delegate `atom` to a validator. These [delegators](https://cosmos.network/resources/delegators) can receive part of the validator's fee revenue. Read more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf). - -### Bond Tokens - -On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator: - -``` -gaiacli stake delegate --amount=10steak --address-delegator= --address-validator= --name= --chain-id= -``` - -While tokens are bonded, they are pooled with all the other bonded tokens in the network. Validators and delegators obtain a percentage of shares that equal their stake in this pool. - -### Unbond Tokens - -If for any reason the validator misbehaves, or you want to unbond a certain amount of tokens, use this following command. You can unbond a specific amount of`shares`\(eg:`12.1`\) or all of them \(`MAX`\). - -``` -gaiacli stake unbond --address-delegator= --address-validator= --shares=MAX --name= --chain-id= -``` - -You can check your balance and your stake delegation to see that the unbonding went through successfully. - -``` -gaiacli account -gaiacli stake delegation --address-delegator= --address-validator= --chain-id= -``` diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md deleted file mode 100644 index d53c49e09..000000000 --- a/cmd/gaia/testnets/STATUS.md +++ /dev/null @@ -1,74 +0,0 @@ -# TESTNET STATUS - -## *June 10, 2018, 8:30 EST* - Gaia-6001 consensus failure - -- Validator unbonding and revocation activity caused a consensus failure -- There is a bug in the staking module that must be fixed -- The team is taking its time to look into this and release a fix following a - proper protocol for hotfix upgrades to the testnet -- Please stay tuned! - -## *June 9, 2018, 14:00 EST* - New Release - -- Released gaia - [v0.18.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.18.0) with - update for Tendermint - [v0.20.0](https://github.com/tendermint/tendermint/releases/tag/v0.20.0) -- Includes bug fix for declaring candidacy from the command line - -## *June 8, 2018, 23:30 EST* - Gaia-6001 is making blocks - -- +2/3 of the voting power is finally online for Gaia-6001 and it is making - blocks! -- This is a momentous achievement - a successful asynchronous decentralized - testnet launch -- Congrats everyone! - -## *June 8, 2018, 12:00 EST* - New Testnet Gaia-6001 - -- After some confusion around testnet deployment and a contention testnet - hardfork, a new genesis file and network was released for `gaia-6001` - -## *June 7, 2018, 9:00 EST* - New Testnet Gaia-6000 - -- Released a new `genesis.json` file for `gaia-6000` -- Initial validators include those that were most active in - the gaia-5001 testnet -- Join the network via gaia `v0.18.0-rc0` - -## *June 5, 2018, 21:00 EST* - New Release - -- Released gaia - [v0.17.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.17.5) - with update for Tendermint - [v0.19.9](https://github.com/tendermint/tendermint/releases/tag/v0.19.9) -- Fixes many bugs! - - evidence gossipping - - mempool deadlock - - WAL panic - - memory leak -- Please update to this to put a stop to the rampant invalid evidence gossiping - :) - -## *May 31, 2018, 14:00 EST* - New Release - -- Released gaia - [v0.17.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.17.4) with update for Tendermint v0.19.7 -- Fixes a WAL bug and some more -- Please update to this if you have trouble restarting a node - -## *May 31, 2018, 2:00 EST* - Testnet Halt - -- A validator equivocated last week and Evidence is being rampantly gossipped -- Peers that can't process the evidence (either too far behind or too far ahead) are disconnecting from the peers that - sent it, causing high peer turn-over -- The high peer turn-over may be causing a memory-leak, resulting in some nodes - crashing and the testnet halting -- We need to fix some issues in the EvidenceReactor to address this and also - investigate the possible memory-leak - -## *May 29, 2018* - New Release - -- Released v0.17.3 with update for Tendermint v0.19.6 -- Fixes fast-sync bug -- Please update to this to sync with the testnet diff --git a/cmd/gaia/testnets/gaia-5001/adrian.json b/cmd/gaia/testnets/gaia-5001/adrian.json deleted file mode 100644 index 7ca99cb1e..000000000 --- a/cmd/gaia/testnets/gaia-5001/adrian.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "1ebc5ca705b3ae1c06a0888ff1287ada82149dc3", - "ip": "138.68.77.24", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "power": 100, - "name": "adrian" - }, - "app_gen_tx": { - "name": "default", - "address": "D9C12CB5186FE0018179742FD3110EE534C63460", - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/anton.json b/cmd/gaia/testnets/gaia-5001/anton.json deleted file mode 100644 index 701e85887..000000000 --- a/cmd/gaia/testnets/gaia-5001/anton.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "c272ae3cff7558db2c6195eea38fd43fd08406dc", - "ip": "206.189.31.178", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "tJlZJWjOpYvRitYFTWNPTaUtvQVf+hoNjlfI84VPqvI=" - }, - "power": 100, - "name": "anton" - }, - "app_gen_tx": { - "name": "default", - "address": "E766088FD171906289617F60BF0014C46F0F85EC", - "pub_key": { - "type": "AC26791624DE60", - "value": "tJlZJWjOpYvRitYFTWNPTaUtvQVf+hoNjlfI84VPqvI=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/aurel.json b/cmd/gaia/testnets/gaia-5001/aurel.json deleted file mode 100644 index 0c2ea8166..000000000 --- a/cmd/gaia/testnets/gaia-5001/aurel.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "aef085c4bfed0c1ffc6705f2e1e3bf85e5164600", - "ip": "45.77.53.208", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "power": 100, - "name": "aurel" - }, - "app_gen_tx": { - "name": "aurel", - "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/bucky.json b/cmd/gaia/testnets/gaia-5001/bucky.json deleted file mode 100644 index fc4bb51cd..000000000 --- a/cmd/gaia/testnets/gaia-5001/bucky.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "b0dd378c3fbc4c156cd6d302a799f0d2e4227201", - "ip": "159.89.121.174", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "power": 100, - "name": "bucky" - }, - "app_gen_tx": { - "name": "bucky", - "address": "935E48ED79F1006ED135553768E1D9A768747CF6", - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/cwgoes.json b/cmd/gaia/testnets/gaia-5001/cwgoes.json deleted file mode 100644 index dce7e20c9..000000000 --- a/cmd/gaia/testnets/gaia-5001/cwgoes.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "e25603602d8cf8542570ad0e311d50f55f497f85", - "ip": "158.69.63.13", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "power": 100, - "name": "cwgoes" - }, - "app_gen_tx": { - "name": "cwgoes", - "address": "328FBB8EA315D070DF908982A5F91A3618001D20", - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/iris.json b/cmd/gaia/testnets/gaia-5001/iris.json deleted file mode 100644 index 1a1019672..000000000 --- a/cmd/gaia/testnets/gaia-5001/iris.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "aabf05a67b2f399807dc602d05bf97b0ed283ac2", - "ip": "116.62.62.39", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "power": 100, - "name": "iris" - }, - "app_gen_tx": { - "name": "=suyu", - "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - } - } -} \ No newline at end of file diff --git a/cmd/gaia/testnets/gaia-5001/lino.json b/cmd/gaia/testnets/gaia-5001/lino.json deleted file mode 100644 index 5bc98bb6e..000000000 --- a/cmd/gaia/testnets/gaia-5001/lino.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "79466a03e9d4b4648a7dd8cead1fa7121ce76ee3", - "ip": "34.235.130.1", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "power": 100, - "name": "lino" - }, - "app_gen_tx": { - "name": "lino", - "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/pbostrom.json b/cmd/gaia/testnets/gaia-5001/pbostrom.json deleted file mode 100644 index 59cd46950..000000000 --- a/cmd/gaia/testnets/gaia-5001/pbostrom.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "adb290585a2753bf1a520c76802b0dab3dffa895", - "ip": "34.201.21.179", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "power": 100, - "name": "pbostrom" - }, - "app_gen_tx": { - "name": "default", - "address": "109720515B4F8C0858DA3521E448262334534FFD", - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/poldsam.json b/cmd/gaia/testnets/gaia-5001/poldsam.json deleted file mode 100644 index 8149a9259..000000000 --- a/cmd/gaia/testnets/gaia-5001/poldsam.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "678503e6c8f50db7279c7da3cb9b072aac4bc0d5", - "ip": "35.193.188.125", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "power": 100, - "name": "polsdam" - }, - "app_gen_tx": { - "name": "poldsam", - "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/staked.json b/cmd/gaia/testnets/gaia-5001/staked.json deleted file mode 100644 index f39cced6b..000000000 --- a/cmd/gaia/testnets/gaia-5001/staked.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "3519f05985394107e0b2e285361b7e012adb1113", - "ip": "54.209.118.64", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "vq0V0BjpmIh6WyNnFpMaO5LyUK2FamkNt65eJYa5AaQ=" - }, - "power": 100, - "name": "staked" - }, - "app_gen_tx": { - "name": "default", - "address": "935E04662697134905706A4CCDB822AC6FC11C2E", - "pub_key": { - "type": "AC26791624DE60", - "value": "vq0V0BjpmIh6WyNnFpMaO5LyUK2FamkNt65eJYa5AaQ=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/zach.json b/cmd/gaia/testnets/gaia-5001/zach.json deleted file mode 100644 index 76a08cc92..000000000 --- a/cmd/gaia/testnets/gaia-5001/zach.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "8a2802fb25d352f3e7e277559a4f683780c3ef22", - "ip": "167.99.191.184", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "power": 100, - "name": "" - }, - "app_gen_tx": { - "name": "zach", - "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-5001/zaki.json b/cmd/gaia/testnets/gaia-5001/zaki.json deleted file mode 100644 index 956f2bf8c..000000000 --- a/cmd/gaia/testnets/gaia-5001/zaki.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "node_id": "30b45459e4881680c0ef1750fde136fefa6c3b98", - "ip": "35.184.182.143", - "validator": { - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "power": 100, - "name": "zaki" - }, - "app_gen_tx": { - "name": "zaki", - "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - } - } -} diff --git a/cmd/gaia/testnets/gaia-6000/genesis.json b/cmd/gaia/testnets/gaia-6000/genesis.json deleted file mode 100644 index aefab9286..000000000 --- a/cmd/gaia/testnets/gaia-6000/genesis.json +++ /dev/null @@ -1,1459 +0,0 @@ -{ - "genesis_time": "2018-05-15T18:29:12.38288148Z", - "chain_id": "gaia-6000", - "consensus_params": { - "block_size_params": { - "max_bytes": 22020096, - "max_txs": 100000, - "max_gas": -1 - }, - "tx_size_params": { - "max_bytes": 10240, - "max_gas": -1 - }, - "block_gossip_params": { - "block_part_size_bytes": 65536 - }, - "evidence_params": { - "max_age": 100000 - } - }, - "validators": [ - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "power": 1000, - "name": "adrian" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "power": 1000, - "name": "zaki" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "power": 100, - "name": "staked" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "power": 1000, - "name": "polsdam" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "power": 1000, - "name": "lino" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "power": 100, - "name": "" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "power": 1000, - "name": "iris" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "power": 1000, - "name": "pbostrom" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "power": 1000, - "name": "aurel" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "power": 1000, - "name": "bucky" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "power": 100, - "name": "cwgoes" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "power": 1000, - "name": "bdnet" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "power": 1000, - "name": "melea-trust" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "power": 1000, - "name": "naruemon" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "power": 1000, - "name": "idoor" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "power": 1000, - "name": "ATEAM1" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "power": 1000, - "name": "figmatt" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "power": 1000, - "name": "jla-bsd" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "power": 1000, - "name": "Gold" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "power": 1000, - "name": "nylira" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "power": 1000, - "name": "BKCM" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "power": 1000, - "name": "Dev's Validator" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "power": 1000, - "name": "Staking Facilities" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "power": 1000, - "name": "nuevax" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "power": 1000, - "name": "vultr.guest" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "power": 1000, - "name": "forebole" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "coins": [ - { - "denom": "devToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "coins": [ - { - "denom": "adrianToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "109720515B4F8C0858DA3521E448262334534FFD", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "coins": [ - { - "denom": "aurelToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "328FBB8EA315D070DF908982A5F91A3618001D20", - "coins": [ - { - "denom": "cwgoesToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "coins": [ - { - "denom": "BKCMToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "coins": [ - { - "denom": "BDToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "coins": [ - { - "denom": "suyuToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "coins": [ - { - "denom": "linoToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "coins": [ - { - "denom": "stakingToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E04662697134905706A4CCDB822AC6FC11C2E", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E48ED79F1006ED135553768E1D9A768747CF6", - "coins": [ - { - "denom": "buckyToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", - "coins": [ - { - "denom": "kwunyeungToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zachToken", - "amount": 1000 - } - ] - }, - { - "address": "A323EC45243D600204BA3D298E3C20322D08C84C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "nuevaxToken", - "amount": 1000 - } - ] - }, - { - "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "dokiaToken", - "amount": 1000 - } - ] - }, - { - "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "forboleToken", - "amount": 1000 - } - ] - }, - { - "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "coins": [ - { - "denom": "steak", - "amount": 100 - }, - { - "denom": "pengToken", - "amount": 1000 - } - ] - }, - { - "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", - "coins": [ - { - "denom": "steak", - "amount": 900 - }, - { - "denom": "faucetToken", - "amount": 10000000 - } - ] - }, - { - "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "goldToken", - "amount": 100 - } - ] - }, - { - "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "jlaToken", - "amount": 100 - } - ] - }, - { - "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "figmattToken", - "amount": 100 - } - ] - }, - { - "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "ATEAM1Token", - "amount": 100 - } - ] - }, - { - "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "idoorToken", - "amount": 100 - } - ] - }, - { - "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "naruemonToken", - "amount": 100 - } - ] - }, - { - "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zakiToken", - "amount": 1000 - } - ] - }, - { - "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "trustToken", - "amount": 1000 - } - ] - }, - { - "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "coins": [ - { - "denom": "poldsamToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - } - ], - "stake": { - "pool": { - "loose_unbonded_tokens": 2350, - "unbonded_tokens": 0, - "unbonding_tokens": 0, - "bonded_tokens": 25200, - "unbonded_shares": "0", - "unbonding_shares": "0", - "bonded_shares": "25200", - "inflation_last_time": 0, - "inflation": "9012837/100000000", - "date_last_commission_reset": 0, - "prev_bonded_shares": "0" - }, - "params": { - "inflation_rate_change": "13/100", - "inflation_max": "1/5", - "inflation_min": "7/100", - "goal_bonded": "67/100", - "max_validators": 100, - "bond_denom": "steak" - }, - "bonds": [ - { - "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "shares": "1000", - "height": 0 - } - ], - "validators": [ - { - "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "description": { - "moniker": "Dev's Validator", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "109720515B4F8C0858DA3521E448262334534FFD", - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "description": { - "moniker": "", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "description": { - "moniker": "aurel", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "description": { - "moniker": "cwgoes", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "description": { - "moniker": "BKCM", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "description": { - "moniker": "bdnet", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "description": { - "moniker": "suyu", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "description": { - "moniker": "lino", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "description": { - "moniker": "Staking Facilities", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "description": { - "moniker": "default", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "description": { - "moniker": "bucky", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "description": { - "moniker": "zach", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "description": { - "moniker": "nuevax", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "description": { - "moniker": "vultr.guest", - "identity": "", - "website": "https://ion.dokia.capital/", - "details": "DokiaValidator" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "description": { - "moniker": "forbole", - "identity": "", - "website": "https://www.forbole.com", - "details": "Recommend. Refer. Reward" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "description": { - "moniker": "nylira", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "description": { - "moniker": "Gold", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "description": { - "moniker": "jla-bsd", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "description": { - "moniker": "figmatt", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "description": { - "moniker": "ATEAM1", - "identity": "", - "website": "", - "details": "ATEAM1" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "description": { - "moniker": "idoor", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "description": { - "moniker": "naruemon", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "description": { - "moniker": "Adrian Brink - Cryptium Labs", - "identity": "", - "website": "https://cryptium.ch", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "description": { - "moniker": "zaki", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "description": { - "moniker": "trust", - "identity": "", - "website": "http://cosmos-trust.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "description": { - "moniker": "proof-of-audit", - "identity": "", - "website": "https://proof-of-audit.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - } - ] - } - } -} diff --git a/cmd/gaia/testnets/gaia-6001/genesis.json b/cmd/gaia/testnets/gaia-6001/genesis.json deleted file mode 100644 index 512d761be..000000000 --- a/cmd/gaia/testnets/gaia-6001/genesis.json +++ /dev/null @@ -1,1459 +0,0 @@ -{ - "genesis_time": "2018-05-15T18:29:12.38288148Z", - "chain_id": "gaia-6001", - "consensus_params": { - "block_size_params": { - "max_bytes": 22020096, - "max_txs": 100000, - "max_gas": -1 - }, - "tx_size_params": { - "max_bytes": 10240, - "max_gas": -1 - }, - "block_gossip_params": { - "block_part_size_bytes": 65536 - }, - "evidence_params": { - "max_age": 100000 - } - }, - "validators": [ - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "power": 1000, - "name": "adrian" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "power": 1000, - "name": "zaki" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "power": 100, - "name": "staked" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "power": 1000, - "name": "polsdam" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "power": 1000, - "name": "lino" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "power": 100, - "name": "" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "power": 1000, - "name": "iris" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "power": 1000, - "name": "pbostrom" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "power": 1000, - "name": "aurel" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "power": 1000, - "name": "bucky" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "power": 100, - "name": "cwgoes" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "power": 1000, - "name": "bdnet" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "power": 1000, - "name": "melea-trust" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "power": 1000, - "name": "naruemon" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "power": 1000, - "name": "idoor" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "power": 1000, - "name": "ATEAM1" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "power": 1000, - "name": "figmatt" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "power": 1000, - "name": "jla-bsd" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "power": 1000, - "name": "Gold" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "power": 1000, - "name": "nylira" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "power": 1000, - "name": "BKCM" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "power": 1000, - "name": "Dev's Validator" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "power": 1000, - "name": "Staking Facilities" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "power": 1000, - "name": "nuevax" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "power": 1000, - "name": "vultr.guest" - }, - { - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "power": 1000, - "name": "forebole" - } - ], - "app_hash": "", - "app_state": { - "accounts": [ - { - "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "coins": [ - { - "denom": "devToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "coins": [ - { - "denom": "adrianToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "109720515B4F8C0858DA3521E448262334534FFD", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "coins": [ - { - "denom": "aurelToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "328FBB8EA315D070DF908982A5F91A3618001D20", - "coins": [ - { - "denom": "cwgoesToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "coins": [ - { - "denom": "BKCMToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "coins": [ - { - "denom": "BDToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "coins": [ - { - "denom": "suyuToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "coins": [ - { - "denom": "linoToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "coins": [ - { - "denom": "stakingToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E04662697134905706A4CCDB822AC6FC11C2E", - "coins": [ - { - "denom": "defaultToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "935E48ED79F1006ED135553768E1D9A768747CF6", - "coins": [ - { - "denom": "buckyToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", - "coins": [ - { - "denom": "kwunyeungToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - }, - { - "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zachToken", - "amount": 1000 - } - ] - }, - { - "address": "A323EC45243D600204BA3D298E3C20322D08C84C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "nuevaxToken", - "amount": 1000 - } - ] - }, - { - "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "dokiaToken", - "amount": 1000 - } - ] - }, - { - "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "forboleToken", - "amount": 1000 - } - ] - }, - { - "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "coins": [ - { - "denom": "steak", - "amount": 100 - }, - { - "denom": "pengToken", - "amount": 1000 - } - ] - }, - { - "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", - "coins": [ - { - "denom": "steak", - "amount": 900 - }, - { - "denom": "faucetToken", - "amount": 10000000 - } - ] - }, - { - "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "goldToken", - "amount": 100 - } - ] - }, - { - "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "jlaToken", - "amount": 100 - } - ] - }, - { - "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "figmattToken", - "amount": 100 - } - ] - }, - { - "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "ATEAM1Token", - "amount": 100 - } - ] - }, - { - "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "idoorToken", - "amount": 100 - } - ] - }, - { - "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "naruemonToken", - "amount": 100 - } - ] - }, - { - "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "zakiToken", - "amount": 1000 - } - ] - }, - { - "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "coins": [ - { - "denom": "steak", - "amount": 50 - }, - { - "denom": "trustToken", - "amount": 1000 - } - ] - }, - { - "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "coins": [ - { - "denom": "poldsamToken", - "amount": 1000 - }, - { - "denom": "steak", - "amount": 50 - } - ] - } - ], - "stake": { - "pool": { - "loose_unbonded_tokens": 2300, - "unbonded_tokens": 0, - "unbonding_tokens": 0, - "bonded_tokens": 23300, - "unbonded_shares": "0", - "unbonding_shares": "0", - "bonded_shares": "23300", - "inflation_last_time": 0, - "inflation": "9012837/100000000", - "date_last_commission_reset": 0, - "prev_bonded_shares": "0" - }, - "params": { - "inflation_rate_change": "13/100", - "inflation_max": "1/5", - "inflation_min": "7/100", - "goal_bonded": "67/100", - "max_validators": 100, - "bond_denom": "steak" - }, - "bonds": [ - { - "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "shares": "100", - "height": 0 - }, - { - "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "shares": "1000", - "height": 0 - }, - { - "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "shares": "1000", - "height": 0 - } - ], - "validators": [ - { - "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", - "pub_key": { - "type": "AC26791624DE60", - "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" - }, - "description": { - "moniker": "Dev's Validator", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "109720515B4F8C0858DA3521E448262334534FFD", - "pub_key": { - "type": "AC26791624DE60", - "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" - }, - "description": { - "moniker": "", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", - "pub_key": { - "type": "AC26791624DE60", - "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" - }, - "description": { - "moniker": "aurel", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", - "pub_key": { - "type": "AC26791624DE60", - "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" - }, - "description": { - "moniker": "cwgoes", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", - "pub_key": { - "type": "AC26791624DE60", - "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" - }, - "description": { - "moniker": "BKCM", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", - "pub_key": { - "type": "AC26791624DE60", - "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" - }, - "description": { - "moniker": "bdnet", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", - "pub_key": { - "type": "AC26791624DE60", - "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" - }, - "description": { - "moniker": "suyu", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", - "pub_key": { - "type": "AC26791624DE60", - "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" - }, - "description": { - "moniker": "lino", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", - "pub_key": { - "type": "AC26791624DE60", - "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" - }, - "description": { - "moniker": "Staking Facilities", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", - "pub_key": { - "type": "AC26791624DE60", - "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" - }, - "description": { - "moniker": "default", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", - "pub_key": { - "type": "AC26791624DE60", - "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" - }, - "description": { - "moniker": "bucky", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", - "pub_key": { - "type": "AC26791624DE60", - "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" - }, - "description": { - "moniker": "zach", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "100" - }, - "delegator_shares": "100", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", - "pub_key": { - "type": "AC26791624DE60", - "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" - }, - "description": { - "moniker": "nuevax", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", - "pub_key": { - "type": "AC26791624DE60", - "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" - }, - "description": { - "moniker": "vultr.guest", - "identity": "", - "website": "https://ion.dokia.capital/", - "details": "DokiaValidator" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", - "pub_key": { - "type": "AC26791624DE60", - "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" - }, - "description": { - "moniker": "forbole", - "identity": "", - "website": "https://www.forbole.com", - "details": "Recommend. Refer. Reward" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", - "pub_key": { - "type": "AC26791624DE60", - "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" - }, - "description": { - "moniker": "nylira", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", - "pub_key": { - "type": "AC26791624DE60", - "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" - }, - "description": { - "moniker": "Gold", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", - "pub_key": { - "type": "AC26791624DE60", - "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" - }, - "description": { - "moniker": "jla-bsd", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", - "pub_key": { - "type": "AC26791624DE60", - "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" - }, - "description": { - "moniker": "figmatt", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", - "pub_key": { - "type": "AC26791624DE60", - "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" - }, - "description": { - "moniker": "ATEAM1", - "identity": "", - "website": "", - "details": "ATEAM1" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", - "pub_key": { - "type": "AC26791624DE60", - "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" - }, - "description": { - "moniker": "idoor", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", - "pub_key": { - "type": "AC26791624DE60", - "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" - }, - "description": { - "moniker": "naruemon", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", - "pub_key": { - "type": "AC26791624DE60", - "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" - }, - "description": { - "moniker": "Adrian Brink - Cryptium Labs", - "identity": "", - "website": "https://cryptium.ch", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", - "pub_key": { - "type": "AC26791624DE60", - "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" - }, - "description": { - "moniker": "zaki", - "identity": "", - "website": "", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", - "pub_key": { - "type": "AC26791624DE60", - "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" - }, - "description": { - "moniker": "trust", - "identity": "", - "website": "http://cosmos-trust.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - }, - { - "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", - "pub_key": { - "type": "AC26791624DE60", - "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" - }, - "description": { - "moniker": "proof-of-audit", - "identity": "", - "website": "https://proof-of-audit.com", - "details": "" - }, - "revoked": false, - "pool_shares": { - "status": 2, - "amount": "1000" - }, - "delegator_shares": "1000", - "bond_height": 0, - "bond_intra_tx_counter": 0, - "commision": "0/1", - "commission_max": "0/1", - "commission_change_rate": "0/1", - "commission_change_rate_today": "0/1", - "prev_bonded_shares": "0/1" - } - ] - } - } -} diff --git a/version/version.go b/version/version.go index 20074c7bc..116f1ff28 100644 --- a/version/version.go +++ b/version/version.go @@ -9,7 +9,7 @@ const Maj = "0" const Min = "18" const Fix = "0" -const Version = "0.18.0" +const Version = "0.18.0-dev" // GitCommit set by build flags var GitCommit = "" From 65786e4578074d0a6a47f5bfbf0291fe78ba7ec3 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 13 Jun 2018 10:05:50 +0200 Subject: [PATCH 78/89] Update version.go & changelog --- CHANGELOG.md | 5 +++++ version/version.go | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f40117f82..4428f7a4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.19.0 + +*June 13, 2018* + BREAKING CHANGES * msg.GetSignBytes() now returns bech32-encoded addresses in all cases * [lcd] REST end-points now include gas @@ -15,6 +19,7 @@ IMPROVEMENTS * [x/stake] More stake tests added to test ByPower index FIXES +* Fixes consensus fault on testnet - see postmortem [here](https://github.com/cosmos/cosmos-sdk/issues/1197#issuecomment-396823021) * [x/stake] bonded inflation removed, non-bonded inflation partially implemented * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs * [lcd] fixed tx indexing/querying diff --git a/version/version.go b/version/version.go index 20074c7bc..e24ef62f1 100644 --- a/version/version.go +++ b/version/version.go @@ -6,10 +6,10 @@ package version // TODO improve const Maj = "0" -const Min = "18" +const Min = "19" const Fix = "0" -const Version = "0.18.0" +const Version = "0.19.0" // GitCommit set by build flags var GitCommit = "" From 1b7396d4872c9650eb854897e658f3d60bcc791f Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 13 Jun 2018 01:34:51 -0700 Subject: [PATCH 79/89] dev version bump --- CHANGELOG.md | 4 ++++ version/version.go | 8 ++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4428f7a4c..fdfd1895f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.20.0 + +*TBD* + ## 0.19.0 *June 13, 2018* diff --git a/version/version.go b/version/version.go index e24ef62f1..496645568 100644 --- a/version/version.go +++ b/version/version.go @@ -1,15 +1,11 @@ //nolint package version -// when updating these, -// remember to also update examples/basecoin/tests/cli/rpc.sh -// TODO improve - const Maj = "0" -const Min = "19" +const Min = "20" const Fix = "0" -const Version = "0.19.0" +const Version = "0.20.0-dev" // GitCommit set by build flags var GitCommit = "" From 8acac9089413528e43dba4f48b6975b6a1e16fde Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 13 Jun 2018 01:39:08 -0700 Subject: [PATCH 80/89] gaia 6002 --- cmd/gaia/testnets/README.md | 12 +- cmd/gaia/testnets/STATUS.md | 14 + cmd/gaia/testnets/gaia-6002/genesis.json | 1459 ++++++++++++++++++++++ 3 files changed, 1479 insertions(+), 6 deletions(-) create mode 100644 cmd/gaia/testnets/gaia-6002/genesis.json diff --git a/cmd/gaia/testnets/README.md b/cmd/gaia/testnets/README.md index b34926aed..b65feeb91 100644 --- a/cmd/gaia/testnets/README.md +++ b/cmd/gaia/testnets/README.md @@ -1,4 +1,4 @@ -# Connect to the `gaia-6001` Testnet +# Connect to the `gaia-6002` Testnet Note: We are aware this documentation is sub-par. We are working to improve the tooling and the documentation to make this process as painless as @@ -23,7 +23,7 @@ Next, let's install the testnet's version of the Cosmos SDK. mkdir -p $GOPATH/src/github.com/cosmos cd $GOPATH/src/github.com/cosmos git clone https://github.com/cosmos/cosmos-sdk -cd cosmos-sdk && git checkout v0.18.0 +cd cosmos-sdk && git checkout v0.19.0 make get_tools && make get_vendor_deps && make install ``` @@ -31,7 +31,7 @@ That will install the `gaiad` and `gaiacli` binaries. Verify that everything is ``` gaiad version -0.18.0-eceb56b7 +0.19.0- ``` ### Node Setup @@ -76,7 +76,7 @@ Now it is time to upgrade the software: ``` cd $GOPATH/src/github.com/cosmos/cosmos-sdk -git fetch --all && git checkout v0.18.0 +git fetch --all && git checkout v0.19.0 make update_tools && make get_vendor_deps && make install ``` @@ -90,7 +90,7 @@ Copy the testnet's `genesis.json` file and place it in `gaiad`'s config director ``` mkdir -p $HOME/.gaiad/config -cp -a $GOPATH/src/github.com/cosmos/cosmos-sdk/cmd/gaia/testnets/gaia-6001/genesis.json $HOME/.gaiad/config/genesis.json +cp -a $GOPATH/src/github.com/cosmos/cosmos-sdk/cmd/gaia/testnets/gaia-6002/genesis.json $HOME/.gaiad/config/genesis.json ``` ### Add Seed Nodes @@ -99,7 +99,7 @@ Your node needs to know how to find peers. You'll need to add healthy seed nodes ``` # Comma separated list of seed nodes to connect to -seeds = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6001.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" +seeds = "38aa9bec3998f12ae9088b21a2d910d19d565c27@gaia-6002.coinculture.net:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@seed.cosmos.cryptium.ch:46656,80a35a46ce09cfb31ee220c8141a25e73e0b239b@35.198.166.171:46656,032fa56301de335d835057fb6ad9f7ce2242a66d@165.227.236.213:46656" ``` You can also [ask other validators](https://riot.im/app/#/room/#cosmos_validators:matrix.org) for a persistent peer and add it under the `persistent_peers` key. For more information on seeds and peers, [read this](https://github.com/tendermint/tendermint/blob/develop/docs/using-tendermint.md#peers). diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md index 6f2140c26..9b3940ef2 100644 --- a/cmd/gaia/testnets/STATUS.md +++ b/cmd/gaia/testnets/STATUS.md @@ -1,5 +1,19 @@ # TESTNET STATUS +## *June 13, 2018, 4:30 EST* - New Testnet Gaia-6002 + +- After fixing bugs from gaia-6001, especially [issue + #1197](https://github.com/cosmos/cosmos-sdk/issues/1197), we are announcing a + new testnet, Gaia-6002 +- Gaia-6002 has the same genesis file as Gaia-6001, just with the chain-id + updated + +## *June 13, 2018, 4:30 EST* - New Release + +- Released gaia + [v0.19.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.19.0) +- Includes various bug-fixes for staking found on Gaia-6001 + ## *June 13, 2018, 2:30 EST* - Published Postmortem of Gaia-6001 failure - A bug in the design of the staking data model caused a sanity check to fail diff --git a/cmd/gaia/testnets/gaia-6002/genesis.json b/cmd/gaia/testnets/gaia-6002/genesis.json new file mode 100644 index 000000000..7f53893a8 --- /dev/null +++ b/cmd/gaia/testnets/gaia-6002/genesis.json @@ -0,0 +1,1459 @@ +{ + "genesis_time": "2018-06-16T18:29:12.38288148Z", + "chain_id": "gaia-6002", + "consensus_params": { + "block_size_params": { + "max_bytes": 22020096, + "max_txs": 100000, + "max_gas": -1 + }, + "tx_size_params": { + "max_bytes": 10240, + "max_gas": -1 + }, + "block_gossip_params": { + "block_part_size_bytes": 65536 + }, + "evidence_params": { + "max_age": 100000 + } + }, + "validators": [ + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "power": 1000, + "name": "adrian" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "power": 1000, + "name": "zaki" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "power": 100, + "name": "staked" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "power": 1000, + "name": "polsdam" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "power": 1000, + "name": "lino" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "power": 100, + "name": "" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "power": 1000, + "name": "iris" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "power": 1000, + "name": "pbostrom" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "power": 1000, + "name": "aurel" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "power": 1000, + "name": "bucky" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "power": 100, + "name": "cwgoes" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "power": 1000, + "name": "bdnet" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "power": 1000, + "name": "melea-trust" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "power": 1000, + "name": "naruemon" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "power": 1000, + "name": "idoor" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "power": 1000, + "name": "ATEAM1" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "power": 1000, + "name": "figmatt" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "power": 1000, + "name": "jla-bsd" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "power": 1000, + "name": "Gold" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "power": 1000, + "name": "nylira" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "power": 1000, + "name": "BKCM" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "power": 1000, + "name": "Dev's Validator" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "power": 1000, + "name": "Staking Facilities" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "power": 1000, + "name": "nuevax" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "power": 1000, + "name": "vultr.guest" + }, + { + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "power": 1000, + "name": "forebole" + } + ], + "app_hash": "", + "app_state": { + "accounts": [ + { + "address": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "coins": [ + { + "denom": "devToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "coins": [ + { + "denom": "adrianToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "109720515B4F8C0858DA3521E448262334534FFD", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "coins": [ + { + "denom": "aurelToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "328FBB8EA315D070DF908982A5F91A3618001D20", + "coins": [ + { + "denom": "cwgoesToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "coins": [ + { + "denom": "BKCMToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "coins": [ + { + "denom": "BDToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "coins": [ + { + "denom": "suyuToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "coins": [ + { + "denom": "linoToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "coins": [ + { + "denom": "stakingToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E04662697134905706A4CCDB822AC6FC11C2E", + "coins": [ + { + "denom": "defaultToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "935E48ED79F1006ED135553768E1D9A768747CF6", + "coins": [ + { + "denom": "buckyToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "99FFAEE5BF6040EADA2F26548C4A702619797C9F", + "coins": [ + { + "denom": "kwunyeungToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + }, + { + "address": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zachToken", + "amount": 1000 + } + ] + }, + { + "address": "A323EC45243D600204BA3D298E3C20322D08C84C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "nuevaxToken", + "amount": 1000 + } + ] + }, + { + "address": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "dokiaToken", + "amount": 1000 + } + ] + }, + { + "address": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "forboleToken", + "amount": 1000 + } + ] + }, + { + "address": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "coins": [ + { + "denom": "steak", + "amount": 100 + }, + { + "denom": "pengToken", + "amount": 1000 + } + ] + }, + { + "address": "FD30D5C983FFEDEC069C3DDFCF270E41A556A86E", + "coins": [ + { + "denom": "steak", + "amount": 900 + }, + { + "denom": "faucetToken", + "amount": 10000000 + } + ] + }, + { + "address": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "goldToken", + "amount": 100 + } + ] + }, + { + "address": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "jlaToken", + "amount": 100 + } + ] + }, + { + "address": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "figmattToken", + "amount": 100 + } + ] + }, + { + "address": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "ATEAM1Token", + "amount": 100 + } + ] + }, + { + "address": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "idoorToken", + "amount": 100 + } + ] + }, + { + "address": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "naruemonToken", + "amount": 100 + } + ] + }, + { + "address": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "zakiToken", + "amount": 1000 + } + ] + }, + { + "address": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "coins": [ + { + "denom": "steak", + "amount": 50 + }, + { + "denom": "trustToken", + "amount": 1000 + } + ] + }, + { + "address": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "coins": [ + { + "denom": "poldsamToken", + "amount": 1000 + }, + { + "denom": "steak", + "amount": 50 + } + ] + } + ], + "stake": { + "pool": { + "loose_unbonded_tokens": 2300, + "unbonded_tokens": 0, + "unbonding_tokens": 0, + "bonded_tokens": 23300, + "unbonded_shares": "0", + "unbonding_shares": "0", + "bonded_shares": "23300", + "inflation_last_time": 0, + "inflation": "9012837/100000000", + "date_last_commission_reset": 0, + "prev_bonded_shares": "0" + }, + "params": { + "inflation_rate_change": "13/100", + "inflation_max": "1/5", + "inflation_min": "7/100", + "goal_bonded": "67/100", + "max_validators": 100, + "bond_denom": "steak" + }, + "bonds": [ + { + "delegator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "validator_addr": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "validator_addr": "109720515B4F8C0858DA3521E448262334534FFD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "validator_addr": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "validator_addr": "328FBB8EA315D070DF908982A5F91A3618001D20", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "validator_addr": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "validator_addr": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "validator_addr": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "validator_addr": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "validator_addr": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "validator_addr": "935E04662697134905706A4CCDB822AC6FC11C2E", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "validator_addr": "935E48ED79F1006ED135553768E1D9A768747CF6", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "validator_addr": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "shares": "100", + "height": 0 + }, + { + "delegator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "validator_addr": "A323EC45243D600204BA3D298E3C20322D08C84C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "validator_addr": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "validator_addr": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "validator_addr": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "validator_addr": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "validator_addr": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "validator_addr": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "validator_addr": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "validator_addr": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "validator_addr": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "validator_addr": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "validator_addr": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "validator_addr": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "shares": "1000", + "height": 0 + }, + { + "delegator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "validator_addr": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "shares": "1000", + "height": 0 + } + ], + "validators": [ + { + "owner": "04F01D5AF8DD248130BBE1D0780EA219CE479A9B", + "pub_key": { + "type": "AC26791624DE60", + "value": "PyFJmNrUres3QOkj2BjxplCxrOF+HDFGohi3tRKsToY=" + }, + "description": { + "moniker": "Dev's Validator", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "109720515B4F8C0858DA3521E448262334534FFD", + "pub_key": { + "type": "AC26791624DE60", + "value": "pY7eLF0Ez3yq495kIjag8mD67Q131np/ssagpEvlV2A=" + }, + "description": { + "moniker": "", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "10B0899E05A486AE4E5589C39587DF7E9A185872", + "pub_key": { + "type": "AC26791624DE60", + "value": "RpX+xkwnCNw5DpBelscz4//TiODyC9RDiyIuD6NEwx0=" + }, + "description": { + "moniker": "aurel", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "328FBB8EA315D070DF908982A5F91A3618001D20", + "pub_key": { + "type": "AC26791624DE60", + "value": "dcmCn+RZTBdwbCa4YqSnw/Va7xQloBw6vF87ItLwdM0=" + }, + "description": { + "moniker": "cwgoes", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4062DAFB9ACD4D91051B569CD4B19A26524B314B", + "pub_key": { + "type": "AC26791624DE60", + "value": "QYONAknaJqx3OKPSKraDrOPkx6xssezYtXVS84nZvZE=" + }, + "description": { + "moniker": "BKCM", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "42D76AF31E36EE23CA5366FBB9CE18610CCB9820", + "pub_key": { + "type": "AC26791624DE60", + "value": "TNPLvN6f6QoSLJqGHzIfbraBoSw3emr9Sk2Us94M4gM=" + }, + "description": { + "moniker": "bdnet", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "4B5BE759EB23B0D76C6A60636BD0E3111178794E", + "pub_key": { + "type": "AC26791624DE60", + "value": "7SaH/LyM+qdz9ovD/pvqIf2q7LC7tc5v0ZJxsA2CGTw=" + }, + "description": { + "moniker": "suyu", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "5A007B81A25AF34B829B79DA508A26E12180BCDB", + "pub_key": { + "type": "AC26791624DE60", + "value": "SW12+WpGKUCO9oT2CV0CD5kUclbXjJHV1MjerLWB7Oc=" + }, + "description": { + "moniker": "lino", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "83C2788B74E1A410A4E62F1040EAE15F4B6EA3F5", + "pub_key": { + "type": "AC26791624DE60", + "value": "s4ER09+WeX10euzGyK7xDW7+myQVXt3Plup8IHUE4nk=" + }, + "description": { + "moniker": "Staking Facilities", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E04662697134905706A4CCDB822AC6FC11C2E", + "pub_key": { + "type": "AC26791624DE60", + "value": "bIvXwf0qlOy0rO0SY/h8FfsqyW/AMpGL2yUhUNOY7hs=" + }, + "description": { + "moniker": "default", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "935E48ED79F1006ED135553768E1D9A768747CF6", + "pub_key": { + "type": "AC26791624DE60", + "value": "0aNTDL49987ZNRi3FtJIi0jk93ybHuYg1FjWrfP9H2o=" + }, + "description": { + "moniker": "bucky", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "9D5723057702E2090405AB5D3B48C45B9ABF4377", + "pub_key": { + "type": "AC26791624DE60", + "value": "NjjEQKUsq8F0gWxl3BoU2Li5n7hEz9H/LX80rfMxVyE=" + }, + "description": { + "moniker": "zach", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "100" + }, + "delegator_shares": "100", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A323EC45243D600204BA3D298E3C20322D08C84C", + "pub_key": { + "type": "AC26791624DE60", + "value": "OPxj9edXgufNEjYNhZKqLgmYnK4A3nGw3rxaFQrHn24=" + }, + "description": { + "moniker": "nuevax", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "A9A3DADDC8BFFAD52BA51C8F4F2E9F62709412DC", + "pub_key": { + "type": "AC26791624DE60", + "value": "Hi2rtbdJdQtOe3Kq4OoD/xkWJbIjIsUI9qgLQ6TlhiM=" + }, + "description": { + "moniker": "vultr.guest", + "identity": "", + "website": "https://ion.dokia.capital/", + "details": "DokiaValidator" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B6834D914FE50F0C743E6A012AB20438CFADFB95", + "pub_key": { + "type": "AC26791624DE60", + "value": "ah3JtmBA7gbxSiimPsLqQlV85gpNOUBJMvnxGx8eVlo=" + }, + "description": { + "moniker": "forbole", + "identity": "", + "website": "https://www.forbole.com", + "details": "Recommend. Refer. Reward" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "B75C2C4309475C91E8DE271BC52CBAC408365B83", + "pub_key": { + "type": "AC26791624DE60", + "value": "VfOsmcON77auerRc9zKwOR+CvL0sj1nA45hS2WqX1xE=" + }, + "description": { + "moniker": "nylira", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C0D0CA58C50B7B02A841E1B27D9A21D939754AC7", + "pub_key": { + "type": "AC26791624DE60", + "value": "KOdWpo4aQFrLxVlkyc66p7m6mBNnPLmGuO4Z4L+CI1Y=" + }, + "description": { + "moniker": "Gold", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C5033FCFB67D7BD7B8546389F125710462D4FB6C", + "pub_key": { + "type": "AC26791624DE60", + "value": "p5ijoVwp2zmA7RkXXvPl+yqdnlaWMwoV2pYIN8bDyFs=" + }, + "description": { + "moniker": "jla-bsd", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "C6CB038C98026D2F17241A3B3166AE7E9488D9AD", + "pub_key": { + "type": "AC26791624DE60", + "value": "vSr94aI+zfF3D8Cr2VtCXPpfgj7t2ck8SlZxRsfn7gk=" + }, + "description": { + "moniker": "figmatt", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D0861E3F22339C507B716102FDD5CA681EDE4F8E", + "pub_key": { + "type": "AC26791624DE60", + "value": "S9urD5q7je21qp5vEobiURdWrtJwvqMsfZGQhb8GOBQ=" + }, + "description": { + "moniker": "ATEAM1", + "identity": "", + "website": "", + "details": "ATEAM1" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D6545CB14FCA7840A295FB0566C27E4B9D526993", + "pub_key": { + "type": "AC26791624DE60", + "value": "rcl+kuM69Un/a7e+fQsQrCEtT1g04tFviOeq2GygSIw=" + }, + "description": { + "moniker": "idoor", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "D841E0DACF3994E6A40126F023F6F32F98A5D89E", + "pub_key": { + "type": "AC26791624DE60", + "value": "kol7Gj60Fct4X8T1rHLJQ0z/b14UqqSae8h1e37rLL8=" + }, + "description": { + "moniker": "naruemon", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FD8DA5F512A59A30F8698E3CA638D384A68DF977", + "pub_key": { + "type": "AC26791624DE60", + "value": "TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4=" + }, + "description": { + "moniker": "Adrian Brink - Cryptium Labs", + "identity": "", + "website": "https://cryptium.ch", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "ECE57661F0CDCF28EED257B72F86240E57F4A612", + "pub_key": { + "type": "AC26791624DE60", + "value": "CDF/8aD8Lt+ikR3LyCg9c7DwWBA51NH+MUkH7tzxrfY=" + }, + "description": { + "moniker": "zaki", + "identity": "", + "website": "", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "EFE597F7A90D3F3E7599B25259449628E2C4AFAD", + "pub_key": { + "type": "AC26791624DE60", + "value": "cvGYknYP9XMUzqlXZde7lRpvAp/kZiSRYHg66krJNxQ=" + }, + "description": { + "moniker": "trust", + "identity": "", + "website": "http://cosmos-trust.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + }, + { + "owner": "FA929191B04C5DB222AFC6F15C63EF48CCC864C5", + "pub_key": { + "type": "AC26791624DE60", + "value": "RMwWTZsVdkq1heicNJb2fosy9Fls4NHxAHReiJvHl+8=" + }, + "description": { + "moniker": "proof-of-audit", + "identity": "", + "website": "https://proof-of-audit.com", + "details": "" + }, + "revoked": false, + "pool_shares": { + "status": 2, + "amount": "1000" + }, + "delegator_shares": "1000", + "bond_height": 0, + "bond_intra_tx_counter": 0, + "commision": "0/1", + "commission_max": "0/1", + "commission_change_rate": "0/1", + "commission_change_rate_today": "0/1", + "prev_bonded_shares": "0/1" + } + ] + } + } +} From 6b9f8510323b701c8bb080d383c52dc23905ca00 Mon Sep 17 00:00:00 2001 From: gamarin2 Date: Wed, 13 Jun 2018 11:11:55 +0200 Subject: [PATCH 81/89] Add update testnet guide to status --- cmd/gaia/testnets/STATUS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md index 9b3940ef2..1e3a67704 100644 --- a/cmd/gaia/testnets/STATUS.md +++ b/cmd/gaia/testnets/STATUS.md @@ -7,6 +7,7 @@ new testnet, Gaia-6002 - Gaia-6002 has the same genesis file as Gaia-6001, just with the chain-id updated +- Update from previous testnet [here](https://github.com/cosmos/cosmos-sdk/tree/master/cmd/gaia/testnets#upgrading-from-previous-testnet) ## *June 13, 2018, 4:30 EST* - New Release From ec5fd99fc4381fc233dbeadf6d68ecc14b2da83e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 13 Jun 2018 20:02:08 +0200 Subject: [PATCH 82/89] Move metalinter installation to lint step --- .circleci/config.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ceb9e78a8..258c0b106 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,12 +27,6 @@ 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 - go get -u github.com/alecthomas/gometalinter - run: name: binaries command: | @@ -63,6 +57,12 @@ jobs: key: v1-pkg-cache - restore_cache: key: v1-tree-{{ .Environment.CIRCLE_SHA1 }} + - run: + name: Get metalinter + command: | + export PATH="$GOBIN:$PATH" + go get -u github.com/tendermint/lint/golint + go get -u github.com/alecthomas/gometalinter - run: name: Lint source command: | From ec2fedd36cc361af03c2ce983ea3762614aa4059 Mon Sep 17 00:00:00 2001 From: David Kajpust Date: Wed, 13 Jun 2018 15:13:22 -0400 Subject: [PATCH 83/89] Merge PR #1227: Set all Error strings 1st letters to lowercase. Fixes issue #1154 --- baseapp/baseapp.go | 10 +++---- client/context/helpers.go | 16 +++++------ client/input.go | 4 +-- client/keys/add.go | 2 +- client/lcd/root.go | 2 +- client/rpc/root.go | 2 +- client/tx/search.go | 2 +- cmd/gaia/app/genesis.go | 2 +- examples/democoin/x/cool/errors.go | 2 +- examples/democoin/x/pow/errors.go | 16 +++++------ server/export.go | 2 +- server/start.go | 4 +-- server/start_test.go | 2 +- store/rootmultistore.go | 10 +++---- types/account.go | 2 +- types/coin.go | 4 +-- types/errors.go | 28 +++++++++---------- x/auth/client/rest/query.go | 6 ++-- x/bank/errors.go | 4 +-- x/ibc/client/cli/relay.go | 6 ++-- x/ibc/errors.go | 4 +-- x/slashing/errors.go | 10 +++---- x/slashing/tick.go | 2 +- x/stake/client/rest/query.go | 8 +++--- x/stake/client/rest/tx.go | 12 ++++---- x/stake/errors.go | 44 +++++++++++++++--------------- x/stake/keeper.go | 6 ++-- x/stake/msg.go | 2 +- 28 files changed, 107 insertions(+), 107 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 4d32b92f5..93ea6ae03 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -193,7 +193,7 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error { // TODO: we don't actually need the main store here main := app.cms.GetKVStore(mainKey) if main == nil { - return errors.New("BaseApp expects MultiStore with 'main' KVStore") + return errors.New("baseapp expects MultiStore with 'main' KVStore") } // XXX: Do we really need the header? What does it have that we want @@ -216,11 +216,11 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error { } err := proto.Unmarshal(headerBytes, &header) if err != nil { - return errors.Wrap(err, "Failed to parse Header") + return errors.Wrap(err, "failed to parse Header") } lastVersion := lastCommitID.Version if header.Height != lastVersion { - errStr := fmt.Sprintf("Expected db://%s.Height %v but got %v", dbHeaderKey, lastVersion, header.Height) + errStr := fmt.Sprintf("expected db://%s.Height %v but got %v", dbHeaderKey, lastVersion, header.Height) return errors.New(errStr) } } @@ -468,10 +468,10 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk if r := recover(); r != nil { switch r.(type) { case sdk.ErrorOutOfGas: - log := fmt.Sprintf("Out of gas in location: %v", r.(sdk.ErrorOutOfGas).Descriptor) + log := fmt.Sprintf("out of gas in location: %v", r.(sdk.ErrorOutOfGas).Descriptor) result = sdk.ErrOutOfGas(log).Result() default: - log := fmt.Sprintf("Recovered: %v\nstack:\n%v", r, string(debug.Stack())) + log := fmt.Sprintf("recovered: %v\nstack:\n%v", r, string(debug.Stack())) result = sdk.ErrInternal(log).Result() } } diff --git a/client/context/helpers.go b/client/context/helpers.go index 0229827fe..0e28f5fd0 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -30,12 +30,12 @@ func (ctx CoreContext) BroadcastTx(tx []byte) (*ctypes.ResultBroadcastTxCommit, } if res.CheckTx.Code != uint32(0) { - return res, errors.Errorf("CheckTx failed: (%d) %s", + return res, errors.Errorf("checkTx failed: (%d) %s", res.CheckTx.Code, res.CheckTx.Log) } if res.DeliverTx.Code != uint32(0) { - return res, errors.Errorf("DeliverTx failed: (%d) %s", + return res, errors.Errorf("deliverTx failed: (%d) %s", res.DeliverTx.Code, res.DeliverTx.Log) } @@ -75,7 +75,7 @@ func (ctx CoreContext) query(key cmn.HexBytes, storeName, endPath string) (res [ } resp := result.Response if resp.Code != uint32(0) { - return res, errors.Errorf("Query failed: (%d) %s", resp.Code, resp.Log) + return res, errors.Errorf("query failed: (%d) %s", resp.Code, resp.Log) } return resp.Value, nil } @@ -95,7 +95,7 @@ func (ctx CoreContext) GetFromAddress() (from sdk.Address, err error) { info, err := keybase.Get(name) if err != nil { - return nil, errors.Errorf("No key for: %s", name) + return nil, errors.Errorf("no key for: %s", name) } return info.PubKey.Address(), nil @@ -107,7 +107,7 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w // build the Sign Messsage from the Standard Message chainID := ctx.ChainID if chainID == "" { - return nil, errors.Errorf("Chain ID required but not specified") + return nil, errors.Errorf("chain ID required but not specified") } accnum := ctx.AccountNumber sequence := ctx.Sequence @@ -174,7 +174,7 @@ func (ctx CoreContext) EnsureSignBuildBroadcast(name string, msg sdk.Msg, cdc *w // get the next sequence for the account address func (ctx CoreContext) GetAccountNumber(address []byte) (int64, error) { if ctx.Decoder == nil { - return 0, errors.New("AccountDecoder required but not provided") + return 0, errors.New("accountDecoder required but not provided") } res, err := ctx.Query(auth.AddressStoreKey(address), ctx.AccountStore) @@ -198,7 +198,7 @@ func (ctx CoreContext) GetAccountNumber(address []byte) (int64, error) { // get the next sequence for the account address func (ctx CoreContext) NextSequence(address []byte) (int64, error) { if ctx.Decoder == nil { - return 0, errors.New("AccountDecoder required but not provided") + return 0, errors.New("accountDecoder required but not provided") } res, err := ctx.Query(auth.AddressStoreKey(address), ctx.AccountStore) @@ -229,7 +229,7 @@ func (ctx CoreContext) GetPassphraseFromStdin(name string) (pass string, err err // GetNode prepares a simple rpc.Client func (ctx CoreContext) GetNode() (rpcclient.Client, error) { if ctx.Client == nil { - return nil, errors.New("Must define node URI") + return nil, errors.New("must define node URI") } return ctx.Client, nil } diff --git a/client/input.go b/client/input.go index 53906ca88..03140a33c 100644 --- a/client/input.go +++ b/client/input.go @@ -32,7 +32,7 @@ func GetPassword(prompt string, buf *bufio.Reader) (pass string, err error) { return "", err } if len(pass) < MinPassLength { - return "", errors.Errorf("Password must be at least %d characters", MinPassLength) + return "", errors.Errorf("password must be at least %d characters", MinPassLength) } return pass, nil } @@ -68,7 +68,7 @@ func GetCheckPassword(prompt, prompt2 string, buf *bufio.Reader) (string, error) return "", err } if pass != pass2 { - return "", errors.New("Passphrases don't match") + return "", errors.New("passphrases don't match") } return pass, nil } diff --git a/client/keys/add.go b/client/keys/add.go index 7ad9474ce..5210a388a 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -53,7 +53,7 @@ func runAddCmd(cmd *cobra.Command, args []string) error { name = "inmemorykey" } else { if len(args) != 1 || len(args[0]) == 0 { - return errors.New("You must provide a name for the key") + return errors.New("you must provide a name for the key") } name = args[0] kb, err = GetKeyBase() diff --git a/client/lcd/root.go b/client/lcd/root.go index c3ec75c96..66491dfec 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -49,7 +49,7 @@ func ServeCommand(cdc *wire.Codec) *cobra.Command { // Wait forever and cleanup cmn.TrapSignal(func() { err := listener.Close() - logger.Error("Error closing listener", "err", err) + logger.Error("error closing listener", "err", err) }) return nil }, diff --git a/client/rpc/root.go b/client/rpc/root.go index e89972c3c..63ba64a18 100644 --- a/client/rpc/root.go +++ b/client/rpc/root.go @@ -18,7 +18,7 @@ const ( // XXX: remove this when not needed func todoNotImplemented(_ *cobra.Command, _ []string) error { - return errors.New("TODO: Command not yet implemented") + return errors.New("todo: Command not yet implemented") } // AddCommands adds a number of rpc-related subcommands diff --git a/client/tx/search.go b/client/tx/search.go index 3ab3a3df1..b3ebbf34e 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -54,7 +54,7 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command { func searchTxs(ctx context.CoreContext, cdc *wire.Codec, tags []string) ([]txInfo, error) { if len(tags) == 0 { - return nil, errors.New("Must declare at least one tag to search") + return nil, errors.New("must declare at least one tag to search") } // XXX: implement ANY query := strings.Join(tags, " AND ") diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 558bca38a..06fdbbcc5 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -92,7 +92,7 @@ func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( overwrite := viper.GetBool(flagOWK) name := viper.GetString(flagName) if name == "" { - return nil, nil, tmtypes.GenesisValidator{}, errors.New("Must specify --name (validator moniker)") + return nil, nil, tmtypes.GenesisValidator{}, errors.New("must specify --name (validator moniker)") } var addr sdk.Address diff --git a/examples/democoin/x/cool/errors.go b/examples/democoin/x/cool/errors.go index 7a5e62c5d..73df2386e 100644 --- a/examples/democoin/x/cool/errors.go +++ b/examples/democoin/x/cool/errors.go @@ -16,5 +16,5 @@ const ( // ErrIncorrectCoolAnswer - Error returned upon an incorrect guess func ErrIncorrectCoolAnswer(codespace sdk.CodespaceType, answer string) sdk.Error { - return sdk.NewError(codespace, CodeIncorrectCoolAnswer, fmt.Sprintf("Incorrect cool answer: %v", answer)) + return sdk.NewError(codespace, CodeIncorrectCoolAnswer, fmt.Sprintf("incorrect cool answer: %v", answer)) } diff --git a/examples/democoin/x/pow/errors.go b/examples/democoin/x/pow/errors.go index a499e0d9f..e25964da7 100644 --- a/examples/democoin/x/pow/errors.go +++ b/examples/democoin/x/pow/errors.go @@ -23,21 +23,21 @@ const ( func codeToDefaultMsg(code CodeType) string { switch code { case CodeInvalidDifficulty: - return "Insuffient difficulty" + return "insuffient difficulty" case CodeNonexistentDifficulty: - return "Nonexistent difficulty" + return "nonexistent difficulty" case CodeNonexistentReward: - return "Nonexistent reward" + return "nonexistent reward" case CodeNonexistentCount: - return "Nonexistent count" + return "nonexistent count" case CodeInvalidProof: - return "Invalid proof" + return "invalid proof" case CodeNotBelowTarget: - return "Not below target" + return "not below target" case CodeInvalidCount: - return "Invalid count" + return "invalid count" case CodeUnknownRequest: - return "Unknown request" + return "unknown request" default: return sdk.CodeToDefaultMsg(code) } diff --git a/server/export.go b/server/export.go index 794235f62..0ff7456ad 100644 --- a/server/export.go +++ b/server/export.go @@ -20,7 +20,7 @@ func ExportCmd(ctx *Context, cdc *wire.Codec, appExporter AppExporter) *cobra.Co home := viper.GetString("home") appState, validators, err := appExporter(home, ctx.Logger) if err != nil { - return errors.Errorf("Error exporting state: %v\n", err) + return errors.Errorf("error exporting state: %v\n", err) } doc, err := tmtypes.GenesisDocFromFile(ctx.Config.GenesisFile()) if err != nil { diff --git a/server/start.go b/server/start.go index 9bf2d30cd..5224ef30d 100644 --- a/server/start.go +++ b/server/start.go @@ -9,8 +9,8 @@ import ( tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" "github.com/tendermint/tendermint/node" - "github.com/tendermint/tendermint/proxy" pvm "github.com/tendermint/tendermint/privval" + "github.com/tendermint/tendermint/proxy" cmn "github.com/tendermint/tmlibs/common" ) @@ -55,7 +55,7 @@ func startStandAlone(ctx *Context, appCreator AppCreator) error { svr, err := server.NewServer(addr, "socket", app) if err != nil { - return errors.Errorf("Error creating listener: %v\n", err) + return errors.Errorf("error creating listener: %v\n", err) } svr.SetLogger(ctx.Logger.With("module", "abci-server")) svr.Start() diff --git a/server/start_test.go b/server/start_test.go index 1c1ad671e..046bbe19b 100644 --- a/server/start_test.go +++ b/server/start_test.go @@ -40,7 +40,7 @@ func TestStartStandAlone(t *testing.T) { svrAddr, _, err := FreeTCPAddr() require.Nil(t, err) svr, err := server.NewServer(svrAddr, "socket", app) - require.Nil(t, err, "Error creating listener") + require.Nil(t, err, "error creating listener") svr.SetLogger(logger.With("module", "abci-server")) svr.Start() diff --git a/store/rootmultistore.go b/store/rootmultistore.go index 11cebc22e..05a2e13fb 100644 --- a/store/rootmultistore.go +++ b/store/rootmultistore.go @@ -89,7 +89,7 @@ func (rs *rootMultiStore) LoadVersion(ver int64) error { id := CommitID{} store, err := rs.loadCommitStoreFromParams(id, storeParams) if err != nil { - return fmt.Errorf("Failed to load rootMultiStore: %v", err) + return fmt.Errorf("failed to load rootMultiStore: %v", err) } rs.stores[key] = store } @@ -112,7 +112,7 @@ func (rs *rootMultiStore) LoadVersion(ver int64) error { storeParams := rs.storesParams[key] store, err := rs.loadCommitStoreFromParams(commitID, storeParams) if err != nil { - return fmt.Errorf("Failed to load rootMultiStore: %v", err) + return fmt.Errorf("failed to load rootMultiStore: %v", err) } newStores[key] = store } @@ -120,7 +120,7 @@ func (rs *rootMultiStore) LoadVersion(ver int64) error { // If any CommitStoreLoaders were not used, return error. for key := range rs.storesParams { if _, ok := newStores[key]; !ok { - return fmt.Errorf("Unused CommitStoreLoader: %v", key) + return fmt.Errorf("unused CommitStoreLoader: %v", key) } } @@ -399,14 +399,14 @@ func getCommitInfo(db dbm.DB, ver int64) (commitInfo, error) { cInfoKey := fmt.Sprintf(commitInfoKeyFmt, ver) cInfoBytes := db.Get([]byte(cInfoKey)) if cInfoBytes == nil { - return commitInfo{}, fmt.Errorf("Failed to get rootMultiStore: no data") + return commitInfo{}, fmt.Errorf("failed to get rootMultiStore: no data") } // Parse bytes. var cInfo commitInfo err := cdc.UnmarshalBinary(cInfoBytes, &cInfo) if err != nil { - return commitInfo{}, fmt.Errorf("Failed to get rootMultiStore: %v", err) + return commitInfo{}, fmt.Errorf("failed to get rootMultiStore: %v", err) } return cInfo, nil } diff --git a/types/account.go b/types/account.go index a7dd50ead..00f6cc524 100644 --- a/types/account.go +++ b/types/account.go @@ -160,7 +160,7 @@ func GetFromBech32(bech32str, prefix string) ([]byte, error) { } if hrp != prefix { - return nil, fmt.Errorf("Invalid bech32 prefix. Expected %s, Got %s", prefix, hrp) + return nil, fmt.Errorf("invalid bech32 prefix. Expected %s, Got %s", prefix, hrp) } return bz, nil diff --git a/types/coin.go b/types/coin.go index 8a80bee22..ee2693964 100644 --- a/types/coin.go +++ b/types/coin.go @@ -280,7 +280,7 @@ func ParseCoin(coinStr string) (coin Coin, err error) { matches := reCoin.FindStringSubmatch(coinStr) if matches == nil { - err = fmt.Errorf("Invalid coin expression: %s", coinStr) + err = fmt.Errorf("invalid coin expression: %s", coinStr) return } denomStr, amountStr := matches[2], matches[1] @@ -316,7 +316,7 @@ func ParseCoins(coinsStr string) (coins Coins, err error) { // Validate coins before returning. if !coins.IsValid() { - return nil, fmt.Errorf("ParseCoins invalid: %#v", coins) + return nil, fmt.Errorf("parseCoins invalid: %#v", coins) } return coins, nil diff --git a/types/errors.go b/types/errors.go index 20d452464..f979ee118 100644 --- a/types/errors.go +++ b/types/errors.go @@ -68,31 +68,31 @@ const ( func CodeToDefaultMsg(code CodeType) string { switch code { case CodeInternal: - return "Internal error" + return "internal error" case CodeTxDecode: - return "Tx parse error" + return "tx parse error" case CodeInvalidSequence: - return "Invalid sequence" + return "invalid sequence" case CodeUnauthorized: - return "Unauthorized" + return "unauthorized" case CodeInsufficientFunds: - return "Insufficent funds" + return "insufficent funds" case CodeUnknownRequest: - return "Unknown request" + return "unknown request" case CodeInvalidAddress: - return "Invalid address" + return "invalid address" case CodeInvalidPubKey: - return "Invalid pubkey" + return "invalid pubkey" case CodeUnknownAddress: - return "Unknown address" + return "unknown address" case CodeInsufficientCoins: - return "Insufficient coins" + return "insufficient coins" case CodeInvalidCoins: - return "Invalid coins" + return "invalid coins" case CodeOutOfGas: - return "Out of gas" + return "out of gas" default: - return fmt.Sprintf("Unknown code %d", code) + return fmt.Sprintf("unknown code %d", code) } } @@ -183,7 +183,7 @@ type sdkError struct { // Implements ABCIError. func (err *sdkError) Error() string { - return fmt.Sprintf("Error{%d:%d,%#v}", err.codespace, err.code, err.err) + return fmt.Sprintf("error{%d:%d,%#v}", err.codespace, err.code, err.err) } // Implements ABCIError. diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 9ccbe8e14..1f68a69e5 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -37,7 +37,7 @@ func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder aut res, err := ctx.Query(auth.AddressStoreKey(addr), storeName) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Could't query account. Error: %s", err.Error()))) + w.Write([]byte(fmt.Sprintf("couldn't query account. Error: %s", err.Error()))) return } @@ -51,7 +51,7 @@ func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder aut 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()))) + w.Write([]byte(fmt.Sprintf("couldn't parse query result. Result: %s. Error: %s", res, err.Error()))) return } @@ -59,7 +59,7 @@ func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder aut output, err := cdc.MarshalJSON(account) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Could't marshall query result. Error: %s", err.Error()))) + w.Write([]byte(fmt.Sprintf("couldn't marshall query result. Error: %s", err.Error()))) return } diff --git a/x/bank/errors.go b/x/bank/errors.go index bf2a3ef26..cf11ddc22 100644 --- a/x/bank/errors.go +++ b/x/bank/errors.go @@ -17,9 +17,9 @@ const ( func codeToDefaultMsg(code sdk.CodeType) string { switch code { case CodeInvalidInput: - return "Invalid input coins" + return "invalid input coins" case CodeInvalidOutput: - return "Invalid output coins" + return "invalid output coins" default: return sdk.CodeToDefaultMsg(code) } diff --git a/x/ibc/client/cli/relay.go b/x/ibc/client/cli/relay.go index caf96d60a..96c5b08cc 100644 --- a/x/ibc/client/cli/relay.go +++ b/x/ibc/client/cli/relay.go @@ -116,7 +116,7 @@ OUTER: lengthKey := ibc.EgressLengthKey(toChainID) egressLengthbz, err := query(fromChainNode, lengthKey, c.ibcStore) if err != nil { - c.logger.Error("Error querying outgoing packet list length", "err", err) + c.logger.Error("error querying outgoing packet list length", "err", err) continue OUTER //TODO replace with continue (I think it should just to the correct place where OUTER is now) } var egressLength int64 @@ -134,14 +134,14 @@ OUTER: for i := processed; i < egressLength; i++ { egressbz, err := query(fromChainNode, ibc.EgressKey(toChainID, i), c.ibcStore) if err != nil { - c.logger.Error("Error querying egress packet", "err", err) + c.logger.Error("error querying egress packet", "err", err) 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) + c.logger.Error("error broadcasting ingress packet", "err", err) continue OUTER // TODO replace to break, will break first loop then send back to the beginning (aka OUTER) } diff --git a/x/ibc/errors.go b/x/ibc/errors.go index 60a141eba..f7beb0e1d 100644 --- a/x/ibc/errors.go +++ b/x/ibc/errors.go @@ -17,9 +17,9 @@ const ( func codeToDefaultMsg(code sdk.CodeType) string { switch code { case CodeInvalidSequence: - return "Invalid IBC packet sequence" + return "invalid IBC packet sequence" case CodeIdenticalChains: - return "Source and destination chain cannot be identical" + return "source and destination chain cannot be identical" default: return sdk.CodeToDefaultMsg(code) } diff --git a/x/slashing/errors.go b/x/slashing/errors.go index 087dc0314..b9b152c7b 100644 --- a/x/slashing/errors.go +++ b/x/slashing/errors.go @@ -19,21 +19,21 @@ const ( ) func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "That address is not associated with any known validator") + return newError(codespace, CodeInvalidValidator, "that address is not associated with any known validator") } func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address") + return newError(codespace, CodeInvalidValidator, "validator does not exist for that address") } func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeValidatorJailed, "Validator jailed, cannot yet be unrevoked") + return newError(codespace, CodeValidatorJailed, "validator jailed, cannot yet be unrevoked") } func codeToDefaultMsg(code CodeType) string { switch code { case CodeInvalidValidator: - return "Invalid Validator" + return "invalid Validator" case CodeValidatorJailed: - return "Validator Jailed" + return "validator Jailed" default: return sdk.CodeToDefaultMsg(code) } diff --git a/x/slashing/tick.go b/x/slashing/tick.go index 526baece0..6eb6eeb32 100644 --- a/x/slashing/tick.go +++ b/x/slashing/tick.go @@ -26,7 +26,7 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags case tmtypes.ABCIEvidenceTypeDuplicateVote: sk.handleDoubleSign(ctx, evidence.Height, evidence.Time, pk) default: - ctx.Logger().With("module", "x/slashing").Error(fmt.Sprintf("Ignored unknown evidence type: %s", string(evidence.Type))) + ctx.Logger().With("module", "x/slashing").Error(fmt.Sprintf("ignored unknown evidence type: %s", string(evidence.Type))) } } diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index f8a2f00e5..d9288fb11 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -51,7 +51,7 @@ func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire 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()))) + w.Write([]byte(fmt.Sprintf("couldn't query bond. Error: %s", err.Error()))) return } @@ -65,7 +65,7 @@ func bondingStatusHandlerFn(ctx context.CoreContext, storeName string, cdc *wire 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()))) + w.Write([]byte(fmt.Sprintf("couldn't decode bond. Error: %s", err.Error()))) return } @@ -142,7 +142,7 @@ func validatorsHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Co kvs, err := ctx.QuerySubspace(cdc, stake.ValidatorsKey, storeName) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Couldn't query validators. Error: %s", err.Error()))) + w.Write([]byte(fmt.Sprintf("couldn't query validators. Error: %s", err.Error()))) return } @@ -163,7 +163,7 @@ func validatorsHandlerFn(ctx context.CoreContext, storeName string, cdc *wire.Co } if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))) + w.Write([]byte(fmt.Sprintf("couldn't decode validator. Error: %s", err.Error()))) return } validators[i] = bech32Validator diff --git a/x/stake/client/rest/tx.go b/x/stake/client/rest/tx.go index 77a6540ee..669bdd39f 100644 --- a/x/stake/client/rest/tx.go +++ b/x/stake/client/rest/tx.go @@ -76,18 +76,18 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx conte delegatorAddr, err := sdk.GetAccAddressBech32(msg.DelegatorAddr) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error()))) + w.Write([]byte(fmt.Sprintf("couldn't decode delegator. Error: %s", err.Error()))) return } validatorAddr, err := sdk.GetValAddressBech32(msg.ValidatorAddr) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))) + w.Write([]byte(fmt.Sprintf("couldn't decode validator. Error: %s", err.Error()))) return } if !bytes.Equal(info.Address(), delegatorAddr) { w.WriteHeader(http.StatusUnauthorized) - w.Write([]byte("Must use own delegator address")) + w.Write([]byte("must use own delegator address")) return } messages[i] = stake.MsgDelegate{ @@ -101,18 +101,18 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx conte delegatorAddr, err := sdk.GetAccAddressBech32(msg.DelegatorAddr) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error()))) + w.Write([]byte(fmt.Sprintf("couldn't decode delegator. Error: %s", err.Error()))) return } validatorAddr, err := sdk.GetValAddressBech32(msg.ValidatorAddr) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))) + w.Write([]byte(fmt.Sprintf("couldn't decode validator. Error: %s", err.Error()))) return } if !bytes.Equal(info.Address(), delegatorAddr) { w.WriteHeader(http.StatusUnauthorized) - w.Write([]byte("Must use own delegator address")) + w.Write([]byte("must use own delegator address")) return } messages[i] = stake.MsgUnbond{ diff --git a/x/stake/errors.go b/x/stake/errors.go index 0ae57530a..796d638db 100644 --- a/x/stake/errors.go +++ b/x/stake/errors.go @@ -26,17 +26,17 @@ const ( func codeToDefaultMsg(code CodeType) string { switch code { case CodeInvalidValidator: - return "Invalid Validator" + return "invalid Validator" case CodeInvalidBond: - return "Invalid Bond" + return "invalid Bond" case CodeInvalidInput: - return "Invalid Input" + return "invalid Input" case CodeUnauthorized: - return "Unauthorized" + return "unauthorized" case CodeInternal: - return "Internal Error" + return "internal Error" case CodeUnknownRequest: - return "Unknown request" + return "unknown request" default: return sdk.CodeToDefaultMsg(code) } @@ -49,55 +49,55 @@ func ErrNotEnoughBondShares(codespace sdk.CodespaceType, shares string) sdk.Erro return newError(codespace, CodeInvalidBond, fmt.Sprintf("not enough shares only have %v", shares)) } func ErrValidatorEmpty(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Cannot bond to an empty validator") + return newError(codespace, CodeInvalidValidator, "cannot bond to an empty validator") } func ErrBadBondingDenom(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidBond, "Invalid coin denomination") + return newError(codespace, CodeInvalidBond, "invalid coin denomination") } func ErrBadBondingAmount(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidBond, "Amount must be > 0") + return newError(codespace, CodeInvalidBond, "amount must be > 0") } func ErrNoBondingAcct(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "No bond account for this (address, validator) pair") + return newError(codespace, CodeInvalidValidator, "no bond account for this (address, validator) pair") } func ErrCommissionNegative(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Commission must be positive") + return newError(codespace, CodeInvalidValidator, "commission must be positive") } func ErrCommissionHuge(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Commission cannot be more than 100%") + return newError(codespace, CodeInvalidValidator, "commission cannot be more than 100%") } func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address") + return newError(codespace, CodeInvalidValidator, "validator does not exist for that address") } func ErrBadDelegatorAddr(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Delegator does not exist for that address") + return newError(codespace, CodeInvalidValidator, "delegator does not exist for that address") } func ErrValidatorExistsAddr(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Validator already exist, cannot re-create validator") + return newError(codespace, CodeInvalidValidator, "validator already exist, cannot re-create validator") } func ErrValidatorRevoked(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Validator for this address is currently revoked") + return newError(codespace, CodeInvalidValidator, "validator for this address is currently revoked") } func ErrMissingSignature(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Missing signature") + return newError(codespace, CodeInvalidValidator, "missing signature") } func ErrBondNotNominated(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Cannot bond to non-nominated account") + return newError(codespace, CodeInvalidValidator, "cannot bond to non-nominated account") } func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address") + return newError(codespace, CodeInvalidValidator, "validator does not exist for that address") } func ErrNoDelegatorForAddress(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Delegator does not contain validator bond") + return newError(codespace, CodeInvalidValidator, "delegator does not contain validator bond") } func ErrInsufficientFunds(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidInput, "Insufficient bond shares") + return newError(codespace, CodeInvalidInput, "insufficient bond shares") } func ErrBadShares(codespace sdk.CodespaceType) sdk.Error { return newError(codespace, CodeInvalidInput, "bad shares provided as input, must be MAX or decimal") } func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error { - return newError(codespace, CodeInvalidValidator, "Error removing validator") + return newError(codespace, CodeInvalidValidator, "error removing validator") } //---------------------------------------- diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 4a2e6ff4b..a4a1bc01c 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -804,7 +804,7 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, height int64, fract logger := ctx.Logger().With("module", "x/stake") val, found := k.GetValidatorByPubKey(ctx, pubkey) if !found { - panic(fmt.Errorf("Attempted to slash a nonexistent validator with address %s", pubkey.Address())) + panic(fmt.Errorf("attempted to slash a nonexistent validator with address %s", pubkey.Address())) } sharesToRemove := val.PoolShares.Amount.Mul(fraction) pool := k.GetPool(ctx) @@ -820,7 +820,7 @@ func (k Keeper) Revoke(ctx sdk.Context, pubkey crypto.PubKey) { logger := ctx.Logger().With("module", "x/stake") val, found := k.GetValidatorByPubKey(ctx, pubkey) if !found { - panic(fmt.Errorf("Validator with pubkey %s not found, cannot revoke", pubkey)) + panic(fmt.Errorf("validator with pubkey %s not found, cannot revoke", pubkey)) } val.Revoked = true k.updateValidator(ctx, val) // update the validator, now revoked @@ -833,7 +833,7 @@ func (k Keeper) Unrevoke(ctx sdk.Context, pubkey crypto.PubKey) { logger := ctx.Logger().With("module", "x/stake") val, found := k.GetValidatorByPubKey(ctx, pubkey) if !found { - panic(fmt.Errorf("Validator with pubkey %s not found, cannot unrevoke", pubkey)) + panic(fmt.Errorf("validator with pubkey %s not found, cannot unrevoke", pubkey)) } val.Revoked = false k.updateValidator(ctx, val) // update the validator, now unrevoked diff --git a/x/stake/msg.go b/x/stake/msg.go index a0922bb87..fbdd04853 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -122,7 +122,7 @@ func (msg MsgEditValidator) ValidateBasic() sdk.Error { } empty := Description{} if msg.Description == empty { - return newError(DefaultCodespace, CodeInvalidInput, "Transaction must include some information to modify") + return newError(DefaultCodespace, CodeInvalidInput, "transaction must include some information to modify") } return nil } From 0fa28cac3bae82b3c63ff8203b85aa98327e3da3 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Wed, 13 Jun 2018 14:44:41 -0700 Subject: [PATCH 84/89] Merge PR #1248: Sync to tendermint develop's latest revision --- Gopkg.lock | 9 ++++----- Gopkg.toml | 4 ++-- server/tm_cmds.go | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 07a3c6d5b..701f383af 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -267,8 +267,8 @@ "server", "types" ] - revision = "ebee2fe114020aa49c70bbbae50b7079fc7e7b90" - version = "v0.11.0" + revision = "198dccf0ddfd1bb176f87657e3286a05a6ed9540" + version = "v0.12.0" [[projects]] branch = "master" @@ -347,8 +347,7 @@ "types", "version" ] - revision = "27bd1deabe4ba6a2d9b463b8f3e3f1e31b993e61" - version = "v0.20.0" + revision = "696e8c6f9e950eec15f150f314d2dd9ddf6bc601" [[projects]] branch = "develop" @@ -463,6 +462,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "31f69b235b2d8f879a215c9e8ca0919adc62d21f6830b17931a3a0efb058721f" + inputs-digest = "d02a24bcfd8bded901e1b154e19b81ff797d3921046ede19d1d11eed61e871e7" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 77de1b78d..49bbf9f79 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -54,7 +54,7 @@ [[constraint]] name = "github.com/tendermint/abci" - version = "=0.11.0" + version = "=0.12.0" [[constraint]] name = "github.com/tendermint/go-crypto" @@ -70,7 +70,7 @@ [[constraint]] name = "github.com/tendermint/tendermint" - version = "=0.20.0" + revision = "696e8c6f9e950eec15f150f314d2dd9ddf6bc601" [[override]] name = "github.com/tendermint/tmlibs" diff --git a/server/tm_cmds.go b/server/tm_cmds.go index 7dccaf531..25d417a66 100644 --- a/server/tm_cmds.go +++ b/server/tm_cmds.go @@ -72,7 +72,7 @@ func UnsafeResetAllCmd(ctx *Context) *cobra.Command { 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) + tcmd.ResetAll(cfg.DBDir(), cfg.P2P.AddrBookFile(), cfg.PrivValidatorFile(), ctx.Logger) return nil }, } From 3cbb06015e88892e65ceccbcfd5c2808c5f5d34c Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 13 Jun 2018 15:17:18 -0700 Subject: [PATCH 85/89] add gaiadebug readme --- cmd/gaia/cmd/gaiadebug/README.md | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 cmd/gaia/cmd/gaiadebug/README.md diff --git a/cmd/gaia/cmd/gaiadebug/README.md b/cmd/gaia/cmd/gaiadebug/README.md new file mode 100644 index 000000000..c2f0b8bc0 --- /dev/null +++ b/cmd/gaia/cmd/gaiadebug/README.md @@ -0,0 +1,35 @@ +# Gaiadebug + +Simple tool for simple debugging. + +We try to accept both hex and base64 formats and provide a useful response. + +Note we often encode bytes as hex in the logs, but as base64 in the JSON. + +## Pubkeys + +The following give the same result: + +``` +gaiadebug pubkey TZTQnfqOsi89SeoXVnIw+tnFJnr4X8qVC0U8AsEmFk4= +gaiadebug pubkey 4D94D09DFA8EB22F3D49EA17567230FAD9C5267AF85FCA950B453C02C126164E +``` + +## Txs + +Pass in a hex/base64 tx and get back the full JSON + +``` +gaiadebug tx +``` + +## Hack + +This is a command with boilerplate for using Go as a scripting language to hack +on an existing Gaia state. + +Currently we have an example for the state of gaia-6001 after it +[crashed](https://github.com/cosmos/cosmos-sdk/blob/master/cmd/gaia/testnets/STATUS.md#june-13-2018-230-est---published-postmortem-of-gaia-6001-failure). +If you run `gaiadebug hack $HOME/.gaiad` on that +state, it will do a binary search on the state history to find when the state +invariant was violated. From 0180a5b48ebbae233ae0fb72e66cb77217fc0b2b Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 13 Jun 2018 15:20:54 -0700 Subject: [PATCH 86/89] testnets/status: gaia-6002 is live --- cmd/gaia/testnets/STATUS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/gaia/testnets/STATUS.md b/cmd/gaia/testnets/STATUS.md index 1e3a67704..0848f27ef 100644 --- a/cmd/gaia/testnets/STATUS.md +++ b/cmd/gaia/testnets/STATUS.md @@ -1,5 +1,11 @@ # TESTNET STATUS +## *June 13, 2018, 17:00 EST* - Gaia-6002 is making blocks! + +- Gaia-6002 is live and making blocks +- Absent validators have been slashed and revoked +- Currently live with 17 validators + ## *June 13, 2018, 4:30 EST* - New Testnet Gaia-6002 - After fixing bugs from gaia-6001, especially [issue From bd362ee590f35436a02b04d8a482392dbe941713 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Wed, 13 Jun 2018 15:13:51 -0700 Subject: [PATCH 87/89] Merge PR #1090: Switch away from ephemeral ports * Switch ports 4665x to be 2655x This is done so the default ports aren't in the linux kernel's default ephemeral port range. * Missed one doc file, change dep so gaiad works * Update changelog, fix Gopkg.lock --- CHANGELOG.md | 5 ++++- baseapp/helpers.go | 2 +- client/flags.go | 4 ++-- client/lcd/root.go | 2 +- client/rpc/block.go | 2 +- client/rpc/root.go | 2 +- client/rpc/status.go | 2 +- client/rpc/validators.go | 2 +- client/tx/query.go | 2 +- client/tx/search.go | 2 +- docs/old/basecoin/basics.rst | 2 +- docs/old/basecoin/extensions.rst | 2 +- docs/old/staking/local-testnet.rst | 12 ++++++------ docs/old/staking/public-testnet.rst | 2 +- docs/sdk/lcd-rest-api.yaml | 2 +- docs/staking/intro.rst | 2 +- docs/staking/testnet.rst | 2 +- examples/kvstore/main.go | 2 +- networks/remote/ansible/status.yml | 2 +- server/init.go | 2 +- server/start.go | 2 +- x/ibc/client/cli/README.md | 4 ++-- x/ibc/client/cli/relay.go | 2 +- 23 files changed, 33 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdfd1895f..b37db2292 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ *TBD* +BREAKING CHANGES +* Change default ports from 466xx to 266xx + ## 0.19.0 *June 13, 2018* @@ -24,7 +27,7 @@ IMPROVEMENTS FIXES * Fixes consensus fault on testnet - see postmortem [here](https://github.com/cosmos/cosmos-sdk/issues/1197#issuecomment-396823021) -* [x/stake] bonded inflation removed, non-bonded inflation partially implemented +* [x/stake] bonded inflation removed, non-bonded inflation partially implemented * [lcd] Switch to bech32 for addresses on all human readable inputs and outputs * [lcd] fixed tx indexing/querying * [cli] Added `--gas` flag to specify transaction gas limit diff --git a/baseapp/helpers.go b/baseapp/helpers.go index 43bd654d6..b7ac45d9a 100644 --- a/baseapp/helpers.go +++ b/baseapp/helpers.go @@ -10,7 +10,7 @@ import ( func RunForever(app abci.Application) { // Start the ABCI server - srv, err := server.NewServer("0.0.0.0:46658", "socket", app) + srv, err := server.NewServer("0.0.0.0:26658", "socket", app) if err != nil { cmn.Exit(err.Error()) } diff --git a/client/flags.go b/client/flags.go index 4991b9a77..5af588bd4 100644 --- a/client/flags.go +++ b/client/flags.go @@ -25,7 +25,7 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command { // TODO: make this default false when we support proofs c.Flags().Bool(FlagTrustNode, true, "Don't verify proofs for responses") c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") - c.Flags().String(FlagNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") + c.Flags().String(FlagNode, "tcp://localhost:26657", ": to tendermint rpc interface for this chain") c.Flags().Int64(FlagHeight, 0, "block height to query, omit to get most recent provable block") } return cmds @@ -39,7 +39,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command { c.Flags().Int64(FlagSequence, 0, "Sequence number to sign the tx") c.Flags().String(FlagFee, "", "Fee to pay along with transaction") c.Flags().String(FlagChainID, "", "Chain ID of tendermint node") - c.Flags().String(FlagNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") + c.Flags().String(FlagNode, "tcp://localhost:26657", ": to tendermint rpc interface for this chain") c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction") } return cmds diff --git a/client/lcd/root.go b/client/lcd/root.go index 66491dfec..7d819740c 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -57,7 +57,7 @@ func ServeCommand(cdc *wire.Codec) *cobra.Command { cmd.Flags().StringP(flagListenAddr, "a", "tcp://localhost:1317", "Address for server to listen on") cmd.Flags().String(flagCORS, "", "Set to domains that can make CORS requests (* for all)") cmd.Flags().StringP(client.FlagChainID, "c", "", "ID of chain we connect to") - cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") return cmd } diff --git a/client/rpc/block.go b/client/rpc/block.go index 693298bb8..3244e8d12 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -24,7 +24,7 @@ func BlockCommand() *cobra.Command { Args: cobra.MaximumNArgs(1), RunE: printBlock, } - cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") // TODO: change this to false when we can cmd.Flags().Bool(client.FlagTrustNode, true, "Don't verify proofs for responses") cmd.Flags().StringSlice(flagSelect, []string{"header", "tx"}, "Fields to return (header|txs|results)") diff --git a/client/rpc/root.go b/client/rpc/root.go index 63ba64a18..bb5a162a7 100644 --- a/client/rpc/root.go +++ b/client/rpc/root.go @@ -36,7 +36,7 @@ func initClientCommand() *cobra.Command { RunE: todoNotImplemented, } cmd.Flags().StringP(client.FlagChainID, "c", "", "ID of chain we connect to") - cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") cmd.Flags().String(flagGenesis, "", "Genesis file to verify header validity") cmd.Flags().String(flagCommit, "", "File with trusted and signed header") cmd.Flags().String(flagValHash, "", "Hash of trusted validator set (hex-encoded)") diff --git a/client/rpc/status.go b/client/rpc/status.go index 70d6628e4..96517cc19 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -18,7 +18,7 @@ func statusCommand() *cobra.Command { Short: "Query remote node for status", RunE: printNodeStatus, } - cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") return cmd } diff --git a/client/rpc/validators.go b/client/rpc/validators.go index f8835d737..d88fb7317 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -24,7 +24,7 @@ func ValidatorCommand() *cobra.Command { Args: cobra.MaximumNArgs(1), RunE: printValidators, } - cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "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 diff --git a/client/tx/query.go b/client/tx/query.go index 7673dd38d..86439b317 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -42,7 +42,7 @@ func QueryTxCmd(cdc *wire.Codec) *cobra.Command { }, } - cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "Node to connect to") // TODO: change this to false when we can cmd.Flags().Bool(client.FlagTrustNode, true, "Don't verify proofs for responses") diff --git a/client/tx/search.go b/client/tx/search.go index b3ebbf34e..7c75be8f7 100644 --- a/client/tx/search.go +++ b/client/tx/search.go @@ -43,7 +43,7 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command { }, } - cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") + cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "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") diff --git a/docs/old/basecoin/basics.rst b/docs/old/basecoin/basics.rst index d3627b2b1..3b61dd6e5 100644 --- a/docs/old/basecoin/basics.rst +++ b/docs/old/basecoin/basics.rst @@ -78,7 +78,7 @@ window. Here run: :: - basecli init --node=tcp://localhost:46657 --genesis=$HOME/.basecoin/genesis.json + basecli init --node=tcp://localhost:26657 --genesis=$HOME/.basecoin/genesis.json If you provide the genesis file to basecli, it can calculate the proper chainID and validator hash. Basecli needs to get this information from diff --git a/docs/old/basecoin/extensions.rst b/docs/old/basecoin/extensions.rst index c1db864a3..6f31222de 100644 --- a/docs/old/basecoin/extensions.rst +++ b/docs/old/basecoin/extensions.rst @@ -49,7 +49,7 @@ initialize the light-client and send a transaction: :: - countercli init --node=tcp://localhost:46657 --genesis=$HOME/.counter/genesis.json + countercli init --node=tcp://localhost:26657 --genesis=$HOME/.counter/genesis.json YOU=$(countercli keys get friend | awk '{print $2}') countercli tx send --name=cool --amount=1000mycoin --to=$YOU --sequence=1 diff --git a/docs/old/staking/local-testnet.rst b/docs/old/staking/local-testnet.rst index e3f69bded..b8d30d2e2 100644 --- a/docs/old/staking/local-testnet.rst +++ b/docs/old/staking/local-testnet.rst @@ -39,18 +39,18 @@ and ports. It should look like: :: - proxy_app = "tcp://127.0.0.1:46668" + proxy_app = "tcp://127.0.0.1:26668" moniker = "anonymous" fast_sync = true db_backend = "leveldb" log_level = "state:info,*:error" [rpc] - laddr = "tcp://0.0.0.0:46667" + laddr = "tcp://0.0.0.0:26667" [p2p] - laddr = "tcp://0.0.0.0:46666" - seeds = "0.0.0.0:46656" + laddr = "tcp://0.0.0.0:26666" + seeds = "0.0.0.0:26656" Start Nodes ----------- @@ -69,14 +69,14 @@ account: :: - gaia client init --chain-id=gaia-test --node=tcp://localhost:46657 + gaia client init --chain-id=gaia-test --node=tcp://localhost:26657 gaia client query account 5D93A6059B6592833CBC8FA3DA90EE0382198985 To see what tendermint considers the validator set is, use: :: - curl localhost:46657/validators + curl localhost:26657/validators and compare the information in this file: ``~/.gaia1/priv_validator.json``. The ``address`` and ``pub_key`` fields should match. diff --git a/docs/old/staking/public-testnet.rst b/docs/old/staking/public-testnet.rst index 640163642..587c025b1 100644 --- a/docs/old/staking/public-testnet.rst +++ b/docs/old/staking/public-testnet.rst @@ -49,7 +49,7 @@ Finally, let's initialize the gaia client to interact with the testnet: :: - gaia client init --chain-id=gaia-1 --node=tcp://localhost:46657 + gaia client init --chain-id=gaia-1 --node=tcp://localhost:26657 and check our balance: diff --git a/docs/sdk/lcd-rest-api.yaml b/docs/sdk/lcd-rest-api.yaml index 3008d7f73..6a5be2394 100644 --- a/docs/sdk/lcd-rest-api.yaml +++ b/docs/sdk/lcd-rest-api.yaml @@ -41,7 +41,7 @@ paths: type: string listen_addr: type: string - example: 192.168.56.1:46656 + example: 192.168.56.1:26656 version: description: Tendermint version type: string diff --git a/docs/staking/intro.rst b/docs/staking/intro.rst index 00a68811a..3ed20852b 100644 --- a/docs/staking/intro.rst +++ b/docs/staking/intro.rst @@ -291,7 +291,7 @@ To confirm for certain the new validator is active, ask the tendermint node: :: - curl localhost:46657/validators + curl localhost:26657/validators 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 diff --git a/docs/staking/testnet.rst b/docs/staking/testnet.rst index 4fca09c4a..0e86a952d 100644 --- a/docs/staking/testnet.rst +++ b/docs/staking/testnet.rst @@ -66,7 +66,7 @@ To confirm for certain the new validator is active, check tendermint: :: - curl localhost:46657/validators + curl localhost:26657/validators Finally, to relinquish all your power, unbond some coins. You should see your VotingPower reduce and your account balance increase. diff --git a/examples/kvstore/main.go b/examples/kvstore/main.go index 856538f63..6835f5407 100644 --- a/examples/kvstore/main.go +++ b/examples/kvstore/main.go @@ -50,7 +50,7 @@ func main() { } // Start the ABCI server - srv, err := server.NewServer("0.0.0.0:46658", "socket", baseApp) + srv, err := server.NewServer("0.0.0.0:26658", "socket", baseApp) if err != nil { fmt.Println(err) os.Exit(1) diff --git a/networks/remote/ansible/status.yml b/networks/remote/ansible/status.yml index fffba41fc..d0b89d13f 100644 --- a/networks/remote/ansible/status.yml +++ b/networks/remote/ansible/status.yml @@ -9,7 +9,7 @@ - name: Gather status uri: body_format: json - url: "http://{{inventory_hostname}}:46657/status" + url: "http://{{inventory_hostname}}:26657/status" register: status - name: Print status diff --git a/server/init.go b/server/init.go index 512751bed..5e5a73fbe 100644 --- a/server/init.go +++ b/server/init.go @@ -255,7 +255,7 @@ func processGenTxs(genTxsDir string, cdc *wire.Codec, appInit AppInit) ( if len(persistentPeers) == 0 { comma = "" } - persistentPeers += fmt.Sprintf("%s%s@%s:46656", comma, genTx.NodeID, genTx.IP) + persistentPeers += fmt.Sprintf("%s%s@%s:26656", comma, genTx.NodeID, genTx.IP) } return diff --git a/server/start.go b/server/start.go index 5224ef30d..77a18fffb 100644 --- a/server/start.go +++ b/server/start.go @@ -37,7 +37,7 @@ func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command { // 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") + cmd.Flags().String(flagAddress, "tcp://0.0.0.0:26658", "Listen address") // AddNodeFlags adds support for all tendermint-specific command line options tcmd.AddNodeFlags(cmd) diff --git a/x/ibc/client/cli/README.md b/x/ibc/client/cli/README.md index ed9652fa3..e91fb55bf 100644 --- a/x/ibc/client/cli/README.md +++ b/x/ibc/client/cli/README.md @@ -58,7 +58,7 @@ I[04-02|14:09:14.453] Generated genesis file module=main p } > ADDR2=DC26002735D3AA9573707CFA6D77C12349E49868 > ID2=test-chain-4XHTPn -> NODE2=tcp://0.0.0.0:46657 +> NODE2=tcp://0.0.0.0:26657 > basecli keys add key2 --recover Enter a passphrase for your key: Repeat the passphrase: @@ -70,7 +70,7 @@ key2 DC26002735D3AA9573707CFA6D77C12349E49868 > basecoind start --home ~/.chain1 --address tcp://0.0.0.0:36658 --rpc.laddr tcp://0.0.0.0:36657 --p2p.laddr tcp://0.0.0.0:36656 ... -> basecoind start --home ~/.chain2 # --address tcp://0.0.0.0:46658 --rpc.laddr tcp://0.0.0.0:46657 --p2p.laddr tcp://0.0.0.0:46656 +> basecoind start --home ~/.chain2 # --address tcp://0.0.0.0:26658 --rpc.laddr tcp://0.0.0.0:26657 --p2p.laddr tcp://0.0.0.0:26656 ... ``` ## Check balance diff --git a/x/ibc/client/cli/relay.go b/x/ibc/client/cli/relay.go index 96c5b08cc..9742f83f9 100644 --- a/x/ibc/client/cli/relay.go +++ b/x/ibc/client/cli/relay.go @@ -54,7 +54,7 @@ func IBCRelayCmd(cdc *wire.Codec) *cobra.Command { } cmd.Flags().String(FlagFromChainID, "", "Chain ID for ibc node to check outgoing packets") - cmd.Flags().String(FlagFromChainNode, "tcp://localhost:46657", ": to tendermint rpc interface for this chain") + cmd.Flags().String(FlagFromChainNode, "tcp://localhost:26657", ": to tendermint rpc interface for this chain") cmd.Flags().String(FlagToChainID, "", "Chain ID for ibc node to broadcast incoming packets") cmd.Flags().String(FlagToChainNode, "tcp://localhost:36657", ": to tendermint rpc interface for this chain") From ff34cbc8bc9684a8297a5f2238a36101867da7b0 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 13 Jun 2018 17:41:01 -0700 Subject: [PATCH 88/89] gaia/cli_test: remove sleeps --- cmd/gaia/cli_test/cli_test.go | 13 ++++---- tests/util.go | 56 +++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 1868452a6..3eee20c85 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "testing" - "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -50,7 +49,7 @@ func TestGaiaCLISend(t *testing.T) { assert.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak")) executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barCech), pass) - time.Sleep(time.Second * 2) // waiting for some blocks to pass + tests.WaitForNextHeightTM(port) barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags)) assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak")) @@ -59,7 +58,7 @@ func TestGaiaCLISend(t *testing.T) { // test autosequencing executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barCech), pass) - time.Sleep(time.Second * 2) // waiting for some blocks to pass + tests.WaitForNextHeightTM(port) barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags)) assert.Equal(t, int64(20), barAcc.GetCoins().AmountOf("steak")) @@ -96,7 +95,7 @@ func TestGaiaCLICreateValidator(t *testing.T) { require.NoError(t, err) executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barCech), pass) - time.Sleep(time.Second * 3) // waiting for some blocks to pass + tests.WaitForNextHeightTM(port) barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags)) assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak")) @@ -112,7 +111,7 @@ func TestGaiaCLICreateValidator(t *testing.T) { cvStr += fmt.Sprintf(" --moniker=%v", "bar-vally") executeWrite(t, cvStr, pass) - time.Sleep(time.Second * 3) // waiting for some blocks to pass + tests.WaitForNextHeightTM(port) barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags)) require.Equal(t, int64(8), barAcc.GetCoins().AmountOf("steak"), "%v", barAcc) @@ -131,7 +130,7 @@ func TestGaiaCLICreateValidator(t *testing.T) { t.Log(fmt.Sprintf("debug unbondStr: %v\n", unbondStr)) executeWrite(t, unbondStr, pass) - time.Sleep(time.Second * 3) // waiting for some blocks to pass + tests.WaitForNextHeightTM(port) barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags)) require.Equal(t, int64(9), barAcc.GetCoins().AmountOf("steak"), "%v", barAcc) @@ -150,6 +149,8 @@ func executeWrite(t *testing.T, cmdStr string, writes ...string) { require.NoError(t, err) } proc.Wait() + // bz := proc.StdoutBuffer.Bytes() + // fmt.Println("EXEC WRITE", string(bz)) } func executeInit(t *testing.T, cmdStr string) (chainID string) { diff --git a/tests/util.go b/tests/util.go index 292cbab06..c47d9907f 100644 --- a/tests/util.go +++ b/tests/util.go @@ -7,16 +7,61 @@ import ( "time" amino "github.com/tendermint/go-amino" + tmclient "github.com/tendermint/tendermint/rpc/client" ctypes "github.com/tendermint/tendermint/rpc/core/types" rpcclient "github.com/tendermint/tendermint/rpc/lib/client" ) +func WaitForNextHeightTM(port string) { + url := fmt.Sprintf("http://localhost:%v", port) + cl := tmclient.NewHTTP(url, "/websocket") + resBlock, err := cl.Block(nil) + if err != nil { + panic(err) + } + waitForHeightTM(resBlock.Block.Height+1, url) +} + +func WaitForHeightTM(height int64, port string) { + url := fmt.Sprintf("http://localhost:%v", port) + waitForHeightTM(height, url) +} + +func waitForHeightTM(height int64, url string) { + cl := tmclient.NewHTTP(url, "/websocket") + for { + // get url, try a few times + var resBlock *ctypes.ResultBlock + var err error + INNER: + for i := 0; i < 5; i++ { + resBlock, err = cl.Block(nil) + if err == nil { + break INNER + } + time.Sleep(time.Millisecond * 200) + } + if err != nil { + panic(err) + } + + if resBlock.Block != nil && + resBlock.Block.Height >= height { + fmt.Println("HEIGHT", resBlock.Block.Height) + return + } + time.Sleep(time.Millisecond * 100) + } +} + // Uses localhost func WaitForHeight(height int64, port string) { + url := fmt.Sprintf("http://localhost:%v/blocks/latest", port) + waitForHeight(height, url) +} + +func waitForHeight(height int64, url string) { for { - - url := fmt.Sprintf("http://localhost:%v/blocks/latest", port) - // get url, try a few times var res *http.Response var err error @@ -25,7 +70,7 @@ func WaitForHeight(height int64, port string) { if err == nil { break } - time.Sleep(time.Second) + time.Sleep(time.Millisecond * 200) } if err != nil { panic(err) @@ -45,7 +90,8 @@ func WaitForHeight(height int64, port string) { panic(err) } - if resultBlock.Block.Height >= height { + if resultBlock.Block != nil && + resultBlock.Block.Height >= height { return } time.Sleep(time.Millisecond * 100) From 059a1659bee9907b1ee705d42328fdd85f309c34 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 13 Jun 2018 18:33:09 -0700 Subject: [PATCH 89/89] add comments --- tests/util.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/util.go b/tests/util.go index c47d9907f..387ccb769 100644 --- a/tests/util.go +++ b/tests/util.go @@ -12,6 +12,8 @@ import ( rpcclient "github.com/tendermint/tendermint/rpc/lib/client" ) +// Wait for the next tendermint block from the Tendermint RPC +// on localhost func WaitForNextHeightTM(port string) { url := fmt.Sprintf("http://localhost:%v", port) cl := tmclient.NewHTTP(url, "/websocket") @@ -22,6 +24,8 @@ func WaitForNextHeightTM(port string) { waitForHeightTM(resBlock.Block.Height+1, url) } +// Wait for the given height from the Tendermint RPC +// on localhost func WaitForHeightTM(height int64, port string) { url := fmt.Sprintf("http://localhost:%v", port) waitForHeightTM(height, url) @@ -54,7 +58,7 @@ func waitForHeightTM(height int64, url string) { } } -// Uses localhost +// Wait for height from the LCD API on localhost func WaitForHeight(height int64, port string) { url := fmt.Sprintf("http://localhost:%v/blocks/latest", port) waitForHeight(height, url)