Merge branch 'master' into gov_split_vote_weighted_vote
This commit is contained in:
commit
81bc4479c0
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -37,12 +37,21 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
## [Unreleased]
|
||||
|
||||
### Improvements
|
||||
|
||||
* (logging) [\#8072](https://github.com/cosmos/cosmos-sdk/pull/8072) Refactor logging:
|
||||
* Use [zerolog](https://github.com/rs/zerolog) over Tendermint's go-kit logging wrapper.
|
||||
* Introduce Tendermint's `--log_format=plain|json` flag. Using format `json` allows for emitting structured JSON
|
||||
logs which can be consumed by an external logging facility (e.g. Loggly). Both formats log to STDERR.
|
||||
* The existing `--log_level` flag and it's default value now solely relates to the global logging
|
||||
level (e.g. `info`, `debug`, etc...) instead of `<module>:<level>`.
|
||||
* (crypto) [\#7987](https://github.com/cosmos/cosmos-sdk/pull/7987) Fix the inconsistency of CryptoCdc, only use `codec/legacy.Cdc`.
|
||||
* (SDK) [\#7925](https://github.com/cosmos/cosmos-sdk/pull/7925) Updated dependencies to use gRPC v1.33.2
|
||||
* Updated gRPC dependency to v1.33.2
|
||||
* Updated iavl dependency to v0.15-rc2
|
||||
* (version) [\#7848](https://github.com/cosmos/cosmos-sdk/pull/7848) [\#7941](https://github.com/cosmos/cosmos-sdk/pull/7941) `version --long` output now shows the list of build dependencies and replaced build dependencies.
|
||||
|
||||
### State Machine Breaking Changes
|
||||
|
||||
* (x/upgrade) [\#7979](https://github.com/cosmos/cosmos-sdk/pull/7979) keeper pubkey storage serialization migration from bech32 to protobuf.
|
||||
|
||||
### Bug Fixes
|
||||
|
@ -53,9 +62,11 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
|
||||
### Client Breaking
|
||||
|
||||
* (crypto) [\#7419](https://github.com/cosmos/cosmos-sdk/pull/7419) The SDK doesn't use Tendermint's `crypto.PubKey` interface anymore, and uses instead it's own `PubKey` interface, defined in `crypto/types`. Replace all instances of `crypto.PubKey` by `cryptotypes.Pubkey`.
|
||||
* (x/staking) [\#7419](https://github.com/cosmos/cosmos-sdk/pull/7419) The `TmConsPubKey` method on ValidatorI has been removed and replaced instead by `ConsPubKey` (which returns a SDK `cryptotypes.PubKey`) and `TmConsPublicKey` (which returns a Tendermint proto PublicKey).
|
||||
|
||||
### Improvements
|
||||
|
||||
* (tendermint) [\#7828](https://github.com/cosmos/cosmos-sdk/pull/7828) Update tendermint dependency to v0.34.0-rc6
|
||||
|
||||
## [v0.40.0-rc2](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0-rc2) - 2020-11-02
|
||||
|
@ -88,18 +99,16 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
* __Modules__
|
||||
* `x/crisis` has a new function: `AddModuleInitFlags`, which will register optional crisis module flags for the start command.
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (client) [\#7699](https://github.com/cosmos/cosmos-sdk/pull/7699) Fix panic in context when setting invalid nodeURI. `WithNodeURI` does not set the `Client` in the context.
|
||||
* (x/gov) [#7641](https://github.com/cosmos/cosmos-sdk/pull/7641) Fix tally calculation precision error.
|
||||
|
||||
### Improvements
|
||||
### Improvements
|
||||
|
||||
* (rest) [#7649](https://github.com/cosmos/cosmos-sdk/pull/7649) Return an unsigned tx in legacy GET /tx endpoint when signature conversion fails
|
||||
* (cli) [#7764](https://github.com/cosmos/cosmos-sdk/pull/7764) Update x/banking and x/crisis InitChain to improve node startup time
|
||||
|
||||
|
||||
## [v0.40.0-rc1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0-rc1) - 2020-10-19
|
||||
|
||||
### Client Breaking Changes
|
||||
|
|
2
Makefile
2
Makefile
|
@ -357,7 +357,7 @@ devdoc-update:
|
|||
### Protobuf ###
|
||||
###############################################################################
|
||||
|
||||
proto-all: proto-format proto-lint proto-check-breaking proto-gen
|
||||
proto-all: proto-format proto-lint proto-gen
|
||||
|
||||
proto-gen:
|
||||
@echo "Generating Protobuf files"
|
||||
|
|
|
@ -291,7 +291,7 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) {
|
|||
// MultiStore (app.cms) so when Commit() is called is persists those values.
|
||||
app.deliverState.ms.Write()
|
||||
commitID := app.cms.Commit()
|
||||
app.logger.Debug("Commit synced", "commit", fmt.Sprintf("%X", commitID))
|
||||
app.logger.Info("commit synced", "commit", fmt.Sprintf("%X", commitID))
|
||||
|
||||
// Reset the Check state to the latest committed.
|
||||
//
|
||||
|
@ -358,30 +358,43 @@ func (app *BaseApp) snapshot(height int64) {
|
|||
app.logger.Info("snapshot manager not configured")
|
||||
return
|
||||
}
|
||||
app.logger.Info("Creating state snapshot", "height", height)
|
||||
|
||||
app.logger.Info("creating state snapshot", "height", height)
|
||||
|
||||
snapshot, err := app.snapshotManager.Create(uint64(height))
|
||||
if err != nil {
|
||||
app.logger.Error("Failed to create state snapshot", "height", height, "err", err)
|
||||
app.logger.Error("failed to create state snapshot", "height", height, "err", err)
|
||||
return
|
||||
}
|
||||
app.logger.Info("Completed state snapshot", "height", height, "format", snapshot.Format)
|
||||
|
||||
app.logger.Info("completed state snapshot", "height", height, "format", snapshot.Format)
|
||||
|
||||
if app.snapshotKeepRecent > 0 {
|
||||
app.logger.Debug("Pruning state snapshots")
|
||||
app.logger.Debug("pruning state snapshots")
|
||||
|
||||
pruned, err := app.snapshotManager.Prune(app.snapshotKeepRecent)
|
||||
if err != nil {
|
||||
app.logger.Error("Failed to prune state snapshots", "err", err)
|
||||
return
|
||||
}
|
||||
app.logger.Debug("Pruned state snapshots", "pruned", pruned)
|
||||
|
||||
app.logger.Debug("pruned state snapshots", "pruned", pruned)
|
||||
}
|
||||
}
|
||||
|
||||
// Query implements the ABCI interface. It delegates to CommitMultiStore if it
|
||||
// implements Queryable.
|
||||
func (app *BaseApp) Query(req abci.RequestQuery) abci.ResponseQuery {
|
||||
func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
defer telemetry.MeasureSince(time.Now(), "abci", "query")
|
||||
|
||||
// Add panic recovery for all queries.
|
||||
// ref: https://github.com/cosmos/cosmos-sdk/pull/8039
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
res = sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrPanic, "%v", r))
|
||||
}
|
||||
}()
|
||||
|
||||
// when a client did not provide a query height, manually inject the latest
|
||||
if req.Height == 0 {
|
||||
req.Height = app.LastBlockHeight()
|
||||
|
@ -425,13 +438,14 @@ func (app *BaseApp) ListSnapshots(req abci.RequestListSnapshots) abci.ResponseLi
|
|||
|
||||
snapshots, err := app.snapshotManager.List()
|
||||
if err != nil {
|
||||
app.logger.Error("Failed to list snapshots", "err", err)
|
||||
app.logger.Error("failed to list snapshots", "err", err)
|
||||
return resp
|
||||
}
|
||||
|
||||
for _, snapshot := range snapshots {
|
||||
abciSnapshot, err := snapshot.ToABCI()
|
||||
if err != nil {
|
||||
app.logger.Error("Failed to list snapshots", "err", err)
|
||||
app.logger.Error("failed to list snapshots", "err", err)
|
||||
return resp
|
||||
}
|
||||
resp.Snapshots = append(resp.Snapshots, &abciSnapshot)
|
||||
|
@ -447,8 +461,13 @@ func (app *BaseApp) LoadSnapshotChunk(req abci.RequestLoadSnapshotChunk) abci.Re
|
|||
}
|
||||
chunk, err := app.snapshotManager.LoadChunk(req.Height, req.Format, req.Chunk)
|
||||
if err != nil {
|
||||
app.logger.Error("Failed to load snapshot chunk", "height", req.Height, "format", req.Format,
|
||||
"chunk", req.Chunk, "err")
|
||||
app.logger.Error(
|
||||
"failed to load snapshot chunk",
|
||||
"height", req.Height,
|
||||
"format", req.Format,
|
||||
"chunk", req.Chunk,
|
||||
"err", err,
|
||||
)
|
||||
return abci.ResponseLoadSnapshotChunk{}
|
||||
}
|
||||
return abci.ResponseLoadSnapshotChunk{Chunk: chunk}
|
||||
|
@ -462,15 +481,16 @@ func (app *BaseApp) OfferSnapshot(req abci.RequestOfferSnapshot) abci.ResponseOf
|
|||
}
|
||||
|
||||
if req.Snapshot == nil {
|
||||
app.logger.Error("Received nil snapshot")
|
||||
app.logger.Error("received nil snapshot")
|
||||
return abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}
|
||||
}
|
||||
|
||||
snapshot, err := snapshottypes.SnapshotFromABCI(req.Snapshot)
|
||||
if err != nil {
|
||||
app.logger.Error("Failed to decode snapshot metadata", "err", err)
|
||||
app.logger.Error("failed to decode snapshot metadata", "err", err)
|
||||
return abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}
|
||||
}
|
||||
|
||||
err = app.snapshotManager.Restore(snapshot)
|
||||
switch {
|
||||
case err == nil:
|
||||
|
@ -480,13 +500,22 @@ func (app *BaseApp) OfferSnapshot(req abci.RequestOfferSnapshot) abci.ResponseOf
|
|||
return abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}
|
||||
|
||||
case errors.Is(err, snapshottypes.ErrInvalidMetadata):
|
||||
app.logger.Error("Rejecting invalid snapshot", "height", req.Snapshot.Height,
|
||||
"format", req.Snapshot.Format, "err", err)
|
||||
app.logger.Error(
|
||||
"rejecting invalid snapshot",
|
||||
"height", req.Snapshot.Height,
|
||||
"format", req.Snapshot.Format,
|
||||
"err", err,
|
||||
)
|
||||
return abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}
|
||||
|
||||
default:
|
||||
app.logger.Error("Failed to restore snapshot", "height", req.Snapshot.Height,
|
||||
"format", req.Snapshot.Format, "err", err)
|
||||
app.logger.Error(
|
||||
"failed to restore snapshot",
|
||||
"height", req.Snapshot.Height,
|
||||
"format", req.Snapshot.Format,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
// We currently don't support resetting the IAVL stores and retrying a different snapshot,
|
||||
// so we ask Tendermint to abort all snapshot restoration.
|
||||
return abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}
|
||||
|
@ -506,8 +535,12 @@ func (app *BaseApp) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.
|
|||
return abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}
|
||||
|
||||
case errors.Is(err, snapshottypes.ErrChunkHashMismatch):
|
||||
app.logger.Error("Chunk checksum mismatch, rejecting sender and requesting refetch",
|
||||
"chunk", req.Index, "sender", req.Sender, "err", err)
|
||||
app.logger.Error(
|
||||
"chunk checksum mismatch; rejecting sender and requesting refetch",
|
||||
"chunk", req.Index,
|
||||
"sender", req.Sender,
|
||||
"err", err,
|
||||
)
|
||||
return abci.ResponseApplySnapshotChunk{
|
||||
Result: abci.ResponseApplySnapshotChunk_RETRY,
|
||||
RefetchChunks: []uint32{req.Index},
|
||||
|
@ -515,7 +548,7 @@ func (app *BaseApp) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.
|
|||
}
|
||||
|
||||
default:
|
||||
app.logger.Error("Failed to restore snapshot", "err", err)
|
||||
app.logger.Error("failed to restore snapshot", "err", err)
|
||||
return abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ABORT}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func TestGRPCRouter(t *testing.T) {
|
||||
func TestGRPCGatewayRouter(t *testing.T) {
|
||||
qr := baseapp.NewGRPCQueryRouter()
|
||||
interfaceRegistry := testdata.NewTestInterfaceRegistry()
|
||||
qr.SetInterfaceRegistry(interfaceRegistry)
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"strconv"
|
||||
|
||||
gogogrpc "github.com/gogo/protobuf/grpc"
|
||||
grpcmiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
grpcrecovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
@ -74,7 +76,10 @@ func (app *BaseApp) RegisterGRPCServer(server gogogrpc.Server) {
|
|||
newMethods[i] = grpc.MethodDesc{
|
||||
MethodName: method.MethodName,
|
||||
Handler: func(srv interface{}, ctx context.Context, dec func(interface{}) error, _ grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
return methodHandler(srv, ctx, dec, interceptor)
|
||||
return methodHandler(srv, ctx, dec, grpcmiddleware.ChainUnaryServer(
|
||||
grpcrecovery.UnaryServerInterceptor(),
|
||||
interceptor,
|
||||
))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,13 @@ import (
|
|||
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
"github.com/tendermint/tendermint/mempool"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
)
|
||||
|
||||
// BroadcastTx broadcasts a transactions either synchronously or asynchronously
|
||||
|
@ -142,3 +145,36 @@ func (ctx Context) BroadcastTxAsync(txBytes []byte) (*sdk.TxResponse, error) {
|
|||
|
||||
return sdk.NewResponseFormatBroadcastTx(res), err
|
||||
}
|
||||
|
||||
// TxServiceBroadcast is a helper function to broadcast a Tx with the correct gRPC types
|
||||
// from the tx service. Calls `clientCtx.BroadcastTx` under the hood.
|
||||
func TxServiceBroadcast(grpcCtx context.Context, clientCtx Context, req *tx.BroadcastTxRequest) (*tx.BroadcastTxResponse, error) {
|
||||
if req == nil || req.TxBytes == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid empty tx")
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithBroadcastMode(normalizeBroadcastMode(req.Mode))
|
||||
resp, err := clientCtx.BroadcastTx(req.TxBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tx.BroadcastTxResponse{
|
||||
TxResponse: resp,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// normalizeBroadcastMode converts a broadcast mode into a normalized string
|
||||
// to be passed into the clientCtx.
|
||||
func normalizeBroadcastMode(mode tx.BroadcastMode) string {
|
||||
switch mode {
|
||||
case tx.BroadcastMode_BROADCAST_MODE_ASYNC:
|
||||
return "async"
|
||||
case tx.BroadcastMode_BROADCAST_MODE_BLOCK:
|
||||
return "block"
|
||||
case tx.BroadcastMode_BROADCAST_MODE_SYNC:
|
||||
return "sync"
|
||||
default:
|
||||
return "unspecified"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,10 @@ const (
|
|||
FlagCountTotal = "count-total"
|
||||
FlagTimeoutHeight = "timeout-height"
|
||||
FlagKeyAlgorithm = "algo"
|
||||
|
||||
// Tendermint logging flags
|
||||
FlagLogLevel = "log_level"
|
||||
FlagLogFormat = "log_format"
|
||||
)
|
||||
|
||||
// LineBreak can be included in a command list to provide a blank line
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: cosmos/base/tendermint/v1beta1/query.proto
|
||||
|
||||
package query
|
||||
package tmservice
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
types "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
query "github.com/cosmos/cosmos-sdk/types/query"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
grpc1 "github.com/gogo/protobuf/grpc"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
p2p "github.com/tendermint/tendermint/proto/tendermint/p2p"
|
||||
types "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
types1 "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
|
@ -35,7 +37,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
|||
type GetValidatorSetByHeightRequest struct {
|
||||
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
|
||||
// pagination defines an pagination for the request.
|
||||
Pagination *PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetValidatorSetByHeightRequest) Reset() { *m = GetValidatorSetByHeightRequest{} }
|
||||
|
@ -78,7 +80,7 @@ func (m *GetValidatorSetByHeightRequest) GetHeight() int64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (m *GetValidatorSetByHeightRequest) GetPagination() *PageRequest {
|
||||
func (m *GetValidatorSetByHeightRequest) GetPagination() *query.PageRequest {
|
||||
if m != nil {
|
||||
return m.Pagination
|
||||
}
|
||||
|
@ -90,7 +92,7 @@ type GetValidatorSetByHeightResponse struct {
|
|||
BlockHeight int64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"`
|
||||
Validators []*Validator `protobuf:"bytes,2,rep,name=validators,proto3" json:"validators,omitempty"`
|
||||
// pagination defines an pagination for the response.
|
||||
Pagination *PageResponse `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
Pagination *query.PageResponse `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetValidatorSetByHeightResponse) Reset() { *m = GetValidatorSetByHeightResponse{} }
|
||||
|
@ -140,7 +142,7 @@ func (m *GetValidatorSetByHeightResponse) GetValidators() []*Validator {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *GetValidatorSetByHeightResponse) GetPagination() *PageResponse {
|
||||
func (m *GetValidatorSetByHeightResponse) GetPagination() *query.PageResponse {
|
||||
if m != nil {
|
||||
return m.Pagination
|
||||
}
|
||||
|
@ -150,7 +152,7 @@ func (m *GetValidatorSetByHeightResponse) GetPagination() *PageResponse {
|
|||
// GetLatestValidatorSetRequest is the request type for the Query/GetValidatorSetByHeight RPC method.
|
||||
type GetLatestValidatorSetRequest struct {
|
||||
// pagination defines an pagination for the request.
|
||||
Pagination *PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetLatestValidatorSetRequest) Reset() { *m = GetLatestValidatorSetRequest{} }
|
||||
|
@ -186,7 +188,7 @@ func (m *GetLatestValidatorSetRequest) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_GetLatestValidatorSetRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *GetLatestValidatorSetRequest) GetPagination() *PageRequest {
|
||||
func (m *GetLatestValidatorSetRequest) GetPagination() *query.PageRequest {
|
||||
if m != nil {
|
||||
return m.Pagination
|
||||
}
|
||||
|
@ -198,7 +200,7 @@ type GetLatestValidatorSetResponse struct {
|
|||
BlockHeight int64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"`
|
||||
Validators []*Validator `protobuf:"bytes,2,rep,name=validators,proto3" json:"validators,omitempty"`
|
||||
// pagination defines an pagination for the response.
|
||||
Pagination *PageResponse `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
Pagination *query.PageResponse `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetLatestValidatorSetResponse) Reset() { *m = GetLatestValidatorSetResponse{} }
|
||||
|
@ -248,7 +250,7 @@ func (m *GetLatestValidatorSetResponse) GetValidators() []*Validator {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *GetLatestValidatorSetResponse) GetPagination() *PageResponse {
|
||||
func (m *GetLatestValidatorSetResponse) GetPagination() *query.PageResponse {
|
||||
if m != nil {
|
||||
return m.Pagination
|
||||
}
|
||||
|
@ -257,10 +259,10 @@ func (m *GetLatestValidatorSetResponse) GetPagination() *PageResponse {
|
|||
|
||||
// Validator is the type for the validator-set.
|
||||
type Validator struct {
|
||||
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
|
||||
PubKey string `protobuf:"bytes,2,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"`
|
||||
VotingPower int64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"`
|
||||
ProposerPriority int64 `protobuf:"varint,4,opt,name=proposer_priority,json=proposerPriority,proto3" json:"proposer_priority,omitempty"`
|
||||
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
|
||||
PubKey *types.Any `protobuf:"bytes,2,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"`
|
||||
VotingPower int64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"`
|
||||
ProposerPriority int64 `protobuf:"varint,4,opt,name=proposer_priority,json=proposerPriority,proto3" json:"proposer_priority,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Validator) Reset() { *m = Validator{} }
|
||||
|
@ -296,18 +298,18 @@ func (m *Validator) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_Validator proto.InternalMessageInfo
|
||||
|
||||
func (m *Validator) GetAddress() []byte {
|
||||
func (m *Validator) GetAddress() string {
|
||||
if m != nil {
|
||||
return m.Address
|
||||
}
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Validator) GetPubKey() string {
|
||||
func (m *Validator) GetPubKey() *types.Any {
|
||||
if m != nil {
|
||||
return m.PubKey
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Validator) GetVotingPower() int64 {
|
||||
|
@ -371,8 +373,8 @@ func (m *GetBlockByHeightRequest) GetHeight() int64 {
|
|||
|
||||
// GetBlockByHeightResponse is the response type for the Query/GetBlockByHeight RPC method.
|
||||
type GetBlockByHeightResponse struct {
|
||||
BlockId *types.BlockID `protobuf:"bytes,1,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"`
|
||||
Block *types.Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"`
|
||||
BlockId *types1.BlockID `protobuf:"bytes,1,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"`
|
||||
Block *types1.Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetBlockByHeightResponse) Reset() { *m = GetBlockByHeightResponse{} }
|
||||
|
@ -408,14 +410,14 @@ func (m *GetBlockByHeightResponse) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_GetBlockByHeightResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *GetBlockByHeightResponse) GetBlockId() *types.BlockID {
|
||||
func (m *GetBlockByHeightResponse) GetBlockId() *types1.BlockID {
|
||||
if m != nil {
|
||||
return m.BlockId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetBlockByHeightResponse) GetBlock() *types.Block {
|
||||
func (m *GetBlockByHeightResponse) GetBlock() *types1.Block {
|
||||
if m != nil {
|
||||
return m.Block
|
||||
}
|
||||
|
@ -461,8 +463,8 @@ var xxx_messageInfo_GetLatestBlockRequest proto.InternalMessageInfo
|
|||
|
||||
// GetLatestBlockResponse is the response type for the Query/GetLatestBlock RPC method.
|
||||
type GetLatestBlockResponse struct {
|
||||
BlockId *types.BlockID `protobuf:"bytes,1,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"`
|
||||
Block *types.Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"`
|
||||
BlockId *types1.BlockID `protobuf:"bytes,1,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"`
|
||||
Block *types1.Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"`
|
||||
}
|
||||
|
||||
func (m *GetLatestBlockResponse) Reset() { *m = GetLatestBlockResponse{} }
|
||||
|
@ -498,14 +500,14 @@ func (m *GetLatestBlockResponse) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_GetLatestBlockResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *GetLatestBlockResponse) GetBlockId() *types.BlockID {
|
||||
func (m *GetLatestBlockResponse) GetBlockId() *types1.BlockID {
|
||||
if m != nil {
|
||||
return m.BlockId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetLatestBlockResponse) GetBlock() *types.Block {
|
||||
func (m *GetLatestBlockResponse) GetBlock() *types1.Block {
|
||||
if m != nil {
|
||||
return m.Block
|
||||
}
|
||||
|
@ -783,7 +785,7 @@ type Module struct {
|
|||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||
// module version
|
||||
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
|
||||
//checksum
|
||||
// checksum
|
||||
Sum string `protobuf:"bytes,3,opt,name=sum,proto3" json:"sum,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -864,72 +866,74 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptor_40c93fb3ef485c5d = []byte{
|
||||
// 1031 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
|
||||
0x14, 0xcf, 0xc6, 0x6d, 0x1c, 0x3f, 0x57, 0x90, 0x4c, 0x4a, 0xb3, 0xb5, 0x52, 0x37, 0xec, 0xa1,
|
||||
0x4d, 0x88, 0xb2, 0x2b, 0x3b, 0x84, 0x82, 0xf8, 0x27, 0x85, 0x40, 0x1a, 0x15, 0xaa, 0x68, 0x83,
|
||||
0x38, 0x20, 0xa4, 0xd5, 0xd8, 0x3b, 0xd9, 0x8c, 0x62, 0xef, 0x4c, 0x77, 0xc6, 0x41, 0x16, 0xaa,
|
||||
0x40, 0xfd, 0x00, 0x08, 0x89, 0xaf, 0xc0, 0x85, 0x2f, 0xc0, 0x11, 0x71, 0xe4, 0x46, 0x25, 0x24,
|
||||
0xe8, 0x11, 0x25, 0x7c, 0x0a, 0x4e, 0x68, 0x67, 0x66, 0xed, 0xdd, 0x26, 0xa9, 0xed, 0x1c, 0x90,
|
||||
0x38, 0x79, 0xf6, 0xbd, 0xf7, 0x7b, 0xf3, 0xfb, 0xbd, 0x79, 0x33, 0x7e, 0xf0, 0x5a, 0x9b, 0x89,
|
||||
0x2e, 0x13, 0x5e, 0x0b, 0x0b, 0xe2, 0x49, 0x12, 0x87, 0x24, 0xe9, 0xd2, 0x58, 0x7a, 0xc7, 0x8d,
|
||||
0x16, 0x91, 0xb8, 0xe1, 0x3d, 0xea, 0x91, 0xa4, 0xef, 0xf2, 0x84, 0x49, 0x86, 0xea, 0x3a, 0xd6,
|
||||
0x4d, 0x63, 0xdd, 0x61, 0xac, 0x6b, 0x62, 0x6b, 0xd7, 0x23, 0x16, 0x31, 0x15, 0xea, 0xa5, 0x2b,
|
||||
0x8d, 0xaa, 0x2d, 0x45, 0x8c, 0x45, 0x1d, 0xe2, 0x61, 0x4e, 0x3d, 0x1c, 0xc7, 0x4c, 0x62, 0x49,
|
||||
0x59, 0x2c, 0x8c, 0xb7, 0x96, 0xdb, 0x93, 0x37, 0xb9, 0x27, 0xfb, 0x9c, 0x64, 0xbe, 0xa5, 0x9c,
|
||||
0x4f, 0xd9, 0xbd, 0x56, 0x87, 0xb5, 0x8f, 0x2e, 0xf4, 0xe6, 0xb1, 0x05, 0x5d, 0x4a, 0xc4, 0x40,
|
||||
0x12, 0xc7, 0x11, 0x8d, 0x15, 0x09, 0x1d, 0xeb, 0x7c, 0x63, 0x41, 0x7d, 0x87, 0xc8, 0xcf, 0x70,
|
||||
0x87, 0x86, 0x58, 0xb2, 0x64, 0x9f, 0xc8, 0xad, 0xfe, 0x7d, 0x42, 0xa3, 0x43, 0xe9, 0x93, 0x47,
|
||||
0x3d, 0x22, 0x24, 0xba, 0x01, 0x33, 0x87, 0xca, 0x60, 0x5b, 0xcb, 0xd6, 0x4a, 0xc9, 0x37, 0x5f,
|
||||
0xe8, 0x23, 0x80, 0x61, 0x3a, 0x7b, 0x7a, 0xd9, 0x5a, 0xa9, 0x36, 0xef, 0xb8, 0xf9, 0x3a, 0xe9,
|
||||
0x02, 0x9a, 0xbd, 0xdd, 0x3d, 0x1c, 0x11, 0x93, 0xd3, 0xcf, 0x21, 0x9d, 0x67, 0x16, 0xdc, 0xbe,
|
||||
0x90, 0x82, 0xe0, 0x2c, 0x16, 0x04, 0xbd, 0x0a, 0xd7, 0x94, 0xfe, 0xa0, 0xc0, 0xa4, 0xaa, 0x6c,
|
||||
0x3a, 0x14, 0xed, 0x02, 0x1c, 0x67, 0x29, 0x84, 0x3d, 0xbd, 0x5c, 0x5a, 0xa9, 0x36, 0x57, 0xdd,
|
||||
0x17, 0x1f, 0x9b, 0x3b, 0xd8, 0xd4, 0xcf, 0x81, 0xd1, 0x4e, 0x41, 0x59, 0x49, 0x29, 0xbb, 0x3b,
|
||||
0x52, 0x99, 0xa6, 0x5a, 0x90, 0x76, 0x00, 0x4b, 0x3b, 0x44, 0x7e, 0x8c, 0x25, 0x11, 0x05, 0x7d,
|
||||
0x59, 0x69, 0x8b, 0x25, 0xb4, 0x2e, 0x5d, 0xc2, 0x3f, 0x2c, 0xb8, 0x75, 0xc1, 0x46, 0xff, 0xef,
|
||||
0x02, 0x7e, 0x6b, 0x41, 0x65, 0xb0, 0x05, 0xb2, 0xa1, 0x8c, 0xc3, 0x30, 0x21, 0x42, 0x28, 0xfe,
|
||||
0xd7, 0xfc, 0xec, 0x13, 0x2d, 0x42, 0x99, 0xf7, 0x5a, 0xc1, 0x11, 0xe9, 0xab, 0x46, 0xac, 0xf8,
|
||||
0x33, 0xbc, 0xd7, 0x7a, 0x40, 0xfa, 0xa9, 0xee, 0x63, 0x26, 0x69, 0x1c, 0x05, 0x9c, 0x7d, 0x49,
|
||||
0x12, 0xc5, 0xa5, 0xe4, 0x57, 0xb5, 0x6d, 0x2f, 0x35, 0xa1, 0x35, 0x98, 0xe7, 0x09, 0xe3, 0x4c,
|
||||
0x90, 0x24, 0xe0, 0x09, 0x65, 0x09, 0x95, 0x7d, 0xfb, 0x8a, 0x8a, 0x9b, 0xcb, 0x1c, 0x7b, 0xc6,
|
||||
0xee, 0x34, 0x60, 0x71, 0x87, 0xc8, 0xad, 0xb4, 0x6c, 0x63, 0xde, 0x13, 0xe7, 0x6b, 0xb0, 0xcf,
|
||||
0x42, 0xcc, 0xb1, 0xbc, 0x0e, 0xb3, 0xfa, 0x58, 0x68, 0x68, 0x8e, 0xff, 0x66, 0xbe, 0xca, 0xfa,
|
||||
0x56, 0x2b, 0xe8, 0xee, 0xb6, 0x5f, 0x56, 0xa1, 0xbb, 0x21, 0x5a, 0x87, 0xab, 0x6a, 0x69, 0x2e,
|
||||
0xdd, 0xe2, 0x05, 0x10, 0x5f, 0x47, 0x39, 0x8b, 0xf0, 0xca, 0xa0, 0x39, 0xb4, 0x43, 0x33, 0x76,
|
||||
0x1e, 0xc3, 0x8d, 0xe7, 0x1d, 0xff, 0x25, 0xaf, 0x05, 0x98, 0xdf, 0x21, 0x72, 0xbf, 0x1f, 0xb7,
|
||||
0x69, 0x1c, 0x65, 0x9c, 0x5c, 0x40, 0x79, 0xa3, 0xe1, 0x63, 0x43, 0x59, 0x68, 0x93, 0xa2, 0x33,
|
||||
0xeb, 0x67, 0x9f, 0xce, 0x75, 0x15, 0xff, 0x90, 0x85, 0x64, 0x37, 0x3e, 0x60, 0x59, 0x96, 0x5f,
|
||||
0x2c, 0x58, 0x28, 0x98, 0x4d, 0x9e, 0x07, 0x30, 0x1f, 0x92, 0x03, 0xdc, 0xeb, 0xc8, 0x20, 0x66,
|
||||
0x21, 0x09, 0x68, 0x7c, 0xc0, 0x8c, 0xc0, 0xdb, 0x79, 0xb6, 0xbc, 0xc9, 0xdd, 0x6d, 0x1d, 0x38,
|
||||
0xc8, 0xf1, 0x72, 0x58, 0x34, 0xa0, 0x2f, 0x60, 0x01, 0x73, 0xde, 0xa1, 0x6d, 0xd5, 0xab, 0xc1,
|
||||
0x31, 0x49, 0xc4, 0xf0, 0x25, 0x5c, 0x1b, 0x79, 0x73, 0x74, 0xb8, 0x4a, 0x8d, 0x72, 0x79, 0x8c,
|
||||
0xdd, 0xf9, 0xc7, 0x82, 0x6a, 0x2e, 0x06, 0x21, 0xb8, 0x12, 0xe3, 0x2e, 0x51, 0x6c, 0x2b, 0xbe,
|
||||
0x5a, 0xa3, 0x9b, 0x30, 0x8b, 0x39, 0x0f, 0x94, 0x5d, 0xf7, 0x7d, 0x19, 0x73, 0xfe, 0x30, 0x75,
|
||||
0xd9, 0x50, 0xce, 0x08, 0x95, 0xb4, 0xc7, 0x7c, 0xa2, 0x5b, 0x00, 0x11, 0x95, 0x41, 0x9b, 0x75,
|
||||
0xbb, 0x54, 0xaa, 0x46, 0xaf, 0xf8, 0x95, 0x88, 0xca, 0x0f, 0x94, 0x21, 0x75, 0xb7, 0x7a, 0xb4,
|
||||
0x13, 0x06, 0x12, 0x47, 0xc2, 0xbe, 0xaa, 0xdd, 0xca, 0xf2, 0x29, 0x8e, 0x84, 0x42, 0xb3, 0x81,
|
||||
0xd6, 0x19, 0x83, 0x66, 0x86, 0x29, 0xfa, 0x30, 0x43, 0x87, 0x84, 0x0b, 0xbb, 0xac, 0x1e, 0x91,
|
||||
0x3b, 0xa3, 0x4a, 0xf1, 0x09, 0x0b, 0x7b, 0x1d, 0x62, 0x76, 0xd9, 0x26, 0x5c, 0x38, 0xf7, 0x61,
|
||||
0x46, 0x1b, 0x53, 0xd9, 0x1c, 0xcb, 0xc3, 0x4c, 0x76, 0xba, 0xce, 0x6b, 0x9b, 0x2e, 0x6a, 0x9b,
|
||||
0x83, 0x92, 0xe8, 0x75, 0x8d, 0xe2, 0x74, 0xd9, 0x7c, 0x52, 0x81, 0xf2, 0x3e, 0x49, 0x8e, 0x69,
|
||||
0x9b, 0xa0, 0x1f, 0x2d, 0xa8, 0xe6, 0xba, 0x02, 0x35, 0x47, 0x11, 0x3b, 0xdb, 0x59, 0xb5, 0x8d,
|
||||
0x89, 0x30, 0xba, 0xed, 0x9c, 0xc6, 0x93, 0xdf, 0xff, 0xfe, 0x7e, 0x7a, 0x0d, 0xad, 0x7a, 0x23,
|
||||
0x46, 0x8e, 0x41, 0x53, 0xa2, 0x1f, 0x2c, 0x80, 0xe1, 0x45, 0x40, 0x8d, 0x31, 0xb6, 0x2d, 0xde,
|
||||
0xa4, 0x5a, 0x73, 0x12, 0x88, 0x21, 0xea, 0x29, 0xa2, 0xab, 0xe8, 0xee, 0x28, 0xa2, 0xe6, 0xfa,
|
||||
0xa1, 0x9f, 0x2c, 0x78, 0xa9, 0xf8, 0x86, 0xa0, 0xcd, 0x31, 0xf6, 0x3d, 0xfb, 0x18, 0xd5, 0xde,
|
||||
0x98, 0x14, 0x66, 0x28, 0x6f, 0x2a, 0xca, 0x1e, 0x5a, 0x1f, 0x45, 0x59, 0x3d, 0x3a, 0xc2, 0xeb,
|
||||
0xa8, 0x1c, 0xe8, 0x67, 0x0b, 0xe6, 0x9e, 0x7f, 0x96, 0xd1, 0xbd, 0x31, 0x38, 0x9c, 0xf7, 0xf6,
|
||||
0xd7, 0xde, 0x9c, 0x1c, 0x68, 0xe8, 0xdf, 0x53, 0xf4, 0x1b, 0xc8, 0x1b, 0x93, 0xfe, 0x57, 0xfa,
|
||||
0x5f, 0xe5, 0x31, 0xfa, 0xcd, 0xca, 0x3d, 0xeb, 0xf9, 0xff, 0x7c, 0xf4, 0xce, 0xd8, 0x95, 0x3c,
|
||||
0x67, 0x26, 0xa9, 0xbd, 0x7b, 0x49, 0xb4, 0xd1, 0xf3, 0x96, 0xd2, 0xb3, 0x81, 0x1a, 0xa3, 0xf4,
|
||||
0x0c, 0xc7, 0x85, 0xec, 0x48, 0xfe, 0xb4, 0xd4, 0x9f, 0xeb, 0x79, 0x83, 0x20, 0x7a, 0x6f, 0x0c,
|
||||
0x56, 0x2f, 0x18, 0x62, 0x6b, 0xef, 0x5f, 0x1a, 0x6f, 0x74, 0xbd, 0xad, 0x74, 0x6d, 0xa2, 0x8d,
|
||||
0x09, 0x74, 0x65, 0x67, 0xb5, 0xb5, 0xf5, 0xeb, 0x49, 0xdd, 0x7a, 0x7a, 0x52, 0xb7, 0xfe, 0x3a,
|
||||
0xa9, 0x5b, 0xdf, 0x9d, 0xd6, 0xa7, 0x9e, 0x9e, 0xd6, 0xa7, 0x9e, 0x9d, 0xd6, 0xa7, 0x3e, 0x5f,
|
||||
0x89, 0xa8, 0x3c, 0xec, 0xb5, 0xdc, 0x36, 0xeb, 0x66, 0x89, 0xf5, 0xcf, 0xba, 0x08, 0x8f, 0xcc,
|
||||
0x6c, 0xaf, 0x66, 0xa5, 0xd6, 0x8c, 0x1a, 0xd8, 0x37, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x20,
|
||||
0x61, 0xbc, 0x54, 0xb6, 0x0c, 0x00, 0x00,
|
||||
// 1059 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcf, 0x6f, 0xdc, 0xc4,
|
||||
0x17, 0x8f, 0xb3, 0x6d, 0x36, 0x79, 0xfb, 0xd5, 0x97, 0x64, 0x12, 0x1a, 0xc7, 0x4a, 0xb7, 0xc1,
|
||||
0x87, 0x36, 0x21, 0x8a, 0xad, 0xdd, 0x10, 0x0a, 0xe2, 0x97, 0x08, 0x81, 0x34, 0x6a, 0xa9, 0x22,
|
||||
0x07, 0x71, 0x40, 0x48, 0x96, 0x77, 0x3d, 0x71, 0x46, 0xd9, 0xf5, 0x4c, 0x3d, 0xe3, 0xa0, 0x15,
|
||||
0xaa, 0x40, 0xfd, 0x0b, 0x90, 0xf8, 0x17, 0x7a, 0xe1, 0x1f, 0xe0, 0x88, 0x38, 0x72, 0xa3, 0x12,
|
||||
0x12, 0xf4, 0x88, 0x12, 0xfe, 0x0a, 0x4e, 0xc8, 0x33, 0xe3, 0x5d, 0xbb, 0x49, 0xba, 0xbb, 0x39,
|
||||
0x20, 0x71, 0xf2, 0xcc, 0xfb, 0x35, 0x9f, 0xcf, 0x9b, 0xf7, 0x9e, 0x07, 0x5e, 0x6f, 0x53, 0xde,
|
||||
0xa5, 0xdc, 0x6d, 0x05, 0x1c, 0xbb, 0x02, 0xc7, 0x21, 0x4e, 0xba, 0x24, 0x16, 0xee, 0x49, 0xa3,
|
||||
0x85, 0x45, 0xd0, 0x70, 0x1f, 0xa5, 0x38, 0xe9, 0x39, 0x2c, 0xa1, 0x82, 0xa2, 0xba, 0xb2, 0x75,
|
||||
0x32, 0x5b, 0x67, 0x60, 0xeb, 0x68, 0x5b, 0x6b, 0x21, 0xa2, 0x11, 0x95, 0xa6, 0x6e, 0xb6, 0x52,
|
||||
0x5e, 0xd6, 0x52, 0x44, 0x69, 0xd4, 0xc1, 0xae, 0xdc, 0xb5, 0xd2, 0x43, 0x37, 0x88, 0x75, 0x40,
|
||||
0x6b, 0x59, 0xab, 0x02, 0x46, 0xdc, 0x20, 0x8e, 0xa9, 0x08, 0x04, 0xa1, 0x31, 0xd7, 0x5a, 0xab,
|
||||
0x00, 0x87, 0x35, 0x99, 0x2b, 0x7a, 0x0c, 0xe7, 0xba, 0xe5, 0x82, 0x4e, 0xca, 0xdd, 0x56, 0x87,
|
||||
0xb6, 0x8f, 0x2f, 0xd5, 0x16, 0x7d, 0x4b, 0x94, 0x25, 0xbf, 0x3e, 0x5b, 0x16, 0x44, 0x24, 0x96,
|
||||
0x20, 0x94, 0xad, 0xfd, 0xad, 0x01, 0xf5, 0x5d, 0x2c, 0x3e, 0x0f, 0x3a, 0x24, 0x0c, 0x04, 0x4d,
|
||||
0x0e, 0xb0, 0xd8, 0xee, 0xdd, 0xc3, 0x24, 0x3a, 0x12, 0x1e, 0x7e, 0x94, 0x62, 0x2e, 0xd0, 0x0d,
|
||||
0x98, 0x3a, 0x92, 0x02, 0xd3, 0x58, 0x31, 0x56, 0x2b, 0x9e, 0xde, 0xa1, 0x4f, 0x00, 0x06, 0xe1,
|
||||
0xcc, 0xc9, 0x15, 0x63, 0xb5, 0xd6, 0xbc, 0xed, 0x14, 0x53, 0xa8, 0x72, 0xab, 0xcf, 0x76, 0xf6,
|
||||
0x83, 0x08, 0xeb, 0x98, 0x5e, 0xc1, 0xd3, 0x7e, 0x6e, 0xc0, 0xad, 0x4b, 0x21, 0x70, 0x46, 0x63,
|
||||
0x8e, 0xd1, 0x6b, 0xf0, 0x3f, 0xc9, 0xdf, 0x2f, 0x21, 0xa9, 0x49, 0x99, 0x32, 0x45, 0x7b, 0x00,
|
||||
0x27, 0x79, 0x08, 0x6e, 0x4e, 0xae, 0x54, 0x56, 0x6b, 0xcd, 0x35, 0xe7, 0xe5, 0x37, 0xea, 0xf4,
|
||||
0x0f, 0xf5, 0x0a, 0xce, 0x68, 0xb7, 0xc4, 0xac, 0x22, 0x99, 0xdd, 0x19, 0xca, 0x4c, 0x41, 0x2d,
|
||||
0x51, 0x3b, 0x84, 0xe5, 0x5d, 0x2c, 0x1e, 0x04, 0x02, 0xf3, 0x12, 0xbf, 0x3c, 0xb5, 0xe5, 0x14,
|
||||
0x1a, 0x57, 0x4e, 0xe1, 0xef, 0x06, 0xdc, 0xbc, 0xe4, 0xa0, 0xff, 0x76, 0x02, 0x9f, 0x1a, 0x30,
|
||||
0xd3, 0x3f, 0x02, 0x99, 0x50, 0x0d, 0xc2, 0x30, 0xc1, 0x9c, 0x4b, 0xfc, 0x33, 0x5e, 0xbe, 0x45,
|
||||
0x1b, 0x50, 0x65, 0x69, 0xcb, 0x3f, 0xc6, 0x3d, 0x5d, 0x88, 0x0b, 0x8e, 0x6a, 0x3d, 0x27, 0xef,
|
||||
0x4a, 0xe7, 0xc3, 0xb8, 0xe7, 0x4d, 0xb1, 0xb4, 0x75, 0x1f, 0xf7, 0xb2, 0x6c, 0x9c, 0x50, 0x41,
|
||||
0xe2, 0xc8, 0x67, 0xf4, 0x2b, 0x9c, 0x48, 0x84, 0x15, 0xaf, 0xa6, 0x64, 0xfb, 0x99, 0x08, 0xad,
|
||||
0xc3, 0x1c, 0x4b, 0x28, 0xa3, 0x1c, 0x27, 0x3e, 0x4b, 0x08, 0x4d, 0x88, 0xe8, 0x99, 0xd7, 0xa4,
|
||||
0xdd, 0x6c, 0xae, 0xd8, 0xd7, 0x72, 0xbb, 0x01, 0x8b, 0xbb, 0x58, 0x6c, 0x67, 0xc9, 0x1c, 0xb1,
|
||||
0x7b, 0xec, 0x6f, 0xc0, 0x3c, 0xef, 0xa2, 0x2f, 0xeb, 0x0d, 0x98, 0x56, 0x97, 0x45, 0x42, 0x5d,
|
||||
0x14, 0x4b, 0xc5, 0xdc, 0xab, 0x5e, 0x97, 0xae, 0x7b, 0x3b, 0x5e, 0x55, 0x9a, 0xee, 0x85, 0x68,
|
||||
0x03, 0xae, 0xcb, 0xa5, 0xce, 0xc0, 0xe2, 0x25, 0x2e, 0x9e, 0xb2, 0xb2, 0x17, 0xe1, 0xd5, 0x7e,
|
||||
0xc9, 0x28, 0x85, 0x42, 0x6c, 0x3f, 0x86, 0x1b, 0x2f, 0x2a, 0xfe, 0x4d, 0x5c, 0xf3, 0x30, 0xb7,
|
||||
0x8b, 0xc5, 0x41, 0x2f, 0x6e, 0x93, 0x38, 0xca, 0x31, 0x39, 0x80, 0x8a, 0x42, 0x8d, 0xc7, 0x84,
|
||||
0x2a, 0x57, 0x22, 0x09, 0x67, 0xda, 0xcb, 0xb7, 0xf6, 0x82, 0xb4, 0x7f, 0x48, 0x43, 0xbc, 0x17,
|
||||
0x1f, 0xd2, 0x3c, 0xca, 0xcf, 0x06, 0xcc, 0x97, 0xc4, 0x3a, 0xce, 0x7d, 0x98, 0x0b, 0xf1, 0x61,
|
||||
0x90, 0x76, 0x84, 0x1f, 0xd3, 0x10, 0xfb, 0x24, 0x3e, 0xa4, 0x9a, 0xe0, 0xad, 0x22, 0x5a, 0xd6,
|
||||
0x64, 0xce, 0x8e, 0x32, 0xec, 0xc7, 0x78, 0x25, 0x2c, 0x0b, 0xd0, 0x97, 0x30, 0x1f, 0x30, 0xd6,
|
||||
0x21, 0x6d, 0x59, 0xc1, 0xfe, 0x09, 0x4e, 0xf8, 0x60, 0x3e, 0xae, 0x0f, 0xed, 0x27, 0x65, 0x2e,
|
||||
0x43, 0xa3, 0x42, 0x1c, 0x2d, 0xb7, 0xff, 0x36, 0xa0, 0x56, 0xb0, 0x41, 0x08, 0xae, 0xc5, 0x41,
|
||||
0x17, 0xeb, 0x7e, 0x90, 0x6b, 0xb4, 0x04, 0xd3, 0x01, 0x63, 0xbe, 0x94, 0x4f, 0xea, 0x3e, 0x61,
|
||||
0xec, 0x61, 0xa6, 0x32, 0xa1, 0x9a, 0x03, 0xaa, 0x28, 0x8d, 0xde, 0xa2, 0x9b, 0x00, 0x11, 0x11,
|
||||
0x7e, 0x9b, 0x76, 0xbb, 0x44, 0xc8, 0x42, 0x9f, 0xf1, 0x66, 0x22, 0x22, 0x3e, 0x92, 0x82, 0x4c,
|
||||
0xdd, 0x4a, 0x49, 0x27, 0xf4, 0x45, 0x10, 0x71, 0xf3, 0xba, 0x52, 0x4b, 0xc9, 0x67, 0x41, 0xc4,
|
||||
0xa5, 0x37, 0xed, 0x73, 0x9d, 0xd2, 0xde, 0x54, 0x23, 0x45, 0x1f, 0xe7, 0xde, 0x21, 0x66, 0xdc,
|
||||
0xac, 0xca, 0xd1, 0x72, 0x7b, 0x58, 0x2a, 0x3e, 0xa5, 0x61, 0xda, 0xc1, 0xfa, 0x94, 0x1d, 0xcc,
|
||||
0xb8, 0x7d, 0x0f, 0xa6, 0x94, 0x30, 0xa3, 0xcd, 0x02, 0x71, 0x94, 0xd3, 0xce, 0xd6, 0x45, 0x6e,
|
||||
0x93, 0x65, 0x6e, 0xb3, 0x50, 0xe1, 0x69, 0x57, 0x33, 0xce, 0x96, 0xcd, 0x27, 0x33, 0x50, 0x3d,
|
||||
0xc0, 0xc9, 0x09, 0x69, 0x63, 0xf4, 0x83, 0x01, 0xb5, 0x42, 0x55, 0xa0, 0xe6, 0x30, 0x60, 0xe7,
|
||||
0x2b, 0xcb, 0xda, 0x1c, 0xcb, 0x47, 0x95, 0x9d, 0xdd, 0x78, 0xf2, 0xdb, 0x5f, 0xdf, 0x4f, 0xae,
|
||||
0xa3, 0x35, 0x77, 0xc8, 0x1b, 0xa5, 0x5f, 0x94, 0xe8, 0xa9, 0x01, 0x30, 0x68, 0x04, 0xd4, 0x18,
|
||||
0xe1, 0xd8, 0x72, 0x27, 0x59, 0xcd, 0x71, 0x5c, 0x34, 0x50, 0x57, 0x02, 0x5d, 0x43, 0x77, 0x86,
|
||||
0x01, 0xd5, 0xed, 0x87, 0x7e, 0x34, 0xe0, 0xff, 0xe5, 0x19, 0x82, 0xb6, 0x46, 0x38, 0xf7, 0xfc,
|
||||
0x30, 0xb2, 0xde, 0x1c, 0xd7, 0x4d, 0x43, 0xde, 0x92, 0x90, 0x5d, 0xb4, 0x31, 0x0c, 0xb2, 0x1c,
|
||||
0x3a, 0xdc, 0xed, 0xc8, 0x18, 0xe8, 0x27, 0x03, 0x66, 0x5f, 0x1c, 0xcb, 0xe8, 0xee, 0x08, 0x18,
|
||||
0x2e, 0x9a, 0xfd, 0xd6, 0x5b, 0xe3, 0x3b, 0x6a, 0xf8, 0x77, 0x25, 0xfc, 0x06, 0x72, 0x47, 0x84,
|
||||
0xff, 0xb5, 0xfa, 0xab, 0x3c, 0x46, 0xbf, 0x1a, 0x85, 0xb1, 0x5e, 0x7c, 0x09, 0xa0, 0x77, 0x47,
|
||||
0xce, 0xe4, 0x05, 0x2f, 0x15, 0xeb, 0xbd, 0x2b, 0x7a, 0x6b, 0x3e, 0x6f, 0x4b, 0x3e, 0x9b, 0xa8,
|
||||
0x31, 0x8c, 0xcf, 0xe0, 0x11, 0x91, 0x5f, 0xc9, 0x1f, 0x86, 0xfc, 0xb9, 0x5e, 0xf4, 0x3c, 0x44,
|
||||
0xef, 0x8f, 0x80, 0xea, 0x25, 0x4f, 0x5b, 0xeb, 0x83, 0x2b, 0xfb, 0x6b, 0x5e, 0xef, 0x48, 0x5e,
|
||||
0x5b, 0x68, 0x73, 0x0c, 0x5e, 0xf9, 0x5d, 0x6d, 0x3f, 0xf8, 0xe5, 0xb4, 0x6e, 0x3c, 0x3b, 0xad,
|
||||
0x1b, 0x7f, 0x9e, 0xd6, 0x8d, 0xef, 0xce, 0xea, 0x13, 0xcf, 0xce, 0xea, 0x13, 0xcf, 0xcf, 0xea,
|
||||
0x13, 0x5f, 0x34, 0x23, 0x22, 0x8e, 0xd2, 0x96, 0xd3, 0xa6, 0xdd, 0x3c, 0xb0, 0xfa, 0x6c, 0xf0,
|
||||
0xf0, 0xd8, 0x6d, 0x77, 0x08, 0x8e, 0x85, 0x1b, 0x25, 0xac, 0xed, 0x8a, 0x2e, 0x57, 0x63, 0xac,
|
||||
0x35, 0x25, 0x5f, 0x3a, 0x9b, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xf6, 0xf3, 0x0e, 0x76, 0xf1,
|
||||
0x0c, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -1417,10 +1421,15 @@ func (m *Validator) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
i--
|
||||
dAtA[i] = 0x18
|
||||
}
|
||||
if len(m.PubKey) > 0 {
|
||||
i -= len(m.PubKey)
|
||||
copy(dAtA[i:], m.PubKey)
|
||||
i = encodeVarintQuery(dAtA, i, uint64(len(m.PubKey)))
|
||||
if m.PubKey != nil {
|
||||
{
|
||||
size, err := m.PubKey.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintQuery(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
|
@ -1922,8 +1931,8 @@ func (m *Validator) Size() (n int) {
|
|||
if l > 0 {
|
||||
n += 1 + l + sovQuery(uint64(l))
|
||||
}
|
||||
l = len(m.PubKey)
|
||||
if l > 0 {
|
||||
if m.PubKey != nil {
|
||||
l = m.PubKey.Size()
|
||||
n += 1 + l + sovQuery(uint64(l))
|
||||
}
|
||||
if m.VotingPower != 0 {
|
||||
|
@ -2181,7 +2190,7 @@ func (m *GetValidatorSetByHeightRequest) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Pagination == nil {
|
||||
m.Pagination = &PageRequest{}
|
||||
m.Pagination = &query.PageRequest{}
|
||||
}
|
||||
if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -2323,7 +2332,7 @@ func (m *GetValidatorSetByHeightResponse) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Pagination == nil {
|
||||
m.Pagination = &PageResponse{}
|
||||
m.Pagination = &query.PageResponse{}
|
||||
}
|
||||
if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -2412,7 +2421,7 @@ func (m *GetLatestValidatorSetRequest) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Pagination == nil {
|
||||
m.Pagination = &PageRequest{}
|
||||
m.Pagination = &query.PageRequest{}
|
||||
}
|
||||
if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -2554,7 +2563,7 @@ func (m *GetLatestValidatorSetResponse) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Pagination == nil {
|
||||
m.Pagination = &PageResponse{}
|
||||
m.Pagination = &query.PageResponse{}
|
||||
}
|
||||
if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -2617,40 +2626,6 @@ func (m *Validator) Unmarshal(dAtA []byte) error {
|
|||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowQuery
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthQuery
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthQuery
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Address == nil {
|
||||
m.Address = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
|
@ -2677,7 +2652,43 @@ func (m *Validator) Unmarshal(dAtA []byte) error {
|
|||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.PubKey = string(dAtA[iNdEx:postIndex])
|
||||
m.Address = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowQuery
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthQuery
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthQuery
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.PubKey == nil {
|
||||
m.PubKey = &types.Any{}
|
||||
}
|
||||
if err := m.PubKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
|
@ -2872,7 +2883,7 @@ func (m *GetBlockByHeightResponse) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.BlockId == nil {
|
||||
m.BlockId = &types.BlockID{}
|
||||
m.BlockId = &types1.BlockID{}
|
||||
}
|
||||
if err := m.BlockId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -2908,7 +2919,7 @@ func (m *GetBlockByHeightResponse) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Block == nil {
|
||||
m.Block = &types.Block{}
|
||||
m.Block = &types1.Block{}
|
||||
}
|
||||
if err := m.Block.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -3050,7 +3061,7 @@ func (m *GetLatestBlockResponse) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.BlockId == nil {
|
||||
m.BlockId = &types.BlockID{}
|
||||
m.BlockId = &types1.BlockID{}
|
||||
}
|
||||
if err := m.BlockId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -3086,7 +3097,7 @@ func (m *GetLatestBlockResponse) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Block == nil {
|
||||
m.Block = &types.Block{}
|
||||
m.Block = &types1.Block{}
|
||||
}
|
||||
if err := m.Block.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
|
@ -2,11 +2,11 @@
|
|||
// source: cosmos/base/tendermint/v1beta1/query.proto
|
||||
|
||||
/*
|
||||
Package query is a reverse proxy.
|
||||
Package tmservice is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package query
|
||||
package tmservice
|
||||
|
||||
import (
|
||||
"context"
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
qtypes "github.com/cosmos/cosmos-sdk/types/query"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
)
|
||||
|
@ -21,10 +22,11 @@ type queryServer struct {
|
|||
interfaceRegistry codectypes.InterfaceRegistry
|
||||
}
|
||||
|
||||
var _ qtypes.ServiceServer = queryServer{}
|
||||
var _ ServiceServer = queryServer{}
|
||||
var _ codectypes.UnpackInterfacesMessage = &GetLatestValidatorSetResponse{}
|
||||
|
||||
// NewQueryServer creates a new tendermint query server.
|
||||
func NewQueryServer(clientCtx client.Context, interfaceRegistry codectypes.InterfaceRegistry) qtypes.ServiceServer {
|
||||
func NewQueryServer(clientCtx client.Context, interfaceRegistry codectypes.InterfaceRegistry) ServiceServer {
|
||||
return queryServer{
|
||||
clientCtx: clientCtx,
|
||||
interfaceRegistry: interfaceRegistry,
|
||||
|
@ -32,18 +34,18 @@ func NewQueryServer(clientCtx client.Context, interfaceRegistry codectypes.Inter
|
|||
}
|
||||
|
||||
// GetSyncing implements ServiceServer.GetSyncing
|
||||
func (s queryServer) GetSyncing(_ context.Context, _ *qtypes.GetSyncingRequest) (*qtypes.GetSyncingResponse, error) {
|
||||
func (s queryServer) GetSyncing(_ context.Context, _ *GetSyncingRequest) (*GetSyncingResponse, error) {
|
||||
status, err := getNodeStatus(s.clientCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &qtypes.GetSyncingResponse{
|
||||
return &GetSyncingResponse{
|
||||
Syncing: status.SyncInfo.CatchingUp,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetLatestBlock implements ServiceServer.GetLatestBlock
|
||||
func (s queryServer) GetLatestBlock(context.Context, *qtypes.GetLatestBlockRequest) (*qtypes.GetLatestBlockResponse, error) {
|
||||
func (s queryServer) GetLatestBlock(context.Context, *GetLatestBlockRequest) (*GetLatestBlockResponse, error) {
|
||||
status, err := getBlock(s.clientCtx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -55,14 +57,14 @@ func (s queryServer) GetLatestBlock(context.Context, *qtypes.GetLatestBlockReque
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return &qtypes.GetLatestBlockResponse{
|
||||
return &GetLatestBlockResponse{
|
||||
BlockId: &protoBlockID,
|
||||
Block: protoBlock,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetBlockByHeight implements ServiceServer.GetBlockByHeight
|
||||
func (s queryServer) GetBlockByHeight(_ context.Context, req *qtypes.GetBlockByHeightRequest) (*qtypes.GetBlockByHeightResponse, error) {
|
||||
func (s queryServer) GetBlockByHeight(_ context.Context, req *GetBlockByHeightRequest) (*GetBlockByHeightResponse, error) {
|
||||
chainHeight, err := rpc.GetChainHeight(s.clientCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -81,14 +83,14 @@ func (s queryServer) GetBlockByHeight(_ context.Context, req *qtypes.GetBlockByH
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &qtypes.GetBlockByHeightResponse{
|
||||
return &GetBlockByHeightResponse{
|
||||
BlockId: &protoBlockID,
|
||||
Block: protoBlock,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetLatestValidatorSet implements ServiceServer.GetLatestValidatorSet
|
||||
func (s queryServer) GetLatestValidatorSet(ctx context.Context, req *qtypes.GetLatestValidatorSetRequest) (*qtypes.GetLatestValidatorSetResponse, error) {
|
||||
func (s queryServer) GetLatestValidatorSet(ctx context.Context, req *GetLatestValidatorSetRequest) (*GetLatestValidatorSetResponse, error) {
|
||||
page, limit, err := qtypes.ParsePagination(req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -99,24 +101,39 @@ func (s queryServer) GetLatestValidatorSet(ctx context.Context, req *qtypes.GetL
|
|||
return nil, err
|
||||
}
|
||||
|
||||
outputValidatorsRes := &qtypes.GetLatestValidatorSetResponse{
|
||||
outputValidatorsRes := &GetLatestValidatorSetResponse{
|
||||
BlockHeight: validatorsRes.BlockHeight,
|
||||
Validators: make([]*qtypes.Validator, len(validatorsRes.Validators)),
|
||||
Validators: make([]*Validator, len(validatorsRes.Validators)),
|
||||
}
|
||||
|
||||
for i, validator := range validatorsRes.Validators {
|
||||
outputValidatorsRes.Validators[i] = &qtypes.Validator{
|
||||
Address: validator.Address,
|
||||
anyPub, err := codectypes.NewAnyWithValue(validator.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outputValidatorsRes.Validators[i] = &Validator{
|
||||
Address: validator.Address.String(),
|
||||
ProposerPriority: validator.ProposerPriority,
|
||||
PubKey: validator.PubKey,
|
||||
PubKey: anyPub,
|
||||
VotingPower: validator.VotingPower,
|
||||
}
|
||||
}
|
||||
return outputValidatorsRes, nil
|
||||
}
|
||||
|
||||
func (m *GetLatestValidatorSetResponse) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
|
||||
var pubKey cryptotypes.PubKey
|
||||
for _, val := range m.Validators {
|
||||
err := unpacker.UnpackAny(val.PubKey, &pubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetValidatorSetByHeight implements ServiceServer.GetValidatorSetByHeight
|
||||
func (s queryServer) GetValidatorSetByHeight(ctx context.Context, req *qtypes.GetValidatorSetByHeightRequest) (*qtypes.GetValidatorSetByHeightResponse, error) {
|
||||
func (s queryServer) GetValidatorSetByHeight(ctx context.Context, req *GetValidatorSetByHeightRequest) (*GetValidatorSetByHeightResponse, error) {
|
||||
page, limit, err := qtypes.ParsePagination(req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -136,16 +153,20 @@ func (s queryServer) GetValidatorSetByHeight(ctx context.Context, req *qtypes.Ge
|
|||
return nil, err
|
||||
}
|
||||
|
||||
outputValidatorsRes := &qtypes.GetValidatorSetByHeightResponse{
|
||||
outputValidatorsRes := &GetValidatorSetByHeightResponse{
|
||||
BlockHeight: validatorsRes.BlockHeight,
|
||||
Validators: make([]*qtypes.Validator, len(validatorsRes.Validators)),
|
||||
Validators: make([]*Validator, len(validatorsRes.Validators)),
|
||||
}
|
||||
|
||||
for i, validator := range validatorsRes.Validators {
|
||||
outputValidatorsRes.Validators[i] = &qtypes.Validator{
|
||||
Address: validator.Address,
|
||||
anyPub, err := codectypes.NewAnyWithValue(validator.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outputValidatorsRes.Validators[i] = &Validator{
|
||||
Address: validator.Address.String(),
|
||||
ProposerPriority: validator.ProposerPriority,
|
||||
PubKey: validator.PubKey,
|
||||
PubKey: anyPub,
|
||||
VotingPower: validator.VotingPower,
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +174,7 @@ func (s queryServer) GetValidatorSetByHeight(ctx context.Context, req *qtypes.Ge
|
|||
}
|
||||
|
||||
// GetNodeInfo implements ServiceServer.GetNodeInfo
|
||||
func (s queryServer) GetNodeInfo(ctx context.Context, req *qtypes.GetNodeInfoRequest) (*qtypes.GetNodeInfoResponse, error) {
|
||||
func (s queryServer) GetNodeInfo(ctx context.Context, req *GetNodeInfoRequest) (*GetNodeInfoResponse, error) {
|
||||
status, err := getNodeStatus(s.clientCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -162,19 +183,19 @@ func (s queryServer) GetNodeInfo(ctx context.Context, req *qtypes.GetNodeInfoReq
|
|||
protoNodeInfo := status.NodeInfo.ToProto()
|
||||
nodeInfo := version.NewInfo()
|
||||
|
||||
deps := make([]*qtypes.Module, len(nodeInfo.BuildDeps))
|
||||
deps := make([]*Module, len(nodeInfo.BuildDeps))
|
||||
|
||||
for i, dep := range nodeInfo.BuildDeps {
|
||||
deps[i] = &qtypes.Module{
|
||||
deps[i] = &Module{
|
||||
Path: dep.Path,
|
||||
Sum: dep.Sum,
|
||||
Version: dep.Version,
|
||||
}
|
||||
}
|
||||
|
||||
resp := qtypes.GetNodeInfoResponse{
|
||||
resp := GetNodeInfoResponse{
|
||||
DefaultNodeInfo: protoNodeInfo,
|
||||
ApplicationVersion: &qtypes.VersionInfo{
|
||||
ApplicationVersion: &VersionInfo{
|
||||
AppName: nodeInfo.AppName,
|
||||
Name: nodeInfo.Name,
|
||||
GitCommit: nodeInfo.GitCommit,
|
||||
|
@ -193,7 +214,7 @@ func RegisterTendermintService(
|
|||
clientCtx client.Context,
|
||||
interfaceRegistry codectypes.InterfaceRegistry,
|
||||
) {
|
||||
qtypes.RegisterServiceServer(
|
||||
RegisterServiceServer(
|
||||
qrt,
|
||||
NewQueryServer(clientCtx, interfaceRegistry),
|
||||
)
|
||||
|
@ -202,5 +223,5 @@ func RegisterTendermintService(
|
|||
// RegisterGRPCGatewayRoutes mounts the tendermint service's GRPC-gateway routes on the
|
||||
// given Mux.
|
||||
func RegisterGRPCGatewayRoutes(clientConn gogogrpc.ClientConn, mux *runtime.ServeMux) {
|
||||
qtypes.RegisterServiceHandlerClient(context.Background(), mux, qtypes.NewServiceClient(clientConn))
|
||||
RegisterServiceHandlerClient(context.Background(), mux, NewServiceClient(clientConn))
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
qtypes "github.com/cosmos/cosmos-sdk/types/query"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
|
@ -19,7 +22,7 @@ type IntegrationTestSuite struct {
|
|||
cfg network.Config
|
||||
network *network.Network
|
||||
|
||||
queryClient qtypes.ServiceClient
|
||||
queryClient tmservice.ServiceClient
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
|
@ -36,7 +39,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
|||
_, err := s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.queryClient = qtypes.NewServiceClient(s.network.Validators[0].ClientCtx)
|
||||
s.queryClient = tmservice.NewServiceClient(s.network.Validators[0].ClientCtx)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
|
@ -47,13 +50,13 @@ func (s *IntegrationTestSuite) TearDownSuite() {
|
|||
func (s IntegrationTestSuite) TestQueryNodeInfo() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
res, err := s.queryClient.GetNodeInfo(context.Background(), &qtypes.GetNodeInfoRequest{})
|
||||
res, err := s.queryClient.GetNodeInfo(context.Background(), &tmservice.GetNodeInfoRequest{})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(res.ApplicationVersion.AppName, version.NewInfo().AppName)
|
||||
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", val.APIAddress))
|
||||
s.Require().NoError(err)
|
||||
var getInfoRes qtypes.GetNodeInfoResponse
|
||||
var getInfoRes tmservice.GetNodeInfoResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &getInfoRes))
|
||||
s.Require().Equal(getInfoRes.ApplicationVersion.AppName, version.NewInfo().AppName)
|
||||
}
|
||||
|
@ -61,35 +64,35 @@ func (s IntegrationTestSuite) TestQueryNodeInfo() {
|
|||
func (s IntegrationTestSuite) TestQuerySyncing() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
_, err := s.queryClient.GetSyncing(context.Background(), &qtypes.GetSyncingRequest{})
|
||||
_, err := s.queryClient.GetSyncing(context.Background(), &tmservice.GetSyncingRequest{})
|
||||
s.Require().NoError(err)
|
||||
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/syncing", val.APIAddress))
|
||||
s.Require().NoError(err)
|
||||
var syncingRes qtypes.GetSyncingResponse
|
||||
var syncingRes tmservice.GetSyncingResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &syncingRes))
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestQueryLatestBlock() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
_, err := s.queryClient.GetLatestBlock(context.Background(), &qtypes.GetLatestBlockRequest{})
|
||||
_, err := s.queryClient.GetLatestBlock(context.Background(), &tmservice.GetLatestBlockRequest{})
|
||||
s.Require().NoError(err)
|
||||
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", val.APIAddress))
|
||||
s.Require().NoError(err)
|
||||
var blockInfoRes qtypes.GetLatestBlockResponse
|
||||
var blockInfoRes tmservice.GetLatestBlockResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &blockInfoRes))
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestQueryBlockByHeight() {
|
||||
val := s.network.Validators[0]
|
||||
_, err := s.queryClient.GetBlockByHeight(context.Background(), &qtypes.GetBlockByHeightRequest{Height: 1})
|
||||
_, err := s.queryClient.GetBlockByHeight(context.Background(), &tmservice.GetBlockByHeightRequest{Height: 1})
|
||||
s.Require().NoError(err)
|
||||
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/%d", val.APIAddress, 1))
|
||||
s.Require().NoError(err)
|
||||
var blockInfoRes qtypes.GetBlockByHeightResponse
|
||||
var blockInfoRes tmservice.GetBlockByHeightResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &blockInfoRes))
|
||||
}
|
||||
|
||||
|
@ -97,13 +100,17 @@ func (s IntegrationTestSuite) TestQueryLatestValidatorSet() {
|
|||
val := s.network.Validators[0]
|
||||
|
||||
// nil pagination
|
||||
_, err := s.queryClient.GetLatestValidatorSet(context.Background(), &qtypes.GetLatestValidatorSetRequest{
|
||||
res, err := s.queryClient.GetLatestValidatorSet(context.Background(), &tmservice.GetLatestValidatorSetRequest{
|
||||
Pagination: nil,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, len(res.Validators))
|
||||
content, ok := res.Validators[0].PubKey.GetCachedValue().(cryptotypes.PubKey)
|
||||
s.Require().Equal(true, ok)
|
||||
s.Require().Equal(content, val.PubKey)
|
||||
|
||||
//with pagination
|
||||
_, err = s.queryClient.GetLatestValidatorSet(context.Background(), &qtypes.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{
|
||||
_, err = s.queryClient.GetLatestValidatorSet(context.Background(), &tmservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
}})
|
||||
|
@ -116,21 +123,25 @@ func (s IntegrationTestSuite) TestQueryLatestValidatorSet() {
|
|||
// rest request with pagination
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validators/latest?pagination.offset=%d&pagination.limit=%d", val.APIAddress, 0, 1))
|
||||
s.Require().NoError(err)
|
||||
var validatorSetRes qtypes.GetLatestValidatorSetResponse
|
||||
var validatorSetRes tmservice.GetLatestValidatorSetResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &validatorSetRes))
|
||||
s.Require().Equal(1, len(validatorSetRes.Validators))
|
||||
anyPub, err := codectypes.NewAnyWithValue(val.PubKey)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(validatorSetRes.Validators[0].PubKey, anyPub)
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestQueryValidatorSetByHeight() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
// nil pagination
|
||||
_, err := s.queryClient.GetValidatorSetByHeight(context.Background(), &qtypes.GetValidatorSetByHeightRequest{
|
||||
_, err := s.queryClient.GetValidatorSetByHeight(context.Background(), &tmservice.GetValidatorSetByHeightRequest{
|
||||
Height: 1,
|
||||
Pagination: nil,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = s.queryClient.GetValidatorSetByHeight(context.Background(), &qtypes.GetValidatorSetByHeightRequest{
|
||||
_, err = s.queryClient.GetValidatorSetByHeight(context.Background(), &tmservice.GetValidatorSetByHeightRequest{
|
||||
Height: 1,
|
||||
Pagination: &qtypes.PageRequest{
|
||||
Offset: 0,
|
||||
|
@ -144,7 +155,7 @@ func (s IntegrationTestSuite) TestQueryValidatorSetByHeight() {
|
|||
|
||||
// rest query with pagination
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validators/%d?pagination.offset=%d&pagination.limit=%d", val.APIAddress, 1, 0, 1))
|
||||
var validatorSetRes qtypes.GetValidatorSetByHeightResponse
|
||||
var validatorSetRes tmservice.GetValidatorSetByHeightResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &validatorSetRes))
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package client
|
|||
import (
|
||||
gocontext "context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
gogogrpc "github.com/gogo/protobuf/grpc"
|
||||
|
@ -12,10 +13,10 @@ import (
|
|||
"google.golang.org/grpc/encoding/proto"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
)
|
||||
|
||||
var _ gogogrpc.ClientConn = Context{}
|
||||
|
@ -23,7 +24,37 @@ var _ gogogrpc.ClientConn = Context{}
|
|||
var protoCodec = encoding.GetCodec(proto.Name)
|
||||
|
||||
// Invoke implements the grpc ClientConn.Invoke method
|
||||
func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, args, reply interface{}, opts ...grpc.CallOption) error {
|
||||
func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, args, reply interface{}, opts ...grpc.CallOption) (err error) {
|
||||
// Two things can happen here:
|
||||
// 1. either we're broadcasting a Tx, in which call we call Tendermint's broadcast endpoint directly,
|
||||
// 2. or we are querying for state, in which case we call ABCI's Query.
|
||||
|
||||
// In both cases, we don't allow empty request args (it will panic unexpectedly).
|
||||
if reflect.ValueOf(args).IsNil() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "request cannot be nil")
|
||||
}
|
||||
|
||||
// Case 1. Broadcasting a Tx.
|
||||
if isBroadcast(method) {
|
||||
req, ok := args.(*tx.BroadcastTxRequest)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "expected %T, got %T", (*tx.BroadcastTxRequest)(nil), args)
|
||||
}
|
||||
res, ok := reply.(*tx.BroadcastTxResponse)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "expected %T, got %T", (*tx.BroadcastTxResponse)(nil), args)
|
||||
}
|
||||
|
||||
broadcastRes, err := TxServiceBroadcast(grpcCtx, ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*res = *broadcastRes
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Case 2. Querying state.
|
||||
reqBz, err := protoCodec.Marshal(args)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -86,3 +117,7 @@ func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, args, reply
|
|||
func (Context) NewStream(gocontext.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||
return nil, fmt.Errorf("streaming rpc not supported")
|
||||
}
|
||||
|
||||
func isBroadcast(method string) bool {
|
||||
return method == "/cosmos.tx.v1beta1.Service/BroadcastTx"
|
||||
}
|
||||
|
|
|
@ -2,23 +2,45 @@ package keys
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
)
|
||||
|
||||
const (
|
||||
flagUnarmoredHex = "unarmored-hex"
|
||||
flagUnsafe = "unsafe"
|
||||
)
|
||||
|
||||
// ExportKeyCommand exports private keys from the key store.
|
||||
func ExportKeyCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
cmd := &cobra.Command{
|
||||
Use: "export <name>",
|
||||
Short: "Export private keys",
|
||||
Long: `Export a private key from the local keybase in ASCII-armored encrypted format.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Long: `Export a private key from the local keyring in ASCII-armored encrypted format.
|
||||
|
||||
When both the --unarmored-hex and --unsafe flags are selected, cryptographic
|
||||
private key material is exported in an INSECURE fashion that is designed to
|
||||
allow users to import their keys in hot wallets. This feature is for advanced
|
||||
users only that are confident about how to handle private keys work and are
|
||||
FULLY AWARE OF THE RISKS. If you are unsure, you may want to do some research
|
||||
and export your keys in ASCII-armored encrypted format.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
buf := bufio.NewReader(cmd.InOrStdin())
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
unarmored, _ := cmd.Flags().GetBool(flagUnarmoredHex)
|
||||
unsafe, _ := cmd.Flags().GetBool(flagUnsafe)
|
||||
|
||||
if unarmored && unsafe {
|
||||
return exportUnsafeUnarmored(cmd, args[0], buf, clientCtx.Keyring)
|
||||
} else if unarmored || unsafe {
|
||||
return fmt.Errorf("the flags %s and %s must be used together", flagUnsafe, flagUnarmoredHex)
|
||||
}
|
||||
|
||||
encryptPassword, err := input.GetPassword("Enter passphrase to encrypt the exported key:", buf)
|
||||
if err != nil {
|
||||
|
@ -31,7 +53,31 @@ func ExportKeyCommand() *cobra.Command {
|
|||
}
|
||||
|
||||
cmd.Println(armored)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().Bool(flagUnarmoredHex, false, "Export unarmored hex privkey. Requires --unsafe.")
|
||||
cmd.Flags().Bool(flagUnsafe, false, "Enable unsafe operations. This flag must be switched on along with all unsafe operation-specific options.")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func exportUnsafeUnarmored(cmd *cobra.Command, uid string, buf *bufio.Reader, kr keyring.Keyring) error {
|
||||
// confirm deletion, unless -y is passed
|
||||
if yes, err := input.GetConfirmation("WARNING: The private key will be exported as an unarmored hexadecimal string. USE AT YOUR OWN RISK. Continue?", buf, cmd.ErrOrStderr()); err != nil {
|
||||
return err
|
||||
} else if !yes {
|
||||
return nil
|
||||
}
|
||||
|
||||
hexPrivKey, err := keyring.NewUnsafe(kr).UnsafeExportPrivKeyHex(uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.Println(hexPrivKey)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -36,15 +36,34 @@ func Test_runExportCmd(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// Now enter password
|
||||
mockIn.Reset("123456789\n123456789\n")
|
||||
cmd.SetArgs([]string{
|
||||
args := []string{
|
||||
"keyname1",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagHome, kbHome),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
|
||||
})
|
||||
}
|
||||
|
||||
mockIn.Reset("123456789\n123456789\n")
|
||||
cmd.SetArgs(args)
|
||||
|
||||
clientCtx := client.Context{}.WithKeyring(kb)
|
||||
ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx)
|
||||
|
||||
require.NoError(t, cmd.ExecuteContext(ctx))
|
||||
|
||||
argsUnsafeOnly := append(args, "--unsafe")
|
||||
cmd.SetArgs(argsUnsafeOnly)
|
||||
require.Error(t, cmd.ExecuteContext(ctx))
|
||||
|
||||
argsUnarmoredHexOnly := append(args, "--unarmored-hex")
|
||||
cmd.SetArgs(argsUnarmoredHexOnly)
|
||||
require.Error(t, cmd.ExecuteContext(ctx))
|
||||
|
||||
argsUnsafeUnarmoredHex := append(args, "--unsafe", "--unarmored-hex")
|
||||
cmd.SetArgs(argsUnsafeUnarmoredHex)
|
||||
require.Error(t, cmd.ExecuteContext(ctx))
|
||||
|
||||
mockIn, mockOut := testutil.ApplyMockIO(cmd)
|
||||
mockIn.Reset("y\n")
|
||||
require.NoError(t, cmd.ExecuteContext(ctx))
|
||||
require.Equal(t, "2485e33678db4175dc0ecef2d6e1fc493d4a0d7f7ce83324b6ed70afe77f3485\n", mockOut.String())
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
)
|
||||
|
@ -66,10 +67,10 @@ func ValidatorCommand() *cobra.Command {
|
|||
|
||||
// Validator output in bech32 format
|
||||
type ValidatorOutput struct {
|
||||
Address sdk.ConsAddress `json:"address"`
|
||||
PubKey string `json:"pub_key"`
|
||||
ProposerPriority int64 `json:"proposer_priority"`
|
||||
VotingPower int64 `json:"voting_power"`
|
||||
Address sdk.ConsAddress `json:"address"`
|
||||
PubKey cryptotypes.PubKey `json:"pub_key"`
|
||||
ProposerPriority int64 `json:"proposer_priority"`
|
||||
VotingPower int64 `json:"voting_power"`
|
||||
}
|
||||
|
||||
// Validators at a certain height output in bech32 format
|
||||
|
@ -99,19 +100,15 @@ func (rvo ResultValidatorsOutput) String() string {
|
|||
return b.String()
|
||||
}
|
||||
|
||||
func bech32ValidatorOutput(validator *tmtypes.Validator) (ValidatorOutput, error) {
|
||||
func validatorOutput(validator *tmtypes.Validator) (ValidatorOutput, error) {
|
||||
pk, err := cryptocodec.FromTmPubKeyInterface(validator.PubKey)
|
||||
if err != nil {
|
||||
return ValidatorOutput{}, err
|
||||
}
|
||||
bechValPubkey, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, pk)
|
||||
if err != nil {
|
||||
return ValidatorOutput{}, err
|
||||
}
|
||||
|
||||
return ValidatorOutput{
|
||||
Address: sdk.ConsAddress(validator.Address),
|
||||
PubKey: bechValPubkey,
|
||||
PubKey: pk,
|
||||
ProposerPriority: validator.ProposerPriority,
|
||||
VotingPower: validator.VotingPower,
|
||||
}, nil
|
||||
|
@ -136,7 +133,7 @@ func GetValidators(clientCtx client.Context, height *int64, page, limit *int) (R
|
|||
}
|
||||
|
||||
for i := 0; i < len(validatorsRes.Validators); i++ {
|
||||
outputValidatorsRes.Validators[i], err = bech32ValidatorOutput(validatorsRes.Validators[i])
|
||||
outputValidatorsRes.Validators[i], err = validatorOutput(validatorsRes.Validators[i])
|
||||
if err != nil {
|
||||
return ResultValidatorsOutput{}, err
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package legacy
|
|||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
)
|
||||
|
||||
// Cdc defines a global generic sealed Amino codec to be used throughout sdk. It
|
||||
|
@ -15,5 +16,16 @@ func init() {
|
|||
Cdc = codec.NewLegacyAmino()
|
||||
cryptocodec.RegisterCrypto(Cdc)
|
||||
codec.RegisterEvidences(Cdc)
|
||||
Cdc.Seal()
|
||||
}
|
||||
|
||||
// PrivKeyFromBytes unmarshals private key bytes and returns a PrivKey
|
||||
func PrivKeyFromBytes(privKeyBytes []byte) (privKey cryptotypes.PrivKey, err error) {
|
||||
err = Cdc.UnmarshalBinaryBare(privKeyBytes, &privKey)
|
||||
return
|
||||
}
|
||||
|
||||
// PubKeyFromBytes unmarshals public key bytes and returns a PubKey
|
||||
func PubKeyFromBytes(pubKeyBytes []byte) (pubKey cryptotypes.PubKey, err error) {
|
||||
err = Cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
type Any struct {
|
||||
|
|
|
@ -12,7 +12,7 @@ VOLUME [ /simd ]
|
|||
WORKDIR /simd
|
||||
EXPOSE 26656 26657
|
||||
ENTRYPOINT ["/usr/bin/wrapper.sh"]
|
||||
CMD ["start"]
|
||||
CMD ["start", "--log_format", "plain"]
|
||||
STOPSIGNAL SIGTERM
|
||||
|
||||
COPY wrapper.sh /usr/bin/wrapper.sh
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/tendermint/tendermint/crypto/xsalsa20symmetric"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
@ -153,7 +152,7 @@ func encryptPrivKey(privKey cryptotypes.PrivKey, passphrase string) (saltBytes [
|
|||
}
|
||||
|
||||
key = crypto.Sha256(key) // get 32 bytes
|
||||
privKeyBytes := legacy.Cdc.Amino.MustMarshalBinaryBare(privKey)
|
||||
privKeyBytes := legacy.Cdc.MustMarshalBinaryBare(privKey)
|
||||
|
||||
return saltBytes, xsalsa20symmetric.EncryptSymmetric(privKeyBytes, key)
|
||||
}
|
||||
|
@ -206,5 +205,5 @@ func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privK
|
|||
return privKey, err
|
||||
}
|
||||
|
||||
return cryptoAmino.PrivKeyFromBytes(privKeyBytes)
|
||||
return legacy.PrivKeyFromBytes(privKeyBytes)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
"github.com/cosmos/cosmos-sdk/crypto"
|
||||
cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
|
@ -79,7 +78,7 @@ func TestArmorUnarmorPubKey(t *testing.T) {
|
|||
armored := crypto.ArmorPubKeyBytes(legacy.Cdc.Amino.MustMarshalBinaryBare(info.GetPubKey()), "")
|
||||
pubBytes, algo, err := crypto.UnarmorPubKeyBytes(armored)
|
||||
require.NoError(t, err)
|
||||
pub, err := cryptoAmino.PubKeyFromBytes(pubBytes)
|
||||
pub, err := legacy.PubKeyFromBytes(pubBytes)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, string(hd.Secp256k1Type), algo)
|
||||
require.True(t, pub.Equals(info.GetPubKey()))
|
||||
|
@ -87,7 +86,7 @@ func TestArmorUnarmorPubKey(t *testing.T) {
|
|||
armored = crypto.ArmorPubKeyBytes(legacy.Cdc.Amino.MustMarshalBinaryBare(info.GetPubKey()), "unknown")
|
||||
pubBytes, algo, err = crypto.UnarmorPubKeyBytes(armored)
|
||||
require.NoError(t, err)
|
||||
pub, err = cryptoAmino.PubKeyFromBytes(pubBytes)
|
||||
pub, err = legacy.PubKeyFromBytes(pubBytes)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "unknown", algo)
|
||||
require.True(t, pub.Equals(info.GetPubKey()))
|
||||
|
|
|
@ -10,13 +10,6 @@ import (
|
|||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
)
|
||||
|
||||
var amino *codec.LegacyAmino
|
||||
|
||||
func init() {
|
||||
amino = codec.NewLegacyAmino()
|
||||
RegisterCrypto(amino)
|
||||
}
|
||||
|
||||
// RegisterCrypto registers all crypto dependency types with the provided Amino
|
||||
// codec.
|
||||
func RegisterCrypto(cdc *codec.LegacyAmino) {
|
||||
|
@ -38,15 +31,3 @@ func RegisterCrypto(cdc *codec.LegacyAmino) {
|
|||
cdc.RegisterConcrete(&secp256k1.PrivKey{},
|
||||
secp256k1.PrivKeyName, nil)
|
||||
}
|
||||
|
||||
// PrivKeyFromBytes unmarshals private key bytes and returns a PrivKey
|
||||
func PrivKeyFromBytes(privKeyBytes []byte) (privKey cryptotypes.PrivKey, err error) {
|
||||
err = amino.UnmarshalBinaryBare(privKeyBytes, &privKey)
|
||||
return
|
||||
}
|
||||
|
||||
// PubKeyFromBytes unmarshals public key bytes and returns a PubKey
|
||||
func PubKeyFromBytes(pubKeyBytes []byte) (pubKey cryptotypes.PubKey, err error) {
|
||||
err = amino.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,18 +2,12 @@ package keyring
|
|||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
)
|
||||
|
||||
// CryptoCdc defines the codec required for keys and info
|
||||
var CryptoCdc *codec.LegacyAmino
|
||||
|
||||
func init() {
|
||||
CryptoCdc = codec.NewLegacyAmino()
|
||||
cryptocodec.RegisterCrypto(CryptoCdc)
|
||||
RegisterLegacyAminoCodec(CryptoCdc)
|
||||
CryptoCdc.Seal()
|
||||
RegisterLegacyAminoCodec(legacy.Cdc)
|
||||
}
|
||||
|
||||
// RegisterLegacyAminoCodec registers concrete types and interfaces on the given codec.
|
||||
|
|
|
@ -3,6 +3,7 @@ package keyring
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
|
||||
|
@ -246,12 +247,12 @@ func (i multiInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
|
|||
|
||||
// encoding info
|
||||
func marshalInfo(i Info) []byte {
|
||||
return CryptoCdc.MustMarshalBinaryLengthPrefixed(i)
|
||||
return legacy.Cdc.MustMarshalBinaryLengthPrefixed(i)
|
||||
}
|
||||
|
||||
// decoding info
|
||||
func unmarshalInfo(bz []byte) (info Info, err error) {
|
||||
err = CryptoCdc.UnmarshalBinaryLengthPrefixed(bz, &info)
|
||||
err = legacy.Cdc.UnmarshalBinaryLengthPrefixed(bz, &info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -266,7 +267,7 @@ func unmarshalInfo(bz []byte) (info Info, err error) {
|
|||
_, ok := info.(multiInfo)
|
||||
if ok {
|
||||
var multi multiInfo
|
||||
err = CryptoCdc.UnmarshalBinaryLengthPrefixed(bz, &multi)
|
||||
err = legacy.Cdc.UnmarshalBinaryLengthPrefixed(bz, &multi)
|
||||
|
||||
return multi, err
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ import (
|
|||
tmcrypto "github.com/tendermint/tendermint/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/input"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
"github.com/cosmos/cosmos-sdk/crypto"
|
||||
cryptoamino "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/ledger"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
|
@ -88,6 +88,13 @@ type Keyring interface {
|
|||
Exporter
|
||||
}
|
||||
|
||||
// UnsafeKeyring exposes unsafe operations such as unsafe unarmored export in
|
||||
// addition to those that are made available by the Keyring interface.
|
||||
type UnsafeKeyring interface {
|
||||
Keyring
|
||||
UnsafeExporter
|
||||
}
|
||||
|
||||
// Signer is implemented by key stores that want to provide signing capabilities.
|
||||
type Signer interface {
|
||||
// Sign sign byte messages with a user key.
|
||||
|
@ -110,12 +117,20 @@ type Exporter interface {
|
|||
// Export public key
|
||||
ExportPubKeyArmor(uid string) (string, error)
|
||||
ExportPubKeyArmorByAddress(address sdk.Address) (string, error)
|
||||
|
||||
// ExportPrivKey returns a private key in ASCII armored format.
|
||||
// It returns an error if the key does not exist or a wrong encryption passphrase is supplied.
|
||||
ExportPrivKeyArmor(uid, encryptPassphrase string) (armor string, err error)
|
||||
ExportPrivKeyArmorByAddress(address sdk.Address, encryptPassphrase string) (armor string, err error)
|
||||
}
|
||||
|
||||
// UnsafeExporter is implemented by key stores that support unsafe export
|
||||
// of private keys' material.
|
||||
type UnsafeExporter interface {
|
||||
// UnsafeExportPrivKeyHex returns a private key in unarmored hex format
|
||||
UnsafeExportPrivKeyHex(uid string) (string, error)
|
||||
}
|
||||
|
||||
// Option overrides keyring configuration options.
|
||||
type Option func(options *Options)
|
||||
|
||||
|
@ -198,7 +213,7 @@ func (ks keystore) ExportPubKeyArmor(uid string) (string, error) {
|
|||
return "", fmt.Errorf("no key to export with name: %s", uid)
|
||||
}
|
||||
|
||||
return crypto.ArmorPubKeyBytes(CryptoCdc.MustMarshalBinaryBare(bz.GetPubKey()), string(bz.GetAlgo())), nil
|
||||
return crypto.ArmorPubKeyBytes(legacy.Cdc.MustMarshalBinaryBare(bz.GetPubKey()), string(bz.GetAlgo())), nil
|
||||
}
|
||||
|
||||
func (ks keystore) ExportPubKeyArmorByAddress(address sdk.Address) (string, error) {
|
||||
|
@ -240,7 +255,7 @@ func (ks keystore) ExportPrivateKeyObject(uid string) (types.PrivKey, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
priv, err = cryptoamino.PrivKeyFromBytes([]byte(linfo.PrivKeyArmor))
|
||||
priv, err = legacy.PrivKeyFromBytes([]byte(linfo.PrivKeyArmor))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -289,7 +304,7 @@ func (ks keystore) ImportPubKey(uid string, armor string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
pubKey, err := cryptoamino.PubKeyFromBytes(pubBytes)
|
||||
pubKey, err := legacy.PubKeyFromBytes(pubBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -316,7 +331,7 @@ func (ks keystore) Sign(uid string, msg []byte) ([]byte, types.PubKey, error) {
|
|||
return nil, nil, fmt.Errorf("private key not available")
|
||||
}
|
||||
|
||||
priv, err = cryptoamino.PrivKeyFromBytes([]byte(i.PrivKeyArmor))
|
||||
priv, err = legacy.PrivKeyFromBytes([]byte(i.PrivKeyArmor))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -696,7 +711,7 @@ func (ks keystore) writeLocalKey(name string, priv types.PrivKey, algo hd.PubKey
|
|||
// encrypt private key using keyring
|
||||
pub := priv.PubKey()
|
||||
|
||||
info := newLocalInfo(name, pub, string(CryptoCdc.MustMarshalBinaryBare(priv)), algo)
|
||||
info := newLocalInfo(name, pub, string(legacy.Cdc.MustMarshalBinaryBare(priv)), algo)
|
||||
if err := ks.writeInfo(info); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -774,6 +789,29 @@ func (ks keystore) writeMultisigKey(name string, pub types.PubKey) (Info, error)
|
|||
return info, nil
|
||||
}
|
||||
|
||||
type unsafeKeystore struct {
|
||||
keystore
|
||||
}
|
||||
|
||||
// NewUnsafe returns a new keyring that provides support for unsafe operations.
|
||||
func NewUnsafe(kr Keyring) UnsafeKeyring {
|
||||
// The type assertion is against the only keystore
|
||||
// implementation that is currently provided.
|
||||
ks := kr.(keystore)
|
||||
|
||||
return unsafeKeystore{ks}
|
||||
}
|
||||
|
||||
// UnsafeExportPrivKeyHex exports private keys in unarmored hexadecimal format.
|
||||
func (ks unsafeKeystore) UnsafeExportPrivKeyHex(uid string) (privkey string, err error) {
|
||||
priv, err := ks.ExportPrivateKeyObject(uid)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return hex.EncodeToString(priv.Bytes()), nil
|
||||
}
|
||||
|
||||
func addrHexKeyAsString(address sdk.Address) string {
|
||||
return fmt.Sprintf("%s.%s", hex.EncodeToString(address.Bytes()), addressSuffix)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package keyring
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -1092,6 +1093,29 @@ func TestAltKeyring_ImportExportPubKey_ByAddress(t *testing.T) {
|
|||
require.EqualError(t, err, fmt.Sprintf("cannot overwrite key: %s", newUID))
|
||||
}
|
||||
|
||||
func TestAltKeyring_UnsafeExportPrivKeyHex(t *testing.T) {
|
||||
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
uid := theID
|
||||
|
||||
_, _, err = keyring.NewMnemonic(uid, English, sdk.FullFundraiserPath, hd.Secp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
unsafeKeyring := NewUnsafe(keyring)
|
||||
privKey, err := unsafeKeyring.UnsafeExportPrivKeyHex(uid)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 64, len(privKey))
|
||||
|
||||
_, err = hex.DecodeString(privKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
// test error on non existing key
|
||||
_, err = unsafeKeyring.UnsafeExportPrivKeyHex("non-existing")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestAltKeyring_ConstructorSupportedAlgos(t *testing.T) {
|
||||
keyring, err := New(t.Name(), BackendTest, t.TempDir(), nil)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -4,10 +4,11 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_writeReadLedgerInfo(t *testing.T) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
|
@ -238,7 +238,7 @@ func TestRealDeviceSecp256k1(t *testing.T) {
|
|||
|
||||
// now, let's serialize the public key and make sure it still works
|
||||
bs := cdc.Amino.MustMarshalBinaryBare(priv.PubKey())
|
||||
pub2, err := cryptoAmino.PubKeyFromBytes(bs)
|
||||
pub2, err := legacy.PubKeyFromBytes(bs)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
|
||||
// make sure we get the same pubkey when we load from disk
|
||||
|
@ -251,8 +251,8 @@ func TestRealDeviceSecp256k1(t *testing.T) {
|
|||
require.True(t, valid)
|
||||
|
||||
// make sure pubkeys serialize properly as well
|
||||
bs = cdc.Amino.MustMarshalBinaryBare(pub)
|
||||
bpub, err := cryptoAmino.PubKeyFromBytes(bs)
|
||||
bs = legacy.Cdc.MustMarshalBinaryBare(pub)
|
||||
bpub, err := legacy.PubKeyFromBytes(bs)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pub, bpub)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ If you want to open a PR on the Cosmos SDK to update the documentation, please f
|
|||
## Translating
|
||||
|
||||
- Docs translations live in a `docs/country-code/` folder, where `country-code` stands for the country code of the language used (`cn` for Chinese, `kr` for Korea, `fr` for France, ...).
|
||||
- Always translate content living on `master`.
|
||||
- Always translate content living on `master`.
|
||||
- Only content under `/docs/intro/`, `/docs/basics/`, `/docs/core/`, `/docs/building-modules/` and `docs/interfaces` needs to be translated, as well as `docs/README.md`. It is also nice (but not mandatory) to translate `/docs/spec/`.
|
||||
- Specify the release/tag of the translation in the README of your translation folder. Update the release/tag each time you update the translation.
|
||||
|
||||
|
@ -103,7 +103,7 @@ We are using [Algolia](https://www.algolia.com) to power full-text search. This
|
|||
## Consistency
|
||||
|
||||
Because the build processes are identical (as is the information contained herein), this file should be kept in sync as
|
||||
much as possible with its [counterpart in the Tendermint Core repo](https://github.com/tendermint/tendermint/blob/master/docs/DOCS_README.md).
|
||||
much as possible with its [counterpart in the Tendermint Core repo](https://github.com/tendermint/tendermint/blob/v0.34.0/docs/DOCS_README.md).
|
||||
|
||||
### Update and Build the RPC docs
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
# ADR 034: Account Rekeying
|
||||
|
||||
## Changelog
|
||||
|
||||
- 30-09-2020: Initial Draft
|
||||
|
||||
## Status
|
||||
|
||||
PROPOSED
|
||||
|
||||
## Abstract
|
||||
|
||||
Account rekeying is a process hat allows an account to replace its authentication pubkey with a new one.
|
||||
|
||||
## Context
|
||||
|
||||
Currently, in the Cosmos SDK, the address of an auth `BaseAccount` is based on the hash of the public key. Once an account is created, the public key for the account is set in stone, and cannot be changed. This can be a problem for users, as key rotation is a useful security practice, but is not possible currently. Furthermore, as multisigs are a type of pubkey, once a multisig for an account is set, it can not be updated. This is problematic, as multisigs are often used by organizations or companies, who may need to change their set of multisig signers for internal reasons.
|
||||
|
||||
Transferring all the assets of an account to a new account with the updated pubkey is not sufficient, because some "engagements" of an account are not easily transferable. For example, in staking, to transfer bonded Atoms, an account would have to unbond all delegations and wait the three week unbonding period. Even more significantly, for validator operators, ownership over a validator is not transferrable at all, meaning that the operator key for a validator can never be updated, leading to poor operational security for validators.
|
||||
|
||||
## Decision
|
||||
|
||||
We propose the addition of a new feature to `x/auth` that allows accounts to update the public key associated with their account, while keeping the address the same.
|
||||
|
||||
This is possible because the Cosmos SDK `BaseAccount` stores the public key for an account in state, instead of making the assumption that the public key is included in the transaction (whether explicitly or implicitly through the signature) as in other blockchains such as Bitcoin and Ethereum. Because the public key is stored on chain, it is okay for the public key to not hash to the address of an account, as the address is not pertinent to the signature checking process.
|
||||
|
||||
To build this system, we design a new Msg type as follows:
|
||||
|
||||
```protobuf
|
||||
service Msg {
|
||||
rpc ChangePubKey(MsgChangePubKey) returns (MsgChangePubKeyResponse);
|
||||
}
|
||||
|
||||
message MsgChangePubKey {
|
||||
string address = 1;
|
||||
google.protobuf.Any pub_key = 2;
|
||||
}
|
||||
|
||||
message MsgChangePubKeyResponse {}
|
||||
```
|
||||
|
||||
The MsgChangePubKey transaction needs to be signed by the existing pubkey in state.
|
||||
|
||||
Once, approved, the handler for this message type, which takes in the AccountKeeper, will update the in-state pubkey for the account and replace it with the pubkey from the Msg.
|
||||
|
||||
|
||||
An account that has had its pubkey changed cannot be automatically pruned from state. This is because if pruned, the original pubkey of the account would be needed to recreate the same address, but the owner of the address may not have the original pubkey anymore. Currently, we do not automatically prune any accounts anyways, but we would like to keep this option open the road (this is the purpose of account numbers). To resolve this, we charge an additional gas fee for this operation to compensate for this this externality (this bound gas amount is configured as parameter `PubKeyChangeCost`). The bonus gas is charged inside the handler, using the `ConsumeGas` function. Furthermore, in the future, we can allow accounts that have rekeyed manually prune themselves using a new Msg type such as `MsgDeleteAccount`. Manually pruning accounts can give a gas refund as an incentive for performing the action.
|
||||
|
||||
|
||||
```go
|
||||
amount := ak.GetParams(ctx).PubKeyChangeCost
|
||||
ctx.GasMeter().ConsumeGas(amount, "pubkey change fee")
|
||||
```
|
||||
|
||||
|
||||
Everytime a key for an address is changed, we will store a log of this change in the state of the chain, thus creating a stack of all previous keys for an address and the time intervals for which they were active. This allows dapps and clients to easily query past keys for an account which may be useful for features such as verifying timestamped off-chain signed messages.
|
||||
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
* Will allow users and validator operators to employ better operational security practices with key rotation.
|
||||
* Will allow organizations or groups to easily change and add/remove multisig signers.
|
||||
|
||||
### Negative
|
||||
|
||||
Breaks the current assumed relationship between address and pubkeys as H(pubkey) = address. This has a couple of consequences.
|
||||
|
||||
* This makes wallets that support this feature more complicated. For example, if an address on chain was updated, the corresponding key in the CLI wallet also needs to be updated.
|
||||
* Cannot automatically prune accounts with 0 balance that have had their pubkey changed.
|
||||
|
||||
|
||||
### Neutral
|
||||
|
||||
* While the purpose of this is intended to allow the owner of an account to update to a new pubkey they own, this could technically also be used to transfer ownership of an account to a new owner. For example, this could be use used to sell a staked position without unbonding or an account that has vesting tokens. However, the friction of this is very high as this would essentially have to be done as a very specific OTC trade. Furthermore, additional constraints could be added to prevent accouns with Vesting tokens to use this feature.
|
||||
* Will require that PubKeys for an account are included in the genesis exports.
|
||||
|
||||
## References
|
||||
|
||||
+ https://www.algorand.com/resources/blog/announcing-rekeying
|
|
@ -62,17 +62,20 @@ In the Cosmos SDK, accounts are stored and managed via an object called a [`Keyr
|
|||
|
||||
A `Keyring` is an object that stores and manages accounts. In the Cosmos SDK, a `Keyring` implementation follows the `Keyring` interface:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keyring/keyring.go#L50-L88
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/crypto/keyring/keyring.go#L50-L88
|
||||
|
||||
The default implementation of `Keyring` comes from the third-party [`99designs/keyring`](https://github.com/99designs/keyring) library.
|
||||
|
||||
A few notes on the `Keyring` methods:
|
||||
|
||||
- `Sign(uid string, msg []byte) ([]byte, tmcrypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form, and this is done in the `GetSignBytes` method. See an example of `message` preparation from the `x/bank` module. Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/x/bank/types/msgs.go#L51-L54
|
||||
- `NewAccount(uid, mnemonic, bip39Passwd, hdPath string, algo SignatureAlgo) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `NewAccount` method derives keys and addresses using the algorithm specified in the last argument `algo`. Currently, the SDK supports two public key algorithms:
|
||||
- `secp256k1`, as implemented in the [SDK's `crypto/keys/secp256k1` package](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/secp256k1/secp256k1.go),
|
||||
- `ed25519`, as implemented in the [SDK's `crypto/keys/ed25519` package](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/ed25519/ed25519.go).
|
||||
- `Sign(uid string, payload []byte) ([]byte, tmcrypto.PubKey, error)` strictly deals with the signature of the `payload` bytes. Some preliminary work should be done beforehand to prepare and encode the transaction into a canonical `[]byte` form. Protobuf being not deterministic, it has been decided in [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md) that the canonical `payload` to sign is the `SignDoc` struct, deterministically encoded using [ADR-027](adr-027-deterministic-protobuf-serialization.md). Note that signature verification is not implemented in the SDK by default, it is deferred to the [`anteHandler`](../core/baseapp.md#antehandler).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/tx/v1beta1/tx.proto#L47-L64
|
||||
|
||||
- `NewAccount(uid, mnemonic, bip39Passwd, hdPath string, algo SignatureAlgo) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/crypto/armor.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `NewAccount` method derives keys and addresses using the algorithm specified in the last argument `algo`. Currently, the SDK supports two public key algorithms:
|
||||
|
||||
- `secp256k1`, as implemented in the [SDK's `crypto/keys/secp256k1` package](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/crypto/keys/secp256k1/secp256k1.go),
|
||||
- `ed25519`, as implemented in the [SDK's `crypto/keys/ed25519` package](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/crypto/keys/ed25519/ed25519.go).
|
||||
|
||||
- `ExportPrivKeyArmor(uid, encryptPassphrase string) (armor string, err error)` exports a private key in ASCII-armored encrypted format, using the given passphrase. You can then either import it again into the keyring using the `ImportPrivKey(uid, armor, passphrase string)` function, or decrypt it into a raw private key using the `UnarmorDecryptPrivKey(armorStr string, passphrase string)` function.
|
||||
|
||||
Also see the [`Addresses`](#addresses) section for more information.
|
||||
|
@ -93,20 +96,18 @@ Also see the [`Addresses`](#addresses) section for more information.
|
|||
|
||||
### PubKeys
|
||||
|
||||
`PubKey`s used in the Cosmos SDK are Protobuf messages and extend the `Pubkey` interface defined in tendermint's `crypto` package:
|
||||
`PubKey`s used in the Cosmos SDK are Protobuf messages and have the following methods:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/types/types.go#L8-L13
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/master/crypto/types/types.go#L8-L17
|
||||
|
||||
+++ https://github.com/tendermint/tendermint/blob/01c32c62e8840d812359c9e87e9c575aa67acb09/crypto/crypto.go#L22-L28
|
||||
|
||||
- For `secp256k1` keys, the actual implementation can be found [here](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/secp256k1/secp256k1.go).
|
||||
- For `ed25519` keys, it can be found [here](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/ed25519/ed25519.go).
|
||||
- For `secp256k1` keys, the actual implementation can be found [here](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/crypto/keys/secp256k1/secp256k1.go).
|
||||
- For `ed25519` keys, it can be found [here](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/crypto/keys/ed25519/ed25519.go).
|
||||
|
||||
In both case, the actual key (as raw bytes) is the compressed form of the pubkey. The first byte is a `0x02` byte if the `y`-coordinate is the lexicographically largest of the two associated with the `x`-coordinate. Otherwise the first byte is a `0x03`. This prefix is followed with the `x`-coordinate.
|
||||
|
||||
Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw bytes form. Instead, they are encoded to string using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK, it is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L579-L729
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/address.go#L579-L729
|
||||
|
||||
### Addresses
|
||||
|
||||
|
@ -124,11 +125,11 @@ aa := sdk.AccAddress(pub.Address().Bytes())
|
|||
|
||||
These addresses implement the `Address` interface:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L73-L82
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/address.go#L73-L82
|
||||
|
||||
Of note, the `Marshal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuf compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. Here is an example:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L232-L246
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/address.go#L232-L246
|
||||
|
||||
## Next {hide}
|
||||
|
||||
|
|
|
@ -49,17 +49,17 @@ The first thing defined in `app.go` is the `type` of the application. It is gene
|
|||
- **A list of module's `keeper`s.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that the latter can only access the authorized functions.
|
||||
- **A reference to an [`appCodec`](../core/encoding.md).** The application's `appCodec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The default codec is [Protocol Buffers](../core/encoding.md).
|
||||
- **A reference to a [`legacyAmino`](../core/encoding.md) codec.** Some parts of the SDK have not been migrated to use the `appCodec` above, and are still hardcoded to use Amino. Other parts explicity use Amino for backwards compatibility. For these reasons, the application still holds a reference to the legacy Amino codec. Please note that the Amino codec will be removed from the SDK in the upcoming releases.
|
||||
- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering their [`Msg` services](../core/baseapp.md#msg-services) and [gRPC `Query` services](../core/baseapp.md#grpc-query-services), or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). For backwards-compatibility reasons, all modules expose [legacy `Msg`s routes](../core/baseapp.md#routing) and [legacy query routes](../core/baseapp.md#legacy-query-routing), which are also registered by the module manager..
|
||||
- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering their [`Msg` service](../core/baseapp.md#msg-services) and [gRPC `Query` service](../core/baseapp.md#grpc-query-services), or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker).
|
||||
|
||||
See an example of application type definition from `simapp`, the SDK's own app used for demo and testing purposes:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/simapp/app.go#L139-L181
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/app.go#L139-L181
|
||||
|
||||
### Constructor Function
|
||||
|
||||
This function constructs a new application of the type defined in the section above. It must fulfill the `AppCreator` signature in order to be used in the [`start` command](../core/node.md#start-command) of the application's daemon command.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/server/types/app.go#L42-L44
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/types/app.go#L42-L44
|
||||
|
||||
Here are the main actions performed by this function:
|
||||
|
||||
|
@ -81,7 +81,7 @@ Note that this function only creates an instance of the app, while the actual st
|
|||
|
||||
See an example of application constructor from `simapp`:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/simapp/app.go#L192-L429
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/app.go#L192-L429
|
||||
|
||||
### InitChainer
|
||||
|
||||
|
@ -91,7 +91,7 @@ In general, the `InitChainer` is mostly composed of the [`InitGenesis`](../build
|
|||
|
||||
See an example of an `InitChainer` from `simapp`:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/simapp/app.go#L452-L459
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/app.go#L452-L459
|
||||
|
||||
### BeginBlocker and EndBlocker
|
||||
|
||||
|
@ -103,13 +103,13 @@ As a sidenote, it is important to remember that application-specific blockchains
|
|||
|
||||
See an example of `BeginBlocker` and `EndBlocker` functions from `simapp`
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/simapp/app.go#L442-L450
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/app.go#L442-L450
|
||||
|
||||
### Register Codec
|
||||
|
||||
The `EncodingConfig` structure is the last important part of the `app.go` file. The goal of this structure is to define the codecs that will be used throughout the app.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/simapp/params/encoding.go#L9-L16
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/params/encoding.go#L9-L16
|
||||
|
||||
Here are descriptions of what each of the four fields means:
|
||||
|
||||
|
@ -123,7 +123,7 @@ The SDK exposes a `MakeCodecs` function used to create a `EncodingConfig`. It us
|
|||
|
||||
See an example of a `MakeCodecs` from `simapp`:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/simapp/app.go#L429-L435
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/app.go#L429-L435
|
||||
|
||||
## Modules
|
||||
|
||||
|
@ -143,33 +143,19 @@ When a valid block of transactions is received by the full-node, Tendermint rela
|
|||
|
||||
1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`.
|
||||
2. Then, it verifies a few things about the transaction like [fee payment and signatures](#gas-fees.md#antehandler) before extracting the `Msg`(s) contained in the transaction.
|
||||
3. `Msg`s are encoded as Protobuf [`Any`s](#register-codec) via the `sdk.ServiceMsg` struct. By analyzing each `Any`'s `type_url`, the application routes the `Msg` to the corresponding module's `Msg` service.
|
||||
3. `Msg`s are encoded as Protobuf [`Any`s](#register-codec) via the `sdk.ServiceMsg` struct. By analyzing each `Any`'s `type_url`, baseapp's `msgServiceRouter` routes the `Msg` to the corresponding module's `Msg` service.
|
||||
4. If the message is successfully processed, the state is updated.
|
||||
|
||||
For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md).
|
||||
|
||||
Module developers create custom `Msg`s when they build their own module. The general practice is to define all `Msg`s in a Protobuf service called `service Msg {}`, and define each `Msg` as a Protobuf service method, using the `rpc` keyword. These definitions usually reside in a `tx.proto` file. For example, the `x/bank` module defines two `Msg`s to allows users to transfer tokens:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L10-L17
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/bank/v1beta1/tx.proto#L10-L17
|
||||
|
||||
These two `Msg`s are processed by the `Msg` service of the `x/bank` module, which ultimately calls the `keeper` of the `x/auth` module in order to update the state.
|
||||
|
||||
Each module should also implement the `RegisterServices` method as part of the [`AppModule` interface](#application-module-interface). This method should call the `RegisterMsgServer` function provided by the generated Protobuf code.
|
||||
|
||||
#### Handlers
|
||||
|
||||
The [handler](../building-modules/msg-services.md#handler-type) refers to the part of the module responsible for processing the `Msg` after it is routed by `baseapp`. Handler functions of modules are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md).
|
||||
|
||||
The `handler` of a module is generally defined in a file called `handler.go` and consists of:
|
||||
|
||||
- A **switch function** `NewHandler` to route the message to the appropriate `handler` function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). Next is an example from `x/bank`:
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/bank/handler.go#L10-L30
|
||||
- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state.
|
||||
|
||||
Handler functions return a result of type `sdk.Result`, which informs the application on whether the message was successfully processed:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/types/result.go#L15-L40
|
||||
|
||||
### gRPC `Query` Services
|
||||
|
||||
gRPC `Query` services are introduced in the v0.40 Stargate release. They allow users to query the state using [gRPC](https://grpc.io). They are enabled by default, and can be configued under the `grpc.enable` and `grpc.address` fields inside `app.toml`.
|
||||
|
@ -180,35 +166,6 @@ Protobuf generates a `QueryServer` interface for each module, containing all the
|
|||
|
||||
Finally, each module should also implement the `RegisterServices` method as part of the [`AppModule` interface](#application-module-interface). This method should call the `RegisterQueryServer` function provided by the generated Protobuf code.
|
||||
|
||||
### Legacy `Msg`s
|
||||
|
||||
While the [`Msg` service](#msg-services) introduced in v0.40 is the official way to define `Msg`s, the SDK still handles legacy `Msg`s defined with previous versions of the SDK.
|
||||
|
||||
[Legacy `Msg`s](../building-modules/messages-and-queries.md#messages) are objects defined by each module that implement the [`sdk.Msg`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transactions.md) contains one or multiple legacy `Msg`s, and can also contain both legacy and non-legacy `Msg`s.
|
||||
|
||||
The application handles the transaction almost like with `Msg` service `Msg`s, only the third step (routing) differs:
|
||||
|
||||
1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`.
|
||||
2. Then, it verifies a few things about the transaction like [fee payment and signatures](#gas-fees.md#antehandler) before extracting the message(s) contained in the transaction.
|
||||
3. With the `Type()` method of the legacy `Msg`, `baseapp` is able to route it to the appropriate module's [legacy `Msg` handler](#handler) in order for it to be processed.
|
||||
4. If the message is successfully processed, the state is updated.
|
||||
|
||||
New `Msg` services are compatible with legacy `Msg`s in terms of how `Msg`s are handled, please refer to the [handler](#handlers) section for more information.
|
||||
|
||||
### Legacy Query Routes
|
||||
|
||||
Legacy queriers were queriers used before the introduction of Protobuf and gRPC in the SDK. They are present for existing modules, but will be deprecated in a future release of the SDK. If you are developing new modules, gRPC `Query` services should be preferred, and you only need to implement the `LegacyQuerierHandler` interface if you wish to use legacy queriers.
|
||||
|
||||
[`Legacy queriers`](../building-modules/query-services.md#legacy-queriers) are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A [query](../building-modules/messages-and-queries.md#queries) is initiated from an [interface](#application-interface) by an end-user who provides a `queryRoute` and some `data`. The query is then routed to the correct application's `querier` by `baseapp`'s `handleQueryCustom` method using `queryRoute`:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/baseapp/abci.go#L388-L418
|
||||
|
||||
The `Querier` of a module is defined in a file called `keeper/querier.go`, and consists of:
|
||||
|
||||
- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch from the [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice):
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/querier.go#L19-L32
|
||||
- **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON.
|
||||
|
||||
### Keeper
|
||||
|
||||
[`Keepers`](../building-modules/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s).
|
||||
|
@ -257,7 +214,7 @@ The [module's Legacy REST interface](../building-modules/module-interfaces.md#le
|
|||
|
||||
- A `RegisterRoutes` function, which registers each route defined in the file. This function is called from the [main application's interface](#application-interfaces) for each module used within the application. The router used in the SDK is [Gorilla's mux](https://github.com/gorilla/mux).
|
||||
- Custom request type definitions for each query or transaction creation function that needs to be exposed. These custom request types build on the base `request` type of the Cosmos SDK:
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/types/rest/rest.go#L62-L76
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/rest/rest.go#L62-L76
|
||||
- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request.
|
||||
|
||||
These Legacy API endpoints are present in the SDK for backward compatibility purposes and will be removed in the next release.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
order: 4
|
||||
-->
|
||||
|
||||
# Gas and Fees
|
||||
# Gas and Fees
|
||||
|
||||
This document describes the default strategies to handle gas and fees within a Cosmos SDK application. {synopsis}
|
||||
|
||||
|
@ -15,21 +15,21 @@ This document describes the default strategies to handle gas and fees within a C
|
|||
In the Cosmos SDK, `gas` is a special unit that is used to track the consumption of resources during execution. `gas` is typically consumed whenever read and writes are made to the store, but it can also be consumed if expensive computation needs to be done. It serves two main purposes:
|
||||
|
||||
- Make sure blocks are not consuming too many resources and will be finalized. This is implemented by default in the SDK via the [block gas meter](#block-gas-meter).
|
||||
- Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). `fees` generally have to be paid by the sender of the `message`. Note that the SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`AnteHandler`](#antehandler).
|
||||
- Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). `fees` generally have to be paid by the sender of the `message`. Note that the SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`AnteHandler`](#antehandler).
|
||||
|
||||
## Gas Meter
|
||||
|
||||
In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a *gas meter*. Gas meters implement the `GasMeter` interface
|
||||
In the Cosmos SDK, `gas` is a simple alias for `uint64`, and is managed by an object called a _gas meter_. Gas meters implement the `GasMeter` interface
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L31-L39
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L34-L43
|
||||
|
||||
where:
|
||||
|
||||
- `GasConsumed()` returns the amount of gas that was consumed by the gas meter instance.
|
||||
- `GasConsumedToLimit()` returns the amount of gas that was consumed by gas meter instance, or the limit if it is reached.
|
||||
- `Limit()` returns the limit of the gas meter instance. `0` if the gas meter is infinite.
|
||||
- `ConsumeGas(amount Gas, descriptor string)` consumes the amount of `gas` provided. If the `gas` overflows, it panics with the `descriptor` message. If the gas meter is not infinite, it panics if `gas` consumed goes above the limit.
|
||||
- `IsPastLimit()` returns `true` if the amount of gas consumed by the gas meter instance is strictly above the limit, `false` otherwise.
|
||||
- `Limit()` returns the limit of the gas meter instance. `0` if the gas meter is infinite.
|
||||
- `ConsumeGas(amount Gas, descriptor string)` consumes the amount of `gas` provided. If the `gas` overflows, it panics with the `descriptor` message. If the gas meter is not infinite, it panics if `gas` consumed goes above the limit.
|
||||
- `IsPastLimit()` returns `true` if the amount of gas consumed by the gas meter instance is strictly above the limit, `false` otherwise.
|
||||
- `IsOutOfGas()` returns `true` if the amount of gas consumed by the gas meter instance is above or equal to the limit, `false` otherwise.
|
||||
|
||||
The gas meter is generally held in [`ctx`](../core/context.md), and consuming gas is done with the following pattern:
|
||||
|
@ -38,19 +38,19 @@ The gas meter is generally held in [`ctx`](../core/context.md), and consuming ga
|
|||
ctx.GasMeter().ConsumeGas(amount, "description")
|
||||
```
|
||||
|
||||
By default, the Cosmos SDK makes use of two different gas meters, the [main gas meter](#main-gas-metter[) and the [block gas meter](#block-gas-meter).
|
||||
By default, the Cosmos SDK makes use of two different gas meters, the [main gas meter](#main-gas-metter[) and the [block gas meter](#block-gas-meter).
|
||||
|
||||
### Main Gas Meter
|
||||
|
||||
`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas consumption per-transaction.
|
||||
`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas consumption per-transaction.
|
||||
|
||||
Gas consumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`Msg` service](../building-modules/msg-services.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store).
|
||||
Gas consumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`Msg` service](../building-modules/msg-services.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store).
|
||||
|
||||
### Block Gas Meter
|
||||
|
||||
`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`BeginBlock`](../core/baseapp.md#beginblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters. By default Cosmos SDK applications use the default consensus parameters provided by Tendermint:
|
||||
|
||||
+++ https://github.com/tendermint/tendermint/blob/f323c80cb3b78e123ea6238c8e136a30ff749ccc/types/params.go#L65-L72
|
||||
+++ https://github.com/tendermint/tendermint/blob/v0.34.0-rc6/types/params.go#L34-L41
|
||||
|
||||
When a new [transaction](../core/transactions.md) is being processed via `DeliverTx`, the current value of `BlockGasMeter` is checked to see if it is above the limit. If it is, `DeliverTx` returns immediately. This can happen even with the first transaction in a block, as `BeginBlock` itself can consume gas. If not, the transaction is processed normally. At the end of `DeliverTx`, the gas tracked by `ctx.BlockGasMeter()` is increased by the amount consumed to process the transaction:
|
||||
|
||||
|
@ -63,7 +63,7 @@ ctx.BlockGasMeter().ConsumeGas(
|
|||
|
||||
## AnteHandler
|
||||
|
||||
The `AnteHandler` is a special `handler` that is run for every transaction during `CheckTx` and `DeliverTx`, before the `handler` of each `message` in the transaction. `AnteHandler`s have a different signature than `handler`s:
|
||||
The `AnteHandler` is run for every transaction during `CheckTx` and `DeliverTx`, before the `Msg` service of each `Msg` in the transaction. `AnteHandler`s have the following signature:
|
||||
|
||||
```go
|
||||
// AnteHandler authenticates transactions, before their internal messages are handled.
|
||||
|
@ -71,18 +71,18 @@ The `AnteHandler` is a special `handler` that is run for every transaction durin
|
|||
type AnteHandler func(ctx Context, tx Tx, simulate bool) (newCtx Context, result Result, abort bool)
|
||||
```
|
||||
|
||||
The `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose which version of `AnteHandler` fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application:
|
||||
The `anteHandler` is not implemented in the core SDK but in a module. This gives the possibility to developers to choose which version of `AnteHandler` fits their application's needs. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application:
|
||||
|
||||
- Verify that the transaction are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the transaction interface:
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L33-L41
|
||||
This enables developers to play with various types for the transaction of their application. In the default `auth` module, the standard transaction type is `StdTx`:
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/stdtx.go#L22-L29
|
||||
- Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`.
|
||||
- During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensure that the mempool cannot be spammed with garbage transactions.
|
||||
- Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use.
|
||||
- Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is extremely important**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx` is set to `newCtx` after `anteHandler` is run, and the `anteHandler` is run each time `DeliverTx` is called).
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/tx_msg.go#L49-L57
|
||||
This enables developers to play with various types for the transaction of their application. In the default `auth` module, the default transaction type is `Tx`:
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/tx/v1beta1/tx.proto#L12-L25
|
||||
- Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`.
|
||||
- During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensure that the mempool cannot be spammed with garbage transactions.
|
||||
- Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use.
|
||||
- Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is extremely important**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx` is set to `newCtx` after `anteHandler` is run, and the `anteHandler` is run each time `DeliverTx` is called).
|
||||
|
||||
As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns.
|
||||
As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns.
|
||||
|
||||
## Next {hide}
|
||||
|
||||
|
|
|
@ -83,11 +83,13 @@ When `Tx` is received by the application from the underlying consensus engine (e
|
|||
|
||||
### ValidateBasic
|
||||
|
||||
[`Message`s](../core/transactions.md#messages) are extracted from `Tx` and `ValidateBasic`, a method of the `Msg` interface implemented by the module developer, is run for each one. It should include basic **stateless** sanity checks. For example, if the message is to send coins from one address to another, `ValidateBasic` likely checks for nonempty addresses and a nonnegative coin amount, but does not require knowledge of state such as account balance of an address.
|
||||
[`Msg`s](../core/transactions.md#messages) are extracted from `Tx` and `ValidateBasic`, a method of the `Msg` interface implemented by the module developer, is run for each one. It should include basic **stateless** sanity checks. For example, if the message is to send coins from one address to another, `ValidateBasic` likely checks for nonempty addresses and a nonnegative coin amount, but does not require knowledge of state such as account balance of an address.
|
||||
|
||||
### AnteHandler
|
||||
|
||||
The [`AnteHandler`](../basics/gas-fees.md#antehandler), which is technically optional but should be defined for each application, is run. A deep copy of the internal state, `checkState`, is made and the defined `AnteHandler` performs limited checks specified for the transaction type. Using a copy allows the handler to do stateful checks for `Tx` without modifying the last committed state, and revert back to the original if the execution fails.
|
||||
After the ValidateBasic checks, the `AnteHandler`s are run. Technically, they are optional, but in practice, they are very often present to perform signature verification, gas calculation, fee deduction and other core operations related to blockchain transactions.
|
||||
|
||||
A copy of the cached context is provided to the `AnteHandler`, which performs limited checks specified for the transaction type. Using a copy allows the AnteHandler to do stateful checks for `Tx` without modifying the last committed state, and revert back to the original if the execution fails.
|
||||
|
||||
For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module `AnteHandler` checks and increments sequence numbers, checks signatures and account numbers, and deducts fees from the first signer of the transaction - all state changes are made using the `checkState`.
|
||||
|
||||
|
@ -198,7 +200,7 @@ Instead of using their `checkState`, full-nodes use `deliverState`:
|
|||
[`runMsgs`](../core/baseapp.md#runtx-and-runmsgs) to fully execute each `Msg` within the transaction.
|
||||
Since the transaction may have messages from different modules, `BaseApp` needs to know which module
|
||||
to find the appropriate handler. This is achieved using `BaseApp`'s `MsgServiceRouter` so that it can be processed by the module's [`Msg` service](../building-modules/msg-services.md).
|
||||
For legacy `Msg` routing, the `Route` function is called via the [module manager](../building-modules/module-manager.md) to retrieve the route name and find the legacy [`Handler`](../building-modules/msg-services.md#handler-type) within the module.
|
||||
For legacy `Msg` routing, the `Route` function is called via the [module manager](../building-modules/module-manager.md) to retrieve the route name and find the legacy [`Handler`](../building-modules/msg-services.md#handler-type) within the module.
|
||||
|
||||
- **`Msg` service:** The `Msg` service, a step up from `AnteHandler`, is responsible for executing each
|
||||
message in the `Tx` and causes state transitions to persist in `deliverTxState`. It is defined
|
||||
|
|
|
@ -14,12 +14,15 @@ Some important information concerning all legacy REST endpoints:
|
|||
|
||||
## Breaking Changes in Legacy REST Endpoints
|
||||
|
||||
| Legacy REST Endpoint | Description | Breaking Change |
|
||||
| ------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `POST /txs` | Query tx by hash | Endpoint will error when trying to broadcast transactions that don't support Amino serialization (e.g. IBC txs)<sup>1</sup>. |
|
||||
| `GET /txs/{hash}` | Query tx by hash | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)<sup>1</sup>. |
|
||||
| `GET /txs` | Query tx by events | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)<sup>1</sup>. |
|
||||
| `GET /staking/validators` | Get all validators | BondStatus is now a protobuf enum instead of an int32, and JSON serialized using its protobuf name, so expect query parameters like `?status=BOND_STATUS_{BONDED,UNBONDED,UNBONDING}` as opposed to `?status={bonded,unbonded,unbonding}`. |
|
||||
| Legacy REST Endpoint | Description | Breaking Change |
|
||||
| ------------------------------------------------------------------------ | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `POST /txs` | Broadcast tx | Endpoint will error when trying to broadcast transactions that don't support Amino serialization (e.g. IBC txs)<sup>1</sup>. |
|
||||
| `POST /txs/encode`, `POST /txs/decode` | Encode/decode Amino txs from JSON to binary | Endpoint will error when trying to encode/decode transactions that don't support Amino serialization (e.g. IBC txs)<sup>1</sup>. |
|
||||
| `GET /txs/{hash}` | Query tx by hash | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)<sup>1</sup>. |
|
||||
| `GET /txs` | Query tx by events | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)<sup>1</sup>. |
|
||||
| `GET /gov/proposals/{id}/votes`, `GET /gov/proposals/{id}/votes/{voter}` | Gov endpoints for querying votes | All gov endpoints which return votes return int32 in the `option` field instead of string: `1=VOTE_OPTION_YES, 2=VOTE_OPTION_ABSTAIN, 3=VOTE_OPTION_NO, 4=VOTE_OPTION_NO_WITH_VETO`. |
|
||||
| `GET /staking/*` | Staking query endpoints | All staking endpoints which return validators have two breaking changes. First, the validator's `consensus_pubkey` field returns an Amino-encoded struct representing an `Any` instead of a bech32-encoded string representing the pubkey. The `value` field of the `Any` is the pubkey's raw key as base64-encoded bytes. Second, the validator's `status` field now returns an int32 instead of string: `1=BOND_STATUS_UNBONDED`, `2=BOND_STATUS_UNBONDING`, `3=BOND_STATUS_BONDED`. |
|
||||
| `GET /staking/validators` | Get all validators | BondStatus is now a protobuf enum instead of an int32, and JSON serialized using its protobuf name, so expect query parameters like `?status=BOND_STATUS_{BONDED,UNBONDED,UNBONDING}` as opposed to `?status={bonded,unbonded,unbonding}`. |
|
||||
|
||||
<sup>1</sup>: Transactions that don't support Amino serialization are the ones that contain one or more `Msg`s that are not registered with the Amino codec. Currently in the SDK, only IBC `Msg`s fall into this case.
|
||||
|
||||
|
@ -31,7 +34,7 @@ Some modules expose legacy `POST` endpoints to generate unsigned transactions fo
|
|||
|
||||
| Legacy REST Endpoint | Description | New gGPC-gateway REST Endpoint |
|
||||
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `GET /txs/{hash}` | Query tx by hash | `GET /cosmos/tx/v1beta1/tx/{hash}` |
|
||||
| `GET /txs/{hash}` | Query tx by hash | `GET /cosmos/tx/v1beta1/txs/{hash}` |
|
||||
| `GET /txs` | Query tx by events | `GET /cosmos/tx/v1beta1/txs` |
|
||||
| `POST /txs` | Broadcast tx | `POST /cosmos/tx/v1beta1/txs` |
|
||||
| `POST /txs/encode` | Encodes an Amino JSON tx to an Amino binary tx | N/A, use Protobuf directly |
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,6 +14,6 @@
|
|||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"vuepress-theme-cosmos": "^1.0.175"
|
||||
"vuepress-theme-cosmos": "^1.0.178"
|
||||
}
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -23,6 +23,7 @@ require (
|
|||
github.com/golang/snappy v0.0.2 // indirect
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/magiconair/properties v1.8.4
|
||||
|
@ -34,6 +35,7 @@ require (
|
|||
github.com/prometheus/common v0.15.0
|
||||
github.com/rakyll/statik v0.1.7
|
||||
github.com/regen-network/cosmos-proto v0.3.0
|
||||
github.com/rs/zerolog v1.20.0
|
||||
github.com/spf13/afero v1.2.2 // indirect
|
||||
github.com/spf13/cast v1.3.1
|
||||
github.com/spf13/cobra v1.1.1
|
||||
|
|
5
go.sum
5
go.sum
|
@ -247,6 +247,7 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
|
|||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
|
@ -480,6 +481,9 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
|
|||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs=
|
||||
github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
|
@ -725,6 +729,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
|
|
@ -2,13 +2,14 @@ syntax = "proto3";
|
|||
package cosmos.base.tendermint.v1beta1;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "tendermint/p2p/types.proto";
|
||||
import "tendermint/types/block.proto";
|
||||
import "tendermint/types/types.proto";
|
||||
import "cosmos/base/query/v1beta1/pagination.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/types/query";
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/tmservice";
|
||||
|
||||
// Service defines the gRPC querier service for tendermint queries.
|
||||
service Service {
|
||||
|
@ -70,10 +71,10 @@ message GetLatestValidatorSetResponse {
|
|||
|
||||
// Validator is the type for the validator-set.
|
||||
message Validator {
|
||||
bytes address = 1;
|
||||
string pub_key = 2;
|
||||
int64 voting_power = 3;
|
||||
int64 proposer_priority = 4;
|
||||
string address = 1;
|
||||
google.protobuf.Any pub_key = 2;
|
||||
int64 voting_power = 3;
|
||||
int64 proposer_priority = 4;
|
||||
}
|
||||
|
||||
// GetBlockByHeightRequest is the request type for the Query/GetBlockByHeight RPC method.
|
||||
|
|
|
@ -4,6 +4,7 @@ package cosmos.tx.v1beta1;
|
|||
import "google/api/annotations.proto";
|
||||
import "cosmos/base/abci/v1beta1/abci.proto";
|
||||
import "cosmos/tx/v1beta1/tx.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
import "cosmos/base/query/v1beta1/pagination.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/types/tx";
|
||||
|
@ -12,13 +13,22 @@ option go_package = "github.com/cosmos/cosmos-sdk/types/tx";
|
|||
service Service {
|
||||
// Simulate simulates executing a transaction for estimating gas usage.
|
||||
rpc Simulate(SimulateRequest) returns (SimulateResponse) {
|
||||
option (google.api.http).post = "/cosmos/tx/v1beta1/simulate";
|
||||
option (google.api.http) = {
|
||||
post: "/cosmos/tx/v1beta1/simulate"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
// GetTx fetches a tx by hash.
|
||||
rpc GetTx(GetTxRequest) returns (GetTxResponse) {
|
||||
option (google.api.http).get = "/cosmos/tx/v1beta1/tx/{hash}";
|
||||
option (google.api.http).get = "/cosmos/tx/v1beta1/txs/{hash}";
|
||||
}
|
||||
// BroadcastTx broadcast transaction.
|
||||
rpc BroadcastTx(BroadcastTxRequest) returns (BroadcastTxResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/cosmos/tx/v1beta1/txs"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// GetTxsEvent fetches txs by event.
|
||||
rpc GetTxsEvent(GetTxsEventRequest) returns (GetTxsEventResponse) {
|
||||
option (google.api.http).get = "/cosmos/tx/v1beta1/txs";
|
||||
|
@ -28,8 +38,8 @@ service Service {
|
|||
// GetTxsEventRequest is the request type for the Service.TxsByEvents
|
||||
// RPC method.
|
||||
message GetTxsEventRequest {
|
||||
// event is the transaction event type.
|
||||
string event = 1;
|
||||
// events is the list of transaction event type.
|
||||
repeated string events = 1;
|
||||
// pagination defines an pagination for the request.
|
||||
cosmos.base.query.v1beta1.PageRequest pagination = 2;
|
||||
}
|
||||
|
@ -45,6 +55,36 @@ message GetTxsEventResponse {
|
|||
cosmos.base.query.v1beta1.PageResponse pagination = 3;
|
||||
}
|
||||
|
||||
// BroadcastTxRequest is the request type for the Service.BroadcastTxRequest
|
||||
// RPC method.
|
||||
message BroadcastTxRequest {
|
||||
// tx_bytes is the raw transaction.
|
||||
bytes tx_bytes = 1;
|
||||
BroadcastMode mode = 2;
|
||||
}
|
||||
|
||||
// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method.
|
||||
enum BroadcastMode {
|
||||
// zero-value for mode ordering
|
||||
BROADCAST_MODE_UNSPECIFIED = 0;
|
||||
// BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for
|
||||
// the tx to be committed in a block.
|
||||
BROADCAST_MODE_BLOCK = 1;
|
||||
// BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for
|
||||
// a CheckTx execution response only.
|
||||
BROADCAST_MODE_SYNC = 2;
|
||||
// BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns
|
||||
// immediately.
|
||||
BROADCAST_MODE_ASYNC = 3;
|
||||
}
|
||||
|
||||
// BroadcastTxResponse is the response type for the
|
||||
// Service.BroadcastTx method.
|
||||
message BroadcastTxResponse {
|
||||
// tx_response is the queried TxResponses.
|
||||
cosmos.base.abci.v1beta1.TxResponse tx_response = 1;
|
||||
}
|
||||
|
||||
// SimulateRequest is the request type for the Service.Simulate
|
||||
// RPC method.
|
||||
message SimulateRequest {
|
||||
|
|
|
@ -17,7 +17,30 @@ message GenesisState {
|
|||
(gogoproto.castrepeated) = "ClientsConsensusStates",
|
||||
(gogoproto.moretags) = "yaml:\"clients_consensus\""
|
||||
];
|
||||
Params params = 3 [(gogoproto.nullable) = false];
|
||||
// metadata from each client
|
||||
repeated IdentifiedGenesisMetadata clients_metadata = 3
|
||||
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"clients_metadata\""];
|
||||
Params params = 4 [(gogoproto.nullable) = false];
|
||||
// create localhost on initialization
|
||||
bool create_localhost = 4 [(gogoproto.moretags) = "yaml:\"create_localhost\""];
|
||||
bool create_localhost = 5 [(gogoproto.moretags) = "yaml:\"create_localhost\""];
|
||||
// the sequence for the next generated client identifier
|
||||
uint64 next_client_sequence = 6 [(gogoproto.moretags) = "yaml:\"next_client_sequence\""];
|
||||
}
|
||||
|
||||
// GenesisMetadata defines the genesis type for metadata that clients may return
|
||||
// with ExportMetadata
|
||||
message GenesisMetadata {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// store key of metadata without clientID-prefix
|
||||
bytes key = 1;
|
||||
// metadata value
|
||||
bytes value = 2;
|
||||
}
|
||||
|
||||
// IdentifiedGenesisMetadata has the client metadata with the corresponding client id.
|
||||
message IdentifiedGenesisMetadata {
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
repeated GenesisMetadata client_metadata = 2
|
||||
[(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_metadata\""];
|
||||
}
|
|
@ -27,15 +27,13 @@ message MsgCreateClient {
|
|||
option (gogoproto.equal) = false;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// client unique identifier
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// light client state
|
||||
google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
// consensus state associated with the client that corresponds to a given
|
||||
// height.
|
||||
google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""];
|
||||
google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""];
|
||||
// signer address
|
||||
string signer = 4;
|
||||
string signer = 3;
|
||||
}
|
||||
|
||||
// MsgCreateClientResponse defines the Msg/CreateClient response type.
|
||||
|
|
|
@ -10,19 +10,23 @@ import "ibc/core/commitment/v1/commitment.proto";
|
|||
// https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics#data-structures
|
||||
|
||||
// ConnectionEnd defines a stateful object on a chain connected to another
|
||||
// separate one. NOTE: there must only be 2 defined ConnectionEnds to establish
|
||||
// separate one.
|
||||
// NOTE: there must only be 2 defined ConnectionEnds to establish
|
||||
// a connection between two chains.
|
||||
message ConnectionEnd {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
// client associated with this connection.
|
||||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
// IBC version which can be utilised to determine encodings or protocols for
|
||||
// channels or packets utilising this connection
|
||||
// channels or packets utilising this connection.
|
||||
repeated Version versions = 2;
|
||||
// current state of the connection end.
|
||||
State state = 3;
|
||||
// counterparty chain associated with this connection.
|
||||
Counterparty counterparty = 4 [(gogoproto.nullable) = false];
|
||||
// delay period that must pass before a consensus state can be used for packet-verification
|
||||
// NOTE: delay period logic is only implemented by some clients.
|
||||
uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""];
|
||||
}
|
||||
|
||||
// IdentifiedConnection defines a connection with additional connection
|
||||
|
@ -40,6 +44,8 @@ message IdentifiedConnection {
|
|||
State state = 4;
|
||||
// counterparty chain associated with this connection.
|
||||
Counterparty counterparty = 5 [(gogoproto.nullable) = false];
|
||||
// delay period associated with this connection.
|
||||
uint64 delay_period = 6 [(gogoproto.moretags) = "yaml:\"delay_period\""];
|
||||
}
|
||||
|
||||
// State defines if a connection is in one of the following states:
|
||||
|
@ -68,7 +74,7 @@ message Counterparty {
|
|||
// identifies the connection end on the counterparty chain associated with a
|
||||
// given connection.
|
||||
string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""];
|
||||
// commitment merkle prefix of the counterparty chain
|
||||
// commitment merkle prefix of the counterparty chain.
|
||||
ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ message MsgConnectionOpenInit {
|
|||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""];
|
||||
Counterparty counterparty = 2 [(gogoproto.nullable) = false];
|
||||
Version version = 3;
|
||||
string signer = 4;
|
||||
uint64 delay_period = 4 [(gogoproto.moretags) = "yaml:\"delay_period\""];
|
||||
string signer = 5;
|
||||
}
|
||||
|
||||
// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response type.
|
||||
|
@ -50,19 +51,20 @@ message MsgConnectionOpenTry {
|
|||
string previous_connection_id = 2 [(gogoproto.moretags) = "yaml:\"previous_connection_id\""];
|
||||
google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""];
|
||||
Counterparty counterparty = 4 [(gogoproto.nullable) = false];
|
||||
repeated Version counterparty_versions = 5 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""];
|
||||
ibc.core.client.v1.Height proof_height = 6
|
||||
uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""];
|
||||
repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""];
|
||||
ibc.core.client.v1.Height proof_height = 7
|
||||
[(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false];
|
||||
// proof of the initialization the connection on Chain A: `UNITIALIZED ->
|
||||
// INIT`
|
||||
bytes proof_init = 7 [(gogoproto.moretags) = "yaml:\"proof_init\""];
|
||||
bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""];
|
||||
// proof of client state included in message
|
||||
bytes proof_client = 8 [(gogoproto.moretags) = "yaml:\"proof_client\""];
|
||||
bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""];
|
||||
// proof of client consensus state
|
||||
bytes proof_consensus = 9 [(gogoproto.moretags) = "yaml:\"proof_consensus\""];
|
||||
ibc.core.client.v1.Height consensus_height = 10
|
||||
bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""];
|
||||
ibc.core.client.v1.Height consensus_height = 11
|
||||
[(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false];
|
||||
string signer = 11;
|
||||
string signer = 12;
|
||||
}
|
||||
|
||||
// MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type.
|
||||
|
|
|
@ -26,9 +26,9 @@ import (
|
|||
|
||||
// Server defines the server's API interface.
|
||||
type Server struct {
|
||||
Router *mux.Router
|
||||
GRPCRouter *runtime.ServeMux
|
||||
ClientCtx client.Context
|
||||
Router *mux.Router
|
||||
GRPCGatewayRouter *runtime.ServeMux
|
||||
ClientCtx client.Context
|
||||
|
||||
logger log.Logger
|
||||
metrics *telemetry.Metrics
|
||||
|
@ -63,7 +63,7 @@ func New(clientCtx client.Context, logger log.Logger) *Server {
|
|||
Router: mux.NewRouter(),
|
||||
ClientCtx: clientCtx,
|
||||
logger: logger,
|
||||
GRPCRouter: runtime.NewServeMux(
|
||||
GRPCGatewayRouter: runtime.NewServeMux(
|
||||
// Custom marshaler option is required for gogo proto
|
||||
runtime.WithMarshalerOption(runtime.MIMEWildcard, marshalerOption),
|
||||
|
||||
|
@ -124,7 +124,7 @@ func (s *Server) Close() error {
|
|||
}
|
||||
|
||||
func (s *Server) registerGRPCGatewayRoutes() {
|
||||
s.Router.PathPrefix("/").Handler(s.GRPCRouter)
|
||||
s.Router.PathPrefix("/").Handler(s.GRPCGatewayRouter)
|
||||
}
|
||||
|
||||
func (s *Server) registerMetrics() {
|
||||
|
|
|
@ -11,55 +11,66 @@ import (
|
|||
"github.com/stretchr/testify/suite"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
|
||||
|
||||
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
conn *grpc.ClientConn
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
s.network = network.New(s.T(), network.DefaultConfig())
|
||||
s.cfg = network.DefaultConfig()
|
||||
s.network = network.New(s.T(), s.cfg)
|
||||
s.Require().NotNil(s.network)
|
||||
|
||||
_, err := s.network.WaitForHeight(2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
val0 := s.network.Validators[0]
|
||||
s.conn, err = grpc.Dial(
|
||||
val0.AppConfig.GRPC.Address,
|
||||
grpc.WithInsecure(), // Or else we get "no transport security set"
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.conn.Close()
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer() {
|
||||
val0 := s.network.Validators[0]
|
||||
conn, err := grpc.Dial(
|
||||
val0.AppConfig.GRPC.Address,
|
||||
grpc.WithInsecure(), // Or else we get "no transport security set"
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
defer conn.Close()
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_TestService() {
|
||||
// gRPC query to test service should work
|
||||
testClient := testdata.NewQueryClient(conn)
|
||||
testClient := testdata.NewQueryClient(s.conn)
|
||||
testRes, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal("hello", testRes.Message)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_BankBalance() {
|
||||
val0 := s.network.Validators[0]
|
||||
|
||||
// gRPC query to bank service should work
|
||||
denom := fmt.Sprintf("%stoken", val0.Moniker)
|
||||
bankClient := banktypes.NewQueryClient(conn)
|
||||
bankClient := banktypes.NewQueryClient(s.conn)
|
||||
var header metadata.MD
|
||||
bankRes, err := bankClient.Balance(
|
||||
context.Background(),
|
||||
|
@ -82,9 +93,11 @@ func (s *IntegrationTestSuite) TestGRPCServer() {
|
|||
)
|
||||
blockHeight = header.Get(grpctypes.GRPCBlockHeightHeader)
|
||||
s.Require().Equal([]string{"1"}, blockHeight)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_Reflection() {
|
||||
// Test server reflection
|
||||
reflectClient := rpb.NewServerReflectionClient(conn)
|
||||
reflectClient := rpb.NewServerReflectionClient(s.conn)
|
||||
stream, err := reflectClient.ServerReflectionInfo(context.Background(), grpc.WaitForReady(true))
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(stream.Send(&rpb.ServerReflectionRequest{
|
||||
|
@ -101,6 +114,65 @@ func (s *IntegrationTestSuite) TestGRPCServer() {
|
|||
s.Require().True(servicesMap["cosmos.bank.v1beta1.Query"])
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_GetTxsEvent() {
|
||||
// Query the tx via gRPC without pagination. This used to panic, see
|
||||
// https://github.com/cosmos/cosmos-sdk/issues/8038.
|
||||
txServiceClient := txtypes.NewServiceClient(s.conn)
|
||||
_, err := txServiceClient.GetTxsEvent(
|
||||
context.Background(),
|
||||
&tx.GetTxsEventRequest{
|
||||
Events: []string{"message.action=send"},
|
||||
},
|
||||
)
|
||||
// TODO Once https://github.com/cosmos/cosmos-sdk/pull/8029 is merged, this
|
||||
// should not error anymore.
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_BroadcastTx() {
|
||||
val0 := s.network.Validators[0]
|
||||
|
||||
// prepare txBuilder with msg
|
||||
txBuilder := val0.ClientCtx.TxConfig.NewTxBuilder()
|
||||
feeAmount := sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)}
|
||||
gasLimit := testdata.NewTestGasLimit()
|
||||
s.Require().NoError(
|
||||
txBuilder.SetMsgs(&banktypes.MsgSend{
|
||||
FromAddress: val0.Address.String(),
|
||||
ToAddress: val0.Address.String(),
|
||||
Amount: sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)},
|
||||
}),
|
||||
)
|
||||
txBuilder.SetFeeAmount(feeAmount)
|
||||
txBuilder.SetGasLimit(gasLimit)
|
||||
|
||||
// setup txFactory
|
||||
txFactory := clienttx.Factory{}.
|
||||
WithChainID(val0.ClientCtx.ChainID).
|
||||
WithKeybase(val0.ClientCtx.Keyring).
|
||||
WithTxConfig(val0.ClientCtx.TxConfig).
|
||||
WithSignMode(signing.SignMode_SIGN_MODE_DIRECT)
|
||||
|
||||
// Sign Tx.
|
||||
err := authclient.SignTx(txFactory, val0.ClientCtx, val0.Moniker, txBuilder, false)
|
||||
s.Require().NoError(err)
|
||||
|
||||
txBytes, err := val0.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Broadcast the tx via gRPC.
|
||||
queryClient := tx.NewServiceClient(s.conn)
|
||||
grpcRes, err := queryClient.BroadcastTx(
|
||||
context.Background(),
|
||||
&tx.BroadcastTxRequest{
|
||||
Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||
TxBytes: txBytes,
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint32(0), grpcRes.TxResponse.Code)
|
||||
}
|
||||
|
||||
// Test and enforce that we upfront reject any connections to baseapp containing
|
||||
// invalid initial x-cosmos-block-height that aren't positive and in the range [0, max(int64)]
|
||||
// See issue https://github.com/cosmos/cosmos-sdk/issues/7662.
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"github.com/rs/zerolog"
|
||||
tmlog "github.com/tendermint/tendermint/libs/log"
|
||||
)
|
||||
|
||||
var _ tmlog.Logger = (*ZeroLogWrapper)(nil)
|
||||
|
||||
// ZeroLogWrapper provides a wrapper around a zerolog.Logger instance. It implements
|
||||
// Tendermint's Logger interface.
|
||||
type ZeroLogWrapper struct {
|
||||
zerolog.Logger
|
||||
}
|
||||
|
||||
// Info implements Tendermint's Logger interface and logs with level INFO. A set
|
||||
// of key/value tuples may be provided to add context to the log. The number of
|
||||
// tuples must be even and the key of the tuple must be a string.
|
||||
func (z ZeroLogWrapper) Info(msg string, keyVals ...interface{}) {
|
||||
z.Logger.Info().Fields(getLogFields(keyVals...)).Msg(msg)
|
||||
}
|
||||
|
||||
// Error implements Tendermint's Logger interface and logs with level ERR. A set
|
||||
// of key/value tuples may be provided to add context to the log. The number of
|
||||
// tuples must be even and the key of the tuple must be a string.
|
||||
func (z ZeroLogWrapper) Error(msg string, keyVals ...interface{}) {
|
||||
z.Logger.Error().Fields(getLogFields(keyVals...)).Msg(msg)
|
||||
}
|
||||
|
||||
// Debug implements Tendermint's Logger interface and logs with level DEBUG. A set
|
||||
// of key/value tuples may be provided to add context to the log. The number of
|
||||
// tuples must be even and the key of the tuple must be a string.
|
||||
func (z ZeroLogWrapper) Debug(msg string, keyVals ...interface{}) {
|
||||
z.Logger.Debug().Fields(getLogFields(keyVals...)).Msg(msg)
|
||||
}
|
||||
|
||||
// With returns a new wrapped logger with additional context provided by a set
|
||||
// of key/value tuples. The number of tuples must be even and the key of the
|
||||
// tuple must be a string.
|
||||
func (z ZeroLogWrapper) With(keyVals ...interface{}) tmlog.Logger {
|
||||
return ZeroLogWrapper{z.Logger.With().Fields(getLogFields(keyVals...)).Logger()}
|
||||
}
|
||||
|
||||
func getLogFields(keyVals ...interface{}) map[string]interface{} {
|
||||
if len(keyVals)%2 != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
fields := make(map[string]interface{})
|
||||
for i := 0; i < len(keyVals); i += 2 {
|
||||
fields[keyVals[i].(string)] = keyVals[i+1]
|
||||
}
|
||||
|
||||
return fields
|
||||
}
|
|
@ -240,17 +240,17 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App
|
|||
genDocProvider,
|
||||
node.DefaultDBProvider,
|
||||
node.DefaultMetricsProvider(cfg.Instrumentation),
|
||||
ctx.Logger.With("module", "node"),
|
||||
ctx.Logger,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Logger.Debug("Initialization: tmNode created")
|
||||
|
||||
ctx.Logger.Debug("initialization: tmNode created")
|
||||
if err := tmNode.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Logger.Debug("Initialization: tmNode started")
|
||||
ctx.Logger.Debug("initialization: tmNode started")
|
||||
|
||||
config := config.GetConfig(ctx.Viper)
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
tmcfg "github.com/tendermint/tendermint/config"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
tmflags "github.com/tendermint/tendermint/libs/cli/flags"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmlog "github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
|
@ -39,7 +39,7 @@ const ServerContextKey = sdk.ContextKey("server.context")
|
|||
type Context struct {
|
||||
Viper *viper.Viper
|
||||
Config *tmcfg.Config
|
||||
Logger log.Logger
|
||||
Logger tmlog.Logger
|
||||
}
|
||||
|
||||
// ErrorCode contains the exit code for server exit.
|
||||
|
@ -52,10 +52,14 @@ func (e ErrorCode) Error() string {
|
|||
}
|
||||
|
||||
func NewDefaultContext() *Context {
|
||||
return NewContext(viper.New(), tmcfg.DefaultConfig(), log.NewTMLogger(log.NewSyncWriter(os.Stdout)))
|
||||
return NewContext(
|
||||
viper.New(),
|
||||
tmcfg.DefaultConfig(),
|
||||
ZeroLogWrapper{log.Logger},
|
||||
)
|
||||
}
|
||||
|
||||
func NewContext(v *viper.Viper, config *tmcfg.Config, logger log.Logger) *Context {
|
||||
func NewContext(v *viper.Viper, config *tmcfg.Config, logger tmlog.Logger) *Context {
|
||||
return &Context{v, config, logger}
|
||||
}
|
||||
|
||||
|
@ -86,27 +90,29 @@ func InterceptConfigsPreRunHandler(cmd *cobra.Command) error {
|
|||
serverCtx.Viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
|
||||
serverCtx.Viper.AutomaticEnv()
|
||||
|
||||
// Intercept configuration files, using both Viper instances separately
|
||||
// intercept configuration files, using both Viper instances separately
|
||||
config, err := interceptConfigs(serverCtx.Viper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Return value is a tendermint configuration object
|
||||
|
||||
// return value is a tendermint configuration object
|
||||
serverCtx.Config = config
|
||||
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, tmcfg.DefaultLogLevel())
|
||||
var logWriter io.Writer
|
||||
if strings.ToLower(serverCtx.Viper.GetString(flags.FlagLogFormat)) == tmcfg.LogFormatPlain {
|
||||
logWriter = zerolog.ConsoleWriter{Out: os.Stderr}
|
||||
} else {
|
||||
logWriter = os.Stderr
|
||||
}
|
||||
|
||||
logLvlStr := serverCtx.Viper.GetString(flags.FlagLogLevel)
|
||||
logLvl, err := zerolog.ParseLevel(logLvlStr)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to parse log level (%s): %w", logLvlStr, err)
|
||||
}
|
||||
|
||||
// Check if the tendermint flag for trace logging is set
|
||||
// if it is then setup a tracing logger in this app as well
|
||||
if serverCtx.Viper.GetBool(tmcli.TraceFlag) {
|
||||
logger = log.NewTracingLogger(logger)
|
||||
}
|
||||
|
||||
serverCtx.Logger = logger.With("module", "main")
|
||||
serverCtx.Logger = ZeroLogWrapper{zerolog.New(logWriter).Level(logLvl).With().Timestamp().Logger()}
|
||||
|
||||
return SetCmdServerContext(cmd, serverCtx)
|
||||
}
|
||||
|
|
|
@ -10,8 +10,9 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
)
|
||||
|
||||
var CancelledInPreRun = errors.New("Canelled in prerun")
|
||||
|
|
|
@ -560,13 +560,13 @@ func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APICon
|
|||
// Register legacy tx routes.
|
||||
authrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
|
||||
// Register new tx routes from grpc-gateway.
|
||||
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCRouter)
|
||||
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
||||
// Register new tendermint queries routes from grpc-gateway.
|
||||
tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCRouter)
|
||||
tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
||||
|
||||
// Register legacy and grpc-gateway routes for all modules.
|
||||
ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router)
|
||||
ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCRouter)
|
||||
ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
|
||||
|
||||
// register swagger API from root so that other applications can override easily
|
||||
if apiConfig.Swagger {
|
||||
|
|
|
@ -6,8 +6,10 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/cobra"
|
||||
tmcfg "github.com/tendermint/tendermint/config"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
@ -79,7 +81,8 @@ func Execute(rootCmd *cobra.Command) error {
|
|||
ctx = context.WithValue(ctx, client.ClientContextKey, &client.Context{})
|
||||
ctx = context.WithValue(ctx, server.ServerContextKey, srvCtx)
|
||||
|
||||
rootCmd.PersistentFlags().String("log_level", srvCtx.Config.LogLevel, "The logging level in the format of <module>:<level>,...")
|
||||
rootCmd.PersistentFlags().String(flags.FlagLogLevel, zerolog.InfoLevel.String(), "The logging level (trace|debug|info|warn|error|fatal|panic)")
|
||||
rootCmd.PersistentFlags().String(flags.FlagLogFormat, tmcfg.LogFormatJSON, "The logging format (json|plain)")
|
||||
|
||||
executor := tmcli.PrepareBaseCmd(rootCmd, "", simapp.DefaultNodeHome)
|
||||
return executor.ExecuteContext(ctx)
|
||||
|
|
|
@ -549,9 +549,12 @@ func (rs *Store) SetInitialVersion(version int64) error {
|
|||
|
||||
// Loop through all the stores, if it's an IAVL store, then set initial
|
||||
// version on it.
|
||||
for _, commitKVStore := range rs.stores {
|
||||
if storeWithVersion, ok := commitKVStore.(types.StoreWithInitialVersion); ok {
|
||||
storeWithVersion.SetInitialVersion(version)
|
||||
for key, store := range rs.stores {
|
||||
if store.GetStoreType() == types.StoreTypeIAVL {
|
||||
// If the store is wrapped with an inter-block cache, we must first unwrap
|
||||
// it to get the underlying IAVL store.
|
||||
store = rs.GetCommitKVStore(key)
|
||||
store.(*iavl.Store).SetInitialVersion(version)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -657,11 +657,18 @@ func TestSetInitialVersion(t *testing.T) {
|
|||
db := dbm.NewMemDB()
|
||||
multi := newMultiStoreWithMounts(db, types.PruneNothing)
|
||||
|
||||
require.NoError(t, multi.LoadLatestVersion())
|
||||
|
||||
multi.SetInitialVersion(5)
|
||||
require.Equal(t, int64(5), multi.initialVersion)
|
||||
|
||||
multi.Commit()
|
||||
require.Equal(t, int64(5), multi.LastCommitID().Version)
|
||||
|
||||
ckvs := multi.GetCommitKVStore(multi.keysByName["store1"])
|
||||
iavlStore, ok := ckvs.(*iavl.Store)
|
||||
require.True(t, ok)
|
||||
require.True(t, iavlStore.VersionExists(5))
|
||||
}
|
||||
|
||||
func BenchmarkMultistoreSnapshot100K(b *testing.B) {
|
||||
|
|
|
@ -5,11 +5,11 @@ import (
|
|||
"io"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmstrings "github.com/tendermint/tendermint/libs/strings"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
tmstrings "github.com/tendermint/tendermint/libs/strings"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/bech32"
|
||||
)
|
||||
|
@ -663,7 +662,7 @@ func GetPubKeyFromBech32(pkt Bech32PubKeyType, pubkeyStr string) (cryptotypes.Pu
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return cryptocodec.PubKeyFromBytes(bz)
|
||||
return legacy.PubKeyFromBytes(bz)
|
||||
}
|
||||
|
||||
// MustGetPubKeyFromBech32 calls GetPubKeyFromBech32 except it panics on error.
|
||||
|
|
|
@ -151,12 +151,14 @@ func errIsNil(err error) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
var errPanicWithMsg = Wrapf(ErrPanic, "panic message redacted to hide potentially sensitive system info")
|
||||
|
||||
// Redact replaces an error that is not initialized as an ABCI Error with a
|
||||
// generic internal error instance. If the error is an ABCI Error, that error is
|
||||
// simply returned.
|
||||
func Redact(err error) error {
|
||||
if ErrPanic.Is(err) {
|
||||
return ErrPanic
|
||||
return errPanicWithMsg
|
||||
}
|
||||
if abciCode(err) == internalABCICode {
|
||||
return errInternal
|
||||
|
|
|
@ -171,7 +171,7 @@ func (s *abciTestSuite) TestRedact() {
|
|||
}{
|
||||
"panic looses message": {
|
||||
err: Wrap(ErrPanic, "some secret stack trace"),
|
||||
changed: ErrPanic,
|
||||
changed: errPanicWithMsg,
|
||||
},
|
||||
"sdk errors untouched": {
|
||||
err: Wrap(ErrUnauthorized, "cannot drop db"),
|
||||
|
@ -233,7 +233,7 @@ func (s *abciTestSuite) TestABCIInfoSerializeErr() {
|
|||
},
|
||||
"redact in default encoder": {
|
||||
src: myPanic,
|
||||
exp: "panic",
|
||||
exp: "panic message redacted to hide potentially sensitive system info: panic",
|
||||
},
|
||||
"do not redact in debug encoder": {
|
||||
src: myPanic,
|
||||
|
|
|
@ -7,10 +7,11 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -159,7 +159,7 @@ func (s *paginationTestSuite) TestPagination() {
|
|||
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
|
||||
res, err = queryClient.AllBalances(gocontext.Background(), request)
|
||||
s.Require().Error(err)
|
||||
s.Require().Equal(err.Error(), "invalid request, either offset or key is expected, got both")
|
||||
s.Require().Equal("rpc error: code = InvalidArgument desc = paginate: invalid request, either offset or key is expected, got both", err.Error())
|
||||
|
||||
s.T().Log("verify paginate with offset greater than total results")
|
||||
pageReq = &query.PageRequest{Offset: 300, Limit: defaultLimit, CountTotal: false}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
fmt "fmt"
|
||||
types "github.com/cosmos/cosmos-sdk/types"
|
||||
query "github.com/cosmos/cosmos-sdk/types/query"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
grpc1 "github.com/gogo/protobuf/grpc"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
|
@ -30,11 +31,50 @@ var _ = math.Inf
|
|||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method.
|
||||
type BroadcastMode int32
|
||||
|
||||
const (
|
||||
// zero-value for mode ordering
|
||||
BroadcastMode_BROADCAST_MODE_UNSPECIFIED BroadcastMode = 0
|
||||
// BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for
|
||||
// the tx to be committed in a block.
|
||||
BroadcastMode_BROADCAST_MODE_BLOCK BroadcastMode = 1
|
||||
// BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for
|
||||
// a CheckTx execution response only.
|
||||
BroadcastMode_BROADCAST_MODE_SYNC BroadcastMode = 2
|
||||
// BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns
|
||||
// immediately.
|
||||
BroadcastMode_BROADCAST_MODE_ASYNC BroadcastMode = 3
|
||||
)
|
||||
|
||||
var BroadcastMode_name = map[int32]string{
|
||||
0: "BROADCAST_MODE_UNSPECIFIED",
|
||||
1: "BROADCAST_MODE_BLOCK",
|
||||
2: "BROADCAST_MODE_SYNC",
|
||||
3: "BROADCAST_MODE_ASYNC",
|
||||
}
|
||||
|
||||
var BroadcastMode_value = map[string]int32{
|
||||
"BROADCAST_MODE_UNSPECIFIED": 0,
|
||||
"BROADCAST_MODE_BLOCK": 1,
|
||||
"BROADCAST_MODE_SYNC": 2,
|
||||
"BROADCAST_MODE_ASYNC": 3,
|
||||
}
|
||||
|
||||
func (x BroadcastMode) String() string {
|
||||
return proto.EnumName(BroadcastMode_name, int32(x))
|
||||
}
|
||||
|
||||
func (BroadcastMode) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_e0b00a618705eca7, []int{0}
|
||||
}
|
||||
|
||||
// GetTxsEventRequest is the request type for the Service.TxsByEvents
|
||||
// RPC method.
|
||||
type GetTxsEventRequest struct {
|
||||
// event is the transaction event type.
|
||||
Event string `protobuf:"bytes,1,opt,name=event,proto3" json:"event,omitempty"`
|
||||
// events is the list of transaction event type.
|
||||
Events []string `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
|
||||
// pagination defines an pagination for the request.
|
||||
Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||
}
|
||||
|
@ -72,11 +112,11 @@ func (m *GetTxsEventRequest) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_GetTxsEventRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *GetTxsEventRequest) GetEvent() string {
|
||||
func (m *GetTxsEventRequest) GetEvents() []string {
|
||||
if m != nil {
|
||||
return m.Event
|
||||
return m.Events
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetTxsEventRequest) GetPagination() *query.PageRequest {
|
||||
|
@ -151,6 +191,108 @@ func (m *GetTxsEventResponse) GetPagination() *query.PageResponse {
|
|||
return nil
|
||||
}
|
||||
|
||||
// BroadcastTxRequest is the request type for the Service.BroadcastTxRequest
|
||||
// RPC method.
|
||||
type BroadcastTxRequest struct {
|
||||
// tx_bytes is the raw transaction.
|
||||
TxBytes []byte `protobuf:"bytes,1,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"`
|
||||
Mode BroadcastMode `protobuf:"varint,2,opt,name=mode,proto3,enum=cosmos.tx.v1beta1.BroadcastMode" json:"mode,omitempty"`
|
||||
}
|
||||
|
||||
func (m *BroadcastTxRequest) Reset() { *m = BroadcastTxRequest{} }
|
||||
func (m *BroadcastTxRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*BroadcastTxRequest) ProtoMessage() {}
|
||||
func (*BroadcastTxRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_e0b00a618705eca7, []int{2}
|
||||
}
|
||||
func (m *BroadcastTxRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *BroadcastTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_BroadcastTxRequest.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *BroadcastTxRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BroadcastTxRequest.Merge(m, src)
|
||||
}
|
||||
func (m *BroadcastTxRequest) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *BroadcastTxRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BroadcastTxRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BroadcastTxRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *BroadcastTxRequest) GetTxBytes() []byte {
|
||||
if m != nil {
|
||||
return m.TxBytes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BroadcastTxRequest) GetMode() BroadcastMode {
|
||||
if m != nil {
|
||||
return m.Mode
|
||||
}
|
||||
return BroadcastMode_BROADCAST_MODE_UNSPECIFIED
|
||||
}
|
||||
|
||||
// BroadcastTxResponse is the response type for the
|
||||
// Service.BroadcastTx method.
|
||||
type BroadcastTxResponse struct {
|
||||
// tx_response is the queried TxResponses.
|
||||
TxResponse *types.TxResponse `protobuf:"bytes,1,opt,name=tx_response,json=txResponse,proto3" json:"tx_response,omitempty"`
|
||||
}
|
||||
|
||||
func (m *BroadcastTxResponse) Reset() { *m = BroadcastTxResponse{} }
|
||||
func (m *BroadcastTxResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*BroadcastTxResponse) ProtoMessage() {}
|
||||
func (*BroadcastTxResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_e0b00a618705eca7, []int{3}
|
||||
}
|
||||
func (m *BroadcastTxResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *BroadcastTxResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_BroadcastTxResponse.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *BroadcastTxResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BroadcastTxResponse.Merge(m, src)
|
||||
}
|
||||
func (m *BroadcastTxResponse) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *BroadcastTxResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BroadcastTxResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BroadcastTxResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *BroadcastTxResponse) GetTxResponse() *types.TxResponse {
|
||||
if m != nil {
|
||||
return m.TxResponse
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SimulateRequest is the request type for the Service.Simulate
|
||||
// RPC method.
|
||||
type SimulateRequest struct {
|
||||
|
@ -162,7 +304,7 @@ func (m *SimulateRequest) Reset() { *m = SimulateRequest{} }
|
|||
func (m *SimulateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SimulateRequest) ProtoMessage() {}
|
||||
func (*SimulateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_e0b00a618705eca7, []int{2}
|
||||
return fileDescriptor_e0b00a618705eca7, []int{4}
|
||||
}
|
||||
func (m *SimulateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
|
@ -211,7 +353,7 @@ func (m *SimulateResponse) Reset() { *m = SimulateResponse{} }
|
|||
func (m *SimulateResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*SimulateResponse) ProtoMessage() {}
|
||||
func (*SimulateResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_e0b00a618705eca7, []int{3}
|
||||
return fileDescriptor_e0b00a618705eca7, []int{5}
|
||||
}
|
||||
func (m *SimulateResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
|
@ -265,7 +407,7 @@ func (m *GetTxRequest) Reset() { *m = GetTxRequest{} }
|
|||
func (m *GetTxRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetTxRequest) ProtoMessage() {}
|
||||
func (*GetTxRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_e0b00a618705eca7, []int{4}
|
||||
return fileDescriptor_e0b00a618705eca7, []int{6}
|
||||
}
|
||||
func (m *GetTxRequest) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
|
@ -313,7 +455,7 @@ func (m *GetTxResponse) Reset() { *m = GetTxResponse{} }
|
|||
func (m *GetTxResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetTxResponse) ProtoMessage() {}
|
||||
func (*GetTxResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_e0b00a618705eca7, []int{5}
|
||||
return fileDescriptor_e0b00a618705eca7, []int{7}
|
||||
}
|
||||
func (m *GetTxResponse) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
|
@ -357,8 +499,11 @@ func (m *GetTxResponse) GetTxResponse() *types.TxResponse {
|
|||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("cosmos.tx.v1beta1.BroadcastMode", BroadcastMode_name, BroadcastMode_value)
|
||||
proto.RegisterType((*GetTxsEventRequest)(nil), "cosmos.tx.v1beta1.GetTxsEventRequest")
|
||||
proto.RegisterType((*GetTxsEventResponse)(nil), "cosmos.tx.v1beta1.GetTxsEventResponse")
|
||||
proto.RegisterType((*BroadcastTxRequest)(nil), "cosmos.tx.v1beta1.BroadcastTxRequest")
|
||||
proto.RegisterType((*BroadcastTxResponse)(nil), "cosmos.tx.v1beta1.BroadcastTxResponse")
|
||||
proto.RegisterType((*SimulateRequest)(nil), "cosmos.tx.v1beta1.SimulateRequest")
|
||||
proto.RegisterType((*SimulateResponse)(nil), "cosmos.tx.v1beta1.SimulateResponse")
|
||||
proto.RegisterType((*GetTxRequest)(nil), "cosmos.tx.v1beta1.GetTxRequest")
|
||||
|
@ -368,43 +513,54 @@ func init() {
|
|||
func init() { proto.RegisterFile("cosmos/tx/v1beta1/service.proto", fileDescriptor_e0b00a618705eca7) }
|
||||
|
||||
var fileDescriptor_e0b00a618705eca7 = []byte{
|
||||
// 563 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xcd, 0x6e, 0xd3, 0x40,
|
||||
0x10, 0xae, 0x1d, 0xfa, 0xc3, 0xa4, 0x08, 0x58, 0x7e, 0x14, 0x99, 0xe2, 0x06, 0xa7, 0x69, 0x23,
|
||||
0x24, 0xbc, 0x6a, 0xb8, 0xf4, 0x80, 0x84, 0x84, 0x54, 0x22, 0x6e, 0xc8, 0xed, 0x89, 0x4b, 0xb5,
|
||||
0x09, 0x5b, 0xc7, 0x22, 0xf1, 0xba, 0xde, 0x4d, 0xb4, 0x15, 0xf4, 0xc2, 0x91, 0x13, 0x12, 0x2f,
|
||||
0xc5, 0x31, 0x12, 0x17, 0x8e, 0x28, 0xe1, 0x0d, 0x78, 0x01, 0xe4, 0xf5, 0x3a, 0x71, 0xa8, 0x4d,
|
||||
0x7b, 0xf2, 0xae, 0xfc, 0xfd, 0xcc, 0x37, 0xe3, 0x31, 0x6c, 0xf7, 0x18, 0x1f, 0x32, 0x8e, 0x85,
|
||||
0xc4, 0xe3, 0xfd, 0x2e, 0x15, 0x64, 0x1f, 0x73, 0x1a, 0x8f, 0x83, 0x1e, 0x75, 0xa3, 0x98, 0x09,
|
||||
0x86, 0xee, 0xa6, 0x00, 0x57, 0x48, 0x57, 0x03, 0xac, 0x2d, 0x9f, 0x31, 0x7f, 0x40, 0x31, 0x89,
|
||||
0x02, 0x4c, 0xc2, 0x90, 0x09, 0x22, 0x02, 0x16, 0xf2, 0x94, 0x60, 0x35, 0xb4, 0x62, 0x97, 0x70,
|
||||
0x8a, 0x49, 0xb7, 0x17, 0xcc, 0x85, 0x93, 0x8b, 0x06, 0x59, 0x97, 0x6d, 0x85, 0xd4, 0xef, 0x9e,
|
||||
0xe6, 0x05, 0xce, 0x46, 0x34, 0x3e, 0x9f, 0x63, 0x22, 0xe2, 0x07, 0xa1, 0x72, 0x4b, 0xb1, 0x4e,
|
||||
0x0c, 0xa8, 0x43, 0xc5, 0xb1, 0xe4, 0x87, 0x63, 0x1a, 0x0a, 0x8f, 0x9e, 0x8d, 0x28, 0x17, 0xe8,
|
||||
0x3e, 0xac, 0xd2, 0xe4, 0x5e, 0x33, 0xea, 0x46, 0xeb, 0xa6, 0x97, 0x5e, 0xd0, 0x6b, 0x80, 0x05,
|
||||
0xbf, 0x66, 0xd6, 0x8d, 0x56, 0xb5, 0xbd, 0xeb, 0xea, 0x78, 0x89, 0x99, 0xab, 0xcc, 0xb2, 0x98,
|
||||
0xee, 0x5b, 0xe2, 0x53, 0xad, 0xe8, 0xe5, 0x98, 0xce, 0xc4, 0x80, 0x7b, 0x4b, 0xa6, 0x3c, 0x62,
|
||||
0x21, 0xa7, 0x68, 0x0f, 0x2a, 0x42, 0xf2, 0x9a, 0x51, 0xaf, 0xb4, 0xaa, 0xed, 0x07, 0xee, 0xa5,
|
||||
0xbe, 0xb9, 0xc7, 0xd2, 0x4b, 0x10, 0xa8, 0x03, 0x9b, 0x42, 0x9e, 0xc4, 0x9a, 0xc7, 0x6b, 0xa6,
|
||||
0x62, 0xec, 0x2c, 0x95, 0xa2, 0x7a, 0x95, 0x23, 0x6a, 0xb0, 0x57, 0x15, 0xf3, 0x73, 0x22, 0x94,
|
||||
0x4f, 0x54, 0x51, 0x89, 0xf6, 0xae, 0x4c, 0xa4, 0x95, 0xf2, 0x91, 0x0e, 0xe0, 0xf6, 0x51, 0x30,
|
||||
0x1c, 0x0d, 0x88, 0xc8, 0x12, 0xa3, 0x26, 0x98, 0x42, 0xaa, 0x06, 0x96, 0x86, 0x31, 0x85, 0x74,
|
||||
0xbe, 0x18, 0x70, 0x67, 0x41, 0xd5, 0x9d, 0x78, 0x01, 0x1b, 0x3e, 0xe1, 0x27, 0x41, 0x78, 0xca,
|
||||
0xb4, 0xc2, 0x93, 0xf2, 0x70, 0x1d, 0xc2, 0xdf, 0x84, 0xa7, 0xcc, 0x5b, 0xf7, 0xd3, 0x03, 0x3a,
|
||||
0x80, 0xb5, 0x98, 0xf2, 0xd1, 0x40, 0xe8, 0x19, 0xd5, 0xcb, 0xb9, 0x9e, 0xc2, 0x79, 0x1a, 0xef,
|
||||
0x38, 0xb0, 0xa9, 0x06, 0x93, 0x65, 0x40, 0x70, 0xa3, 0x4f, 0x78, 0x5f, 0x7f, 0x06, 0xea, 0xec,
|
||||
0x5c, 0xc0, 0x2d, 0x8d, 0xd1, 0xc5, 0x5e, 0x2f, 0x28, 0x3a, 0x84, 0x6a, 0x6e, 0x68, 0xba, 0xb4,
|
||||
0xeb, 0xcd, 0x0c, 0x16, 0x33, 0x6b, 0xff, 0x31, 0x61, 0xfd, 0x28, 0x5d, 0x30, 0x24, 0x61, 0x23,
|
||||
0x6b, 0x1d, 0x72, 0x0a, 0x9c, 0xff, 0x19, 0x89, 0xd5, 0xf8, 0x2f, 0x26, 0x35, 0x70, 0x1a, 0x9f,
|
||||
0x7f, 0xfc, 0xfe, 0x66, 0x3e, 0x76, 0x1e, 0xe1, 0x82, 0xcd, 0xce, 0xdc, 0x22, 0x58, 0x55, 0x4d,
|
||||
0x40, 0xdb, 0x05, 0x92, 0xf9, 0x16, 0x5a, 0xf5, 0x72, 0x80, 0x36, 0xdc, 0x51, 0x86, 0x36, 0xda,
|
||||
0xc2, 0x45, 0x3b, 0x8d, 0x3f, 0x26, 0x5d, 0xbf, 0x40, 0x9f, 0xa0, 0x9a, 0xdb, 0x19, 0xd4, 0x2c,
|
||||
0x93, 0x5d, 0x5a, 0x64, 0x6b, 0xf7, 0x2a, 0x98, 0xae, 0xc1, 0x56, 0x35, 0xd4, 0xd0, 0xc3, 0xc2,
|
||||
0x1a, 0xf8, 0xab, 0x97, 0xdf, 0xa7, 0xb6, 0x31, 0x99, 0xda, 0xc6, 0xaf, 0xa9, 0x6d, 0x7c, 0x9d,
|
||||
0xd9, 0x2b, 0x93, 0x99, 0xbd, 0xf2, 0x73, 0x66, 0xaf, 0xbc, 0x6b, 0xfa, 0x81, 0xe8, 0x8f, 0xba,
|
||||
0x6e, 0x8f, 0x0d, 0x33, 0x6e, 0xfa, 0x78, 0xc6, 0xdf, 0x7f, 0xc0, 0xe2, 0x3c, 0xa2, 0x89, 0x58,
|
||||
0x77, 0x4d, 0xfd, 0x6e, 0x9e, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xae, 0x63, 0xf9, 0x38, 0x2f,
|
||||
0x05, 0x00, 0x00,
|
||||
// 737 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xcd, 0x4f, 0x13, 0x41,
|
||||
0x14, 0xef, 0xb6, 0xc8, 0xc7, 0x2b, 0x68, 0x1d, 0x10, 0x6b, 0xd1, 0xa5, 0x2c, 0x16, 0x08, 0x89,
|
||||
0xbb, 0xa1, 0x7a, 0x20, 0xc6, 0xc4, 0xd0, 0x52, 0x08, 0x51, 0x3e, 0xb2, 0xc5, 0x83, 0xc6, 0xa4,
|
||||
0x99, 0xb6, 0xc3, 0xb2, 0x91, 0xee, 0x94, 0xce, 0x94, 0x2c, 0x01, 0x62, 0xe2, 0xd1, 0x93, 0x89,
|
||||
0xff, 0x94, 0x47, 0x12, 0x2f, 0x1e, 0x0d, 0xf8, 0x47, 0x78, 0x34, 0x3b, 0x3b, 0x6d, 0xb7, 0x65,
|
||||
0x0b, 0xc4, 0x13, 0x33, 0xcc, 0xef, 0xfd, 0x3e, 0xde, 0x9b, 0x9d, 0xc2, 0x74, 0x85, 0xb2, 0x1a,
|
||||
0x65, 0x06, 0x77, 0x8d, 0xa3, 0xa5, 0x32, 0xe1, 0x78, 0xc9, 0x60, 0xa4, 0x71, 0x64, 0x57, 0x88,
|
||||
0x5e, 0x6f, 0x50, 0x4e, 0xd1, 0x7d, 0x1f, 0xa0, 0x73, 0x57, 0x97, 0x80, 0xd4, 0x63, 0x8b, 0x52,
|
||||
0xeb, 0x80, 0x18, 0xb8, 0x6e, 0x1b, 0xd8, 0x71, 0x28, 0xc7, 0xdc, 0xa6, 0x0e, 0xf3, 0x0b, 0x52,
|
||||
0xb3, 0x92, 0xb1, 0x8c, 0x19, 0x31, 0x70, 0xb9, 0x62, 0xb7, 0x89, 0xbd, 0x8d, 0x04, 0xa5, 0xae,
|
||||
0xca, 0x72, 0x57, 0x9e, 0x4d, 0x58, 0xd4, 0xa2, 0x62, 0x69, 0x78, 0x2b, 0xf9, 0xdf, 0xc5, 0x20,
|
||||
0xed, 0x61, 0x93, 0x34, 0x8e, 0xdb, 0x95, 0x75, 0x6c, 0xd9, 0x8e, 0xf0, 0xe0, 0x63, 0x35, 0x0e,
|
||||
0x68, 0x9d, 0xf0, 0x5d, 0x97, 0x15, 0x8e, 0x88, 0xc3, 0x4d, 0x72, 0xd8, 0x24, 0x8c, 0xa3, 0x49,
|
||||
0x18, 0x24, 0xde, 0x9e, 0x25, 0x95, 0x74, 0x6c, 0x61, 0xc4, 0x94, 0x3b, 0xb4, 0x06, 0xd0, 0x61,
|
||||
0x48, 0x46, 0xd3, 0xca, 0x42, 0x3c, 0x3b, 0xa7, 0xcb, 0xd8, 0x9e, 0x9c, 0x2e, 0xe4, 0x5a, 0xf1,
|
||||
0xf5, 0x1d, 0x6c, 0x11, 0xc9, 0x69, 0x06, 0x2a, 0xb5, 0x73, 0x05, 0xc6, 0xbb, 0x64, 0x59, 0x9d,
|
||||
0x3a, 0x8c, 0xa0, 0x79, 0x88, 0x71, 0xd7, 0x17, 0x8d, 0x67, 0x1f, 0xe8, 0x57, 0xfa, 0xa9, 0xef,
|
||||
0xba, 0xa6, 0x87, 0x40, 0xeb, 0x30, 0xca, 0xdd, 0x52, 0x43, 0xd6, 0xb1, 0x64, 0x54, 0x54, 0x3c,
|
||||
0xed, 0xb2, 0x22, 0x7a, 0x18, 0x28, 0x94, 0x60, 0x33, 0xce, 0xdb, 0x6b, 0x8f, 0x28, 0x98, 0x28,
|
||||
0x26, 0x12, 0xcd, 0xdf, 0x98, 0x48, 0x32, 0x05, 0x23, 0x11, 0x40, 0xb9, 0x06, 0xc5, 0xd5, 0x0a,
|
||||
0x66, 0xdc, 0x13, 0xf3, 0x1b, 0xf9, 0x08, 0x86, 0xb9, 0x5b, 0x2a, 0x1f, 0x73, 0xe2, 0xa5, 0x52,
|
||||
0x16, 0x46, 0xcd, 0x21, 0xee, 0xe6, 0xbc, 0x2d, 0x7a, 0x01, 0x03, 0x35, 0x5a, 0x25, 0xa2, 0x8b,
|
||||
0x77, 0xb3, 0xe9, 0x90, 0xb0, 0x6d, 0xbe, 0x4d, 0x5a, 0x25, 0xa6, 0x40, 0x6b, 0x1f, 0x61, 0xbc,
|
||||
0x4b, 0x46, 0x36, 0xae, 0x00, 0xf1, 0x40, 0x3f, 0x84, 0xd4, 0x6d, 0xdb, 0x01, 0x9d, 0x76, 0x68,
|
||||
0xcb, 0x70, 0xaf, 0x68, 0xd7, 0x9a, 0x07, 0x98, 0xb7, 0xc6, 0x86, 0x32, 0x10, 0xe5, 0xae, 0x24,
|
||||
0xec, 0x33, 0x91, 0x28, 0x77, 0xb5, 0xaf, 0x0a, 0x24, 0x3a, 0xa5, 0xd2, 0xd5, 0x2b, 0x18, 0xb6,
|
||||
0x30, 0x2b, 0xd9, 0xce, 0x1e, 0x95, 0x0c, 0x33, 0xfd, 0x2d, 0xad, 0x63, 0xb6, 0xe1, 0xec, 0x51,
|
||||
0x73, 0xc8, 0xf2, 0x17, 0x68, 0x19, 0x06, 0x1b, 0x84, 0x35, 0x0f, 0xb8, 0xbc, 0x68, 0xe9, 0xfe,
|
||||
0xb5, 0xa6, 0xc0, 0x99, 0x12, 0xaf, 0x69, 0x30, 0x2a, 0x6e, 0x57, 0x2b, 0x03, 0x82, 0x81, 0x7d,
|
||||
0xcc, 0xf6, 0x85, 0x87, 0x11, 0x53, 0xac, 0xb5, 0x33, 0x18, 0x93, 0x18, 0x69, 0xf6, 0x76, 0x41,
|
||||
0x7b, 0x3b, 0x1d, 0xfd, 0xbf, 0x4e, 0x2f, 0x9e, 0xc2, 0x58, 0xd7, 0x78, 0x91, 0x0a, 0xa9, 0x9c,
|
||||
0xb9, 0xbd, 0xb2, 0x9a, 0x5f, 0x29, 0xee, 0x96, 0x36, 0xb7, 0x57, 0x0b, 0xa5, 0x77, 0x5b, 0xc5,
|
||||
0x9d, 0x42, 0x7e, 0x63, 0x6d, 0xa3, 0xb0, 0x9a, 0x88, 0xa0, 0x24, 0x4c, 0xf4, 0x9c, 0xe7, 0xde,
|
||||
0x6e, 0xe7, 0xdf, 0x24, 0x14, 0xf4, 0x10, 0xc6, 0x7b, 0x4e, 0x8a, 0xef, 0xb7, 0xf2, 0x89, 0x68,
|
||||
0x48, 0xc9, 0x8a, 0x38, 0x89, 0x65, 0xff, 0xc6, 0x60, 0xa8, 0xe8, 0xbf, 0x5d, 0xe8, 0x04, 0x86,
|
||||
0x5b, 0x83, 0x43, 0x5a, 0x48, 0xee, 0x9e, 0x0b, 0x91, 0x9a, 0xbd, 0x16, 0x23, 0x2f, 0xd2, 0xdc,
|
||||
0x97, 0x9f, 0x7f, 0xbe, 0x47, 0xd3, 0xda, 0x94, 0x11, 0xf2, 0x68, 0x4a, 0xf0, 0x4b, 0x65, 0x11,
|
||||
0x1d, 0xc2, 0x1d, 0x31, 0x05, 0x34, 0x1d, 0xc2, 0x1a, 0x9c, 0x61, 0x2a, 0xdd, 0x1f, 0x20, 0x35,
|
||||
0x33, 0x42, 0x73, 0x1a, 0x3d, 0x31, 0xc2, 0x5e, 0x4c, 0x66, 0x9c, 0x78, 0x73, 0x3f, 0x43, 0x9f,
|
||||
0x21, 0x1e, 0xf8, 0x82, 0x50, 0xe6, 0xba, 0x0f, 0xaf, 0x23, 0x3f, 0x77, 0x13, 0x4c, 0x9a, 0x98,
|
||||
0x11, 0x26, 0xa6, 0xb4, 0xc9, 0x70, 0x13, 0x5e, 0xe6, 0x53, 0x88, 0x07, 0xde, 0xbe, 0x50, 0x03,
|
||||
0x57, 0x9f, 0xe4, 0x50, 0x03, 0x21, 0x4f, 0xa8, 0xa6, 0x0a, 0x03, 0x49, 0xd4, 0xc7, 0x40, 0xee,
|
||||
0xf5, 0x8f, 0x0b, 0x55, 0x39, 0xbf, 0x50, 0x95, 0xdf, 0x17, 0xaa, 0xf2, 0xed, 0x52, 0x8d, 0x9c,
|
||||
0x5f, 0xaa, 0x91, 0x5f, 0x97, 0x6a, 0xe4, 0x43, 0xc6, 0xb2, 0xf9, 0x7e, 0xb3, 0xac, 0x57, 0x68,
|
||||
0xad, 0x55, 0xeb, 0xff, 0x79, 0xc6, 0xaa, 0x9f, 0x0c, 0x7e, 0x5c, 0x27, 0x1e, 0x59, 0x79, 0x50,
|
||||
0xfc, 0x70, 0x3c, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x96, 0xba, 0xfb, 0xcb, 0x0f, 0x07, 0x00,
|
||||
0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -423,6 +579,8 @@ type ServiceClient interface {
|
|||
Simulate(ctx context.Context, in *SimulateRequest, opts ...grpc.CallOption) (*SimulateResponse, error)
|
||||
// GetTx fetches a tx by hash.
|
||||
GetTx(ctx context.Context, in *GetTxRequest, opts ...grpc.CallOption) (*GetTxResponse, error)
|
||||
// BroadcastTx broadcast transaction.
|
||||
BroadcastTx(ctx context.Context, in *BroadcastTxRequest, opts ...grpc.CallOption) (*BroadcastTxResponse, error)
|
||||
// GetTxsEvent fetches txs by event.
|
||||
GetTxsEvent(ctx context.Context, in *GetTxsEventRequest, opts ...grpc.CallOption) (*GetTxsEventResponse, error)
|
||||
}
|
||||
|
@ -453,6 +611,15 @@ func (c *serviceClient) GetTx(ctx context.Context, in *GetTxRequest, opts ...grp
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *serviceClient) BroadcastTx(ctx context.Context, in *BroadcastTxRequest, opts ...grpc.CallOption) (*BroadcastTxResponse, error) {
|
||||
out := new(BroadcastTxResponse)
|
||||
err := c.cc.Invoke(ctx, "/cosmos.tx.v1beta1.Service/BroadcastTx", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *serviceClient) GetTxsEvent(ctx context.Context, in *GetTxsEventRequest, opts ...grpc.CallOption) (*GetTxsEventResponse, error) {
|
||||
out := new(GetTxsEventResponse)
|
||||
err := c.cc.Invoke(ctx, "/cosmos.tx.v1beta1.Service/GetTxsEvent", in, out, opts...)
|
||||
|
@ -468,6 +635,8 @@ type ServiceServer interface {
|
|||
Simulate(context.Context, *SimulateRequest) (*SimulateResponse, error)
|
||||
// GetTx fetches a tx by hash.
|
||||
GetTx(context.Context, *GetTxRequest) (*GetTxResponse, error)
|
||||
// BroadcastTx broadcast transaction.
|
||||
BroadcastTx(context.Context, *BroadcastTxRequest) (*BroadcastTxResponse, error)
|
||||
// GetTxsEvent fetches txs by event.
|
||||
GetTxsEvent(context.Context, *GetTxsEventRequest) (*GetTxsEventResponse, error)
|
||||
}
|
||||
|
@ -482,6 +651,9 @@ func (*UnimplementedServiceServer) Simulate(ctx context.Context, req *SimulateRe
|
|||
func (*UnimplementedServiceServer) GetTx(ctx context.Context, req *GetTxRequest) (*GetTxResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetTx not implemented")
|
||||
}
|
||||
func (*UnimplementedServiceServer) BroadcastTx(ctx context.Context, req *BroadcastTxRequest) (*BroadcastTxResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method BroadcastTx not implemented")
|
||||
}
|
||||
func (*UnimplementedServiceServer) GetTxsEvent(ctx context.Context, req *GetTxsEventRequest) (*GetTxsEventResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetTxsEvent not implemented")
|
||||
}
|
||||
|
@ -526,6 +698,24 @@ func _Service_GetTx_Handler(srv interface{}, ctx context.Context, dec func(inter
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Service_BroadcastTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(BroadcastTxRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ServiceServer).BroadcastTx(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/cosmos.tx.v1beta1.Service/BroadcastTx",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ServiceServer).BroadcastTx(ctx, req.(*BroadcastTxRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Service_GetTxsEvent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetTxsEventRequest)
|
||||
if err := dec(in); err != nil {
|
||||
|
@ -556,6 +746,10 @@ var _Service_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "GetTx",
|
||||
Handler: _Service_GetTx_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "BroadcastTx",
|
||||
Handler: _Service_BroadcastTx_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetTxsEvent",
|
||||
Handler: _Service_GetTxsEvent_Handler,
|
||||
|
@ -597,12 +791,14 @@ func (m *GetTxsEventRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if len(m.Event) > 0 {
|
||||
i -= len(m.Event)
|
||||
copy(dAtA[i:], m.Event)
|
||||
i = encodeVarintService(dAtA, i, uint64(len(m.Event)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
if len(m.Events) > 0 {
|
||||
for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- {
|
||||
i -= len(m.Events[iNdEx])
|
||||
copy(dAtA[i:], m.Events[iNdEx])
|
||||
i = encodeVarintService(dAtA, i, uint64(len(m.Events[iNdEx])))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
@ -670,6 +866,76 @@ func (m *GetTxsEventResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *BroadcastTxRequest) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *BroadcastTxRequest) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *BroadcastTxRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Mode != 0 {
|
||||
i = encodeVarintService(dAtA, i, uint64(m.Mode))
|
||||
i--
|
||||
dAtA[i] = 0x10
|
||||
}
|
||||
if len(m.TxBytes) > 0 {
|
||||
i -= len(m.TxBytes)
|
||||
copy(dAtA[i:], m.TxBytes)
|
||||
i = encodeVarintService(dAtA, i, uint64(len(m.TxBytes)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *BroadcastTxResponse) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *BroadcastTxResponse) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *BroadcastTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.TxResponse != nil {
|
||||
{
|
||||
size, err := m.TxResponse.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintService(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *SimulateRequest) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
|
@ -846,9 +1112,11 @@ func (m *GetTxsEventRequest) Size() (n int) {
|
|||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Event)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovService(uint64(l))
|
||||
if len(m.Events) > 0 {
|
||||
for _, s := range m.Events {
|
||||
l = len(s)
|
||||
n += 1 + l + sovService(uint64(l))
|
||||
}
|
||||
}
|
||||
if m.Pagination != nil {
|
||||
l = m.Pagination.Size()
|
||||
|
@ -882,6 +1150,35 @@ func (m *GetTxsEventResponse) Size() (n int) {
|
|||
return n
|
||||
}
|
||||
|
||||
func (m *BroadcastTxRequest) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.TxBytes)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovService(uint64(l))
|
||||
}
|
||||
if m.Mode != 0 {
|
||||
n += 1 + sovService(uint64(m.Mode))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *BroadcastTxResponse) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.TxResponse != nil {
|
||||
l = m.TxResponse.Size()
|
||||
n += 1 + l + sovService(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *SimulateRequest) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
|
@ -979,7 +1276,7 @@ func (m *GetTxsEventRequest) Unmarshal(dAtA []byte) error {
|
|||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
|
@ -1007,7 +1304,7 @@ func (m *GetTxsEventRequest) Unmarshal(dAtA []byte) error {
|
|||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Event = string(dAtA[iNdEx:postIndex])
|
||||
m.Events = append(m.Events, string(dAtA[iNdEx:postIndex]))
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
|
@ -1226,6 +1523,201 @@ func (m *GetTxsEventResponse) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (m *BroadcastTxRequest) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowService
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: BroadcastTxRequest: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: BroadcastTxRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field TxBytes", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowService
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthService
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthService
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.TxBytes = append(m.TxBytes[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.TxBytes == nil {
|
||||
m.TxBytes = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType)
|
||||
}
|
||||
m.Mode = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowService
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Mode |= BroadcastMode(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipService(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthService
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthService
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *BroadcastTxResponse) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowService
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: BroadcastTxResponse: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: BroadcastTxResponse: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field TxResponse", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowService
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthService
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthService
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.TxResponse == nil {
|
||||
m.TxResponse = &types.TxResponse{}
|
||||
}
|
||||
if err := m.TxResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipService(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthService
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthService
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *SimulateRequest) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
|
|
@ -31,18 +31,15 @@ var _ = runtime.String
|
|||
var _ = utilities.NewDoubleArray
|
||||
var _ = descriptor.ForMessage
|
||||
|
||||
var (
|
||||
filter_Service_Simulate_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_Service_Simulate_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq SimulateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Service_Simulate_0); err != nil {
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
|
@ -55,10 +52,11 @@ func local_request_Service_Simulate_0(ctx context.Context, marshaler runtime.Mar
|
|||
var protoReq SimulateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Service_Simulate_0); err != nil {
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
|
@ -121,6 +119,40 @@ func local_request_Service_GetTx_0(ctx context.Context, marshaler runtime.Marsha
|
|||
|
||||
}
|
||||
|
||||
func request_Service_BroadcastTx_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq BroadcastTxRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.BroadcastTx(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Service_BroadcastTx_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq BroadcastTxRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.BroadcastTx(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_Service_GetTxsEvent_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
@ -203,6 +235,26 @@ func RegisterServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, se
|
|||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_Service_BroadcastTx_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Service_BroadcastTx_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Service_BroadcastTx_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Service_GetTxsEvent_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
@ -304,6 +356,26 @@ func RegisterServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl
|
|||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_Service_BroadcastTx_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Service_BroadcastTx_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Service_BroadcastTx_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Service_GetTxsEvent_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
|
@ -330,7 +402,9 @@ func RegisterServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, cl
|
|||
var (
|
||||
pattern_Service_Simulate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "tx", "v1beta1", "simulate"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Service_GetTx_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3}, []string{"cosmos", "tx", "v1beta1", "hash"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
pattern_Service_GetTx_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "tx", "v1beta1", "txs", "hash"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Service_BroadcastTx_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "tx", "v1beta1", "txs"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Service_GetTxsEvent_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "tx", "v1beta1", "txs"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
)
|
||||
|
@ -340,5 +414,7 @@ var (
|
|||
|
||||
forward_Service_GetTx_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Service_BroadcastTx_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Service_GetTxsEvent_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
)
|
||||
|
||||
type (
|
||||
|
|
|
@ -735,6 +735,71 @@ func (s *IntegrationTestSuite) TestCLIMultisign() {
|
|||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestSignBatchMultisig() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
// Fetch 2 accounts and a multisig.
|
||||
account1, err := val.ClientCtx.Keyring.Key("newAccount1")
|
||||
s.Require().NoError(err)
|
||||
account2, err := val.ClientCtx.Keyring.Key("newAccount2")
|
||||
s.Require().NoError(err)
|
||||
multisigInfo, err := val.ClientCtx.Keyring.Key("multi")
|
||||
|
||||
// Send coins from validator to multisig.
|
||||
sendTokens := sdk.NewInt64Coin(s.cfg.BondDenom, 10)
|
||||
_, err = bankcli.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
multisigInfo.GetAddress(),
|
||||
sdk.NewCoins(sendTokens),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--gas=%d", flags.DefaultGasLimit),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
|
||||
generatedStd, err := bankcli.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
multisigInfo.GetAddress(),
|
||||
val.Address,
|
||||
sdk.NewCoins(
|
||||
sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(1)),
|
||||
),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Write the output to disk
|
||||
filename, cleanup1 := testutil.WriteToNewTempFile(s.T(), strings.Repeat(generatedStd.String(), 1))
|
||||
defer cleanup1()
|
||||
|
||||
val.ClientCtx.HomeDir = strings.Replace(val.ClientCtx.HomeDir, "simd", "simcli", 1)
|
||||
|
||||
// sign-batch file
|
||||
res, err := authtest.TxSignBatchExec(val.ClientCtx, account1.GetAddress(), filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", multisigInfo.GetAddress().String())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, len(strings.Split(strings.Trim(res.String(), "\n"), "\n")))
|
||||
// write sigs to file
|
||||
file1, cleanup2 := testutil.WriteToNewTempFile(s.T(), res.String())
|
||||
defer cleanup2()
|
||||
|
||||
// sign-batch file with account2
|
||||
res, err = authtest.TxSignBatchExec(val.ClientCtx, account2.GetAddress(), filename.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--multisig", multisigInfo.GetAddress().String())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, len(strings.Split(strings.Trim(res.String(), "\n"), "\n")))
|
||||
|
||||
// write sigs to file2
|
||||
file2, cleanup3 := testutil.WriteToNewTempFile(s.T(), res.String())
|
||||
defer cleanup3()
|
||||
res, err = authtest.TxMultiSignExec(val.ClientCtx, multisigInfo.GetName(), filename.Name(), file1.Name(), file2.Name())
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetAccountCmd() {
|
||||
val := s.network.Validators[0]
|
||||
_, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
|
|
@ -119,7 +119,10 @@ func makeSignBatchCmd() func(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
err = authclient.SignTxWithSignerAddress(txFactory, clientCtx, multisigAddr, clientCtx.GetFromName(), txBuilder, true)
|
||||
if txFactory.SignMode() == signing.SignMode_SIGN_MODE_UNSPECIFIED {
|
||||
txFactory = txFactory.WithSignMode(signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON)
|
||||
}
|
||||
err = authclient.SignTxWithSignerAddress(txFactory, clientCtx, multisigAddr, clientCtx.GetFromName(), txBuilder, clientCtx.Offline)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
clientrest "github.com/cosmos/cosmos-sdk/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
@ -30,8 +32,15 @@ func BroadcastTxRequest(clientCtx client.Context) http.HandlerFunc {
|
|||
}
|
||||
|
||||
// NOTE: amino is used intentionally here, don't migrate it!
|
||||
if err := clientCtx.LegacyAmino.UnmarshalJSON(body, &req); rest.CheckBadRequestError(w, err) {
|
||||
return
|
||||
err = clientCtx.LegacyAmino.UnmarshalJSON(body, &req)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("this transaction cannot be broadcasted via legacy REST endpoints, because it does not support"+
|
||||
" Amino serialization. Please either use CLI, gRPC, gRPC-gateway, or directly query the Tendermint RPC"+
|
||||
" endpoint to broadcast this transaction. The new REST endpoint (via gRPC-gateway) is POST /cosmos/tx/v1beta1/txs."+
|
||||
" Please also see the REST endpoints migration guide at %s for more info", clientrest.DeprecationURL)
|
||||
if rest.CheckBadRequestError(w, err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
txBytes, err := tx.ConvertAndEncodeStdTx(clientCtx.TxConfig, req.Tx)
|
||||
|
|
|
@ -55,7 +55,7 @@ func DecodeTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
|||
|
||||
response := DecodeResp(stdTx)
|
||||
|
||||
err = checkSignModeError(clientCtx, response, "/cosmos/tx/v1beta1/txs/decode")
|
||||
err = checkAminoMarshalError(clientCtx, response, "/cosmos/tx/v1beta1/txs/decode")
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
|
||||
|
|
|
@ -2,12 +2,13 @@ package rest
|
|||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
clientrest "github.com/cosmos/cosmos-sdk/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
|
||||
)
|
||||
|
@ -17,6 +18,12 @@ type EncodeResp struct {
|
|||
Tx string `json:"tx" yaml:"tx"`
|
||||
}
|
||||
|
||||
// ErrEncodeDecode is the error to show when encoding/decoding txs that are not
|
||||
// amino-serializable (e.g. IBC txs).
|
||||
var ErrEncodeDecode error = fmt.Errorf("this endpoint does not support txs that are not serializable"+
|
||||
" via Amino, such as txs that contain IBC `Msg`s. For more info, please refer to our"+
|
||||
" REST migration guide at %s", clientrest.DeprecationURL)
|
||||
|
||||
// EncodeTxRequestHandlerFn returns the encode tx REST handler. In particular,
|
||||
// it takes a json-formatted transaction, encodes it to the Amino wire protocol,
|
||||
// and responds with base64-encoded bytes.
|
||||
|
@ -31,8 +38,12 @@ func EncodeTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
|||
|
||||
// NOTE: amino is used intentionally here, don't migrate it
|
||||
err = clientCtx.LegacyAmino.UnmarshalJSON(body, &req)
|
||||
if rest.CheckBadRequestError(w, err) {
|
||||
return
|
||||
// If there's an unmarshalling error, we assume that it's because we're
|
||||
// using amino to unmarshal a non-amino tx.
|
||||
if err != nil {
|
||||
if rest.CheckBadRequestError(w, ErrEncodeDecode) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// re-encode it in the chain's native binary format
|
||||
|
|
|
@ -108,7 +108,7 @@ func QueryTxsRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
|||
packStdTxResponse(w, clientCtx, txRes)
|
||||
}
|
||||
|
||||
err = checkSignModeError(clientCtx, searchResult, "/cosmos/tx/v1beta1/txs")
|
||||
err = checkAminoMarshalError(clientCtx, searchResult, "/cosmos/tx/v1beta1/txs")
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
|
||||
|
@ -151,7 +151,7 @@ func QueryTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
|||
rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr))
|
||||
}
|
||||
|
||||
err = checkSignModeError(clientCtx, output, "/cosmos/tx/v1beta1/tx/{txhash}")
|
||||
err = checkAminoMarshalError(clientCtx, output, "/cosmos/tx/v1beta1/txs/{txhash}")
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
|
||||
|
@ -198,9 +198,9 @@ func packStdTxResponse(w http.ResponseWriter, clientCtx client.Context, txRes *s
|
|||
return nil
|
||||
}
|
||||
|
||||
// checkSignModeError checks if there are errors with marshalling non-amino
|
||||
// checkAminoMarshalError checks if there are errors with marshalling non-amino
|
||||
// txs with amino.
|
||||
func checkSignModeError(ctx client.Context, resp interface{}, grpcEndPoint string) error {
|
||||
func checkAminoMarshalError(ctx client.Context, resp interface{}, grpcEndPoint string) error {
|
||||
// LegacyAmino used intentionally here to handle the SignMode errors
|
||||
marshaler := ctx.LegacyAmino
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
||||
authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
rest2 "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx"
|
||||
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
|
@ -72,7 +72,7 @@ func (s *IntegrationTestSuite) TearDownSuite() {
|
|||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func mkTx() legacytx.StdTx {
|
||||
func mkStdTx() legacytx.StdTx {
|
||||
// NOTE: this uses StdTx explicitly, don't migrate it!
|
||||
return legacytx.StdTx{
|
||||
Msgs: []sdk.Msg{&types.MsgSend{}},
|
||||
|
@ -84,10 +84,49 @@ func mkTx() legacytx.StdTx {
|
|||
}
|
||||
}
|
||||
|
||||
// Create an IBC tx that's encoded as amino-JSON. Since we can't amino-marshal
|
||||
// a tx with "cosmos-sdk/MsgTransfer" using the SDK, we just hardcode the tx
|
||||
// here. But external clients might, see https://github.com/cosmos/cosmos-sdk/issues/8022.
|
||||
func mkIBCStdTx() []byte {
|
||||
ibcTx := `{
|
||||
"account_number": "68",
|
||||
"chain_id": "stargate-4",
|
||||
"fee": {
|
||||
"amount": [
|
||||
{
|
||||
"amount": "3500",
|
||||
"denom": "umuon"
|
||||
}
|
||||
],
|
||||
"gas": "350000"
|
||||
},
|
||||
"memo": "",
|
||||
"msg": [
|
||||
{
|
||||
"type": "cosmos-sdk/MsgTransfer",
|
||||
"value": {
|
||||
"receiver": "cosmos1q9wtnlwdjrhwtcjmt2uq77jrgx7z3usrq2yz7z",
|
||||
"sender": "cosmos1q9wtnlwdjrhwtcjmt2uq77jrgx7z3usrq2yz7z",
|
||||
"source_channel": "THEslipperCHANNEL",
|
||||
"source_port": "transfer",
|
||||
"token": {
|
||||
"amount": "1000000",
|
||||
"denom": "umuon"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"sequence": "24"
|
||||
}`
|
||||
req := fmt.Sprintf(`{"tx":%s,"mode":"async"}`, ibcTx)
|
||||
|
||||
return []byte(req)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestEncodeDecode() {
|
||||
var require = s.Require()
|
||||
val := s.network.Validators[0]
|
||||
stdTx := mkTx()
|
||||
stdTx := mkStdTx()
|
||||
|
||||
// NOTE: this uses amino explicitly, don't migrate it!
|
||||
cdc := val.ClientCtx.LegacyAmino
|
||||
|
@ -98,11 +137,11 @@ func (s *IntegrationTestSuite) TestEncodeDecode() {
|
|||
res, err := rest.PostRequest(fmt.Sprintf("%s/txs/encode", val.APIAddress), "application/json", bz)
|
||||
require.NoError(err)
|
||||
|
||||
var encodeResp rest2.EncodeResp
|
||||
var encodeResp authrest.EncodeResp
|
||||
err = cdc.UnmarshalJSON(res, &encodeResp)
|
||||
require.NoError(err)
|
||||
|
||||
bz, err = cdc.MarshalJSON(rest2.DecodeReq{Tx: encodeResp.Tx})
|
||||
bz, err = cdc.MarshalJSON(authrest.DecodeReq{Tx: encodeResp.Tx})
|
||||
require.NoError(err)
|
||||
|
||||
res, err = rest.PostRequest(fmt.Sprintf("%s/txs/decode", val.APIAddress), "application/json", bz)
|
||||
|
@ -111,14 +150,24 @@ func (s *IntegrationTestSuite) TestEncodeDecode() {
|
|||
var respWithHeight rest.ResponseWithHeight
|
||||
err = cdc.UnmarshalJSON(res, &respWithHeight)
|
||||
require.NoError(err)
|
||||
var decodeResp rest2.DecodeResp
|
||||
var decodeResp authrest.DecodeResp
|
||||
err = cdc.UnmarshalJSON(respWithHeight.Result, &decodeResp)
|
||||
require.NoError(err)
|
||||
require.Equal(stdTx, legacytx.StdTx(decodeResp))
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestEncodeIBCTx() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
req := mkIBCStdTx()
|
||||
res, err := rest.PostRequest(fmt.Sprintf("%s/txs/encode", val.APIAddress), "application/json", []byte(req))
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Contains(string(res), authrest.ErrEncodeDecode.Error())
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestBroadcastTxRequest() {
|
||||
stdTx := mkTx()
|
||||
stdTx := mkStdTx()
|
||||
|
||||
// we just test with async mode because this tx will fail - all we care about is that it got encoded and broadcast correctly
|
||||
res, err := s.broadcastReq(stdTx, "async")
|
||||
|
@ -130,6 +179,17 @@ func (s *IntegrationTestSuite) TestBroadcastTxRequest() {
|
|||
s.Require().NotEmpty(txRes.TxHash)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestBroadcastIBCTxRequest() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
req := mkIBCStdTx()
|
||||
res, err := rest.PostRequest(fmt.Sprintf("%s/txs", val.APIAddress), "application/json", []byte(req))
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Make sure the error message is correct.
|
||||
s.Require().Contains(string(res), "this transaction cannot be broadcasted via legacy REST endpoints")
|
||||
}
|
||||
|
||||
// Helper function to test querying txs. We will use it to query StdTx and service `Msg`s.
|
||||
func (s *IntegrationTestSuite) testQueryTx(txHeight int64, txHash, txRecipient string) {
|
||||
val0 := s.network.Validators[0]
|
||||
|
@ -332,7 +392,7 @@ func (s *IntegrationTestSuite) broadcastReq(stdTx legacytx.StdTx, mode string) (
|
|||
|
||||
// NOTE: this uses amino explicitly, don't migrate it!
|
||||
cdc := val.ClientCtx.LegacyAmino
|
||||
req := rest2.BroadcastReq{
|
||||
req := authrest.BroadcastReq{
|
||||
Tx: stdTx,
|
||||
Mode: mode,
|
||||
}
|
||||
|
@ -345,7 +405,7 @@ func (s *IntegrationTestSuite) broadcastReq(stdTx legacytx.StdTx, mode string) (
|
|||
// testQueryIBCTx is a helper function to test querying txs which:
|
||||
// - show an error message on legacy REST endpoints
|
||||
// - succeed using gRPC
|
||||
// In practise, we call this function on IBC txs.
|
||||
// In practice, we call this function on IBC txs.
|
||||
func (s *IntegrationTestSuite) testQueryIBCTx(txRes sdk.TxResponse, cmd *cobra.Command, args []string) {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
|
@ -381,7 +441,7 @@ func (s *IntegrationTestSuite) testQueryIBCTx(txRes sdk.TxResponse, cmd *cobra.C
|
|||
}
|
||||
|
||||
// try fetching the txn using gRPC req, it will fetch info since it has proto codec.
|
||||
grpcJSON, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/tx/%s", val.APIAddress, txRes.TxHash))
|
||||
grpcJSON, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", val.APIAddress, txRes.TxHash))
|
||||
s.Require().NoError(err)
|
||||
|
||||
var getTxRes txtypes.GetTxResponse
|
||||
|
@ -401,7 +461,7 @@ func (s *IntegrationTestSuite) testQueryIBCTx(txRes sdk.TxResponse, cmd *cobra.C
|
|||
out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, authcli.GetEncodeCommand(), []string{txFileName})
|
||||
s.Require().NoError(err)
|
||||
|
||||
bz, err := val.ClientCtx.LegacyAmino.MarshalJSON(rest2.DecodeReq{Tx: string(out.Bytes())})
|
||||
bz, err := val.ClientCtx.LegacyAmino.MarshalJSON(authrest.DecodeReq{Tx: string(out.Bytes())})
|
||||
s.Require().NoError(err)
|
||||
|
||||
// try to decode the txn using legacy rest, it fails.
|
||||
|
@ -453,7 +513,6 @@ func (s *IntegrationTestSuite) TestLegacyRestErrMessages() {
|
|||
"Successful IBC message",
|
||||
ibcsolomachinecli.NewCreateClientCmd(),
|
||||
[]string{
|
||||
"21212121212", // dummy client-id
|
||||
"1", // dummy sequence
|
||||
consensusJSON.Name(), // path to consensus json,
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
|
|
|
@ -86,7 +86,7 @@ func NewAccountKeeper(
|
|||
|
||||
// Logger returns a module-specific logger.
|
||||
func (ak AccountKeeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
|
||||
return ctx.Logger().With("module", "x/"+types.ModuleName)
|
||||
}
|
||||
|
||||
// GetPubKey Returns the PubKey of the account at address
|
||||
|
|
|
@ -49,32 +49,21 @@ const (
|
|||
|
||||
// TxsByEvents implements the ServiceServer.TxsByEvents RPC method.
|
||||
func (s txServer) GetTxsEvent(ctx context.Context, req *txtypes.GetTxsEventRequest) (*txtypes.GetTxsEventResponse, error) {
|
||||
offset := int(req.Pagination.Offset)
|
||||
limit := int(req.Pagination.Limit)
|
||||
if offset < 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "offset must greater than 0")
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "request cannot be nil")
|
||||
}
|
||||
if len(req.Event) == 0 {
|
||||
|
||||
page, limit, err := pagination.ParsePagination(req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.Events) == 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "must declare at least one event to search")
|
||||
}
|
||||
|
||||
if limit < 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "limit must greater than 0")
|
||||
} else if limit == 0 {
|
||||
limit = pagination.DefaultLimit
|
||||
}
|
||||
|
||||
page := offset/limit + 1
|
||||
|
||||
var events []string
|
||||
|
||||
if strings.Contains(req.Event, "&") {
|
||||
events = strings.Split(req.Event, "&")
|
||||
} else {
|
||||
events = append(events, req.Event)
|
||||
}
|
||||
tmEvents := make([]string, len(events))
|
||||
for i, event := range events {
|
||||
tmEvents := make([]string, len(req.Events))
|
||||
for i, event := range req.Events {
|
||||
if !strings.Contains(event, "=") {
|
||||
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid event; event %s should be of the format: %s", event, eventFormat))
|
||||
} else if strings.Count(event, "=") > 1 {
|
||||
|
@ -128,7 +117,7 @@ func (s txServer) GetTxsEvent(ctx context.Context, req *txtypes.GetTxsEventReque
|
|||
|
||||
// Simulate implements the ServiceServer.Simulate RPC method.
|
||||
func (s txServer) Simulate(ctx context.Context, req *txtypes.SimulateRequest) (*txtypes.SimulateResponse, error) {
|
||||
if req.Tx == nil {
|
||||
if req == nil || req.Tx == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "invalid empty tx")
|
||||
}
|
||||
|
||||
|
@ -154,6 +143,10 @@ func (s txServer) Simulate(ctx context.Context, req *txtypes.SimulateRequest) (*
|
|||
|
||||
// GetTx implements the ServiceServer.GetTx RPC method.
|
||||
func (s txServer) GetTx(ctx context.Context, req *txtypes.GetTxRequest) (*txtypes.GetTxResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "request cannot be nil")
|
||||
}
|
||||
|
||||
// We get hash as a hex string in the request, convert it to bytes.
|
||||
hash, err := hex.DecodeString(req.Hash)
|
||||
if err != nil {
|
||||
|
@ -185,6 +178,10 @@ func (s txServer) GetTx(ctx context.Context, req *txtypes.GetTxRequest) (*txtype
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (s txServer) BroadcastTx(ctx context.Context, req *txtypes.BroadcastTxRequest) (*txtypes.BroadcastTxResponse, error) {
|
||||
return client.TxServiceBroadcast(ctx, s.clientCtx, req)
|
||||
}
|
||||
|
||||
// RegisterTxService registers the tx service on the gRPC router.
|
||||
func RegisterTxService(
|
||||
qrt gogogrpc.Server,
|
||||
|
|
|
@ -31,6 +31,7 @@ type IntegrationTestSuite struct {
|
|||
network *network.Network
|
||||
|
||||
queryClient tx.ServiceClient
|
||||
txRes sdk.TxResponse
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
|
@ -41,13 +42,34 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
|||
|
||||
s.cfg = cfg
|
||||
s.network = network.New(s.T(), cfg)
|
||||
|
||||
s.Require().NotNil(s.network)
|
||||
|
||||
val := s.network.Validators[0]
|
||||
|
||||
_, err := s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.queryClient = tx.NewServiceClient(s.network.Validators[0].ClientCtx)
|
||||
s.queryClient = tx.NewServiceClient(val.ClientCtx)
|
||||
|
||||
// Create a new MsgSend tx from val to itself.
|
||||
out, err := bankcli.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
val.Address,
|
||||
sdk.NewCoins(
|
||||
sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)),
|
||||
),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--gas=%d", flags.DefaultGasLimit),
|
||||
fmt.Sprintf("--%s=foobar", flags.FlagMemo),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &s.txRes))
|
||||
s.Require().Equal(uint32(0), s.txRes.Code)
|
||||
|
||||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
|
@ -55,8 +77,354 @@ func (s *IntegrationTestSuite) TearDownSuite() {
|
|||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestSimulate() {
|
||||
func (s IntegrationTestSuite) TestSimulateTx_GRPC() {
|
||||
txBuilder := s.mkTxBuilder()
|
||||
// Convert the txBuilder to a tx.Tx.
|
||||
protoTx, err := txBuilderToProtoTx(txBuilder)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
req *tx.SimulateRequest
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{"nil request", nil, true, "request cannot be nil"},
|
||||
{"empty request", &tx.SimulateRequest{}, true, "invalid empty tx"},
|
||||
{"valid request", &tx.SimulateRequest{Tx: protoTx}, false, ""},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
// Broadcast the tx via gRPC via the validator's clientCtx (which goes
|
||||
// through Tendermint).
|
||||
res, err := s.queryClient.Simulate(context.Background(), tc.req)
|
||||
if tc.expErr {
|
||||
s.Require().Error(err)
|
||||
s.Require().Contains(err.Error(), tc.expErrMsg)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
// Check the result and gas used are correct.
|
||||
s.Require().Equal(len(res.GetResult().GetEvents()), 4) // 1 transfer, 3 messages.
|
||||
s.Require().True(res.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty.
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestSimulateTx_GRPCGateway() {
|
||||
val := s.network.Validators[0]
|
||||
txBuilder := s.mkTxBuilder()
|
||||
// Convert the txBuilder to a tx.Tx.
|
||||
protoTx, err := txBuilderToProtoTx(txBuilder)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
req *tx.SimulateRequest
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{"empty request", &tx.SimulateRequest{}, true, "invalid empty tx"},
|
||||
{"valid request", &tx.SimulateRequest{Tx: protoTx}, false, ""},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
req, err := val.ClientCtx.JSONMarshaler.MarshalJSON(tc.req)
|
||||
s.Require().NoError(err)
|
||||
res, err := rest.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/simulate", val.APIAddress), "application/json", req)
|
||||
s.Require().NoError(err)
|
||||
if tc.expErr {
|
||||
s.Require().Contains(string(res), tc.expErrMsg)
|
||||
} else {
|
||||
var result tx.SimulateResponse
|
||||
err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(res, &result)
|
||||
s.Require().NoError(err)
|
||||
// Check the result and gas used are correct.
|
||||
s.Require().Equal(len(result.GetResult().GetEvents()), 4) // 1 transfer, 3 messages.
|
||||
s.Require().True(result.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty.
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestGetTxEvents_GRPC() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
req *tx.GetTxsEventRequest
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"nil request",
|
||||
nil,
|
||||
true, "request cannot be nil",
|
||||
},
|
||||
{
|
||||
"empty request",
|
||||
&tx.GetTxsEventRequest{},
|
||||
true, "must declare at least one event to search",
|
||||
},
|
||||
{
|
||||
"request with dummy event",
|
||||
&tx.GetTxsEventRequest{Events: []string{"foobar"}},
|
||||
true, "event foobar should be of the format: {eventType}.{eventAttribute}={value}",
|
||||
},
|
||||
{
|
||||
"without pagination",
|
||||
&tx.GetTxsEventRequest{
|
||||
Events: []string{"message.action=send"},
|
||||
},
|
||||
false, "",
|
||||
},
|
||||
{
|
||||
"with pagination",
|
||||
&tx.GetTxsEventRequest{
|
||||
Events: []string{"message.action=send"},
|
||||
Pagination: &query.PageRequest{
|
||||
CountTotal: false,
|
||||
Offset: 0,
|
||||
Limit: 1,
|
||||
},
|
||||
},
|
||||
false, "",
|
||||
},
|
||||
{
|
||||
"with multi events",
|
||||
&tx.GetTxsEventRequest{
|
||||
Events: []string{"message.action=send", "message.module=bank"},
|
||||
},
|
||||
false, "",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
// Query the tx via gRPC.
|
||||
grpcRes, err := s.queryClient.GetTxsEvent(context.Background(), tc.req)
|
||||
if tc.expErr {
|
||||
s.Require().Error(err)
|
||||
s.Require().Contains(err.Error(), tc.expErrMsg)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().GreaterOrEqual(len(grpcRes.Txs), 1)
|
||||
s.Require().Equal("foobar", grpcRes.Txs[0].Body.Memo)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestGetTxEvents_GRPCGateway() {
|
||||
val := s.network.Validators[0]
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty params",
|
||||
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", val.APIAddress),
|
||||
true,
|
||||
"must declare at least one event to search",
|
||||
},
|
||||
{
|
||||
"without pagination",
|
||||
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s", val.APIAddress, "message.action=send"),
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"with pagination",
|
||||
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&pagination.offset=%d&pagination.limit=%d", val.APIAddress, "message.action=send", 0, 10),
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"expect pass with multiple-events",
|
||||
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s&events=%s", val.APIAddress, "message.action=send", "message.module=bank"),
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"expect pass with escape event",
|
||||
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?events=%s", val.APIAddress, "message.action%3Dsend"),
|
||||
false,
|
||||
"",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
res, err := rest.GetRequest(tc.url)
|
||||
s.Require().NoError(err)
|
||||
if tc.expErr {
|
||||
s.Require().Contains(string(res), tc.expErrMsg)
|
||||
} else {
|
||||
var result tx.GetTxsEventResponse
|
||||
err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(res, &result)
|
||||
s.Require().NoError(err)
|
||||
s.Require().GreaterOrEqual(len(result.Txs), 1)
|
||||
s.Require().Equal("foobar", result.Txs[0].Body.Memo)
|
||||
s.Require().NotZero(result.TxResponses[0].Height)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestGetTx_GRPC() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
req *tx.GetTxRequest
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{"nil request", nil, true, "request cannot be nil"},
|
||||
{"empty request", &tx.GetTxRequest{}, true, "transaction hash cannot be empty"},
|
||||
{"request with dummy hash", &tx.GetTxRequest{Hash: "deadbeef"}, true, "tx (DEADBEEF) not found"},
|
||||
{"good request", &tx.GetTxRequest{Hash: s.txRes.TxHash}, false, ""},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
// Query the tx via gRPC.
|
||||
grpcRes, err := s.queryClient.GetTx(context.Background(), tc.req)
|
||||
if tc.expErr {
|
||||
s.Require().Error(err)
|
||||
s.Require().Contains(err.Error(), tc.expErrMsg)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal("foobar", grpcRes.Tx.Body.Memo)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestGetTx_GRPCGateway() {
|
||||
val := s.network.Validators[0]
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"empty params",
|
||||
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/", val.APIAddress),
|
||||
true, "transaction hash cannot be empty",
|
||||
},
|
||||
{
|
||||
"dummy hash",
|
||||
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", val.APIAddress, "deadbeef"),
|
||||
true, "tx (DEADBEEF) not found",
|
||||
},
|
||||
{
|
||||
"good hash",
|
||||
fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", val.APIAddress, s.txRes.TxHash),
|
||||
false, "",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
res, err := rest.GetRequest(tc.url)
|
||||
s.Require().NoError(err)
|
||||
if tc.expErr {
|
||||
s.Require().Contains(string(res), tc.expErrMsg)
|
||||
} else {
|
||||
var result tx.GetTxResponse
|
||||
err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(res, &result)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal("foobar", result.Tx.Body.Memo)
|
||||
s.Require().NotZero(result.TxResponse.Height)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestBroadcastTx_GRPC() {
|
||||
val := s.network.Validators[0]
|
||||
txBuilder := s.mkTxBuilder()
|
||||
txBytes, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
req *tx.BroadcastTxRequest
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{"nil request", nil, true, "request cannot be nil"},
|
||||
{"empty request", &tx.BroadcastTxRequest{}, true, "invalid empty tx"},
|
||||
{"no mode", &tx.BroadcastTxRequest{
|
||||
TxBytes: txBytes,
|
||||
}, true, "supported types: sync, async, block"},
|
||||
{"valid request", &tx.BroadcastTxRequest{
|
||||
Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||
TxBytes: txBytes,
|
||||
}, false, ""},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
// Broadcast the tx via gRPC via the validator's clientCtx (which goes
|
||||
// through Tendermint).
|
||||
grpcRes, err := s.queryClient.BroadcastTx(context.Background(), tc.req)
|
||||
if tc.expErr {
|
||||
s.Require().Error(err)
|
||||
s.Require().Contains(err.Error(), tc.expErrMsg)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint32(0), grpcRes.TxResponse.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestBroadcastTx_GRPCGateway() {
|
||||
val := s.network.Validators[0]
|
||||
txBuilder := s.mkTxBuilder()
|
||||
txBytes, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
s.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
req *tx.BroadcastTxRequest
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{"empty request", &tx.BroadcastTxRequest{}, true, "invalid empty tx"},
|
||||
{"no mode", &tx.BroadcastTxRequest{TxBytes: txBytes}, true, "supported types: sync, async, block"},
|
||||
{"valid request", &tx.BroadcastTxRequest{
|
||||
Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||
TxBytes: txBytes,
|
||||
}, false, ""},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
req, err := val.ClientCtx.JSONMarshaler.MarshalJSON(tc.req)
|
||||
s.Require().NoError(err)
|
||||
res, err := rest.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs", val.APIAddress), "application/json", req)
|
||||
s.Require().NoError(err)
|
||||
if tc.expErr {
|
||||
s.Require().Contains(string(res), tc.expErrMsg)
|
||||
} else {
|
||||
var result tx.BroadcastTxResponse
|
||||
err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(res, &result)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint32(0), result.TxResponse.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IntegrationTestSuite))
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) mkTxBuilder() client.TxBuilder {
|
||||
val := s.network.Validators[0]
|
||||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
|
||||
// prepare txBuilder with msg
|
||||
txBuilder := val.ClientCtx.TxConfig.NewTxBuilder()
|
||||
|
@ -71,7 +439,6 @@ func (s IntegrationTestSuite) TestSimulate() {
|
|||
)
|
||||
txBuilder.SetFeeAmount(feeAmount)
|
||||
txBuilder.SetGasLimit(gasLimit)
|
||||
txBuilder.SetMemo("foobar")
|
||||
|
||||
// setup txFactory
|
||||
txFactory := clienttx.Factory{}.
|
||||
|
@ -84,115 +451,7 @@ func (s IntegrationTestSuite) TestSimulate() {
|
|||
err := authclient.SignTx(txFactory, val.ClientCtx, val.Moniker, txBuilder, false)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Convert the txBuilder to a tx.Tx.
|
||||
protoTx, err := txBuilderToProtoTx(txBuilder)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Run the simulate gRPC query.
|
||||
res, err := s.queryClient.Simulate(
|
||||
context.Background(),
|
||||
&tx.SimulateRequest{Tx: protoTx},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Check the result and gas used are correct.
|
||||
s.Require().Equal(len(res.GetResult().GetEvents()), 4) // 1 transfer, 3 messages.
|
||||
s.Require().True(res.GetGasInfo().GetGasUsed() > 0) // Gas used sometimes change, just check it's not empty.
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestGetTxEvents() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
// Create a new MsgSend tx from val to itself.
|
||||
out, err := bankcli.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
val.Address,
|
||||
sdk.NewCoins(
|
||||
sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)),
|
||||
),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--gas=%d", flags.DefaultGasLimit),
|
||||
fmt.Sprintf("--%s=foobar", flags.FlagMemo),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
var txRes sdk.TxResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txRes))
|
||||
s.Require().Equal(uint32(0), txRes.Code)
|
||||
|
||||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
|
||||
// Query the tx via gRPC.
|
||||
grpcRes, err := s.queryClient.GetTxsEvent(
|
||||
context.Background(),
|
||||
&tx.GetTxsEventRequest{Event: "message.action=send",
|
||||
Pagination: &query.PageRequest{
|
||||
CountTotal: false,
|
||||
Offset: 0,
|
||||
Limit: 1,
|
||||
},
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(len(grpcRes.Txs), 1)
|
||||
s.Require().Equal("foobar", grpcRes.Txs[0].Body.Memo)
|
||||
|
||||
// Query the tx via grpc-gateway.
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs?event=%s&pagination.offset=%d&pagination.limit=%d", val.APIAddress, "message.action=send", 0, 1))
|
||||
s.Require().NoError(err)
|
||||
var getTxRes tx.GetTxsEventResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &getTxRes))
|
||||
s.Require().Equal(len(grpcRes.Txs), 1)
|
||||
s.Require().Equal("foobar", getTxRes.Txs[0].Body.Memo)
|
||||
s.Require().NotZero(grpcRes.TxResponses[0].Height)
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestGetTx() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
// Create a new MsgSend tx from val to itself.
|
||||
out, err := bankcli.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
val.Address,
|
||||
sdk.NewCoins(
|
||||
sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)),
|
||||
),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
fmt.Sprintf("--gas=%d", flags.DefaultGasLimit),
|
||||
fmt.Sprintf("--%s=foobar", flags.FlagMemo),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
var txRes sdk.TxResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txRes))
|
||||
s.Require().Equal(uint32(0), txRes.Code)
|
||||
|
||||
s.Require().NoError(s.network.WaitForNextBlock())
|
||||
|
||||
// Query the tx via gRPC.
|
||||
grpcRes, err := s.queryClient.GetTx(
|
||||
context.Background(),
|
||||
&tx.GetTxRequest{Hash: txRes.TxHash},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal("foobar", grpcRes.Tx.Body.Memo)
|
||||
s.Require().NotZero(grpcRes.TxResponse.Height)
|
||||
|
||||
// Query the tx via grpc-gateway.
|
||||
restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/tx/%s", val.APIAddress, txRes.TxHash))
|
||||
s.Require().NoError(err)
|
||||
var getTxRes tx.GetTxResponse
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &getTxRes))
|
||||
s.Require().Equal("foobar", grpcRes.Tx.Body.Memo)
|
||||
s.Require().NotZero(grpcRes.TxResponse.Height)
|
||||
}
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IntegrationTestSuite))
|
||||
return txBuilder
|
||||
}
|
||||
|
||||
// txBuilderToProtoTx converts a txBuilder into a proto tx.Tx.
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client/rest"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/rest"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
)
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
// InitGenesis initializes the bank module's state from a given genesis state.
|
||||
func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
|
||||
func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) {
|
||||
k.SetParams(ctx, genState.Params)
|
||||
|
||||
var totalSupply sdk.Coins
|
||||
|
@ -32,6 +32,10 @@ func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
|
|||
}
|
||||
|
||||
k.SetSupply(ctx, types.NewSupply(genState.Supply))
|
||||
|
||||
for _, meta := range genState.DenomMetadata {
|
||||
k.SetDenomMetaData(ctx, meta)
|
||||
}
|
||||
}
|
||||
|
||||
// ExportGenesis returns the bank module's genesis state.
|
||||
|
|
|
@ -37,8 +37,20 @@ func (suite *IntegrationTestSuite) getTestBalances() []types.Balance {
|
|||
addr2, _ := sdk.AccAddressFromBech32("cosmos1f9xjhxm0plzrh9cskf4qee4pc2xwp0n0556gh0")
|
||||
addr1, _ := sdk.AccAddressFromBech32("cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh")
|
||||
return []types.Balance{
|
||||
{addr2.String(), sdk.Coins{sdk.NewInt64Coin("testcoin1", 32), sdk.NewInt64Coin("testcoin2", 34)}},
|
||||
{addr1.String(), sdk.Coins{sdk.NewInt64Coin("testcoin3", 10)}},
|
||||
{Address: addr2.String(), Coins: sdk.Coins{sdk.NewInt64Coin("testcoin1", 32), sdk.NewInt64Coin("testcoin2", 34)}},
|
||||
{Address: addr1.String(), Coins: sdk.Coins{sdk.NewInt64Coin("testcoin3", 10)}},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestInitGenesis() {
|
||||
require := suite.Require()
|
||||
m := types.Metadata{Description: sdk.DefaultBondDenom, Base: sdk.DefaultBondDenom, Display: sdk.DefaultBondDenom}
|
||||
g := types.DefaultGenesisState()
|
||||
g.DenomMetadata = []types.Metadata{m}
|
||||
bk := suite.app.BankKeeper
|
||||
bk.InitGenesis(suite.ctx, g)
|
||||
|
||||
m2 := bk.GetDenomMetaData(suite.ctx, m.Base)
|
||||
require.Equal(m, m2)
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func (k BaseKeeper) Balance(ctx context.Context, req *types.QueryBalanceRequest)
|
|||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
address, err := sdk.AccAddressFromBech32(req.Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid address: %s", err.Error())
|
||||
}
|
||||
|
||||
balance := k.GetBalance(sdkCtx, address, req.Denom)
|
||||
|
@ -45,9 +45,13 @@ func (k BaseKeeper) AllBalances(ctx context.Context, req *types.QueryAllBalances
|
|||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
if req.Address == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "address cannot be empty")
|
||||
}
|
||||
|
||||
addr, err := sdk.AccAddressFromBech32(req.Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid address: %s", err.Error())
|
||||
}
|
||||
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
|
@ -68,7 +72,7 @@ func (k BaseKeeper) AllBalances(ctx context.Context, req *types.QueryAllBalances
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return &types.QueryAllBalancesResponse{}, err
|
||||
return nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err)
|
||||
}
|
||||
|
||||
return &types.QueryAllBalancesResponse{Balances: balances, Pagination: pageRes}, nil
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
@ -22,7 +21,7 @@ var _ Keeper = (*BaseKeeper)(nil)
|
|||
type Keeper interface {
|
||||
SendKeeper
|
||||
|
||||
InitGenesis(sdk.Context, types.GenesisState)
|
||||
InitGenesis(sdk.Context, *types.GenesisState)
|
||||
ExportGenesis(sdk.Context) *types.GenesisState
|
||||
|
||||
GetSupply(ctx sdk.Context) exported.SupplyI
|
||||
|
@ -186,7 +185,6 @@ func (k BaseKeeper) GetDenomMetaData(ctx sdk.Context, denom string) types.Metada
|
|||
store = prefix.NewStore(store, types.DenomMetadataKey(denom))
|
||||
|
||||
bz := store.Get([]byte(denom))
|
||||
|
||||
var metadata types.Metadata
|
||||
k.cdc.MustUnmarshalBinaryBare(bz, &metadata)
|
||||
|
||||
|
@ -342,7 +340,7 @@ func (k BaseKeeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins)
|
|||
k.SetSupply(ctx, supply)
|
||||
|
||||
logger := k.Logger(ctx)
|
||||
logger.Info(fmt.Sprintf("minted %s from %s module account", amt.String(), moduleName))
|
||||
logger.Info("minted coins from module account", "amount", amt.String(), "from", moduleName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -370,7 +368,7 @@ func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins)
|
|||
k.SetSupply(ctx, supply)
|
||||
|
||||
logger := k.Logger(ctx)
|
||||
logger.Info(fmt.Sprintf("burned %s from %s module account", amt.String(), moduleName))
|
||||
logger.Info("burned tokens from module account", "amount", amt.String(), "from", moduleName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ func NewBaseViewKeeper(cdc codec.BinaryMarshaler, storeKey sdk.StoreKey, ak type
|
|||
|
||||
// Logger returns a module-specific logger.
|
||||
func (k BaseViewKeeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
|
||||
return ctx.Logger().With("module", "x/"+types.ModuleName)
|
||||
}
|
||||
|
||||
// HasBalance returns whether or not an account has at least amt balance.
|
||||
|
|
|
@ -52,7 +52,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
|
|||
}
|
||||
|
||||
// ValidateGenesis performs genesis state validation for the bank module.
|
||||
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
|
||||
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, _ client.TxEncodingConfig, bz json.RawMessage) error {
|
||||
var data types.GenesisState
|
||||
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
|
||||
|
@ -140,7 +140,7 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data j
|
|||
cdc.MustUnmarshalJSON(data, &genesisState)
|
||||
telemetry.MeasureSince(start, "InitGenesis", "crisis", "unmarshal")
|
||||
|
||||
am.keeper.InitGenesis(ctx, genesisState)
|
||||
am.keeper.InitGenesis(ctx, &genesisState)
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
|||
}
|
||||
|
||||
// ProposalContents doesn't return any content functions for governance proposals.
|
||||
func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ func NewKeeper(
|
|||
|
||||
// Logger returns a module-specific logger.
|
||||
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
|
||||
return ctx.Logger().With("module", "x/"+types.ModuleName)
|
||||
}
|
||||
|
||||
// RegisterRoute register the routes for each of the invariants
|
||||
|
@ -76,7 +76,7 @@ func (k Keeper) AssertInvariants(ctx sdk.Context) {
|
|||
invarRoutes := k.Routes()
|
||||
n := len(invarRoutes)
|
||||
for i, ir := range invarRoutes {
|
||||
logger.Debug("Asserting cirisis invariants", "inv", fmt.Sprint(i, "/", n))
|
||||
logger.Info("asserting crisis invariants", "inv", fmt.Sprint(i, "/", n))
|
||||
if res, stop := ir.Invar(ctx); stop {
|
||||
// TODO: Include app name as part of context to allow for this to be
|
||||
// variable.
|
||||
|
|
|
@ -152,9 +152,13 @@ func (k Keeper) withdrawDelegationRewards(ctx sdk.Context, val stakingtypes.Vali
|
|||
rewards := rewardsRaw.Intersect(outstanding)
|
||||
if !rewards.IsEqual(rewardsRaw) {
|
||||
logger := k.Logger(ctx)
|
||||
logger.Info(fmt.Sprintf("missing rewards rounding error, delegator %v"+
|
||||
"withdrawing rewards from validator %v, should have received %v, got %v",
|
||||
val.GetOperator(), del.GetDelegatorAddr(), rewardsRaw, rewards))
|
||||
logger.Info(
|
||||
"rounding error withdrawing rewards from validator",
|
||||
"delegator", del.GetDelegatorAddr().String(),
|
||||
"validator", val.GetOperator().String(),
|
||||
"got", rewards.String(),
|
||||
"expected", rewardsRaw.String(),
|
||||
)
|
||||
}
|
||||
|
||||
// truncate coins, return remainder to community pool
|
||||
|
|
|
@ -57,7 +57,7 @@ func NewKeeper(
|
|||
|
||||
// Logger returns a module-specific logger.
|
||||
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
|
||||
return ctx.Logger().With("module", "x/"+types.ModuleName)
|
||||
}
|
||||
|
||||
// SetWithdrawAddr sets a new address that will receive the rewards upon withdrawal
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
|
@ -13,16 +11,19 @@ func HandleCommunityPoolSpendProposal(ctx sdk.Context, k Keeper, p *types.Commun
|
|||
if k.blockedAddrs[p.Recipient] {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive external funds", p.Recipient)
|
||||
}
|
||||
|
||||
recipient, addrErr := sdk.AccAddressFromBech32(p.Recipient)
|
||||
if addrErr != nil {
|
||||
return addrErr
|
||||
}
|
||||
|
||||
err := k.DistributeFromFeePool(ctx, p.Amount, recipient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger := k.Logger(ctx)
|
||||
logger.Info(fmt.Sprintf("transferred %s from the community pool to recipient %s", p.Amount, p.Recipient))
|
||||
logger.Info("transferred from the community pool to recipient", "amount", p.Amount.String(), "recipient", p.Recipient)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package cli_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
testnet "github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/client/cli"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
cfg testnet.Config
|
||||
network *testnet.Network
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
cfg := testnet.DefaultConfig()
|
||||
cfg.NumValidators = 1
|
||||
|
||||
s.cfg = cfg
|
||||
s.network = testnet.New(s.T(), cfg)
|
||||
|
||||
_, err := s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IntegrationTestSuite))
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetQueryCmd() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
testCases := map[string]struct {
|
||||
args []string
|
||||
expectedOutput string
|
||||
expectErr bool
|
||||
}{
|
||||
"non-existent evidence": {
|
||||
[]string{"DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660"},
|
||||
"evidence DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660 not found",
|
||||
true,
|
||||
},
|
||||
"all evidence (default pagination)": {
|
||||
[]string{},
|
||||
"evidence: []\npagination:\n next_key: null\n total: \"0\"",
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
s.Run(name, func() {
|
||||
cmd := cli.GetQueryCmd()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expectErr {
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
s.Require().Contains(strings.TrimSpace(out.String()), tc.expectedOutput)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -47,18 +47,14 @@ $ %s query %s --page=2 --limit=50
|
|||
// can be queried for by hash or paginated evidence can be returned.
|
||||
func QueryEvidenceCmd() func(*cobra.Command, []string) error {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
if err := client.ValidateCmd(cmd, args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clientCtx := client.GetClientContextFromCmd(cmd)
|
||||
clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if hash := args[0]; hash != "" {
|
||||
return queryEvidence(clientCtx, hash)
|
||||
if len(args) > 0 {
|
||||
return queryEvidence(clientCtx, args[0])
|
||||
}
|
||||
|
||||
pageReq, err := client.ReadPageRequest(cmd.Flags())
|
||||
|
|
|
@ -40,7 +40,7 @@ func NewKeeper(
|
|||
|
||||
// Logger returns a module-specific logger.
|
||||
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
|
||||
return ctx.Logger().With("module", "x/"+types.ModuleName)
|
||||
}
|
||||
|
||||
// SetRouter sets the Evidence Handler router for the x/evidence module. Note,
|
||||
|
|
|
@ -30,13 +30,13 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {
|
|||
)
|
||||
|
||||
logger.Info(
|
||||
fmt.Sprintf("proposal %d (%s) didn't meet minimum deposit of %s (had only %s); deleted",
|
||||
proposal.ProposalId,
|
||||
proposal.GetTitle(),
|
||||
keeper.GetDepositParams(ctx).MinDeposit,
|
||||
proposal.TotalDeposit,
|
||||
),
|
||||
"proposal did not meet minimum deposit; deleted",
|
||||
"proposal", proposal.ProposalId,
|
||||
"title", proposal.GetTitle(),
|
||||
"min_deposit", keeper.GetDepositParams(ctx).MinDeposit.String(),
|
||||
"total_deposit", proposal.TotalDeposit.String(),
|
||||
)
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
|
@ -90,10 +90,10 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {
|
|||
keeper.RemoveFromActiveProposalQueue(ctx, proposal.ProposalId, proposal.VotingEndTime)
|
||||
|
||||
logger.Info(
|
||||
fmt.Sprintf(
|
||||
"proposal %d (%s) tallied; result: %s",
|
||||
proposal.ProposalId, proposal.GetTitle(), logMsg,
|
||||
),
|
||||
"proposal tallied",
|
||||
"proposal", proposal.ProposalId,
|
||||
"title", proposal.GetTitle(),
|
||||
"result", logMsg,
|
||||
)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
|
|
|
@ -162,7 +162,7 @@ func (s *IntegrationTestSuite) TestGetProposalsGRPC() {
|
|||
func (s *IntegrationTestSuite) TestGetProposalVoteGRPC() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
voterAddressBase64 := val.Address.String()
|
||||
voterAddressBech32 := val.Address.String()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
@ -172,13 +172,13 @@ func (s *IntegrationTestSuite) TestGetProposalVoteGRPC() {
|
|||
}{
|
||||
{
|
||||
"empty proposal",
|
||||
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "", voterAddressBase64),
|
||||
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "", voterAddressBech32),
|
||||
true,
|
||||
types.NewNonSplitVoteOption(types.OptionYes),
|
||||
},
|
||||
{
|
||||
"get non existing proposal",
|
||||
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "10", voterAddressBase64),
|
||||
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "10", voterAddressBech32),
|
||||
true,
|
||||
types.NewNonSplitVoteOption(types.OptionYes),
|
||||
},
|
||||
|
@ -190,7 +190,7 @@ func (s *IntegrationTestSuite) TestGetProposalVoteGRPC() {
|
|||
},
|
||||
{
|
||||
"get proposal with id",
|
||||
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "1", voterAddressBase64),
|
||||
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "1", voterAddressBech32),
|
||||
false,
|
||||
types.NewNonSplitVoteOption(types.OptionYes),
|
||||
},
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
// +build norace
|
||||
|
||||
package rest_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
)
|
||||
|
||||
func (s *IntegrationTestSuite) TestLegacyGetVote() {
|
||||
val := s.network.Validators[0]
|
||||
voterAddressBech32 := val.Address.String()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"get non existing proposal",
|
||||
fmt.Sprintf("%s/gov/proposals/%s/votes/%s", val.APIAddress, "10", voterAddressBech32),
|
||||
true, "proposalID 10 does not exist",
|
||||
},
|
||||
{
|
||||
"get proposal with wrong voter address",
|
||||
fmt.Sprintf("%s/gov/proposals/%s/votes/%s", val.APIAddress, "1", "wrongVoterAddress"),
|
||||
true, "decoding bech32 failed: string not all lowercase or all uppercase",
|
||||
},
|
||||
{
|
||||
"get proposal with id",
|
||||
fmt.Sprintf("%s/gov/proposals/%s/votes/%s", val.APIAddress, "1", voterAddressBech32),
|
||||
false, "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
respJSON, err := rest.GetRequest(tc.url)
|
||||
s.Require().NoError(err)
|
||||
|
||||
if tc.expErr {
|
||||
var errResp rest.ErrorResponse
|
||||
s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(respJSON, &errResp))
|
||||
|
||||
s.Require().Equal(errResp.Error, tc.expErrMsg)
|
||||
} else {
|
||||
var resp = rest.ResponseWithHeight{}
|
||||
err = val.ClientCtx.LegacyAmino.UnmarshalJSON(respJSON, &resp)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Check result is not empty.
|
||||
var vote types.Vote
|
||||
s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(resp.Result, &vote))
|
||||
s.Require().Equal(val.Address.String(), vote.Voter)
|
||||
// Note that option is now an int.
|
||||
s.Require().Equal(types.VoteOption(1), vote.Option)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestLegacyGetVotes() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expErr bool
|
||||
expErrMsg string
|
||||
}{
|
||||
{
|
||||
"votes with empty proposal id",
|
||||
fmt.Sprintf("%s/gov/proposals/%s/votes", val.APIAddress, ""),
|
||||
true, "'votes' is not a valid uint64",
|
||||
},
|
||||
{
|
||||
"get votes with valid id",
|
||||
fmt.Sprintf("%s/gov/proposals/%s/votes", val.APIAddress, "1"),
|
||||
false, "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
respJSON, err := rest.GetRequest(tc.url)
|
||||
s.Require().NoError(err)
|
||||
|
||||
if tc.expErr {
|
||||
var errResp rest.ErrorResponse
|
||||
s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(respJSON, &errResp))
|
||||
|
||||
s.Require().Equal(errResp.Error, tc.expErrMsg)
|
||||
} else {
|
||||
var resp = rest.ResponseWithHeight{}
|
||||
err = val.ClientCtx.LegacyAmino.UnmarshalJSON(respJSON, &resp)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Check result is not empty.
|
||||
var votes []types.Vote
|
||||
s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(resp.Result, &votes))
|
||||
s.Require().Greater(len(votes), 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -3,13 +3,14 @@ package keeper_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -68,7 +68,7 @@ func NewKeeper(
|
|||
|
||||
// Logger returns a module-specific logger.
|
||||
func (keeper Keeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
|
||||
return ctx.Logger().With("module", "x/"+types.ModuleName)
|
||||
}
|
||||
|
||||
// Router returns the gov Keeper's Router
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
|
@ -63,7 +61,7 @@ func NewKeeper(
|
|||
|
||||
// Logger returns a module-specific logger.
|
||||
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s-%s", host.ModuleName, types.ModuleName))
|
||||
return ctx.Logger().With("module", "x/"+host.ModuleName+"-"+types.ModuleName)
|
||||
}
|
||||
|
||||
// GetTransferAccount returns the ICS20 - transfers ModuleAccount
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
|
||||
localhosttypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/09-localhost/types"
|
||||
)
|
||||
|
||||
// InitGenesis initializes the ibc client submodule's state from a provided genesis
|
||||
|
@ -15,6 +14,12 @@ import (
|
|||
func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) {
|
||||
k.SetParams(ctx, gs.Params)
|
||||
|
||||
// Set all client metadata first. This will allow client keeper to overwrite client and consensus state keys
|
||||
// if clients accidentally write to ClientKeeper reserved keys.
|
||||
if len(gs.ClientsMetadata) != 0 {
|
||||
k.SetAllClientMetadata(ctx, gs.ClientsMetadata)
|
||||
}
|
||||
|
||||
for _, client := range gs.Clients {
|
||||
cs, ok := client.ClientState.GetCachedValue().(exported.ClientState)
|
||||
if !ok {
|
||||
|
@ -39,37 +44,24 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) {
|
|||
}
|
||||
}
|
||||
|
||||
if !gs.CreateLocalhost {
|
||||
return
|
||||
}
|
||||
k.SetNextClientSequence(ctx, gs.NextClientSequence)
|
||||
|
||||
// NOTE: return if the localhost client was already imported. The chain-id and
|
||||
// block height will be overwriten to the correct values during BeginBlock.
|
||||
if _, found := k.GetClientState(ctx, exported.Localhost); found {
|
||||
return
|
||||
}
|
||||
|
||||
// client id is always "localhost"
|
||||
revision := types.ParseChainID(ctx.ChainID())
|
||||
clientState := localhosttypes.NewClientState(
|
||||
ctx.ChainID(), types.NewHeight(revision, uint64(ctx.BlockHeight())),
|
||||
)
|
||||
|
||||
if err := clientState.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := k.CreateClient(ctx, exported.Localhost, clientState, nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// NOTE: localhost creation is specifically disallowed for the time being.
|
||||
// Issue: https://github.com/cosmos/cosmos-sdk/issues/7871
|
||||
}
|
||||
|
||||
// ExportGenesis returns the ibc client submodule's exported genesis.
|
||||
// NOTE: CreateLocalhost should always be false on export since a
|
||||
// created localhost will be included in the exported clients.
|
||||
func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
|
||||
genClients := k.GetAllGenesisClients(ctx)
|
||||
clientsMetadata, err := k.GetAllClientMetadata(ctx, genClients)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return types.GenesisState{
|
||||
Clients: k.GetAllGenesisClients(ctx),
|
||||
Clients: genClients,
|
||||
ClientsMetadata: clientsMetadata,
|
||||
ClientsConsensus: k.GetAllConsensusStates(ctx),
|
||||
Params: k.GetParams(ctx),
|
||||
CreateLocalhost: false,
|
||||
|
|
|
@ -12,22 +12,26 @@ import (
|
|||
|
||||
// CreateClient creates a new client state and populates it with a given consensus
|
||||
// state as defined in https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#create
|
||||
//
|
||||
// CONTRACT: ClientState was constructed correctly from given initial consensusState
|
||||
func (k Keeper) CreateClient(
|
||||
ctx sdk.Context, clientID string, clientState exported.ClientState, consensusState exported.ConsensusState,
|
||||
) error {
|
||||
ctx sdk.Context, clientState exported.ClientState, consensusState exported.ConsensusState,
|
||||
) (string, error) {
|
||||
params := k.GetParams(ctx)
|
||||
if !params.IsAllowedClient(clientState.ClientType()) {
|
||||
return sdkerrors.Wrapf(
|
||||
return "", sdkerrors.Wrapf(
|
||||
types.ErrInvalidClientType,
|
||||
"client state type %s is not registered in the allowlist", clientState.ClientType(),
|
||||
)
|
||||
}
|
||||
|
||||
_, found := k.GetClientState(ctx, clientID)
|
||||
if found {
|
||||
return sdkerrors.Wrapf(types.ErrClientExists, "cannot create client with ID %s", clientID)
|
||||
clientID := k.GenerateClientIdentifier(ctx, clientState.ClientType())
|
||||
|
||||
k.SetClientState(ctx, clientID, clientState)
|
||||
k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String())
|
||||
|
||||
// verifies initial consensus state against client state and initializes client store with any client-specific metadata
|
||||
// e.g. set ProcessedTime in Tendermint clients
|
||||
if err := clientState.Initialize(ctx, k.cdc, k.ClientStore(ctx, clientID), consensusState); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// check if consensus state is nil in case the created client is Localhost
|
||||
|
@ -35,7 +39,6 @@ func (k Keeper) CreateClient(
|
|||
k.SetClientConsensusState(ctx, clientID, clientState.GetLatestHeight(), consensusState)
|
||||
}
|
||||
|
||||
k.SetClientState(ctx, clientID, clientState)
|
||||
k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String())
|
||||
|
||||
defer func() {
|
||||
|
@ -46,7 +49,7 @@ func (k Keeper) CreateClient(
|
|||
)
|
||||
}()
|
||||
|
||||
return nil
|
||||
return clientID, nil
|
||||
}
|
||||
|
||||
// UpdateClient updates the consensus state and the state root from a provided header.
|
||||
|
|
|
@ -19,36 +19,23 @@ import (
|
|||
|
||||
func (suite *KeeperTestSuite) TestCreateClient() {
|
||||
cases := []struct {
|
||||
msg string
|
||||
clientID string
|
||||
expPass bool
|
||||
expPanic bool
|
||||
msg string
|
||||
clientState exported.ClientState
|
||||
expPass bool
|
||||
}{
|
||||
{"success", testClientID, true, false},
|
||||
{"client ID exists", testClientID, false, false},
|
||||
{"success", ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), true},
|
||||
{"client type not supported", localhosttypes.NewClientState(testChainID, clienttypes.NewHeight(0, 1)), false},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
tc := tc
|
||||
i := i
|
||||
if tc.expPanic {
|
||||
suite.Require().Panics(func() {
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
suite.keeper.CreateClient(suite.ctx, tc.clientID, clientState, suite.consensusState)
|
||||
}, "Msg %d didn't panic: %s", i, tc.msg)
|
||||
} else {
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
if tc.expPass {
|
||||
suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.msg)
|
||||
}
|
||||
// If we were able to NewClientState clientstate successfully, try persisting it to state
|
||||
err := suite.keeper.CreateClient(suite.ctx, tc.clientID, clientState, suite.consensusState)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg)
|
||||
} else {
|
||||
suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg)
|
||||
}
|
||||
clientID, err := suite.keeper.CreateClient(suite.ctx, tc.clientState, suite.consensusState)
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg)
|
||||
suite.Require().NotNil(clientID, "valid test case %d failed: %s", i, tc.msg)
|
||||
} else {
|
||||
suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg)
|
||||
suite.Require().Equal("", clientID, "invalid test case %d passed: %s", i, tc.msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +59,8 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
var (
|
||||
updateHeader *ibctmtypes.Header
|
||||
clientState *ibctmtypes.ClientState
|
||||
clientID string
|
||||
err error
|
||||
)
|
||||
|
||||
cases := []struct {
|
||||
|
@ -81,7 +70,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
}{
|
||||
{"valid update", func() error {
|
||||
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
|
||||
// store intermediate consensus state to check that trustedHeight does not need to be highest consensus state before header height
|
||||
incrementedClientHeight := testClientHeight.Increment()
|
||||
|
@ -89,17 +78,17 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
Timestamp: suite.now.Add(time.Minute),
|
||||
NextValidatorsHash: suite.valSetHash,
|
||||
}
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, incrementedClientHeight, intermediateConsState)
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, clientID, incrementedClientHeight, intermediateConsState)
|
||||
|
||||
clientState.LatestHeight = incrementedClientHeight
|
||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||
suite.keeper.SetClientState(suite.ctx, clientID, clientState)
|
||||
|
||||
updateHeader = createFutureUpdateFn(suite)
|
||||
return err
|
||||
}, true},
|
||||
{"valid past update", func() error {
|
||||
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
height1 := types.NewHeight(0, 1)
|
||||
|
@ -109,7 +98,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
Timestamp: suite.past,
|
||||
NextValidatorsHash: suite.valSetHash,
|
||||
}
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height1, prevConsState)
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, clientID, height1, prevConsState)
|
||||
|
||||
height2 := types.NewHeight(0, 2)
|
||||
|
||||
|
@ -118,7 +107,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
Timestamp: suite.past.Add(time.Minute),
|
||||
NextValidatorsHash: suite.valSetHash,
|
||||
}
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height2, intermediateConsState)
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, clientID, height2, intermediateConsState)
|
||||
|
||||
// updateHeader will fill in consensus state between prevConsState and suite.consState
|
||||
// clientState should not be updated
|
||||
|
@ -147,7 +136,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
{"valid past update before client was frozen", func() error {
|
||||
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
clientState.FrozenHeight = types.NewHeight(0, testClientHeight.RevisionHeight-1)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
height1 := types.NewHeight(0, 1)
|
||||
|
@ -157,7 +146,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
Timestamp: suite.past,
|
||||
NextValidatorsHash: suite.valSetHash,
|
||||
}
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, height1, prevConsState)
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, clientID, height1, prevConsState)
|
||||
|
||||
// updateHeader will fill in consensus state between prevConsState and suite.consState
|
||||
// clientState should not be updated
|
||||
|
@ -166,7 +155,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
}, true},
|
||||
{"invalid header", func() error {
|
||||
clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
_, err := suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
suite.Require().NoError(err)
|
||||
updateHeader = createPastUpdateFn(suite)
|
||||
|
||||
|
@ -179,13 +168,14 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
i := i
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
suite.SetupTest()
|
||||
clientID = testClientID // must be explicitly changed
|
||||
|
||||
err := tc.malleate()
|
||||
suite.Require().NoError(err)
|
||||
|
||||
suite.ctx = suite.ctx.WithBlockTime(updateHeader.Header.Time.Add(time.Minute))
|
||||
|
||||
err = suite.keeper.UpdateClient(suite.ctx, testClientID, updateHeader)
|
||||
err = suite.keeper.UpdateClient(suite.ctx, clientID, updateHeader)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err, err)
|
||||
|
@ -196,10 +186,10 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
|
|||
NextValidatorsHash: updateHeader.Header.NextValidatorsHash,
|
||||
}
|
||||
|
||||
newClientState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
|
||||
newClientState, found := suite.keeper.GetClientState(suite.ctx, clientID)
|
||||
suite.Require().True(found, "valid test case %d failed: %s", i, tc.name)
|
||||
|
||||
consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, updateHeader.GetHeight())
|
||||
consensusState, found := suite.keeper.GetClientConsensusState(suite.ctx, clientID, updateHeader.GetHeight())
|
||||
suite.Require().True(found, "valid test case %d failed: %s", i, tc.name)
|
||||
|
||||
// Determine if clientState should be updated or not
|
||||
|
@ -399,6 +389,11 @@ func (suite *KeeperTestSuite) TestUpgradeClient() {
|
|||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
||||
var (
|
||||
clientID string
|
||||
err error
|
||||
)
|
||||
|
||||
altPrivVal := ibctestingmock.NewPV()
|
||||
altPubKey, err := altPrivVal.GetPubKey()
|
||||
suite.Require().NoError(err)
|
||||
|
@ -437,12 +432,12 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
|||
&ibctmtypes.Misbehaviour{
|
||||
Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners),
|
||||
Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners),
|
||||
ClientId: testClientID,
|
||||
ClientId: clientID,
|
||||
},
|
||||
func() error {
|
||||
suite.consensusState.NextValidatorsHash = bothValsHash
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
|
||||
return err
|
||||
},
|
||||
|
@ -453,22 +448,22 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
|||
&ibctmtypes.Misbehaviour{
|
||||
Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners),
|
||||
Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners),
|
||||
ClientId: testClientID,
|
||||
ClientId: clientID,
|
||||
},
|
||||
func() error {
|
||||
suite.consensusState.NextValidatorsHash = valsHash
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
|
||||
// store intermediate consensus state to check that trustedHeight does not need to be highest consensus state before header height
|
||||
intermediateConsState := &ibctmtypes.ConsensusState{
|
||||
Timestamp: suite.now.Add(time.Minute),
|
||||
NextValidatorsHash: suite.valSetHash,
|
||||
}
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, heightPlus3, intermediateConsState)
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, clientID, heightPlus3, intermediateConsState)
|
||||
|
||||
clientState.LatestHeight = heightPlus3
|
||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||
suite.keeper.SetClientState(suite.ctx, clientID, clientState)
|
||||
|
||||
return err
|
||||
},
|
||||
|
@ -479,22 +474,22 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
|||
&ibctmtypes.Misbehaviour{
|
||||
Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners),
|
||||
Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners),
|
||||
ClientId: testClientID,
|
||||
ClientId: clientID,
|
||||
},
|
||||
func() error {
|
||||
suite.consensusState.NextValidatorsHash = valsHash
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
|
||||
// store trusted consensus state for Header2
|
||||
intermediateConsState := &ibctmtypes.ConsensusState{
|
||||
Timestamp: suite.now.Add(time.Minute),
|
||||
NextValidatorsHash: bothValsHash,
|
||||
}
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, testClientID, heightPlus3, intermediateConsState)
|
||||
suite.keeper.SetClientConsensusState(suite.ctx, clientID, heightPlus3, intermediateConsState)
|
||||
|
||||
clientState.LatestHeight = heightPlus3
|
||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||
suite.keeper.SetClientState(suite.ctx, clientID, clientState)
|
||||
|
||||
return err
|
||||
},
|
||||
|
@ -505,12 +500,12 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
|||
&ibctmtypes.Misbehaviour{
|
||||
Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, altTime, bothValSet, bothValSet, bothSigners),
|
||||
Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners),
|
||||
ClientId: testClientID,
|
||||
ClientId: clientID,
|
||||
},
|
||||
func() error {
|
||||
suite.consensusState.NextValidatorsHash = valsHash
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
// intermediate consensus state at height + 3 is not created
|
||||
return err
|
||||
},
|
||||
|
@ -521,12 +516,12 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
|||
&ibctmtypes.Misbehaviour{
|
||||
Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners),
|
||||
Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners),
|
||||
ClientId: testClientID,
|
||||
ClientId: clientID,
|
||||
},
|
||||
func() error {
|
||||
suite.consensusState.NextValidatorsHash = valsHash
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
// intermediate consensus state at height + 3 is not created
|
||||
return err
|
||||
},
|
||||
|
@ -543,15 +538,15 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
|||
&ibctmtypes.Misbehaviour{
|
||||
Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners),
|
||||
Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners),
|
||||
ClientId: testClientID,
|
||||
ClientId: clientID,
|
||||
},
|
||||
func() error {
|
||||
suite.consensusState.NextValidatorsHash = bothValsHash
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
|
||||
clientState.FrozenHeight = types.NewHeight(0, 1)
|
||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||
suite.keeper.SetClientState(suite.ctx, clientID, clientState)
|
||||
|
||||
return err
|
||||
},
|
||||
|
@ -562,14 +557,14 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
|||
&ibctmtypes.Misbehaviour{
|
||||
Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners),
|
||||
Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners),
|
||||
ClientId: testClientID,
|
||||
ClientId: clientID,
|
||||
},
|
||||
func() error {
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState)
|
||||
clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState)
|
||||
|
||||
return err
|
||||
},
|
||||
|
@ -580,18 +575,22 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() {
|
|||
for i, tc := range testCases {
|
||||
tc := tc
|
||||
i := i
|
||||
|
||||
suite.Run(tc.name, func() {
|
||||
suite.SetupTest() // reset
|
||||
suite.SetupTest() // reset
|
||||
clientID = testClientID // must be explicitly changed
|
||||
|
||||
err := tc.malleate()
|
||||
suite.Require().NoError(err)
|
||||
|
||||
tc.misbehaviour.ClientId = clientID
|
||||
|
||||
err = suite.keeper.CheckMisbehaviourAndUpdateState(suite.ctx, tc.misbehaviour)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name)
|
||||
|
||||
clientState, found := suite.keeper.GetClientState(suite.ctx, testClientID)
|
||||
clientState, found := suite.keeper.GetClientState(suite.ctx, clientID)
|
||||
suite.Require().True(found, "valid test case %d failed: %s", i, tc.name)
|
||||
suite.Require().True(clientState.IsFrozen(), "valid test case %d failed: %s", i, tc.name)
|
||||
suite.Require().Equal(tc.misbehaviour.GetHeight(), clientState.GetFrozenHeight(),
|
||||
|
|
|
@ -43,7 +43,7 @@ func (suite *KeeperTestSuite) TestQueryClientState() {
|
|||
{
|
||||
"success",
|
||||
func() {
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
suite.keeper.SetClientState(suite.ctx, testClientID, clientState)
|
||||
|
||||
var err error
|
||||
|
@ -183,10 +183,10 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() {
|
|||
"invalid height",
|
||||
func() {
|
||||
req = &types.QueryConsensusStateRequest{
|
||||
ClientId: testClientID,
|
||||
ClientId: testClientID,
|
||||
RevisionNumber: 0,
|
||||
RevisionHeight: 0,
|
||||
LatestHeight: false,
|
||||
LatestHeight: false,
|
||||
}
|
||||
},
|
||||
false,
|
||||
|
@ -204,7 +204,7 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() {
|
|||
{
|
||||
"success latest height",
|
||||
func() {
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false)
|
||||
cs := ibctmtypes.NewConsensusState(
|
||||
suite.consensusState.Timestamp, commitmenttypes.NewMerkleRoot([]byte("hash1")), nil,
|
||||
)
|
||||
|
@ -235,7 +235,7 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() {
|
|||
suite.Require().NoError(err)
|
||||
|
||||
req = &types.QueryConsensusStateRequest{
|
||||
ClientId: testClientID,
|
||||
ClientId: testClientID,
|
||||
RevisionNumber: 0,
|
||||
RevisionHeight: height,
|
||||
}
|
||||
|
|
|
@ -47,7 +47,17 @@ func NewKeeper(cdc codec.BinaryMarshaler, key sdk.StoreKey, paramSpace paramtype
|
|||
|
||||
// Logger returns a module-specific logger.
|
||||
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
|
||||
return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", host.ModuleName, types.SubModuleName))
|
||||
return ctx.Logger().With("module", "x/"+host.ModuleName+"/"+types.SubModuleName)
|
||||
}
|
||||
|
||||
// GenerateClientIdentifier returns the next client identifier.
|
||||
func (k Keeper) GenerateClientIdentifier(ctx sdk.Context, clientType string) string {
|
||||
nextClientSeq := k.GetNextClientSequence(ctx)
|
||||
clientID := types.FormatClientIdentifier(clientType, nextClientSeq)
|
||||
|
||||
nextClientSeq++
|
||||
k.SetNextClientSequence(ctx, nextClientSeq)
|
||||
return clientID
|
||||
}
|
||||
|
||||
// GetClientState gets a particular client from the store
|
||||
|
@ -87,6 +97,24 @@ func (k Keeper) SetClientConsensusState(ctx sdk.Context, clientID string, height
|
|||
store.Set(host.ConsensusStateKey(height), k.MustMarshalConsensusState(consensusState))
|
||||
}
|
||||
|
||||
// GetNextClientSequence gets the next client sequence from the store.
|
||||
func (k Keeper) GetNextClientSequence(ctx sdk.Context) uint64 {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get([]byte(types.KeyNextClientSequence))
|
||||
if bz == nil {
|
||||
panic("next client sequence is nil")
|
||||
}
|
||||
|
||||
return sdk.BigEndianToUint64(bz)
|
||||
}
|
||||
|
||||
// SetNextClientSequence sets the next client sequence to the store.
|
||||
func (k Keeper) SetNextClientSequence(ctx sdk.Context, sequence uint64) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := sdk.Uint64ToBigEndian(sequence)
|
||||
store.Set([]byte(types.KeyNextClientSequence), bz)
|
||||
}
|
||||
|
||||
// IterateConsensusStates provides an iterator over all stored consensus states.
|
||||
// objects. For each State object, cb will be called. If the cb returns true,
|
||||
// the iterator will close and stop.
|
||||
|
@ -124,6 +152,49 @@ func (k Keeper) GetAllGenesisClients(ctx sdk.Context) types.IdentifiedClientStat
|
|||
return genClients.Sort()
|
||||
}
|
||||
|
||||
// GetAllClientMetadata will take a list of IdentifiedClientState and return a list
|
||||
// of IdentifiedGenesisMetadata necessary for exporting and importing client metadata
|
||||
// into the client store.
|
||||
func (k Keeper) GetAllClientMetadata(ctx sdk.Context, genClients []types.IdentifiedClientState) ([]types.IdentifiedGenesisMetadata, error) {
|
||||
genMetadata := make([]types.IdentifiedGenesisMetadata, 0)
|
||||
for _, ic := range genClients {
|
||||
cs, err := types.UnpackClientState(ic.ClientState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gms := cs.ExportMetadata(k.ClientStore(ctx, ic.ClientId))
|
||||
if len(gms) == 0 {
|
||||
continue
|
||||
}
|
||||
clientMetadata := make([]types.GenesisMetadata, len(gms))
|
||||
for i, metadata := range gms {
|
||||
cmd, ok := metadata.(types.GenesisMetadata)
|
||||
if !ok {
|
||||
return nil, sdkerrors.Wrapf(types.ErrInvalidClientMetadata, "expected metadata type: %T, got: %T",
|
||||
types.GenesisMetadata{}, cmd)
|
||||
}
|
||||
clientMetadata[i] = cmd
|
||||
}
|
||||
genMetadata = append(genMetadata, types.NewIdentifiedGenesisMetadata(
|
||||
ic.ClientId,
|
||||
clientMetadata,
|
||||
))
|
||||
}
|
||||
return genMetadata, nil
|
||||
}
|
||||
|
||||
// SetAllClientMetadata takes a list of IdentifiedGenesisMetadata and stores all of the metadata in the client store at the appropriate paths.
|
||||
func (k Keeper) SetAllClientMetadata(ctx sdk.Context, genMetadata []types.IdentifiedGenesisMetadata) {
|
||||
for _, igm := range genMetadata {
|
||||
// create client store
|
||||
store := k.ClientStore(ctx, igm.ClientId)
|
||||
// set all metadata kv pairs in client store
|
||||
for _, md := range igm.ClientMetadata {
|
||||
store.Set(md.GetKey(), md.GetValue())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllConsensusStates returns all stored client consensus states.
|
||||
func (k Keeper) GetAllConsensusStates(ctx sdk.Context) types.ClientsConsensusStates {
|
||||
clientConsStates := make(types.ClientsConsensusStates, 0)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue