Skip to content

Commit 2b7df73

Browse files
CoderZhienvestcc
andauthored
introduce producer private key range and using random key if inactive (#4662)
--------- Co-authored-by: Chen Chen <chen1233216@hotmail.com>
1 parent 42f3cf4 commit 2b7df73

File tree

3 files changed

+120
-4
lines changed

3 files changed

+120
-4
lines changed

blockchain/config.go

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package blockchain
88
import (
99
"crypto/ecdsa"
1010
"os"
11+
"strconv"
1112
"strings"
1213
"time"
1314

@@ -44,6 +45,7 @@ type (
4445
Address string `yaml:"address"`
4546
ProducerPrivKey string `yaml:"producerPrivKey"`
4647
ProducerPrivKeySchema string `yaml:"producerPrivKeySchema"`
48+
ProducerPrivKeyRange string `yaml:"producerPrivKeyRange"`
4749
SignatureScheme []string `yaml:"signatureScheme"`
4850
EmptyGenesis bool `yaml:"emptyGenesis"`
4951
GravityChainDB db.Config `yaml:"gravityChainDB"`
@@ -104,7 +106,7 @@ var (
104106
ID: 1,
105107
EVMNetworkID: 4689,
106108
Address: "",
107-
ProducerPrivKey: generateRandomKey(SigP256k1),
109+
ProducerPrivKey: GenerateRandomKey(SigP256k1),
108110
SignatureScheme: []string{SigP256k1},
109111
EmptyGenesis: false,
110112
GravityChainDB: db.Config{DbPath: "/var/data/poll.db", NumRetries: 10},
@@ -169,7 +171,35 @@ func (cfg *Config) ProducerPrivateKeys() []crypto.PrivateKey {
169171
}
170172
privateKeys = append(privateKeys, sk)
171173
}
172-
return privateKeys
174+
175+
if cfg.ProducerPrivKeyRange == "" {
176+
return privateKeys
177+
}
178+
// Expecting format "[$start:$end]"
179+
r := strings.Trim(cfg.ProducerPrivKeyRange, "[]")
180+
parts := strings.Split(r, ":")
181+
if len(parts) != 2 {
182+
log.L().Panic("invalid format", zap.String("ProducerPrivKeyRange", cfg.ProducerPrivKeyRange))
183+
}
184+
start, end := 0, len(privateKeys)
185+
var err error
186+
if parts[0] != "" {
187+
start, err = strconv.Atoi(parts[0])
188+
if err != nil {
189+
log.L().Panic("invalid start", zap.String("start", parts[0]), zap.Error(err))
190+
}
191+
}
192+
if parts[1] != "" {
193+
end, err = strconv.Atoi(parts[1])
194+
if err != nil {
195+
log.L().Panic("invalid end", zap.String("end", parts[1]), zap.Error(err))
196+
}
197+
}
198+
if start < 0 || end > len(privateKeys) || start > end {
199+
log.L().Panic("ProducerPrivKeyRange out of bounds", zap.Int("start", start), zap.Int("end", end), zap.Int("len", len(privateKeys)))
200+
}
201+
202+
return privateKeys[start:end]
173203
}
174204

175205
// SetProducerPrivKey set producer privKey by PrivKeyConfigFile info
@@ -203,7 +233,8 @@ func (cfg *Config) SetProducerPrivKey() error {
203233
return nil
204234
}
205235

206-
func generateRandomKey(scheme string) string {
236+
// GenerateRandomKey generates a random private key based on the signature scheme
237+
func GenerateRandomKey(scheme string) string {
207238
// generate a random key
208239
switch scheme {
209240
case SigP256k1:

blockchain/config_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package blockchain
77

88
import (
9+
"strings"
910
"testing"
1011

1112
"github.com/iotexproject/go-pkgs/crypto"
@@ -33,3 +34,79 @@ func TestWhitelist(t *testing.T) {
3334
r.Equal(sk, cfg.ProducerPrivateKeys()[0])
3435
r.Equal(sk.PublicKey().Address().String(), cfg.ProducerAddress()[0].String())
3536
}
37+
38+
func TestProducerPrivateKeys_RangeParsing(t *testing.T) {
39+
r := require.New(t)
40+
cfg := DefaultConfig
41+
genKeys := func(size int) string {
42+
var privKeyStrs []string
43+
for i := 0; i < size; i++ {
44+
sk, err := crypto.GenerateKey()
45+
r.NoError(err)
46+
privKeyStrs = append(privKeyStrs, sk.HexString())
47+
}
48+
return strings.Join(privKeyStrs, ",")
49+
}
50+
51+
getKeys := func(privKey, privKeyRange string) (keys []crypto.PrivateKey, panicked bool) {
52+
cfg.ProducerPrivKey = privKey
53+
cfg.ProducerPrivKeyRange = privKeyRange
54+
defer func() {
55+
if r := recover(); r != nil {
56+
panicked = true
57+
}
58+
}()
59+
keys = cfg.ProducerPrivateKeys()
60+
return
61+
}
62+
63+
privKeys := genKeys(5)
64+
keys, panicked := getKeys(privKeys, "")
65+
r.False(panicked)
66+
r.Len(keys, 5)
67+
68+
keys, panicked = getKeys(privKeys, "[:]")
69+
r.False(panicked)
70+
r.Len(keys, 5)
71+
72+
keys, panicked = getKeys(privKeys, "[0:0]")
73+
r.False(panicked)
74+
r.Len(keys, 0)
75+
76+
keys, panicked = getKeys(privKeys, "[0:1]")
77+
r.False(panicked)
78+
r.Len(keys, 1)
79+
80+
keys, panicked = getKeys(privKeys, "[1:3]")
81+
r.False(panicked)
82+
r.Len(keys, 2)
83+
84+
keys, panicked = getKeys(privKeys, "[3:5]")
85+
r.False(panicked)
86+
r.Len(keys, 2)
87+
88+
keys, panicked = getKeys(privKeys, "[5:]")
89+
r.False(panicked)
90+
r.Len(keys, 0)
91+
92+
keys, panicked = getKeys(privKeys, "[:5]")
93+
r.False(panicked)
94+
r.Len(keys, 5)
95+
96+
keys, panicked = getKeys(privKeys, "[2:]")
97+
r.False(panicked)
98+
r.Len(keys, 3)
99+
100+
_, panicked = getKeys(privKeys, "[invalid]")
101+
r.True(panicked)
102+
103+
_, panicked = getKeys(privKeys, "[-1:1]")
104+
r.True(panicked)
105+
106+
_, panicked = getKeys(privKeys, "[2:1]")
107+
r.True(panicked)
108+
_, panicked = getKeys(privKeys, "[1:6]")
109+
r.True(panicked)
110+
_, panicked = getKeys(privKeys, "[1:5:7]")
111+
r.True(panicked)
112+
}

config/config.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,15 @@ func New(configPaths []string, _plugins []string, validates ...Validate) (Config
173173

174174
// set network master key to private key
175175
if cfg.Network.MasterKey == "" {
176-
cfg.Network.MasterKey = cfg.Chain.ProducerPrivKey
176+
if cfg.System.Active {
177+
pks := cfg.Chain.ProducerPrivateKeys()
178+
if len(pks) > 0 {
179+
cfg.Network.MasterKey = pks[0].HexString()
180+
}
181+
}
182+
if cfg.Network.MasterKey == "" {
183+
cfg.Network.MasterKey = blockchain.GenerateRandomKey(blockchain.SigP256k1)
184+
}
177185
}
178186

179187
// set plugins

0 commit comments

Comments
 (0)