Merge PR #1880: Staking Gaia-lite (ex LCD) refactor

This commit is contained in:
Federico Kunze 2018-08-08 12:38:39 +02:00 committed by Christopher Goes
parent 4582de4902
commit 1da1115a24
16 changed files with 1298 additions and 347 deletions

47
Gopkg.lock generated
View File

@ -34,11 +34,11 @@
[[projects]]
branch = "master"
digest = "1:2c00f064ba355903866cbfbf3f7f4c0fe64af6638cc7d1b8bdcf3181bc67f1d8"
digest = "1:6aabc1566d6351115d561d038da82a4c19b46c3b6e17f4a0a2fa60260663dc79"
name = "github.com/btcsuite/btcd"
packages = ["btcec"]
pruneopts = "UT"
revision = "9a2f9524024889e129a5422aca2cff73cb3eabf6"
revision = "cf05f92c3f815bbd5091ed6c73eff51f7b1945e8"
[[projects]]
digest = "1:386de157f7d19259a7f9c81f26ce011223ce0f090353c1152ffdf730d7d10ac2"
@ -71,7 +71,7 @@
version = "v1.4.7"
[[projects]]
digest = "1:fdf5169073fb0ad6dc12a70c249145e30f4058647bea25f0abd48b6d9f228a11"
digest = "1:fa30c0652956e159cdb97dcb2ef8b8db63ed668c02a5c3a40961c8f0641252fe"
name = "github.com/go-kit/kit"
packages = [
"log",
@ -103,7 +103,7 @@
version = "v1.7.0"
[[projects]]
digest = "1:35621fe20f140f05a0c4ef662c26c0ab4ee50bca78aa30fe87d33120bd28165e"
digest = "1:212285efb97b9ec2e20550d81f0446cb7897e57cbdfd7301b1363ab113d8be45"
name = "github.com/gogo/protobuf"
packages = [
"gogoproto",
@ -118,7 +118,7 @@
version = "v1.1.1"
[[projects]]
digest = "1:17fe264ee908afc795734e8c4e63db2accabaf57326dbf21763a7d6b86096260"
digest = "1:cb22af0ed7c72d495d8be1106233ee553898950f15fd3f5404406d44c2e86888"
name = "github.com/golang/protobuf"
packages = [
"proto",
@ -165,7 +165,7 @@
[[projects]]
branch = "master"
digest = "1:a361611b8c8c75a1091f00027767f7779b29cb37c456a71b8f2604c88057ab40"
digest = "1:ac64f01acc5eeea9dde40e326de6b6471e501392ec06524c3b51033aa50789bc"
name = "github.com/hashicorp/hcl"
packages = [
".",
@ -263,7 +263,7 @@
version = "v1.0.0"
[[projects]]
digest = "1:c1a04665f9613e082e1209cf288bf64f4068dcd6c87a64bf1c4ff006ad422ba0"
digest = "1:98225904b7abff96c052b669b25788f18225a36673fba022fb93514bb9a2a64e"
name = "github.com/prometheus/client_golang"
packages = [
"prometheus",
@ -274,7 +274,7 @@
[[projects]]
branch = "master"
digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4"
digest = "1:0f37e09b3e92aaeda5991581311f8dbf38944b36a3edec61cc2d1991f527554a"
name = "github.com/prometheus/client_model"
packages = ["go"]
pruneopts = "UT"
@ -282,7 +282,7 @@
[[projects]]
branch = "master"
digest = "1:63b68062b8968092eb86bedc4e68894bd096ea6b24920faca8b9dcf451f54bb5"
digest = "1:dad2e5a2153ee7a6c9ab8fc13673a16ee4fb64434a7da980965a3741b0c981a3"
name = "github.com/prometheus/common"
packages = [
"expfmt",
@ -294,7 +294,7 @@
[[projects]]
branch = "master"
digest = "1:8c49953a1414305f2ff5465147ee576dd705487c35b15918fcd4efdc0cb7a290"
digest = "1:a37c98f4b7a66bb5c539c0539f0915a74ef1c8e0b3b6f45735289d94cae92bfd"
name = "github.com/prometheus/procfs"
packages = [
".",
@ -313,7 +313,7 @@
revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
[[projects]]
digest = "1:bd1ae00087d17c5a748660b8e89e1043e1e5479d0fea743352cda2f8dd8c4f84"
digest = "1:37ace7f35375adec11634126944bdc45a673415e2fcc07382d03b75ec76ea94c"
name = "github.com/spf13/afero"
packages = [
".",
@ -332,7 +332,7 @@
version = "v1.2.0"
[[projects]]
digest = "1:7ffc0983035bc7e297da3688d9fe19d60a420e9c38bef23f845c53788ed6a05e"
digest = "1:627ab2f549a6a55c44f46fa24a4307f4d0da81bfc7934ed0473bf38b24051d26"
name = "github.com/spf13/cobra"
packages = ["."]
pruneopts = "UT"
@ -364,7 +364,7 @@
version = "v1.0.0"
[[projects]]
digest = "1:7e8d267900c7fa7f35129a2a37596e38ed0f11ca746d6d9ba727980ee138f9f6"
digest = "1:73697231b93fb74a73ebd8384b68b9a60c57ea6b13c56d2425414566a72c8e6d"
name = "github.com/stretchr/testify"
packages = [
"assert",
@ -376,7 +376,7 @@
[[projects]]
branch = "master"
digest = "1:b3cfb8d82b1601a846417c3f31c03a7961862cb2c98dcf0959c473843e6d9a2b"
digest = "1:922191411ad8f61bcd8018ac127589bb489712c1d1a0ab2497aca4b16de417d2"
name = "github.com/syndtr/goleveldb"
packages = [
"leveldb",
@ -397,7 +397,7 @@
[[projects]]
branch = "master"
digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722"
digest = "1:203b409c21115233a576f99e8f13d8e07ad82b25500491f7e1cca12588fb3232"
name = "github.com/tendermint/ed25519"
packages = [
".",
@ -424,7 +424,7 @@
version = "v0.9.2"
[[projects]]
digest = "1:e10e95fd9f0a3a31686c9696f8995f6c04b0bc1b4ed0562a4f53cddc0b89d059"
digest = "1:049c779b867a182cea567c65d7c81e3b9e4e4a7eece4c35a19639f75d2aa7da9"
name = "github.com/tendermint/tendermint"
packages = [
"abci/client",
@ -499,7 +499,7 @@
[[projects]]
branch = "master"
digest = "1:65a21a9e051d54eb6a3f70c659a765f706a998d9287c302269f4ed8054b2a852"
digest = "1:e8206c1653e050116ec8c9a823a86413fc9f9ee3c2f3ae977c96d6a1747f7325"
name = "golang.org/x/crypto"
packages = [
"blowfish",
@ -515,10 +515,10 @@
"salsa20/salsa",
]
pruneopts = "UT"
revision = "c126467f60eb25f8f27e5a981f32a87e3965053f"
revision = "f027049dab0ad238e394a753dba2d14753473a04"
[[projects]]
digest = "1:d36f55a999540d29b6ea3c2ea29d71c76b1d9853fdcd3e5c5cb4836f2ba118f1"
digest = "1:04dda8391c3e2397daf254ac68003f30141c069b228d06baec8324a5f81dc1e9"
name = "golang.org/x/net"
packages = [
"context",
@ -535,14 +535,14 @@
[[projects]]
branch = "master"
digest = "1:8466957fb2af510f68b13aec64ccad13e9e756dc1da3ea28c422f8ac410e56f0"
digest = "1:4d7a8265af700258feaff86722049eb5b787240d66dfaf45ff4962f09de6e0be"
name = "golang.org/x/sys"
packages = ["unix"]
pruneopts = "UT"
revision = "bd9dbc187b6e1dacfdd2722a87e83093c2d7bd6e"
revision = "acbc56fc7007d2a01796d5bde54f39e3b3e95945"
[[projects]]
digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18"
digest = "1:7509ba4347d1f8de6ae9be8818b0cd1abc3deeffe28aeaf4be6d4b6b5178d9ca"
name = "golang.org/x/text"
packages = [
"collate",
@ -573,7 +573,7 @@
revision = "daca94659cb50e9f37c1b834680f2e46358f10b0"
[[projects]]
digest = "1:2dab32a43451e320e49608ff4542fdfc653c95dcc35d0065ec9c6c3dd540ed74"
digest = "1:4515e3030c440845b046354fd5d57671238428b820deebce2e9dabb5cd3c51ac"
name = "google.golang.org/grpc"
packages = [
".",
@ -617,7 +617,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "71e86b1f1e9ec71901c20d8532dc8477df66eff37a407322379f6a8b03e5d91b"
input-imports = [
"github.com/bartekn/go-bip39",
"github.com/bgentry/speakeasy",

View File

@ -1,6 +1,8 @@
## PENDING
BREAKING CHANGES
* API
- \#1880 [x/stake] changed the endpoints to be more REST-ful
* Update to tendermint v0.22.5. This involves changing all of the cryptography imports. [Ref](https://github.com/tendermint/tendermint/pull/1966)
* [baseapp] Msgs are no longer run on CheckTx, removed `ctx.IsCheckTx()`
* [x/gov] CLI flag changed from `proposalID` to `proposal-id`

View File

@ -7,13 +7,13 @@ import (
"regexp"
"testing"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
cryptoKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/common"
p2p "github.com/tendermint/tendermint/p2p"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
@ -27,6 +27,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/x/stake/client/rest"
)
func init() {
@ -316,13 +317,7 @@ func TestTxs(t *testing.T) {
res, body = Request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
type txInfo struct {
Hash common.HexBytes `json:"hash"`
Height int64 `json:"height"`
Tx sdk.Tx `json:"tx"`
Result abci.ResponseDeliverTx `json:"result"`
}
var indexedTxs []txInfo
var indexedTxs []tx.Info
// check if tx is queryable
res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=tx.hash='%s'", resultTx.Hash), nil)
@ -374,6 +369,19 @@ func TestValidatorsQuery(t *testing.T) {
require.True(t, foundVal, "pkBech %v, owner %v", pkBech, validators[0].Owner)
}
func TestValidatorQuery(t *testing.T) {
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
require.Equal(t, 1, len(pks))
validator1Owner := sdk.AccAddress(pks[0].Address())
validator := getValidator(t, port, validator1Owner)
bech32ValAddress, err := sdk.Bech32ifyValPub(pks[0])
require.NoError(t, err)
assert.Equal(t, validator.PubKey, bech32ValAddress, "The returned validator does not hold the correct data")
}
func TestBonding(t *testing.T) {
name, password, denom := "test", "1234567890", "steak"
addr, seed := CreateAddr(t, "test", password, GetKeyBase(t))
@ -398,7 +406,7 @@ func TestBonding(t *testing.T) {
// query validator
bond := getDelegation(t, port, addr, validator1Owner)
require.Equal(t, "60/1", bond.Shares.String())
require.Equal(t, "60.0000000000", bond.Shares)
//////////////////////
// testing unbonding
@ -409,7 +417,7 @@ func TestBonding(t *testing.T) {
// query validator
bond = getDelegation(t, port, addr, validator1Owner)
require.Equal(t, "30/1", bond.Shares.String())
require.Equal(t, "30.0000000000", bond.Shares)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
@ -421,7 +429,33 @@ func TestBonding(t *testing.T) {
coins = acc.GetCoins()
require.Equal(t, int64(40), coins.AmountOf("steak").Int64())
// query unbonding delegation
validatorAddr := sdk.AccAddress(pks[0].Address())
unbondings := getUndelegations(t, port, addr, validatorAddr)
assert.Len(t, unbondings, 1, "Unbondings holds all unbonding-delegations")
assert.Equal(t, "30", unbondings[0].Balance.Amount.String())
// query summary
summary := getDelegationSummary(t, port, addr)
assert.Len(t, summary.Delegations, 1, "Delegation summary holds all delegations")
assert.Equal(t, "30.0000000000", summary.Delegations[0].Shares)
assert.Len(t, summary.UnbondingDelegations, 1, "Delegation summary holds all unbonding-delegations")
assert.Equal(t, "30", summary.UnbondingDelegations[0].Balance.Amount.String())
// TODO add redelegation, need more complex capabilities such to mock context and
// TODO check summary for redelegation
// assert.Len(t, summary.Redelegations, 1, "Delegation summary holds all redelegations")
// query txs
txs := getBondingTxs(t, port, addr, "")
assert.Len(t, txs, 2, "All Txs found")
txs = getBondingTxs(t, port, addr, "bond")
assert.Len(t, txs, 1, "All bonding txs found")
txs = getBondingTxs(t, port, addr, "unbond")
assert.Len(t, txs, 1, "All unbonding txs found")
}
func TestSubmitProposal(t *testing.T) {
@ -719,17 +753,58 @@ func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.
return signingInfo
}
func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) stake.Delegation {
// ============= Stake Module ================
func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) rest.DelegationWithoutRat {
// get the account to get the sequence
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/%s/delegation/%s", delegatorAddr, validatorAddr), nil)
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var bond stake.Delegation
var bond rest.DelegationWithoutRat
err := cdc.UnmarshalJSON([]byte(body), &bond)
require.Nil(t, err)
return bond
}
func getUndelegations(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) []stake.UnbondingDelegation {
// get the account to get the sequence
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delegatorAddr, validatorAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var unbondings []stake.UnbondingDelegation
err := cdc.UnmarshalJSON([]byte(body), &unbondings)
require.Nil(t, err)
return unbondings
}
func getDelegationSummary(t *testing.T, port string, delegatorAddr sdk.AccAddress) rest.DelegationSummary {
// get the account to get the sequence
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s", delegatorAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var summary rest.DelegationSummary
err := cdc.UnmarshalJSON([]byte(body), &summary)
require.Nil(t, err)
return summary
}
func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, query string) []tx.Info {
// get the account to get the sequence
var res *http.Response
var body string
if len(query) > 0 {
res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs?type=%s", delegatorAddr, query), nil)
} else {
res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs", delegatorAddr), nil)
}
require.Equal(t, http.StatusOK, res.StatusCode, body)
var txs []tx.Info
err := cdc.UnmarshalJSON([]byte(body), &txs)
require.Nil(t, err)
return txs
}
func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, delegatorAddr)
@ -758,7 +833,7 @@ func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr,
"begin_redelegates": [],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr, "steak"))
res, body := Request(t, port, "POST", "/stake/delegations", jsonStr)
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results []ctypes.ResultBroadcastTxCommit
@ -798,7 +873,7 @@ func doBeginUnbonding(t *testing.T, port, seed, name, password string,
"begin_redelegates": [],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr))
res, body := Request(t, port, "POST", "/stake/delegations", jsonStr)
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results []ctypes.ResultBroadcastTxCommit
@ -839,7 +914,7 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string,
],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorSrcAddr, validatorDstAddr))
res, body := Request(t, port, "POST", "/stake/delegations", jsonStr)
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results []ctypes.ResultBroadcastTxCommit
@ -859,6 +934,18 @@ func getValidators(t *testing.T, port string) []stake.BechValidator {
return validators
}
func getValidator(t *testing.T, port string, validatorAddr sdk.AccAddress) stake.BechValidator {
// get the account to get the sequence
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var validator stake.BechValidator
err := cdc.UnmarshalJSON([]byte(body), &validator)
require.Nil(t, err)
return validator
}
// ============= Governance Module ================
func getProposal(t *testing.T, port string, proposalID int64) gov.Proposal {
res, body := Request(t, port, "GET", fmt.Sprintf("/gov/proposals/%d", proposalID), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)

View File

@ -121,7 +121,7 @@ func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress
config.TxIndex.IndexAllTags = true
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
logger = log.NewFilter(logger, log.AllowDebug())
logger = log.NewFilter(logger, log.AllowError())
privValidatorFile := config.PrivValidatorFile()
privVal := pvm.LoadOrGenFilePV(privValidatorFile)
@ -256,6 +256,7 @@ func Request(t *testing.T, port, method, path string, payload []byte) (*http.Res
res *http.Response
)
url := fmt.Sprintf("http://localhost:%v%v", port, path)
fmt.Println("REQUEST " + method + " " + url)
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
require.Nil(t, err)

View File

@ -75,14 +75,14 @@ func queryTx(cdc *wire.Codec, cliCtx context.CLIContext, hashHexStr string, trus
return wire.MarshalJSONIndent(cdc, info)
}
func formatTxResult(cdc *wire.Codec, res *ctypes.ResultTx) (txInfo, error) {
func formatTxResult(cdc *wire.Codec, res *ctypes.ResultTx) (Info, error) {
// TODO: verify the proof if requested
tx, err := parseTx(cdc, res.Tx)
if err != nil {
return txInfo{}, err
return Info{}, err
}
return txInfo{
return Info{
Hash: res.Hash,
Height: res.Height,
Tx: tx,
@ -90,8 +90,8 @@ func formatTxResult(cdc *wire.Codec, res *ctypes.ResultTx) (txInfo, error) {
}, nil
}
// txInfo is used to prepare info to display
type txInfo struct {
// Info is used to prepare info to display
type Info struct {
Hash common.HexBytes `json:"hash"`
Height int64 `json:"height"`
Tx sdk.Tx `json:"tx"`

View File

@ -57,7 +57,7 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command {
return cmd
}
func searchTxs(cliCtx context.CLIContext, cdc *wire.Codec, tags []string) ([]txInfo, error) {
func searchTxs(cliCtx context.CLIContext, cdc *wire.Codec, tags []string) ([]Info, error) {
if len(tags) == 0 {
return nil, errors.New("must declare at least one tag to search")
}
@ -81,7 +81,7 @@ func searchTxs(cliCtx context.CLIContext, cdc *wire.Codec, tags []string) ([]txI
return nil, err
}
info, err := formatTxResults(cdc, res.Txs)
info, err := FormatTxResults(cdc, res.Txs)
if err != nil {
return nil, err
}
@ -89,9 +89,10 @@ func searchTxs(cliCtx context.CLIContext, cdc *wire.Codec, tags []string) ([]txI
return info, nil
}
func formatTxResults(cdc *wire.Codec, res []*ctypes.ResultTx) ([]txInfo, error) {
// parse the indexed txs into an array of Info
func FormatTxResults(cdc *wire.Codec, res []*ctypes.ResultTx) ([]Info, error) {
var err error
out := make([]txInfo, len(res))
out := make([]Info, len(res))
for i := range res {
out[i], err = formatTxResult(cdc, res[i])
if err != nil {

View File

@ -8,7 +8,7 @@ import (
keys "github.com/cosmos/cosmos-sdk/crypto/keys"
)
// REST request body
// REST request body for signed txs
// TODO does this need to be exposed?
type SignTxBody struct {
Name string `json:"name"`

View File

@ -7,10 +7,11 @@ import (
"os"
"strings"
"path/filepath"
"github.com/cosmos/cosmos-sdk/version"
"github.com/spf13/cobra"
tmversion "github.com/tendermint/tendermint/version"
"path/filepath"
)
var remoteBasecoinPath = "github.com/cosmos/cosmos-sdk/examples/basecoin"

View File

@ -1,8 +1,26 @@
swagger: '2.0'
info:
version: '1.1.0'
title: Light client daemon to interface with Cosmos baseserver via REST
description: Specification for the LCD provided by `gaiacli advanced rest-server`
title: Gaia-Lite (former LCD) to interface with Cosmos BaseServer via REST
description: Specification for Gaia-lite provided by `gaiacli advanced rest-server`
tags:
- name: keys
description: Key management to add or view local private keys
- name: send
description: Create and sign a send tx
- name: stake
description: Stake module API for staking and validation
- name: account
description: Query account balance
- name: query
description: Information about blocks and txs
- name: validator set
description: Check the state of the validator set
- name: node
description: Information of the connected node
- name: version
description: Information about the app version
securityDefinitions:
@ -12,22 +30,28 @@ securityDefinitions:
paths:
/version:
get:
summary: Version of the light client daemon
description: Get the version of the LCD running locally to compare against expected
summary: Version of Gaia-lite
tags:
- version
description: Get the version of gaia-lite running locally to compare against expected
responses:
200:
description: Plaintext version i.e. "v0.5.0"
/node_version:
get:
summary: Version of the connected node
tags:
- node
description: Get the version of the SDK running on the connected node to compare against expected
responses:
200:
description: Plaintext version i.e. "v0.5.0"
/node_info:
get:
description: Only the node info. Block information can be queried via /block/latest
summary: The propertied of the connected node
description: Information about the connected node
summary: The properties of the connected node
tags:
- node
produces:
- application/json
responses:
@ -61,6 +85,8 @@ paths:
/syncing:
get:
summary: Syncing state of node
tags:
- node
description: Get if the node is currently syning with other nodes
responses:
200:
@ -69,6 +95,8 @@ paths:
/keys:
get:
summary: List of accounts stored locally
tags:
- keys
produces:
- application/json
responses:
@ -80,6 +108,8 @@ paths:
$ref: '#/definitions/Account'
post:
summary: Create a new account locally
tags:
- keys
consumes:
- application/json
parameters:
@ -105,6 +135,8 @@ paths:
/keys/seed:
get:
summary: Create a new seed to create a new account with
tags:
- keys
produces:
- application/json
responses:
@ -121,6 +153,8 @@ paths:
type: string
get:
summary: Get a certain locally stored account
tags:
- keys
produces:
- application/json
responses:
@ -132,6 +166,8 @@ paths:
description: Account is not available
put:
summary: Update the password for this account in the KMS
tags:
- keys
consumes:
- application/json
parameters:
@ -157,6 +193,8 @@ paths:
description: Account is not available
delete:
summary: Remove an account
tags:
- keys
consumes:
- application/json
parameters:
@ -216,6 +254,8 @@ paths:
type: string
get:
summary: Get the account balances
tags:
- account
produces:
- application/json
responses:
@ -234,6 +274,8 @@ paths:
type: string
post:
summary: Send coins (build -> sign -> send)
tags:
- send
security:
- kms: []
consumes:
@ -265,6 +307,8 @@ paths:
/blocks/latest:
get:
summary: Get the latest block
tags:
- query
produces:
- application/json
responses:
@ -281,6 +325,8 @@ paths:
type: number
get:
summary: Get a block at a certain height
tags:
- query
produces:
- application/json
responses:
@ -293,6 +339,8 @@ paths:
/validatorsets/latest:
get:
summary: Get the latest validator set
tags:
- validator set
produces:
- application/json
responses:
@ -316,6 +364,8 @@ paths:
type: number
get:
summary: Get a validator set a certain height
tags:
- validator set
produces:
- application/json
responses:
@ -407,6 +457,8 @@ paths:
type: string
get:
summary: Get a Tx by hash
tags:
- query
produces:
- application/json
responses:
@ -416,141 +468,201 @@ paths:
$ref: "#/definitions/Tx"
404:
description: Tx not available for provided hash
# /delegates:
# parameters:
# - in: query
# name: delegator
# description: Query for all delegates a delegator has stake with
# schema:
# $ref: "#/definitions/Address"
# get:
# summary: Get a list of canidates/delegates/validators (optionally filtered by delegator)
# responses:
# 200:
# description: List of delegates, filtered by provided delegator address
# content:
# application/json:
# schema:
# type: array
# items:
# $ref: "#/definitions/Delegate"
# /delegates/bond:
# post:
# summary: Bond atoms (build -> sign -> send)
# security:
# - sign: []
# requestBody:
# content:
# application/json:
# schema:
# type: array
# items:
# type: object
# properties:
# amount:
# $ref: "#/definitions/Coins"
# pub_key:
# $ref: "#/definitions/PubKey"
# responses:
# 202:
# description: Tx was send and will probably be added to the next block
# 400:
# description: The Tx was malformated
# /delegates/unbond:
# post:
# summary: Unbond atoms (build -> sign -> send)
# security:
# - sign: []
# requestBody:
# content:
# application/json:
# schema:
# type: array
# items:
# type: object
# properties:
# amount:
# $ref: "#/definitions/Coins"
# pub_key:
# $ref: "#/definitions/PubKey"
# responses:
# 202:
# description: Tx was send and will probably be added to the next block
# 400:
# description: The Tx was malformated
# /delegates/{pubkey}:
# parameters:
# - in: path
# name: pubkey
# description: Pubkey of a delegate
# required: true
# schema:
# type: string
# example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958
# get:
# summary: Get a certain canidate/delegate/validator
# responses:
# 200:
# description: Delegate for specified pub_key
# content:
# application/json:
# schema:
# $ref: "#/definitions/Delegate"
# 404:
# description: No delegate found for provided pub_key
# /delegates/{pubkey}/bond:
# parameters:
# - in: path
# name: pubkey
# description: Pubkey of a delegate
# required: true
# schema:
# type: string
# example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958
# post:
# summary: Bond atoms (build -> sign -> send)
# security:
# - sign: []
# requestBody:
# content:
# application/json:
# schema:
# type: object
# properties:
# amount:
# $ref: "#/definitions/Coins"
# responses:
# 202:
# description: Tx was send and will probably be added to the next block
# 400:
# description: The Tx was malformated
# /delegates/{pubkey}/unbond:
# parameters:
# - in: path
# name: pubkey
# description: Pubkey of a delegate
# required: true
# schema:
# type: string
# example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958
# post:
# summary: Unbond atoms (build -> sign -> send)
# security:
# - sign: []
# requestBody:
# content:
# application/json:
# schema:
# type: object
# properties:
# amount:
# $ref: "#/definitions/Coins"
# responses:
# 202:
# description: Tx was send and will probably be added to the next block
# 400:
# description: The Tx was malformated
# ================== Staking Module # ==================
# TODO create D
/stake/delegators/{delegatorAddr}:
parameters:
- in: path
name: delegatorAddr
description: AccAddress of Delegator
required: true
type: string
get:
summary: Get all delegations (delegation, undelegation) from a delegator
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
404:
description: Not Found
500:
description: Internal Server Error
/stake/delegators/{delegatorAddr}/txs:
parameters:
- in: path
name: delegatorAddr
description: AccAddress of Delegator
required: true
type: string
get:
summary: Get all staking txs (i.e msgs) from a delegator
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
schema:
$ref: "#/definitions/Tx"
404:
description: Not Found
500:
description: Internal Server Error
/stake/delegators/{delegatorAddr}/delegations:
parameters:
- in: path
name: delegatorAddr
description: Bech32 AccAddress of Delegator
required: true
type: string
post:
summary: Submit delegation
parameters:
- in: body
name: delegation
description: The password of the account to remove from the KMS
schema:
type: object
properties:
name:
type: string
password:
type: string
account_number:
type: number
delegations:
type: array
items:
type: string
begin_unbondings:
type: array
items:
type: string
complete_unbondings:
type: array
items:
type: string
begin_redelegates:
type: array
items:
type: string
complete_redelegates:
type: array
items:
type: string
chain_id:
type: string
gas:
type: number
sequence:
type: number
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
schema:
$ref: "#/definitions/Tx"
404:
description: Not Found
500:
description: Internal Server Error
/stake/delegators/{delegatorAddr}/delegations/{validatorAddr}:
parameters:
- in: path
name: delegatorAddr
description: Bech32 AccAddress of Delegator
required: true
type: string
- in: path
name: validatorAddr
description: Bech32 ValAddress of Delegator
required: true
type: string
get:
summary: Query the current delegation status between a delegator and a validator
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
404:
description: Not Found
/stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}:
parameters:
- in: path
name: delegatorAddr
description: Bech32 AccAddress of Delegator
required: true
type: string
- in: path
name: validatorAddr
description: Bech32 ValAddress of Delegator
required: true
type: string
get:
summary: Query all unbonding delegations between a delegator and a validator
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
404:
description: Not Found
500:
description: Internal Server Error
/stake/validators:
get:
summary: Get all validator candidates
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
500:
description: Internal Server Error
/stake/validators/{validatorAddr}:
parameters:
- in: path
name: validatorAddr
description: Bech32 ValAddress of Delegator
required: true
type: string
get:
summary: Query the information from a single validator
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
404:
description: Not Found
500:
description: Internal Server Error
# TODO Add staking definitions
definitions:
Address:
type: string

View File

@ -442,3 +442,219 @@ Returns on failure:
"result":{}
}
```
## ICS21 - StakingAPI
The StakingAPI exposes all functionality needed for validation and delegation in Proof-of-Stake.
### /stake/delegators/{delegatorAddr} - GET
url: /stake/delegators/{delegatorAddr}
Functionality: Get all delegations (delegation, undelegation) from a delegator.
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result": {
"atom":1000,
"photon":500,
"ether":20
}
}
```
Returns on error:
```json
{
"rest api":"2.0",
"code":500,
"error":"Could not find any balance for the specified account.",
"result":{}
}
```
### /stake/delegators/{delegatorAddr}/txs - GET
url: /stake/delegators/{delegatorAddr}/txs
Functionality: Get all staking txs (i.e msgs) from a delegator.
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result":{
"transaction":"TODO"
}
}
```
Returns on failure:
```json
{
"rest api":"2.0",
"code":500,
"error":"Could not create the transaction.",
"result":{}
}
```
### /stake/delegators/{delegatorAddr}/delegations - POST
url: /stake/delegators/{delegatorAddr}/delegations
Functionality: Submit a delegation.
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result":{
"transaction":"TODO"
}
}
```
Returns on failure:
```json
{
"rest api":"2.0",
"code":500,
"error":"Could not create the transaction.",
"result":{}
}
```
### /stake/delegators/{delegatorAddr}/delegations/{validatorAddr} - GET
url: /stake/delegators/{delegatorAddr}/delegations/{validatorAddr}
Functionality: Query the current delegation status between a delegator and a validator.
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result":{
"transaction":"TODO"
}
}
```
Returns on failure:
```json
{
"rest api":"2.0",
"code":500,
"error":"Could not create the transaction.",
"result":{}
}
```
### /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} - GET
url: /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}
Functionality: Query all unbonding delegations between a delegator and a validator.
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result":{
"transaction":"TODO"
}
}
```
Returns on failure:
```json
{
"rest api":"2.0",
"code":500,
"error":"Could not create the transaction.",
"result":{}
}
```
### /stake/validators - GET
url: /stake/validators
Functionality: Get all validator candidates.
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result":{
"transaction":"TODO"
}
}
```
Returns on failure:
```json
{
"rest api":"2.0",
"code":500,
"error":"Could not create the transaction.",
"result":{}
}
```
### /stake/validators/{validatorAddr} - GET
url: /stake/validators/{validatorAddr}
Functionality: Query the information from a single validator.
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result":{
"transaction":"TODO"
}
}
```
Returns on failure:
```json
{
"rest api":"2.0",
"code":500,
"error":"Could not create the transaction.",
"result":{}
}
```

View File

@ -19,7 +19,7 @@ LCD will be used in the Cosmos Hub, the first Hub in the Cosmos network.
1. [**Overview**](##Overview)
2. [**Get Started**](getting_started.md)
3. [**API**](api.md)
4. [**Specifications**](hspecification.md)
4. [**Specifications**](specification.md)
## Overview
@ -67,7 +67,7 @@ A full node of ABCI is different from its light client in the following ways:
| Provide APIs|All cosmos APIs|Modular APIs|Full node supports all cosmos APIs. LCD provides modular APIs according to users' configuration|
| Secuity level| High|High|Full node will verify all transactions and blocks by itself. LCD can't do this, but it can query any data from other full nodes and verify the data independently. So both full node and LCD don't need to trust any third nodes, they all can achieve high security|
According to the above table, LCD can meet all users' functionality and security requirements, but
According to the above table, LCD can meet all users' functionality and security requirements, but
only requires little resource on bandwidth, computing, storage and power.
## How does LCD achieve high security?

View File

@ -14,7 +14,7 @@ tree is the AppHash which will be included in block header.
![Simple Merkle Tree](pics/simpleMerkleTree.png)
As we have discussed in [LCD trust-propagation](https://github.com/irisnet/cosmos-sdk/tree/bianjie/lcd_spec/docs/spec/lcd#trust-propagation),
As we have discussed in [LCD trust-propagation](https://github.com/irisnet/cosmos-sdk/tree/bianjie/lcd_spec/docs/spec/lcd#trust-propagation),
the AppHash can be verified by checking voting power against a trusted validator set. Here we just
need to build proof from ABCI state to AppHash. The proof contains two parts:
@ -212,7 +212,7 @@ For instance:
To improve LCD reliability and TPS, we recommend to connect LCD to more than one fullnode. But the
complexity will increase a lot. So load balancing module will be imported as the adapter. Please
refer to this link for detailed description: [load balancing](https://github.com/irisnet/cosmos-sdk/blob/bianjie/lcd_spec/docs/spec/lcd/loadbalance.md)
refer to this link for detailed description: [load balancer](load_balancer.md)
## ICS1 (KeyAPI)
@ -305,14 +305,44 @@ return KeyOutput{
## ICS20 (TokenAPI)
### [/bank/balance/{account}](api.md#balanceaccount---get)
### [/bank/balance/{account}](api.md#bankbalanceaccount---get)
1. Decode the address from bech32 to hex.
2. Send a query request to a full node. Ask for proof if required by Gaia Light.
3. Verify the proof against the root of trust.
### [/bank/create_transfer](api.md#create_transfer---post)
### [/bank/create_transfer](api.md#bankcreate_transfer---post)
1. Check the parameters.
2. Build the transaction with the specified parameters.
3. Serialise the transaction and return the JSON encoded sign bytes.
## ICS21 (StakingAPI)
### [/stake/delegators/{delegatorAddr}](api.md#stakedelegatorsdelegatorAddr---get)
TODO
### [/stake/delegators/{delegatorAddr}/txs](api.md#stakedelegatorsdelegatorAddrtxs---get)
TODO
### [/stake/delegators/{delegatorAddr}/delegations](api.md#stakedelegatorsdelegatorAddrdelegations---post)
TODO
### [/stake/delegators/{delegatorAddr}/delegations/{validatorAddr}](api.md#stakedelegatorsdelegatorAddrdelegationsvalidatorAddr---get)
TODO
### [/stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}](api.md#stakedelegatorsdelegatorAddrunbonding_delegationsvalidatorAddr---get)
TODO
### [/stake/validators](api.md#stakevalidators---get)
TODO
### [/stake/validators/{validatorAddr}](api.md#stakevalidatorsvalidatorAddr---get)
TODO

View File

@ -3,11 +3,14 @@ package rest
import (
"fmt"
"net/http"
"strings"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/x/stake/tags"
"github.com/cosmos/cosmos-sdk/x/stake/types"
"github.com/gorilla/mux"
@ -16,33 +19,222 @@ import (
const storeName = "stake"
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec) {
// GET /stake/delegators/{delegatorAddr} // Get all delegations (delegation, undelegation and redelegation) from a delegator
r.HandleFunc(
"/stake/{delegator}/delegation/{validator}",
"/stake/delegators/{delegatorAddr}",
delegatorHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/delegators/{delegatorAddr}/txs?type=<bond/unbond/redelegate> // Get all staking txs (i.e msgs) from a delegator
r.HandleFunc(
"/stake/delegators/{delegatorAddr}/txs",
delegatorTxsHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/delegators/{delegatorAddr}/delegations/{validatorAddr} // Query a delegation between a delegator and a validator
r.HandleFunc(
"/stake/delegators/{delegatorAddr}/delegations/{validatorAddr}",
delegationHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} // Query all unbonding_delegations between a delegator and a validator
r.HandleFunc(
"/stake/{delegator}/ubd/{validator}",
ubdHandlerFn(cliCtx, cdc),
).Methods("GET")
r.HandleFunc(
"/stake/{delegator}/red/{validator_src}/{validator_dst}",
redHandlerFn(cliCtx, cdc),
"/stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}",
unbondingDelegationsHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/validators/
r.HandleFunc(
"/stake/validators",
validatorsHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/validators/{addr}
r.HandleFunc(
"/stake/validators/{addr}",
validatorHandlerFn(cliCtx, cdc),
).Methods("GET")
}
// http request handler to query a delegation
func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
// already resolve the rational shares to not handle this in the client
// defines a delegation without type Rat for shares
type DelegationWithoutRat struct {
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
ValidatorAddr sdk.AccAddress `json:"validator_addr"`
Shares string `json:"shares"`
Height int64 `json:"height"`
}
// aggregation of all delegations, unbondings and redelegations
type DelegationSummary struct {
Delegations []DelegationWithoutRat `json:"delegations"`
UnbondingDelegations []stake.UnbondingDelegation `json:"unbonding_delegations"`
Redelegations []stake.Redelegation `json:"redelegations"`
}
// HTTP request handler to query a delegator delegations
func delegatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var validatorAddr sdk.AccAddress
var delegationSummary = DelegationSummary{}
// read parameters
vars := mux.Vars(r)
bech32delegator := vars["delegatorAddr"]
delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
// Get all validators using key
validators, statusCode, errMsg, err := getBech32Validators(storeName, cliCtx, cdc)
if err != nil {
w.WriteHeader(statusCode)
w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error())))
return
}
for _, validator := range validators {
validatorAddr = validator.Owner
// Delegations
delegations, statusCode, errMsg, err := getDelegatorDelegations(cliCtx, cdc, delegatorAddr, validatorAddr)
if err != nil {
w.WriteHeader(statusCode)
w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error())))
return
}
if statusCode != http.StatusNoContent {
delegationSummary.Delegations = append(delegationSummary.Delegations, delegations)
}
// Undelegations
unbondingDelegation, statusCode, errMsg, err := getDelegatorUndelegations(cliCtx, cdc, delegatorAddr, validatorAddr)
if err != nil {
w.WriteHeader(statusCode)
w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error())))
return
}
if statusCode != http.StatusNoContent {
delegationSummary.UnbondingDelegations = append(delegationSummary.UnbondingDelegations, unbondingDelegation)
}
// Redelegations
// only querying redelegations to a validator as this should give us already all relegations
// if we also would put in redelegations from, we would have every redelegation double
redelegations, statusCode, errMsg, err := getDelegatorRedelegations(cliCtx, cdc, delegatorAddr, validatorAddr)
if err != nil {
w.WriteHeader(statusCode)
w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error())))
return
}
if statusCode != http.StatusNoContent {
delegationSummary.Redelegations = append(delegationSummary.Redelegations, redelegations)
}
output, err := cdc.MarshalJSON(delegationSummary)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
// success
w.Write(output) // write
}
}
}
// nolint gocyclo
// HTTP request handler to query all staking txs (msgs) from a delegator
func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var output []byte
var typesQuerySlice []string
vars := mux.Vars(r)
delegatorAddr := vars["delegatorAddr"]
_, err := sdk.AccAddressFromBech32(delegatorAddr)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
node, err := cliCtx.GetNode()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Couldn't get current Node information. Error: %s", err.Error())))
return
}
// Get values from query
typesQuery := r.URL.Query().Get("type")
trimmedQuery := strings.TrimSpace(typesQuery)
if len(trimmedQuery) != 0 {
typesQuerySlice = strings.Split(trimmedQuery, " ")
}
noQuery := len(typesQuerySlice) == 0
isBondTx := contains(typesQuerySlice, "bond")
isUnbondTx := contains(typesQuerySlice, "unbond")
isRedTx := contains(typesQuerySlice, "redelegate")
var txs = []tx.Info{}
var actions []string
switch {
case isBondTx:
actions = append(actions, string(tags.ActionDelegate))
case isUnbondTx:
actions = append(actions, string(tags.ActionBeginUnbonding))
actions = append(actions, string(tags.ActionCompleteUnbonding))
case isRedTx:
actions = append(actions, string(tags.ActionBeginRedelegation))
actions = append(actions, string(tags.ActionCompleteRedelegation))
case noQuery:
actions = append(actions, string(tags.ActionDelegate))
actions = append(actions, string(tags.ActionBeginUnbonding))
actions = append(actions, string(tags.ActionCompleteUnbonding))
actions = append(actions, string(tags.ActionBeginRedelegation))
actions = append(actions, string(tags.ActionCompleteRedelegation))
default:
w.WriteHeader(http.StatusNoContent)
return
}
for _, action := range actions {
foundTxs, errQuery := queryTxs(node, cdc, action, delegatorAddr)
if errQuery != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("error querying transactions. Error: %s", errQuery.Error())))
}
txs = append(txs, foundTxs...)
}
// success
output, err = cdc.MarshalJSON(txs)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
w.Write(output) // write
}
}
// HTTP request handler to query an unbonding-delegation
func unbondingDelegationsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bech32delegator := vars["delegator"]
bech32validator := vars["validator"]
bech32delegator := vars["delegatorAddr"]
bech32validator := vars["validatorAddr"]
delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator)
if err != nil {
@ -57,8 +249,68 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle
w.Write([]byte(err.Error()))
return
}
validatorAddrAcc := sdk.AccAddress(validatorAddr)
key := stake.GetDelegationKey(delegatorAddr, validatorAddr)
key := stake.GetUBDKey(delegatorAddr, validatorAddrAcc)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't query unbonding-delegation. Error: %s", err.Error())))
return
}
// the query will return empty if there is no data for this record
if len(res) == 0 {
w.WriteHeader(http.StatusNoContent)
return
}
ubd, err := types.UnmarshalUBD(cdc, key, res)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't unmarshall unbonding-delegation. Error: %s", err.Error())))
return
}
// unbondings will be a list in the future but is not yet, but we want to keep the API consistent
ubdArray := []stake.UnbondingDelegation{ubd}
output, err := cdc.MarshalJSON(ubdArray)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't marshall unbonding-delegation. Error: %s", err.Error())))
return
}
w.Write(output)
}
}
// HTTP request handler to query a bonded validator
func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// read parameters
vars := mux.Vars(r)
bech32delegator := vars["delegatorAddr"]
bech32validator := vars["validatorAddr"]
delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
validatorAddr, err := sdk.AccAddressFromBech32(bech32validator)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
validatorAddrAcc := sdk.AccAddress(validatorAddr)
key := stake.GetDelegationKey(delegatorAddr, validatorAddrAcc)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
@ -80,7 +332,14 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle
return
}
output, err := cdc.MarshalJSON(delegation)
outputDelegation := DelegationWithoutRat{
DelegatorAddr: delegation.DelegatorAddr,
ValidatorAddr: delegation.ValidatorAddr,
Height: delegation.Height,
Shares: delegation.Shares.FloatString(),
}
output, err := cdc.MarshalJSON(outputDelegation)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
@ -91,68 +350,16 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle
}
}
// http request handler to query an unbonding-delegation
func ubdHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
// HTTP request handler to query all delegator bonded validators
func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bech32delegator := vars["delegator"]
bech32validator := vars["validator"]
delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
var validatorAccAddr sdk.AccAddress
var bondedValidators []types.BechValidator
validatorAddr, err := sdk.AccAddressFromBech32(bech32validator)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
key := stake.GetUBDKey(delegatorAddr, validatorAddr)
res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't query unbonding-delegation. Error: %s", err.Error())))
return
}
// the query will return empty if there is no data for this record
if len(res) == 0 {
w.WriteHeader(http.StatusNoContent)
return
}
ubd, err := types.UnmarshalUBD(cdc, key, res)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't query unbonding-delegation. Error: %s", err.Error())))
return
}
output, err := cdc.MarshalJSON(ubd)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
}
// http request handler to query an redelegation
func redHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// read parameters
vars := mux.Vars(r)
bech32delegator := vars["delegator"]
bech32validatorSrc := vars["validator_src"]
bech32validatorDst := vars["validator_dst"]
bech32delegator := vars["delegatorAddr"]
delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator)
if err != nil {
@ -161,49 +368,86 @@ func redHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return
}
validatorSrcAddr, err := sdk.AccAddressFromBech32(bech32validatorSrc)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
validatorDstAddr, err := sdk.AccAddressFromBech32(bech32validatorDst)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
key := stake.GetREDKey(delegatorAddr, validatorSrcAddr, validatorDstAddr)
res, err := cliCtx.QueryStore(key, storeName)
// Get all validators using key
kvs, err := cliCtx.QuerySubspace(stake.ValidatorsKey, storeName)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't query redelegation. Error: %s", err.Error())))
w.Write([]byte(fmt.Sprintf("couldn't query validators. Error: %s", err.Error())))
return
}
// the query will return empty if there is no data for this record
if len(res) == 0 {
} else if len(kvs) == 0 {
// the query will return empty if there are no validators
w.WriteHeader(http.StatusNoContent)
return
}
red, err := types.UnmarshalRED(cdc, key, res)
validators, err := getValidators(kvs, cdc)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't query unbonding-delegation. Error: %s", err.Error())))
w.Write([]byte(fmt.Sprintf("Error: %s", err.Error())))
return
}
output, err := cdc.MarshalJSON(red)
for _, validator := range validators {
// get all transactions from the delegator to val and append
validatorAccAddr = validator.Owner
validator, statusCode, errMsg, errRes := getDelegatorValidator(cliCtx, cdc, delegatorAddr, validatorAccAddr)
if errRes != nil {
w.WriteHeader(statusCode)
w.Write([]byte(fmt.Sprintf("%s%s", errMsg, errRes.Error())))
return
} else if statusCode == http.StatusNoContent {
continue
}
bondedValidators = append(bondedValidators, validator)
}
// success
output, err := cdc.MarshalJSON(bondedValidators)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
w.Write(output) // write
}
}
// HTTP request handler to get information from a currently bonded validator
func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// read parameters
var output []byte
vars := mux.Vars(r)
bech32delegator := vars["delegatorAddr"]
bech32validator := vars["validatorAddr"]
delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator)
validatorAccAddr, err := sdk.AccAddressFromBech32(bech32validator)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Error: %s", err.Error())))
return
}
// Check if there if the delegator is bonded or redelegated to the validator
validator, statusCode, errMsg, err := getDelegatorValidator(cliCtx, cdc, delegatorAddr, validatorAccAddr)
if err != nil {
w.WriteHeader(statusCode)
w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error())))
return
} else if statusCode == http.StatusNoContent {
w.WriteHeader(statusCode)
return
}
// success
output, err = cdc.MarshalJSON(validator)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
w.Write(output)
}
}
@ -225,25 +469,11 @@ func validatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle
return
}
// parse out the validators
validators := make([]types.BechValidator, len(kvs))
for i, kv := range kvs {
addr := kv.Key[1:]
validator, err := types.UnmarshalValidator(cdc, addr, kv.Value)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't query unbonding-delegation. Error: %s", err.Error())))
return
}
bech32Validator, err := validator.Bech32Validator()
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
validators[i] = bech32Validator
validators, err := getValidators(kvs, cdc)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Error: %s", err.Error())))
return
}
output, err := cdc.MarshalJSON(validators)
@ -256,3 +486,47 @@ func validatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle
w.Write(output)
}
}
// HTTP request handler to query the validator information from a given validator address
func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var output []byte
// read parameters
vars := mux.Vars(r)
bech32validatorAddr := vars["addr"]
valAddress, err := sdk.AccAddressFromBech32(bech32validatorAddr)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Error: %s", err.Error())))
return
}
kvs, err := cliCtx.QuerySubspace(stake.ValidatorsKey, storeName)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Error: %s", err.Error())))
return
}
validator, err := getValidator(valAddress, kvs, cdc)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("couldn't query validator. Error: %s", err.Error())))
return
}
output, err = cdc.MarshalJSON(validator)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Error: %s", err.Error())))
return
}
if output == nil {
w.WriteHeader(http.StatusNoContent)
return
}
w.Write(output)
}
}

View File

@ -10,7 +10,7 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
authcliCtx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/x/stake/types"
@ -21,8 +21,8 @@ import (
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
r.HandleFunc(
"/stake/delegations",
editDelegationsRequestHandlerFn(cdc, kb, cliCtx),
"/stake/delegators/{delegatorAddr}/delegations",
delegationsRequestHandlerFn(cdc, kb, cliCtx),
).Methods("POST")
}
@ -52,7 +52,7 @@ type msgCompleteUnbondingInput struct {
ValidatorAddr string `json:"validator_addr"` // in bech32
}
// request body for edit delegations
// the request body for edit delegations
type EditDelegationsBody struct {
LocalAccountName string `json:"name"`
Password string `json:"password"`
@ -69,7 +69,8 @@ type EditDelegationsBody struct {
// nolint: gocyclo
// TODO: Split this up into several smaller functions, and remove the above nolint
func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc {
// TODO: use sdk.ValAddress instead of sdk.AccAddress for validators in messages
func delegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var m EditDelegationsBody
@ -152,7 +153,6 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx co
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
return
}
validatorDstAddr, err := sdk.AccAddressFromBech32(msg.ValidatorDstAddr)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
@ -191,7 +191,6 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx co
w.Write([]byte(fmt.Sprintf("Couldn't decode validator. Error: %s", err.Error())))
return
}
validatorDstAddr, err := sdk.AccAddressFromBech32(msg.ValidatorDstAddr)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
@ -280,7 +279,7 @@ func editDelegationsRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx co
i++
}
txCtx := authctx.TxContext{
txCtx := authcliCtx.TxContext{
Codec: cdc,
ChainID: m.ChainID,
Gas: m.Gas,

View File

@ -0,0 +1,228 @@
package rest
import (
"bytes"
"fmt"
"net/http"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/x/stake/tags"
"github.com/cosmos/cosmos-sdk/x/stake/types"
"github.com/pkg/errors"
rpcclient "github.com/tendermint/tendermint/rpc/client"
)
// contains checks if the a given query contains one of the tx types
func contains(stringSlice []string, txType string) bool {
for _, word := range stringSlice {
if word == txType {
return true
}
}
return false
}
func getDelegatorValidator(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAccAddr sdk.AccAddress) (
validator types.BechValidator, httpStatusCode int, errMsg string, err error) {
// check if the delegator is bonded or redelegated to the validator
keyDel := stake.GetDelegationKey(delegatorAddr, validatorAccAddr)
res, err := cliCtx.QueryStore(keyDel, storeName)
if err != nil {
return types.BechValidator{}, http.StatusInternalServerError, "couldn't query delegation. Error: ", err
}
if len(res) == 0 {
return types.BechValidator{}, http.StatusNoContent, "", nil
}
kvs, err := cliCtx.QuerySubspace(stake.ValidatorsKey, storeName)
if err != nil {
return types.BechValidator{}, http.StatusInternalServerError, "Error: ", err
}
if len(kvs) == 0 {
// the query will return empty if there are no delegations
return types.BechValidator{}, http.StatusNoContent, "", nil
}
validator, errVal := getValidatorFromAccAdrr(validatorAccAddr, kvs, cdc)
if errVal != nil {
return types.BechValidator{}, http.StatusInternalServerError, "Couldn't get info from validator. Error: ", errVal
}
return validator, http.StatusOK, "", nil
}
func getDelegatorDelegations(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) (
outputDelegation DelegationWithoutRat, httpStatusCode int, errMsg string, err error) {
delegationKey := stake.GetDelegationKey(delegatorAddr, validatorAddr)
marshalledDelegation, err := cliCtx.QueryStore(delegationKey, storeName)
if err != nil {
return DelegationWithoutRat{}, http.StatusInternalServerError, "couldn't query delegation. Error: ", err
}
// the query will return empty if there is no data for this record
if len(marshalledDelegation) == 0 {
return DelegationWithoutRat{}, http.StatusNoContent, "", nil
}
delegation, err := types.UnmarshalDelegation(cdc, delegationKey, marshalledDelegation)
if err != nil {
return DelegationWithoutRat{}, http.StatusInternalServerError, "couldn't unmarshall delegation. Error: ", err
}
outputDelegation = DelegationWithoutRat{
DelegatorAddr: delegation.DelegatorAddr,
ValidatorAddr: delegation.ValidatorAddr,
Height: delegation.Height,
Shares: delegation.Shares.FloatString(),
}
return outputDelegation, http.StatusOK, "", nil
}
func getDelegatorUndelegations(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) (
unbonds types.UnbondingDelegation, httpStatusCode int, errMsg string, err error) {
undelegationKey := stake.GetUBDKey(delegatorAddr, validatorAddr)
marshalledUnbondingDelegation, err := cliCtx.QueryStore(undelegationKey, storeName)
if err != nil {
return types.UnbondingDelegation{}, http.StatusInternalServerError, "couldn't query unbonding-delegation. Error: ", err
}
// the query will return empty if there is no data for this record
if len(marshalledUnbondingDelegation) == 0 {
return types.UnbondingDelegation{}, http.StatusNoContent, "", nil
}
unbondingDelegation, err := types.UnmarshalUBD(cdc, undelegationKey, marshalledUnbondingDelegation)
if err != nil {
return types.UnbondingDelegation{}, http.StatusInternalServerError, "couldn't unmarshall unbonding-delegation. Error: ", err
}
return unbondingDelegation, http.StatusOK, "", nil
}
func getDelegatorRedelegations(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) (
regelegations types.Redelegation, httpStatusCode int, errMsg string, err error) {
keyRedelegateTo := stake.GetREDsByDelToValDstIndexKey(delegatorAddr, validatorAddr)
marshalledRedelegations, err := cliCtx.QueryStore(keyRedelegateTo, storeName)
if err != nil {
return types.Redelegation{}, http.StatusInternalServerError, "couldn't query redelegation. Error: ", err
}
if len(marshalledRedelegations) == 0 {
return types.Redelegation{}, http.StatusNoContent, "", nil
}
redelegations, err := types.UnmarshalRED(cdc, keyRedelegateTo, marshalledRedelegations)
if err != nil {
return types.Redelegation{}, http.StatusInternalServerError, "couldn't unmarshall redelegations. Error: ", err
}
return redelegations, http.StatusOK, "", nil
}
// queries staking txs
func queryTxs(node rpcclient.Client, cdc *wire.Codec, tag string, delegatorAddr string) ([]tx.Info, error) {
page := 0
perPage := 100
prove := false
query := fmt.Sprintf("%s='%s' AND %s='%s'", tags.Action, tag, tags.Delegator, delegatorAddr)
res, err := node.TxSearch(query, prove, page, perPage)
if err != nil {
return nil, err
}
return tx.FormatTxResults(cdc, res.Txs)
}
// gets all validators
func getValidators(validatorKVs []sdk.KVPair, cdc *wire.Codec) ([]types.BechValidator, error) {
validators := make([]types.BechValidator, len(validatorKVs))
for i, kv := range validatorKVs {
addr := kv.Key[1:]
validator, err := types.UnmarshalValidator(cdc, addr, kv.Value)
if err != nil {
return nil, err
}
bech32Validator, err := validator.Bech32Validator()
if err != nil {
return nil, err
}
validators[i] = bech32Validator
}
return validators, nil
}
// gets a validator given a ValAddress
func getValidator(address sdk.AccAddress, validatorKVs []sdk.KVPair, cdc *wire.Codec) (stake.BechValidator, error) {
// parse out the validators
for _, kv := range validatorKVs {
addr := kv.Key[1:]
validator, err := types.UnmarshalValidator(cdc, addr, kv.Value)
if err != nil {
return stake.BechValidator{}, err
}
ownerAddress := validator.PubKey.Address()
if bytes.Equal(ownerAddress.Bytes(), address.Bytes()) {
bech32Validator, err := validator.Bech32Validator()
if err != nil {
return stake.BechValidator{}, err
}
return bech32Validator, nil
}
}
return stake.BechValidator{}, errors.Errorf("Couldn't find validator")
}
// gets a validator given an AccAddress
func getValidatorFromAccAdrr(address sdk.AccAddress, validatorKVs []sdk.KVPair, cdc *wire.Codec) (stake.BechValidator, error) {
// parse out the validators
for _, kv := range validatorKVs {
addr := kv.Key[1:]
validator, err := types.UnmarshalValidator(cdc, addr, kv.Value)
if err != nil {
return stake.BechValidator{}, err
}
ownerAddress := validator.PubKey.Address()
if bytes.Equal(ownerAddress.Bytes(), address.Bytes()) {
bech32Validator, err := validator.Bech32Validator()
if err != nil {
return stake.BechValidator{}, err
}
return bech32Validator, nil
}
}
return stake.BechValidator{}, errors.Errorf("Couldn't find validator")
}
// gets all Bech32 validators from a key
func getBech32Validators(storeName string, cliCtx context.CLIContext, cdc *wire.Codec) (
validators []types.BechValidator, httpStatusCode int, errMsg string, err error) {
// Get all validators using key
kvs, err := cliCtx.QuerySubspace(stake.ValidatorsKey, storeName)
if err != nil {
return nil, http.StatusInternalServerError, "couldn't query validators. Error: ", err
}
// the query will return empty if there are no validators
if len(kvs) == 0 {
return nil, http.StatusNoContent, "", nil
}
validators, err = getValidators(kvs, cdc)
if err != nil {
return nil, http.StatusInternalServerError, "Error: ", err
}
return validators, http.StatusOK, "", nil
}

View File

@ -34,19 +34,19 @@ var (
const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch
// get the key for the validator with address.
// gets the key for the validator with address
// VALUE: stake/types.Validator
func GetValidatorKey(ownerAddr sdk.AccAddress) []byte {
return append(ValidatorsKey, ownerAddr.Bytes()...)
}
// get the key for the validator with pubkey.
// gets the key for the validator with pubkey
// VALUE: validator owner address ([]byte)
func GetValidatorByPubKeyIndexKey(pubkey crypto.PubKey) []byte {
return append(ValidatorsByPubKeyIndexKey, pubkey.Bytes()...)
}
// get the key for the current validator group
// gets the key for the current validator group
// VALUE: none (key rearrangement with GetValKeyFromValBondedIndexKey)
func GetValidatorsBondedIndexKey(ownerAddr sdk.AccAddress) []byte {
return append(ValidatorsBondedIndexKey, ownerAddr.Bytes()...)
@ -57,8 +57,9 @@ func GetAddressFromValBondedIndexKey(IndexKey []byte) []byte {
return IndexKey[1:] // remove prefix bytes
}
// get the validator by power index. power index is the key used in the power-store,
// and represents the relative power ranking of the validator.
// get the validator by power index.
// Power index is the key used in the power-store, and represents the relative
// power ranking of the validator.
// VALUE: validator owner address ([]byte)
func GetValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []byte {
// NOTE the address doesn't need to be stored because counter bytes must always be different
@ -93,29 +94,29 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte {
counterBytes...)
}
// get the key for the accumulated update validators.
// get the key for the accumulated update validators
// VALUE: abci.Validator
// note records using these keys should never persist between blocks
func GetTendermintUpdatesKey(ownerAddr sdk.AccAddress) []byte {
return append(TendermintUpdatesKey, ownerAddr.Bytes()...)
}
//________________________________________________________________________________
//______________________________________________________________________________
// get the key for delegator bond with validator.
// gets the key for delegator bond with validator
// VALUE: stake/types.Delegation
func GetDelegationKey(delegatorAddr, validatorAddr sdk.AccAddress) []byte {
return append(GetDelegationsKey(delegatorAddr), validatorAddr.Bytes()...)
}
// get the prefix for a delegator for all validators
// gets the prefix for a delegator for all validators
func GetDelegationsKey(delegatorAddr sdk.AccAddress) []byte {
return append(DelegationKey, delegatorAddr.Bytes()...)
}
//________________________________________________________________________________
//______________________________________________________________________________
// get the key for an unbonding delegation by delegator and validator addr.
// gets the key for an unbonding delegation by delegator and validator addr
// VALUE: stake/types.UnbondingDelegation
func GetUBDKey(delegatorAddr, validatorAddr sdk.AccAddress) []byte {
return append(
@ -123,13 +124,13 @@ func GetUBDKey(delegatorAddr, validatorAddr sdk.AccAddress) []byte {
validatorAddr.Bytes()...)
}
// get the index-key for an unbonding delegation, stored by validator-index
// gets the index-key for an unbonding delegation, stored by validator-index
// VALUE: none (key rearrangement used)
func GetUBDByValIndexKey(delegatorAddr, validatorAddr sdk.AccAddress) []byte {
return append(GetUBDsByValIndexKey(validatorAddr), delegatorAddr.Bytes()...)
}
// rearrange the ValIndexKey to get the UBDKey
// rearranges the ValIndexKey to get the UBDKey
func GetUBDKeyFromValIndexKey(IndexKey []byte) []byte {
addrs := IndexKey[1:] // remove prefix bytes
if len(addrs) != 2*sdk.AddrLen {
@ -142,19 +143,19 @@ func GetUBDKeyFromValIndexKey(IndexKey []byte) []byte {
//______________
// get the prefix for all unbonding delegations from a delegator
// gets the prefix for all unbonding delegations from a delegator
func GetUBDsKey(delegatorAddr sdk.AccAddress) []byte {
return append(UnbondingDelegationKey, delegatorAddr.Bytes()...)
}
// get the prefix keyspace for the indexes of unbonding delegations for a validator
// gets the prefix keyspace for the indexes of unbonding delegations for a validator
func GetUBDsByValIndexKey(validatorAddr sdk.AccAddress) []byte {
return append(UnbondingDelegationByValIndexKey, validatorAddr.Bytes()...)
}
//________________________________________________________________________________
// get the key for a redelegation
// gets the key for a redelegation
// VALUE: stake/types.RedelegationKey
func GetREDKey(delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) []byte {
return append(append(
@ -163,7 +164,7 @@ func GetREDKey(delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress)
validatorDstAddr.Bytes()...)
}
// get the index-key for a redelegation, stored by source-validator-index
// gets the index-key for a redelegation, stored by source-validator-index
// VALUE: none (key rearrangement used)
func GetREDByValSrcIndexKey(delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) []byte {
return append(append(
@ -172,7 +173,7 @@ func GetREDByValSrcIndexKey(delegatorAddr, validatorSrcAddr, validatorDstAddr sd
validatorDstAddr.Bytes()...)
}
// get the index-key for a redelegation, stored by destination-validator-index
// gets the index-key for a redelegation, stored by destination-validator-index
// VALUE: none (key rearrangement used)
func GetREDByValDstIndexKey(delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) []byte {
return append(append(
@ -181,7 +182,7 @@ func GetREDByValDstIndexKey(delegatorAddr, validatorSrcAddr, validatorDstAddr sd
validatorSrcAddr.Bytes()...)
}
// rearrange the ValSrcIndexKey to get the REDKey
// rearranges the ValSrcIndexKey to get the REDKey
func GetREDKeyFromValSrcIndexKey(IndexKey []byte) []byte {
addrs := IndexKey[1:] // remove prefix bytes
if len(addrs) != 3*sdk.AddrLen {
@ -194,7 +195,7 @@ func GetREDKeyFromValSrcIndexKey(IndexKey []byte) []byte {
return GetREDKey(delAddr, valSrcAddr, valDstAddr)
}
// rearrange the ValDstIndexKey to get the REDKey
// rearranges the ValDstIndexKey to get the REDKey
func GetREDKeyFromValDstIndexKey(IndexKey []byte) []byte {
addrs := IndexKey[1:] // remove prefix bytes
if len(addrs) != 3*sdk.AddrLen {
@ -208,22 +209,22 @@ func GetREDKeyFromValDstIndexKey(IndexKey []byte) []byte {
//______________
// get the prefix keyspace for redelegations from a delegator
// gets the prefix keyspace for redelegations from a delegator
func GetREDsKey(delegatorAddr sdk.AccAddress) []byte {
return append(RedelegationKey, delegatorAddr.Bytes()...)
}
// get the prefix keyspace for all redelegations redelegating away from a source validator
// gets the prefix keyspace for all redelegations redelegating away from a source validator
func GetREDsFromValSrcIndexKey(validatorSrcAddr sdk.AccAddress) []byte {
return append(RedelegationByValSrcIndexKey, validatorSrcAddr.Bytes()...)
}
// get the prefix keyspace for all redelegations redelegating towards a destination validator
// gets the prefix keyspace for all redelegations redelegating towards a destination validator
func GetREDsToValDstIndexKey(validatorDstAddr sdk.AccAddress) []byte {
return append(RedelegationByValDstIndexKey, validatorDstAddr.Bytes()...)
}
// get the prefix keyspace for all redelegations redelegating towards a destination validator
// gets the prefix keyspace for all redelegations redelegating towards a destination validator
// from a particular delegator
func GetREDsByDelToValDstIndexKey(delegatorAddr, validatorDstAddr sdk.AccAddress) []byte {
return append(