2022-08-12 12:44:13 +00:00
|
|
|
//go:build gowaku_rln
|
|
|
|
// +build gowaku_rln
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
package node
|
2022-08-09 00:02:08 +00:00
|
|
|
|
|
|
|
import (
|
2022-10-10 22:08:35 +00:00
|
|
|
"bytes"
|
2022-08-09 00:02:08 +00:00
|
|
|
"encoding/json"
|
2022-11-08 20:20:08 +00:00
|
|
|
"errors"
|
2022-08-09 00:02:08 +00:00
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2022-09-11 21:08:58 +00:00
|
|
|
"path/filepath"
|
2022-08-09 00:02:08 +00:00
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2022-10-27 15:23:20 +00:00
|
|
|
"github.com/waku-org/go-zerokit-rln/rln"
|
2022-09-11 21:08:58 +00:00
|
|
|
"go.uber.org/zap"
|
2022-08-09 00:02:08 +00:00
|
|
|
)
|
|
|
|
|
2022-09-11 21:08:58 +00:00
|
|
|
const RLN_CREDENTIALS_FILENAME = "rlnCredentials.txt"
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
func WriteRLNMembershipCredentialsToFile(keyPair *rln.MembershipKeyPair, idx rln.MembershipIndex, contractAddress common.Address, path string, passwd []byte) error {
|
2022-10-10 22:08:35 +00:00
|
|
|
if path == "" {
|
|
|
|
return nil // we dont want to use a credentials file
|
|
|
|
}
|
|
|
|
|
|
|
|
if keyPair == nil {
|
|
|
|
return nil // no credentials to store
|
|
|
|
}
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
credentialsJSON, err := json.Marshal(MembershipCredentials{
|
2022-10-10 22:08:35 +00:00
|
|
|
Keypair: keyPair,
|
|
|
|
Index: idx,
|
|
|
|
Contract: contractAddress,
|
2022-08-09 00:02:08 +00:00
|
|
|
})
|
2022-10-10 22:08:35 +00:00
|
|
|
|
2022-08-09 00:02:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
encryptedCredentials, err := keystore.EncryptDataV3(credentialsJSON, passwd, keystore.StandardScryptN, keystore.StandardScryptP)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
output, err := json.Marshal(encryptedCredentials)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
path = filepath.Join(path, RLN_CREDENTIALS_FILENAME)
|
|
|
|
|
2022-08-09 00:02:08 +00:00
|
|
|
return ioutil.WriteFile(path, output, 0600)
|
|
|
|
}
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
func loadMembershipCredentialsFromFile(credentialsFilePath string, passwd string) (MembershipCredentials, error) {
|
2022-09-11 21:08:58 +00:00
|
|
|
src, err := ioutil.ReadFile(credentialsFilePath)
|
2022-08-09 00:02:08 +00:00
|
|
|
if err != nil {
|
2022-11-08 20:20:08 +00:00
|
|
|
return MembershipCredentials{}, err
|
2022-08-09 00:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var encryptedK keystore.CryptoJSON
|
|
|
|
err = json.Unmarshal(src, &encryptedK)
|
|
|
|
if err != nil {
|
2022-11-08 20:20:08 +00:00
|
|
|
return MembershipCredentials{}, err
|
2022-08-09 00:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
credentialsBytes, err := keystore.DecryptDataV3(encryptedK, passwd)
|
|
|
|
if err != nil {
|
2022-11-08 20:20:08 +00:00
|
|
|
return MembershipCredentials{}, err
|
2022-08-09 00:02:08 +00:00
|
|
|
}
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
var credentials MembershipCredentials
|
2022-08-09 00:02:08 +00:00
|
|
|
err = json.Unmarshal(credentialsBytes, &credentials)
|
|
|
|
|
2022-10-10 22:08:35 +00:00
|
|
|
return credentials, err
|
2022-08-09 00:02:08 +00:00
|
|
|
}
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
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,
|
2022-10-10 22:08:35 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
credentialsFilePath := filepath.Join(credentialsPath, RLN_CREDENTIALS_FILENAME)
|
2022-09-11 21:08:58 +00:00
|
|
|
if _, err = os.Stat(credentialsFilePath); err == nil {
|
2022-11-08 20:20:08 +00:00
|
|
|
if credentials, err := loadMembershipCredentialsFromFile(credentialsFilePath, password); err != nil {
|
|
|
|
return MembershipCredentials{}, fmt.Errorf("could not read membership credentials file: %w", err)
|
2022-08-09 00:02:08 +00:00
|
|
|
} else {
|
2022-09-11 21:08:58 +00:00
|
|
|
logger.Info("loaded rln credentials", zap.String("filepath", credentialsFilePath))
|
2022-10-10 22:08:35 +00:00
|
|
|
if (bytes.Equal(credentials.Contract.Bytes(), common.Address{}.Bytes())) {
|
2022-11-08 20:20:08 +00:00
|
|
|
credentials.Contract = membershipContract
|
|
|
|
}
|
|
|
|
if (bytes.Equal(membershipContract.Bytes(), common.Address{}.Bytes())) {
|
|
|
|
return MembershipCredentials{}, errors.New("no contract address specified")
|
2022-10-10 22:08:35 +00:00
|
|
|
}
|
2022-11-08 20:20:08 +00:00
|
|
|
return credentials, nil
|
2022-08-09 00:02:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if os.IsNotExist(err) {
|
2022-11-08 20:20:08 +00:00
|
|
|
return MembershipCredentials{
|
2022-10-20 21:49:45 +00:00
|
|
|
Keypair: nil,
|
2022-11-08 20:20:08 +00:00
|
|
|
Index: membershipIndex,
|
|
|
|
Contract: membershipContract,
|
2022-10-10 22:08:35 +00:00
|
|
|
}, nil
|
2022-08-09 00:02:08 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-11-08 20:20:08 +00:00
|
|
|
return MembershipCredentials{}, fmt.Errorf("could not read membership credentials file: %w", err)
|
2022-08-09 00:02:08 +00:00
|
|
|
}
|