mirror of https://github.com/status-im/go-waku.git
refactor: remove credential registering from waku
This commit is contained in:
parent
f088e49075
commit
0b943caaa8
|
@ -64,15 +64,6 @@ func rlnFlags() []cli.Flag {
|
||||||
Usage: "the index of credentials to use",
|
Usage: "the index of credentials to use",
|
||||||
Destination: &options.RLNRelay.CredentialsIndex,
|
Destination: &options.RLNRelay.CredentialsIndex,
|
||||||
},
|
},
|
||||||
// TODO: this is a good candidate option for subcommands
|
|
||||||
// TODO: consider accepting a private key file and passwd
|
|
||||||
&cli.GenericFlag{
|
|
||||||
Name: "rln-relay-eth-account-private-key",
|
|
||||||
Usage: "Ethereum account private key used for registering in member contract",
|
|
||||||
Value: &wcli.PrivateKeyValue{
|
|
||||||
Value: &options.RLNRelay.ETHPrivateKey,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "rln-relay-eth-client-address",
|
Name: "rln-relay-eth-client-address",
|
||||||
Usage: "Ethereum testnet client address",
|
Usage: "Ethereum testnet client address",
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/waku-org/go-waku/waku/v2/node"
|
"github.com/waku-org/go-waku/waku/v2/node"
|
||||||
|
@ -20,12 +19,6 @@ func checkForRLN(logger *zap.Logger, options NodeOptions, nodeOpts *[]node.WakuN
|
||||||
if !options.RLNRelay.Dynamic {
|
if !options.RLNRelay.Dynamic {
|
||||||
*nodeOpts = append(*nodeOpts, node.WithStaticRLNRelay(options.RLNRelay.PubsubTopic, options.RLNRelay.ContentTopic, rln.MembershipIndex(options.RLNRelay.MembershipGroupIndex), nil))
|
*nodeOpts = append(*nodeOpts, node.WithStaticRLNRelay(options.RLNRelay.PubsubTopic, options.RLNRelay.ContentTopic, rln.MembershipIndex(options.RLNRelay.MembershipGroupIndex), nil))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
var ethPrivKey *ecdsa.PrivateKey
|
|
||||||
if options.RLNRelay.ETHPrivateKey != nil {
|
|
||||||
ethPrivKey = options.RLNRelay.ETHPrivateKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: too many parameters in this function
|
// TODO: too many parameters in this function
|
||||||
// consider passing a config struct instead
|
// consider passing a config struct instead
|
||||||
*nodeOpts = append(*nodeOpts, node.WithDynamicRLNRelay(
|
*nodeOpts = append(*nodeOpts, node.WithDynamicRLNRelay(
|
||||||
|
@ -39,8 +32,6 @@ func checkForRLN(logger *zap.Logger, options NodeOptions, nodeOpts *[]node.WakuN
|
||||||
rln.MembershipIndex(options.RLNRelay.MembershipGroupIndex),
|
rln.MembershipIndex(options.RLNRelay.MembershipGroupIndex),
|
||||||
nil,
|
nil,
|
||||||
options.RLNRelay.ETHClientAddress,
|
options.RLNRelay.ETHClientAddress,
|
||||||
ethPrivKey,
|
|
||||||
nil,
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ type RLNRelayOptions struct {
|
||||||
PubsubTopic string
|
PubsubTopic string
|
||||||
ContentTopic string
|
ContentTopic string
|
||||||
Dynamic bool
|
Dynamic bool
|
||||||
ETHPrivateKey *ecdsa.PrivateKey
|
|
||||||
ETHClientAddress string
|
ETHClientAddress string
|
||||||
MembershipContractAddress common.Address
|
MembershipContractAddress common.Address
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,12 +130,13 @@ func persistCredentials(identityCredential *rln.IdentityCredential, membershipIn
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
keystoreIndex, membershipGroupIndex, err := keystore.AddMembershipCredentials(options.CredentialsPath, identityCredential, membershipGroup, options.CredentialsPassword, dynamic.RLNAppInfo, keystore.DefaultSeparator)
|
membershipGroupIndex, err := keystore.AddMembershipCredentials(options.CredentialsPath, identityCredential, membershipGroup, options.CredentialsPassword, dynamic.RLNAppInfo, keystore.DefaultSeparator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to persist credentials: %w", err)
|
return fmt.Errorf("failed to persist credentials: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("persisted credentials succesfully", zap.Int("keystoreIndex", keystoreIndex), zap.Int("membershipGroupIndex", membershipGroupIndex))
|
// TODO: obtain keystore index?
|
||||||
|
logger.Info("persisted credentials succesfully", zap.Uint("membershipGroupIndex", membershipGroupIndex))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/libp2p/go-libp2p/core/protocol"
|
"github.com/libp2p/go-libp2p/core/protocol"
|
||||||
"github.com/multiformats/go-multiaddr"
|
"github.com/multiformats/go-multiaddr"
|
||||||
|
@ -48,26 +47,6 @@ func execute(options Options) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
registrationHandler := func(tx *types.Transaction) {
|
|
||||||
chainID := tx.ChainId().Int64()
|
|
||||||
url := ""
|
|
||||||
switch chainID {
|
|
||||||
case 1:
|
|
||||||
url = "https://etherscan.io"
|
|
||||||
case 5:
|
|
||||||
url = "https://goerli.etherscan.io"
|
|
||||||
case 11155111:
|
|
||||||
url = "https://sepolia.etherscan.io"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if url != "" {
|
|
||||||
fmt.Println(fmt.Sprintf("You are registered to the rln membership contract, find details of your registration transaction in %s/tx/%s", url, tx.Hash()))
|
|
||||||
} else {
|
|
||||||
fmt.Println(fmt.Sprintf("You are registered to the rln membership contract. Transaction hash: %s", url, tx.Hash()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.RLNRelay.Dynamic {
|
if options.RLNRelay.Dynamic {
|
||||||
fmt.Println("Setting up dynamic rln...")
|
fmt.Println("Setting up dynamic rln...")
|
||||||
opts = append(opts, node.WithDynamicRLNRelay(
|
opts = append(opts, node.WithDynamicRLNRelay(
|
||||||
|
@ -81,8 +60,6 @@ func execute(options Options) {
|
||||||
uint(options.RLNRelay.MembershipIndex),
|
uint(options.RLNRelay.MembershipIndex),
|
||||||
spamHandler,
|
spamHandler,
|
||||||
options.RLNRelay.ETHClientAddress,
|
options.RLNRelay.ETHClientAddress,
|
||||||
options.RLNRelay.ETHPrivateKey,
|
|
||||||
registrationHandler,
|
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
opts = append(opts, node.WithStaticRLNRelay(
|
opts = append(opts, node.WithStaticRLNRelay(
|
||||||
|
|
|
@ -227,15 +227,6 @@ func getFlags() []cli.Flag {
|
||||||
Usage: "Password for encrypting RLN credentials",
|
Usage: "Password for encrypting RLN credentials",
|
||||||
Destination: &options.RLNRelay.CredentialsPassword,
|
Destination: &options.RLNRelay.CredentialsPassword,
|
||||||
},
|
},
|
||||||
// TODO: this is a good candidate option for subcommands
|
|
||||||
// TODO: consider accepting a private key file and passwd
|
|
||||||
&cli.GenericFlag{
|
|
||||||
Name: "rln-relay-eth-account-private-key",
|
|
||||||
Usage: "Ethereum Goerli testnet account private key used for registering in member contract",
|
|
||||||
Value: &wcli.PrivateKeyValue{
|
|
||||||
Value: &options.RLNRelay.ETHPrivateKey,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "rln-relay-eth-client-address",
|
Name: "rln-relay-eth-client-address",
|
||||||
Usage: "Ethereum testnet client address",
|
Usage: "Ethereum testnet client address",
|
||||||
|
|
|
@ -37,7 +37,6 @@ type RLNRelayOptions struct {
|
||||||
PubsubTopic string
|
PubsubTopic string
|
||||||
ContentTopic string
|
ContentTopic string
|
||||||
Dynamic bool
|
Dynamic bool
|
||||||
ETHPrivateKey *ecdsa.PrivateKey
|
|
||||||
ETHClientAddress string
|
ETHClientAddress string
|
||||||
MembershipContractAddress common.Address
|
MembershipContractAddress common.Address
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/waku-org/go-waku/waku/v2/node"
|
"github.com/waku-org/go-waku/waku/v2/node"
|
||||||
"github.com/waku-org/go-waku/waku/v2/payload"
|
"github.com/waku-org/go-waku/waku/v2/payload"
|
||||||
|
@ -27,10 +26,11 @@ var log = utils.Logger().Named("rln")
|
||||||
// Update these values
|
// Update these values
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
const ethClientAddress = "wss://sepolia.infura.io/ws/v3/API_KEY_GOES_HERE"
|
const ethClientAddress = "wss://sepolia.infura.io/ws/v3/API_KEY_GOES_HERE"
|
||||||
const ethPrivateKey = "PRIVATE_KEY_GOES_HERE"
|
|
||||||
const contractAddress = "0x9C09146844C1326c2dBC41c451766C7138F88155"
|
const contractAddress = "0x9C09146844C1326c2dBC41c451766C7138F88155"
|
||||||
const credentialsPath = "" // Empty to store in current folder
|
const keystorePath = "" // Empty to store in current folder
|
||||||
const credentialsPassword = "" // Empty to use default
|
const keystorePassword = "" // Empty to use default
|
||||||
|
const keystoreIndex = 0
|
||||||
|
const membershipGroupIndex = 0
|
||||||
|
|
||||||
var contentTopic = protocol.NewContentTopic("rln", 1, "test", "proto").String()
|
var contentTopic = protocol.NewContentTopic("rln", 1, "test", "proto").String()
|
||||||
var pubsubTopic = protocol.DefaultPubsubTopic()
|
var pubsubTopic = protocol.DefaultPubsubTopic()
|
||||||
|
@ -57,34 +57,6 @@ func main() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
registrationHandler := func(tx *types.Transaction) {
|
|
||||||
chainID := tx.ChainId().Int64()
|
|
||||||
url := ""
|
|
||||||
switch chainID {
|
|
||||||
case 1:
|
|
||||||
url = "https://etherscan.io"
|
|
||||||
case 5:
|
|
||||||
url = "https://goerli.etherscan.io"
|
|
||||||
case 11155111:
|
|
||||||
url = "https://sepolia.etherscan.io"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if url != "" {
|
|
||||||
fmt.Println(fmt.Sprintf("You are registered to the rln membership contract, find details of your registration transaction in %s/tx/%s", url, tx.Hash()))
|
|
||||||
} else {
|
|
||||||
fmt.Println(fmt.Sprintf("You are registered to the rln membership contract. Transaction hash: %s", url, tx.Hash()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: set configuration values in constants
|
|
||||||
|
|
||||||
ethPrivKey, err := crypto.HexToECDSA(ethPrivateKey)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Could not convert hex into ecdsa key", zap.Error(err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
wakuNode, err := node.New(
|
wakuNode, err := node.New(
|
||||||
node.WithPrivateKey(prvKey),
|
node.WithPrivateKey(prvKey),
|
||||||
node.WithHostAddress(hostAddr),
|
node.WithHostAddress(hostAddr),
|
||||||
|
@ -93,13 +65,14 @@ func main() {
|
||||||
node.WithDynamicRLNRelay(
|
node.WithDynamicRLNRelay(
|
||||||
pubsubTopic.String(),
|
pubsubTopic.String(),
|
||||||
contentTopic,
|
contentTopic,
|
||||||
credentialsPath,
|
keystorePath,
|
||||||
credentialsPassword,
|
keystorePassword,
|
||||||
|
keystoreIndex,
|
||||||
|
"", // Will use default tree path
|
||||||
common.HexToAddress(contractAddress),
|
common.HexToAddress(contractAddress),
|
||||||
|
membershipGroupIndex,
|
||||||
spamHandler,
|
spamHandler,
|
||||||
ethClientAddress,
|
ethClientAddress,
|
||||||
ethPrivKey,
|
|
||||||
registrationHandler,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -48,14 +48,12 @@ func (w *WakuNode) mountRlnRelay(ctx context.Context) error {
|
||||||
|
|
||||||
groupManager, err = dynamic.NewDynamicGroupManager(
|
groupManager, err = dynamic.NewDynamicGroupManager(
|
||||||
w.opts.rlnETHClientAddress,
|
w.opts.rlnETHClientAddress,
|
||||||
w.opts.rlnETHPrivateKey,
|
|
||||||
w.opts.rlnMembershipContractAddress,
|
w.opts.rlnMembershipContractAddress,
|
||||||
w.opts.rlnRelayMemIndex,
|
w.opts.rlnRelayMemIndex,
|
||||||
w.opts.keystorePath,
|
w.opts.keystorePath,
|
||||||
w.opts.keystorePassword,
|
w.opts.keystorePassword,
|
||||||
w.opts.keystoreIndex,
|
w.opts.keystoreIndex,
|
||||||
true,
|
true,
|
||||||
w.opts.rlnRegistrationHandler,
|
|
||||||
w.log,
|
w.log,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"github.com/libp2p/go-libp2p"
|
"github.com/libp2p/go-libp2p"
|
||||||
|
@ -100,14 +99,12 @@ type WakuNodeParameters struct {
|
||||||
rlnRelayContentTopic string
|
rlnRelayContentTopic string
|
||||||
rlnRelayDynamic bool
|
rlnRelayDynamic bool
|
||||||
rlnSpamHandler func(message *pb.WakuMessage) error
|
rlnSpamHandler func(message *pb.WakuMessage) error
|
||||||
rlnETHPrivateKey *ecdsa.PrivateKey
|
|
||||||
rlnETHClientAddress string
|
rlnETHClientAddress string
|
||||||
keystorePath string
|
keystorePath string
|
||||||
keystorePassword string
|
keystorePassword string
|
||||||
keystoreIndex uint
|
keystoreIndex uint
|
||||||
rlnTreePath string
|
rlnTreePath string
|
||||||
rlnMembershipContractAddress common.Address
|
rlnMembershipContractAddress common.Address
|
||||||
rlnRegistrationHandler func(tx *types.Transaction)
|
|
||||||
|
|
||||||
keepAliveInterval time.Duration
|
keepAliveInterval time.Duration
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
package node
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/waku-org/go-waku/waku/v2/protocol/rln"
|
"github.com/waku-org/go-waku/waku/v2/protocol/rln"
|
||||||
r "github.com/waku-org/go-zerokit-rln/rln"
|
r "github.com/waku-org/go-zerokit-rln/rln"
|
||||||
|
@ -27,7 +25,7 @@ func WithStaticRLNRelay(pubsubTopic string, contentTopic string, memberIndex r.M
|
||||||
|
|
||||||
// WithDynamicRLNRelay enables the Waku V2 RLN protocol in onchain mode.
|
// WithDynamicRLNRelay enables the Waku V2 RLN protocol in onchain mode.
|
||||||
// Requires the `gowaku_rln` build constrain (or the env variable RLN=true if building go-waku)
|
// Requires the `gowaku_rln` build constrain (or the env variable RLN=true if building go-waku)
|
||||||
func WithDynamicRLNRelay(pubsubTopic string, contentTopic string, keystorePath string, keystorePassword string, keystoreIndex uint, treePath string, membershipContract common.Address, membershipGroupIndex uint, spamHandler rln.SpamHandler, ethClientAddress string, ethPrivateKey *ecdsa.PrivateKey, registrationHandler rln.RegistrationHandler) WakuNodeOption {
|
func WithDynamicRLNRelay(pubsubTopic string, contentTopic string, keystorePath string, keystorePassword string, keystoreIndex uint, treePath string, membershipContract common.Address, membershipGroupIndex uint, spamHandler rln.SpamHandler, ethClientAddress string) WakuNodeOption {
|
||||||
return func(params *WakuNodeParameters) error {
|
return func(params *WakuNodeParameters) error {
|
||||||
params.enableRLN = true
|
params.enableRLN = true
|
||||||
params.rlnRelayDynamic = true
|
params.rlnRelayDynamic = true
|
||||||
|
@ -38,9 +36,7 @@ func WithDynamicRLNRelay(pubsubTopic string, contentTopic string, keystorePath s
|
||||||
params.rlnRelayContentTopic = contentTopic
|
params.rlnRelayContentTopic = contentTopic
|
||||||
params.rlnSpamHandler = spamHandler
|
params.rlnSpamHandler = spamHandler
|
||||||
params.rlnETHClientAddress = ethClientAddress
|
params.rlnETHClientAddress = ethClientAddress
|
||||||
params.rlnETHPrivateKey = ethPrivateKey
|
|
||||||
params.rlnMembershipContractAddress = membershipContract
|
params.rlnMembershipContractAddress = membershipContract
|
||||||
params.rlnRegistrationHandler = registrationHandler
|
|
||||||
params.rlnRelayMemIndex = membershipGroupIndex
|
params.rlnRelayMemIndex = membershipGroupIndex
|
||||||
params.rlnTreePath = treePath
|
params.rlnTreePath = treePath
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -2,7 +2,6 @@ package dynamic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -43,17 +42,10 @@ type DynamicGroupManager struct {
|
||||||
|
|
||||||
lastBlockProcessed uint64
|
lastBlockProcessed uint64
|
||||||
|
|
||||||
// ethAccountPrivateKey is required for signing transactions
|
|
||||||
// TODO may need to erase this ethAccountPrivateKey when is not used
|
|
||||||
// TODO may need to make ethAccountPrivateKey mandatory
|
|
||||||
ethAccountPrivateKey *ecdsa.PrivateKey
|
|
||||||
|
|
||||||
eventHandler RegistrationEventHandler
|
eventHandler RegistrationEventHandler
|
||||||
|
|
||||||
registrationHandler RegistrationHandler
|
chainId *big.Int
|
||||||
chainId *big.Int
|
rlnContract *contracts.RLN
|
||||||
rlnContract *contracts.RLN
|
|
||||||
membershipFee *big.Int
|
|
||||||
|
|
||||||
saveKeystore bool
|
saveKeystore bool
|
||||||
keystorePath string
|
keystorePath string
|
||||||
|
@ -120,14 +112,12 @@ type RegistrationHandler = func(tx *types.Transaction)
|
||||||
|
|
||||||
func NewDynamicGroupManager(
|
func NewDynamicGroupManager(
|
||||||
ethClientAddr string,
|
ethClientAddr string,
|
||||||
ethAccountPrivateKey *ecdsa.PrivateKey,
|
|
||||||
memContractAddr common.Address,
|
memContractAddr common.Address,
|
||||||
membershipGroupIndex uint,
|
membershipGroupIndex uint,
|
||||||
keystorePath string,
|
keystorePath string,
|
||||||
keystorePassword string,
|
keystorePassword string,
|
||||||
keystoreIndex uint,
|
keystoreIndex uint,
|
||||||
saveKeystore bool,
|
saveKeystore bool,
|
||||||
registrationHandler RegistrationHandler,
|
|
||||||
log *zap.Logger,
|
log *zap.Logger,
|
||||||
) (*DynamicGroupManager, error) {
|
) (*DynamicGroupManager, error) {
|
||||||
log = log.Named("rln-dynamic")
|
log = log.Named("rln-dynamic")
|
||||||
|
@ -148,8 +138,6 @@ func NewDynamicGroupManager(
|
||||||
membershipGroupIndex: membershipGroupIndex,
|
membershipGroupIndex: membershipGroupIndex,
|
||||||
membershipContractAddress: memContractAddr,
|
membershipContractAddress: memContractAddr,
|
||||||
ethClientAddress: ethClientAddr,
|
ethClientAddress: ethClientAddr,
|
||||||
ethAccountPrivateKey: ethAccountPrivateKey,
|
|
||||||
registrationHandler: registrationHandler,
|
|
||||||
eventHandler: handler,
|
eventHandler: handler,
|
||||||
saveKeystore: saveKeystore,
|
saveKeystore: saveKeystore,
|
||||||
keystorePath: path,
|
keystorePath: path,
|
||||||
|
@ -193,7 +181,7 @@ func (gm *DynamicGroupManager) Start(ctx context.Context, rlnInstance *rln.RLN,
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the contract exists by calling a static function
|
// check if the contract exists by calling a static function
|
||||||
gm.membershipFee, err = gm.getMembershipFee(ctx)
|
_, err = gm.getMembershipFee(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -227,34 +215,6 @@ func (gm *DynamicGroupManager) Start(ctx context.Context, rlnInstance *rln.RLN,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if gm.identityCredential == nil && gm.ethAccountPrivateKey == nil {
|
|
||||||
return errors.New("either a credentials path or a private key must be specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare rln membership key pair
|
|
||||||
if gm.identityCredential == nil && gm.ethAccountPrivateKey != nil {
|
|
||||||
gm.log.Info("no rln-relay key is provided, generating one")
|
|
||||||
identityCredential, err := rlnInstance.MembershipKeyGen()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
gm.identityCredential = identityCredential
|
|
||||||
|
|
||||||
// register the rln-relay peer to the membership contract
|
|
||||||
gm.membershipIndex, err = gm.Register(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = gm.persistCredentials()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
gm.log.Info("registered peer into the membership contract")
|
|
||||||
}
|
|
||||||
|
|
||||||
if gm.identityCredential == nil || gm.membershipIndex == nil {
|
if gm.identityCredential == nil || gm.membershipIndex == nil {
|
||||||
return errors.New("no credentials available")
|
return errors.New("no credentials available")
|
||||||
}
|
}
|
||||||
|
@ -266,31 +226,6 @@ func (gm *DynamicGroupManager) Start(ctx context.Context, rlnInstance *rln.RLN,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gm *DynamicGroupManager) persistCredentials() error {
|
|
||||||
if !gm.saveKeystore {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if gm.identityCredential == nil || gm.membershipIndex == nil {
|
|
||||||
return errors.New("no credentials to persist")
|
|
||||||
}
|
|
||||||
|
|
||||||
membershipGroup := keystore.MembershipGroup{
|
|
||||||
TreeIndex: *gm.membershipIndex,
|
|
||||||
MembershipContract: keystore.MembershipContract{
|
|
||||||
ChainId: fmt.Sprintf("0x%X", gm.chainId),
|
|
||||||
Address: gm.membershipContractAddress.String(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := keystore.AddMembershipCredentials(gm.keystorePath, gm.identityCredential, membershipGroup, gm.keystorePassword, RLNAppInfo, keystore.DefaultSeparator)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to persist credentials: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gm *DynamicGroupManager) InsertMembers(toInsert *om.OrderedMap) error {
|
func (gm *DynamicGroupManager) InsertMembers(toInsert *om.OrderedMap) error {
|
||||||
for pair := toInsert.Oldest(); pair != nil; pair = pair.Next() {
|
for pair := toInsert.Oldest(); pair != nil; pair = pair.Next() {
|
||||||
events := pair.Value.([]*contracts.RLNMemberRegistered) // TODO: should these be sortered by index? we assume all members arrive in order
|
events := pair.Value.([]*contracts.RLNMemberRegistered) // TODO: should these be sortered by index? we assume all members arrive in order
|
||||||
|
@ -345,11 +280,6 @@ func (gm *DynamicGroupManager) IdentityCredentials() (rln.IdentityCredential, er
|
||||||
return *gm.identityCredential, nil
|
return *gm.identityCredential, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gm *DynamicGroupManager) SetCredentials(identityCredential *rln.IdentityCredential, index *rln.MembershipIndex) {
|
|
||||||
gm.identityCredential = identityCredential
|
|
||||||
gm.membershipIndex = index
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gm *DynamicGroupManager) MembershipIndex() (rln.MembershipIndex, error) {
|
func (gm *DynamicGroupManager) MembershipIndex() (rln.MembershipIndex, error) {
|
||||||
if gm.membershipIndex == nil {
|
if gm.membershipIndex == nil {
|
||||||
return 0, errors.New("membership index has not been setup")
|
return 0, errors.New("membership index has not been setup")
|
||||||
|
|
|
@ -2,90 +2,17 @@ package dynamic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
|
||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/waku-org/go-waku/waku/v2/protocol/rln/contracts"
|
"github.com/waku-org/go-waku/waku/v2/protocol/rln/contracts"
|
||||||
"github.com/waku-org/go-zerokit-rln/rln"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func register(ctx context.Context, backend *ethclient.Client, membershipFee *big.Int, idComm rln.IDCommitment, ethAccountPrivateKey *ecdsa.PrivateKey, rlnContract *contracts.RLN, chainID *big.Int, registrationHandler RegistrationHandler, log *zap.Logger) (*rln.MembershipIndex, error) {
|
|
||||||
auth, err := bind.NewKeyedTransactorWithChainID(ethAccountPrivateKey, chainID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
auth.Value = membershipFee
|
|
||||||
auth.Context = ctx
|
|
||||||
|
|
||||||
log.Debug("registering an id commitment", zap.Binary("idComm", idComm[:]))
|
|
||||||
|
|
||||||
// registers the idComm into the membership contract whose address is in rlnPeer.membershipContractAddress
|
|
||||||
tx, err := rlnContract.Register(auth, rln.Bytes32ToBigInt(idComm))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("transaction broadcasted", zap.String("transactionHash", tx.Hash().Hex()))
|
|
||||||
|
|
||||||
if registrationHandler != nil {
|
|
||||||
registrationHandler(tx)
|
|
||||||
}
|
|
||||||
|
|
||||||
txReceipt, err := bind.WaitMined(ctx, backend, tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if txReceipt.Status != types.ReceiptStatusSuccessful {
|
|
||||||
return nil, errors.New("transaction reverted")
|
|
||||||
}
|
|
||||||
|
|
||||||
// the receipt topic holds the hash of signature of the raised events
|
|
||||||
evt, err := rlnContract.ParseMemberRegistered(*txReceipt.Logs[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var eventIDComm rln.IDCommitment = rln.BigIntToBytes32(evt.Pubkey)
|
|
||||||
|
|
||||||
log.Debug("the identity commitment key extracted from tx log", zap.Binary("eventIDComm", eventIDComm[:]))
|
|
||||||
|
|
||||||
if eventIDComm != idComm {
|
|
||||||
return nil, errors.New("invalid id commitment key")
|
|
||||||
}
|
|
||||||
|
|
||||||
result := new(rln.MembershipIndex)
|
|
||||||
*result = rln.MembershipIndex(uint(evt.Index.Int64()))
|
|
||||||
|
|
||||||
// debug "the index of registered identity commitment key", eventIndex=eventIndex
|
|
||||||
|
|
||||||
log.Debug("the index of registered identity commitment key", zap.Uint("eventIndex", uint(*result)))
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register registers the public key of the rlnPeer which is rlnPeer.membershipKeyPair.publicKey
|
|
||||||
// into the membership contract whose address is in rlnPeer.membershipContractAddress
|
|
||||||
func (gm *DynamicGroupManager) Register(ctx context.Context) (*rln.MembershipIndex, error) {
|
|
||||||
return register(ctx,
|
|
||||||
gm.ethClient,
|
|
||||||
gm.membershipFee,
|
|
||||||
gm.identityCredential.IDCommitment,
|
|
||||||
gm.ethAccountPrivateKey,
|
|
||||||
gm.rlnContract,
|
|
||||||
gm.chainId,
|
|
||||||
gm.registrationHandler,
|
|
||||||
gm.log)
|
|
||||||
}
|
|
||||||
|
|
||||||
// the types of inputs to this handler matches the MemberRegistered event/proc defined in the MembershipContract interface
|
// the types of inputs to this handler matches the MemberRegistered event/proc defined in the MembershipContract interface
|
||||||
type RegistrationEventHandler = func(*DynamicGroupManager, []*contracts.RLNMemberRegistered) error
|
type RegistrationEventHandler = func(*DynamicGroupManager, []*contracts.RLNMemberRegistered) error
|
||||||
|
|
||||||
|
|
|
@ -220,10 +220,10 @@ func GetMembershipCredentials(logger *zap.Logger, credentialsPath string, passwo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a membership credential to the keystore matching the application, appIdentifier and version filters.
|
// Adds a membership credential to the keystore matching the application, appIdentifier and version filters.
|
||||||
func AddMembershipCredentials(path string, newIdentityCredential *rln.IdentityCredential, newMembershipGroup MembershipGroup, password string, appInfo AppInfo, separator string) (keystoreIndex int, membershipGroupIndex int, err error) {
|
func AddMembershipCredentials(path string, newIdentityCredential *rln.IdentityCredential, newMembershipGroup MembershipGroup, password string, appInfo AppInfo, separator string) (membershipGroupIndex uint, err error) {
|
||||||
k, err := LoadAppKeystore(path, appInfo, DefaultSeparator)
|
k, err := LoadAppKeystore(path, appInfo, DefaultSeparator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// A flag to tell us if the keystore contains a credential associated to the input identity credential, i.e. membershipCredential
|
// A flag to tell us if the keystore contains a credential associated to the input identity credential, i.e. membershipCredential
|
||||||
|
@ -266,12 +266,12 @@ func AddMembershipCredentials(path string, newIdentityCredential *rln.IdentityCr
|
||||||
// we re-encrypt creating a new keyfile
|
// we re-encrypt creating a new keyfile
|
||||||
b, err := json.Marshal(updatedCredential)
|
b, err := json.Marshal(updatedCredential)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptedCredentials, err := keystore.EncryptDataV3(b, []byte(password), keystore.StandardScryptN, keystore.StandardScryptP)
|
encryptedCredentials, err := keystore.EncryptDataV3(b, []byte(password), keystore.StandardScryptN, keystore.StandardScryptP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// we update the original credential field in keystoreCredentials
|
// we update the original credential field in keystoreCredentials
|
||||||
|
@ -280,11 +280,10 @@ func AddMembershipCredentials(path string, newIdentityCredential *rln.IdentityCr
|
||||||
found = true
|
found = true
|
||||||
|
|
||||||
// We setup the return values
|
// We setup the return values
|
||||||
membershipGroupIndex = len(allMemberships)
|
membershipGroupIndex = uint(len(allMemberships))
|
||||||
keystoreIndex = i
|
|
||||||
for mIdx, mg := range updatedCredential.MembershipGroups {
|
for mIdx, mg := range updatedCredential.MembershipGroups {
|
||||||
if mg.MembershipContract.Equals(newMembershipGroup.MembershipContract) {
|
if mg.MembershipContract.Equals(newMembershipGroup.MembershipContract) {
|
||||||
membershipGroupIndex = mIdx
|
membershipGroupIndex = uint(mIdx)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,21 +301,20 @@ func AddMembershipCredentials(path string, newIdentityCredential *rln.IdentityCr
|
||||||
|
|
||||||
b, err := json.Marshal(newCredential)
|
b, err := json.Marshal(newCredential)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptedCredentials, err := keystore.EncryptDataV3(b, []byte(password), keystore.StandardScryptN, keystore.StandardScryptP)
|
encryptedCredentials, err := keystore.EncryptDataV3(b, []byte(password), keystore.StandardScryptN, keystore.StandardScryptP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
k.Credentials = append(k.Credentials, AppKeystoreCredential{Crypto: encryptedCredentials})
|
k.Credentials = append(k.Credentials, AppKeystoreCredential{Crypto: encryptedCredentials})
|
||||||
|
|
||||||
keystoreIndex = len(k.Credentials) - 1
|
membershipGroupIndex = uint(len(newCredential.MembershipGroups) - 1)
|
||||||
membershipGroupIndex = len(newCredential.MembershipGroups) - 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return keystoreIndex, membershipGroupIndex, save(k, path, separator)
|
return membershipGroupIndex, save(k, path, separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safely saves a Keystore's JsonNode to disk.
|
// Safely saves a Keystore's JsonNode to disk.
|
||||||
|
|
|
@ -4,11 +4,10 @@
|
||||||
package rln
|
package rln
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"errors"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -16,9 +15,11 @@ import (
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/waku-org/go-zerokit-rln/rln"
|
"github.com/waku-org/go-zerokit-rln/rln"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
@ -27,11 +28,13 @@ import (
|
||||||
"github.com/waku-org/go-waku/waku/v2/protocol/rln/contracts"
|
"github.com/waku-org/go-waku/waku/v2/protocol/rln/contracts"
|
||||||
"github.com/waku-org/go-waku/waku/v2/protocol/rln/group_manager"
|
"github.com/waku-org/go-waku/waku/v2/protocol/rln/group_manager"
|
||||||
"github.com/waku-org/go-waku/waku/v2/protocol/rln/group_manager/dynamic"
|
"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/timesource"
|
"github.com/waku-org/go-waku/waku/v2/timesource"
|
||||||
"github.com/waku-org/go-waku/waku/v2/utils"
|
"github.com/waku-org/go-waku/waku/v2/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var MEMBERSHIP_FEE = big.NewInt(1000000000000000) // wei - 0.001 eth
|
var membershipFee = big.NewInt(1000000000000000) // wei - 0.001 eth
|
||||||
|
const keystorePassword = "test"
|
||||||
|
|
||||||
func TestWakuRLNRelayDynamicSuite(t *testing.T) {
|
func TestWakuRLNRelayDynamicSuite(t *testing.T) {
|
||||||
suite.Run(t, new(WakuRLNRelayDynamicSuite))
|
suite.Run(t, new(WakuRLNRelayDynamicSuite))
|
||||||
|
@ -49,11 +52,10 @@ type WakuRLNRelayDynamicSuite struct {
|
||||||
|
|
||||||
u1PrivKey *ecdsa.PrivateKey
|
u1PrivKey *ecdsa.PrivateKey
|
||||||
u2PrivKey *ecdsa.PrivateKey
|
u2PrivKey *ecdsa.PrivateKey
|
||||||
u3PrivKey *ecdsa.PrivateKey
|
|
||||||
u4PrivKey *ecdsa.PrivateKey
|
|
||||||
u5PrivKey *ecdsa.PrivateKey
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: on teardown, remove credentials
|
||||||
|
|
||||||
func (s *WakuRLNRelayDynamicSuite) SetupTest() {
|
func (s *WakuRLNRelayDynamicSuite) SetupTest() {
|
||||||
|
|
||||||
s.clientAddr = os.Getenv("GANACHE_NETWORK_RPC_URL")
|
s.clientAddr = os.Getenv("GANACHE_NETWORK_RPC_URL")
|
||||||
|
@ -73,12 +75,6 @@ func (s *WakuRLNRelayDynamicSuite) SetupTest() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.u2PrivKey, err = crypto.ToECDSA(common.FromHex("0xa00da43843ad6b5161ddbace48f293ac3f82f8a8257af34de4c32900bb6e9a97"))
|
s.u2PrivKey, err = crypto.ToECDSA(common.FromHex("0xa00da43843ad6b5161ddbace48f293ac3f82f8a8257af34de4c32900bb6e9a97"))
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.u3PrivKey, err = crypto.ToECDSA(common.FromHex("0xa4c8d3ed78cd722521fac9d734c45187a4f5e887570be1f707a7bbce054c01ea"))
|
|
||||||
s.Require().NoError(err)
|
|
||||||
s.u4PrivKey, err = crypto.ToECDSA(common.FromHex("0x6b11ba548a7fd1958eb156877cc7bdd02d99d876b55381aa9b106c16b0b7a805"))
|
|
||||||
s.Require().NoError(err)
|
|
||||||
s.u5PrivKey, err = crypto.ToECDSA(common.FromHex("0x0410196287d0af405e5c16f610de52416bd48be74836dbca93d73e24bffb5a81"))
|
|
||||||
s.Require().NoError(err)
|
|
||||||
|
|
||||||
s.backend = backend
|
s.backend = backend
|
||||||
s.chainID = chainID
|
s.chainID = chainID
|
||||||
|
@ -87,35 +83,63 @@ func (s *WakuRLNRelayDynamicSuite) SetupTest() {
|
||||||
auth, err := bind.NewKeyedTransactorWithChainID(s.u1PrivKey, chainID)
|
auth, err := bind.NewKeyedTransactorWithChainID(s.u1PrivKey, chainID)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// TODO: update rln contract
|
||||||
|
|
||||||
poseidonHasherAddr, _, _, err := contracts.DeployPoseidonHasher(auth, backend)
|
poseidonHasherAddr, _, _, err := contracts.DeployPoseidonHasher(auth, backend)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
rlnAddr, _, rlnContract, err := contracts.DeployRLN(auth, backend, MEMBERSHIP_FEE, big.NewInt(20), poseidonHasherAddr)
|
rlnAddr, _, rlnContract, err := contracts.DeployRLN(auth, backend, membershipFee, big.NewInt(20), poseidonHasherAddr)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
s.rlnAddr = rlnAddr
|
s.rlnAddr = rlnAddr
|
||||||
s.rlnContract = rlnContract
|
s.rlnContract = rlnContract
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WakuRLNRelayDynamicSuite) register(privKey *ecdsa.PrivateKey, commitment *big.Int, handler func(evt *contracts.RLNMemberRegistered) error) {
|
func (s *WakuRLNRelayDynamicSuite) removeCredentials(path string) {
|
||||||
|
err := os.Remove(path)
|
||||||
|
if err != nil {
|
||||||
|
utils.Logger().Warn("could not remove credentials", zap.String("path", path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WakuRLNRelayDynamicSuite) generateCredentials(rlnInstance *rln.RLN) *rln.IdentityCredential {
|
||||||
|
identityCredential, err := rlnInstance.MembershipKeyGen()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
return identityCredential
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *WakuRLNRelayDynamicSuite) register(identityCredential *rln.IdentityCredential, privKey *ecdsa.PrivateKey, keystorePath string) (rln.MembershipIndex, uint) {
|
||||||
|
|
||||||
auth, err := bind.NewKeyedTransactorWithChainID(privKey, s.chainID)
|
auth, err := bind.NewKeyedTransactorWithChainID(privKey, s.chainID)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
auth.Value = MEMBERSHIP_FEE
|
auth.Value = membershipFee
|
||||||
auth.Context = context.TODO()
|
auth.Context = context.TODO()
|
||||||
|
|
||||||
tx, err := s.rlnContract.Register(auth, commitment)
|
tx, err := s.rlnContract.Register(auth, rln.Bytes32ToBigInt(identityCredential.IDCommitment))
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
receipt, err := bind.WaitMined(context.TODO(), s.backend, tx)
|
txReceipt, err := bind.WaitMined(context.TODO(), s.backend, tx)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
evt, err := s.rlnContract.ParseMemberRegistered(*receipt.Logs[0])
|
s.Require().Equal(txReceipt.Status, types.ReceiptStatusSuccessful)
|
||||||
|
|
||||||
|
evt, err := s.rlnContract.ParseMemberRegistered(*txReceipt.Logs[0])
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
if handler != nil {
|
membershipIndex := rln.MembershipIndex(uint(evt.Index.Int64()))
|
||||||
err = handler(evt)
|
|
||||||
s.Require().NoError(err)
|
membershipGroup := keystore.MembershipGroup{
|
||||||
|
TreeIndex: membershipIndex,
|
||||||
|
MembershipContract: keystore.MembershipContract{
|
||||||
|
ChainId: fmt.Sprintf("0x%X", s.chainID.Int64()),
|
||||||
|
Address: s.rlnAddr.String(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
membershipGroupIndex, err := keystore.AddMembershipCredentials(keystorePath, identityCredential, membershipGroup, keystorePassword, dynamic.RLNAppInfo, keystore.DefaultSeparator)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
return membershipIndex, membershipGroupIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WakuRLNRelayDynamicSuite) TestDynamicGroupManagement() {
|
func (s *WakuRLNRelayDynamicSuite) TestDynamicGroupManagement() {
|
||||||
|
@ -138,7 +162,12 @@ func (s *WakuRLNRelayDynamicSuite) TestDynamicGroupManagement() {
|
||||||
rt, err := group_manager.NewMerkleRootTracker(5, rlnInstance)
|
rt, err := group_manager.NewMerkleRootTracker(5, rlnInstance)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
gm, err := dynamic.NewDynamicGroupManager(s.clientAddr, s.u1PrivKey, s.rlnAddr, 0, "./test_onchain.json", "", 0, false, nil, utils.Logger())
|
u1Credentials := s.generateCredentials(rlnInstance)
|
||||||
|
keystorePath1 := "./test_onchain.json"
|
||||||
|
_, membershipGroupIndex := s.register(u1Credentials, s.u1PrivKey, keystorePath1)
|
||||||
|
defer s.removeCredentials(keystorePath1)
|
||||||
|
|
||||||
|
gm, err := dynamic.NewDynamicGroupManager(s.clientAddr, s.rlnAddr, membershipGroupIndex, keystorePath1, keystorePassword, 0, false, utils.Logger())
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// initialize the WakuRLNRelay
|
// initialize the WakuRLNRelay
|
||||||
|
@ -151,47 +180,47 @@ func (s *WakuRLNRelayDynamicSuite) TestDynamicGroupManagement() {
|
||||||
nullifierLog: make(map[rln.MerkleNode][]rln.ProofMetadata),
|
nullifierLog: make(map[rln.MerkleNode][]rln.ProofMetadata),
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate another membership key pair
|
err = rlnRelay.Start(context.TODO())
|
||||||
keyPair2, err := rlnInstance.MembershipKeyGen()
|
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
err = rlnRelay.Start(context.Background())
|
u2Credentials := s.generateCredentials(rlnInstance)
|
||||||
|
keystorePath2 := "./test_onchain2.json"
|
||||||
|
membershipIndex, _ := s.register(u2Credentials, s.u2PrivKey, keystorePath2)
|
||||||
|
defer s.removeCredentials(keystorePath2)
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
|
treeCommitment, err := rlnInstance.GetLeaf(membershipIndex)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
s.Require().Equal(u2Credentials.IDCommitment, treeCommitment)
|
||||||
// register user
|
|
||||||
gm.Register(context.TODO())
|
|
||||||
|
|
||||||
handler := func(evt *contracts.RLNMemberRegistered) error {
|
|
||||||
pubkey := rln.BigIntToBytes32(evt.Pubkey)
|
|
||||||
if !bytes.Equal(pubkey[:], keyPair2.IDCommitment[:]) {
|
|
||||||
return errors.New("not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
return rlnInstance.InsertMember(pubkey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// register member with contract
|
|
||||||
s.register(s.u2PrivKey, rln.Bytes32ToBigInt(keyPair2.IDCommitment), handler)
|
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WakuRLNRelayDynamicSuite) TestInsertKeyMembershipContract() {
|
func (s *WakuRLNRelayDynamicSuite) TestInsertKeyMembershipContract() {
|
||||||
|
// Create a RLN instance
|
||||||
|
rlnInstance, err := rln.NewRLN()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
s.register(s.u1PrivKey, big.NewInt(20), nil)
|
credentials1 := s.generateCredentials(rlnInstance)
|
||||||
|
credentials2 := s.generateCredentials(rlnInstance)
|
||||||
|
credentials3 := s.generateCredentials(rlnInstance)
|
||||||
|
|
||||||
|
keystorePath1 := "./test_onchain.json"
|
||||||
|
s.register(credentials1, s.u1PrivKey, keystorePath1)
|
||||||
|
defer s.removeCredentials(keystorePath1)
|
||||||
|
|
||||||
// Batch Register
|
// Batch Register
|
||||||
auth, err := bind.NewKeyedTransactorWithChainID(s.u2PrivKey, s.chainID)
|
auth, err := bind.NewKeyedTransactorWithChainID(s.u2PrivKey, s.chainID)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
auth.Value = MEMBERSHIP_FEE.Mul(big.NewInt(2), MEMBERSHIP_FEE)
|
auth.Value = membershipFee.Mul(big.NewInt(2), membershipFee)
|
||||||
auth.Context = context.TODO()
|
auth.Context = context.TODO()
|
||||||
|
|
||||||
tx, err := s.rlnContract.RegisterBatch(auth, []*big.Int{big.NewInt(20), big.NewInt(21)})
|
tx, err := s.rlnContract.RegisterBatch(auth, []*big.Int{rln.Bytes32ToBigInt(credentials2.IDCommitment), rln.Bytes32ToBigInt(credentials3.IDCommitment)})
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
_, err = bind.WaitMined(context.TODO(), s.backend, tx)
|
txReceipt, err := bind.WaitMined(context.TODO(), s.backend, tx)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
s.Require().Equal(txReceipt.Status, types.ReceiptStatusSuccessful)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
|
func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
|
||||||
|
@ -199,16 +228,13 @@ func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
|
||||||
rlnInstance, err := rln.NewRLN()
|
rlnInstance, err := rln.NewRLN()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
keyPair1, err := rlnInstance.MembershipKeyGen()
|
credentials1 := s.generateCredentials(rlnInstance)
|
||||||
|
credentials2 := s.generateCredentials(rlnInstance)
|
||||||
|
|
||||||
|
err = rlnInstance.InsertMember(credentials1.IDCommitment)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
keyPair2, err := rlnInstance.MembershipKeyGen()
|
err = rlnInstance.InsertMember(credentials2.IDCommitment)
|
||||||
s.Require().NoError(err)
|
|
||||||
|
|
||||||
err = rlnInstance.InsertMember(keyPair1.IDCommitment)
|
|
||||||
s.Require().NoError(err)
|
|
||||||
|
|
||||||
err = rlnInstance.InsertMember(keyPair2.IDCommitment)
|
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// get the Merkle root
|
// get the Merkle root
|
||||||
|
@ -216,8 +242,8 @@ func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// register the members to the contract
|
// register the members to the contract
|
||||||
s.register(s.u1PrivKey, rln.Bytes32ToBigInt(keyPair1.IDCommitment), nil)
|
_, membershipGroupIndex := s.register(credentials1, s.u1PrivKey, "./test_onchain.json")
|
||||||
s.register(s.u1PrivKey, rln.Bytes32ToBigInt(keyPair2.IDCommitment), nil)
|
_, membershipGroupIndex = s.register(credentials2, s.u1PrivKey, "./test_onchain.json")
|
||||||
|
|
||||||
// Creating relay
|
// Creating relay
|
||||||
port, err := tests.FindFreePort(s.T(), "", 5)
|
port, err := tests.FindFreePort(s.T(), "", 5)
|
||||||
|
@ -239,16 +265,15 @@ func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
|
||||||
defer sub.Unsubscribe()
|
defer sub.Unsubscribe()
|
||||||
|
|
||||||
// mount the rln relay protocol in the on-chain/dynamic mode
|
// mount the rln relay protocol in the on-chain/dynamic mode
|
||||||
gm, err := dynamic.NewDynamicGroupManager(s.clientAddr, s.u1PrivKey, s.rlnAddr, 0, "./test_onchain.json", "", 0, false, nil, utils.Logger())
|
// TODO: This assumes the keystoreIndex is 0, but there are two possible credentials in this keystore due to using the same contract address
|
||||||
|
// when credentials1 and credentials2 were registered. We should remove this hardcoded value and obtain the correct value when the credentials are persisted
|
||||||
|
keystoreIndex := uint(0)
|
||||||
|
gm, err := dynamic.NewDynamicGroupManager(s.clientAddr, s.rlnAddr, membershipGroupIndex, "./test_onchain.json", keystorePassword, keystoreIndex, false, utils.Logger())
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
rlnRelay, err := New(relay, gm, "test-merkle-tree.db", RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
|
rlnRelay, err := New(relay, gm, "test-merkle-tree.db", RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// PreRegistering the keypair
|
|
||||||
membershipIndex := rln.MembershipIndex(0)
|
|
||||||
gm.SetCredentials(keyPair1, &membershipIndex)
|
|
||||||
|
|
||||||
err = rlnRelay.Start(context.TODO())
|
err = rlnRelay.Start(context.TODO())
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
@ -264,6 +289,9 @@ func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WakuRLNRelayDynamicSuite) TestCorrectRegistrationOfPeers() {
|
func (s *WakuRLNRelayDynamicSuite) TestCorrectRegistrationOfPeers() {
|
||||||
|
// Creating an RLN instance (just for generating membership keys)
|
||||||
|
rlnInstance, err := rln.NewRLN()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
// Node 1 ============================================================
|
// Node 1 ============================================================
|
||||||
port1, err := tests.FindFreePort(s.T(), "", 5)
|
port1, err := tests.FindFreePort(s.T(), "", 5)
|
||||||
|
@ -282,8 +310,14 @@ func (s *WakuRLNRelayDynamicSuite) TestCorrectRegistrationOfPeers() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
defer sub1.Unsubscribe()
|
defer sub1.Unsubscribe()
|
||||||
|
|
||||||
|
// Register credentials1 in contract and keystore1
|
||||||
|
credentials1 := s.generateCredentials(rlnInstance)
|
||||||
|
keystorePath1 := "./test_onchain.json"
|
||||||
|
_, membershipGroupIndex := s.register(credentials1, s.u1PrivKey, keystorePath1)
|
||||||
|
defer s.removeCredentials(keystorePath1)
|
||||||
|
|
||||||
// mount the rln relay protocol in the on-chain/dynamic mode
|
// mount the rln relay protocol in the on-chain/dynamic mode
|
||||||
gm1, err := dynamic.NewDynamicGroupManager(s.clientAddr, s.u1PrivKey, s.rlnAddr, 0, "./test_onchain.json", "", 0, false, nil, utils.Logger())
|
gm1, err := dynamic.NewDynamicGroupManager(s.clientAddr, s.rlnAddr, membershipGroupIndex, keystorePath1, keystorePassword, 0, false, utils.Logger())
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
rlnRelay1, err := New(relay1, gm1, "test-correct-registration-1.db", RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
|
rlnRelay1, err := New(relay1, gm1, "test-correct-registration-1.db", RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
|
||||||
|
@ -308,8 +342,14 @@ func (s *WakuRLNRelayDynamicSuite) TestCorrectRegistrationOfPeers() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
defer sub2.Unsubscribe()
|
defer sub2.Unsubscribe()
|
||||||
|
|
||||||
|
// Register credentials2 in contract and keystore2
|
||||||
|
credentials2 := s.generateCredentials(rlnInstance)
|
||||||
|
keystorePath2 := "./test_onchain2.json"
|
||||||
|
_, membershipGroupIndex = s.register(credentials2, s.u2PrivKey, keystorePath2)
|
||||||
|
defer s.removeCredentials(keystorePath2)
|
||||||
|
|
||||||
// mount the rln relay protocol in the on-chain/dynamic mode
|
// mount the rln relay protocol in the on-chain/dynamic mode
|
||||||
gm2, err := dynamic.NewDynamicGroupManager(s.clientAddr, s.u2PrivKey, s.rlnAddr, 0, "./test_onchain.json", "", 0, false, nil, utils.Logger())
|
gm2, err := dynamic.NewDynamicGroupManager(s.clientAddr, s.rlnAddr, membershipGroupIndex, keystorePath2, keystorePassword, 0, false, utils.Logger())
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
rlnRelay2, err := New(relay2, gm2, "test-correct-registration-2.db", RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
|
rlnRelay2, err := New(relay2, gm2, "test-correct-registration-2.db", RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
|
||||||
|
|
Loading…
Reference in New Issue