fix(rln): onchain tests

This commit is contained in:
Richard Ramos 2023-04-26 11:55:03 -04:00
parent c479daa926
commit 360a44830a
No known key found for this signature in database
GPG Key ID: 1CE87DB518195760
4 changed files with 119 additions and 96 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
nodekey
rlnCredentials.txt
rlnCredentials.json
test_onchain.json
*.bkp
*.log

View File

@ -45,6 +45,8 @@ type DynamicGroupManager struct {
// TODO may need to make ethAccountPrivateKey mandatory
ethAccountPrivateKey *ecdsa.PrivateKey
eventHandler RegistrationEventHandler
registrationHandler RegistrationHandler
chainId *big.Int
rlnContract *contracts.RLN
@ -124,6 +126,7 @@ func NewDynamicGroupManager(
ethClientAddress: ethClientAddr,
ethAccountPrivateKey: ethAccountPrivateKey,
registrationHandler: registrationHandler,
eventHandler: handler,
saveKeystore: saveKeystore,
keystorePath: path,
keystorePassword: password,
@ -176,7 +179,7 @@ func (gm *DynamicGroupManager) Start(ctx context.Context, rlnInstance *rln.RLN,
return err
}
if gm.keystorePassword != "" && gm.keystorePath != "" {
if gm.identityCredential == nil && gm.keystorePassword != "" && gm.keystorePath != "" {
credentials, err := keystore.GetMembershipCredentials(gm.log,
gm.keystorePath,
gm.keystorePassword,
@ -229,7 +232,7 @@ func (gm *DynamicGroupManager) Start(ctx context.Context, rlnInstance *rln.RLN,
return errors.New("no credentials available")
}
if err = gm.HandleGroupUpdates(ctx, handler); err != nil {
if err = gm.HandleGroupUpdates(ctx, gm.eventHandler); err != nil {
return err
}
@ -309,6 +312,11 @@ func (gm *DynamicGroupManager) IdentityCredentials() (rln.IdentityCredential, er
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) {
if gm.membershipIndex == nil {
return 0, errors.New("membership index has not been setup")

View File

@ -17,7 +17,7 @@ import (
"go.uber.org/zap"
)
func toBigInt(i []byte) *big.Int {
func ToBigInt(i []byte) *big.Int {
result := new(big.Int)
result.SetBytes(i[:])
return result
@ -34,7 +34,7 @@ func register(ctx context.Context, backend *ethclient.Client, membershipFee *big
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, toBigInt(idComm[:]))
tx, err := rlnContract.Register(auth, ToBigInt(idComm[:]))
if err != nil {
return nil, err
}
@ -190,7 +190,7 @@ func (gm *DynamicGroupManager) getEvents(ctx context.Context, from uint64, to *u
return nil, err
}
blockNumber := block.Number().Uint64() - 50 // Keep a buffer to retrieve latest block
blockNumber := block.Number().Uint64()
toBlock = &blockNumber
}
@ -221,6 +221,8 @@ func (gm *DynamicGroupManager) getEvents(ctx context.Context, from uint64, to *u
results = append(results, evts...)
currentBlockNum = end
if batchSize < maxBatchSize {
// update the batchSize with additive increase
batchSize = batchSize + additiveFactor
@ -230,15 +232,6 @@ func (gm *DynamicGroupManager) getEvents(ctx context.Context, from uint64, to *u
}
}
if to == nil {
evts, err := gm.fetchEvents(ctx, *toBlock, nil)
if err != nil {
return nil, err
}
results = append(results, evts...)
}
return results, nil
}

View File

@ -4,15 +4,18 @@
package rln
import (
"bytes"
"context"
"crypto/ecdsa"
"crypto/rand"
r "github.com/waku-org/go-zerokit-rln/rln"
"errors"
"math/big"
"sync"
"testing"
"time"
"github.com/waku-org/go-zerokit-rln/rln"
r "github.com/waku-org/go-zerokit-rln/rln"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
@ -21,12 +24,16 @@ import (
"github.com/waku-org/go-waku/tests"
"github.com/waku-org/go-waku/waku/v2/protocol/relay"
"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/dynamic"
"github.com/waku-org/go-waku/waku/v2/timesource"
"github.com/waku-org/go-waku/waku/v2/utils"
)
const ETH_CLIENT_ADDRESS = "ws://localhost:8545"
var MEMBERSHIP_FEE = big.NewInt(1000000000000000) // wei - 0.001 eth
func TestWakuRLNRelayDynamicSuite(t *testing.T) {
suite.Run(t, new(WakuRLNRelayDynamicSuite))
}
@ -83,7 +90,7 @@ func (s *WakuRLNRelayDynamicSuite) SetupTest() {
s.rlnContract = rlnContract
}
func (s *WakuRLNRelayDynamicSuite) register(privKey *ecdsa.PrivateKey, commitment *big.Int) {
func (s *WakuRLNRelayDynamicSuite) register(privKey *ecdsa.PrivateKey, commitment *big.Int, handler func(evt *contracts.RLNMemberRegistered) error) {
auth, err := bind.NewKeyedTransactorWithChainID(privKey, s.chainID)
s.Require().NoError(err)
@ -92,8 +99,16 @@ func (s *WakuRLNRelayDynamicSuite) register(privKey *ecdsa.PrivateKey, commitmen
tx, err := s.rlnContract.Register(auth, commitment)
s.Require().NoError(err)
_, err = bind.WaitMined(context.TODO(), s.backend, tx)
receipt, err := bind.WaitMined(context.TODO(), s.backend, tx)
s.Require().NoError(err)
evt, err := s.rlnContract.ParseMemberRegistered(*receipt.Logs[0])
s.Require().NoError(err)
if handler != nil {
err = handler(evt)
s.Require().NoError(err)
}
}
func (s *WakuRLNRelayDynamicSuite) TestDynamicGroupManagement() {
@ -101,62 +116,62 @@ func (s *WakuRLNRelayDynamicSuite) TestDynamicGroupManagement() {
rlnInstance, err := r.NewRLN()
s.Require().NoError(err)
keyPair, err := rlnInstance.MembershipKeyGen()
port, err := tests.FindFreePort(s.T(), "", 5)
s.Require().NoError(err)
host, err := tests.MakeHost(context.Background(), port, rand.Reader)
s.Require().NoError(err)
relay := relay.NewWakuRelay(nil, 0, timesource.NewDefaultClock(), utils.Logger())
relay.SetHost(host)
err = relay.Start(context.TODO())
defer relay.Stop()
s.Require().NoError(err)
rt, err := group_manager.NewMerkleRootTracker(5, rlnInstance)
s.Require().NoError(err)
gm, err := dynamic.NewDynamicGroupManager(ETH_CLIENT_ADDRESS, s.u1PrivKey, s.rlnAddr, "./test_onchain.json", "", false, nil, utils.Logger())
s.Require().NoError(err)
// initialize the WakuRLNRelay
rlnPeer := &WakuRLNRelay{
ctx: context.TODO(),
membershipIndex: r.MembershipIndex(0),
membershipContractAddress: s.rlnAddr,
ethClientAddress: ETH_CLIENT_ADDRESS,
ethAccountPrivateKey: s.u1PrivKey,
RLN: rlnInstance,
log: utils.Logger(),
nullifierLog: make(map[r.Epoch][]r.ProofMetadata),
membershipKeyPair: keyPair,
rlnRelay := &WakuRLNRelay{
rootTracker: rt,
groupManager: gm,
relay: relay,
RLN: rlnInstance,
log: utils.Logger(),
nullifierLog: make(map[r.MerkleNode][]r.ProofMetadata),
}
// generate another membership key pair
keyPair2, err := rlnInstance.MembershipKeyGen()
s.Require().NoError(err)
wg := &sync.WaitGroup{}
wg.Add(1)
err = rlnRelay.Start(context.Background())
s.Require().NoError(err)
handler := func(pubkey r.IDCommitment, index r.MembershipIndex) error {
if pubkey == keyPair.IDCommitment || pubkey == keyPair2.IDCommitment {
wg.Done()
// register user
gm.Register(context.TODO())
handler := func(evt *contracts.RLNMemberRegistered) error {
pubkey := rln.Bytes32(evt.Pubkey.Bytes())
if !bytes.Equal(pubkey[:], keyPair2.IDCommitment[:]) {
return errors.New("not found")
}
return rlnInstance.InsertMember(pubkey)
}
errChan := make(chan error, 1)
// register member with contract
s.register(s.u2PrivKey, dynamic.ToBigInt(keyPair2.IDCommitment[:]), handler)
// mount the handler for listening to the contract events
go rlnPeer.HandleGroupUpdates(handler, errChan)
// Register first member
s.register(s.u1PrivKey, toBigInt(keyPair.IDCommitment[:]))
// Register second member
s.register(s.u2PrivKey, toBigInt(keyPair2.IDCommitment[:]))
wg.Wait()
timer1 := time.NewTimer(2 * time.Second)
select {
case <-timer1.C:
return
case err = <-errChan:
s.Require().NoError(err)
}
time.Sleep(2 * time.Second)
}
func (s *WakuRLNRelayDynamicSuite) TestInsertKeyMembershipContract() {
s.register(s.u1PrivKey, big.NewInt(20))
s.register(s.u1PrivKey, big.NewInt(20), nil)
// Batch Register
auth, err := bind.NewKeyedTransactorWithChainID(s.u2PrivKey, s.chainID)
@ -172,31 +187,6 @@ func (s *WakuRLNRelayDynamicSuite) TestInsertKeyMembershipContract() {
s.Require().NoError(err)
}
func (s *WakuRLNRelayDynamicSuite) TestRegistrationProcedure() {
// Create a RLN instance
rlnInstance, err := r.NewRLN()
s.Require().NoError(err)
keyPair, err := rlnInstance.MembershipKeyGen()
s.Require().NoError(err)
// initialize the WakuRLNRelay
rlnPeer := &WakuRLNRelay{
ctx: context.TODO(),
membershipIndex: r.MembershipIndex(0),
membershipContractAddress: s.rlnAddr,
ethClientAddress: ETH_CLIENT_ADDRESS,
ethAccountPrivateKey: s.u1PrivKey,
RLN: rlnInstance,
log: utils.Logger(),
nullifierLog: make(map[r.Epoch][]r.ProofMetadata),
membershipKeyPair: keyPair,
}
_, err = rlnPeer.Register(context.TODO())
s.Require().NoError(err)
}
func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
// Create a RLN instance
rlnInstance, err := r.NewRLN()
@ -219,26 +209,40 @@ func (s *WakuRLNRelayDynamicSuite) TestMerkleTreeConstruction() {
s.Require().NoError(err)
// register the members to the contract
s.register(s.u1PrivKey, toBigInt(keyPair1.IDCommitment[:]))
s.register(s.u1PrivKey, toBigInt(keyPair2.IDCommitment[:]))
s.register(s.u1PrivKey, dynamic.ToBigInt(keyPair1.IDCommitment[:]), nil)
s.register(s.u1PrivKey, dynamic.ToBigInt(keyPair2.IDCommitment[:]), nil)
// Creating relay
port, err := tests.FindFreePort(s.T(), "", 5)
s.Require().NoError(err)
host, err := tests.MakeHost(context.TODO(), port, rand.Reader)
host, err := tests.MakeHost(context.Background(), port, rand.Reader)
s.Require().NoError(err)
relay := relay.NewWakuRelay(host, nil, 0, timesource.NewDefaultClock(), utils.Logger())
relay := relay.NewWakuRelay(nil, 0, timesource.NewDefaultClock(), utils.Logger())
relay.SetHost(host)
err = relay.Start(context.TODO())
s.Require().NoError(err)
defer relay.Stop()
s.Require().NoError(err)
// Subscribing to topic
sub, err := relay.SubscribeToTopic(context.TODO(), RLNRELAY_PUBSUB_TOPIC)
s.Require().NoError(err)
defer sub.Unsubscribe()
// mount the rln relay protocol in the on-chain/dynamic mode
rlnRelay, err := RlnRelayDynamic(context.TODO(), relay, ETH_CLIENT_ADDRESS, nil, s.rlnAddr, keyPair1, r.MembershipIndex(0), RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, nil, timesource.NewDefaultClock(), utils.Logger())
gm, err := dynamic.NewDynamicGroupManager(ETH_CLIENT_ADDRESS, s.u1PrivKey, s.rlnAddr, "./test_onchain.json", "", false, nil, utils.Logger())
s.Require().NoError(err)
rlnRelay, err := New(relay, gm, RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
s.Require().NoError(err)
// PreRegistering the keypair
membershipIndex := rln.MembershipIndex(0)
gm.SetCredentials(keyPair1, &membershipIndex)
err = rlnRelay.Start(context.TODO())
s.Require().NoError(err)
// wait for the event to reach the group handler
@ -258,46 +262,63 @@ func (s *WakuRLNRelayDynamicSuite) TestCorrectRegistrationOfPeers() {
port1, err := tests.FindFreePort(s.T(), "", 5)
s.Require().NoError(err)
host1, err := tests.MakeHost(context.TODO(), port1, rand.Reader)
host1, err := tests.MakeHost(context.Background(), port1, rand.Reader)
s.Require().NoError(err)
relay1 := relay.NewWakuRelay(host1, nil, 0, timesource.NewDefaultClock(), utils.Logger())
relay1.Start(context.TODO())
s.Require().NoError(err)
relay1 := relay.NewWakuRelay(nil, 0, timesource.NewDefaultClock(), utils.Logger())
relay1.SetHost(host1)
err = relay1.Start(context.TODO())
defer relay1.Stop()
s.Require().NoError(err)
sub1, err := relay1.SubscribeToTopic(context.TODO(), RLNRELAY_PUBSUB_TOPIC)
s.Require().NoError(err)
defer sub1.Unsubscribe()
// mount the rln relay protocol in the on-chain/dynamic mode
rlnRelay1, err := RlnRelayDynamic(context.TODO(), relay1, ETH_CLIENT_ADDRESS, s.u1PrivKey, s.rlnAddr, nil, r.MembershipIndex(0), RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, nil, timesource.NewDefaultClock(), utils.Logger())
gm1, err := dynamic.NewDynamicGroupManager(ETH_CLIENT_ADDRESS, s.u1PrivKey, s.rlnAddr, "./test_onchain.json", "", false, nil, utils.Logger())
s.Require().NoError(err)
rlnRelay1, err := New(relay1, gm1, RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
s.Require().NoError(err)
err = rlnRelay1.Start(context.TODO())
s.Require().NoError(err)
// Node 2 ============================================================
port2, err := tests.FindFreePort(s.T(), "", 5)
s.Require().NoError(err)
host2, err := tests.MakeHost(context.TODO(), port2, rand.Reader)
host2, err := tests.MakeHost(context.Background(), port2, rand.Reader)
s.Require().NoError(err)
relay2 := relay.NewWakuRelay(host2, nil, 0, timesource.NewDefaultClock(), utils.Logger())
relay2 := relay.NewWakuRelay(nil, 0, timesource.NewDefaultClock(), utils.Logger())
relay2.SetHost(host2)
err = relay2.Start(context.TODO())
s.Require().NoError(err)
defer relay2.Stop()
s.Require().NoError(err)
sub2, err := relay2.SubscribeToTopic(context.TODO(), RLNRELAY_PUBSUB_TOPIC)
s.Require().NoError(err)
defer sub2.Unsubscribe()
// mount the rln relay protocol in the on-chain/dynamic mode
rlnRelay2, err := RlnRelayDynamic(context.TODO(), relay2, ETH_CLIENT_ADDRESS, s.u2PrivKey, s.rlnAddr, nil, r.MembershipIndex(0), RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, nil, timesource.NewDefaultClock(), utils.Logger())
gm2, err := dynamic.NewDynamicGroupManager(ETH_CLIENT_ADDRESS, s.u2PrivKey, s.rlnAddr, "./test_onchain.json", "", false, nil, utils.Logger())
s.Require().NoError(err)
rlnRelay2, err := New(relay2, gm2, RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, timesource.NewDefaultClock(), utils.Logger())
s.Require().NoError(err)
err = rlnRelay2.Start(context.TODO())
s.Require().NoError(err)
// ==================================
// the two nodes should be registered into the contract
// since nodes are spun up sequentially
// the first node has index 0 whereas the second node gets index 1
s.Require().Equal(r.MembershipIndex(0), rlnRelay1.membershipIndex)
s.Require().Equal(r.MembershipIndex(1), rlnRelay2.membershipIndex)
idx1, err := rlnRelay1.groupManager.MembershipIndex()
s.Require().NoError(err)
idx2, err := rlnRelay2.groupManager.MembershipIndex()
s.Require().NoError(err)
s.Require().Equal(r.MembershipIndex(0), idx1)
s.Require().Equal(r.MembershipIndex(1), idx2)
}