Skip to content

Commit 8783cd2

Browse files
committed
chore(rln-relay): use the only key from keystore if only 1 exists
1 parent 08cabab commit 8783cd2

File tree

14 files changed

+107
-48
lines changed

14 files changed

+107
-48
lines changed

.codeclimate.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
plugins:
2-
golint:
3-
enabled: true
2+
# golint:
3+
# enabled: true
44
gofmt:
55
enabled: true
66
govet:
77
enabled: true
8-
# golangci-lint:
9-
#enabled: true
8+
# golangci-lint:
9+
# enabled: true
1010
exclude_patterns:
1111
- "."
1212
- "**/*.pb.go"
1313
- "**/rln/contracts/*.go"
1414
- "**/bindata.go"
1515
- "./examples/waku-csharp"
16-
- "./examples/swift-waku"
16+
- "./examples/swift-waku"

cmd/waku/flags_rln.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ func rlnFlags() []cli.Flag {
1717
Usage: "Enable spam protection through rln-relay",
1818
Destination: &options.RLNRelay.Enable,
1919
},
20-
&cli.UintFlag{
21-
Name: "rln-relay-membership-index",
22-
Value: 0,
23-
Usage: "the index of credentials to use",
24-
Destination: &options.RLNRelay.MembershipIndex,
20+
&cli.GenericFlag{
21+
Name: "rln-relay-cred-index",
22+
Usage: "the index of the onchain commitment to use",
23+
Value: &wcli.OptionalUint{
24+
Value: &options.RLNRelay.MembershipIndex,
25+
},
2526
},
2627
&cli.BoolFlag{
2728
Name: "rln-relay-dynamic",

cmd/waku/node_rln.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func checkForRLN(logger *zap.Logger, options NodeOptions, nodeOpts *[]node.WakuN
1717
failOnErr(errors.New("relay not available"), "Could not enable RLN Relay")
1818
}
1919
if !options.RLNRelay.Dynamic {
20-
*nodeOpts = append(*nodeOpts, node.WithStaticRLNRelay(rln.MembershipIndex(options.RLNRelay.MembershipIndex), nil))
20+
*nodeOpts = append(*nodeOpts, node.WithStaticRLNRelay((*rln.MembershipIndex)(options.RLNRelay.MembershipIndex), nil))
2121
} else {
2222
// TODO: too many parameters in this function
2323
// consider passing a config struct instead
@@ -26,7 +26,7 @@ func checkForRLN(logger *zap.Logger, options NodeOptions, nodeOpts *[]node.WakuN
2626
options.RLNRelay.CredentialsPassword,
2727
options.RLNRelay.TreePath,
2828
options.RLNRelay.MembershipContractAddress,
29-
rln.MembershipIndex(options.RLNRelay.MembershipIndex),
29+
options.RLNRelay.MembershipIndex,
3030
nil,
3131
options.RLNRelay.ETHClientAddress,
3232
))

cmd/waku/options.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type RLNRelayOptions struct {
4040
CredentialsPath string
4141
CredentialsPassword string
4242
TreePath string
43-
MembershipIndex uint
43+
MembershipIndex *uint
4444
Dynamic bool
4545
ETHClientAddress string
4646
MembershipContractAddress common.Address

examples/chat2/exec.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ func execute(options Options) {
5454
options.RLNRelay.CredentialsPassword,
5555
"", // Will use default tree path
5656
options.RLNRelay.MembershipContractAddress,
57-
uint(options.RLNRelay.MembershipIndex),
57+
options.RLNRelay.MembershipIndex,
5858
spamHandler,
5959
options.RLNRelay.ETHClientAddress,
6060
))
6161
} else {
6262
opts = append(opts, node.WithStaticRLNRelay(
63-
uint(options.RLNRelay.MembershipIndex),
63+
options.RLNRelay.MembershipIndex,
6464
spamHandler))
6565
}
6666
}

examples/chat2/flags.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ func getFlags() []cli.Flag {
3636

3737
testCT, err := protocol.NewContentTopic("toy-chat", 3, "mingde", "proto")
3838
if err != nil {
39-
fmt.Println("Invalid contentTopic")
40-
return nil
39+
panic("invalid contentTopic")
4140
}
4241
testnetContentTopic := testCT.String()
4342

@@ -190,11 +189,12 @@ func getFlags() []cli.Flag {
190189
Usage: "Enable spam protection through rln-relay",
191190
Destination: &options.RLNRelay.Enable,
192191
},
193-
&cli.UintFlag{
194-
Name: "rln-relay-membership-index",
195-
Value: 0,
196-
Usage: "the index of credentials to use",
197-
Destination: &options.RLNRelay.MembershipIndex,
192+
&cli.GenericFlag{
193+
Name: "rln-relay-cred-index",
194+
Usage: "the index of the onchain commitment to use",
195+
Value: &wcli.OptionalUint{
196+
Value: &options.RLNRelay.MembershipIndex,
197+
},
198198
},
199199
&cli.BoolFlag{
200200
Name: "rln-relay-dynamic",

examples/chat2/options.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type RLNRelayOptions struct {
3131
Enable bool
3232
CredentialsPath string
3333
CredentialsPassword string
34-
MembershipIndex uint
34+
MembershipIndex *uint
3535
Dynamic bool
3636
ETHClientAddress string
3737
MembershipContractAddress common.Address

waku/cliutils/cli.go

+31
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/ecdsa"
55
"errors"
66
"fmt"
7+
"strconv"
78
"strings"
89

910
"github.com/ethereum/go-ethereum/common"
@@ -73,3 +74,33 @@ func (v *ChoiceValue) String() string {
7374
}
7475
return *v.Value
7576
}
77+
78+
// OptionalUint represents a urfave/cli flag to store uint values that can be
79+
// optionally set and not have any default value assigned to it
80+
type OptionalUint struct {
81+
Value **uint
82+
}
83+
84+
// Set assigns a value to the flag only if it represents a valid uint value
85+
func (v *OptionalUint) Set(value string) error {
86+
if value != "" {
87+
uintVal, err := strconv.ParseUint(value, 10, 0)
88+
if err != nil {
89+
return err
90+
}
91+
uVal := uint(uintVal)
92+
*v.Value = &uVal
93+
} else {
94+
v.Value = nil
95+
}
96+
97+
return nil
98+
}
99+
100+
// String returns the string representation of the OptionalUint flag, if set
101+
func (v *OptionalUint) String() string {
102+
if v.Value == nil {
103+
return ""
104+
}
105+
return fmt.Sprintf("%d", *v.Value)
106+
}

waku/v2/node/wakunode2_rln.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,18 @@ func (w *WakuNode) setupRLNRelay() error {
3838
if !w.opts.rlnRelayDynamic {
3939
w.log.Info("setting up waku-rln-relay in off-chain mode")
4040

41+
index := uint(0)
42+
if w.opts.rlnRelayMemIndex != nil {
43+
index = *w.opts.rlnRelayMemIndex
44+
}
45+
4146
// set up rln relay inputs
42-
groupKeys, idCredential, err := static.Setup(w.opts.rlnRelayMemIndex)
47+
groupKeys, idCredential, err := static.Setup(index)
4348
if err != nil {
4449
return err
4550
}
4651

47-
groupManager, err = static.NewStaticGroupManager(groupKeys, idCredential, w.opts.rlnRelayMemIndex, rlnInstance,
48-
rootTracker, w.log)
52+
groupManager, err = static.NewStaticGroupManager(groupKeys, idCredential, index, rlnInstance, rootTracker, w.log)
4953
if err != nil {
5054
return err
5155
}

waku/v2/node/wakuoptions.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ type WakuNodeParameters struct {
9494
enablePeerExchange bool
9595

9696
enableRLN bool
97-
rlnRelayMemIndex uint
97+
rlnRelayMemIndex *uint
9898
rlnRelayDynamic bool
9999
rlnSpamHandler func(message *pb.WakuMessage) error
100100
rlnETHClientAddress string

waku/v2/node/wakuoptions_rln.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
// WithStaticRLNRelay enables the Waku V2 RLN protocol in offchain mode
1313
// Requires the `gowaku_rln` build constrain (or the env variable RLN=true if building go-waku)
14-
func WithStaticRLNRelay(memberIndex r.MembershipIndex, spamHandler rln.SpamHandler) WakuNodeOption {
14+
func WithStaticRLNRelay(memberIndex *r.MembershipIndex, spamHandler rln.SpamHandler) WakuNodeOption {
1515
return func(params *WakuNodeParameters) error {
1616
params.enableRLN = true
1717
params.rlnRelayDynamic = false
@@ -23,7 +23,7 @@ func WithStaticRLNRelay(memberIndex r.MembershipIndex, spamHandler rln.SpamHandl
2323

2424
// WithDynamicRLNRelay enables the Waku V2 RLN protocol in onchain mode.
2525
// Requires the `gowaku_rln` build constrain (or the env variable RLN=true if building go-waku)
26-
func WithDynamicRLNRelay(keystorePath string, keystorePassword string, treePath string, membershipContract common.Address, membershipIndex uint, spamHandler rln.SpamHandler, ethClientAddress string) WakuNodeOption {
26+
func WithDynamicRLNRelay(keystorePath string, keystorePassword string, treePath string, membershipContract common.Address, membershipIndex *uint, spamHandler rln.SpamHandler, ethClientAddress string) WakuNodeOption {
2727
return func(params *WakuNodeParameters) error {
2828
params.enableRLN = true
2929
params.rlnRelayDynamic = true

waku/v2/protocol/rln/group_manager/dynamic/dynamic.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ type DynamicGroupManager struct {
3737

3838
lastBlockProcessed uint64
3939

40-
appKeystore *keystore.AppKeystore
41-
keystorePassword string
40+
appKeystore *keystore.AppKeystore
41+
keystorePassword string
42+
membershipIndexToLoad *uint
4243
}
4344

4445
func (gm *DynamicGroupManager) handler(events []*contracts.RLNMemberRegistered) error {
@@ -104,7 +105,7 @@ type RegistrationHandler = func(tx *types.Transaction)
104105
func NewDynamicGroupManager(
105106
ethClientAddr string,
106107
memContractAddr common.Address,
107-
membershipIndex uint,
108+
membershipIndexToLoad *uint,
108109
appKeystore *keystore.AppKeystore,
109110
keystorePassword string,
110111
reg prometheus.Registerer,
@@ -116,11 +117,11 @@ func NewDynamicGroupManager(
116117

117118
web3Config := web3.NewConfig(ethClientAddr, memContractAddr)
118119
return &DynamicGroupManager{
119-
membershipIndex: membershipIndex,
120-
appKeystore: appKeystore,
121-
keystorePassword: keystorePassword,
122-
MembershipFetcher: NewMembershipFetcher(web3Config, rlnInstance, rootTracker, log),
123-
metrics: newMetrics(reg),
120+
membershipIndexToLoad: membershipIndexToLoad,
121+
appKeystore: appKeystore,
122+
keystorePassword: keystorePassword,
123+
MembershipFetcher: NewMembershipFetcher(web3Config, rlnInstance, rootTracker, log),
124+
metrics: newMetrics(reg),
124125
}, nil
125126
}
126127

@@ -170,7 +171,7 @@ func (gm *DynamicGroupManager) loadCredential(ctx context.Context) error {
170171

171172
credentials, err := gm.appKeystore.GetMembershipCredentials(
172173
gm.keystorePassword,
173-
gm.membershipIndex,
174+
gm.membershipIndexToLoad,
174175
keystore.NewMembershipContractInfo(gm.web3Config.ChainID, gm.web3Config.RegistryContract.Address))
175176
if err != nil {
176177
return err
@@ -191,6 +192,7 @@ func (gm *DynamicGroupManager) loadCredential(ctx context.Context) error {
191192
}
192193

193194
gm.identityCredential = credentials.IdentityCredential
195+
gm.membershipIndex = credentials.TreeIndex
194196

195197
return nil
196198
}

waku/v2/protocol/rln/keystore/keystore.go

+27-6
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,31 @@ func getKey(treeIndex rln.MembershipIndex, filterMembershipContract MembershipCo
8181
}
8282

8383
// GetMembershipCredentials decrypts and retrieves membership credentials from the keystore applying filters
84-
func (k *AppKeystore) GetMembershipCredentials(keystorePassword string, treeIndex rln.MembershipIndex, filterMembershipContract MembershipContractInfo) (*MembershipCredentials, error) {
85-
key, err := getKey(treeIndex, filterMembershipContract)
86-
if err != nil {
87-
return nil, err
84+
func (k *AppKeystore) GetMembershipCredentials(keystorePassword string, index *rln.MembershipIndex, filterMembershipContract MembershipContractInfo) (*MembershipCredentials, error) {
85+
// If there is only one, and index to laod nil, assume 0,
86+
// if there is more than one, complain if the index to load is nil
87+
88+
var key Key
89+
var err error
90+
if len(k.Credentials) == 1 {
91+
// Only one credential, the tree index does not matter.
92+
k.logger.Warn("automatically loading the only credential found on the keystore")
93+
for k := range k.Credentials {
94+
key = k // Obtain the first c
95+
break
96+
}
97+
} else {
98+
treeIndex := uint(0)
99+
if index != nil {
100+
treeIndex = *index
101+
} else {
102+
return nil, errors.New("the index of the onchain commitment to use was not specified")
103+
}
104+
105+
key, err = getKey(treeIndex, filterMembershipContract)
106+
if err != nil {
107+
return nil, err
108+
}
88109
}
89110

90111
credential, ok := k.Credentials[key]
@@ -108,7 +129,7 @@ func (k *AppKeystore) GetMembershipCredentials(keystorePassword string, treeInde
108129

109130
// AddMembershipCredentials inserts a membership credential to the keystore matching the application, appIdentifier and version filters.
110131
func (k *AppKeystore) AddMembershipCredentials(newCredential MembershipCredentials, password string) error {
111-
credentials, err := k.GetMembershipCredentials(password, newCredential.TreeIndex, newCredential.MembershipContractInfo)
132+
credentials, err := k.GetMembershipCredentials(password, &newCredential.TreeIndex, newCredential.MembershipContractInfo)
112133
if err != nil {
113134
return err
114135
}
@@ -118,7 +139,7 @@ func (k *AppKeystore) AddMembershipCredentials(newCredential MembershipCredentia
118139
return err
119140
}
120141

121-
if credentials != nil {
142+
if credentials != nil && credentials.TreeIndex == newCredential.TreeIndex && credentials.MembershipContractInfo.Equals(newCredential.MembershipContractInfo) {
122143
return errors.New("credential already present")
123144
}
124145

waku/v2/protocol/rln/onchain_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ func (s *WakuRLNRelayDynamicSuite) TestDynamicGroupManagement() {
149149

150150
membershipIndex := s.register(appKeystore, u1Credentials, s.u1PrivKey)
151151

152-
gm, err := dynamic.NewDynamicGroupManager(s.web3Config.ETHClientAddress, s.web3Config.RegistryContract.Address, membershipIndex, appKeystore, keystorePassword, prometheus.DefaultRegisterer, rlnInstance, rt, utils.Logger())
152+
gm, err := dynamic.NewDynamicGroupManager(s.web3Config.ETHClientAddress, s.web3Config.RegistryContract.Address, &membershipIndex, appKeystore, keystorePassword, prometheus.DefaultRegisterer, rlnInstance, rt, utils.Logger())
153153
s.Require().NoError(err)
154154

155155
// initialize the WakuRLNRelay
@@ -236,7 +236,7 @@ func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
236236
rlnInstance, rootTracker, err := GetRLNInstanceAndRootTracker(s.tmpRLNDBPath())
237237
s.Require().NoError(err)
238238
// mount the rln relay protocol in the on-chain/dynamic mode
239-
gm, err := dynamic.NewDynamicGroupManager(s.web3Config.ETHClientAddress, s.web3Config.RegistryContract.Address, membershipIndex, appKeystore, keystorePassword, prometheus.DefaultRegisterer, rlnInstance, rootTracker, utils.Logger())
239+
gm, err := dynamic.NewDynamicGroupManager(s.web3Config.ETHClientAddress, s.web3Config.RegistryContract.Address, &membershipIndex, appKeystore, keystorePassword, prometheus.DefaultRegisterer, rlnInstance, rootTracker, utils.Logger())
240240
s.Require().NoError(err)
241241

242242
rlnRelay := New(group_manager.Details{
@@ -275,7 +275,7 @@ func (s *WakuRLNRelayDynamicSuite) TestCorrectRegistrationOfPeers() {
275275
// mount the rln relay protocol in the on-chain/dynamic mode
276276
rootInstance, rootTracker, err := GetRLNInstanceAndRootTracker(s.tmpRLNDBPath())
277277
s.Require().NoError(err)
278-
gm1, err := dynamic.NewDynamicGroupManager(s.web3Config.ETHClientAddress, s.web3Config.RegistryContract.Address, membershipGroupIndex, appKeystore, keystorePassword, prometheus.DefaultRegisterer, rootInstance, rootTracker, utils.Logger())
278+
gm1, err := dynamic.NewDynamicGroupManager(s.web3Config.ETHClientAddress, s.web3Config.RegistryContract.Address, &membershipGroupIndex, appKeystore, keystorePassword, prometheus.DefaultRegisterer, rootInstance, rootTracker, utils.Logger())
279279
s.Require().NoError(err)
280280

281281
rlnRelay1 := New(group_manager.Details{
@@ -299,7 +299,7 @@ func (s *WakuRLNRelayDynamicSuite) TestCorrectRegistrationOfPeers() {
299299
// mount the rln relay protocol in the on-chain/dynamic mode
300300
rootInstance, rootTracker, err = GetRLNInstanceAndRootTracker(s.tmpRLNDBPath())
301301
s.Require().NoError(err)
302-
gm2, err := dynamic.NewDynamicGroupManager(s.web3Config.ETHClientAddress, s.web3Config.RegistryContract.Address, membershipGroupIndex, appKeystore2, keystorePassword, prometheus.DefaultRegisterer, rootInstance, rootTracker, utils.Logger())
302+
gm2, err := dynamic.NewDynamicGroupManager(s.web3Config.ETHClientAddress, s.web3Config.RegistryContract.Address, &membershipGroupIndex, appKeystore2, keystorePassword, prometheus.DefaultRegisterer, rootInstance, rootTracker, utils.Logger())
303303
s.Require().NoError(err)
304304

305305
rlnRelay2 := New(group_manager.Details{

0 commit comments

Comments
 (0)