Merge remote-tracking branch 'origin/develop' into rigel/fee-distribution
This commit is contained in:
commit
7d864fee11
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@
|
||||
|
||||
# Build
|
||||
vendor
|
||||
.vendor-new
|
||||
build
|
||||
tools/bin/*
|
||||
examples/build/*
|
||||
|
||||
71
Gopkg.lock
generated
71
Gopkg.lock
generated
@ -1,6 +1,14 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7736fc6da04620727f8f3aa2ced8d77be8e074a302820937aa5993848c769b27"
|
||||
name = "github.com/ZondaX/hid-go"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "48b08affede2cea076a3cf13b2e3f72ed262b743"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:09a7f74eb6bb3c0f14d8926610c87f569c5cff68e978d30e9a3540aeb626fdf0"
|
||||
name = "github.com/bartekn/go-bip39"
|
||||
@ -26,15 +34,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:70f6b224a59b2fa453debffa85c77f71063d8754b90c8c4fbad5794e2c382b0f"
|
||||
name = "github.com/brejski/hid"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "06112dcfcc50a7e0e4fd06e17f9791e788fdaafc"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2c00f064ba355903866cbfbf3f7f4c0fe64af6638cc7d1b8bdcf3181bc67f1d8"
|
||||
digest = "1:6aabc1566d6351115d561d038da82a4c19b46c3b6e17f4a0a2fa60260663dc79"
|
||||
name = "github.com/btcsuite/btcd"
|
||||
packages = ["btcec"]
|
||||
pruneopts = "UT"
|
||||
@ -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,7 +165,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:12247a2e99a060cc692f6680e5272c8adf0b8f572e6bce0d7095e624c958a240"
|
||||
digest = "1:8951fe6e358876736d8fa1f3992624fdbb2dec6bc49401c1381d1ef8abbb544f"
|
||||
name = "github.com/hashicorp/hcl"
|
||||
packages = [
|
||||
".",
|
||||
@ -262,7 +262,7 @@
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c1a04665f9613e082e1209cf288bf64f4068dcd6c87a64bf1c4ff006ad422ba0"
|
||||
digest = "1:98225904b7abff96c052b669b25788f18225a36673fba022fb93514bb9a2a64e"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"prometheus",
|
||||
@ -273,7 +273,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4"
|
||||
digest = "1:0f37e09b3e92aaeda5991581311f8dbf38944b36a3edec61cc2d1991f527554a"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
pruneopts = "UT"
|
||||
@ -281,7 +281,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:63b68062b8968092eb86bedc4e68894bd096ea6b24920faca8b9dcf451f54bb5"
|
||||
digest = "1:dad2e5a2153ee7a6c9ab8fc13673a16ee4fb64434a7da980965a3741b0c981a3"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = [
|
||||
"expfmt",
|
||||
@ -293,7 +293,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8c49953a1414305f2ff5465147ee576dd705487c35b15918fcd4efdc0cb7a290"
|
||||
digest = "1:a37c98f4b7a66bb5c539c0539f0915a74ef1c8e0b3b6f45735289d94cae92bfd"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [
|
||||
".",
|
||||
@ -312,7 +312,7 @@
|
||||
revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bd1ae00087d17c5a748660b8e89e1043e1e5479d0fea743352cda2f8dd8c4f84"
|
||||
digest = "1:37ace7f35375adec11634126944bdc45a673415e2fcc07382d03b75ec76ea94c"
|
||||
name = "github.com/spf13/afero"
|
||||
packages = [
|
||||
".",
|
||||
@ -331,7 +331,7 @@
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7ffc0983035bc7e297da3688d9fe19d60a420e9c38bef23f845c53788ed6a05e"
|
||||
digest = "1:627ab2f549a6a55c44f46fa24a4307f4d0da81bfc7934ed0473bf38b24051d26"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
@ -363,7 +363,7 @@
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7e8d267900c7fa7f35129a2a37596e38ed0f11ca746d6d9ba727980ee138f9f6"
|
||||
digest = "1:73697231b93fb74a73ebd8384b68b9a60c57ea6b13c56d2425414566a72c8e6d"
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = [
|
||||
"assert",
|
||||
@ -375,7 +375,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:f2ffd421680b0a3f7887501b3c6974bcf19217ecd301d0e2c9b681940ec363d5"
|
||||
digest = "1:442d2ffa75ffae302ce8800bf4144696b92bef02917923ea132ce2d39efe7d65"
|
||||
name = "github.com/syndtr/goleveldb"
|
||||
packages = [
|
||||
"leveldb",
|
||||
@ -396,7 +396,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722"
|
||||
digest = "1:203b409c21115233a576f99e8f13d8e07ad82b25500491f7e1cca12588fb3232"
|
||||
name = "github.com/tendermint/ed25519"
|
||||
packages = [
|
||||
".",
|
||||
@ -415,15 +415,15 @@
|
||||
version = "v0.12.0-rc0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d4a15d404afbf591e8be16fcda7f5ac87948d5c7531f9d909fd84cc730ab16e2"
|
||||
digest = "1:53397098d6acb7613358683cc84ae59281a60c6033f0bff62fa8d3f279c6c430"
|
||||
name = "github.com/tendermint/iavl"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "35f66e53d9b01e83b30de68b931f54b2477a94c9"
|
||||
version = "v0.9.2"
|
||||
revision = "3acc91fb8811db2c5409a855ae1f8e441fe98e2d"
|
||||
version = "v0.11.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4f15e95fe3888cc75dd34f407d6394cbc7fd3ff24920851b92b295f6a8b556e6"
|
||||
digest = "1:963f6c04345ce36f900c1d6367200eebc3cc2db6ee632ff865ea8dcf64b748a0"
|
||||
name = "github.com/tendermint/tendermint"
|
||||
packages = [
|
||||
"abci/client",
|
||||
@ -490,7 +490,7 @@
|
||||
version = "v0.23.1-rc0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bf6d9a827ea3cad964c2f863302e4f6823170d0b5ed16f72cf1184a7c615067e"
|
||||
digest = "1:ad879bb8c71020a3f92f0c61f414d93eae1d5dc2f37023b6abaa3cc84b00165e"
|
||||
name = "github.com/tendermint/tmlibs"
|
||||
packages = ["cli"]
|
||||
pruneopts = "UT"
|
||||
@ -498,15 +498,16 @@
|
||||
version = "v0.9.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4dcb0dd65feecb068ce23a234d1a07c7868a1e39f52a6defcae0bb371d03abf6"
|
||||
digest = "1:7886f86064faff6f8d08a3eb0e8c773648ff5a2e27730831e2bfbf07467f6666"
|
||||
name = "github.com/zondax/ledger-goclient"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "4296ee5701e945f9b3a7dbe51f402e0b9be57259"
|
||||
revision = "58598458c11bc0ad1c1b8dac3dc3e11eaf270b79"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[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:86171d21d59449dcf7cee0b7d2da83dff989dab9b9b69bfe0a3d59c3c1ca6081"
|
||||
digest = "1:9d9e5fc87553258c36ee18d38023587edd61e4b2521f4473da34b47a83a492e5"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"cpu",
|
||||
"unix",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "11551d06cbcc94edc80a0facaccbda56473c19c1"
|
||||
revision = "4ea2f632f6e912459fe60b26b1749377f0d889d5"
|
||||
|
||||
[[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 = [
|
||||
".",
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
|
||||
[[override]]
|
||||
name = "github.com/tendermint/iavl"
|
||||
version = "=v0.9.2"
|
||||
version = "=v0.11.0"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/tendermint/tendermint"
|
||||
@ -65,7 +65,7 @@
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/zondax/ledger-goclient"
|
||||
revision = "4296ee5701e945f9b3a7dbe51f402e0b9be57259"
|
||||
version = "=v0.1.0"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
|
||||
2
Makefile
2
Makefile
@ -157,7 +157,7 @@ test_sim_gaia_nondeterminism:
|
||||
|
||||
test_sim_gaia_fast:
|
||||
@echo "Running quick Gaia simulation. This may take several minutes..."
|
||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=150 -v -timeout 24h
|
||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=200 -v -timeout 24h
|
||||
|
||||
test_sim_gaia_slow:
|
||||
@echo "Running full Gaia simulation. This may take awhile!"
|
||||
|
||||
81
PENDING.md
81
PENDING.md
@ -8,33 +8,39 @@ BREAKING CHANGES
|
||||
* Gaia CLI (`gaiacli`)
|
||||
* [x/stake] Validator.Owner renamed to Validator.Operator
|
||||
* [cli] unsafe_reset_all, show_validator, and show_node_id have been renamed to unsafe-reset-all, show-validator, and show-node-id
|
||||
* [cli] \#1983 --print-response now defaults to true in commands that create and send a transaction
|
||||
* [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
|
||||
* [cli] [\#1983](https://github.com/cosmos/cosmos-sdk/issues/1983) --print-response now defaults to true in commands that create and send a transaction
|
||||
* [cli] [\#1983](https://github.com/cosmos/cosmos-sdk/issues/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](https://github.com/cosmos/cosmos-sdk/issues/2061) changed proposalID in governance REST endpoints to proposal-id
|
||||
* [cli] [\#2014](https://github.com/cosmos/cosmos-sdk/issues/2014) `gaiacli advanced` no longer exists - to access `ibc`, `rest-server`, and `validator-set` commands use `gaiacli ibc`, `gaiacli rest-server`, and `gaiacli tendermint`, respectively
|
||||
* [makefile] `get_vendor_deps` no longer updates lock file it just updates vendor directory. Use `update_vendor_deps` to update the lock file. [#2152](https://github.com/cosmos/cosmos-sdk/pull/2152)
|
||||
* [cli] \#2190 `gaiacli init --gen-txs` is now `gaiacli init --with-txs` to reduce confusion
|
||||
* \#2040 All commands that utilize a validator's address must now use the new
|
||||
bech32 prefix, `cosmosval`. A validator's Tendermint signing key and address
|
||||
now use a new bech32 prefix, `cosmoscons`.
|
||||
* [cli] [\#2221](https://github.com/cosmos/cosmos-sdk/issues/2221) All commands that
|
||||
utilize a validator's operator address must now use the new Bech32 prefix,
|
||||
`cosmosvaloper`.
|
||||
* [cli] [\#2190](https://github.com/cosmos/cosmos-sdk/issues/2190) `gaiacli init --gen-txs` is now `gaiacli init --with-txs` to reduce confusion
|
||||
|
||||
* Gaia
|
||||
* Make the transient store key use a distinct store key. [#2013](https://github.com/cosmos/cosmos-sdk/pull/2013)
|
||||
* [x/stake] \#1901 Validator type's Owner field renamed to Operator; Validator's GetOwner() renamed accordingly to comply with the SDK's Validator interface.
|
||||
* [x/stake] [\#1901](https://github.com/cosmos/cosmos-sdk/issues/1901) Validator type's Owner field renamed to Operator; Validator's GetOwner() renamed accordingly to comply with the SDK's Validator interface.
|
||||
* [docs] [#2001](https://github.com/cosmos/cosmos-sdk/pull/2001) Update slashing spec for slashing period
|
||||
* [x/stake, x/slashing] [#1305](https://github.com/cosmos/cosmos-sdk/issues/1305) - Rename "revoked" to "jailed"
|
||||
* [x/stake] [#1676] Revoked and jailed validators put into the unbonding state
|
||||
* [x/stake] [#1877] Redelegations/unbonding-delegation from unbonding validator have reduced time
|
||||
* [x/stake] \#2040 Validator operator type has now changed to `sdk.ValAddress`
|
||||
* A new bech32 prefix has been introduced for Tendermint signing keys and
|
||||
addresses, `cosmosconspub` and `cosmoscons` respectively.
|
||||
* [x/stake] [\#2040](https://github.com/cosmos/cosmos-sdk/issues/2040) Validator
|
||||
operator type has now changed to `sdk.ValAddress`
|
||||
* [x/stake] [\#2221](https://github.com/cosmos/cosmos-sdk/issues/2221) New
|
||||
Bech32 prefixes have been introduced for a validator's consensus address and
|
||||
public key: `cosmosvalcons` and `cosmosvalconspub` respectively. Also, existing Bech32 prefixes have been
|
||||
renamed for accounts and validator operators:
|
||||
* `cosmosaccaddr` / `cosmosaccpub` => `cosmos` / `cosmospub`
|
||||
* `cosmosvaladdr` / `cosmosvalpub` => `cosmosvaloper` / `cosmosvaloperpub`
|
||||
|
||||
* SDK
|
||||
* [core] \#1807 Switch from use of rational to decimal
|
||||
* [types] \#1901 Validator interface's GetOwner() renamed to GetOperator()
|
||||
* [core] [\#1807](https://github.com/cosmos/cosmos-sdk/issues/1807) Switch from use of rational to decimal
|
||||
* [types] [\#1901](https://github.com/cosmos/cosmos-sdk/issues/1901) Validator interface's GetOwner() renamed to GetOperator()
|
||||
* [x/slashing] [#2122](https://github.com/cosmos/cosmos-sdk/pull/2122) - Implement slashing period
|
||||
* [types] \#2119 Parsed error messages and ABCI log errors to make them more human readable.
|
||||
* [types] [\#2119](https://github.com/cosmos/cosmos-sdk/issues/2119) Parsed error messages and ABCI log errors to make them more human readable.
|
||||
* [simulation] Rename TestAndRunTx to Operation [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
|
||||
* [simulation] Remove log and testing.TB from Operation and Invariants, in favor of using errors \#2282
|
||||
* [tools] Removed gocyclo [#2211](https://github.com/cosmos/cosmos-sdk/issues/2211)
|
||||
* [baseapp] Remove `SetTxDecoder` in favor of requiring the decoder be set in baseapp initialization. [#1441](https://github.com/cosmos/cosmos-sdk/issues/1441)
|
||||
|
||||
@ -44,27 +50,32 @@ BREAKING CHANGES
|
||||
FEATURES
|
||||
|
||||
* Gaia REST API (`gaiacli advanced rest-server`)
|
||||
* [lcd] Endpoints to query staking pool and params
|
||||
* [lcd] \#2110 Add support for `simulate=true` requests query argument to endpoints that send txs to run simulations of transactions
|
||||
* [lcd] \#966 Add support for `generate_only=true` query argument to generate offline unsigned transactions
|
||||
* [gaia-lite] Endpoints to query staking pool and params
|
||||
* [gaia-lite] [\#2110](https://github.com/cosmos/cosmos-sdk/issues/2110) Add support for `simulate=true` requests query argument to endpoints that send txs to run simulations of transactions
|
||||
* [gaia-lite] [\#966](https://github.com/cosmos/cosmos-sdk/issues/966) Add support for `generate_only=true` query argument to generate offline unsigned transactions
|
||||
* [gaia-lite] [\#1953](https://github.com/cosmos/cosmos-sdk/issues/1953) Add /sign endpoint to sign transactions generated with `generate_only=true`.
|
||||
* [gaia-lite] [\#1954](https://github.com/cosmos/cosmos-sdk/issues/1954) Add /broadcast endpoint to broadcast transactions signed by the /sign endpoint.
|
||||
|
||||
* Gaia CLI (`gaiacli`)
|
||||
* [cli] Cmds to query staking pool and params
|
||||
* [gov][cli] #2062 added `--proposal` flag to `submit-proposal` that allows a JSON file containing a proposal to be passed in
|
||||
* \#2040 Add `--bech` to `gaiacli keys show` and respective REST endpoint to
|
||||
* [\#2040](https://github.com/cosmos/cosmos-sdk/issues/2040) Add `--bech` to `gaiacli keys show` and respective REST endpoint to
|
||||
provide desired Bech32 prefix encoding
|
||||
* [cli] \#2047 Setting the --gas flag value to 0 triggers a simulation of the tx before the actual execution. The gas estimate obtained via the simulation will be used as gas limit in the actual execution.
|
||||
* [cli] \#2047 The --gas-adjustment flag can be used to adjust the estimate obtained via the simulation triggered by --gas=0.
|
||||
* [cli] \#2110 Add --dry-run flag to perform a simulation of a transaction without broadcasting it. The --gas flag is ignored as gas would be automatically estimated.
|
||||
* [cli] \#966 Add --generate-only flag to build an unsigned transaction and write it to STDOUT.
|
||||
* [cli] [\#2047](https://github.com/cosmos/cosmos-sdk/issues/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](https://github.com/cosmos/cosmos-sdk/issues/2047) The --gas-adjustment flag can be used to adjust the estimate obtained via the simulation triggered by --gas=0.
|
||||
* [cli] [\#2110](https://github.com/cosmos/cosmos-sdk/issues/2110) Add --dry-run flag to perform a simulation of a transaction without broadcasting it. The --gas flag is ignored as gas would be automatically estimated.
|
||||
* [cli] [\#2204](https://github.com/cosmos/cosmos-sdk/issues/2204) Support generating and broadcasting messages with multiple signatures via command line:
|
||||
* [\#966](https://github.com/cosmos/cosmos-sdk/issues/966) Add --generate-only flag to build an unsigned transaction and write it to STDOUT.
|
||||
* [\#1953](https://github.com/cosmos/cosmos-sdk/issues/1953) New `sign` command to sign transactions generated with the --generate-only flag.
|
||||
* [\#1954](https://github.com/cosmos/cosmos-sdk/issues/1954) New `broadcast` command to broadcast transactions generated offline and signed with the `sign` command.
|
||||
|
||||
* Gaia
|
||||
* [cli] #2170 added ability to show the node's address via `gaiad tendermint show-address`
|
||||
|
||||
* SDK
|
||||
* [querier] added custom querier functionality, so ABCI query requests can be handled by keepers
|
||||
* [simulation] \#1924 allow operations to specify future operations
|
||||
* [simulation] \#1924 Add benchmarking capabilities, with makefile commands "test_sim_gaia_benchmark, test_sim_gaia_profile"
|
||||
* [simulation] [\#1924](https://github.com/cosmos/cosmos-sdk/issues/1924) allow operations to specify future operations
|
||||
* [simulation] [\#1924](https://github.com/cosmos/cosmos-sdk/issues/1924) Add benchmarking capabilities, with makefile commands "test_sim_gaia_benchmark, test_sim_gaia_profile"
|
||||
|
||||
* Tendermint
|
||||
|
||||
@ -74,7 +85,7 @@ IMPROVEMENTS
|
||||
* [tools] Added ansible script to enable process core dumps
|
||||
|
||||
* Gaia REST API (`gaiacli advanced rest-server`)
|
||||
* [x/stake] \#2000 Added tests for new staking endpoints
|
||||
* [x/stake] [\#2000](https://github.com/cosmos/cosmos-sdk/issues/2000) Added tests for new staking endpoints
|
||||
|
||||
* Gaia CLI (`gaiacli`)
|
||||
* [cli] #2060 removed `--select` from `block` command
|
||||
@ -85,12 +96,16 @@ IMPROVEMENTS
|
||||
* [x/auth] Signature verification's gas cost now accounts for pubkey type. [#2046](https://github.com/tendermint/tendermint/pull/2046)
|
||||
* [x/stake] [x/slashing] Ensure delegation invariants to jailed validators [#1883](https://github.com/cosmos/cosmos-sdk/issues/1883).
|
||||
* [x/stake] Improve speed of GetValidator, which was shown to be a performance bottleneck. [#2046](https://github.com/tendermint/tendermint/pull/2200)
|
||||
* [genesis] \#2229 Ensure that there are no duplicate accounts or validators in the genesis state.
|
||||
|
||||
* SDK
|
||||
* [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present.
|
||||
* [spec] Added simple piggy bank distribution spec
|
||||
* [cli] \#1632 Add integration tests to ensure `basecoind init && basecoind` start sequences run successfully for both `democoin` and `basecoin` examples.
|
||||
* [cli] [\#1632](https://github.com/cosmos/cosmos-sdk/issues/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)
|
||||
* [store] \#1952, \#2281 Update IAVL dependency to v0.11.0
|
||||
* [simulation] Make timestamps randomized [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
|
||||
* [simulation] Make logs not just pure strings, speeding it up by a large factor at greater block heights \#2282
|
||||
|
||||
* Tendermint
|
||||
|
||||
@ -99,15 +114,17 @@ BUG FIXES
|
||||
* Gaia REST API (`gaiacli advanced rest-server`)
|
||||
|
||||
* Gaia CLI (`gaiacli`)
|
||||
* [cli] \#1997 Handle panics gracefully when `gaiacli stake {delegation,unbond}` fail to unmarshal delegation.
|
||||
* [cli] [\#1997](https://github.com/cosmos/cosmos-sdk/issues/1997) Handle panics gracefully when `gaiacli stake {delegation,unbond}` fail to unmarshal delegation.
|
||||
* [cli] [\#2265](https://github.com/cosmos/cosmos-sdk/issues/2265) Fix JSON formatting of the `gaiacli send` command.
|
||||
|
||||
* Gaia
|
||||
|
||||
* 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
|
||||
* [\#1988](https://github.com/cosmos/cosmos-sdk/issues/1988) Make us compile on OpenBSD (disable ledger) [#1988] (https://github.com/cosmos/cosmos-sdk/issues/1988)
|
||||
* [\#2105](https://github.com/cosmos/cosmos-sdk/issues/2105) Fix DB Iterator leak, which may leak a go routine.
|
||||
* [ledger] [\#2064](https://github.com/cosmos/cosmos-sdk/issues/2064) Fix inability to sign and send transactions via the LCD by
|
||||
loading a Ledger device at runtime.
|
||||
* \#2158 Fix non-deterministic ordering of validator iteration when slashing in `gov EndBlocker`
|
||||
* [\#2158](https://github.com/cosmos/cosmos-sdk/issues/2158) Fix non-deterministic ordering of validator iteration when slashing in `gov EndBlocker`
|
||||
* [simulation] \#1924 Make simulation stop on SIGTERM
|
||||
|
||||
* Tendermint
|
||||
|
||||
@ -345,6 +345,7 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) (res a
|
||||
return queryable.Query(req)
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func handleQueryP2P(app *BaseApp, path []string, req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
// "/p2p" prefix for p2p queries
|
||||
if len(path) >= 4 {
|
||||
|
||||
@ -626,12 +626,12 @@ func TestSimulateTx(t *testing.T) {
|
||||
// simulate a message, check gas reported
|
||||
result := app.Simulate(tx)
|
||||
require.True(t, result.IsOK(), result.Log)
|
||||
require.Equal(t, int64(gasConsumed), result.GasUsed)
|
||||
require.Equal(t, gasConsumed, result.GasUsed)
|
||||
|
||||
// simulate again, same result
|
||||
result = app.Simulate(tx)
|
||||
require.True(t, result.IsOK(), result.Log)
|
||||
require.Equal(t, int64(gasConsumed), result.GasUsed)
|
||||
require.Equal(t, gasConsumed, result.GasUsed)
|
||||
|
||||
// simulate by calling Query with encoded tx
|
||||
txBytes, err := codec.MarshalBinary(tx)
|
||||
|
||||
@ -10,6 +10,8 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
@ -17,7 +19,6 @@ import (
|
||||
tmliteProxy "github.com/tendermint/tendermint/lite/proxy"
|
||||
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetNode returns an RPC client. If the context's client is not defined, an
|
||||
@ -254,11 +255,11 @@ func (ctx CLIContext) ensureBroadcastTx(txBytes []byte) error {
|
||||
type toJSON struct {
|
||||
Height int64
|
||||
TxHash string
|
||||
Response string
|
||||
Response abci.ResponseDeliverTx
|
||||
}
|
||||
|
||||
if ctx.Logger != nil {
|
||||
resJSON := toJSON{res.Height, res.Hash.String(), fmt.Sprintf("%+v", res.DeliverTx)}
|
||||
resJSON := toJSON{res.Height, res.Hash.String(), res.DeliverTx}
|
||||
bz, err := ctx.Codec.MarshalJSON(resJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -323,6 +324,7 @@ func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, err erro
|
||||
}
|
||||
|
||||
// verifyProof perform response proof verification
|
||||
// nolint: unparam
|
||||
func (ctx CLIContext) verifyProof(path string, resp abci.ResponseQuery) error {
|
||||
|
||||
if ctx.Certifier == nil {
|
||||
|
||||
@ -24,7 +24,7 @@ func BufferStdin() *bufio.Reader {
|
||||
// It enforces the password length
|
||||
func GetPassword(prompt string, buf *bufio.Reader) (pass string, err error) {
|
||||
if inputIsTty() {
|
||||
pass, err = speakeasy.Ask(prompt)
|
||||
pass, err = speakeasy.FAsk(os.Stderr, prompt)
|
||||
} else {
|
||||
pass, err = readLineFromBuf(buf)
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
@ -205,8 +206,8 @@ func TestValidators(t *testing.T) {
|
||||
|
||||
require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals)
|
||||
|
||||
require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosval")
|
||||
require.Contains(t, resultVals.Validators[0].PubKey, "cosmosconspub")
|
||||
require.Contains(t, resultVals.Validators[0].Address.String(), "cosmosvaloper")
|
||||
require.Contains(t, resultVals.Validators[0].PubKey, "cosmosvalconspub")
|
||||
|
||||
// --
|
||||
|
||||
@ -313,12 +314,14 @@ func TestIBCTransfer(t *testing.T) {
|
||||
// TODO: query ibc egress packet state
|
||||
}
|
||||
|
||||
func TestCoinSendGenerateOnly(t *testing.T) {
|
||||
func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
|
||||
name, password := "test", "1234567890"
|
||||
addr, seed := CreateAddr(t, "test", password, GetKeyBase(t))
|
||||
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
|
||||
defer cleanup()
|
||||
// create TX
|
||||
acc := getAccount(t, port, addr)
|
||||
|
||||
// generate TX
|
||||
res, body, _ := doSendWithGas(t, port, seed, name, password, addr, 0, 0, "?generate_only=true")
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
var msg auth.StdTx
|
||||
@ -327,6 +330,47 @@ func TestCoinSendGenerateOnly(t *testing.T) {
|
||||
require.Equal(t, msg.Msgs[0].Type(), "bank")
|
||||
require.Equal(t, msg.Msgs[0].GetSigners(), []sdk.AccAddress{addr})
|
||||
require.Equal(t, 0, len(msg.Signatures))
|
||||
gasEstimate := msg.Fee.Gas
|
||||
|
||||
// sign tx
|
||||
var signedMsg auth.StdTx
|
||||
accnum := acc.GetAccountNumber()
|
||||
sequence := acc.GetSequence()
|
||||
|
||||
payload := authrest.SignBody{
|
||||
Tx: msg,
|
||||
LocalAccountName: name,
|
||||
Password: password,
|
||||
ChainID: viper.GetString(client.FlagChainID),
|
||||
AccountNumber: accnum,
|
||||
Sequence: sequence,
|
||||
}
|
||||
json, err := cdc.MarshalJSON(payload)
|
||||
require.Nil(t, err)
|
||||
res, body = Request(t, port, "POST", "/tx/sign", json)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &signedMsg))
|
||||
require.Equal(t, len(msg.Msgs), len(signedMsg.Msgs))
|
||||
require.Equal(t, msg.Msgs[0].Type(), signedMsg.Msgs[0].Type())
|
||||
require.Equal(t, msg.Msgs[0].GetSigners(), signedMsg.Msgs[0].GetSigners())
|
||||
require.Equal(t, 1, len(signedMsg.Signatures))
|
||||
|
||||
// broadcast tx
|
||||
broadcastPayload := struct {
|
||||
Tx auth.StdTx `json:"tx"`
|
||||
}{Tx: signedMsg}
|
||||
json, err = cdc.MarshalJSON(broadcastPayload)
|
||||
require.Nil(t, err)
|
||||
res, body = Request(t, port, "POST", "/tx/broadcast", json)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
// check if tx was committed
|
||||
var resultTx ctypes.ResultBroadcastTxCommit
|
||||
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &resultTx))
|
||||
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
|
||||
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
|
||||
require.Equal(t, gasEstimate, resultTx.DeliverTx.GasWanted)
|
||||
require.Equal(t, gasEstimate, resultTx.DeliverTx.GasUsed)
|
||||
}
|
||||
|
||||
func TestTxs(t *testing.T) {
|
||||
@ -434,11 +478,12 @@ func TestValidatorsQuery(t *testing.T) {
|
||||
|
||||
// make sure all the validators were found (order unknown because sorted by operator addr)
|
||||
foundVal := false
|
||||
pkBech := sdk.MustBech32ifyConsPub(pks[0])
|
||||
if validators[0].PubKey == pkBech {
|
||||
|
||||
if validators[0].ConsPubKey == pks[0] {
|
||||
foundVal = true
|
||||
}
|
||||
require.True(t, foundVal, "pkBech %v, operator %v", pkBech, validators[0].Operator)
|
||||
|
||||
require.True(t, foundVal, "pk %v, operator %v", pks[0], validators[0].OperatorAddr)
|
||||
}
|
||||
|
||||
func TestValidatorQuery(t *testing.T) {
|
||||
@ -448,7 +493,7 @@ func TestValidatorQuery(t *testing.T) {
|
||||
|
||||
validator1Operator := sdk.ValAddress(pks[0].Address())
|
||||
validator := getValidator(t, port, validator1Operator)
|
||||
assert.Equal(t, validator.Operator, validator1Operator, "The returned validator does not hold the correct data")
|
||||
assert.Equal(t, validator.OperatorAddr, validator1Operator, "The returned validator does not hold the correct data")
|
||||
}
|
||||
|
||||
func TestBonding(t *testing.T) {
|
||||
@ -484,11 +529,11 @@ func TestBonding(t *testing.T) {
|
||||
|
||||
bondedValidators := getDelegatorValidators(t, port, addr)
|
||||
require.Len(t, bondedValidators, 1)
|
||||
require.Equal(t, validator1Operator, bondedValidators[0].Operator)
|
||||
require.Equal(t, validator1Operator, bondedValidators[0].OperatorAddr)
|
||||
require.Equal(t, validator.DelegatorShares.Add(sdk.NewDec(60)).String(), bondedValidators[0].DelegatorShares.String())
|
||||
|
||||
bondedValidator := getDelegatorValidator(t, port, addr, validator1Operator)
|
||||
require.Equal(t, validator1Operator, bondedValidator.Operator)
|
||||
require.Equal(t, validator1Operator, bondedValidator.OperatorAddr)
|
||||
|
||||
//////////////////////
|
||||
// testing unbonding
|
||||
@ -905,11 +950,11 @@ func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, quer
|
||||
return txs
|
||||
}
|
||||
|
||||
func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.BechValidator {
|
||||
func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Validator {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators", delegatorAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var bondedValidators []stake.BechValidator
|
||||
var bondedValidators []stake.Validator
|
||||
|
||||
err := cdc.UnmarshalJSON([]byte(body), &bondedValidators)
|
||||
require.Nil(t, err)
|
||||
@ -917,11 +962,11 @@ func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddr
|
||||
return bondedValidators
|
||||
}
|
||||
|
||||
func getDelegatorValidator(t *testing.T, port string, delAddr sdk.AccAddress, valAddr sdk.ValAddress) stake.BechValidator {
|
||||
func getDelegatorValidator(t *testing.T, port string, delAddr sdk.AccAddress, valAddr sdk.ValAddress) stake.Validator {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators/%s", delAddr, valAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
var bondedValidator stake.BechValidator
|
||||
var bondedValidator stake.Validator
|
||||
err := cdc.UnmarshalJSON([]byte(body), &bondedValidator)
|
||||
require.Nil(t, err)
|
||||
|
||||
@ -1041,19 +1086,19 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string,
|
||||
return results[0]
|
||||
}
|
||||
|
||||
func getValidators(t *testing.T, port string) []stake.BechValidator {
|
||||
func getValidators(t *testing.T, port string) []stake.Validator {
|
||||
res, body := Request(t, port, "GET", "/stake/validators", nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
var validators []stake.BechValidator
|
||||
var validators []stake.Validator
|
||||
err := cdc.UnmarshalJSON([]byte(body), &validators)
|
||||
require.Nil(t, err)
|
||||
return validators
|
||||
}
|
||||
|
||||
func getValidator(t *testing.T, port string, valAddr sdk.ValAddress) stake.BechValidator {
|
||||
func getValidator(t *testing.T, port string, valAddr sdk.ValAddress) stake.Validator {
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", valAddr.String()), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
var validator stake.BechValidator
|
||||
var validator stake.Validator
|
||||
err := cdc.UnmarshalJSON([]byte(body), &validator)
|
||||
require.Nil(t, err)
|
||||
return validator
|
||||
|
||||
@ -151,7 +151,7 @@ func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress
|
||||
|
||||
var validatorsPKs []crypto.PubKey
|
||||
|
||||
// NOTE: It's bad practice to reuse public key address for the owner
|
||||
// NOTE: It's bad practice to reuse public key address for the operator
|
||||
// address but doing in the test for simplicity.
|
||||
var appGenTxs []json.RawMessage
|
||||
for _, gdValidator := range genDoc.Validators {
|
||||
|
||||
@ -8,7 +8,7 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -52,13 +52,13 @@ func ParseFloat64OrReturnBadRequest(w http.ResponseWriter, s string, defaultIfEm
|
||||
}
|
||||
|
||||
// WriteGenerateStdTxResponse writes response for the generate_only mode.
|
||||
func WriteGenerateStdTxResponse(w http.ResponseWriter, txCtx authctx.TxContext, msgs []sdk.Msg) {
|
||||
stdMsg, err := txCtx.Build(msgs)
|
||||
func WriteGenerateStdTxResponse(w http.ResponseWriter, txBldr authtxb.TxBuilder, msgs []sdk.Msg) {
|
||||
stdMsg, err := txBldr.Build(msgs)
|
||||
if err != nil {
|
||||
WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
output, err := txCtx.Codec.MarshalJSON(auth.NewStdTx(stdMsg.Msgs, stdMsg.Fee, nil, stdMsg.Memo))
|
||||
output, err := txBldr.Codec.MarshalJSON(auth.NewStdTx(stdMsg.Msgs, stdMsg.Fee, nil, stdMsg.Memo))
|
||||
if err != nil {
|
||||
WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
@ -8,28 +9,28 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
)
|
||||
|
||||
// SendTx implements a auxiliary handler that facilitates sending a series of
|
||||
// messages in a signed transaction given a TxContext and a QueryContext. It
|
||||
// messages in a signed transaction given a TxBuilder and a QueryContext. It
|
||||
// ensures that the account exists, has a proper number and sequence set. In
|
||||
// addition, it builds and signs a transaction with the supplied messages.
|
||||
// Finally, it broadcasts the signed transaction to a node.
|
||||
func SendTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg) error {
|
||||
txCtx, err := prepareTxContext(txCtx, cliCtx)
|
||||
func SendTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg) error {
|
||||
txBldr, err := prepareTxContext(txBldr, cliCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
autogas := cliCtx.DryRun || (cliCtx.Gas == 0)
|
||||
if autogas {
|
||||
txCtx, err = EnrichCtxWithGas(txCtx, cliCtx, cliCtx.FromAddressName, msgs)
|
||||
txBldr, err = EnrichCtxWithGas(txBldr, cliCtx, cliCtx.FromAddressName, msgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txCtx.Gas)
|
||||
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.Gas)
|
||||
}
|
||||
if cliCtx.DryRun {
|
||||
return nil
|
||||
@ -41,7 +42,7 @@ func SendTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg)
|
||||
}
|
||||
|
||||
// build and sign the transaction
|
||||
txBytes, err := txCtx.BuildAndSign(cliCtx.FromAddressName, passphrase, msgs)
|
||||
txBytes, err := txBldr.BuildAndSign(cliCtx.FromAddressName, passphrase, msgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -50,8 +51,8 @@ func SendTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg)
|
||||
}
|
||||
|
||||
// SimulateMsgs simulates the transaction and returns the gas estimate and the adjusted value.
|
||||
func SimulateMsgs(txCtx authctx.TxContext, cliCtx context.CLIContext, name string, msgs []sdk.Msg, gas int64) (estimated, adjusted int64, err error) {
|
||||
txBytes, err := txCtx.WithGas(gas).BuildWithPubKey(name, msgs)
|
||||
func SimulateMsgs(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name string, msgs []sdk.Msg, gas int64) (estimated, adjusted int64, err error) {
|
||||
txBytes, err := txBldr.WithGas(gas).BuildWithPubKey(name, msgs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -61,19 +62,19 @@ func SimulateMsgs(txCtx authctx.TxContext, cliCtx context.CLIContext, name strin
|
||||
|
||||
// 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 string, msgs []sdk.Msg) (authctx.TxContext, error) {
|
||||
_, adjusted, err := SimulateMsgs(txCtx, cliCtx, name, msgs, 0)
|
||||
func EnrichCtxWithGas(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name string, msgs []sdk.Msg) (authtxb.TxBuilder, error) {
|
||||
_, adjusted, err := SimulateMsgs(txBldr, cliCtx, name, msgs, 0)
|
||||
if err != nil {
|
||||
return txCtx, err
|
||||
return txBldr, err
|
||||
}
|
||||
return txCtx.WithGas(adjusted), nil
|
||||
return txBldr.WithGas(adjusted), nil
|
||||
}
|
||||
|
||||
// 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
|
||||
// estimate gas and update TxBuilder accordingly
|
||||
rawRes, err := queryFunc("/app/simulate", txBytes)
|
||||
if err != nil {
|
||||
return
|
||||
@ -87,18 +88,61 @@ func CalculateGas(queryFunc func(string, common.HexBytes) ([]byte, error), cdc *
|
||||
}
|
||||
|
||||
// PrintUnsignedStdTx builds an unsigned StdTx and prints it to os.Stdout.
|
||||
func PrintUnsignedStdTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg) (err error) {
|
||||
stdTx, err := buildUnsignedStdTx(txCtx, cliCtx, msgs)
|
||||
func PrintUnsignedStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg) (err error) {
|
||||
stdTx, err := buildUnsignedStdTx(txBldr, cliCtx, msgs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
json, err := txCtx.Codec.MarshalJSON(stdTx)
|
||||
json, err := txBldr.Codec.MarshalJSON(stdTx)
|
||||
if err == nil {
|
||||
fmt.Printf("%s\n", json)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SignStdTx appends a signature to a StdTx and returns a copy of a it. If appendSig
|
||||
// is false, it replaces the signatures already attached with the new signature.
|
||||
func SignStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name string, stdTx auth.StdTx, appendSig bool) (auth.StdTx, error) {
|
||||
var signedStdTx auth.StdTx
|
||||
|
||||
keybase, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
return signedStdTx, err
|
||||
}
|
||||
info, err := keybase.Get(name)
|
||||
if err != nil {
|
||||
return signedStdTx, err
|
||||
}
|
||||
addr := info.GetPubKey().Address()
|
||||
|
||||
// Check whether the address is a signer
|
||||
if !isTxSigner(sdk.AccAddress(addr), stdTx.GetSigners()) {
|
||||
fmt.Fprintf(os.Stderr, "WARNING: The generated transaction's intended signer does not match the given signer: '%v'", name)
|
||||
}
|
||||
|
||||
if txBldr.AccountNumber == 0 {
|
||||
accNum, err := cliCtx.GetAccountNumber(addr)
|
||||
if err != nil {
|
||||
return signedStdTx, err
|
||||
}
|
||||
txBldr = txBldr.WithAccountNumber(accNum)
|
||||
}
|
||||
|
||||
if txBldr.Sequence == 0 {
|
||||
accSeq, err := cliCtx.GetAccountSequence(addr)
|
||||
if err != nil {
|
||||
return signedStdTx, err
|
||||
}
|
||||
txBldr = txBldr.WithSequence(accSeq)
|
||||
}
|
||||
|
||||
passphrase, err := keys.GetPassphrase(name)
|
||||
if err != nil {
|
||||
return signedStdTx, err
|
||||
}
|
||||
return txBldr.SignStdTx(name, passphrase, stdTx, appendSig)
|
||||
}
|
||||
|
||||
func adjustGasEstimate(estimate int64, adjustment float64) int64 {
|
||||
return int64(adjustment * float64(estimate))
|
||||
}
|
||||
@ -111,55 +155,64 @@ func parseQueryResponse(cdc *amino.Codec, rawRes []byte) (int64, error) {
|
||||
return simulationResult.GasUsed, nil
|
||||
}
|
||||
|
||||
func prepareTxContext(txCtx authctx.TxContext, cliCtx context.CLIContext) (authctx.TxContext, error) {
|
||||
func prepareTxContext(txBldr authtxb.TxBuilder, cliCtx context.CLIContext) (authtxb.TxBuilder, error) {
|
||||
if err := cliCtx.EnsureAccountExists(); err != nil {
|
||||
return txCtx, err
|
||||
return txBldr, err
|
||||
}
|
||||
|
||||
from, err := cliCtx.GetFromAddress()
|
||||
if err != nil {
|
||||
return txCtx, err
|
||||
return txBldr, err
|
||||
}
|
||||
|
||||
// TODO: (ref #1903) Allow for user supplied account number without
|
||||
// automatically doing a manual lookup.
|
||||
if txCtx.AccountNumber == 0 {
|
||||
if txBldr.AccountNumber == 0 {
|
||||
accNum, err := cliCtx.GetAccountNumber(from)
|
||||
if err != nil {
|
||||
return txCtx, err
|
||||
return txBldr, err
|
||||
}
|
||||
txCtx = txCtx.WithAccountNumber(accNum)
|
||||
txBldr = txBldr.WithAccountNumber(accNum)
|
||||
}
|
||||
|
||||
// TODO: (ref #1903) Allow for user supplied account sequence without
|
||||
// automatically doing a manual lookup.
|
||||
if txCtx.Sequence == 0 {
|
||||
if txBldr.Sequence == 0 {
|
||||
accSeq, err := cliCtx.GetAccountSequence(from)
|
||||
if err != nil {
|
||||
return txCtx, err
|
||||
return txBldr, err
|
||||
}
|
||||
txCtx = txCtx.WithSequence(accSeq)
|
||||
txBldr = txBldr.WithSequence(accSeq)
|
||||
}
|
||||
return txCtx, nil
|
||||
return txBldr, nil
|
||||
}
|
||||
|
||||
// buildUnsignedStdTx builds a StdTx as per the parameters passed in the
|
||||
// contexts. Gas is automatically estimated if gas wanted is set to 0.
|
||||
func buildUnsignedStdTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg) (stdTx auth.StdTx, err error) {
|
||||
txCtx, err = prepareTxContext(txCtx, cliCtx)
|
||||
func buildUnsignedStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, msgs []sdk.Msg) (stdTx auth.StdTx, err error) {
|
||||
txBldr, err = prepareTxContext(txBldr, cliCtx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if txCtx.Gas == 0 {
|
||||
txCtx, err = EnrichCtxWithGas(txCtx, cliCtx, cliCtx.FromAddressName, msgs)
|
||||
if txBldr.Gas == 0 {
|
||||
txBldr, err = EnrichCtxWithGas(txBldr, cliCtx, cliCtx.FromAddressName, msgs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txCtx.Gas)
|
||||
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.Gas)
|
||||
}
|
||||
stdSignMsg, err := txCtx.Build(msgs)
|
||||
stdSignMsg, err := txBldr.Build(msgs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return auth.NewStdTx(stdSignMsg.Msgs, stdSignMsg.Fee, nil, stdSignMsg.Memo), nil
|
||||
}
|
||||
|
||||
func isTxSigner(user sdk.AccAddress, signers []sdk.AccAddress) bool {
|
||||
for _, s := range signers {
|
||||
if bytes.Equal(user.Bytes(), s.Bytes()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@ -60,6 +60,7 @@ func resolveProjectPath(remoteProjectPath string) string {
|
||||
return gopath + string(os.PathSeparator) + "src" + string(os.PathSeparator) + remoteProjectPath
|
||||
}
|
||||
|
||||
// nolint: unparam, errcheck
|
||||
func copyBasecoinTemplate(projectName string, projectPath string, remoteProjectPath string) {
|
||||
basecoinProjectPath := resolveProjectPath(remoteBasecoinPath)
|
||||
filepath.Walk(basecoinProjectPath, func(path string, f os.FileInfo, err error) error {
|
||||
@ -88,6 +89,7 @@ func copyBasecoinTemplate(projectName string, projectPath string, remoteProjectP
|
||||
})
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func createGopkg(projectPath string) {
|
||||
// Create gopkg.toml file
|
||||
dependencies := map[string]string{
|
||||
@ -111,6 +113,7 @@ func createGopkg(projectPath string) {
|
||||
ioutil.WriteFile(projectPath+"/Gopkg.toml", []byte(contents), os.ModePerm)
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func createMakefile(projectPath string) {
|
||||
// Create makefile
|
||||
// TODO: Should we use tools/ directory as in Cosmos-SDK to get tools for linting etc.
|
||||
|
||||
@ -52,7 +52,7 @@ type GaiaApp struct {
|
||||
// Manage getting and setting accounts
|
||||
accountMapper auth.AccountMapper
|
||||
feeCollectionKeeper auth.FeeCollectionKeeper
|
||||
coinKeeper bank.Keeper
|
||||
bankKeeper bank.Keeper
|
||||
ibcMapper ibc.Mapper
|
||||
stakeKeeper stake.Keeper
|
||||
slashingKeeper slashing.Keeper
|
||||
@ -89,19 +89,19 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
|
||||
)
|
||||
|
||||
// add handlers
|
||||
app.coinKeeper = bank.NewKeeper(app.accountMapper)
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
||||
app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams)
|
||||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace))
|
||||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.bankKeeper, app.RegisterCodespace(stake.DefaultCodespace))
|
||||
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Getter(), app.RegisterCodespace(slashing.DefaultCodespace))
|
||||
app.stakeKeeper = app.stakeKeeper.WithValidatorHooks(app.slashingKeeper.ValidatorHooks())
|
||||
app.govKeeper = gov.NewKeeper(app.cdc, app.keyGov, app.paramsKeeper.Setter(), app.coinKeeper, app.stakeKeeper, app.RegisterCodespace(gov.DefaultCodespace))
|
||||
app.govKeeper = gov.NewKeeper(app.cdc, app.keyGov, app.paramsKeeper.Setter(), app.bankKeeper, app.stakeKeeper, app.RegisterCodespace(gov.DefaultCodespace))
|
||||
app.feeCollectionKeeper = auth.NewFeeCollectionKeeper(app.cdc, app.keyFeeCollection)
|
||||
|
||||
// register message routes
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(app.coinKeeper)).
|
||||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)).
|
||||
AddRoute("bank", bank.NewHandler(app.bankKeeper)).
|
||||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.bankKeeper)).
|
||||
AddRoute("stake", stake.NewHandler(app.stakeKeeper)).
|
||||
AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)).
|
||||
AddRoute("gov", gov.NewHandler(app.govKeeper))
|
||||
@ -190,6 +190,11 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.StakeData)
|
||||
|
||||
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
||||
err = GaiaValidateGenesisState(genesisState)
|
||||
if err != nil {
|
||||
// TODO find a way to do this w/o panics
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return abci.ResponseInitChain{
|
||||
Validators: validators,
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
@ -180,38 +181,12 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState
|
||||
}
|
||||
|
||||
// create the genesis account, give'm few steaks and a buncha token with there name
|
||||
accAuth := auth.NewBaseAccountWithAddress(genTx.Address)
|
||||
accAuth.Coins = sdk.Coins{
|
||||
{genTx.Name + "Token", sdk.NewInt(1000)},
|
||||
{"steak", freeFermionsAcc},
|
||||
}
|
||||
acc := NewGenesisAccount(&accAuth)
|
||||
genaccs[i] = acc
|
||||
genaccs[i] = genesisAccountFromGenTx(genTx)
|
||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
|
||||
|
||||
// add the validator
|
||||
if len(genTx.Name) > 0 {
|
||||
desc := stake.NewDescription(genTx.Name, "", "", "")
|
||||
validator := stake.NewValidator(
|
||||
sdk.ValAddress(genTx.Address), sdk.MustGetConsPubKeyBech32(genTx.PubKey), desc,
|
||||
)
|
||||
|
||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDec(freeFermionVal)) // increase the supply
|
||||
|
||||
// add some new shares to the validator
|
||||
var issuedDelShares sdk.Dec
|
||||
validator, stakeData.Pool, issuedDelShares = validator.AddTokensFromDel(stakeData.Pool, sdk.NewInt(freeFermionVal))
|
||||
stakeData.Validators = append(stakeData.Validators, validator)
|
||||
|
||||
// create the self-delegation from the issuedDelShares
|
||||
delegation := stake.Delegation{
|
||||
DelegatorAddr: sdk.AccAddress(validator.Operator),
|
||||
ValidatorAddr: validator.Operator,
|
||||
Shares: issuedDelShares,
|
||||
Height: 0,
|
||||
}
|
||||
|
||||
stakeData.Bonds = append(stakeData.Bonds, delegation)
|
||||
stakeData = addValidatorToStakeData(genTx, stakeData)
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,6 +199,86 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState
|
||||
return
|
||||
}
|
||||
|
||||
func addValidatorToStakeData(genTx GaiaGenTx, stakeData stake.GenesisState) stake.GenesisState {
|
||||
desc := stake.NewDescription(genTx.Name, "", "", "")
|
||||
validator := stake.NewValidator(
|
||||
sdk.ValAddress(genTx.Address), sdk.MustGetConsPubKeyBech32(genTx.PubKey), desc,
|
||||
)
|
||||
|
||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDec(freeFermionVal)) // increase the supply
|
||||
|
||||
// add some new shares to the validator
|
||||
var issuedDelShares sdk.Dec
|
||||
validator, stakeData.Pool, issuedDelShares = validator.AddTokensFromDel(stakeData.Pool, sdk.NewInt(freeFermionVal))
|
||||
stakeData.Validators = append(stakeData.Validators, validator)
|
||||
|
||||
// create the self-delegation from the issuedDelShares
|
||||
delegation := stake.Delegation{
|
||||
DelegatorAddr: sdk.AccAddress(validator.OperatorAddr),
|
||||
ValidatorAddr: validator.OperatorAddr,
|
||||
Shares: issuedDelShares,
|
||||
Height: 0,
|
||||
}
|
||||
|
||||
stakeData.Bonds = append(stakeData.Bonds, delegation)
|
||||
return stakeData
|
||||
}
|
||||
|
||||
func genesisAccountFromGenTx(genTx GaiaGenTx) GenesisAccount {
|
||||
accAuth := auth.NewBaseAccountWithAddress(genTx.Address)
|
||||
accAuth.Coins = sdk.Coins{
|
||||
{genTx.Name + "Token", sdk.NewInt(1000)},
|
||||
{"steak", freeFermionsAcc},
|
||||
}
|
||||
return NewGenesisAccount(&accAuth)
|
||||
}
|
||||
|
||||
// GaiaValidateGenesisState ensures that the genesis state obeys the expected invariants
|
||||
// TODO: No validators are both bonded and revoked (#2088)
|
||||
// TODO: Error if there is a duplicate validator (#1708)
|
||||
// TODO: Ensure all state machine parameters are in genesis (#1704)
|
||||
func GaiaValidateGenesisState(genesisState GenesisState) (err error) {
|
||||
err = validateGenesisStateAccounts(genesisState.Accounts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = validateGenesisStateValidators(genesisState.StakeData.Validators)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func validateGenesisStateValidators(validators []stakeTypes.Validator) (err error) {
|
||||
addrMap := make(map[string]bool, len(validators))
|
||||
for i := 0; i < len(validators); i++ {
|
||||
val := validators[i]
|
||||
strKey := string(val.ConsPubKey.Bytes())
|
||||
if _, ok := addrMap[strKey]; ok {
|
||||
return fmt.Errorf("Duplicate validator in genesis state: moniker %v, Address %v", val.Description.Moniker, val.ConsAddress())
|
||||
}
|
||||
if val.Jailed && val.Status == sdk.Bonded {
|
||||
return fmt.Errorf("Validator is bonded and revoked in genesis state: moniker %v, Address %v", val.Description.Moniker, val.ConsAddress())
|
||||
}
|
||||
addrMap[strKey] = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Ensures that there are no duplicate accounts in the genesis state,
|
||||
func validateGenesisStateAccounts(accs []GenesisAccount) (err error) {
|
||||
addrMap := make(map[string]bool, len(accs))
|
||||
for i := 0; i < len(accs); i++ {
|
||||
acc := accs[i]
|
||||
strAddr := string(acc.Address)
|
||||
if _, ok := addrMap[strAddr]; ok {
|
||||
return fmt.Errorf("Duplicate account in genesis state: Address %v", acc.Address)
|
||||
}
|
||||
addrMap[strAddr] = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GaiaAppGenState but with JSON
|
||||
func GaiaAppGenStateJSON(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
|
||||
|
||||
|
||||
@ -5,10 +5,50 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
)
|
||||
|
||||
var (
|
||||
pk1 = ed25519.GenPrivKey().PubKey()
|
||||
pk2 = ed25519.GenPrivKey().PubKey()
|
||||
pk3 = ed25519.GenPrivKey().PubKey()
|
||||
addr1 = sdk.ValAddress(pk1.Address())
|
||||
addr2 = sdk.ValAddress(pk2.Address())
|
||||
addr3 = sdk.ValAddress(pk3.Address())
|
||||
|
||||
emptyAddr sdk.ValAddress
|
||||
emptyPubkey crypto.PubKey
|
||||
)
|
||||
|
||||
func makeGenesisState(genTxs []GaiaGenTx) GenesisState {
|
||||
// start with the default staking genesis state
|
||||
stakeData := stake.DefaultGenesisState()
|
||||
|
||||
// get genesis flag account information
|
||||
genaccs := make([]GenesisAccount, len(genTxs))
|
||||
for i, genTx := range genTxs {
|
||||
genaccs[i] = genesisAccountFromGenTx(genTx)
|
||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
|
||||
|
||||
// add the validator
|
||||
if len(genTx.Name) > 0 {
|
||||
stakeData = addValidatorToStakeData(genTx, stakeData)
|
||||
}
|
||||
}
|
||||
|
||||
// create the final app state
|
||||
return GenesisState{
|
||||
Accounts: genaccs,
|
||||
StakeData: stakeData,
|
||||
GovData: gov.DefaultGenesisState(),
|
||||
}
|
||||
}
|
||||
|
||||
func TestToAccount(t *testing.T) {
|
||||
priv := ed25519.GenPrivKey()
|
||||
addr := sdk.AccAddress(priv.PubKey().Address())
|
||||
@ -34,3 +74,30 @@ func TestGaiaAppGenState(t *testing.T) {
|
||||
// TODO test with both one and two genesis transactions:
|
||||
// TODO correct: genesis account created, canididates created, pool token variance
|
||||
}
|
||||
|
||||
func TestGaiaGenesisValidation(t *testing.T) {
|
||||
genTxs := make([]GaiaGenTx, 2)
|
||||
addr := pk1.Address()
|
||||
// Test duplicate accounts fails
|
||||
genTxs[0] = GaiaGenTx{"", sdk.AccAddress(addr), ""}
|
||||
genTxs[1] = GaiaGenTx{"", sdk.AccAddress(addr), ""}
|
||||
genesisState := makeGenesisState(genTxs)
|
||||
err := GaiaValidateGenesisState(genesisState)
|
||||
require.NotNil(t, err)
|
||||
// Test bonded + revoked validator fails
|
||||
genesisState = makeGenesisState(genTxs[:1])
|
||||
val1 := stakeTypes.NewValidator(addr1, pk1, stakeTypes.Description{Moniker: "test #2"})
|
||||
val1.Jailed = true
|
||||
val1.Status = sdk.Bonded
|
||||
genesisState.StakeData.Validators = append(genesisState.StakeData.Validators, val1)
|
||||
err = GaiaValidateGenesisState(genesisState)
|
||||
require.NotNil(t, err)
|
||||
// Test duplicate validator fails
|
||||
val1.Jailed = false
|
||||
genesisState = makeGenesisState(genTxs[:1])
|
||||
val2 := stakeTypes.NewValidator(addr1, pk1, stakeTypes.Description{Moniker: "test #3"})
|
||||
genesisState.StakeData.Validators = append(genesisState.StakeData.Validators, val1)
|
||||
genesisState.StakeData.Validators = append(genesisState.StakeData.Validators, val2)
|
||||
err = GaiaValidateGenesisState(genesisState)
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
|
||||
@ -14,7 +14,6 @@ import (
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
@ -93,9 +92,8 @@ func appStateFn(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress) json
|
||||
func testAndRunTxs(app *GaiaApp) []simulation.Operation {
|
||||
return []simulation.Operation{
|
||||
banksim.SimulateSingleInputMsgSend(app.accountMapper),
|
||||
govsim.SimulateMsgSubmitProposal(app.govKeeper, app.stakeKeeper),
|
||||
govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, app.stakeKeeper),
|
||||
govsim.SimulateMsgDeposit(app.govKeeper, app.stakeKeeper),
|
||||
govsim.SimulateMsgVote(app.govKeeper, app.stakeKeeper),
|
||||
stakesim.SimulateMsgCreateValidator(app.accountMapper, app.stakeKeeper),
|
||||
stakesim.SimulateMsgEditValidator(app.stakeKeeper),
|
||||
stakesim.SimulateMsgDelegate(app.accountMapper, app.stakeKeeper),
|
||||
@ -109,12 +107,10 @@ func testAndRunTxs(app *GaiaApp) []simulation.Operation {
|
||||
|
||||
func invariants(app *GaiaApp) []simulation.Invariant {
|
||||
return []simulation.Invariant{
|
||||
func(t *testing.T, baseapp *baseapp.BaseApp, log string) {
|
||||
banksim.NonnegativeBalanceInvariant(app.accountMapper)(t, baseapp, log)
|
||||
govsim.AllInvariants()(t, baseapp, log)
|
||||
stakesim.AllInvariants(app.coinKeeper, app.stakeKeeper, app.accountMapper)(t, baseapp, log)
|
||||
slashingsim.AllInvariants()(t, baseapp, log)
|
||||
},
|
||||
banksim.NonnegativeBalanceInvariant(app.accountMapper),
|
||||
govsim.AllInvariants(),
|
||||
stakesim.AllInvariants(app.bankKeeper, app.stakeKeeper, app.accountMapper),
|
||||
slashingsim.AllInvariants(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,11 +5,13 @@ package clitest
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
@ -111,8 +113,17 @@ func TestGaiaCLIGasAuto(t *testing.T) {
|
||||
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)
|
||||
success, stdout, _ := executeWriteRetStdStreams(t, fmt.Sprintf("gaiacli send %v --json --gas=0 --amount=10steak --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
// check that gas wanted == gas used
|
||||
cdc := app.MakeCodec()
|
||||
jsonOutput := struct {
|
||||
Height int64
|
||||
TxHash string
|
||||
Response abci.ResponseDeliverTx
|
||||
}{}
|
||||
require.Nil(t, cdc.UnmarshalJSON([]byte(stdout), &jsonOutput))
|
||||
require.Equal(t, jsonOutput.Response.GasWanted, jsonOutput.Response.GasUsed)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
// Check state has changed accordingly
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags))
|
||||
@ -177,7 +188,7 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
require.Equal(t, int64(8), barAcc.GetCoins().AmountOf("steak").Int64(), "%v", barAcc)
|
||||
|
||||
validator := executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %s --output=json %v", sdk.ValAddress(barAddr), flags))
|
||||
require.Equal(t, validator.Operator, sdk.ValAddress(barAddr))
|
||||
require.Equal(t, validator.OperatorAddr, sdk.ValAddress(barAddr))
|
||||
require.True(sdk.DecEq(t, sdk.NewDec(2), validator.Tokens))
|
||||
|
||||
// unbond a single share
|
||||
@ -332,7 +343,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
require.Equal(t, " 2 - Apples", proposalsQuery)
|
||||
}
|
||||
|
||||
func TestGaiaCLISendGenerateOnly(t *testing.T) {
|
||||
func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) {
|
||||
chainID, servAddr, port := initializeFixtures(t)
|
||||
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
|
||||
|
||||
@ -343,6 +354,7 @@ func TestGaiaCLISendGenerateOnly(t *testing.T) {
|
||||
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))
|
||||
|
||||
// Test generate sendTx with default gas
|
||||
@ -356,16 +368,6 @@ func TestGaiaCLISendGenerateOnly(t *testing.T) {
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
require.Equal(t, 0, len(msg.GetSignatures()))
|
||||
|
||||
// Test generate sendTx, estimate gas
|
||||
success, stdout, stderr = executeWriteRetStdStreams(t, fmt.Sprintf(
|
||||
"gaiacli send %v --amount=10steak --to=%s --from=foo --gas=0 --generate-only",
|
||||
flags, barAddr), []string{}...)
|
||||
require.True(t, success)
|
||||
require.NotEmpty(t, stderr)
|
||||
msg = unmarshalStdTx(t, stdout)
|
||||
require.NotZero(t, msg.Fee.Gas)
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
|
||||
// Test generate sendTx with --gas=$amount
|
||||
success, stdout, stderr = executeWriteRetStdStreams(t, fmt.Sprintf(
|
||||
"gaiacli send %v --amount=10steak --to=%s --from=foo --gas=100 --generate-only",
|
||||
@ -376,6 +378,64 @@ func TestGaiaCLISendGenerateOnly(t *testing.T) {
|
||||
require.Equal(t, msg.Fee.Gas, int64(100))
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
require.Equal(t, 0, len(msg.GetSignatures()))
|
||||
|
||||
// Test generate sendTx, estimate gas
|
||||
success, stdout, stderr = executeWriteRetStdStreams(t, fmt.Sprintf(
|
||||
"gaiacli send %v --amount=10steak --to=%s --from=foo --gas=0 --generate-only",
|
||||
flags, barAddr), []string{}...)
|
||||
require.True(t, success)
|
||||
require.NotEmpty(t, stderr)
|
||||
msg = unmarshalStdTx(t, stdout)
|
||||
require.True(t, msg.Fee.Gas > 0)
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
|
||||
// Write the output to disk
|
||||
unsignedTxFile := writeToNewTempFile(t, stdout)
|
||||
defer os.Remove(unsignedTxFile.Name())
|
||||
|
||||
// Test sign --print-sigs
|
||||
success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf(
|
||||
"gaiacli sign %v --print-sigs %v", flags, unsignedTxFile.Name()))
|
||||
require.True(t, success)
|
||||
require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n", fooAddr.String()), stdout)
|
||||
|
||||
// Test sign
|
||||
success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf(
|
||||
"gaiacli sign %v --name=foo %v", flags, unsignedTxFile.Name()), app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
msg = unmarshalStdTx(t, stdout)
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
require.Equal(t, 1, len(msg.GetSignatures()))
|
||||
require.Equal(t, fooAddr.String(), msg.GetSigners()[0].String())
|
||||
|
||||
// Write the output to disk
|
||||
signedTxFile := writeToNewTempFile(t, stdout)
|
||||
defer os.Remove(signedTxFile.Name())
|
||||
|
||||
// Test sign --print-signatures
|
||||
success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf(
|
||||
"gaiacli sign %v --print-sigs %v", flags, signedTxFile.Name()))
|
||||
require.True(t, success)
|
||||
require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n 0: %v\n", fooAddr.String(), fooAddr.String()), stdout)
|
||||
|
||||
// Test broadcast
|
||||
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags))
|
||||
require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64())
|
||||
|
||||
success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf("gaiacli broadcast %v --json %v", flags, signedTxFile.Name()))
|
||||
require.True(t, success)
|
||||
var result struct {
|
||||
Response abci.ResponseDeliverTx
|
||||
}
|
||||
require.Nil(t, app.MakeCodec().UnmarshalJSON([]byte(stdout), &result))
|
||||
require.Equal(t, msg.Fee.Gas, result.Response.GasUsed)
|
||||
require.Equal(t, msg.Fee.Gas, result.Response.GasWanted)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
|
||||
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", barAddr, flags))
|
||||
require.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak").Int64())
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags))
|
||||
require.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak").Int64())
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
@ -408,6 +468,14 @@ func unmarshalStdTx(t *testing.T, s string) (stdTx auth.StdTx) {
|
||||
return
|
||||
}
|
||||
|
||||
func writeToNewTempFile(t *testing.T, s string) *os.File {
|
||||
fp, err := ioutil.TempFile(os.TempDir(), "cosmos_cli_test_")
|
||||
require.Nil(t, err)
|
||||
_, err = fp.WriteString(s)
|
||||
require.Nil(t, err)
|
||||
return fp
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
// executors
|
||||
|
||||
|
||||
@ -127,10 +127,12 @@ func main() {
|
||||
rootCmd.AddCommand(
|
||||
client.GetCommands(
|
||||
authcmd.GetAccountCmd("acc", cdc, authcmd.GetAccountDecoder(cdc)),
|
||||
authcmd.GetSignCommand(cdc, authcmd.GetAccountDecoder(cdc)),
|
||||
)...)
|
||||
rootCmd.AddCommand(
|
||||
client.PostCommands(
|
||||
bankcmd.SendTxCmd(cdc),
|
||||
bankcmd.GetBroadcastCommand(cdc),
|
||||
)...)
|
||||
|
||||
// add proxy, version and key info
|
||||
|
||||
@ -65,7 +65,7 @@ func runHackCmd(cmd *cobra.Command, args []string) error {
|
||||
// The following powerKey was there, but the corresponding "trouble" validator did not exist.
|
||||
// So here we do a binary search on the past states to find when the powerKey first showed up ...
|
||||
|
||||
// owner of the validator the bonds, gets revoked, later unbonds, and then later is still found in the bypower store
|
||||
// operator of the validator the bonds, gets revoked, later unbonds, and then later is still found in the bypower store
|
||||
trouble := hexToBytes("D3DC0FF59F7C3B548B7AFA365561B87FD0208AF8")
|
||||
// this is his "bypower" key
|
||||
powerKey := hexToBytes("05303030303030303030303033FFFFFFFFFFFF4C0C0000FFFED3DC0FF59F7C3B548B7AFA365561B87FD0208AF8")
|
||||
@ -140,7 +140,7 @@ type GaiaApp struct {
|
||||
// Manage getting and setting accounts
|
||||
accountMapper auth.AccountMapper
|
||||
feeCollectionKeeper auth.FeeCollectionKeeper
|
||||
coinKeeper bank.Keeper
|
||||
bankKeeper bank.Keeper
|
||||
ibcMapper ibc.Mapper
|
||||
stakeKeeper stake.Keeper
|
||||
slashingKeeper slashing.Keeper
|
||||
@ -173,16 +173,16 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.BaseAp
|
||||
)
|
||||
|
||||
// add handlers
|
||||
app.coinKeeper = bank.NewKeeper(app.accountMapper)
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
||||
app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams)
|
||||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace))
|
||||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.bankKeeper, app.RegisterCodespace(stake.DefaultCodespace))
|
||||
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Getter(), app.RegisterCodespace(slashing.DefaultCodespace))
|
||||
|
||||
// register message routes
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(app.coinKeeper)).
|
||||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)).
|
||||
AddRoute("bank", bank.NewHandler(app.bankKeeper)).
|
||||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.bankKeeper)).
|
||||
AddRoute("stake", stake.NewHandler(app.stakeKeeper))
|
||||
|
||||
// initialize BaseApp
|
||||
|
||||
@ -224,9 +224,15 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig []byte, pub t
|
||||
}
|
||||
case offlineInfo:
|
||||
linfo := info.(offlineInfo)
|
||||
fmt.Fprintf(os.Stderr, "Bytes to sign:\n%s", msg)
|
||||
_, err := fmt.Fprintf(os.Stderr, "Bytes to sign:\n%s", msg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
buf := bufio.NewReader(os.Stdin)
|
||||
fmt.Fprintf(os.Stderr, "\nEnter Amino-encoded signature:\n")
|
||||
_, err = fmt.Fprintf(os.Stderr, "\nEnter Amino-encoded signature:\n")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Will block until user inputs the signature
|
||||
signed, err := buf.ReadString('\n')
|
||||
if err != nil {
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
- [ ] 3. Merge items in `PENDING.md` into the `CHANGELOG.md`. While doing this make sure that each entry contains links to issues/PRs for each item
|
||||
- [ ] 4. Summarize breaking API changes section under “Breaking Changes” section to the `CHANGELOG.md` to bring attention to any breaking API changes that affect RPC consumers.
|
||||
- [ ] 5. Tag the commit `{ .Release.Name }-rcN`
|
||||
- [ ] 6. Kick off 1 day of automated fuzz testing
|
||||
- [ ] 7. Release Lead assigns 2 people to perform [buddy testing script](/docs/RELEASE_TEST_SCRIPT.md) and update the relevant documentation
|
||||
- [ ] 8. If errors are found in either #6 or #7 go back to #2 (*NOTE*: be sure to increment the `rcN`)
|
||||
- [ ] 9. After #6 and #7 have successfully completed then merge the release PR and push the final release tag
|
||||
- [ ] 6. Open a branch & PR to merge the pending release back into `develop`. If any changes are made to the release branch, they must also be made to the pending develop merge, and both must pass tests.
|
||||
- [ ] 7. Kick off 1 day of automated fuzz testing
|
||||
- [ ] 8. Release Lead assigns 2 people to perform [buddy testing script](/docs/RELEASE_TEST_SCRIPT.md) and update the relevant documentation
|
||||
- [ ] 9. If errors are found in either #6 or #7 go back to #2 (*NOTE*: be sure to increment the `rcN`)
|
||||
- [ ] 10. After #6 and #7 have successfully completed then merge the release PR and push the final release tag
|
||||
|
||||
@ -213,7 +213,7 @@ Note that the distribution scenario structures are found in `state.md`.
|
||||
#### Delegation's entitlement to Global.Pool
|
||||
|
||||
For delegations (including validator's self-delegation) all fees from fee pool
|
||||
are subject to commission rate from the owner of the validator. The global
|
||||
are subject to commission rate from the operator of the validator. The global
|
||||
shares should be taken as true number of global bonded shares. The recipients
|
||||
shares should be taken as the bonded tokens less the validator's commission.
|
||||
|
||||
|
||||
@ -714,7 +714,7 @@ definitions:
|
||||
ValidatorAddress:
|
||||
type: string
|
||||
description: bech32 encoded addres
|
||||
example: cosmosval:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
example: cosmosvaloper:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
PubKey:
|
||||
type: string
|
||||
description: bech32 encoded public key
|
||||
@ -722,7 +722,7 @@ definitions:
|
||||
ValidatorPubKey:
|
||||
type: string
|
||||
description: bech32 encoded public key
|
||||
example: cosmosvalpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
example: cosmosvalconspub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
Coins:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@ -226,6 +226,113 @@ Returns on success:
|
||||
"sequence": 7
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### POST /auth/tx/sign
|
||||
|
||||
- **URL**: `/auth/tx/sign`
|
||||
- **Functionality**: Sign a transaction without broadcasting it.
|
||||
- Returns on success:
|
||||
|
||||
```json
|
||||
{
|
||||
"rest api": "1.0",
|
||||
"code": 200,
|
||||
"error": "",
|
||||
"result": {
|
||||
"type": "auth/StdTx",
|
||||
"value": {
|
||||
"msg": [
|
||||
{
|
||||
"type": "cosmos-sdk/Send",
|
||||
"value": {
|
||||
"inputs": [
|
||||
{
|
||||
"address": "cosmos1ql4ekxkujf3xllk8h5ldhhgh4ylpu7kwec6q3d",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "steak",
|
||||
"amount": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "cosmos1dhyqhg4px33ed3erqymls0hc7q2lxw9hhfwklj",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "steak",
|
||||
"amount": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"fee": {
|
||||
"amount": [
|
||||
{
|
||||
"denom": "",
|
||||
"amount": "0"
|
||||
}
|
||||
],
|
||||
"gas": "2742"
|
||||
},
|
||||
"signatures": [
|
||||
{
|
||||
"pub_key": {
|
||||
"type": "tendermint/PubKeySecp256k1",
|
||||
"value": "A2A/f2IYnrPUMTMqhwN81oas9jurtfcsvxdeLlNw3gGy"
|
||||
},
|
||||
"signature": "MEQCIGVn73y9QLwBa3vmsAD1bs3ygX75Wo+lAFSAUDs431ZPAiBWAf2amyqTCDXE9J87rL9QF9sd5JvVMt7goGSuamPJwg==",
|
||||
"account_number": "1",
|
||||
"sequence": "0"
|
||||
}
|
||||
],
|
||||
"memo": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### POST /auth/tx/broadcast
|
||||
|
||||
- **URL**: `/auth/broadcast`
|
||||
- **Functionality**: Broadcast a transaction.
|
||||
- Returns on success:
|
||||
|
||||
```json
|
||||
{
|
||||
"rest api": "1.0",
|
||||
"code": 200,
|
||||
"error": "",
|
||||
"result":
|
||||
{
|
||||
"check_tx": {
|
||||
"log": "Msg 0: ",
|
||||
"gasWanted": "2742",
|
||||
"gasUsed": "1002"
|
||||
},
|
||||
"deliver_tx": {
|
||||
"log": "Msg 0: ",
|
||||
"gasWanted": "2742",
|
||||
"gasUsed": "2742",
|
||||
"tags": [
|
||||
{
|
||||
"key": "c2VuZGVy",
|
||||
"value": "Y29zbW9zMXdjNTl6ZXU3MmNjdnp5ZWR6ZGE1N3pzcXh2eXZ2Y3poaHBhdDI4"
|
||||
},
|
||||
{
|
||||
"key": "cmVjaXBpZW50",
|
||||
"value": "Y29zbW9zMTJ4OTNmY3V2azg3M3o1ejZnejRlNTl2dnlxcXp1eDdzdDcwNWd5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"hash": "784314784503582AC885BD6FB0D2A5B79FF703A7",
|
||||
"height": "5"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -22,17 +22,17 @@ There are three types of key representations that are used:
|
||||
- Derived from account keys generated by `gaiacli keys add`
|
||||
- Used to receive funds
|
||||
- e.g. `cosmos15h6vd5f0wqps26zjlwrc6chah08ryu4hzzdwhc`
|
||||
* `cosmosval`
|
||||
* `cosmosvaloper`
|
||||
* Used to associate a validator to it's operator
|
||||
* Used to invoke staking commands
|
||||
* e.g. `cosmosval1carzvgq3e6y3z5kz5y6gxp3wpy3qdrv928vyah`
|
||||
* e.g. `cosmosvaloper1carzvgq3e6y3z5kz5y6gxp3wpy3qdrv928vyah`
|
||||
- `cosmospub`
|
||||
- Derived from account keys generated by `gaiacli keys add`
|
||||
- e.g. `cosmospub1zcjduc3q7fu03jnlu2xpl75s2nkt7krm6grh4cc5aqth73v0zwmea25wj2hsqhlqzm`
|
||||
- `cosmosconspub`
|
||||
- `cosmosvalconspub`
|
||||
- Generated when the node is created with `gaiad init`.
|
||||
- Get this value with `gaiad tendermint show-validator`
|
||||
- e.g. `cosmosconspub1zcjduepq0ms2738680y72v44tfyqm3c9ppduku8fs6sr73fx7m666sjztznqzp2emf`
|
||||
- e.g. `cosmosvalconspub1zcjduepq0ms2738680y72v44tfyqm3c9ppduku8fs6sr73fx7m666sjztznqzp2emf`
|
||||
|
||||
#### Generate Keys
|
||||
|
||||
@ -147,7 +147,22 @@ gaiacli send \
|
||||
--chain-id=<chain_id> \
|
||||
--name=<key_name> \
|
||||
--to=<destination_cosmosaccaddr> \
|
||||
--generate-only
|
||||
--generate-only > unsignedSendTx.json
|
||||
```
|
||||
|
||||
You can now sign the transaction file generated through the `--generate-only` flag by providing your key to the following command:
|
||||
|
||||
```bash
|
||||
gaiacli sign \
|
||||
--chain-id=<chain_id> \
|
||||
--name=<key_name>
|
||||
unsignedSendTx.json > signedSendTx.json
|
||||
```
|
||||
|
||||
You can broadcast the signed transaction to a node by providing the JSON file to the following command:
|
||||
|
||||
```
|
||||
gaiacli broadcast --node=<node> signedSendTx.json
|
||||
```
|
||||
|
||||
### Staking
|
||||
|
||||
@ -285,7 +285,7 @@ it can't increment sequence numbers, change PubKeys, or otherwise.
|
||||
A `bank.Keeper` is easily instantiated from an `AccountMapper`:
|
||||
|
||||
```go
|
||||
coinKeeper = bank.NewKeeper(accountMapper)
|
||||
bankKeeper = bank.NewBaseKeeper(accountMapper)
|
||||
```
|
||||
|
||||
We can then use it within a handler, instead of working directly with the
|
||||
@ -295,7 +295,7 @@ We can then use it within a handler, instead of working directly with the
|
||||
// Finds account with addr in AccountMapper.
|
||||
// Adds coins to account's coin array.
|
||||
// Sets updated account in AccountMapper
|
||||
app.coinKeeper.AddCoins(ctx, addr, coins)
|
||||
app.bankKeeper.AddCoins(ctx, addr, coins)
|
||||
```
|
||||
|
||||
See the [bank.Keeper API
|
||||
@ -336,7 +336,7 @@ func NewApp3(logger log.Logger, db dbm.DB) *bapp.BaseApp {
|
||||
|
||||
// Set various mappers/keepers to interact easily with underlying stores
|
||||
accountMapper := auth.NewAccountMapper(cdc, keyAccount, auth.ProtoBaseAccount)
|
||||
coinKeeper := bank.NewKeeper(accountMapper)
|
||||
bankKeeper := bank.NewBaseKeeper(accountMapper)
|
||||
feeKeeper := auth.NewFeeCollectionKeeper(cdc, keyFees)
|
||||
|
||||
app.SetAnteHandler(auth.NewAnteHandler(accountMapper, feeKeeper))
|
||||
@ -344,7 +344,7 @@ func NewApp3(logger log.Logger, db dbm.DB) *bapp.BaseApp {
|
||||
// Register message routes.
|
||||
// Note the handler gets access to
|
||||
app.Router().
|
||||
AddRoute("send", bank.NewHandler(coinKeeper))
|
||||
AddRoute("send", bank.NewHandler(bankKeeper))
|
||||
|
||||
// Mount stores and load the latest state.
|
||||
app.MountStoresIAVL(keyAccount, keyFees)
|
||||
|
||||
@ -31,7 +31,7 @@ func NewApp3(logger log.Logger, db dbm.DB) *bapp.BaseApp {
|
||||
|
||||
// Set various mappers/keepers to interact easily with underlying stores
|
||||
accountMapper := auth.NewAccountMapper(cdc, keyAccount, auth.ProtoBaseAccount)
|
||||
coinKeeper := bank.NewKeeper(accountMapper)
|
||||
bankKeeper := bank.NewBaseKeeper(accountMapper)
|
||||
feeKeeper := auth.NewFeeCollectionKeeper(cdc, keyFees)
|
||||
|
||||
app.SetAnteHandler(auth.NewAnteHandler(accountMapper, feeKeeper))
|
||||
@ -39,7 +39,7 @@ func NewApp3(logger log.Logger, db dbm.DB) *bapp.BaseApp {
|
||||
// Register message routes.
|
||||
// Note the handler gets access to
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(coinKeeper))
|
||||
AddRoute("bank", bank.NewHandler(bankKeeper))
|
||||
|
||||
// Mount stores and load the latest state.
|
||||
app.MountStoresIAVL(keyAccount, keyFees)
|
||||
|
||||
@ -29,7 +29,7 @@ func NewApp4(logger log.Logger, db dbm.DB) *bapp.BaseApp {
|
||||
|
||||
// Set various mappers/keepers to interact easily with underlying stores
|
||||
accountMapper := auth.NewAccountMapper(cdc, keyAccount, auth.ProtoBaseAccount)
|
||||
coinKeeper := bank.NewKeeper(accountMapper)
|
||||
bankKeeper := bank.NewBaseKeeper(accountMapper)
|
||||
|
||||
// TODO
|
||||
keyFees := sdk.NewKVStoreKey("fee")
|
||||
@ -43,7 +43,7 @@ func NewApp4(logger log.Logger, db dbm.DB) *bapp.BaseApp {
|
||||
// Register message routes.
|
||||
// Note the handler gets access to the account store.
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(coinKeeper))
|
||||
AddRoute("bank", bank.NewHandler(bankKeeper))
|
||||
|
||||
// Mount stores and load the latest state.
|
||||
app.MountStoresIAVL(keyAccount, keyFees)
|
||||
|
||||
@ -33,16 +33,16 @@ var cdc = MakeCodec()
|
||||
- Instantiate the keepers. Note that keepers generally need access to other module's keepers. In this case, make sure you only pass an instance of the keeper for the functionality that is needed. If a keeper only needs to read in another module's store, a read-only keeper should be passed to it.
|
||||
|
||||
```go
|
||||
app.coinKeeper = bank.NewKeeper(app.accountMapper)
|
||||
app.stakeKeeper = simplestake.NewKeeper(app.capKeyStakingStore, app.coinKeeper,app.RegisterCodespace(simplestake.DefaultCodespace))
|
||||
app.simpleGovKeeper = simpleGov.NewKeeper(app.capKeySimpleGovStore, app.coinKeeper, app.stakeKeeper, app.RegisterCodespace(simpleGov.DefaultCodespace))
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
||||
app.stakeKeeper = simplestake.NewKeeper(app.capKeyStakingStore, app.bankKeeper,app.RegisterCodespace(simplestake.DefaultCodespace))
|
||||
app.simpleGovKeeper = simpleGov.NewKeeper(app.capKeySimpleGovStore, app.bankKeeper, app.stakeKeeper, app.RegisterCodespace(simpleGov.DefaultCodespace))
|
||||
```
|
||||
|
||||
- Declare the handlers.
|
||||
|
||||
```go
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(app.coinKeeper)).
|
||||
AddRoute("bank", bank.NewHandler(app.bankKeeper)).
|
||||
AddRoute("simplestake", simplestake.NewHandler(app.stakeKeeper)).
|
||||
AddRoute("simpleGov", simpleGov.NewHandler(app.simpleGovKeeper))
|
||||
```
|
||||
|
||||
@ -38,7 +38,7 @@ type SimpleGovApp struct {
|
||||
|
||||
// keepers
|
||||
feeCollectionKeeper auth.FeeCollectionKeeper
|
||||
coinKeeper bank.Keeper
|
||||
bankKeeper bank.Keeper
|
||||
stakeKeeper simplestake.Keeper
|
||||
simpleGovKeeper simpleGov.Keeper
|
||||
|
||||
|
||||
@ -6,14 +6,14 @@ In the Cosmos network, keys and addresses may refer to a number of different rol
|
||||
|
||||
## HRP table
|
||||
|
||||
| HRP | Definition |
|
||||
|---------------|--------------------------------------|
|
||||
| cosmos | Cosmos Account Address |
|
||||
| cosmospub | Cosmos Account Public Key |
|
||||
| cosmoscons | Cosmos Consensus Address |
|
||||
| cosmosconspub | Cosmos Consensus Public Key |
|
||||
| cosmosval | Cosmos Validator Operator Address |
|
||||
| cosmosvalpub | Cosmos Validator Operator Public Key |
|
||||
| HRP | Definition |
|
||||
|-------------------|---------------------------------------|
|
||||
| cosmos | Cosmos Account Address |
|
||||
| cosmospub | Cosmos Account Public Key |
|
||||
| cosmosvalcons | Cosmos Validator Consensus Address |
|
||||
| cosmosvalconspub | Cosmos Validator Consensus Public Key |
|
||||
| cosmosvaloper | Cosmos Validator Operator Address |
|
||||
| cosmosvaloperpub | Cosmos Validator Operator Public Key |
|
||||
|
||||
## Encoding
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ type Pool struct {
|
||||
BondedTokens int64 // reserve of bonded tokens
|
||||
InflationLastTime int64 // block which the last inflation was processed // TODO make time
|
||||
Inflation sdk.Dec // current annual inflation rate
|
||||
|
||||
|
||||
DateLastCommissionReset int64 // unix timestamp for last commission accounting reset (daily)
|
||||
}
|
||||
```
|
||||
@ -29,41 +29,40 @@ overall functioning of the stake module.
|
||||
```golang
|
||||
type Params struct {
|
||||
InflationRateChange sdk.Dec // maximum annual change in inflation rate
|
||||
InflationMax sdk.Dec // maximum inflation rate
|
||||
InflationMin sdk.Dec // minimum inflation rate
|
||||
GoalBonded sdk.Dec // Goal of percent bonded atoms
|
||||
InflationMax sdk.Dec // maximum inflation rate
|
||||
InflationMin sdk.Dec // minimum inflation rate
|
||||
GoalBonded sdk.Dec // Goal of percent bonded atoms
|
||||
|
||||
MaxValidators uint16 // maximum number of validators
|
||||
BondDenom string // bondable coin denomination
|
||||
MaxValidators uint16 // maximum number of validators
|
||||
BondDenom string // bondable coin denomination
|
||||
}
|
||||
```
|
||||
|
||||
### Validator
|
||||
|
||||
Validators are identified according to the `ValOwnerAddr`,
|
||||
an SDK account address for the owner of the validator.
|
||||
Validators are identified according to the `OperatorAddr`, an SDK validator
|
||||
address for the operator of the validator.
|
||||
|
||||
Validators also have a `ValTendermintAddr`, the address
|
||||
of the public key of the validator.
|
||||
Validators also have a `ConsPubKey`, the public key of the validator.
|
||||
|
||||
Validators are indexed in the store using the following maps:
|
||||
|
||||
- Validators: `0x02 | ValOwnerAddr -> amino(validator)`
|
||||
- ValidatorsByPubKey: `0x03 | ValTendermintAddr -> ValOwnerAddr`
|
||||
- ValidatorsByPower: `0x05 | power | blockHeight | blockTx -> ValOwnerAddr`
|
||||
- Validators: `0x02 | OperatorAddr -> amino(validator)`
|
||||
- ValidatorsByPubKey: `0x03 | ConsPubKey -> OperatorAddr`
|
||||
- ValidatorsByPower: `0x05 | power | blockHeight | blockTx -> OperatorAddr`
|
||||
|
||||
`Validators` is the primary index - it ensures that each owner can have only one
|
||||
associated validator, where the public key of that validator can change in the
|
||||
future. Delegators can refer to the immutable owner of the validator, without
|
||||
concern for the changing public key.
|
||||
`Validators` is the primary index - it ensures that each operator can have only one
|
||||
associated validator, where the public key of that validator can change in the
|
||||
future. Delegators can refer to the immutable operator of the validator, without
|
||||
concern for the changing public key.
|
||||
|
||||
`ValidatorsByPubKey` is a secondary index that enables lookups for slashing.
|
||||
When Tendermint reports evidence, it provides the validator address, so this
|
||||
map is needed to find the owner.
|
||||
`ValidatorsByPubKey` is a secondary index that enables lookups for slashing.
|
||||
When Tendermint reports evidence, it provides the validator address, so this
|
||||
map is needed to find the operator.
|
||||
|
||||
`ValidatorsByPower` is a secondary index that provides a sorted list of
|
||||
potential validators to quickly determine the current active set. For instance,
|
||||
the first 100 validators in this list can be returned with every EndBlock.
|
||||
`ValidatorsByPower` is a secondary index that provides a sorted list of
|
||||
potential validators to quickly determine the current active set. For instance,
|
||||
the first 100 validators in this list can be returned with every EndBlock.
|
||||
|
||||
The `Validator` holds the current state and some historical actions of the
|
||||
validator.
|
||||
@ -72,18 +71,18 @@ validator.
|
||||
type Validator struct {
|
||||
ConsensusPubKey crypto.PubKey // Tendermint consensus pubkey of validator
|
||||
Jailed bool // has the validator been jailed?
|
||||
|
||||
Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
|
||||
Tokens sdk.Dec // delegated tokens (incl. self-delegation)
|
||||
|
||||
Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
|
||||
Tokens sdk.Dec // delegated tokens (incl. self-delegation)
|
||||
DelegatorShares sdk.Dec // total shares issued to a validator's delegators
|
||||
SlashRatio sdk.Dec // increases each time the validator is slashed
|
||||
|
||||
|
||||
Description Description // description terms for the validator
|
||||
|
||||
|
||||
// Needed for ordering vals in the by-power key
|
||||
BondHeight int64 // earliest height as a bonded validator
|
||||
BondIntraTxCounter int16 // block-local tx index of validator change
|
||||
|
||||
|
||||
CommissionInfo CommissionInfo // info about the validator's commission
|
||||
}
|
||||
|
||||
@ -96,42 +95,41 @@ type CommissionInfo struct {
|
||||
}
|
||||
|
||||
type Description struct {
|
||||
Moniker string // name
|
||||
Identity string // optional identity signature (ex. UPort or Keybase)
|
||||
Website string // optional website link
|
||||
Details string // optional details
|
||||
Moniker string // name
|
||||
Identity string // optional identity signature (ex. UPort or Keybase)
|
||||
Website string // optional website link
|
||||
Details string // optional details
|
||||
}
|
||||
```
|
||||
|
||||
### Delegation
|
||||
|
||||
Delegations are identified by combining `DelegatorAddr` (the address of the delegator) with the ValOwnerAddr
|
||||
Delegators are indexed in the store as follows:
|
||||
Delegations are identified by combining `DelegatorAddr` (the address of the delegator)
|
||||
with the `OperatorAddr` Delegators are indexed in the store as follows:
|
||||
|
||||
- Delegation: ` 0x0A | DelegatorAddr | ValOwnerAddr -> amino(delegation)`
|
||||
- Delegation: ` 0x0A | DelegatorAddr | OperatorAddr -> amino(delegation)`
|
||||
|
||||
Atom holders may delegate coins to validators; under this circumstance their
|
||||
funds are held in a `Delegation` data structure. It is owned by one
|
||||
delegator, and is associated with the shares for one validator. The sender of
|
||||
funds are held in a `Delegation` data structure. It is owned by one
|
||||
delegator, and is associated with the shares for one validator. The sender of
|
||||
the transaction is the owner of the bond.
|
||||
|
||||
```golang
|
||||
type Delegation struct {
|
||||
Shares sdk.Dec // delegation shares recieved
|
||||
Height int64 // last height bond updated
|
||||
Shares sdk.Dec // delegation shares received
|
||||
Height int64 // last height bond updated
|
||||
}
|
||||
```
|
||||
|
||||
### UnbondingDelegation
|
||||
|
||||
Shares in a `Delegation` can be unbonded, but they must for some time exist as an `UnbondingDelegation`,
|
||||
where shares can be reduced if Byzantine behaviour is detected.
|
||||
Shares in a `Delegation` can be unbonded, but they must for some time exist as an `UnbondingDelegation`, where shares can be reduced if Byzantine behavior is detected.
|
||||
|
||||
`UnbondingDelegation` are indexed in the store as:
|
||||
|
||||
- UnbondingDelegationByDelegator: ` 0x0B | DelegatorAddr | ValOwnerAddr ->
|
||||
- UnbondingDelegationByDelegator: ` 0x0B | DelegatorAddr | OperatorAddr ->
|
||||
amino(unbondingDelegation)`
|
||||
- UnbondingDelegationByValOwner: ` 0x0C | ValOwnerAddr | DelegatorAddr | ValOwnerAddr ->
|
||||
- UnbondingDelegationByValOwner: ` 0x0C | OperatorAddr | DelegatorAddr | OperatorAddr ->
|
||||
nil`
|
||||
|
||||
The first map here is used in queries, to lookup all unbonding delegations for
|
||||
@ -148,26 +146,26 @@ type UnbondingDelegation struct {
|
||||
Tokens sdk.Coins // the value in Atoms of the amount of shares which are unbonding
|
||||
CompleteTime int64 // unix time to complete redelegation
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### Redelegation
|
||||
|
||||
Shares in a `Delegation` can be rebonded to a different validator, but they must for some time exist as a `Redelegation`,
|
||||
where shares can be reduced if Byzantine behaviour is detected. This is tracked
|
||||
as moving a delegation from a `FromValOwnerAddr` to a `ToValOwnerAddr`.
|
||||
Shares in a `Delegation` can be rebonded to a different validator, but they must
|
||||
for some time exist as a `Redelegation`, where shares can be reduced if Byzantine
|
||||
behavior is detected. This is tracked as moving a delegation from a `FromOperatorAddr`
|
||||
to a `ToOperatorAddr`.
|
||||
|
||||
`Redelegation` are indexed in the store as:
|
||||
|
||||
- Redelegations: `0x0D | DelegatorAddr | FromValOwnerAddr | ToValOwnerAddr ->
|
||||
- Redelegations: `0x0D | DelegatorAddr | FromOperatorAddr | ToOperatorAddr ->
|
||||
amino(redelegation)`
|
||||
- RedelegationsBySrc: `0x0E | FromValOwnerAddr | ToValOwnerAddr |
|
||||
- RedelegationsBySrc: `0x0E | FromOperatorAddr | ToOperatorAddr |
|
||||
DelegatorAddr -> nil`
|
||||
- RedelegationsByDst: `0x0F | ToValOwnerAddr | FromValOwnerAddr | DelegatorAddr
|
||||
- RedelegationsByDst: `0x0F | ToOperatorAddr | FromOperatorAddr | DelegatorAddr
|
||||
-> nil`
|
||||
|
||||
|
||||
The first map here is used for queries, to lookup all redelegations for a given
|
||||
delegator. The second map is used for slashing based on the FromValOwnerAddr,
|
||||
delegator. The second map is used for slashing based on the `FromOperatorAddr`,
|
||||
while the third map is for slashing based on the ToValOwnerAddr.
|
||||
|
||||
A redelegation object is created every time a redelegation occurs. The
|
||||
|
||||
@ -77,14 +77,14 @@ We view testnet participation as a great way to signal to the community that you
|
||||
|
||||
In short, there are two types of keys:
|
||||
|
||||
* **Tendermint Key**: This is a unique key used to sign block hashes. It is associated with a public key `cosmosconspub`.
|
||||
* **Tendermint Key**: This is a unique key used to sign block hashes. It is associated with a public key `cosmosvalconspub`.
|
||||
* Generated when the node is created with gaiad init.
|
||||
* Get this value with `gaiad tendermint show-validator`
|
||||
e.g. `cosmosconspub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c`
|
||||
e.g. `cosmosvalconspub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c`
|
||||
|
||||
* **Application keys**: These keys are created from the application and used to sign transactions. As a validator, you will probably use one key to sign staking-related transactions, and another key to sign governance-related transactions. Application keys are associated with a public key `cosmospub` and an address `cosmos`. Both are derived from account keys generated by `gaiacli keys add`.
|
||||
* Note: A validator's operator key is directly tied to an application key, but
|
||||
uses reserved prefixes solely for this purpose: `cosmosval` and `cosmosvalpub`
|
||||
uses reserved prefixes solely for this purpose: `cosmosvaloper` and `cosmosvaloperpub`
|
||||
|
||||
### What are the different states a validator can be in?
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ If you want to become a validator for the Hub's `mainnet`, you should [research
|
||||
|
||||
### Create Your Validator
|
||||
|
||||
Your `cosmosconspub` can be used to create a new validator by staking tokens. You can find your validator pubkey by running:
|
||||
Your `cosmosvalconspub` can be used to create a new validator by staking tokens. You can find your validator pubkey by running:
|
||||
|
||||
```bash
|
||||
gaiad tendermint show-validator
|
||||
|
||||
@ -37,7 +37,7 @@ type BasecoinApp struct {
|
||||
// manage getting and setting accounts
|
||||
accountMapper auth.AccountMapper
|
||||
feeCollectionKeeper auth.FeeCollectionKeeper
|
||||
coinKeeper bank.Keeper
|
||||
bankKeeper bank.Keeper
|
||||
ibcMapper ibc.Mapper
|
||||
}
|
||||
|
||||
@ -67,13 +67,13 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.Ba
|
||||
return &types.AppAccount{}
|
||||
},
|
||||
)
|
||||
app.coinKeeper = bank.NewKeeper(app.accountMapper)
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
||||
app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||
|
||||
// register message routes
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(app.coinKeeper)).
|
||||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper))
|
||||
AddRoute("bank", bank.NewHandler(app.bankKeeper)).
|
||||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.bankKeeper))
|
||||
|
||||
// perform initialization logic
|
||||
app.SetInitChainer(app.initChainer)
|
||||
|
||||
@ -41,7 +41,7 @@ type DemocoinApp struct {
|
||||
|
||||
// keepers
|
||||
feeCollectionKeeper auth.FeeCollectionKeeper
|
||||
coinKeeper bank.Keeper
|
||||
bankKeeper bank.Keeper
|
||||
coolKeeper cool.Keeper
|
||||
powKeeper pow.Keeper
|
||||
ibcMapper ibc.Mapper
|
||||
@ -75,17 +75,17 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp {
|
||||
)
|
||||
|
||||
// Add handlers.
|
||||
app.coinKeeper = bank.NewKeeper(app.accountMapper)
|
||||
app.coolKeeper = cool.NewKeeper(app.capKeyMainStore, app.coinKeeper, app.RegisterCodespace(cool.DefaultCodespace))
|
||||
app.powKeeper = pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), app.coinKeeper, app.RegisterCodespace(pow.DefaultCodespace))
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
||||
app.coolKeeper = cool.NewKeeper(app.capKeyMainStore, app.bankKeeper, app.RegisterCodespace(cool.DefaultCodespace))
|
||||
app.powKeeper = pow.NewKeeper(app.capKeyPowStore, pow.NewConfig("pow", int64(1)), app.bankKeeper, app.RegisterCodespace(pow.DefaultCodespace))
|
||||
app.ibcMapper = ibc.NewMapper(app.cdc, app.capKeyIBCStore, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||
app.stakeKeeper = simplestake.NewKeeper(app.capKeyStakingStore, app.coinKeeper, app.RegisterCodespace(simplestake.DefaultCodespace))
|
||||
app.stakeKeeper = simplestake.NewKeeper(app.capKeyStakingStore, app.bankKeeper, app.RegisterCodespace(simplestake.DefaultCodespace))
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(app.coinKeeper)).
|
||||
AddRoute("bank", bank.NewHandler(app.bankKeeper)).
|
||||
AddRoute("cool", cool.NewHandler(app.coolKeeper)).
|
||||
AddRoute("pow", app.powKeeper.Handler).
|
||||
AddRoute("sketchy", sketchy.NewHandler()).
|
||||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)).
|
||||
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.bankKeeper)).
|
||||
AddRoute("simplestake", simplestake.NewHandler(app.stakeKeeper))
|
||||
|
||||
// Initialize BaseApp.
|
||||
|
||||
@ -62,6 +62,7 @@ func GetAssocKey(base sdk.ValAddress, assoc sdk.ValAddress) []byte {
|
||||
}
|
||||
|
||||
// Associate associates new address with validator address
|
||||
// nolint: unparam
|
||||
func (valset ValidatorSet) Associate(ctx sdk.Context, base sdk.ValAddress, assoc sdk.ValAddress) bool {
|
||||
if len(base) != valset.addrLen || len(assoc) != valset.addrLen {
|
||||
return false
|
||||
@ -76,6 +77,7 @@ func (valset ValidatorSet) Associate(ctx sdk.Context, base sdk.ValAddress, assoc
|
||||
}
|
||||
|
||||
// Dissociate removes association between addresses
|
||||
// nolint: unparam
|
||||
func (valset ValidatorSet) Dissociate(ctx sdk.Context, base sdk.ValAddress, assoc sdk.ValAddress) bool {
|
||||
if len(base) != valset.addrLen || len(assoc) != valset.addrLen {
|
||||
return false
|
||||
@ -90,6 +92,7 @@ func (valset ValidatorSet) Dissociate(ctx sdk.Context, base sdk.ValAddress, asso
|
||||
}
|
||||
|
||||
// Associations returns all associated addresses with a validator
|
||||
// nolint: unparam
|
||||
func (valset ValidatorSet) Associations(ctx sdk.Context, base sdk.ValAddress) (res []sdk.ValAddress) {
|
||||
res = make([]sdk.ValAddress, valset.maxAssoc)
|
||||
iter := sdk.KVStorePrefixIterator(valset.store, GetAssocPrefix(base))
|
||||
|
||||
@ -49,8 +49,8 @@ func getMockApp(t *testing.T) *mock.App {
|
||||
|
||||
RegisterWire(mapp.Cdc)
|
||||
keyCool := sdk.NewKVStoreKey("cool")
|
||||
coinKeeper := bank.NewKeeper(mapp.AccountMapper)
|
||||
keeper := NewKeeper(keyCool, coinKeeper, mapp.RegisterCodespace(DefaultCodespace))
|
||||
bankKeeper := bank.NewBaseKeeper(mapp.AccountMapper)
|
||||
keeper := NewKeeper(keyCool, bankKeeper, mapp.RegisterCodespace(DefaultCodespace))
|
||||
mapp.Router().AddRoute("cool", NewHandler(keeper))
|
||||
|
||||
mapp.SetInitChainer(getInitChainer(mapp, keeper, "ice-cold"))
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
)
|
||||
|
||||
// QuizTxCmd invokes the coolness quiz transaction.
|
||||
@ -21,7 +21,7 @@ func QuizTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
Short: "What's cooler than being cool?",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -34,7 +34,7 @@ func QuizTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
msg := cool.NewMsgQuiz(from, args[0])
|
||||
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -46,7 +46,7 @@ func SetTrendTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
Short: "You're so cool, tell us what is cool!",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -59,7 +59,7 @@ func SetTrendTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
msg := cool.NewMsgSetTrend(from, args[0])
|
||||
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ func TestCoolKeeper(t *testing.T) {
|
||||
|
||||
am := auth.NewAccountMapper(cdc, capKey, auth.ProtoBaseAccount)
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
|
||||
ck := bank.NewKeeper(am)
|
||||
ck := bank.NewBaseKeeper(am)
|
||||
keeper := NewKeeper(capKey, ck, DefaultCodespace)
|
||||
|
||||
err := InitGenesis(ctx, keeper, Genesis{"icy"})
|
||||
|
||||
@ -25,9 +25,9 @@ func getMockApp(t *testing.T) *mock.App {
|
||||
|
||||
RegisterWire(mapp.Cdc)
|
||||
keyPOW := sdk.NewKVStoreKey("pow")
|
||||
coinKeeper := bank.NewKeeper(mapp.AccountMapper)
|
||||
bankKeeper := bank.NewBaseKeeper(mapp.AccountMapper)
|
||||
config := Config{"pow", 1}
|
||||
keeper := NewKeeper(keyPOW, config, coinKeeper, mapp.RegisterCodespace(DefaultCodespace))
|
||||
keeper := NewKeeper(keyPOW, config, bankKeeper, mapp.RegisterCodespace(DefaultCodespace))
|
||||
mapp.Router().AddRoute("pow", keeper.Handler)
|
||||
|
||||
mapp.SetInitChainer(getInitChainer(mapp, keeper))
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -22,7 +22,7 @@ func MineCmd(cdc *wire.Codec) *cobra.Command {
|
||||
Short: "Mine some coins with proof-of-work!",
|
||||
Args: cobra.ExactArgs(4),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -53,7 +53,7 @@ func MineCmd(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
// Build and sign the transaction, then broadcast to a Tendermint
|
||||
// node.
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ func TestPowHandler(t *testing.T) {
|
||||
am := auth.NewAccountMapper(cdc, capKey, auth.ProtoBaseAccount)
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
|
||||
config := NewConfig("pow", int64(1))
|
||||
ck := bank.NewKeeper(am)
|
||||
ck := bank.NewBaseKeeper(am)
|
||||
keeper := NewKeeper(capKey, config, ck, DefaultCodespace)
|
||||
|
||||
handler := keeper.Handler
|
||||
|
||||
@ -35,7 +35,7 @@ func TestPowKeeperGetSet(t *testing.T) {
|
||||
am := auth.NewAccountMapper(cdc, capKey, auth.ProtoBaseAccount)
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
|
||||
config := NewConfig("pow", int64(1))
|
||||
ck := bank.NewKeeper(am)
|
||||
ck := bank.NewBaseKeeper(am)
|
||||
keeper := NewKeeper(capKey, config, ck, DefaultCodespace)
|
||||
|
||||
err := InitGenesis(ctx, keeper, Genesis{uint64(1), uint64(0)})
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
@ -30,7 +30,7 @@ func BondTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
Use: "bond",
|
||||
Short: "Bond to a validator",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -68,7 +68,7 @@ func BondTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
// Build and sign the transaction, then broadcast to a Tendermint
|
||||
// node.
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ func UnbondTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
Use: "unbond",
|
||||
Short: "Unbond from a validator",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout)
|
||||
@ -98,7 +98,7 @@ func UnbondTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
// Build and sign the transaction, then broadcast to a Tendermint
|
||||
// node.
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -21,13 +21,13 @@ type Keeper struct {
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
|
||||
func NewKeeper(key sdk.StoreKey, coinKeeper bank.Keeper, codespace sdk.CodespaceType) Keeper {
|
||||
func NewKeeper(key sdk.StoreKey, bankKeeper bank.Keeper, codespace sdk.CodespaceType) Keeper {
|
||||
cdc := wire.NewCodec()
|
||||
wire.RegisterCrypto(cdc)
|
||||
return Keeper{
|
||||
key: key,
|
||||
cdc: cdc,
|
||||
ck: coinKeeper,
|
||||
ck: bankKeeper,
|
||||
codespace: codespace,
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ func TestKeeperGetSet(t *testing.T) {
|
||||
auth.RegisterBaseAccount(cdc)
|
||||
|
||||
accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount)
|
||||
stakeKeeper := NewKeeper(capKey, bank.NewKeeper(accountMapper), DefaultCodespace)
|
||||
stakeKeeper := NewKeeper(capKey, bank.NewBaseKeeper(accountMapper), DefaultCodespace)
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
|
||||
addr := sdk.AccAddress([]byte("some-address"))
|
||||
|
||||
@ -66,8 +66,8 @@ func TestBonding(t *testing.T) {
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
|
||||
|
||||
accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount)
|
||||
coinKeeper := bank.NewKeeper(accountMapper)
|
||||
stakeKeeper := NewKeeper(capKey, coinKeeper, DefaultCodespace)
|
||||
bankKeeper := bank.NewBaseKeeper(accountMapper)
|
||||
stakeKeeper := NewKeeper(capKey, bankKeeper, DefaultCodespace)
|
||||
addr := sdk.AccAddress([]byte("some-address"))
|
||||
privKey := ed25519.GenPrivKey()
|
||||
pubKey := privKey.PubKey()
|
||||
|
||||
13
scripts/linkify_changelog.py
Normal file
13
scripts/linkify_changelog.py
Normal file
@ -0,0 +1,13 @@
|
||||
import fileinput
|
||||
import re
|
||||
|
||||
# This script goes through the provided file, and replaces any " \#<number>",
|
||||
# with the valid mark down formatted link to it. e.g.
|
||||
# " [\#number](https://github.com/cosmos/cosmos-sdk/issues/<number>)
|
||||
# Note that if the number is for a PR, github will auto-redirect you when you click the link.
|
||||
# It is safe to run the script multiple times in succession.
|
||||
#
|
||||
# Example usage $ python3 linkify_changelog.py ../PENDING.md
|
||||
for line in fileinput.input(inplace=1):
|
||||
line = re.sub(r"\s\\#([0-9]*)", r" [\\#\1](https://github.com/cosmos/cosmos-sdk/issues/\1)", line.rstrip())
|
||||
print(line)
|
||||
@ -344,6 +344,7 @@ func readOrCreatePrivValidator(tmConfig *cfg.Config) crypto.PubKey {
|
||||
|
||||
// writeGenesisFile creates and writes the genesis configuration to disk. An
|
||||
// error is returned if building or writing the configuration to file fails.
|
||||
// nolint: unparam
|
||||
func writeGenesisFile(cdc *wire.Codec, genesisFile, chainID string, validators []tmtypes.GenesisValidator, appState json.RawMessage) error {
|
||||
genDoc := tmtypes.GenesisDoc{
|
||||
ChainID: chainID,
|
||||
|
||||
@ -84,6 +84,7 @@ func startStandAlone(ctx *Context, appCreator AppCreator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func startInProcess(ctx *Context, appCreator AppCreator) (*node.Node, error) {
|
||||
cfg := ctx.Config
|
||||
home := cfg.RootDir
|
||||
|
||||
@ -20,7 +20,7 @@ const (
|
||||
|
||||
// load the iavl store
|
||||
func LoadIAVLStore(db dbm.DB, id CommitID, pruning sdk.PruningStrategy) (CommitStore, error) {
|
||||
tree := iavl.NewVersionedTree(db, defaultIAVLCacheSize)
|
||||
tree := iavl.NewMutableTree(db, defaultIAVLCacheSize)
|
||||
_, err := tree.LoadVersion(id.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -40,7 +40,7 @@ var _ Queryable = (*iavlStore)(nil)
|
||||
type iavlStore struct {
|
||||
|
||||
// The underlying tree.
|
||||
tree *iavl.VersionedTree
|
||||
tree *iavl.MutableTree
|
||||
|
||||
// How many old versions we hold onto.
|
||||
// A value of 0 means keep no recent states.
|
||||
@ -56,7 +56,8 @@ type iavlStore struct {
|
||||
}
|
||||
|
||||
// CONTRACT: tree should be fully loaded.
|
||||
func newIAVLStore(tree *iavl.VersionedTree, numRecent int64, storeEvery int64) *iavlStore {
|
||||
// nolint: unparam
|
||||
func newIAVLStore(tree *iavl.MutableTree, numRecent int64, storeEvery int64) *iavlStore {
|
||||
st := &iavlStore{
|
||||
tree: tree,
|
||||
numRecent: numRecent,
|
||||
@ -95,7 +96,7 @@ func (st *iavlStore) Commit() CommitID {
|
||||
// Implements Committer.
|
||||
func (st *iavlStore) LastCommitID() CommitID {
|
||||
return CommitID{
|
||||
Version: st.tree.Version64(),
|
||||
Version: st.tree.Version(),
|
||||
Hash: st.tree.Hash(),
|
||||
}
|
||||
}
|
||||
@ -167,19 +168,19 @@ func (st *iavlStore) Gas(meter GasMeter, config GasConfig) KVStore {
|
||||
|
||||
// Implements KVStore.
|
||||
func (st *iavlStore) Iterator(start, end []byte) Iterator {
|
||||
return newIAVLIterator(st.tree.Tree(), start, end, true)
|
||||
return newIAVLIterator(st.tree.ImmutableTree, start, end, true)
|
||||
}
|
||||
|
||||
// Implements KVStore.
|
||||
func (st *iavlStore) ReverseIterator(start, end []byte) Iterator {
|
||||
return newIAVLIterator(st.tree.Tree(), start, end, false)
|
||||
return newIAVLIterator(st.tree.ImmutableTree, start, end, false)
|
||||
}
|
||||
|
||||
// Handle gatest the latest height, if height is 0
|
||||
func getHeight(tree *iavl.VersionedTree, req abci.RequestQuery) int64 {
|
||||
func getHeight(tree *iavl.MutableTree, req abci.RequestQuery) int64 {
|
||||
height := req.Height
|
||||
if height == 0 {
|
||||
latest := tree.Version64()
|
||||
latest := tree.Version()
|
||||
if tree.VersionExists(latest - 1) {
|
||||
height = latest - 1
|
||||
} else {
|
||||
@ -255,7 +256,7 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
// Implements Iterator.
|
||||
type iavlIterator struct {
|
||||
// Underlying store
|
||||
tree *iavl.Tree
|
||||
tree *iavl.ImmutableTree
|
||||
|
||||
// Domain
|
||||
start, end []byte
|
||||
@ -286,7 +287,7 @@ var _ Iterator = (*iavlIterator)(nil)
|
||||
// newIAVLIterator will create a new iavlIterator.
|
||||
// CONTRACT: Caller must release the iavlIterator, as each one creates a new
|
||||
// goroutine.
|
||||
func newIAVLIterator(tree *iavl.Tree, start, end []byte, ascending bool) *iavlIterator {
|
||||
func newIAVLIterator(tree *iavl.ImmutableTree, start, end []byte, ascending bool) *iavlIterator {
|
||||
iter := &iavlIterator{
|
||||
tree: tree,
|
||||
start: cp(start),
|
||||
|
||||
@ -29,8 +29,8 @@ var (
|
||||
)
|
||||
|
||||
// make a tree and save it
|
||||
func newTree(t *testing.T, db dbm.DB) (*iavl.VersionedTree, CommitID) {
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
func newTree(t *testing.T, db dbm.DB) (*iavl.MutableTree, CommitID) {
|
||||
tree := iavl.NewMutableTree(db, cacheSize)
|
||||
for k, v := range treeData {
|
||||
tree.Set([]byte(k), []byte(v))
|
||||
}
|
||||
@ -325,7 +325,7 @@ type pruneState struct {
|
||||
|
||||
func testPruning(t *testing.T, numRecent int64, storeEvery int64, states []pruneState) {
|
||||
db := dbm.NewMemDB()
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
tree := iavl.NewMutableTree(db, cacheSize)
|
||||
iavlStore := newIAVLStore(tree, numRecent, storeEvery)
|
||||
for step, state := range states {
|
||||
for _, ver := range state.stored {
|
||||
@ -344,7 +344,7 @@ func testPruning(t *testing.T, numRecent int64, storeEvery int64, states []prune
|
||||
|
||||
func TestIAVLNoPrune(t *testing.T) {
|
||||
db := dbm.NewMemDB()
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
tree := iavl.NewMutableTree(db, cacheSize)
|
||||
iavlStore := newIAVLStore(tree, numRecent, int64(1))
|
||||
nextVersion(iavlStore)
|
||||
for i := 1; i < 100; i++ {
|
||||
@ -359,7 +359,7 @@ func TestIAVLNoPrune(t *testing.T) {
|
||||
|
||||
func TestIAVLPruneEverything(t *testing.T) {
|
||||
db := dbm.NewMemDB()
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
tree := iavl.NewMutableTree(db, cacheSize)
|
||||
iavlStore := newIAVLStore(tree, int64(0), int64(0))
|
||||
nextVersion(iavlStore)
|
||||
for i := 1; i < 100; i++ {
|
||||
@ -377,7 +377,7 @@ func TestIAVLPruneEverything(t *testing.T) {
|
||||
|
||||
func TestIAVLStoreQuery(t *testing.T) {
|
||||
db := dbm.NewMemDB()
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
tree := iavl.NewMutableTree(db, cacheSize)
|
||||
iavlStore := newIAVLStore(tree, numRecent, storeEvery)
|
||||
|
||||
k1, v1 := []byte("key1"), []byte("val1")
|
||||
@ -468,7 +468,7 @@ func TestIAVLStoreQuery(t *testing.T) {
|
||||
func BenchmarkIAVLIteratorNext(b *testing.B) {
|
||||
db := dbm.NewMemDB()
|
||||
treeSize := 1000
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
tree := iavl.NewMutableTree(db, cacheSize)
|
||||
for i := 0; i < treeSize; i++ {
|
||||
key := cmn.RandBytes(4)
|
||||
value := cmn.RandBytes(50)
|
||||
|
||||
@ -2,10 +2,12 @@ package store
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tendermint/iavl"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
"testing"
|
||||
"github.com/tendermint/tendermint/libs/db"
|
||||
)
|
||||
|
||||
func TestVerifyMultiStoreCommitInfo(t *testing.T) {
|
||||
@ -91,7 +93,7 @@ func TestVerifyMultiStoreCommitInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVerifyRangeProof(t *testing.T) {
|
||||
tree := iavl.NewTree(nil, 0)
|
||||
tree := iavl.NewMutableTree(db.NewMemDB(), 0)
|
||||
|
||||
rand := cmn.NewRand()
|
||||
rand.Seed(0) // for determinism
|
||||
@ -100,7 +102,7 @@ func TestVerifyRangeProof(t *testing.T) {
|
||||
tree.Set(key, []byte(rand.Str(8)))
|
||||
}
|
||||
|
||||
root := tree.Hash()
|
||||
root := tree.WorkingHash()
|
||||
|
||||
key := []byte{0x32}
|
||||
val, proof, err := tree.GetWithProof(key)
|
||||
|
||||
@ -66,7 +66,7 @@ func testPrefixStore(t *testing.T, baseStore KVStore, prefix []byte) {
|
||||
|
||||
func TestIAVLStorePrefix(t *testing.T) {
|
||||
db := dbm.NewMemDB()
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
tree := iavl.NewMutableTree(db, cacheSize)
|
||||
iavlStore := newIAVLStore(tree, numRecent, storeEvery)
|
||||
|
||||
testPrefixStore(t, iavlStore, []byte("test"))
|
||||
|
||||
@ -179,6 +179,7 @@ func (tkv *TraceKVStore) CacheWrapWithTrace(_ io.Writer, _ TraceContext) CacheWr
|
||||
|
||||
// writeOperation writes a KVStore operation to the underlying io.Writer as
|
||||
// JSON-encoded data where the key/value pair is base64 encoded.
|
||||
// nolint: errcheck
|
||||
func writeOperation(w io.Writer, op operation, tc TraceContext, key, value []byte) {
|
||||
traceOp := traceOperation{
|
||||
Operation: op,
|
||||
|
||||
@ -156,8 +156,8 @@ func TestTestTraceKVStoreIterator(t *testing.T) {
|
||||
iterator := store.Iterator(nil, nil)
|
||||
|
||||
s, e := iterator.Domain()
|
||||
require.Equal(t, []uint8([]byte(nil)), s)
|
||||
require.Equal(t, []uint8([]byte(nil)), e)
|
||||
require.Equal(t, []byte(nil), s)
|
||||
require.Equal(t, []byte(nil), e)
|
||||
|
||||
testCases := []struct {
|
||||
expectedKey []byte
|
||||
@ -212,8 +212,8 @@ func TestTestTraceKVStoreReverseIterator(t *testing.T) {
|
||||
iterator := store.ReverseIterator(nil, nil)
|
||||
|
||||
s, e := iterator.Domain()
|
||||
require.Equal(t, []uint8([]byte(nil)), s)
|
||||
require.Equal(t, []uint8([]byte(nil)), e)
|
||||
require.Equal(t, []byte(nil), s)
|
||||
require.Equal(t, []byte(nil), e)
|
||||
|
||||
testCases := []struct {
|
||||
expectedKey []byte
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
)
|
||||
|
||||
@ -41,3 +42,8 @@ func (ts *transientStore) Prefix(prefix []byte) KVStore {
|
||||
func (ts *transientStore) Gas(meter GasMeter, config GasConfig) KVStore {
|
||||
return NewGasKVStore(meter, config, ts)
|
||||
}
|
||||
|
||||
// Implements Store.
|
||||
func (ts *transientStore) GetStoreType() StoreType {
|
||||
return sdk.StoreTypeTransient
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
|
||||
// ExecuteT executes the command, pipes any input to STDIN and return STDOUT,
|
||||
// logging STDOUT/STDERR to t.
|
||||
// nolint: errcheck
|
||||
func ExecuteT(t *testing.T, cmd, input string) (out string) {
|
||||
t.Log("Running", cmn.Cyan(cmd))
|
||||
|
||||
|
||||
@ -22,13 +22,13 @@ const (
|
||||
// Bech32PrefixAccPub defines the Bech32 prefix of an account's public key
|
||||
Bech32PrefixAccPub = "cosmospub"
|
||||
// Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address
|
||||
Bech32PrefixValAddr = "cosmosval"
|
||||
Bech32PrefixValAddr = "cosmosvaloper"
|
||||
// Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key
|
||||
Bech32PrefixValPub = "cosmosvalpub"
|
||||
Bech32PrefixValPub = "cosmosvaloperpub"
|
||||
// Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address
|
||||
Bech32PrefixConsAddr = "cosmoscons"
|
||||
Bech32PrefixConsAddr = "cosmosvalcons"
|
||||
// Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key
|
||||
Bech32PrefixConsPub = "cosmosconspub"
|
||||
Bech32PrefixConsPub = "cosmosvalconspub"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -133,6 +133,7 @@ func (aa AccAddress) String() string {
|
||||
}
|
||||
|
||||
// Format implements the fmt.Formatter interface.
|
||||
// nolint: errcheck
|
||||
func (aa AccAddress) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
@ -145,7 +146,7 @@ func (aa AccAddress) Format(s fmt.State, verb rune) {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// validator owner
|
||||
// validator operator
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ValAddress defines a wrapper around bytes meant to present a validator's
|
||||
@ -247,6 +248,7 @@ func (va ValAddress) String() string {
|
||||
}
|
||||
|
||||
// Format implements the fmt.Formatter interface.
|
||||
// nolint: errcheck
|
||||
func (va ValAddress) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
@ -361,6 +363,7 @@ func (ca ConsAddress) String() string {
|
||||
}
|
||||
|
||||
// Format implements the fmt.Formatter interface.
|
||||
// nolint: errcheck
|
||||
func (ca ConsAddress) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
@ -30,6 +30,7 @@ type Context struct {
|
||||
}
|
||||
|
||||
// create a new context
|
||||
// nolint: unparam
|
||||
func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, logger log.Logger) Context {
|
||||
c := Context{
|
||||
Context: context.Background(),
|
||||
|
||||
@ -219,6 +219,7 @@ func (err *sdkError) WithDefaultCodespace(cs CodespaceType) Error {
|
||||
}
|
||||
|
||||
// Implements ABCIError.
|
||||
// nolint: errcheck
|
||||
func (err *sdkError) TraceSDK(format string, args ...interface{}) Error {
|
||||
err.Trace(1, format, args...)
|
||||
return err
|
||||
|
||||
@ -40,7 +40,7 @@ type Validator interface {
|
||||
GetJailed() bool // whether the validator is jailed
|
||||
GetMoniker() string // moniker of the validator
|
||||
GetStatus() BondStatus // status of the validator
|
||||
GetOperator() ValAddress // owner address to receive/return validators coins
|
||||
GetOperator() ValAddress // operator address to receive/return validators coins
|
||||
GetPubKey() crypto.PubKey // validation pubkey
|
||||
GetPower() Dec // validation power
|
||||
GetTokens() Dec // validation tokens
|
||||
@ -59,11 +59,11 @@ func ABCIValidator(v Validator) abci.Validator {
|
||||
|
||||
// properties for the set of all validators
|
||||
type ValidatorSet interface {
|
||||
// iterate through validator by owner-AccAddress, execute func for each validator
|
||||
// iterate through validators by operator address, execute func for each validator
|
||||
IterateValidators(Context,
|
||||
func(index int64, validator Validator) (stop bool))
|
||||
|
||||
// iterate through bonded validator by pubkey-AccAddress, execute func for each validator
|
||||
// iterate through bonded validators by operator address, execute func for each validator
|
||||
IterateValidatorsBonded(Context,
|
||||
func(index int64, validator Validator) (stop bool))
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -190,6 +191,13 @@ func processSig(
|
||||
return
|
||||
}
|
||||
|
||||
var dummySecp256k1Pubkey secp256k1.PubKeySecp256k1
|
||||
|
||||
func init() {
|
||||
bz, _ := hex.DecodeString("035AD6810A47F073553FF30D2FCC7E0D3B1C0B74B61A1AAA2582344037151E143A")
|
||||
copy(dummySecp256k1Pubkey[:], bz)
|
||||
}
|
||||
|
||||
func processPubKey(acc Account, sig StdSignature, simulate bool) (crypto.PubKey, sdk.Result) {
|
||||
// If pubkey is not known for account,
|
||||
// set it from the StdSignature.
|
||||
@ -200,7 +208,7 @@ func processPubKey(acc Account, sig StdSignature, simulate bool) (crypto.PubKey,
|
||||
// and gasKVStore.Set() shall consume the largest amount, i.e.
|
||||
// it takes more gas to verifiy secp256k1 keys than ed25519 ones.
|
||||
if pubKey == nil {
|
||||
return secp256k1.GenPrivKey().PubKey(), sdk.Result{}
|
||||
return dummySecp256k1Pubkey, sdk.Result{}
|
||||
}
|
||||
return pubKey, sdk.Result{}
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ func GetAccountDecoder(cdc *wire.Codec) auth.AccountDecoder {
|
||||
|
||||
// GetAccountCmd returns a query account that will display the state of the
|
||||
// account at a given address.
|
||||
// nolint: unparam
|
||||
func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "account [address]",
|
||||
|
||||
91
x/auth/client/cli/sign.go
Normal file
91
x/auth/client/cli/sign.go
Normal file
@ -0,0 +1,91 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"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/x/auth"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
"github.com/spf13/cobra"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
)
|
||||
|
||||
const (
|
||||
flagAppend = "append"
|
||||
flagPrintSigs = "print-sigs"
|
||||
)
|
||||
|
||||
// GetSignCommand returns the sign command
|
||||
func GetSignCommand(codec *amino.Codec, decoder auth.AccountDecoder) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "sign <file>",
|
||||
Short: "Sign transactions",
|
||||
Long: `Sign transactions created with the --generate-only flag.
|
||||
Read a transaction from <file>, sign it, and print its JSON encoding.`,
|
||||
RunE: makeSignCmd(codec, decoder),
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
cmd.Flags().String(client.FlagName, "", "Name of private key with which to sign")
|
||||
cmd.Flags().Bool(flagAppend, true, "Append the signature to the existing ones. If disabled, old signatures would be overwritten")
|
||||
cmd.Flags().Bool(flagPrintSigs, false, "Print the addresses that must sign the transaction and those who have already signed it, then exit")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra.Command, args []string) error {
|
||||
return func(cmd *cobra.Command, args []string) (err error) {
|
||||
stdTx, err := readAndUnmarshalStdTx(cdc, args[0])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if viper.GetBool(flagPrintSigs) {
|
||||
printSignatures(stdTx)
|
||||
return nil
|
||||
}
|
||||
|
||||
name := viper.GetString(client.FlagName)
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(decoder)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI()
|
||||
|
||||
newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, viper.GetBool(flagAppend))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
json, err := cdc.MarshalJSON(newTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s\n", json)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func printSignatures(stdTx auth.StdTx) {
|
||||
fmt.Println("Signers:")
|
||||
for i, signer := range stdTx.GetSigners() {
|
||||
fmt.Printf(" %v: %v\n", i, signer.String())
|
||||
}
|
||||
fmt.Println("")
|
||||
fmt.Println("Signatures:")
|
||||
for i, sig := range stdTx.GetSignatures() {
|
||||
fmt.Printf(" %v: %v\n", i, sdk.AccAddress(sig.Address()).String())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func readAndUnmarshalStdTx(cdc *amino.Codec, filename string) (stdTx auth.StdTx, err error) {
|
||||
var bytes []byte
|
||||
if bytes, err = ioutil.ReadFile(filename); err != nil {
|
||||
return
|
||||
}
|
||||
if err = cdc.UnmarshalJSON(bytes, &stdTx); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -1,179 +0,0 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// TxContext implements a transaction context created in SDK modules.
|
||||
type TxContext struct {
|
||||
Codec *wire.Codec
|
||||
AccountNumber int64
|
||||
Sequence int64
|
||||
Gas int64
|
||||
ChainID string
|
||||
Memo string
|
||||
Fee string
|
||||
}
|
||||
|
||||
// NewTxContextFromCLI returns a new initialized TxContext with parameters from
|
||||
// the command line using Viper.
|
||||
func NewTxContextFromCLI() TxContext {
|
||||
// if chain ID is not specified manually, read default chain ID
|
||||
chainID := viper.GetString(client.FlagChainID)
|
||||
if chainID == "" {
|
||||
defaultChainID, err := defaultChainID()
|
||||
if err != nil {
|
||||
chainID = defaultChainID
|
||||
}
|
||||
}
|
||||
|
||||
return TxContext{
|
||||
ChainID: chainID,
|
||||
Gas: viper.GetInt64(client.FlagGas),
|
||||
AccountNumber: viper.GetInt64(client.FlagAccountNumber),
|
||||
Sequence: viper.GetInt64(client.FlagSequence),
|
||||
Fee: viper.GetString(client.FlagFee),
|
||||
Memo: viper.GetString(client.FlagMemo),
|
||||
}
|
||||
}
|
||||
|
||||
// WithCodec returns a copy of the context with an updated codec.
|
||||
func (ctx TxContext) WithCodec(cdc *wire.Codec) TxContext {
|
||||
ctx.Codec = cdc
|
||||
return ctx
|
||||
}
|
||||
|
||||
// WithChainID returns a copy of the context with an updated chainID.
|
||||
func (ctx TxContext) WithChainID(chainID string) TxContext {
|
||||
ctx.ChainID = chainID
|
||||
return ctx
|
||||
}
|
||||
|
||||
// WithGas returns a copy of the context with an updated gas.
|
||||
func (ctx TxContext) WithGas(gas int64) TxContext {
|
||||
ctx.Gas = gas
|
||||
return ctx
|
||||
}
|
||||
|
||||
// WithFee returns a copy of the context with an updated fee.
|
||||
func (ctx TxContext) WithFee(fee string) TxContext {
|
||||
ctx.Fee = fee
|
||||
return ctx
|
||||
}
|
||||
|
||||
// WithSequence returns a copy of the context with an updated sequence number.
|
||||
func (ctx TxContext) WithSequence(sequence int64) TxContext {
|
||||
ctx.Sequence = sequence
|
||||
return ctx
|
||||
}
|
||||
|
||||
// WithMemo returns a copy of the context with an updated memo.
|
||||
func (ctx TxContext) WithMemo(memo string) TxContext {
|
||||
ctx.Memo = memo
|
||||
return ctx
|
||||
}
|
||||
|
||||
// WithAccountNumber returns a copy of the context with an account number.
|
||||
func (ctx TxContext) WithAccountNumber(accnum int64) TxContext {
|
||||
ctx.AccountNumber = accnum
|
||||
return ctx
|
||||
}
|
||||
|
||||
// Build builds a single message to be signed from a TxContext given a set of
|
||||
// messages. It returns an error if a fee is supplied but cannot be parsed.
|
||||
func (ctx TxContext) Build(msgs []sdk.Msg) (auth.StdSignMsg, error) {
|
||||
chainID := ctx.ChainID
|
||||
if chainID == "" {
|
||||
return auth.StdSignMsg{}, errors.Errorf("chain ID required but not specified")
|
||||
}
|
||||
|
||||
fee := sdk.Coin{}
|
||||
if ctx.Fee != "" {
|
||||
parsedFee, err := sdk.ParseCoin(ctx.Fee)
|
||||
if err != nil {
|
||||
return auth.StdSignMsg{}, err
|
||||
}
|
||||
|
||||
fee = parsedFee
|
||||
}
|
||||
|
||||
return auth.StdSignMsg{
|
||||
ChainID: ctx.ChainID,
|
||||
AccountNumber: ctx.AccountNumber,
|
||||
Sequence: ctx.Sequence,
|
||||
Memo: ctx.Memo,
|
||||
Msgs: msgs,
|
||||
Fee: auth.NewStdFee(ctx.Gas, fee),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Sign signs a transaction given a name, passphrase, and a single message to
|
||||
// signed. An error is returned if signing fails.
|
||||
func (ctx TxContext) Sign(name, passphrase string, msg auth.StdSignMsg) ([]byte, error) {
|
||||
keybase, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig, pubkey, err := keybase.Sign(name, passphrase, msg.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sigs := []auth.StdSignature{{
|
||||
AccountNumber: msg.AccountNumber,
|
||||
Sequence: msg.Sequence,
|
||||
PubKey: pubkey,
|
||||
Signature: sig,
|
||||
}}
|
||||
|
||||
return ctx.Codec.MarshalBinary(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
|
||||
}
|
||||
|
||||
// BuildAndSign builds a single message to be signed, and signs a transaction
|
||||
// with the built message given a name, passphrase, and a set of
|
||||
// messages.
|
||||
func (ctx TxContext) BuildAndSign(name, passphrase string, msgs []sdk.Msg) ([]byte, error) {
|
||||
msg, err := ctx.Build(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ctx.Sign(name, passphrase, msg)
|
||||
}
|
||||
|
||||
// BuildWithPubKey builds a single message to be signed from a TxContext given a set of
|
||||
// messages and attach the public key associated to the given name.
|
||||
// It returns an error if a fee is supplied but cannot be parsed or the key cannot be
|
||||
// retrieved.
|
||||
func (ctx TxContext) BuildWithPubKey(name string, msgs []sdk.Msg) ([]byte, error) {
|
||||
msg, err := ctx.Build(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keybase, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info, err := keybase.Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sigs := []auth.StdSignature{{
|
||||
AccountNumber: msg.AccountNumber,
|
||||
Sequence: msg.Sequence,
|
||||
PubKey: info.GetPubKey(),
|
||||
}}
|
||||
|
||||
return ctx.Codec.MarshalBinary(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
|
||||
}
|
||||
@ -20,6 +20,10 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, s
|
||||
"/accounts/{address}",
|
||||
QueryAccountRequestHandlerFn(storeName, cdc, authcmd.GetAccountDecoder(cdc), cliCtx),
|
||||
).Methods("GET")
|
||||
r.HandleFunc(
|
||||
"/tx/sign",
|
||||
SignTxRequestHandlerFn(cdc, cliCtx),
|
||||
).Methods("POST")
|
||||
}
|
||||
|
||||
// query accountREST Handler
|
||||
|
||||
61
x/auth/client/rest/sign.go
Normal file
61
x/auth/client/rest/sign.go
Normal file
@ -0,0 +1,61 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
)
|
||||
|
||||
// SignBody defines the properties of a sign request's body.
|
||||
type SignBody struct {
|
||||
Tx auth.StdTx `json:"tx"`
|
||||
LocalAccountName string `json:"name"`
|
||||
Password string `json:"password"`
|
||||
ChainID string `json:"chain_id"`
|
||||
AccountNumber int64 `json:"account_number"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
AppendSig bool `json:"append_sig"`
|
||||
}
|
||||
|
||||
// sign tx REST handler
|
||||
func SignTxRequestHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var m SignBody
|
||||
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = cdc.UnmarshalJSON(body, &m)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
txBldr := authtxb.TxBuilder{
|
||||
ChainID: m.ChainID,
|
||||
AccountNumber: m.AccountNumber,
|
||||
Sequence: m.Sequence,
|
||||
}
|
||||
|
||||
signedTx, err := txBldr.SignStdTx(m.LocalAccountName, m.Password, m.Tx, m.AppendSig)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
output, err := wire.MarshalJSONIndent(cdc, signedTx)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
w.Write(output)
|
||||
}
|
||||
}
|
||||
209
x/auth/client/txbuilder/txbuilder.go
Normal file
209
x/auth/client/txbuilder/txbuilder.go
Normal file
@ -0,0 +1,209 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// TxBuilder implements a transaction context created in SDK modules.
|
||||
type TxBuilder struct {
|
||||
Codec *wire.Codec
|
||||
AccountNumber int64
|
||||
Sequence int64
|
||||
Gas int64
|
||||
ChainID string
|
||||
Memo string
|
||||
Fee string
|
||||
}
|
||||
|
||||
// NewTxBuilderFromCLI returns a new initialized TxBuilder with parameters from
|
||||
// the command line using Viper.
|
||||
func NewTxBuilderFromCLI() TxBuilder {
|
||||
// if chain ID is not specified manually, read default chain ID
|
||||
chainID := viper.GetString(client.FlagChainID)
|
||||
if chainID == "" {
|
||||
defaultChainID, err := defaultChainID()
|
||||
if err != nil {
|
||||
chainID = defaultChainID
|
||||
}
|
||||
}
|
||||
|
||||
return TxBuilder{
|
||||
ChainID: chainID,
|
||||
Gas: viper.GetInt64(client.FlagGas),
|
||||
AccountNumber: viper.GetInt64(client.FlagAccountNumber),
|
||||
Sequence: viper.GetInt64(client.FlagSequence),
|
||||
Fee: viper.GetString(client.FlagFee),
|
||||
Memo: viper.GetString(client.FlagMemo),
|
||||
}
|
||||
}
|
||||
|
||||
// WithCodec returns a copy of the context with an updated codec.
|
||||
func (bldr TxBuilder) WithCodec(cdc *wire.Codec) TxBuilder {
|
||||
bldr.Codec = cdc
|
||||
return bldr
|
||||
}
|
||||
|
||||
// WithChainID returns a copy of the context with an updated chainID.
|
||||
func (bldr TxBuilder) WithChainID(chainID string) TxBuilder {
|
||||
bldr.ChainID = chainID
|
||||
return bldr
|
||||
}
|
||||
|
||||
// WithGas returns a copy of the context with an updated gas.
|
||||
func (bldr TxBuilder) WithGas(gas int64) TxBuilder {
|
||||
bldr.Gas = gas
|
||||
return bldr
|
||||
}
|
||||
|
||||
// WithFee returns a copy of the context with an updated fee.
|
||||
func (bldr TxBuilder) WithFee(fee string) TxBuilder {
|
||||
bldr.Fee = fee
|
||||
return bldr
|
||||
}
|
||||
|
||||
// WithSequence returns a copy of the context with an updated sequence number.
|
||||
func (bldr TxBuilder) WithSequence(sequence int64) TxBuilder {
|
||||
bldr.Sequence = sequence
|
||||
return bldr
|
||||
}
|
||||
|
||||
// WithMemo returns a copy of the context with an updated memo.
|
||||
func (bldr TxBuilder) WithMemo(memo string) TxBuilder {
|
||||
bldr.Memo = memo
|
||||
return bldr
|
||||
}
|
||||
|
||||
// WithAccountNumber returns a copy of the context with an account number.
|
||||
func (bldr TxBuilder) WithAccountNumber(accnum int64) TxBuilder {
|
||||
bldr.AccountNumber = accnum
|
||||
return bldr
|
||||
}
|
||||
|
||||
// Build builds a single message to be signed from a TxBuilder given a set of
|
||||
// messages. It returns an error if a fee is supplied but cannot be parsed.
|
||||
func (bldr TxBuilder) Build(msgs []sdk.Msg) (auth.StdSignMsg, error) {
|
||||
chainID := bldr.ChainID
|
||||
if chainID == "" {
|
||||
return auth.StdSignMsg{}, errors.Errorf("chain ID required but not specified")
|
||||
}
|
||||
|
||||
fee := sdk.Coin{}
|
||||
if bldr.Fee != "" {
|
||||
parsedFee, err := sdk.ParseCoin(bldr.Fee)
|
||||
if err != nil {
|
||||
return auth.StdSignMsg{}, err
|
||||
}
|
||||
|
||||
fee = parsedFee
|
||||
}
|
||||
|
||||
return auth.StdSignMsg{
|
||||
ChainID: bldr.ChainID,
|
||||
AccountNumber: bldr.AccountNumber,
|
||||
Sequence: bldr.Sequence,
|
||||
Memo: bldr.Memo,
|
||||
Msgs: msgs,
|
||||
Fee: auth.NewStdFee(bldr.Gas, fee),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Sign signs a transaction given a name, passphrase, and a single message to
|
||||
// signed. An error is returned if signing fails.
|
||||
func (bldr TxBuilder) Sign(name, passphrase string, msg auth.StdSignMsg) ([]byte, error) {
|
||||
sig, err := MakeSignature(name, passphrase, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bldr.Codec.MarshalBinary(auth.NewStdTx(msg.Msgs, msg.Fee, []auth.StdSignature{sig}, msg.Memo))
|
||||
}
|
||||
|
||||
// BuildAndSign builds a single message to be signed, and signs a transaction
|
||||
// with the built message given a name, passphrase, and a set of
|
||||
// messages.
|
||||
func (bldr TxBuilder) BuildAndSign(name, passphrase string, msgs []sdk.Msg) ([]byte, error) {
|
||||
msg, err := bldr.Build(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bldr.Sign(name, passphrase, msg)
|
||||
}
|
||||
|
||||
// BuildWithPubKey builds a single message to be signed from a TxBuilder given a set of
|
||||
// messages and attach the public key associated to the given name.
|
||||
// It returns an error if a fee is supplied but cannot be parsed or the key cannot be
|
||||
// retrieved.
|
||||
func (bldr TxBuilder) BuildWithPubKey(name string, msgs []sdk.Msg) ([]byte, error) {
|
||||
msg, err := bldr.Build(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keybase, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info, err := keybase.Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sigs := []auth.StdSignature{{
|
||||
AccountNumber: msg.AccountNumber,
|
||||
Sequence: msg.Sequence,
|
||||
PubKey: info.GetPubKey(),
|
||||
}}
|
||||
|
||||
return bldr.Codec.MarshalBinary(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
|
||||
}
|
||||
|
||||
// SignStdTx appends a signature to a StdTx and returns a copy of a it. If append
|
||||
// is false, it replaces the signatures already attached with the new signature.
|
||||
func (bldr TxBuilder) SignStdTx(name, passphrase string, stdTx auth.StdTx, appendSig bool) (signedStdTx auth.StdTx, err error) {
|
||||
stdSignature, err := MakeSignature(name, passphrase, auth.StdSignMsg{
|
||||
ChainID: bldr.ChainID,
|
||||
AccountNumber: bldr.AccountNumber,
|
||||
Sequence: bldr.Sequence,
|
||||
Fee: stdTx.Fee,
|
||||
Msgs: stdTx.GetMsgs(),
|
||||
Memo: stdTx.GetMemo(),
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sigs := stdTx.GetSignatures()
|
||||
if len(sigs) == 0 || !appendSig {
|
||||
sigs = []auth.StdSignature{stdSignature}
|
||||
} else {
|
||||
sigs = append(sigs, stdSignature)
|
||||
}
|
||||
signedStdTx = auth.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, sigs, stdTx.GetMemo())
|
||||
return
|
||||
}
|
||||
|
||||
// MakeSignature builds a StdSignature given key name, passphrase, and a StdSignMsg.
|
||||
func MakeSignature(name, passphrase string, msg auth.StdSignMsg) (sig auth.StdSignature, err error) {
|
||||
keybase, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sigBytes, pubkey, err := keybase.Sign(name, passphrase, msg.Bytes())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return auth.StdSignature{
|
||||
AccountNumber: msg.AccountNumber,
|
||||
Sequence: msg.Sequence,
|
||||
PubKey: pubkey,
|
||||
Signature: sigBytes,
|
||||
}, nil
|
||||
}
|
||||
@ -16,8 +16,8 @@ func getBenchmarkMockApp() (*mock.App, error) {
|
||||
mapp := mock.NewApp()
|
||||
|
||||
RegisterWire(mapp.Cdc)
|
||||
coinKeeper := NewKeeper(mapp.AccountMapper)
|
||||
mapp.Router().AddRoute("bank", NewHandler(coinKeeper))
|
||||
bankKeeper := NewBaseKeeper(mapp.AccountMapper)
|
||||
mapp.Router().AddRoute("bank", NewHandler(bankKeeper))
|
||||
|
||||
err := mapp.CompleteSetup([]*sdk.KVStoreKey{})
|
||||
return mapp, err
|
||||
|
||||
52
x/bank/client/cli/broadcast.go
Normal file
52
x/bank/client/cli/broadcast.go
Normal file
@ -0,0 +1,52 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/spf13/cobra"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
)
|
||||
|
||||
// GetSignCommand returns the sign command
|
||||
func GetBroadcastCommand(codec *amino.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "broadcast <file>",
|
||||
Short: "Broadcast transactions generated offline",
|
||||
Long: `Broadcast transactions created with the --generate-only flag and signed with the sign command.
|
||||
Read a transaction from <file> and broadcast it to a node. If you supply a dash (-) argument
|
||||
in place of an input filename, the command reads from standard input.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
cliCtx := context.NewCLIContext().WithCodec(codec).WithLogger(os.Stdout)
|
||||
stdTx, err := readAndUnmarshalStdTx(cliCtx.Codec, args[0])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
txBytes, err := cliCtx.Codec.MarshalBinary(stdTx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return cliCtx.EnsureBroadcastTx(txBytes)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func readAndUnmarshalStdTx(cdc *amino.Codec, filename string) (stdTx auth.StdTx, err error) {
|
||||
var bytes []byte
|
||||
if filename == "-" {
|
||||
bytes, err = ioutil.ReadAll(os.Stdin)
|
||||
} else {
|
||||
bytes, err = ioutil.ReadFile(filename)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = cdc.UnmarshalJSON(bytes, &stdTx); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -8,7 +8,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/client"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@ -27,7 +27,7 @@ func SendTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
Use: "send",
|
||||
Short: "Create and sign a send tx",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -69,10 +69,10 @@ func SendTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
msg := client.BuildMsg(from, to, coins)
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
57
x/bank/client/rest/broadcast.go
Normal file
57
x/bank/client/rest/broadcast.go
Normal file
@ -0,0 +1,57 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
)
|
||||
|
||||
type broadcastBody struct {
|
||||
Tx auth.StdTx `json:"tx"`
|
||||
}
|
||||
|
||||
// BroadcastTxRequestHandlerFn returns the broadcast tx REST handler
|
||||
func BroadcastTxRequestHandlerFn(cdc *wire.Codec, cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var m broadcastBody
|
||||
if ok := unmarshalBodyOrReturnBadRequest(cliCtx, w, r, &m); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := cliCtx.Codec.MarshalBinary(m.Tx)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
res, err := cliCtx.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
output, err := wire.MarshalJSONIndent(cdc, res)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
w.Write(output)
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalBodyOrReturnBadRequest(cliCtx context.CLIContext, w http.ResponseWriter, r *http.Request, m *broadcastBody) bool {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return false
|
||||
}
|
||||
err = cliCtx.Codec.UnmarshalJSON(body, m)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/client"
|
||||
|
||||
@ -20,6 +20,7 @@ import (
|
||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
r.HandleFunc("/accounts/{address}/send", SendRequestHandlerFn(cdc, kb, cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/tx/broadcast", BroadcastTxRequestHandlerFn(cdc, cliCtx)).Methods("POST")
|
||||
}
|
||||
|
||||
type sendBody struct {
|
||||
@ -80,7 +81,7 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLICo
|
||||
return
|
||||
}
|
||||
|
||||
txCtx := authctx.TxContext{
|
||||
txBldr := authtxb.TxBuilder{
|
||||
Codec: cdc,
|
||||
Gas: m.Gas,
|
||||
ChainID: m.ChainID,
|
||||
@ -95,24 +96,24 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLICo
|
||||
cliCtx = cliCtx.WithGasAdjustment(adjustment)
|
||||
|
||||
if utils.HasDryRunArg(r) || m.Gas == 0 {
|
||||
newCtx, err := utils.EnrichCtxWithGas(txCtx, cliCtx, m.LocalAccountName, []sdk.Msg{msg})
|
||||
newCtx, err := utils.EnrichCtxWithGas(txBldr, cliCtx, m.LocalAccountName, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
if utils.HasDryRunArg(r) {
|
||||
utils.WriteSimulationResponse(w, txCtx.Gas)
|
||||
utils.WriteSimulationResponse(w, txBldr.Gas)
|
||||
return
|
||||
}
|
||||
txCtx = newCtx
|
||||
txBldr = newCtx
|
||||
}
|
||||
|
||||
if utils.HasGenerateOnlyArg(r) {
|
||||
utils.WriteGenerateStdTxResponse(w, txCtx, []sdk.Msg{msg})
|
||||
utils.WriteGenerateStdTxResponse(w, txBldr, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
txBytes, err := txBldr.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
|
||||
103
x/bank/keeper.go
103
x/bank/keeper.go
@ -15,102 +15,149 @@ const (
|
||||
costAddCoins sdk.Gas = 10
|
||||
)
|
||||
|
||||
// Keeper manages transfers between accounts
|
||||
type Keeper struct {
|
||||
// Keeper defines a module interface that facilitates the transfer of coins
|
||||
// between accounts.
|
||||
type Keeper interface {
|
||||
SendKeeper
|
||||
SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error
|
||||
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error)
|
||||
AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error)
|
||||
}
|
||||
|
||||
var _ Keeper = (*BaseKeeper)(nil)
|
||||
|
||||
// BaseKeeper manages transfers between accounts. It implements the Keeper
|
||||
// interface.
|
||||
type BaseKeeper struct {
|
||||
am auth.AccountMapper
|
||||
}
|
||||
|
||||
// NewKeeper returns a new Keeper
|
||||
func NewKeeper(am auth.AccountMapper) Keeper {
|
||||
return Keeper{am: am}
|
||||
// NewBaseKeeper returns a new BaseKeeper
|
||||
func NewBaseKeeper(am auth.AccountMapper) BaseKeeper {
|
||||
return BaseKeeper{am: am}
|
||||
}
|
||||
|
||||
// GetCoins returns the coins at the addr.
|
||||
func (keeper Keeper) GetCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins {
|
||||
func (keeper BaseKeeper) GetCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins {
|
||||
return getCoins(ctx, keeper.am, addr)
|
||||
}
|
||||
|
||||
// SetCoins sets the coins at the addr.
|
||||
func (keeper Keeper) SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
func (keeper BaseKeeper) SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
return setCoins(ctx, keeper.am, addr, amt)
|
||||
}
|
||||
|
||||
// HasCoins returns whether or not an account has at least amt coins.
|
||||
func (keeper Keeper) HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) bool {
|
||||
func (keeper BaseKeeper) HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) bool {
|
||||
return hasCoins(ctx, keeper.am, addr, amt)
|
||||
}
|
||||
|
||||
// SubtractCoins subtracts amt from the coins at the addr.
|
||||
func (keeper Keeper) SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) {
|
||||
func (keeper BaseKeeper) SubtractCoins(
|
||||
ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Coins, sdk.Tags, sdk.Error) {
|
||||
|
||||
return subtractCoins(ctx, keeper.am, addr, amt)
|
||||
}
|
||||
|
||||
// AddCoins adds amt to the coins at the addr.
|
||||
func (keeper Keeper) AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) {
|
||||
func (keeper BaseKeeper) AddCoins(
|
||||
ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Coins, sdk.Tags, sdk.Error) {
|
||||
|
||||
return addCoins(ctx, keeper.am, addr, amt)
|
||||
}
|
||||
|
||||
// SendCoins moves coins from one account to another
|
||||
func (keeper Keeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error) {
|
||||
func (keeper BaseKeeper) SendCoins(
|
||||
ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
|
||||
return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt)
|
||||
}
|
||||
|
||||
// InputOutputCoins handles a list of inputs and outputs
|
||||
func (keeper Keeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) {
|
||||
func (keeper BaseKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) {
|
||||
return inputOutputCoins(ctx, keeper.am, inputs, outputs)
|
||||
}
|
||||
|
||||
//______________________________________________________________________________________________
|
||||
|
||||
// SendKeeper only allows transfers between accounts, without the possibility of creating coins
|
||||
type SendKeeper struct {
|
||||
// SendKeeper defines a module interface that facilitates the transfer of coins
|
||||
// between accounts without the possibility of creating coins.
|
||||
type SendKeeper interface {
|
||||
ViewKeeper
|
||||
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error)
|
||||
InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error)
|
||||
}
|
||||
|
||||
var _ SendKeeper = (*BaseSendKeeper)(nil)
|
||||
|
||||
// SendKeeper only allows transfers between accounts without the possibility of
|
||||
// creating coins. It implements the SendKeeper interface.
|
||||
type BaseSendKeeper struct {
|
||||
am auth.AccountMapper
|
||||
}
|
||||
|
||||
// NewSendKeeper returns a new Keeper
|
||||
func NewSendKeeper(am auth.AccountMapper) SendKeeper {
|
||||
return SendKeeper{am: am}
|
||||
// NewBaseSendKeeper returns a new BaseSendKeeper.
|
||||
func NewBaseSendKeeper(am auth.AccountMapper) BaseSendKeeper {
|
||||
return BaseSendKeeper{am: am}
|
||||
}
|
||||
|
||||
// GetCoins returns the coins at the addr.
|
||||
func (keeper SendKeeper) GetCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins {
|
||||
func (keeper BaseSendKeeper) GetCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins {
|
||||
return getCoins(ctx, keeper.am, addr)
|
||||
}
|
||||
|
||||
// HasCoins returns whether or not an account has at least amt coins.
|
||||
func (keeper SendKeeper) HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) bool {
|
||||
func (keeper BaseSendKeeper) HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) bool {
|
||||
return hasCoins(ctx, keeper.am, addr, amt)
|
||||
}
|
||||
|
||||
// SendCoins moves coins from one account to another
|
||||
func (keeper SendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error) {
|
||||
func (keeper BaseSendKeeper) SendCoins(
|
||||
ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
|
||||
return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt)
|
||||
}
|
||||
|
||||
// InputOutputCoins handles a list of inputs and outputs
|
||||
func (keeper SendKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) {
|
||||
func (keeper BaseSendKeeper) InputOutputCoins(
|
||||
ctx sdk.Context, inputs []Input, outputs []Output,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
|
||||
return inputOutputCoins(ctx, keeper.am, inputs, outputs)
|
||||
}
|
||||
|
||||
//______________________________________________________________________________________________
|
||||
|
||||
// ViewKeeper only allows reading of balances
|
||||
type ViewKeeper struct {
|
||||
// ViewKeeper defines a module interface that facilitates read only access to
|
||||
// account balances.
|
||||
type ViewKeeper interface {
|
||||
GetCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) bool
|
||||
}
|
||||
|
||||
var _ ViewKeeper = (*BaseViewKeeper)(nil)
|
||||
|
||||
// BaseViewKeeper implements a read only keeper implementation of ViewKeeper.
|
||||
type BaseViewKeeper struct {
|
||||
am auth.AccountMapper
|
||||
}
|
||||
|
||||
// NewViewKeeper returns a new Keeper
|
||||
func NewViewKeeper(am auth.AccountMapper) ViewKeeper {
|
||||
return ViewKeeper{am: am}
|
||||
// NewBaseViewKeeper returns a new BaseViewKeeper.
|
||||
func NewBaseViewKeeper(am auth.AccountMapper) BaseViewKeeper {
|
||||
return BaseViewKeeper{am: am}
|
||||
}
|
||||
|
||||
// GetCoins returns the coins at the addr.
|
||||
func (keeper ViewKeeper) GetCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins {
|
||||
func (keeper BaseViewKeeper) GetCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins {
|
||||
return getCoins(ctx, keeper.am, addr)
|
||||
}
|
||||
|
||||
// HasCoins returns whether or not an account has at least amt coins.
|
||||
func (keeper ViewKeeper) HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) bool {
|
||||
func (keeper BaseViewKeeper) HasCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) bool {
|
||||
return hasCoins(ctx, keeper.am, addr, amt)
|
||||
}
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ func TestKeeper(t *testing.T) {
|
||||
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
|
||||
accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount)
|
||||
coinKeeper := NewKeeper(accountMapper)
|
||||
bankKeeper := NewBaseKeeper(accountMapper)
|
||||
|
||||
addr := sdk.AccAddress([]byte("addr1"))
|
||||
addr2 := sdk.AccAddress([]byte("addr2"))
|
||||
@ -43,57 +43,57 @@ func TestKeeper(t *testing.T) {
|
||||
|
||||
// Test GetCoins/SetCoins
|
||||
accountMapper.SetAccount(ctx, acc)
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{}))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{}))
|
||||
|
||||
coinKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
bankKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
|
||||
// Test HasCoins
|
||||
require.True(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
require.True(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
|
||||
require.False(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 15)}))
|
||||
require.False(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 5)}))
|
||||
require.True(t, bankKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
require.True(t, bankKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
|
||||
require.False(t, bankKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 15)}))
|
||||
require.False(t, bankKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 5)}))
|
||||
|
||||
// Test AddCoins
|
||||
coinKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 15)})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 25)}))
|
||||
bankKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 15)})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 25)}))
|
||||
|
||||
coinKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 15)})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 15), sdk.NewInt64Coin("foocoin", 25)}))
|
||||
bankKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 15)})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 15), sdk.NewInt64Coin("foocoin", 25)}))
|
||||
|
||||
// Test SubtractCoins
|
||||
coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
|
||||
coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 5)})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15)}))
|
||||
bankKeeper.SubtractCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
|
||||
bankKeeper.SubtractCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 5)})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15)}))
|
||||
|
||||
coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 11)})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15)}))
|
||||
bankKeeper.SubtractCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 11)})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15)}))
|
||||
|
||||
coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 10)})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 15)}))
|
||||
require.False(t, coinKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 1)}))
|
||||
bankKeeper.SubtractCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 10)})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 15)}))
|
||||
require.False(t, bankKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 1)}))
|
||||
|
||||
// Test SendCoins
|
||||
coinKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 5)})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
|
||||
bankKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 5)})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
|
||||
|
||||
_, err2 := coinKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 50)})
|
||||
_, err2 := bankKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 50)})
|
||||
assert.Implements(t, (*sdk.Error)(nil), err2)
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
|
||||
|
||||
coinKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 30)})
|
||||
coinKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 5)})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5)}))
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10)}))
|
||||
bankKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 30)})
|
||||
bankKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 5)})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5)}))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10)}))
|
||||
|
||||
// Test InputOutputCoins
|
||||
input1 := NewInput(addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 2)})
|
||||
output1 := NewOutput(addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 2)})
|
||||
coinKeeper.InputOutputCoins(ctx, []Input{input1}, []Output{output1})
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 7)}))
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 8)}))
|
||||
bankKeeper.InputOutputCoins(ctx, []Input{input1}, []Output{output1})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 7)}))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 8)}))
|
||||
|
||||
inputs := []Input{
|
||||
NewInput(addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 3)}),
|
||||
@ -104,10 +104,10 @@ func TestKeeper(t *testing.T) {
|
||||
NewOutput(addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 1)}),
|
||||
NewOutput(addr3, sdk.Coins{sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5)}),
|
||||
}
|
||||
coinKeeper.InputOutputCoins(ctx, inputs, outputs)
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 21), sdk.NewInt64Coin("foocoin", 4)}))
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 7), sdk.NewInt64Coin("foocoin", 6)}))
|
||||
require.True(t, coinKeeper.GetCoins(ctx, addr3).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5)}))
|
||||
bankKeeper.InputOutputCoins(ctx, inputs, outputs)
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 21), sdk.NewInt64Coin("foocoin", 4)}))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 7), sdk.NewInt64Coin("foocoin", 6)}))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr3).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5)}))
|
||||
|
||||
}
|
||||
|
||||
@ -119,8 +119,8 @@ func TestSendKeeper(t *testing.T) {
|
||||
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
|
||||
accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount)
|
||||
coinKeeper := NewKeeper(accountMapper)
|
||||
sendKeeper := NewSendKeeper(accountMapper)
|
||||
bankKeeper := NewBaseKeeper(accountMapper)
|
||||
sendKeeper := NewBaseSendKeeper(accountMapper)
|
||||
|
||||
addr := sdk.AccAddress([]byte("addr1"))
|
||||
addr2 := sdk.AccAddress([]byte("addr2"))
|
||||
@ -131,7 +131,7 @@ func TestSendKeeper(t *testing.T) {
|
||||
accountMapper.SetAccount(ctx, acc)
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{}))
|
||||
|
||||
coinKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
|
||||
bankKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
|
||||
// Test HasCoins
|
||||
@ -140,7 +140,7 @@ func TestSendKeeper(t *testing.T) {
|
||||
require.False(t, sendKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 15)}))
|
||||
require.False(t, sendKeeper.HasCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 5)}))
|
||||
|
||||
coinKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 15)})
|
||||
bankKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 15)})
|
||||
|
||||
// Test SendCoins
|
||||
sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 5)})
|
||||
@ -152,7 +152,7 @@ func TestSendKeeper(t *testing.T) {
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 5)}))
|
||||
|
||||
coinKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 30)})
|
||||
bankKeeper.AddCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 30)})
|
||||
sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 5)})
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5)}))
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10)}))
|
||||
@ -188,8 +188,8 @@ func TestViewKeeper(t *testing.T) {
|
||||
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger())
|
||||
accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount)
|
||||
coinKeeper := NewKeeper(accountMapper)
|
||||
viewKeeper := NewViewKeeper(accountMapper)
|
||||
bankKeeper := NewBaseKeeper(accountMapper)
|
||||
viewKeeper := NewBaseViewKeeper(accountMapper)
|
||||
|
||||
addr := sdk.AccAddress([]byte("addr1"))
|
||||
acc := accountMapper.NewAccountWithAddress(ctx, addr)
|
||||
@ -198,7 +198,7 @@ func TestViewKeeper(t *testing.T) {
|
||||
accountMapper.SetAccount(ctx, acc)
|
||||
require.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{}))
|
||||
|
||||
coinKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
|
||||
bankKeeper.SetCoins(ctx, addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)})
|
||||
require.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}))
|
||||
|
||||
// Test HasCoins
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -16,25 +14,25 @@ import (
|
||||
|
||||
// NonnegativeBalanceInvariant checks that all accounts in the application have non-negative balances
|
||||
func NonnegativeBalanceInvariant(mapper auth.AccountMapper) simulation.Invariant {
|
||||
return func(t *testing.T, app *baseapp.BaseApp, log string) {
|
||||
return func(app *baseapp.BaseApp) error {
|
||||
ctx := app.NewContext(false, abci.Header{})
|
||||
accts := mock.GetAllAccounts(mapper, ctx)
|
||||
for _, acc := range accts {
|
||||
coins := acc.GetCoins()
|
||||
require.True(t, coins.IsNotNegative(),
|
||||
fmt.Sprintf("%s has a negative denomination of %s\n%s",
|
||||
if !coins.IsNotNegative() {
|
||||
return fmt.Errorf("%s has a negative denomination of %s",
|
||||
acc.GetAddress().String(),
|
||||
coins.String(),
|
||||
log),
|
||||
)
|
||||
coins.String())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// TotalCoinsInvariant checks that the sum of the coins across all accounts
|
||||
// is what is expected
|
||||
func TotalCoinsInvariant(mapper auth.AccountMapper, totalSupplyFn func() sdk.Coins) simulation.Invariant {
|
||||
return func(t *testing.T, app *baseapp.BaseApp, log string) {
|
||||
return func(app *baseapp.BaseApp) error {
|
||||
ctx := app.NewContext(false, abci.Header{})
|
||||
totalCoins := sdk.Coins{}
|
||||
|
||||
@ -45,6 +43,9 @@ func TotalCoinsInvariant(mapper auth.AccountMapper, totalSupplyFn func() sdk.Coi
|
||||
}
|
||||
|
||||
mapper.IterateAccounts(ctx, chkAccount)
|
||||
require.Equal(t, totalSupplyFn(), totalCoins, log)
|
||||
if !totalSupplyFn().IsEqual(totalCoins) {
|
||||
return errors.New("total calculated coins doesn't equal expected coins")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,9 +5,6 @@ import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -21,7 +18,7 @@ import (
|
||||
// SimulateSingleInputMsgSend tests and runs a single msg send, with one input and one output, where both
|
||||
// accounts already exist.
|
||||
func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation {
|
||||
return func(tb testing.TB, 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) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
fromKey := simulation.RandomKey(r, keys)
|
||||
fromAddr := sdk.AccAddress(fromKey.PubKey().Address())
|
||||
toKey := simulation.RandomKey(r, keys)
|
||||
@ -51,14 +48,16 @@ func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation
|
||||
initFromCoins[denomIndex].Denom,
|
||||
toAddr.String(),
|
||||
)
|
||||
log = fmt.Sprintf("%s\n%s", log, action)
|
||||
|
||||
coins := sdk.Coins{{initFromCoins[denomIndex].Denom, amt}}
|
||||
var msg = bank.MsgSend{
|
||||
Inputs: []bank.Input{bank.NewInput(fromAddr, coins)},
|
||||
Outputs: []bank.Output{bank.NewOutput(toAddr, coins)},
|
||||
}
|
||||
sendAndVerifyMsgSend(tb, app, mapper, msg, ctx, log, []crypto.PrivKey{fromKey})
|
||||
goErr = sendAndVerifyMsgSend(app, mapper, msg, ctx, []crypto.PrivKey{fromKey})
|
||||
if goErr != nil {
|
||||
return "", nil, goErr
|
||||
}
|
||||
event("bank/sendAndVerifyMsgSend/ok")
|
||||
|
||||
return action, nil, nil
|
||||
@ -66,7 +65,7 @@ func SimulateSingleInputMsgSend(mapper auth.AccountMapper) simulation.Operation
|
||||
}
|
||||
|
||||
// Sends and verifies the transition of a msg send. This fails if there are repeated inputs or outputs
|
||||
func sendAndVerifyMsgSend(tb testing.TB, app *baseapp.BaseApp, mapper auth.AccountMapper, msg bank.MsgSend, ctx sdk.Context, log string, privkeys []crypto.PrivKey) {
|
||||
func sendAndVerifyMsgSend(app *baseapp.BaseApp, mapper auth.AccountMapper, msg bank.MsgSend, ctx sdk.Context, privkeys []crypto.PrivKey) error {
|
||||
initialInputAddrCoins := make([]sdk.Coins, len(msg.Inputs))
|
||||
initialOutputAddrCoins := make([]sdk.Coins, len(msg.Outputs))
|
||||
AccountNumbers := make([]int64, len(msg.Inputs))
|
||||
@ -89,25 +88,22 @@ func sendAndVerifyMsgSend(tb testing.TB, app *baseapp.BaseApp, mapper auth.Accou
|
||||
res := app.Deliver(tx)
|
||||
if !res.IsOK() {
|
||||
// TODO: Do this in a more 'canonical' way
|
||||
fmt.Println(res)
|
||||
fmt.Println(log)
|
||||
tb.FailNow()
|
||||
return fmt.Errorf("Deliver failed %v", res)
|
||||
}
|
||||
|
||||
for i := 0; i < len(msg.Inputs); i++ {
|
||||
terminalInputCoins := mapper.GetAccount(ctx, msg.Inputs[i].Address).GetCoins()
|
||||
require.Equal(tb,
|
||||
initialInputAddrCoins[i].Minus(msg.Inputs[i].Coins),
|
||||
terminalInputCoins,
|
||||
fmt.Sprintf("Input #%d had an incorrect amount of coins\n%s", i, log),
|
||||
)
|
||||
if !initialInputAddrCoins[i].Minus(msg.Inputs[i].Coins).IsEqual(terminalInputCoins) {
|
||||
return fmt.Errorf("input #%d had an incorrect amount of coins", i)
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(msg.Outputs); i++ {
|
||||
terminalOutputCoins := mapper.GetAccount(ctx, msg.Outputs[i].Address).GetCoins()
|
||||
if !terminalOutputCoins.IsEqual(initialOutputAddrCoins[i].Plus(msg.Outputs[i].Coins)) {
|
||||
tb.Fatalf("Output #%d had an incorrect amount of coins\n%s", i, log)
|
||||
return fmt.Errorf("output #%d had an incorrect amount of coins", i)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func randPositiveInt(r *rand.Rand, max sdk.Int) (sdk.Int, error) {
|
||||
|
||||
@ -18,8 +18,8 @@ func TestBankWithRandomMessages(t *testing.T) {
|
||||
|
||||
bank.RegisterWire(mapp.Cdc)
|
||||
mapper := mapp.AccountMapper
|
||||
coinKeeper := bank.NewKeeper(mapper)
|
||||
mapp.Router().AddRoute("bank", bank.NewHandler(coinKeeper))
|
||||
bankKeeper := bank.NewBaseKeeper(mapper)
|
||||
mapp.Router().AddRoute("bank", bank.NewHandler(bankKeeper))
|
||||
|
||||
err := mapp.CompleteSetup([]*sdk.KVStoreKey{})
|
||||
if err != nil {
|
||||
|
||||
91
x/distribution/keeper.go
Normal file
91
x/distribution/keeper.go
Normal file
@ -0,0 +1,91 @@
|
||||
package stake
|
||||
|
||||
//// keeper of the staking store
|
||||
//type Keeper struct {
|
||||
//storeKey sdk.StoreKey
|
||||
//cdc *wire.Codec
|
||||
//bankKeeper bank.Keeper
|
||||
|
||||
//// codespace
|
||||
//codespace sdk.CodespaceType
|
||||
//}
|
||||
|
||||
//func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
|
||||
//keeper := Keeper{
|
||||
//storeKey: key,
|
||||
//cdc: cdc,
|
||||
//bankKeeper: ck,
|
||||
//codespace: codespace,
|
||||
//}
|
||||
//return keeper
|
||||
//}
|
||||
|
||||
////_________________________________________________________________________
|
||||
|
||||
//// cummulative power of the non-absent prevotes
|
||||
//func (k Keeper) GetTotalPrecommitVotingPower(ctx sdk.Context) sdk.Dec {
|
||||
//store := ctx.KVStore(k.storeKey)
|
||||
|
||||
//// get absent prevote indexes
|
||||
//absents := ctx.AbsentValidators()
|
||||
|
||||
//TotalPower := sdk.ZeroDec()
|
||||
//i := int32(0)
|
||||
//iterator := store.SubspaceIterator(ValidatorsBondedKey)
|
||||
//for ; iterator.Valid(); iterator.Next() {
|
||||
|
||||
//skip := false
|
||||
//for j, absentIndex := range absents {
|
||||
//if absentIndex > i {
|
||||
//break
|
||||
//}
|
||||
|
||||
//// if non-voting validator found, skip adding its power
|
||||
//if absentIndex == i {
|
||||
//absents = append(absents[:j], absents[j+1:]...) // won't need again
|
||||
//skip = true
|
||||
//break
|
||||
//}
|
||||
//}
|
||||
//if skip {
|
||||
//continue
|
||||
//}
|
||||
|
||||
//bz := iterator.Value()
|
||||
//var validator Validator
|
||||
//k.cdc.MustUnmarshalBinary(bz, &validator)
|
||||
//TotalPower = TotalPower.Add(validator.Power)
|
||||
//i++
|
||||
//}
|
||||
//iterator.Close()
|
||||
//return TotalPower
|
||||
//}
|
||||
|
||||
////_______________________________________________________________________
|
||||
|
||||
//// XXX TODO trim functionality
|
||||
|
||||
//// retrieve all the power changes which occur after a height
|
||||
//func (k Keeper) GetPowerChangesAfterHeight(ctx sdk.Context, earliestHeight int64) (pcs []PowerChange) {
|
||||
//store := ctx.KVStore(k.storeKey)
|
||||
|
||||
//iterator := store.SubspaceIterator(PowerChangeKey) //smallest to largest
|
||||
//for ; iterator.Valid(); iterator.Next() {
|
||||
//pcBytes := iterator.Value()
|
||||
//var pc PowerChange
|
||||
//k.cdc.MustUnmarshalBinary(pcBytes, &pc)
|
||||
//if pc.Height < earliestHeight {
|
||||
//break
|
||||
//}
|
||||
//pcs = append(pcs, pc)
|
||||
//}
|
||||
//iterator.Close()
|
||||
//return
|
||||
//}
|
||||
|
||||
//// set a power change
|
||||
//func (k Keeper) setPowerChange(ctx sdk.Context, pc PowerChange) {
|
||||
//store := ctx.KVStore(k.storeKey)
|
||||
//b := k.cdc.MustMarshalBinary(pc)
|
||||
//store.Set(GetPowerChangeKey(pc.Height), b)
|
||||
//}
|
||||
@ -9,7 +9,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
|
||||
"encoding/json"
|
||||
@ -77,7 +77,7 @@ $ gaiacli gov submit-proposal --title="Test Proposal" --description="My awesome
|
||||
return err
|
||||
}
|
||||
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -105,13 +105,13 @@ $ gaiacli gov submit-proposal --title="Test Proposal" --description="My awesome
|
||||
}
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
// Build and sign the transaction, then broadcast to Tendermint
|
||||
// proposalID must be returned, and it is a part of response.
|
||||
cliCtx.PrintResponse = true
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ func GetCmdDeposit(cdc *wire.Codec) *cobra.Command {
|
||||
Use: "deposit",
|
||||
Short: "deposit tokens for activing proposal",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -186,12 +186,12 @@ func GetCmdDeposit(cdc *wire.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
// Build and sign the transaction, then broadcast to a Tendermint
|
||||
// node.
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command {
|
||||
Use: "vote",
|
||||
Short: "vote for an active proposal, options: Yes/No/NoWithVeto/Abstain",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -233,7 +233,7 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
fmt.Printf("Vote[Voter:%s,ProposalID:%d,Option:%s]",
|
||||
@ -242,7 +242,7 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
// Build and sign the transaction, then broadcast to a Tendermint
|
||||
// node.
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"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"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
)
|
||||
|
||||
type baseReq struct {
|
||||
@ -70,7 +70,7 @@ func (req baseReq) baseReqValidate(w http.ResponseWriter) bool {
|
||||
// (probably should live in client/lcd).
|
||||
func signAndBuild(w http.ResponseWriter, r *http.Request, cliCtx context.CLIContext, baseReq baseReq, msg sdk.Msg, cdc *wire.Codec) {
|
||||
var err error
|
||||
txCtx := authctx.TxContext{
|
||||
txBldr := authtxb.TxBuilder{
|
||||
Codec: cdc,
|
||||
AccountNumber: baseReq.AccountNumber,
|
||||
Sequence: baseReq.Sequence,
|
||||
@ -85,24 +85,24 @@ func signAndBuild(w http.ResponseWriter, r *http.Request, cliCtx context.CLICont
|
||||
cliCtx = cliCtx.WithGasAdjustment(adjustment)
|
||||
|
||||
if utils.HasDryRunArg(r) || baseReq.Gas == 0 {
|
||||
newCtx, err := utils.EnrichCtxWithGas(txCtx, cliCtx, baseReq.Name, []sdk.Msg{msg})
|
||||
newCtx, err := utils.EnrichCtxWithGas(txBldr, cliCtx, baseReq.Name, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
if utils.HasDryRunArg(r) {
|
||||
utils.WriteSimulationResponse(w, txCtx.Gas)
|
||||
utils.WriteSimulationResponse(w, txBldr.Gas)
|
||||
return
|
||||
}
|
||||
txCtx = newCtx
|
||||
txBldr = newCtx
|
||||
}
|
||||
|
||||
if utils.HasGenerateOnlyArg(r) {
|
||||
utils.WriteGenerateStdTxResponse(w, txCtx, []sdk.Msg{msg})
|
||||
utils.WriteGenerateStdTxResponse(w, txBldr, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(baseReq.Name, baseReq.Password, []sdk.Msg{msg})
|
||||
txBytes, err := txBldr.BuildAndSign(baseReq.Name, baseReq.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
|
||||
@ -132,6 +132,7 @@ func (vo VoteOption) String() string {
|
||||
}
|
||||
|
||||
// For Printf / Sprintf, returns bech32 when using %s
|
||||
// nolint: errcheck
|
||||
func (vo VoteOption) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
|
||||
@ -210,6 +210,7 @@ func (keeper Keeper) activateVotingPeriod(ctx sdk.Context, proposal Proposal) {
|
||||
// Procedures
|
||||
|
||||
// Returns the current Deposit Procedure from the global param store
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) GetDepositProcedure(ctx sdk.Context) DepositProcedure {
|
||||
var depositProcedure DepositProcedure
|
||||
keeper.ps.Get(ctx, ParamStoreKeyDepositProcedure, &depositProcedure)
|
||||
@ -217,6 +218,7 @@ func (keeper Keeper) GetDepositProcedure(ctx sdk.Context) DepositProcedure {
|
||||
}
|
||||
|
||||
// Returns the current Voting Procedure from the global param store
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) GetVotingProcedure(ctx sdk.Context) VotingProcedure {
|
||||
var votingProcedure VotingProcedure
|
||||
keeper.ps.Get(ctx, ParamStoreKeyVotingProcedure, &votingProcedure)
|
||||
@ -224,20 +226,24 @@ func (keeper Keeper) GetVotingProcedure(ctx sdk.Context) VotingProcedure {
|
||||
}
|
||||
|
||||
// Returns the current Tallying Procedure from the global param store
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) GetTallyingProcedure(ctx sdk.Context) TallyingProcedure {
|
||||
var tallyingProcedure TallyingProcedure
|
||||
keeper.ps.Get(ctx, ParamStoreKeyTallyingProcedure, &tallyingProcedure)
|
||||
return tallyingProcedure
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) setDepositProcedure(ctx sdk.Context, depositProcedure DepositProcedure) {
|
||||
keeper.ps.Set(ctx, ParamStoreKeyDepositProcedure, &depositProcedure)
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) setVotingProcedure(ctx sdk.Context, votingProcedure VotingProcedure) {
|
||||
keeper.ps.Set(ctx, ParamStoreKeyVotingProcedure, &votingProcedure)
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) setTallyingProcedure(ctx sdk.Context, tallyingProcedure TallyingProcedure) {
|
||||
keeper.ps.Set(ctx, ParamStoreKeyTallyingProcedure, &tallyingProcedure)
|
||||
}
|
||||
|
||||
@ -187,6 +187,7 @@ func (pt ProposalKind) String() string {
|
||||
}
|
||||
|
||||
// For Printf / Sprintf, returns bech32 when using %s
|
||||
// nolint: errcheck
|
||||
func (pt ProposalKind) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
@ -289,6 +290,7 @@ func (status ProposalStatus) String() string {
|
||||
}
|
||||
|
||||
// For Printf / Sprintf, returns bech32 when using %s
|
||||
// nolint: errcheck
|
||||
func (status ProposalStatus) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 's':
|
||||
|
||||
@ -36,6 +36,7 @@ type QueryProposalParams struct {
|
||||
ProposalID int64
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||
var params QueryProposalParams
|
||||
err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
@ -61,6 +62,7 @@ type QueryDepositParams struct {
|
||||
Depositer sdk.AccAddress
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||
var params QueryDepositParams
|
||||
err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
@ -82,6 +84,7 @@ type QueryVoteParams struct {
|
||||
Voter sdk.AccAddress
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||
var params QueryVoteParams
|
||||
err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
@ -102,6 +105,7 @@ type QueryDepositsParams struct {
|
||||
ProposalID int64
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||
var params QueryDepositParams
|
||||
err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
@ -129,6 +133,7 @@ type QueryVotesParams struct {
|
||||
ProposalID int64
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||
var params QueryVotesParams
|
||||
err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
@ -160,6 +165,7 @@ type QueryProposalsParams struct {
|
||||
NumLatestProposals int64
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||
var params QueryProposalsParams
|
||||
err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
@ -181,6 +187,7 @@ type QueryTallyParams struct {
|
||||
ProposalID int64
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
|
||||
// TODO: Dependant on #1914
|
||||
|
||||
|
||||
@ -1,19 +1,15 @@
|
||||
package simulation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
|
||||
)
|
||||
|
||||
// AllInvariants tests all governance invariants
|
||||
func AllInvariants() simulation.Invariant {
|
||||
return func(t *testing.T, app *baseapp.BaseApp, log string) {
|
||||
return func(app *baseapp.BaseApp) error {
|
||||
// TODO Add some invariants!
|
||||
// Checking proposal queues, no passed-but-unexecuted proposals, etc.
|
||||
require.Nil(t, nil)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,8 @@ package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
@ -18,32 +18,97 @@ const (
|
||||
denom = "steak"
|
||||
)
|
||||
|
||||
// SimulateSubmittingVotingAndSlashingForProposal simulates creating a msg Submit Proposal
|
||||
// voting on the proposal, and subsequently slashing the proposal. It is implemented using
|
||||
// future operations.
|
||||
// TODO: Vote more intelligently, so we can actually do some checks regarding votes passing or failing
|
||||
// TODO: Actually check that validator slashings happened
|
||||
func SimulateSubmittingVotingAndSlashingForProposal(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
handler := gov.NewHandler(k)
|
||||
// The states are:
|
||||
// column 1: All validators vote
|
||||
// column 2: 90% vote
|
||||
// column 3: 75% vote
|
||||
// column 4: 40% vote
|
||||
// column 5: 15% vote
|
||||
// column 6: noone votes
|
||||
// All columns sum to 100 for simplicity, values chosen by @valardragon semi-arbitrarily,
|
||||
// feel free to change.
|
||||
numVotesTransitionMatrix, _ := simulation.CreateTransitionMatrix([][]int{
|
||||
{20, 10, 0, 0, 0, 0},
|
||||
{55, 50, 20, 10, 0, 0},
|
||||
{25, 25, 30, 25, 30, 15},
|
||||
{0, 15, 30, 25, 30, 30},
|
||||
{0, 0, 20, 30, 30, 30},
|
||||
{0, 0, 0, 10, 10, 25},
|
||||
})
|
||||
statePercentageArray := []float64{1, .9, .75, .4, .15, 0}
|
||||
curNumVotesState := 1
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
// 1) submit proposal now
|
||||
sender := simulation.RandomKey(r, keys)
|
||||
msg, err := simulationCreateMsgSubmitProposal(r, sender)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
action = simulateHandleMsgSubmitProposal(msg, sk, handler, ctx, event)
|
||||
proposalID := k.GetLastProposalID(ctx)
|
||||
// 2) Schedule operations for votes
|
||||
// 2.1) first pick a number of people to vote.
|
||||
curNumVotesState = numVotesTransitionMatrix.NextState(r, curNumVotesState)
|
||||
numVotes := int(math.Ceil(float64(len(keys)) * statePercentageArray[curNumVotesState]))
|
||||
// 2.2) select who votes and when
|
||||
whoVotes := r.Perm(len(keys))
|
||||
// didntVote := whoVotes[numVotes:]
|
||||
whoVotes = whoVotes[:numVotes]
|
||||
votingPeriod := k.GetVotingProcedure(ctx).VotingPeriod
|
||||
fops := make([]simulation.FutureOperation, numVotes+1)
|
||||
for i := 0; i < numVotes; i++ {
|
||||
whenVote := ctx.BlockHeight() + r.Int63n(votingPeriod)
|
||||
fops[i] = simulation.FutureOperation{int(whenVote), operationSimulateMsgVote(k, sk, keys[whoVotes[i]], proposalID)}
|
||||
}
|
||||
// 3) Make an operation to ensure slashes were done correctly. (Really should be a future invariant)
|
||||
// TODO: Find a way to check if a validator was slashed other than just checking their balance a block
|
||||
// before and after.
|
||||
|
||||
return action, fops, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
handler := gov.NewHandler(k)
|
||||
return func(tb testing.TB, 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) {
|
||||
msg := simulationCreateMsgSubmitProposal(tb, r, keys, log)
|
||||
ctx, write := ctx.CacheContext()
|
||||
result := handler(ctx, msg)
|
||||
if result.IsOK() {
|
||||
// Update pool to keep invariants
|
||||
pool := sk.GetPool(ctx)
|
||||
pool.LooseTokens = pool.LooseTokens.Sub(sdk.NewDecFromInt(msg.InitialDeposit.AmountOf(denom)))
|
||||
sk.SetPool(ctx, pool)
|
||||
write()
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOps []simulation.FutureOperation, err error) {
|
||||
sender := simulation.RandomKey(r, keys)
|
||||
msg, err := simulationCreateMsgSubmitProposal(r, sender)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
event(fmt.Sprintf("gov/MsgSubmitProposal/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgSubmitProposal: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
action = simulateHandleMsgSubmitProposal(msg, sk, handler, ctx, event)
|
||||
return action, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func simulationCreateMsgSubmitProposal(tb testing.TB, r *rand.Rand, keys []crypto.PrivKey, log string) gov.MsgSubmitProposal {
|
||||
key := simulation.RandomKey(r, keys)
|
||||
addr := sdk.AccAddress(key.PubKey().Address())
|
||||
func simulateHandleMsgSubmitProposal(msg gov.MsgSubmitProposal, sk stake.Keeper, handler sdk.Handler, ctx sdk.Context, event func(string)) (action string) {
|
||||
ctx, write := ctx.CacheContext()
|
||||
result := handler(ctx, msg)
|
||||
if result.IsOK() {
|
||||
// Update pool to keep invariants
|
||||
pool := sk.GetPool(ctx)
|
||||
pool.LooseTokens = pool.LooseTokens.Sub(sdk.NewDecFromInt(msg.InitialDeposit.AmountOf(denom)))
|
||||
sk.SetPool(ctx, pool)
|
||||
write()
|
||||
}
|
||||
event(fmt.Sprintf("gov/MsgSubmitProposal/%v", result.IsOK()))
|
||||
action = fmt.Sprintf("TestMsgSubmitProposal: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
|
||||
return action
|
||||
}
|
||||
|
||||
func simulationCreateMsgSubmitProposal(r *rand.Rand, sender crypto.PrivKey) (msg gov.MsgSubmitProposal, err error) {
|
||||
addr := sdk.AccAddress(sender.PubKey().Address())
|
||||
deposit := randomDeposit(r)
|
||||
msg := gov.NewMsgSubmitProposal(
|
||||
msg = gov.NewMsgSubmitProposal(
|
||||
simulation.RandStringOfLength(r, 5),
|
||||
simulation.RandStringOfLength(r, 5),
|
||||
gov.ProposalTypeText,
|
||||
@ -51,14 +116,14 @@ func simulationCreateMsgSubmitProposal(tb testing.TB, r *rand.Rand, keys []crypt
|
||||
deposit,
|
||||
)
|
||||
if msg.ValidateBasic() != nil {
|
||||
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||
err = fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
||||
}
|
||||
return msg
|
||||
return
|
||||
}
|
||||
|
||||
// SimulateMsgDeposit
|
||||
func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
return func(tb testing.TB, 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) {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
key := simulation.RandomKey(r, keys)
|
||||
addr := sdk.AccAddress(key.PubKey().Address())
|
||||
proposalID, ok := randomProposalID(r, k, ctx)
|
||||
@ -68,7 +133,7 @@ func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
deposit := randomDeposit(r)
|
||||
msg := gov.NewMsgDeposit(addr, proposalID, deposit)
|
||||
if msg.ValidateBasic() != nil {
|
||||
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
||||
}
|
||||
ctx, write := ctx.CacheContext()
|
||||
result := gov.NewHandler(k)(ctx, msg)
|
||||
@ -86,18 +151,29 @@ func SimulateMsgDeposit(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
}
|
||||
|
||||
// SimulateMsgVote
|
||||
// nolint: unparam
|
||||
func SimulateMsgVote(k gov.Keeper, sk stake.Keeper) simulation.Operation {
|
||||
return func(tb testing.TB, 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, nil
|
||||
return operationSimulateMsgVote(k, sk, nil, -1)
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func operationSimulateMsgVote(k gov.Keeper, sk stake.Keeper, key crypto.PrivKey, proposalID int64) simulation.Operation {
|
||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, event func(string)) (action string, fOp []simulation.FutureOperation, err error) {
|
||||
if key == nil {
|
||||
key = simulation.RandomKey(r, keys)
|
||||
}
|
||||
var ok bool
|
||||
if proposalID < 0 {
|
||||
proposalID, ok = randomProposalID(r, k, ctx)
|
||||
if !ok {
|
||||
return "no-operation", nil, nil
|
||||
}
|
||||
}
|
||||
addr := sdk.AccAddress(key.PubKey().Address())
|
||||
option := randomVotingOption(r)
|
||||
msg := gov.NewMsgVote(addr, proposalID, option)
|
||||
if msg.ValidateBasic() != nil {
|
||||
tb.Fatalf("expected msg to pass ValidateBasic: %s, log %s", msg.GetSignBytes(), log)
|
||||
return "", nil, fmt.Errorf("expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
|
||||
}
|
||||
ctx, write := ctx.CacheContext()
|
||||
result := gov.NewHandler(k)(ctx, msg)
|
||||
|
||||
@ -24,13 +24,13 @@ func TestGovWithRandomMessages(t *testing.T) {
|
||||
bank.RegisterWire(mapp.Cdc)
|
||||
gov.RegisterWire(mapp.Cdc)
|
||||
mapper := mapp.AccountMapper
|
||||
coinKeeper := bank.NewKeeper(mapper)
|
||||
bankKeeper := bank.NewBaseKeeper(mapper)
|
||||
stakeKey := sdk.NewKVStoreKey("stake")
|
||||
stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, coinKeeper, stake.DefaultCodespace)
|
||||
stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, bankKeeper, stake.DefaultCodespace)
|
||||
paramKey := sdk.NewKVStoreKey("params")
|
||||
paramKeeper := params.NewKeeper(mapp.Cdc, paramKey)
|
||||
govKey := sdk.NewKVStoreKey("gov")
|
||||
govKeeper := gov.NewKeeper(mapp.Cdc, govKey, paramKeeper.Setter(), coinKeeper, stakeKeeper, gov.DefaultCodespace)
|
||||
govKeeper := gov.NewKeeper(mapp.Cdc, govKey, paramKeeper.Setter(), bankKeeper, stakeKeeper, gov.DefaultCodespace)
|
||||
mapp.Router().AddRoute("gov", gov.NewHandler(govKeeper))
|
||||
mapp.SetEndBlocker(func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
gov.EndBlocker(ctx, govKeeper)
|
||||
@ -53,6 +53,7 @@ func TestGovWithRandomMessages(t *testing.T) {
|
||||
gov.InitGenesis(ctx, govKeeper, gov.DefaultGenesisState())
|
||||
}
|
||||
|
||||
// Test with unscheduled votes
|
||||
simulation.Simulate(
|
||||
t, mapp.BaseApp, appStateFn,
|
||||
[]simulation.Operation{
|
||||
@ -66,4 +67,18 @@ func TestGovWithRandomMessages(t *testing.T) {
|
||||
}, 10, 100,
|
||||
false,
|
||||
)
|
||||
|
||||
// Test with scheduled votes
|
||||
simulation.Simulate(
|
||||
t, mapp.BaseApp, appStateFn,
|
||||
[]simulation.Operation{
|
||||
SimulateSubmittingVotingAndSlashingForProposal(govKeeper, stakeKeeper),
|
||||
SimulateMsgDeposit(govKeeper, stakeKeeper),
|
||||
}, []simulation.RandSetup{
|
||||
setup,
|
||||
}, []simulation.Invariant{
|
||||
AllInvariants(),
|
||||
}, 10, 100,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
@ -440,7 +440,7 @@ func TestTallyJailedValidator(t *testing.T) {
|
||||
|
||||
val2, found := sk.GetValidator(ctx, sdk.ValAddress(addrs[1]))
|
||||
require.True(t, found)
|
||||
sk.Jail(ctx, val2.PubKey)
|
||||
sk.Jail(ctx, val2.ConsPubKey)
|
||||
|
||||
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
|
||||
proposalID := proposal.GetProposalID()
|
||||
|
||||
@ -31,7 +31,7 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper,
|
||||
keyGov := sdk.NewKVStoreKey("gov")
|
||||
|
||||
pk := params.NewKeeper(mapp.Cdc, keyGlobalParams)
|
||||
ck := bank.NewKeeper(mapp.AccountMapper)
|
||||
ck := bank.NewBaseKeeper(mapp.AccountMapper)
|
||||
sk := stake.NewKeeper(mapp.Cdc, keyStake, ck, mapp.RegisterCodespace(stake.DefaultCodespace))
|
||||
keeper := NewKeeper(mapp.Cdc, keyGov, pk.Setter(), ck, sk, DefaultCodespace)
|
||||
mapp.Router().AddRoute("gov", NewHandler(keeper))
|
||||
|
||||
@ -21,8 +21,8 @@ func getMockApp(t *testing.T) *mock.App {
|
||||
RegisterWire(mapp.Cdc)
|
||||
keyIBC := sdk.NewKVStoreKey("ibc")
|
||||
ibcMapper := NewMapper(mapp.Cdc, keyIBC, mapp.RegisterCodespace(DefaultCodespace))
|
||||
coinKeeper := bank.NewKeeper(mapp.AccountMapper)
|
||||
mapp.Router().AddRoute("ibc", NewHandler(ibcMapper, coinKeeper))
|
||||
bankKeeper := bank.NewBaseKeeper(mapp.AccountMapper)
|
||||
mapp.Router().AddRoute("ibc", NewHandler(ibcMapper, bankKeeper))
|
||||
|
||||
require.NoError(t, mapp.CompleteSetup([]*sdk.KVStoreKey{keyIBC}))
|
||||
return mapp
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
wire "github.com/cosmos/cosmos-sdk/wire"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@ -28,7 +28,7 @@ func IBCTransferCmd(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "transfer",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
@ -44,10 +44,10 @@ func IBCTransferCmd(cdc *wire.Codec) *cobra.Command {
|
||||
return err
|
||||
}
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
return utils.SendTx(txBldr, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
wire "github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@ -163,6 +163,7 @@ func query(node string, key []byte, storeName string) (res []byte, err error) {
|
||||
return context.NewCLIContext().WithNodeURI(node).QueryStore(key, storeName)
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func (c relayCommander) broadcastTx(seq int64, node string, tx []byte) error {
|
||||
_, err := context.NewCLIContext().WithNodeURI(node).BroadcastTx(tx)
|
||||
return err
|
||||
@ -198,10 +199,10 @@ func (c relayCommander) refine(bz []byte, sequence int64, passphrase string) []b
|
||||
Sequence: sequence,
|
||||
}
|
||||
|
||||
txCtx := authctx.NewTxContextFromCLI().WithSequence(sequence).WithCodec(c.cdc)
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithSequence(sequence).WithCodec(c.cdc)
|
||||
cliCtx := context.NewCLIContext()
|
||||
|
||||
res, err := txCtx.BuildAndSign(cliCtx.FromAddressName, passphrase, []sdk.Msg{msg})
|
||||
res, err := txBldr.BuildAndSign(cliCtx.FromAddressName, passphrase, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
@ -71,7 +71,7 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
|
||||
packet := ibc.NewIBCPacket(sdk.AccAddress(info.GetPubKey().Address()), to, m.Amount, m.SrcChainID, destChainID)
|
||||
msg := ibc.IBCTransferMsg{packet}
|
||||
|
||||
txCtx := authctx.TxContext{
|
||||
txBldr := authtxb.TxBuilder{
|
||||
Codec: cdc,
|
||||
ChainID: m.SrcChainID,
|
||||
AccountNumber: m.AccountNumber,
|
||||
@ -86,24 +86,24 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
|
||||
cliCtx = cliCtx.WithGasAdjustment(adjustment)
|
||||
|
||||
if utils.HasDryRunArg(r) || m.Gas == 0 {
|
||||
newCtx, err := utils.EnrichCtxWithGas(txCtx, cliCtx, m.LocalAccountName, []sdk.Msg{msg})
|
||||
newCtx, err := utils.EnrichCtxWithGas(txBldr, cliCtx, m.LocalAccountName, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
if utils.HasDryRunArg(r) {
|
||||
utils.WriteSimulationResponse(w, txCtx.Gas)
|
||||
utils.WriteSimulationResponse(w, txBldr.Gas)
|
||||
return
|
||||
}
|
||||
txCtx = newCtx
|
||||
txBldr = newCtx
|
||||
}
|
||||
|
||||
if utils.HasGenerateOnlyArg(r) {
|
||||
utils.WriteGenerateStdTxResponse(w, txCtx, []sdk.Msg{msg})
|
||||
utils.WriteGenerateStdTxResponse(w, txBldr, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
txBytes, err := txBldr.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
|
||||
@ -65,7 +65,7 @@ func TestIBC(t *testing.T) {
|
||||
ctx := defaultContext(key)
|
||||
|
||||
am := auth.NewAccountMapper(cdc, key, auth.ProtoBaseAccount)
|
||||
ck := bank.NewKeeper(am)
|
||||
ck := bank.NewBaseKeeper(am)
|
||||
|
||||
src := newAddress()
|
||||
dest := newAddress()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user