forked from zilm13/eth2-testnet-genesis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
merge.go
111 lines (96 loc) · 3.41 KB
/
merge.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"bufio"
"context"
"fmt"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/protolambda/zcli/util"
"github.com/protolambda/zrnt/eth2/beacon/common"
"github.com/protolambda/zrnt/eth2/beacon/merge"
"github.com/protolambda/ztyp/codec"
"github.com/protolambda/ztyp/tree"
"github.com/protolambda/ztyp/view"
"os"
"time"
)
type MergeGenesisCmd struct {
util.SpecOptions `ask:"."`
Eth1Config string `ask:"--eth1-config" help:"Path to config JSON for eth1"`
MnemonicsSrcFilePath string `ask:"--mnemonics" help:"File with YAML of key sources"`
StateOutputPath string `ask:"--state-output" help:"Output path for state file"`
TranchesDir string `ask:"--tranches-dir" help:"Directory to dump lists of pubkeys of each tranche in"`
}
func (g *MergeGenesisCmd) Help() string {
return "Create genesis state for post-merge beacon chain, from eth1 and eth2 configs"
}
func (g *MergeGenesisCmd) Default() {
g.SpecOptions.Default()
g.Eth1Config = "eth1_testnet.json"
g.MnemonicsSrcFilePath = "mnemonics.yaml"
g.StateOutputPath = "genesis.ssz"
g.TranchesDir = "tranches"
}
func (g *MergeGenesisCmd) Run(ctx context.Context, args ...string) error {
eth1Genesis, err := loadEth1GenesisConf(g.Eth1Config)
if err != nil {
return err
}
eth1Db := rawdb.NewMemoryDatabase()
eth1GenesisBlock := eth1Genesis.ToBlock(eth1Db)
spec, err := g.SpecOptions.Spec()
if err != nil {
return err
}
if err := os.MkdirAll(g.TranchesDir, 0777); err != nil {
return err
}
validators, err := loadValidatorKeys(spec, g.MnemonicsSrcFilePath, g.TranchesDir)
if err != nil {
return err
}
if uint64(len(validators)) < spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT {
fmt.Printf("WARNING: not enough validators for genesis. Key sources sum up to %d total. But need %d.\n", len(validators), spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT)
}
eth1BlockHash := common.Root(eth1GenesisBlock.Hash())
state := merge.NewBeaconStateView(spec)
if err := setupState(spec, state,
common.Timestamp(eth1Genesis.Timestamp),
eth1BlockHash, validators); err != nil {
return err
}
if err := state.SetLatestExecutionPayloadHeader(&common.ExecutionPayloadHeader{
BlockHash: eth1BlockHash,
ParentHash: common.Root(eth1GenesisBlock.ParentHash()),
CoinBase: common.Eth1Address(eth1GenesisBlock.Coinbase()),
StateRoot: common.Bytes32(eth1GenesisBlock.Root()),
Number: view.Uint64View(eth1GenesisBlock.NumberU64()),
GasLimit: view.Uint64View(eth1GenesisBlock.GasLimit()),
GasUsed: view.Uint64View(eth1GenesisBlock.GasUsed()),
Timestamp: common.Timestamp(eth1GenesisBlock.Time()),
ReceiptRoot: common.Bytes32(eth1GenesisBlock.ReceiptHash()),
LogsBloom: common.LogsBloom(eth1GenesisBlock.Bloom()),
// empty transactions root
TransactionsRoot: common.PayloadTransactionsType.DefaultNode().MerkleRoot(tree.GetHashFn()),
}); err != nil {
return err
}
t, err := state.GenesisTime()
if err != nil {
return err
}
fmt.Printf("eth2 genesis at %d + %d = %d (%s)\n", eth1Genesis.Timestamp, spec.GENESIS_DELAY, t, time.Unix(int64(t), 0).String())
fmt.Println("done preparing state, serializing SSZ now...")
f, err := os.OpenFile(g.StateOutputPath, os.O_CREATE|os.O_WRONLY, 0777)
if err != nil {
return err
}
defer f.Close()
buf := bufio.NewWriter(f)
defer buf.Flush()
w := codec.NewEncodingWriter(f)
if err := state.Serialize(w); err != nil {
return err
}
fmt.Println("done!")
return nil
}