-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create
generate-rln-credentials
subcommand
- Loading branch information
1 parent
2818c3d
commit 6ff7116
Showing
8 changed files
with
465 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//go:build !gowaku_rln | ||
// +build !gowaku_rln | ||
|
||
package rlngenerate | ||
|
||
import ( | ||
"errors" | ||
|
||
cli "github.com/urfave/cli/v2" | ||
) | ||
|
||
// Command generates a key file used to generate the node's peerID, encrypted with an optional password | ||
var Command = cli.Command{ | ||
Name: "generate-rln-credentials", | ||
Usage: "Generate credentials for usage with RLN", | ||
Action: func(cCtx *cli.Context) error { | ||
return errors.New("not available. Execute `make RLN=true` to add RLN support to go-waku") | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
//go:build gowaku_rln | ||
// +build gowaku_rln | ||
|
||
package rlngenerate | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"math/big" | ||
|
||
"github.com/ethereum/go-ethereum/ethclient" | ||
cli "github.com/urfave/cli/v2" | ||
"github.com/waku-org/go-waku/logging" | ||
"github.com/waku-org/go-waku/waku/v2/protocol/rln/contracts" | ||
"github.com/waku-org/go-waku/waku/v2/protocol/rln/group_manager/dynamic" | ||
"github.com/waku-org/go-waku/waku/v2/protocol/rln/keystore" | ||
"github.com/waku-org/go-waku/waku/v2/utils" | ||
"github.com/waku-org/go-zerokit-rln/rln" | ||
"go.uber.org/zap" | ||
) | ||
|
||
var options Options | ||
var logger = utils.Logger().Named("rln-credentials") | ||
|
||
// Command generates a key file used to generate the node's peerID, encrypted with an optional password | ||
var Command = cli.Command{ | ||
Name: "generate-rln-credentials", | ||
Usage: "Generate credentials for usage with RLN", | ||
Action: func(cCtx *cli.Context) error { | ||
err := verifyFlags() | ||
if err != nil { | ||
logger.Error("validating option flags", zap.Error(err)) | ||
return cli.Exit(err, 1) | ||
} | ||
|
||
err = execute(context.Background()) | ||
if err != nil { | ||
logger.Error("registering RLN credentials", zap.Error(err)) | ||
return cli.Exit(err, 1) | ||
} | ||
|
||
return nil | ||
}, | ||
Flags: flags, | ||
} | ||
|
||
func verifyFlags() error { | ||
if options.CredentialsPath == "" { | ||
logger.Warn("keystore: no credentials path set, using default path", zap.String("path", keystore.RLN_CREDENTIALS_FILENAME)) | ||
options.CredentialsPath = keystore.RLN_CREDENTIALS_FILENAME | ||
} | ||
|
||
if options.CredentialsPassword == "" { | ||
logger.Warn("keystore: no credentials password set, using default password", zap.String("password", keystore.RLN_CREDENTIALS_PASSWORD)) | ||
options.CredentialsPassword = keystore.RLN_CREDENTIALS_PASSWORD | ||
} | ||
|
||
if options.ETHPrivateKey == nil { | ||
return errors.New("a private key must be specified") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func execute(ctx context.Context) error { | ||
ethClient, err := ethclient.Dial(options.ETHClientAddress) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
rlnInstance, err := rln.NewRLN() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
chainID, err := ethClient.ChainID(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
rlnContract, err := contracts.NewRLN(options.MembershipContractAddress, ethClient) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// prepare rln membership key pair | ||
logger.Info("generating rln credential") | ||
identityCredential, err := rlnInstance.MembershipKeyGen() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// register the rln-relay peer to the membership contract | ||
membershipIndex, err := register(ctx, ethClient, rlnContract, identityCredential.IDCommitment, chainID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// TODO: clean private key from memory | ||
|
||
err = persistCredentials(identityCredential, membershipIndex, chainID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if logger.Level() == zap.DebugLevel { | ||
logger.Info("registered credentials into the membership contract", | ||
logging.HexString("IDCommitment", identityCredential.IDCommitment[:]), | ||
logging.HexString("IDNullifier", identityCredential.IDNullifier[:]), | ||
logging.HexString("IDSecretHash", identityCredential.IDSecretHash[:]), | ||
logging.HexString("IDTrapDoor", identityCredential.IDTrapdoor[:]), | ||
zap.Uint("index", membershipIndex), | ||
) | ||
} else { | ||
logger.Info("registered credentials into the membership contract", logging.HexString("idCommitment", identityCredential.IDCommitment[:]), zap.Uint("index", membershipIndex)) | ||
} | ||
|
||
ethClient.Close() | ||
|
||
return nil | ||
} | ||
|
||
func persistCredentials(identityCredential *rln.IdentityCredential, membershipIndex rln.MembershipIndex, chainID *big.Int) error { | ||
membershipGroup := keystore.MembershipGroup{ | ||
TreeIndex: membershipIndex, | ||
MembershipContract: keystore.MembershipContract{ | ||
ChainId: fmt.Sprintf("0x%X", chainID.Int64()), | ||
Address: options.MembershipContractAddress.String(), | ||
}, | ||
} | ||
|
||
keystoreIndex, membershipGroupIndex, err := keystore.AddMembershipCredentials(options.CredentialsPath, identityCredential, membershipGroup, options.CredentialsPassword, dynamic.RLNAppInfo, keystore.DefaultSeparator) | ||
if err != nil { | ||
return fmt.Errorf("failed to persist credentials: %w", err) | ||
} | ||
|
||
logger.Info("persisted credentials succesfully", zap.Int("keystoreIndex", keystoreIndex), zap.Int("membershipGroupIndex", membershipGroupIndex)) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
//go:build gowaku_rln | ||
// +build gowaku_rln | ||
|
||
package rlngenerate | ||
|
||
import ( | ||
cli "github.com/urfave/cli/v2" | ||
wcli "github.com/waku-org/go-waku/waku/cliutils" | ||
"github.com/waku-org/go-waku/waku/v2/protocol/rln/keystore" | ||
) | ||
|
||
var flags = []cli.Flag{ | ||
&cli.PathFlag{ | ||
Name: "cred-path", | ||
Usage: "RLN relay membership credentials file", | ||
Value: keystore.RLN_CREDENTIALS_FILENAME, | ||
Destination: &options.CredentialsPath, | ||
}, | ||
&cli.StringFlag{ | ||
Name: "cred-password", | ||
Value: keystore.RLN_CREDENTIALS_PASSWORD, | ||
Usage: "Password for encrypting RLN credentials", | ||
Destination: &options.CredentialsPassword, | ||
}, | ||
&cli.GenericFlag{ | ||
Name: "eth-account-private-key", | ||
Usage: "Ethereum account private key used for registering in member contract", | ||
Value: &wcli.PrivateKeyValue{ | ||
Value: &options.ETHPrivateKey, | ||
}, | ||
}, | ||
&cli.StringFlag{ | ||
Name: "eth-client-address", | ||
Usage: "Ethereum testnet client address", | ||
Value: "ws://localhost:8545", | ||
Destination: &options.ETHClientAddress, | ||
}, | ||
&cli.GenericFlag{ | ||
Name: "eth-contract-address", | ||
Usage: "Address of membership contract", | ||
Value: &wcli.AddressValue{ | ||
Value: &options.MembershipContractAddress, | ||
}, | ||
}, | ||
&cli.StringFlag{ | ||
Name: "eth-nonce", | ||
Value: "", | ||
Usage: "Set an specific ETH transaction nonce. Leave empty to calculate the nonce automatically", | ||
Destination: &options.ETHNonce, | ||
}, | ||
&cli.Uint64Flag{ | ||
Name: "eth-gas-limit", | ||
Value: 0, | ||
Usage: "Gas limit to set for the transaction execution (0 = estimate)", | ||
Destination: &options.ETHGasLimit, | ||
}, | ||
&cli.StringFlag{ | ||
Name: "eth-gas-price", | ||
Value: "", | ||
Usage: "Gas price in wei to use for the transaction execution (empty = gas price oracle)", | ||
Destination: &options.ETHGasPrice, | ||
}, | ||
&cli.StringFlag{ | ||
Name: "eth-gas-fee-cap", | ||
Value: "", | ||
Usage: "Gas fee cap in wei to use for the 1559 transaction execution (empty = gas price oracle)", | ||
Destination: &options.ETHGasFeeCap, | ||
}, | ||
&cli.StringFlag{ | ||
Name: "eth-gas-tip-cap", | ||
Value: "", | ||
Usage: "Gas priority fee cap in wei to use for the 1559 transaction execution (empty = gas price oracle)", | ||
Destination: &options.ETHGasTipCap, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package rlngenerate | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
) | ||
|
||
// Options are settings used to create RLN credentials. | ||
type Options struct { | ||
CredentialsPath string | ||
CredentialsPassword string | ||
ETHPrivateKey *ecdsa.PrivateKey | ||
ETHClientAddress string | ||
MembershipContractAddress common.Address | ||
ETHGasLimit uint64 | ||
ETHNonce string | ||
ETHGasPrice string | ||
ETHGasFeeCap string | ||
ETHGasTipCap string | ||
} |
Oops, something went wrong.