-
Notifications
You must be signed in to change notification settings - Fork 211
/
genesis.go
146 lines (128 loc) · 4.34 KB
/
genesis.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package config
import (
"encoding/json"
"fmt"
"os"
"strconv"
"time"
"github.com/google/go-cmp/cmp"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/common/util"
"github.com/spacemeshos/go-spacemesh/hash"
"github.com/spacemeshos/go-spacemesh/log"
"github.com/spacemeshos/go-spacemesh/signing"
)
// GenesisConfig contains immutable parameters for the protocol.
type GenesisConfig struct {
GenesisTime string `mapstructure:"genesis-time"`
ExtraData string `mapstructure:"genesis-extra-data"`
Accounts map[string]uint64 `mapstructure:"accounts"`
}
// GenesisID computes genesis id from GenesisTime and ExtraData.
func (g *GenesisConfig) GenesisID() types.Hash20 {
return g.GoldenATX().ToHash20()
}
func (g *GenesisConfig) GoldenATX() types.Hash32 {
hh := hash.New()
parsed, err := time.Parse(time.RFC3339, g.GenesisTime)
if err != nil {
panic("code should have run Validate before this method")
}
hh.Write([]byte(strconv.FormatInt(parsed.Unix(), 10)))
hh.Write([]byte(g.ExtraData))
return types.BytesToHash(hh.Sum(nil))
}
// Validate GenesisConfig.
func (g *GenesisConfig) Validate() error {
if len(g.ExtraData) == 0 {
return fmt.Errorf("wait until genesis-extra-data is available")
}
if len(g.ExtraData) > 255 {
return fmt.Errorf("extra-data is longer than 255 symbols: %s", g.ExtraData)
}
_, err := time.Parse(time.RFC3339, g.GenesisTime)
if err != nil {
return fmt.Errorf("can't parse genesis time %s using time.RFC3339(%s) %w",
g.GenesisTime, time.RFC3339, err)
}
return nil
}
// Diff returns difference between two configs.
func (g *GenesisConfig) Diff(other *GenesisConfig) string {
return cmp.Diff(g, other)
}
// LoadFromFile loads config from file.
func (g *GenesisConfig) LoadFromFile(filename string) error {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
return json.NewDecoder(f).Decode(g)
}
// WriteToFile writes config content to file.
func (g *GenesisConfig) WriteToFile(filename string) error {
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
return err
}
defer f.Close()
return json.NewEncoder(f).Encode(g)
}
// ToAccounts creates list of types.Account instance from config.
func (g *GenesisConfig) ToAccounts() []types.Account {
var rst []types.Account
for addr, balance := range g.Accounts {
genesisAddr, err := types.StringToAddress(addr)
if err != nil {
log.Panic("could not create address from genesis config `%s`: %s", addr, err.Error())
}
rst = append(rst, types.Account{
Address: genesisAddr,
Balance: balance,
})
}
return rst
}
// Account1Private is the private key for test account.
const Account1Private = "0x2dcddb8e0ddd2269f536da5768e890790f2b84366e0fb8396bdcd15c0d7c30b90002abedccd3ffcbf46f35f11b314d17c05a2905f918d0d72f2f6989640fbb43"
// Account2Private is the private key for second test account.
const Account2Private = "0x0bb3f2936d42f463e597f5fb2c48bbd8475ce74ba91f1eaae97df4084d306b49feaf3d38b6ef430933ebedeb073af7bec018e8d2e379fa47df6a9fa07a6a8344"
// DefaultGenesisConfig is the default configuration for the node.
func DefaultGenesisConfig() *GenesisConfig {
// NOTE(dshulyak) keys in default config are used in some tests
return &GenesisConfig{
ExtraData: "mainnet",
GenesisTime: time.Now().Format(time.RFC3339),
Accounts: generateGenesisAccounts(),
}
}
// DefaultTestGenesisConfig is the default test configuration for the node.
func DefaultTestGenesisConfig() *GenesisConfig {
// NOTE(dshulyak) keys in default config are used in some tests
return &GenesisConfig{
ExtraData: "testnet",
GenesisTime: time.Now().Format(time.RFC3339),
Accounts: generateGenesisAccounts(),
}
}
func generateGenesisAccounts() map[string]uint64 {
acc1Signer, err := signing.NewEdSigner(
signing.WithPrivateKey(util.FromHex(Account1Private)),
)
if err != nil {
panic("could not build ed signer")
}
acc2Signer, err := signing.NewEdSigner(
signing.WithPrivateKey(util.FromHex(Account2Private)),
)
if err != nil {
panic("could not build ed signer")
}
// we default to 10^8 SMH per account which is 10^17 smidge
// each genesis account starts off with 10^17 smidge
return map[string]uint64{
types.GenerateAddress(acc1Signer.PublicKey().Bytes()).String(): 100000000000000000,
types.GenerateAddress(acc2Signer.PublicKey().Bytes()).String(): 100000000000000000,
}
}