Skip to content

Commit

Permalink
feat: add NewSeed spam check and default proposal checks
Browse files Browse the repository at this point in the history
  • Loading branch information
hacheigriega committed Dec 21, 2023
1 parent e72c03f commit aedfc40
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 78 deletions.
17 changes: 7 additions & 10 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import (
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/std"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/mempool"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
Expand Down Expand Up @@ -305,12 +304,7 @@ func NewApp(
std.RegisterLegacyAminoCodec(legacyAmino)
std.RegisterInterfaces(interfaceRegistry)

// TO-DO
// building BaseApp
nonceMempool := mempool.NewSenderNonceMempool()
mempoolOpt := baseapp.SetMempool(nonceMempool)
baseAppOptions = append(baseAppOptions, mempoolOpt)

bApp := baseapp.NewBaseApp(Name, logger, db, txConfig.TxDecoder(), baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetVersion(version.Version)
Expand Down Expand Up @@ -874,11 +868,15 @@ func NewApp(
if vrfKey == nil || err != nil {
// TO-DO if validator, panic
app.Logger().Info("failed to load vrf key")
vrfKey = nil
if err != nil {
app.Logger().Error(err.Error())
}
}

proposalHandler := randomnesskeeper.NewDefaultProposalHandler(bApp)

app.SetPrepareProposal(
randomnesskeeper.PrepareProposalHandler(
proposalHandler.PrepareProposalHandler(
txConfig,
vrfKey,
app.RandomnessKeeper,
Expand All @@ -888,8 +886,7 @@ func NewApp(
)

app.SetProcessProposal(
randomnesskeeper.ProcessProposalHandler(
txConfig,
proposalHandler.ProcessProposalHandler(
vrfKey,
app.RandomnessKeeper,
app.StakingKeeper,
Expand Down
17 changes: 7 additions & 10 deletions cmd/seda-chaind/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ import (
"path/filepath"
"strings"

"github.com/cosmos/go-bip39"
"github.com/pkg/errors"
"github.com/spf13/cobra"

cfg "github.com/cometbft/cometbft/config"
cmtos "github.com/cometbft/cometbft/libs/os"
"github.com/cometbft/cometbft/privval"
"github.com/cometbft/cometbft/types"

// "github.com/cometbft/cometbft/types"

"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/go-bip39"
"github.com/cosmos/cosmos-sdk/x/genutil/types"

"github.com/sedaprotocol/seda-chain/cmd/seda-chaind/utils"
)
Expand Down Expand Up @@ -76,16 +78,11 @@ func downloadAndApplyNetworkConfig(network, moniker string, config *cfg.Config)
}

// check genesis file
genFile := config.GenesisFile()
jsonBlob, err := os.ReadFile(genFile)
if err != nil {
return "", "", err
}
genDoc, err := types.GenesisDocFromJSON(jsonBlob)
appGenesis, err := types.AppGenesisFromFile(config.GenesisFile())
if err != nil {
return "", "", errors.Wrapf(err, "error reading GenesisDoc at %s", genFile)
return "", "", errors.Wrapf(err, "failed to read genesis doc file %s", config.GenesisFile())
}
chainID = genDoc.ChainID
chainID = appGenesis.ChainID

// obtain seeds from seeds file, if exists, and write to config file
seedsBytes, err := os.ReadFile(seedsFile)
Expand Down
6 changes: 3 additions & 3 deletions cmd/seda-chaind/cmd/init_cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,13 @@ $ %s init join moniker --network devnet

network, _ := cmd.Flags().GetString(FlagNetwork)
var seeds, chainID string
if network == "mainnet" || network == "devnet" || network == "testnet" || network == "localnet" {
switch network {
case "mainnet", "devnet", "testnet", "localnet":
chainID, seeds, err = downloadAndApplyNetworkConfig(network, args[0], config)
if err != nil {
return err
}
} else {
default:
return fmt.Errorf("unsupported network type: %s", network)
}

Expand Down Expand Up @@ -205,6 +206,5 @@ $ %s init join moniker --network devnet
if err != nil {
panic(err)
}

return cmd
}
5 changes: 5 additions & 0 deletions cmd/seda-chaind/utils/vrf_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type VRFSigner interface {
VRFVerify(publicKey, alpha, pi []byte) (beta []byte, err error)
SignTransaction(ctx sdk.Context, txBuilder client.TxBuilder, txConfig client.TxConfig,
signMode signing.SignMode, account sdk.AccountI) (signing.SignatureV2, error)
IsNil() bool
}

var _ VRFSigner = &VRFKey{}
Expand Down Expand Up @@ -150,6 +151,10 @@ func (v *VRFKey) SignTransaction(
return sigV2, nil
}

func (v *VRFKey) IsNil() bool {
return v == nil
}

// NewVRFKey generates a new VRFKey from the given key and key file path.
func NewVRFKey(privKey crypto.PrivKey, keyFilePath string) (*VRFKey, error) {
vrfStruct := vrf.NewK256VRF()
Expand Down
93 changes: 72 additions & 21 deletions x/randomness/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

abci "github.com/cometbft/cometbft/abci/types"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
txsigning "github.com/cosmos/cosmos-sdk/types/tx/signing"
Expand All @@ -15,24 +16,61 @@ import (
"github.com/sedaprotocol/seda-chain/x/randomness/types"
)

func PrepareProposalHandler(
type ProposalHandler struct {
txVerifier baseapp.ProposalTxVerifier
txSelector baseapp.TxSelector
}

func NewDefaultProposalHandler(txVerifier baseapp.ProposalTxVerifier) *ProposalHandler {
return &ProposalHandler{
txVerifier: txVerifier,
txSelector: baseapp.NewDefaultTxSelector(),
}
}

func (h *ProposalHandler) PrepareProposalHandler(
txConfig client.TxConfig,
vrfSigner utils.VRFSigner,
keeper Keeper,
authKeeper types.AccountKeeper,
stakingKeeper types.StakingKeeper,
) sdk.PrepareProposalHandler {
return func(ctx sdk.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) {
if vrfSigner == nil {
return &abci.ResponsePrepareProposal{Txs: [][]byte{}}, nil
if vrfSigner.IsNil() {
return nil, fmt.Errorf("vrf signer is nil")
}

// Default prepare proposal - check max block gas and req.MaxTxBytes
var maxBlockGas uint64
if b := ctx.ConsensusParams().Block; b != nil {
maxBlockGas = uint64(b.MaxGas)
}

// TO-DO run DefaultProposalHandler.PrepareProposalHandler first?
defer h.txSelector.Clear()

for _, txBz := range req.Txs {
tx, err := h.txVerifier.TxDecode(txBz)
if err != nil {
return nil, err
}

// do not include any NewSeed txs
_, ok := decodeNewSeedTx(tx)
if ok {
continue
}

stop := h.txSelector.SelectTxForProposal(ctx, uint64(req.MaxTxBytes), maxBlockGas, tx, txBz)
if stop {
break
}
}

// Seed transaction
// alpha = (seed_{i-1} || timestamp)
prevSeed := keeper.GetSeed(ctx)
if prevSeed == "" {
panic("seed should never be empty")
return nil, fmt.Errorf("previous seed is empty - this should never happen")
}
timestamp, err := req.Time.MarshalBinary()
if err != nil {
Expand All @@ -46,7 +84,7 @@ func PrepareProposalHandler(
return nil, err
}

// create a NewSeed tx
// generate and sign NewSeed tx
pubKey, err := keeper.GetValidatorVRFPubKey(ctx, sdk.ConsAddress(req.ProposerAddress).String())
if err != nil {
return nil, err
Expand All @@ -67,20 +105,40 @@ func PrepareProposalHandler(

// prepend to list of txs and return
res := new(abci.ResponsePrepareProposal)
res.Txs = append([][]byte{newSeedTx}, req.Txs...)
res.Txs = append([][]byte{newSeedTx}, h.txSelector.SelectedTxs(ctx)...)
return res, nil
}
}

func ProcessProposalHandler(
txConfig client.TxConfig,
func (h *ProposalHandler) ProcessProposalHandler(
vrfSigner utils.VRFSigner,
keeper Keeper,
stakingKeeper types.StakingKeeper,
) sdk.ProcessProposalHandler {
return func(ctx sdk.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) {
msg, err := decodeNewSeedTx(txConfig, req.Txs[0])
defer h.txSelector.Clear()

for _, txBz := range req.Txs[1:] {
tx, err := h.txVerifier.TxDecode(txBz)
if err != nil {
return nil, err
}

// reject proposal that includes NewSeed tx in any position other
// than top of tx list
_, ok := decodeNewSeedTx(tx)
if ok {
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, err
}
}

tx, err := h.txVerifier.TxDecode(req.Txs[0])
if err != nil {
return nil, err
}

msg, ok := decodeNewSeedTx(tx)
if !ok {
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, err
}

Expand All @@ -89,9 +147,6 @@ func ProcessProposalHandler(
fmt.Errorf("the NewSeed transaction must be from the block proposer")
}

// TO-DO run DefaultProposalHandler.ProcessProposalHandler first?
// TO-DO Validate()?

// get block proposer's validator public key
pubKey, err := keeper.GetValidatorVRFPubKey(ctx, sdk.ConsAddress(req.ProposerAddress).String())
if err != nil {
Expand Down Expand Up @@ -165,18 +220,14 @@ func generateAndSignNewSeedTx(ctx sdk.Context, txConfig client.TxConfig, vrfSign
return txBytes, nil
}

func decodeNewSeedTx(txConfig client.TxConfig, txBytes []byte) (*types.MsgNewSeed, error) {
tx, err := txConfig.TxDecoder()(txBytes)
if err != nil {
return nil, err
}
func decodeNewSeedTx(tx sdk.Tx) (*types.MsgNewSeed, bool) {
msgs := tx.GetMsgs()
if len(msgs) != 1 {
return nil, err
return nil, false
}
msgNewSeed, ok := msgs[0].(*types.MsgNewSeed)
if !ok {
return nil, err
return nil, false
}
return msgNewSeed, nil
return msgNewSeed, true
}
16 changes: 2 additions & 14 deletions x/randomness/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,10 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer {
var _ types.MsgServer = msgServer{}

func (k msgServer) NewSeed(goCtx context.Context, msg *types.MsgNewSeed) (*types.MsgNewSeedResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// TO-DO spam prevention?

k.Keeper.SetSeed(ctx, msg.Beta)
sdkCtx := sdk.UnwrapSDKContext(goCtx)
k.Keeper.SetSeed(sdkCtx, msg.Beta)

// TO-DO event?
// err = ctx.EventManager().EmitTypedEvent(
// &types.EventNewSeed{
// Hash: hashString,
// WasmType: msg.WasmType,
// Bytecode: msg.Wasm,
// })
// if err != nil {
// return nil, err
// }

return &types.MsgNewSeedResponse{}, nil
}
20 changes: 0 additions & 20 deletions x/randomness/types/tx.go

This file was deleted.

5 changes: 5 additions & 0 deletions x/staking/types/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking/types"
)

var (
_ sdk.Msg = &MsgCreateValidatorWithVRF{}
_ codectypes.UnpackInterfacesMessage = (*MsgCreateValidatorWithVRF)(nil)
)

// NewMsgCreateValidator creates a new MsgCreateValidator instance.
// Delegator address and validator address are the same.
func NewMsgCreateValidatorWithVRF(
Expand Down

0 comments on commit aedfc40

Please sign in to comment.