forked from xuperchain/burrow
/
deterministic_genesis.go
94 lines (86 loc) · 2.75 KB
/
deterministic_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
package genesis
import (
"fmt"
"math/rand"
"time"
"github.com/hyperledger/burrow/acm"
"github.com/hyperledger/burrow/crypto"
"github.com/hyperledger/burrow/permission"
)
type deterministicGenesis struct {
random *rand.Rand
}
// Generates deterministic pseudo-random genesis state
func NewDeterministicGenesis(seed int64) *deterministicGenesis {
return &deterministicGenesis{
random: rand.New(rand.NewSource(seed)),
}
}
func (dg *deterministicGenesis) GenesisDoc(numAccounts int, randBalance bool, minBalance uint64, numValidators int,
randBonded bool, minBonded int64) (*GenesisDoc, []*acm.PrivateAccount, []*acm.PrivateAccount) {
accounts := make([]Account, numAccounts)
privAccounts := make([]*acm.PrivateAccount, numAccounts)
defaultPerms := permission.DefaultAccountPermissions
for i := 0; i < numAccounts; i++ {
account, privAccount := dg.Account(randBalance, minBalance)
acc := Account{
BasicAccount: BasicAccount{
Address: account.GetAddress(),
Amount: account.Balance,
},
Permissions: defaultPerms.Clone(), // This will get copied into each state.Account.
}
acc.Permissions.Base.Set(permission.Root, true)
accounts[i] = acc
privAccounts[i] = privAccount
}
validators := make([]Validator, numValidators)
privValidators := make([]*acm.PrivateAccount, numValidators)
for i := 0; i < numValidators; i++ {
validator := acm.GeneratePrivateAccountFromSecret(fmt.Sprintf("val_%v", i))
privValidators[i] = validator
validators[i] = Validator{
BasicAccount: BasicAccount{
Address: validator.GetAddress(),
PublicKey: validator.GetPublicKey(),
// Avoid max validator cap
Amount: uint64(dg.random.Int63()/16 + 1),
},
UnbondTo: []BasicAccount{
{
Address: validator.GetAddress(),
Amount: uint64(dg.random.Int63()),
},
},
}
}
return &GenesisDoc{
ChainName: "TestChain",
GenesisTime: time.Unix(1506172037, 0).UTC(),
Accounts: accounts,
Validators: validators,
}, privAccounts, privValidators
}
func (dg *deterministicGenesis) Account(randBalance bool, minBalance uint64) (*acm.Account, *acm.PrivateAccount) {
privateKey, err := crypto.GeneratePrivateKey(dg.random, crypto.CurveTypeEd25519)
if err != nil {
panic(fmt.Errorf("could not generate private key deterministically"))
}
privAccount := &acm.ConcretePrivateAccount{
PublicKey: privateKey.GetPublicKey(),
PrivateKey: privateKey,
Address: privateKey.GetPublicKey().GetAddress(),
}
perms := permission.DefaultAccountPermissions
acc := &acm.Account{
Address: privAccount.Address,
PublicKey: privAccount.PublicKey,
Sequence: uint64(dg.random.Int()),
Balance: minBalance,
Permissions: perms,
}
if randBalance {
acc.Balance += uint64(dg.random.Int())
}
return acc, privAccount.PrivateAccount()
}