diff --git a/CHANGELOG.md b/CHANGELOG.md index 737a1cc914..0d040e66f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * [#1592](https://github.com/crypto-org-chain/cronos/pull/1592) Change the default parallelism of the block-stm to minimum between GOMAXPROCS and NumCPU * [#1600](https://github.com/crypto-org-chain/cronos/pull/1600) Update ethermint to avoid unnecessary block result in header related api call. * [#1606](https://github.com/crypto-org-chain/cronos/pull/1606) Fix pebbledb support. +* [#1610](https://github.com/crypto-org-chain/cronos/pull/1610) Sync e2ee module with v1.3.x branch. ### Bug Fixes diff --git a/app/app.go b/app/app.go index f4148bffda..6f1f68ed31 100644 --- a/app/app.go +++ b/app/app.go @@ -15,8 +15,11 @@ import ( stdruntime "runtime" "sort" + "filippo.io/age" + abci "github.com/cometbft/cometbft/abci/types" tmos "github.com/cometbft/cometbft/libs/os" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/gogoproto/proto" "github.com/gorilla/mux" @@ -159,6 +162,7 @@ import ( cronosprecompiles "github.com/crypto-org-chain/cronos/v2/x/cronos/keeper/precompiles" "github.com/crypto-org-chain/cronos/v2/x/cronos/middleware" cronostypes "github.com/crypto-org-chain/cronos/v2/x/cronos/types" + e2eekeyring "github.com/crypto-org-chain/cronos/v2/x/e2ee/keyring" e2ee "github.com/crypto-org-chain/cronos/v2/x/e2ee" e2eekeeper "github.com/crypto-org-chain/cronos/v2/x/e2ee/keeper" @@ -179,7 +183,8 @@ const ( // NOTE: In the SDK, the default value is 255. AddrLen = 20 - FlagBlockedAddresses = "blocked-addresses" + FlagBlockedAddresses = "blocked-addresses" + FlagUnsafeIgnoreBlockListFailure = "unsafe-ignore-block-list-failure" ) var Forks = []Fork{} @@ -342,6 +347,8 @@ type App struct { configurator module.Configurator qms storetypes.RootMultiStore + + blockProposalHandler *ProposalHandler } // New returns a reference to an initialized chain. @@ -360,23 +367,67 @@ func New( cdc := encodingConfig.Amino txConfig := encodingConfig.TxConfig interfaceRegistry := encodingConfig.InterfaceRegistry - + txDecoder := txConfig.TxDecoder() eip712.SetEncodingConfig(encodingConfig) + homePath := cast.ToString(appOpts.Get(flags.FlagHome)) + var identity age.Identity + { + if cast.ToString(appOpts.Get("mode")) == "validator" { + krBackend := cast.ToString(appOpts.Get(flags.FlagKeyringBackend)) + kr, err := e2eekeyring.New("cronosd", krBackend, homePath, os.Stdin) + if err != nil { + panic(err) + } + bz, err := kr.Get(e2eetypes.DefaultKeyringName) + if err != nil { + logger.Error("e2ee identity for validator not found", "error", err) + identity = noneIdentity{} + } else { + identity, err = age.ParseX25519Identity(string(bz)) + if err != nil { + logger.Error("e2ee identity for validator is invalid", "error", err) + identity = noneIdentity{} + } + } + } + } + + addressCodec := authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()) + + var mpool mempool.Mempool if maxTxs := cast.ToInt(appOpts.Get(server.FlagMempoolMaxTxs)); maxTxs >= 0 { // NOTE we use custom transaction decoder that supports the sdk.Tx interface instead of sdk.StdTx // Setup Mempool and Proposal Handlers - mempool := mempool.NewPriorityMempool(mempool.PriorityNonceMempoolConfig[int64]{ + mpool = mempool.NewPriorityMempool(mempool.PriorityNonceMempoolConfig[int64]{ TxPriority: mempool.NewDefaultTxPriority(), SignerExtractor: evmapp.NewEthSignerExtractionAdapter(mempool.NewDefaultSignerExtractionAdapter()), MaxTx: maxTxs, }) - baseAppOptions = append(baseAppOptions, baseapp.SetMempool(mempool)) + } else { + mpool = mempool.NoOpMempool{} } + blockProposalHandler := NewProposalHandler(txDecoder, identity, addressCodec) + baseAppOptions = append(baseAppOptions, func(app *baseapp.BaseApp) { + app.SetMempool(mpool) + + // Re-use the default prepare proposal handler, extend the transaction validation logic + defaultProposalHandler := baseapp.NewDefaultProposalHandler(mpool, app) + defaultProposalHandler.SetTxSelector(NewExtTxSelector( + baseapp.NewDefaultTxSelector(), + txDecoder, + blockProposalHandler.ValidateTransaction, + )) + + app.SetPrepareProposal(defaultProposalHandler.PrepareProposalHandler()) + + // The default process proposal handler do nothing when the mempool is noop, + // so we just implement a new one. + app.SetProcessProposal(blockProposalHandler.ProcessProposalHandler()) + }) blockSTMEnabled := cast.ToString(appOpts.Get(srvflags.EVMBlockExecutor)) == "block-stm" - homePath := cast.ToString(appOpts.Get(flags.FlagHome)) var cacheSize int if !blockSTMEnabled { // only enable memiavl cache if block-stm is not enabled, because it's not concurrency-safe. @@ -399,16 +450,17 @@ func New( invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)) app := &App{ - BaseApp: bApp, - cdc: cdc, - txConfig: txConfig, - appCodec: appCodec, - interfaceRegistry: interfaceRegistry, - invCheckPeriod: invCheckPeriod, - keys: keys, - tkeys: tkeys, - okeys: okeys, - memKeys: memKeys, + BaseApp: bApp, + cdc: cdc, + txConfig: txConfig, + appCodec: appCodec, + interfaceRegistry: interfaceRegistry, + invCheckPeriod: invCheckPeriod, + keys: keys, + tkeys: tkeys, + okeys: okeys, + memKeys: memKeys, + blockProposalHandler: blockProposalHandler, } app.SetDisableBlockGasMeter(true) @@ -449,7 +501,7 @@ func New( runtime.NewKVStoreService(keys[authtypes.StoreKey]), ethermint.ProtoAccount, maccPerms, - authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + addressCodec, sdk.GetConfig().GetBech32AccountAddrPrefix(), authAddr, ) @@ -976,6 +1028,15 @@ func New( tmos.Exit(fmt.Sprintf("versiondb version %d lag behind iavl version %d", v1, v2)) } } + + if err := app.RefreshBlockList(app.NewUncachedContext(false, cmtproto.Header{})); err != nil { + if !cast.ToBool(appOpts.Get(FlagUnsafeIgnoreBlockListFailure)) { + panic(err) + } + + // otherwise, just emit error log + app.Logger().Error("failed to update blocklist", "error", err) + } } app.ScopedIBCKeeper = scopedIBCKeeper @@ -1025,7 +1086,7 @@ func (app *App) setAnteHandler(txConfig client.TxConfig, maxGasWanted uint64, bl return fmt.Errorf("invalid bech32 address: %s, err: %w", str, err) } - blockedMap[string(addr)] = struct{}{} + blockedMap[addr.String()] = struct{}{} } blockAddressDecorator := NewBlockAddressesDecorator(blockedMap) options := evmante.HandlerOptions{ @@ -1085,7 +1146,16 @@ func (app *App) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { // EndBlocker application updates every end block func (app *App) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) { - return app.ModuleManager.EndBlock(ctx) + rsp, err := app.ModuleManager.EndBlock(ctx) + if err := app.RefreshBlockList(ctx); err != nil { + app.Logger().Error("failed to update blocklist", "error", err) + } + return rsp, err +} + +func (app *App) RefreshBlockList(ctx sdk.Context) error { + // refresh blocklist + return app.blockProposalHandler.SetBlockList(app.CronosKeeper.GetBlockList(ctx)) } // InitChainer application update at chain initialization diff --git a/app/block_address.go b/app/block_address.go index 7208cd6d3c..4fc3e4cfd1 100644 --- a/app/block_address.go +++ b/app/block_address.go @@ -26,7 +26,7 @@ func (bad BlockAddressesDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula return ctx, err } for _, signer := range signers { - if _, ok := bad.blockedMap[string(signer)]; ok { + if _, ok := bad.blockedMap[sdk.AccAddress(signer).String()]; ok { return ctx, fmt.Errorf("signer is blocked: %s", sdk.AccAddress(signer).String()) } } diff --git a/app/proposal.go b/app/proposal.go new file mode 100644 index 0000000000..8a755941c5 --- /dev/null +++ b/app/proposal.go @@ -0,0 +1,172 @@ +package app + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + + "filippo.io/age" + + "cosmossdk.io/core/address" + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/signing" +) + +type BlockList struct { + Addresses []string `mapstructure:"addresses"` +} + +var _ baseapp.TxSelector = &ExtTxSelector{} + +// ExtTxSelector extends a baseapp.TxSelector with extra tx validation method +type ExtTxSelector struct { + baseapp.TxSelector + TxDecoder sdk.TxDecoder + ValidateTx func(sdk.Tx) error +} + +func NewExtTxSelector(parent baseapp.TxSelector, txDecoder sdk.TxDecoder, validateTx func(sdk.Tx) error) *ExtTxSelector { + return &ExtTxSelector{ + TxSelector: parent, + TxDecoder: txDecoder, + ValidateTx: validateTx, + } +} + +func (ts *ExtTxSelector) SelectTxForProposal(ctx context.Context, maxTxBytes, maxBlockGas uint64, memTx sdk.Tx, txBz []byte, gasWanted uint64) bool { + var err error + if memTx == nil { + memTx, err = ts.TxDecoder(txBz) + if err != nil { + return false + } + } + + if err := ts.ValidateTx(memTx); err != nil { + return false + } + + // don't pass `memTx` to parent selector so it don't check tx gas wanted against block gas limit, + // it conflicts with the max-tx-gas-wanted logic. + return ts.TxSelector.SelectTxForProposal(ctx, maxTxBytes, maxBlockGas, nil, txBz, gasWanted) +} + +type ProposalHandler struct { + TxDecoder sdk.TxDecoder + // Identity is nil if it's not a validator node + Identity age.Identity + blocklist map[string]struct{} + lastBlockList []byte + addressCodec address.Codec +} + +func NewProposalHandler(txDecoder sdk.TxDecoder, identity age.Identity, addressCodec address.Codec) *ProposalHandler { + return &ProposalHandler{ + TxDecoder: txDecoder, + Identity: identity, + blocklist: make(map[string]struct{}), + addressCodec: addressCodec, + } +} + +// SetBlockList don't fail if the identity is not set or the block list is empty. +func (h *ProposalHandler) SetBlockList(blob []byte) error { + if h.Identity == nil { + return nil + } + + if bytes.Equal(h.lastBlockList, blob) { + return nil + } + h.lastBlockList = make([]byte, len(blob)) + copy(h.lastBlockList, blob) + + if len(blob) == 0 { + h.blocklist = make(map[string]struct{}) + return nil + } + + reader, err := age.Decrypt(bytes.NewBuffer(blob), h.Identity) + if err != nil { + return err + } + + data, err := io.ReadAll(reader) + if err != nil { + return err + } + + var blocklist BlockList + if err := json.Unmarshal(data, &blocklist); err != nil { + return err + } + + // convert to map + m := make(map[string]struct{}, len(blocklist.Addresses)) + for _, s := range blocklist.Addresses { + addr, err := h.addressCodec.StringToBytes(s) + if err != nil { + return fmt.Errorf("invalid bech32 address: %s, err: %w", s, err) + } + encoded, err := h.addressCodec.BytesToString(addr) + if err != nil { + return fmt.Errorf("invalid bech32 address: %s, err: %w", s, err) + } + m[encoded] = struct{}{} + } + + h.blocklist = m + return nil +} + +func (h *ProposalHandler) ValidateTransaction(tx sdk.Tx) error { + sigTx, ok := tx.(signing.SigVerifiableTx) + if !ok { + return fmt.Errorf("tx of type %T does not implement SigVerifiableTx", tx) + } + + signers, err := sigTx.GetSigners() + if err != nil { + return err + } + for _, signer := range signers { + encoded, err := h.addressCodec.BytesToString(signer) + if err != nil { + return fmt.Errorf("invalid bech32 address: %s, err: %w", signer, err) + } + if _, ok := h.blocklist[encoded]; ok { + return fmt.Errorf("signer is blocked: %s", encoded) + } + } + return nil +} + +func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler { + return func(ctx sdk.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { + for _, txBz := range req.Txs { + memTx, err := h.TxDecoder(txBz) + if err != nil { + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil + } + + if err := h.ValidateTransaction(memTx); err != nil { + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil + } + } + + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil + } +} + +// noneIdentity is a dummy identity which postpone the failure to the decryption time +type noneIdentity struct{} + +var _ age.Identity = noneIdentity{} + +func (noneIdentity) Unwrap([]*age.Stanza) ([]byte, error) { + return nil, age.ErrIncorrectIdentity +} diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index ceb1f05701..5160e9cea5 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -4,6 +4,216 @@ info: description: A REST interface for state queries version: 1.0.0 paths: + /cronos/v1/blocklist: + get: + summary: BlockList + operationId: BlockList + responses: + '200': + description: A successful response. + schema: + type: object + properties: + blob: + type: string + format: byte + title: QueryBlockListResponse + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at + least + + one "/" character. The last segment of the URL's path + must represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in + a canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary + all types that they + + expect it to use in the context of Any. However, for + URLs which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in + the official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer + message along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values + in the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := anypb.New(foo) + if err != nil { + ... + } + ... + foo := &pb.Foo{} + if err := any.UnmarshalTo(foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by + default use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the + last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + JSON + + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with + an + + additional field `@type` which contains the type URL. + Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding + a field + + `value` which holds the custom JSON in addition to the + `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + tags: + - Query /cronos/v1/contract_by_denom: get: summary: >- @@ -44682,6 +44892,13 @@ definitions: type: string format: uint64 description: Params defines the parameters for the cronos module. + cronos.QueryBlockListResponse: + type: object + properties: + blob: + type: string + format: byte + title: QueryBlockListResponse cronos.QueryParamsResponse: type: object properties: diff --git a/go.mod b/go.mod index bf9e4f453c..ccae11b4d9 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,6 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - github.com/test-go/testify v1.1.4 golang.org/x/crypto v0.27.0 google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 google.golang.org/grpc v1.66.1 diff --git a/gomod2nix.toml b/gomod2nix.toml index 4cd1e69bfb..f8d0f20ce7 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -585,9 +585,6 @@ schema = 3 [mod."github.com/tendermint/go-amino"] version = "v0.16.0" hash = "sha256-JW4zO/0vMzf1dXLePOqaMtiLUZgNbuIseh9GV+jQlf0=" - [mod."github.com/test-go/testify"] - version = "v1.1.4" - hash = "sha256-8xygO1Rd4eTrmRe/g7zaifpNkeb6EmjNfUvTWbjDtPg=" [mod."github.com/tidwall/btree"] version = "v0.0.0-20240406140148-2687063b042c" hash = "sha256-8eDLGHhw4qXG6MEa7w5Q9KLwOobXr8Vn5qqyQhuipQw=" diff --git a/integration_tests/configs/broken-cronosd.patch b/integration_tests/configs/broken-cronosd.patch index 4935f14260..1169bdebd6 100644 --- a/integration_tests/configs/broken-cronosd.patch +++ b/integration_tests/configs/broken-cronosd.patch @@ -1,8 +1,8 @@ diff --git a/app/app.go b/app/app.go -index c5190b3..1aaa765 100644 +index 6e9d3a80..83b83274 100644 --- a/app/app.go +++ b/app/app.go -@@ -1057,6 +1057,11 @@ func (app *App) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { +@@ -1144,6 +1144,10 @@ func (app *App) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { // EndBlocker application updates every end block func (app *App) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) { @@ -10,7 +10,6 @@ index c5190b3..1aaa765 100644 + store := ctx.KVStore(app.keys["cronos"]) + store.Set([]byte("hello"), []byte("world")) + } -+ - return app.ModuleManager.EndBlock(ctx) - } - + rsp, err := app.ModuleManager.EndBlock(ctx) + if err := app.RefreshBlockList(ctx); err != nil { + app.Logger().Error("failed to update blocklist", "error", err) diff --git a/integration_tests/cosmoscli.py b/integration_tests/cosmoscli.py index 4817e33d50..8d4ad25f1c 100644 --- a/integration_tests/cosmoscli.py +++ b/integration_tests/cosmoscli.py @@ -247,6 +247,18 @@ def tx_search_rpc(self, criteria: str, order=None): assert "error" not in rsp, rsp["error"] return rsp["result"]["txs"] + def query_account(self, addr, **kwargs): + return json.loads( + self.raw( + "query", + "auth", + "account", + addr, + home=self.data_dir, + **kwargs, + ) + ) + def distribution_commission(self, addr): coin = json.loads( self.raw( @@ -353,7 +365,16 @@ def staking_pool(self, bonded=True): res = res.get("pool") or res return int(res["bonded_tokens" if bonded else "not_bonded_tokens"]) - def transfer(self, from_, to, coins, generate_only=False, fees=None, **kwargs): + def transfer( + self, + from_, + to, + coins, + generate_only=False, + event_query_tx=True, + fees=None, + **kwargs, + ): kwargs.setdefault("gas_prices", DEFAULT_GAS_PRICE) rsp = json.loads( self.raw( @@ -370,7 +391,7 @@ def transfer(self, from_, to, coins, generate_only=False, fees=None, **kwargs): **kwargs, ) ) - if rsp["code"] == 0: + if rsp["code"] == 0 and event_query_tx: rsp = self.event_query_tx_for(rsp["txhash"]) return rsp @@ -1699,6 +1720,24 @@ def update_permissions(self, address, permissions, **kwargs): rsp = self.event_query_tx_for(rsp["txhash"]) return rsp + def store_blocklist(self, data, **kwargs): + kwargs.setdefault("gas_prices", DEFAULT_GAS_PRICE) + kwargs.setdefault("gas", DEFAULT_GAS) + rsp = json.loads( + self.raw( + "tx", + "cronos", + "store-block-list", + data, + "-y", + home=self.data_dir, + **kwargs, + ) + ) + if rsp["code"] == 0: + rsp = self.event_query_tx_for(rsp["txhash"]) + return rsp + def rollback(self): self.raw("rollback", home=self.data_dir) @@ -1807,7 +1846,6 @@ def event_query_tx_for(self, hash): "event-query-tx-for", hash, home=self.data_dir, - stderr=subprocess.DEVNULL, ) ) @@ -1865,10 +1903,13 @@ def register_e2ee_key(self, key, **kwargs): rsp = self.event_query_tx_for(rsp["txhash"]) return rsp - def keygen(self, **kwargs): + def e2ee_keygen(self, **kwargs): return self.raw("e2ee", "keygen", home=self.data_dir, **kwargs).strip().decode() - def encrypt(self, input, *recipients, **kwargs): + def e2ee_pubkey(self, **kwargs): + return self.raw("e2ee", "pubkey", home=self.data_dir, **kwargs).strip().decode() + + def e2ee_encrypt(self, input, *recipients, **kwargs): return ( self.raw( "e2ee", @@ -1882,7 +1923,7 @@ def encrypt(self, input, *recipients, **kwargs): .decode() ) - def decrypt(self, input, identity="e2ee-identity", **kwargs): + def e2ee_decrypt(self, input, identity="e2ee-identity", **kwargs): return ( self.raw( "e2ee", @@ -1895,3 +1936,16 @@ def decrypt(self, input, identity="e2ee-identity", **kwargs): .strip() .decode() ) + + def e2ee_encrypt_to_validators(self, input, **kwargs): + return ( + self.raw( + "e2ee", + "encrypt-to-validators", + input, + home=self.data_dir, + **kwargs, + ) + .strip() + .decode() + ) diff --git a/integration_tests/test_e2ee.py b/integration_tests/test_e2ee.py index 1912ccc77d..93ed7e61cc 100644 --- a/integration_tests/test_e2ee.py +++ b/integration_tests/test_e2ee.py @@ -1,40 +1,152 @@ -def test_register(cronos): +import json + +import pytest +from eth_utils import to_checksum_address +from hexbytes import HexBytes +from pystarport import ports + +from .network import Cronos +from .utils import ADDRS, bech32_to_eth, wait_for_new_blocks, wait_for_port + + +def test_register(cronos: Cronos): cli = cronos.cosmos_cli() - pubkey0 = cli.keygen(keyring_name="key0") - rsp = cli.register_e2ee_key(pubkey0 + "malformed", _from="validator") - assert rsp["code"] != 0 - assert "malformed recipient" in rsp["raw_log"] + pubkey0 = cli.e2ee_keygen(keyring_name="key0") + with pytest.raises(AssertionError) as exc: + cli.register_e2ee_key(pubkey0 + "malformed", _from="validator") + assert "malformed recipient" in str(exc.value) assert not cli.query_e2ee_key(cli.address("validator")) +def gen_validator_identity(cronos: Cronos): + for i in range(len(cronos.config["validators"])): + cli = cronos.cosmos_cli(i) + if cli.query_e2ee_key(cli.address("validator")): + return + pubkey = cli.e2ee_keygen() + assert cli.e2ee_pubkey() == pubkey + cli.register_e2ee_key(pubkey, _from="validator") + assert cli.query_e2ee_key(cli.address("validator")) == pubkey + + cronos.supervisorctl("restart", f"cronos_777-1-node{i}") + + wait_for_new_blocks(cronos.cosmos_cli(), 1) + + def test_encrypt_decrypt(cronos): - cli = cronos.cosmos_cli() + gen_validator_identity(cronos) - # gen two keys for two accounts - pubkey0 = cli.keygen(keyring_name="key0") - cli.register_e2ee_key(pubkey0, _from="validator") - assert cli.query_e2ee_key(cli.address("validator")) == pubkey0 - pubkey1 = cli.keygen(keyring_name="key1") - cli.register_e2ee_key(pubkey1, _from="community") + cli0 = cronos.cosmos_cli() + cli1 = cronos.cosmos_cli(1) # query in batch - assert cli.query_e2ee_keys(cli.address("validator"), cli.address("community")) == [ - pubkey0, - pubkey1, - ] + assert ( + len( + cli0.query_e2ee_keys( + cli0.address("validator"), + cli1.address("validator"), + ) + ) + == 2 + ) # prepare data file to encrypt content = "Hello World!" - plainfile = cli.data_dir / "plaintext" + plainfile = cli0.data_dir / "plaintext" plainfile.write_text(content) - - cipherfile = cli.data_dir / "ciphertext" - cli.encrypt( + cipherfile = cli0.data_dir / "ciphertext" + cli0.e2ee_encrypt( plainfile, - cli.address("validator"), - cli.address("community"), + cli0.address("validator"), + cli1.address("validator"), output=cipherfile, ) - assert cli.decrypt(cipherfile, identity="key0") == content - assert cli.decrypt(cipherfile, identity="key1") == content + assert cli0.e2ee_decrypt(cipherfile) == content + assert cli1.e2ee_decrypt(cipherfile) == content + + +def encrypt_to_validators(cli, content): + blocklist = json.dumps(content) + plainfile = cli.data_dir / "plaintext" + plainfile.write_text(blocklist) + cipherfile = cli.data_dir / "ciphertext" + cli.e2ee_encrypt_to_validators(plainfile, output=cipherfile) + rsp = cli.store_blocklist(cipherfile, _from="validator") + assert rsp["code"] == 0, rsp["raw_log"] + + +def get_nonce(cli, user): + acc = cli.query_account(user)["account"]["value"] + return int(acc.get("sequence", 0)) + + +def test_block_list(cronos): + gen_validator_identity(cronos) + cli = cronos.cosmos_cli() + user = cli.address("signer2") + # set blocklist + encrypt_to_validators(cli, {"addresses": [user]}) + + # normal tx works + cli.transfer(cli.address("validator"), user, "1basetcro") + + # blocked tx can be included into mempool + rsp = cli.transfer( + user, cli.address("validator"), "1basetcro", event_query_tx=False + ) + assert rsp["code"] == 0, rsp["raw_log"] + + # but won't be included into block + txhash = rsp["txhash"] + with pytest.raises(AssertionError) as exc: + cli.event_query_tx_for(txhash) + assert "timed out waiting" in str(exc.value) + nonce = get_nonce(cli, user) + + # clear blocklist + encrypt_to_validators(cli, {}) + + # the blocked tx should be unblocked now + wait_for_new_blocks(cli, 1) + assert nonce + 1 == get_nonce(cli, user) + + +def test_block_list_evm(cronos): + gen_validator_identity(cronos) + cli = cronos.cosmos_cli() + user = cli.address("signer2") + # set blocklist + encrypt_to_validators(cli, {"addresses": [user]}) + tx = { + "from": to_checksum_address(bech32_to_eth(user)), + "to": ADDRS["community"], + "value": 1, + } + base_port = cronos.base_port(0) + wait_for_port(ports.evmrpc_ws_port(base_port)) + w3 = cronos.w3 + flt = w3.eth.filter("pending") + assert flt.get_new_entries() == [] + + txhash = w3.eth.send_transaction(tx).hex() + nonce = get_nonce(cli, user) + # check tx in mempool + assert HexBytes(txhash) in w3.eth.get_filter_changes(flt.filter_id) + + # clear blocklist + encrypt_to_validators(cli, {}) + + # the blocked tx should be unblocked now + wait_for_new_blocks(cli, 1) + assert nonce + 1 == get_nonce(cli, user) + assert w3.eth.get_filter_changes(flt.filter_id) == [] + + +def test_invalid_block_list(cronos): + cli = cronos.cosmos_cli() + cipherfile = cli.data_dir / "ciphertext" + cipherfile.write_text("{}") + with pytest.raises(AssertionError) as exc: + cli.store_blocklist(cipherfile, _from="validator") + assert "failed to read header" in str(exc.value) diff --git a/proto/cronos/query.proto b/proto/cronos/query.proto index 00127962b8..cfe8bd7f30 100644 --- a/proto/cronos/query.proto +++ b/proto/cronos/query.proto @@ -36,6 +36,11 @@ service Query { option (google.api.http).get = "/cronos/v1/permissions"; } + // BlockList + rpc BlockList(QueryBlockListRequest) returns (QueryBlockListResponse) { + option (google.api.http).get = "/cronos/v1/blocklist"; + } + // this line is used by starport scaffolding # 2 } @@ -105,4 +110,10 @@ message QueryPermissionsResponse { bool can_turn_bridge = 2; } -// this line is used by starport scaffolding # 3 +// QueryBlockListRequest +message QueryBlockListRequest { } + +// QueryBlockListResponse +message QueryBlockListResponse { + bytes blob = 1; +} diff --git a/proto/cronos/tx.proto b/proto/cronos/tx.proto index ed9863a978..6484d93f03 100644 --- a/proto/cronos/tx.proto +++ b/proto/cronos/tx.proto @@ -34,6 +34,9 @@ service Msg { // UpdatePermissions defines a method to update cronos admins permissions rpc UpdatePermissions(MsgUpdatePermissions) returns (MsgUpdatePermissionsResponse); + + // StoreBlockList + rpc StoreBlockList(MsgStoreBlockList) returns (MsgStoreBlockListResponse); } // MsgConvertVouchers represents a message to convert ibc voucher coins to @@ -110,4 +113,13 @@ message MsgUpdatePermissions { // MsgUpdatePermissionsResponse defines the response type. message MsgUpdatePermissionsResponse {} -// this line is used by starport scaffolding # proto/tx/message +// MsgStoreBlockList +message MsgStoreBlockList { + option (cosmos.msg.v1.signer) = "from"; + string from = 1; + bytes blob = 2; +} + +// MsgStoreBlockListResponse +message MsgStoreBlockListResponse { +} diff --git a/x/cronos/client/cli/tx.go b/x/cronos/client/cli/tx.go index 8d4c1e1b96..7ccfc82b4e 100644 --- a/x/cronos/client/cli/tx.go +++ b/x/cronos/client/cli/tx.go @@ -3,6 +3,8 @@ package cli import ( "encoding/json" "fmt" + "io" + "os" "strconv" "strings" @@ -44,6 +46,7 @@ func GetTxCmd() *cobra.Command { cmd.AddCommand(CmdUpdateTokenMapping()) cmd.AddCommand(CmdTurnBridge()) cmd.AddCommand(CmdUpdatePermissions()) + cmd.AddCommand(CmdStoreBlockList()) cmd.AddCommand(MigrateGenesisCmd()) return cmd } @@ -317,6 +320,43 @@ func CmdUpdatePermissions() *cobra.Command { return cmd } +// CmdStoreBlockList returns a CLI command handler for updating cronos permissions +func CmdStoreBlockList() *cobra.Command { + cmd := &cobra.Command{ + Use: "store-block-list [encrypted-block-list-file]", + Short: "Store encrypted block list", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + fp, err := os.Open(args[0]) + if err != nil { + return err + } + defer fp.Close() + + // Read the file + blob, err := io.ReadAll(fp) + if err != nil { + return err + } + + msg := types.NewMsgStoreBlockList(clientCtx.GetFromAddress().String(), blob) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + type ExportEvmGenesisState struct { evmtypes.GenesisState Params ExportEvmParams `json:"params"` diff --git a/x/cronos/keeper/grpc_query.go b/x/cronos/keeper/grpc_query.go index 7bc1568154..f8381025e5 100644 --- a/x/cronos/keeper/grpc_query.go +++ b/x/cronos/keeper/grpc_query.go @@ -142,3 +142,11 @@ func (k Keeper) Permissions(goCtx context.Context, req *types.QueryPermissionsRe CanTurnBridge: CanTurnBridge == (permissions & CanTurnBridge), }, nil } + +func (k Keeper) BlockList(goCtx context.Context, req *types.QueryBlockListRequest) (*types.QueryBlockListResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + blob := ctx.KVStore(k.storeKey).Get(types.KeyPrefixBlockList) + return &types.QueryBlockListResponse{ + Blob: blob, + }, nil +} diff --git a/x/cronos/keeper/keeper.go b/x/cronos/keeper/keeper.go index 1f7d84b593..0a53d1d2d2 100644 --- a/x/cronos/keeper/keeper.go +++ b/x/cronos/keeper/keeper.go @@ -355,3 +355,7 @@ func (k Keeper) IBCSendPacketCallback( ) error { return nil } + +func (k Keeper) GetBlockList(ctx sdk.Context) []byte { + return ctx.KVStore(k.storeKey).Get(types.KeyPrefixBlockList) +} diff --git a/x/cronos/keeper/msg_server.go b/x/cronos/keeper/msg_server.go index 00d9f605b7..070c9fd651 100644 --- a/x/cronos/keeper/msg_server.go +++ b/x/cronos/keeper/msg_server.go @@ -112,3 +112,13 @@ func (k msgServer) UpdatePermissions(goCtx context.Context, msg *types.MsgUpdate return &types.MsgUpdatePermissionsResponse{}, nil } + +func (k msgServer) StoreBlockList(goCtx context.Context, msg *types.MsgStoreBlockList) (*types.MsgStoreBlockListResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + admin := k.Keeper.GetParams(ctx).CronosAdmin + if admin != msg.From { + return nil, errors.Wrap(sdkerrors.ErrUnauthorized, "msg sender is not authorized") + } + ctx.KVStore(k.storeKey).Set(types.KeyPrefixBlockList, msg.Blob) + return &types.MsgStoreBlockListResponse{}, nil +} diff --git a/x/cronos/types/keys.go b/x/cronos/types/keys.go index 91a8b6b2e6..bf5da7a4c2 100644 --- a/x/cronos/types/keys.go +++ b/x/cronos/types/keys.go @@ -27,6 +27,7 @@ const ( prefixContractToDenom paramsKey prefixAdminToPermissions + prefixBlockList ) // KVStore key prefixes @@ -37,6 +38,7 @@ var ( // ParamsKey is the key for params. ParamsKey = []byte{paramsKey} KeyPrefixAdminToPermissions = []byte{prefixAdminToPermissions} + KeyPrefixBlockList = []byte{prefixBlockList} ) // this line is used by starport scaffolding # ibc/keys/port diff --git a/x/cronos/types/messages.go b/x/cronos/types/messages.go index d7a63da759..a0064f748a 100644 --- a/x/cronos/types/messages.go +++ b/x/cronos/types/messages.go @@ -1,7 +1,12 @@ package types import ( + "bytes" + + stderrors "errors" + "cosmossdk.io/errors" + "filippo.io/age" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/ethereum/go-ethereum/common" @@ -14,6 +19,7 @@ const ( TypeMsgUpdateParams = "UpdateParams" TypeMsgTurnBridge = "TurnBridge" TypeMsgUpdatePermissions = "UpdatePermissions" + TypeMsgStoreBlockList = "StoreBlockList" ) var ( @@ -23,6 +29,7 @@ var ( _ sdk.Msg = &MsgUpdateParams{} _ sdk.Msg = &MsgTurnBridge{} _ sdk.Msg = &MsgUpdatePermissions{} + _ sdk.Msg = &MsgStoreBlockList{} ) func NewMsgConvertVouchers(address string, coins sdk.Coins) *MsgConvertVouchers { @@ -318,3 +325,56 @@ func (msg *MsgUpdatePermissions) GetSignBytes() []byte { bz := ModuleCdc.MustMarshalJSON(msg) return sdk.MustSortJSON(bz) } + +func NewMsgStoreBlockList(from string, blob []byte) *MsgStoreBlockList { + return &MsgStoreBlockList{ + From: from, + Blob: blob, + } +} + +var errDummyIdentity = stderrors.New("dummy") + +type dummyIdentity struct{} + +func (i *dummyIdentity) Unwrap(stanzas []*age.Stanza) ([]byte, error) { + return nil, errDummyIdentity +} + +func (msg *MsgStoreBlockList) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.From) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid sender address (%s)", err) + } + + _, err = age.Decrypt(bytes.NewBuffer(msg.Blob), new(dummyIdentity)) + if err != nil && err != errDummyIdentity { + return err + } + return nil +} + +func (msg *MsgStoreBlockList) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(msg.From) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{addr} +} + +// GetSignBytes ... +func (msg *MsgStoreBlockList) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +// Route ... +func (msg MsgStoreBlockList) Route() string { + return RouterKey +} + +// Type ... +func (msg MsgStoreBlockList) Type() string { + return TypeMsgStoreBlockList +} diff --git a/x/cronos/types/query.pb.go b/x/cronos/types/query.pb.go index 569ff486c8..92d67d9067 100644 --- a/x/cronos/types/query.pb.go +++ b/x/cronos/types/query.pb.go @@ -478,6 +478,88 @@ func (m *QueryPermissionsResponse) GetCanTurnBridge() bool { return false } +// QueryBlockListRequest +type QueryBlockListRequest struct { +} + +func (m *QueryBlockListRequest) Reset() { *m = QueryBlockListRequest{} } +func (m *QueryBlockListRequest) String() string { return proto.CompactTextString(m) } +func (*QueryBlockListRequest) ProtoMessage() {} +func (*QueryBlockListRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d4ed0fd688c48372, []int{10} +} +func (m *QueryBlockListRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryBlockListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryBlockListRequest.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 *QueryBlockListRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryBlockListRequest.Merge(m, src) +} +func (m *QueryBlockListRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryBlockListRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryBlockListRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryBlockListRequest proto.InternalMessageInfo + +// QueryBlockListResponse +type QueryBlockListResponse struct { + Blob []byte `protobuf:"bytes,1,opt,name=blob,proto3" json:"blob,omitempty"` +} + +func (m *QueryBlockListResponse) Reset() { *m = QueryBlockListResponse{} } +func (m *QueryBlockListResponse) String() string { return proto.CompactTextString(m) } +func (*QueryBlockListResponse) ProtoMessage() {} +func (*QueryBlockListResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d4ed0fd688c48372, []int{11} +} +func (m *QueryBlockListResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryBlockListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryBlockListResponse.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 *QueryBlockListResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryBlockListResponse.Merge(m, src) +} +func (m *QueryBlockListResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryBlockListResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryBlockListResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryBlockListResponse proto.InternalMessageInfo + +func (m *QueryBlockListResponse) GetBlob() []byte { + if m != nil { + return m.Blob + } + return nil +} + func init() { proto.RegisterType((*ContractByDenomRequest)(nil), "cronos.ContractByDenomRequest") proto.RegisterType((*ContractByDenomResponse)(nil), "cronos.ContractByDenomResponse") @@ -489,61 +571,67 @@ func init() { proto.RegisterType((*QueryParamsResponse)(nil), "cronos.QueryParamsResponse") proto.RegisterType((*QueryPermissionsRequest)(nil), "cronos.QueryPermissionsRequest") proto.RegisterType((*QueryPermissionsResponse)(nil), "cronos.QueryPermissionsResponse") + proto.RegisterType((*QueryBlockListRequest)(nil), "cronos.QueryBlockListRequest") + proto.RegisterType((*QueryBlockListResponse)(nil), "cronos.QueryBlockListResponse") } func init() { proto.RegisterFile("cronos/query.proto", fileDescriptor_d4ed0fd688c48372) } var fileDescriptor_d4ed0fd688c48372 = []byte{ - // 773 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0x41, 0x4f, 0xe3, 0x46, - 0x14, 0x8e, 0x21, 0xa4, 0x61, 0x02, 0x45, 0x9d, 0x50, 0x30, 0x2e, 0xb5, 0x53, 0xb7, 0x2a, 0x54, - 0x2a, 0xb6, 0x08, 0x95, 0x5a, 0xf5, 0xd0, 0x43, 0x52, 0x24, 0x2e, 0xa0, 0xd6, 0xca, 0x09, 0x21, - 0x59, 0x13, 0x67, 0xea, 0x58, 0xe0, 0x19, 0xe3, 0x19, 0x47, 0x89, 0x50, 0x2f, 0xed, 0xa5, 0x47, - 0xa4, 0xfe, 0x01, 0xfa, 0x6f, 0x38, 0x22, 0xf5, 0xb2, 0xda, 0xc3, 0xee, 0x0a, 0xf6, 0xb0, 0x3f, - 0x63, 0xe5, 0xf1, 0x4c, 0x12, 0x48, 0xd8, 0x3d, 0xc5, 0xf3, 0x7d, 0x6f, 0xde, 0xf7, 0xde, 0xbc, - 0xef, 0x05, 0xc0, 0x20, 0xa5, 0x84, 0x32, 0xf7, 0x32, 0xc3, 0xe9, 0xc8, 0x49, 0x52, 0xca, 0x29, - 0xac, 0x14, 0x98, 0xb1, 0x1e, 0xd2, 0x90, 0x0a, 0xc8, 0xcd, 0xbf, 0x0a, 0xd6, 0xd8, 0x0e, 0x29, - 0x0d, 0x2f, 0xb0, 0x8b, 0x92, 0xc8, 0x45, 0x84, 0x50, 0x8e, 0x78, 0x44, 0x09, 0x93, 0xac, 0x25, - 0x59, 0x71, 0xea, 0x66, 0x7f, 0xb8, 0x3c, 0x8a, 0x31, 0xe3, 0x28, 0x4e, 0x64, 0xc0, 0x16, 0xe6, - 0x7d, 0x9c, 0xc6, 0x11, 0xe1, 0x2e, 0x1e, 0xc4, 0xee, 0x60, 0xdf, 0xe5, 0x43, 0x49, 0xd5, 0x65, - 0x2d, 0xc5, 0x4f, 0x01, 0xda, 0x3f, 0x81, 0x8d, 0x36, 0x25, 0x3c, 0x45, 0x01, 0x6f, 0x8d, 0x7e, - 0xc5, 0x84, 0xc6, 0x1e, 0xbe, 0xcc, 0x30, 0xe3, 0x70, 0x1d, 0x2c, 0xf5, 0xf2, 0xb3, 0xae, 0x35, - 0xb4, 0xdd, 0x65, 0xaf, 0x38, 0xfc, 0x5c, 0xfd, 0xe7, 0xc6, 0x2a, 0xbd, 0xbb, 0xb1, 0x4a, 0xf6, - 0x29, 0xd8, 0x9c, 0xb9, 0xc9, 0x12, 0x4a, 0x18, 0x86, 0x06, 0xa8, 0x06, 0x92, 0x92, 0xb7, 0xc7, - 0x67, 0xf8, 0x35, 0x58, 0x45, 0x19, 0xa7, 0xfe, 0x38, 0x60, 0x41, 0x04, 0xac, 0xe4, 0xa0, 0xca, - 0x67, 0xff, 0x02, 0x36, 0x44, 0xc6, 0xd6, 0x48, 0x41, 0xaa, 0xaa, 0x0f, 0xa4, 0x9e, 0xaa, 0xcd, - 0x05, 0x9b, 0x33, 0xf7, 0x65, 0x6d, 0x73, 0xdb, 0xb2, 0x5f, 0x6a, 0x00, 0x7a, 0x38, 0xb9, 0x40, - 0xa3, 0xd6, 0x05, 0x0d, 0xce, 0x95, 0xda, 0x01, 0x28, 0xc7, 0x2c, 0x64, 0xba, 0xd6, 0x58, 0xdc, - 0xad, 0x35, 0x2d, 0x67, 0xfc, 0xb8, 0x0e, 0x1e, 0xc4, 0xce, 0x60, 0xdf, 0x39, 0x66, 0xe1, 0x61, - 0x8e, 0xe1, 0x2c, 0xee, 0x0c, 0x3d, 0x11, 0x0c, 0xbf, 0x02, 0x2b, 0xdd, 0x3c, 0x89, 0x4f, 0xb2, - 0xb8, 0x8b, 0x53, 0xd1, 0xe0, 0xa2, 0x57, 0x13, 0xd8, 0x89, 0x80, 0xe0, 0x97, 0x00, 0x14, 0x21, - 0x7d, 0xc4, 0xfa, 0xfa, 0xa2, 0xa8, 0x64, 0x59, 0x20, 0x47, 0x88, 0xf5, 0x61, 0x5b, 0xd1, 0xf9, - 0x74, 0xf5, 0x72, 0x43, 0xdb, 0xad, 0x35, 0x0d, 0xa7, 0x18, 0xbd, 0xa3, 0x46, 0xef, 0x74, 0xd4, - 0xe8, 0x5b, 0xd5, 0xdb, 0x57, 0x56, 0xe9, 0xfa, 0xb5, 0xa5, 0xc9, 0x24, 0x39, 0x33, 0xf5, 0x1a, - 0x67, 0xa0, 0xfe, 0xa8, 0x37, 0xf9, 0x12, 0x87, 0x60, 0x39, 0x95, 0xdf, 0xaa, 0xc3, 0x9d, 0x8f, - 0x75, 0x28, 0xe3, 0xbd, 0xc9, 0x4d, 0x7b, 0x1d, 0xc0, 0xdf, 0x73, 0x77, 0xff, 0x86, 0x52, 0x14, - 0x33, 0xf9, 0x72, 0x76, 0x1b, 0xd4, 0x1f, 0xa1, 0x52, 0xf3, 0x7b, 0x50, 0x49, 0x04, 0x22, 0x9e, - 0xbf, 0xd6, 0xfc, 0xd4, 0x91, 0x6e, 0x2c, 0xe2, 0x5a, 0xe5, 0xbc, 0x13, 0x4f, 0xc6, 0xd8, 0x07, - 0x60, 0xb3, 0x48, 0x92, 0x97, 0xc4, 0x58, 0xbe, 0x07, 0x6a, 0x32, 0x3a, 0xf8, 0x04, 0xf5, 0x7a, - 0x29, 0x66, 0x4c, 0x0e, 0x52, 0x1d, 0xed, 0x2b, 0xa0, 0xcf, 0x5e, 0x92, 0xf2, 0x3f, 0x02, 0x3d, - 0x40, 0xc4, 0x0f, 0xfa, 0x88, 0x84, 0xd8, 0xe7, 0xf4, 0x1c, 0x13, 0x3f, 0x46, 0x49, 0x12, 0x91, - 0x50, 0xa4, 0xa9, 0x7a, 0x9f, 0x07, 0x88, 0xb4, 0x05, 0xdd, 0xc9, 0xd9, 0xe3, 0x82, 0x84, 0xdf, - 0x82, 0xb5, 0xfc, 0x22, 0xcf, 0x52, 0xe2, 0x77, 0xd3, 0xa8, 0x17, 0x62, 0x31, 0xd6, 0xaa, 0xb7, - 0x1a, 0x20, 0xd2, 0xc9, 0x52, 0xd2, 0x12, 0x60, 0xf3, 0xbf, 0x32, 0x58, 0x12, 0xea, 0x70, 0x08, - 0xd6, 0x9e, 0xac, 0x07, 0x34, 0x55, 0xb3, 0xf3, 0x37, 0xce, 0xb0, 0x9e, 0xe5, 0x8b, 0xf2, 0xed, - 0x6f, 0xfe, 0xfa, 0xff, 0xed, 0xbf, 0x0b, 0x26, 0xdc, 0x96, 0x3b, 0x9c, 0xaf, 0xb7, 0x72, 0xbf, - 0xdf, 0x1d, 0xf9, 0xc2, 0xcb, 0xf0, 0x6f, 0x0d, 0xac, 0x3d, 0x71, 0xff, 0x44, 0x7a, 0xfe, 0x5a, - 0x4d, 0xa4, 0x9f, 0x59, 0x1b, 0xdb, 0x15, 0xd2, 0xdf, 0xc1, 0x9d, 0x29, 0x69, 0x21, 0x97, 0xeb, - 0xaa, 0x1a, 0xdc, 0x2b, 0xf5, 0xf5, 0x27, 0x3c, 0x02, 0xb5, 0x29, 0xd3, 0x41, 0x43, 0x09, 0xcc, - 0x6e, 0x99, 0xf1, 0xc5, 0x5c, 0x4e, 0x0a, 0x97, 0xe0, 0x19, 0xa8, 0x14, 0xee, 0x98, 0x24, 0x99, - 0x35, 0xdc, 0x24, 0xc9, 0x1c, 0xdb, 0xd9, 0x5b, 0xa2, 0xfa, 0x3a, 0xfc, 0x6c, 0xaa, 0xfa, 0xc2, - 0x63, 0x30, 0x01, 0xb5, 0x29, 0xa7, 0x40, 0xeb, 0x71, 0x9a, 0x19, 0xe3, 0x19, 0x8d, 0xe7, 0x03, - 0xa4, 0x98, 0x29, 0xc4, 0x74, 0xb8, 0x31, 0x2d, 0x36, 0x89, 0x6b, 0x9d, 0xdc, 0xde, 0x9b, 0xda, - 0xdd, 0xbd, 0xa9, 0xbd, 0xb9, 0x37, 0xb5, 0xeb, 0x07, 0xb3, 0x74, 0xf7, 0x60, 0x96, 0x5e, 0x3c, - 0x98, 0xa5, 0xd3, 0x1f, 0xc2, 0x88, 0xf7, 0xb3, 0xae, 0x13, 0xd0, 0xd8, 0x0d, 0xd2, 0x51, 0xc2, - 0xe9, 0x1e, 0x4d, 0xc3, 0xbd, 0xa0, 0x8f, 0x22, 0x32, 0x4e, 0xd6, 0x74, 0x87, 0xea, 0x9b, 0x8f, - 0x12, 0xcc, 0xba, 0x15, 0xf1, 0x8f, 0x70, 0xf0, 0x3e, 0x00, 0x00, 0xff, 0xff, 0x40, 0x82, 0x6e, - 0xe3, 0x6c, 0x06, 0x00, 0x00, + // 834 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0x4f, 0x6f, 0xdc, 0x44, + 0x14, 0x5f, 0x37, 0x7f, 0xd8, 0xbc, 0x4d, 0x89, 0x98, 0xa4, 0x1b, 0xd7, 0xa4, 0x76, 0x30, 0x88, + 0x06, 0xa9, 0xb5, 0xd5, 0x0d, 0x12, 0x88, 0x03, 0x87, 0x0d, 0x95, 0x7a, 0xa0, 0x15, 0x58, 0x39, + 0x55, 0x95, 0xac, 0xb1, 0x33, 0xd8, 0x56, 0xd7, 0x33, 0xae, 0x67, 0x1c, 0xed, 0xaa, 0xe2, 0x02, + 0x17, 0x24, 0x2e, 0x95, 0xf8, 0x02, 0xfd, 0x38, 0x3d, 0x56, 0xe2, 0x82, 0x38, 0x00, 0x4a, 0x38, + 0xf0, 0x31, 0x90, 0xc7, 0x33, 0xbb, 0xde, 0x7f, 0x70, 0xf2, 0xcc, 0xfb, 0xbd, 0x79, 0xbf, 0xf7, + 0xe7, 0xf7, 0x0c, 0x28, 0x2e, 0x19, 0x65, 0xdc, 0x7f, 0x51, 0x91, 0x72, 0xe2, 0x15, 0x25, 0x13, + 0x0c, 0x6d, 0x37, 0x36, 0xeb, 0x20, 0x61, 0x09, 0x93, 0x26, 0xbf, 0x3e, 0x35, 0xa8, 0x75, 0x94, + 0x30, 0x96, 0x8c, 0x88, 0x8f, 0x8b, 0xcc, 0xc7, 0x94, 0x32, 0x81, 0x45, 0xc6, 0x28, 0x57, 0xa8, + 0xa3, 0x50, 0x79, 0x8b, 0xaa, 0xef, 0x7c, 0x91, 0xe5, 0x84, 0x0b, 0x9c, 0x17, 0xca, 0xe1, 0x36, + 0x11, 0x29, 0x29, 0xf3, 0x8c, 0x0a, 0x9f, 0x5c, 0xe6, 0xfe, 0xe5, 0x03, 0x5f, 0x8c, 0x15, 0xb4, + 0xaf, 0x72, 0x69, 0x3e, 0x8d, 0xd1, 0xfd, 0x1c, 0xfa, 0x67, 0x8c, 0x8a, 0x12, 0xc7, 0x62, 0x38, + 0xf9, 0x8a, 0x50, 0x96, 0x07, 0xe4, 0x45, 0x45, 0xb8, 0x40, 0x07, 0xb0, 0x75, 0x51, 0xdf, 0x4d, + 0xe3, 0xd8, 0x38, 0xd9, 0x09, 0x9a, 0xcb, 0x17, 0xdd, 0x9f, 0x5e, 0x3b, 0x9d, 0x7f, 0x5e, 0x3b, + 0x1d, 0xf7, 0x29, 0x1c, 0x2e, 0xbd, 0xe4, 0x05, 0xa3, 0x9c, 0x20, 0x0b, 0xba, 0xb1, 0x82, 0xd4, + 0xeb, 0xe9, 0x1d, 0x7d, 0x08, 0x37, 0x71, 0x25, 0x58, 0x38, 0x75, 0xb8, 0x21, 0x1d, 0x76, 0x6b, + 0xa3, 0x8e, 0xe7, 0x7e, 0x09, 0x7d, 0x19, 0x71, 0x38, 0xd1, 0x26, 0x9d, 0xd5, 0x7f, 0x84, 0x6e, + 0xe5, 0xe6, 0xc3, 0xe1, 0xd2, 0x7b, 0x95, 0xdb, 0xca, 0xb2, 0xdc, 0xdf, 0x0d, 0x40, 0x01, 0x29, + 0x46, 0x78, 0x32, 0x1c, 0xb1, 0xf8, 0xb9, 0x66, 0x3b, 0x85, 0xcd, 0x9c, 0x27, 0xdc, 0x34, 0x8e, + 0x37, 0x4e, 0x7a, 0x03, 0xc7, 0x9b, 0x36, 0xd7, 0x23, 0x97, 0xb9, 0x77, 0xf9, 0xc0, 0x7b, 0xcc, + 0x93, 0x87, 0xb5, 0x8d, 0x54, 0xf9, 0xf9, 0x38, 0x90, 0xce, 0xe8, 0x03, 0xd8, 0x8d, 0xea, 0x20, + 0x21, 0xad, 0xf2, 0x88, 0x94, 0xb2, 0xc0, 0x8d, 0xa0, 0x27, 0x6d, 0x4f, 0xa4, 0x09, 0xdd, 0x01, + 0x68, 0x5c, 0x52, 0xcc, 0x53, 0x73, 0x43, 0x66, 0xb2, 0x23, 0x2d, 0x8f, 0x30, 0x4f, 0xd1, 0x99, + 0x86, 0xeb, 0xe9, 0x9a, 0x9b, 0xc7, 0xc6, 0x49, 0x6f, 0x60, 0x79, 0xcd, 0xe8, 0x3d, 0x3d, 0x7a, + 0xef, 0x5c, 0x8f, 0x7e, 0xd8, 0x7d, 0xf3, 0x87, 0xd3, 0x79, 0xf5, 0xa7, 0x63, 0xa8, 0x20, 0x35, + 0xd2, 0xea, 0xc6, 0x33, 0xd8, 0x9f, 0xab, 0x4d, 0x75, 0xe2, 0x21, 0xec, 0x94, 0xea, 0xac, 0x2b, + 0xbc, 0xfb, 0x7f, 0x15, 0x2a, 0xff, 0x60, 0xf6, 0xd2, 0x3d, 0x00, 0xf4, 0x6d, 0xad, 0xee, 0x6f, + 0x70, 0x89, 0x73, 0xae, 0x3a, 0xe7, 0x9e, 0xc1, 0xfe, 0x9c, 0x55, 0x71, 0xde, 0x83, 0xed, 0x42, + 0x5a, 0x64, 0xfb, 0x7b, 0x83, 0x77, 0x3d, 0xa5, 0xc6, 0xc6, 0x6f, 0xb8, 0x59, 0x57, 0x12, 0x28, + 0x1f, 0xf7, 0x14, 0x0e, 0x9b, 0x20, 0x75, 0x4a, 0x9c, 0xd7, 0x7b, 0xa0, 0x27, 0x63, 0xc2, 0x3b, + 0xf8, 0xe2, 0xa2, 0x24, 0x9c, 0xab, 0x41, 0xea, 0xab, 0xfb, 0x12, 0xcc, 0xe5, 0x47, 0x8a, 0xfe, + 0x33, 0x30, 0x63, 0x4c, 0xc3, 0x38, 0xc5, 0x34, 0x21, 0xa1, 0x60, 0xcf, 0x09, 0x0d, 0x73, 0x5c, + 0x14, 0x19, 0x4d, 0x64, 0x98, 0x6e, 0x70, 0x2b, 0xc6, 0xf4, 0x4c, 0xc2, 0xe7, 0x35, 0xfa, 0xb8, + 0x01, 0xd1, 0xc7, 0xb0, 0x57, 0x3f, 0x14, 0x55, 0x49, 0xc3, 0xa8, 0xcc, 0x2e, 0x12, 0x22, 0xc7, + 0xda, 0x0d, 0x6e, 0xc6, 0x98, 0x9e, 0x57, 0x25, 0x1d, 0x4a, 0xa3, 0x7b, 0x08, 0xb7, 0x24, 0xb9, + 0xec, 0xf4, 0xd7, 0x19, 0xd7, 0xba, 0x75, 0xef, 0x41, 0x7f, 0x11, 0x50, 0x39, 0x21, 0xd8, 0x8c, + 0x46, 0x2c, 0x92, 0xfc, 0xbb, 0x81, 0x3c, 0x0f, 0x7e, 0xde, 0x82, 0x2d, 0xe9, 0x8e, 0xc6, 0xb0, + 0xb7, 0xb0, 0x65, 0xc8, 0xd6, 0x3d, 0x5b, 0xbd, 0xb8, 0x96, 0xb3, 0x16, 0x6f, 0x18, 0xdd, 0x8f, + 0x7e, 0xf8, 0xf5, 0xef, 0x5f, 0x6e, 0xd8, 0xe8, 0x48, 0xfd, 0x0a, 0xea, 0xbf, 0x84, 0x5e, 0xa2, + 0x30, 0x9a, 0x84, 0x72, 0x25, 0xd0, 0x8f, 0x06, 0xec, 0x2d, 0x2c, 0xd1, 0x8c, 0x7a, 0xf5, 0x76, + 0xce, 0xa8, 0xd7, 0x6c, 0x9f, 0xeb, 0x4b, 0xea, 0x4f, 0xd0, 0xdd, 0x16, 0xb5, 0xa4, 0xab, 0x79, + 0x75, 0x0e, 0xfe, 0x4b, 0x7d, 0xfa, 0x1e, 0x3d, 0x82, 0x5e, 0x4b, 0xbb, 0xc8, 0xd2, 0x04, 0xcb, + 0xcb, 0x6a, 0xbd, 0xbf, 0x12, 0x53, 0xc4, 0x1d, 0xf4, 0x0c, 0xb6, 0x1b, 0x91, 0xcd, 0x82, 0x2c, + 0xeb, 0x76, 0x16, 0x64, 0x85, 0x7a, 0xdd, 0xdb, 0x32, 0xfb, 0x7d, 0xf4, 0x5e, 0x2b, 0xfb, 0x46, + 0xaa, 0xa8, 0x80, 0x5e, 0x4b, 0x70, 0xc8, 0x99, 0x0f, 0xb3, 0xa4, 0x5f, 0xeb, 0x78, 0xbd, 0x83, + 0x22, 0xb3, 0x25, 0x99, 0x89, 0xfa, 0x6d, 0xb2, 0x16, 0x45, 0x0a, 0x3b, 0x53, 0x31, 0xa1, 0x3b, + 0x73, 0xe1, 0x16, 0xd5, 0x67, 0xd9, 0xeb, 0x60, 0xc5, 0x75, 0x24, 0xb9, 0xfa, 0xe8, 0xa0, 0xc5, + 0x25, 0xff, 0x24, 0xa3, 0x8c, 0x8b, 0xe1, 0x93, 0x37, 0x57, 0xb6, 0xf1, 0xf6, 0xca, 0x36, 0xfe, + 0xba, 0xb2, 0x8d, 0x57, 0xd7, 0x76, 0xe7, 0xed, 0xb5, 0xdd, 0xf9, 0xed, 0xda, 0xee, 0x3c, 0xfd, + 0x34, 0xc9, 0x44, 0x5a, 0x45, 0x5e, 0xcc, 0x72, 0x3f, 0x2e, 0x27, 0x85, 0x60, 0xf7, 0x59, 0x99, + 0xdc, 0x8f, 0x53, 0x9c, 0xd1, 0x69, 0xa8, 0x81, 0x3f, 0xd6, 0x67, 0x31, 0x29, 0x08, 0x8f, 0xb6, + 0xe5, 0x2f, 0xec, 0xf4, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x17, 0xeb, 0x13, 0xde, 0x1d, 0x07, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -569,6 +657,8 @@ type QueryClient interface { Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) // Params queries permissions for a specific address.. Permissions(ctx context.Context, in *QueryPermissionsRequest, opts ...grpc.CallOption) (*QueryPermissionsResponse, error) + // BlockList + BlockList(ctx context.Context, in *QueryBlockListRequest, opts ...grpc.CallOption) (*QueryBlockListResponse, error) } type queryClient struct { @@ -624,6 +714,15 @@ func (c *queryClient) Permissions(ctx context.Context, in *QueryPermissionsReque return out, nil } +func (c *queryClient) BlockList(ctx context.Context, in *QueryBlockListRequest, opts ...grpc.CallOption) (*QueryBlockListResponse, error) { + out := new(QueryBlockListResponse) + err := c.cc.Invoke(ctx, "/cronos.Query/BlockList", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // ContractByDenom queries contract addresses by native denom from a query string. @@ -637,6 +736,8 @@ type QueryServer interface { Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) // Params queries permissions for a specific address.. Permissions(context.Context, *QueryPermissionsRequest) (*QueryPermissionsResponse, error) + // BlockList + BlockList(context.Context, *QueryBlockListRequest) (*QueryBlockListResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -658,6 +759,9 @@ func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsReq func (*UnimplementedQueryServer) Permissions(ctx context.Context, req *QueryPermissionsRequest) (*QueryPermissionsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Permissions not implemented") } +func (*UnimplementedQueryServer) BlockList(ctx context.Context, req *QueryBlockListRequest) (*QueryBlockListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BlockList not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -753,6 +857,24 @@ func _Query_Permissions_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Query_BlockList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryBlockListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).BlockList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cronos.Query/BlockList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).BlockList(ctx, req.(*QueryBlockListRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "cronos.Query", HandlerType: (*QueryServer)(nil), @@ -777,6 +899,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Permissions", Handler: _Query_Permissions_Handler, }, + { + MethodName: "BlockList", + Handler: _Query_BlockList_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cronos/query.proto", @@ -1132,6 +1258,59 @@ func (m *QueryPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *QueryBlockListRequest) 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 *QueryBlockListRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryBlockListRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryBlockListResponse) 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 *QueryBlockListResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryBlockListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Blob) > 0 { + i -= len(m.Blob) + copy(dAtA[i:], m.Blob) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Blob))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -1286,6 +1465,28 @@ func (m *QueryPermissionsResponse) Size() (n int) { return n } +func (m *QueryBlockListRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryBlockListResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Blob) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2209,6 +2410,140 @@ func (m *QueryPermissionsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryBlockListRequest) 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 ErrIntOverflowQuery + } + 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: QueryBlockListRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryBlockListRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryBlockListResponse) 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 ErrIntOverflowQuery + } + 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: QueryBlockListResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryBlockListResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Blob", 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.Blob = append(m.Blob[:0], dAtA[iNdEx:postIndex]...) + if m.Blob == nil { + m.Blob = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/cronos/types/query.pb.gw.go b/x/cronos/types/query.pb.gw.go index f127cb7749..5c14de004f 100644 --- a/x/cronos/types/query.pb.gw.go +++ b/x/cronos/types/query.pb.gw.go @@ -177,6 +177,24 @@ func local_request_Query_Permissions_0(ctx context.Context, marshaler runtime.Ma } +func request_Query_BlockList_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryBlockListRequest + var metadata runtime.ServerMetadata + + msg, err := client.BlockList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_BlockList_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryBlockListRequest + var metadata runtime.ServerMetadata + + msg, err := server.BlockList(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -275,6 +293,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_BlockList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + 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_Query_BlockList_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_BlockList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -396,6 +437,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_BlockList_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_Query_BlockList_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_BlockList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -407,6 +468,8 @@ var ( pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"cronos", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_Permissions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"cronos", "v1", "permissions"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_BlockList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"cronos", "v1", "blocklist"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -417,4 +480,6 @@ var ( forward_Query_Params_0 = runtime.ForwardResponseMessage forward_Query_Permissions_0 = runtime.ForwardResponseMessage + + forward_Query_BlockList_0 = runtime.ForwardResponseMessage ) diff --git a/x/cronos/types/tx.pb.go b/x/cronos/types/tx.pb.go index 14b0a74671..6b423ee04b 100644 --- a/x/cronos/types/tx.pb.go +++ b/x/cronos/types/tx.pb.go @@ -617,6 +617,96 @@ func (m *MsgUpdatePermissionsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdatePermissionsResponse proto.InternalMessageInfo +// MsgStoreBlockList +type MsgStoreBlockList struct { + From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + Blob []byte `protobuf:"bytes,2,opt,name=blob,proto3" json:"blob,omitempty"` +} + +func (m *MsgStoreBlockList) Reset() { *m = MsgStoreBlockList{} } +func (m *MsgStoreBlockList) String() string { return proto.CompactTextString(m) } +func (*MsgStoreBlockList) ProtoMessage() {} +func (*MsgStoreBlockList) Descriptor() ([]byte, []int) { + return fileDescriptor_28e09e4eabb18884, []int{12} +} +func (m *MsgStoreBlockList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgStoreBlockList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgStoreBlockList.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 *MsgStoreBlockList) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgStoreBlockList.Merge(m, src) +} +func (m *MsgStoreBlockList) XXX_Size() int { + return m.Size() +} +func (m *MsgStoreBlockList) XXX_DiscardUnknown() { + xxx_messageInfo_MsgStoreBlockList.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgStoreBlockList proto.InternalMessageInfo + +func (m *MsgStoreBlockList) GetFrom() string { + if m != nil { + return m.From + } + return "" +} + +func (m *MsgStoreBlockList) GetBlob() []byte { + if m != nil { + return m.Blob + } + return nil +} + +// MsgStoreBlockListResponse +type MsgStoreBlockListResponse struct { +} + +func (m *MsgStoreBlockListResponse) Reset() { *m = MsgStoreBlockListResponse{} } +func (m *MsgStoreBlockListResponse) String() string { return proto.CompactTextString(m) } +func (*MsgStoreBlockListResponse) ProtoMessage() {} +func (*MsgStoreBlockListResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_28e09e4eabb18884, []int{13} +} +func (m *MsgStoreBlockListResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgStoreBlockListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgStoreBlockListResponse.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 *MsgStoreBlockListResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgStoreBlockListResponse.Merge(m, src) +} +func (m *MsgStoreBlockListResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgStoreBlockListResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgStoreBlockListResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgStoreBlockListResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgConvertVouchers)(nil), "cronos.MsgConvertVouchers") proto.RegisterType((*MsgTransferTokens)(nil), "cronos.MsgTransferTokens") @@ -630,57 +720,62 @@ func init() { proto.RegisterType((*MsgUpdateParamsResponse)(nil), "cronos.MsgUpdateParamsResponse") proto.RegisterType((*MsgUpdatePermissions)(nil), "cronos.MsgUpdatePermissions") proto.RegisterType((*MsgUpdatePermissionsResponse)(nil), "cronos.MsgUpdatePermissionsResponse") + proto.RegisterType((*MsgStoreBlockList)(nil), "cronos.MsgStoreBlockList") + proto.RegisterType((*MsgStoreBlockListResponse)(nil), "cronos.MsgStoreBlockListResponse") } func init() { proto.RegisterFile("cronos/tx.proto", fileDescriptor_28e09e4eabb18884) } var fileDescriptor_28e09e4eabb18884 = []byte{ - // 709 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x3f, 0x6f, 0xd3, 0x40, - 0x14, 0x8f, 0xf3, 0x8f, 0xf6, 0xa5, 0x4d, 0xd5, 0xa3, 0x6d, 0x12, 0x93, 0x3a, 0x21, 0x02, 0x29, - 0xaa, 0x68, 0x4c, 0x03, 0x53, 0xc7, 0x74, 0x61, 0x20, 0x15, 0x44, 0x05, 0xa4, 0x6e, 0x8e, 0x7d, - 0x75, 0xac, 0xd6, 0x3e, 0x73, 0x77, 0x89, 0x9a, 0x0d, 0xf1, 0x09, 0xf8, 0x06, 0xb0, 0xb0, 0x30, - 0xf5, 0x63, 0x74, 0xec, 0xc8, 0x04, 0xa8, 0x1d, 0xba, 0xf3, 0x09, 0x90, 0xcf, 0x67, 0xc7, 0x69, - 0x92, 0x6e, 0x4c, 0xbe, 0xf7, 0x7e, 0xf7, 0x7e, 0xbf, 0xdf, 0xf3, 0xbd, 0xb3, 0x61, 0xcd, 0xa4, - 0xc4, 0x23, 0x4c, 0xe7, 0xe7, 0x2d, 0x9f, 0x12, 0x4e, 0x50, 0x3e, 0x4c, 0xa8, 0x25, 0x93, 0x30, - 0x97, 0x30, 0xdd, 0x65, 0xb6, 0x3e, 0xda, 0x0b, 0x1e, 0xe1, 0x06, 0x75, 0xc3, 0x26, 0x36, 0x11, - 0x4b, 0x3d, 0x58, 0xc9, 0xac, 0x26, 0xb7, 0xf7, 0x0d, 0x86, 0xf5, 0xd1, 0x5e, 0x1f, 0x73, 0x63, - 0x4f, 0x37, 0x89, 0xe3, 0x49, 0xfc, 0xa1, 0xd4, 0x09, 0x1f, 0x61, 0xb2, 0xf1, 0x55, 0x01, 0xd4, - 0x65, 0xf6, 0x01, 0xf1, 0x46, 0x98, 0xf2, 0xf7, 0x64, 0x68, 0x0e, 0x30, 0x65, 0xa8, 0x0c, 0x0f, - 0x0c, 0xcb, 0xa2, 0x98, 0xb1, 0xb2, 0x52, 0x57, 0x9a, 0xcb, 0xbd, 0x28, 0x44, 0x06, 0xe4, 0x02, - 0x4e, 0x56, 0x4e, 0xd7, 0x33, 0xcd, 0x42, 0xbb, 0xd2, 0x0a, 0x55, 0x5b, 0x81, 0x6a, 0x4b, 0xaa, - 0xb6, 0x0e, 0x88, 0xe3, 0x75, 0x9e, 0x5f, 0xfe, 0xaa, 0xa5, 0x7e, 0xfc, 0xae, 0x35, 0x6d, 0x87, - 0x0f, 0x86, 0xfd, 0x96, 0x49, 0x5c, 0x5d, 0x5a, 0x0c, 0x1f, 0xbb, 0xcc, 0x3a, 0xd5, 0xf9, 0xd8, - 0xc7, 0x4c, 0x14, 0xb0, 0x5e, 0xc8, 0xbc, 0xbf, 0xf2, 0xf9, 0xf6, 0x62, 0x27, 0x12, 0x6c, 0x7c, - 0x57, 0x60, 0xbd, 0xcb, 0xec, 0x23, 0x6a, 0x78, 0xec, 0x04, 0xd3, 0x23, 0x72, 0x8a, 0x3d, 0x86, - 0x10, 0x64, 0x4f, 0x28, 0x71, 0xa5, 0x3b, 0xb1, 0x46, 0x45, 0x48, 0x73, 0x52, 0x4e, 0x8b, 0x4c, - 0x9a, 0x93, 0x89, 0xd5, 0xcc, 0x7f, 0xb3, 0xba, 0x1c, 0x58, 0x15, 0xea, 0x8d, 0x2a, 0xa8, 0xb3, - 0x2f, 0xb2, 0x87, 0x99, 0x4f, 0x3c, 0x86, 0x1b, 0x8f, 0xa0, 0x32, 0xd3, 0x44, 0x0c, 0x7e, 0x53, - 0x60, 0xb3, 0xcb, 0xec, 0x77, 0xbe, 0x65, 0x70, 0x2c, 0xb0, 0xae, 0xe1, 0xfb, 0x8e, 0x67, 0xa3, - 0x2d, 0xc8, 0x33, 0xec, 0x59, 0x98, 0xca, 0x46, 0x65, 0x84, 0x36, 0x20, 0x67, 0x61, 0x8f, 0xb8, - 0xb2, 0xdb, 0x30, 0x40, 0x2a, 0x2c, 0x99, 0xc4, 0xe3, 0xd4, 0x30, 0x79, 0x39, 0x23, 0x80, 0x38, - 0x16, 0x4c, 0x63, 0xb7, 0x4f, 0xce, 0xca, 0x59, 0xc9, 0x24, 0xa2, 0xe0, 0xa4, 0x2d, 0x6c, 0x3a, - 0xae, 0x71, 0x56, 0xce, 0xd5, 0x95, 0xe6, 0x6a, 0x2f, 0x0a, 0xf7, 0x0b, 0x41, 0x6f, 0x52, 0xb0, - 0x51, 0x83, 0xed, 0xb9, 0x0e, 0xe3, 0x1e, 0x5e, 0xc3, 0x6a, 0xd0, 0xe0, 0x90, 0x7a, 0x1d, 0xea, - 0x58, 0x36, 0x5e, 0x68, 0x7d, 0x0b, 0xf2, 0xd8, 0x33, 0xfa, 0x67, 0x58, 0x78, 0x5f, 0xea, 0xc9, - 0x68, 0x5a, 0xae, 0x24, 0x5e, 0xc8, 0x84, 0x2d, 0x96, 0x71, 0x61, 0x2d, 0xf6, 0xf1, 0xc6, 0xa0, - 0x86, 0xcb, 0x50, 0x15, 0x96, 0x8d, 0x21, 0x1f, 0x10, 0xea, 0xf0, 0xb1, 0xd4, 0x9a, 0x24, 0xd0, - 0x33, 0xc8, 0xfb, 0x62, 0x9f, 0x90, 0x2b, 0xb4, 0x8b, 0x2d, 0x39, 0xff, 0x61, 0x75, 0x27, 0x1b, - 0x1c, 0x7d, 0x4f, 0xee, 0xd9, 0x2f, 0x06, 0x26, 0x26, 0xd5, 0x8d, 0x0a, 0x94, 0xee, 0xc8, 0xc5, - 0x4e, 0x3e, 0xc2, 0xc6, 0x04, 0xc2, 0xd4, 0x75, 0x18, 0x73, 0xc8, 0x82, 0xc9, 0x4c, 0x5c, 0xa7, - 0xf4, 0xf4, 0x75, 0xaa, 0x43, 0xc1, 0x9f, 0x14, 0x8b, 0x53, 0xcb, 0xf6, 0x92, 0xa9, 0xe4, 0x88, - 0x69, 0x50, 0x9d, 0x27, 0x19, 0x59, 0x6a, 0xff, 0xcd, 0x40, 0xa6, 0xcb, 0x6c, 0xf4, 0x16, 0xd6, - 0xee, 0x5e, 0x68, 0x35, 0x6a, 0x7b, 0x76, 0x46, 0xd5, 0xc6, 0x62, 0x2c, 0xa2, 0x46, 0x87, 0x50, - 0xbc, 0x73, 0x03, 0x2b, 0x89, 0xaa, 0x69, 0x48, 0x7d, 0xbc, 0x10, 0x8a, 0xf9, 0x8e, 0x01, 0xcd, - 0x19, 0xf7, 0xed, 0x44, 0xe1, 0x2c, 0xac, 0x3e, 0xbd, 0x17, 0x8e, 0xb9, 0x3b, 0x00, 0x89, 0x39, - 0xdc, 0x4c, 0x9a, 0x89, 0xd3, 0xea, 0xf6, 0xdc, 0x74, 0xcc, 0xf1, 0x0a, 0x56, 0xa6, 0x86, 0xac, - 0x34, 0x23, 0x1d, 0x02, 0x6a, 0x6d, 0x01, 0x10, 0x33, 0x7d, 0x80, 0xf5, 0xd9, 0x21, 0xa9, 0xce, - 0x56, 0x4d, 0x50, 0xf5, 0xc9, 0x7d, 0x68, 0x44, 0xac, 0xe6, 0x3e, 0xdd, 0x5e, 0xec, 0x28, 0x9d, - 0xc3, 0xcb, 0x6b, 0x4d, 0xb9, 0xba, 0xd6, 0x94, 0x3f, 0xd7, 0x9a, 0xf2, 0xe5, 0x46, 0x4b, 0x5d, - 0xdd, 0x68, 0xa9, 0x9f, 0x37, 0x5a, 0xea, 0xf8, 0x65, 0xf2, 0x6b, 0x46, 0xc7, 0x3e, 0x27, 0xbb, - 0x84, 0xda, 0xbb, 0xe6, 0xc0, 0x70, 0x3c, 0xf9, 0x17, 0xd0, 0x47, 0x6d, 0xfd, 0x3c, 0x5a, 0x8b, - 0xef, 0x5b, 0x3f, 0x2f, 0x7e, 0x0c, 0x2f, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0x29, 0xd8, 0x30, - 0x36, 0x97, 0x06, 0x00, 0x00, + // 761 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xbd, 0x6e, 0xe3, 0x46, + 0x10, 0x16, 0xf5, 0x17, 0x7b, 0x64, 0xcb, 0xf0, 0xc6, 0xb6, 0x24, 0x46, 0xa6, 0x14, 0x21, 0x01, + 0x04, 0x23, 0x16, 0x63, 0x25, 0x95, 0x4b, 0x19, 0x08, 0x52, 0x58, 0x46, 0xc2, 0x38, 0x09, 0xe0, + 0x8e, 0x3f, 0x6b, 0x8a, 0xb0, 0xc8, 0x65, 0x76, 0x57, 0x82, 0xd5, 0x05, 0x79, 0x82, 0xbc, 0xc1, + 0x5d, 0x73, 0xcd, 0x55, 0x7e, 0x86, 0xab, 0x5c, 0xba, 0xbc, 0xea, 0xee, 0x60, 0x17, 0x7e, 0x8d, + 0x03, 0x97, 0x2b, 0x8a, 0xfa, 0x73, 0x77, 0x15, 0x77, 0xe6, 0xdb, 0x99, 0xef, 0x1b, 0xce, 0x0c, + 0x09, 0x3b, 0x36, 0x25, 0x01, 0x61, 0x3a, 0xbf, 0xed, 0x84, 0x94, 0x70, 0x82, 0x8a, 0xb1, 0x43, + 0xad, 0xd8, 0x84, 0xf9, 0x84, 0xe9, 0x3e, 0x73, 0xf5, 0xf1, 0x49, 0xf4, 0x88, 0x2f, 0xa8, 0x7b, + 0x2e, 0x71, 0x89, 0x38, 0xea, 0xd1, 0x49, 0x7a, 0x35, 0x79, 0xdd, 0x32, 0x19, 0xd6, 0xc7, 0x27, + 0x16, 0xe6, 0xe6, 0x89, 0x6e, 0x13, 0x2f, 0x90, 0xf8, 0xd7, 0x92, 0x27, 0x7e, 0xc4, 0xce, 0xd6, + 0x2b, 0x05, 0x50, 0x9f, 0xb9, 0x67, 0x24, 0x18, 0x63, 0xca, 0xff, 0x22, 0x23, 0x7b, 0x80, 0x29, + 0x43, 0x55, 0xf8, 0xca, 0x74, 0x1c, 0x8a, 0x19, 0xab, 0x2a, 0x4d, 0xa5, 0xbd, 0x69, 0x4c, 0x4d, + 0x64, 0x42, 0x21, 0xca, 0xc9, 0xaa, 0xd9, 0x66, 0xae, 0x5d, 0xea, 0xd6, 0x3a, 0x31, 0x6b, 0x27, + 0x62, 0xed, 0x48, 0xd6, 0xce, 0x19, 0xf1, 0x82, 0xde, 0x8f, 0xf7, 0x1f, 0x1a, 0x99, 0xb7, 0x1f, + 0x1b, 0x6d, 0xd7, 0xe3, 0x83, 0x91, 0xd5, 0xb1, 0x89, 0xaf, 0x4b, 0x89, 0xf1, 0xe3, 0x98, 0x39, + 0x37, 0x3a, 0x9f, 0x84, 0x98, 0x89, 0x00, 0x66, 0xc4, 0x99, 0x4f, 0xb7, 0xfe, 0x7b, 0xbe, 0x3b, + 0x9a, 0x12, 0xb6, 0xde, 0x28, 0xb0, 0xdb, 0x67, 0xee, 0x25, 0x35, 0x03, 0x76, 0x8d, 0xe9, 0x25, + 0xb9, 0xc1, 0x01, 0x43, 0x08, 0xf2, 0xd7, 0x94, 0xf8, 0x52, 0x9d, 0x38, 0xa3, 0x32, 0x64, 0x39, + 0xa9, 0x66, 0x85, 0x27, 0xcb, 0xc9, 0x4c, 0x6a, 0xee, 0x8b, 0x49, 0xdd, 0x8c, 0xa4, 0x0a, 0xf6, + 0x56, 0x1d, 0xd4, 0xe5, 0x17, 0x69, 0x60, 0x16, 0x92, 0x80, 0xe1, 0xd6, 0x37, 0x50, 0x5b, 0x2a, + 0x22, 0x01, 0x5f, 0x2b, 0xb0, 0xdf, 0x67, 0xee, 0x9f, 0xa1, 0x63, 0x72, 0x2c, 0xb0, 0xbe, 0x19, + 0x86, 0x5e, 0xe0, 0xa2, 0x03, 0x28, 0x32, 0x1c, 0x38, 0x98, 0xca, 0x42, 0xa5, 0x85, 0xf6, 0xa0, + 0xe0, 0xe0, 0x80, 0xf8, 0xb2, 0xda, 0xd8, 0x40, 0x2a, 0x6c, 0xd8, 0x24, 0xe0, 0xd4, 0xb4, 0x79, + 0x35, 0x27, 0x80, 0xc4, 0x16, 0x99, 0x26, 0xbe, 0x45, 0x86, 0xd5, 0xbc, 0xcc, 0x24, 0xac, 0xa8, + 0xd3, 0x0e, 0xb6, 0x3d, 0xdf, 0x1c, 0x56, 0x0b, 0x4d, 0xa5, 0xbd, 0x6d, 0x4c, 0xcd, 0xd3, 0x52, + 0x54, 0x9b, 0x24, 0x6c, 0x35, 0xe0, 0x70, 0xa5, 0xc2, 0xa4, 0x86, 0x73, 0xd8, 0x8e, 0x0a, 0x1c, + 0xd1, 0xa0, 0x47, 0x3d, 0xc7, 0xc5, 0x6b, 0xa5, 0x1f, 0x40, 0x11, 0x07, 0xa6, 0x35, 0xc4, 0x42, + 0xfb, 0x86, 0x21, 0xad, 0x79, 0xba, 0x8a, 0x78, 0x21, 0xb3, 0x6c, 0x09, 0x8d, 0x0f, 0x3b, 0x89, + 0x8e, 0xdf, 0x4c, 0x6a, 0xfa, 0x0c, 0xd5, 0x61, 0xd3, 0x1c, 0xf1, 0x01, 0xa1, 0x1e, 0x9f, 0x48, + 0xae, 0x99, 0x03, 0xfd, 0x00, 0xc5, 0x50, 0xdc, 0x13, 0x74, 0xa5, 0x6e, 0xb9, 0x23, 0xe7, 0x3f, + 0x8e, 0xee, 0xe5, 0xa3, 0xd6, 0x1b, 0xf2, 0xce, 0x69, 0x39, 0x12, 0x31, 0x8b, 0x6e, 0xd5, 0xa0, + 0xb2, 0x40, 0x97, 0x28, 0xf9, 0x07, 0xf6, 0x66, 0x10, 0xa6, 0xbe, 0xc7, 0x98, 0x47, 0xd6, 0x4c, + 0x66, 0x6a, 0x9d, 0xb2, 0xf3, 0xeb, 0xd4, 0x84, 0x52, 0x38, 0x0b, 0x16, 0x5d, 0xcb, 0x1b, 0x69, + 0x57, 0x7a, 0xc4, 0x34, 0xa8, 0xaf, 0xa2, 0x4c, 0x24, 0xfd, 0x22, 0x36, 0xe5, 0x0f, 0x4e, 0x28, + 0xee, 0x0d, 0x89, 0x7d, 0x73, 0xee, 0x31, 0xbe, 0x52, 0x0f, 0x82, 0xbc, 0x35, 0x24, 0x96, 0x10, + 0xb3, 0x65, 0x88, 0x73, 0x9a, 0x27, 0x1e, 0xd6, 0xf9, 0x3c, 0x53, 0x92, 0xee, 0xbb, 0x3c, 0xe4, + 0xfa, 0xcc, 0x45, 0xbf, 0xc3, 0xce, 0xe2, 0x57, 0x43, 0x9d, 0xbe, 0xdb, 0xe5, 0x45, 0x50, 0x5b, + 0xeb, 0xb1, 0x69, 0x6a, 0x74, 0x01, 0xe5, 0x85, 0x35, 0xaf, 0xa5, 0xa2, 0xe6, 0x21, 0xf5, 0xdb, + 0xb5, 0x50, 0x92, 0xef, 0x0a, 0xd0, 0x8a, 0x9d, 0x3a, 0x4c, 0x05, 0x2e, 0xc3, 0xea, 0xf7, 0x2f, + 0xc2, 0x49, 0xee, 0x1e, 0x40, 0x6a, 0xd8, 0xf7, 0xd3, 0x62, 0x12, 0xb7, 0x7a, 0xb8, 0xd2, 0x9d, + 0xe4, 0xf8, 0x15, 0xb6, 0xe6, 0x26, 0xb9, 0xb2, 0x44, 0x1d, 0x03, 0x6a, 0x63, 0x0d, 0x90, 0x64, + 0xfa, 0x1b, 0x76, 0x97, 0x27, 0xb1, 0xbe, 0x1c, 0x35, 0x43, 0xd5, 0xef, 0x5e, 0x42, 0xd3, 0x2d, + 0x59, 0x98, 0xa7, 0x74, 0x4b, 0xe6, 0xa1, 0xb9, 0x96, 0xac, 0x9e, 0x1e, 0xb5, 0xf0, 0xef, 0xf3, + 0xdd, 0x91, 0xd2, 0xbb, 0xb8, 0x7f, 0xd4, 0x94, 0x87, 0x47, 0x4d, 0xf9, 0xf4, 0xa8, 0x29, 0xff, + 0x3f, 0x69, 0x99, 0x87, 0x27, 0x2d, 0xf3, 0xfe, 0x49, 0xcb, 0x5c, 0xfd, 0x9c, 0xfe, 0x04, 0xd3, + 0x49, 0xc8, 0xc9, 0x31, 0xa1, 0xee, 0xb1, 0x3d, 0x30, 0xbd, 0x40, 0xfe, 0xba, 0xf4, 0x71, 0x57, + 0xbf, 0x9d, 0x9e, 0xc5, 0x47, 0xd9, 0x2a, 0x8a, 0xbf, 0xd9, 0x4f, 0x9f, 0x03, 0x00, 0x00, 0xff, + 0xff, 0x6d, 0x0b, 0x10, 0xeb, 0x4c, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -709,6 +804,8 @@ type MsgClient interface { UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) // UpdatePermissions defines a method to update cronos admins permissions UpdatePermissions(ctx context.Context, in *MsgUpdatePermissions, opts ...grpc.CallOption) (*MsgUpdatePermissionsResponse, error) + // StoreBlockList + StoreBlockList(ctx context.Context, in *MsgStoreBlockList, opts ...grpc.CallOption) (*MsgStoreBlockListResponse, error) } type msgClient struct { @@ -773,6 +870,15 @@ func (c *msgClient) UpdatePermissions(ctx context.Context, in *MsgUpdatePermissi return out, nil } +func (c *msgClient) StoreBlockList(ctx context.Context, in *MsgStoreBlockList, opts ...grpc.CallOption) (*MsgStoreBlockListResponse, error) { + out := new(MsgStoreBlockListResponse) + err := c.cc.Invoke(ctx, "/cronos.Msg/StoreBlockList", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // ConvertVouchers defines a method for converting ibc voucher to cronos evm @@ -789,6 +895,8 @@ type MsgServer interface { UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) // UpdatePermissions defines a method to update cronos admins permissions UpdatePermissions(context.Context, *MsgUpdatePermissions) (*MsgUpdatePermissionsResponse, error) + // StoreBlockList + StoreBlockList(context.Context, *MsgStoreBlockList) (*MsgStoreBlockListResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -813,6 +921,9 @@ func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateP func (*UnimplementedMsgServer) UpdatePermissions(ctx context.Context, req *MsgUpdatePermissions) (*MsgUpdatePermissionsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdatePermissions not implemented") } +func (*UnimplementedMsgServer) StoreBlockList(ctx context.Context, req *MsgStoreBlockList) (*MsgStoreBlockListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StoreBlockList not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -926,6 +1037,24 @@ func _Msg_UpdatePermissions_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _Msg_StoreBlockList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgStoreBlockList) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).StoreBlockList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cronos.Msg/StoreBlockList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).StoreBlockList(ctx, req.(*MsgStoreBlockList)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "cronos.Msg", HandlerType: (*MsgServer)(nil), @@ -954,6 +1083,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdatePermissions", Handler: _Msg_UpdatePermissions_Handler, }, + { + MethodName: "StoreBlockList", + Handler: _Msg_StoreBlockList_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cronos/tx.proto", @@ -1370,6 +1503,66 @@ func (m *MsgUpdatePermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *MsgStoreBlockList) 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 *MsgStoreBlockList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgStoreBlockList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Blob) > 0 { + i -= len(m.Blob) + copy(dAtA[i:], m.Blob) + i = encodeVarintTx(dAtA, i, uint64(len(m.Blob))) + i-- + dAtA[i] = 0x12 + } + if len(m.From) > 0 { + i -= len(m.From) + copy(dAtA[i:], m.From) + i = encodeVarintTx(dAtA, i, uint64(len(m.From))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgStoreBlockListResponse) 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 *MsgStoreBlockListResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgStoreBlockListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -1556,6 +1749,32 @@ func (m *MsgUpdatePermissionsResponse) Size() (n int) { return n } +func (m *MsgStoreBlockList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.From) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Blob) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgStoreBlockListResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2673,6 +2892,172 @@ func (m *MsgUpdatePermissionsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgStoreBlockList) 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 ErrIntOverflowTx + } + 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: MsgStoreBlockList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgStoreBlockList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.From = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Blob", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Blob = append(m.Blob[:0], dAtA[iNdEx:postIndex]...) + if m.Blob == nil { + m.Blob = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgStoreBlockListResponse) 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 ErrIntOverflowTx + } + 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: MsgStoreBlockListResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgStoreBlockListResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/e2ee/client/cli/cmd.go b/x/e2ee/client/cli/cmd.go index e7358085a4..5e88ce5287 100644 --- a/x/e2ee/client/cli/cmd.go +++ b/x/e2ee/client/cli/cmd.go @@ -12,6 +12,8 @@ func E2EECommand() *cobra.Command { KeygenCommand(), EncryptCommand(), DecryptCommand(), + EncryptToValidatorsCommand(), + PubKeyCommand(), ) return cmd diff --git a/x/e2ee/client/cli/encrypt_to_validators.go b/x/e2ee/client/cli/encrypt_to_validators.go new file mode 100644 index 0000000000..fc30b1953e --- /dev/null +++ b/x/e2ee/client/cli/encrypt_to_validators.go @@ -0,0 +1,110 @@ +package cli + +import ( + "context" + "fmt" + "io" + "os" + + "filippo.io/age" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/spf13/cobra" + + "github.com/crypto-org-chain/cronos/v2/x/e2ee/types" +) + +func EncryptToValidatorsCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "encrypt-to-validators [input-file]", + Short: "Encrypt input file to one or multiple recipients", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + outputFile, err := cmd.Flags().GetString(flags.FlagOutput) + if err != nil { + return err + } + + ctx := context.Background() + + // get validator list + stakingClient := stakingtypes.NewQueryClient(clientCtx) + valsRsp, err := stakingClient.Validators(ctx, &stakingtypes.QueryValidatorsRequest{ + Status: stakingtypes.BondStatusBonded, + }) + if err != nil { + return err + } + + recs := make([]string, len(valsRsp.Validators)) + for i, val := range valsRsp.Validators { + bz, err := sdk.ValAddressFromBech32(val.OperatorAddress) + if err != nil { + return err + } + // convert to account address + recs[i] = sdk.AccAddress(bz).String() + } + + // query encryption key from chain state + client := types.NewQueryClient(clientCtx) + rsp, err := client.Keys(context.Background(), &types.KeysRequest{ + Addresses: recs, + }) + if err != nil { + return err + } + + recipients := make([]age.Recipient, len(recs)) + for i, key := range rsp.Keys { + if len(key) == 0 { + fmt.Fprintf(os.Stderr, "missing encryption key for validator %s\n", recs[i]) + continue + } + + recipient, err := age.ParseX25519Recipient(key) + if err != nil { + fmt.Fprintf(os.Stderr, "invalid encryption key for validator %s, %v\n", recs[i], err) + continue + } + recipients[i] = recipient + } + + inputFile := args[0] + var input io.Reader + if inputFile == "-" { + input = os.Stdin + } else { + f, err := os.Open(inputFile) + if err != nil { + return err + } + defer f.Close() + input = f + } + + var output io.Writer + if outputFile == "-" { + output = os.Stdout + } else { + fp, err := os.Create(outputFile) + if err != nil { + return err + } + defer fp.Close() + output = fp + } + return encrypt(recipients, input, output) + }, + } + f := cmd.Flags() + f.StringP(flags.FlagOutput, "o", "-", "output file (default stdout)") + return cmd +} diff --git a/x/e2ee/client/cli/pubkey.go b/x/e2ee/client/cli/pubkey.go new file mode 100644 index 0000000000..45900fceab --- /dev/null +++ b/x/e2ee/client/cli/pubkey.go @@ -0,0 +1,53 @@ +package cli + +import ( + "fmt" + "os" + + "filippo.io/age" + "github.com/cosmos/cosmos-sdk/client" + "github.com/crypto-org-chain/cronos/v2/x/e2ee/keyring" + "github.com/crypto-org-chain/cronos/v2/x/e2ee/types" + "github.com/spf13/cobra" +) + +func PubKeyCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "pubkey", + Short: "Show the recipient of current identity stored in keyring", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + krName, err := cmd.Flags().GetString(FlagKeyringName) + if err != nil { + return err + } + + kr, err := keyring.New("cronosd", clientCtx.Keyring.Backend(), clientCtx.HomeDir, os.Stdin) + if err != nil { + return err + } + + bz, err := kr.Get(krName) + if err != nil { + return err + } + + k, err := age.ParseX25519Identity(string(bz)) + if err != nil { + return err + } + + fmt.Println(k.Recipient()) + return nil + }, + } + + cmd.Flags().String(FlagKeyringName, types.DefaultKeyringName, "The keyring name to use") + + return cmd +} diff --git a/x/e2ee/client/cli/query.go b/x/e2ee/client/cli/query.go new file mode 100644 index 0000000000..a2ae880808 --- /dev/null +++ b/x/e2ee/client/cli/query.go @@ -0,0 +1,78 @@ +package cli + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/crypto-org-chain/cronos/v2/x/e2ee/types" + "github.com/spf13/cobra" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string) *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + cmd.AddCommand(CmdEncryptionKey()) + cmd.AddCommand(CmdEncryptionKeys()) + return cmd +} + +func CmdEncryptionKey() *cobra.Command { + cmd := &cobra.Command{ + Use: "key [address]", + Short: "Query an encryption key by address", + + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + params := &types.KeyRequest{ + Address: args[0], + } + res, err := queryClient.Key(cmd.Context(), params) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func CmdEncryptionKeys() *cobra.Command { + cmd := &cobra.Command{ + Use: "keys [addresses] ...", + Short: "Query a batch of encryption key by addresses", + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + params := &types.KeysRequest{ + Addresses: args, + } + res, err := queryClient.Keys(cmd.Context(), params) + if err != nil { + return err + } + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/e2ee/client/cli/tx.go b/x/e2ee/client/cli/tx.go new file mode 100644 index 0000000000..7a9516d48d --- /dev/null +++ b/x/e2ee/client/cli/tx.go @@ -0,0 +1,50 @@ +package cli + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/crypto-org-chain/cronos/v2/x/e2ee/types" + "github.com/spf13/cobra" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + cmd.AddCommand(CmdRegisterAccount()) + return cmd +} + +func CmdRegisterAccount() *cobra.Command { + cmd := &cobra.Command{ + Use: "register-encryption-key [key]", + Short: "Register encryption key stores an public key for asymmetric encryption with the user address.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + msg := types.MsgRegisterEncryptionKey{ + Address: clientCtx.GetFromAddress().String(), + Key: args[0], + } + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/e2ee/keyring/keyring_test.go b/x/e2ee/keyring/keyring_test.go index 56ef87ee74..ef5690f619 100644 --- a/x/e2ee/keyring/keyring_test.go +++ b/x/e2ee/keyring/keyring_test.go @@ -6,7 +6,7 @@ import ( "testing" "filippo.io/age" - "github.com/test-go/testify/require" + "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/crypto/keyring" ) diff --git a/x/e2ee/module.go b/x/e2ee/module.go index c91f233d6e..5d62e923bf 100644 --- a/x/e2ee/module.go +++ b/x/e2ee/module.go @@ -16,6 +16,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/crypto-org-chain/cronos/v2/x/e2ee/client/cli" "github.com/crypto-org-chain/cronos/v2/x/e2ee/keeper" "github.com/crypto-org-chain/cronos/v2/x/e2ee/types" ) @@ -82,6 +83,16 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r } } +// GetTxCmd returns the capability module's root tx command. +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the capability module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd(types.StoreKey) +} + // ---------------------------------------------------------------------------- // AppModule // ---------------------------------------------------------------------------- diff --git a/x/e2ee/types/msg.go b/x/e2ee/types/msg.go index 316efbdec8..85b2ec0cfc 100644 --- a/x/e2ee/types/msg.go +++ b/x/e2ee/types/msg.go @@ -7,6 +7,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +var _ sdk.Msg = (*MsgRegisterEncryptionKey)(nil) + func (m *MsgRegisterEncryptionKey) ValidateBasic() error { // validate bech32 format of Address if _, err := sdk.AccAddressFromBech32(m.Address); err != nil { @@ -19,3 +21,11 @@ func ValidateRecipientKey(key string) error { _, err := age.ParseX25519Recipient(key) return err } + +func (m *MsgRegisterEncryptionKey) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.Address) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +}