Skip to content

Commit

Permalink
Add keyType to the ValidatorType and GenesisLeader config
Browse files Browse the repository at this point in the history
  • Loading branch information
charithabandi committed Jan 9, 2025
1 parent 41a698f commit 2d8ad62
Show file tree
Hide file tree
Showing 37 changed files with 568 additions and 274 deletions.
11 changes: 6 additions & 5 deletions app/node/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (

"github.com/kwilteam/kwil-db/common"
"github.com/kwilteam/kwil-db/config"
"github.com/kwilteam/kwil-db/core/crypto"
"github.com/kwilteam/kwil-db/core/crypto/auth"
ktypes "github.com/kwilteam/kwil-db/core/types"
"github.com/kwilteam/kwil-db/extensions/precompiles"
Expand Down Expand Up @@ -55,8 +54,9 @@ func buildServer(ctx context.Context, d *coreDependencies) *server {
valSet := make(map[string]ktypes.Validator)
for _, v := range d.genesisCfg.Validators {
valSet[hex.EncodeToString(v.PubKey)] = ktypes.Validator{
PubKey: v.PubKey,
Power: v.Power,
PubKey: v.PubKey,
PubKeyType: v.PubKeyType,
Power: v.Power,
}
}

Expand Down Expand Up @@ -403,9 +403,10 @@ func buildMigrator(d *coreDependencies, db *pg.DB, accounts *accounts.Accounts,

func buildConsensusEngine(_ context.Context, d *coreDependencies, db *pg.DB,
mempool *mempool.Mempool, bs *store.BlockStore, bp *blockprocessor.BlockProcessor, valSet map[string]ktypes.Validator) *consensus.ConsensusEngine {
leaderPubKey, err := crypto.UnmarshalSecp256k1PublicKey(d.genesisCfg.Leader)

leaderPubKey, err := config.DecodeLeader(d.genesisCfg.Leader)
if err != nil {
failBuild(err, "failed to parse leader public key")
failBuild(err, "failed to decode leader public key")
}

ceCfg := &consensus.Config{
Expand Down
5 changes: 3 additions & 2 deletions app/node/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ func (m *migrationClient) downloadGenesisState(ctx context.Context) error {
if len(m.genesisCfg.Validators) == 0 {
for _, v := range metadata.GenesisInfo.Validators {
m.genesisCfg.Validators = append(m.genesisCfg.Validators, &types.Validator{
PubKey: v.PubKey,
Power: v.Power,
PubKey: v.PubKey,
PubKeyType: v.PubKeyType,
Power: v.Power,
})
}
} else {
Expand Down
8 changes: 5 additions & 3 deletions app/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,12 @@ func loadGenesisAndPrivateKey(rootDir string, autogen bool) (privKey crypto.Priv
}

genCfg = config.DefaultGenesisConfig()
genCfg.Leader = privKey.Public().Bytes()
leader := fmt.Sprintf("%s#%d", hex.EncodeToString(privKey.Public().Bytes()), privKey.Type())
genCfg.Leader = leader
genCfg.Validators = append(genCfg.Validators, &types.Validator{
PubKey: privKey.Public().Bytes(),
Power: 1,
PubKey: privKey.Public().Bytes(),
PubKeyType: privKey.Type(),
Power: 1,
})
if err := genCfg.SaveAs(genFile); err != nil {
return nil, nil, fmt.Errorf("failed to write genesis file in autogen mode %s: %w", genFile, err)
Expand Down
24 changes: 14 additions & 10 deletions app/setup/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/kwilteam/kwil-db/app/shared/display"
"github.com/kwilteam/kwil-db/config"
"github.com/kwilteam/kwil-db/core/crypto"
"github.com/kwilteam/kwil-db/core/types"
"github.com/kwilteam/kwil-db/node"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -104,7 +105,7 @@ func GenesisCmd() *cobra.Command {
// bindGenesisFlags binds the genesis configuration flags to the given command.
func bindGenesisFlags(cmd *cobra.Command, cfg *genesisFlagConfig) {
cmd.Flags().StringVar(&cfg.chainID, "chain-id", "", "chainID for the genesis.json file")
cmd.Flags().StringSliceVar(&cfg.validators, "validators", nil, "public keys and power of initial validator(s)")
cmd.Flags().StringSliceVar(&cfg.validators, "validators", nil, "public key, keyType and power of initial validator(s)") // accept: [pubkey1#keyType1:power1]
cmd.Flags().StringSliceVar(&cfg.allocs, "allocs", nil, "address and initial balance allocation(s)")
cmd.Flags().BoolVar(&cfg.withGas, "with-gas", false, "include gas costs in the genesis.json file")
cmd.Flags().StringVar(&cfg.leader, "leader", "", "public key of the block proposer")
Expand Down Expand Up @@ -133,7 +134,8 @@ func mergeGenesisFlags(conf *config.GenesisConfig, cmd *cobra.Command, flagCfg *
return nil, makeErr(fmt.Errorf("invalid format for validator, expected key:power, received: %s", v))
}

hexPub, err := hex.DecodeString(parts[0])
keyParts := strings.Split(parts[0], "#")
hexPub, err := hex.DecodeString(keyParts[0])
if err != nil {
return nil, makeErr(fmt.Errorf("invalid public key for validator: %s", parts[0]))
}
Expand All @@ -143,9 +145,16 @@ func mergeGenesisFlags(conf *config.GenesisConfig, cmd *cobra.Command, flagCfg *
return nil, makeErr(fmt.Errorf("invalid power for validator: %s", parts[1]))
}

// string to Int
keyType, err := strconv.ParseInt(keyParts[1], 10, 64)
if err != nil {
return nil, makeErr(fmt.Errorf("invalid power for validator: %s", keyParts[1]))
}

conf.Validators = append(conf.Validators, &types.Validator{
PubKey: hexPub,
Power: power,
PubKey: hexPub,
PubKeyType: crypto.KeyType(keyType),
Power: power,
})
}
}
Expand All @@ -172,12 +181,7 @@ func mergeGenesisFlags(conf *config.GenesisConfig, cmd *cobra.Command, flagCfg *
}

if cmd.Flags().Changed("leader") {
leaderHex, err := hex.DecodeString(flagCfg.leader)
if err != nil {
return nil, makeErr(fmt.Errorf("invalid public key for leader: %s", flagCfg.leader))
}

conf.Leader = leaderHex
conf.Leader = flagCfg.leader
}

if cmd.Flags().Changed("db-owner") {
Expand Down
9 changes: 6 additions & 3 deletions app/setup/init.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package setup

import (
"encoding/hex"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -125,10 +126,12 @@ func InitCmd() *cobra.Command {
return display.PrintErr(cmd, err)
}

genCfg.Leader = privKey.Public().Bytes()
leader := fmt.Sprintf("%s#%d", hex.EncodeToString(privKey.Public().Bytes()), privKey.Type())
genCfg.Leader = leader
genCfg.Validators = append(genCfg.Validators, &types.Validator{
PubKey: privKey.Public().Bytes(),
Power: 1,
PubKey: privKey.Public().Bytes(),
PubKeyType: privKey.Type(),
Power: 1,
})

// allocate some initial balance to validators if gas is enabled and
Expand Down
10 changes: 7 additions & 3 deletions app/setup/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package setup
import (
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"fmt"
"math/rand/v2"
"net"
Expand Down Expand Up @@ -143,9 +144,11 @@ func GenerateTestnetConfigs(cfg *TestnetConfig, opts *ConfigOpts) error {
if chainID == "" {
chainID = "kwil-testnet"
}

leader := fmt.Sprintf("%s#%d", hex.EncodeToString(leaderPub.Bytes()), leaderPub.Type())
genConfig := &config.GenesisConfig{
ChainID: chainID,
Leader: leaderPub.Bytes(), // rethink this so it can be different key types?
Leader: leader,
Validators: make([]*ktypes.Validator, cfg.NumVals),
DisabledGasCosts: true,
JoinExpiry: 14400,
Expand All @@ -157,8 +160,9 @@ func GenerateTestnetConfigs(cfg *TestnetConfig, opts *ConfigOpts) error {

for i := range cfg.NumVals {
genConfig.Validators[i] = &ktypes.Validator{
PubKey: keys[i].Public().Bytes(),
Power: 1,
PubKey: keys[i].Public().Bytes(),
PubKeyType: keys[i].Type(),
Power: 1,
}
}

Expand Down
1 change: 1 addition & 0 deletions app/snapshot/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ func PGDump(ctx context.Context, dbName, dbUser, dbPass, dbHost, dbPort string,
return -1, nil, nil, fmt.Errorf("failed to parse power: %w", err)
}

// TODO: update this once the keytype is added to the voters table
genCfg.Validators = append(genCfg.Validators, &types.Validator{
PubKey: voterID,
Power: power,
Expand Down
10 changes: 6 additions & 4 deletions app/validator/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,18 @@ type respValSets struct {
}

type valInfo struct {
PubKey string `json:"pubkey"`
Power int64 `json:"power"`
PubKey string `json:"pubkey"`
PubKeyType string `json:"pubkey_type"`
Power int64 `json:"power"`
}

func (r *respValSets) MarshalJSON() ([]byte, error) {
valInfos := make([]valInfo, len(r.Data))
for i, v := range r.Data {
valInfos[i] = valInfo{
PubKey: fmt.Sprintf("%x", v.PubKey),
Power: v.Power,
PubKey: fmt.Sprintf("%x", v.PubKey),
Power: v.Power,
PubKeyType: v.PubKeyType.String(),
}
}

Expand Down
5 changes: 3 additions & 2 deletions common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/kwilteam/kwil-db/config"
"github.com/kwilteam/kwil-db/core/crypto"
"github.com/kwilteam/kwil-db/core/log"
"github.com/kwilteam/kwil-db/core/types"
"github.com/kwilteam/kwil-db/node/types/sql"
Expand Down Expand Up @@ -142,15 +143,15 @@ type Accounts interface {
type Validators interface {
// GetValidatorPower retrieves the power of the given validator. If
// the validator does not exist, it will return 0.
GetValidatorPower(ctx context.Context, validator []byte) (int64, error)
GetValidatorPower(ctx context.Context, pubKey []byte, pubKeyType crypto.KeyType) (int64, error)
// GetValidators retrieves all validators.
GetValidators() []*types.Validator
// SetValidatorPower sets the power of a validator. If the target
// validator does not exist, it will be created with the given power.
// If set to 0, the target validator will be deleted, and will no
// longer be considered a validator. It will return an error if a
// negative power is given.
SetValidatorPower(ctx context.Context, tx sql.Executor, validator []byte, power int64) error
SetValidatorPower(ctx context.Context, tx sql.Executor, pubKey []byte, pubKeyType crypto.KeyType, power int64) error
}

// ExecutionOptions is contextual data that is passed to a procedure
Expand Down
4 changes: 3 additions & 1 deletion common/context.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package common

import "github.com/kwilteam/kwil-db/core/crypto"

// ChainContext provides context for all chain operations.
// Fields in ChainContext should never be mutated, except
// NetworkParameters can be deterministically mutated as part
Expand Down Expand Up @@ -30,7 +32,7 @@ type BlockContext struct {
// timestamps could result in security vulnerabilities.
Timestamp int64
// Proposer gets the proposer public key of the current block.
Proposer []byte
Proposer crypto.PublicKey
}

// MigrationContext provides context for all migration operations.
Expand Down
36 changes: 33 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package config

import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math/big"
"os"
"strconv"
"strings"
"time"

"github.com/kwilteam/kwil-db/core/crypto"
"github.com/kwilteam/kwil-db/core/log"
"github.com/kwilteam/kwil-db/core/types"

Expand Down Expand Up @@ -41,8 +46,9 @@ type GenesisAlloc map[string]*big.Int
type GenesisConfig struct {
ChainID string `json:"chain_id"`
InitialHeight int64 `json:"initial_height"`
// Leader is the leader's public key.
Leader types.HexBytes `json:"leader"`
// Leader is the leader's public key. It is of the format "pubkey#pubkeyType".
// PubkeyType is 0 for Secp256k1 and 1 for Ed25519.
Leader string `json:"leader"`
// Validators is the list of genesis validators (including the leader).
Validators []*types.Validator `json:"validators"`
// DBOwner is the owner of the database.
Expand Down Expand Up @@ -100,6 +106,30 @@ func (gc *GenesisConfig) SanityChecks() error {
return nil
}

func DecodeLeader(leader string) (crypto.PublicKey, error) {
parts := strings.Split(leader, "#")
if len(parts) != 2 {
return nil, errors.New("invalid leader config in genesis, expected pubkey#pubkeyType")
}

pubKeyStr, err := hex.DecodeString(parts[0])
if err != nil {
return nil, fmt.Errorf("error decoding leader public key: %s error: %s", parts[0], err)
}

pubKeyType, err := strconv.ParseInt(parts[1], 10, 64)
if err != nil {
return nil, fmt.Errorf("error parsing leader public key type: %s error: %s", parts[1], err)
}

pubKey, err := crypto.UnmarshalPublicKey(pubKeyStr, crypto.KeyType(pubKeyType))
if err != nil {
return nil, fmt.Errorf("error unmarshalling leader public key: %s error: %s", parts[0], err)
}

return pubKey, nil
}

type MigrationParams struct {
// StartHeight is the height from which the state from the old chain is to be migrated.
StartHeight int64 `json:"start_height"`
Expand Down Expand Up @@ -138,7 +168,7 @@ func DefaultGenesisConfig() *GenesisConfig {
return &GenesisConfig{
ChainID: "kwil-test-chain",
InitialHeight: 0,
Leader: types.HexBytes{},
Leader: "",
Validators: []*types.Validator{},
Allocs: make(map[string]*big.Int),
DisabledGasCosts: true,
Expand Down
14 changes: 10 additions & 4 deletions core/rpc/json/admin/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@
// and response objects.
package adminjson

import "github.com/kwilteam/kwil-db/core/types"
import (
"github.com/kwilteam/kwil-db/core/crypto"
"github.com/kwilteam/kwil-db/core/types"
)

type StatusRequest struct{}
type PeersRequest struct{}
type GetConfigRequest struct{}
type ApproveRequest struct {
PubKey []byte `json:"pubkey"`
PubKey []byte `json:"pubkey"`
PubKeyType crypto.KeyType `json:"pubkey_type"`
}
type JoinRequest struct{}
type LeaveRequest struct{}
type RemoveRequest struct {
PubKey []byte `json:"pubkey"`
PubKey []byte `json:"pubkey"`
PubKeyType crypto.KeyType `json:"pubkey_type"`
}
type JoinStatusRequest struct {
PubKey []byte `json:"pubkey"`
PubKey []byte `json:"pubkey"`
PubKeyType crypto.KeyType `json:"pubkey_type"`
}
type ListValidatorsRequest struct{}
type ListJoinRequestsRequest struct{}
Expand Down
8 changes: 6 additions & 2 deletions core/types/messages.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package types

import "time"
import (
"time"

"github.com/kwilteam/kwil-db/core/crypto"
)

// This file contains the messages exchanged between the consensus engine and the block processor.

type BlockExecRequest struct {
Height int64
Block *Block
BlockID Hash
Proposer []byte
Proposer crypto.PublicKey
}

type BlockExecResult struct {
Expand Down
3 changes: 3 additions & 0 deletions core/types/payloads.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"reflect"
"strconv"

"github.com/kwilteam/kwil-db/core/crypto"
"github.com/kwilteam/kwil-db/core/types/decimal"
"github.com/kwilteam/kwil-db/core/types/serialize"
)
Expand Down Expand Up @@ -522,6 +523,7 @@ func (v *ValidatorJoin) MarshalBinary() ([]byte, error) {
// ValidatorApprove is used to vote for a validators approval to join the network
type ValidatorApprove struct {
Candidate []byte
KeyType crypto.KeyType
}

func (v *ValidatorApprove) Type() PayloadType {
Expand All @@ -542,6 +544,7 @@ func (v *ValidatorApprove) MarshalBinary() ([]byte, error) {
// ValidatorRemove is used to vote for a validators removal from the network
type ValidatorRemove struct {
Validator []byte
KeyType crypto.KeyType
}

func (v *ValidatorRemove) Type() PayloadType {
Expand Down
Loading

0 comments on commit 2d8ad62

Please sign in to comment.