fix: chat2 rln credentials

This commit is contained in:
Richard Ramos 2022-11-08 16:20:08 -04:00 committed by RichΛrd
parent 448781687e
commit dc0968ca0a
9 changed files with 60 additions and 143 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/status-im/go-waku/waku/v2/protocol/lightpush"
"github.com/status-im/go-waku/waku/v2/protocol/pb"
"github.com/status-im/go-waku/waku/v2/protocol/store"
"github.com/status-im/go-waku/waku/v2/utils"
)
func execute(options Options) {
@ -48,7 +49,13 @@ func execute(options Options) {
}
if options.RLNRelay.Dynamic {
membershipCredentials, err := getMembershipCredentials(options.RLNRelay)
membershipCredentials, err := node.GetMembershipCredentials(
utils.Logger(),
options.RLNRelay.CredentialsPath,
options.RLNRelay.CredentialsPassword,
options.RLNRelay.MembershipContractAddress,
uint(options.RLNRelay.MembershipIndex),
)
if err != nil {
fmt.Println(err)
return
@ -114,7 +121,7 @@ func execute(options Options) {
}
if options.RLNRelay.Enable && options.RLNRelay.Dynamic {
err := writeRLNMembershipCredentialsToFile(options.RLNRelay.CredentialsPath, wakuNode.RLNRelay().MembershipKeyPair(), wakuNode.RLNRelay().MembershipIndex(), wakuNode.RLNRelay().MembershipContractAddress())
err := node.WriteRLNMembershipCredentialsToFile(wakuNode.RLNRelay().MembershipKeyPair(), wakuNode.RLNRelay().MembershipIndex(), wakuNode.RLNRelay().MembershipContractAddress(), options.RLNRelay.CredentialsPath, []byte(options.RLNRelay.CredentialsPassword))
if err != nil {
fmt.Println(err.Error())
return

View File

@ -218,6 +218,12 @@ func getFlags() []cli.Flag {
Value: "",
Destination: &options.RLNRelay.CredentialsPath,
},
&cli.StringFlag{
Name: "rln-relay-cred-password",
Value: "",
Usage: "Password for encrypting RLN credentials",
Destination: &options.RLNRelay.CredentialsPassword,
},
// TODO: this is a good candidate option for subcommands
// TODO: consider accepting a private key file and passwd
&cli.GenericFlag{

View File

@ -30,6 +30,7 @@ type RelayOptions struct {
type RLNRelayOptions struct {
Enable bool
CredentialsPath string
CredentialsPassword string
MembershipIndex int
PubsubTopic string
ContentTopic string

View File

@ -1,102 +0,0 @@
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/go-waku/waku/v2/node"
"github.com/waku-org/go-zerokit-rln/rln"
)
const RLN_CREDENTIALS_FILENAME = "rlnCredentials.txt"
func fileExists(path string) bool {
if _, err := os.Stat(path); err == nil {
return false
} else if errors.Is(err, os.ErrNotExist) {
return false
} else {
return false
}
}
func writeRLNMembershipCredentialsToFile(path string, keyPair *rln.MembershipKeyPair, idx rln.MembershipIndex, contractAddress common.Address) error {
if path == "" {
return nil // No path to save file
}
path = filepath.Join(path, RLN_CREDENTIALS_FILENAME)
if fileExists(path) {
return nil
}
if keyPair == nil {
return nil // No credentials to write
}
credentialsJSON, err := json.Marshal(node.MembershipCredentials{
Keypair: &rln.MembershipKeyPair{
IDKey: keyPair.IDKey,
IDCommitment: keyPair.IDCommitment,
},
Index: idx,
Contract: contractAddress,
})
if err != nil {
return err
}
return ioutil.WriteFile(path, credentialsJSON, 0600)
}
func loadMembershipCredentialsFromFile(rlnCredentialsPath string) (node.MembershipCredentials, error) {
src, err := ioutil.ReadFile(rlnCredentialsPath)
if err != nil {
return node.MembershipCredentials{}, err
}
var credentials node.MembershipCredentials
err = json.Unmarshal(src, &credentials)
return credentials, err
}
func getMembershipCredentials(options RLNRelayOptions) (credentials node.MembershipCredentials, err error) {
path := options.CredentialsPath
if path == "" {
return node.MembershipCredentials{
Contract: options.MembershipContractAddress,
}, nil
}
path = filepath.Join(path, RLN_CREDENTIALS_FILENAME)
_, osErr := os.Stat(path)
if osErr == nil {
if credentials, err := loadMembershipCredentialsFromFile(path); err != nil {
return node.MembershipCredentials{}, fmt.Errorf("could not read membership credentials file: %w", err)
} else {
if (bytes.Equal(credentials.Contract.Bytes(), common.Address{}.Bytes())) {
credentials.Contract = options.MembershipContractAddress
}
return credentials, nil
}
}
if os.IsNotExist(osErr) {
return node.MembershipCredentials{
Index: uint(options.MembershipIndex),
Contract: options.MembershipContractAddress,
}, nil
}
return node.MembershipCredentials{}, fmt.Errorf("could not read membership credentials file: %w", err)
}

View File

@ -12,8 +12,6 @@ import (
"go.uber.org/zap"
)
var loadedCredentialsFromFile bool = false
func checkForRLN(logger *zap.Logger, options Options, nodeOpts *[]node.WakuNodeOption) {
if options.RLNRelay.Enable {
if !options.Relay.Enable {
@ -27,12 +25,15 @@ func checkForRLN(logger *zap.Logger, options Options, nodeOpts *[]node.WakuNodeO
if options.RLNRelay.ETHPrivateKey != nil {
ethPrivKey = options.RLNRelay.ETHPrivateKey
}
loaded, membershipCredentials, err := getMembershipCredentials(logger, options)
membershipCredentials, err := node.GetMembershipCredentials(
logger,
options.RLNRelay.CredentialsPath,
options.RLNRelay.CredentialsPassword,
options.RLNRelay.MembershipContractAddress,
uint(options.RLNRelay.MembershipIndex),
)
failOnErr(err, "Invalid membership credentials")
loadedCredentialsFromFile = loaded
*nodeOpts = append(*nodeOpts, node.WithDynamicRLNRelay(
options.RLNRelay.PubsubTopic,
options.RLNRelay.ContentTopic,
@ -47,8 +48,8 @@ func checkForRLN(logger *zap.Logger, options Options, nodeOpts *[]node.WakuNodeO
}
func onStartRLN(wakuNode *node.WakuNode, options Options) {
if options.RLNRelay.Enable && options.RLNRelay.Dynamic && !loadedCredentialsFromFile && options.RLNRelay.CredentialsPath != "" {
err := writeRLNMembershipCredentialsToFile(wakuNode.RLNRelay().MembershipKeyPair(), wakuNode.RLNRelay().MembershipIndex(), wakuNode.RLNRelay().MembershipContractAddress(), options.RLNRelay.CredentialsPath, []byte(options.KeyPasswd), options.Overwrite)
if options.RLNRelay.Enable && options.RLNRelay.Dynamic && options.RLNRelay.CredentialsPath != "" {
err := node.WriteRLNMembershipCredentialsToFile(wakuNode.RLNRelay().MembershipKeyPair(), wakuNode.RLNRelay().MembershipIndex(), wakuNode.RLNRelay().MembershipContractAddress(), options.RLNRelay.CredentialsPath, []byte(options.RLNRelay.CredentialsPassword))
failOnErr(err, "Could not write membership credentials file")
}
}

View File

@ -31,6 +31,7 @@ type RelayOptions struct {
type RLNRelayOptions struct {
Enable bool
CredentialsPath string
CredentialsPassword string
MembershipIndex int
PubsubTopic string
ContentTopic string

View File

@ -1,11 +1,12 @@
//go:build gowaku_rln
// +build gowaku_rln
package waku
package node
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
@ -13,14 +14,13 @@ import (
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/go-waku/waku/v2/node"
"github.com/waku-org/go-zerokit-rln/rln"
"go.uber.org/zap"
)
const RLN_CREDENTIALS_FILENAME = "rlnCredentials.txt"
func writeRLNMembershipCredentialsToFile(keyPair *rln.MembershipKeyPair, idx rln.MembershipIndex, contractAddress common.Address, path string, passwd []byte, overwrite bool) error {
func WriteRLNMembershipCredentialsToFile(keyPair *rln.MembershipKeyPair, idx rln.MembershipIndex, contractAddress common.Address, path string, passwd []byte) error {
if path == "" {
return nil // we dont want to use a credentials file
}
@ -29,19 +29,12 @@ func writeRLNMembershipCredentialsToFile(keyPair *rln.MembershipKeyPair, idx rln
return nil // no credentials to store
}
path = filepath.Join(path, RLN_CREDENTIALS_FILENAME)
if err := checkForFileExistence(path, overwrite); err != nil {
return err
}
credentialsJSON, err := json.Marshal(node.MembershipCredentials{
credentialsJSON, err := json.Marshal(MembershipCredentials{
Keypair: keyPair,
Index: idx,
Contract: contractAddress,
})
fmt.Println(string(credentialsJSON))
if err != nil {
return err
}
@ -56,60 +49,65 @@ func writeRLNMembershipCredentialsToFile(keyPair *rln.MembershipKeyPair, idx rln
return err
}
path = filepath.Join(path, RLN_CREDENTIALS_FILENAME)
return ioutil.WriteFile(path, output, 0600)
}
func loadMembershipCredentialsFromFile(credentialsFilePath string, passwd string) (node.MembershipCredentials, error) {
func loadMembershipCredentialsFromFile(credentialsFilePath string, passwd string) (MembershipCredentials, error) {
src, err := ioutil.ReadFile(credentialsFilePath)
if err != nil {
return node.MembershipCredentials{}, err
return MembershipCredentials{}, err
}
var encryptedK keystore.CryptoJSON
err = json.Unmarshal(src, &encryptedK)
if err != nil {
return node.MembershipCredentials{}, err
return MembershipCredentials{}, err
}
credentialsBytes, err := keystore.DecryptDataV3(encryptedK, passwd)
if err != nil {
return node.MembershipCredentials{}, err
return MembershipCredentials{}, err
}
var credentials node.MembershipCredentials
var credentials MembershipCredentials
err = json.Unmarshal(credentialsBytes, &credentials)
return credentials, err
}
func getMembershipCredentials(logger *zap.Logger, options Options) (fromFile bool, credentials node.MembershipCredentials, err error) {
if options.RLNRelay.CredentialsPath == "" { // Not using a file
return false, node.MembershipCredentials{
Contract: options.RLNRelay.MembershipContractAddress,
func GetMembershipCredentials(logger *zap.Logger, credentialsPath string, password string, membershipContract common.Address, membershipIndex uint) (credentials MembershipCredentials, err error) {
if credentialsPath == "" { // Not using a file
return MembershipCredentials{
Contract: membershipContract,
}, nil
}
credentialsFilePath := filepath.Join(options.RLNRelay.CredentialsPath, RLN_CREDENTIALS_FILENAME)
credentialsFilePath := filepath.Join(credentialsPath, RLN_CREDENTIALS_FILENAME)
if _, err = os.Stat(credentialsFilePath); err == nil {
if credentials, err := loadMembershipCredentialsFromFile(credentialsFilePath, options.KeyPasswd); err != nil {
return false, node.MembershipCredentials{}, fmt.Errorf("could not read membership credentials file: %w", err)
if credentials, err := loadMembershipCredentialsFromFile(credentialsFilePath, password); err != nil {
return MembershipCredentials{}, fmt.Errorf("could not read membership credentials file: %w", err)
} else {
logger.Info("loaded rln credentials", zap.String("filepath", credentialsFilePath))
if (bytes.Equal(credentials.Contract.Bytes(), common.Address{}.Bytes())) {
credentials.Contract = options.RLNRelay.MembershipContractAddress
credentials.Contract = membershipContract
}
return true, credentials, nil
if (bytes.Equal(membershipContract.Bytes(), common.Address{}.Bytes())) {
return MembershipCredentials{}, errors.New("no contract address specified")
}
return credentials, nil
}
}
if os.IsNotExist(err) {
return false, node.MembershipCredentials{
return MembershipCredentials{
Keypair: nil,
Index: uint(options.RLNRelay.MembershipIndex),
Contract: options.RLNRelay.MembershipContractAddress,
Index: membershipIndex,
Contract: membershipContract,
}, nil
}
return false, node.MembershipCredentials{}, fmt.Errorf("could not read membership credentials file: %w", err)
return MembershipCredentials{}, fmt.Errorf("could not read membership credentials file: %w", err)
}

View File

@ -195,10 +195,9 @@ func (rln *WakuRLNRelay) watchNewEvents(rlnContract *contracts.RLN, handler Regi
}
errCh <- err
subs.Unsubscribe()
rln.log.Error("subscribing to rln events", zap.Error(err))
}
rln.log.Error("subscribing to rln events", zap.Error(err))
return subs, err
})
defer subs.Unsubscribe()

View File

@ -45,6 +45,12 @@ func rlnFlags() []cli.Flag {
Value: "",
Destination: &options.RLNRelay.CredentialsPath,
},
&cli.StringFlag{
Name: "rln-relay-cred-password",
Value: "",
Usage: "Password for encrypting RLN credentials",
Destination: &options.RLNRelay.CredentialsPassword,
},
// TODO: this is a good candidate option for subcommands
// TODO: consider accepting a private key file and passwd
&cli.GenericFlag{