Merge remote-tracking branch 'origin/develop' into rigel/validator-unbonding
This commit is contained in:
commit
c4d0a00550
|
@ -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
|
||||
|
|
|
@ -12,6 +12,7 @@ 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)
|
||||
|
||||
* Gaia
|
||||
* Make the transient store key use a distinct store key. [#2013](https://github.com/cosmos/cosmos-sdk/pull/2013)
|
||||
|
@ -36,11 +37,14 @@ 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
|
||||
* [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
|
||||
|
||||
* SDK
|
||||
* [querier] added custom querier functionality, so ABCI query requests can be handled by keepers
|
||||
* [simulation] \#1924 allow operations to specify future operations
|
||||
|
||||
* Tendermint
|
||||
|
||||
|
@ -63,6 +67,7 @@ IMPROVEMENTS
|
|||
* SDK
|
||||
* [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present.
|
||||
* [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
|
||||
|
@ -79,5 +84,7 @@ 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.
|
||||
|
||||
* 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)")
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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":[
|
||||
{
|
||||
|
@ -887,7 +906,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": [
|
||||
{
|
||||
|
@ -925,7 +943,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": [
|
||||
|
@ -964,7 +981,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": [],
|
||||
|
@ -1116,8 +1132,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 +1162,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 +1192,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())))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ package app
|
|||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
|
@ -87,7 +86,7 @@ func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json
|
|||
|
||||
func testAndRunTxs(app *GaiaApp) []simulation.Operation {
|
||||
return []simulation.Operation{
|
||||
banksim.TestAndRunSingleInputMsgSend(app.accountMapper),
|
||||
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
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -2,7 +2,7 @@ module.exports = {
|
|||
title: "Cosmos Network",
|
||||
description: "Documentation for the Cosmos Network.",
|
||||
dest: "./dist/docs",
|
||||
base: "/",
|
||||
base: "/docs/",
|
||||
markdown: {
|
||||
lineNumbers: true
|
||||
},
|
||||
|
|
|
@ -97,6 +97,12 @@ gaiacli send \
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -332,39 +332,42 @@ func (iter *iavlIterator) Domain() (start, end []byte) {
|
|||
func (iter *iavlIterator) Valid() bool {
|
||||
iter.waitInit()
|
||||
iter.mtx.Lock()
|
||||
defer iter.mtx.Unlock()
|
||||
|
||||
return !iter.invalid
|
||||
validity := !iter.invalid
|
||||
iter.mtx.Unlock()
|
||||
return validity
|
||||
}
|
||||
|
||||
// Implements Iterator.
|
||||
func (iter *iavlIterator) Next() {
|
||||
iter.waitInit()
|
||||
iter.mtx.Lock()
|
||||
defer iter.mtx.Unlock()
|
||||
iter.assertIsValid()
|
||||
iter.assertIsValid(true)
|
||||
|
||||
iter.receiveNext()
|
||||
iter.mtx.Unlock()
|
||||
}
|
||||
|
||||
// Implements Iterator.
|
||||
func (iter *iavlIterator) Key() []byte {
|
||||
iter.waitInit()
|
||||
iter.mtx.Lock()
|
||||
defer iter.mtx.Unlock()
|
||||
iter.assertIsValid()
|
||||
iter.assertIsValid(true)
|
||||
|
||||
return iter.key
|
||||
key := iter.key
|
||||
iter.mtx.Unlock()
|
||||
return key
|
||||
}
|
||||
|
||||
// Implements Iterator.
|
||||
func (iter *iavlIterator) Value() []byte {
|
||||
iter.waitInit()
|
||||
iter.mtx.Lock()
|
||||
defer iter.mtx.Unlock()
|
||||
iter.assertIsValid()
|
||||
iter.assertIsValid(true)
|
||||
|
||||
return iter.value
|
||||
val := iter.value
|
||||
iter.mtx.Unlock()
|
||||
return val
|
||||
}
|
||||
|
||||
// Implements Iterator.
|
||||
|
@ -375,14 +378,14 @@ func (iter *iavlIterator) Close() {
|
|||
//----------------------------------------
|
||||
|
||||
func (iter *iavlIterator) setNext(key, value []byte) {
|
||||
iter.assertIsValid()
|
||||
iter.assertIsValid(false)
|
||||
|
||||
iter.key = key
|
||||
iter.value = value
|
||||
}
|
||||
|
||||
func (iter *iavlIterator) setInvalid() {
|
||||
iter.assertIsValid()
|
||||
iter.assertIsValid(false)
|
||||
|
||||
iter.invalid = true
|
||||
}
|
||||
|
@ -400,8 +403,14 @@ func (iter *iavlIterator) receiveNext() {
|
|||
}
|
||||
}
|
||||
|
||||
func (iter *iavlIterator) assertIsValid() {
|
||||
// assertIsValid panics if the iterator is invalid. If unlockMutex is true,
|
||||
// it also unlocks the mutex before panicing, to prevent deadlocks in code that
|
||||
// recovers from panics
|
||||
func (iter *iavlIterator) assertIsValid(unlockMutex bool) {
|
||||
if iter.invalid {
|
||||
if unlockMutex {
|
||||
iter.mtx.Unlock()
|
||||
}
|
||||
panic("invalid iterator")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -464,3 +464,26 @@ func TestIAVLStoreQuery(t *testing.T) {
|
|||
require.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
require.Equal(t, v1, qres.Value)
|
||||
}
|
||||
|
||||
func BenchmarkIAVLIteratorNext(b *testing.B) {
|
||||
db := dbm.NewMemDB()
|
||||
treeSize := 1000
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
for i := 0; i < treeSize; i++ {
|
||||
key := cmn.RandBytes(4)
|
||||
value := cmn.RandBytes(50)
|
||||
tree.Set(key, value)
|
||||
}
|
||||
iavlStore := newIAVLStore(tree, numRecent, storeEvery)
|
||||
iterators := make([]Iterator, b.N/treeSize)
|
||||
for i := 0; i < len(iterators); i++ {
|
||||
iterators[i] = iavlStore.Iterator([]byte{0}, []byte{255, 255, 255, 255, 255})
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < len(iterators); i++ {
|
||||
iter := iterators[i]
|
||||
for j := 0; j < treeSize; j++ {
|
||||
iter.Next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,4 +5,4 @@ type Handler func(ctx Context, msg Msg) Result
|
|||
|
||||
// AnteHandler authenticates transactions, before their internal messages are handled.
|
||||
// If newCtx.IsZero(), ctx is used instead.
|
||||
type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool)
|
||||
type AnteHandler func(ctx Context, tx Tx, simulate bool) (newCtx Context, result Result, abort bool)
|
||||
|
|
|
@ -25,7 +25,7 @@ const (
|
|||
func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler {
|
||||
|
||||
return func(
|
||||
ctx sdk.Context, tx sdk.Tx,
|
||||
ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||
) (newCtx sdk.Context, res sdk.Result, abort bool) {
|
||||
|
||||
// This AnteHandler requires Txs to be StdTxs
|
||||
|
@ -35,7 +35,11 @@ func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler {
|
|||
}
|
||||
|
||||
// set the gas meter
|
||||
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(stdTx.Fee.Gas))
|
||||
if simulate {
|
||||
newCtx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||
} else {
|
||||
newCtx = ctx.WithGasMeter(sdk.NewGasMeter(stdTx.Fee.Gas))
|
||||
}
|
||||
|
||||
// AnteHandlers must have their own defer/recover in order
|
||||
// for the BaseApp to know how much gas was used!
|
||||
|
|
|
@ -39,16 +39,16 @@ func privAndAddr() (crypto.PrivKey, sdk.AccAddress) {
|
|||
}
|
||||
|
||||
// run the tx through the anteHandler and ensure its valid
|
||||
func checkValidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx) {
|
||||
_, result, abort := anteHandler(ctx, tx)
|
||||
func checkValidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, simulate bool) {
|
||||
_, result, abort := anteHandler(ctx, tx, simulate)
|
||||
require.False(t, abort)
|
||||
require.Equal(t, sdk.ABCICodeOK, result.Code)
|
||||
require.True(t, result.IsOK())
|
||||
}
|
||||
|
||||
// run the tx through the anteHandler and ensure it fails with the given code
|
||||
func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, code sdk.CodeType) {
|
||||
newCtx, result, abort := anteHandler(ctx, tx)
|
||||
func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, simulate bool, code sdk.CodeType) {
|
||||
newCtx, result, abort := anteHandler(ctx, tx, simulate)
|
||||
require.True(t, abort)
|
||||
require.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, code), result.Code,
|
||||
fmt.Sprintf("Expected %v, got %v", sdk.ToABCICode(sdk.CodespaceRoot, code), result))
|
||||
|
@ -140,23 +140,23 @@ func TestAnteHandlerSigErrors(t *testing.T) {
|
|||
require.Equal(t, expectedSigners, stdTx.GetSigners())
|
||||
|
||||
// Check no signatures fails
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnauthorized)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized)
|
||||
|
||||
// test num sigs dont match GetSigners
|
||||
privs, accNums, seqs = []crypto.PrivKey{priv1}, []int64{0}, []int64{0}
|
||||
tx = newTestTx(ctx, msgs, privs, accNums, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnauthorized)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized)
|
||||
|
||||
// test an unrecognized account
|
||||
privs, accNums, seqs = []crypto.PrivKey{priv1, priv2, priv3}, []int64{0, 1, 2}, []int64{0, 0, 0}
|
||||
tx = newTestTx(ctx, msgs, privs, accNums, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnknownAddress)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnknownAddress)
|
||||
|
||||
// save the first account, but second is still unrecognized
|
||||
acc1 := mapper.NewAccountWithAddress(ctx, addr1)
|
||||
acc1.SetCoins(fee.Amount)
|
||||
mapper.SetAccount(ctx, acc1)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnknownAddress)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnknownAddress)
|
||||
}
|
||||
|
||||
// Test logic around account number checking with one signer and many signers.
|
||||
|
@ -192,17 +192,17 @@ func TestAnteHandlerAccountNumbers(t *testing.T) {
|
|||
// test good tx from one signer
|
||||
privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
// new tx from wrong account number
|
||||
seqs = []int64{1}
|
||||
tx = newTestTx(ctx, msgs, privs, []int64{1}, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidSequence)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidSequence)
|
||||
|
||||
// from correct account number
|
||||
seqs = []int64{1}
|
||||
tx = newTestTx(ctx, msgs, privs, []int64{0}, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
// new tx with another signer and incorrect account numbers
|
||||
msg1 := newTestMsg(addr1, addr2)
|
||||
|
@ -210,12 +210,12 @@ func TestAnteHandlerAccountNumbers(t *testing.T) {
|
|||
msgs = []sdk.Msg{msg1, msg2}
|
||||
privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{1, 0}, []int64{2, 0}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidSequence)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidSequence)
|
||||
|
||||
// correct account numbers
|
||||
privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{2, 0}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
}
|
||||
|
||||
// Test logic around sequence checking with one signer and many signers.
|
||||
|
@ -255,15 +255,15 @@ func TestAnteHandlerSequences(t *testing.T) {
|
|||
// test good tx from one signer
|
||||
privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
// test sending it again fails (replay protection)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidSequence)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidSequence)
|
||||
|
||||
// fix sequence, should pass
|
||||
seqs = []int64{1}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
// new tx with another signer and correct sequences
|
||||
msg1 := newTestMsg(addr1, addr2)
|
||||
|
@ -272,28 +272,28 @@ func TestAnteHandlerSequences(t *testing.T) {
|
|||
|
||||
privs, accnums, seqs = []crypto.PrivKey{priv1, priv2, priv3}, []int64{0, 1, 2}, []int64{2, 0, 0}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
// replay fails
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidSequence)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidSequence)
|
||||
|
||||
// tx from just second signer with incorrect sequence fails
|
||||
msg = newTestMsg(addr2)
|
||||
msgs = []sdk.Msg{msg}
|
||||
privs, accnums, seqs = []crypto.PrivKey{priv2}, []int64{1}, []int64{0}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidSequence)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidSequence)
|
||||
|
||||
// fix the sequence and it passes
|
||||
tx = newTestTx(ctx, msgs, []crypto.PrivKey{priv2}, []int64{1}, []int64{1}, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
// another tx from both of them that passes
|
||||
msg = newTestMsg(addr1, addr2)
|
||||
msgs = []sdk.Msg{msg}
|
||||
privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{3, 2}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
}
|
||||
|
||||
// Test logic around fee deduction.
|
||||
|
@ -323,17 +323,17 @@ func TestAnteHandlerFees(t *testing.T) {
|
|||
|
||||
// signer does not have enough funds to pay the fee
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInsufficientFunds)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInsufficientFunds)
|
||||
|
||||
acc1.SetCoins(sdk.Coins{sdk.NewInt64Coin("atom", 149)})
|
||||
mapper.SetAccount(ctx, acc1)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInsufficientFunds)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInsufficientFunds)
|
||||
|
||||
require.True(t, feeCollector.GetCollectedFees(ctx).IsEqual(emptyCoins))
|
||||
|
||||
acc1.SetCoins(sdk.Coins{sdk.NewInt64Coin("atom", 150)})
|
||||
mapper.SetAccount(ctx, acc1)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
require.True(t, feeCollector.GetCollectedFees(ctx).IsEqual(sdk.Coins{sdk.NewInt64Coin("atom", 150)}))
|
||||
}
|
||||
|
@ -364,22 +364,22 @@ func TestAnteHandlerMemoGas(t *testing.T) {
|
|||
|
||||
// tx does not have enough gas
|
||||
tx = newTestTx(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeOutOfGas)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeOutOfGas)
|
||||
|
||||
// tx with memo doesn't have enough gas
|
||||
fee = NewStdFee(801, sdk.NewInt64Coin("atom", 0))
|
||||
tx = newTestTxWithMemo(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee, "abcininasidniandsinasindiansdiansdinaisndiasndiadninsd")
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeOutOfGas)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeOutOfGas)
|
||||
|
||||
// memo too large
|
||||
fee = NewStdFee(2001, sdk.NewInt64Coin("atom", 0))
|
||||
tx = newTestTxWithMemo(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee, "abcininasidniandsinasindiansdiansdinaisndiasndiadninsdabcininasidniandsinasindiansdiansdinaisndiasndiadninsdabcininasidniandsinasindiansdiansdinaisndiasndiadninsd")
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeMemoTooLarge)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeMemoTooLarge)
|
||||
|
||||
// tx with memo has enough gas
|
||||
fee = NewStdFee(1100, sdk.NewInt64Coin("atom", 0))
|
||||
tx = newTestTxWithMemo(ctx, []sdk.Msg{msg}, privs, accnums, seqs, fee, "abcininasidniandsinasindiansdiansdinaisndiasndiadninsd")
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
}
|
||||
|
||||
func TestAnteHandlerMultiSigner(t *testing.T) {
|
||||
|
@ -420,17 +420,17 @@ func TestAnteHandlerMultiSigner(t *testing.T) {
|
|||
privs, accnums, seqs := []crypto.PrivKey{priv1, priv2, priv3}, []int64{0, 1, 2}, []int64{0, 0, 0}
|
||||
tx = newTestTxWithMemo(ctx, msgs, privs, accnums, seqs, fee, "Check signers are in expected order and different account numbers works")
|
||||
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
// change sequence numbers
|
||||
tx = newTestTx(ctx, []sdk.Msg{msg1}, []crypto.PrivKey{priv1, priv2}, []int64{0, 1}, []int64{1, 1}, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
tx = newTestTx(ctx, []sdk.Msg{msg2}, []crypto.PrivKey{priv3, priv1}, []int64{2, 0}, []int64{1, 2}, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
// expected seqs = [3, 2, 2]
|
||||
tx = newTestTxWithMemo(ctx, msgs, privs, accnums, []int64{3, 2, 2}, fee, "Check signers are in expected order and different account numbers and sequence numbers works")
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
}
|
||||
|
||||
func TestAnteHandlerBadSignBytes(t *testing.T) {
|
||||
|
@ -467,7 +467,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) {
|
|||
// test good tx and signBytes
|
||||
privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
chainID := ctx.ChainID()
|
||||
chainID2 := chainID + "somemorestuff"
|
||||
|
@ -497,20 +497,20 @@ func TestAnteHandlerBadSignBytes(t *testing.T) {
|
|||
StdSignBytes(cs.chainID, cs.accnum, cs.seq, cs.fee, cs.msgs, ""),
|
||||
"",
|
||||
)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, cs.code)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, cs.code)
|
||||
}
|
||||
|
||||
// test wrong signer if public key exist
|
||||
privs, accnums, seqs = []crypto.PrivKey{priv2}, []int64{0}, []int64{1}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeUnauthorized)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeUnauthorized)
|
||||
|
||||
// test wrong signer if public doesn't exist
|
||||
msg = newTestMsg(addr2)
|
||||
msgs = []sdk.Msg{msg}
|
||||
privs, accnums, seqs = []crypto.PrivKey{priv1}, []int64{1}, []int64{0}
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey)
|
||||
|
||||
}
|
||||
|
||||
|
@ -544,7 +544,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) {
|
|||
privs, accnums, seqs := []crypto.PrivKey{priv1}, []int64{0}, []int64{0}
|
||||
fee := newStdFee()
|
||||
tx = newTestTx(ctx, msgs, privs, accnums, seqs, fee)
|
||||
checkValidTx(t, anteHandler, ctx, tx)
|
||||
checkValidTx(t, anteHandler, ctx, tx, false)
|
||||
|
||||
acc1 = mapper.GetAccount(ctx, addr1)
|
||||
require.Equal(t, acc1.GetPubKey(), priv1.PubKey())
|
||||
|
@ -555,14 +555,14 @@ func TestAnteHandlerSetPubKey(t *testing.T) {
|
|||
tx = newTestTx(ctx, msgs, privs, []int64{1}, seqs, fee)
|
||||
sigs := tx.(StdTx).GetSignatures()
|
||||
sigs[0].PubKey = nil
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey)
|
||||
|
||||
acc2 = mapper.GetAccount(ctx, addr2)
|
||||
require.Nil(t, acc2.GetPubKey())
|
||||
|
||||
// test invalid signature and public key
|
||||
tx = newTestTx(ctx, msgs, privs, []int64{1}, seqs, fee)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey)
|
||||
checkInvalidTx(t, anteHandler, ctx, tx, false, sdk.CodeInvalidPubKey)
|
||||
|
||||
acc2 = mapper.GetAccount(ctx, addr2)
|
||||
require.Nil(t, acc2.GetPubKey())
|
||||
|
|
|
@ -110,9 +110,7 @@ func (ctx TxContext) Build(msgs []sdk.Msg) (auth.StdSignMsg, error) {
|
|||
Sequence: ctx.Sequence,
|
||||
Memo: ctx.Memo,
|
||||
Msgs: msgs,
|
||||
|
||||
// TODO: run simulate to estimate gas?
|
||||
Fee: auth.NewStdFee(ctx.Gas, fee),
|
||||
Fee: auth.NewStdFee(ctx.Gas, fee),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
|
@ -32,15 +33,13 @@ func QueryAccountRequestHandlerFn(
|
|||
|
||||
addr, err := sdk.AccAddressFromBech32(bech32addr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryStore(auth.AddressStoreKey(addr), storeName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("couldn't query account. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("couldn't query account. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -53,16 +52,14 @@ func QueryAccountRequestHandlerFn(
|
|||
// decode the value
|
||||
account, err := decoder(res)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("couldn't parse query result. Result: %s. Error: %s", res, err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("couldn't parse query result. Result: %s. Error: %s", res, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// print out whole account
|
||||
output, err := cdc.MarshalJSON(account)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("couldn't marshall query result. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("couldn't marshall query result. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
|
@ -47,37 +48,32 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLICo
|
|||
|
||||
to, err := sdk.AccAddressFromBech32(bech32addr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var m sendBody
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = msgCdc.UnmarshalJSON(body, &m)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
info, err := kb.Get(m.LocalAccountName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// build message
|
||||
msg := client.BuildMsg(sdk.AccAddress(info.GetPubKey().Address()), to, m.Amount)
|
||||
if err != nil { // XXX rechecking same error ?
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -89,24 +85,30 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLICo
|
|||
Sequence: m.Sequence,
|
||||
}
|
||||
|
||||
if m.Gas == 0 {
|
||||
newCtx, err := utils.EnrichCtxWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
output, err := wire.MarshalJSONIndent(cdc, res)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ import (
|
|||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
// TestAndRunSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both
|
||||
// SimulateSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both
|
||||
// accounts already exist.
|
||||
func TestAndRunSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
|
||||
fromKey := simulation.RandomKey(r, keys)
|
||||
fromAddr := sdk.AccAddress(fromKey.PubKey().Address())
|
||||
toKey := simulation.RandomKey(r, keys)
|
||||
|
@ -36,13 +36,13 @@ func TestAndRunSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operatio
|
|||
initFromCoins := mapper.GetAccount(ctx, fromAddr).GetCoins()
|
||||
|
||||
if len(initFromCoins) == 0 {
|
||||
return "skipping, no coins at all", nil
|
||||
return "skipping, no coins at all", nil, nil
|
||||
}
|
||||
|
||||
denomIndex := r.Intn(len(initFromCoins))
|
||||
amt, goErr := randPositiveInt(r, initFromCoins[denomIndex].Amount)
|
||||
if goErr != nil {
|
||||
return "skipping bank send due to account having no coins of denomination " + initFromCoins[denomIndex].Denom, nil
|
||||
return "skipping bank send due to account having no coins of denomination " + initFromCoins[denomIndex].Denom, nil, nil
|
||||
}
|
||||
|
||||
action = fmt.Sprintf("%s is sending %s %s to %s",
|
||||
|
@ -61,7 +61,7 @@ func TestAndRunSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operatio
|
|||
sendAndVerifyMsgSend(t, app, mapper, msg, ctx, log, []crypto.PrivKey{fromKey})
|
||||
event("bank/sendAndVerifyMsgSend/ok")
|
||||
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ func TestBankWithRandomMessages(t *testing.T) {
|
|||
simulation.Simulate(
|
||||
t, mapp.BaseApp, appStateFn,
|
||||
[]simulation.Operation{
|
||||
TestAndRunSingleInputMsgSend(mapper),
|
||||
SimulateSingleInputMsgSend(mapper),
|
||||
},
|
||||
[]simulation.RandSetup{},
|
||||
[]simulation.Invariant{
|
||||
|
|
|
@ -13,11 +13,11 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
|
||||
"encoding/json"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -244,7 +244,7 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command {
|
|||
}
|
||||
|
||||
// GetCmdQueryProposal implements the query proposal command.
|
||||
func GetCmdQueryProposal(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
func GetCmdQueryProposal(queryRoute string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-proposal",
|
||||
Short: "query proposal details",
|
||||
|
@ -252,20 +252,21 @@ func GetCmdQueryProposal(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
proposalID := viper.GetInt64(flagProposalID)
|
||||
|
||||
res, err := cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName)
|
||||
if len(res) == 0 || err != nil {
|
||||
return errors.Errorf("proposalID [%d] is not existed", proposalID)
|
||||
params := gov.QueryProposalParams{
|
||||
ProposalID: proposalID,
|
||||
}
|
||||
|
||||
var proposal gov.Proposal
|
||||
cdc.MustUnmarshalBinary(res, &proposal)
|
||||
|
||||
output, err := wire.MarshalJSONIndent(cdc, proposal)
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(output))
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/proposal", queryRoute), bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(res))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -277,7 +278,7 @@ func GetCmdQueryProposal(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
|
||||
// nolint: gocyclo
|
||||
// GetCmdQueryProposals implements a query proposals command.
|
||||
func GetCmdQueryProposals(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
func GetCmdQueryProposals(queryRoute string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-proposals",
|
||||
Short: "query proposals with optional filters",
|
||||
|
@ -287,77 +288,50 @@ func GetCmdQueryProposals(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
strProposalStatus := viper.GetString(flagStatus)
|
||||
latestProposalsIDs := viper.GetInt64(flagLatestProposalIDs)
|
||||
|
||||
var err error
|
||||
var voterAddr sdk.AccAddress
|
||||
var depositerAddr sdk.AccAddress
|
||||
var proposalStatus gov.ProposalStatus
|
||||
params := gov.QueryProposalsParams{
|
||||
NumLatestProposals: latestProposalsIDs,
|
||||
}
|
||||
|
||||
if len(bechDepositerAddr) != 0 {
|
||||
depositerAddr, err = sdk.AccAddressFromBech32(bechDepositerAddr)
|
||||
depositerAddr, err := sdk.AccAddressFromBech32(bechDepositerAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params.Depositer = depositerAddr
|
||||
}
|
||||
|
||||
if len(bechVoterAddr) != 0 {
|
||||
voterAddr, err = sdk.AccAddressFromBech32(bechVoterAddr)
|
||||
voterAddr, err := sdk.AccAddressFromBech32(bechVoterAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params.Voter = voterAddr
|
||||
}
|
||||
|
||||
if len(strProposalStatus) != 0 {
|
||||
proposalStatus, err = gov.ProposalStatusFromString(strProposalStatus)
|
||||
proposalStatus, err := gov.ProposalStatusFromString(strProposalStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params.ProposalStatus = proposalStatus
|
||||
}
|
||||
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
res, err := cliCtx.QueryStore(gov.KeyNextProposalID, storeName)
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/proposals", queryRoute), bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var maxProposalID int64
|
||||
cdc.MustUnmarshalBinary(res, &maxProposalID)
|
||||
|
||||
matchingProposals := []gov.Proposal{}
|
||||
|
||||
if latestProposalsIDs == 0 {
|
||||
latestProposalsIDs = maxProposalID
|
||||
}
|
||||
|
||||
for proposalID := maxProposalID - latestProposalsIDs; proposalID < maxProposalID; proposalID++ {
|
||||
if voterAddr != nil {
|
||||
res, err = cliCtx.QueryStore(gov.KeyVote(proposalID, voterAddr), storeName)
|
||||
if err != nil || len(res) == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if depositerAddr != nil {
|
||||
res, err = cliCtx.QueryStore(gov.KeyDeposit(proposalID, depositerAddr), storeName)
|
||||
if err != nil || len(res) == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
res, err = cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName)
|
||||
if err != nil || len(res) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
var proposal gov.Proposal
|
||||
cdc.MustUnmarshalBinary(res, &proposal)
|
||||
|
||||
if len(strProposalStatus) != 0 {
|
||||
if proposal.GetStatus() != proposalStatus {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
matchingProposals = append(matchingProposals, proposal)
|
||||
var matchingProposals []gov.Proposal
|
||||
err = cdc.UnmarshalJSON(res, &matchingProposals)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(matchingProposals) == 0 {
|
||||
|
@ -383,7 +357,7 @@ func GetCmdQueryProposals(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
|
||||
// Command to Get a Proposal Information
|
||||
// GetCmdQueryVote implements the query proposal vote command.
|
||||
func GetCmdQueryVote(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
func GetCmdQueryVote(queryRoute string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-vote",
|
||||
Short: "query vote",
|
||||
|
@ -396,20 +370,21 @@ func GetCmdQueryVote(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryStore(gov.KeyVote(proposalID, voterAddr), storeName)
|
||||
if len(res) == 0 || err != nil {
|
||||
return errors.Errorf("proposalID [%d] does not exist", proposalID)
|
||||
params := gov.QueryVoteParams{
|
||||
Voter: voterAddr,
|
||||
ProposalID: proposalID,
|
||||
}
|
||||
|
||||
var vote gov.Vote
|
||||
cdc.MustUnmarshalBinary(res, &vote)
|
||||
|
||||
output, err := wire.MarshalJSONIndent(cdc, vote)
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(output))
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/vote", queryRoute), bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(res))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -421,7 +396,7 @@ func GetCmdQueryVote(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
}
|
||||
|
||||
// GetCmdQueryVotes implements the command to query for proposal votes.
|
||||
func GetCmdQueryVotes(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
func GetCmdQueryVotes(queryRoute string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-votes",
|
||||
Short: "query votes on a proposal",
|
||||
|
@ -429,37 +404,20 @@ func GetCmdQueryVotes(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
proposalID := viper.GetInt64(flagProposalID)
|
||||
|
||||
res, err := cliCtx.QueryStore(gov.KeyProposal(proposalID), storeName)
|
||||
if len(res) == 0 || err != nil {
|
||||
return errors.Errorf("proposalID [%d] does not exist", proposalID)
|
||||
params := gov.QueryVotesParams{
|
||||
ProposalID: proposalID,
|
||||
}
|
||||
|
||||
var proposal gov.Proposal
|
||||
cdc.MustUnmarshalBinary(res, &proposal)
|
||||
|
||||
if proposal.GetStatus() != gov.StatusVotingPeriod {
|
||||
fmt.Println("Proposal not in voting period.")
|
||||
return nil
|
||||
}
|
||||
|
||||
res2, err := cliCtx.QuerySubspace(gov.KeyVotesSubspace(proposalID), storeName)
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var votes []gov.Vote
|
||||
for i := 0; i < len(res2); i++ {
|
||||
var vote gov.Vote
|
||||
cdc.MustUnmarshalBinary(res2[i].Value, &vote)
|
||||
votes = append(votes, vote)
|
||||
}
|
||||
|
||||
output, err := wire.MarshalJSONIndent(cdc, votes)
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/votes", queryRoute), bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(output))
|
||||
fmt.Println(string(res))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -468,3 +426,107 @@ func GetCmdQueryVotes(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Command to Get a specific Deposit Information
|
||||
// GetCmdQueryDeposit implements the query proposal deposit command.
|
||||
func GetCmdQueryDeposit(queryRoute string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-deposit",
|
||||
Short: "query deposit",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
proposalID := viper.GetInt64(flagProposalID)
|
||||
|
||||
depositerAddr, err := sdk.AccAddressFromBech32(viper.GetString(flagDepositer))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params := gov.QueryDepositParams{
|
||||
Depositer: depositerAddr,
|
||||
ProposalID: proposalID,
|
||||
}
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/deposit", queryRoute), bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(res))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String(flagProposalID, "", "proposalID of proposal deposited on")
|
||||
cmd.Flags().String(flagDepositer, "", "bech32 depositer address")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdQueryDeposits implements the command to query for proposal deposits.
|
||||
func GetCmdQueryDeposits(queryRoute string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-deposits",
|
||||
Short: "query deposits on a proposal",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
proposalID := viper.GetInt64(flagProposalID)
|
||||
|
||||
params := gov.QueryDepositsParams{
|
||||
ProposalID: proposalID,
|
||||
}
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/deposits", queryRoute), bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(res))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String(flagProposalID, "", "proposalID of which proposal's deposits are being queried")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdQueryDeposits implements the command to query for proposal deposits.
|
||||
func GetCmdQueryTally(queryRoute string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-tally",
|
||||
Short: "get the tally of a proposal vote",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
proposalID := viper.GetInt64(flagProposalID)
|
||||
|
||||
params := gov.QueryTallyParams{
|
||||
ProposalID: proposalID,
|
||||
}
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/tally", queryRoute), bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(res))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String(flagProposalID, "", "proposalID of which proposal is being tallied")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
|
@ -76,7 +77,7 @@ func postProposalHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.Hand
|
|||
msg := gov.NewMsgSubmitProposal(req.Title, req.Description, req.ProposalType, req.Proposer, req.InitialDeposit)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
writeErr(&w, http.StatusBadRequest, err.Error())
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -90,10 +91,8 @@ func depositHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.HandlerFu
|
|||
strProposalID := vars[RestProposalID]
|
||||
|
||||
if len(strProposalID) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("proposalId required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -115,7 +114,7 @@ func depositHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.HandlerFu
|
|||
msg := gov.NewMsgDeposit(req.Depositer, proposalID, req.Amount)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
writeErr(&w, http.StatusBadRequest, err.Error())
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -129,10 +128,8 @@ func voteHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.HandlerFunc
|
|||
strProposalID := vars[RestProposalID]
|
||||
|
||||
if len(strProposalID) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("proposalId required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -154,7 +151,7 @@ func voteHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.HandlerFunc
|
|||
msg := gov.NewMsgVote(req.Voter, proposalID, req.Option)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
writeErr(&w, http.StatusBadRequest, err.Error())
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -168,10 +165,8 @@ func queryProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
strProposalID := vars[RestProposalID]
|
||||
|
||||
if len(strProposalID) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("proposalId required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -188,16 +183,13 @@ func queryProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryWithData("custom/gov/proposal", bz)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -212,10 +204,8 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
bechDepositerAddr := vars[RestDepositer]
|
||||
|
||||
if len(strProposalID) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("proposalId required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -225,19 +215,15 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
}
|
||||
|
||||
if len(bechDepositerAddr) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("depositer address required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
depositerAddr, err := sdk.AccAddressFromBech32(bechDepositerAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.Errorf("'%s' needs to be bech32 encoded", RestDepositer)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -250,16 +236,13 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryWithData("custom/gov/deposit", bz)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -268,14 +251,12 @@ func queryDepositHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
if deposit.Empty() {
|
||||
res, err := cliCtx.QueryWithData("custom/gov/proposal", cdc.MustMarshalBinary(gov.QueryProposalParams{params.ProposalID}))
|
||||
if err != nil || len(res) == 0 {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
err = errors.Errorf("depositer [%s] did not deposit on proposalID [%d]", bechDepositerAddr, proposalID)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -290,9 +271,8 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
bechVoterAddr := vars[RestVoter]
|
||||
|
||||
if len(strProposalID) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("proposalId required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -302,18 +282,15 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
}
|
||||
|
||||
if len(bechVoterAddr) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("voter address required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
voterAddr, err := sdk.AccAddressFromBech32(bechVoterAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.Errorf("'%s' needs to be bech32 encoded", RestVoter)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -325,16 +302,13 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
}
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryWithData("custom/gov/vote", bz)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -343,20 +317,17 @@ func queryVoteHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
if vote.Empty() {
|
||||
bz, err := cdc.MarshalJSON(gov.QueryProposalParams{params.ProposalID})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
res, err := cliCtx.QueryWithData("custom/gov/proposal", bz)
|
||||
if err != nil || len(res) == 0 {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
err = errors.Errorf("voter [%s] did not deposit on proposalID [%d]", bechVoterAddr, proposalID)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
w.Write(res)
|
||||
|
@ -371,10 +342,8 @@ func queryVotesOnProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
strProposalID := vars[RestProposalID]
|
||||
|
||||
if len(strProposalID) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("proposalId required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -390,15 +359,13 @@ func queryVotesOnProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
}
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryWithData("custom/gov/votes", bz)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -420,9 +387,8 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
if len(bechVoterAddr) != 0 {
|
||||
voterAddr, err := sdk.AccAddressFromBech32(bechVoterAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.Errorf("'%s' needs to be bech32 encoded", RestVoter)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
params.Voter = voterAddr
|
||||
|
@ -431,10 +397,8 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
if len(bechDepositerAddr) != 0 {
|
||||
depositerAddr, err := sdk.AccAddressFromBech32(bechDepositerAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.Errorf("'%s' needs to be bech32 encoded", RestDepositer)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
params.Depositer = depositerAddr
|
||||
|
@ -443,10 +407,8 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
if len(strProposalStatus) != 0 {
|
||||
proposalStatus, err := gov.ProposalStatusFromString(strProposalStatus)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.Errorf("'%s' is not a valid Proposal Status", strProposalStatus)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
params.ProposalStatus = proposalStatus
|
||||
|
@ -461,8 +423,7 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -470,9 +431,50 @@ func queryProposalsWithParameterFn(cdc *wire.Codec) http.HandlerFunc {
|
|||
|
||||
res, err := cliCtx.QueryWithData("custom/gov/proposals", bz)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(res)
|
||||
}
|
||||
}
|
||||
|
||||
// nolint: gocyclo
|
||||
// todo: Split this functionality into helper functions to remove the above
|
||||
func queryTallyOnProposalHandlerFn(cdc *wire.Codec) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
strProposalID := vars[RestProposalID]
|
||||
|
||||
if len(strProposalID) == 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err := errors.New("proposalId required but not specified")
|
||||
w.Write([]byte(err.Error()))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
proposalID, ok := parseInt64OrReturnBadRequest(strProposalID, w)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
params := gov.QueryTallyParams{
|
||||
ProposalID: proposalID,
|
||||
}
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryWithData("custom/gov/tally", bz)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,10 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type baseReq struct {
|
||||
|
@ -26,12 +25,12 @@ type baseReq struct {
|
|||
func buildReq(w http.ResponseWriter, r *http.Request, cdc *wire.Codec, req interface{}) error {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
writeErr(&w, http.StatusBadRequest, err.Error())
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return err
|
||||
}
|
||||
err = cdc.UnmarshalJSON(body, req)
|
||||
if err != nil {
|
||||
writeErr(&w, http.StatusBadRequest, err.Error())
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -39,41 +38,36 @@ func buildReq(w http.ResponseWriter, r *http.Request, cdc *wire.Codec, req inter
|
|||
|
||||
func (req baseReq) baseReqValidate(w http.ResponseWriter) bool {
|
||||
if len(req.Name) == 0 {
|
||||
writeErr(&w, http.StatusUnauthorized, "Name required but not specified")
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Name required but not specified")
|
||||
return false
|
||||
}
|
||||
|
||||
if len(req.Password) == 0 {
|
||||
writeErr(&w, http.StatusUnauthorized, "Password required but not specified")
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Password required but not specified")
|
||||
return false
|
||||
}
|
||||
|
||||
if len(req.ChainID) == 0 {
|
||||
writeErr(&w, http.StatusUnauthorized, "ChainID required but not specified")
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "ChainID required but not specified")
|
||||
return false
|
||||
}
|
||||
|
||||
if req.AccountNumber < 0 {
|
||||
writeErr(&w, http.StatusUnauthorized, "Account Number required but not specified")
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Account Number required but not specified")
|
||||
return false
|
||||
}
|
||||
|
||||
if req.Sequence < 0 {
|
||||
writeErr(&w, http.StatusUnauthorized, "Sequence required but not specified")
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Sequence required but not specified")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func writeErr(w *http.ResponseWriter, status int, msg string) {
|
||||
(*w).WriteHeader(status)
|
||||
err := errors.New(msg)
|
||||
(*w).Write([]byte(err.Error()))
|
||||
}
|
||||
|
||||
// TODO: Build this function out into a more generic base-request
|
||||
// (probably should live in client/lcd).
|
||||
func signAndBuild(w http.ResponseWriter, cliCtx context.CLIContext, baseReq baseReq, msg sdk.Msg, cdc *wire.Codec) {
|
||||
var err error
|
||||
txCtx := authctx.TxContext{
|
||||
Codec: cdc,
|
||||
AccountNumber: baseReq.AccountNumber,
|
||||
|
@ -82,21 +76,29 @@ func signAndBuild(w http.ResponseWriter, cliCtx context.CLIContext, baseReq base
|
|||
Gas: baseReq.Gas,
|
||||
}
|
||||
|
||||
if baseReq.Gas == 0 {
|
||||
newCtx, err := utils.EnrichCtxWithGas(txCtx, cliCtx, baseReq.Name, baseReq.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
txCtx = newCtx
|
||||
}
|
||||
txBytes, err := txCtx.BuildAndSign(baseReq.Name, baseReq.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
writeErr(&w, http.StatusUnauthorized, err.Error())
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
writeErr(&w, http.StatusInternalServerError, err.Error())
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
output, err := wire.MarshalJSONIndent(cdc, res)
|
||||
if err != nil {
|
||||
writeErr(&w, http.StatusInternalServerError, err.Error())
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,10 @@ const (
|
|||
denom = "steak"
|
||||
)
|
||||
|
||||
// SimulateMsgSubmitProposal
|
||||
// SimulateMsgSubmitProposal simulates a msg Submit Proposal
|
||||
// Note: Currently doesn't ensure that the proposal txt is in JSON form
|
||||
func SimulateMsgSubmitProposal(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOps []simulation.FutureOperation, err sdk.Error) {
|
||||
key := simulation.RandomKey(r, keys)
|
||||
addr := sdk.AccAddress(key.PubKey().Address())
|
||||
deposit := randomDeposit(r)
|
||||
|
@ -45,18 +46,18 @@ func SimulateMsgSubmitProposal(k gov.Keeper, sk stake.Keeper) simulation.Operati
|
|||
}
|
||||
event(fmt.Sprintf("gov/MsgSubmitProposal/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgSubmitProposal: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgDeposit
|
||||
func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
key := simulation.RandomKey(r, keys)
|
||||
addr := sdk.AccAddress(key.PubKey().Address())
|
||||
proposalID, ok := randomProposalID(r, k, ctx)
|
||||
if !ok {
|
||||
return "no-operation", nil
|
||||
return "no-operation", nil, nil
|
||||
}
|
||||
deposit := randomDeposit(r)
|
||||
msg := gov.NewMsgDeposit(addr, proposalID, deposit)
|
||||
|
@ -72,18 +73,18 @@ func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
|||
}
|
||||
event(fmt.Sprintf("gov/MsgDeposit/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgDeposit: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgVote
|
||||
func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
key := simulation.RandomKey(r, keys)
|
||||
addr := sdk.AccAddress(key.PubKey().Address())
|
||||
proposalID, ok := randomProposalID(r, k, ctx)
|
||||
if !ok {
|
||||
return "no-operation", nil
|
||||
return "no-operation", nil, nil
|
||||
}
|
||||
option := randomVotingOption(r)
|
||||
msg := gov.NewMsgVote(addr, proposalID, option)
|
||||
|
@ -95,7 +96,7 @@ func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
|||
}
|
||||
event(fmt.Sprintf("gov/MsgVote/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgVote: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
|
@ -40,30 +41,26 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
|
|||
|
||||
to, err := sdk.AccAddressFromBech32(bech32addr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var m transferBody
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err = cdc.UnmarshalJSON(body, &m)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
info, err := kb.Get(m.LocalAccountName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -79,24 +76,30 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
|
|||
Gas: m.Gas,
|
||||
}
|
||||
|
||||
if m.Gas == 0 {
|
||||
newCtx, err := utils.EnrichCtxWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
output, err := cdc.MarshalJSON(res)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ func SimulateFromSeed(
|
|||
request := abci.RequestBeginBlock{Header: header}
|
||||
|
||||
var pastTimes []time.Time
|
||||
// These are operations which have been queued by previous operations
|
||||
operationQueue := make(map[int][]Operation)
|
||||
|
||||
for i := 0; i < numBlocks; i++ {
|
||||
|
||||
|
@ -96,9 +98,14 @@ func SimulateFromSeed(
|
|||
default:
|
||||
thisBlockSize = r.Intn(blockSize * 4)
|
||||
}
|
||||
// Run queued operations. Ignores blocksize if blocksize is too small
|
||||
log, numQueuedOpsRan := runQueuedOperations(operationQueue, int(header.Height), t, r, app, ctx, keys, log, event)
|
||||
opCount += numQueuedOpsRan
|
||||
thisBlockSize -= numQueuedOpsRan
|
||||
for j := 0; j < thisBlockSize; j++ {
|
||||
logUpdate, err := ops[r.Intn(len(ops))](t, r, app, ctx, keys, log, event)
|
||||
logUpdate, futureOps, err := ops[r.Intn(len(ops))](t, r, app, ctx, keys, log, event)
|
||||
log += "\n" + logUpdate
|
||||
queueOperations(operationQueue, futureOps)
|
||||
|
||||
require.Nil(t, err, log)
|
||||
if onOperation {
|
||||
|
@ -134,6 +141,39 @@ func SimulateFromSeed(
|
|||
DisplayEvents(events)
|
||||
}
|
||||
|
||||
// adds all future operations into the operation queue.
|
||||
func queueOperations(queuedOperations map[int][]Operation, futureOperations []FutureOperation) {
|
||||
if futureOperations == nil {
|
||||
return
|
||||
}
|
||||
for _, futureOp := range futureOperations {
|
||||
if val, ok := queuedOperations[futureOp.BlockHeight]; ok {
|
||||
queuedOperations[futureOp.BlockHeight] = append(val, futureOp.Op)
|
||||
} else {
|
||||
queuedOperations[futureOp.BlockHeight] = []Operation{futureOp.Op}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runQueuedOperations(queueOperations map[int][]Operation, height int, t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
privKeys []crypto.PrivKey, log string, event func(string)) (updatedLog string, numOpsRan int) {
|
||||
updatedLog = log
|
||||
if queuedOps, ok := queueOperations[height]; ok {
|
||||
numOps := len(queuedOps)
|
||||
for i := 0; i < numOps; i++ {
|
||||
// For now, queued operations cannot queue more operations.
|
||||
// If a need arises for us to support queued messages to queue more messages, this can
|
||||
// be changed.
|
||||
logUpdate, _, err := queuedOps[i](t, r, app, ctx, privKeys, updatedLog, event)
|
||||
updatedLog += "\n" + logUpdate
|
||||
require.Nil(t, err, updatedLog)
|
||||
}
|
||||
delete(queueOperations, height)
|
||||
return updatedLog, numOps
|
||||
}
|
||||
return log, 0
|
||||
}
|
||||
|
||||
func getKeys(validators map[string]mockValidator) []string {
|
||||
keys := make([]string, len(validators))
|
||||
i := 0
|
||||
|
|
|
@ -19,10 +19,13 @@ type (
|
|||
// For ease of debugging,
|
||||
// an operation returns a descriptive message "action",
|
||||
// which details what this fuzzed state machine transition actually did.
|
||||
//
|
||||
// Operations can optionally provide a list of "FutureOperations" to run later
|
||||
// These will be ran at the beginning of the corresponding block.
|
||||
Operation func(
|
||||
t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
privKeys []crypto.PrivKey, log string, event func(string),
|
||||
) (action string, err sdk.Error)
|
||||
) (action string, futureOperations []FutureOperation, err sdk.Error)
|
||||
|
||||
// RandSetup performs the random setup the mock module needs.
|
||||
RandSetup func(r *rand.Rand, privKeys []crypto.PrivKey)
|
||||
|
@ -36,6 +39,15 @@ type (
|
|||
val abci.Validator
|
||||
livenessState int
|
||||
}
|
||||
|
||||
// FutureOperation is an operation which will be ran at the
|
||||
// beginning of the provided BlockHeight.
|
||||
// In the (likely) event that multiple operations are queued at the same
|
||||
// block height, they will execute in a FIFO pattern.
|
||||
FutureOperation struct {
|
||||
BlockHeight int
|
||||
Op Operation
|
||||
}
|
||||
)
|
||||
|
||||
// PeriodicInvariant returns an Invariant function closure that asserts
|
||||
|
|
|
@ -24,7 +24,7 @@ func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
|||
// NewAnteHandler returns an AnteHandler that checks
|
||||
// whether msg type is activate or not
|
||||
func NewAnteHandler(k Keeper) sdk.AnteHandler {
|
||||
return func(ctx sdk.Context, tx sdk.Tx) (sdk.Context, sdk.Result, bool) {
|
||||
return func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, sdk.Result, bool) {
|
||||
for _, msg := range tx.GetMsgs() {
|
||||
ok := k.Getter().GetBoolWithDefault(ctx, ActivatedParamKey(msg.Type()), false)
|
||||
if !ok {
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
func GetCmdUnjail(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "unjail",
|
||||
Args: cobra.ExactArgs(0),
|
||||
Args: cobra.NoArgs,
|
||||
Short: "unjail validator previously jailed for downtime",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
|
@ -40,34 +41,29 @@ func unjailRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLI
|
|||
var m UnjailBody
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
info, err := kb.Get(m.LocalAccountName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
validatorAddr, err := sdk.AccAddressFromBech32(m.ValidatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(info.GetPubKey().Address(), validatorAddr) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Must use own validator address"))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Must use own validator address")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -81,24 +77,30 @@ func unjailRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLI
|
|||
|
||||
msg := slashing.NewMsgUnjail(validatorAddr)
|
||||
|
||||
if m.Gas == 0 {
|
||||
newCtx, err := utils.EnrichCtxWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Must use own validator address")
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
output, err := json.MarshalIndent(res, "", " ")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
|
||||
// SimulateMsgUnjail
|
||||
func SimulateMsgUnjail(k slashing.Keeper) simulation.Operation {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
key := simulation.RandomKey(r, keys)
|
||||
address := sdk.AccAddress(key.PubKey().Address())
|
||||
msg := slashing.NewMsgUnjail(address)
|
||||
|
@ -29,6 +29,6 @@ func SimulateMsgUnjail(k slashing.Keeper) simulation.Operation {
|
|||
}
|
||||
event(fmt.Sprintf("slashing/MsgUnjail/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgUnjail: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -423,7 +423,7 @@ func GetCmdQueryPool(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "pool",
|
||||
Short: "Query the current staking pool values",
|
||||
Args: cobra.ExactArgs(0),
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
key := stake.PoolKey
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
@ -462,7 +462,7 @@ func GetCmdQueryParams(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "parameters",
|
||||
Short: "Query the current staking parameters information",
|
||||
Args: cobra.ExactArgs(0),
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
key := stake.ParamKey
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
|
@ -105,21 +106,18 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
|||
for _, msg := range m.Delegations {
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
validatorAddr, err := sdk.AccAddressFromBech32(msg.ValidatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(info.GetPubKey().Address(), delegatorAddr) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Must use own delegator address"))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Must use own delegator address")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -135,34 +133,29 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
|||
for _, msg := range m.BeginRedelegates {
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(info.GetPubKey().Address(), delegatorAddr) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Must use own delegator address"))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Must use own delegator address")
|
||||
return
|
||||
}
|
||||
|
||||
validatorSrcAddr, err := sdk.AccAddressFromBech32(msg.ValidatorSrcAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
validatorDstAddr, err := sdk.AccAddressFromBech32(msg.ValidatorDstAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
shares, err := sdk.NewDecFromStr(msg.SharesAmount)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode shares amount. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode shares amount. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -179,27 +172,23 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
|||
for _, msg := range m.CompleteRedelegates {
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
validatorSrcAddr, err := sdk.AccAddressFromBech32(msg.ValidatorSrcAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
validatorDstAddr, err := sdk.AccAddressFromBech32(msg.ValidatorDstAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(info.GetPubKey().Address(), delegatorAddr) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Must use own delegator address"))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Must use own delegator address")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -215,28 +204,24 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
|||
for _, msg := range m.BeginUnbondings {
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(info.GetPubKey().Address(), delegatorAddr) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Must use own delegator address"))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Must use own delegator address")
|
||||
return
|
||||
}
|
||||
|
||||
validatorAddr, err := sdk.AccAddressFromBech32(msg.ValidatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
shares, err := sdk.NewDecFromStr(msg.SharesAmount)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode shares amount. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode shares amount. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -252,21 +237,18 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
|||
for _, msg := range m.CompleteUnbondings {
|
||||
delegatorAddr, err := sdk.AccAddressFromBech32(msg.DelegatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode delegator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
validatorAddr, err := sdk.AccAddressFromBech32(msg.ValidatorAddr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(info.GetPubKey().Address(), delegatorAddr) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte("Must use own delegator address"))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, "Must use own delegator address")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -293,10 +275,18 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
|||
|
||||
m.Sequence++
|
||||
|
||||
if m.Gas == 0 {
|
||||
newCtx, err := utils.EnrichCtxWithGas(txCtx, cliCtx, m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -310,8 +300,7 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
|||
for i, txBytes := range signedTxs {
|
||||
res, err := cliCtx.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -320,8 +309,7 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
|||
|
||||
output, err := wire.MarshalJSONIndent(cdc, results[:])
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(&w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
description := stake.Description{
|
||||
|
@ -35,7 +35,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
amount = simulation.RandomAmount(r, amount)
|
||||
}
|
||||
if amount.Equal(sdk.ZeroInt()) {
|
||||
return "no-operation", nil
|
||||
return "no-operation", nil, nil
|
||||
}
|
||||
msg := stake.MsgCreateValidator{
|
||||
Description: description,
|
||||
|
@ -53,7 +53,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
event(fmt.Sprintf("stake/MsgCreateValidator/%v", result.IsOK()))
|
||||
// require.True(t, result.IsOK(), "expected OK result but instead got %v", result)
|
||||
action = fmt.Sprintf("TestMsgCreateValidator: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ func SimulateMsgCreateValidator(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
||||
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
|
||||
description := stake.Description{
|
||||
Moniker: simulation.RandStringOfLength(r, 10),
|
||||
|
@ -84,7 +84,7 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
|||
}
|
||||
event(fmt.Sprintf("stake/MsgEditValidator/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgEditValidator: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ func SimulateMsgEditValidator(k stake.Keeper) simulation.Operation {
|
|||
func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
validatorKey := simulation.RandomKey(r, keys)
|
||||
|
@ -104,7 +104,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operat
|
|||
amount = simulation.RandomAmount(r, amount)
|
||||
}
|
||||
if amount.Equal(sdk.ZeroInt()) {
|
||||
return "no-operation", nil
|
||||
return "no-operation", nil, nil
|
||||
}
|
||||
msg := stake.MsgDelegate{
|
||||
DelegatorAddr: delegatorAddress,
|
||||
|
@ -119,7 +119,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operat
|
|||
}
|
||||
event(fmt.Sprintf("stake/MsgDelegate/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgDelegate: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ func SimulateMsgDelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operat
|
|||
func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
validatorKey := simulation.RandomKey(r, keys)
|
||||
|
@ -139,7 +139,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.
|
|||
amount = simulation.RandomAmount(r, amount)
|
||||
}
|
||||
if amount.Equal(sdk.ZeroInt()) {
|
||||
return "no-operation", nil
|
||||
return "no-operation", nil, nil
|
||||
}
|
||||
msg := stake.MsgBeginUnbonding{
|
||||
DelegatorAddr: delegatorAddress,
|
||||
|
@ -154,7 +154,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.
|
|||
}
|
||||
event(fmt.Sprintf("stake/MsgBeginUnbonding/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgBeginUnbonding: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ func SimulateMsgBeginUnbonding(m auth.AccountMapper, k stake.Keeper) simulation.
|
|||
func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
||||
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
|
||||
validatorKey := simulation.RandomKey(r, keys)
|
||||
validatorAddress := sdk.AccAddress(validatorKey.PubKey().Address())
|
||||
|
@ -180,7 +180,7 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
|||
}
|
||||
event(fmt.Sprintf("stake/MsgCompleteUnbonding/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgCompleteUnbonding: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ func SimulateMsgCompleteUnbonding(k stake.Keeper) simulation.Operation {
|
|||
func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation.Operation {
|
||||
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
|
||||
denom := k.GetParams(ctx).BondDenom
|
||||
sourceValidatorKey := simulation.RandomKey(r, keys)
|
||||
|
@ -203,7 +203,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
amount = simulation.RandomAmount(r, amount)
|
||||
}
|
||||
if amount.Equal(sdk.ZeroInt()) {
|
||||
return "no-operation", nil
|
||||
return "no-operation", nil, nil
|
||||
}
|
||||
msg := stake.MsgBeginRedelegate{
|
||||
DelegatorAddr: delegatorAddress,
|
||||
|
@ -219,7 +219,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
}
|
||||
event(fmt.Sprintf("stake/MsgBeginRedelegate/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgBeginRedelegate: %s", msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountMapper, k stake.Keeper) simulation
|
|||
func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.Operation {
|
||||
|
||||
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
|
||||
keys []crypto.PrivKey, log string, event func(string)) (action string, fOp []simulation.FutureOperation, err sdk.Error) {
|
||||
|
||||
validatorSrcKey := simulation.RandomKey(r, keys)
|
||||
validatorSrcAddress := sdk.AccAddress(validatorSrcKey.PubKey().Address())
|
||||
|
@ -248,7 +248,7 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.Operation {
|
|||
}
|
||||
event(fmt.Sprintf("stake/MsgCompleteRedelegate/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgCompleteRedelegate: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action, nil
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue