Skip to content

Commit c1388bf

Browse files
committed
merge conflicts
2 parents b1beadf + b6ed1a7 commit c1388bf

File tree

14 files changed

+1537
-210
lines changed

14 files changed

+1537
-210
lines changed

app/app.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ import (
116116
"github.com/sei-protocol/sei-chain/utils"
117117
"github.com/sei-protocol/sei-chain/utils/metrics"
118118
"github.com/sei-protocol/sei-chain/wasmbinding"
119+
ctmodule "github.com/sei-protocol/sei-chain/x/confidentialtransfers"
119120
ctkeeper "github.com/sei-protocol/sei-chain/x/confidentialtransfers/keeper"
120121
cttypes "github.com/sei-protocol/sei-chain/x/confidentialtransfers/types"
121122
epochmodule "github.com/sei-protocol/sei-chain/x/epoch"
@@ -209,6 +210,7 @@ var (
209210
wasm.AppModuleBasic{},
210211
epochmodule.AppModuleBasic{},
211212
tokenfactorymodule.AppModuleBasic{},
213+
ctmodule.AppModuleBasic{},
212214
// this line is used by starport scaffolding # stargate/app/moduleBasic
213215
)
214216

@@ -226,9 +228,13 @@ var (
226228
wasm.ModuleName: {authtypes.Burner},
227229
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
228230
tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner},
231+
<<<<<<< HEAD
229232
// Confidential Transfers module is not live yet, but we add the permissions for testing
230233
cttypes.ModuleName: nil,
231234

235+
=======
236+
cttypes.ModuleName: {},
237+
>>>>>>> feature/ct_types
232238
// this line is used by starport scaffolding # stargate/app/maccPerms
233239
}
234240

@@ -558,6 +564,12 @@ func New(
558564
tokenFactoryConfig,
559565
)
560566

567+
app.ConfidentialTransfersKeeper = ctkeeper.NewKeeper(
568+
appCodec,
569+
app.keys[(cttypes.StoreKey)],
570+
app.GetSubspace(cttypes.ModuleName),
571+
app.AccountKeeper)
572+
561573
// The last arguments can contain custom message handlers, and custom query handlers,
562574
// if we want to allow any custom callbacks
563575
supportedFeatures := "iterator,staking,stargate,sei"
@@ -760,6 +772,7 @@ func New(
760772
epochModule,
761773
tokenfactorymodule.NewAppModule(app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper),
762774
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
775+
ctmodule.NewAppModule(app.ConfidentialTransfersKeeper),
763776
// this line is used by starport scaffolding # stargate/app/appModule
764777
)
765778

@@ -791,6 +804,7 @@ func New(
791804
evmtypes.ModuleName,
792805
wasm.ModuleName,
793806
tokenfactorytypes.ModuleName,
807+
cttypes.ModuleName,
794808
acltypes.ModuleName,
795809
)
796810

@@ -822,6 +836,7 @@ func New(
822836
evmtypes.ModuleName,
823837
wasm.ModuleName,
824838
tokenfactorytypes.ModuleName,
839+
cttypes.ModuleName,
825840
acltypes.ModuleName,
826841
)
827842

@@ -851,6 +866,7 @@ func New(
851866
feegrant.ModuleName,
852867
oracletypes.ModuleName,
853868
tokenfactorytypes.ModuleName,
869+
cttypes.ModuleName,
854870
epochmoduletypes.ModuleName,
855871
wasm.ModuleName,
856872
evmtypes.ModuleName,
@@ -882,6 +898,7 @@ func New(
882898
transferModule,
883899
epochModule,
884900
tokenfactorymodule.NewAppModule(app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper),
901+
ctmodule.NewAppModule(app.ConfidentialTransfersKeeper),
885902
// this line is used by starport scaffolding # stargate/app/appModule
886903
)
887904
app.sm.RegisterStoreDecoders()

proto/confidentialtransfers/confidential.proto

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ message CtAccount {
1515
uint32 pending_balance_credit_counter = 4;
1616
Ciphertext available_balance = 5; // elgamal encoded balance
1717
string decryptable_available_balance = 6; // aes encoded balance
18+
}
19+
20+
message CtAccountWithDenom {
21+
string denom = 1;
22+
CtAccount account = 2 [(gogoproto.nullable) = false];
1823
}
Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,50 @@
11
syntax = "proto3";
22
package seiprotocol.seichain.confidentialtransfers;
33

4+
import "cosmos/base/query/v1beta1/pagination.proto";
45
import "gogoproto/gogo.proto";
56
import "google/api/annotations.proto";
7+
import "confidentialtransfers/confidential.proto";
68

79
option go_package = "github.com/sei-protocol/sei-chain/x/confidentialtransfers/types";
810

9-
// TODO: Define any query messages here
1011
// Query defines the gRPC querier service.
1112
service Query {
12-
// TODO: This is a mock method. Remove when we add real queries
13-
rpc TestQuery (TestQueryRequest) returns (TestQueryResponse) {
13+
rpc GetCtAccount (GetCtAccountRequest) returns (GetCtAccountResponse) {
1414
option (google.api.http) = {
15-
get: "/seichain/confidentialtransfers/test_query"
15+
get: "/seichain/confidentialtransfers/account/{address}/{denom}"
1616
};
1717
}
18+
19+
rpc GetAllCtAccounts (GetAllCtAccountsRequest) returns (GetAllCtAccountsResponse) {
20+
option (google.api.http) = {
21+
get: "/seichain/confidentialtransfers/account/{address}"
22+
};
23+
}
24+
}
25+
26+
message GetCtAccountRequest {
27+
string address = 1;
28+
string denom = 2;
1829
}
1930

20-
// TODO: This is a mock method. Remove when we add real queries
21-
message TestQueryRequest {
22-
string test_field = 1;
31+
message GetCtAccountResponse {
32+
CtAccount account = 1;
2333
}
2434

25-
// TODO: This is a mock method. Remove when we add real queries
26-
message TestQueryResponse {
27-
string test_field = 1;
35+
message GetAllCtAccountsRequest {
36+
option (gogoproto.equal) = false;
37+
option (gogoproto.goproto_getters) = false;
38+
39+
string address = 1;
40+
41+
// pagination defines an optional pagination for the request.
42+
cosmos.base.query.v1beta1.PageRequest pagination = 2;
43+
}
44+
45+
message GetAllCtAccountsResponse {
46+
repeated CtAccountWithDenom accounts = 1 [(gogoproto.nullable) = false];
47+
48+
// pagination defines the pagination in the response.
49+
cosmos.base.query.v1beta1.PageResponse pagination = 2;
2850
}

x/confidentialtransfers/keeper/genesis.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@ package keeper
33
import (
44
"fmt"
55
sdk "github.com/cosmos/cosmos-sdk/types"
6+
"github.com/cosmos/cosmos-sdk/types/query"
67
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
78
"github.com/sei-protocol/sei-chain/x/confidentialtransfers/types"
8-
9-
"github.com/cosmos/cosmos-sdk/store/prefix"
10-
"github.com/cosmos/cosmos-sdk/types/query"
119
)
1210

1311
func (k BaseKeeper) InitGenesis(ctx sdk.Context, gs *types.GenesisState) {
1412
moduleAcc := authtypes.NewEmptyModuleAccount(types.ModuleName)
1513
k.accountKeeper.SetModuleAccount(ctx, moduleAcc)
1614
k.SetParams(ctx, gs.Params)
15+
store := k.getAccountStore(ctx)
1716
for i := range gs.Accounts {
1817
genesisCtAccount := gs.Accounts[i]
19-
store := ctx.KVStore(k.storeKey)
18+
2019
bz := k.cdc.MustMarshal(&genesisCtAccount.Account) // Marshal the Account object into bytes
2120
store.Set(genesisCtAccount.Key, bz)
2221
}
@@ -34,11 +33,10 @@ func (k BaseKeeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
3433
}
3534

3635
func (k BaseKeeper) GetPaginatedAccounts(ctx sdk.Context, pagination *query.PageRequest) ([]types.GenesisCtAccount, *query.PageResponse, error) {
37-
store := ctx.KVStore(k.storeKey)
38-
supplyStore := prefix.NewStore(store, types.AccountsKey)
36+
store := k.getAccountStore(ctx)
3937

4038
genesisAccounts := make([]types.GenesisCtAccount, 0)
41-
pageRes, err := query.Paginate(supplyStore, pagination, func(key, value []byte) error {
39+
pageRes, err := query.Paginate(store, pagination, func(key, value []byte) error {
4240
var ctAccount types.CtAccount
4341
err := ctAccount.Unmarshal(value)
4442
if err != nil {

x/confidentialtransfers/keeper/genesis_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package keeper_test
22

33
import (
4+
"crypto/ecdsa"
5+
"fmt"
6+
sdk "github.com/cosmos/cosmos-sdk/types"
47
"github.com/sei-protocol/sei-chain/x/confidentialtransfers/types"
8+
"github.com/sei-protocol/sei-cryptography/pkg/encryption"
9+
"github.com/sei-protocol/sei-cryptography/pkg/encryption/elgamal"
510
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
611
)
712

@@ -16,3 +21,63 @@ func (suite *KeeperTestSuite) TestDefaultGenesisState() {
1621
suite.Require().NotNil(exportedGenesis)
1722
suite.Require().Equal(genesisState, exportedGenesis)
1823
}
24+
25+
func (suite *KeeperTestSuite) TestGenesisExportImportState() {
26+
pk1, _ := encryption.GenerateKey()
27+
pk2, _ := encryption.GenerateKey()
28+
addr1 := sdk.AccAddress("addr1")
29+
addr2 := sdk.AccAddress("addr2")
30+
testDenom1 := fmt.Sprintf("factory/%s/TEST1", addr1.String())
31+
testDenom2 := fmt.Sprintf("factory/%s/TEST2", addr2.String())
32+
33+
ctAcc1 := generateCtAccount(pk1, testDenom1, 1000)
34+
ctAcc2 := generateCtAccount(pk2, testDenom2, 2000)
35+
36+
accounts := []types.GenesisCtAccount{
37+
{
38+
Key: []byte(addr1.String() + testDenom1),
39+
Account: ctAcc1,
40+
},
41+
{
42+
Key: []byte(addr2.String() + testDenom2),
43+
Account: ctAcc2,
44+
},
45+
}
46+
genesisState := types.NewGenesisState(types.DefaultParams(), accounts)
47+
app := suite.App
48+
suite.Ctx = app.BaseApp.NewContext(false, tmproto.Header{})
49+
50+
suite.App.ConfidentialTransfersKeeper.InitGenesis(suite.Ctx, genesisState)
51+
52+
exportedGenesis := suite.App.ConfidentialTransfersKeeper.ExportGenesis(suite.Ctx)
53+
suite.Require().NotNil(exportedGenesis)
54+
suite.Require().Equal(genesisState, exportedGenesis)
55+
}
56+
57+
func generateCtAccount(pk *ecdsa.PrivateKey, testDenom string, balance uint64) types.CtAccount {
58+
eg := elgamal.NewTwistedElgamal()
59+
keyPair, _ := eg.KeyGen(*pk, testDenom)
60+
61+
aesPK1, _ := encryption.GetAESKey(*pk, testDenom)
62+
63+
amountLo := uint64(100)
64+
amountHi := uint64(0)
65+
66+
decryptableBalance, _ := encryption.EncryptAESGCM(balance, aesPK1)
67+
68+
ciphertextLo, _, _ := eg.Encrypt(keyPair.PublicKey, amountLo)
69+
ciphertextHi, _, _ := eg.Encrypt(keyPair.PublicKey, amountHi)
70+
71+
zeroCiphertextAvailable, _, _ := eg.Encrypt(keyPair.PublicKey, amountLo)
72+
73+
account := &types.Account{
74+
PublicKey: keyPair.PublicKey,
75+
PendingBalanceLo: ciphertextLo,
76+
PendingBalanceHi: ciphertextHi,
77+
PendingBalanceCreditCounter: 1,
78+
AvailableBalance: zeroCiphertextAvailable,
79+
DecryptableAvailableBalance: decryptableBalance,
80+
}
81+
82+
return *types.NewCtAccount(account)
83+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package keeper
2+
3+
import (
4+
"context"
5+
6+
"github.com/cosmos/cosmos-sdk/types/query"
7+
8+
sdk "github.com/cosmos/cosmos-sdk/types"
9+
"github.com/sei-protocol/sei-chain/x/confidentialtransfers/types"
10+
"google.golang.org/grpc/codes"
11+
"google.golang.org/grpc/status"
12+
)
13+
14+
var _ types.QueryServer = BaseKeeper{}
15+
16+
func (k BaseKeeper) GetCtAccount(ctx context.Context, req *types.GetCtAccountRequest) (*types.GetCtAccountResponse, error) {
17+
if req == nil {
18+
return nil, status.Error(codes.InvalidArgument, "empty request")
19+
}
20+
21+
if req.Address == "" {
22+
return nil, status.Error(codes.InvalidArgument, "address cannot be empty")
23+
}
24+
25+
address, err := sdk.AccAddressFromBech32(req.Address)
26+
if err != nil {
27+
return nil, status.Errorf(codes.InvalidArgument, "invalid address: %s", err.Error())
28+
}
29+
30+
if req.Denom == "" {
31+
return nil, status.Error(codes.InvalidArgument, "invalid denom")
32+
}
33+
34+
sdkCtx := sdk.UnwrapSDKContext(ctx)
35+
36+
ctAccount, found := k.getCtAccount(sdkCtx, address, req.Denom)
37+
if !found {
38+
return nil, status.Errorf(codes.NotFound, "account not found for account %s and denom %s",
39+
req.Address, req.Denom)
40+
}
41+
42+
return &types.GetCtAccountResponse{Account: &ctAccount}, nil
43+
}
44+
45+
func (k BaseKeeper) GetAllCtAccounts(ctx context.Context, req *types.GetAllCtAccountsRequest) (*types.GetAllCtAccountsResponse, error) {
46+
if req == nil {
47+
return nil, status.Error(codes.InvalidArgument, "empty request")
48+
}
49+
50+
if req.Address == "" {
51+
return nil, status.Error(codes.InvalidArgument, "address cannot be empty")
52+
}
53+
54+
address, err := sdk.AccAddressFromBech32(req.Address)
55+
if err != nil {
56+
return nil, status.Errorf(codes.InvalidArgument, "invalid address: %s", err.Error())
57+
}
58+
59+
sdkCtx := sdk.UnwrapSDKContext(ctx)
60+
61+
store := k.getAccountStoreForAddress(sdkCtx, address)
62+
accounts := make([]types.CtAccountWithDenom, 0)
63+
pageRes, err := query.Paginate(store, req.Pagination, func(denom, value []byte) error {
64+
65+
var ctAccount types.CtAccount
66+
err = k.cdc.Unmarshal(value, &ctAccount)
67+
if err != nil {
68+
return err
69+
}
70+
accounts = append(accounts, types.CtAccountWithDenom{Denom: string(denom), Account: ctAccount})
71+
return nil
72+
})
73+
74+
if err != nil {
75+
return nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err)
76+
}
77+
78+
return &types.GetAllCtAccountsResponse{Accounts: accounts, Pagination: pageRes}, nil
79+
80+
}

0 commit comments

Comments
 (0)