Squash merge develop into master

This commit is contained in:
Prad Nukala
2024-09-14 14:27:45 -04:00
parent a929e61d01
commit 05bda3d1b2
227 changed files with 56902 additions and 10178 deletions
+60
View File
@@ -0,0 +1,60 @@
package keeper
import (
"context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/onsonr/sonr/x/did/builder"
"github.com/onsonr/sonr/x/did/types"
"google.golang.org/grpc/peer"
)
type Context struct {
SDKCtx sdk.Context
Keeper Keeper
Peer *peer.Peer
}
func (k Keeper) CurrentCtx(goCtx context.Context) Context {
ctx := sdk.UnwrapSDKContext(goCtx)
peer, _ := peer.FromContext(goCtx)
return Context{SDKCtx: ctx, Peer: peer, Keeper: k}
}
func (c Context) Params() *types.Params {
return c.Keeper.GetParams(c.SDK())
}
func (c Context) SDK() sdk.Context {
return c.SDKCtx
}
func (c Context) IsAnonymous() bool {
if c.Peer == nil {
return true
}
return c.Peer.Addr == nil
}
func (c Context) PeerID() string {
if c.Peer == nil {
return ""
}
return c.Peer.Addr.String()
}
func (c Context) GetService(origin string) (*types.Service, error) {
rec, err := c.Keeper.OrmDB.ServiceRecordTable().GetByOrigin(c.SDK(), origin)
if err != nil {
return nil, err
}
return builder.ModuleFormatAPIServiceRecord(rec), nil
}
func (c Context) GetServiceInfo(origin string) *types.ServiceInfo {
rec, _ := c.GetService(origin)
if rec == nil {
return &types.ServiceInfo{Exists: false, Origin: origin, Fingerprint: types.ComputeOriginTXTRecord(origin)}
}
return &types.ServiceInfo{Exists: true, Origin: origin, Fingerprint: types.ComputeOriginTXTRecord(origin), Service: rec}
}
+40 -1
View File
@@ -2,9 +2,12 @@ package keeper
import (
"context"
"time"
"cosmossdk.io/log"
"github.com/onsonr/hway/x/did/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/onsonr/sonr/x/did/types"
)
// Logger returns the logger
@@ -35,3 +38,39 @@ func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState {
Params: params,
}
}
// CheckValidatorExists checks if a validator exists
func (k Keeper) CheckValidatorExists(ctx sdk.Context, addr string) bool {
address, err := sdk.ValAddressFromBech32(addr)
if err != nil {
return false
}
ok, err := k.StakingKeeper.Validator(ctx, address)
if err != nil {
return false
}
if ok != nil {
return true
}
return false
}
// GetAverageBlockTime returns the average block time in seconds
func (k Keeper) GetAverageBlockTime(ctx sdk.Context) float64 {
return float64(ctx.BlockTime().Sub(ctx.BlockTime()).Seconds())
}
// GetParams returns the module parameters.
func (k Keeper) GetParams(ctx sdk.Context) *types.Params {
p, err := k.Params.Get(ctx)
if err != nil {
p = types.DefaultParams()
}
params := p.ActiveParams(k.HasIPFSConnection())
return &params
}
// GetExpirationBlockHeight returns the block height at which the given duration will have passed
func (k Keeper) GetExpirationBlockHeight(ctx sdk.Context, duration time.Duration) int64 {
return ctx.BlockHeight() + int64(duration.Seconds()/k.GetAverageBlockTime(ctx))
}
+1 -2
View File
@@ -5,7 +5,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/onsonr/hway/x/did/types"
"github.com/onsonr/sonr/x/did/types"
)
func TestGenesis(t *testing.T) {
@@ -20,7 +20,6 @@ func TestGenesis(t *testing.T) {
err := f.k.InitGenesis(f.ctx, genesisState)
require.NoError(t, err)
got := f.k.ExportGenesis(f.ctx)
require.NotNil(t, got)
+106
View File
@@ -0,0 +1,106 @@
package keeper
import (
"context"
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ipfs/boxo/files"
"github.com/ipfs/boxo/path"
"github.com/ipfs/kubo/client/rpc"
"github.com/ipfs/kubo/core/coreiface/options"
"github.com/onsonr/sonr/internal/vfs"
)
// assembleInitialVault assembles the initial vault
func (k Keeper) assembleInitialVault(ctx sdk.Context) (string, int64, error) {
cid, err := k.ipfsClient.Unixfs().Add(context.Background(), vfs.AssembleDirectory())
if err != nil {
return "", 0, err
}
return cid.String(), k.GetExpirationBlockHeight(ctx, time.Second*15), nil
}
// pinInitialVault pins the initial vault to the local IPFS node
func (k Keeper) pinInitialVault(_ sdk.Context, cid string, address string) (bool, error) {
// Resolve the path
path, err := path.NewPath(cid)
if err != nil {
return false, err
}
// 1. Initialize vault.db sqlite database in local IPFS with Mount
// 2. Insert the InitialWalletAccounts
// 3. Publish the path to the IPNS
_, err = k.ipfsClient.Name().Publish(context.Background(), path, options.Name.Key(address))
if err != nil {
return false, err
}
// 4. Insert the accounts into x/auth
// 5. Insert the controller into state
return true, nil
}
// GetFromIPFS gets a file from the local IPFS node
func (k Keeper) GetFromIPFS(ctx sdk.Context, cid string) (files.Directory, error) {
path, err := path.NewPath(cid)
if err != nil {
return nil, err
}
node, err := k.ipfsClient.Unixfs().Get(ctx, path)
if err != nil {
return nil, err
}
dir, ok := node.(files.Directory)
if !ok {
return nil, fmt.Errorf("retrieved node is not a directory")
}
return dir, nil
}
// HasIPFSConnection returns true if the IPFS client is initialized
func (k *Keeper) HasIPFSConnection() bool {
if k.ipfsClient == nil {
ipfsClient, err := rpc.NewLocalApi()
if err != nil {
return false
}
k.ipfsClient = ipfsClient
}
return k.ipfsClient != nil
}
// HasPathInIPFS checks if a file is in the local IPFS node
func (k Keeper) HasPathInIPFS(ctx sdk.Context, cid string) (bool, error) {
path, err := path.NewPath(cid)
if err != nil {
return false, err
}
v, err := k.ipfsClient.Unixfs().Get(ctx, path)
if err != nil {
return false, err
}
if v == nil {
return false, nil
}
return true, nil
}
// PinToIPFS pins a file to the local IPFS node
func (k Keeper) PinToIPFS(ctx sdk.Context, cid string, name string) error {
path, err := path.NewPath(cid)
if err != nil {
return err
}
err = k.ipfsClient.Pin().Add(ctx, path, options.Pin.Name(name))
if err != nil {
return err
}
return nil
}
+87 -9
View File
@@ -5,13 +5,18 @@ import (
storetypes "cosmossdk.io/core/store"
"cosmossdk.io/log"
"cosmossdk.io/orm/model/ormdb"
nftkeeper "cosmossdk.io/x/nft/keeper"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
apiv1 "github.com/onsonr/hway/api/did/v1"
"github.com/onsonr/hway/x/did/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
stakkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/ipfs/kubo/client/rpc"
apiv1 "github.com/onsonr/sonr/api/did/v1"
"github.com/onsonr/sonr/x/did/types"
)
// Keeper defines the middleware keeper.
@@ -26,18 +31,32 @@ type Keeper struct {
Schema collections.Schema
AccountKeeper authkeeper.AccountKeeper
NftKeeper nftkeeper.Keeper
StakingKeeper *stakkeeper.Keeper
authority string
authority string
ipfsClient *rpc.HttpApi
}
// NewKeeper creates a new poa Keeper instance
func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService, accKeeper authkeeper.AccountKeeper, logger log.Logger, authority string) Keeper {
func NewKeeper(
cdc codec.BinaryCodec,
storeService storetypes.KVStoreService,
accKeeper authkeeper.AccountKeeper,
nftKeeper nftkeeper.Keeper,
stkKeeper *stakkeeper.Keeper,
logger log.Logger,
authority string,
) Keeper {
logger = logger.With(log.ModuleKey, "x/"+types.ModuleName)
sb := collections.NewSchemaBuilder(storeService)
if authority == "" {
authority = authtypes.NewModuleAddress(govtypes.ModuleName).String()
}
db, err := ormdb.NewModuleDB(&types.ORMModuleSchema, ormdb.ModuleDBOptions{KVStoreService: storeService})
db, err := ormdb.NewModuleDB(
&types.ORMModuleSchema,
ormdb.ModuleDBOptions{KVStoreService: storeService},
)
if err != nil {
panic(err)
}
@@ -45,13 +64,24 @@ func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService, ac
if err != nil {
panic(err)
}
// Initialize IPFS client
ipfsClient, _ := rpc.NewLocalApi()
k := Keeper{
cdc: cdc,
logger: logger,
Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)),
ipfsClient: ipfsClient,
cdc: cdc,
logger: logger,
Params: collections.NewItem(
sb,
types.ParamsKey,
"params",
codec.CollValue[types.Params](cdc),
),
authority: authority,
OrmDB: store,
AccountKeeper: accKeeper,
NftKeeper: nftKeeper,
StakingKeeper: stkKeeper,
}
schema, err := sb.Build()
if err != nil {
@@ -61,3 +91,51 @@ func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService, ac
k.Schema = schema
return k
}
// IsClaimedServiceOrigin checks if a service origin is unclaimed
func (k Keeper) IsUnclaimedServiceOrigin(ctx sdk.Context, origin string) bool {
rec, _ := k.OrmDB.ServiceRecordTable().GetByOrigin(ctx, origin)
return rec == nil
}
// IsValidServiceOrigin checks if a service origin is valid
func (k Keeper) IsValidServiceOrigin(ctx sdk.Context, origin string) bool {
rec, err := k.OrmDB.ServiceRecordTable().GetByOrigin(ctx, origin)
if err != nil {
return false
}
if rec == nil {
return false
}
return true
}
// VerifyMinimumStake checks if a validator has a minimum stake
func (k Keeper) VerifyMinimumStake(ctx sdk.Context, addr string) bool {
address, err := sdk.AccAddressFromBech32(addr)
if err != nil {
return false
}
addval, err := sdk.ValAddressFromBech32(addr)
if err != nil {
return false
}
del, err := k.StakingKeeper.GetDelegation(ctx, address, addval)
if err != nil {
return false
}
if del.Shares.IsZero() {
return false
}
return del.Shares.IsPositive()
}
// VerifyServicePermissions checks if a service has permission
func (k Keeper) VerifyServicePermissions(
ctx sdk.Context,
addr string,
service string,
permissions string,
) bool {
return false
}
+11 -12
View File
@@ -3,12 +3,10 @@ package keeper_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"cosmossdk.io/core/store"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
nftkeeper "cosmossdk.io/x/nft/keeper"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
@@ -23,13 +21,13 @@ import (
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"cosmossdk.io/core/store"
module "github.com/onsonr/hway/x/did"
"github.com/onsonr/hway/x/did/keeper"
"github.com/onsonr/hway/x/did/types"
"github.com/strangelove-ventures/poa"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
module "github.com/onsonr/sonr/x/did"
"github.com/onsonr/sonr/x/did/keeper"
"github.com/onsonr/sonr/x/did/types"
)
var maccPerms = map[string][]string{
@@ -51,6 +49,7 @@ type testFixture struct {
accountkeeper authkeeper.AccountKeeper
bankkeeper bankkeeper.BaseKeeper
nftKeeper nftkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
mintkeeper mintkeeper.Keeper
@@ -80,10 +79,10 @@ func SetupTest(t *testing.T) *testFixture {
registerBaseSDKModules(f, encCfg, storeService, logger, require)
// Setup POA Keeper.
f.k = keeper.NewKeeper(encCfg.Codec, storeService, f.accountkeeper, logger, f.govModAddr)
f.k = keeper.NewKeeper(encCfg.Codec, storeService, f.accountkeeper, f.nftKeeper, f.stakingKeeper, logger, f.govModAddr)
f.msgServer = keeper.NewMsgServerImpl(f.k)
f.queryServer = keeper.NewQuerier(f.k)
f.appModule = module.NewAppModule(encCfg.Codec, f.k)
f.appModule = module.NewAppModule(encCfg.Codec, f.k, f.nftKeeper)
return f
}
+58 -13
View File
@@ -3,10 +3,7 @@ package keeper
import (
"context"
sdk "github.com/cosmos/cosmos-sdk/types"
// "github.com/onsonr/hway/internal/local"
"github.com/onsonr/hway/x/did/types"
"github.com/onsonr/sonr/x/did/types"
)
var _ types.QueryServer = Querier{}
@@ -20,17 +17,65 @@ func NewQuerier(keeper Keeper) Querier {
}
// Params returns the total set of did parameters.
func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
p, err := k.Keeper.Params.Get(ctx)
if err != nil {
return nil, err
}
return &types.QueryParamsResponse{Params: &p}, nil
func (k Querier) Params(
goCtx context.Context,
req *types.QueryRequest,
) (*types.QueryParamsResponse, error) {
ctx := k.CurrentCtx(goCtx)
return &types.QueryParamsResponse{Params: k.GetParams(ctx.SDK())}, nil
}
// Resolve implements types.QueryServer.
func (k Querier) Resolve(
goCtx context.Context,
req *types.QueryRequest,
) (*types.QueryResponse, error) {
ctx := k.CurrentCtx(goCtx)
return &types.QueryResponse{Params: k.GetParams(ctx.SDK())}, nil
}
// Service implements types.QueryServer.
func (k Querier) Service(
goCtx context.Context,
req *types.QueryRequest,
) (*types.QueryResponse, error) {
ctx := k.CurrentCtx(goCtx)
return &types.QueryResponse{Service: ctx.GetServiceInfo(req.GetOrigin()), Params: ctx.Params()}, nil
}
// ParamsAssets implements types.QueryServer.
func (k Querier) ParamsAssets(goCtx context.Context, req *types.QueryRequest) (*types.QueryResponse, error) {
// ctx := sdk.UnwrapSDKContext(goCtx)
panic("ParamsAssets is unimplemented")
return &types.QueryResponse{}, nil
}
// ParamsByAsset implements types.QueryServer.
func (k Querier) ParamsByAsset(goCtx context.Context, req *types.QueryRequest) (*types.QueryResponse, error) {
// ctx := sdk.UnwrapSDKContext(goCtx)
panic("ParamsByAsset is unimplemented")
return &types.QueryResponse{}, nil
}
// ParamsKeys implements types.QueryServer.
func (k Querier) ParamsKeys(goCtx context.Context, req *types.QueryRequest) (*types.QueryResponse, error) {
// ctx := sdk.UnwrapSDKContext(goCtx)
panic("ParamsKeys is unimplemented")
return &types.QueryResponse{}, nil
}
// ParamsByKey implements types.QueryServer.
func (k Querier) ParamsByKey(goCtx context.Context, req *types.QueryRequest) (*types.QueryResponse, error) {
// ctx := sdk.UnwrapSDKContext(goCtx)
panic("ParamsByKey is unimplemented")
return &types.QueryResponse{}, nil
}
// RegistrationOptionsByKey implements types.QueryServer.
func (k Querier) RegistrationOptionsByKey(goCtx context.Context, req *types.QueryRequest) (*types.QueryResponse, error) {
// ctx := sdk.UnwrapSDKContext(goCtx)
panic("RegistrationOptionsByKey is unimplemented")
return &types.QueryResponse{}, nil
// Accounts implements types.QueryServer.
func (k Querier) Accounts(goCtx context.Context, req *types.QueryAccountsRequest) (*types.QueryAccountsResponse, error) {
// ctx := sdk.UnwrapSDKContext(goCtx)
+107 -4
View File
@@ -2,6 +2,14 @@ package keeper
import (
"context"
"encoding/json"
"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/onsonr/sonr/x/did/builder"
"github.com/onsonr/sonr/x/did/types"
sdk "github.com/cosmos/cosmos-sdk/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
@@ -22,12 +30,107 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &msgServer{k: keeper}
}
// UpdateParams updates the x/did module parameters.
func (ms msgServer) UpdateParams(ctx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
if ms.k.authority != msg.Authority {
return nil, errors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", ms.k.authority, msg.Authority)
// # AuthorizeService
//
// AuthorizeService implements types.MsgServer.
func (ms msgServer) AuthorizeService(goCtx context.Context, msg *types.MsgAuthorizeService) (*types.MsgAuthorizeServiceResponse, error) {
if ms.k.authority != msg.Controller {
return nil, errors.Wrapf(
govtypes.ErrInvalidSigner,
"invalid authority; expected %s, got %s",
ms.k.authority,
msg.Controller,
)
}
return &types.MsgAuthorizeServiceResponse{}, nil
}
// # AllocateVault
//
// AllocateVault implements types.MsgServer.
func (ms msgServer) AllocateVault(
goCtx context.Context,
msg *types.MsgAllocateVault,
) (*types.MsgAllocateVaultResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// 1.Check if the service origin is valid
if ms.k.IsValidServiceOrigin(ctx, msg.Origin) {
return nil, types.ErrInvalidServiceOrigin
}
cid, expiryBlock, err := ms.k.assembleInitialVault(ctx)
if err != nil {
return nil, err
}
regOpts, err := builder.GetPublicKeyCredentialCreationOptions(msg.Origin, msg.Subject, cid, ms.k.GetParams(ctx))
if err != nil {
return nil, err
}
// Convert to string
regOptsJSON, err := json.Marshal(regOpts)
if err != nil {
return nil, err
}
return &types.MsgAllocateVaultResponse{
ExpiryBlock: expiryBlock,
Cid: cid,
RegistrationOptions: string(regOptsJSON),
}, nil
}
// # RegisterController
//
// RegisterController implements types.MsgServer.
func (ms msgServer) RegisterController(
goCtx context.Context,
msg *types.MsgRegisterController,
) (*types.MsgRegisterControllerResponse, error) {
_ = sdk.UnwrapSDKContext(goCtx)
return &types.MsgRegisterControllerResponse{}, nil
}
// # RegisterService
//
// RegisterService implements types.MsgServer.
func (ms msgServer) RegisterService(
goCtx context.Context,
msg *types.MsgRegisterService,
) (*types.MsgRegisterServiceResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// 1.Check if the service origin is valid
if !ms.k.IsValidServiceOrigin(ctx, msg.Service.Origin) {
return nil, types.ErrInvalidServiceOrigin
}
return ms.k.insertService(ctx, msg.Service)
}
// # SyncController
//
// SyncController implements types.MsgServer.
func (ms msgServer) SyncController(ctx context.Context, msg *types.MsgSyncController) (*types.MsgSyncControllerResponse, error) {
// ctx := sdk.UnwrapSDKContext(goCtx)
return &types.MsgSyncControllerResponse{}, nil
}
// # UpdateParams
//
// UpdateParams updates the x/did module parameters.
func (ms msgServer) UpdateParams(
ctx context.Context,
msg *types.MsgUpdateParams,
) (*types.MsgUpdateParamsResponse, error) {
if ms.k.authority != msg.Authority {
return nil, errors.Wrapf(
govtypes.ErrInvalidSigner,
"invalid authority; expected %s, got %s",
ms.k.authority,
msg.Authority,
)
}
return nil, ms.k.Params.Set(ctx, msg.Params)
}
-55
View File
@@ -1,55 +0,0 @@
package keeper_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/onsonr/hway/x/did/types"
)
func TestParams(t *testing.T) {
f := SetupTest(t)
require := require.New(t)
testCases := []struct {
name string
request *types.MsgUpdateParams
err bool
}{
{
name: "fail; invalid authority",
request: &types.MsgUpdateParams{
Authority: f.addrs[0].String(),
Params: types.DefaultParams(),
},
err: true,
},
{
name: "success",
request: &types.MsgUpdateParams{
Authority: f.govModAddr,
Params: types.DefaultParams(),
},
err: false,
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
_, err := f.msgServer.UpdateParams(f.ctx, tc.request)
if tc.err {
require.Error(err)
} else {
require.NoError(err)
r, err := f.queryServer.Params(f.ctx, &types.QueryParamsRequest{})
require.NoError(err)
require.EqualValues(&tc.request.Params, r.Params)
}
})
}
}
+21
View File
@@ -1,5 +1,26 @@
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/onsonr/sonr/x/did/builder"
"github.com/onsonr/sonr/x/did/types"
)
// insertService inserts a service record into the database
func (k Keeper) insertService(
ctx sdk.Context,
svc *types.Service,
) (*types.MsgRegisterServiceResponse, error) {
record := builder.APIFormatServiceRecord(svc)
err := k.OrmDB.ServiceRecordTable().Insert(ctx, record)
if err != nil {
return nil, err
}
return &types.MsgRegisterServiceResponse{
Success: true,
Did: record.Id,
}, nil
func (k Keeper) insertAliasFromDisplayName() {
}