Skip to content

Commit

Permalink
added staking code, and spec dep
Browse files Browse the repository at this point in the history
  • Loading branch information
omerlavanet committed Mar 15, 2022
1 parent 9841acf commit e9241a7
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 43 deletions.
3 changes: 2 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,9 @@ func New(
app.BankKeeper,
app.AccountKeeper,
app.EvidenceKeeper,
app.SpecKeeper,
)
servicerModule := servicermodule.NewAppModule(appCodec, app.ServicerKeeper, app.AccountKeeper, app.BankKeeper)
servicerModule := servicermodule.NewAppModule(appCodec, app.ServicerKeeper, app.AccountKeeper, app.BankKeeper, app.SpecKeeper)

// this line is used by starport scaffolding # stargate/app/keeperDefinition

Expand Down
32 changes: 16 additions & 16 deletions vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,37 +263,37 @@ export default {
}
}
},
async sendMsgProofOfWork({ rootGetters }, { value, fee = [], memo = '' }) {
async sendMsgUnstakeServicer({ rootGetters }, { value, fee = [], memo = '' }) {
try {
const txClient = await initTxClient(rootGetters);
const msg = await txClient.msgProofOfWork(value);
const msg = await txClient.msgUnstakeServicer(value);
const result = await txClient.signAndBroadcast([msg], { fee: { amount: fee,
gas: "200000" }, memo });
return result;
}
catch (e) {
if (e == MissingWalletError) {
throw new SpVuexError('TxClient:MsgProofOfWork:Init', 'Could not initialize signing client. Wallet is required.');
throw new SpVuexError('TxClient:MsgUnstakeServicer:Init', 'Could not initialize signing client. Wallet is required.');
}
else {
throw new SpVuexError('TxClient:MsgProofOfWork:Send', 'Could not broadcast Tx: ' + e.message);
throw new SpVuexError('TxClient:MsgUnstakeServicer:Send', 'Could not broadcast Tx: ' + e.message);
}
}
},
async sendMsgUnstakeServicer({ rootGetters }, { value, fee = [], memo = '' }) {
async sendMsgProofOfWork({ rootGetters }, { value, fee = [], memo = '' }) {
try {
const txClient = await initTxClient(rootGetters);
const msg = await txClient.msgUnstakeServicer(value);
const msg = await txClient.msgProofOfWork(value);
const result = await txClient.signAndBroadcast([msg], { fee: { amount: fee,
gas: "200000" }, memo });
return result;
}
catch (e) {
if (e == MissingWalletError) {
throw new SpVuexError('TxClient:MsgUnstakeServicer:Init', 'Could not initialize signing client. Wallet is required.');
throw new SpVuexError('TxClient:MsgProofOfWork:Init', 'Could not initialize signing client. Wallet is required.');
}
else {
throw new SpVuexError('TxClient:MsgUnstakeServicer:Send', 'Could not broadcast Tx: ' + e.message);
throw new SpVuexError('TxClient:MsgProofOfWork:Send', 'Could not broadcast Tx: ' + e.message);
}
}
},
Expand All @@ -312,33 +312,33 @@ export default {
}
}
},
async MsgProofOfWork({ rootGetters }, { value }) {
async MsgUnstakeServicer({ rootGetters }, { value }) {
try {
const txClient = await initTxClient(rootGetters);
const msg = await txClient.msgProofOfWork(value);
const msg = await txClient.msgUnstakeServicer(value);
return msg;
}
catch (e) {
if (e == MissingWalletError) {
throw new SpVuexError('TxClient:MsgProofOfWork:Init', 'Could not initialize signing client. Wallet is required.');
throw new SpVuexError('TxClient:MsgUnstakeServicer:Init', 'Could not initialize signing client. Wallet is required.');
}
else {
throw new SpVuexError('TxClient:MsgProofOfWork:Create', 'Could not create message: ' + e.message);
throw new SpVuexError('TxClient:MsgUnstakeServicer:Create', 'Could not create message: ' + e.message);
}
}
},
async MsgUnstakeServicer({ rootGetters }, { value }) {
async MsgProofOfWork({ rootGetters }, { value }) {
try {
const txClient = await initTxClient(rootGetters);
const msg = await txClient.msgUnstakeServicer(value);
const msg = await txClient.msgProofOfWork(value);
return msg;
}
catch (e) {
if (e == MissingWalletError) {
throw new SpVuexError('TxClient:MsgUnstakeServicer:Init', 'Could not initialize signing client. Wallet is required.');
throw new SpVuexError('TxClient:MsgProofOfWork:Init', 'Could not initialize signing client. Wallet is required.');
}
else {
throw new SpVuexError('TxClient:MsgUnstakeServicer:Create', 'Could not create message: ' + e.message);
throw new SpVuexError('TxClient:MsgProofOfWork:Create', 'Could not create message: ' + e.message);
}
}
},
Expand Down
32 changes: 16 additions & 16 deletions vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,33 +321,33 @@ export default {
}
}
},
async sendMsgProofOfWork({ rootGetters }, { value, fee = [], memo = '' }) {
async sendMsgUnstakeServicer({ rootGetters }, { value, fee = [], memo = '' }) {
try {
const txClient=await initTxClient(rootGetters)
const msg = await txClient.msgProofOfWork(value)
const msg = await txClient.msgUnstakeServicer(value)
const result = await txClient.signAndBroadcast([msg], {fee: { amount: fee,
gas: "200000" }, memo})
return result
} catch (e) {
if (e == MissingWalletError) {
throw new SpVuexError('TxClient:MsgProofOfWork:Init', 'Could not initialize signing client. Wallet is required.')
throw new SpVuexError('TxClient:MsgUnstakeServicer:Init', 'Could not initialize signing client. Wallet is required.')
}else{
throw new SpVuexError('TxClient:MsgProofOfWork:Send', 'Could not broadcast Tx: '+ e.message)
throw new SpVuexError('TxClient:MsgUnstakeServicer:Send', 'Could not broadcast Tx: '+ e.message)
}
}
},
async sendMsgUnstakeServicer({ rootGetters }, { value, fee = [], memo = '' }) {
async sendMsgProofOfWork({ rootGetters }, { value, fee = [], memo = '' }) {
try {
const txClient=await initTxClient(rootGetters)
const msg = await txClient.msgUnstakeServicer(value)
const msg = await txClient.msgProofOfWork(value)
const result = await txClient.signAndBroadcast([msg], {fee: { amount: fee,
gas: "200000" }, memo})
return result
} catch (e) {
if (e == MissingWalletError) {
throw new SpVuexError('TxClient:MsgUnstakeServicer:Init', 'Could not initialize signing client. Wallet is required.')
throw new SpVuexError('TxClient:MsgProofOfWork:Init', 'Could not initialize signing client. Wallet is required.')
}else{
throw new SpVuexError('TxClient:MsgUnstakeServicer:Send', 'Could not broadcast Tx: '+ e.message)
throw new SpVuexError('TxClient:MsgProofOfWork:Send', 'Could not broadcast Tx: '+ e.message)
}
}
},
Expand All @@ -366,30 +366,30 @@ export default {
}
}
},
async MsgProofOfWork({ rootGetters }, { value }) {
async MsgUnstakeServicer({ rootGetters }, { value }) {
try {
const txClient=await initTxClient(rootGetters)
const msg = await txClient.msgProofOfWork(value)
const msg = await txClient.msgUnstakeServicer(value)
return msg
} catch (e) {
if (e == MissingWalletError) {
throw new SpVuexError('TxClient:MsgProofOfWork:Init', 'Could not initialize signing client. Wallet is required.')
throw new SpVuexError('TxClient:MsgUnstakeServicer:Init', 'Could not initialize signing client. Wallet is required.')
}else{
throw new SpVuexError('TxClient:MsgProofOfWork:Create', 'Could not create message: ' + e.message)
throw new SpVuexError('TxClient:MsgUnstakeServicer:Create', 'Could not create message: ' + e.message)

}
}
},
async MsgUnstakeServicer({ rootGetters }, { value }) {
async MsgProofOfWork({ rootGetters }, { value }) {
try {
const txClient=await initTxClient(rootGetters)
const msg = await txClient.msgUnstakeServicer(value)
const msg = await txClient.msgProofOfWork(value)
return msg
} catch (e) {
if (e == MissingWalletError) {
throw new SpVuexError('TxClient:MsgUnstakeServicer:Init', 'Could not initialize signing client. Wallet is required.')
throw new SpVuexError('TxClient:MsgProofOfWork:Init', 'Could not initialize signing client. Wallet is required.')
}else{
throw new SpVuexError('TxClient:MsgUnstakeServicer:Create', 'Could not create message: ' + e.message)
throw new SpVuexError('TxClient:MsgProofOfWork:Create', 'Could not create message: ' + e.message)

}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { StdFee } from "@cosmjs/launchpad";
import { Registry, OfflineSigner, EncodeObject } from "@cosmjs/proto-signing";
import { Api } from "./rest";
import { MsgStakeServicer } from "./types/servicer/tx";
import { MsgProofOfWork } from "./types/servicer/tx";
import { MsgUnstakeServicer } from "./types/servicer/tx";
import { MsgProofOfWork } from "./types/servicer/tx";
export declare const MissingWalletError: Error;
export declare const registry: Registry;
interface TxClientOptions {
Expand All @@ -16,8 +16,8 @@ interface SignAndBroadcastOptions {
declare const txClient: (wallet: OfflineSigner, { addr: addr }?: TxClientOptions) => Promise<{
signAndBroadcast: (msgs: EncodeObject[], { fee, memo }?: SignAndBroadcastOptions) => any;
msgStakeServicer: (data: MsgStakeServicer) => EncodeObject;
msgProofOfWork: (data: MsgProofOfWork) => EncodeObject;
msgUnstakeServicer: (data: MsgUnstakeServicer) => EncodeObject;
msgProofOfWork: (data: MsgProofOfWork) => EncodeObject;
}>;
interface QueryClientOptions {
addr: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { SigningStargateClient } from "@cosmjs/stargate";
import { Registry } from "@cosmjs/proto-signing";
import { Api } from "./rest";
import { MsgStakeServicer } from "./types/servicer/tx";
import { MsgProofOfWork } from "./types/servicer/tx";
import { MsgUnstakeServicer } from "./types/servicer/tx";
import { MsgProofOfWork } from "./types/servicer/tx";
const types = [
["/lavanet.lava.servicer.MsgStakeServicer", MsgStakeServicer],
["/lavanet.lava.servicer.MsgProofOfWork", MsgProofOfWork],
["/lavanet.lava.servicer.MsgUnstakeServicer", MsgUnstakeServicer],
["/lavanet.lava.servicer.MsgProofOfWork", MsgProofOfWork],
];
export const MissingWalletError = new Error("wallet is required");
export const registry = new Registry(types);
Expand All @@ -30,8 +30,8 @@ const txClient = async (wallet, { addr: addr } = { addr: "http://localhost:26657
return {
signAndBroadcast: (msgs, { fee, memo } = { fee: defaultFee, memo: "" }) => client.signAndBroadcast(address, msgs, fee, memo),
msgStakeServicer: (data) => ({ typeUrl: "/lavanet.lava.servicer.MsgStakeServicer", value: MsgStakeServicer.fromPartial(data) }),
msgProofOfWork: (data) => ({ typeUrl: "/lavanet.lava.servicer.MsgProofOfWork", value: MsgProofOfWork.fromPartial(data) }),
msgUnstakeServicer: (data) => ({ typeUrl: "/lavanet.lava.servicer.MsgUnstakeServicer", value: MsgUnstakeServicer.fromPartial(data) }),
msgProofOfWork: (data) => ({ typeUrl: "/lavanet.lava.servicer.MsgProofOfWork", value: MsgProofOfWork.fromPartial(data) }),
};
};
const queryClient = async ({ addr: addr } = { addr: "http://localhost:1317" }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { SigningStargateClient } from "@cosmjs/stargate";
import { Registry, OfflineSigner, EncodeObject, DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { Api } from "./rest";
import { MsgStakeServicer } from "./types/servicer/tx";
import { MsgProofOfWork } from "./types/servicer/tx";
import { MsgUnstakeServicer } from "./types/servicer/tx";
import { MsgProofOfWork } from "./types/servicer/tx";


const types = [
["/lavanet.lava.servicer.MsgStakeServicer", MsgStakeServicer],
["/lavanet.lava.servicer.MsgProofOfWork", MsgProofOfWork],
["/lavanet.lava.servicer.MsgUnstakeServicer", MsgUnstakeServicer],
["/lavanet.lava.servicer.MsgProofOfWork", MsgProofOfWork],

];
export const MissingWalletError = new Error("wallet is required");
Expand Down Expand Up @@ -46,8 +46,8 @@ const txClient = async (wallet: OfflineSigner, { addr: addr }: TxClientOptions =
return {
signAndBroadcast: (msgs: EncodeObject[], { fee, memo }: SignAndBroadcastOptions = {fee: defaultFee, memo: ""}) => client.signAndBroadcast(address, msgs, fee,memo),
msgStakeServicer: (data: MsgStakeServicer): EncodeObject => ({ typeUrl: "/lavanet.lava.servicer.MsgStakeServicer", value: MsgStakeServicer.fromPartial( data ) }),
msgProofOfWork: (data: MsgProofOfWork): EncodeObject => ({ typeUrl: "/lavanet.lava.servicer.MsgProofOfWork", value: MsgProofOfWork.fromPartial( data ) }),
msgUnstakeServicer: (data: MsgUnstakeServicer): EncodeObject => ({ typeUrl: "/lavanet.lava.servicer.MsgUnstakeServicer", value: MsgUnstakeServicer.fromPartial( data ) }),
msgProofOfWork: (data: MsgProofOfWork): EncodeObject => ({ typeUrl: "/lavanet.lava.servicer.MsgProofOfWork", value: MsgProofOfWork.fromPartial( data ) }),

};
};
Expand Down
5 changes: 3 additions & 2 deletions x/servicer/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type (
bankKeeper types.BankKeeper
accountKeeper types.AccountKeeper
evidenceKeeper types.EvidenceKeeper
specKeeper types.SpecKeeper
}
)

Expand All @@ -30,7 +31,7 @@ func NewKeeper(
memKey sdk.StoreKey,
ps paramtypes.Subspace,

bankKeeper types.BankKeeper, accountKeeper types.AccountKeeper, evidenceKeeper types.EvidenceKeeper,
bankKeeper types.BankKeeper, accountKeeper types.AccountKeeper, evidenceKeeper types.EvidenceKeeper, specKeeper types.SpecKeeper,
) *Keeper {
// set KeyTable if it has not already been set
if !ps.HasKeyTable() {
Expand All @@ -43,7 +44,7 @@ func NewKeeper(
storeKey: storeKey,
memKey: memKey,
paramstore: ps,
bankKeeper: bankKeeper, accountKeeper: accountKeeper, evidenceKeeper: evidenceKeeper,
bankKeeper: bankKeeper, accountKeeper: accountKeeper, evidenceKeeper: evidenceKeeper, specKeeper: specKeeper,
}
}

Expand Down
31 changes: 31 additions & 0 deletions x/servicer/keeper/msg_server_stake_servicer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
"context"
"errors"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/lavanet/lava/x/servicer/types"
Expand All @@ -10,6 +11,36 @@ import (
func (k msgServer) StakeServicer(goCtx context.Context, msg *types.MsgStakeServicer) (*types.MsgStakeServicerResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

specName := msg.Spec
err := specName.ValidateBasic() //TODO: basic validation, we dont want to read the entire spec list here
if err != nil {
return nil, err
}

foundAndActive := k.Keeper.specKeeper.IsSpecFoundAndActive(ctx, specName.Name)
if foundAndActive != true {
return nil, errors.New("spec not found or not enabled")
}
//if we get here, the spec is active and supported
//TODO: transfer stake from servicer
specStakeStorage, found := k.Keeper.GetSpecStakeStorage(ctx, specName.Name)
if found != true {
//this is the first servicer for the supported spec
// newSpecStakeStorage := types.SpecStakeStorage{
// Index: specName.Name,
// StakeStorage: stakeStorage,
// }
// k.Keeper.SetSpecStakeStorage(ctx, newSpecStakeStorage)
return nil, errors.New("specName not found in SpecStakeStorage")
} else {
stakeStorage := specStakeStorage.StakeStorage
//TODO: find if it already exists
// stakeStorage.Staked, types.StakeMap{
// Index: msg.Creator,
// Stake: msg.Amount,
// Deadline: msg.Deadline,
// }
}
// TODO: Handling the message
_ = ctx

Expand Down
3 changes: 3 additions & 0 deletions x/servicer/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,22 @@ type AppModule struct {
keeper keeper.Keeper
accountKeeper types.AccountKeeper
bankKeeper types.BankKeeper
specKeeper types.SpecKeeper
}

func NewAppModule(
cdc codec.Codec,
keeper keeper.Keeper,
accountKeeper types.AccountKeeper,
bankKeeper types.BankKeeper,
specKeeper types.SpecKeeper,
) AppModule {
return AppModule{
AppModuleBasic: NewAppModuleBasic(cdc),
keeper: keeper,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
specKeeper: specKeeper,
}
}

Expand Down
4 changes: 4 additions & 0 deletions x/servicer/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ type BankKeeper interface {
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
// Methods imported from bank should be defined here
}

type SpecKeeper interface {
IsSpecFoundAndActive(ctx sdk.Context, specName string) bool
}
9 changes: 9 additions & 0 deletions x/servicer/types/types.go
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
package types

import "errors"

func (specN *SpecName) ValidateBasic() error {
if len(specN.Name) > 100 {
return errors.New("invalid spec name string, length too big")
}
return nil
}
20 changes: 20 additions & 0 deletions x/spec/keeper/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,26 @@ func (k Keeper) GetAllSpec(ctx sdk.Context) (list []types.Spec) {
return
}

func (k Keeper) IsSpecFoundAndActive(ctx sdk.Context, specName string) bool {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.SpecKey))
iterator := sdk.KVStorePrefixIterator(store, []byte{})

defer iterator.Close()

for ; iterator.Valid(); iterator.Next() {
var val types.Spec
k.cdc.MustUnmarshal(iterator.Value(), &val)
if val.Name == specName {
if val.Status == "enabled" {
return true
}
// specs are unique, theres no reason to keep iterating
return false
}
}
return false
}

// GetSpecIDBytes returns the byte representation of the ID
func GetSpecIDBytes(id uint64) []byte {
bz := make([]byte, 8)
Expand Down

0 comments on commit e9241a7

Please sign in to comment.