Merge branch 'develop' into cwgoes/update-tendermint-upstream
This commit is contained in:
commit
f45cfb2f70
52
Gopkg.lock
generated
52
Gopkg.lock
generated
@ -38,7 +38,7 @@
|
||||
name = "github.com/btcsuite/btcd"
|
||||
packages = ["btcec"]
|
||||
pruneopts = "UT"
|
||||
revision = "79e00513b1011888b1e675157ab89f527f901cae"
|
||||
revision = "d81d8877b8f327112e94e814937143a71d1692a7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:386de157f7d19259a7f9c81f26ce011223ce0f090353c1152ffdf730d7d10ac2"
|
||||
@ -95,12 +95,12 @@
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d"
|
||||
digest = "1:c4a2528ccbcabf90f9f3c464a5fc9e302d592861bbfd0b7135a7de8a943d0406"
|
||||
name = "github.com/go-stack/stack"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a"
|
||||
version = "v1.8.0"
|
||||
revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:35621fe20f140f05a0c4ef662c26c0ab4ee50bca78aa30fe87d33120bd28165e"
|
||||
@ -164,13 +164,13 @@
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10"
|
||||
branch = "master"
|
||||
digest = "1:12247a2e99a060cc692f6680e5272c8adf0b8f572e6bce0d7095e624c958a240"
|
||||
name = "github.com/hashicorp/hcl"
|
||||
packages = [
|
||||
".",
|
||||
"hcl/ast",
|
||||
"hcl/parser",
|
||||
"hcl/printer",
|
||||
"hcl/scanner",
|
||||
"hcl/strconv",
|
||||
"hcl/token",
|
||||
@ -179,8 +179,7 @@
|
||||
"json/token",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241"
|
||||
version = "v1.0.0"
|
||||
revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be"
|
||||
@ -215,12 +214,12 @@
|
||||
version = "v1.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5"
|
||||
digest = "1:d4d17353dbd05cb52a2a52b7fe1771883b682806f68db442b436294926bbfafb"
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
|
||||
version = "v0.0.4"
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc"
|
||||
@ -395,13 +394,6 @@
|
||||
pruneopts = "UT"
|
||||
revision = "ae2bd5eed72d46b28834ec3f60db3a3ebedd8dbd"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:605b6546f3f43745695298ec2d342d3e952b6d91cdf9f349bea9315f677d759f"
|
||||
name = "github.com/tendermint/btcd"
|
||||
packages = ["btcec"]
|
||||
pruneopts = "UT"
|
||||
revision = "e5840949ff4fff0c56f9b6a541e22b63581ea9df"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722"
|
||||
@ -423,16 +415,15 @@
|
||||
version = "v0.12.0-rc0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d4a15d404afbf591e8be16fcda7f5ac87948d5c7531f9d909fd84cc730ab16e2"
|
||||
digest = "1:e99ef92d64f2391efbbfb15310df635f96247532bbac2676ea43e466d706401d"
|
||||
name = "github.com/tendermint/iavl"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "35f66e53d9b01e83b30de68b931f54b2477a94c9"
|
||||
version = "v0.9.2"
|
||||
revision = "e5726c0066ccdd299a2ec9262f93c7896cdfcd87"
|
||||
version = "v0.10.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "develop"
|
||||
digest = "1:010630eb6059fa5dd143b9cddb8c9e7c740a9267aca553455de7839515b2fee0"
|
||||
digest = "1:4f15e95fe3888cc75dd34f407d6394cbc7fd3ff24920851b92b295f6a8b556e6"
|
||||
name = "github.com/tendermint/tendermint"
|
||||
packages = [
|
||||
"abci/client",
|
||||
@ -450,8 +441,6 @@
|
||||
"crypto/ed25519",
|
||||
"crypto/encoding/amino",
|
||||
"crypto/merkle",
|
||||
"crypto/multisig",
|
||||
"crypto/multisig/bitarray",
|
||||
"crypto/secp256k1",
|
||||
"crypto/tmhash",
|
||||
"crypto/xsalsa20symmetric",
|
||||
@ -471,6 +460,7 @@
|
||||
"lite",
|
||||
"lite/client",
|
||||
"lite/errors",
|
||||
"lite/files",
|
||||
"lite/proxy",
|
||||
"mempool",
|
||||
"node",
|
||||
@ -493,11 +483,11 @@
|
||||
"state/txindex/kv",
|
||||
"state/txindex/null",
|
||||
"types",
|
||||
"types/time",
|
||||
"version",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "1de32fba17a392b656c73a917843724b92b8989d"
|
||||
revision = "81df19e68ab1519399fccf0cab81cb75bf9d782e"
|
||||
version = "v0.23.1-rc0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bf6d9a827ea3cad964c2f863302e4f6823170d0b5ed16f72cf1184a7c615067e"
|
||||
@ -535,7 +525,7 @@
|
||||
"salsa20/salsa",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "182538f80094b6a8efaade63a8fd8e0d9d5843dd"
|
||||
revision = "614d502a4dac94afa3a6ce146bd1736da82514c6"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d36f55a999540d29b6ea3c2ea29d71c76b1d9853fdcd3e5c5cb4836f2ba118f1"
|
||||
@ -555,14 +545,14 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:0cd3b4a6aec2641ff2bf7e35d93427787c60e5d94998460aab8f54921a1bc2db"
|
||||
digest = "1:86171d21d59449dcf7cee0b7d2da83dff989dab9b9b69bfe0a3d59c3c1ca6081"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"cpu",
|
||||
"unix",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "fa5fdf94c78965f1aa8423f0cc50b8b8d728b05a"
|
||||
revision = "4ea2f632f6e912459fe60b26b1749377f0d889d5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18"
|
||||
@ -593,7 +583,7 @@
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/rpc/status"]
|
||||
pruneopts = "UT"
|
||||
revision = "11092d34479b07829b72e10713b159248caf5dad"
|
||||
revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2dab32a43451e320e49608ff4542fdfc653c95dcc35d0065ec9c6c3dd540ed74"
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
|
||||
[[override]]
|
||||
name = "github.com/tendermint/iavl"
|
||||
version = "=v0.9.2"
|
||||
version = "=v0.10.0"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/tendermint/tendermint"
|
||||
|
||||
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=50 -v -timeout 24h
|
||||
@go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=150 -v -timeout 24h
|
||||
|
||||
test_sim_gaia_slow:
|
||||
@echo "Running full Gaia simulation. This may take awhile!"
|
||||
|
||||
@ -35,6 +35,8 @@ BREAKING CHANGES
|
||||
* [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.
|
||||
* [simulation] Rename TestAndRunTx to Operation [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
|
||||
* [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)
|
||||
|
||||
* Tendermint
|
||||
|
||||
@ -44,6 +46,7 @@ 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 CLI (`gaiacli`)
|
||||
* [cli] Cmds to query staking pool and params
|
||||
@ -53,6 +56,7 @@ FEATURES
|
||||
* [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.
|
||||
|
||||
* Gaia
|
||||
* [cli] #2170 added ability to show the node's address via `gaiad tendermint show-address`
|
||||
@ -83,8 +87,10 @@ IMPROVEMENTS
|
||||
* [x/stake] Improve speed of GetValidator, which was shown to be a performance bottleneck. [#2046](https://github.com/tendermint/tendermint/pull/2200)
|
||||
* 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.
|
||||
* [store] Speedup IAVL iteration, and consequently everything that requires IAVL iteration. [#2143](https://github.com/cosmos/cosmos-sdk/issues/2143)
|
||||
* [store] \#1952 Update IAVL dependency to v0.10.0
|
||||
* [simulation] Make timestamps randomized [#2153](https://github.com/cosmos/cosmos-sdk/pull/2153)
|
||||
|
||||
* 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)
|
||||
|
||||
@ -26,12 +26,6 @@ func (app *BaseApp) SetCMS(cms store.CommitMultiStore) {
|
||||
}
|
||||
app.cms = cms
|
||||
}
|
||||
func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) {
|
||||
if app.sealed {
|
||||
panic("SetTxDecoder() on sealed BaseApp")
|
||||
}
|
||||
app.txDecoder = txDecoder
|
||||
}
|
||||
func (app *BaseApp) SetInitChainer(initChainer sdk.InitChainer) {
|
||||
if app.sealed {
|
||||
panic("SetInitChainer() on sealed BaseApp")
|
||||
|
||||
@ -3,10 +3,11 @@ package context
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
@ -39,6 +40,7 @@ type CLIContext struct {
|
||||
PrintResponse bool
|
||||
Verifier tmlite.Verifier
|
||||
DryRun bool
|
||||
GenerateOnly bool
|
||||
}
|
||||
|
||||
// NewCLIContext returns a new initialized CLIContext with parameters from the
|
||||
@ -66,6 +68,7 @@ func NewCLIContext() CLIContext {
|
||||
PrintResponse: viper.GetBool(client.FlagPrintResponse),
|
||||
Verifier: createVerifier(),
|
||||
DryRun: viper.GetBool(client.FlagDryRun),
|
||||
GenerateOnly: viper.GetBool(client.FlagGenerateOnly),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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.Verifier == nil {
|
||||
|
||||
@ -27,6 +27,7 @@ const (
|
||||
FlagJson = "json"
|
||||
FlagPrintResponse = "print-response"
|
||||
FlagDryRun = "dry-run"
|
||||
FlagGenerateOnly = "generate-only"
|
||||
)
|
||||
|
||||
// LineBreak can be included in a command list to provide a blank line
|
||||
@ -64,6 +65,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command {
|
||||
c.Flags().Bool(FlagPrintResponse, true, "return tx response (only works with async = false)")
|
||||
c.Flags().Bool(FlagTrustNode, true, "Don't verify proofs for query responses")
|
||||
c.Flags().Bool(FlagDryRun, false, "ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it")
|
||||
c.Flags().Bool(FlagGenerateOnly, false, "build an unsigned transaction and write it to STDOUT")
|
||||
}
|
||||
return cmds
|
||||
}
|
||||
|
||||
@ -313,6 +313,22 @@ func TestIBCTransfer(t *testing.T) {
|
||||
// TODO: query ibc egress packet state
|
||||
}
|
||||
|
||||
func TestCoinSendGenerateOnly(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
|
||||
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
|
||||
require.Nil(t, cdc.UnmarshalJSON([]byte(body), &msg))
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
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))
|
||||
}
|
||||
|
||||
func TestTxs(t *testing.T) {
|
||||
name, password := "test", "1234567890"
|
||||
addr, seed := CreateAddr(t, "test", password, GetKeyBase(t))
|
||||
|
||||
@ -3,11 +3,17 @@ package utils
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
const (
|
||||
queryArgDryRun = "simulate"
|
||||
queryArgDryRun = "simulate"
|
||||
queryArgGenerateOnly = "generate_only"
|
||||
)
|
||||
|
||||
// WriteErrorResponse prepares and writes a HTTP error
|
||||
@ -26,9 +32,10 @@ func WriteSimulationResponse(w http.ResponseWriter, gas int64) {
|
||||
|
||||
// HasDryRunArg returns true if the request's URL query contains
|
||||
// the dry run argument and its value is set to "true".
|
||||
func HasDryRunArg(r *http.Request) bool {
|
||||
return r.URL.Query().Get(queryArgDryRun) == "true"
|
||||
}
|
||||
func HasDryRunArg(r *http.Request) bool { return urlQueryHasArg(r.URL, queryArgDryRun) }
|
||||
|
||||
// HasGenerateOnlyArg returns whether a URL's query "generate-only" parameter is set to "true".
|
||||
func HasGenerateOnlyArg(r *http.Request) bool { return urlQueryHasArg(r.URL, queryArgGenerateOnly) }
|
||||
|
||||
// ParseFloat64OrReturnBadRequest converts s to a float64 value. It returns a default
|
||||
// value if the string is empty. Write
|
||||
@ -43,3 +50,21 @@ func ParseFloat64OrReturnBadRequest(w http.ResponseWriter, s string, defaultIfEm
|
||||
}
|
||||
return n, true
|
||||
}
|
||||
|
||||
// WriteGenerateStdTxResponse writes response for the generate_only mode.
|
||||
func WriteGenerateStdTxResponse(w http.ResponseWriter, txCtx authctx.TxContext, msgs []sdk.Msg) {
|
||||
stdMsg, err := txCtx.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))
|
||||
if err != nil {
|
||||
WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
w.Write(output)
|
||||
return
|
||||
}
|
||||
|
||||
func urlQueryHasArg(url *url.URL, arg string) bool { return url.Query().Get(arg) == "true" }
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"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"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
@ -28,7 +29,7 @@ func SendTx(txCtx authctx.TxContext, cliCtx context.CLIContext, msgs []sdk.Msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "estimated gas = %v\n", txCtx.Gas)
|
||||
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txCtx.Gas)
|
||||
}
|
||||
if cliCtx.DryRun {
|
||||
return nil
|
||||
@ -85,6 +86,19 @@ func CalculateGas(queryFunc func(string, common.HexBytes) ([]byte, error), cdc *
|
||||
return
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
json, err := txCtx.Codec.MarshalJSON(stdTx)
|
||||
if err == nil {
|
||||
fmt.Printf("%s\n", json)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func adjustGasEstimate(estimate int64, adjustment float64) int64 {
|
||||
return int64(adjustment * float64(estimate))
|
||||
}
|
||||
@ -128,3 +142,24 @@ func prepareTxContext(txCtx authctx.TxContext, cliCtx context.CLIContext) (authc
|
||||
}
|
||||
return txCtx, 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)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if txCtx.Gas == 0 {
|
||||
txCtx, err = EnrichCtxWithGas(txCtx, cliCtx, cliCtx.FromAddressName, msgs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txCtx.Gas)
|
||||
}
|
||||
stdSignMsg, err := txCtx.Build(msgs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return auth.NewStdTx(stdSignMsg.Msgs, stdSignMsg.Fee, nil, stdSignMsg.Memo), nil
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -189,7 +189,7 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||
t.Skip("Skipping Gaia simulation")
|
||||
}
|
||||
|
||||
numSeeds := 5
|
||||
numSeeds := 3
|
||||
numTimesToRunPerSeed := 5
|
||||
appHashList := make([]json.RawMessage, numTimesToRunPerSeed)
|
||||
|
||||
@ -206,10 +206,11 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||
testAndRunTxs(app),
|
||||
[]simulation.RandSetup{},
|
||||
[]simulation.Invariant{},
|
||||
20,
|
||||
20,
|
||||
true,
|
||||
50,
|
||||
100,
|
||||
false,
|
||||
)
|
||||
app.Commit()
|
||||
appHash := app.LastCommitID().Hash
|
||||
appHashList[j] = appHash
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
@ -155,8 +156,18 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
|
||||
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(1))
|
||||
|
||||
// Test --generate-only
|
||||
success, stdout, stderr := executeWriteRetStdStreams(t, cvStr+" --generate-only", app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
require.True(t, success)
|
||||
require.Empty(t, stderr)
|
||||
msg := unmarshalStdTx(t, stdout)
|
||||
require.NotZero(t, msg.Fee.Gas)
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
require.Equal(t, 0, len(msg.GetSignatures()))
|
||||
|
||||
// Test --dry-run
|
||||
success := executeWrite(t, cvStr+" --dry-run", app.DefaultKeyPass)
|
||||
success = executeWrite(t, cvStr+" --dry-run", app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
|
||||
executeWrite(t, cvStr, app.DefaultKeyPass)
|
||||
@ -222,8 +233,18 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
spStr += fmt.Sprintf(" --title=%s", "Test")
|
||||
spStr += fmt.Sprintf(" --description=%s", "test")
|
||||
|
||||
// Test generate only
|
||||
success, stdout, stderr := executeWriteRetStdStreams(t, spStr+" --generate-only", app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
require.True(t, success)
|
||||
require.Empty(t, stderr)
|
||||
msg := unmarshalStdTx(t, stdout)
|
||||
require.NotZero(t, msg.Fee.Gas)
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
require.Equal(t, 0, len(msg.GetSignatures()))
|
||||
|
||||
// Test --dry-run
|
||||
success := executeWrite(t, spStr+" --dry-run", app.DefaultKeyPass)
|
||||
success = executeWrite(t, spStr+" --dry-run", app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
|
||||
executeWrite(t, spStr, app.DefaultKeyPass)
|
||||
@ -244,6 +265,16 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
depositStr += fmt.Sprintf(" --deposit=%s", "10steak")
|
||||
depositStr += fmt.Sprintf(" --proposal-id=%s", "1")
|
||||
|
||||
// Test generate only
|
||||
success, stdout, stderr = executeWriteRetStdStreams(t, depositStr+" --generate-only", app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
require.True(t, success)
|
||||
require.Empty(t, stderr)
|
||||
msg = unmarshalStdTx(t, stdout)
|
||||
require.NotZero(t, msg.Fee.Gas)
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
require.Equal(t, 0, len(msg.GetSignatures()))
|
||||
|
||||
executeWrite(t, depositStr, app.DefaultKeyPass)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
|
||||
@ -258,6 +289,16 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
voteStr += fmt.Sprintf(" --proposal-id=%s", "1")
|
||||
voteStr += fmt.Sprintf(" --option=%s", "Yes")
|
||||
|
||||
// Test generate only
|
||||
success, stdout, stderr = executeWriteRetStdStreams(t, voteStr+" --generate-only", app.DefaultKeyPass)
|
||||
require.True(t, success)
|
||||
require.True(t, success)
|
||||
require.Empty(t, stderr)
|
||||
msg = unmarshalStdTx(t, stdout)
|
||||
require.NotZero(t, msg.Fee.Gas)
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
require.Equal(t, 0, len(msg.GetSignatures()))
|
||||
|
||||
executeWrite(t, voteStr, app.DefaultKeyPass)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
|
||||
@ -291,6 +332,52 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
require.Equal(t, " 2 - Apples", proposalsQuery)
|
||||
}
|
||||
|
||||
func TestGaiaCLISendGenerateOnly(t *testing.T) {
|
||||
chainID, servAddr, port := initializeFixtures(t)
|
||||
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
|
||||
|
||||
defer proc.Stop(false)
|
||||
tests.WaitForTMStart(port)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
|
||||
barAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show bar --output=json --home=%s", gaiacliHome))
|
||||
|
||||
// Test generate sendTx with default gas
|
||||
success, stdout, stderr := executeWriteRetStdStreams(t, fmt.Sprintf(
|
||||
"gaiacli send %v --amount=10steak --to=%s --from=foo --generate-only",
|
||||
flags, barAddr), []string{}...)
|
||||
require.True(t, success)
|
||||
require.Empty(t, stderr)
|
||||
msg := unmarshalStdTx(t, stdout)
|
||||
require.Equal(t, msg.Fee.Gas, int64(client.DefaultGasLimit))
|
||||
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",
|
||||
flags, barAddr), []string{}...)
|
||||
require.True(t, success)
|
||||
require.Empty(t, stderr)
|
||||
msg = unmarshalStdTx(t, stdout)
|
||||
require.Equal(t, msg.Fee.Gas, int64(100))
|
||||
require.Equal(t, len(msg.Msgs), 1)
|
||||
require.Equal(t, 0, len(msg.GetSignatures()))
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
// helper methods
|
||||
|
||||
@ -315,6 +402,12 @@ func initializeFixtures(t *testing.T) (chainID, servAddr, port string) {
|
||||
return
|
||||
}
|
||||
|
||||
func unmarshalStdTx(t *testing.T, s string) (stdTx auth.StdTx) {
|
||||
cdc := app.MakeCodec()
|
||||
require.Nil(t, cdc.UnmarshalJSON([]byte(s), &stdTx))
|
||||
return
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
// executors
|
||||
|
||||
|
||||
@ -224,9 +224,9 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig []byte, pub t
|
||||
}
|
||||
case offlineInfo:
|
||||
linfo := info.(offlineInfo)
|
||||
fmt.Printf("Bytes to sign:\n%s", msg)
|
||||
fmt.Fprintf(os.Stderr, "Bytes to sign:\n%s", msg)
|
||||
buf := bufio.NewReader(os.Stdin)
|
||||
fmt.Printf("\nEnter Amino-encoded signature:\n")
|
||||
fmt.Fprintf(os.Stderr, "\nEnter Amino-encoded signature:\n")
|
||||
// Will block until user inputs the signature
|
||||
signed, err := buf.ReadString('\n')
|
||||
if err != nil {
|
||||
|
||||
2
docs/_attic/WIP-lamborghini-distribution/README.md
Normal file
2
docs/_attic/WIP-lamborghini-distribution/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
Please note that this folder is a WIP specification for an advanced fee distribution
|
||||
mechanism which is not set to be implemented.
|
||||
36
docs/_attic/WIP-lamborghini-distribution/end_block.md
Normal file
36
docs/_attic/WIP-lamborghini-distribution/end_block.md
Normal file
@ -0,0 +1,36 @@
|
||||
# End Block
|
||||
|
||||
At each endblock, the fees received are sorted to the proposer, community fund,
|
||||
and global pool. When the validator is the proposer of the round, that
|
||||
validator (and their delegators) receives between 1% and 5% of fee rewards, the
|
||||
reserve tax is then charged, then the remainder is distributed proportionally
|
||||
by voting power to all bonded validators independent of whether they voted
|
||||
(social distribution). Note the social distribution is applied to proposer
|
||||
validator in addition to the proposer reward.
|
||||
|
||||
The amount of proposer reward is calculated from pre-commits Tendermint
|
||||
messages in order to incentivize validators to wait and include additional
|
||||
pre-commits in the block. All provision rewards are added to a provision reward
|
||||
pool which validator holds individually
|
||||
(`ValidatorDistribution.ProvisionsRewardPool`).
|
||||
|
||||
```
|
||||
func SortFees(feesCollected sdk.Coins, global Global, proposer ValidatorDistribution,
|
||||
sumPowerPrecommitValidators, totalBondedTokens, communityTax sdk.Dec)
|
||||
|
||||
feesCollectedDec = MakeDecCoins(feesCollected)
|
||||
proposerReward = feesCollectedDec * (0.01 + 0.04
|
||||
* sumPowerPrecommitValidators / totalBondedTokens)
|
||||
proposer.ProposerPool += proposerReward
|
||||
|
||||
communityFunding = feesCollectedDec * communityTax
|
||||
global.CommunityFund += communityFunding
|
||||
|
||||
poolReceived = feesCollectedDec - proposerReward - communityFunding
|
||||
global.Pool += poolReceived
|
||||
global.EverReceivedPool += poolReceived
|
||||
global.LastReceivedPool = poolReceived
|
||||
|
||||
SetValidatorDistribution(proposer)
|
||||
SetGlobal(global)
|
||||
```
|
||||
54
docs/_attic/WIP-lamborghini-distribution/overview.md
Normal file
54
docs/_attic/WIP-lamborghini-distribution/overview.md
Normal file
@ -0,0 +1,54 @@
|
||||
# Distribution
|
||||
|
||||
## Overview
|
||||
|
||||
Collected fees are pooled globally and divided out passively to validators and
|
||||
delegators. Each validator has the opportunity to charge commission to the
|
||||
delegators on the fees collected on behalf of the delegators by the validators.
|
||||
Fees are paid directly into a global fee pool, and validator proposer-reward
|
||||
pool. Due to the nature of passive accounting whenever changes to parameters
|
||||
which affect the rate of fee distribution occurs, withdrawal of fees must also
|
||||
occur when:
|
||||
|
||||
- withdrawing one must withdrawal the maximum amount they are entitled
|
||||
too, leaving nothing in the pool,
|
||||
- bonding, unbonding, or re-delegating tokens to an existing account a
|
||||
full withdrawal of the fees must occur (as the rules for lazy accounting
|
||||
change),
|
||||
- a validator chooses to change the commission on fees, all accumulated
|
||||
commission fees must be simultaneously withdrawn.
|
||||
|
||||
The above scenarios are covered in `triggers.md`.
|
||||
|
||||
The distribution mechanism outlines herein is used to lazily distribute the
|
||||
following between validators and associated delegators:
|
||||
- multi-token fees to be socially distributed,
|
||||
- proposer reward pool,
|
||||
- inflated atom provisions, and
|
||||
- validator commission on all rewards earned by their delegators stake
|
||||
|
||||
Fees are pooled within a global pool, as well as validator specific
|
||||
proposer-reward pools. The mechanisms used allow for validators and delegators
|
||||
to independently and lazily withdrawn their rewards. As a part of the lazy
|
||||
computations adjustment factors must be maintained for each validator and
|
||||
delegator to determine the true proportion of fees in each pool which they are
|
||||
entitled too. Adjustment factors are updated every time a validator or
|
||||
delegator's voting power changes. Validators and delegators must withdraw all
|
||||
fees they are entitled too before they can change their portion of bonded
|
||||
Atoms.
|
||||
|
||||
## Affect on Staking
|
||||
|
||||
|
||||
Charging commission on Atom provisions while also allowing for Atom-provisions
|
||||
to be auto-bonded (distributed directly to the validators bonded stake) is
|
||||
problematic within DPoS. Fundamentally these two mechnisms are mutually
|
||||
exclusive. If there are atoms commissions and auto-bonding Atoms, the portion
|
||||
of Atoms the fee distribution calculation would become very large as the Atom
|
||||
portion for each delegator would change each block making a withdrawal of fees
|
||||
for a delegator require a calculation for every single block since the last
|
||||
withdrawal. In conclusion we can only have atom commission and unbonded atoms
|
||||
provisions, or bonded atom provisions with no Atom commission, and we elect to
|
||||
implement the former. Stakeholders wishing to rebond their provisions may elect
|
||||
to set up a script to periodically withdraw and rebond fees.
|
||||
|
||||
100
docs/_attic/WIP-lamborghini-distribution/state.md
Normal file
100
docs/_attic/WIP-lamborghini-distribution/state.md
Normal file
@ -0,0 +1,100 @@
|
||||
## State
|
||||
|
||||
### Global
|
||||
|
||||
All globally tracked parameters for distribution are stored within
|
||||
`Global`. Rewards are collected and added to the reward pool and
|
||||
distributed to validators/delegators from here.
|
||||
|
||||
Note that the reward pool holds decimal coins (`DecCoins`) to allow
|
||||
for fractions of coins to be received from operations like inflation.
|
||||
When coins are distributed from the pool they are truncated back to
|
||||
`sdk.Coins` which are non-decimal.
|
||||
|
||||
- Global: `0x00 -> amino(global)`
|
||||
|
||||
```golang
|
||||
// coins with decimal
|
||||
type DecCoins []DecCoin
|
||||
|
||||
type DecCoin struct {
|
||||
Amount sdk.Dec
|
||||
Denom string
|
||||
}
|
||||
|
||||
type Global struct {
|
||||
PrevBondedTokens sdk.Dec // bonded token amount for the global pool on the previous block
|
||||
Adjustment sdk.Dec // global adjustment factor for lazy calculations
|
||||
Pool DecCoins // funds for all validators which have yet to be withdrawn
|
||||
PrevReceivedPool DecCoins // funds added to the pool on the previous block
|
||||
EverReceivedPool DecCoins // total funds ever added to the pool
|
||||
CommunityFund DecCoins // pool for community funds yet to be spent
|
||||
}
|
||||
```
|
||||
|
||||
### Validator Distribution
|
||||
|
||||
Validator distribution information for the relevant validator is updated each time:
|
||||
1. delegation amount to a validator are updated,
|
||||
2. a validator successfully proposes a block and receives a reward,
|
||||
3. any delegator withdraws from a validator, or
|
||||
4. the validator withdraws it's commission.
|
||||
|
||||
- ValidatorDistribution: `0x02 | ValOwnerAddr -> amino(validatorDistribution)`
|
||||
|
||||
```golang
|
||||
type ValidatorDistribution struct {
|
||||
CommissionWithdrawalHeight int64 // last time this validator withdrew commission
|
||||
Adjustment sdk.Dec // global pool adjustment factor
|
||||
ProposerAdjustment DecCoins // proposer pool adjustment factor
|
||||
ProposerPool DecCoins // reward pool collected from being the proposer
|
||||
EverReceivedProposerReward DecCoins // all rewards ever collected from being the proposer
|
||||
PrevReceivedProposerReward DecCoins // previous rewards collected from being the proposer
|
||||
PrevBondedTokens sdk.Dec // bonded token amount on the previous block
|
||||
PrevDelegatorShares sdk.Dec // amount of delegator shares for the validator on the previous block
|
||||
}
|
||||
```
|
||||
|
||||
### Delegation Distribution
|
||||
|
||||
Each delegation holds multiple adjustment factors to specify its entitlement to
|
||||
the rewards from a validator. `AdjustmentPool` is used to passively calculate
|
||||
each bonds entitled fees from the `RewardPool`. `AdjustmentPool` is used to
|
||||
passively calculate each bonds entitled fees from
|
||||
`ValidatorDistribution.ProposerRewardPool`
|
||||
|
||||
- DelegatorDistribution: ` 0x02 | DelegatorAddr | ValOwnerAddr -> amino(delegatorDist)`
|
||||
|
||||
```golang
|
||||
type DelegatorDist struct {
|
||||
WithdrawalHeight int64 // last time this delegation withdrew rewards
|
||||
Adjustment sdk.Dec // fee provisioning adjustment factor
|
||||
AdjustmentProposer DecCoins // proposers pool adjustment factor
|
||||
PrevTokens sdk.Dec // bonded tokens held by the delegation on the previous block
|
||||
PrevShares sdk.Dec // delegator shares held by the delegation on the previous block
|
||||
}
|
||||
```
|
||||
|
||||
### Power Change
|
||||
|
||||
Every instance that the voting power changes, information about the state of
|
||||
the validator set during the change must be recorded as a `PowerChange` for
|
||||
other validators to run through. Each power change is indexed by its block
|
||||
height.
|
||||
|
||||
- PowerChange: `0x03 | amino(Height) -> amino(validatorDist)`
|
||||
|
||||
```golang
|
||||
type PowerChange struct {
|
||||
Height int64 // block height at change
|
||||
ValidatorBondedTokens sdk.Dec // following used to create distribution scenarios
|
||||
ValidatorDelegatorShares sdk.Dec
|
||||
ValidatorDelegatorShareExRate sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
PoolBondedTokens sdk.Dec
|
||||
Global Global
|
||||
ValDistr ValidatorDistribution
|
||||
DelegationShares sdk.Dec
|
||||
DelDistr DelegatorDistribution
|
||||
}
|
||||
```
|
||||
399
docs/_attic/WIP-lamborghini-distribution/transactions.md
Normal file
399
docs/_attic/WIP-lamborghini-distribution/transactions.md
Normal file
@ -0,0 +1,399 @@
|
||||
# Transactions
|
||||
|
||||
## TxWithdrawDelegation
|
||||
|
||||
When a delegator wishes to withdraw their transaction fees it must send
|
||||
`TxWithdrawDelegation`. Note that parts of this transaction logic are also
|
||||
triggered each with any change in individual delegations, such as an unbond,
|
||||
redelegation, or delegation of additional tokens to a specific validator.
|
||||
|
||||
Each time a withdrawal is made by a recipient the adjustment term must be
|
||||
modified for each block with a change in distributors shares since the time of
|
||||
last withdrawal. This is accomplished by iterating over all relevant
|
||||
`PowerChange`'s stored in distribution state.
|
||||
|
||||
|
||||
```golang
|
||||
type TxWithdrawDelegation struct {
|
||||
delegatorAddr sdk.AccAddress
|
||||
withdrawAddr sdk.AccAddress // address to make the withdrawal to
|
||||
}
|
||||
|
||||
func WithdrawDelegator(delegatorAddr, withdrawAddr sdk.AccAddress)
|
||||
entitlement = GetDelegatorEntitlement(delegatorAddr)
|
||||
AddCoins(withdrawAddr, totalEntitlment.TruncateDecimal())
|
||||
|
||||
func GetDelegatorEntitlement(delegatorAddr sdk.AccAddress) DecCoins
|
||||
|
||||
// compile all the distribution scenarios
|
||||
delegations = GetDelegations(delegatorAddr)
|
||||
DelDistr = GetDelegationDistribution(delegation.DelegatorAddr,
|
||||
delegation.ValidatorAddr)
|
||||
pcs = GetPowerChanges(DelDistr.WithdrawalHeight)
|
||||
|
||||
// update all adjustment factors for each delegation since last withdrawal
|
||||
for pc = range pcs
|
||||
for delegation = range delegations
|
||||
DelDistr = GetDelegationDistribution(delegation.DelegatorAddr,
|
||||
delegation.ValidatorAddr)
|
||||
pc.ProcessPowerChangeDelegation(delegation, DelDistr)
|
||||
|
||||
// collect all entitled fees
|
||||
entitlement = 0
|
||||
for delegation = range delegations
|
||||
global = GetGlobal()
|
||||
pool = GetPool()
|
||||
DelDistr = GetDelegationDistribution(delegation.DelegatorAddr,
|
||||
delegation.ValidatorAddr)
|
||||
ValDistr = GetValidatorDistribution(delegation.ValidatorAddr)
|
||||
validator = GetValidator(delegation.ValidatorAddr)
|
||||
|
||||
scenerio1 = NewDelegationFromGlobalPool(delegation, validator,
|
||||
pool, global, ValDistr, DelDistr)
|
||||
scenerio2 = NewDelegationFromProvisionPool(delegation, validator,
|
||||
ValDistr, DelDistr)
|
||||
entitlement += scenerio1.WithdrawalEntitlement()
|
||||
entitlement += scenerio2.WithdrawalEntitlement()
|
||||
|
||||
return entitlement
|
||||
|
||||
func (pc PowerChange) ProcessPowerChangeDelegation(delegation sdk.Delegation,
|
||||
DelDistr DelegationDistribution)
|
||||
|
||||
// get the historical scenarios
|
||||
scenario1 = pc.DelegationFromGlobalPool(delegation, DelDistr)
|
||||
scenario2 = pc.DelegationFromProvisionPool(delegation, DelDistr)
|
||||
|
||||
// process the adjustment factors
|
||||
scenario1.UpdateAdjustmentForPowerChange(pc.Height)
|
||||
scenario2.UpdateAdjustmentForPowerChange(pc.Height)
|
||||
```
|
||||
|
||||
## TxWithdrawValidator
|
||||
|
||||
When a validator wishes to withdraw their transaction fees it must send
|
||||
`TxWithdrawDelegation`. Note that parts of this transaction logic is also
|
||||
triggered each with any change in individual delegations, such as an unbond,
|
||||
redelegation, or delegation of additional tokens to a specific validator. This
|
||||
transaction withdraws the validators commission rewards, as well as any rewards
|
||||
earning on their self-delegation.
|
||||
|
||||
```golang
|
||||
type TxWithdrawValidator struct {
|
||||
ownerAddr sdk.AccAddress // validator address to withdraw from
|
||||
withdrawAddr sdk.AccAddress // address to make the withdrawal to
|
||||
}
|
||||
|
||||
func WithdrawalValidator(ownerAddr, withdrawAddr sdk.AccAddress)
|
||||
|
||||
// update the delegator adjustment factors and also withdrawal delegation fees
|
||||
entitlement = GetDelegatorEntitlement(ownerAddr)
|
||||
|
||||
// update the validator adjustment factors for commission
|
||||
ValDistr = GetValidatorDistribution(ownerAddr.ValidatorAddr)
|
||||
pcs = GetPowerChanges(ValDistr.CommissionWithdrawalHeight)
|
||||
for pc = range pcs
|
||||
pc.ProcessPowerChangeCommission()
|
||||
|
||||
// withdrawal validator commission rewards
|
||||
global = GetGlobal()
|
||||
pool = GetPool()
|
||||
ValDistr = GetValidatorDistribution(delegation.ValidatorAddr)
|
||||
validator = GetValidator(delegation.ValidatorAddr)
|
||||
|
||||
scenerio1 = NewCommissionFromGlobalPool(validator,
|
||||
pool, global, ValDistr)
|
||||
scenerio2 = CommissionFromProposerPool(validator, ValDistr)
|
||||
entitlement += scenerio1.WithdrawalEntitlement()
|
||||
entitlement += scenerio2.WithdrawalEntitlement()
|
||||
|
||||
AddCoins(withdrawAddr, totalEntitlment.TruncateDecimal())
|
||||
|
||||
func (pc PowerChange) ProcessPowerChangeCommission()
|
||||
|
||||
// get the historical scenarios
|
||||
scenario1 = pc.CommissionFromGlobalPool()
|
||||
scenario2 = pc.CommissionFromProposerPool()
|
||||
|
||||
// process the adjustment factors
|
||||
scenario1.UpdateAdjustmentForPowerChange(pc.Height)
|
||||
scenario2.UpdateAdjustmentForPowerChange(pc.Height)
|
||||
```
|
||||
|
||||
## Common Calculations
|
||||
|
||||
### Distribution scenario
|
||||
|
||||
A common form of abstracted calculations exists between validators and
|
||||
delegations attempting to withdrawal their rewards, either from `Global.Pool`
|
||||
or from `ValidatorDistribution.ProposerPool`. With the following interface
|
||||
fulfilled the entitled fees for the various scenarios can be calculated.
|
||||
|
||||
```golang
|
||||
type DistributionScenario interface {
|
||||
DistributorTokens() DecCoins // current tokens from distributor
|
||||
DistributorCumulativeTokens() DecCoins // total tokens ever received
|
||||
DistributorPrevReceivedTokens() DecCoins // last value of tokens received
|
||||
DistributorShares() sdk.Dec // current shares
|
||||
DistributorPrevShares() sdk.Dec // shares last block
|
||||
|
||||
RecipientAdjustment() sdk.Dec
|
||||
RecipientShares() sdk.Dec // current shares
|
||||
RecipientPrevShares() sdk.Dec // shares last block
|
||||
|
||||
ModifyAdjustments(withdrawal sdk.Dec) // proceedure to modify adjustment factors
|
||||
}
|
||||
```
|
||||
|
||||
#### Entitled reward from distribution scenario
|
||||
|
||||
The entitlement to the distributor's tokens held can be accounted for lazily.
|
||||
To begin this calculation we must determine the recipient's _simple pool_ and
|
||||
_projected pool_. The simple pool represents a lazy accounting of what a
|
||||
recipient's entitlement to the distributor's tokens would be if all recipients
|
||||
for that distributor had static shares (equal to the current shares), and no
|
||||
recipients had ever withdrawn their entitled rewards. The projected pool
|
||||
represents the anticipated recipient's entitlement to the distributors tokens
|
||||
based on the current blocks token input (for example fees reward received) to
|
||||
the distributor, and the distributor's tokens and shares of the previous block
|
||||
assuming that neither had changed in the current block. Using the simple and
|
||||
projected pools we can determine all cumulative changes which have taken place
|
||||
outside of the recipient and adjust the recipient's _adjustment factor_ to
|
||||
account for these changes and ultimately keep track of the correct entitlement
|
||||
to the distributors tokens.
|
||||
|
||||
```
|
||||
func (d DistributionScenario) RecipientCount(height int64) sdk.Dec
|
||||
return v.RecipientShares() * height
|
||||
|
||||
func (d DistributionScenario) GlobalCount(height int64) sdk.Dec
|
||||
return d.DistributorShares() * height
|
||||
|
||||
func (d DistributionScenario) SimplePool() DecCoins
|
||||
return d.RecipientCount() / d.GlobalCount() * d.DistributorCumulativeTokens
|
||||
|
||||
func (d DistributionScenario) ProjectedPool(height int64) DecCoins
|
||||
return d.RecipientPrevShares() * (height-1)
|
||||
/ (d.DistributorPrevShares() * (height-1))
|
||||
* d.DistributorCumulativeTokens
|
||||
+ d.RecipientShares() / d.DistributorShares()
|
||||
* d.DistributorPrevReceivedTokens()
|
||||
```
|
||||
|
||||
The `DistributionScenario` _adjustment_ terms account for changes in
|
||||
recipient/distributor shares and recipient withdrawals. The adjustment factor
|
||||
must be modified whenever the recipient withdraws from the distributor or the
|
||||
distributor's/recipient's shares are changed.
|
||||
- When the shares of the recipient is changed the adjustment factor is
|
||||
increased/decreased by the difference between the _simple_ and _projected_
|
||||
pools. In other words, the cumulative difference in the shares if the shares
|
||||
has been the new shares as opposed to the old shares for the entire duration of
|
||||
the blockchain up the previous block.
|
||||
- When a recipient makes a withdrawal the adjustment factor is increased by the
|
||||
withdrawal amount.
|
||||
|
||||
```
|
||||
func (d DistributionScenario) UpdateAdjustmentForPowerChange(height int64)
|
||||
simplePool = d.SimplePool()
|
||||
projectedPool = d.ProjectedPool(height)
|
||||
AdjustmentChange = simplePool - projectedPool
|
||||
if AdjustmentChange > 0
|
||||
d.ModifyAdjustments(AdjustmentChange)
|
||||
|
||||
func (d DistributionScenario) WithdrawalEntitlement() DecCoins
|
||||
entitlement = d.SimplePool() - d.RecipientAdjustment()
|
||||
d.ModifyAdjustments(entitlement)
|
||||
return entitlement
|
||||
```
|
||||
|
||||
### Distribution scenarios
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
```
|
||||
type DelegationFromGlobalPool struct {
|
||||
DelegationShares sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
ValidatorBondedTokens sdk.Dec
|
||||
ValidatorDelegatorShareExRate sdk.Dec
|
||||
PoolBondedTokens sdk.Dec
|
||||
Global Global
|
||||
ValDistr ValidatorDistribution
|
||||
DelDistr DelegatorDistribution
|
||||
}
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorTokens() DecCoins
|
||||
return d.Global.Pool
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorCumulativeTokens() DecCoins
|
||||
return d.Global.EverReceivedPool
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorPrevReceivedTokens() DecCoins
|
||||
return d.Global.PrevReceivedPool
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorShares() sdk.Dec
|
||||
return d.PoolBondedTokens
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorPrevShares() sdk.Dec
|
||||
return d.Global.PrevBondedTokens
|
||||
|
||||
func (d DelegationFromGlobalPool) RecipientShares() sdk.Dec
|
||||
return d.DelegationShares * d.ValidatorDelegatorShareExRate() *
|
||||
d.ValidatorBondedTokens() * (1 - d.ValidatorCommission)
|
||||
|
||||
func (d DelegationFromGlobalPool) RecipientPrevShares() sdk.Dec
|
||||
return d.DelDistr.PrevTokens
|
||||
|
||||
func (d DelegationFromGlobalPool) RecipientAdjustment() sdk.Dec
|
||||
return d.DelDistr.Adjustment
|
||||
|
||||
func (d DelegationFromGlobalPool) ModifyAdjustments(withdrawal sdk.Dec)
|
||||
d.ValDistr.Adjustment += withdrawal
|
||||
d.DelDistr.Adjustment += withdrawal
|
||||
d.global.Adjustment += withdrawal
|
||||
SetValidatorDistribution(d.ValDistr)
|
||||
SetDelegatorDistribution(d.DelDistr)
|
||||
SetGlobal(d.Global)
|
||||
```
|
||||
|
||||
#### Delegation's entitlement to ValidatorDistribution.ProposerPool
|
||||
|
||||
Delegations (including validator's self-delegation) are still subject
|
||||
commission on the rewards gained from the proposer pool. Global shares in this
|
||||
context is actually the validators total delegations shares. The recipient's
|
||||
shares is taken as the effective delegation shares less the validator's
|
||||
commission.
|
||||
|
||||
```
|
||||
type DelegationFromProposerPool struct {
|
||||
DelegationShares sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
ValidatorDelegatorShares sdk.Dec
|
||||
ValDistr ValidatorDistribution
|
||||
DelDistr DelegatorDistribution
|
||||
}
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorTokens() DecCoins
|
||||
return d.ValDistr.ProposerPool
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorCumulativeTokens() DecCoins
|
||||
return d.ValDistr.EverReceivedProposerReward
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorPrevReceivedTokens() DecCoins
|
||||
return d.ValDistr.PrevReceivedProposerReward
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorShares() sdk.Dec
|
||||
return d.ValidatorDelegatorShares
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorPrevShares() sdk.Dec
|
||||
return d.ValDistr.PrevDelegatorShares
|
||||
|
||||
func (d DelegationFromProposerPool) RecipientShares() sdk.Dec
|
||||
return d.DelegationShares * (1 - d.ValidatorCommission)
|
||||
|
||||
func (d DelegationFromProposerPool) RecipientPrevShares() sdk.Dec
|
||||
return d.DelDistr.PrevShares
|
||||
|
||||
func (d DelegationFromProposerPool) RecipientAdjustment() sdk.Dec
|
||||
return d.DelDistr.AdjustmentProposer
|
||||
|
||||
func (d DelegationFromProposerPool) ModifyAdjustments(withdrawal sdk.Dec)
|
||||
d.ValDistr.AdjustmentProposer += withdrawal
|
||||
d.DelDistr.AdjustmentProposer += withdrawal
|
||||
SetValidatorDistribution(d.ValDistr)
|
||||
SetDelegatorDistribution(d.DelDistr)
|
||||
```
|
||||
|
||||
#### Validators's commission entitlement to Global.Pool
|
||||
|
||||
Similar to a delegator's entitlement, but with recipient shares based on the
|
||||
commission portion of bonded tokens.
|
||||
|
||||
```
|
||||
type CommissionFromGlobalPool struct {
|
||||
ValidatorBondedTokens sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
PoolBondedTokens sdk.Dec
|
||||
Global Global
|
||||
ValDistr ValidatorDistribution
|
||||
}
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorTokens() DecCoins
|
||||
return c.Global.Pool
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorCumulativeTokens() DecCoins
|
||||
return c.Global.EverReceivedPool
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorPrevReceivedTokens() DecCoins
|
||||
return c.Global.PrevReceivedPool
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorShares() sdk.Dec
|
||||
return c.PoolBondedTokens
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorPrevShares() sdk.Dec
|
||||
return c.Global.PrevBondedTokens
|
||||
|
||||
func (c CommissionFromGlobalPool) RecipientShares() sdk.Dec
|
||||
return c.ValidatorBondedTokens() * c.ValidatorCommission
|
||||
|
||||
func (c CommissionFromGlobalPool) RecipientPrevShares() sdk.Dec
|
||||
return c.ValDistr.PrevBondedTokens * c.ValidatorCommission
|
||||
|
||||
func (c CommissionFromGlobalPool) RecipientAdjustment() sdk.Dec
|
||||
return c.ValDistr.Adjustment
|
||||
|
||||
func (c CommissionFromGlobalPool) ModifyAdjustments(withdrawal sdk.Dec)
|
||||
c.ValDistr.Adjustment += withdrawal
|
||||
c.Global.Adjustment += withdrawal
|
||||
SetValidatorDistribution(c.ValDistr)
|
||||
SetGlobal(c.Global)
|
||||
```
|
||||
|
||||
#### Validators's commission entitlement to ValidatorDistribution.ProposerPool
|
||||
|
||||
Similar to a delegators entitlement to the proposer pool, but with recipient
|
||||
shares based on the commission portion of the total delegator shares.
|
||||
|
||||
```
|
||||
type CommissionFromProposerPool struct {
|
||||
ValidatorDelegatorShares sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
ValDistr ValidatorDistribution
|
||||
}
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorTokens() DecCoins
|
||||
return c.ValDistr.ProposerPool
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorCumulativeTokens() DecCoins
|
||||
return c.ValDistr.EverReceivedProposerReward
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorPrevReceivedTokens() DecCoins
|
||||
return c.ValDistr.PrevReceivedProposerReward
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorShares() sdk.Dec
|
||||
return c.ValidatorDelegatorShares
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorPrevShares() sdk.Dec
|
||||
return c.ValDistr.PrevDelegatorShares
|
||||
|
||||
func (c CommissionFromProposerPool) RecipientShares() sdk.Dec
|
||||
return c.ValidatorDelegatorShares * (c.ValidatorCommission)
|
||||
|
||||
func (c CommissionFromProposerPool) RecipientPrevShares() sdk.Dec
|
||||
return c.ValDistr.PrevDelegatorShares * (c.ValidatorCommission)
|
||||
|
||||
func (c CommissionFromProposerPool) RecipientAdjustment() sdk.Dec
|
||||
return c.ValDistr.AdjustmentProposer
|
||||
|
||||
func (c CommissionFromProposerPool) ModifyAdjustments(withdrawal sdk.Dec)
|
||||
c.ValDistr.AdjustmentProposer += withdrawal
|
||||
SetValidatorDistribution(c.ValDistr)
|
||||
```
|
||||
|
||||
@ -139,6 +139,17 @@ gaiacli send \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
Furthermore, you can build a transaction and print its JSON format to STDOUT by appending `--generate-only` to the list of the command line arguments:
|
||||
|
||||
```bash
|
||||
gaiacli send \
|
||||
--amount=10faucetToken \
|
||||
--chain-id=<chain_id> \
|
||||
--name=<key_name> \
|
||||
--to=<destination_cosmosaccaddr> \
|
||||
--generate-only
|
||||
```
|
||||
|
||||
### Staking
|
||||
|
||||
#### Set up a Validator
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
# End Block
|
||||
|
||||
At each endblock, the fees received are sorted to the proposer, community fund,
|
||||
At each endblock, the fees received are allocated to the proposer, community fund,
|
||||
and global pool. When the validator is the proposer of the round, that
|
||||
validator (and their delegators) receives between 1% and 5% of fee rewards, the
|
||||
reserve tax is then charged, then the remainder is distributed proportionally
|
||||
by voting power to all bonded validators independent of whether they voted
|
||||
(social distribution). Note the social distribution is applied to proposer
|
||||
validator in addition to the proposer reward.
|
||||
reserve community tax is then charged, then the remainder is distributed
|
||||
proportionally by voting power to all bonded validators independent of whether
|
||||
they voted (social distribution). Note the social distribution is applied to
|
||||
proposer validator in addition to the proposer reward.
|
||||
|
||||
The amount of proposer reward is calculated from pre-commits Tendermint
|
||||
messages in order to incentivize validators to wait and include additional
|
||||
@ -15,13 +15,17 @@ pool which validator holds individually
|
||||
(`ValidatorDistribution.ProvisionsRewardPool`).
|
||||
|
||||
```
|
||||
func SortFees(feesCollected sdk.Coins, global Global, proposer ValidatorDistribution,
|
||||
sumPowerPrecommitValidators, totalBondedTokens, communityTax sdk.Dec)
|
||||
func AllocateFees(feesCollected sdk.Coins, global Global, proposer ValidatorDistribution,
|
||||
sumPowerPrecommitValidators, totalBondedTokens, communityTax,
|
||||
proposerCommissionRate sdk.Dec)
|
||||
|
||||
feesCollectedDec = MakeDecCoins(feesCollected)
|
||||
proposerReward = feesCollectedDec * (0.01 + 0.04
|
||||
* sumPowerPrecommitValidators / totalBondedTokens)
|
||||
proposer.ProposerPool += proposerReward
|
||||
|
||||
commission = proposerReward * proposerCommissionRate
|
||||
proposer.PoolCommission += commission
|
||||
proposer.Pool += proposerReward - commission
|
||||
|
||||
communityFunding = feesCollectedDec * communityTax
|
||||
global.CommunityFund += communityFunding
|
||||
|
||||
26
docs/spec/distribution/hooks.md
Normal file
26
docs/spec/distribution/hooks.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Hooks
|
||||
|
||||
## Create or modify delegation distribution
|
||||
|
||||
- triggered-by: `stake.TxDelegate`, `stake.TxBeginRedelegate`, `stake.TxBeginUnbonding`
|
||||
|
||||
The pool of a new delegator bond will be 0 for the height at which the bond was
|
||||
added, or the withdrawal has taken place. This is achieved by setting
|
||||
`DelegatorDistInfo.WithdrawalHeight` to the height of the triggering transaction.
|
||||
|
||||
## Commission rate change
|
||||
|
||||
- triggered-by: `stake.TxEditValidator`
|
||||
|
||||
If a validator changes its commission rate, all commission on fees must be
|
||||
simultaneously withdrawn using the transaction `TxWithdrawValidator`.
|
||||
Additionally the change and associated height must be recorded in a
|
||||
`ValidatorUpdate` state record.
|
||||
|
||||
## Change in Validator State
|
||||
|
||||
- triggered-by: `stake.Slash`, `stake.UpdateValidator`
|
||||
|
||||
Whenever a validator is slashed or enters/leaves the validator group all of the
|
||||
validator entitled reward tokens must be simultaneously withdrawn from
|
||||
`Global.Pool` and added to `ValidatorDistInfo.Pool`.
|
||||
@ -2,53 +2,71 @@
|
||||
|
||||
## Overview
|
||||
|
||||
Collected fees are pooled globally and divided out passively to validators and
|
||||
delegators. Each validator has the opportunity to charge commission to the
|
||||
delegators on the fees collected on behalf of the delegators by the validators.
|
||||
Fees are paid directly into a global fee pool, and validator proposer-reward
|
||||
pool. Due to the nature of passive accounting whenever changes to parameters
|
||||
which affect the rate of fee distribution occurs, withdrawal of fees must also
|
||||
occur when:
|
||||
|
||||
- withdrawing one must withdrawal the maximum amount they are entitled
|
||||
too, leaving nothing in the pool,
|
||||
- bonding, unbonding, or re-delegating tokens to an existing account a
|
||||
full withdrawal of the fees must occur (as the rules for lazy accounting
|
||||
change),
|
||||
- a validator chooses to change the commission on fees, all accumulated
|
||||
commission fees must be simultaneously withdrawn.
|
||||
This _simple_ distribution mechanism describes a functional way to passively
|
||||
distribute rewards between validator and delegators. Note that this mechanism does
|
||||
not distribute funds in as precisely as active reward distribution and will therefore
|
||||
be upgraded in the future.
|
||||
|
||||
The above scenarios are covered in `triggers.md`.
|
||||
The mechanism operates as follows. Collected rewards are pooled globally and
|
||||
divided out passively to validators and delegators. Each validator has the
|
||||
opportunity to charge commission to the delegators on the rewards collected on
|
||||
behalf of the delegators by the validators. Fees are paid directly into a
|
||||
global reward pool, and validator proposer-reward pool. Due to the nature of
|
||||
passive accounting, whenever changes to parameters which affect the rate of reward
|
||||
distribution occurs, withdrawal of rewards must also occur.
|
||||
|
||||
- Whenever withdrawing, one must withdraw the maximum amount they are entitled
|
||||
too, leaving nothing in the pool.
|
||||
- Whenever bonding, unbonding, or re-delegating tokens to an existing account, a
|
||||
full withdrawal of the rewards must occur (as the rules for lazy accounting
|
||||
change).
|
||||
- Whenever a validator chooses to change the commission on rewards, all accumulated
|
||||
commission rewards must be simultaneously withdrawn.
|
||||
|
||||
The above scenarios are covered in `hooks.md`.
|
||||
|
||||
The distribution mechanism outlines herein is used to lazily distribute the
|
||||
following between validators and associated delegators:
|
||||
following rewards between validators and associated delegators:
|
||||
- multi-token fees to be socially distributed,
|
||||
- proposer reward pool,
|
||||
- inflated atom provisions, and
|
||||
- validator commission on all rewards earned by their delegators stake
|
||||
|
||||
Fees are pooled within a global pool, as well as validator specific
|
||||
proposer-reward pools. The mechanisms used allow for validators and delegators
|
||||
to independently and lazily withdrawn their rewards. As a part of the lazy
|
||||
computations adjustment factors must be maintained for each validator and
|
||||
delegator to determine the true proportion of fees in each pool which they are
|
||||
entitled too. Adjustment factors are updated every time a validator or
|
||||
delegator's voting power changes. Validators and delegators must withdraw all
|
||||
fees they are entitled too before they can change their portion of bonded
|
||||
Atoms.
|
||||
proposer-reward pools. The mechanisms used allow for validators and delegators
|
||||
to independently and lazily withdraw their rewards.
|
||||
|
||||
## Shortcomings
|
||||
|
||||
As a part of the lazy computations, each delegator holds an accumulation term
|
||||
specific to each validator which is used to estimate what their approximate
|
||||
fair portion of tokens held in the global pool is owed to them.
|
||||
|
||||
```
|
||||
entitlement = delegator-accumulation / all-delegators-accumulation
|
||||
```
|
||||
|
||||
Under the circumstance that there were constant and equal flow of incoming
|
||||
reward tokens every block, this distribution mechanism would be equal to the
|
||||
active distribution (distribute individually to all delegators each block).
|
||||
However this is unrealistic so deviations from the active distribution will
|
||||
occur based on fluctuations of incoming reward tokens as well as timing of
|
||||
reward withdrawal by other delegators.
|
||||
|
||||
If you happen to know that incoming rewards are about significantly move up,
|
||||
you are incentivized to not withdraw until after this event, increasing the
|
||||
worth of your existing _accum_.
|
||||
|
||||
## Affect on Staking
|
||||
|
||||
|
||||
Charging commission on Atom provisions while also allowing for Atom-provisions
|
||||
to be auto-bonded (distributed directly to the validators bonded stake) is
|
||||
problematic within DPoS. Fundamentally these two mechnisms are mutually
|
||||
exclusive. If there are atoms commissions and auto-bonding Atoms, the portion
|
||||
of Atoms the fee distribution calculation would become very large as the Atom
|
||||
portion for each delegator would change each block making a withdrawal of fees
|
||||
problematic within DPoS. Fundamentally these two mechanisms are mutually
|
||||
exclusive. If there are Atom commissions and auto-bonding Atoms, the portion
|
||||
of Atoms the reward distribution calculation would become very large as the Atom
|
||||
portion for each delegator would change each block making a withdrawal of rewards
|
||||
for a delegator require a calculation for every single block since the last
|
||||
withdrawal. In conclusion we can only have atom commission and unbonded atoms
|
||||
provisions, or bonded atom provisions with no Atom commission, and we elect to
|
||||
withdrawal. In conclusion, we can only have Atom commission and unbonded atoms
|
||||
provisions or bonded atom provisions with no Atom commission, and we elect to
|
||||
implement the former. Stakeholders wishing to rebond their provisions may elect
|
||||
to set up a script to periodically withdraw and rebond fees.
|
||||
|
||||
to set up a script to periodically withdraw and rebond rewards.
|
||||
|
||||
@ -23,78 +23,46 @@ type DecCoin struct {
|
||||
}
|
||||
|
||||
type Global struct {
|
||||
PrevBondedTokens sdk.Dec // bonded token amount for the global pool on the previous block
|
||||
Adjustment sdk.Dec // global adjustment factor for lazy calculations
|
||||
Pool DecCoins // funds for all validators which have yet to be withdrawn
|
||||
PrevReceivedPool DecCoins // funds added to the pool on the previous block
|
||||
EverReceivedPool DecCoins // total funds ever added to the pool
|
||||
CommunityFund DecCoins // pool for community funds yet to be spent
|
||||
TotalValAccumUpdateHeight int64 // last height which the total validator accum was updated
|
||||
TotalValAccum sdk.Dec // total valdator accum held by validators
|
||||
Pool DecCoins // funds for all validators which have yet to be withdrawn
|
||||
CommunityPool DecCoins // pool for community funds yet to be spent
|
||||
}
|
||||
```
|
||||
|
||||
### Validator Distribution
|
||||
|
||||
Validator distribution information for the relevant validator is updated each time:
|
||||
1. delegation amount to a validator are updated,
|
||||
1. delegation amount to a validator is updated,
|
||||
2. a validator successfully proposes a block and receives a reward,
|
||||
3. any delegator withdraws from a validator, or
|
||||
4. the validator withdraws it's commission.
|
||||
|
||||
- ValidatorDistribution: `0x02 | ValOwnerAddr -> amino(validatorDistribution)`
|
||||
- ValidatorDistInfo: `0x02 | ValOperatorAddr -> amino(validatorDistribution)`
|
||||
|
||||
```golang
|
||||
type ValidatorDistribution struct {
|
||||
CommissionWithdrawalHeight int64 // last time this validator withdrew commission
|
||||
Adjustment sdk.Dec // global pool adjustment factor
|
||||
ProposerAdjustment DecCoins // proposer pool adjustment factor
|
||||
ProposerPool DecCoins // reward pool collected from being the proposer
|
||||
EverReceivedProposerReward DecCoins // all rewards ever collected from being the proposer
|
||||
PrevReceivedProposerReward DecCoins // previous rewards collected from being the proposer
|
||||
PrevBondedTokens sdk.Dec // bonded token amount on the previous block
|
||||
PrevDelegatorShares sdk.Dec // amount of delegator shares for the validator on the previous block
|
||||
type ValidatorDistInfo struct {
|
||||
GlobalWithdrawalHeight int64 // last height this validator withdrew from the global pool
|
||||
Pool DecCoins // rewards owed to delegators, commission has already been charged (includes proposer reward)
|
||||
PoolCommission DecCoins // commission collected by this validator (pending withdrawal)
|
||||
|
||||
TotalDelAccumUpdateHeight int64 // last height which the total delegator accum was updated
|
||||
TotalDelAccum sdk.Dec // total proposer pool accumulation factor held by delegators
|
||||
}
|
||||
```
|
||||
|
||||
### Delegation Distribution
|
||||
|
||||
Each delegation holds multiple adjustment factors to specify its entitlement to
|
||||
the rewards from a validator. `AdjustmentPool` is used to passively calculate
|
||||
each bonds entitled fees from the `RewardPool`. `AdjustmentPool` is used to
|
||||
passively calculate each bonds entitled fees from
|
||||
`ValidatorDistribution.ProposerRewardPool`
|
||||
Each delegation distribution only needs to record the height at which it last
|
||||
withdrew fees. Because a delegation must withdraw fees each time it's
|
||||
properties change (aka bonded tokens etc.) its properties will remain constant
|
||||
and the delegator's _accumulation_ factor can be calculated passively knowing
|
||||
only the height of the last withdrawal and its current properties.
|
||||
|
||||
- DelegatorDistribution: ` 0x02 | DelegatorAddr | ValOwnerAddr -> amino(delegatorDist)`
|
||||
- DelegatorDistInfo: ` 0x02 | DelegatorAddr | ValOperatorAddr -> amino(delegatorDist)`
|
||||
|
||||
```golang
|
||||
type DelegatorDist struct {
|
||||
WithdrawalHeight int64 // last time this delegation withdrew rewards
|
||||
Adjustment sdk.Dec // fee provisioning adjustment factor
|
||||
AdjustmentProposer DecCoins // proposers pool adjustment factor
|
||||
PrevTokens sdk.Dec // bonded tokens held by the delegation on the previous block
|
||||
PrevShares sdk.Dec // delegator shares held by the delegation on the previous block
|
||||
}
|
||||
```
|
||||
|
||||
### Power Change
|
||||
|
||||
Every instance that the voting power changes, information about the state of
|
||||
the validator set during the change must be recorded as a `PowerChange` for
|
||||
other validators to run through. Each power change is indexed by its block
|
||||
height.
|
||||
|
||||
- PowerChange: `0x03 | amino(Height) -> amino(validatorDist)`
|
||||
|
||||
```golang
|
||||
type PowerChange struct {
|
||||
Height int64 // block height at change
|
||||
ValidatorBondedTokens sdk.Dec // following used to create distribution scenarios
|
||||
ValidatorDelegatorShares sdk.Dec
|
||||
ValidatorDelegatorShareExRate sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
PoolBondedTokens sdk.Dec
|
||||
Global Global
|
||||
ValDistr ValidatorDistribution
|
||||
DelegationShares sdk.Dec
|
||||
DelDistr DelegatorDistribution
|
||||
type DelegatorDistInfo struct {
|
||||
WithdrawalHeight int64 // last time this delegation withdrew rewards
|
||||
}
|
||||
```
|
||||
|
||||
@ -1,399 +1,213 @@
|
||||
# Transactions
|
||||
|
||||
## TxWithdrawDelegation
|
||||
## TxWithdrawDelegationRewardsAll
|
||||
|
||||
When a delegator wishes to withdraw their transaction fees it must send
|
||||
`TxWithdrawDelegation`. Note that parts of this transaction logic are also
|
||||
When a delegator wishes to withdraw their rewards it must send
|
||||
`TxWithdrawDelegationRewardsAll`. Note that parts of this transaction logic are also
|
||||
triggered each with any change in individual delegations, such as an unbond,
|
||||
redelegation, or delegation of additional tokens to a specific validator.
|
||||
|
||||
Each time a withdrawal is made by a recipient the adjustment term must be
|
||||
modified for each block with a change in distributors shares since the time of
|
||||
last withdrawal. This is accomplished by iterating over all relevant
|
||||
`PowerChange`'s stored in distribution state.
|
||||
|
||||
|
||||
```golang
|
||||
type TxWithdrawDelegation struct {
|
||||
type TxWithdrawDelegationRewardsAll struct {
|
||||
delegatorAddr sdk.AccAddress
|
||||
withdrawAddr sdk.AccAddress // address to make the withdrawal to
|
||||
}
|
||||
|
||||
func WithdrawDelegator(delegatorAddr, withdrawAddr sdk.AccAddress)
|
||||
entitlement = GetDelegatorEntitlement(delegatorAddr)
|
||||
AddCoins(withdrawAddr, totalEntitlment.TruncateDecimal())
|
||||
func WithdrawDelegationRewardsAll(delegatorAddr, withdrawAddr sdk.AccAddress)
|
||||
height = GetHeight()
|
||||
withdraw = GetDelegatorRewardsAll(delegatorAddr, height)
|
||||
AddCoins(withdrawAddr, withdraw.TruncateDecimal())
|
||||
|
||||
func GetDelegatorEntitlement(delegatorAddr sdk.AccAddress) DecCoins
|
||||
func GetDelegatorRewardsAll(delegatorAddr sdk.AccAddress, height int64) DecCoins
|
||||
|
||||
// compile all the distribution scenarios
|
||||
// get all distribution scenarios
|
||||
delegations = GetDelegations(delegatorAddr)
|
||||
DelDistr = GetDelegationDistribution(delegation.DelegatorAddr,
|
||||
delegation.ValidatorAddr)
|
||||
pcs = GetPowerChanges(DelDistr.WithdrawalHeight)
|
||||
|
||||
// update all adjustment factors for each delegation since last withdrawal
|
||||
for pc = range pcs
|
||||
for delegation = range delegations
|
||||
DelDistr = GetDelegationDistribution(delegation.DelegatorAddr,
|
||||
delegation.ValidatorAddr)
|
||||
pc.ProcessPowerChangeDelegation(delegation, DelDistr)
|
||||
|
||||
// collect all entitled fees
|
||||
entitlement = 0
|
||||
// collect all entitled rewards
|
||||
withdraw = 0
|
||||
pool = stake.GetPool()
|
||||
global = GetGlobal()
|
||||
for delegation = range delegations
|
||||
global = GetGlobal()
|
||||
pool = GetPool()
|
||||
DelDistr = GetDelegationDistribution(delegation.DelegatorAddr,
|
||||
delInfo = GetDelegationDistInfo(delegation.DelegatorAddr,
|
||||
delegation.ValidatorAddr)
|
||||
ValDistr = GetValidatorDistribution(delegation.ValidatorAddr)
|
||||
valInfo = GetValidatorDistInfo(delegation.ValidatorAddr)
|
||||
validator = GetValidator(delegation.ValidatorAddr)
|
||||
|
||||
scenerio1 = NewDelegationFromGlobalPool(delegation, validator,
|
||||
pool, global, ValDistr, DelDistr)
|
||||
scenerio2 = NewDelegationFromProvisionPool(delegation, validator,
|
||||
ValDistr, DelDistr)
|
||||
entitlement += scenerio1.WithdrawalEntitlement()
|
||||
entitlement += scenerio2.WithdrawalEntitlement()
|
||||
|
||||
return entitlement
|
||||
global, diWithdraw = delInfo.WithdrawRewards(global, valInfo, height, pool.BondedTokens,
|
||||
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
||||
withdraw += diWithdraw
|
||||
|
||||
func (pc PowerChange) ProcessPowerChangeDelegation(delegation sdk.Delegation,
|
||||
DelDistr DelegationDistribution)
|
||||
|
||||
// get the historical scenarios
|
||||
scenario1 = pc.DelegationFromGlobalPool(delegation, DelDistr)
|
||||
scenario2 = pc.DelegationFromProvisionPool(delegation, DelDistr)
|
||||
|
||||
// process the adjustment factors
|
||||
scenario1.UpdateAdjustmentForPowerChange(pc.Height)
|
||||
scenario2.UpdateAdjustmentForPowerChange(pc.Height)
|
||||
SetGlobal(global)
|
||||
return withdraw
|
||||
```
|
||||
|
||||
## TxWithdrawValidator
|
||||
## TxWithdrawDelegationReward
|
||||
|
||||
When a validator wishes to withdraw their transaction fees it must send
|
||||
`TxWithdrawDelegation`. Note that parts of this transaction logic is also
|
||||
triggered each with any change in individual delegations, such as an unbond,
|
||||
redelegation, or delegation of additional tokens to a specific validator. This
|
||||
transaction withdraws the validators commission rewards, as well as any rewards
|
||||
earning on their self-delegation.
|
||||
under special circumstances a delegator may wish to withdraw rewards from only
|
||||
a single validator.
|
||||
|
||||
```golang
|
||||
type TxWithdrawValidator struct {
|
||||
ownerAddr sdk.AccAddress // validator address to withdraw from
|
||||
type TxWithdrawDelegationReward struct {
|
||||
delegatorAddr sdk.AccAddress
|
||||
validatorAddr sdk.AccAddress
|
||||
withdrawAddr sdk.AccAddress // address to make the withdrawal to
|
||||
}
|
||||
|
||||
func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.AccAddress)
|
||||
height = GetHeight()
|
||||
|
||||
// get all distribution scenarios
|
||||
pool = stake.GetPool()
|
||||
global = GetGlobal()
|
||||
delInfo = GetDelegationDistInfo(delegatorAddr,
|
||||
validatorAddr)
|
||||
valInfo = GetValidatorDistInfo(validatorAddr)
|
||||
validator = GetValidator(validatorAddr)
|
||||
|
||||
global, withdraw = delInfo.WithdrawRewards(global, valInfo, height, pool.BondedTokens,
|
||||
validator.Tokens, validator.DelegatorShares, validator.Commission)
|
||||
|
||||
SetGlobal(global)
|
||||
AddCoins(withdrawAddr, withdraw.TruncateDecimal())
|
||||
```
|
||||
|
||||
|
||||
## TxWithdrawValidatorRewardsAll
|
||||
|
||||
When a validator wishes to withdraw their rewards it must send
|
||||
`TxWithdrawValidatorRewardsAll`. Note that parts of this transaction logic are also
|
||||
triggered each with any change in individual delegations, such as an unbond,
|
||||
redelegation, or delegation of additional tokens to a specific validator. This
|
||||
transaction withdraws the validators commission fee, as well as any rewards
|
||||
earning on their self-delegation.
|
||||
|
||||
```
|
||||
type TxWithdrawValidatorRewardsAll struct {
|
||||
operatorAddr sdk.AccAddress // validator address to withdraw from
|
||||
withdrawAddr sdk.AccAddress // address to make the withdrawal to
|
||||
}
|
||||
|
||||
func WithdrawalValidator(ownerAddr, withdrawAddr sdk.AccAddress)
|
||||
func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress)
|
||||
|
||||
// update the delegator adjustment factors and also withdrawal delegation fees
|
||||
entitlement = GetDelegatorEntitlement(ownerAddr)
|
||||
|
||||
// update the validator adjustment factors for commission
|
||||
ValDistr = GetValidatorDistribution(ownerAddr.ValidatorAddr)
|
||||
pcs = GetPowerChanges(ValDistr.CommissionWithdrawalHeight)
|
||||
for pc = range pcs
|
||||
pc.ProcessPowerChangeCommission()
|
||||
|
||||
// withdrawal validator commission rewards
|
||||
height = GetHeight()
|
||||
global = GetGlobal()
|
||||
pool = GetPool()
|
||||
ValDistr = GetValidatorDistribution(delegation.ValidatorAddr)
|
||||
ValInfo = GetValidatorDistInfo(delegation.ValidatorAddr)
|
||||
validator = GetValidator(delegation.ValidatorAddr)
|
||||
|
||||
scenerio1 = NewCommissionFromGlobalPool(validator,
|
||||
pool, global, ValDistr)
|
||||
scenerio2 = CommissionFromProposerPool(validator, ValDistr)
|
||||
entitlement += scenerio1.WithdrawalEntitlement()
|
||||
entitlement += scenerio2.WithdrawalEntitlement()
|
||||
// withdraw self-delegation
|
||||
withdraw = GetDelegatorRewardsAll(validator.OperatorAddr, height)
|
||||
|
||||
// withdrawal validator commission rewards
|
||||
global, commission = valInfo.WithdrawCommission(global, valInfo, height, pool.BondedTokens,
|
||||
validator.Tokens, validator.Commission)
|
||||
withdraw += commission
|
||||
SetGlobal(global)
|
||||
|
||||
AddCoins(withdrawAddr, withdraw.TruncateDecimal())
|
||||
```
|
||||
|
||||
AddCoins(withdrawAddr, totalEntitlment.TruncateDecimal())
|
||||
## Common calculations
|
||||
|
||||
func (pc PowerChange) ProcessPowerChangeCommission()
|
||||
### Update total validator accum
|
||||
|
||||
// get the historical scenarios
|
||||
scenario1 = pc.CommissionFromGlobalPool()
|
||||
scenario2 = pc.CommissionFromProposerPool()
|
||||
The total amount of validator accum must be calculated in order to determine
|
||||
the amount of pool tokens which a validator is entitled to at a particular
|
||||
block. The accum is always additive to the existing accum. This term is to be
|
||||
updated each time rewards are withdrawn from the system.
|
||||
|
||||
// process the adjustment factors
|
||||
scenario1.UpdateAdjustmentForPowerChange(pc.Height)
|
||||
scenario2.UpdateAdjustmentForPowerChange(pc.Height)
|
||||
```
|
||||
func (g Global) UpdateTotalValAccum(height int64, totalBondedTokens Dec) Global
|
||||
blocks = height - g.TotalValAccumUpdateHeight
|
||||
g.TotalValAccum += totalDelShares * blocks
|
||||
g.TotalValAccumUpdateHeight = height
|
||||
return g
|
||||
```
|
||||
|
||||
## Common Calculations
|
||||
### Update validator's accums
|
||||
|
||||
### Distribution scenario
|
||||
The total amount of delegator accum must be updated in order to determine the
|
||||
amount of pool tokens which each delegator is entitled to, relative to the
|
||||
other delegators for that validator. The accum is always additive to
|
||||
the existing accum. This term is to be updated each time a
|
||||
withdrawal is made from a validator.
|
||||
|
||||
A common form of abstracted calculations exists between validators and
|
||||
delegations attempting to withdrawal their rewards, either from `Global.Pool`
|
||||
or from `ValidatorDistribution.ProposerPool`. With the following interface
|
||||
fulfilled the entitled fees for the various scenarios can be calculated.
|
||||
|
||||
```golang
|
||||
type DistributionScenario interface {
|
||||
DistributorTokens() DecCoins // current tokens from distributor
|
||||
DistributorCumulativeTokens() DecCoins // total tokens ever received
|
||||
DistributorPrevReceivedTokens() DecCoins // last value of tokens received
|
||||
DistributorShares() sdk.Dec // current shares
|
||||
DistributorPrevShares() sdk.Dec // shares last block
|
||||
|
||||
RecipientAdjustment() sdk.Dec
|
||||
RecipientShares() sdk.Dec // current shares
|
||||
RecipientPrevShares() sdk.Dec // shares last block
|
||||
|
||||
ModifyAdjustments(withdrawal sdk.Dec) // proceedure to modify adjustment factors
|
||||
}
|
||||
```
|
||||
func (vi ValidatorDistInfo) UpdateTotalDelAccum(height int64, totalDelShares Dec) ValidatorDistInfo
|
||||
blocks = height - vi.TotalDelAccumUpdateHeight
|
||||
vi.TotalDelAccum += totalDelShares * blocks
|
||||
vi.TotalDelAccumUpdateHeight = height
|
||||
return vi
|
||||
```
|
||||
|
||||
#### Entitled reward from distribution scenario
|
||||
### Global pool to validator pool
|
||||
|
||||
The entitlement to the distributor's tokens held can be accounted for lazily.
|
||||
To begin this calculation we must determine the recipient's _simple pool_ and
|
||||
_projected pool_. The simple pool represents a lazy accounting of what a
|
||||
recipient's entitlement to the distributor's tokens would be if all recipients
|
||||
for that distributor had static shares (equal to the current shares), and no
|
||||
recipients had ever withdrawn their entitled rewards. The projected pool
|
||||
represents the anticipated recipient's entitlement to the distributors tokens
|
||||
based on the current blocks token input (for example fees reward received) to
|
||||
the distributor, and the distributor's tokens and shares of the previous block
|
||||
assuming that neither had changed in the current block. Using the simple and
|
||||
projected pools we can determine all cumulative changes which have taken place
|
||||
outside of the recipient and adjust the recipient's _adjustment factor_ to
|
||||
account for these changes and ultimately keep track of the correct entitlement
|
||||
to the distributors tokens.
|
||||
Every time a validator or delegator executes a withdrawal or the validator is
|
||||
the proposer and receives new tokens, the relevant validator must move tokens
|
||||
from the passive global pool to their own pool. It is at this point that the
|
||||
commission is withdrawn
|
||||
|
||||
```
|
||||
func (d DistributionScenario) RecipientCount(height int64) sdk.Dec
|
||||
return v.RecipientShares() * height
|
||||
```
|
||||
func (vi ValidatorDistInfo) TakeAccum(g Global, height int64, totalBonded, vdTokens, commissionRate Dec) (
|
||||
vi ValidatorDistInfo, g Global)
|
||||
|
||||
func (d DistributionScenario) GlobalCount(height int64) sdk.Dec
|
||||
return d.DistributorShares() * height
|
||||
|
||||
func (d DistributionScenario) SimplePool() DecCoins
|
||||
return d.RecipientCount() / d.GlobalCount() * d.DistributorCumulativeTokens
|
||||
|
||||
func (d DistributionScenario) ProjectedPool(height int64) DecCoins
|
||||
return d.RecipientPrevShares() * (height-1)
|
||||
/ (d.DistributorPrevShares() * (height-1))
|
||||
* d.DistributorCumulativeTokens
|
||||
+ d.RecipientShares() / d.DistributorShares()
|
||||
* d.DistributorPrevReceivedTokens()
|
||||
```
|
||||
|
||||
The `DistributionScenario` _adjustment_ terms account for changes in
|
||||
recipient/distributor shares and recipient withdrawals. The adjustment factor
|
||||
must be modified whenever the recipient withdraws from the distributor or the
|
||||
distributor's/recipient's shares are changed.
|
||||
- When the shares of the recipient is changed the adjustment factor is
|
||||
increased/decreased by the difference between the _simple_ and _projected_
|
||||
pools. In other words, the cumulative difference in the shares if the shares
|
||||
has been the new shares as opposed to the old shares for the entire duration of
|
||||
the blockchain up the previous block.
|
||||
- When a recipient makes a withdrawal the adjustment factor is increased by the
|
||||
withdrawal amount.
|
||||
|
||||
```
|
||||
func (d DistributionScenario) UpdateAdjustmentForPowerChange(height int64)
|
||||
simplePool = d.SimplePool()
|
||||
projectedPool = d.ProjectedPool(height)
|
||||
AdjustmentChange = simplePool - projectedPool
|
||||
if AdjustmentChange > 0
|
||||
d.ModifyAdjustments(AdjustmentChange)
|
||||
|
||||
func (d DistributionScenario) WithdrawalEntitlement() DecCoins
|
||||
entitlement = d.SimplePool() - d.RecipientAdjustment()
|
||||
d.ModifyAdjustments(entitlement)
|
||||
return entitlement
|
||||
```
|
||||
|
||||
### Distribution scenarios
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
```
|
||||
type DelegationFromGlobalPool struct {
|
||||
DelegationShares sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
ValidatorBondedTokens sdk.Dec
|
||||
ValidatorDelegatorShareExRate sdk.Dec
|
||||
PoolBondedTokens sdk.Dec
|
||||
Global Global
|
||||
ValDistr ValidatorDistribution
|
||||
DelDistr DelegatorDistribution
|
||||
}
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorTokens() DecCoins
|
||||
return d.Global.Pool
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorCumulativeTokens() DecCoins
|
||||
return d.Global.EverReceivedPool
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorPrevReceivedTokens() DecCoins
|
||||
return d.Global.PrevReceivedPool
|
||||
g.UpdateTotalValAccum(height, totalBondedShares)
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorShares() sdk.Dec
|
||||
return d.PoolBondedTokens
|
||||
|
||||
func (d DelegationFromGlobalPool) DistributorPrevShares() sdk.Dec
|
||||
return d.Global.PrevBondedTokens
|
||||
|
||||
func (d DelegationFromGlobalPool) RecipientShares() sdk.Dec
|
||||
return d.DelegationShares * d.ValidatorDelegatorShareExRate() *
|
||||
d.ValidatorBondedTokens() * (1 - d.ValidatorCommission)
|
||||
|
||||
func (d DelegationFromGlobalPool) RecipientPrevShares() sdk.Dec
|
||||
return d.DelDistr.PrevTokens
|
||||
|
||||
func (d DelegationFromGlobalPool) RecipientAdjustment() sdk.Dec
|
||||
return d.DelDistr.Adjustment
|
||||
|
||||
func (d DelegationFromGlobalPool) ModifyAdjustments(withdrawal sdk.Dec)
|
||||
d.ValDistr.Adjustment += withdrawal
|
||||
d.DelDistr.Adjustment += withdrawal
|
||||
d.global.Adjustment += withdrawal
|
||||
SetValidatorDistribution(d.ValDistr)
|
||||
SetDelegatorDistribution(d.DelDistr)
|
||||
SetGlobal(d.Global)
|
||||
```
|
||||
|
||||
#### Delegation's entitlement to ValidatorDistribution.ProposerPool
|
||||
|
||||
Delegations (including validator's self-delegation) are still subject
|
||||
commission on the rewards gained from the proposer pool. Global shares in this
|
||||
context is actually the validators total delegations shares. The recipient's
|
||||
shares is taken as the effective delegation shares less the validator's
|
||||
commission.
|
||||
|
||||
```
|
||||
type DelegationFromProposerPool struct {
|
||||
DelegationShares sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
ValidatorDelegatorShares sdk.Dec
|
||||
ValDistr ValidatorDistribution
|
||||
DelDistr DelegatorDistribution
|
||||
}
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorTokens() DecCoins
|
||||
return d.ValDistr.ProposerPool
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorCumulativeTokens() DecCoins
|
||||
return d.ValDistr.EverReceivedProposerReward
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorPrevReceivedTokens() DecCoins
|
||||
return d.ValDistr.PrevReceivedProposerReward
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorShares() sdk.Dec
|
||||
return d.ValidatorDelegatorShares
|
||||
|
||||
func (d DelegationFromProposerPool) DistributorPrevShares() sdk.Dec
|
||||
return d.ValDistr.PrevDelegatorShares
|
||||
|
||||
func (d DelegationFromProposerPool) RecipientShares() sdk.Dec
|
||||
return d.DelegationShares * (1 - d.ValidatorCommission)
|
||||
|
||||
func (d DelegationFromProposerPool) RecipientPrevShares() sdk.Dec
|
||||
return d.DelDistr.PrevShares
|
||||
|
||||
func (d DelegationFromProposerPool) RecipientAdjustment() sdk.Dec
|
||||
return d.DelDistr.AdjustmentProposer
|
||||
|
||||
func (d DelegationFromProposerPool) ModifyAdjustments(withdrawal sdk.Dec)
|
||||
d.ValDistr.AdjustmentProposer += withdrawal
|
||||
d.DelDistr.AdjustmentProposer += withdrawal
|
||||
SetValidatorDistribution(d.ValDistr)
|
||||
SetDelegatorDistribution(d.DelDistr)
|
||||
```
|
||||
|
||||
#### Validators's commission entitlement to Global.Pool
|
||||
|
||||
Similar to a delegator's entitlement, but with recipient shares based on the
|
||||
commission portion of bonded tokens.
|
||||
|
||||
```
|
||||
type CommissionFromGlobalPool struct {
|
||||
ValidatorBondedTokens sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
PoolBondedTokens sdk.Dec
|
||||
Global Global
|
||||
ValDistr ValidatorDistribution
|
||||
}
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorTokens() DecCoins
|
||||
return c.Global.Pool
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorCumulativeTokens() DecCoins
|
||||
return c.Global.EverReceivedPool
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorPrevReceivedTokens() DecCoins
|
||||
return c.Global.PrevReceivedPool
|
||||
// update the validators pool
|
||||
blocks = height - vi.GlobalWithdrawalHeight
|
||||
vi.GlobalWithdrawalHeight = height
|
||||
accum = blocks * vdTokens
|
||||
withdrawalTokens := g.Pool * accum / g.TotalValAccum
|
||||
commission := withdrawalTokens * commissionRate
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorShares() sdk.Dec
|
||||
return c.PoolBondedTokens
|
||||
g.TotalValAccum -= accumm
|
||||
vi.PoolCommission += commission
|
||||
vi.PoolCommissionFree += withdrawalTokens - commission
|
||||
g.Pool -= withdrawalTokens
|
||||
|
||||
func (c CommissionFromGlobalPool) DistributorPrevShares() sdk.Dec
|
||||
return c.Global.PrevBondedTokens
|
||||
|
||||
func (c CommissionFromGlobalPool) RecipientShares() sdk.Dec
|
||||
return c.ValidatorBondedTokens() * c.ValidatorCommission
|
||||
|
||||
func (c CommissionFromGlobalPool) RecipientPrevShares() sdk.Dec
|
||||
return c.ValDistr.PrevBondedTokens * c.ValidatorCommission
|
||||
|
||||
func (c CommissionFromGlobalPool) RecipientAdjustment() sdk.Dec
|
||||
return c.ValDistr.Adjustment
|
||||
|
||||
func (c CommissionFromGlobalPool) ModifyAdjustments(withdrawal sdk.Dec)
|
||||
c.ValDistr.Adjustment += withdrawal
|
||||
c.Global.Adjustment += withdrawal
|
||||
SetValidatorDistribution(c.ValDistr)
|
||||
SetGlobal(c.Global)
|
||||
return vi, g
|
||||
```
|
||||
|
||||
#### Validators's commission entitlement to ValidatorDistribution.ProposerPool
|
||||
|
||||
Similar to a delegators entitlement to the proposer pool, but with recipient
|
||||
shares based on the commission portion of the total delegator shares.
|
||||
### Delegation reward withdrawal
|
||||
|
||||
For delegations (including validator's self-delegation) all rewards from reward
|
||||
pool have already had the validator's commission taken away.
|
||||
|
||||
```
|
||||
type CommissionFromProposerPool struct {
|
||||
ValidatorDelegatorShares sdk.Dec
|
||||
ValidatorCommission sdk.Dec
|
||||
ValDistr ValidatorDistribution
|
||||
}
|
||||
func (di DelegatorDistInfo) WithdrawRewards(g Global, vi ValidatorDistInfo,
|
||||
height int64, totalBonded, vdTokens, totalDelShares, commissionRate Dec) (
|
||||
di DelegatorDistInfo, g Global, withdrawn DecCoins)
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorTokens() DecCoins
|
||||
return c.ValDistr.ProposerPool
|
||||
vi.UpdateTotalDelAccum(height, totalDelShares)
|
||||
g = vi.TakeAccum(g, height, totalBonded, vdTokens, commissionRate)
|
||||
|
||||
blocks = height - di.WithdrawalHeight
|
||||
di.WithdrawalHeight = height
|
||||
accum = delegatorShares * blocks
|
||||
|
||||
withdrawalTokens := vi.Pool * accum / vi.TotalDelAccum
|
||||
vi.TotalDelAccum -= accum
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorCumulativeTokens() DecCoins
|
||||
return c.ValDistr.EverReceivedProposerReward
|
||||
vi.Pool -= withdrawalTokens
|
||||
vi.TotalDelAccum -= accum
|
||||
return di, g, withdrawalTokens
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorPrevReceivedTokens() DecCoins
|
||||
return c.ValDistr.PrevReceivedProposerReward
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorShares() sdk.Dec
|
||||
return c.ValidatorDelegatorShares
|
||||
|
||||
func (c CommissionFromProposerPool) DistributorPrevShares() sdk.Dec
|
||||
return c.ValDistr.PrevDelegatorShares
|
||||
|
||||
func (c CommissionFromProposerPool) RecipientShares() sdk.Dec
|
||||
return c.ValidatorDelegatorShares * (c.ValidatorCommission)
|
||||
|
||||
func (c CommissionFromProposerPool) RecipientPrevShares() sdk.Dec
|
||||
return c.ValDistr.PrevDelegatorShares * (c.ValidatorCommission)
|
||||
|
||||
func (c CommissionFromProposerPool) RecipientAdjustment() sdk.Dec
|
||||
return c.ValDistr.AdjustmentProposer
|
||||
|
||||
func (c CommissionFromProposerPool) ModifyAdjustments(withdrawal sdk.Dec)
|
||||
c.ValDistr.AdjustmentProposer += withdrawal
|
||||
SetValidatorDistribution(c.ValDistr)
|
||||
```
|
||||
|
||||
### Validator commission withdrawal
|
||||
|
||||
Commission is calculated each time rewards enter into the validator.
|
||||
|
||||
```
|
||||
func (vi ValidatorDistInfo) WithdrawCommission(g Global, height int64,
|
||||
totalBonded, vdTokens, commissionRate Dec) (
|
||||
vi ValidatorDistInfo, g Global, withdrawn DecCoins)
|
||||
|
||||
g = vi.TakeAccum(g, height, totalBonded, vdTokens, commissionRate)
|
||||
|
||||
withdrawalTokens := vi.PoolCommission
|
||||
vi.PoolCommission = 0
|
||||
|
||||
return vi, g, withdrawalTokens
|
||||
```
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -85,6 +85,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,
|
||||
@ -167,16 +168,16 @@ 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()
|
||||
@ -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
|
||||
|
||||
@ -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,7 +22,7 @@ INEFFASSIGN_CHECK := $(shell command -v ineffassign 2> /dev/null)
|
||||
MISSPELL_CHECK := $(shell command -v misspell 2> /dev/null)
|
||||
ERRCHECK_CHECK := $(shell command -v errcheck 2> /dev/null)
|
||||
UNPARAM_CHECK := $(shell command -v unparam 2> /dev/null)
|
||||
GOCYCLO_CHECK := $(shell command -v gocyclo 2> /dev/null)
|
||||
# GOCYCLO_CHECK := $(shell command -v gocyclo 2> /dev/null)
|
||||
|
||||
check_tools:
|
||||
ifndef DEP_CHECK
|
||||
@ -126,12 +126,12 @@ else
|
||||
@echo "Installing unparam"
|
||||
go get -v $(UNPARAM)
|
||||
endif
|
||||
ifdef GOCYCLO_CHECK
|
||||
@echo "gocyclo is already installed. Run 'make update_tools' to update."
|
||||
else
|
||||
@echo "Installing gocyclo"
|
||||
go get -v $(GOCYCLO)
|
||||
endif
|
||||
# ifdef GOCYCLO_CHECK
|
||||
# @echo "gocyclo is already installed. Run 'make update_tools' to update."
|
||||
# else
|
||||
# @echo "Installing gocyclo"
|
||||
# go get -v $(GOCYCLO)
|
||||
# endif
|
||||
|
||||
update_tools:
|
||||
@echo "Updating dep"
|
||||
@ -153,8 +153,8 @@ update_dev_tools:
|
||||
go get -u -v $(ERRCHECK)
|
||||
@echo "Updating unparam"
|
||||
go get -u -v $(UNPARAM)
|
||||
@echo "Updating goyclo"
|
||||
go get -u -v $(GOCYCLO)
|
||||
# @echo "Updating goyclo"
|
||||
# go get -u -v $(GOCYCLO)
|
||||
|
||||
# To avoid unintended conflicts with file names, always add to .PHONY
|
||||
# unless there is a reason not to.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"Linters": {
|
||||
"vet": "go tool vet -composites=false :PATH:LINE:MESSAGE"
|
||||
},
|
||||
"Enable": ["golint", "vet", "ineffassign", "unparam", "unconvert", "misspell", "gocyclo"],
|
||||
"Enable": ["golint", "vet", "ineffassign", "unparam", "unconvert", "misspell"],
|
||||
"Deadline": "500s",
|
||||
"Vendor": true,
|
||||
"Cyclo": 11
|
||||
|
||||
@ -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':
|
||||
@ -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
|
||||
|
||||
@ -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]",
|
||||
|
||||
@ -143,12 +143,12 @@ func StdSignBytes(chainID string, accnum int64, sequence int64, fee StdFee, msgs
|
||||
// a Msg with the other requirements for a StdSignDoc before
|
||||
// it is signed. For use in the CLI.
|
||||
type StdSignMsg struct {
|
||||
ChainID string
|
||||
AccountNumber int64
|
||||
Sequence int64
|
||||
Fee StdFee
|
||||
Msgs []sdk.Msg
|
||||
Memo string
|
||||
ChainID string `json:"chain_id"`
|
||||
AccountNumber int64 `json:"account_number"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
Fee StdFee `json:"fee"`
|
||||
Msgs []sdk.Msg `json:"msgs"`
|
||||
Memo string `json:"memo"`
|
||||
}
|
||||
|
||||
// get message bytes
|
||||
|
||||
@ -68,6 +68,9 @@ 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.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
|
||||
@ -107,6 +107,11 @@ func SendRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLICo
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
if utils.HasGenerateOnlyArg(r) {
|
||||
utils.WriteGenerateStdTxResponse(w, txCtx, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
|
||||
@ -99,12 +99,15 @@ $ gaiacli gov submit-proposal --title="Test Proposal" --description="My awesome
|
||||
}
|
||||
|
||||
msg := gov.NewMsgSubmitProposal(proposal.Title, proposal.Description, proposalType, fromAddr, amount)
|
||||
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, 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
|
||||
@ -177,12 +180,15 @@ func GetCmdDeposit(cdc *wire.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
msg := gov.NewMsgDeposit(depositerAddr, proposalID, amount)
|
||||
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
// Build and sign the transaction, then broadcast to a Tendermint
|
||||
// node.
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
@ -221,12 +227,15 @@ func GetCmdVote(cdc *wire.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
msg := gov.NewMsgVote(voterAddr, proposalID, byteVoteOption)
|
||||
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
fmt.Printf("Vote[Voter:%s,ProposalID:%d,Option:%s]",
|
||||
voterAddr.String(), msg.ProposalID, msg.Option.String(),
|
||||
)
|
||||
|
||||
@ -96,6 +96,12 @@ func signAndBuild(w http.ResponseWriter, r *http.Request, cliCtx context.CLICont
|
||||
}
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
if utils.HasGenerateOnlyArg(r) {
|
||||
utils.WriteGenerateStdTxResponse(w, txCtx, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(baseReq.Name, baseReq.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -12,11 +12,11 @@ const MsgType = "gov"
|
||||
//-----------------------------------------------------------
|
||||
// MsgSubmitProposal
|
||||
type MsgSubmitProposal struct {
|
||||
Title string // Title of the proposal
|
||||
Description string // Description of the proposal
|
||||
ProposalType ProposalKind // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
|
||||
Proposer sdk.AccAddress // Address of the proposer
|
||||
InitialDeposit sdk.Coins // Initial deposit paid by sender. Must be strictly positive.
|
||||
Title string `json:"title"` // Title of the proposal
|
||||
Description string `json:"description"` // Description of the proposal
|
||||
ProposalType ProposalKind `json:"proposal_type"` // Type of proposal. Initial set {PlainTextProposal, SoftwareUpgradeProposal}
|
||||
Proposer sdk.AccAddress `json:"proposer"` // Address of the proposer
|
||||
InitialDeposit sdk.Coins `json:"initial_deposit"` // Initial deposit paid by sender. Must be strictly positive.
|
||||
}
|
||||
|
||||
func NewMsgSubmitProposal(title string, description string, proposalType ProposalKind, proposer sdk.AccAddress, initialDeposit sdk.Coins) MsgSubmitProposal {
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -86,6 +86,7 @@ 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)
|
||||
|
||||
@ -43,6 +43,9 @@ func IBCTransferCmd(cdc *wire.Codec) *cobra.Command {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
|
||||
@ -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
|
||||
|
||||
@ -98,6 +98,11 @@ func TransferRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
if utils.HasGenerateOnlyArg(r) {
|
||||
utils.WriteGenerateStdTxResponse(w, txCtx, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
|
||||
@ -22,11 +22,11 @@ func init() {
|
||||
// IBCPacket defines a piece of data that can be send between two separate
|
||||
// blockchains.
|
||||
type IBCPacket struct {
|
||||
SrcAddr sdk.AccAddress
|
||||
DestAddr sdk.AccAddress
|
||||
Coins sdk.Coins
|
||||
SrcChain string
|
||||
DestChain string
|
||||
SrcAddr sdk.AccAddress `json:"src_addr"`
|
||||
DestAddr sdk.AccAddress `json:"dest_addr"`
|
||||
Coins sdk.Coins `json:"coins"`
|
||||
SrcChain string `json:"src_chain"`
|
||||
DestChain string `json:"dest_chain"`
|
||||
}
|
||||
|
||||
func NewIBCPacket(srcAddr sdk.AccAddress, destAddr sdk.AccAddress, coins sdk.Coins,
|
||||
|
||||
@ -86,6 +86,7 @@ func (app *App) CompleteSetup(newKeys []*sdk.KVStoreKey) error {
|
||||
}
|
||||
|
||||
// InitChainer performs custom logic for initialization.
|
||||
// nolint: errcheck
|
||||
func (app *App) InitChainer(ctx sdk.Context, _ abci.RequestInitChain) abci.ResponseInitChain {
|
||||
// Load the genesis accounts
|
||||
for _, genacc := range app.GenesisAccounts {
|
||||
@ -207,6 +208,7 @@ func GeneratePrivKeyAddressPairsFromRand(rand *rand.Rand, n int) (keys []crypto.
|
||||
|
||||
// RandomSetGenesis set genesis accounts with random coin values using the
|
||||
// provided addresses and coin denominations.
|
||||
// nolint: errcheck
|
||||
func RandomSetGenesis(r *rand.Rand, app *App, addrs []sdk.AccAddress, denoms []string) {
|
||||
accts := make([]auth.Account, len(addrs), len(addrs))
|
||||
randCoinIntervals := []BigInterval{
|
||||
|
||||
@ -155,7 +155,7 @@ func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, event f
|
||||
AssertAllInvariants(t, app, invariants, log)
|
||||
}
|
||||
if opCount%50 == 0 {
|
||||
fmt.Printf("\rSimulating... block %d/%d, operation %d/%d.", header.Height, totalNumBlocks, opCount, blocksize)
|
||||
fmt.Printf("\rSimulating... block %d/%d, operation %d/%d. ", header.Height, totalNumBlocks, opCount, blocksize)
|
||||
}
|
||||
}
|
||||
opCount++
|
||||
@ -209,6 +209,7 @@ func queueOperations(queuedOperations map[int][]Operation, futureOperations []Fu
|
||||
}
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func runQueuedOperations(queueOperations map[int][]Operation, height int, tb testing.TB, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||
privKeys []crypto.PrivKey, log string, event func(string)) (updatedLog string, numOpsRan int) {
|
||||
updatedLog = log
|
||||
@ -243,6 +244,7 @@ func getKeys(validators map[string]mockValidator) []string {
|
||||
}
|
||||
|
||||
// RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction
|
||||
// nolint: unparam
|
||||
func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64,
|
||||
pastTimes []time.Time, pastVoteInfos [][]abci.VoteInfo, event func(string), header abci.Header, log string) abci.RequestBeginBlock {
|
||||
if len(validators) == 0 {
|
||||
@ -320,6 +322,7 @@ func AssertAllInvariants(t *testing.T, app *baseapp.BaseApp, tests []Invariant,
|
||||
}
|
||||
|
||||
// updateValidators mimicks Tendermint's update logic
|
||||
// nolint: unparam
|
||||
func updateValidators(tb testing.TB, r *rand.Rand, current map[string]mockValidator, updates []abci.Validator, event func(string)) map[string]mockValidator {
|
||||
for _, update := range updates {
|
||||
switch {
|
||||
|
||||
@ -23,6 +23,7 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey) Keeper {
|
||||
}
|
||||
|
||||
// InitKeeper constructs a new Keeper with initial parameters
|
||||
// nolint: errcheck
|
||||
func InitKeeper(ctx sdk.Context, cdc *wire.Codec, key sdk.StoreKey, params ...interface{}) Keeper {
|
||||
if len(params)%2 != 0 {
|
||||
panic("Odd params list length for InitKeeper")
|
||||
|
||||
@ -15,6 +15,7 @@ func ActivatedParamKey(ty string) string {
|
||||
}
|
||||
|
||||
// InitGenesis stores activated type to param store
|
||||
// nolint: errcheck
|
||||
func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
||||
for _, ty := range data.ActivatedTypes {
|
||||
k.set(ctx, ActivatedParamKey(ty), true)
|
||||
|
||||
@ -33,7 +33,9 @@ func GetCmdUnjail(cdc *wire.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
msg := slashing.NewMsgUnjail(sdk.ValAddress(valAddr))
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Cod
|
||||
}
|
||||
|
||||
// http request handler to query signing info
|
||||
// nolint: unparam
|
||||
func signingInfoHandlerFn(cliCtx context.CLIContext, storeName string, cdc *wire.Codec) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
@ -99,6 +99,11 @@ func unjailRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLI
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
if utils.HasGenerateOnlyArg(r) {
|
||||
utils.WriteGenerateStdTxResponse(w, txCtx, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusUnauthorized, "Must use own validator address")
|
||||
|
||||
@ -16,15 +16,15 @@ func TestCannotUnjailUnlessJailed(t *testing.T) {
|
||||
slh := NewHandler(keeper)
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
msg := newTestMsgCreateValidator(sdk.ValAddress(addr), val, amt)
|
||||
msg := newTestMsgCreateValidator(addr, val, amt)
|
||||
got := stake.NewHandler(sk)(ctx, msg)
|
||||
require.True(t, got.IsOK())
|
||||
stake.EndBlocker(ctx, sk)
|
||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, sdk.ValAddress(addr)).GetPower()))
|
||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||
|
||||
// assert non-jailed validator can't be unjailed
|
||||
got = slh(ctx, NewMsgUnjail(sdk.ValAddress(addr)))
|
||||
got = slh(ctx, NewMsgUnjail(addr))
|
||||
require.False(t, got.IsOK(), "allowed unjail of non-jailed validator")
|
||||
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotJailed), got.Code)
|
||||
}
|
||||
@ -39,7 +39,7 @@ func TestJailedValidatorDelegations(t *testing.T) {
|
||||
// create a validator
|
||||
amount := int64(10)
|
||||
valPubKey, bondAmount := pks[0], sdk.NewInt(amount)
|
||||
valAddr, consAddr := sdk.ValAddress(addrs[1]), sdk.ConsAddress(addrs[0])
|
||||
valAddr, consAddr := addrs[1], sdk.ConsAddress(addrs[0])
|
||||
|
||||
msgCreateVal := newTestMsgCreateValidator(valAddr, valPubKey, bondAmount)
|
||||
got := stake.NewHandler(stakeKeeper)(ctx, msgCreateVal)
|
||||
|
||||
@ -27,12 +27,12 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
sk = sk.WithValidatorHooks(keeper.ValidatorHooks())
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(sdk.ValAddress(addr), val, amt))
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, sdk.ValAddress(addr)).GetPower()))
|
||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||
|
||||
// handle a signature to set signing info
|
||||
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true)
|
||||
@ -41,13 +41,13 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt)
|
||||
|
||||
// should be jailed
|
||||
require.True(t, sk.Validator(ctx, sdk.ValAddress(addr)).GetJailed())
|
||||
require.True(t, sk.Validator(ctx, addr).GetJailed())
|
||||
// unjail to measure power
|
||||
sk.Unjail(ctx, val)
|
||||
// power should be reduced
|
||||
require.Equal(
|
||||
t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))),
|
||||
sk.Validator(ctx, sdk.ValAddress(addr)).GetPower(),
|
||||
sk.Validator(ctx, addr).GetPower(),
|
||||
)
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))})
|
||||
|
||||
@ -55,7 +55,7 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt)
|
||||
require.Equal(
|
||||
t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))),
|
||||
sk.Validator(ctx, sdk.ValAddress(addr)).GetPower(),
|
||||
sk.Validator(ctx, addr).GetPower(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -125,12 +125,12 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
sh := stake.NewHandler(sk)
|
||||
slh := NewHandler(keeper)
|
||||
got := sh(ctx, newTestMsgCreateValidator(sdk.ValAddress(addr), val, amt))
|
||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, sdk.ValAddress(addr)).GetPower()))
|
||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||
info, found := keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||
require.False(t, found)
|
||||
require.Equal(t, int64(0), info.StartHeight)
|
||||
@ -165,7 +165,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
validator, _ := sk.GetValidatorByPubKey(ctx, val)
|
||||
require.Equal(t, sdk.Bonded, validator.GetStatus())
|
||||
pool := sk.GetPool(ctx)
|
||||
require.Equal(t, int64(amtInt), pool.BondedTokens.RoundInt64())
|
||||
require.Equal(t, amtInt, pool.BondedTokens.RoundInt64())
|
||||
|
||||
// 501st block missed
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
@ -180,12 +180,12 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
require.Equal(t, sdk.Unbonding, validator.GetStatus())
|
||||
|
||||
// unrevocation should fail prior to jail expiration
|
||||
got = slh(ctx, NewMsgUnjail(sdk.ValAddress(addr)))
|
||||
got = slh(ctx, NewMsgUnjail(addr))
|
||||
require.False(t, got.IsOK())
|
||||
|
||||
// unrevocation should succeed after jail expiration
|
||||
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.DowntimeUnbondDuration(ctx))})
|
||||
got = slh(ctx, NewMsgUnjail(sdk.ValAddress(addr)))
|
||||
got = slh(ctx, NewMsgUnjail(addr))
|
||||
require.True(t, got.IsOK())
|
||||
|
||||
// validator should be rebonded now
|
||||
@ -195,7 +195,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
// validator should have been slashed
|
||||
pool = sk.GetPool(ctx)
|
||||
slashAmt := sdk.NewDec(amtInt).Mul(keeper.SlashFractionDowntime(ctx)).RoundInt64()
|
||||
require.Equal(t, int64(amtInt)-slashAmt, pool.BondedTokens.RoundInt64())
|
||||
require.Equal(t, amtInt-slashAmt, pool.BondedTokens.RoundInt64())
|
||||
|
||||
// validator start height should have been changed
|
||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||
@ -235,12 +235,12 @@ func TestHandleNewValidator(t *testing.T) {
|
||||
ctx, ck, sk, _, keeper := createTestInput(t)
|
||||
addr, val, amt := addrs[0], pks[0], int64(100)
|
||||
sh := stake.NewHandler(sk)
|
||||
got := sh(ctx, newTestMsgCreateValidator(sdk.ValAddress(addr), val, sdk.NewInt(amt)))
|
||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, sdk.NewInt(amt)))
|
||||
require.True(t, got.IsOK())
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.SubRaw(amt)}})
|
||||
require.Equal(t, sdk.NewDec(amt), sk.Validator(ctx, sdk.ValAddress(addr)).GetPower())
|
||||
require.Equal(t, sdk.NewDec(amt), sk.Validator(ctx, addr).GetPower())
|
||||
|
||||
// 1000 first blocks not a validator
|
||||
ctx = ctx.WithBlockHeight(keeper.SignedBlocksWindow(ctx) + 1)
|
||||
@ -252,7 +252,7 @@ func TestHandleNewValidator(t *testing.T) {
|
||||
|
||||
info, found := keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||
require.True(t, found)
|
||||
require.Equal(t, int64(keeper.SignedBlocksWindow(ctx)+1), info.StartHeight)
|
||||
require.Equal(t, keeper.SignedBlocksWindow(ctx)+1, info.StartHeight)
|
||||
require.Equal(t, int64(2), info.IndexOffset)
|
||||
require.Equal(t, int64(1), info.SignedBlocksCounter)
|
||||
require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
|
||||
@ -273,7 +273,7 @@ func TestHandleAlreadyJailed(t *testing.T) {
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
sh := stake.NewHandler(sk)
|
||||
got := sh(ctx, newTestMsgCreateValidator(sdk.ValAddress(addr), val, amt))
|
||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
@ -296,7 +296,7 @@ func TestHandleAlreadyJailed(t *testing.T) {
|
||||
require.Equal(t, sdk.Unbonding, validator.GetStatus())
|
||||
|
||||
// validator should have been slashed
|
||||
require.Equal(t, int64(amtInt-1), validator.GetTokens().RoundInt64())
|
||||
require.Equal(t, amtInt-1, validator.GetTokens().RoundInt64())
|
||||
|
||||
// another block missed
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
@ -304,6 +304,6 @@ func TestHandleAlreadyJailed(t *testing.T) {
|
||||
|
||||
// validator should not have been slashed twice
|
||||
validator, _ = sk.GetValidatorByPubKey(ctx, val)
|
||||
require.Equal(t, int64(amtInt-1), validator.GetTokens().RoundInt64())
|
||||
require.Equal(t, amtInt-1, validator.GetTokens().RoundInt64())
|
||||
|
||||
}
|
||||
|
||||
@ -17,12 +17,12 @@ func TestBeginBlocker(t *testing.T) {
|
||||
addr, pk, amt := addrs[2], pks[2], sdk.NewInt(100)
|
||||
|
||||
// bond the validator
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(sdk.ValAddress(addr), pk, amt))
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, pk, amt))
|
||||
require.True(t, got.IsOK())
|
||||
validatorUpdates := stake.EndBlocker(ctx, sk)
|
||||
keeper.AddValidators(ctx, validatorUpdates)
|
||||
require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, sdk.ValAddress(addr)).GetPower()))
|
||||
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||
|
||||
val := abci.Validator{
|
||||
Address: pk.Address(),
|
||||
|
||||
@ -77,7 +77,9 @@ func GetCmdCreateValidator(cdc *wire.Codec) *cobra.Command {
|
||||
} else {
|
||||
msg = stake.NewMsgCreateValidator(sdk.ValAddress(valAddr), pk, amount, description)
|
||||
}
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
@ -117,6 +119,9 @@ func GetCmdEditValidator(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
msg := stake.NewMsgEditValidator(sdk.ValAddress(valAddr), description)
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
@ -156,6 +161,9 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
msg := stake.NewMsgDelegate(delAddr, valAddr, amount)
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
@ -225,6 +233,9 @@ func GetCmdBeginRedelegate(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
msg := stake.NewMsgBeginRedelegate(delAddr, valSrcAddr, valDstAddr, sharesAmount)
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
@ -313,6 +324,9 @@ func GetCmdCompleteRedelegate(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
msg := stake.NewMsgCompleteRedelegate(delAddr, valSrcAddr, valDstAddr)
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
@ -374,6 +388,9 @@ func GetCmdBeginUnbonding(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
msg := stake.NewMsgBeginUnbonding(delAddr, valAddr, sharesAmount)
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
@ -409,6 +426,9 @@ func GetCmdCompleteUnbonding(cdc *wire.Codec) *cobra.Command {
|
||||
|
||||
msg := stake.NewMsgCompleteUnbonding(delAddr, valAddr)
|
||||
|
||||
if cliCtx.GenerateOnly {
|
||||
return utils.PrintUnsignedStdTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
}
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
|
||||
@ -297,6 +297,11 @@ func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx contex
|
||||
txCtx = newCtx
|
||||
}
|
||||
|
||||
if utils.HasGenerateOnlyArg(r) {
|
||||
utils.WriteGenerateStdTxResponse(w, txCtx, []sdk.Msg{msg})
|
||||
return
|
||||
}
|
||||
|
||||
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
|
||||
@ -163,6 +163,7 @@ func getValidators(validatorKVs []sdk.KVPair, cdc *wire.Codec) ([]types.BechVali
|
||||
}
|
||||
|
||||
// gets all Bech32 validators from a key
|
||||
// nolint: unparam
|
||||
func getBech32Validators(storeName string, cliCtx context.CLIContext, cdc *wire.Codec) (
|
||||
validators []types.BechValidator, httpStatusCode int, errMsg string, err error) {
|
||||
|
||||
|
||||
@ -430,7 +430,7 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
||||
initBond,
|
||||
}
|
||||
for _, c := range errorCases {
|
||||
unbondShares := sdk.NewDec(int64(c))
|
||||
unbondShares := sdk.NewDec(c)
|
||||
msgBeginUnbonding := NewMsgBeginUnbonding(delegatorAddr, validatorAddr, unbondShares)
|
||||
got = handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper)
|
||||
require.False(t, got.IsOK(), "expected unbond msg to fail")
|
||||
|
||||
@ -68,6 +68,7 @@ func GetValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []
|
||||
|
||||
// get the power ranking of a validator
|
||||
// NOTE the larger values are of higher value
|
||||
// nolint: unparam
|
||||
func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte {
|
||||
|
||||
potentialPower := validator.Tokens
|
||||
|
||||
@ -203,6 +203,7 @@ func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty
|
||||
// the unbonding delegation had enough stake to slash
|
||||
// (the amount actually slashed may be less if there's
|
||||
// insufficient stake remaining)
|
||||
// nolint: unparam
|
||||
func (k Keeper) slashRedelegation(ctx sdk.Context, validator types.Validator, redelegation types.Redelegation,
|
||||
infractionHeight int64, slashFactor sdk.Dec) (slashAmount sdk.Dec) {
|
||||
|
||||
|
||||
@ -372,6 +372,7 @@ func (k Keeper) updateForJailing(ctx sdk.Context, oldFound bool, oldValidator, n
|
||||
return newValidator
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func (k Keeper) getPowerIncreasing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) bool {
|
||||
if oldFound && oldValidator.BondedTokens().LT(newValidator.BondedTokens()) {
|
||||
return true
|
||||
@ -380,6 +381,7 @@ func (k Keeper) getPowerIncreasing(ctx sdk.Context, oldFound bool, oldValidator,
|
||||
}
|
||||
|
||||
// get the bond height and incremented intra-tx counter
|
||||
// nolint: unparam
|
||||
func (k Keeper) bondIncrement(ctx sdk.Context, oldFound bool, oldValidator,
|
||||
newValidator types.Validator) (height int64, intraTxCounter int16) {
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ func AllInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simula
|
||||
}
|
||||
|
||||
// SupplyInvariants checks that the total supply reflects all held loose tokens, bonded tokens, and unbonding delegations
|
||||
// nolint: unparam
|
||||
func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) simulation.Invariant {
|
||||
return func(t *testing.T, app *baseapp.BaseApp, log string) {
|
||||
ctx := app.NewContext(false, abci.Header{})
|
||||
|
||||
@ -258,6 +258,7 @@ func SimulateMsgCompleteRedelegate(k stake.Keeper) simulation.Operation {
|
||||
}
|
||||
|
||||
// Setup
|
||||
// nolint: errcheck
|
||||
func Setup(mapp *mock.App, k stake.Keeper) simulation.RandSetup {
|
||||
return func(r *rand.Rand, privKeys []crypto.PrivKey) {
|
||||
ctx := mapp.NewContext(false, abci.Header{})
|
||||
|
||||
@ -23,7 +23,7 @@ func TestDelegationEqual(t *testing.T) {
|
||||
ok := d1.Equal(d2)
|
||||
require.True(t, ok)
|
||||
|
||||
d2.ValidatorAddr = sdk.ValAddress(addr3)
|
||||
d2.ValidatorAddr = addr3
|
||||
d2.Shares = sdk.NewDec(200)
|
||||
|
||||
ok = d1.Equal(d2)
|
||||
@ -57,7 +57,7 @@ func TestUnbondingDelegationEqual(t *testing.T) {
|
||||
ok := ud1.Equal(ud2)
|
||||
require.True(t, ok)
|
||||
|
||||
ud2.ValidatorAddr = sdk.ValAddress(addr3)
|
||||
ud2.ValidatorAddr = addr3
|
||||
|
||||
ud2.MinTime = time.Unix(20*20*2, 0)
|
||||
ok = ud1.Equal(ud2)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user