Merge remote-tracking branch 'origin/develop' into rigel/fee-distribution
This commit is contained in:
commit
b2eab0d0c4
53
Gopkg.lock
generated
53
Gopkg.lock
generated
@ -34,11 +34,11 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2c00f064ba355903866cbfbf3f7f4c0fe64af6638cc7d1b8bdcf3181bc67f1d8"
|
||||
digest = "1:6aabc1566d6351115d561d038da82a4c19b46c3b6e17f4a0a2fa60260663dc79"
|
||||
name = "github.com/btcsuite/btcd"
|
||||
packages = ["btcec"]
|
||||
pruneopts = "UT"
|
||||
revision = "f899737d7f2764dc13e4d01ff00108ec58f766a9"
|
||||
revision = "d81d8877b8f327112e94e814937143a71d1692a7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:386de157f7d19259a7f9c81f26ce011223ce0f090353c1152ffdf730d7d10ac2"
|
||||
@ -71,7 +71,7 @@
|
||||
version = "v1.4.7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:fdf5169073fb0ad6dc12a70c249145e30f4058647bea25f0abd48b6d9f228a11"
|
||||
digest = "1:fa30c0652956e159cdb97dcb2ef8b8db63ed668c02a5c3a40961c8f0641252fe"
|
||||
name = "github.com/go-kit/kit"
|
||||
packages = [
|
||||
"log",
|
||||
@ -103,7 +103,7 @@
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:35621fe20f140f05a0c4ef662c26c0ab4ee50bca78aa30fe87d33120bd28165e"
|
||||
digest = "1:212285efb97b9ec2e20550d81f0446cb7897e57cbdfd7301b1363ab113d8be45"
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = [
|
||||
"gogoproto",
|
||||
@ -118,7 +118,7 @@
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:17fe264ee908afc795734e8c4e63db2accabaf57326dbf21763a7d6b86096260"
|
||||
digest = "1:cb22af0ed7c72d495d8be1106233ee553898950f15fd3f5404406d44c2e86888"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"proto",
|
||||
@ -165,12 +165,13 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:12247a2e99a060cc692f6680e5272c8adf0b8f572e6bce0d7095e624c958a240"
|
||||
digest = "1:ac64f01acc5eeea9dde40e326de6b6471e501392ec06524c3b51033aa50789bc"
|
||||
name = "github.com/hashicorp/hcl"
|
||||
packages = [
|
||||
".",
|
||||
"hcl/ast",
|
||||
"hcl/parser",
|
||||
"hcl/printer",
|
||||
"hcl/scanner",
|
||||
"hcl/strconv",
|
||||
"hcl/token",
|
||||
@ -230,12 +231,12 @@
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:5ab79470a1d0fb19b041a624415612f8236b3c06070161a910562f2b2d064355"
|
||||
digest = "1:645110e089152bd0f4a011a2648fbb0e4df5977be73ca605781157ac297f50c4"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "f15292f7a699fcc1a38a80977f80a046874ba8ac"
|
||||
revision = "fa473d140ef3c6adf42d6b391fe76707f1f243c8"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e"
|
||||
@ -262,7 +263,7 @@
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c1a04665f9613e082e1209cf288bf64f4068dcd6c87a64bf1c4ff006ad422ba0"
|
||||
digest = "1:98225904b7abff96c052b669b25788f18225a36673fba022fb93514bb9a2a64e"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"prometheus",
|
||||
@ -273,7 +274,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4"
|
||||
digest = "1:0f37e09b3e92aaeda5991581311f8dbf38944b36a3edec61cc2d1991f527554a"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
pruneopts = "UT"
|
||||
@ -281,7 +282,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:63b68062b8968092eb86bedc4e68894bd096ea6b24920faca8b9dcf451f54bb5"
|
||||
digest = "1:dad2e5a2153ee7a6c9ab8fc13673a16ee4fb64434a7da980965a3741b0c981a3"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = [
|
||||
"expfmt",
|
||||
@ -293,7 +294,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8c49953a1414305f2ff5465147ee576dd705487c35b15918fcd4efdc0cb7a290"
|
||||
digest = "1:a37c98f4b7a66bb5c539c0539f0915a74ef1c8e0b3b6f45735289d94cae92bfd"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [
|
||||
".",
|
||||
@ -312,7 +313,7 @@
|
||||
revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bd1ae00087d17c5a748660b8e89e1043e1e5479d0fea743352cda2f8dd8c4f84"
|
||||
digest = "1:37ace7f35375adec11634126944bdc45a673415e2fcc07382d03b75ec76ea94c"
|
||||
name = "github.com/spf13/afero"
|
||||
packages = [
|
||||
".",
|
||||
@ -331,7 +332,7 @@
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7ffc0983035bc7e297da3688d9fe19d60a420e9c38bef23f845c53788ed6a05e"
|
||||
digest = "1:627ab2f549a6a55c44f46fa24a4307f4d0da81bfc7934ed0473bf38b24051d26"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
@ -363,7 +364,7 @@
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7e8d267900c7fa7f35129a2a37596e38ed0f11ca746d6d9ba727980ee138f9f6"
|
||||
digest = "1:73697231b93fb74a73ebd8384b68b9a60c57ea6b13c56d2425414566a72c8e6d"
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = [
|
||||
"assert",
|
||||
@ -375,7 +376,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:f2ffd421680b0a3f7887501b3c6974bcf19217ecd301d0e2c9b681940ec363d5"
|
||||
digest = "1:442d2ffa75ffae302ce8800bf4144696b92bef02917923ea132ce2d39efe7d65"
|
||||
name = "github.com/syndtr/goleveldb"
|
||||
packages = [
|
||||
"leveldb",
|
||||
@ -396,7 +397,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722"
|
||||
digest = "1:203b409c21115233a576f99e8f13d8e07ad82b25500491f7e1cca12588fb3232"
|
||||
name = "github.com/tendermint/ed25519"
|
||||
packages = [
|
||||
".",
|
||||
@ -423,7 +424,7 @@
|
||||
version = "v0.9.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4f15e95fe3888cc75dd34f407d6394cbc7fd3ff24920851b92b295f6a8b556e6"
|
||||
digest = "1:963f6c04345ce36f900c1d6367200eebc3cc2db6ee632ff865ea8dcf64b748a0"
|
||||
name = "github.com/tendermint/tendermint"
|
||||
packages = [
|
||||
"abci/client",
|
||||
@ -490,7 +491,7 @@
|
||||
version = "v0.23.1-rc0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bf6d9a827ea3cad964c2f863302e4f6823170d0b5ed16f72cf1184a7c615067e"
|
||||
digest = "1:ad879bb8c71020a3f92f0c61f414d93eae1d5dc2f37023b6abaa3cc84b00165e"
|
||||
name = "github.com/tendermint/tmlibs"
|
||||
packages = ["cli"]
|
||||
pruneopts = "UT"
|
||||
@ -506,7 +507,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:27507554c6d4f060d8d700c31c624a43d3a92baa634e178ddc044bdf7d13b44a"
|
||||
digest = "1:2a3ce1f08dcae8bac666deb6e4c88b5d7170c510da38fd746231144cac351704"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"blowfish",
|
||||
@ -528,7 +529,7 @@
|
||||
revision = "614d502a4dac94afa3a6ce146bd1736da82514c6"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d36f55a999540d29b6ea3c2ea29d71c76b1d9853fdcd3e5c5cb4836f2ba118f1"
|
||||
digest = "1:04dda8391c3e2397daf254ac68003f30141c069b228d06baec8324a5f81dc1e9"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
@ -545,17 +546,17 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:a0e12bc26f317c0e2d497baf767285e1790e526e8dd46553c5a67fcbc8692157"
|
||||
digest = "1:c8baf78f0ac6eb27c645e264fe5e8a74d5a50db188ab41a7ff3b275c112e0735"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"cpu",
|
||||
"unix",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "3b58ed4ad3395d483fc92d5d14123ce2c3581fec"
|
||||
revision = "11551d06cbcc94edc80a0facaccbda56473c19c1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18"
|
||||
digest = "1:7509ba4347d1f8de6ae9be8818b0cd1abc3deeffe28aeaf4be6d4b6b5178d9ca"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
@ -586,7 +587,7 @@
|
||||
revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2dab32a43451e320e49608ff4542fdfc653c95dcc35d0065ec9c6c3dd540ed74"
|
||||
digest = "1:4515e3030c440845b046354fd5d57671238428b820deebce2e9dabb5cd3c51ac"
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
|
||||
5
Makefile
5
Makefile
@ -106,6 +106,11 @@ get_dev_tools:
|
||||
cd tools && $(MAKE) get_dev_tools
|
||||
|
||||
get_vendor_deps:
|
||||
@echo "--> Generating vendor directory via dep ensure"
|
||||
@rm -rf .vendor-new
|
||||
@dep ensure -v -vendor-only
|
||||
|
||||
update_vendor_deps:
|
||||
@echo "--> Running dep ensure"
|
||||
@rm -rf .vendor-new
|
||||
@dep ensure -v
|
||||
|
||||
24
PENDING.md
24
PENDING.md
@ -12,17 +12,26 @@ BREAKING CHANGES
|
||||
* [cli] \#1983 you can now pass --pubkey or --address to gaiacli keys show to return a plaintext representation of the key's address or public key for use with other commands
|
||||
* [cli] \#2061 changed proposalID in governance REST endpoints to proposal-id
|
||||
* [cli] \#2014 `gaiacli advanced` no longer exists - to access `ibc`, `rest-server`, and `validator-set` commands use `gaiacli ibc`, `gaiacli rest-server`, and `gaiacli tendermint`, respectively
|
||||
* [makefile] `get_vendor_deps` no longer updates lock file it just updates vendor directory. Use `update_vendor_deps` to update the lock file. [#2152](https://github.com/cosmos/cosmos-sdk/pull/2152)
|
||||
* [cli] \#2190 `gaiacli init --gen-txs` is now `gaiacli init --with-txs` to reduce confusion
|
||||
* \#2040 All commands that utilize a validator's address must now use the new
|
||||
bech32 prefix, `cosmosval`. A validator's Tendermint signing key and address
|
||||
now use a new bech32 prefix, `cosmoscons`.
|
||||
|
||||
* Gaia
|
||||
* Make the transient store key use a distinct store key. [#2013](https://github.com/cosmos/cosmos-sdk/pull/2013)
|
||||
* [x/stake] \#1901 Validator type's Owner field renamed to Operator; Validator's GetOwner() renamed accordingly to comply with the SDK's Validator interface.
|
||||
* [docs] [#2001](https://github.com/cosmos/cosmos-sdk/pull/2001) Update slashing spec for slashing period
|
||||
* [x/stake, x/slashing] [#1305](https://github.com/cosmos/cosmos-sdk/issues/1305) - Rename "revoked" to "jailed"
|
||||
* [x/stake] \#2040 Validator operator type has now changed to `sdk.ValAddress`
|
||||
* A new bech32 prefix has been introduced for Tendermint signing keys and
|
||||
addresses, `cosmosconspub` and `cosmoscons` respectively.
|
||||
|
||||
* SDK
|
||||
* [core] \#1807 Switch from use of rational to decimal
|
||||
* [types] \#1901 Validator interface's GetOwner() renamed to GetOperator()
|
||||
* [types] \#2119 Parsed error messages and ABCI log errors to make them more human readable.
|
||||
* [simulation] Rename TestAndRunTx to Operation [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
|
||||
|
||||
* Tendermint
|
||||
|
||||
@ -35,22 +44,31 @@ FEATURES
|
||||
* Gaia CLI (`gaiacli`)
|
||||
* [cli] Cmds to query staking pool and params
|
||||
* [gov][cli] #2062 added `--proposal` flag to `submit-proposal` that allows a JSON file containing a proposal to be passed in
|
||||
* \#2040 Add `--bech` to `gaiacli keys show` and respective REST endpoint to
|
||||
provide desired Bech32 prefix encoding
|
||||
* [cli] \#2047 Setting the --gas flag value to 0 triggers a simulation of the tx before the actual execution. The gas estimate obtained via the simulation will be used as gas limit in the actual execution.
|
||||
* [cli] \#2047 The --gas-adjustment flag can be used to adjust the estimate obtained via the simulation triggered by --gas=0.
|
||||
|
||||
* Gaia
|
||||
* [cli] #2170 added ability to show the node's address via `gaiad tendermint show-address`
|
||||
|
||||
* SDK
|
||||
* [querier] added custom querier functionality, so ABCI query requests can be handled by keepers
|
||||
* [simulation] \#1924 allow operations to specify future operations
|
||||
|
||||
* Tendermint
|
||||
|
||||
|
||||
IMPROVEMENTS
|
||||
* [tools] Improved terraform and ansible scripts for infrastructure deployment
|
||||
* [tools] Added ansible script to enable process core dumps
|
||||
|
||||
* Gaia REST API (`gaiacli advanced rest-server`)
|
||||
* [x/stake] \#2000 Added tests for new staking endpoints
|
||||
|
||||
* Gaia CLI (`gaiacli`)
|
||||
* [cli] #2060 removed `--select` from `block` command
|
||||
* [cli] #2128 fixed segfault when exporting directly after `gaiad init`
|
||||
|
||||
* Gaia
|
||||
* [x/stake] [#2023](https://github.com/cosmos/cosmos-sdk/pull/2023) Terminate iteration loop in `UpdateBondedValidators` and `UpdateBondedValidatorsFull` when the first revoked validator is encountered and perform a sanity check.
|
||||
@ -60,10 +78,11 @@ IMPROVEMENTS
|
||||
* [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present.
|
||||
* [spec] Added simple piggy bank distribution spec
|
||||
* [cli] \#1632 Add integration tests to ensure `basecoind init && basecoind` start sequences run successfully for both `democoin` and `basecoin` examples.
|
||||
* [store] Speedup IAVL iteration, and consequently everything that requires IAVL iteration. [#2143](https://github.com/cosmos/cosmos-sdk/issues/2143)
|
||||
* [simulation] Make timestamps randomized [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
|
||||
|
||||
* Tendermint
|
||||
|
||||
|
||||
BUG FIXES
|
||||
|
||||
* Gaia REST API (`gaiacli advanced rest-server`)
|
||||
@ -76,5 +95,8 @@ BUG FIXES
|
||||
* SDK
|
||||
* \#1988 Make us compile on OpenBSD (disable ledger) [#1988] (https://github.com/cosmos/cosmos-sdk/issues/1988)
|
||||
* \#2105 Fix DB Iterator leak, which may leak a go routine.
|
||||
* [ledger] \#2064 Fix inability to sign and send transactions via the LCD by
|
||||
loading a Ledger device at runtime.
|
||||
* \#2158 Fix non-deterministic ordering of validator iteration when slashing in `gov EndBlocker`
|
||||
|
||||
* Tendermint
|
||||
|
||||
@ -493,15 +493,14 @@ func validateBasicTxMsgs(msgs []sdk.Msg) sdk.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// retrieve the context for the ante handler and store the tx bytes; store
|
||||
// the signing validators if the tx runs within the deliverTx() state.
|
||||
func (app *BaseApp) getContextForAnte(mode runTxMode, txBytes []byte) (ctx sdk.Context) {
|
||||
// Get the context
|
||||
if mode == runTxModeCheck || mode == runTxModeSimulate {
|
||||
ctx = app.checkState.ctx.WithTxBytes(txBytes)
|
||||
} else {
|
||||
ctx = app.deliverState.ctx.WithTxBytes(txBytes)
|
||||
ctx = getState(app, mode).ctx.WithTxBytes(txBytes)
|
||||
if mode == runTxModeDeliver {
|
||||
ctx = ctx.WithSigningValidators(app.signedValidators)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -567,6 +566,13 @@ func getState(app *BaseApp, mode runTxMode) *state {
|
||||
return app.deliverState
|
||||
}
|
||||
|
||||
func (app *BaseApp) initializeContext(ctx sdk.Context, mode runTxMode) sdk.Context {
|
||||
if mode == runTxModeSimulate {
|
||||
ctx = ctx.WithMultiStore(getState(app, runTxModeSimulate).CacheMultiStore())
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
// runTx processes a transaction. The transactions is proccessed via an
|
||||
// anteHandler. txBytes may be nil in some cases, eg. in tests. Also, in the
|
||||
// future we may support "internal" transactions.
|
||||
@ -575,7 +581,9 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
|
||||
// determined by the GasMeter. We need access to the context to get the gas
|
||||
// meter so we initialize upfront.
|
||||
var gasWanted int64
|
||||
var msCache sdk.CacheMultiStore
|
||||
ctx := app.getContextForAnte(mode, txBytes)
|
||||
ctx = app.initializeContext(ctx, mode)
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -594,15 +602,13 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
|
||||
}()
|
||||
|
||||
var msgs = tx.GetMsgs()
|
||||
|
||||
err := validateBasicTxMsgs(msgs)
|
||||
if err != nil {
|
||||
if err := validateBasicTxMsgs(msgs); err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
// run the ante handler
|
||||
if app.anteHandler != nil {
|
||||
newCtx, result, abort := app.anteHandler(ctx, tx)
|
||||
newCtx, result, abort := app.anteHandler(ctx, tx, (mode == runTxModeSimulate))
|
||||
if abort {
|
||||
return result
|
||||
}
|
||||
@ -613,9 +619,15 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
|
||||
gasWanted = result.GasWanted
|
||||
}
|
||||
|
||||
if mode == runTxModeSimulate {
|
||||
result = app.runMsgs(ctx, msgs, mode)
|
||||
result.GasWanted = gasWanted
|
||||
return
|
||||
}
|
||||
|
||||
// Keep the state in a transient CacheWrap in case processing the messages
|
||||
// fails.
|
||||
msCache := getState(app, mode).CacheMultiStore()
|
||||
msCache = getState(app, mode).CacheMultiStore()
|
||||
if msCache.TracingEnabled() {
|
||||
msCache = msCache.WithTracingContext(sdk.TraceContext(
|
||||
map[string]interface{}{"txHash": cmn.HexBytes(tmhash.Sum(txBytes)).String()},
|
||||
@ -626,8 +638,8 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
|
||||
result = app.runMsgs(ctx, msgs, mode)
|
||||
result.GasWanted = gasWanted
|
||||
|
||||
// only update state if all messages pass and we're not in a simulation
|
||||
if result.IsOK() && mode != runTxModeSimulate {
|
||||
// only update state if all messages pass
|
||||
if result.IsOK() {
|
||||
msCache.Write()
|
||||
}
|
||||
|
||||
|
||||
@ -365,7 +365,7 @@ func testTxDecoder(cdc *wire.Codec) sdk.TxDecoder {
|
||||
}
|
||||
|
||||
func anteHandlerTxTest(t *testing.T, capKey *sdk.KVStoreKey, storeKey []byte) sdk.AnteHandler {
|
||||
return func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
return func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
store := ctx.KVStore(capKey)
|
||||
msgCounter := tx.(txTest).Counter
|
||||
res = incrementingCounter(t, store, storeKey, msgCounter)
|
||||
@ -595,7 +595,7 @@ func TestSimulateTx(t *testing.T) {
|
||||
gasConsumed := int64(5)
|
||||
|
||||
anteOpt := func(bapp *BaseApp) {
|
||||
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasConsumed))
|
||||
return
|
||||
})
|
||||
@ -659,7 +659,9 @@ func TestSimulateTx(t *testing.T) {
|
||||
|
||||
func TestRunInvalidTransaction(t *testing.T) {
|
||||
anteOpt := func(bapp *BaseApp) {
|
||||
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
|
||||
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
return
|
||||
})
|
||||
}
|
||||
routerOpt := func(bapp *BaseApp) {
|
||||
bapp.Router().AddRoute(typeMsgCounter, func(ctx sdk.Context, msg sdk.Msg) (res sdk.Result) { return })
|
||||
@ -734,7 +736,7 @@ func TestRunInvalidTransaction(t *testing.T) {
|
||||
func TestTxGasLimits(t *testing.T) {
|
||||
gasGranted := int64(10)
|
||||
anteOpt := func(bapp *BaseApp) {
|
||||
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasGranted))
|
||||
|
||||
// NOTE/TODO/XXX:
|
||||
@ -825,7 +827,7 @@ func TestTxGasLimits(t *testing.T) {
|
||||
func TestQuery(t *testing.T) {
|
||||
key, value := []byte("hello"), []byte("goodbye")
|
||||
anteOpt := func(bapp *BaseApp) {
|
||||
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
store := ctx.KVStore(capKey1)
|
||||
store.Set(key, value)
|
||||
return
|
||||
|
||||
@ -22,6 +22,8 @@ type CLIContext struct {
|
||||
Client rpcclient.Client
|
||||
Logger io.Writer
|
||||
Height int64
|
||||
Gas int64
|
||||
GasAdjustment float64
|
||||
NodeURI string
|
||||
FromAddressName string
|
||||
AccountStore string
|
||||
@ -48,6 +50,8 @@ func NewCLIContext() CLIContext {
|
||||
AccountStore: ctxAccStoreName,
|
||||
FromAddressName: viper.GetString(client.FlagFrom),
|
||||
Height: viper.GetInt64(client.FlagHeight),
|
||||
Gas: viper.GetInt64(client.FlagGas),
|
||||
GasAdjustment: viper.GetFloat64(client.FlagGasAdjustment),
|
||||
TrustNode: viper.GetBool(client.FlagTrustNode),
|
||||
UseLedger: viper.GetBool(client.FlagUseLedger),
|
||||
Async: viper.GetBool(client.FlagAsync),
|
||||
|
||||
@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
@ -27,8 +26,8 @@ func (ctx CLIContext) GetNode() (rpcclient.Client, error) {
|
||||
}
|
||||
|
||||
// Query performs a query for information about the connected node.
|
||||
func (ctx CLIContext) Query(path string) (res []byte, err error) {
|
||||
return ctx.query(path, nil)
|
||||
func (ctx CLIContext) Query(path string, data cmn.HexBytes) (res []byte, err error) {
|
||||
return ctx.query(path, data)
|
||||
}
|
||||
|
||||
// Query information about the connected node with a data payload
|
||||
@ -284,7 +283,7 @@ func (ctx CLIContext) ensureBroadcastTx(txBytes []byte) error {
|
||||
|
||||
// query performs a query from a Tendermint node with the provided store name
|
||||
// and path.
|
||||
func (ctx CLIContext) query(path string, key common.HexBytes) (res []byte, err error) {
|
||||
func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, err error) {
|
||||
node, err := ctx.GetNode()
|
||||
if err != nil {
|
||||
return res, err
|
||||
|
||||
@ -4,11 +4,15 @@ import "github.com/spf13/cobra"
|
||||
|
||||
// nolint
|
||||
const (
|
||||
DefaultGasLimit = 200000
|
||||
DefaultGasAdjustment = 1.2
|
||||
|
||||
FlagUseLedger = "ledger"
|
||||
FlagChainID = "chain-id"
|
||||
FlagNode = "node"
|
||||
FlagHeight = "height"
|
||||
FlagGas = "gas"
|
||||
FlagGasAdjustment = "gas-adjustment"
|
||||
FlagTrustNode = "trust-node"
|
||||
FlagFrom = "from"
|
||||
FlagName = "name"
|
||||
@ -49,7 +53,8 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command {
|
||||
c.Flags().String(FlagChainID, "", "Chain ID of tendermint node")
|
||||
c.Flags().String(FlagNode, "tcp://localhost:26657", "<host>:<port> to tendermint rpc interface for this chain")
|
||||
c.Flags().Bool(FlagUseLedger, false, "Use a connected Ledger device")
|
||||
c.Flags().Int64(FlagGas, 200000, "gas limit to set per-transaction")
|
||||
c.Flags().Int64(FlagGas, DefaultGasLimit, "gas limit to set per-transaction; set to 0 to calculate required gas automatically")
|
||||
c.Flags().Float64(FlagGasAdjustment, DefaultGasAdjustment, "adjustment factor to be multiplied against the estimate returned by the tx simulation")
|
||||
c.Flags().Bool(FlagAsync, false, "broadcast transactions asynchronously")
|
||||
c.Flags().Bool(FlagJson, false, "return output in json format")
|
||||
c.Flags().Bool(FlagPrintResponse, true, "return tx response (only works with async = false)")
|
||||
|
||||
@ -128,7 +128,8 @@ func printCreate(info keys.Info, seed string) {
|
||||
output := viper.Get(cli.OutputFlag)
|
||||
switch output {
|
||||
case "text":
|
||||
printInfo(info)
|
||||
printKeyInfo(info, Bech32KeyOutput)
|
||||
|
||||
// print seed unless requested not to.
|
||||
if !viper.GetBool(client.FlagUseLedger) && !viper.GetBool(flagNoBackup) {
|
||||
fmt.Println("**Important** write this seed phrase in a safe place.")
|
||||
|
||||
@ -21,7 +21,7 @@ func Commands() *cobra.Command {
|
||||
cmd.AddCommand(
|
||||
addKeyCommand(),
|
||||
listKeysCmd,
|
||||
showKeysCmd,
|
||||
showKeysCmd(),
|
||||
client.LineBreak,
|
||||
deleteKeyCommand(),
|
||||
updateKeyCommand(),
|
||||
|
||||
@ -2,6 +2,7 @@ package keys
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
@ -18,46 +19,69 @@ const (
|
||||
FlagAddress = "address"
|
||||
// FlagPublicKey represents the user's public key on the command line.
|
||||
FlagPublicKey = "pubkey"
|
||||
// FlagBechPrefix defines a desired Bech32 prefix encoding for a key
|
||||
FlagBechPrefix = "bech"
|
||||
)
|
||||
|
||||
var showKeysCmd = &cobra.Command{
|
||||
Use: "show <name>",
|
||||
Short: "Show key info for the given name",
|
||||
Long: `Return public details of one local key.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
name := args[0]
|
||||
info, err := getKey(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func showKeysCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "show [name]",
|
||||
Short: "Show key info for the given name",
|
||||
Long: `Return public details of one local key.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
name := args[0]
|
||||
info, err := getKey(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
showAddress := viper.GetBool(FlagAddress)
|
||||
showPublicKey := viper.GetBool(FlagPublicKey)
|
||||
outputSet := cmd.Flag(cli.OutputFlag).Changed
|
||||
if showAddress && showPublicKey {
|
||||
return errors.New("cannot use both --address and --pubkey at once")
|
||||
}
|
||||
if outputSet && (showAddress || showPublicKey) {
|
||||
return errors.New("cannot use --output with --address or --pubkey")
|
||||
}
|
||||
if showAddress {
|
||||
printKeyAddress(info)
|
||||
return nil
|
||||
}
|
||||
if showPublicKey {
|
||||
printPubKey(info)
|
||||
return nil
|
||||
}
|
||||
showAddress := viper.GetBool(FlagAddress)
|
||||
showPublicKey := viper.GetBool(FlagPublicKey)
|
||||
outputSet := cmd.Flag(cli.OutputFlag).Changed
|
||||
|
||||
printInfo(info)
|
||||
return nil
|
||||
},
|
||||
if showAddress && showPublicKey {
|
||||
return errors.New("cannot use both --address and --pubkey at once")
|
||||
}
|
||||
if outputSet && (showAddress || showPublicKey) {
|
||||
return errors.New("cannot use --output with --address or --pubkey")
|
||||
}
|
||||
|
||||
bechKeyOut, err := getBechKeyOut(viper.GetString(FlagBechPrefix))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case showAddress:
|
||||
printKeyAddress(info, bechKeyOut)
|
||||
case showPublicKey:
|
||||
printPubKey(info, bechKeyOut)
|
||||
default:
|
||||
printKeyInfo(info, bechKeyOut)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String(FlagBechPrefix, "acc", "The Bech32 prefix encoding for a key (acc|val|cons)")
|
||||
cmd.Flags().Bool(FlagAddress, false, "output the address only (overrides --output)")
|
||||
cmd.Flags().Bool(FlagPublicKey, false, "output the public key only (overrides --output)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func init() {
|
||||
showKeysCmd.Flags().Bool(FlagAddress, false, "output the address only (overrides --output)")
|
||||
showKeysCmd.Flags().Bool(FlagPublicKey, false, "output the public key only (overrides --output)")
|
||||
func getBechKeyOut(bechPrefix string) (bechKeyOutFn, error) {
|
||||
switch bechPrefix {
|
||||
case "acc":
|
||||
return Bech32KeyOutput, nil
|
||||
case "val":
|
||||
return Bech32ValKeyOutput, nil
|
||||
case "cons":
|
||||
return Bech32ConsKeyOutput, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("invalid Bech32 prefix encoding provided: %s", bechPrefix)
|
||||
}
|
||||
|
||||
func getKey(name string) (keys.Info, error) {
|
||||
@ -76,21 +100,35 @@ func getKey(name string) (keys.Info, error) {
|
||||
func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
name := vars["name"]
|
||||
bechPrefix := r.URL.Query().Get(FlagBechPrefix)
|
||||
|
||||
if bechPrefix == "" {
|
||||
bechPrefix = "acc"
|
||||
}
|
||||
|
||||
bechKeyOut, err := getBechKeyOut(bechPrefix)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
info, err := getKey(name)
|
||||
// TODO check for the error if key actually does not exist, instead of assuming this as the reason
|
||||
// TODO: check for the error if key actually does not exist, instead of
|
||||
// assuming this as the reason
|
||||
if err != nil {
|
||||
w.WriteHeader(404)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
keyOutput, err := Bech32KeyOutput(info)
|
||||
keyOutput, err := bechKeyOut(info)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
output, err := json.MarshalIndent(keyOutput, "", " ")
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
|
||||
@ -21,6 +21,8 @@ const KeyDBName = "keys"
|
||||
// keybase is used to make GetKeyBase a singleton
|
||||
var keybase keys.Keybase
|
||||
|
||||
type bechKeyOutFn func(keyInfo keys.Info) (KeyOutput, error)
|
||||
|
||||
// TODO make keybase take a database not load from the directory
|
||||
|
||||
// initialize a keybase based on the configuration
|
||||
@ -97,11 +99,11 @@ func SetKeyBase(kb keys.Keybase) {
|
||||
|
||||
// used for outputting keys.Info over REST
|
||||
type KeyOutput struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Address sdk.AccAddress `json:"address"`
|
||||
PubKey string `json:"pub_key"`
|
||||
Seed string `json:"seed,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Address string `json:"address"`
|
||||
PubKey string `json:"pub_key"`
|
||||
Seed string `json:"seed,omitempty"`
|
||||
}
|
||||
|
||||
// create a list of KeyOutput in bech32 format
|
||||
@ -119,24 +121,61 @@ func Bech32KeysOutput(infos []keys.Info) ([]KeyOutput, error) {
|
||||
|
||||
// create a KeyOutput in bech32 format
|
||||
func Bech32KeyOutput(info keys.Info) (KeyOutput, error) {
|
||||
account := sdk.AccAddress(info.GetPubKey().Address().Bytes())
|
||||
accAddr := sdk.AccAddress(info.GetPubKey().Address().Bytes())
|
||||
bechPubKey, err := sdk.Bech32ifyAccPub(info.GetPubKey())
|
||||
if err != nil {
|
||||
return KeyOutput{}, err
|
||||
}
|
||||
|
||||
return KeyOutput{
|
||||
Name: info.GetName(),
|
||||
Type: info.GetType().String(),
|
||||
Address: account,
|
||||
Address: accAddr.String(),
|
||||
PubKey: bechPubKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func printInfo(info keys.Info) {
|
||||
ko, err := Bech32KeyOutput(info)
|
||||
// Bech32ConsKeyOutput returns key output for a consensus node's key
|
||||
// information.
|
||||
func Bech32ConsKeyOutput(keyInfo keys.Info) (KeyOutput, error) {
|
||||
consAddr := sdk.ConsAddress(keyInfo.GetPubKey().Address().Bytes())
|
||||
|
||||
bechPubKey, err := sdk.Bech32ifyConsPub(keyInfo.GetPubKey())
|
||||
if err != nil {
|
||||
return KeyOutput{}, err
|
||||
}
|
||||
|
||||
return KeyOutput{
|
||||
Name: keyInfo.GetName(),
|
||||
Type: keyInfo.GetType().String(),
|
||||
Address: consAddr.String(),
|
||||
PubKey: bechPubKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Bech32ValKeyOutput returns key output for a validator's key information.
|
||||
func Bech32ValKeyOutput(keyInfo keys.Info) (KeyOutput, error) {
|
||||
valAddr := sdk.ValAddress(keyInfo.GetPubKey().Address().Bytes())
|
||||
|
||||
bechPubKey, err := sdk.Bech32ifyValPub(keyInfo.GetPubKey())
|
||||
if err != nil {
|
||||
return KeyOutput{}, err
|
||||
}
|
||||
|
||||
return KeyOutput{
|
||||
Name: keyInfo.GetName(),
|
||||
Type: keyInfo.GetType().String(),
|
||||
Address: valAddr.String(),
|
||||
PubKey: bechPubKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func printKeyInfo(keyInfo keys.Info, bechKeyOut bechKeyOutFn) {
|
||||
ko, err := bechKeyOut(keyInfo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
switch viper.Get(cli.OutputFlag) {
|
||||
case "text":
|
||||
fmt.Printf("NAME:\tTYPE:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
|
||||
@ -146,6 +185,7 @@ func printInfo(info keys.Info) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(string(out))
|
||||
}
|
||||
}
|
||||
@ -174,18 +214,20 @@ func printKeyOutput(ko KeyOutput) {
|
||||
fmt.Printf("%s\t%s\t%s\t%s\n", ko.Name, ko.Type, ko.Address, ko.PubKey)
|
||||
}
|
||||
|
||||
func printKeyAddress(info keys.Info) {
|
||||
ko, err := Bech32KeyOutput(info)
|
||||
func printKeyAddress(info keys.Info, bechKeyOut bechKeyOutFn) {
|
||||
ko, err := bechKeyOut(info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(ko.Address.String())
|
||||
|
||||
fmt.Println(ko.Address)
|
||||
}
|
||||
|
||||
func printPubKey(info keys.Info) {
|
||||
ko, err := Bech32KeyOutput(info)
|
||||
func printPubKey(info keys.Info, bechKeyOut bechKeyOutFn) {
|
||||
ko, err := bechKeyOut(info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(ko.PubKey)
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ func TestKeys(t *testing.T) {
|
||||
err = wire.Cdc.UnmarshalJSON([]byte(body), &resp)
|
||||
require.Nil(t, err, body)
|
||||
|
||||
addr2Bech32 := resp.Address.String()
|
||||
addr2Bech32 := resp.Address
|
||||
_, err = sdk.AccAddressFromBech32(addr2Bech32)
|
||||
require.NoError(t, err, "Failed to return a correct bech32 address")
|
||||
|
||||
@ -81,9 +81,9 @@ func TestKeys(t *testing.T) {
|
||||
addrBech32 := addr.String()
|
||||
|
||||
require.Equal(t, name, m[0].Name, "Did not serve keys name correctly")
|
||||
require.Equal(t, addrBech32, m[0].Address.String(), "Did not serve keys Address correctly")
|
||||
require.Equal(t, addrBech32, m[0].Address, "Did not serve keys Address correctly")
|
||||
require.Equal(t, newName, m[1].Name, "Did not serve keys name correctly")
|
||||
require.Equal(t, addr2Bech32, m[1].Address.String(), "Did not serve keys Address correctly")
|
||||
require.Equal(t, addr2Bech32, m[1].Address, "Did not serve keys Address correctly")
|
||||
|
||||
// select key
|
||||
keyEndpoint := fmt.Sprintf("/keys/%s", newName)
|
||||
@ -94,7 +94,7 @@ func TestKeys(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Equal(t, newName, m2.Name, "Did not serve keys name correctly")
|
||||
require.Equal(t, addr2Bech32, m2.Address.String(), "Did not serve keys Address correctly")
|
||||
require.Equal(t, addr2Bech32, m2.Address, "Did not serve keys Address correctly")
|
||||
|
||||
// update key
|
||||
jsonStr = []byte(fmt.Sprintf(`{
|
||||
@ -204,8 +204,8 @@ func TestValidators(t *testing.T) {
|
||||
|
||||
require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals)
|
||||
|
||||
require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosvaladdr")
|
||||
require.Contains(t, resultVals.Validators[0].PubKey, "cosmosvalpub")
|
||||
require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosval")
|
||||
require.Contains(t, resultVals.Validators[0].PubKey, "cosmosconspub")
|
||||
|
||||
// --
|
||||
|
||||
@ -263,6 +263,14 @@ func TestCoinSend(t *testing.T) {
|
||||
|
||||
require.Equal(t, "steak", mycoins.Denom)
|
||||
require.Equal(t, int64(1), mycoins.Amount.Int64())
|
||||
|
||||
// test failure with too little gas
|
||||
res, body, _ = doSendWithGas(t, port, seed, name, password, addr, 100)
|
||||
require.Equal(t, http.StatusInternalServerError, res.StatusCode, body)
|
||||
|
||||
// test success with just enough gas
|
||||
res, body, _ = doSendWithGas(t, port, seed, name, password, addr, 3000)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
}
|
||||
|
||||
func TestIBCTransfer(t *testing.T) {
|
||||
@ -305,7 +313,7 @@ func TestTxs(t *testing.T) {
|
||||
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'", "cosmos1jawd35d9aq4u76sr3fjalmcqc8hqygs90d0g0v"), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.Equal(t, "[]", body)
|
||||
|
||||
@ -399,7 +407,7 @@ func TestValidatorsQuery(t *testing.T) {
|
||||
|
||||
// make sure all the validators were found (order unknown because sorted by operator addr)
|
||||
foundVal := false
|
||||
pkBech := sdk.MustBech32ifyValPub(pks[0])
|
||||
pkBech := sdk.MustBech32ifyConsPub(pks[0])
|
||||
if validators[0].PubKey == pkBech {
|
||||
foundVal = true
|
||||
}
|
||||
@ -411,7 +419,7 @@ func TestValidatorQuery(t *testing.T) {
|
||||
defer cleanup()
|
||||
require.Equal(t, 1, len(pks))
|
||||
|
||||
validator1Operator := sdk.AccAddress(pks[0].Address())
|
||||
validator1Operator := sdk.ValAddress(pks[0].Address())
|
||||
validator := getValidator(t, port, validator1Operator)
|
||||
assert.Equal(t, validator.Operator, validator1Operator, "The returned validator does not hold the correct data")
|
||||
}
|
||||
@ -422,7 +430,7 @@ func TestBonding(t *testing.T) {
|
||||
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
|
||||
defer cleanup()
|
||||
|
||||
validator1Operator := sdk.AccAddress(pks[0].Address())
|
||||
validator1Operator := sdk.ValAddress(pks[0].Address())
|
||||
validator := getValidator(t, port, validator1Operator)
|
||||
|
||||
// create bond TX
|
||||
@ -603,7 +611,7 @@ func TestUnjail(t *testing.T) {
|
||||
|
||||
// XXX: any less than this and it fails
|
||||
tests.WaitForHeight(3, port)
|
||||
pkString, _ := sdk.Bech32ifyValPub(pks[0])
|
||||
pkString, _ := sdk.Bech32ifyConsPub(pks[0])
|
||||
signingInfo := getSigningInfo(t, port, pkString)
|
||||
tests.WaitForHeight(4, port)
|
||||
require.Equal(t, true, signingInfo.IndexOffset > 0)
|
||||
@ -712,7 +720,7 @@ func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account {
|
||||
return acc
|
||||
}
|
||||
|
||||
func doSend(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
func doSendWithGas(t *testing.T, port, seed, name, password string, addr sdk.AccAddress, gas int64) (res *http.Response, body string, receiveAddr sdk.AccAddress) {
|
||||
|
||||
// create receive address
|
||||
kb := client.MockKeyBase()
|
||||
@ -730,19 +738,31 @@ func doSend(t *testing.T, port, seed, name, password string, addr sdk.AccAddress
|
||||
panic(err)
|
||||
}
|
||||
|
||||
gasStr := ""
|
||||
if gas > 0 {
|
||||
gasStr = fmt.Sprintf(`
|
||||
"gas":"%v",
|
||||
`, gas)
|
||||
}
|
||||
jsonStr := []byte(fmt.Sprintf(`{
|
||||
%v
|
||||
"name":"%s",
|
||||
"password":"%s",
|
||||
"account_number":"%d",
|
||||
"sequence":"%d",
|
||||
"gas": "10000",
|
||||
"amount":[%s],
|
||||
"chain_id":"%s"
|
||||
}`, name, password, accnum, sequence, coinbz, chainID))
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/accounts/%s/send", receiveAddr), jsonStr)
|
||||
}`, gasStr, name, password, accnum, sequence, coinbz, chainID))
|
||||
|
||||
res, body = Request(t, port, "POST", fmt.Sprintf("/accounts/%s/send", receiveAddr), jsonStr)
|
||||
return
|
||||
}
|
||||
|
||||
func doSend(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
res, body, receiveAddr := doSendWithGas(t, port, seed, name, password, addr, 0)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
err = cdc.UnmarshalJSON([]byte(body), &resultTx)
|
||||
err := cdc.UnmarshalJSON([]byte(body), &resultTx)
|
||||
require.Nil(t, err)
|
||||
|
||||
return receiveAddr, resultTx
|
||||
@ -768,7 +788,6 @@ func doIBCTransfer(t *testing.T, port, seed, name, password string, addr sdk.Acc
|
||||
"password": "%s",
|
||||
"account_number":"%d",
|
||||
"sequence": "%d",
|
||||
"gas": "100000",
|
||||
"src_chain_id": "%s",
|
||||
"amount":[
|
||||
{
|
||||
@ -798,8 +817,8 @@ func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.
|
||||
|
||||
// ============= Stake Module ================
|
||||
|
||||
func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) rest.DelegationWithoutRat {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil)
|
||||
func getDelegation(t *testing.T, port string, delAddr sdk.AccAddress, valAddr sdk.ValAddress) rest.DelegationWithoutRat {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delAddr, valAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var bond rest.DelegationWithoutRat
|
||||
@ -810,8 +829,8 @@ func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.A
|
||||
return bond
|
||||
}
|
||||
|
||||
func getUndelegations(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) []stake.UnbondingDelegation {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delegatorAddr, validatorAddr), nil)
|
||||
func getUndelegations(t *testing.T, port string, delAddr sdk.AccAddress, valAddr sdk.ValAddress) []stake.UnbondingDelegation {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delAddr, valAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var unbondings []stake.UnbondingDelegation
|
||||
@ -865,8 +884,8 @@ func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddr
|
||||
return bondedValidators
|
||||
}
|
||||
|
||||
func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) stake.BechValidator {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators/%s", delegatorAddr, validatorAddr), nil)
|
||||
func getDelegatorValidator(t *testing.T, port string, delAddr sdk.AccAddress, valAddr sdk.ValAddress) stake.BechValidator {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators/%s", delAddr, valAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var bondedValidator stake.BechValidator
|
||||
@ -876,8 +895,10 @@ func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddre
|
||||
return bondedValidator
|
||||
}
|
||||
|
||||
func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.AccAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
acc := getAccount(t, port, delegatorAddr)
|
||||
func doDelegate(t *testing.T, port, seed, name, password string,
|
||||
delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
|
||||
acc := getAccount(t, port, delAddr)
|
||||
accnum := acc.GetAccountNumber()
|
||||
sequence := acc.GetSequence()
|
||||
chainID := viper.GetString(client.FlagChainID)
|
||||
@ -887,7 +908,6 @@ func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr,
|
||||
"password": "%s",
|
||||
"account_number": "%d",
|
||||
"sequence": "%d",
|
||||
"gas": "10000",
|
||||
"chain_id": "%s",
|
||||
"delegations": [
|
||||
{
|
||||
@ -900,9 +920,9 @@ func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr,
|
||||
"complete_unbondings": [],
|
||||
"begin_redelegates": [],
|
||||
"complete_redelegates": []
|
||||
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr, "steak", amount))
|
||||
}`, name, password, accnum, sequence, chainID, delAddr, valAddr, "steak", amount))
|
||||
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr), jsonStr)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var results []ctypes.ResultBroadcastTxCommit
|
||||
@ -913,9 +933,9 @@ func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr,
|
||||
}
|
||||
|
||||
func doBeginUnbonding(t *testing.T, port, seed, name, password string,
|
||||
delegatorAddr, validatorAddr sdk.AccAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
delAddr sdk.AccAddress, valAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
|
||||
acc := getAccount(t, port, delegatorAddr)
|
||||
acc := getAccount(t, port, delAddr)
|
||||
accnum := acc.GetAccountNumber()
|
||||
sequence := acc.GetSequence()
|
||||
chainID := viper.GetString(client.FlagChainID)
|
||||
@ -925,7 +945,6 @@ func doBeginUnbonding(t *testing.T, port, seed, name, password string,
|
||||
"password": "%s",
|
||||
"account_number": "%d",
|
||||
"sequence": "%d",
|
||||
"gas": "20000",
|
||||
"chain_id": "%s",
|
||||
"delegations": [],
|
||||
"begin_unbondings": [
|
||||
@ -938,9 +957,9 @@ func doBeginUnbonding(t *testing.T, port, seed, name, password string,
|
||||
"complete_unbondings": [],
|
||||
"begin_redelegates": [],
|
||||
"complete_redelegates": []
|
||||
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr, amount))
|
||||
}`, name, password, accnum, sequence, chainID, delAddr, valAddr, amount))
|
||||
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr), jsonStr)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var results []ctypes.ResultBroadcastTxCommit
|
||||
@ -951,9 +970,9 @@ func doBeginUnbonding(t *testing.T, port, seed, name, password string,
|
||||
}
|
||||
|
||||
func doBeginRedelegation(t *testing.T, port, seed, name, password string,
|
||||
delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
|
||||
acc := getAccount(t, port, delegatorAddr)
|
||||
acc := getAccount(t, port, delAddr)
|
||||
accnum := acc.GetAccountNumber()
|
||||
sequence := acc.GetSequence()
|
||||
|
||||
@ -964,7 +983,6 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string,
|
||||
"password": "%s",
|
||||
"account_number": "%d",
|
||||
"sequence": "%d",
|
||||
"gas": "10000",
|
||||
"chain_id": "%s",
|
||||
"delegations": [],
|
||||
"begin_unbondings": [],
|
||||
@ -978,9 +996,9 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string,
|
||||
}
|
||||
],
|
||||
"complete_redelegates": []
|
||||
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorSrcAddr, validatorDstAddr))
|
||||
}`, name, password, accnum, sequence, chainID, delAddr, valSrcAddr, valDstAddr))
|
||||
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr), jsonStr)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var results []ctypes.ResultBroadcastTxCommit
|
||||
@ -999,8 +1017,8 @@ func getValidators(t *testing.T, port string) []stake.BechValidator {
|
||||
return validators
|
||||
}
|
||||
|
||||
func getValidator(t *testing.T, port string, validatorAddr sdk.AccAddress) stake.BechValidator {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil)
|
||||
func getValidator(t *testing.T, port string, valAddr sdk.ValAddress) stake.BechValidator {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", valAddr.String()), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
var validator stake.BechValidator
|
||||
err := cdc.UnmarshalJSON([]byte(body), &validator)
|
||||
@ -1116,8 +1134,7 @@ func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerA
|
||||
"password": "%s",
|
||||
"chain_id": "%s",
|
||||
"account_number":"%d",
|
||||
"sequence":"%d",
|
||||
"gas":"100000"
|
||||
"sequence":"%d"
|
||||
}
|
||||
}`, proposerAddr, name, password, chainID, accnum, sequence))
|
||||
res, body := Request(t, port, "POST", "/gov/proposals", jsonStr)
|
||||
@ -1147,8 +1164,7 @@ func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk
|
||||
"password": "%s",
|
||||
"chain_id": "%s",
|
||||
"account_number":"%d",
|
||||
"sequence": "%d",
|
||||
"gas":"100000"
|
||||
"sequence": "%d"
|
||||
}
|
||||
}`, proposerAddr, name, password, chainID, accnum, sequence))
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/deposits", proposalID), jsonStr)
|
||||
@ -1178,8 +1194,7 @@ func doVote(t *testing.T, port, seed, name, password string, proposerAddr sdk.Ac
|
||||
"password": "%s",
|
||||
"chain_id": "%s",
|
||||
"account_number": "%d",
|
||||
"sequence": "%d",
|
||||
"gas":"100000"
|
||||
"sequence": "%d"
|
||||
}
|
||||
}`, proposerAddr, name, password, chainID, accnum, sequence))
|
||||
res, body := Request(t, port, "POST", fmt.Sprintf("/gov/proposals/%d/votes", proposalID), jsonStr)
|
||||
|
||||
@ -17,7 +17,7 @@ func CLIVersionRequestHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// connected node version REST handler endpoint
|
||||
func NodeVersionRequestHandler(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
version, err := cliCtx.Query("/app/version")
|
||||
version, err := cliCtx.Query("/app/version", nil)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Could't query version. Error: %s", err.Error())))
|
||||
|
||||
@ -45,7 +45,7 @@ type ResultValidatorsOutput struct {
|
||||
}
|
||||
|
||||
func bech32ValidatorOutput(validator *tmtypes.Validator) (ValidatorOutput, error) {
|
||||
bechValPubkey, err := sdk.Bech32ifyValPub(validator.PubKey)
|
||||
bechValPubkey, err := sdk.Bech32ifyConsPub(validator.PubKey)
|
||||
if err != nil {
|
||||
return ValidatorOutput{}, err
|
||||
}
|
||||
|
||||
12
client/utils/rest.go
Normal file
12
client/utils/rest.go
Normal file
@ -0,0 +1,12 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// WriteErrorResponse prepares and writes a HTTP error
|
||||
// given a status code and an error message.
|
||||
func WriteErrorResponse(w *http.ResponseWriter, status int, msg string) {
|
||||
(*w).WriteHeader(status)
|
||||
(*w).Write([]byte(msg))
|
||||
}
|
||||
@ -1,12 +1,22 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
)
|
||||
|
||||
// DefaultGasAdjustment is applied to gas estimates to avoid tx
|
||||
// execution failures due to state changes that might
|
||||
// occur between the tx simulation and the actual run.
|
||||
const DefaultGasAdjustment = 1.2
|
||||
|
||||
// SendTx implements a auxiliary handler that facilitates sending a series of
|
||||
// messages in a signed transaction given a TxContext and a QueryContext. It
|
||||
// ensures that the account exists, has a proper number and sequence set. In
|
||||
@ -49,12 +59,71 @@ func SendTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg)
|
||||
return err
|
||||
}
|
||||
|
||||
if cliCtx.Gas == 0 {
|
||||
txCtx, err = EnrichCtxWithGas(txCtx, cliCtx, cliCtx.FromAddressName, passphrase, msgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// build and sign the transaction
|
||||
txBytes, err := txCtx.BuildAndSign(cliCtx.FromAddressName, passphrase, msgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// broadcast to a Tendermint node
|
||||
return cliCtx.EnsureBroadcastTx(txBytes)
|
||||
}
|
||||
|
||||
// EnrichCtxWithGas calculates the gas estimate that would be consumed by the
|
||||
// transaction and set the transaction's respective value accordingly.
|
||||
func EnrichCtxWithGas(txCtx authctx.TxContext, cliCtx context.CLIContext, name, passphrase string, msgs []sdk.Msg) (authctx.TxContext, error) {
|
||||
txBytes, err := BuildAndSignTxWithZeroGas(txCtx, name, passphrase, msgs)
|
||||
if err != nil {
|
||||
return txCtx, err
|
||||
}
|
||||
estimate, adjusted, err := CalculateGas(cliCtx.Query, cliCtx.Codec, txBytes, cliCtx.GasAdjustment)
|
||||
if err != nil {
|
||||
return txCtx, err
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "gas: [estimated = %v] [adjusted = %v]\n", estimate, adjusted)
|
||||
return txCtx.WithGas(adjusted), nil
|
||||
}
|
||||
|
||||
// BuildAndSignTxWithZeroGas builds transactions with GasWanted set to 0.
|
||||
func BuildAndSignTxWithZeroGas(txCtx authctx.TxContext, name, passphrase string, msgs []sdk.Msg) ([]byte, error) {
|
||||
return txCtx.WithGas(0).BuildAndSign(name, passphrase, msgs)
|
||||
}
|
||||
|
||||
// CalculateGas simulates the execution of a transaction and returns
|
||||
// both the estimate obtained by the query and the adjusted amount.
|
||||
func CalculateGas(queryFunc func(string, common.HexBytes) ([]byte, error), cdc *amino.Codec, txBytes []byte, adjustment float64) (estimate, adjusted int64, err error) {
|
||||
// run a simulation (via /app/simulate query) to
|
||||
// estimate gas and update TxContext accordingly
|
||||
rawRes, err := queryFunc("/app/simulate", txBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
estimate, err = parseQueryResponse(cdc, rawRes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
adjusted = adjustGasEstimate(estimate, adjustment)
|
||||
fmt.Fprintf(os.Stderr, "gas: [estimated = %v] [adjusted = %v]\n", estimate, adjusted)
|
||||
return
|
||||
}
|
||||
|
||||
func adjustGasEstimate(estimate int64, adjustment float64) int64 {
|
||||
if adjustment == 0 {
|
||||
return int64(DefaultGasAdjustment * float64(estimate))
|
||||
}
|
||||
return int64(adjustment * float64(estimate))
|
||||
}
|
||||
|
||||
func parseQueryResponse(cdc *amino.Codec, rawRes []byte) (int64, error) {
|
||||
var simulationResult sdk.Result
|
||||
if err := cdc.UnmarshalBinary(rawRes, &simulationResult); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return simulationResult.GasUsed, nil
|
||||
}
|
||||
|
||||
58
client/utils/utils_test.go
Normal file
58
client/utils/utils_test.go
Normal file
@ -0,0 +1,58 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
)
|
||||
|
||||
func TestParseQueryResponse(t *testing.T) {
|
||||
cdc := app.MakeCodec()
|
||||
sdkResBytes := cdc.MustMarshalBinary(sdk.Result{GasUsed: 10})
|
||||
gas, err := parseQueryResponse(cdc, sdkResBytes)
|
||||
assert.Equal(t, gas, int64(10))
|
||||
assert.Nil(t, err)
|
||||
gas, err = parseQueryResponse(cdc, []byte("fuzzy"))
|
||||
assert.Equal(t, gas, int64(0))
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestCalculateGas(t *testing.T) {
|
||||
cdc := app.MakeCodec()
|
||||
makeQueryFunc := func(gasUsed int64, wantErr bool) func(string, common.HexBytes) ([]byte, error) {
|
||||
return func(string, common.HexBytes) ([]byte, error) {
|
||||
if wantErr {
|
||||
return nil, errors.New("")
|
||||
}
|
||||
return cdc.MustMarshalBinary(sdk.Result{GasUsed: gasUsed}), nil
|
||||
}
|
||||
}
|
||||
type args struct {
|
||||
queryFuncGasUsed int64
|
||||
queryFuncWantErr bool
|
||||
adjustment float64
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantEstimate int64
|
||||
wantAdjusted int64
|
||||
wantErr bool
|
||||
}{
|
||||
{"error", args{0, true, 1.2}, 0, 0, true},
|
||||
{"adjusted gas", args{10, false, 1.2}, 10, 12, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
queryFunc := makeQueryFunc(tt.args.queryFuncGasUsed, tt.args.queryFuncWantErr)
|
||||
gotEstimate, gotAdjusted, err := CalculateGas(queryFunc, cdc, []byte(""), tt.args.adjustment)
|
||||
assert.Equal(t, err != nil, tt.wantErr)
|
||||
assert.Equal(t, gotEstimate, tt.wantEstimate)
|
||||
assert.Equal(t, gotAdjusted, tt.wantAdjusted)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,7 @@ const DefaultKeyPass = "12345678"
|
||||
var (
|
||||
// bonded tokens given to genesis validators/accounts
|
||||
freeFermionVal = int64(100)
|
||||
freeFermionsAcc = int64(50)
|
||||
freeFermionsAcc = sdk.NewInt(50)
|
||||
)
|
||||
|
||||
// State to Unmarshal
|
||||
@ -142,7 +142,7 @@ func GaiaAppGenTxNF(cdc *wire.Codec, pk crypto.PubKey, addr sdk.AccAddress, name
|
||||
gaiaGenTx := GaiaGenTx{
|
||||
Name: name,
|
||||
Address: addr,
|
||||
PubKey: sdk.MustBech32ifyAccPub(pk),
|
||||
PubKey: sdk.MustBech32ifyConsPub(pk),
|
||||
}
|
||||
bz, err = wire.MarshalJSONIndent(cdc, gaiaGenTx)
|
||||
if err != nil {
|
||||
@ -183,28 +183,29 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState
|
||||
accAuth := auth.NewBaseAccountWithAddress(genTx.Address)
|
||||
accAuth.Coins = sdk.Coins{
|
||||
{genTx.Name + "Token", sdk.NewInt(1000)},
|
||||
{"steak", sdk.NewInt(freeFermionsAcc)},
|
||||
{"steak", freeFermionsAcc},
|
||||
}
|
||||
acc := NewGenesisAccount(&accAuth)
|
||||
genaccs[i] = acc
|
||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDec(freeFermionsAcc)) // increase the supply
|
||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
|
||||
|
||||
// add the validator
|
||||
if len(genTx.Name) > 0 {
|
||||
desc := stake.NewDescription(genTx.Name, "", "", "")
|
||||
validator := stake.NewValidator(genTx.Address,
|
||||
sdk.MustGetAccPubKeyBech32(genTx.PubKey), desc)
|
||||
validator := stake.NewValidator(
|
||||
sdk.ValAddress(genTx.Address), sdk.MustGetConsPubKeyBech32(genTx.PubKey), desc,
|
||||
)
|
||||
|
||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDec(freeFermionVal)) // increase the supply
|
||||
|
||||
// add some new shares to the validator
|
||||
var issuedDelShares sdk.Dec
|
||||
validator, stakeData.Pool, issuedDelShares = validator.AddTokensFromDel(stakeData.Pool, freeFermionVal)
|
||||
validator, stakeData.Pool, issuedDelShares = validator.AddTokensFromDel(stakeData.Pool, sdk.NewInt(freeFermionVal))
|
||||
stakeData.Validators = append(stakeData.Validators, validator)
|
||||
|
||||
// create the self-delegation from the issuedDelShares
|
||||
delegation := stake.Delegation{
|
||||
DelegatorAddr: validator.Operator,
|
||||
DelegatorAddr: sdk.AccAddress(validator.Operator),
|
||||
ValidatorAddr: validator.Operator,
|
||||
Shares: issuedDelShares,
|
||||
Height: 0,
|
||||
|
||||
@ -3,7 +3,6 @@ package app
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
@ -58,10 +57,10 @@ func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json
|
||||
// XXX Try different numbers of initially bonded validators
|
||||
numInitiallyBonded := int64(50)
|
||||
for i := 0; i < int(numInitiallyBonded); i++ {
|
||||
validator := stake.NewValidator(accs[i], keys[i].PubKey(), stake.Description{})
|
||||
validator := stake.NewValidator(sdk.ValAddress(accs[i]), keys[i].PubKey(), stake.Description{})
|
||||
validator.Tokens = sdk.NewDec(100)
|
||||
validator.DelegatorShares = sdk.NewDec(100)
|
||||
delegation := stake.Delegation{accs[i], accs[i], sdk.NewDec(100), 0}
|
||||
delegation := stake.Delegation{accs[i], sdk.ValAddress(accs[i]), sdk.NewDec(100), 0}
|
||||
validators = append(validators, validator)
|
||||
delegations = append(delegations, delegation)
|
||||
}
|
||||
@ -85,9 +84,9 @@ func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json
|
||||
return appState
|
||||
}
|
||||
|
||||
func testAndRunTxs(app *GaiaApp) []simulation.TestAndRunTx {
|
||||
return []simulation.TestAndRunTx{
|
||||
banksim.TestAndRunSingleInputMsgSend(app.accountMapper),
|
||||
func testAndRunTxs(app *GaiaApp) []simulation.Operation {
|
||||
return []simulation.Operation{
|
||||
banksim.SimulateSingleInputMsgSend(app.accountMapper),
|
||||
govsim.SimulateMsgSubmitProposal(app.govKeeper, app.stakeKeeper),
|
||||
govsim.SimulateMsgDeposit(app.govKeeper, app.stakeKeeper),
|
||||
govsim.SimulateMsgVote(app.govKeeper, app.stakeKeeper),
|
||||
@ -171,11 +170,10 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||
true,
|
||||
)
|
||||
appHash := app.LastCommitID().Hash
|
||||
fmt.Printf(">>> APP HASH: %v, %X\n", appHash, appHash)
|
||||
appHashList[j] = appHash
|
||||
}
|
||||
for k := 1; k < numTimesToRunPerSeed; k++ {
|
||||
require.Equal(t, appHashList[0], appHashList[k])
|
||||
require.Equal(t, appHashList[0], appHashList[k], "appHash list: %v", appHashList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,16 +34,7 @@ func init() {
|
||||
}
|
||||
|
||||
func TestGaiaCLISend(t *testing.T) {
|
||||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "")
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass)
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass)
|
||||
|
||||
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass)
|
||||
|
||||
// get a free port, also setup some common flags
|
||||
servAddr, port, err := server.FreeTCPAddr()
|
||||
require.NoError(t, err)
|
||||
chainID, servAddr, port := initializeFixtures(t)
|
||||
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
@ -86,16 +77,42 @@ func TestGaiaCLISend(t *testing.T) {
|
||||
require.Equal(t, int64(20), fooAcc.GetCoins().AmountOf("steak").Int64())
|
||||
}
|
||||
|
||||
func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "")
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass)
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass)
|
||||
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass)
|
||||
func TestGaiaCLIGasAuto(t *testing.T) {
|
||||
chainID, servAddr, port := initializeFixtures(t)
|
||||
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
|
||||
|
||||
// get a free port, also setup some common flags
|
||||
servAddr, port, err := server.FreeTCPAddr()
|
||||
require.NoError(t, err)
|
||||
// start gaiad server
|
||||
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
|
||||
|
||||
defer proc.Stop(false)
|
||||
tests.WaitForTMStart(port)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
|
||||
fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show foo --output=json --home=%s", gaiacliHome))
|
||||
barAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show bar --output=json --home=%s", gaiacliHome))
|
||||
|
||||
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags))
|
||||
require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64())
|
||||
|
||||
// Test failure with auto gas disabled and very little gas set by hand
|
||||
success := executeWrite(t, fmt.Sprintf("gaiacli send %v --gas=10 --amount=10steak --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass)
|
||||
require.False(t, success)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
// Check state didn't change
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags))
|
||||
require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64())
|
||||
|
||||
// Enable auto gas
|
||||
success = executeWrite(t, fmt.Sprintf("gaiacli send %v --gas=0 --amount=10steak --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
// Check state has changed accordingly
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags))
|
||||
require.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak").Int64())
|
||||
}
|
||||
|
||||
func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
chainID, servAddr, port := initializeFixtures(t)
|
||||
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
@ -107,7 +124,7 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
|
||||
fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show foo --output=json --home=%s", gaiacliHome))
|
||||
barAddr, barPubKey := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show bar --output=json --home=%s", gaiacliHome))
|
||||
barCeshPubKey := sdk.MustBech32ifyValPub(barPubKey)
|
||||
barCeshPubKey := sdk.MustBech32ifyConsPub(barPubKey)
|
||||
|
||||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
@ -137,14 +154,14 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", barAddr, flags))
|
||||
require.Equal(t, int64(8), barAcc.GetCoins().AmountOf("steak").Int64(), "%v", barAcc)
|
||||
|
||||
validator := executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %s --output=json %v", barAddr, flags))
|
||||
require.Equal(t, validator.Operator, barAddr)
|
||||
validator := executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %s --output=json %v", sdk.ValAddress(barAddr), flags))
|
||||
require.Equal(t, validator.Operator, sdk.ValAddress(barAddr))
|
||||
require.True(sdk.DecEq(t, sdk.NewDec(2), validator.Tokens))
|
||||
|
||||
// unbond a single share
|
||||
unbondStr := fmt.Sprintf("gaiacli stake unbond begin %v", flags)
|
||||
unbondStr += fmt.Sprintf(" --from=%s", "bar")
|
||||
unbondStr += fmt.Sprintf(" --validator=%s", barAddr)
|
||||
unbondStr += fmt.Sprintf(" --validator=%s", sdk.ValAddress(barAddr))
|
||||
unbondStr += fmt.Sprintf(" --shares-amount=%v", "1")
|
||||
|
||||
success := executeWrite(t, unbondStr, app.DefaultKeyPass)
|
||||
@ -155,7 +172,7 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags))
|
||||
require.Equal(t, int64(9), barAcc.GetCoins().AmountOf("steak").Int64(), "%v", barAcc)
|
||||
*/
|
||||
validator = executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %s --output=json %v", barAddr, flags))
|
||||
validator = executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %s --output=json %v", sdk.ValAddress(barAddr), flags))
|
||||
require.Equal(t, "1.0000000000", validator.Tokens.String())
|
||||
|
||||
params := executeGetParams(t, fmt.Sprintf("gaiacli stake parameters --output=json %v", flags))
|
||||
@ -168,15 +185,7 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "")
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass)
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass)
|
||||
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass)
|
||||
|
||||
// get a free port, also setup some common flags
|
||||
servAddr, port, err := server.FreeTCPAddr()
|
||||
require.NoError(t, err)
|
||||
chainID, servAddr, port := initializeFixtures(t)
|
||||
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
@ -277,10 +286,29 @@ func getTestingHomeDirs() (string, string) {
|
||||
return gaiadHome, gaiacliHome
|
||||
}
|
||||
|
||||
func initializeFixtures(t *testing.T) (chainID, servAddr, port string) {
|
||||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "")
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass)
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass)
|
||||
|
||||
chainID = executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
|
||||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass)
|
||||
|
||||
// get a free port, also setup some common flags
|
||||
servAddr, port, err := server.FreeTCPAddr()
|
||||
require.NoError(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
// executors
|
||||
|
||||
func executeWrite(t *testing.T, cmdStr string, writes ...string) bool {
|
||||
func executeWrite(t *testing.T, cmdStr string, writes ...string) (exitSuccess bool) {
|
||||
exitSuccess, _, _ = executeWriteRetStdStreams(t, cmdStr, writes...)
|
||||
return
|
||||
}
|
||||
|
||||
func executeWriteRetStdStreams(t *testing.T, cmdStr string, writes ...string) (bool, string, string) {
|
||||
proc := tests.GoExecuteT(t, cmdStr)
|
||||
|
||||
for _, write := range writes {
|
||||
@ -300,9 +328,7 @@ func executeWrite(t *testing.T, cmdStr string, writes ...string) bool {
|
||||
}
|
||||
|
||||
proc.Wait()
|
||||
return proc.ExitState.Success()
|
||||
// bz := proc.StdoutBuffer.Bytes()
|
||||
// fmt.Println("EXEC WRITE", string(bz))
|
||||
return proc.ExitState.Success(), string(stdout), string(stderr)
|
||||
}
|
||||
|
||||
func executeInit(t *testing.T, cmdStr string) (chainID string) {
|
||||
@ -326,7 +352,10 @@ func executeGetAddrPK(t *testing.T, cmdStr string) (sdk.AccAddress, crypto.PubKe
|
||||
pk, err := sdk.GetAccPubKeyBech32(ko.PubKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
return ko.Address, pk
|
||||
accAddr, err := sdk.AccAddressFromBech32(ko.Address)
|
||||
require.NoError(t, err)
|
||||
|
||||
return accAddr, pk
|
||||
}
|
||||
|
||||
func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount {
|
||||
|
||||
@ -6,13 +6,16 @@ import (
|
||||
ledger "github.com/zondax/ledger-goclient"
|
||||
)
|
||||
|
||||
// If ledger support (build tag) has been enabled, automically attempt to load
|
||||
// and set the ledger device, ledgerDevice, if it has not already been set.
|
||||
// If ledger support (build tag) has been enabled, which implies a CGO dependency,
|
||||
// set the discoverLedger function which is responsible for loading the Ledger
|
||||
// device at runtime or returning an error.
|
||||
func init() {
|
||||
device, err := ledger.FindLedger()
|
||||
if err != nil {
|
||||
ledgerDeviceErr = err
|
||||
} else {
|
||||
ledgerDevice = device
|
||||
discoverLedger = func() (LedgerSECP256K1, error) {
|
||||
device, err := ledger.FindLedger()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return device, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,24 +1,27 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
secp256k1 "github.com/btcsuite/btcd/btcec"
|
||||
tmcrypto "github.com/tendermint/tendermint/crypto"
|
||||
tmsecp256k1 "github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
)
|
||||
|
||||
var (
|
||||
ledgerDevice LedgerSECP256K1
|
||||
ledgerDeviceErr error
|
||||
|
||||
// ErrMissingLedgerDevice is used to reflect that a ledger device load has
|
||||
// not been attempted.
|
||||
ErrMissingLedgerDevice = errors.New("missing ledger device")
|
||||
// discoverLedger defines a function to be invoked at runtime for discovering
|
||||
// a connected Ledger device.
|
||||
discoverLedger discoverLedgerFn
|
||||
)
|
||||
|
||||
type (
|
||||
// discoverLedgerFn defines a Ledger discovery function that returns a
|
||||
// connected device or an error upon failure. Its allows a method to avoid CGO
|
||||
// dependencies when Ledger support is potentially not enabled.
|
||||
discoverLedgerFn func() (LedgerSECP256K1, error)
|
||||
|
||||
// DerivationPath represents a Ledger derivation path.
|
||||
DerivationPath []uint32
|
||||
|
||||
@ -47,18 +50,17 @@ type (
|
||||
// CONTRACT: The ledger device, ledgerDevice, must be loaded and set prior to
|
||||
// any creation of a PrivKeyLedgerSecp256k1.
|
||||
func NewPrivKeyLedgerSecp256k1(path DerivationPath) (tmcrypto.PrivKey, error) {
|
||||
if ledgerDevice == nil {
|
||||
err := ErrMissingLedgerDevice
|
||||
if ledgerDeviceErr != nil {
|
||||
err = ledgerDeviceErr
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("failed to create PrivKeyLedgerSecp256k1: %v", err)
|
||||
if discoverLedger == nil {
|
||||
return nil, errors.New("no Ledger discovery function defined")
|
||||
}
|
||||
|
||||
pkl := &PrivKeyLedgerSecp256k1{Path: path, ledger: ledgerDevice}
|
||||
device, err := discoverLedger()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create PrivKeyLedgerSecp256k1")
|
||||
}
|
||||
|
||||
pkl := &PrivKeyLedgerSecp256k1{Path: path, ledger: device}
|
||||
|
||||
// cache the pubkey for later use
|
||||
pubKey, err := pkl.getPubKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -1,78 +1,77 @@
|
||||
## Fees
|
||||
- Collection
|
||||
- Gas price based on parameter
|
||||
- (which gets changed automatically)
|
||||
- https://github.com/cosmos/cosmos-sdk/issues/1921
|
||||
- Per block gas usage as %
|
||||
- Windowing function
|
||||
- Block N,
|
||||
- For Block N-x ~ N, get average of %
|
||||
- Should take into account time.
|
||||
- Standard for querying this price // needs to be used by UX.
|
||||
- Distribution
|
||||
- MVP: 1 week, 1 week for testing.
|
||||
# High priority
|
||||
|
||||
## Governance v2
|
||||
- V1 is just text proposals
|
||||
- Software upgrade stuff
|
||||
- https://github.com/cosmos/cosmos-sdk/issues/1734#issuecomment-407254938
|
||||
- https://github.com/cosmos/cosmos-sdk/issues/1079
|
||||
- We need to test auto-flipping w/ threshold voting power.
|
||||
- Super simple:
|
||||
- Only use text proposals
|
||||
- On-chain mechanism for agreeing on when to "flip" to new functionality
|
||||
## Fees
|
||||
|
||||
- Collection
|
||||
- Simple flat fee set in-config by validators & full nodes - ref [#1921](https://github.com/cosmos/cosmos-sdk/issues/1921)
|
||||
- @sunnya97 working on implementation
|
||||
- _*BLOCKER:*_ Blocked on [tendermint/tendermint#2275](https://github.com/tendermint/tendermint/issues/2275) @ValarDragon
|
||||
- Distribution
|
||||
- "Piggy bank" fee distribution - ref [#1944](https://github.com/cosmos/cosmos-sdk/pull/1944) (spec)
|
||||
- @rigelrozanski working on implementation
|
||||
- EST TIMELINE:
|
||||
- Work on fees should be completed in the `v0.25.0` release
|
||||
|
||||
## Staking/Slashing/Stability
|
||||
- Unbonding state for validators https://github.com/cosmos/cosmos-sdk/issues/1676
|
||||
- current: downtime, double signing during unbonding
|
||||
- who gets slashed when -- needs review about edge cases
|
||||
- need to communicate to everyone that lite has this edge case
|
||||
- Issues:
|
||||
- https://github.com/cosmos/cosmos-sdk/issues/1378
|
||||
- https://github.com/cosmos/cosmos-sdk/issues/1348
|
||||
- https://github.com/cosmos/cosmos-sdk/issues/1440
|
||||
* Est Difficulty: Hard
|
||||
* _*Note:*_ This feature needs to be fully fleshed out. Will require a meeting between @jaekwon, @cwgoes, @rigel, @zaki, @bucky to discuss the issues. @jackzampolin to facilitate.
|
||||
|
||||
- Unbonding state for validators (WIP) [#2163](https://github.com/cosmos/cosmos-sdk/pull/2163) @rigelrozanski
|
||||
- Needs :eyes: from @chris
|
||||
- Should be in `v0.25.0` release
|
||||
- Slashing period PR - ref [#2122](https://github.com/cosmos/cosmos-sdk/pull/2122)
|
||||
- Needs :eyes: from @cwgoes and @jaekwon
|
||||
- Should be in `v0.25.0` release
|
||||
- Other slashing issues blocking for launch - [#1256](https://github.com/cosmos/cosmos-sdk/issues/1256)
|
||||
- Update staking/slashing for NextValSet change
|
||||
- @cwgoes to start next
|
||||
- Miscellaneous minor staking issues
|
||||
- [List here](https://github.com/cosmos/cosmos-sdk/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Astaking+label%3Aprelaunch)
|
||||
- Need to figure out scope of work here to estimate time
|
||||
- @rigelrozanski to start next
|
||||
|
||||
## Vesting
|
||||
- 24 accounts with NLocktime
|
||||
- “No funds can be transferred before timelock”
|
||||
- New atoms and such can be withdrawn right way
|
||||
- Requires being able to send fees and inflation to new account
|
||||
|
||||
- Single `VestingAccount` allowing delegation/voting but no withdrawals
|
||||
- Ref [#1875](https://github.com/cosmos/cosmos-sdk/pull/1875) (spec)
|
||||
- @AdityaSripal working on this.
|
||||
- Should be in `v0.25.0` release
|
||||
|
||||
## Multisig
|
||||
- Make it work with Cli
|
||||
- ADR
|
||||
|
||||
## Reserve Pool
|
||||
- No withdrawing from it at launch
|
||||
- Already implemented on TM side, need simple CLI interface
|
||||
- @alessio working on the SDK side of things here
|
||||
- Need to schedule some time with @alessio, @ebuchman and @ValarDragon this week to finalize feature set/implementation plan
|
||||
|
||||
## Other:
|
||||
- Need to update for NextValidatorSet - need to upgrade SDK for it
|
||||
- Need to update for new ABCI changes - error string, tags are list of lists, proposer in header
|
||||
- Inflation ?
|
||||
## ABCI Changes
|
||||
|
||||
- Need to update for new ABCI changes - error string, tags are list of lists, proposer in header (Tendermint 0.24?)
|
||||
- @cwgoes has done some work here. Should be on `develop` in tendermint w/in next week.
|
||||
- Include in tendermint `v0.24.0` release?
|
||||
|
||||
## Gas
|
||||
- Calculate gas
|
||||
|
||||
## Reward proposer
|
||||
- Requires tendermint changes
|
||||
- Simple transaction benchmarking work by @jlandrews to inform additional work here
|
||||
- Integrate @alessio's simulation work into CLI and LCD
|
||||
- Sanity Checks
|
||||
|
||||
## LCD
|
||||
|
||||
- Bianje working on implementation ([#2147](https://github.com/cosmos/cosmos-sdk/pull/2147))
|
||||
- ICS 0,ICS 1, ICS 20 and ICS 21 implemented in this PR :point_up:
|
||||
- @fedekunze, @jackzampolin and @alexanderbez to review
|
||||
- Additional PR incoming for ICS 22 and ICS 23
|
||||
- Include [#382](https://github.com/cosmos/cosmos-sdk/issues/382)
|
||||
|
||||
# Lower priority
|
||||
|
||||
## Circuit Breaker
|
||||
- Kinda needed for enabling txs.
|
||||
## Governance v2
|
||||
|
||||
## Governance proposal changes
|
||||
- V2 is parameter changes
|
||||
- Simple software upgrade proposals
|
||||
- Implementation described in [#1079](https://github.com/cosmos/cosmos-sdk/issues/1079)
|
||||
- Agree upon a block height to switch to new version
|
||||
- Another Governance proposal from @jaekwon [#2116](https://github.com/cosmos/cosmos-sdk/pull/2116)
|
||||
- Circuit breaker
|
||||
- Parameter change proposals (roughly the same implementation as circuit breaker)
|
||||
|
||||
## Slashing/Stability
|
||||
- tendermint evidence: we don’t yet slash byzantine signatures (signing at all) when not bonded.
|
||||
## Documentation
|
||||
|
||||
# Other priority
|
||||
|
||||
## gaiad // gaiacli
|
||||
- Documentation // language
|
||||
|
||||
## gaialite
|
||||
- Documentation // language
|
||||
- gaiad / gaiacli / gaialite documentation!
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
- [ ] 2. Add commits/PRs that are desired for this release **that haven’t already been added to develop**
|
||||
- [ ] 3. Merge items in `PENDING.md` into the `CHANGELOG.md`. While doing this make sure that each entry contains links to issues/PRs for each item
|
||||
- [ ] 4. Summarize breaking API changes section under “Breaking Changes” section to the `CHANGELOG.md` to bring attention to any breaking API changes that affect RPC consumers.
|
||||
- [ ] 5. Tag the commit `{{ .Release.Name }}-rcN`
|
||||
- [ ] 5. Tag the commit `{ .Release.Name }-rcN`
|
||||
- [ ] 6. Kick off 1 day of automated fuzz testing
|
||||
- [ ] 7. Release Lead assigns 2 people to perform [buddy testing script](/docs/RELEASE_TEST_SCRIPT.md) and update the relevant documentation
|
||||
- [ ] 8. If errors are found in either #6 or #7 go back to #2 (*NOTE*: be sure to increment the `rcN`)
|
||||
|
||||
@ -710,15 +710,15 @@ definitions:
|
||||
Address:
|
||||
type: string
|
||||
description: bech32 encoded addres
|
||||
example: cosmosaccaddr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
example: cosmos:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
ValidatorAddress:
|
||||
type: string
|
||||
description: bech32 encoded addres
|
||||
example: cosmosvaladdr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
example: cosmosval:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
PubKey:
|
||||
type: string
|
||||
description: bech32 encoded public key
|
||||
example: cosmosaccpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
example: cosmospub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
ValidatorPubKey:
|
||||
type: string
|
||||
description: bech32 encoded public key
|
||||
|
||||
@ -17,7 +17,7 @@ Once you have the Cosmos app installed on your Ledger, and the Ledger is accessi
|
||||
```bash
|
||||
$ gaiacli keys add {{ .Key.Name }} --ledger
|
||||
NAME: TYPE: ADDRESS: PUBKEY:
|
||||
{{ .Key.Name }} ledger cosmosaccaddr1aw64xxr80lwqqdk8u2xhlrkxqaxamkr3e2g943 cosmosaccpub1addwnpepqvhs678gh9aqrjc2tg2vezw86csnvgzqq530ujkunt5tkuc7lhjkz5mj629
|
||||
{{ .Key.Name }} ledger cosmos1aw64xxr80lwqqdk8u2xhlrkxqaxamkr3e2g943 cosmospub1addwnpepqvhs678gh9aqrjc2tg2vezw86csnvgzqq530ujkunt5tkuc7lhjkz5mj629
|
||||
```
|
||||
|
||||
This key will only be accessible while the Ledger is plugged in and unlocked. To send some coins with this key, run the following:
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
module.exports = {
|
||||
title: "Cosmos Network",
|
||||
description: "Documentation for the Cosmos Network.",
|
||||
dest: "./site-docs",
|
||||
base: "/",
|
||||
dest: "./dist/docs",
|
||||
base: "/docs/",
|
||||
markdown: {
|
||||
lineNumbers: true
|
||||
},
|
||||
|
||||
@ -13,7 +13,7 @@ Now these json files need to be aggregated together via Github, a Google form, p
|
||||
Place all files on one computer in `$HOME/.gaiad/gen-tx/`
|
||||
|
||||
```bash
|
||||
gaiad init --gen-txs -o --chain=<chain-name>
|
||||
gaiad init --with-txs -o --chain=<chain-name>
|
||||
```
|
||||
|
||||
This will generate a `genesis.json` in `$HOME/.gaiad/config/genesis.json` distribute this file to all validators on your testnet.
|
||||
|
||||
@ -186,7 +186,7 @@ data = {
|
||||
"text": "I hereby claim I am ABC on Keybase!"
|
||||
}
|
||||
|
||||
cosmosSignBytes(data, "cosmosaccaddr1pvsch6cddahhrn5e8ekw0us50dpnugwnlfngt3")
|
||||
cosmosSignBytes(data, "cosmos1pvsch6cddahhrn5e8ekw0us50dpnugwnlfngt3")
|
||||
> "0x7fc4a495473045022100dec81a9820df0102381cdbf7e8b0f1e2cb64c58e0ecda1324543742e0388e41a02200df37905a6505c1b56a404e23b7473d2c0bc5bcda96771d2dda59df6ed2b98f8"
|
||||
```
|
||||
|
||||
|
||||
@ -71,13 +71,13 @@ This API exposes all functionality needed for key creation, signing and manageme
|
||||
"account":[
|
||||
{
|
||||
"name":"monkey",
|
||||
"address":"cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd",
|
||||
"pub_key":"cosmosaccpub1zcjduc3q8s8ha96ry4xc5xvjp9tr9w9p0e5lk5y0rpjs5epsfxs4wmf72x3shvus0t"
|
||||
"address":"cosmos1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd",
|
||||
"pub_key":"cosmospub1zcjduc3q8s8ha96ry4xc5xvjp9tr9w9p0e5lk5y0rpjs5epsfxs4wmf72x3shvus0t"
|
||||
},
|
||||
{
|
||||
"name":"test",
|
||||
"address":"cosmosaccaddr1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2",
|
||||
"pub_key":"cosmosaccpub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak"
|
||||
"address":"cosmos1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2",
|
||||
"pub_key":"cosmospub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak"
|
||||
}
|
||||
],
|
||||
"block_height":5241
|
||||
@ -125,8 +125,8 @@ Returns on success:
|
||||
"error":"",
|
||||
"result":{
|
||||
"name":"test",
|
||||
"address":"cosmosaccaddr1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2",
|
||||
"pub_key":"cosmosaccpub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak"
|
||||
"address":"cosmos1thlqhjqw78zvcy0ua4ldj9gnazqzavyw4eske2",
|
||||
"pub_key":"cosmospub1zcjduc3qyx6hlf825jcnj39adpkaxjer95q7yvy25yhfj3dmqy2ctev0rxmse9cuak"
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -588,7 +588,7 @@ The GovernanceAPI exposes all functionality needed for casting votes on plain te
|
||||
"description": "string",
|
||||
// PlainTextProposal supported now. SoftwareUpgradeProposal and other types may be supported soon
|
||||
"proposal_type": "string",
|
||||
// A cosmosaccaddr address
|
||||
// A cosmos address
|
||||
"proposer": "string",
|
||||
"initial_deposit": [
|
||||
{
|
||||
@ -689,7 +689,7 @@ The GovernanceAPI exposes all functionality needed for casting votes on plain te
|
||||
"error":"",
|
||||
"result":{
|
||||
"amount": {"atom": 150},
|
||||
"depositer": "cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd",
|
||||
"depositer": "cosmos1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd",
|
||||
"proposal-id": 16
|
||||
}
|
||||
}
|
||||
@ -731,12 +731,12 @@ The GovernanceAPI exposes all functionality needed for casting votes on plain te
|
||||
"result": [
|
||||
{
|
||||
"proposal-id": 1,
|
||||
"voter": "cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd",
|
||||
"voter": "cosmos1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd",
|
||||
"option": "no_with_veto"
|
||||
},
|
||||
{
|
||||
"proposal-id": 1,
|
||||
"voter": "cosmosaccaddr1849m9wncrqp6v4tkss6a3j8uzvuv0cp7f75lrq",
|
||||
"voter": "cosmos1849m9wncrqp6v4tkss6a3j8uzvuv0cp7f75lrq",
|
||||
"option": "yes"
|
||||
},
|
||||
]
|
||||
@ -761,7 +761,7 @@ The GovernanceAPI exposes all functionality needed for casting votes on plain te
|
||||
"sequence": 0,
|
||||
"gas": 0
|
||||
},
|
||||
// A cosmosaccaddr address
|
||||
// A cosmos address
|
||||
"voter": "string",
|
||||
// Value of the vote option `Yes`, `No` `Abstain`, `NoWithVeto`
|
||||
"option": "string",
|
||||
@ -794,7 +794,7 @@ The GovernanceAPI exposes all functionality needed for casting votes on plain te
|
||||
"error":"",
|
||||
"result":{
|
||||
"proposal-id": 1,
|
||||
"voter": "cosmosaccaddr1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd",
|
||||
"voter": "cosmos1fedh326uxqlxs8ph9ej7cf854gz7fd5zlym5pd",
|
||||
"option": "no_with_veto"
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,17 +18,21 @@
|
||||
|
||||
There are three types of key representations that are used:
|
||||
|
||||
- `cosmosaccaddr`
|
||||
- `cosmos`
|
||||
- Derived from account keys generated by `gaiacli keys add`
|
||||
- Used to receive funds
|
||||
- e.g. `cosmosaccaddr15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc`
|
||||
- `cosmosaccpub`
|
||||
- e.g. `cosmos15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc`
|
||||
* `cosmosval`
|
||||
* Used to associate a validator to it's operator
|
||||
* Used to invoke staking commands
|
||||
* e.g. `cosmosval1carzvgq3e6y3z5kz5y6gxp3wpy3qdrv928vyah`
|
||||
- `cosmospub`
|
||||
- Derived from account keys generated by `gaiacli keys add`
|
||||
- e.g. `cosmosaccpub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm`
|
||||
- `cosmosvalpub`
|
||||
- e.g. `cosmospub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm`
|
||||
- `cosmosconspub`
|
||||
- Generated when the node is created with `gaiad init`.
|
||||
- Get this value with `gaiad tendermint show-validator`
|
||||
- e.g. `cosmosvalpub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c`
|
||||
- e.g. `cosmosconspub1zcjduepq0ms2738680y72v44tfyqm3c9ppduku8fs6sr73fx7m666sjztznqzp2emf`
|
||||
|
||||
#### Generate Keys
|
||||
|
||||
@ -48,6 +52,12 @@ If you check your private keys, you'll now see `<account_name>`:
|
||||
gaiacli keys show <account_name>
|
||||
```
|
||||
|
||||
View the validator operator's address via:
|
||||
|
||||
```shell
|
||||
gaiacli keys show <account_name> --bech=val
|
||||
```
|
||||
|
||||
You can see all your available keys by typing:
|
||||
|
||||
```bash
|
||||
@ -68,18 +78,18 @@ We strongly recommend _NOT_ using the same passphrase for multiple keys. The Ten
|
||||
|
||||
#### 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). The faucet needs the `cosmosaccaddr` from the account you wish to use for staking.
|
||||
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). The faucet needs the `cosmos` from the account you wish to use for staking.
|
||||
|
||||
#### Query Account balance
|
||||
|
||||
After receiving tokens to your address, you can view your account's balance by typing:
|
||||
|
||||
```bash
|
||||
gaiacli account <account_cosmosaccaddr>
|
||||
gaiacli account <account_cosmos>
|
||||
```
|
||||
|
||||
::: warning Note
|
||||
When you query an account balance with zero tokens, you will get this error: `No account with address <account_cosmosaccaddr> was found in the state.` This can also happen if you fund the account before your node has fully synced with the chain. These are both normal.
|
||||
When you query an account balance with zero tokens, you will get this error: `No account with address <account_cosmos> was found in the state.` This can also happen if you fund the account before your node has fully synced with the chain. These are both normal.
|
||||
|
||||
:::
|
||||
|
||||
@ -90,24 +100,30 @@ gaiacli send \
|
||||
--amount=10faucetToken \
|
||||
--chain-id=<chain_id> \
|
||||
--name=<key_name> \
|
||||
--to=<destination_cosmosaccaddr>
|
||||
--to=<destination_cosmos>
|
||||
```
|
||||
|
||||
::: warning Note
|
||||
The `--amount` flag accepts the format `--amount=<value|coin_name>`.
|
||||
:::
|
||||
|
||||
::: tip Note
|
||||
You may want to cap the maximum gas that can be consumed by the transaction via the `--gas` flag.
|
||||
If set to 0, the gas limit will be automatically estimated.
|
||||
Gas estimate might be inaccurate as state changes could occur in between the end of the simulation and the actual execution of a transaction, thus an adjustment is applied on top of the original estimate in order to ensure the transaction is broadcasted successfully. The adjustment can be controlled via the `--gas-adjustment` flag, whose default value is 1.2.
|
||||
:::
|
||||
|
||||
Now, view the updated balances of the origin and destination accounts:
|
||||
|
||||
```bash
|
||||
gaiacli account <account_cosmosaccaddr>
|
||||
gaiacli account <destination_cosmosaccaddr>
|
||||
gaiacli account <account_cosmos>
|
||||
gaiacli account <destination_cosmos>
|
||||
```
|
||||
|
||||
You can also check your balance at a given block by using the `--block` flag:
|
||||
|
||||
```bash
|
||||
gaiacli account <account_cosmosaccaddr> --block=<block_height>
|
||||
gaiacli account <account_cosmos> --block=<block_height>
|
||||
```
|
||||
|
||||
### Staking
|
||||
@ -131,7 +147,7 @@ gaiacli stake validators
|
||||
If you want to get the information of a single validator you can check it with:
|
||||
|
||||
```bash
|
||||
gaiacli stake validator <account_cosmosaccaddr>
|
||||
gaiacli stake validator <account_cosmosval>
|
||||
```
|
||||
|
||||
#### Bond Tokens
|
||||
@ -158,14 +174,14 @@ Once submitted a delegation to a validator, you can see it's information by usin
|
||||
|
||||
```bash
|
||||
gaiacli stake delegation \
|
||||
--address-delegator=<account_cosmosaccaddr> \
|
||||
--address-validator=$(gaiad tendermint show-validator)
|
||||
--address-delegator=<account_cosmos> \
|
||||
--validator=<account_cosmosval>
|
||||
```
|
||||
|
||||
Or if you want to check all your current delegations with disctinct validators:
|
||||
|
||||
```bash
|
||||
gaiacli stake delegations <account_cosmosaccaddr>
|
||||
gaiacli stake delegations <account_cosmos>
|
||||
```
|
||||
|
||||
You can also get previous delegation(s) status by adding the `--height` flag.
|
||||
@ -176,7 +192,7 @@ If for any reason the validator misbehaves, or you just want to unbond a certain
|
||||
|
||||
```bash
|
||||
gaiacli stake unbond begin \
|
||||
--address-validator=$(gaiad tendermint show-validator) \
|
||||
--validator=<account_cosmosval> \
|
||||
--shares-percent=100 \
|
||||
--from=<key_name> \
|
||||
--chain-id=<chain_id>
|
||||
@ -186,7 +202,7 @@ Later you must complete the unbonding process by using the `gaiacli stake unbond
|
||||
|
||||
```bash
|
||||
gaiacli stake unbond complete \
|
||||
--address-validator=$(gaiad tendermint show-validator) \
|
||||
--validator=<account_cosmosval> \
|
||||
--from=<key_name> \
|
||||
--chain-id=<chain_id>
|
||||
```
|
||||
@ -197,14 +213,14 @@ Once you begin an unbonding-delegation, you can see it's information by using th
|
||||
|
||||
```bash
|
||||
gaiacli stake unbonding-delegation \
|
||||
--address-delegator=<account_cosmosaccaddr> \
|
||||
--address-validator=$(gaiad tendermint show-validator) \
|
||||
--address-delegator=<account_cosmos> \
|
||||
--validator=<account_cosmosval> \
|
||||
```
|
||||
|
||||
Or if you want to check all your current unbonding-delegations with disctinct validators:
|
||||
|
||||
```bash
|
||||
gaiacli stake unbonding-delegations <account_cosmosaccaddr>
|
||||
gaiacli stake unbonding-delegations <account_cosmos>
|
||||
```
|
||||
|
||||
You can also get previous unbonding-delegation(s) status by adding the `--height` flag.
|
||||
@ -215,8 +231,8 @@ A redelegation is a type delegation that allows you to bond illiquid tokens from
|
||||
|
||||
```bash
|
||||
gaiacli stake redelegate begin \
|
||||
--address-validator-source=$(gaiad tendermint show-validator) \
|
||||
--address-validator-dest=<account_cosmosaccaddr> \
|
||||
--address-validator-source=<account_cosmosval> \
|
||||
--address-validator-dest=<account_cosmosval> \
|
||||
--shares-percent=50 \
|
||||
--from=<key_name> \
|
||||
--chain-id=<chain_id>
|
||||
@ -228,7 +244,7 @@ Later you must complete the redelegation process by using the `gaiacli stake red
|
||||
|
||||
```bash
|
||||
gaiacli stake unbond complete \
|
||||
--address-validator=$(gaiad tendermint show-validator) \
|
||||
--validator=<account_cosmosval> \
|
||||
--from=<key_name> \
|
||||
--chain-id=<chain_id>
|
||||
```
|
||||
@ -239,15 +255,15 @@ Once you begin an redelegation, you can see it's information by using the follow
|
||||
|
||||
```bash
|
||||
gaiacli stake redelegation \
|
||||
--address-delegator=<account_cosmosaccaddr> \
|
||||
--address-validator-source=$(gaiad tendermint show-validator) \
|
||||
--address-validator-dest=<account_cosmosaccaddr> \
|
||||
--address-delegator=<account_cosmos> \
|
||||
--address-validator-source=<account_cosmosval> \
|
||||
--address-validator-dest=<account_cosmosval> \
|
||||
```
|
||||
|
||||
Or if you want to check all your current unbonding-delegations with disctinct validators:
|
||||
|
||||
```bash
|
||||
gaiacli stake redelegations <account_cosmosaccaddr>
|
||||
gaiacli stake redelegations <account_cosmos>
|
||||
```
|
||||
|
||||
You can also get previous redelegation(s) status by adding the `--height` flag.
|
||||
@ -280,7 +296,7 @@ gaiacli gov submit-proposal \
|
||||
--title=<title> \
|
||||
--description=<description> \
|
||||
--type=<Text/ParameterChange/SoftwareUpgrade> \
|
||||
--proposer=<account_cosmosaccaddr> \
|
||||
--proposer=<account_cosmos> \
|
||||
--deposit=<40steak> \
|
||||
--from=<name> \
|
||||
--chain-id=<chain_id>
|
||||
@ -310,7 +326,7 @@ In order for a proposal to be broadcasted to the network, the amount deposited m
|
||||
```bash
|
||||
gaiacli gov deposit \
|
||||
--proposal-id=<proposal_id> \
|
||||
--depositer=<account_cosmosaccaddr> \
|
||||
--depositer=<account_cosmos> \
|
||||
--deposit=<200steak> \
|
||||
--from=<name> \
|
||||
--chain-id=<chain_id>
|
||||
@ -325,7 +341,7 @@ After a proposal's deposit reaches the `MinDeposit` value, the voting period ope
|
||||
```bash
|
||||
gaiacli gov vote \
|
||||
--proposal-id=<proposal_id> \
|
||||
--voter=<account_cosmosaccaddr> \
|
||||
--voter=<account_cosmos> \
|
||||
--option=<Yes/No/NoWithVeto/Abstain> \
|
||||
--from=<name> \
|
||||
--chain-id=<chain_id>
|
||||
@ -338,7 +354,7 @@ Check the vote with the option you just submitted:
|
||||
```bash
|
||||
gaiacli gov query-vote \
|
||||
--proposal-id=<proposal_id> \
|
||||
--voter=<account_cosmosaccaddr>
|
||||
--voter=<account_cosmos>
|
||||
```
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
@ -208,7 +208,7 @@ type Result struct {
|
||||
// GasWanted is the maximum units of work we allow this tx to perform.
|
||||
GasWanted int64
|
||||
|
||||
// GasUsed is the amount of gas actually consumed. NOTE: unimplemented
|
||||
// GasUsed is the amount of gas actually consumed.
|
||||
GasUsed int64
|
||||
|
||||
// Tx fee amount and denom.
|
||||
|
||||
@ -211,7 +211,7 @@ func tx2Decoder(cdc *wire.Codec) sdk.TxDecoder {
|
||||
|
||||
// Simple anteHandler that ensures msg signers have signed.
|
||||
// Provides no replay protection.
|
||||
func antehandler(ctx sdk.Context, tx sdk.Tx) (_ sdk.Context, _ sdk.Result, abort bool) {
|
||||
func antehandler(ctx sdk.Context, tx sdk.Tx, simulate bool) (_ sdk.Context, _ sdk.Result, abort bool) {
|
||||
appTx, ok := tx.(app2Tx)
|
||||
if !ok {
|
||||
// set abort boolean to true so that we don't continue to process failed tx
|
||||
|
||||
@ -1,25 +1,24 @@
|
||||
# Bech32 on Cosmos
|
||||
|
||||
The Cosmos network prefers to use the Bech32 address format whereever users must handle binary data. Bech32 encoding provides robust integrity checks on data and the human readable part(HRP) provides contextual hints that can assist UI developers with providing informative error messages.
|
||||
The Cosmos network prefers to use the Bech32 address format wherever users must handle binary data. Bech32 encoding provides robust integrity checks on data and the human readable part(HRP) provides contextual hints that can assist UI developers with providing informative error messages.
|
||||
|
||||
In the Cosmos network, keys and addresses may refer to a number of different roles in the network like accounts, validators etc.
|
||||
|
||||
## HRP table
|
||||
|
||||
## HRP table
|
||||
|
||||
| HRP | Definition |
|
||||
| ------------- |:-------------:|
|
||||
| `cosmosaccaddr` | Cosmos Account Address |
|
||||
| `cosmosaccpub` | Cosmos Account Public Key |
|
||||
| `cosmosvaladdr` | Cosmos Consensus Address |
|
||||
| `cosmosvalpub` | Cosmos Consensus Public Key|
|
||||
| HRP | Definition |
|
||||
|---------------|--------------------------------------|
|
||||
| cosmos | Cosmos Account Address |
|
||||
| cosmospub | Cosmos Account Public Key |
|
||||
| cosmoscons | Cosmos Consensus Address |
|
||||
| cosmosconspub | Cosmos Consensus Public Key |
|
||||
| cosmosval | Cosmos Validator Operator Address |
|
||||
| cosmosvalpub | Cosmos Validator Operator Public Key |
|
||||
|
||||
## Encoding
|
||||
|
||||
While all user facing interfaces to Cosmos software should exposed bech32 interfaces, many internal interfaces encode binary value in hex or base64 encoded form.
|
||||
While all user facing interfaces to Cosmos software should exposed Bech32 interfaces, many internal interfaces encode binary value in hex or base64 encoded form.
|
||||
|
||||
To covert between other binary reprsentation of addresses and keys, it is important to first apply the Amino enocoding process before bech32 encoding.
|
||||
To covert between other binary representation of addresses and keys, it is important to first apply the Amino encoding process before bech32 encoding.
|
||||
|
||||
A complete implementation of the Amino serialization format is unncessary in most cases. Simply prepending bytes from this [table](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md#public-key-cryptography) to the bytestring payload before bech32 encoding will sufficient for compatible representation.
|
||||
|
||||
|
||||
A complete implementation of the Amino serialization format is unnecessary in most cases. Simply prepending bytes from this [table](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md#public-key-cryptography) to the byte string payload before bech32 encoding will sufficient for compatible representation.
|
||||
|
||||
@ -39,3 +39,14 @@ Sentry Nodes should edit their config.toml:
|
||||
# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
|
||||
private_peer_ids = "ipaddress of validator nodes"
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
By default, uppercase environment variables with the following prefixes will replace lowercase command-line flags:
|
||||
|
||||
- `GA` (for Gaia flags)
|
||||
- `TM` (for Tendermint flags)
|
||||
- `BC` (for democli or basecli flags)
|
||||
|
||||
For example, the environment variable `GA_CHAIN_ID` will map to the command line flag `--chain-id`. Note that while explicit command-line flags will take precedence over environment variables, environment variables will take precedence over any of your configuration files. For this reason, it's imperative that you lock down your environment such that any critical parameters are defined as flags on the CLI or prevent modification of any environment variables.
|
||||
|
||||
@ -77,13 +77,14 @@ We view testnet participation as a great way to signal to the community that you
|
||||
|
||||
In short, there are two types of keys:
|
||||
|
||||
- **Tendermint Key**: This is a unique key used to sign block hashes. It is associated with a public key `cosmosvalpub`.
|
||||
+ Generated when the node is created with gaiad init.
|
||||
+ Get this value with gaiad tendermint show_validator
|
||||
+M e.g. cosmosvalpub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c
|
||||
|
||||
- **Application keys**: These keys are created from the application and used to sign transactions. As a validator, you will probably use one key to sign staking-related transactions, and another key to sign governance-related transactions. Application keys are associated with a public key `cosmosaccpub` and an address `cosmosaccaddr`. Both are derived from account keys generated by `gaiacli keys add`.
|
||||
* **Tendermint Key**: This is a unique key used to sign block hashes. It is associated with a public key `cosmosconspub`.
|
||||
* Generated when the node is created with gaiad init.
|
||||
* Get this value with `gaiad tendermint show-validator`
|
||||
e.g. `cosmosconspub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c`
|
||||
|
||||
* **Application keys**: These keys are created from the application and used to sign transactions. As a validator, you will probably use one key to sign staking-related transactions, and another key to sign governance-related transactions. Application keys are associated with a public key `cosmospub` and an address `cosmos`. Both are derived from account keys generated by `gaiacli keys add`.
|
||||
* Note: A validator's operator key is directly tied to an application key, but
|
||||
uses reserved prefixes solely for this purpose: `cosmosval` and `cosmosvalpub`
|
||||
|
||||
### What are the different states a validator can be in?
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ If you want to become a validator for the Hub's `mainnet`, you should [research
|
||||
|
||||
### Create Your Validator
|
||||
|
||||
Your `cosmosvalpub` can be used to create a new validator by staking tokens. You can find your validator pubkey by running:
|
||||
Your `cosmosconspub` can be used to create a new validator by staking tokens. You can find your validator pubkey by running:
|
||||
|
||||
```bash
|
||||
gaiad tendermint show-validator
|
||||
@ -32,7 +32,7 @@ Don't use more `steak` thank you have! You can always get more by using the [Fau
|
||||
gaiacli stake create-validator \
|
||||
--amount=5steak \
|
||||
--pubkey=$(gaiad tendermint show-validator) \
|
||||
--address-validator=<account_cosmosaccaddr>
|
||||
--address-validator=<account_cosmosval>
|
||||
--moniker="choose a moniker" \
|
||||
--chain-id=<chain_id> \
|
||||
--name=<key_name>
|
||||
@ -46,7 +46,7 @@ The `--identity` can be used as to verify identity with systems like Keybase or
|
||||
|
||||
```bash
|
||||
gaiacli stake edit-validator
|
||||
--validator=<account_cosmosaccaddr>
|
||||
--validator=<account_cosmos>
|
||||
--moniker="choose a moniker" \
|
||||
--website="https://cosmos.network" \
|
||||
--identity=6A0D65E29A4CBC8E
|
||||
@ -60,7 +60,7 @@ gaiacli stake edit-validator
|
||||
View the validator's information with this command:
|
||||
|
||||
```bash
|
||||
gaiacli stake validator <account_cosmosaccaddr>
|
||||
gaiacli stake validator <account_cosmos>
|
||||
```
|
||||
|
||||
### Track Validator Signing Information
|
||||
@ -80,7 +80,7 @@ When a validator is "jailed" for downtime, you must submit an `Unjail` transacti
|
||||
gaiacli stake unjail \
|
||||
--from=<key_name> \
|
||||
--chain-id=<chain_id>
|
||||
--validator=<account_cosmosaccaddr> \
|
||||
--validator=<account_cosmosval> \
|
||||
--chain-id=gaia-6002
|
||||
```
|
||||
|
||||
@ -110,10 +110,10 @@ Here's how you can return the voting power back to your validator. First, if `ga
|
||||
gaiad start
|
||||
```
|
||||
|
||||
Wait for your full node to catch up to the latest block. Next, run the following command. Note that `<cosmosaccaddr>` is the address of your validator account, and `<name>` is the name of the validator account. You can find this info by running `gaiacli keys list`.
|
||||
Wait for your full node to catch up to the latest block. Next, run the following command. Note that `<cosmos>` is the address of your validator account, and `<name>` is the name of the validator account. You can find this info by running `gaiacli keys list`.
|
||||
|
||||
```bash
|
||||
gaiacli stake unjail <cosmosaccaddr> --chain-id=<chain_id> --name=<name>
|
||||
gaiacli stake unjail <cosmos> --chain-id=<chain_id> --name=<name>
|
||||
```
|
||||
|
||||
::: danger Warning
|
||||
|
||||
@ -103,10 +103,10 @@ basecli keys list
|
||||
You should now see alice, bob and charlie's account all show up.
|
||||
|
||||
```
|
||||
NAME: ADDRESS: PUBKEY:
|
||||
alice cosmosaccaddr1khygs0qh7gz3p4m39u00mjhvgvc2dcpxhsuh5f cosmosaccpub1addwnpepq0w037u5g7y7lvdvsred2dehg90j84k0weyss5ynysf0nnnax74agrsxns6
|
||||
bob cosmosaccaddr18se8tz6kwwfga6k2yjsu7n64e9z52nen29rhzz cosmosaccpub1addwnpepqwe97n8lryxrzvamrvjfj24jys3uzf8wndfvqa2l7mh5nsv4jrvdznvyeg6
|
||||
charlie cosmosaccaddr13wq5mklhn03ljpd4dkph5rflk5a3ssma2ag07q cosmosaccpub1addwnpepqdmtxv35rrmv2dvcr3yhfyxj7dzrd4z4rnhmclksq4g55a4wpl54clvx33l
|
||||
NAME: ADDRESS: PUBKEY:
|
||||
alice cosmos1khygs0qh7gz3p4m39u00mjhvgvc2dcpxhsuh5f cosmospub1addwnpepq0w037u5g7y7lvdvsred2dehg90j84k0weyss5ynysf0nnnax74agrsxns6
|
||||
bob cosmos18se8tz6kwwfga6k2yjsu7n64e9z52nen29rhzz cosmospub1addwnpepqwe97n8lryxrzvamrvjfj24jys3uzf8wndfvqa2l7mh5nsv4jrvdznvyeg6
|
||||
charlie cosmos13wq5mklhn03ljpd4dkph5rflk5a3ssma2ag07q cosmospub1addwnpepqdmtxv35rrmv2dvcr3yhfyxj7dzrd4z4rnhmclksq4g55a4wpl54clvx33l
|
||||
```
|
||||
|
||||
|
||||
@ -115,15 +115,15 @@ charlie cosmosaccaddr13wq5mklhn03ljpd4dkph5rflk5a3ssma2ag07q cosmosaccpub1addwnp
|
||||
Lets send bob and charlie some tokens. First, lets query alice's account so we can see what kind of tokens she has:
|
||||
|
||||
```
|
||||
basecli account cosmosaccaddr1khygs0qh7gz3p4m39u00mjhvgvc2dcpxhsuh5f
|
||||
basecli account cosmos1khygs0qh7gz3p4m39u00mjhvgvc2dcpxhsuh5f
|
||||
```
|
||||
|
||||
Where `cosmosaccaddr1khygs0qh7gz3p4m39u00mjhvgvc2dcpxhsuh5f` is alice's address we got from running `basecli keys list`. You should see a large amount of "mycoin" there. If you search for bob's or charlie's address, the command will fail, because they haven't been added into the blockchain database yet since they have no coins. We need to send them some!
|
||||
Where `cosmos1khygs0qh7gz3p4m39u00mjhvgvc2dcpxhsuh5f` is alice's address we got from running `basecli keys list`. You should see a large amount of "mycoin" there. If you search for bob's or charlie's address, the command will fail, because they haven't been added into the blockchain database yet since they have no coins. We need to send them some!
|
||||
|
||||
The following command will send coins from alice, to bob:
|
||||
|
||||
```
|
||||
basecli send --from=alice --amount=10000mycoin --to=cosmosaccaddr18se8tz6kwwfga6k2yjsu7n64e9z52nen29rhzz
|
||||
basecli send --from=alice --amount=10000mycoin --to=cosmos18se8tz6kwwfga6k2yjsu7n64e9z52nen29rhzz
|
||||
--sequence=0 --chain-id=test-chain-AE4XQo
|
||||
```
|
||||
|
||||
@ -136,13 +136,13 @@ Flag Descriptions:
|
||||
Now if we check bobs account, it should have `10000 mycoin`. You can do so by running :
|
||||
|
||||
```
|
||||
basecli account cosmosaccaddr18se8tz6kwwfga6k2yjsu7n64e9z52nen29rhzz
|
||||
basecli account cosmos18se8tz6kwwfga6k2yjsu7n64e9z52nen29rhzz
|
||||
```
|
||||
|
||||
Now lets send some from bob to charlie. Make sure you send less than bob has, otherwise the transaction will fail:
|
||||
|
||||
```
|
||||
basecli send --from=bob --amount=5000mycoin --to=cosmosaccaddr13wq5mklhn03ljpd4dkph5rflk5a3ssma2ag07q
|
||||
basecli send --from=bob --amount=5000mycoin --to=cosmos13wq5mklhn03ljpd4dkph5rflk5a3ssma2ag07q
|
||||
--sequence=0 --chain-id=test-chain-AE4XQo
|
||||
```
|
||||
|
||||
@ -151,7 +151,7 @@ Note how we use the ``--from`` flag to select a different account to send from.
|
||||
Lets now try to send from bob back to alice:
|
||||
|
||||
```
|
||||
basecli send --from=bob --amount=3000mycoin --to=cosmosaccaddr1khygs0qh7gz3p4m39u00mjhvgvc2dcpxhsuh5f
|
||||
basecli send --from=bob --amount=3000mycoin --to=cosmos1khygs0qh7gz3p4m39u00mjhvgvc2dcpxhsuh5f
|
||||
--sequence=1 --chain-id=test-chain-AE4XQo
|
||||
```
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
|
||||
// Validator implements sdk.Validator
|
||||
type Validator struct {
|
||||
Address sdk.AccAddress
|
||||
Address sdk.ValAddress
|
||||
Power sdk.Dec
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ func (v Validator) GetStatus() sdk.BondStatus {
|
||||
}
|
||||
|
||||
// Implements sdk.Validator
|
||||
func (v Validator) GetOperator() sdk.AccAddress {
|
||||
func (v Validator) GetOperator() sdk.ValAddress {
|
||||
return v.Address
|
||||
}
|
||||
|
||||
@ -78,9 +78,9 @@ func (vs *ValidatorSet) IterateValidatorsBonded(ctx sdk.Context, fn func(index i
|
||||
}
|
||||
|
||||
// Validator implements sdk.ValidatorSet
|
||||
func (vs *ValidatorSet) Validator(ctx sdk.Context, addr sdk.AccAddress) sdk.Validator {
|
||||
func (vs *ValidatorSet) Validator(ctx sdk.Context, addr sdk.ValAddress) sdk.Validator {
|
||||
for _, val := range vs.Validators {
|
||||
if bytes.Equal(val.Address, addr) {
|
||||
if bytes.Equal(val.Address.Bytes(), addr.Bytes()) {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ func NewValidatorSet(cdc *wire.Codec, store sdk.KVStore, valset sdk.ValidatorSet
|
||||
}
|
||||
|
||||
// Implements sdk.ValidatorSet
|
||||
func (valset ValidatorSet) Validator(ctx sdk.Context, addr sdk.AccAddress) (res sdk.Validator) {
|
||||
func (valset ValidatorSet) Validator(ctx sdk.Context, addr sdk.ValAddress) (res sdk.Validator) {
|
||||
base := valset.store.Get(GetBaseKey(addr))
|
||||
res = valset.ValidatorSet.Validator(ctx, base)
|
||||
if res == nil {
|
||||
@ -46,23 +46,23 @@ func (valset ValidatorSet) Validator(ctx sdk.Context, addr sdk.AccAddress) (res
|
||||
return
|
||||
}
|
||||
|
||||
// GetBaseKey :: sdk.AccAddress -> sdk.AccAddress
|
||||
func GetBaseKey(addr sdk.AccAddress) []byte {
|
||||
// GetBaseKey :: sdk.ValAddress -> sdk.ValAddress
|
||||
func GetBaseKey(addr sdk.ValAddress) []byte {
|
||||
return append([]byte{0x00}, addr...)
|
||||
}
|
||||
|
||||
// GetAssocPrefix :: sdk.AccAddress -> (sdk.AccAddress -> byte)
|
||||
func GetAssocPrefix(base sdk.AccAddress) []byte {
|
||||
// GetAssocPrefix :: sdk.ValAddress -> (sdk.ValAddress -> byte)
|
||||
func GetAssocPrefix(base sdk.ValAddress) []byte {
|
||||
return append([]byte{0x01}, base...)
|
||||
}
|
||||
|
||||
// GetAssocKey :: (sdk.AccAddress, sdk.AccAddress) -> byte
|
||||
func GetAssocKey(base sdk.AccAddress, assoc sdk.AccAddress) []byte {
|
||||
// GetAssocKey :: (sdk.ValAddress, sdk.ValAddress) -> byte
|
||||
func GetAssocKey(base sdk.ValAddress, assoc sdk.ValAddress) []byte {
|
||||
return append(append([]byte{0x01}, base...), assoc...)
|
||||
}
|
||||
|
||||
// Associate associates new address with validator address
|
||||
func (valset ValidatorSet) Associate(ctx sdk.Context, base sdk.AccAddress, assoc sdk.AccAddress) bool {
|
||||
func (valset ValidatorSet) Associate(ctx sdk.Context, base sdk.ValAddress, assoc sdk.ValAddress) bool {
|
||||
if len(base) != valset.addrLen || len(assoc) != valset.addrLen {
|
||||
return false
|
||||
}
|
||||
@ -76,7 +76,7 @@ func (valset ValidatorSet) Associate(ctx sdk.Context, base sdk.AccAddress, assoc
|
||||
}
|
||||
|
||||
// Dissociate removes association between addresses
|
||||
func (valset ValidatorSet) Dissociate(ctx sdk.Context, base sdk.AccAddress, assoc sdk.AccAddress) bool {
|
||||
func (valset ValidatorSet) Dissociate(ctx sdk.Context, base sdk.ValAddress, assoc sdk.ValAddress) bool {
|
||||
if len(base) != valset.addrLen || len(assoc) != valset.addrLen {
|
||||
return false
|
||||
}
|
||||
@ -90,8 +90,8 @@ func (valset ValidatorSet) Dissociate(ctx sdk.Context, base sdk.AccAddress, asso
|
||||
}
|
||||
|
||||
// Associations returns all associated addresses with a validator
|
||||
func (valset ValidatorSet) Associations(ctx sdk.Context, base sdk.AccAddress) (res []sdk.AccAddress) {
|
||||
res = make([]sdk.AccAddress, valset.maxAssoc)
|
||||
func (valset ValidatorSet) Associations(ctx sdk.Context, base sdk.ValAddress) (res []sdk.ValAddress) {
|
||||
res = make([]sdk.ValAddress, valset.maxAssoc)
|
||||
iter := sdk.KVStorePrefixIterator(valset.store, GetAssocPrefix(base))
|
||||
defer iter.Close()
|
||||
i := 0
|
||||
|
||||
@ -68,8 +68,8 @@ func (keeper Keeper) Handle(h Handler, ctx sdk.Context, o Msg, codespace sdk.Cod
|
||||
}
|
||||
info.LastSigned = ctx.BlockHeight()
|
||||
|
||||
// Check the signer is a validater
|
||||
val := valset.Validator(ctx, signer)
|
||||
// check the signer is a validator
|
||||
val := valset.Validator(ctx, sdk.ValAddress(signer))
|
||||
if val == nil {
|
||||
return ErrNotValidator(codespace, signer).Result()
|
||||
}
|
||||
|
||||
@ -55,14 +55,14 @@ func TestMsgMineString(t *testing.T) {
|
||||
addr := sdk.AccAddress([]byte("sender"))
|
||||
msg := MsgMine{addr, 0, 0, 0, []byte("abc")}
|
||||
res := msg.String()
|
||||
require.Equal(t, res, "MsgMine{Sender: cosmosaccaddr1wdjkuer9wg4wml9c, Difficulty: 0, Count: 0, Nonce: 0, Proof: abc}")
|
||||
require.Equal(t, res, "MsgMine{Sender: cosmos1wdjkuer9wgh76ts6, Difficulty: 0, Count: 0, Nonce: 0, Proof: abc}")
|
||||
}
|
||||
|
||||
func TestMsgMineGetSignBytes(t *testing.T) {
|
||||
addr := sdk.AccAddress([]byte("sender"))
|
||||
msg := MsgMine{addr, 1, 1, 1, []byte("abc")}
|
||||
res := msg.GetSignBytes()
|
||||
require.Equal(t, string(res), `{"count":1,"difficulty":1,"nonce":1,"proof":"YWJj","sender":"cosmosaccaddr1wdjkuer9wg4wml9c"}`)
|
||||
require.Equal(t, string(res), `{"count":1,"difficulty":1,"nonce":1,"proof":"YWJj","sender":"cosmos1wdjkuer9wgh76ts6"}`)
|
||||
}
|
||||
|
||||
func TestMsgMineGetSigners(t *testing.T) {
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
[defaults]
|
||||
retry_files_enabled = False
|
||||
host_key_checking = False
|
||||
|
||||
8
networks/remote/ansible/increase-openfiles.yml
Normal file
8
networks/remote/ansible/increase-openfiles.yml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
any_errors_fatal: true
|
||||
gather_facts: no
|
||||
roles:
|
||||
- increase-openfiles
|
||||
|
||||
@ -6,5 +6,7 @@
|
||||
any_errors_fatal: true
|
||||
gather_facts: no
|
||||
roles:
|
||||
- setup-journald
|
||||
- install-datadog-agent
|
||||
- update-datadog-agent
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
---
|
||||
|
||||
GAIAD_ADDRESS: tcp://0.0.0.0:1317
|
||||
GAIACLI_ADDRESS: tcp://0.0.0.0:1317
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
- name: Copy binary
|
||||
copy:
|
||||
src: "{{GAIACLI_BINARY}}"
|
||||
dest: /usr/bin
|
||||
dest: /usr/bin/gaiacli
|
||||
mode: 0755
|
||||
notify: restart gaiacli
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ Restart=on-failure
|
||||
User=gaiad
|
||||
Group=gaiad
|
||||
PermissionsStartOnly=true
|
||||
ExecStart=/usr/bin/gaiacli rest-server --laddr {{GAIAD_ADDRESS}}
|
||||
ExecStart=/usr/bin/gaiacli rest-server --laddr {{GAIACLI_ADDRESS}}
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillSignal=SIGTERM
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
fs.file-max=262144
|
||||
@ -0,0 +1,3 @@
|
||||
* soft nofile 262144
|
||||
* hard nofile 262144
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
[Service]
|
||||
LimitNOFILE=infinity
|
||||
LimitMEMLOCK=infinity
|
||||
@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
- name: reload systemctl
|
||||
systemd: name=systemd daemon_reload=yes
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
---
|
||||
# Based on: https://stackoverflow.com/questions/38155108/how-to-increase-limit-for-open-processes-and-files-using-ansible
|
||||
|
||||
- name: Set sysctl File Limits
|
||||
copy:
|
||||
src: 50-fs.conf
|
||||
dest: /etc/sysctl.d
|
||||
|
||||
- name: Set Shell File Limits
|
||||
copy:
|
||||
src: 91-nofiles.conf
|
||||
dest: /etc/security/limits.d
|
||||
|
||||
- name: Set gaia filehandle Limits
|
||||
copy:
|
||||
src: limits.conf
|
||||
dest: "/lib/systemd/system/{{item}}.service.d"
|
||||
notify: reload systemctl
|
||||
with_items:
|
||||
- gaiad
|
||||
- gaiacli
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIESTCCAzGgAwIBAgITBn+UV4WH6Kx33rJTMlu8mYtWDTANBgkqhkiG9w0BAQsF
|
||||
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
|
||||
b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL
|
||||
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB
|
||||
IDFCMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQDCThZn3c68asg3Wuw6MLAd5tES6BIoSMzoKcG5blPVo+sDORrMd4f2AbnZ
|
||||
cMzPa43j4wNxhplty6aUKk4T1qe9BOwKFjwK6zmxxLVYo7bHViXsPlJ6qOMpFge5
|
||||
blDP+18x+B26A0piiQOuPkfyDyeR4xQghfj66Yo19V+emU3nazfvpFA+ROz6WoVm
|
||||
B5x+F2pV8xeKNR7u6azDdU5YVX1TawprmxRC1+WsAYmz6qP+z8ArDITC2FMVy2fw
|
||||
0IjKOtEXc/VfmtTFch5+AfGYMGMqqvJ6LcXiAhqG5TI+Dr0RtM88k+8XUBCeQ8IG
|
||||
KuANaL7TiItKZYxK1MMuTJtV9IblAgMBAAGjggE7MIIBNzASBgNVHRMBAf8ECDAG
|
||||
AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUWaRmBlKge5WSPKOUByeW
|
||||
dFv5PdAwHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH
|
||||
AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy
|
||||
dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy
|
||||
dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js
|
||||
LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBMGA1UdIAQMMAow
|
||||
CAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IBAQCFkr41u3nPo4FCHOTjY3NTOVI1
|
||||
59Gt/a6ZiqyJEi+752+a1U5y6iAwYfmXss2lJwJFqMp2PphKg5625kXg8kP2CN5t
|
||||
6G7bMQcT8C8xDZNtYTd7WPD8UZiRKAJPBXa30/AbwuZe0GaFEQ8ugcYQgSn+IGBI
|
||||
8/LwhBNTZTUVEWuCUUBVV18YtbAiPq3yXqMB48Oz+ctBWuZSkbvkNodPLamkB2g1
|
||||
upRyzQ7qDn1X8nn8N8V7YJ6y68AtkHcNSRAnpTitxBKjtKPISLMVCx7i4hncxHZS
|
||||
yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEkjCCA3qgAwIBAgITBn+USionzfP6wq4rAfkI7rnExjANBgkqhkiG9w0BAQsF
|
||||
ADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNj
|
||||
b3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4x
|
||||
OzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1
|
||||
dGhvcml0eSAtIEcyMB4XDTE1MDUyNTEyMDAwMFoXDTM3MTIzMTAxMDAwMFowOTEL
|
||||
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
|
||||
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
|
||||
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
|
||||
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
|
||||
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
|
||||
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
|
||||
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
|
||||
jgSubJrIqg0CAwEAAaOCATEwggEtMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
|
||||
BAQDAgGGMB0GA1UdDgQWBBSEGMyFNOy8DJSULghZnMeyEE4KCDAfBgNVHSMEGDAW
|
||||
gBScXwDfqgHXMCs4iKK4bUqc8hGRgzB4BggrBgEFBQcBAQRsMGowLgYIKwYBBQUH
|
||||
MAGGImh0dHA6Ly9vY3NwLnJvb3RnMi5hbWF6b250cnVzdC5jb20wOAYIKwYBBQUH
|
||||
MAKGLGh0dHA6Ly9jcnQucm9vdGcyLmFtYXpvbnRydXN0LmNvbS9yb290ZzIuY2Vy
|
||||
MD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwucm9vdGcyLmFtYXpvbnRydXN0
|
||||
LmNvbS9yb290ZzIuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsF
|
||||
AAOCAQEAYjdCXLwQtT6LLOkMm2xF4gcAevnFWAu5CIw+7bMlPLVvUOTNNWqnkzSW
|
||||
MiGpSESrnO09tKpzbeR/FoCJbM8oAxiDR3mjEH4wW6w7sGDgd9QIpuEdfF7Au/ma
|
||||
eyKdpwAJfqxGF4PcnCZXmTA5YpaP7dreqsXMGz7KQ2hsVxa81Q4gLv7/wmpdLqBK
|
||||
bRRYh5TmOTFffHPLkIhqhBGWJ6bt2YFGpn6jcgAKUj6DiAdjd4lpFw85hdKrCEVN
|
||||
0FE6/V1dN2RMfjCyVSRCnTawXZwXgWHxyvkQAiSr6w10kY17RSlQOYiypok1JR4U
|
||||
akcjMS9cmvqtmg5iUaQqqcT5NJ0hGA==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEdTCCA12gAwIBAgIJAKcOSkw0grd/MA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
|
||||
BAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw
|
||||
MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
|
||||
eTAeFw0wOTA5MDIwMDAwMDBaFw0zNDA2MjgxNzM5MTZaMIGYMQswCQYDVQQGEwJV
|
||||
UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UE
|
||||
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjE7MDkGA1UEAxMyU3RhcmZp
|
||||
ZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDDrEKvlO4vW+GZdfjohTsR8/
|
||||
y8+fIBNtKTrID30892t2OGPZNmCom15cAICyL1l/9of5JUOG52kbUpqQ4XHj2C0N
|
||||
Tm/2yEnZtvMaVq4rtnQU68/7JuMauh2WLmo7WJSJR1b/JaCTcFOD2oR0FMNnngRo
|
||||
Ot+OQFodSk7PQ5E751bWAHDLUu57fa4657wx+UX2wmDPE1kCK4DMNEffud6QZW0C
|
||||
zyyRpqbn3oUYSXxmTqM6bam17jQuug0DuDPfR+uxa40l2ZvOgdFFRjKWcIfeAg5J
|
||||
Q4W2bHO7ZOphQazJ1FTfhy/HIrImzJ9ZVGif/L4qL8RVHHVAYBeFAlU5i38FAgMB
|
||||
AAGjgfAwge0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0O
|
||||
BBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtV
|
||||
rNzXEMIOqYjnME8GCCsGAQUFBwEBBEMwQTAcBggrBgEFBQcwAYYQaHR0cDovL28u
|
||||
c3MyLnVzLzAhBggrBgEFBQcwAoYVaHR0cDovL3guc3MyLnVzL3guY2VyMCYGA1Ud
|
||||
HwQfMB0wG6AZoBeGFWh0dHA6Ly9zLnNzMi51cy9yLmNybDARBgNVHSAECjAIMAYG
|
||||
BFUdIAAwDQYJKoZIhvcNAQELBQADggEBACMd44pXyn3pF3lM8R5V/cxTbj5HD9/G
|
||||
VfKyBDbtgB9TxF00KGu+x1X8Z+rLP3+QsjPNG1gQggL4+C/1E2DUBc7xgQjB3ad1
|
||||
l08YuW3e95ORCLp+QCztweq7dp4zBncdDQh/U90bZKuCJ/Fp1U1ervShw3WnWEQt
|
||||
8jxwmKy6abaVd38PMV4s/KCHOkdp8Hlf9BRUpJVeEXgSYCfOn8J3/yNTd126/+pZ
|
||||
59vPr5KW7ySaNRB6nJHGDn2Z9j8Z3/VyVOEVqQdZe4O/Ui5GjLIAZHYcSNPYeehu
|
||||
VsyuLAOQ1xk4meTKCRlb/weWsKh/NEnfVqn3sF/tM+2MR7cwA130A4w=
|
||||
-----END CERTIFICATE-----
|
||||
@ -1,35 +0,0 @@
|
||||
# see "man logrotate" for details
|
||||
# rotate log files weekly
|
||||
daily
|
||||
|
||||
# keep 4 days worth of backlogs
|
||||
rotate 4
|
||||
|
||||
# create new (empty) log files after rotating old ones
|
||||
create
|
||||
|
||||
# use date as a suffix of the rotated file
|
||||
dateext
|
||||
|
||||
# uncomment this if you want your log files compressed
|
||||
compress
|
||||
|
||||
# RPM packages drop log rotation information into this directory
|
||||
include /etc/logrotate.d
|
||||
|
||||
# no packages own wtmp and btmp -- we'll rotate them here
|
||||
/var/log/wtmp {
|
||||
monthly
|
||||
create 0664 root utmp
|
||||
minsize 1M
|
||||
rotate 1
|
||||
}
|
||||
|
||||
/var/log/btmp {
|
||||
missingok
|
||||
monthly
|
||||
create 0600 root utmp
|
||||
rotate 1
|
||||
}
|
||||
|
||||
# system-specific logs may be also be configured here.
|
||||
@ -1,13 +0,0 @@
|
||||
/var/log/cron
|
||||
/var/log/maillog
|
||||
/var/log/messages
|
||||
/var/log/secure
|
||||
/var/log/spooler
|
||||
{
|
||||
missingok
|
||||
sharedscripts
|
||||
postrotate
|
||||
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
|
||||
service datadog-agent restart 2> /dev/null || true
|
||||
endscript
|
||||
}
|
||||
@ -13,46 +13,3 @@
|
||||
DD_API_KEY: "{{DD_API_KEY}}"
|
||||
DD_HOST_TAGS: "testnet:{{TESTNET_NAME}},cluster:{{CLUSTER_NAME}}"
|
||||
|
||||
- name: Set datadog.yaml config
|
||||
template: src=datadog.yaml.j2 dest=/etc/datadog-agent/datadog.yaml
|
||||
notify: restart datadog-agent
|
||||
|
||||
- name: Set metrics config
|
||||
copy: src=conf.d/ dest=/etc/datadog-agent/conf.d/
|
||||
notify: restart datadog-agent
|
||||
|
||||
- name: Disable journald rate-limiting
|
||||
lineinfile: "dest=/etc/systemd/journald.conf regexp={{item.regexp}} line='{{item.line}}'"
|
||||
with_items:
|
||||
- { regexp: "^#RateLimitInterval", line: "RateLimitInterval=0s" }
|
||||
- { regexp: "^#RateLimitBurst", line: "RateLimitBurst=0" }
|
||||
- { regexp: "^#SystemMaxFileSize", line: "SystemMaxFileSize=500M" }
|
||||
notify: restart journald
|
||||
|
||||
- name: As long as Datadog does not support journald on RPM-based linux, we enable rsyslog
|
||||
yum: "name={{item}} state=installed"
|
||||
with_items:
|
||||
- rsyslog
|
||||
- rsyslog-gnutls
|
||||
|
||||
#- name: Get DataDog certificate for rsyslog
|
||||
# get_url: url=https://docs.datadoghq.com/crt/intake.logs.datadoghq.com.crt dest=/etc/ssl/certs/intake.logs.datadoghq.com.crt
|
||||
|
||||
- name: Get DataDog certificate for rsyslog
|
||||
copy: src=intake.logs.datadoghq.com.crt dest=/etc/ssl/certs/intake.logs.datadoghq.com.crt
|
||||
|
||||
- name: Add datadog config to rsyslog
|
||||
template: src=datadog.conf.j2 dest=/etc/rsyslog.d/datadog.conf mode=0600
|
||||
notify: restart rsyslog
|
||||
|
||||
- name: Set logrotate to rotate daily so syslog does not use up all space
|
||||
copy: src=logrotate.conf dest=/etc/logrotate.conf
|
||||
|
||||
- name: Set syslog to restart datadog-agent after logrotate
|
||||
copy: src=syslog dest=/etc/logrotate.d/syslog
|
||||
|
||||
#semanage port -a -t syslog_tls_port_t -p tcp 10516
|
||||
- name: Enable rsyslog to report to port 10516 in SELinux
|
||||
seport: ports=10516 proto=tcp reload=yes setype=syslog_tls_port_t state=present
|
||||
notify: restart rsyslog
|
||||
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
$template DatadogFormat,"{{DD_API_KEY}} <%pri%>%protocol-version% %timestamp:::date-rfc3339% %HOSTNAME% %app-name% - - - %msg%\n"
|
||||
|
||||
$imjournalRatelimitInterval 0
|
||||
$imjournalRatelimitBurst 0
|
||||
|
||||
$DefaultNetstreamDriver gtls
|
||||
$DefaultNetstreamDriverCAFile /etc/ssl/certs/intake.logs.datadoghq.com.crt
|
||||
$ActionSendStreamDriver gtls
|
||||
$ActionSendStreamDriverMode 1
|
||||
$ActionSendStreamDriverAuthMode x509/name
|
||||
$ActionSendStreamDriverPermittedPeer *.logs.datadoghq.com
|
||||
*.* @@intake.logs.datadoghq.com:10516;DatadogFormat
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
DAEMON_COREFILE_LIMIT='unlimited'
|
||||
@ -0,0 +1 @@
|
||||
DAEMON_COREFILE_LIMIT='unlimited'
|
||||
@ -0,0 +1,3 @@
|
||||
kernel.core_uses_pid = 1
|
||||
kernel.core_pattern = /tmp/core-%e-%s-%u-%g-%p-%t
|
||||
fs.suid_dumpable = 2
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
- name: reload sysctl
|
||||
command: "/sbin/sysctl -p"
|
||||
9
networks/remote/ansible/roles/set-debug/tasks/main.yml
Normal file
9
networks/remote/ansible/roles/set-debug/tasks/main.yml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
# Based on https://www.cyberciti.biz/tips/linux-core-dumps.html
|
||||
|
||||
- name: Copy sysctl and sysconfig files to enable app and daemon core dumps
|
||||
file: src=. dest=/etc/
|
||||
notify: reload sysctl
|
||||
|
||||
- name: Enable debugging for all apps
|
||||
lineinfile: create=yes line="DAEMON_COREFILE_LIMIT='unlimited'" path=/etc/sysconfig/init regexp=^DAEMON_COREFILE_LIMIT=
|
||||
@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
- name: reload systemd
|
||||
systemd: name=gaiad enabled=yes daemon_reload=yes
|
||||
|
||||
@ -6,14 +6,21 @@
|
||||
run_once: true
|
||||
become: no
|
||||
|
||||
- name: Create gaiad user
|
||||
user: name=gaiad home=/home/gaiad shell=/bin/bash
|
||||
|
||||
- name: Copy binary
|
||||
copy:
|
||||
src: "{{BINARY}}"
|
||||
dest: /usr/bin
|
||||
mode: 0755
|
||||
|
||||
- name: Copy service file
|
||||
copy: src=gaiad.service dest=/etc/systemd/system/gaiad.service mode=0755
|
||||
notify: reload systemd
|
||||
|
||||
- name: Get node ID
|
||||
command: "cat /etc/gaiad-nodeid"
|
||||
command: "cat /etc/nodeid"
|
||||
changed_when: false
|
||||
register: nodeid
|
||||
|
||||
|
||||
@ -5,8 +5,17 @@
|
||||
with_items:
|
||||
- { regexp: "^#RateLimitInterval", line: "RateLimitInterval=0s" }
|
||||
- { regexp: "^#RateLimitBurst", line: "RateLimitBurst=0" }
|
||||
- { regexp: "^#SystemMaxFileSize", line: "SystemMaxFileSize=100M" }
|
||||
- { regexp: "^#SystemMaxUse", line: "SystemMaxUse=500M" }
|
||||
- { regexp: "^#SystemMaxFiles", line: "SystemMaxFiles=10" }
|
||||
notify: restart journald
|
||||
|
||||
- name: Change logrotate to daily
|
||||
lineinfile: "dest=/etc/logrotate.conf regexp={{item.regexp}} line='{{item.line}}'"
|
||||
with_items:
|
||||
- { regexp: "^weekly", line: "daily" }
|
||||
- { regexp: "^#compress", line: "compress" }
|
||||
|
||||
- name: Create journal directory for permanent logs
|
||||
file: path=/var/log/journal state=directory
|
||||
notify: restart journald
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
- name: reload systemd
|
||||
systemd: name=gaiad enabled=yes daemon_reload=yes
|
||||
|
||||
@ -6,14 +6,21 @@
|
||||
run_once: true
|
||||
become: no
|
||||
|
||||
- name: Create gaiad user
|
||||
user: name=gaiad home=/home/gaiad shell=/bin/bash
|
||||
|
||||
- name: Copy binary
|
||||
copy:
|
||||
src: "{{BINARY}}"
|
||||
dest: /usr/bin
|
||||
mode: 0755
|
||||
|
||||
- name: Copy service file
|
||||
copy: src=gaiad.service dest=/etc/systemd/system/gaiad.service mode=0755
|
||||
notify: reload systemd
|
||||
|
||||
- name: Get node ID
|
||||
command: "cat /etc/gaiad-nodeid"
|
||||
command: "cat /etc/nodeid"
|
||||
changed_when: false
|
||||
register: nodeid
|
||||
|
||||
@ -63,7 +70,7 @@
|
||||
unarchive: src=files/gen-tx.tgz dest=/home/gaiad/.gaiad/config/gentx owner=gaiad
|
||||
|
||||
- name: Generate genesis.json
|
||||
command: "/usr/bin/gaiad init --gen-txs --name=node{{nodeid.stdout_lines[0]}} --chain-id={{TESTNET_NAME}}"
|
||||
command: "/usr/bin/gaiad init --with-txs --name=node{{nodeid.stdout_lines[0]}} --chain-id={{TESTNET_NAME}}"
|
||||
become: yes
|
||||
become_user: gaiad
|
||||
args:
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
init_config:
|
||||
|
||||
instances:
|
||||
- name: gaiad
|
||||
url: http://localhost:26657/status
|
||||
timeout: 1
|
||||
content_match: '"latest_block_height": "0",'
|
||||
reverse_content_match: true
|
||||
|
||||
- name: gaiacli
|
||||
url: http://localhost:1317/node_version
|
||||
timeout: 1
|
||||
|
||||
@ -2,6 +2,9 @@ init_config:
|
||||
|
||||
instances:
|
||||
- prometheus_url: http://127.0.0.1:26660
|
||||
namespace: "gaiad"
|
||||
metrics:
|
||||
- p2p: *
|
||||
- go*
|
||||
- mempool*
|
||||
- p2p*
|
||||
- process*
|
||||
- promhttp*
|
||||
@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
- name: restart datadog-agent
|
||||
service: name=datadog-agent state=restarted
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
---
|
||||
|
||||
- name: Set datadog.yaml config
|
||||
template: src=datadog.yaml.j2 dest=/etc/datadog-agent/datadog.yaml
|
||||
notify: restart datadog-agent
|
||||
|
||||
- name: Set metrics config
|
||||
copy: src=conf.d/ dest=/etc/datadog-agent/conf.d/
|
||||
notify: restart datadog-agent
|
||||
|
||||
@ -28,10 +28,10 @@ api_key: {{DD_API_KEY}}
|
||||
|
||||
# Setting this option to "yes" will force the agent to only use TLS 1.2 when
|
||||
# pushing data to the url specified in "dd_url".
|
||||
# force_tls_12: no
|
||||
force_tls_12: yes
|
||||
|
||||
# Force the hostname to whatever you want. (default: auto-detected)
|
||||
# hostname: mymachine.mydomain
|
||||
hostname: {{inventory_hostname | replace ("_","-")}}
|
||||
|
||||
# Make the agent use "hostname -f" on unix-based systems as a last resort
|
||||
# way of determining the hostname instead of Golang "os.Hostname()"
|
||||
@ -220,7 +220,7 @@ collect_ec2_tags: true
|
||||
# Logs agent
|
||||
#
|
||||
# Logs agent is disabled by default
|
||||
logs_enabled: true
|
||||
#logs_enabled: true
|
||||
#
|
||||
# Enable logs collection for all containers, disabled by default
|
||||
# logs_config:
|
||||
@ -3,7 +3,7 @@
|
||||
- name: Copy binary
|
||||
copy:
|
||||
src: "{{BINARY}}"
|
||||
dest: /usr/bin
|
||||
dest: /usr/bin/gaiad
|
||||
mode: 0755
|
||||
notify: restart gaiad
|
||||
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
---
|
||||
|
||||
# Set the core file size to unlimited to allow the system to generate core dumps
|
||||
|
||||
- hosts: all
|
||||
any_errors_fatal: true
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
|
||||
- name: Set core file size to unlimited to be able to get the core dump on SIGABRT
|
||||
shell: "ulimit -c unlimited"
|
||||
|
||||
8
networks/remote/ansible/set-debug.yml
Normal file
8
networks/remote/ansible/set-debug.yml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
any_errors_fatal: true
|
||||
gather_facts: no
|
||||
roles:
|
||||
- set-debug
|
||||
|
||||
@ -2,10 +2,12 @@
|
||||
|
||||
#GENESISFILE required
|
||||
#CONFIGFILE required
|
||||
#BINARY required
|
||||
|
||||
- hosts: all
|
||||
any_errors_fatal: true
|
||||
gather_facts: no
|
||||
roles:
|
||||
- increase-openfiles
|
||||
- setup-fullnodes
|
||||
|
||||
|
||||
@ -4,5 +4,6 @@
|
||||
any_errors_fatal: true
|
||||
gather_facts: no
|
||||
roles:
|
||||
- increase-openfiles
|
||||
- setup-validators
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
- name: Gather status
|
||||
uri:
|
||||
body_format: json
|
||||
url: "http://{{inventory_hostname}}:26657/status"
|
||||
url: "http://{{ansible_host}}:26657/status"
|
||||
register: status
|
||||
|
||||
- name: Print status
|
||||
|
||||
10
networks/remote/ansible/update-datadog-agent.yml
Normal file
10
networks/remote/ansible/update-datadog-agent.yml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
|
||||
#DD_API_KEY,TESTNET_NAME,CLUSTER_NAME required
|
||||
|
||||
- hosts: all
|
||||
any_errors_fatal: true
|
||||
gather_facts: no
|
||||
roles:
|
||||
- update-datadog-agent
|
||||
|
||||
@ -4,13 +4,5 @@
|
||||
#Usage: terraform.sh <testnet_name> <testnet_node_number>
|
||||
|
||||
#Add gaiad node number for remote identification
|
||||
echo "$2" > /etc/gaiad-nodeid
|
||||
|
||||
#Create gaiad user
|
||||
useradd -m -s /bin/bash gaiad
|
||||
|
||||
#Reload services to enable the gaiad service (note that the gaiad binary is not available yet)
|
||||
systemctl daemon-reload
|
||||
systemctl enable gaiad
|
||||
|
||||
echo "$2" > /etc/nodeid
|
||||
|
||||
|
||||
@ -6,10 +6,16 @@
|
||||
|
||||
#Instance Attachment (autoscaling is the future)
|
||||
resource "aws_lb_target_group_attachment" "lb_attach" {
|
||||
count = "${var.SERVERS*length(data.aws_availability_zones.zones.names)}"
|
||||
count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}"
|
||||
target_group_arn = "${aws_lb_target_group.lb_target_group.arn}"
|
||||
target_id = "${element(aws_instance.node.*.id,count.index)}"
|
||||
port = 80
|
||||
port = 26657
|
||||
}
|
||||
|
||||
resource "aws_lb_target_group_attachment" "lb_attach_lcd" {
|
||||
count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}"
|
||||
target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.arn}"
|
||||
target_id = "${element(aws_instance.node.*.id,count.index)}"
|
||||
port = 1317
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ data "aws_ami" "linux" {
|
||||
|
||||
resource "aws_instance" "node" {
|
||||
# depends_on = ["${element(aws_route_table_association.route_table_association.*,count.index)}"]
|
||||
count = "${var.SERVERS*length(data.aws_availability_zones.zones.names)}"
|
||||
count = "${var.SERVERS*min(length(data.aws_availability_zones.zones.names),var.max_zones)}"
|
||||
ami = "${data.aws_ami.linux.image_id}"
|
||||
instance_type = "${var.instance_type}"
|
||||
key_name = "${aws_key_pair.key.key_name}"
|
||||
@ -33,7 +33,7 @@ resource "aws_instance" "node" {
|
||||
}
|
||||
|
||||
root_block_device {
|
||||
volume_size = 20
|
||||
volume_size = 40
|
||||
}
|
||||
|
||||
connection {
|
||||
@ -47,14 +47,8 @@ resource "aws_instance" "node" {
|
||||
destination = "/tmp/terraform.sh"
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
source = "files/gaiad.service"
|
||||
destination = "/tmp/gaiad.service"
|
||||
}
|
||||
|
||||
provisioner "remote-exec" {
|
||||
inline = [
|
||||
"sudo cp /tmp/gaiad.service /etc/systemd/system/gaiad.service",
|
||||
"chmod +x /tmp/terraform.sh",
|
||||
"sudo /tmp/terraform.sh ${var.name} ${count.index}",
|
||||
]
|
||||
|
||||
@ -1,20 +1,22 @@
|
||||
resource "aws_lb" "lb" {
|
||||
name = "${var.name}"
|
||||
subnets = ["${aws_subnet.subnet.*.id}"]
|
||||
# security_groups = ["${split(",", var.lb_security_groups)}"]
|
||||
security_groups = ["${aws_security_group.secgroup.id}"]
|
||||
tags {
|
||||
Name = "${var.name}"
|
||||
}
|
||||
# access_logs {
|
||||
# bucket = "${var.s3_bucket}"
|
||||
# prefix = "ELB-logs"
|
||||
# prefix = "lblogs"
|
||||
# }
|
||||
}
|
||||
|
||||
resource "aws_lb_listener" "lb_listener" {
|
||||
load_balancer_arn = "${aws_lb.lb.arn}"
|
||||
port = "80"
|
||||
protocol = "HTTP"
|
||||
port = "443"
|
||||
protocol = "HTTPS"
|
||||
ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
|
||||
certificate_arn = "${var.certificate_arn}"
|
||||
|
||||
default_action {
|
||||
target_group_arn = "${aws_lb_target_group.lb_target_group.arn}"
|
||||
@ -23,7 +25,6 @@ resource "aws_lb_listener" "lb_listener" {
|
||||
}
|
||||
|
||||
resource "aws_lb_listener_rule" "listener_rule" {
|
||||
# depends_on = ["aws_lb_target_group.lb_target_group"]
|
||||
listener_arn = "${aws_lb_listener.lb_listener.arn}"
|
||||
priority = "100"
|
||||
action {
|
||||
@ -38,24 +39,14 @@ resource "aws_lb_listener_rule" "listener_rule" {
|
||||
|
||||
resource "aws_lb_target_group" "lb_target_group" {
|
||||
name = "${var.name}"
|
||||
port = "80"
|
||||
port = "26657"
|
||||
protocol = "HTTP"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
tags {
|
||||
name = "${var.name}"
|
||||
}
|
||||
# stickiness {
|
||||
# type = "lb_cookie"
|
||||
# cookie_duration = 1800
|
||||
# enabled = "true"
|
||||
# }
|
||||
# health_check {
|
||||
# healthy_threshold = 3
|
||||
# unhealthy_threshold = 10
|
||||
# timeout = 5
|
||||
# interval = 10
|
||||
# path = "${var.target_group_path}"
|
||||
# port = "${var.target_group_port}"
|
||||
# }
|
||||
health_check {
|
||||
path = "/health"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
39
networks/remote/terraform-app/infra/lcd.tf
Normal file
39
networks/remote/terraform-app/infra/lcd.tf
Normal file
@ -0,0 +1,39 @@
|
||||
resource "aws_lb_listener" "lb_listener_lcd" {
|
||||
load_balancer_arn = "${aws_lb.lb.arn}"
|
||||
port = "1317"
|
||||
protocol = "HTTPS"
|
||||
ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
|
||||
certificate_arn = "${var.certificate_arn}"
|
||||
|
||||
default_action {
|
||||
target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.arn}"
|
||||
type = "forward"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_lb_listener_rule" "listener_rule_lcd" {
|
||||
listener_arn = "${aws_lb_listener.lb_listener_lcd.arn}"
|
||||
priority = "100"
|
||||
action {
|
||||
type = "forward"
|
||||
target_group_arn = "${aws_lb_target_group.lb_target_group_lcd.id}"
|
||||
}
|
||||
condition {
|
||||
field = "path-pattern"
|
||||
values = ["/"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_lb_target_group" "lb_target_group_lcd" {
|
||||
name = "${var.name}lcd"
|
||||
port = "1317"
|
||||
protocol = "HTTP"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
tags {
|
||||
name = "${var.name}"
|
||||
}
|
||||
health_check {
|
||||
path = "/node_version"
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,9 +8,9 @@ output "instances" {
|
||||
value = ["${aws_instance.node.*.id}"]
|
||||
}
|
||||
|
||||
output "instances_count" {
|
||||
value = "${length(aws_instance.node.*)}"
|
||||
}
|
||||
#output "instances_count" {
|
||||
# value = "${length(aws_instance.node.*)}"
|
||||
#}
|
||||
|
||||
// The list of cluster instance public IPs
|
||||
output "public_ips" {
|
||||
|
||||
@ -17,6 +17,11 @@ variable "SERVERS" {
|
||||
default = "1"
|
||||
}
|
||||
|
||||
variable "max_zones" {
|
||||
description = "Maximum number of availability zones to use"
|
||||
default = "1"
|
||||
}
|
||||
|
||||
variable "ssh_private_file" {
|
||||
description = "SSH private key file to be used to connect to the nodes"
|
||||
type = "string"
|
||||
@ -27,3 +32,8 @@ variable "ssh_public_file" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "certificate_arn" {
|
||||
description = "Load-balancer SSL certificate AWS ARN"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ data "aws_availability_zones" "zones" {
|
||||
}
|
||||
|
||||
resource "aws_subnet" "subnet" {
|
||||
count = "${length(data.aws_availability_zones.zones.names)}"
|
||||
count = "${min(length(data.aws_availability_zones.zones.names),var.max_zones)}"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
availability_zone = "${element(data.aws_availability_zones.zones.names,count.index)}"
|
||||
cidr_block = "${cidrsubnet(aws_vpc.vpc.cidr_block, 8, count.index)}"
|
||||
@ -45,7 +45,7 @@ resource "aws_subnet" "subnet" {
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "route_table_association" {
|
||||
count = "${length(data.aws_availability_zones.zones.names)}"
|
||||
count = "${min(length(data.aws_availability_zones.zones.names),var.max_zones)}"
|
||||
subnet_id = "${element(aws_subnet.subnet.*.id,count.index)}"
|
||||
route_table_id = "${aws_route_table.route_table.id}"
|
||||
}
|
||||
@ -66,8 +66,15 @@ resource "aws_security_group" "secgroup" {
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 1317
|
||||
to_port = 1317
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
@ -9,11 +9,16 @@ variable "SERVERS" {
|
||||
default = "1"
|
||||
}
|
||||
|
||||
variable "MAX_ZONES" {
|
||||
description = "Maximum number of availability zones to use"
|
||||
default = "4"
|
||||
}
|
||||
|
||||
#See https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region
|
||||
#eu-west-3 does not contain CentOS images
|
||||
variable "REGION" {
|
||||
description = "AWS Regions"
|
||||
default = "us-east-2"
|
||||
default = "us-east-1"
|
||||
}
|
||||
|
||||
variable "SSH_PRIVATE_FILE" {
|
||||
@ -26,6 +31,11 @@ variable "SSH_PUBLIC_FILE" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "CERTIFICATE_ARN" {
|
||||
description = "Load-balancer certificate AWS ARN"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
# ap-southeast-1 and ap-southeast-2 does not contain the newer CentOS 1704 image
|
||||
variable "image" {
|
||||
description = "AWS image name"
|
||||
@ -34,7 +44,7 @@ variable "image" {
|
||||
|
||||
variable "instance_type" {
|
||||
description = "AWS instance type"
|
||||
default = "t2.medium"
|
||||
default = "t2.large"
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
@ -48,7 +58,9 @@ module "nodes" {
|
||||
instance_type = "${var.instance_type}"
|
||||
ssh_public_file = "${var.SSH_PUBLIC_FILE}"
|
||||
ssh_private_file = "${var.SSH_PRIVATE_FILE}"
|
||||
certificate_arn = "${var.CERTIFICATE_ARN}"
|
||||
SERVERS = "${var.SERVERS}"
|
||||
max_zones = "${var.MAX_ZONES}"
|
||||
}
|
||||
|
||||
output "public_ips" {
|
||||
|
||||
@ -7,13 +7,5 @@
|
||||
REGION="$(($2 + 1))"
|
||||
RNODE="$(($3 + 1))"
|
||||
ID="$((${REGION} * 100 + ${RNODE}))"
|
||||
echo "$ID" > /etc/gaiad-nodeid
|
||||
|
||||
#Create gaiad user
|
||||
useradd -m -s /bin/bash gaiad
|
||||
|
||||
#Reload services to enable the gaiad service (note that the gaiad binary is not available yet)
|
||||
systemctl daemon-reload
|
||||
systemctl enable gaiad
|
||||
|
||||
echo "$ID" > /etc/nodeid
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ variable "image" {
|
||||
|
||||
variable "instance_type" {
|
||||
description = "AWS instance type"
|
||||
default = "t2.medium"
|
||||
default = "t2.large"
|
||||
}
|
||||
|
||||
module "nodes-0" {
|
||||
|
||||
@ -79,7 +79,7 @@ resource "aws_instance" "node" {
|
||||
}
|
||||
|
||||
root_block_device {
|
||||
volume_size = 20
|
||||
volume_size = 40
|
||||
}
|
||||
|
||||
connection {
|
||||
@ -93,14 +93,8 @@ resource "aws_instance" "node" {
|
||||
destination = "/tmp/terraform.sh"
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
source = "files/gaiad.service"
|
||||
destination = "/tmp/gaiad.service"
|
||||
}
|
||||
|
||||
provisioner "remote-exec" {
|
||||
inline = [
|
||||
"sudo cp /tmp/gaiad.service /etc/systemd/system/gaiad.service",
|
||||
"chmod +x /tmp/terraform.sh",
|
||||
"sudo /tmp/terraform.sh ${var.name} ${var.multiplier} ${count.index}",
|
||||
]
|
||||
|
||||
@ -29,11 +29,6 @@ resource "digitalocean_droplet" "cluster" {
|
||||
destination = "/tmp/terraform.sh"
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
source = "files/gaiad.service"
|
||||
destination = "/etc/systemd/system/gaiad.service"
|
||||
}
|
||||
|
||||
provisioner "remote-exec" {
|
||||
inline = [
|
||||
"chmod +x /tmp/terraform.sh",
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
[Unit]
|
||||
Description=gaiad
|
||||
Requires=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Restart=on-failure
|
||||
User=gaiad
|
||||
Group=gaiad
|
||||
PermissionsStartOnly=true
|
||||
ExecStart=/usr/bin/gaiad start
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillSignal=SIGTERM
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@ -4,16 +4,5 @@
|
||||
#Usage: terraform.sh <testnet_name> <testnet_node_number>
|
||||
|
||||
#Add gaiad node number for remote identification
|
||||
echo "$2" > /etc/gaiad-nodeid
|
||||
|
||||
#Create gaiad user
|
||||
useradd -m -s /bin/bash gaiad
|
||||
#cp -r /root/.ssh /home/gaiad/.ssh
|
||||
#chown -R gaiad.gaiad /home/gaiad/.ssh
|
||||
#chmod -R 700 /home/gaiad/.ssh
|
||||
|
||||
#Reload services to enable the gaiad service (note that the gaiad binary is not available yet)
|
||||
systemctl daemon-reload
|
||||
systemctl enable gaiad
|
||||
|
||||
echo "$2" > /etc/nodeid
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user