Merge branch 'master' into gov_split_vote_weighted_vote
This commit is contained in:
commit
157a24681c
|
@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
|
||||
* (x/{bank,distrib,gov,slashing,staking}) [\#8363](https://github.com/cosmos/cosmos-sdk/issues/8363) Store keys have been modified to allow for variable-length addresses.
|
||||
* (x/ibc) [\#8266](https://github.com/cosmos/cosmos-sdk/issues/8266) Add amino JSON for IBC messages in order to support Ledger text signing.
|
||||
* (x/evidence) [\#8502](https://github.com/cosmos/cosmos-sdk/pull/8502) `HandleEquivocationEvidence` persists the evidence to state.
|
||||
|
||||
### Improvements
|
||||
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
# Cosmovisor
|
||||
|
||||
This is a tiny shim around Cosmos SDK binaries that use the upgrade
|
||||
module that allows for smooth and configurable management of upgrading
|
||||
binaries as a live chain is upgraded, and can be used to simplify validator
|
||||
devops while doing upgrades or to make syncing a full node for genesis
|
||||
simple. The `cosmovisor` will monitor the stdout of the daemon to look
|
||||
for messages from the upgrade module indicating a pending or required upgrade
|
||||
and act appropriately. (With better integrations possible in the future).
|
||||
|
||||
## Arguments
|
||||
|
||||
`cosmovisor` is a shim around a native binary. All arguments passed to the `cosmovisor`
|
||||
command will be passed to the current daemon binary (as a subprocess).
|
||||
It will return stdout and stderr of the subprocess as
|
||||
it's own. Because of that, it cannot accept any command line arguments, nor
|
||||
print anything to output (unless it dies before executing a binary).
|
||||
|
||||
Configuration will be passed in the following environmental variables:
|
||||
|
||||
* `DAEMON_HOME` is the location where upgrade binaries should be kept (can
|
||||
be `$HOME/.gaiad` or `$HOME/.xrnd`)
|
||||
* `DAEMON_NAME` is the name of the binary itself (eg. `xrnd`, `gaiad`, `simd`)
|
||||
* `DAEMON_ALLOW_DOWNLOAD_BINARIES` (optional) if set to `true` will enable auto-downloading of new binaries
|
||||
(for security reasons, this is intended for fullnodes rather than validators)
|
||||
* `DAEMON_RESTART_AFTER_UPGRADE` (optional) if set to `true` it will restart the sub-process with the same args
|
||||
(but new binary) after a successful upgrade. By default, the `cosmovisor` dies afterward and allows the cosmovisor
|
||||
to restart it if needed. Note that this will not auto-restart the child if there was an error.
|
||||
|
||||
## Folder Layout
|
||||
|
||||
`$DAEMON_HOME/cosmovisor` is expected to belong completely to the cosmovisor and
|
||||
subprocesses
|
||||
controlled by it. Under this folder, we will see the following:
|
||||
|
||||
```
|
||||
.
|
||||
├── current -> genesis or upgrades/<name>
|
||||
├── genesis
|
||||
│ └── bin
|
||||
│ └── $DAEMON_NAME
|
||||
└── upgrades
|
||||
└── <name>
|
||||
└── bin
|
||||
└── $DAEMON_NAME
|
||||
```
|
||||
|
||||
Each version of the chain is stored under either `genesis` or `upgrades/<name>`, which holds `bin/$DAEMON_NAME`
|
||||
along with any other needed files (maybe the cli client? maybe some dlls?). `current` is a symlink to the currently
|
||||
active folder (so `current/bin/$DAEMON_NAME` is the binary)
|
||||
|
||||
Note: the `<name>` after `upgrades` is the URI-encoded name of the upgrade as specified in the upgrade module plan.
|
||||
|
||||
Please note that `$DAEMON_HOME/cosmovisor` just stores the *binaries* and associated *program code*.
|
||||
The `cosmovisor` binary can be stored in any typical location (eg `/usr/local/bin`). The actual blockchain
|
||||
program will store it's data under `$GAIA_HOME` etc, which is independent of the `$DAEMON_HOME`. You can
|
||||
choose to export `GAIA_HOME=$DAEMON_HOME` and then end up with a configuation like the following, but this
|
||||
is left as a choice to the admin for best directory layout.
|
||||
|
||||
```
|
||||
.gaiad
|
||||
├── config
|
||||
├── data
|
||||
└── cosmovisor
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Basic Usage:
|
||||
|
||||
* The admin is responsible for installing the `cosmovisor` and setting it as a eg. systemd service to auto-restart, along with proper environmental variables
|
||||
* The admin is responsible for installing the `genesis` folder manually
|
||||
* The `cosmovisor` will set the `current` link to point to `genesis` at first start (when no `current` link exists)
|
||||
* The admin is (generally) responsible for installing the `upgrades/<name>` folders manually
|
||||
* The `cosmovisor` handles switching over the binaries at the correct points, so the admin can prepare days in advance and relax at upgrade time
|
||||
|
||||
Note that chains that wish to support upgrades may package up a genesis `cosmovisor` tar file with this info, just as they
|
||||
prepare the genesis binary tar file. In fact, they may offer a tar file will all upgrades up to current point for easy download
|
||||
for those who wish to sync a fullnode from start.
|
||||
|
||||
The `DAEMON` specific code, like the tendermint config, the application db, syncing blocks, etc is done as normal.
|
||||
The same eg. `GAIA_HOME` directives and command-line flags work, just the binary name is different.
|
||||
|
||||
## Upgradeable Binary Specification
|
||||
|
||||
In the basic version, the `cosmovisor` will read the stdout log messages
|
||||
to determine when an upgrade is needed. We are considering more complex solutions
|
||||
via signaling of some sort, but starting with the simple design:
|
||||
|
||||
* when an upgrade is needed the binary will print a line that matches this
|
||||
regular expression: `UPGRADE "(.*)" NEEDED at height (\d+):(.*)`.
|
||||
* the second match in the above regular expression can be a JSON object with
|
||||
a `binaries` key as described above
|
||||
|
||||
The name (first regexp) will be used to select the new binary to run. If it is present,
|
||||
the current subprocess will be killed, `current` will be upgraded to the new directory,
|
||||
and the new binary will be launched.
|
||||
|
||||
**Question** should we just kill the `cosmovisor` after it does the updates?
|
||||
so it gets a clean restart and just runs the new binary (under `current`).
|
||||
it should be safe to restart (as a service).
|
||||
|
||||
## Auto-Download
|
||||
|
||||
Generally, the system requires that the administrator place all relevant binaries
|
||||
on the disk before the upgrade happens. However, for people who don't need such
|
||||
control and want an easier setup (maybe they are syncing a non-validating fullnode
|
||||
and want to do little maintenance), there is another option.
|
||||
|
||||
If you set `DAEMON_ALLOW_DOWNLOAD_BINARIES=on` then when an upgrade is triggered and no local binary
|
||||
can be found, the `cosmovisor` will attempt to download and install the binary itself.
|
||||
The plan stored in the upgrade module has an info field for arbitrary json.
|
||||
This info is expected to be outputed on the halt log message. There are two
|
||||
valid format to specify a download in such a message:
|
||||
|
||||
1. Store an os/architecture -> binary URI map in the upgrade plan info field
|
||||
as JSON under the `"binaries"` key, eg:
|
||||
```json
|
||||
{
|
||||
"binaries": {
|
||||
"linux/amd64":"https://example.com/gaia.zip?checksum=sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f"
|
||||
}
|
||||
}
|
||||
```
|
||||
The `"any"` key, if it exists, will be used as a default if there is not a specific os/architecture key.
|
||||
2. Store a link to a file that contains all information in the above format (eg. if you want
|
||||
to specify lots of binaries, changelog info, etc without filling up the blockchain).
|
||||
|
||||
e.g `https://example.com/testnet-1001-info.json?checksum=sha256:deaaa99fda9407c4dbe1d04bd49bab0cc3c1dd76fa392cd55a9425be074af01e`
|
||||
|
||||
This file contained in link will be retrieved by [go-getter](https://github.com/hashicorp/go-getter)
|
||||
and the "binaries" field will be parsed as above.
|
||||
|
||||
If there is no local binary, `DAEMON_ALLOW_DOWNLOAD_BINARIES=true`, and we can access a canonical url for the new binary,
|
||||
then the `cosmovisor` will download it with [go-getter](https://github.com/hashicorp/go-getter) and
|
||||
unpack it into the `upgrades/<name>` folder to be run as if we installed it manually
|
||||
|
||||
Note that for this mechanism to provide strong security guarantees, all URLs should include a
|
||||
sha{256,512} checksum. This ensures that no false binary is run, even if someone hacks the server
|
||||
or hijacks the dns. go-getter will always ensure the downloaded file matches the checksum if it
|
||||
is provided. And also handles unpacking archives into directories (so these download links should be
|
||||
a zip of all data in the bin directory).
|
||||
|
||||
To properly create a checksum on linux, you can use the `sha256sum` utility. eg.
|
||||
`sha256sum ./testdata/repo/zip_directory/autod.zip`
|
||||
which should return `29139e1381b8177aec909fab9a75d11381cab5adf7d3af0c05ff1c9c117743a7`.
|
||||
You can also use `sha512sum` if you like longer hashes, or `md5sum` if you like to use broken hashes.
|
||||
Make sure to set the hash algorithm properly in the checksum argument to the url.
|
|
@ -0,0 +1 @@
|
|||
../docs/run-node/cosmovisor.md
|
|
@ -13,7 +13,7 @@ The `context` is a data structure intended to be passed from function to functio
|
|||
|
||||
## Context Definition
|
||||
|
||||
The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) as its base, and has many additional types within its definition that are specific to the Cosmos SDK. he `Context` is integral to transaction processing in that it allows modules to easily access their respective [store](./store.md#base-layer-kvstores) in the [`multistore`](./store.md#multistore) and retrieve transactional context such as the block header and gas meter.
|
||||
The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) as its base, and has many additional types within its definition that are specific to the Cosmos SDK. The `Context` is integral to transaction processing in that it allows modules to easily access their respective [store](./store.md#base-layer-kvstores) in the [`multistore`](./store.md#multistore) and retrieve transactional context such as the block header and gas meter.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L16-L39
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ The full-node client of any SDK application is built by running a `main` functio
|
|||
|
||||
In general, developers will implement the `main.go` function with the following structure:
|
||||
|
||||
- First, an [`appCodec`](./encoding.md) is instanciated for the application.
|
||||
- First, an [`appCodec`](./encoding.md) is instantiated for the application.
|
||||
- Then, the `config` is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/config.go#L13-L24
|
||||
- Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`.
|
||||
|
|
3
go.mod
3
go.mod
|
@ -25,7 +25,7 @@ require (
|
|||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/improbable-eng/grpc-web v0.13.0
|
||||
github.com/improbable-eng/grpc-web v0.14.0
|
||||
github.com/magiconair/properties v1.8.4
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/otiai10/copy v1.4.2
|
||||
|
@ -55,6 +55,7 @@ require (
|
|||
google.golang.org/protobuf v1.25.0
|
||||
gopkg.in/ini.v1 v1.61.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
nhooyr.io/websocket v1.8.6 // indirect
|
||||
)
|
||||
|
||||
replace google.golang.org/grpc => google.golang.org/grpc v1.33.2
|
||||
|
|
36
go.sum
36
go.sum
|
@ -201,6 +201,10 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
|
|||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
|
@ -212,10 +216,24 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
|||
github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0=
|
||||
|
@ -285,6 +303,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
|
|||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
|
@ -343,8 +362,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
|||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
github.com/improbable-eng/grpc-web v0.13.0 h1:7XqtaBWaOCH0cVGKHyvhtcuo6fgW32Y10yRKrDHFHOc=
|
||||
github.com/improbable-eng/grpc-web v0.13.0/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs=
|
||||
github.com/improbable-eng/grpc-web v0.14.0 h1:GdoK+cXABdB+1keuqsV1drSFO2XLYIxqt/4Rj8SWGBk=
|
||||
github.com/improbable-eng/grpc-web v0.14.0/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||
|
@ -363,6 +382,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
|||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
|
@ -377,6 +397,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
|||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA=
|
||||
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
|
@ -388,6 +410,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
|
||||
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
|
@ -433,8 +457,10 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
|
|||
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
|
||||
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs=
|
||||
github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=
|
||||
|
@ -661,7 +687,11 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
|||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vmihailenco/msgpack/v5 v5.0.0-beta.9/go.mod h1:HVxBVPUK/+fZMonk4bi1islLa8V3cfnBug0+4dykPzo=
|
||||
|
@ -951,6 +981,8 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
|
||||
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
|
|
|
@ -15,7 +15,11 @@ var _ exported.GenesisBalance = (*Balance)(nil)
|
|||
|
||||
// GetAddress returns the account address of the Balance object.
|
||||
func (b Balance) GetAddress() sdk.AccAddress {
|
||||
addr, _ := sdk.AccAddressFromBech32(b.Address)
|
||||
addr, err := sdk.AccAddressFromBech32(b.Address)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("couldn't convert %q to account address: %v", b.Address, err))
|
||||
}
|
||||
|
||||
return addr
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package types
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
@ -6,34 +6,34 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
func TestBalanceValidate(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
balance Balance
|
||||
balance bank.Balance
|
||||
expErr bool
|
||||
}{
|
||||
{
|
||||
"valid balance",
|
||||
Balance{
|
||||
bank.Balance{
|
||||
Address: "cosmos1yq8lgssgxlx9smjhes6ryjasmqmd3ts2559g0t",
|
||||
Coins: sdk.Coins{sdk.NewInt64Coin("uatom", 1)},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{"empty balance", Balance{}, true},
|
||||
{"empty balance", bank.Balance{}, true},
|
||||
{
|
||||
"nil balance coins",
|
||||
Balance{
|
||||
bank.Balance{
|
||||
Address: "cosmos1yq8lgssgxlx9smjhes6ryjasmqmd3ts2559g0t",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"dup coins",
|
||||
Balance{
|
||||
bank.Balance{
|
||||
Address: "cosmos1yq8lgssgxlx9smjhes6ryjasmqmd3ts2559g0t",
|
||||
Coins: sdk.Coins{
|
||||
sdk.NewInt64Coin("uatom", 1),
|
||||
|
@ -44,7 +44,7 @@ func TestBalanceValidate(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"invalid coin denom",
|
||||
Balance{
|
||||
bank.Balance{
|
||||
Address: "cosmos1yq8lgssgxlx9smjhes6ryjasmqmd3ts2559g0t",
|
||||
Coins: sdk.Coins{
|
||||
sdk.Coin{Denom: "", Amount: sdk.OneInt()},
|
||||
|
@ -54,7 +54,7 @@ func TestBalanceValidate(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"negative coin",
|
||||
Balance{
|
||||
bank.Balance{
|
||||
Address: "cosmos1yq8lgssgxlx9smjhes6ryjasmqmd3ts2559g0t",
|
||||
Coins: sdk.Coins{
|
||||
sdk.Coin{Denom: "uatom", Amount: sdk.NewInt(-1)},
|
||||
|
@ -78,3 +78,26 @@ func TestBalanceValidate(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalance_GetAddress(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
Address string
|
||||
wantPanic bool
|
||||
}{
|
||||
{"empty address", "", true},
|
||||
{"malformed address", "invalid", true},
|
||||
{"valid address", "cosmos1vy0ga0klndqy92ceqehfkvgmn4t94eteq4hmqv", false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
b := bank.Balance{Address: tt.Address}
|
||||
if tt.wantPanic {
|
||||
require.Panics(t, func() { b.GetAddress() })
|
||||
} else {
|
||||
require.False(t, b.GetAddress().Empty())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,4 +119,5 @@ func (k Keeper) HandleEquivocationEvidence(ctx sdk.Context, evidence *types.Equi
|
|||
|
||||
k.slashingKeeper.JailUntil(ctx, consAddr, types.DoubleSignJailEndTime)
|
||||
k.slashingKeeper.Tombstone(ctx, consAddr)
|
||||
k.SetEvidence(ctx, evidence)
|
||||
}
|
||||
|
|
|
@ -69,6 +69,10 @@ func (suite *KeeperTestSuite) TestHandleDoubleSign() {
|
|||
tstaking.Ctx = ctx
|
||||
tstaking.Denom = stakingParams.BondDenom
|
||||
tstaking.Undelegate(sdk.AccAddress(operatorAddr), operatorAddr, totalBond, true)
|
||||
|
||||
// query evidence from store
|
||||
evidences := suite.app.EvidenceKeeper.GetAllEvidence(ctx)
|
||||
suite.Len(evidences, 1)
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestHandleDoubleSign_TooOld() {
|
||||
|
|
|
@ -66,7 +66,8 @@ The `Handler` (defined below) is responsible for executing the entirety of the
|
|||
business logic for handling `Evidence`. This typically includes validating the
|
||||
evidence, both stateless checks via `ValidateBasic` and stateful checks via any
|
||||
keepers provided to the `Handler`. In addition, the `Handler` may also perform
|
||||
capabilities such as slashing and jailing a validator.
|
||||
capabilities such as slashing and jailing a validator. All `Evidence` handled
|
||||
by the `Handler` should be persisted.
|
||||
|
||||
```go
|
||||
// Handler defines an agnostic Evidence handler. The handler is responsible
|
||||
|
|
Loading…
Reference in New Issue