Merge branch 'develop' into release/v0.34.0
This commit is contained in:
commit
046932b084
|
@ -196,7 +196,7 @@ jobs:
|
|||
command: |
|
||||
export PATH="$GOBIN:$PATH"
|
||||
export GO111MODULE=on
|
||||
scripts/multisim.sh 500 50 TestFullGaiaSimulation
|
||||
cmd/gaia/contrib/sim/multisim.sh 500 50 TestFullGaiaSimulation
|
||||
|
||||
test_sim_gaia_multi_seed:
|
||||
<<: *linux_defaults
|
||||
|
@ -214,7 +214,7 @@ jobs:
|
|||
command: |
|
||||
export PATH="$GOBIN:$PATH"
|
||||
export GO111MODULE=on
|
||||
scripts/multisim.sh 50 10 TestFullGaiaSimulation
|
||||
cmd/gaia/contrib/sim/multisim.sh 50 10 TestFullGaiaSimulation
|
||||
|
||||
test_cover:
|
||||
<<: *linux_defaults
|
||||
|
|
|
@ -8,17 +8,25 @@ about: Create a report to help us squash bugs!
|
|||
v ✰ Thanks for opening an issue! ✰
|
||||
v Before smashing the submit button please review the template.
|
||||
v Please also ensure that this is not a duplicate issue :)
|
||||
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -->
|
||||
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -->
|
||||
|
||||
## Summary of Bug
|
||||
<!-- Concisely describe the issue -->
|
||||
## Summary of Bug
|
||||
|
||||
<!-- Concisely describe the issue -->
|
||||
|
||||
## Version
|
||||
|
||||
<!-- Output from `gaiad version --long` and `gaiacli version --long` -->
|
||||
|
||||
## Steps to Reproduce
|
||||
<!-- What commands in order should someone run to reproduce your problem -->
|
||||
|
||||
<!-- What commands in order should someone run to reproduce your problem -->
|
||||
|
||||
____
|
||||
|
||||
#### For Admin Use
|
||||
- [ ] Not duplicate issue
|
||||
- [ ] Appropriate labels applied
|
||||
- [ ] Appropriate contributors tagged
|
||||
- [ ] Contributor assigned/self-assigned
|
||||
|
||||
- [ ] Not duplicate issue
|
||||
- [ ] Appropriate labels applied
|
||||
- [ ] Appropriate contributors tagged
|
||||
- [ ] Contributor assigned/self-assigned
|
||||
|
|
|
@ -9,23 +9,28 @@ v ✰ Thanks for opening an issue! ✰
|
|||
v Before smashing the submit button please review the template.
|
||||
v Word of caution: poorly thought-out proposals may be rejected
|
||||
v without deliberation
|
||||
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -->
|
||||
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -->
|
||||
|
||||
## Summary
|
||||
<!-- Short, concise description of the proposed feature -->
|
||||
|
||||
<!-- Short, concise description of the proposed feature -->
|
||||
|
||||
## Problem Definition
|
||||
|
||||
<!-- Why do we need this feature?
|
||||
What problems may be addressed by introducing this feature?
|
||||
What benefits does the SDK stand to gain by including this feature?
|
||||
Are there any disadvantages of including this feature? -->
|
||||
|
||||
## Proposal
|
||||
<!-- Detailed description of requirements of implementation -->
|
||||
|
||||
<!-- Detailed description of requirements of implementation -->
|
||||
|
||||
____
|
||||
|
||||
#### For Admin Use
|
||||
- [ ] Not duplicate issue
|
||||
- [ ] Appropriate labels applied
|
||||
- [ ] Appropriate contributors tagged
|
||||
- [ ] Contributor assigned/self-assigned
|
||||
|
||||
- [ ] Not duplicate issue
|
||||
- [ ] Appropriate labels applied
|
||||
- [ ] Appropriate contributors tagged
|
||||
- [ ] Contributor assigned/self-assigned
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#4053 Add --inv-check-period flag to gaiad to set period at which invariants checks will run.
|
|
@ -0,0 +1 @@
|
|||
#4049 update tag MsgWithdrawValidatorCommission to match type
|
|
@ -0,0 +1 @@
|
|||
#3775 unify sender transaction tag for ease of querying
|
|
@ -0,0 +1 @@
|
|||
#3945 There's no check for chain-id in TxBuilder.SignStdTx
|
|
@ -0,0 +1 @@
|
|||
#3705 Return `[]` instead of `null` when querying delegator rewards.
|
|
@ -0,0 +1,2 @@
|
|||
#3966 fixed multiple assigns to action tags
|
||||
#3793 add delegator tag for MsgCreateValidator and deleted unused moniker and identity tags
|
|
@ -0,0 +1 @@
|
|||
#4042 Update docs and scripts to include the correct `GO111MODULE=on` environment variable.
|
|
@ -0,0 +1 @@
|
|||
#4066 Fix 'ExportGenesisFile() incorrectly overwrites genesis'
|
|
@ -0,0 +1 @@
|
|||
#4064 Remove `dep` and `vendor` from `doc` and `version`.
|
|
@ -0,0 +1 @@
|
|||
#4080 add missing invariants during simulations
|
|
@ -0,0 +1 @@
|
|||
#4068 Remove redundant account check on `gaiacli`
|
|
@ -0,0 +1 @@
|
|||
#2007 Return 200 status code on empty results
|
|
@ -0,0 +1 @@
|
|||
#3774 add category tag to transactions for ease of filtering
|
|
@ -0,0 +1 @@
|
|||
#3914 Implement invariant benchmarks and add target to makefile.
|
27
Makefile
27
Makefile
|
@ -1,8 +1,9 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
PACKAGES_NOSIMULATION=$(shell go list ./... | grep -v '/simulation')
|
||||
PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation')
|
||||
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')
|
||||
COMMIT := $(shell git log -1 --format='%H')
|
||||
CAT := $(if $(filter $(OS),Windows_NT),type,cat)
|
||||
LEDGER_ENABLED ?= true
|
||||
GOBIN ?= $(GOPATH)/bin
|
||||
GOSUM := $(shell which gosum)
|
||||
|
@ -48,7 +49,7 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
|
|||
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags)"
|
||||
|
||||
ifneq ($(GOSUM),)
|
||||
ldflags += -X github.com/cosmos/cosmos-sdk/version.VendorDirHash=$(shell $(GOSUM) go.sum)
|
||||
ldflags += -X github.com/cosmos/cosmos-sdk/version.GoSumHash=$(shell $(GOSUM) go.sum)
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_CLEVELDB),yes)
|
||||
|
@ -62,7 +63,7 @@ BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)'
|
|||
all: tools install lint test
|
||||
|
||||
# The below include contains the tools target.
|
||||
include scripts/Makefile
|
||||
include contrib/devtools/Makefile
|
||||
|
||||
########################################
|
||||
### CI
|
||||
|
@ -121,8 +122,6 @@ draw_deps: tools
|
|||
clean:
|
||||
rm -rf snapcraft-local.yaml build/
|
||||
|
||||
distclean: clean
|
||||
rm -rf vendor/
|
||||
|
||||
########################################
|
||||
### Documentation
|
||||
|
@ -168,20 +167,26 @@ test_sim_gaia_fast:
|
|||
|
||||
test_sim_gaia_import_export:
|
||||
@echo "Running Gaia import/export simulation. This may take several minutes..."
|
||||
@bash scripts/multisim.sh 50 5 TestGaiaImportExport
|
||||
@bash cmd/gaia/contrib/sim/multisim.sh 50 5 TestGaiaImportExport
|
||||
|
||||
test_sim_gaia_simulation_after_import:
|
||||
@echo "Running Gaia simulation-after-import. This may take several minutes..."
|
||||
@bash scripts/multisim.sh 50 5 TestGaiaSimulationAfterImport
|
||||
@bash cmd/gaia/contrib/sim/multisim.sh 50 5 TestGaiaSimulationAfterImport
|
||||
|
||||
test_sim_gaia_custom_genesis_multi_seed:
|
||||
@echo "Running multi-seed custom genesis simulation..."
|
||||
@echo "By default, ${HOME}/.gaiad/config/genesis.json will be used."
|
||||
@bash scripts/multisim.sh 400 5 TestFullGaiaSimulation ${HOME}/.gaiad/config/genesis.json
|
||||
@bash cmd/gaia/contrib/sim/multisim.sh 400 5 TestFullGaiaSimulation ${HOME}/.gaiad/config/genesis.json
|
||||
|
||||
test_sim_gaia_multi_seed:
|
||||
@echo "Running multi-seed Gaia simulation. This may take awhile!"
|
||||
@bash scripts/multisim.sh 400 5 TestFullGaiaSimulation
|
||||
@bash cmd/gaia/contrib/sim/multisim.sh 400 5 TestFullGaiaSimulation
|
||||
|
||||
test_sim_benchmark_invariants:
|
||||
@echo "Running simulation invariant benchmarks..."
|
||||
@go test -mod=readonly ./cmd/gaia/app -benchmem -bench=BenchmarkInvariants -run=^$ \
|
||||
-SimulationEnabled=true -SimulationNumBlocks=1000 -SimulationBlockSize=200 \
|
||||
-SimulationCommit=true -SimulationSeed=57 -v -timeout 24h
|
||||
|
||||
SIM_NUM_BLOCKS ?= 500
|
||||
SIM_BLOCK_SIZE ?= 200
|
||||
|
@ -264,11 +269,11 @@ snapcraft-local.yaml: snapcraft-local.yaml.in
|
|||
# To avoid unintended conflicts with file names, always add to .PHONY
|
||||
# unless there is a reason not to.
|
||||
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
|
||||
.PHONY: install install_debug dist clean distclean \
|
||||
.PHONY: install install_debug dist clean \
|
||||
draw_deps test test_cli test_unit \
|
||||
test_cover lint benchmark devdoc_init devdoc devdoc_save devdoc_update \
|
||||
build-linux build-docker-gaiadnode localnet-start localnet-stop \
|
||||
format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast \
|
||||
test_sim_gaia_custom_genesis_fast test_sim_gaia_custom_genesis_multi_seed \
|
||||
test_sim_gaia_multi_seed test_sim_gaia_import_export \
|
||||
test_sim_gaia_multi_seed test_sim_gaia_import_export test_sim_benchmark_invariants \
|
||||
go-mod-cache
|
||||
|
|
|
@ -9,13 +9,16 @@ import (
|
|||
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/pelletier/go-toml"
|
||||
toml "github.com/pelletier/go-toml"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
flagGet = "get"
|
||||
|
||||
// DefaultKeyPass contains the default key password for genesis transactions
|
||||
DefaultKeyPass = "12345678"
|
||||
)
|
||||
|
||||
var configDefaults = map[string]string{
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
)
|
||||
|
||||
// For https://github.com/cosmos/cosmos-sdk/issues/3899
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
|
@ -102,7 +101,7 @@ func runAddCmd(_ *cobra.Command, args []string) error {
|
|||
// we throw this away, so don't enforce args,
|
||||
// we want to get a new random seed phrase quickly
|
||||
kb = keys.NewInMemory()
|
||||
encryptPassword = app.DefaultKeyPass
|
||||
encryptPassword = client.DefaultKeyPass
|
||||
} else {
|
||||
kb, err = NewKeyBaseFromHomeFlag()
|
||||
if err != nil {
|
||||
|
|
|
@ -7,11 +7,12 @@ import (
|
|||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
)
|
||||
|
||||
func Test_runDeleteCmd(t *testing.T) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package keys
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
)
|
||||
|
||||
func listKeysCmd() *cobra.Command {
|
||||
|
|
|
@ -3,9 +3,10 @@ package keys
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package keys
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto"
|
||||
|
|
|
@ -7,10 +7,11 @@ import (
|
|||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -38,7 +37,7 @@ const (
|
|||
name2 = "test2"
|
||||
name3 = "test3"
|
||||
memo = "LCD test tx"
|
||||
pw = app.DefaultKeyPass
|
||||
pw = client.DefaultKeyPass
|
||||
altPw = "12345678901"
|
||||
)
|
||||
|
||||
|
@ -115,7 +114,7 @@ func TestCoinSend(t *testing.T) {
|
|||
|
||||
// query empty
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/auth/accounts/%s", someFakeAddr), nil)
|
||||
require.Equal(t, http.StatusNoContent, res.StatusCode, body)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
acc := getAccount(t, port, addr)
|
||||
initialBalance := acc.GetCoins()
|
||||
|
@ -337,7 +336,7 @@ func TestTxs(t *testing.T) {
|
|||
txs = getTransactions(t, port, fmt.Sprintf("sender=%s", addr.String()))
|
||||
require.Equal(t, emptyTxs, txs)
|
||||
|
||||
txs = getTransactions(t, port, fmt.Sprintf("action=submit%%20proposal&proposer=%s", addr.String()))
|
||||
txs = getTransactions(t, port, fmt.Sprintf("action=submit%%20proposal&sender=%s", addr.String()))
|
||||
require.Equal(t, emptyTxs, txs)
|
||||
|
||||
// create tx
|
||||
|
@ -456,7 +455,7 @@ func TestBonding(t *testing.T) {
|
|||
|
||||
// query tx
|
||||
txs := getTransactions(t, port,
|
||||
fmt.Sprintf("action=delegate&delegator=%s", addr),
|
||||
fmt.Sprintf("action=delegate&sender=%s", addr),
|
||||
fmt.Sprintf("destination-validator=%s", operAddrs[0]),
|
||||
)
|
||||
require.Len(t, txs, 1)
|
||||
|
@ -509,7 +508,7 @@ func TestBonding(t *testing.T) {
|
|||
|
||||
// query tx
|
||||
txs = getTransactions(t, port,
|
||||
fmt.Sprintf("action=begin_unbonding&delegator=%s", addr),
|
||||
fmt.Sprintf("action=begin_unbonding&sender=%s", addr),
|
||||
fmt.Sprintf("source-validator=%s", operAddrs[0]),
|
||||
)
|
||||
require.Len(t, txs, 1)
|
||||
|
@ -546,7 +545,7 @@ func TestBonding(t *testing.T) {
|
|||
|
||||
// query tx
|
||||
txs = getTransactions(t, port,
|
||||
fmt.Sprintf("action=begin_redelegate&delegator=%s", addr),
|
||||
fmt.Sprintf("action=begin_redelegate&sender=%s", addr),
|
||||
fmt.Sprintf("source-validator=%s", operAddrs[0]),
|
||||
fmt.Sprintf("destination-validator=%s", operAddrs[1]),
|
||||
)
|
||||
|
@ -674,7 +673,7 @@ func TestDeposit(t *testing.T) {
|
|||
require.Equal(t, expectedBalance.Amount.Sub(depositTokens), acc.GetCoins().AmountOf(sdk.DefaultBondDenom))
|
||||
|
||||
// query tx
|
||||
txs := getTransactions(t, port, fmt.Sprintf("action=deposit&depositor=%s", addr))
|
||||
txs := getTransactions(t, port, fmt.Sprintf("action=deposit&sender=%s", addr))
|
||||
require.Len(t, txs, 1)
|
||||
require.Equal(t, resultTx.Height, txs[0].Height)
|
||||
|
||||
|
@ -735,7 +734,7 @@ func TestVote(t *testing.T) {
|
|||
expectedBalance = coins[0]
|
||||
|
||||
// query tx
|
||||
txs := getTransactions(t, port, fmt.Sprintf("action=vote&voter=%s", addr))
|
||||
txs := getTransactions(t, port, fmt.Sprintf("action=vote&sender=%s", addr))
|
||||
require.Len(t, txs, 1)
|
||||
require.Equal(t, resultTx.Height, txs[0].Height)
|
||||
|
||||
|
@ -1045,3 +1044,26 @@ func TestMintingQueries(t *testing.T) {
|
|||
var annualProvisions sdk.Dec
|
||||
require.NoError(t, cdc.UnmarshalJSON([]byte(body), &annualProvisions))
|
||||
}
|
||||
|
||||
func TestAccountBalanceQuery(t *testing.T) {
|
||||
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
|
||||
require.NoError(t, err)
|
||||
addr, _ := CreateAddr(t, name1, pw, kb)
|
||||
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
|
||||
defer cleanup()
|
||||
|
||||
bz, err := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6")
|
||||
require.NoError(t, err)
|
||||
someFakeAddr := sdk.AccAddress(bz)
|
||||
|
||||
// empty account
|
||||
res, body := Request(t, port, "GET", fmt.Sprintf("/auth/accounts/%s", someFakeAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.Contains(t, body, `"type":"auth/Account"`)
|
||||
|
||||
// empty account balance
|
||||
res, body = Request(t, port, "GET", fmt.Sprintf("/bank/balances/%s", someFakeAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
require.Contains(t, body, "[]")
|
||||
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ paths:
|
|||
- in: query
|
||||
name: tag
|
||||
type: string
|
||||
description: "transaction tags such as 'action=submit-proposal' and 'proposer=cosmos1g9ahr6xhht5rmqven628nklxluzyv8z9jqjcmc' which results in the following endpoint: 'GET /txs?action=submit-proposal&proposer=cosmos1g9ahr6xhht5rmqven628nklxluzyv8z9jqjcmc'"
|
||||
description: "transaction tags such as 'action=submit-proposal' and 'sender=cosmos1g9ahr6xhht5rmqven628nklxluzyv8z9jqjcmc' which results in the following endpoint: 'GET /txs?action=submit-proposal&sender=cosmos1g9ahr6xhht5rmqven628nklxluzyv8z9jqjcmc'"
|
||||
required: true
|
||||
x-example: 'TODO'
|
||||
- in: query
|
||||
|
|
|
@ -221,7 +221,7 @@ func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress
|
|||
privVal.Reset()
|
||||
|
||||
db := dbm.NewMemDB()
|
||||
app := gapp.NewGaiaApp(logger, db, nil, true, false)
|
||||
app := gapp.NewGaiaApp(logger, db, nil, true, 0)
|
||||
cdc = gapp.MakeCodec()
|
||||
|
||||
genesisFile := config.GenesisFile()
|
||||
|
@ -695,7 +695,7 @@ func doTransferWithGas(
|
|||
kb := crkeys.NewInMemory()
|
||||
|
||||
receiveInfo, _, err := kb.CreateMnemonic(
|
||||
"receive_address", crkeys.English, gapp.DefaultKeyPass, crkeys.SigningAlgo("secp256k1"),
|
||||
"receive_address", crkeys.English, client.DefaultKeyPass, crkeys.SigningAlgo("secp256k1"),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
|
@ -742,7 +742,7 @@ func doTransferWithGasAccAuto(
|
|||
acc := getAccount(t, port, addr)
|
||||
|
||||
receiveInfo, _, err := kb.CreateMnemonic(
|
||||
"receive_address", crkeys.English, gapp.DefaultKeyPass, crkeys.SigningAlgo("secp256k1"),
|
||||
"receive_address", crkeys.English, client.DefaultKeyPass, crkeys.SigningAlgo("secp256k1"),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-amino"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,11 +6,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
)
|
||||
|
||||
// SearchTxs performs a search for transactions for a given set of tags via
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation')
|
||||
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')
|
||||
COMMIT := $(shell git log -1 --format='%H')
|
||||
LEDGER_ENABLED ?= true
|
||||
GOBIN ?= $(GOPATH)/bin
|
||||
GOSUM := $(shell which gosum)
|
||||
|
||||
export GO111MODULE = on
|
||||
|
||||
# process build tags
|
||||
|
||||
build_tags = netgo
|
||||
ifeq ($(LEDGER_ENABLED),true)
|
||||
ifeq ($(OS),Windows_NT)
|
||||
GCCEXE = $(shell where gcc.exe 2> NUL)
|
||||
ifeq ($(GCCEXE),)
|
||||
$(error gcc.exe not installed for ledger support, please install or set LEDGER_ENABLED=false)
|
||||
else
|
||||
build_tags += ledger
|
||||
endif
|
||||
else
|
||||
UNAME_S = $(shell uname -s)
|
||||
ifeq ($(UNAME_S),OpenBSD)
|
||||
$(warning OpenBSD detected, disabling ledger support (https://github.com/cosmos/cosmos-sdk/issues/1988))
|
||||
else
|
||||
GCC = $(shell command -v gcc 2> /dev/null)
|
||||
ifeq ($(GCC),)
|
||||
$(error gcc not installed for ledger support, please install or set LEDGER_ENABLED=false)
|
||||
else
|
||||
build_tags += ledger
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_CLEVELDB),yes)
|
||||
build_tags += gcc
|
||||
endif
|
||||
build_tags += $(BUILD_TAGS)
|
||||
build_tags := $(strip $(build_tags))
|
||||
|
||||
# process linker flags
|
||||
|
||||
ldflags = -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
|
||||
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
|
||||
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags)"
|
||||
|
||||
ifneq ($(GOSUM),)
|
||||
ldflags += -X github.com/cosmos/cosmos-sdk/version.GoSumHash=$(shell $(GOSUM) ../../go.sum)
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_CLEVELDB),yes)
|
||||
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
|
||||
endif
|
||||
ldflags += $(LDFLAGS)
|
||||
ldflags := $(strip $(ldflags))
|
||||
|
||||
BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)'
|
||||
|
||||
# The below include contains the tools target.
|
||||
include ../../contrib/devtools/Makefile
|
||||
|
||||
all: install lint check
|
||||
|
||||
build: ../../go.sum
|
||||
ifeq ($(OS),Windows_NT)
|
||||
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiad.exe ../../cmd/gaia/cmd/gaiad
|
||||
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiacli.exe ../../cmd/gaia/cmd/gaiacli
|
||||
else
|
||||
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiad ../../cmd/gaia/cmd/gaiad
|
||||
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiacli ../../cmd/gaia/cmd/gaiacli
|
||||
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiareplay ../../cmd/gaia/cmd/gaiareplay
|
||||
go build -mod=readonly $(BUILD_FLAGS) -o build/gaiakeyutil ../../cmd/gaia/cmd/gaiakeyutil
|
||||
endif
|
||||
|
||||
build-linux: ../../go.sum
|
||||
LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build
|
||||
|
||||
install: ../../go.sum check-ledger
|
||||
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiad
|
||||
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiacli
|
||||
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiareplay
|
||||
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiakeyutil
|
||||
|
||||
install-debug: ../../go.sum
|
||||
go install -mod=readonly $(BUILD_FLAGS) ../../cmd/gaia/cmd/gaiadebug
|
||||
|
||||
|
||||
########################################
|
||||
### Tools & dependencies
|
||||
|
||||
go-mod-cache: go.sum
|
||||
@echo "--> Download go modules to local cache"
|
||||
@go mod download
|
||||
|
||||
go.sum: go.mod
|
||||
@echo "--> Ensure dependencies have not been modified"
|
||||
@go mod verify
|
||||
|
||||
draw-deps:
|
||||
@# requires brew install graphviz or apt-get install graphviz
|
||||
go get github.com/RobotsAndPencils/goviz
|
||||
@goviz -i ./cmd/gaiad -d 2 | dot -Tpng -o dependency-graph.png
|
||||
|
||||
clean:
|
||||
rm -rf snapcraft-local.yaml build/
|
||||
|
||||
distclean: clean
|
||||
rm -rf vendor/
|
||||
|
||||
########################################
|
||||
### Testing
|
||||
|
||||
|
||||
check: check-unit
|
||||
check-unit:
|
||||
@VERSION=$(VERSION) go test -mod=readonly -race -tags='ledger test_ledger_mock' ./...
|
||||
|
||||
check-race:
|
||||
@VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock' -race ./...
|
||||
|
||||
check-cover:
|
||||
@go test -mod=readonly -timeout 30m -race -coverprofile=coverage.txt -covermode=atomic -tags='ledger test_ledger_mock' ./...
|
||||
|
||||
check-build: build
|
||||
@go test -mod=readonly -p 4 `go list ./cli_test/...` -tags=cli_test
|
||||
|
||||
check-all: check-unit check-race check-cover check-build
|
||||
|
||||
lint: ci-lint
|
||||
ci-lint:
|
||||
golangci-lint run
|
||||
go vet -composites=false -tests=false ./...
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" | xargs gofmt -d -s
|
||||
go mod verify
|
||||
|
||||
format:
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs gofmt -w -s
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs misspell -w
|
||||
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs goimports -w -local github.com/cosmos/cosmos-sdk
|
||||
|
||||
benchmark:
|
||||
@go test -mod=readonly -bench=. ./...
|
||||
|
||||
|
||||
# include simulations
|
||||
include sims.mk
|
||||
|
||||
.PHONY: all build-linux install install-debug \
|
||||
go-mod-cache draw-deps clean \
|
||||
check check-all check-build check-cover check-ledger check-unit check-race
|
||||
|
|
@ -27,8 +27,6 @@ import (
|
|||
|
||||
const (
|
||||
appName = "GaiaApp"
|
||||
// DefaultKeyPass contains the default key password for genesis transactions
|
||||
DefaultKeyPass = "12345678"
|
||||
)
|
||||
|
||||
// default home directories for expected binaries
|
||||
|
@ -42,7 +40,7 @@ type GaiaApp struct {
|
|||
*bam.BaseApp
|
||||
cdc *codec.Codec
|
||||
|
||||
assertInvariantsBlockly bool
|
||||
invCheckPeriod uint
|
||||
|
||||
// keys to access the substores
|
||||
keyMain *sdk.KVStoreKey
|
||||
|
@ -72,7 +70,8 @@ type GaiaApp struct {
|
|||
}
|
||||
|
||||
// NewGaiaApp returns a reference to an initialized GaiaApp.
|
||||
func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest, assertInvariantsBlockly bool,
|
||||
func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
||||
invCheckPeriod uint,
|
||||
baseAppOptions ...func(*bam.BaseApp)) *GaiaApp {
|
||||
|
||||
cdc := MakeCodec()
|
||||
|
@ -83,6 +82,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest,
|
|||
var app = &GaiaApp{
|
||||
BaseApp: bApp,
|
||||
cdc: cdc,
|
||||
invCheckPeriod: invCheckPeriod,
|
||||
keyMain: sdk.NewKVStoreKey(bam.MainStoreKey),
|
||||
keyAccount: sdk.NewKVStoreKey(auth.StoreKey),
|
||||
keyStaking: sdk.NewKVStoreKey(staking.StoreKey),
|
||||
|
@ -244,7 +244,7 @@ func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R
|
|||
validatorUpdates, endBlockerTags := staking.EndBlocker(ctx, app.stakingKeeper)
|
||||
tags = append(tags, endBlockerTags...)
|
||||
|
||||
if app.assertInvariantsBlockly {
|
||||
if app.invCheckPeriod != 0 && ctx.BlockHeight()%int64(app.invCheckPeriod) == 0 {
|
||||
app.assertRuntimeInvariants()
|
||||
}
|
||||
|
||||
|
|
|
@ -55,11 +55,11 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error {
|
|||
|
||||
func TestGaiadExport(t *testing.T) {
|
||||
db := db.NewMemDB()
|
||||
gapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, false)
|
||||
gapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0)
|
||||
setGenesis(gapp)
|
||||
|
||||
// Making a new app object with the db, so that initchain hasn't been called
|
||||
newGapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, false)
|
||||
newGapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0)
|
||||
_, _, err := newGapp.ExportAppStateAndValidators(false, []string{})
|
||||
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
|
||||
}
|
||||
|
|
|
@ -26,5 +26,6 @@ func (app *GaiaApp) assertRuntimeInvariantsOnContext(ctx sdk.Context) {
|
|||
}
|
||||
end := time.Now()
|
||||
diff := end.Sub(start)
|
||||
app.BaseApp.Logger().With("module", "invariants").Info("Asserted all invariants", "duration", diff)
|
||||
app.BaseApp.Logger().With("module", "invariants").Info(
|
||||
"Asserted all invariants", "duration", diff, "height", app.LastBlockHeight())
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"os"
|
||||
|
@ -61,11 +62,11 @@ func init() {
|
|||
}
|
||||
|
||||
// helper function for populating input for SimulateFromSeed
|
||||
func getSimulateFromSeedInput(tb testing.TB, app *GaiaApp) (
|
||||
testing.TB, *baseapp.BaseApp, simulation.AppStateFn, int64,
|
||||
func getSimulateFromSeedInput(tb testing.TB, w io.Writer, app *GaiaApp) (
|
||||
testing.TB, io.Writer, *baseapp.BaseApp, simulation.AppStateFn, int64,
|
||||
simulation.WeightedOperations, sdk.Invariants, int, int, bool, bool) {
|
||||
|
||||
return tb, app.BaseApp, appStateFn, seed,
|
||||
return tb, w, app.BaseApp, appStateFn, seed,
|
||||
testAndRunTxs(app), invariants(app), numBlocks, blockSize, commit, lean
|
||||
}
|
||||
|
||||
|
@ -293,12 +294,7 @@ func testAndRunTxs(app *GaiaApp) []simulation.WeightedOperation {
|
|||
}
|
||||
|
||||
func invariants(app *GaiaApp) []sdk.Invariant {
|
||||
return []sdk.Invariant{
|
||||
simulation.PeriodicInvariant(bank.NonnegativeBalanceInvariant(app.accountKeeper), period, 0),
|
||||
simulation.PeriodicInvariant(distr.AllInvariants(app.distrKeeper, app.stakingKeeper), period, 0),
|
||||
simulation.PeriodicInvariant(staking.AllInvariants(app.stakingKeeper, app.feeCollectionKeeper,
|
||||
app.distrKeeper, app.accountKeeper), period, 0),
|
||||
}
|
||||
return simulation.PeriodicInvariants(app.crisisKeeper.Invariants(), period, 0)
|
||||
}
|
||||
|
||||
// Pass this in as an option to use a dbStoreAdapter instead of an IAVLStore for simulation speed.
|
||||
|
@ -319,11 +315,11 @@ func BenchmarkFullGaiaSimulation(b *testing.B) {
|
|||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil, true, false)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0)
|
||||
|
||||
// Run randomized simulation
|
||||
// TODO parameterize numbers, save for a later PR
|
||||
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(b, app))
|
||||
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(b, os.Stdout, app))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
b.Fail()
|
||||
|
@ -354,11 +350,11 @@ func TestFullGaiaSimulation(t *testing.T) {
|
|||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil, true, false, fauxMerkleModeOpt)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, app))
|
||||
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
|
||||
if commit {
|
||||
// for memdb:
|
||||
// fmt.Println("Database Size", db.Stats()["database.size"])
|
||||
|
@ -388,11 +384,11 @@ func TestGaiaImportExport(t *testing.T) {
|
|||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil, true, false, fauxMerkleModeOpt)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, app))
|
||||
_, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
|
||||
|
||||
if commit {
|
||||
// for memdb:
|
||||
|
@ -415,7 +411,7 @@ func TestGaiaImportExport(t *testing.T) {
|
|||
newDB.Close()
|
||||
os.RemoveAll(newDir)
|
||||
}()
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, false, fauxMerkleModeOpt)
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", newApp.Name())
|
||||
var genesisState GenesisState
|
||||
err = app.cdc.UnmarshalJSON(appState, &genesisState)
|
||||
|
@ -478,11 +474,11 @@ func TestGaiaSimulationAfterImport(t *testing.T) {
|
|||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil, true, false, fauxMerkleModeOpt)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
stopEarly, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, app))
|
||||
stopEarly, err := simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, app))
|
||||
|
||||
if commit {
|
||||
// for memdb:
|
||||
|
@ -514,14 +510,14 @@ func TestGaiaSimulationAfterImport(t *testing.T) {
|
|||
newDB.Close()
|
||||
os.RemoveAll(newDir)
|
||||
}()
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, false, fauxMerkleModeOpt)
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", newApp.Name())
|
||||
newApp.InitChain(abci.RequestInitChain{
|
||||
AppStateBytes: appState,
|
||||
})
|
||||
|
||||
// Run randomized simulation on imported app
|
||||
_, err = simulation.SimulateFromSeed(getSimulateFromSeedInput(t, newApp))
|
||||
_, err = simulation.SimulateFromSeed(getSimulateFromSeedInput(t, os.Stdout, newApp))
|
||||
require.Nil(t, err)
|
||||
|
||||
}
|
||||
|
@ -542,11 +538,11 @@ func TestAppStateDeterminism(t *testing.T) {
|
|||
for j := 0; j < numTimesToRunPerSeed; j++ {
|
||||
logger := log.NewNopLogger()
|
||||
db := dbm.NewMemDB()
|
||||
app := NewGaiaApp(logger, db, nil, true, false)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0)
|
||||
|
||||
// Run randomized simulation
|
||||
simulation.SimulateFromSeed(
|
||||
t, app.BaseApp, appStateFn, seed,
|
||||
t, os.Stdout, app.BaseApp, appStateFn, seed,
|
||||
testAndRunTxs(app),
|
||||
[]sdk.Invariant{},
|
||||
50,
|
||||
|
@ -562,3 +558,42 @@ func TestAppStateDeterminism(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInvariants(b *testing.B) {
|
||||
// 1. Setup a simulated Gaia application
|
||||
logger := log.NewNopLogger()
|
||||
dir, _ := ioutil.TempDir("", "goleveldb-gaia-invariant-bench")
|
||||
db, _ := sdk.NewLevelDB("simulation", dir)
|
||||
|
||||
defer func() {
|
||||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
app := NewGaiaApp(logger, db, nil, true, 0)
|
||||
|
||||
// 2. Run parameterized simulation (w/o invariants)
|
||||
_, err := simulation.SimulateFromSeed(
|
||||
b, ioutil.Discard, app.BaseApp, appStateFn, seed, testAndRunTxs(app),
|
||||
[]sdk.Invariant{}, numBlocks, blockSize, commit, lean,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
b.FailNow()
|
||||
}
|
||||
|
||||
ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight() + 1})
|
||||
|
||||
// 3. Benchmark each invariant separately
|
||||
//
|
||||
// NOTE: We use the crisis keeper as it has all the invariants registered with
|
||||
// their respective metadata which makes it useful for testing/benchmarking.
|
||||
for _, cr := range app.crisisKeeper.Routes() {
|
||||
b.Run(fmt.Sprintf("%s/%s", cr.ModuleName, cr.Route), func(b *testing.B) {
|
||||
if err := cr.Invar(ctx); err != nil {
|
||||
fmt.Println(err)
|
||||
b.FailNow()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
@ -223,6 +224,17 @@ func TestGaiaCLISend(t *testing.T) {
|
|||
success, _, _ := f.TxSend(keyFoo, barAddr, sdk.NewCoin(denom, sendTokens), "--dry-run")
|
||||
require.True(t, success)
|
||||
|
||||
// Test --generate-only
|
||||
success, stdout, stderr := f.TxSend(
|
||||
fooAddr.String(), barAddr, sdk.NewCoin(denom, sendTokens), "--generate-only=true",
|
||||
)
|
||||
require.Empty(t, stderr)
|
||||
require.True(t, success)
|
||||
msg := unmarshalStdTx(f.T, stdout)
|
||||
require.NotZero(t, msg.Fee.Gas)
|
||||
require.Len(t, msg.Msgs, 1)
|
||||
require.Len(t, msg.GetSignatures(), 0)
|
||||
|
||||
// Check state didn't change
|
||||
fooAcc = f.QueryAccount(fooAddr)
|
||||
require.Equal(t, startTokens.Sub(sendTokens), fooAcc.GetCoins().AmountOf(denom))
|
||||
|
@ -456,7 +468,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
|||
tests.WaitForNextNBlocksTM(1, f.Port)
|
||||
|
||||
// Ensure transaction tags can be queried
|
||||
txs := f.QueryTxs(1, 50, "action:submit_proposal", fmt.Sprintf("proposer:%s", fooAddr))
|
||||
txs := f.QueryTxs(1, 50, "action:submit_proposal", fmt.Sprintf("sender:%s", fooAddr))
|
||||
require.Len(t, txs, 1)
|
||||
|
||||
// Ensure deposit was deducted
|
||||
|
@ -500,7 +512,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
|||
require.Equal(t, proposalTokens.Add(depositTokens), deposit.Amount.AmountOf(denom))
|
||||
|
||||
// Ensure tags are set on the transaction
|
||||
txs = f.QueryTxs(1, 50, "action:deposit", fmt.Sprintf("depositor:%s", fooAddr))
|
||||
txs = f.QueryTxs(1, 50, "action:deposit", fmt.Sprintf("sender:%s", fooAddr))
|
||||
require.Len(t, txs, 1)
|
||||
|
||||
// Ensure account has expected amount of funds
|
||||
|
@ -537,7 +549,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
|||
require.Equal(t, gov.OptionYes, votes[0].Option)
|
||||
|
||||
// Ensure tags are applied to voting transaction properly
|
||||
txs = f.QueryTxs(1, 50, "action:vote", fmt.Sprintf("voter:%s", fooAddr))
|
||||
txs = f.QueryTxs(1, 50, "action:vote", fmt.Sprintf("sender:%s", fooAddr))
|
||||
require.Len(t, txs, 1)
|
||||
|
||||
// Ensure no proposals in deposit period
|
||||
|
@ -992,6 +1004,7 @@ trust-node = true
|
|||
|
||||
func TestGaiadCollectGentxs(t *testing.T) {
|
||||
t.Parallel()
|
||||
var customMaxBytes, customMaxGas int64 = 99999999, 1234567
|
||||
f := NewFixtures(t)
|
||||
|
||||
// Initialise temporary directories
|
||||
|
@ -1011,6 +1024,15 @@ func TestGaiadCollectGentxs(t *testing.T) {
|
|||
// Run init
|
||||
f.GDInit(keyFoo)
|
||||
|
||||
// Customise genesis.json
|
||||
|
||||
genFile := f.GenesisFile()
|
||||
genDoc, err := tmtypes.GenesisDocFromFile(genFile)
|
||||
require.NoError(t, err)
|
||||
genDoc.ConsensusParams.Block.MaxBytes = customMaxBytes
|
||||
genDoc.ConsensusParams.Block.MaxGas = customMaxGas
|
||||
genDoc.SaveAs(genFile)
|
||||
|
||||
// Add account to genesis.json
|
||||
f.AddGenesisAccount(f.KeyAddress(keyFoo), startCoins)
|
||||
|
||||
|
@ -1020,6 +1042,11 @@ func TestGaiadCollectGentxs(t *testing.T) {
|
|||
// Collect gentxs from a custom directory
|
||||
f.CollectGenTxs(fmt.Sprintf("--gentx-dir=%s", gentxDir))
|
||||
|
||||
genDoc, err = tmtypes.GenesisDocFromFile(genFile)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, genDoc.ConsensusParams.Block.MaxBytes, customMaxBytes)
|
||||
require.Equal(t, genDoc.ConsensusParams.Block.MaxGas, customMaxGas)
|
||||
|
||||
f.Cleanup(gentxDir)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,13 +10,15 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
appInit "github.com/cosmos/cosmos-sdk/cmd/gaia/init"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
|
@ -96,7 +98,7 @@ func (f Fixtures) GenesisFile() string {
|
|||
// GenesisFile returns the application's genesis state
|
||||
func (f Fixtures) GenesisState() app.GenesisState {
|
||||
cdc := codec.New()
|
||||
genDoc, err := appInit.LoadGenesisDoc(cdc, f.GenesisFile())
|
||||
genDoc, err := tmtypes.GenesisDocFromFile(f.GenesisFile())
|
||||
require.NoError(f.T, err)
|
||||
|
||||
var appState app.GenesisState
|
||||
|
@ -177,7 +179,7 @@ func (f *Fixtures) UnsafeResetAll(flags ...string) {
|
|||
// NOTE: GDInit sets the ChainID for the Fixtures instance
|
||||
func (f *Fixtures) GDInit(moniker string, flags ...string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiad init -o --home=%s %s", f.GDHome, moniker)
|
||||
_, stderr := tests.ExecuteT(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
_, stderr := tests.ExecuteT(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
|
||||
var chainID string
|
||||
var initRes map[string]json.RawMessage
|
||||
|
@ -200,13 +202,13 @@ func (f *Fixtures) AddGenesisAccount(address sdk.AccAddress, coins sdk.Coins, fl
|
|||
// GenTx is gaiad gentx
|
||||
func (f *Fixtures) GenTx(name string, flags ...string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiad gentx --name=%s --home=%s --home-client=%s", name, f.GDHome, f.GCLIHome)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// CollectGenTxs is gaiad collect-gentxs
|
||||
func (f *Fixtures) CollectGenTxs(flags ...string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiad collect-gentxs --home=%s", f.GDHome)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// GDStart runs gaiad start with the appropriate flags and returns a process
|
||||
|
@ -245,19 +247,19 @@ func (f *Fixtures) KeysDelete(name string, flags ...string) {
|
|||
// KeysAdd is gaiacli keys add
|
||||
func (f *Fixtures) KeysAdd(name string, flags ...string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s %s", f.GCLIHome, name)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// KeysAddRecover prepares gaiacli keys add --recover
|
||||
func (f *Fixtures) KeysAddRecover(name, mnemonic string, flags ...string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s --recover %s", f.GCLIHome, name)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass, mnemonic)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass, mnemonic)
|
||||
}
|
||||
|
||||
// KeysAddRecoverHDPath prepares gaiacli keys add --recover --account --index
|
||||
func (f *Fixtures) KeysAddRecoverHDPath(name, mnemonic string, account uint32, index uint32, flags ...string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli keys add --home=%s --recover %s --account %d --index %d", f.GCLIHome, name, account, index)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), app.DefaultKeyPass, mnemonic)
|
||||
executeWriteCheckErr(f.T, addFlags(cmd, flags), client.DefaultKeyPass, mnemonic)
|
||||
}
|
||||
|
||||
// KeysShow is gaiacli keys show
|
||||
|
@ -293,7 +295,7 @@ func (f *Fixtures) CLIConfig(key, value string, flags ...string) {
|
|||
// TxSend is gaiacli tx send
|
||||
func (f *Fixtures) TxSend(from string, to sdk.AccAddress, amount sdk.Coin, flags ...string) (bool, string, string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx send %s %s %v --from=%s", to, amount, f.Flags(), from)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
func (f *Fixtures) txSendWithConfirm(
|
||||
|
@ -301,25 +303,25 @@ func (f *Fixtures) txSendWithConfirm(
|
|||
) (bool, string, string) {
|
||||
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx send %s %s %v --from=%s", to, amount, f.Flags(), from)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), confirm, app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), confirm, client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// TxSign is gaiacli tx sign
|
||||
func (f *Fixtures) TxSign(signer, fileName string, flags ...string) (bool, string, string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx sign %v --from=%s %v", f.Flags(), signer, fileName)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// TxBroadcast is gaiacli tx broadcast
|
||||
func (f *Fixtures) TxBroadcast(fileName string, flags ...string) (bool, string, string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx broadcast %v %v", f.Flags(), fileName)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// TxEncode is gaiacli tx encode
|
||||
func (f *Fixtures) TxEncode(fileName string, flags ...string) (bool, string, string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx encode %v %v", f.Flags(), fileName)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// TxMultisign is gaiacli tx multisign
|
||||
|
@ -341,13 +343,13 @@ func (f *Fixtures) TxStakingCreateValidator(from, consPubKey string, amount sdk.
|
|||
cmd += fmt.Sprintf(" --amount=%v --moniker=%v --commission-rate=%v", amount, from, "0.05")
|
||||
cmd += fmt.Sprintf(" --commission-max-rate=%v --commission-max-change-rate=%v", "0.20", "0.10")
|
||||
cmd += fmt.Sprintf(" --min-self-delegation=%v", "1")
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// TxStakingUnbond is gaiacli tx staking unbond
|
||||
func (f *Fixtures) TxStakingUnbond(from, shares string, validator sdk.ValAddress, flags ...string) bool {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx staking unbond %s %v --from=%s %v", validator, shares, from, f.Flags())
|
||||
return executeWrite(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWrite(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
|
@ -357,19 +359,19 @@ func (f *Fixtures) TxStakingUnbond(from, shares string, validator sdk.ValAddress
|
|||
func (f *Fixtures) TxGovSubmitProposal(from, typ, title, description string, deposit sdk.Coin, flags ...string) (bool, string, string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx gov submit-proposal %v --from=%s --type=%s", f.Flags(), from, typ)
|
||||
cmd += fmt.Sprintf(" --title=%s --description=%s --deposit=%s", title, description, deposit)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// TxGovDeposit is gaiacli tx gov deposit
|
||||
func (f *Fixtures) TxGovDeposit(proposalID int, from string, amount sdk.Coin, flags ...string) (bool, string, string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx gov deposit %d %s --from=%s %v", proposalID, amount, from, f.Flags())
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
// TxGovVote is gaiacli tx gov vote
|
||||
func (f *Fixtures) TxGovVote(proposalID int, option gov.VoteOption, from string, flags ...string) (bool, string, string) {
|
||||
cmd := fmt.Sprintf("../../../build/gaiacli tx gov vote %d %s --from=%s %v", proposalID, option, from, f.Flags())
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), app.DefaultKeyPass)
|
||||
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/go-amino"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
|
|
@ -23,9 +23,9 @@ import (
|
|||
)
|
||||
|
||||
// gaiad custom flags
|
||||
const flagAssertInvariantsBlockly = "assert-invariants-blockly"
|
||||
const flagInvCheckPeriod = "inv-check-period"
|
||||
|
||||
var assertInvariantsBlockly bool
|
||||
var invCheckPeriod uint
|
||||
|
||||
func main() {
|
||||
cdc := app.MakeCodec()
|
||||
|
@ -43,6 +43,7 @@ func main() {
|
|||
Short: "Gaia Daemon (server)",
|
||||
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
|
||||
}
|
||||
|
||||
rootCmd.AddCommand(gaiaInit.InitCmd(ctx, cdc))
|
||||
rootCmd.AddCommand(gaiaInit.CollectGenTxsCmd(ctx, cdc))
|
||||
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc))
|
||||
|
@ -55,8 +56,8 @@ func main() {
|
|||
|
||||
// prepare and add flags
|
||||
executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome)
|
||||
rootCmd.PersistentFlags().BoolVar(&assertInvariantsBlockly, flagAssertInvariantsBlockly,
|
||||
false, "Assert registered invariants on a blockly basis")
|
||||
rootCmd.PersistentFlags().UintVar(&invCheckPeriod, flagInvCheckPeriod,
|
||||
1, "Assert registered invariants every N blocks")
|
||||
err := executor.Execute()
|
||||
if err != nil {
|
||||
// handle with #870
|
||||
|
@ -66,7 +67,7 @@ func main() {
|
|||
|
||||
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application {
|
||||
return app.NewGaiaApp(
|
||||
logger, db, traceStore, true, assertInvariantsBlockly,
|
||||
logger, db, traceStore, true, invCheckPeriod,
|
||||
baseapp.SetPruning(store.NewPruningOptionsFromString(viper.GetString("pruning"))),
|
||||
baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)),
|
||||
)
|
||||
|
@ -77,13 +78,13 @@ func exportAppStateAndTMValidators(
|
|||
) (json.RawMessage, []tmtypes.GenesisValidator, error) {
|
||||
|
||||
if height != -1 {
|
||||
gApp := app.NewGaiaApp(logger, db, traceStore, false, false)
|
||||
gApp := app.NewGaiaApp(logger, db, traceStore, false, uint(1))
|
||||
err := gApp.LoadHeight(height)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return gApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
|
||||
}
|
||||
gApp := app.NewGaiaApp(logger, db, traceStore, true, false)
|
||||
gApp := app.NewGaiaApp(logger, db, traceStore, true, uint(1))
|
||||
return gApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tendermint/tendermint/libs/bech32"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var bech32Prefixes = []string{
|
||||
|
|
|
@ -107,7 +107,7 @@ func run(rootDir string) {
|
|||
// Application
|
||||
fmt.Println("Creating application")
|
||||
myapp := app.NewGaiaApp(
|
||||
ctx.Logger, appDB, traceStoreWriter, true, true,
|
||||
ctx.Logger, appDB, traceStoreWriter, true, uint(1),
|
||||
baseapp.SetPruning(store.PruneEverything), // nothing
|
||||
)
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ sim() {
|
|||
echo "Running Gaia simulation with seed $seed. This may take awhile!"
|
||||
file="$tmpdir/gaia-simulation-seed-$seed-date-$(date -u +"%Y-%m-%dT%H:%M:%S+00:00").stdout"
|
||||
echo "Writing stdout to $file..."
|
||||
go test ./cmd/gaia/app -run $testname -SimulationEnabled=true -SimulationNumBlocks=$blocks -SimulationGenesis=$genesis \
|
||||
go test github.com/cosmos/cosmos-sdk/cmd/gaia/app -run $testname -SimulationEnabled=true -SimulationNumBlocks=$blocks -SimulationGenesis=$genesis \
|
||||
-SimulationVerbose=true -SimulationCommit=true -SimulationSeed=$seed -SimulationPeriod=$period -v -timeout 24h > $file
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
genDoc, err := LoadGenesisDoc(cdc, config.GenesisFile())
|
||||
genDoc, err := types.GenesisDocFromFile(config.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
|||
toPrint := newPrintInfo(config.Moniker, genDoc.ChainID, nodeID, genTxsDir, json.RawMessage(""))
|
||||
initCfg := newInitConfig(genDoc.ChainID, genTxsDir, name, nodeID, valPubKey)
|
||||
|
||||
appMessage, err := genAppStateFromConfig(cdc, config, initCfg, genDoc)
|
||||
appMessage, err := genAppStateFromConfig(cdc, config, initCfg, *genDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -82,7 +82,6 @@ func genAppStateFromConfig(
|
|||
cdc *codec.Codec, config *cfg.Config, initCfg initConfig, genDoc types.GenesisDoc,
|
||||
) (appState json.RawMessage, err error) {
|
||||
|
||||
genFile := config.GenesisFile()
|
||||
var (
|
||||
appGenTxs []auth.StdTx
|
||||
persistentPeers string
|
||||
|
@ -116,7 +115,8 @@ func genAppStateFromConfig(
|
|||
return
|
||||
}
|
||||
|
||||
err = ExportGenesisFile(genFile, initCfg.ChainID, nil, appState)
|
||||
genDoc.AppState = appState
|
||||
err = ExportGenesisFile(&genDoc, config.GenesisFile())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
|
@ -58,7 +59,7 @@ func AddGenesisAccountCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command
|
|||
return fmt.Errorf("%s does not exist, run `gaiad init` first", genFile)
|
||||
}
|
||||
|
||||
genDoc, err := LoadGenesisDoc(cdc, genFile)
|
||||
genDoc, err := tmtypes.GenesisDocFromFile(genFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -78,7 +79,8 @@ func AddGenesisAccountCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command
|
|||
return err
|
||||
}
|
||||
|
||||
return ExportGenesisFile(genFile, genDoc.ChainID, nil, appStateJSON)
|
||||
genDoc.AppState = appStateJSON
|
||||
return ExportGenesisFile(genDoc, genFile)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/tendermint/tendermint/crypto"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
|
@ -79,7 +80,7 @@ following delegation and commission default parameters:
|
|||
"the tx's memo field will be unset")
|
||||
}
|
||||
|
||||
genDoc, err := LoadGenesisDoc(cdc, config.GenesisFile())
|
||||
genDoc, err := tmtypes.GenesisDocFromFile(config.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -3,15 +3,16 @@ package init
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/require"
|
||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
|
||||
)
|
||||
|
||||
func Test_prepareFlagsForTxCreateValidator(t *testing.T) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
|
@ -76,7 +77,22 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { // nolint:
|
|||
return err
|
||||
}
|
||||
|
||||
if err = ExportGenesisFile(genFile, chainID, nil, appState); err != nil {
|
||||
genDoc := &types.GenesisDoc{}
|
||||
if _, err := os.Stat(genFile); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
genDoc, err = types.GenesisDocFromFile(genFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
genDoc.ChainID = chainID
|
||||
genDoc.Validators = nil
|
||||
genDoc.AppState = appState
|
||||
if err = ExportGenesisFile(genDoc, genFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -8,16 +8,17 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"github.com/cosmos/cosmos-sdk/server/mock"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/require"
|
||||
abciServer "github.com/tendermint/tendermint/abci/server"
|
||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"github.com/cosmos/cosmos-sdk/server/mock"
|
||||
)
|
||||
|
||||
func TestInitCmd(t *testing.T) {
|
||||
|
|
|
@ -157,7 +157,7 @@ func initTestnet(config *tmconfig.Config, cdc *codec.Codec) error {
|
|||
|
||||
buf := client.BufferStdin()
|
||||
prompt := fmt.Sprintf(
|
||||
"Password for account '%s' (default %s):", nodeDirName, app.DefaultKeyPass,
|
||||
"Password for account '%s' (default %s):", nodeDirName, client.DefaultKeyPass,
|
||||
)
|
||||
|
||||
keyPass, err := client.GetPassword(prompt, buf)
|
||||
|
@ -169,7 +169,7 @@ func initTestnet(config *tmconfig.Config, cdc *codec.Codec) error {
|
|||
}
|
||||
|
||||
if keyPass == "" {
|
||||
keyPass = app.DefaultKeyPass
|
||||
keyPass = client.DefaultKeyPass
|
||||
}
|
||||
|
||||
addr, secret, err := server.GenerateSaveCoinKey(clientDir, nodeDirName, keyPass, true)
|
||||
|
@ -217,7 +217,7 @@ func initTestnet(config *tmconfig.Config, cdc *codec.Codec) error {
|
|||
tx := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo)
|
||||
txBldr := authtx.NewTxBuilderFromCLI().WithChainID(chainID).WithMemo(memo).WithKeybase(kb)
|
||||
|
||||
signedTx, err := txBldr.SignStdTx(nodeDirName, app.DefaultKeyPass, tx, false)
|
||||
signedTx, err := txBldr.SignStdTx(nodeDirName, client.DefaultKeyPass, tx, false)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(outDir)
|
||||
return err
|
||||
|
@ -306,12 +306,12 @@ func collectGenFiles(
|
|||
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
|
||||
initCfg := newInitConfig(chainID, gentxsDir, moniker, nodeID, valPubKey)
|
||||
|
||||
genDoc, err := LoadGenesisDoc(cdc, config.GenesisFile())
|
||||
genDoc, err := types.GenesisDocFromFile(config.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nodeAppState, err := genAppStateFromConfig(cdc, config, initCfg, genDoc)
|
||||
nodeAppState, err := genAppStateFromConfig(cdc, config, initCfg, *genDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -3,11 +3,9 @@ package init
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
amino "github.com/tendermint/go-amino"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
|
@ -22,16 +20,7 @@ import (
|
|||
|
||||
// ExportGenesisFile creates and writes the genesis configuration to disk. An
|
||||
// error is returned if building or writing the configuration to file fails.
|
||||
func ExportGenesisFile(
|
||||
genFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage,
|
||||
) error {
|
||||
|
||||
genDoc := types.GenesisDoc{
|
||||
ChainID: chainID,
|
||||
Validators: validators,
|
||||
AppState: appState,
|
||||
}
|
||||
|
||||
func ExportGenesisFile(genDoc *types.GenesisDoc, genFile string) error {
|
||||
if err := genDoc.ValidateAndComplete(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -88,20 +77,6 @@ func InitializeNodeValidatorFiles(
|
|||
return nodeID, valPubKey, nil
|
||||
}
|
||||
|
||||
// LoadGenesisDoc reads and unmarshals GenesisDoc from the given file.
|
||||
func LoadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) {
|
||||
genContents, err := ioutil.ReadFile(genFile)
|
||||
if err != nil {
|
||||
return genDoc, err
|
||||
}
|
||||
|
||||
if err := cdc.UnmarshalJSON(genContents, &genDoc); err != nil {
|
||||
return genDoc, err
|
||||
}
|
||||
|
||||
return genDoc, err
|
||||
}
|
||||
|
||||
func initializeEmptyGenesis(
|
||||
cdc *codec.Codec, genFile, chainID string, overwrite bool,
|
||||
) (appState json.RawMessage, err error) {
|
||||
|
|
|
@ -2,13 +2,10 @@ package init
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -22,28 +19,3 @@ func TestExportGenesisFileWithTime(t *testing.T) {
|
|||
fname := filepath.Join(dir, "genesis.json")
|
||||
require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now()))
|
||||
}
|
||||
|
||||
func TestLoadGenesisDoc(t *testing.T) {
|
||||
t.Parallel()
|
||||
dir, cleanup := tests.NewTestCaseDir(t)
|
||||
defer cleanup()
|
||||
|
||||
fname := filepath.Join(dir, "genesis.json")
|
||||
require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now()))
|
||||
|
||||
_, err := LoadGenesisDoc(codec.Cdc, fname)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Non-existing file
|
||||
_, err = LoadGenesisDoc(codec.Cdc, "non-existing-file")
|
||||
require.Error(t, err)
|
||||
|
||||
malformedFilename := filepath.Join(dir, "malformed")
|
||||
malformedFile, err := os.Create(malformedFilename)
|
||||
require.NoError(t, err)
|
||||
fmt.Fprint(malformedFile, "invalidjson")
|
||||
malformedFile.Close()
|
||||
// Non-existing file
|
||||
_, err = LoadGenesisDoc(codec.Cdc, malformedFilename)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
|
|
@ -4,11 +4,12 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// Validate genesis command takes
|
||||
|
@ -30,8 +31,8 @@ func ValidateGenesisCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
|||
//nolint
|
||||
fmt.Fprintf(os.Stderr, "validating genesis file at %s\n", genesis)
|
||||
|
||||
var genDoc types.GenesisDoc
|
||||
if genDoc, err = LoadGenesisDoc(cdc, genesis); err != nil {
|
||||
var genDoc *types.GenesisDoc
|
||||
if genDoc, err = types.GenesisDocFromFile(genesis); err != nil {
|
||||
return fmt.Errorf("Error loading genesis doc from %s: %s", genesis, err.Error())
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
########################################
|
||||
### Simulations
|
||||
|
||||
sim-gaia-nondeterminism:
|
||||
@echo "Running nondeterminism test..."
|
||||
@go test -mod=readonly ./cmd/gaia/app -run TestAppStateDeterminism -SimulationEnabled=true -v -timeout 10m
|
||||
|
||||
sim-gaia-custom-genesis-fast:
|
||||
@echo "Running custom genesis simulation..."
|
||||
@echo "By default, ${HOME}/.gaiad/config/genesis.json will be used."
|
||||
@go test -mod=readonly github.com/cosmos/cosmos-sdk/cmd/gaia/app -run TestFullGaiaSimulation -SimulationGenesis=${HOME}/.gaiad/config/genesis.json \
|
||||
-SimulationEnabled=true -SimulationNumBlocks=100 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=99 -SimulationPeriod=5 -v -timeout 24h
|
||||
|
||||
sim-gaia-fast:
|
||||
@echo "Running quick Gaia simulation. This may take several minutes..."
|
||||
@go test -mod=readonly github.com/cosmos/cosmos-sdk/cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=100 -SimulationBlockSize=200 -SimulationCommit=true -SimulationSeed=99 -SimulationPeriod=5 -v -timeout 24h
|
||||
|
||||
sim-gaia-import-export:
|
||||
@echo "Running Gaia import/export simulation. This may take several minutes..."
|
||||
@bash contrib/sim/multisim.sh 50 5 TestGaiaImportExport
|
||||
|
||||
sim-gaia-simulation-after-import:
|
||||
@echo "Running Gaia simulation-after-import. This may take several minutes..."
|
||||
@bash contrib/sim/multisim.sh 50 5 TestGaiaSimulationAfterImport
|
||||
|
||||
sim-gaia-custom-genesis-multi-seed:
|
||||
@echo "Running multi-seed custom genesis simulation..."
|
||||
@echo "By default, ${HOME}/.gaiad/config/genesis.json will be used."
|
||||
@bash contrib/sim/multisim.sh 400 5 TestFullGaiaSimulation ${HOME}/.gaiad/config/genesis.json
|
||||
|
||||
sim-gaia-multi-seed:
|
||||
@echo "Running multi-seed Gaia simulation. This may take awhile!"
|
||||
@bash contrib/sim/multisim.sh 400 5 TestFullGaiaSimulation
|
||||
|
||||
sim-benchmark-invariants:
|
||||
@echo "Running simulation invariant benchmarks..."
|
||||
@go test -mod=readonly github.com/cosmos/cosmos-sdk/cmd/gaia/app -benchmem -bench=BenchmarkInvariants -run=^$ \
|
||||
-SimulationEnabled=true -SimulationNumBlocks=1000 -SimulationBlockSize=200 \
|
||||
-SimulationCommit=true -SimulationSeed=57 -v -timeout 24h
|
||||
|
||||
SIM_NUM_BLOCKS ?= 500
|
||||
SIM_BLOCK_SIZE ?= 200
|
||||
SIM_COMMIT ?= true
|
||||
sim-gaia-benchmark:
|
||||
@echo "Running Gaia benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
|
||||
@go test -mod=readonly -benchmem -run=^$$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$$ \
|
||||
-SimulationEnabled=true -SimulationNumBlocks=$(SIM_NUM_BLOCKS) -SimulationBlockSize=$(SIM_BLOCK_SIZE) -SimulationCommit=$(SIM_COMMIT) -timeout 24h
|
||||
|
||||
sim-gaia-profile:
|
||||
@echo "Running Gaia benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
|
||||
@go test -mod=readonly -benchmem -run=^$$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$$ \
|
||||
-SimulationEnabled=true -SimulationNumBlocks=$(SIM_NUM_BLOCKS) -SimulationBlockSize=$(SIM_BLOCK_SIZE) -SimulationCommit=$(SIM_COMMIT) -timeout 24h -cpuprofile cpu.out -memprofile mem.out
|
||||
|
||||
.PHONY: sim-gaia-nondeterminism sim-gaia-custom-genesis-fast sim-gaia-fast sim-gaia-import-export \
|
||||
sim-gaia-simulation-after-import sim-gaia-custom-genesis-multi-seed sim-gaia-multi-seed \
|
||||
sim-benchmark-invariants sim-gaia-benchmark sim-gaia-profile
|
|
@ -5,7 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
)
|
||||
|
||||
// amino codec to marshal/unmarshal
|
||||
|
|
|
@ -44,11 +44,11 @@ mkfile_dir := $(shell cd $(shell dirname $(mkfile_path)); pwd)
|
|||
all: tools
|
||||
|
||||
tools: tools-stamp
|
||||
tools-stamp: $(GOBIN)/golangci-lint $(GOBIN)/statik $(GOBIN)/goimports $(GOBIN)/gosum $(GOBIN)/sdkch
|
||||
tools-stamp: $(GOBIN)/golangci-lint $(GOBIN)/statik $(GOBIN)/goimports $(GOBIN)/gosum $(GOBIN)/clog
|
||||
touch $@
|
||||
|
||||
$(GOBIN)/golangci-lint: contrib/install-golangci-lint.sh $(GOBIN)/gosum
|
||||
bash contrib/install-golangci-lint.sh $(GOBIN) $(GOLANGCI_LINT_VERSION) $(GOLANGCI_LINT_HASHSUM)
|
||||
$(GOBIN)/golangci-lint: $(mkfile_dir)/install-golangci-lint.sh $(GOBIN)/gosum
|
||||
bash $(mkfile_dir)/install-golangci-lint.sh $(GOBIN) $(GOLANGCI_LINT_VERSION) $(GOLANGCI_LINT_HASHSUM)
|
||||
|
||||
$(GOBIN)/statik:
|
||||
$(call go_install,rakyll,statik,v0.1.5)
|
||||
|
@ -57,13 +57,13 @@ $(GOBIN)/goimports:
|
|||
go get golang.org/x/tools/cmd/goimports@v0.0.0-20190114222345-bf090417da8b
|
||||
|
||||
$(GOBIN)/gosum:
|
||||
go install -mod=readonly ./cmd/gosum/
|
||||
go install -mod=readonly github.com/cosmos/cosmos-sdk/contrib/devtools/gosum/
|
||||
|
||||
$(GOBIN)/sdkch:
|
||||
go install -mod=readonly ./cmd/sdkch/
|
||||
$(GOBIN)/clog:
|
||||
go install -mod=readonly github.com/cosmos/cosmos-sdk/contrib/devtools/clog/
|
||||
|
||||
tools-clean:
|
||||
cd $(GOBIN) && rm -f golangci-lint statik goimports gosum sdkch
|
||||
cd $(GOBIN) && rm -f golangci-lint statik goimports gosum clog
|
||||
rm -f tools-stamp
|
||||
|
||||
.PHONY: all tools tools-clean
|
|
@ -7,12 +7,13 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -26,8 +27,9 @@ var (
|
|||
progName string
|
||||
verboseLog *log.Logger
|
||||
|
||||
entriesDir string
|
||||
verboseLogging bool
|
||||
entriesDir string
|
||||
verboseLogging bool
|
||||
interactiveMode bool
|
||||
|
||||
// sections name-title map
|
||||
sections = map[string]string{
|
||||
|
@ -44,22 +46,91 @@ var (
|
|||
"sdk": "SDK",
|
||||
"tendermint": "Tendermint",
|
||||
}
|
||||
|
||||
// RootCmd represents the base command when called without any subcommands
|
||||
RootCmd = &cobra.Command{
|
||||
Use: "clog",
|
||||
Short: "Maintain unreleased changelog entries in a modular fashion.",
|
||||
}
|
||||
|
||||
// command to add a pending log entry
|
||||
AddCmd = &cobra.Command{
|
||||
Use: "add [section] [stanza] [message]",
|
||||
Short: "Add an entry file.",
|
||||
Long: `Add an entry file. If message is empty, start the editor to edit the message.
|
||||
|
||||
Sections Stanzas
|
||||
--- ---
|
||||
breaking gaia
|
||||
features gaiacli
|
||||
improvements gaiarest
|
||||
bugfixes sdk
|
||||
tendermint`,
|
||||
Args: cobra.MaximumNArgs(3),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if interactiveMode {
|
||||
return addEntryFileFromConsoleInput()
|
||||
}
|
||||
|
||||
if len(args) < 2 {
|
||||
log.Println("must include at least 2 arguments when not in interactive mode")
|
||||
return nil
|
||||
}
|
||||
sectionDir, stanzaDir := args[0], args[1]
|
||||
err := validateSectionStanzaDirs(sectionDir, stanzaDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(args) == 3 {
|
||||
return addSinglelineEntryFile(sectionDir, stanzaDir, strings.TrimSpace(args[2]))
|
||||
}
|
||||
return addEntryFile(sectionDir, stanzaDir)
|
||||
},
|
||||
}
|
||||
|
||||
// command to generate the changelog
|
||||
GenerateCmd = &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate a changelog in Markdown format and print it to STDOUT. version defaults to UNRELEASED.",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
version := "UNRELEASED"
|
||||
if flag.NArg() > 1 {
|
||||
version = strings.Join(flag.Args()[1:], " ")
|
||||
}
|
||||
return generateChangelog(version)
|
||||
},
|
||||
}
|
||||
|
||||
// command to delete empty sub-directories recursively
|
||||
PruneCmd = &cobra.Command{
|
||||
Use: "prune",
|
||||
Short: "Delete empty sub-directories recursively.",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return pruneEmptyDirectories()
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
progName = filepath.Base(os.Args[0])
|
||||
RootCmd.AddCommand(AddCmd)
|
||||
RootCmd.AddCommand(GenerateCmd)
|
||||
RootCmd.AddCommand(PruneCmd)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
flag.StringVar(&entriesDir, "d", filepath.Join(cwd, entriesDirName), "entry files directory")
|
||||
flag.BoolVar(&verboseLogging, "v", false, "enable verbose logging")
|
||||
flag.Usage = printUsage
|
||||
|
||||
AddCmd.Flags().BoolVarP(&interactiveMode, "interactive", "i", false, "get the section/stanza/message with interactive CLI prompts")
|
||||
RootCmd.PersistentFlags().BoolVarP(&verboseLogging, "verbose-logging", "v", false, "enable verbose logging")
|
||||
RootCmd.PersistentFlags().StringVarP(&entriesDir, "entries-dir", "d", filepath.Join(cwd, entriesDirName), "entry files directory")
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
logPrefix := fmt.Sprintf("%s: ", filepath.Base(progName))
|
||||
log.SetFlags(0)
|
||||
log.SetPrefix(logPrefix)
|
||||
|
@ -70,67 +141,65 @@ func main() {
|
|||
verboseLog.SetPrefix(logPrefix)
|
||||
}
|
||||
|
||||
if flag.NArg() < 1 {
|
||||
errInsufficientArgs()
|
||||
}
|
||||
|
||||
cmd := flag.Arg(0)
|
||||
switch cmd {
|
||||
|
||||
case "add":
|
||||
if flag.NArg() < 3 {
|
||||
errInsufficientArgs()
|
||||
}
|
||||
if flag.NArg() > 4 {
|
||||
errTooManyArgs()
|
||||
}
|
||||
sectionDir, stanzaDir := flag.Arg(1), flag.Arg(2)
|
||||
validateSectionStanzaDirs(sectionDir, stanzaDir)
|
||||
if flag.NArg() == 4 {
|
||||
addSinglelineEntryFile(sectionDir, stanzaDir, strings.TrimSpace(flag.Arg(3)))
|
||||
return
|
||||
}
|
||||
addEntryFile(sectionDir, stanzaDir)
|
||||
|
||||
case "generate":
|
||||
version := "UNRELEASED"
|
||||
if flag.NArg() > 1 {
|
||||
version = strings.Join(flag.Args()[1:], " ")
|
||||
}
|
||||
generateChangelog(version)
|
||||
|
||||
case "prune":
|
||||
pruneEmptyDirectories()
|
||||
|
||||
default:
|
||||
unknownCommand(cmd)
|
||||
if err := RootCmd.Execute(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func addSinglelineEntryFile(sectionDir, stanzaDir, message string) {
|
||||
func addEntryFileFromConsoleInput() error {
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
fmt.Println("Please enter the section (either: \"breaking\", \"features\", \"improvements\", \"bugfixes\")")
|
||||
sectionDir, _ := reader.ReadString('\n')
|
||||
sectionDir = strings.TrimSpace(sectionDir)
|
||||
if _, ok := sections[sectionDir]; !ok {
|
||||
return errors.New("invalid section, please try again")
|
||||
}
|
||||
|
||||
fmt.Println("Please enter the stanza (either: \"gaia\", \"gaiacli\", \"gaiarest\", \"sdk\", \"tendermint\")")
|
||||
stanzaDir, _ := reader.ReadString('\n')
|
||||
stanzaDir = strings.TrimSpace(stanzaDir)
|
||||
if _, ok := stanzas[stanzaDir]; !ok {
|
||||
return errors.New("invalid stanza, please try again")
|
||||
}
|
||||
|
||||
fmt.Println("Please enter the changelog message (or press enter to write in default $EDITOR)")
|
||||
message, _ := reader.ReadString('\n')
|
||||
message = strings.TrimSpace(message)
|
||||
if message == "" {
|
||||
return addEntryFile(sectionDir, stanzaDir)
|
||||
}
|
||||
|
||||
return addSinglelineEntryFile(sectionDir, stanzaDir, message)
|
||||
}
|
||||
|
||||
func addSinglelineEntryFile(sectionDir, stanzaDir, message string) error {
|
||||
filename := filepath.Join(
|
||||
filepath.Join(entriesDir, sectionDir, stanzaDir),
|
||||
generateFileName(message),
|
||||
)
|
||||
|
||||
writeEntryFile(filename, []byte(message))
|
||||
return writeEntryFile(filename, []byte(message))
|
||||
}
|
||||
|
||||
func addEntryFile(sectionDir, stanzaDir string) {
|
||||
bs := readUserInput()
|
||||
func addEntryFile(sectionDir, stanzaDir string) error {
|
||||
bs, err := readUserInputFromEditor()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
firstLine := strings.TrimSpace(strings.Split(string(bs), "\n")[0])
|
||||
filename := filepath.Join(
|
||||
filepath.Join(entriesDir, sectionDir, stanzaDir),
|
||||
generateFileName(firstLine),
|
||||
)
|
||||
|
||||
writeEntryFile(filename, bs)
|
||||
return writeEntryFile(filename, bs)
|
||||
}
|
||||
|
||||
var filenameInvalidChars = regexp.MustCompile(`[^a-zA-Z0-9-_]`)
|
||||
|
||||
func generateFileName(line string) string {
|
||||
var chunks []string
|
||||
|
||||
filenameInvalidChars := regexp.MustCompile(`[^a-zA-Z0-9-_]`)
|
||||
subsWithInvalidCharsRemoved := strings.Split(filenameInvalidChars.ReplaceAllString(line, " "), " ")
|
||||
for _, sub := range subsWithInvalidCharsRemoved {
|
||||
sub = strings.TrimSpace(sub)
|
||||
|
@ -140,17 +209,21 @@ func generateFileName(line string) string {
|
|||
}
|
||||
|
||||
ret := strings.Join(chunks, "-")
|
||||
return ret[:int(math.Min(float64(len(ret)), float64(maxEntryFilenameLength)))]
|
||||
|
||||
if len(ret) > maxEntryFilenameLength {
|
||||
return ret[:maxEntryFilenameLength]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func directoryContents(dirPath string) []os.FileInfo {
|
||||
func directoryContents(dirPath string) ([]os.FileInfo, error) {
|
||||
contents, err := ioutil.ReadDir(dirPath)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
log.Fatalf("couldn't read directory %s: %v", dirPath, err)
|
||||
return nil, fmt.Errorf("couldn't read directory %s: %v", dirPath, err)
|
||||
}
|
||||
|
||||
if len(contents) == 0 {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Filter out hidden files
|
||||
|
@ -164,16 +237,19 @@ func directoryContents(dirPath string) []os.FileInfo {
|
|||
contents[i] = nil
|
||||
}
|
||||
|
||||
return newContents
|
||||
return newContents, nil
|
||||
}
|
||||
|
||||
func generateChangelog(version string) {
|
||||
func generateChangelog(version string) error {
|
||||
fmt.Printf("# %s\n\n", version)
|
||||
for sectionDir, sectionTitle := range sections {
|
||||
sectionTitlePrinted := false
|
||||
for stanzaDir, stanzaTitle := range stanzas {
|
||||
path := filepath.Join(entriesDir, sectionDir, stanzaDir)
|
||||
files := directoryContents(path)
|
||||
files, err := directoryContents(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(files) == 0 {
|
||||
continue
|
||||
}
|
||||
|
@ -188,22 +264,27 @@ func generateChangelog(version string) {
|
|||
verboseLog.Println("processing", f.Name())
|
||||
filename := filepath.Join(path, f.Name())
|
||||
if err := indentAndPrintFile(filename); err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func pruneEmptyDirectories() {
|
||||
for sectionDir, _ := range sections {
|
||||
for stanzaDir, _ := range stanzas {
|
||||
mustPruneDirIfEmpty(filepath.Join(entriesDir, sectionDir, stanzaDir))
|
||||
func pruneEmptyDirectories() error {
|
||||
for sectionDir := range sections {
|
||||
for stanzaDir := range stanzas {
|
||||
err := mustPruneDirIfEmpty(filepath.Join(entriesDir, sectionDir, stanzaDir))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
mustPruneDirIfEmpty(filepath.Join(entriesDir, sectionDir))
|
||||
return mustPruneDirIfEmpty(filepath.Join(entriesDir, sectionDir))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
|
@ -238,45 +319,47 @@ func indentAndPrintFile(filename string) error {
|
|||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func writeEntryFile(filename string, bs []byte) {
|
||||
func writeEntryFile(filename string, bs []byte) error {
|
||||
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
outFile, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
if _, err := outFile.Write(bs); err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Unreleased changelog entry written to: %s\n", filename)
|
||||
log.Println("To modify this entry please edit or delete the above file directly.")
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateSectionStanzaDirs(sectionDir, stanzaDir string) {
|
||||
func validateSectionStanzaDirs(sectionDir, stanzaDir string) error {
|
||||
if _, ok := sections[sectionDir]; !ok {
|
||||
log.Fatalf("invalid section -- %s", sectionDir)
|
||||
return fmt.Errorf("invalid section -- %s", sectionDir)
|
||||
}
|
||||
if _, ok := stanzas[stanzaDir]; !ok {
|
||||
log.Fatalf("invalid stanza -- %s", stanzaDir)
|
||||
return fmt.Errorf("invalid stanza -- %s", stanzaDir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func readUserInput() []byte {
|
||||
func readUserInputFromEditor() ([]byte, error) {
|
||||
tempfilename, err := launchUserEditor()
|
||||
if err != nil {
|
||||
log.Fatalf("couldn't open an editor: %v", err)
|
||||
return []byte{}, fmt.Errorf("couldn't open an editor: %v", err)
|
||||
}
|
||||
defer os.Remove(tempfilename)
|
||||
bs, err := ioutil.ReadFile(tempfilename)
|
||||
if err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
return []byte{}, fmt.Errorf("error: %v", err)
|
||||
}
|
||||
return bs
|
||||
return bs, nil
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
|
@ -296,7 +379,7 @@ func launchUserEditor() (string, error) {
|
|||
"VISUAL or EDITOR variables is set and pointing to a correct editor")
|
||||
}
|
||||
|
||||
tempfile, err := ioutil.TempFile("", "sdkch_*")
|
||||
tempfile, err := ioutil.TempFile("", "clog_*")
|
||||
tempfilename := tempfile.Name()
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -317,62 +400,28 @@ func launchUserEditor() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
if fileInfo.Size() == 0 {
|
||||
log.Fatal("aborting due to empty message")
|
||||
return "", errors.New("aborting due to empty message")
|
||||
}
|
||||
|
||||
return tempfilename, nil
|
||||
}
|
||||
|
||||
func mustPruneDirIfEmpty(path string) {
|
||||
if contents := directoryContents(path); len(contents) == 0 {
|
||||
if err := os.Remove(path); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Println(path, "removed")
|
||||
func mustPruneDirIfEmpty(path string) error {
|
||||
contents, err := directoryContents(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func printUsage() {
|
||||
usageText := fmt.Sprintf(`usage: %s [-d directory] [-v] command
|
||||
|
||||
Maintain unreleased changelog entries in a modular fashion.
|
||||
|
||||
Commands:
|
||||
add [section] [stanza] [message] Add an entry file. If message is empty, start
|
||||
the editor to edit the message.
|
||||
generate [version] Generate a changelog in Markdown format and print
|
||||
it to STDOUT. version defaults to UNRELEASED.
|
||||
prune Delete empty sub-directories recursively.
|
||||
|
||||
Sections Stanzas
|
||||
--- ---
|
||||
breaking gaia
|
||||
features gaiacli
|
||||
improvements gaiarest
|
||||
bugfixes sdk
|
||||
tendermint
|
||||
`, progName)
|
||||
fmt.Fprintf(os.Stderr, "%s\nFlags:\n", usageText)
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
func errInsufficientArgs() {
|
||||
log.Println("insufficient arguments")
|
||||
printUsage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func errTooManyArgs() {
|
||||
log.Println("too many arguments")
|
||||
printUsage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func unknownCommand(cmd string) {
|
||||
log.Fatalf("unknown command -- '%s'\nTry '%s -help' for more information.", cmd, progName)
|
||||
if len(contents) != 0 {
|
||||
return nil
|
||||
}
|
||||
if err := os.Remove(path); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
log.Println(path, "removed")
|
||||
return nil
|
||||
}
|
||||
|
||||
// DONTCOVER
|
|
@ -1,8 +1,8 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
)
|
||||
|
||||
var cdc = amino.NewCodec()
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/go-bip39"
|
||||
bip39 "github.com/cosmos/go-bip39"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/go-bip39"
|
||||
bip39 "github.com/cosmos/go-bip39"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
|
@ -7,11 +7,12 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/armor"
|
||||
"github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
"github.com/tendermint/tendermint/crypto/xsalsa20symmetric"
|
||||
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
|
|
@ -3,11 +3,12 @@ package mintkey_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
|
||||
"github.com/stretchr/testify/require"
|
||||
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
|
||||
)
|
||||
|
||||
func TestArmorUnarmorPrivKey(t *testing.T) {
|
||||
|
|
|
@ -6,12 +6,13 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
bip39 "github.com/cosmos/go-bip39"
|
||||
"github.com/pkg/errors"
|
||||
secp256k1 "github.com/tendermint/btcd/btcec"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
||||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
)
|
||||
|
||||
// If ledger support (build tag) has been enabled, which implies a CGO dependency,
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
|
|
|
@ -7,11 +7,12 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/tests"
|
||||
|
||||
tmcrypto "github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLedgerErrorHandling(t *testing.T) {
|
||||
|
|
|
@ -7,7 +7,6 @@ Once you have finallized your application, install it using `go get`. The follow
|
|||
```bash
|
||||
go get github.com/<your_username>/cosmos-sdk
|
||||
cd $GOPATH/src/github.com/<your_username>/cosmos-sdk
|
||||
make get_vendor_deps
|
||||
make install
|
||||
make install_examples
|
||||
```
|
||||
|
|
|
@ -6,7 +6,18 @@ The bank module emits the following events/tags:
|
|||
|
||||
### MsgSend
|
||||
|
||||
| Key | Value |
|
||||
|-----------|---------------------------|
|
||||
| sender | {senderAccountAddress} |
|
||||
| recipient | {recipientAccountAddress} |
|
||||
| Key | Value |
|
||||
|-------------|---------------------------|
|
||||
| `action` | `send` |
|
||||
| `category` | `bank` |
|
||||
| `sender` | {senderAccountAddress} |
|
||||
| `recipient` | {recipientAccountAddress} |
|
||||
|
||||
### MsgMultiSend
|
||||
|
||||
| Key | Value |
|
||||
|-------------|---------------------------|
|
||||
| `action` | `multisend` |
|
||||
| `category` | `bank` |
|
||||
| `sender` | {senderAccountAddress} |
|
||||
| `recipient` | {recipientAccountAddress} |
|
||||
|
|
|
@ -6,8 +6,9 @@ The crisis module emits the following events/tags:
|
|||
|
||||
### MsgVerifyInvariance
|
||||
|
||||
| Key | Value |
|
||||
|-----------|---------------------|
|
||||
| action | verify_invariant |
|
||||
| sender | {message-sender} |
|
||||
| invariant | {invariant-route} |
|
||||
| Key | Value |
|
||||
|-------------|--------------------|
|
||||
| `action` | `verify_invariant` |
|
||||
| `category` | `crisis` |
|
||||
| `sender` | {message-sender} |
|
||||
| `invariant` | {invariant-route} |
|
||||
|
|
|
@ -6,25 +6,25 @@ The distribution module emits the following events/tags:
|
|||
|
||||
### MsgSetWithdrawAddress
|
||||
|
||||
| Key | Value |
|
||||
|-----------|---------------------------|
|
||||
| delegator | {delegatorAccountAddress} |
|
||||
|
||||
### MsgWithdrawDelegatorRewardsAll
|
||||
|
||||
| Key | Value |
|
||||
|-----------|---------------------------|
|
||||
| delegator | {delegatorAccountAddress} |
|
||||
| Key | Value |
|
||||
|------------|---------------------------|
|
||||
| `action` | `set_withdraw_address` |
|
||||
| `category` | `distribution` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
|
||||
### MsgWithdrawDelegatorReward
|
||||
|
||||
| Key | Value |
|
||||
|------------------|---------------------------|
|
||||
| delegator | {delegatorAccountAddress} |
|
||||
| source-validator | {srcOperatorAddress} |
|
||||
| Key | Value |
|
||||
|--------------------|-----------------------------|
|
||||
| `action` | `withdraw_delegator_reward` |
|
||||
| `category` | `distribution` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
| `source-validator` | {srcOperatorAddress} |
|
||||
|
||||
### MsgWithdrawValidatorRewardsAll
|
||||
### MsgWithdrawValidatorCommission
|
||||
|
||||
| Key | Value |
|
||||
|------------------|----------------------|
|
||||
| source-validator | {srcOperatorAddress} |
|
||||
| Key | Value |
|
||||
|------------|---------------------------------|
|
||||
| `action` | `withdraw_validator_commission` |
|
||||
| `category` | `distribution` |
|
||||
| `sender` | {srcOperatorAddress} |
|
||||
|
|
|
@ -4,35 +4,38 @@ The governance module emits the following events/tags:
|
|||
|
||||
## EndBlocker
|
||||
|
||||
| Key | Value |
|
||||
|-----------------|------------------------------------------------------|
|
||||
| proposal-result | proposal-passed\|proposal-rejected\|proposal-dropped |
|
||||
| Key | Value |
|
||||
|-------------------|------------------------------------------------------------|
|
||||
| `proposal-result` | `proposal-passed`\|`proposal-rejected`\|`proposal-dropped` |
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgSubmitProposal
|
||||
|
||||
| Key | Value |
|
||||
|-------------------------|--------------------------|
|
||||
| action | proposal-vote |
|
||||
| proposer | {proposerAccountAddress} |
|
||||
| proposal-id | {proposalID} |
|
||||
| voting-period-start [0] | {proposalID} |
|
||||
| Key | Value |
|
||||
|---------------------------|--------------------------|
|
||||
| `action` | `submit_proposal` |
|
||||
| `category` | `governance` |
|
||||
| `sender` | {proposerAccountAddress} |
|
||||
| `proposal-id` | {proposalID} |
|
||||
| `voting-period-start` [0] | {proposalID} |
|
||||
|
||||
* [0] Tag only emitted if the voting period starts during the submission.
|
||||
|
||||
### MsgVote
|
||||
|
||||
| Key | Value |
|
||||
|-------------|-----------------------|
|
||||
| action | proposal-vote |
|
||||
| voter | {voterAccountAddress} |
|
||||
| proposal-id | {proposalID} |
|
||||
| Key | Value |
|
||||
|---------------|-----------------------|
|
||||
| `action` | `vote` |
|
||||
| `category` | `governance` |
|
||||
| `sender` | {voterAccountAddress} |
|
||||
| `proposal-id` | {proposalID} |
|
||||
|
||||
### MsgDeposit
|
||||
|
||||
| Key | Value |
|
||||
|-------------|---------------------------|
|
||||
| action | proposal-vote |
|
||||
| depositor | {depositorAccountAddress} |
|
||||
| proposal-id | {proposalID} |
|
||||
| Key | Value |
|
||||
|---------------|---------------------------|
|
||||
| `action` | `deposit` |
|
||||
| `category` | `governance` |
|
||||
| `sender` | {depositorAccountAddress} |
|
||||
| `proposal-id` | {proposalID} |
|
||||
|
|
|
@ -8,7 +8,7 @@ The IBC protocol creates a mechanism by which two replicated fault-tolerant stat
|
|||
|
||||
The IBC protocol assumes that multiple applications are running on their own blockchain with their own state and own logic. Communication is achieved over an ordered message queue primitive, allowing the creation of complex inter-chain processes without trusted third parties.
|
||||
|
||||
The message packets are not signed by one psuedonymous account, or even multiple, as in multi-signature sidechain implementations. Rather, IBC assigns authorization of the packets to the source blockchain's consensus algorithm, performing light-client style verification on the destination chain. The Byzantine-fault-tolerant properties of the underlying blockchains are preserved: a user transferring assets between two chains using IBC must trust only the consensus algorithms of both chains.
|
||||
The message packets are not signed by one pseudonymous account, or even multiple, as in multi-signature sidechain implementations. Rather, IBC assigns authorization of the packets to the source blockchain's consensus algorithm, performing light-client style verification on the destination chain. The Byzantine-fault-tolerant properties of the underlying blockchains are preserved: a user transferring assets between two chains using IBC must trust only the consensus algorithms of both chains.
|
||||
|
||||
In this paper, we define a process of posting block headers and Merkle tree proofs to enable secure verification of individual packets. We then describe how to combine these packets into a messaging queue to guarantee ordered delivery. We then explain how to handle packet receipts (response/error) on the source chain, which enables the creation of asynchronous RPC-like protocols on top of IBC. Finally, we detail some optimizations and how to handle Byzantine blockchains.
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ The slashing module emits the following events/tags:
|
|||
|
||||
### MsgUnjail
|
||||
|
||||
| Key | Value |
|
||||
|-----------|----------------------------|
|
||||
| action | validator-unjailed |
|
||||
| validator | {validatorOperatorAddress} |
|
||||
| Key | Value |
|
||||
|------------|----------------------------|
|
||||
| `action` | `unjail` |
|
||||
| `category` | `slashing` |
|
||||
| `sender` | {validatorOperatorAddress} |
|
||||
|
|
|
@ -4,55 +4,62 @@ The staking module emits the following events/tags:
|
|||
|
||||
## EndBlocker
|
||||
|
||||
| Key | Value |
|
||||
|-----------------------|-------------------------------------------|
|
||||
| action | complete-unbonding\|complete-redelegation |
|
||||
| delegator | {delegatorAccountAddress} |
|
||||
| source-validator | {srcOperatorAddress} |
|
||||
| destination-validator | {dstOperatorAddress} |
|
||||
| Key | Value |
|
||||
|-------------------------|-----------------------------------------------|
|
||||
| `action` | `complete-unbonding`\|`complete-redelegation` |
|
||||
| `category` | `staking` |
|
||||
| `delegator` | {delegatorAccountAddress} |
|
||||
| `source-validator` | {srcOperatorAddress} |
|
||||
| `destination-validator` | {dstOperatorAddress} |
|
||||
|
||||
## Handlers
|
||||
|
||||
### MsgCreateValidator
|
||||
|
||||
| Key | Value |
|
||||
|-----------------------|----------------------|
|
||||
| destination-validator | {dstOperatorAddress} |
|
||||
| moniker | {validatorMoniker} |
|
||||
| identity | {validatorIdentity} |
|
||||
| Key | Value |
|
||||
|------------|----------------------|
|
||||
| `action` | `create_validator` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {dstOperatorAddress} |
|
||||
|
||||
### MsgEditValidator
|
||||
|
||||
| Key | Value |
|
||||
|-----------------------|----------------------|
|
||||
| destination-validator | {dstOperatorAddress} |
|
||||
| moniker | {validatorMoniker} |
|
||||
| identity | {validatorIdentity} |
|
||||
| Key | Value |
|
||||
|------------|----------------------|
|
||||
| `action` | `edit_validator` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {dstOperatorAddress} |
|
||||
|
||||
### MsgDelegate
|
||||
|
||||
| Key | Value |
|
||||
|-----------------------|-------------------------------------------|
|
||||
| delegator | {delegatorAccountAddress} |
|
||||
| destination-validator | {dstOperatorAddress} |
|
||||
| Key | Value |
|
||||
|-------------------------|---------------------------|
|
||||
| `action` | `delegate` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
| `destination-validator` | {dstOperatorAddress} |
|
||||
|
||||
### MsgBeginRedelegate
|
||||
|
||||
| Key | Value |
|
||||
|-----------------------|-------------------------------------------|
|
||||
| delegator | {delegatorAccountAddress} |
|
||||
| source-validator | {srcOperatorAddress} |
|
||||
| destination-validator | {dstOperatorAddress} |
|
||||
| end-time [0] | {delegationFinishTime} |
|
||||
| Key | Value |
|
||||
|-------------------------|---------------------------|
|
||||
| `action` | `begin_redelegate` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
| `source-validator` | {srcOperatorAddress} |
|
||||
| `destination-validator` | {dstOperatorAddress} |
|
||||
| `end-time` [0] | {delegationFinishTime} |
|
||||
|
||||
* [0] Time is formatted in the RFC3339 standard
|
||||
|
||||
### MsgUndelegate
|
||||
|
||||
| Key | Value |
|
||||
|------------------|---------------------------|
|
||||
| delegator | {delegatorAccountAddress} |
|
||||
| source-validator | {srcOperatorAddress} |
|
||||
| end-time [0] | {delegationFinishTime} |
|
||||
| Key | Value |
|
||||
|--------------------|---------------------------|
|
||||
| `action` | `begin_unbonding` |
|
||||
| `category` | `staking` |
|
||||
| `sender` | {delegatorAccountAddress} |
|
||||
| `source-validator` | {srcOperatorAddress} |
|
||||
| `end-time` [0] | {delegationFinishTime} |
|
||||
|
||||
* [0] Time is formatted in the RFC3339 standard
|
||||
|
|
|
@ -11,6 +11,7 @@ mkdir -p $HOME/go/bin
|
|||
echo "export GOPATH=$HOME/go" >> ~/.bash_profile
|
||||
echo "export GOBIN=\$GOPATH/bin" >> ~/.bash_profile
|
||||
echo "export PATH=\$PATH:\$GOBIN" >> ~/.bash_profile
|
||||
echo "export GO111MODULE=on" >> ~/.bash_profile
|
||||
source ~/.bash_profile
|
||||
```
|
||||
|
||||
|
@ -48,7 +49,7 @@ $ gaiacli version --long
|
|||
```
|
||||
cosmos-sdk: 0.33.0
|
||||
git commit: 7b4104aced52aa5b59a96c28b5ebeea7877fc4f0
|
||||
vendor hash: 5db0df3e24cf10545c84f462a24ddc61882aa58f
|
||||
go.sum hash: d156153bd5e128fec3868eca9a1397a63a864edb5cfa0ac486db1b574b8eecfe
|
||||
build tags: netgo ledger
|
||||
go version go1.12 linux/amd64
|
||||
```
|
||||
|
@ -63,4 +64,4 @@ build tags指定了可执行程序具有的特殊特性。
|
|||
| ledger | 支持Ledger设备(硬件钱包) |
|
||||
|
||||
### 接下来
|
||||
然后你可以选择 加入公共测试网 或是 创建私有测试网。
|
||||
然后你可以选择 加入公共测试网 或是 创建私有测试网。
|
||||
|
|
|
@ -11,6 +11,7 @@ mkdir -p $HOME/go/bin
|
|||
echo "export GOPATH=$HOME/go" >> ~/.bash_profile
|
||||
echo "export GOBIN=\$GOPATH/bin" >> ~/.bash_profile
|
||||
echo "export PATH=\$PATH:\$GOBIN" >> ~/.bash_profile
|
||||
echo "export GO111MODULE=on" >> ~/.bash_profile
|
||||
source ~/.bash_profile
|
||||
```
|
||||
|
||||
|
|
1
go.sum
1
go.sum
|
@ -24,6 +24,7 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa
|
|||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8 h1:Iwin12wRQtyZhH6FV3ykFcdGNlYEzoeR0jN8Vn+JWsI=
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
|
||||
|
|
|
@ -22,7 +22,7 @@ echo "export PATH=\$PATH:/usr/local/go/bin" >> ~/.profile
|
|||
mkdir go
|
||||
echo "export GOPATH=$HOME/go" >> ~/.profile
|
||||
echo "export PATH=\$PATH:\$GOPATH/bin" >> ~/.profile
|
||||
|
||||
echo "export GO111MODULE=on" >> ~/.profile
|
||||
source ~/.profile
|
||||
|
||||
# get the code and move into repo
|
||||
|
@ -32,7 +32,6 @@ cd $GOPATH/src/$REPO
|
|||
# build & install master
|
||||
git checkout $BRANCH
|
||||
LEDGER_ENABLED=false make tools
|
||||
LEDGER_ENABLED=false make get_vendor_deps
|
||||
LEDGER_ENABLED=false make install
|
||||
|
||||
source ~/.profile
|
||||
|
|
|
@ -48,6 +48,5 @@ cd $GOPATH/src/$REPO
|
|||
# build & install master
|
||||
git checkout $BRANCH
|
||||
gmake tools
|
||||
gmake get_vendor_deps
|
||||
gmake install
|
||||
gmake install_examples
|
||||
|
|
|
@ -25,7 +25,7 @@ echo "export PATH=\$PATH:/usr/local/go/bin" >> ~/.profile
|
|||
mkdir go
|
||||
echo "export GOPATH=$HOME/go" >> ~/.profile
|
||||
echo "export PATH=\$PATH:\$GOPATH/bin" >> ~/.profile
|
||||
|
||||
echo "export GO111MODULE=on" >> ~/.profile
|
||||
source ~/.profile
|
||||
|
||||
# get the code and move into repo
|
||||
|
@ -35,7 +35,6 @@ cd $GOPATH/src/$REPO
|
|||
# build & install master
|
||||
git checkout $BRANCH
|
||||
LEDGER_ENABLED=false make tools
|
||||
LEDGER_ENABLED=false make get_vendor_deps
|
||||
LEDGER_ENABLED=false make install
|
||||
|
||||
source ~/.profile
|
||||
|
|
|
@ -6,11 +6,12 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
type (
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/bech32"
|
||||
)
|
||||
|
|
|
@ -7,9 +7,10 @@ import (
|
|||
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
var invalidStrs = []string{
|
||||
|
|
|
@ -6,5 +6,5 @@ package types
|
|||
// The simulator will then halt and print the logs.
|
||||
type Invariant func(ctx Context) error
|
||||
|
||||
// group of Invarient
|
||||
// Invariants defines a group of invariants
|
||||
type Invariants []Invariant
|
||||
|
|
|
@ -5,13 +5,14 @@ package rest
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
|
|
@ -71,6 +71,8 @@ func MakeTag(k string, v string) Tag {
|
|||
// common tags
|
||||
var (
|
||||
TagAction = "action"
|
||||
TagCategory = "category"
|
||||
TagSender = "sender"
|
||||
TagSrcValidator = "source-validator"
|
||||
TagDstValidator = "destination-validator"
|
||||
TagDelegator = "delegator"
|
||||
|
|
|
@ -8,33 +8,33 @@ import (
|
|||
|
||||
// Variables set by build flags
|
||||
var (
|
||||
Commit = ""
|
||||
Version = ""
|
||||
VendorDirHash = ""
|
||||
BuildTags = ""
|
||||
Commit = ""
|
||||
Version = ""
|
||||
GoSumHash = ""
|
||||
BuildTags = ""
|
||||
)
|
||||
|
||||
type versionInfo struct {
|
||||
CosmosSDK string `json:"cosmos_sdk"`
|
||||
GitCommit string `json:"commit"`
|
||||
VendorDirHash string `json:"vendor_hash"`
|
||||
BuildTags string `json:"build_tags"`
|
||||
GoVersion string `json:"go"`
|
||||
CosmosSDK string `json:"cosmos_sdk"`
|
||||
GitCommit string `json:"commit"`
|
||||
GoSumHash string `json:"gosum_hash"`
|
||||
BuildTags string `json:"build_tags"`
|
||||
GoVersion string `json:"go"`
|
||||
}
|
||||
|
||||
func (v versionInfo) String() string {
|
||||
return fmt.Sprintf(`cosmos-sdk: %s
|
||||
git commit: %s
|
||||
vendor hash: %s
|
||||
go.sum hash: %s
|
||||
build tags: %s
|
||||
%s`, v.CosmosSDK, v.GitCommit, v.VendorDirHash, v.BuildTags, v.GoVersion)
|
||||
%s`, v.CosmosSDK, v.GitCommit, v.GoSumHash, v.BuildTags, v.GoVersion)
|
||||
}
|
||||
|
||||
func newVersionInfo() versionInfo {
|
||||
return versionInfo{
|
||||
Version,
|
||||
Commit,
|
||||
VendorDirHash,
|
||||
GoSumHash,
|
||||
BuildTags,
|
||||
fmt.Sprintf("go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,9 @@ func QueryAccountRequestHandlerFn(
|
|||
return
|
||||
}
|
||||
|
||||
// the query will return empty if there is no data for this account
|
||||
// the query will return empty account if there is no data
|
||||
if len(res) == 0 {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
rest.PostProcessResponse(w, cdc, auth.BaseAccount{}, cliCtx.Indent)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ func QueryBalancesRequestHandlerFn(
|
|||
|
||||
// the query will return empty if there is no data for this account
|
||||
if len(res) == 0 {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
rest.PostProcessResponse(w, cdc, sdk.Coins{}, cliCtx.Indent)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -178,8 +178,7 @@ func (bldr TxBuilder) WithAccountNumber(accnum uint64) TxBuilder {
|
|||
// set of messages. It returns an error if a fee is supplied but cannot be
|
||||
// parsed.
|
||||
func (bldr TxBuilder) BuildSignMsg(msgs []sdk.Msg) (StdSignMsg, error) {
|
||||
chainID := bldr.chainID
|
||||
if chainID == "" {
|
||||
if bldr.chainID == "" {
|
||||
return StdSignMsg{}, fmt.Errorf("chain ID required but not specified")
|
||||
}
|
||||
|
||||
|
@ -248,6 +247,10 @@ func (bldr TxBuilder) BuildTxForSim(msgs []sdk.Msg) ([]byte, error) {
|
|||
// SignStdTx appends a signature to a StdTx and returns a copy of it. If append
|
||||
// is false, it replaces the signatures already attached with the new signature.
|
||||
func (bldr TxBuilder) SignStdTx(name, passphrase string, stdTx auth.StdTx, appendSig bool) (signedStdTx auth.StdTx, err error) {
|
||||
if bldr.chainID == "" {
|
||||
return auth.StdTx{}, fmt.Errorf("chain ID required but not specified")
|
||||
}
|
||||
|
||||
stdSignature, err := MakeSignature(bldr.keybase, name, passphrase, StdSignMsg{
|
||||
ChainID: bldr.chainID,
|
||||
AccountNumber: bldr.accountNumber,
|
||||
|
|
|
@ -33,12 +33,14 @@ func TestTxBuilderBuild(t *testing.T) {
|
|||
}
|
||||
defaultMsg := []sdk.Msg{sdk.NewTestMsg(addr)}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
msgs []sdk.Msg
|
||||
want StdSignMsg
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
"builder with fees",
|
||||
fields{
|
||||
TxEncoder: auth.DefaultTxEncoder(codec.New()),
|
||||
AccountNumber: 1,
|
||||
|
@ -48,7 +50,7 @@ func TestTxBuilderBuild(t *testing.T) {
|
|||
SimulateGas: false,
|
||||
ChainID: "test-chain",
|
||||
Memo: "hello from Voyager 1!",
|
||||
Fees: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))},
|
||||
Fees: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))),
|
||||
},
|
||||
defaultMsg,
|
||||
StdSignMsg{
|
||||
|
@ -62,6 +64,7 @@ func TestTxBuilderBuild(t *testing.T) {
|
|||
false,
|
||||
},
|
||||
{
|
||||
"builder with gas prices",
|
||||
fields{
|
||||
TxEncoder: auth.DefaultTxEncoder(codec.New()),
|
||||
AccountNumber: 1,
|
||||
|
@ -84,19 +87,69 @@ func TestTxBuilderBuild(t *testing.T) {
|
|||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"no chain-id supplied",
|
||||
fields{
|
||||
TxEncoder: auth.DefaultTxEncoder(codec.New()),
|
||||
AccountNumber: 1,
|
||||
Sequence: 1,
|
||||
Gas: 200000,
|
||||
GasAdjustment: 1.1,
|
||||
SimulateGas: false,
|
||||
ChainID: "",
|
||||
Memo: "hello from Voyager 1!",
|
||||
Fees: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))),
|
||||
},
|
||||
defaultMsg,
|
||||
StdSignMsg{
|
||||
ChainID: "test-chain",
|
||||
AccountNumber: 1,
|
||||
Sequence: 1,
|
||||
Memo: "hello from Voyager 1!",
|
||||
Msgs: defaultMsg,
|
||||
Fee: auth.NewStdFee(200000, sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))}),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"builder w/ fees and gas prices",
|
||||
fields{
|
||||
TxEncoder: auth.DefaultTxEncoder(codec.New()),
|
||||
AccountNumber: 1,
|
||||
Sequence: 1,
|
||||
Gas: 200000,
|
||||
GasAdjustment: 1.1,
|
||||
SimulateGas: false,
|
||||
ChainID: "test-chain",
|
||||
Memo: "hello from Voyager 1!",
|
||||
Fees: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))),
|
||||
GasPrices: sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(10000, sdk.Precision))},
|
||||
},
|
||||
defaultMsg,
|
||||
StdSignMsg{
|
||||
ChainID: "test-chain",
|
||||
AccountNumber: 1,
|
||||
Sequence: 1,
|
||||
Memo: "hello from Voyager 1!",
|
||||
Msgs: defaultMsg,
|
||||
Fee: auth.NewStdFee(200000, sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))}),
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range tests {
|
||||
bldr := NewTxBuilder(
|
||||
tc.fields.TxEncoder, tc.fields.AccountNumber, tc.fields.Sequence,
|
||||
tc.fields.Gas, tc.fields.GasAdjustment, tc.fields.SimulateGas,
|
||||
tc.fields.ChainID, tc.fields.Memo, tc.fields.Fees, tc.fields.GasPrices,
|
||||
)
|
||||
|
||||
got, err := bldr.BuildSignMsg(tc.msgs)
|
||||
require.Equal(t, tc.wantErr, (err != nil), "TxBuilder.Build() error = %v, wantErr %v, tc %d", err, tc.wantErr, i)
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("TxBuilder.Build() = %v, want %v", got, tc.want)
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
bldr := NewTxBuilder(
|
||||
tt.fields.TxEncoder, tt.fields.AccountNumber, tt.fields.Sequence,
|
||||
tt.fields.Gas, tt.fields.GasAdjustment, tt.fields.SimulateGas,
|
||||
tt.fields.ChainID, tt.fields.Memo, tt.fields.Fees, tt.fields.GasPrices,
|
||||
)
|
||||
got, err := bldr.BuildSignMsg(tt.msgs)
|
||||
require.Equal(t, tt.wantErr, (err != nil))
|
||||
if err == nil {
|
||||
require.True(t, reflect.DeepEqual(tt.want, got))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
|
@ -47,15 +45,6 @@ func SendTxCmd(cdc *codec.Codec) *cobra.Command {
|
|||
}
|
||||
|
||||
from := cliCtx.GetFromAddress()
|
||||
account, err := cliCtx.GetAccount(from)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ensure account has enough coins
|
||||
if !account.GetCoins().IsAllGTE(coins) {
|
||||
return fmt.Errorf("address %s doesn't have enough coins to pay for this transaction", from)
|
||||
}
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
msg := bank.NewMsgSend(from, to, coins)
|
||||
|
|
|
@ -2,6 +2,7 @@ package bank
|
|||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/tags"
|
||||
)
|
||||
|
||||
// NewHandler returns a handler for "bank" type messages.
|
||||
|
@ -24,13 +25,19 @@ func handleMsgSend(ctx sdk.Context, k Keeper, msg MsgSend) sdk.Result {
|
|||
if !k.GetSendEnabled(ctx) {
|
||||
return ErrSendDisabled(k.Codespace()).Result()
|
||||
}
|
||||
tags, err := k.SendCoins(ctx, msg.FromAddress, msg.ToAddress, msg.Amount)
|
||||
err := k.SendCoins(ctx, msg.FromAddress, msg.ToAddress, msg.Amount)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
resTags := sdk.NewTags(
|
||||
tags.Category, tags.TxCategory,
|
||||
tags.Sender, msg.FromAddress.String(),
|
||||
tags.Recipient, msg.ToAddress.String(),
|
||||
)
|
||||
|
||||
return sdk.Result{
|
||||
Tags: tags,
|
||||
Tags: resTags,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,12 +47,13 @@ func handleMsgMultiSend(ctx sdk.Context, k Keeper, msg MsgMultiSend) sdk.Result
|
|||
if !k.GetSendEnabled(ctx) {
|
||||
return ErrSendDisabled(k.Codespace()).Result()
|
||||
}
|
||||
tags, err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs)
|
||||
resTags, err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
||||
resTags = resTags.AppendTag(tags.Category, tags.TxCategory)
|
||||
return sdk.Result{
|
||||
Tags: tags,
|
||||
Tags: resTags,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/tags"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
|
@ -17,8 +18,8 @@ type Keeper interface {
|
|||
SendKeeper
|
||||
|
||||
SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error
|
||||
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error)
|
||||
AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error)
|
||||
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error)
|
||||
AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error)
|
||||
InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error)
|
||||
|
||||
DelegateCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error)
|
||||
|
@ -60,10 +61,10 @@ func (keeper BaseKeeper) SetCoins(
|
|||
// SubtractCoins subtracts amt from the coins at the addr.
|
||||
func (keeper BaseKeeper) SubtractCoins(
|
||||
ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Coins, sdk.Tags, sdk.Error) {
|
||||
) (sdk.Coins, sdk.Error) {
|
||||
|
||||
if !amt.IsValid() {
|
||||
return nil, nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
return subtractCoins(ctx, keeper.ak, addr, amt)
|
||||
}
|
||||
|
@ -71,10 +72,10 @@ func (keeper BaseKeeper) SubtractCoins(
|
|||
// AddCoins adds amt to the coins at the addr.
|
||||
func (keeper BaseKeeper) AddCoins(
|
||||
ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Coins, sdk.Tags, sdk.Error) {
|
||||
) (sdk.Coins, sdk.Error) {
|
||||
|
||||
if !amt.IsValid() {
|
||||
return nil, nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
return addCoins(ctx, keeper.ak, addr, amt)
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ func (keeper BaseKeeper) UndelegateCoins(
|
|||
type SendKeeper interface {
|
||||
ViewKeeper
|
||||
|
||||
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error)
|
||||
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error
|
||||
|
||||
GetSendEnabled(ctx sdk.Context) bool
|
||||
SetSendEnabled(ctx sdk.Context, enabled bool)
|
||||
|
@ -150,10 +151,10 @@ func NewBaseSendKeeper(ak auth.AccountKeeper,
|
|||
// SendCoins moves coins from one account to another
|
||||
func (keeper BaseSendKeeper) SendCoins(
|
||||
ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins,
|
||||
) (sdk.Tags, sdk.Error) {
|
||||
) sdk.Error {
|
||||
|
||||
if !amt.IsValid() {
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
return sendCoins(ctx, keeper.ak, fromAddr, toAddr, amt)
|
||||
}
|
||||
|
@ -249,10 +250,10 @@ func setAccount(ctx sdk.Context, ak auth.AccountKeeper, acc auth.Account) {
|
|||
// subtractCoins subtracts amt coins from an account with the given address addr.
|
||||
//
|
||||
// CONTRACT: If the account is a vesting account, the amount has to be spendable.
|
||||
func subtractCoins(ctx sdk.Context, ak auth.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) {
|
||||
func subtractCoins(ctx sdk.Context, ak auth.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
|
||||
if !amt.IsValid() {
|
||||
return nil, nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
|
||||
oldCoins, spendableCoins := sdk.NewCoins(), sdk.NewCoins()
|
||||
|
@ -267,59 +268,57 @@ func subtractCoins(ctx sdk.Context, ak auth.AccountKeeper, addr sdk.AccAddress,
|
|||
// So the check here is sufficient instead of subtracting from oldCoins.
|
||||
_, hasNeg := spendableCoins.SafeSub(amt)
|
||||
if hasNeg {
|
||||
return amt, nil, sdk.ErrInsufficientCoins(
|
||||
return amt, sdk.ErrInsufficientCoins(
|
||||
fmt.Sprintf("insufficient account funds; %s < %s", spendableCoins, amt),
|
||||
)
|
||||
}
|
||||
|
||||
newCoins := oldCoins.Sub(amt) // should not panic as spendable coins was already checked
|
||||
err := setCoins(ctx, ak, addr, newCoins)
|
||||
tags := sdk.NewTags(TagKeySender, addr.String())
|
||||
|
||||
return newCoins, tags, err
|
||||
return newCoins, err
|
||||
}
|
||||
|
||||
// AddCoins adds amt to the coins at the addr.
|
||||
func addCoins(ctx sdk.Context, am auth.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) {
|
||||
func addCoins(ctx sdk.Context, am auth.AccountKeeper, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
|
||||
if !amt.IsValid() {
|
||||
return nil, nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
|
||||
oldCoins := getCoins(ctx, am, addr)
|
||||
newCoins := oldCoins.Add(amt)
|
||||
|
||||
if newCoins.IsAnyNegative() {
|
||||
return amt, nil, sdk.ErrInsufficientCoins(
|
||||
return amt, sdk.ErrInsufficientCoins(
|
||||
fmt.Sprintf("insufficient account funds; %s < %s", oldCoins, amt),
|
||||
)
|
||||
}
|
||||
|
||||
err := setCoins(ctx, am, addr, newCoins)
|
||||
tags := sdk.NewTags(TagKeyRecipient, addr.String())
|
||||
|
||||
return newCoins, tags, err
|
||||
return newCoins, err
|
||||
}
|
||||
|
||||
// SendCoins moves coins from one account to another
|
||||
// Returns ErrInvalidCoins if amt is invalid.
|
||||
func sendCoins(ctx sdk.Context, am auth.AccountKeeper, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error) {
|
||||
func sendCoins(ctx sdk.Context, am auth.AccountKeeper, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) sdk.Error {
|
||||
// Safety check ensuring that when sending coins the keeper must maintain the
|
||||
if !amt.IsValid() {
|
||||
return nil, sdk.ErrInvalidCoins(amt.String())
|
||||
return sdk.ErrInvalidCoins(amt.String())
|
||||
}
|
||||
|
||||
_, subTags, err := subtractCoins(ctx, am, fromAddr, amt)
|
||||
_, err := subtractCoins(ctx, am, fromAddr, amt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
_, addTags, err := addCoins(ctx, am, toAddr, amt)
|
||||
_, err = addCoins(ctx, am, toAddr, amt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
return subTags.AppendTags(addTags), nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// InputOutputCoins handles a list of inputs and outputs
|
||||
|
@ -334,19 +333,24 @@ func inputOutputCoins(ctx sdk.Context, am auth.AccountKeeper, inputs []Input, ou
|
|||
allTags := sdk.EmptyTags()
|
||||
|
||||
for _, in := range inputs {
|
||||
_, tags, err := subtractCoins(ctx, am, in.Address, in.Coins)
|
||||
_, err := subtractCoins(ctx, am, in.Address, in.Coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allTags = allTags.AppendTags(tags)
|
||||
|
||||
allTags = allTags.AppendTag(
|
||||
tags.Sender, in.Address.String(),
|
||||
)
|
||||
}
|
||||
|
||||
for _, out := range outputs {
|
||||
_, tags, err := addCoins(ctx, am, out.Address, out.Coins)
|
||||
_, err := addCoins(ctx, am, out.Address, out.Coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allTags = allTags.AppendTags(tags)
|
||||
allTags = allTags.AppendTag(
|
||||
tags.Recipient, out.Address.String(),
|
||||
)
|
||||
}
|
||||
|
||||
return allTags, nil
|
||||
|
@ -381,8 +385,8 @@ func delegateCoins(
|
|||
setAccount(ctx, ak, acc)
|
||||
|
||||
return sdk.NewTags(
|
||||
sdk.TagAction, TagActionDelegateCoins,
|
||||
sdk.TagDelegator, []byte(addr.String()),
|
||||
sdk.TagAction, tags.ActionDelegateCoins,
|
||||
sdk.TagDelegator, addr.String(),
|
||||
), nil
|
||||
}
|
||||
|
||||
|
@ -406,8 +410,8 @@ func undelegateCoins(
|
|||
setAccount(ctx, ak, acc)
|
||||
|
||||
return sdk.NewTags(
|
||||
sdk.TagAction, TagActionUndelegateCoins,
|
||||
sdk.TagDelegator, []byte(addr.String()),
|
||||
sdk.TagAction, tags.ActionUndelegateCoins,
|
||||
sdk.TagDelegator, addr.String(),
|
||||
), nil
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ func TestKeeper(t *testing.T) {
|
|||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
|
||||
_, err2 := bankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)))
|
||||
err2 := bankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)))
|
||||
require.Implements(t, (*sdk.Error)(nil), err2)
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
|
@ -165,7 +165,7 @@ func TestSendKeeper(t *testing.T) {
|
|||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
|
||||
_, err := sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)))
|
||||
err := sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)))
|
||||
require.Implements(t, (*sdk.Error)(nil), err)
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
|
@ -178,7 +178,7 @@ func TestSendKeeper(t *testing.T) {
|
|||
// validate coins with invalid denoms or negative values cannot be sent
|
||||
// NOTE: We must use the Coin literal as the constructor does not allow
|
||||
// negative values.
|
||||
_, err = sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.Coin{"FOOCOIN", sdk.NewInt(-5)}})
|
||||
err = sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.Coin{"FOOCOIN", sdk.NewInt(-5)}})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ func TestVestingAccountSend(t *testing.T) {
|
|||
input.ak.SetAccount(ctx, vacc)
|
||||
|
||||
// require that no coins be sendable at the beginning of the vesting schedule
|
||||
_, err := bankKeeper.SendCoins(ctx, addr1, addr2, sendCoins)
|
||||
err := bankKeeper.SendCoins(ctx, addr1, addr2, sendCoins)
|
||||
require.Error(t, err)
|
||||
|
||||
// receive some coins
|
||||
|
@ -235,7 +235,7 @@ func TestVestingAccountSend(t *testing.T) {
|
|||
|
||||
// require that all vested coins are spendable plus any received
|
||||
ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
|
||||
_, err = bankKeeper.SendCoins(ctx, addr1, addr2, sendCoins)
|
||||
err = bankKeeper.SendCoins(ctx, addr1, addr2, sendCoins)
|
||||
vacc = input.ak.GetAccount(ctx, addr1).(*auth.ContinuousVestingAccount)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, origCoins, vacc.GetCoins())
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package bank
|
||||
|
||||
// Tag keys and values
|
||||
var (
|
||||
TagActionUndelegateCoins = []byte("undelegateCoins")
|
||||
TagActionDelegateCoins = []byte("delegateCoins")
|
||||
|
||||
TagKeyRecipient = "recipient"
|
||||
TagKeySender = "sender"
|
||||
)
|
|
@ -0,0 +1,17 @@
|
|||
package tags
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Tag keys and values
|
||||
var (
|
||||
ActionUndelegateCoins = "undelegateCoins"
|
||||
ActionDelegateCoins = "delegateCoins"
|
||||
TxCategory = "bank"
|
||||
|
||||
Action = sdk.TagAction
|
||||
Category = sdk.TagCategory
|
||||
Recipient = "recipient"
|
||||
Sender = "sender"
|
||||
)
|
|
@ -16,5 +16,5 @@ type FeeCollectionKeeper interface {
|
|||
|
||||
// expected bank keeper
|
||||
type BankKeeper interface {
|
||||
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error)
|
||||
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Error)
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue