diff --git a/waku/v2/protocol/rln/rln_relay_builder.go b/waku/v2/protocol/rln/rln_relay_builder.go index 0f255cfe..1635044d 100644 --- a/waku/v2/protocol/rln/rln_relay_builder.go +++ b/waku/v2/protocol/rln/rln_relay_builder.go @@ -36,13 +36,6 @@ func RlnRelayStatic( return nil, err } - // add members to the Merkle tree - for _, member := range group { - if err := rlnInstance.InsertMember(member); err != nil { - return nil, err - } - } - // create the WakuRLNRelay rlnPeer := &WakuRLNRelay{ ctx: ctx, @@ -55,6 +48,20 @@ func RlnRelayStatic( nullifierLog: make(map[r.Epoch][]r.ProofMetadata), } + root, err := rlnPeer.RLN.GetMerkleRoot() + if err != nil { + return nil, err + } + + rlnPeer.validMerkleRoots = append(rlnPeer.validMerkleRoots, root) + + // add members to the Merkle tree + for _, member := range group { + if err := rlnPeer.insertMember(member); err != nil { + return nil, err + } + } + // adds a topic validator for the supplied pubsub topic at the relay protocol // messages published on this pubsub topic will be relayed upon a successful validation, otherwise they will be dropped // the topic validator checks for the correct non-spamming proof of the message @@ -106,6 +113,13 @@ func RlnRelayDynamic( registrationHandler: registrationHandler, } + root, err := rlnPeer.RLN.GetMerkleRoot() + if err != nil { + return nil, err + } + + rlnPeer.validMerkleRoots = append(rlnPeer.validMerkleRoots, root) + // prepare rln membership key pair if memKeyPair == nil && ethAccountPrivateKey != nil { log.Debug("no rln-relay key is provided, generating one") @@ -130,9 +144,7 @@ func RlnRelayDynamic( } handler := func(pubkey r.IDCommitment, index r.MembershipIndex) error { - log.Debug("a new key is added", zap.Binary("pubkey", pubkey[:])) - // assuming all the members arrive in order - return rlnInstance.InsertMember(pubkey) + return rlnPeer.insertMember(pubkey) } errChan := make(chan error) diff --git a/waku/v2/protocol/rln/waku_rln_relay.go b/waku/v2/protocol/rln/waku_rln_relay.go index 6282905c..58fda8ab 100644 --- a/waku/v2/protocol/rln/waku_rln_relay.go +++ b/waku/v2/protocol/rln/waku_rln_relay.go @@ -30,6 +30,8 @@ const MAX_EPOCH_GAP = int64(MAX_CLOCK_GAP_SECONDS / r.EPOCH_UNIT_SECONDS) type RegistrationHandler = func(tx *types.Transaction) +const AcceptableRootWindowSize = 5 + type WakuRLNRelay struct { ctx context.Context @@ -52,6 +54,8 @@ type WakuRLNRelay struct { pubsubTopic string contentTopic string + validMerkleRoots []r.MerkleNode + // the log of nullifiers and Shamir shares of the past messages grouped per epoch nullifierLogLock sync.RWMutex nullifierLog map[r.Epoch][]r.ProofMetadata @@ -307,6 +311,25 @@ func (r *WakuRLNRelay) MembershipContractAddress() common.Address { return r.membershipContractAddress } +func (r *WakuRLNRelay) insertMember(pubkey [32]byte) error { + r.log.Debug("a new key is added", zap.Binary("pubkey", pubkey[:])) + // assuming all the members arrive in order + err := r.RLN.InsertMember(pubkey) + if err == nil { + newRoot, err := r.RLN.GetMerkleRoot() + if err != nil { + r.log.Error("inserting member into merkletree", zap.Error(err)) + return err + } + r.validMerkleRoots = append(r.validMerkleRoots, newRoot) + if len(r.validMerkleRoots) > AcceptableRootWindowSize { + r.validMerkleRoots = r.validMerkleRoots[1:] + } + } + + return err +} + type SpamHandler = func(message *pb.WakuMessage) error // this function sets a validator for the waku messages published on the supplied pubsubTopic and contentTopic