Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CT-1195] add keeper methods and msg server implementation #2285

Merged
merged 4 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@ export interface MsgRemoveAuthenticatorResponseSDKType {
/** MsgSetActiveState sets the active state of the module. */

export interface MsgSetActiveState {
sender: string;
/** Authority is the address that may send this message. */
authority: string;
active: boolean;
}
/** MsgSetActiveState sets the active state of the module. */

export interface MsgSetActiveStateSDKType {
sender: string;
/** Authority is the address that may send this message. */
authority: string;
active: boolean;
}
/** MsgSetActiveStateResponse defines the Msg/SetActiveState response type. */
Expand Down Expand Up @@ -323,15 +325,15 @@ export const MsgRemoveAuthenticatorResponse = {

function createBaseMsgSetActiveState(): MsgSetActiveState {
return {
sender: "",
authority: "",
active: false
};
}

export const MsgSetActiveState = {
encode(message: MsgSetActiveState, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.sender !== "") {
writer.uint32(10).string(message.sender);
if (message.authority !== "") {
writer.uint32(10).string(message.authority);
}

if (message.active === true) {
Expand All @@ -351,7 +353,7 @@ export const MsgSetActiveState = {

switch (tag >>> 3) {
case 1:
message.sender = reader.string();
message.authority = reader.string();
break;

case 2:
Expand All @@ -369,7 +371,7 @@ export const MsgSetActiveState = {

fromPartial(object: DeepPartial<MsgSetActiveState>): MsgSetActiveState {
const message = createBaseMsgSetActiveState();
message.sender = object.sender ?? "";
message.authority = object.authority ?? "";
message.active = object.active ?? false;
return message;
}
Expand Down
6 changes: 4 additions & 2 deletions proto/dydxprotocol/accountplus/tx.proto
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
syntax = "proto3";
package dydxprotocol.accountplus;

import "cosmos_proto/cosmos.proto";
import "cosmos/msg/v1/msg.proto";
import "amino/amino.proto";

Expand Down Expand Up @@ -50,9 +51,10 @@ message MsgRemoveAuthenticatorResponse { bool success = 1; }
// MsgSetActiveState sets the active state of the module.
message MsgSetActiveState {
option (amino.name) = "osmosis/smartaccount/set-active-state";
option (cosmos.msg.v1.signer) = "sender";
option (cosmos.msg.v1.signer) = "authority";

string sender = 1;
// Authority is the address that may send this message.
string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just updated the name of this field to Authority for consistency with other gov controlled messages

bool active = 2;
}

Expand Down
3 changes: 3 additions & 0 deletions protocol/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,9 @@ func New(
appCodec,
keys[accountplusmoduletypes.StoreKey],
app.AuthenticatorManager,
[]string{
lib.GovModuleAddress.String(),
},
)
accountplusModule := accountplusmodule.NewAppModule(appCodec, app.AccountPlusKeeper)

Expand Down
4 changes: 4 additions & 0 deletions protocol/testutil/ante/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
txtestutil "github.com/cosmos/cosmos-sdk/x/auth/tx/testutil"
"github.com/cosmos/cosmos-sdk/x/bank"
v4module "github.com/dydxprotocol/v4-chain/protocol/app/module"
"github.com/dydxprotocol/v4-chain/protocol/lib"
"github.com/dydxprotocol/v4-chain/protocol/x/accountplus/authenticator"
accountpluskeeper "github.com/dydxprotocol/v4-chain/protocol/x/accountplus/keeper"
accountplustypes "github.com/dydxprotocol/v4-chain/protocol/x/accountplus/types"
Expand Down Expand Up @@ -116,6 +117,9 @@ func SetupTestSuite(t testing.TB, isCheckTx bool) *AnteTestSuite {
suite.EncCfg.Codec,
keys[accountplustypes.StoreKey],
authenticator.NewAuthenticatorManager(),
[]string{
lib.GovModuleAddress.String(),
},
)

// We're using TestMsg encoding in some tests, so register it here.
Expand Down
4 changes: 4 additions & 0 deletions protocol/testutil/keeper/accountplus.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
dbm "github.com/cosmos/cosmos-db"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/dydxprotocol/v4-chain/protocol/lib"
"github.com/dydxprotocol/v4-chain/protocol/x/revshare/types"

storetypes "cosmossdk.io/store/types"
Expand Down Expand Up @@ -57,6 +58,9 @@ func createTimestampNonceKeeper(
cdc,
storeKey,
authenticator.NewAuthenticatorManager(),
[]string{
lib.GovModuleAddress.String(),
},
)

return k, storeKey, mockTimeProvider
Expand Down
108 changes: 108 additions & 0 deletions protocol/x/accountplus/keeper/authenticators.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package keeper

import (
"fmt"
"strconv"

"cosmossdk.io/errors"
"cosmossdk.io/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
gogotypes "github.com/cosmos/gogoproto/types"
"github.com/dydxprotocol/v4-chain/protocol/x/accountplus/types"
)

// AddAuthenticator adds an authenticator to an account, this function is used to add multiple
// authenticators such as SignatureVerifications and AllOfs
func (k Keeper) AddAuthenticator(
ctx sdk.Context,
account sdk.AccAddress,
authenticatorType string,
config []byte,
) (uint64, error) {
impl := k.authenticatorManager.GetAuthenticatorByType(authenticatorType)
if impl == nil {
return 0, fmt.Errorf("authenticator type %s is not registered", authenticatorType)
}

// Get the next global id value for authenticators from the store
id := k.InitializeOrGetNextAuthenticatorId(ctx)

// Each authenticator has a custom OnAuthenticatorAdded function
err := impl.OnAuthenticatorAdded(ctx, account, config, strconv.FormatUint(id, 10))
if err != nil {
return 0, errors.Wrapf(err, "`OnAuthenticatorAdded` failed on authenticator type %s", authenticatorType)
}

k.SetNextAuthenticatorId(ctx, id+1)

store := prefix.NewStore(
ctx.KVStore(k.storeKey),
[]byte(types.AuthenticatorKeyPrefix),
)
authenticator := types.AccountAuthenticator{
Id: id,
Type: authenticatorType,
Config: config,
}
b := k.cdc.MustMarshal(&authenticator)
store.Set(types.KeyAccountId(account, id), b)
return id, nil
}

// RemoveAuthenticator removes an authenticator from an account
func (k Keeper) RemoveAuthenticator(ctx sdk.Context, account sdk.AccAddress, authenticatorId uint64) error {
store := prefix.NewStore(
ctx.KVStore(k.storeKey),
[]byte(types.AuthenticatorKeyPrefix),
)
key := types.KeyAccountId(account, authenticatorId)

var existing types.AccountAuthenticator
bz := store.Get(key)
if bz == nil {
return errors.Wrapf(
types.ErrAuthenticatorNotFound,
"RemoveAuthenticator: failed to get authenticator %d for address %s",
authenticatorId,
account.String(),
)
}
k.cdc.MustUnmarshal(bz, &existing)

impl := k.authenticatorManager.GetAuthenticatorByType(existing.Type)
if impl == nil {
return fmt.Errorf("authenticator type %s is not registered", existing.Type)
}

// Authenticators can prevent removal. This should be used sparingly
err := impl.OnAuthenticatorRemoved(ctx, account, existing.Config, strconv.FormatUint(authenticatorId, 10))
if err != nil {
return errors.Wrapf(err, "`OnAuthenticatorRemoved` failed on authenticator type %s", existing.Type)
}

store.Delete(key)
return nil
}

// InitializeOrGetNextAuthenticatorId returns the next authenticator id.
func (k Keeper) InitializeOrGetNextAuthenticatorId(ctx sdk.Context) uint64 {
store := ctx.KVStore(k.storeKey)

b := store.Get([]byte(types.AuthenticatorIdKeyPrefix))
if b == nil {
return 0
}

result := gogotypes.UInt64Value{Value: 0}
k.cdc.MustUnmarshal(b, &result)
return result.Value
}

// SetNextAuthenticatorId sets next authenticator id.
func (k Keeper) SetNextAuthenticatorId(ctx sdk.Context, authenticatorId uint64) {
value := gogotypes.UInt64Value{Value: authenticatorId}
b := k.cdc.MustMarshal(&value)

store := ctx.KVStore(k.storeKey)
store.Set([]byte(types.AuthenticatorIdKeyPrefix), b)
}
14 changes: 11 additions & 3 deletions protocol/x/accountplus/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/dydxprotocol/v4-chain/protocol/lib"
"github.com/dydxprotocol/v4-chain/protocol/x/accountplus/authenticator"
"github.com/dydxprotocol/v4-chain/protocol/x/accountplus/types"
)
Expand All @@ -18,18 +19,20 @@ type Keeper struct {
storeKey storetypes.StoreKey

authenticatorManager *authenticator.AuthenticatorManager
authorities map[string]struct{}
}

func NewKeeper(
cdc codec.BinaryCodec,
key storetypes.StoreKey,
authenticatorManager *authenticator.AuthenticatorManager,
authorities []string,
) *Keeper {
return &Keeper{
cdc: cdc,
storeKey: key,

cdc: cdc,
storeKey: key,
authenticatorManager: authenticatorManager,
authorities: lib.UniqueSliceToSet(authorities),
}
}

Expand Down Expand Up @@ -118,3 +121,8 @@ func (k Keeper) SetAccountState(
bz := k.cdc.MustMarshal(&accountState)
store.Set(address.Bytes(), bz)
}

func (k Keeper) HasAuthority(authority string) bool {
_, ok := k.authorities[authority]
return ok
}
Loading
Loading