Skip to content

Commit

Permalink
Extend the genesis.json to include clique initial signers (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranbt authored Sep 18, 2023
1 parent fe3bc4e commit 8baaded
Showing 1 changed file with 60 additions and 6 deletions.
66 changes: 60 additions & 6 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"os"
"path/filepath"
godebug "runtime/debug"
"sort"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -2258,16 +2259,69 @@ func MakeConsolePreloads(ctx *cli.Context) []string {
return preloads
}

// jsonGenesis is an extension over the traditional Geth genesis file
type jsonGenesis struct {
core *core.Genesis `json:"-"`

Config struct {
Clique struct {
// Signers is the list of initial validators of the clique protocol
InitialSigners []string `json:"initial_signers"`
} `json:"clique,omitempty"`
} `json:"config"`
}

func readJSONGenesis(genesisPath string) (*jsonGenesis, error) {
genesisRaw, err := os.ReadFile(genesisPath)
if err != nil {
return nil, err
}

coreGenesis := new(core.Genesis)
if err := json.Unmarshal(genesisRaw, coreGenesis); err != nil {
return nil, fmt.Errorf("invalid genesis file: %v", err)
}

genesis := new(jsonGenesis)
if err := json.Unmarshal(genesisRaw, genesis); err != nil {
return nil, fmt.Errorf("invalid genesis file: %v", err)
}

genesis.core = coreGenesis
return genesis, nil
}

// initCustomGenesis is a simplified version of the initGenesis command
func initCustomGenesis(ctx *cli.Context, stack *node.Node, genesisPath string) (*core.Genesis, common.Hash, error) {
genesisRaw, err := os.ReadFile(genesisPath)
genesis, err := readJSONGenesis(genesisPath)
if err != nil {
return nil, common.Hash{}, err
}

genesis := new(core.Genesis)
if err := json.Unmarshal(genesisRaw, genesis); err != nil {
return nil, common.Hash{}, fmt.Errorf("invalid genesis file: %v", err)
// if we are running Clique, read the initial validator set from the Config.Clique.Signers path
// and build the extra genesis data as [(32 byte), signer1, signer2, (65 byte)] where the
// signers are sorted by their address
if genesis.core.Config.Clique != nil {
signersStr := genesis.Config.Clique.InitialSigners
if len(signersStr) == 0 {
return nil, common.Hash{}, fmt.Errorf("no initial signers for Clique")
}

signers := make([]common.Address, len(signersStr))
for i, signerStr := range signersStr {
signers[i] = common.HexToAddress(signerStr)
}

sort.Slice(signers, func(i, j int) bool {
return bytes.Compare(signers[i][:], signers[j][:]) < 0
})

extra := make([]byte, 32)
for _, addr := range signers {
extra = append(extra, addr.Bytes()...)
}
extra = append(extra, make([]byte, 65)...)
genesis.core.ExtraData = extra
}

chaindb, err := stack.OpenDatabaseWithFreezer("chaindata", 0, 0, ctx.String(AncientFlag.Name), "", false)
Expand All @@ -2277,12 +2331,12 @@ func initCustomGenesis(ctx *cli.Context, stack *node.Node, genesisPath string) (
triedb := trie.NewDatabaseWithConfig(chaindb, &trie.Config{
Preimages: false,
})
_, hash, err := core.SetupGenesisBlock(chaindb, triedb, genesis)
_, hash, err := core.SetupGenesisBlock(chaindb, triedb, genesis.core)
if err != nil {
return nil, common.Hash{}, err
}
chaindb.Close()

log.Info("Successfully wrote genesis state", "database", "chaindata", "hash", hash)
return genesis, hash, nil
return genesis.core, hash, nil
}

0 comments on commit 8baaded

Please sign in to comment.