Merge branch 'develop' into release/v0.34.0

This commit is contained in:
Aleksandr Bezobchuk 2019-04-15 10:10:52 -04:00
commit 046932b084
No known key found for this signature in database
GPG Key ID: 7DAC30FBD99879B0
146 changed files with 1199 additions and 700 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
#4053 Add --inv-check-period flag to gaiad to set period at which invariants checks will run.

View File

@ -0,0 +1 @@
#4049 update tag MsgWithdrawValidatorCommission to match type

View File

@ -0,0 +1 @@
#3775 unify sender transaction tag for ease of querying

View File

@ -0,0 +1 @@
#3945 There's no check for chain-id in TxBuilder.SignStdTx

View File

@ -0,0 +1 @@
#3705 Return `[]` instead of `null` when querying delegator rewards.

View File

@ -0,0 +1,2 @@
#3966 fixed multiple assigns to action tags
#3793 add delegator tag for MsgCreateValidator and deleted unused moniker and identity tags

View File

@ -0,0 +1 @@
#4042 Update docs and scripts to include the correct `GO111MODULE=on` environment variable.

View File

@ -0,0 +1 @@
#4066 Fix 'ExportGenesisFile() incorrectly overwrites genesis'

View File

@ -0,0 +1 @@
#4064 Remove `dep` and `vendor` from `doc` and `version`.

View File

@ -0,0 +1 @@
#4080 add missing invariants during simulations

View File

@ -0,0 +1 @@
#4068 Remove redundant account check on `gaiacli`

View File

@ -0,0 +1 @@
#2007 Return 200 status code on empty results

View File

@ -0,0 +1 @@
#3774 add category tag to transactions for ease of filtering

View File

@ -0,0 +1 @@
#3914 Implement invariant benchmarks and add target to makefile.

View File

@ -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

View File

@ -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{

View File

@ -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

View File

@ -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 {

View File

@ -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) {

View File

@ -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 {

View File

@ -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"

View File

@ -3,6 +3,7 @@ package keys
import (
"errors"
"fmt"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/crypto"

View File

@ -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"
)

View File

@ -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, "[]")
}

View File

@ -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

View File

@ -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)

View File

@ -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"
)

View File

@ -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

154
cmd/gaia/Makefile Normal file
View File

@ -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

View File

@ -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()
}

View File

@ -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")
}

View File

@ -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())
}

View File

@ -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()
}
})
}
}

View File

@ -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)
}

View File

@ -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)
}
//___________________________________________________________________________________

View File

@ -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"

View File

@ -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)
}

View File

@ -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{

View File

@ -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
)

View File

@ -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
}

View 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
}

View File

@ -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)
},
}

View File

@ -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
}

View File

@ -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) {

View File

@ -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
}

View File

@ -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) {

View File

@ -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
}

View File

@ -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) {

View File

@ -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)
}

View File

@ -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())
}

58
cmd/gaia/sims.mk Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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"

View File

@ -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"
)

View File

@ -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() {

View File

@ -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"

View File

@ -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) {

View File

@ -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,

View File

@ -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"

View File

@ -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) {

View File

@ -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
```

View File

@ -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} |

View File

@ -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} |

View File

@ -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} |

View File

@ -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} |

View File

@ -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.

View File

@ -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} |

View File

@ -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

View File

@ -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设备(硬件钱包) |
### 接下来
然后你可以选择 加入公共测试网 或是 创建私有测试网。
然后你可以选择 加入公共测试网 或是 创建私有测试网。

View File

@ -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
View File

@ -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=

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 (

View File

@ -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"
)

View File

@ -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{

View File

@ -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

View File

@ -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"
)

View File

@ -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"

View File

@ -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)}
}

View File

@ -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
}

View File

@ -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,

View File

@ -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))
}
})
}
}

View File

@ -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)

View File

@ -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,
}
}

View File

@ -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
}

View File

@ -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())

View File

@ -1,10 +0,0 @@
package bank
// Tag keys and values
var (
TagActionUndelegateCoins = []byte("undelegateCoins")
TagActionDelegateCoins = []byte("delegateCoins")
TagKeyRecipient = "recipient"
TagKeySender = "sender"
)

17
x/bank/tags/tags.go Normal file
View File

@ -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"
)

View File

@ -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