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

feat: basic keeper implemenation #9

Merged
merged 12 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
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
198 changes: 198 additions & 0 deletions testutils/testutils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
package testutils

import (
"math/rand"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

feemarkettypes "github.com/skip-mev/feemarket/x/feemarket/types"
)

type EncodingConfig struct {
InterfaceRegistry types.InterfaceRegistry
Codec codec.Codec
TxConfig client.TxConfig
Amino *codec.LegacyAmino
}

func CreateTestEncodingConfig() EncodingConfig {
cdc := codec.NewLegacyAmino()
interfaceRegistry := types.NewInterfaceRegistry()

banktypes.RegisterInterfaces(interfaceRegistry)
cryptocodec.RegisterInterfaces(interfaceRegistry)
feemarkettypes.RegisterInterfaces(interfaceRegistry)
stakingtypes.RegisterInterfaces(interfaceRegistry)

codec := codec.NewProtoCodec(interfaceRegistry)

return EncodingConfig{
InterfaceRegistry: interfaceRegistry,
Codec: codec,
TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes),
Amino: cdc,
}
}

type Account struct {
PrivKey cryptotypes.PrivKey
PubKey cryptotypes.PubKey
Address sdk.AccAddress
ConsKey cryptotypes.PrivKey
}

func (acc Account) Equals(acc2 Account) bool {
return acc.Address.Equals(acc2.Address)
}

func RandomAccounts(r *rand.Rand, n int) []Account {
accs := make([]Account, n)

for i := 0; i < n; i++ {
pkSeed := make([]byte, 15)
r.Read(pkSeed)

accs[i].PrivKey = secp256k1.GenPrivKeyFromSecret(pkSeed)
accs[i].PubKey = accs[i].PrivKey.PubKey()
accs[i].Address = sdk.AccAddress(accs[i].PubKey.Address())

accs[i].ConsKey = ed25519.GenPrivKeyFromSecret(pkSeed)
}

return accs
}

func CreateTx(txCfg client.TxConfig, account Account, nonce, timeout uint64, msgs []sdk.Msg, fees ...sdk.Coin) (authsigning.Tx, error) {
aljo242 marked this conversation as resolved.
Show resolved Hide resolved
txBuilder := txCfg.NewTxBuilder()
if err := txBuilder.SetMsgs(msgs...); err != nil {
return nil, err
}

sigV2 := signing.SignatureV2{
PubKey: account.PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: nonce,
}
if err := txBuilder.SetSignatures(sigV2); err != nil {
return nil, err
}

txBuilder.SetTimeoutHeight(timeout)

txBuilder.SetFeeAmount(fees)

return txBuilder.GetTx(), nil
}

func CreateFreeTx(txCfg client.TxConfig, account Account, nonce, timeout uint64, validator string, amount sdk.Coin, fees ...sdk.Coin) (authsigning.Tx, error) {
msgs := []sdk.Msg{
&stakingtypes.MsgDelegate{
DelegatorAddress: account.Address.String(),
ValidatorAddress: validator,
Amount: amount,
},
}

return CreateTx(txCfg, account, nonce, timeout, msgs, fees...)
}

func CreateRandomTx(txCfg client.TxConfig, account Account, nonce, numberMsgs, timeout uint64, gasLimit uint64, fees ...sdk.Coin) (authsigning.Tx, error) {
msgs := make([]sdk.Msg, numberMsgs)
for i := 0; i < int(numberMsgs); i++ {
msgs[i] = &banktypes.MsgSend{
FromAddress: account.Address.String(),
ToAddress: account.Address.String(),
}
}

txBuilder := txCfg.NewTxBuilder()
if err := txBuilder.SetMsgs(msgs...); err != nil {
return nil, err
}

sigV2 := signing.SignatureV2{
PubKey: account.PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: nonce,
}
if err := txBuilder.SetSignatures(sigV2); err != nil {
return nil, err
}

txBuilder.SetTimeoutHeight(timeout)

txBuilder.SetFeeAmount(fees)

txBuilder.SetGasLimit(gasLimit)

return txBuilder.GetTx(), nil
}
aljo242 marked this conversation as resolved.
Show resolved Hide resolved

func CreateRandomTxBz(txCfg client.TxConfig, account Account, nonce, numberMsgs, timeout, gasLimit uint64) ([]byte, error) {
tx, err := CreateRandomTx(txCfg, account, nonce, numberMsgs, timeout, gasLimit)
if err != nil {
return nil, err
}

return txCfg.TxEncoder()(tx)
}

func CreateTxWithSigners(txCfg client.TxConfig, nonce, timeout uint64, signers []Account) (authsigning.Tx, error) {
msgs := []sdk.Msg{}
for _, signer := range signers {
msg := CreateRandomMsgs(signer.Address, 1)
msgs = append(msgs, msg...)
}

txBuilder := txCfg.NewTxBuilder()
if err := txBuilder.SetMsgs(msgs...); err != nil {
return nil, err
}

sigV2 := signing.SignatureV2{
PubKey: signers[0].PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: nonce,
}

if err := txBuilder.SetSignatures(sigV2); err != nil {
return nil, err
}

txBuilder.SetTimeoutHeight(timeout)

return txBuilder.GetTx(), nil
}

func CreateRandomMsgs(acc sdk.AccAddress, numberMsgs int) []sdk.Msg {
msgs := make([]sdk.Msg, numberMsgs)
for i := 0; i < numberMsgs; i++ {
msgs[i] = &banktypes.MsgSend{
FromAddress: acc.String(),
ToAddress: acc.String(),
}
}

return msgs
}
134 changes: 134 additions & 0 deletions x/feemarket/keeper/keeper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package keeper

import (
"fmt"

"github.com/cometbft/cometbft/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/skip-mev/feemarket/x/feemarket/interfaces"
"github.com/skip-mev/feemarket/x/feemarket/types"
)

type Keeper struct {
cdc codec.BinaryCodec
storeKey storetypes.StoreKey

// plugin is the fee market implementation to be used.
plugin interfaces.FeeMarketImplementation

// The address that is capable of executing a MsgParams message.
// Typically, this will be the governance module's address.
authority string
}

// NewKeeper is a wrapper around NewKeeperWithRewardsAddressProvider for backwards compatibility.
aljo242 marked this conversation as resolved.
Show resolved Hide resolved
func NewKeeper(
cdc codec.BinaryCodec,
storeKey storetypes.StoreKey,
plugin interfaces.FeeMarketImplementation,
authority string,
) *Keeper {
k := &Keeper{
cdc,
storeKey,
plugin,
authority,
}

return k
}

// Logger returns a feemarket module-specific logger.
func (k *Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+types.ModuleName)
}

// GetAuthority returns the address that is capable of executing a MsgUpdateParams message.
func (k *Keeper) GetAuthority() string {
return k.authority
}

// Plugin returns the plugged fee market implementation of the keeper.
func (k *Keeper) Plugin() interfaces.FeeMarketImplementation {
return k.plugin
}

// SetFeeMarket sets the fee market implementation data in the keeper.
func (k *Keeper) SetFeeMarket(ctx sdk.Context, fm interfaces.FeeMarketImplementation) error {
bz, err := fm.Marshal()
if err != nil {
return fmt.Errorf("unable to marshal fee market implemenation: %w", err)
}

k.setData(ctx, bz)
k.plugin = fm

return nil
}

// GetFeeMarket gets the fee market implementation data in the keeper. Will
func (k *Keeper) GetFeeMarket(ctx sdk.Context) (interfaces.FeeMarketImplementation, error) {
bz, err := k.getData(ctx)
if err != nil {
return nil, err
}

err = k.plugin.Unmarshal(bz)
return k.plugin, err
}

// setData sets arbitrary byte data in the keeper.
func (k *Keeper) setData(ctx sdk.Context, data []byte) {
// TODO: limit max data size?

store := ctx.KVStore(k.storeKey)
store.Set(types.KeyData, data)
}

// getData gets arbitrary byte data in the keeper.
func (k *Keeper) getData(ctx sdk.Context) ([]byte, error) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.KeyData)

if len(bz) == 0 {
return nil, fmt.Errorf("no data set in the keeper")
}

return bz, nil
}

// GetParams returns the feemarket module's parameters.
func (k *Keeper) GetParams(ctx sdk.Context) (types.Params, error) {
store := ctx.KVStore(k.storeKey)

key := types.KeyParams
bz := store.Get(key)

if len(bz) == 0 {
return types.Params{}, fmt.Errorf("no params found for the feemarket module")
}

params := types.Params{}
if err := params.Unmarshal(bz); err != nil {
return types.Params{}, err
}

return params, nil
}

// SetParams sets the feemarket module's parameters.
func (k *Keeper) SetParams(ctx sdk.Context, params types.Params) error {
store := ctx.KVStore(k.storeKey)

bz, err := params.Marshal()
if err != nil {
return err
}

store.Set(types.KeyParams, bz)

return nil
}
Loading
Loading