From 3275b572bcb4ae41019a25e0cb109bdce147c6b0 Mon Sep 17 00:00:00 2001
From: mmsqe <mavis@crypto.com>
Date: Fri, 26 Apr 2024 18:37:50 +0800
Subject: [PATCH] Problem: encryption-key cmd is not supported (#1409)

* Problem: encryption-key cmd is not supported

* gen doc

* add validate
---
 CHANGELOG.md                              |  4 ++
 client/docs/config.json                   |  8 ++++
 client/docs/swagger-ui/swagger.yaml       | 50 +++++++++++++++++++++++
 integration_tests/configs/default.jsonnet |  6 +++
 integration_tests/cosmoscli.py            | 30 ++++++++++++++
 integration_tests/test_e2ee.py            | 10 +++++
 x/e2ee/autocli.go                         | 13 ++++++
 x/e2ee/types/genesis.go                   |  5 +++
 x/e2ee/types/keys.go                      | 13 ++++++
 9 files changed, 139 insertions(+)
 create mode 100644 integration_tests/test_e2ee.py

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67b9c59cc4..c8613f9153 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,10 @@
 
 * (rpc) [#1397](https://github.com/crypto-org-chain/cronos/pull/1397) Avoid panic on invalid elasticity_multiplier.
 
+### Features
+
+*  [#1406](https://github.com/crypto-org-chain/cronos/pull/1406) Add set-encryption-key for encryption module.
+
 *April 8, 2024*
 
 ## v1.2.0-rc1
diff --git a/client/docs/config.json b/client/docs/config.json
index 59927bc19f..dfa434bdd8 100644
--- a/client/docs/config.json
+++ b/client/docs/config.json
@@ -14,6 +14,14 @@
         }
       }
     },
+    {
+      "url": "./tmp-swagger-gen/e2ee/query.swagger.json",
+      "operationIds": {
+        "rename": {
+          "Params": "Keys"
+        }
+      }
+    },
     {
       "url": "./tmp-swagger-gen/ethermint/evm/v1/query.swagger.json",
       "operationIds": {
diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml
index 8618dc42f9..fd0103c893 100644
--- a/client/docs/swagger-ui/swagger.yaml
+++ b/client/docs/swagger-ui/swagger.yaml
@@ -884,6 +884,49 @@ paths:
           type: string
       tags:
         - Query
+  /e2ee/v1/key/{address}:
+    get:
+      summary: Key queries the encryption key of a given address
+      operationId: Key
+      responses:
+        '200':
+          description: A successful response.
+          schema:
+            type: object
+            properties:
+              key:
+                type: string
+                format: byte
+            description: KeyResponse is the response type for the Query/Key RPC method.
+        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
+                    value:
+                      type: string
+                      format: byte
+      parameters:
+        - name: address
+          in: path
+          required: true
+          type: string
+      tags:
+        - Query
   /ethermint/evm/v1/account/{address}:
     get:
       summary: Account queries an Ethereum account.
@@ -45506,6 +45549,13 @@ definitions:
                   "@type": "type.googleapis.com/google.protobuf.Duration",
                   "value": "1.212s"
                 }
+  e2ee.KeyResponse:
+    type: object
+    properties:
+      key:
+        type: string
+        format: byte
+    description: KeyResponse is the response type for the Query/Key RPC method.
   ethermint.evm.v1.ChainConfig:
     type: object
     properties:
diff --git a/integration_tests/configs/default.jsonnet b/integration_tests/configs/default.jsonnet
index 4b19a0f1b1..04dc9271bc 100644
--- a/integration_tests/configs/default.jsonnet
+++ b/integration_tests/configs/default.jsonnet
@@ -87,6 +87,12 @@
             ibc_cro_denom: '${IBC_CRO_DENOM}',
           },
         },
+        e2ee: {
+          keys: [{
+            address: 'crc16z0herz998946wr659lr84c8c556da55dc34hh',
+            key: std.base64('key'),
+          }],
+        },
         gov: {
           params: {
             expedited_voting_period: '1s',
diff --git a/integration_tests/cosmoscli.py b/integration_tests/cosmoscli.py
index 809137c596..06f459590a 100644
--- a/integration_tests/cosmoscli.py
+++ b/integration_tests/cosmoscli.py
@@ -1840,3 +1840,33 @@ def query_bank_send(self, *denoms):
                 output="json",
             )
         ).get("send_enabled", [])
+
+    def query_e2ee_key(self, address):
+        return json.loads(
+            self.raw(
+                "q",
+                "e2ee",
+                "key",
+                address,
+                home=self.data_dir,
+                output="json",
+            )
+        )
+
+    def set_e2ee_key(self, key, **kwargs):
+        kwargs.setdefault("gas_prices", DEFAULT_GAS_PRICE)
+        kwargs.setdefault("gas", DEFAULT_GAS)
+        rsp = json.loads(
+            self.raw(
+                "tx",
+                "e2ee",
+                "set-encryption-key",
+                key,
+                "-y",
+                home=self.data_dir,
+                **kwargs,
+            )
+        )
+        if rsp["code"] == 0:
+            rsp = self.event_query_tx_for(rsp["txhash"])
+        return rsp
diff --git a/integration_tests/test_e2ee.py b/integration_tests/test_e2ee.py
new file mode 100644
index 0000000000..9b20796d56
--- /dev/null
+++ b/integration_tests/test_e2ee.py
@@ -0,0 +1,10 @@
+import base64
+
+
+def test_set_key(cronos):
+    cli = cronos.cosmos_cli()
+    key = base64.b64encode(b"new_key").decode("utf-8")
+    cli.set_e2ee_key(key, _from="community")
+    adr = cli.address("community")
+    p = cli.query_e2ee_key(adr)
+    assert p["key"] == key
diff --git a/x/e2ee/autocli.go b/x/e2ee/autocli.go
index 1d4ec40126..f83bedd8d0 100644
--- a/x/e2ee/autocli.go
+++ b/x/e2ee/autocli.go
@@ -18,5 +18,18 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
 				},
 			},
 		},
+		Tx: &autocliv1.ServiceCommandDescriptor{
+			Service: "e2ee.Msg",
+			RpcCommandOptions: []*autocliv1.RpcCommandOptions{
+				{
+					RpcMethod: "RegisterEncryptionKey",
+					Use:       "set-encryption-key [key]",
+					Short:     "Set encryption key is stored associated with the user address.",
+					PositionalArgs: []*autocliv1.PositionalArgDescriptor{
+						{ProtoField: "key"},
+					},
+				},
+			},
+		},
 	}
 }
diff --git a/x/e2ee/types/genesis.go b/x/e2ee/types/genesis.go
index 5c5ec3cc2e..d2a392ceab 100644
--- a/x/e2ee/types/genesis.go
+++ b/x/e2ee/types/genesis.go
@@ -8,5 +8,10 @@ func DefaultGenesis() *GenesisState {
 // Validate performs basic genesis state validation returning an error upon any
 // failure.
 func (gs GenesisState) Validate() error {
+	for _, key := range gs.Keys {
+		if err := key.Validate(); err != nil {
+			return err
+		}
+	}
 	return nil
 }
diff --git a/x/e2ee/types/keys.go b/x/e2ee/types/keys.go
index c89cac2311..c5744d7c7a 100644
--- a/x/e2ee/types/keys.go
+++ b/x/e2ee/types/keys.go
@@ -1,6 +1,8 @@
 package types
 
 import (
+	"errors"
+
 	sdk "github.com/cosmos/cosmos-sdk/types"
 )
 
@@ -27,3 +29,14 @@ func KeyPrefix(addr sdk.AccAddress) []byte {
 	copy(key[1:], addr)
 	return key
 }
+
+// Validate checks for address and key correctness.
+func (e EncryptionKeyEntry) Validate() error {
+	if _, err := sdk.AccAddressFromBech32(e.Address); err != nil {
+		return err
+	}
+	if e.Key == nil {
+		return errors.New("key can't be nil")
+	}
+	return nil
+}