This repository has been archived by the owner on Jul 6, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
helper.go
127 lines (109 loc) · 3.41 KB
/
helper.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
package certifiers
import (
"time"
crypto "github.com/tendermint/go-crypto"
lc "github.com/tendermint/light-client"
"github.com/tendermint/tendermint/types"
)
// Test Helper: ValKeys lets us simulate signing with many keys
type ValKeys []crypto.PrivKey
// GenValKeys produces an array of private keys to generate commits
func GenValKeys(n int) ValKeys {
res := make(ValKeys, n)
for i := range res {
res[i] = crypto.GenPrivKeyEd25519().Wrap()
}
return res
}
// Change replaces the key at index i
func (v ValKeys) Change(i int) ValKeys {
res := make(ValKeys, len(v))
copy(res, v)
res[i] = crypto.GenPrivKeyEd25519().Wrap()
return res
}
// Extend adds n more keys (to remove, just take a slice)
func (v ValKeys) Extend(n int) ValKeys {
extra := GenValKeys(n)
return append(v, extra...)
}
// GenSecValKeys produces an array of secp256k1 private keys to generate commits
func GenSecValKeys(n int) ValKeys {
res := make(ValKeys, n)
for i := range res {
res[i] = crypto.GenPrivKeySecp256k1().Wrap()
}
return res
}
// Extend adds n more secp256k1 keys (to remove, just take a slice)
func (v ValKeys) ExtendSec(n int) ValKeys {
extra := GenSecValKeys(n)
return append(v, extra...)
}
// ToValidators produces a list of validators from the set of keys
// The first key has weight `init` and it increases by `inc` every step
// so we can have all the same weight, or a simple linear distribution
// (should be enough for testing)
func (v ValKeys) ToValidators(init, inc int64) *types.ValidatorSet {
res := make([]*types.Validator, len(v))
for i, k := range v {
res[i] = types.NewValidator(k.PubKey(), init+int64(i)*inc)
}
return types.NewValidatorSet(res)
}
// SignHeader properly signs the header with all keys from first to last exclusive
func (v ValKeys) SignHeader(header *types.Header, first, last int) *types.Commit {
votes := make([]*types.Vote, len(v))
// we need this list to keep the ordering...
vset := v.ToValidators(1, 0)
// fill in the votes we want
for i := first; i < last; i++ {
vote := makeVote(header, vset, v[i])
votes[vote.ValidatorIndex] = vote
}
res := &types.Commit{
BlockID: types.BlockID{Hash: header.Hash()},
Precommits: votes,
}
return res
}
func makeVote(header *types.Header, vals *types.ValidatorSet, key crypto.PrivKey) *types.Vote {
addr := key.PubKey().Address()
idx, _ := vals.GetByAddress(addr)
vote := &types.Vote{
ValidatorAddress: addr,
ValidatorIndex: idx,
Height: header.Height,
Round: 1,
Type: types.VoteTypePrecommit,
BlockID: types.BlockID{Hash: header.Hash()},
}
// Sign it
signBytes := types.SignBytes(header.ChainID, vote)
vote.Signature = key.Sign(signBytes)
return vote
}
func GenHeader(chainID string, height int, txs types.Txs,
vals *types.ValidatorSet, appHash []byte) *types.Header {
return &types.Header{
ChainID: chainID,
Height: height,
Time: time.Now(),
NumTxs: len(txs),
// LastBlockID
// LastCommitHash
ValidatorsHash: vals.Hash(),
DataHash: txs.Hash(),
AppHash: appHash,
}
}
// GenCheckpoint calls GenHeader and SignHeader and combines them into a Checkpoint
func (v ValKeys) GenCheckpoint(chainID string, height int, txs types.Txs,
vals *types.ValidatorSet, appHash []byte, first, last int) lc.Checkpoint {
header := GenHeader(chainID, height, txs, vals, appHash)
check := lc.Checkpoint{
Header: header,
Commit: v.SignHeader(header, first, last),
}
return check
}