waku-org/go-waku

View on GitHub
waku/v2/protocol/rln/group_manager/dynamic/handler_test.go

Summary

Maintainability
A
1 hr
Test Coverage
package dynamic

import (
    "context"
    "math/big"
    "testing"

    "github.com/ethereum/go-ethereum/core/types"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/stretchr/testify/require"
    "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/web3"
    "github.com/waku-org/go-waku/waku/v2/utils"
    "github.com/waku-org/go-zerokit-rln/rln"
)

func eventBuilder(blockNumber uint64, removed bool, idCommitment int64, index int64) *contracts.RLNMemberRegistered {
    return &contracts.RLNMemberRegistered{
        Raw: types.Log{
            BlockNumber: blockNumber,
            Removed:     removed,
        },
        Index:        big.NewInt(index),
        IdCommitment: big.NewInt(idCommitment),
    }
}

func TestHandler(t *testing.T) {
    // Create a RLN instance
    rlnInstance, err := rln.NewRLN()
    require.NoError(t, err)

    rootTracker := group_manager.NewMerkleRootTracker(5, rlnInstance)

    _, cancel := context.WithCancel(context.TODO())
    defer cancel()

    gm := &DynamicGroupManager{
        MembershipFetcher: NewMembershipFetcher(
            &web3.Config{
                ChainID: big.NewInt(1),
            },
            rlnInstance,
            rootTracker,
            utils.Logger(),
        ),
        cancel: cancel,

        metrics: newMetrics(prometheus.DefaultRegisterer),
    }

    root0 := [32]byte{62, 31, 25, 34, 223, 182, 113, 211, 249, 18, 247, 234, 70, 30, 10, 136, 238, 132, 143, 221, 225, 43, 108, 24, 171, 26, 210, 197, 106, 231, 52, 33}
    roots := gm.rootTracker.Roots()
    require.Len(t, roots, 1)
    require.Equal(t, roots[0], root0)

    events := []*contracts.RLNMemberRegistered{eventBuilder(1, false, 0xaaaa, 1)}

    err = gm.handler(events, 1)
    require.NoError(t, err)

    roots = gm.rootTracker.Roots()

    require.Len(t, roots, 2)
    require.Equal(t, root0, roots[0])
    require.Equal(t, [32]byte{0x1c, 0xe4, 0x6b, 0x9a, 0xb2, 0x54, 0xa1, 0xb0, 0x2, 0x77, 0xbf, 0xc0, 0xf6, 0x27, 0x38, 0x38, 0x8f, 0xc8, 0x6a, 0x3d, 0x18, 0xe3, 0x1a, 0xd, 0xdd, 0xb8, 0xe5, 0x38, 0xf5, 0x9e, 0xc3, 0x16}, roots[1])

    events = []*contracts.RLNMemberRegistered{
        eventBuilder(1, false, 0xbbbb, 2),
        eventBuilder(2, false, 0xcccc, 3),
        eventBuilder(3, false, 0xdddd, 4),
        eventBuilder(4, false, 0xeeee, 5),
    }

    err = gm.handler(events, 4)
    require.NoError(t, err)

    // Root[1] should become [0]
    roots = gm.rootTracker.Roots()
    require.Len(t, roots, 5)
    require.Equal(t, [32]byte{0x1c, 0xe4, 0x6b, 0x9a, 0xb2, 0x54, 0xa1, 0xb0, 0x2, 0x77, 0xbf, 0xc0, 0xf6, 0x27, 0x38, 0x38, 0x8f, 0xc8, 0x6a, 0x3d, 0x18, 0xe3, 0x1a, 0xd, 0xdd, 0xb8, 0xe5, 0x38, 0xf5, 0x9e, 0xc3, 0x16}, roots[0])
    require.Len(t, rootTracker.Buffer(), 1)
    require.Equal(t, root0, rootTracker.Buffer()[0])

    // We detect a fork
    //
    // [0] -> [1] -> [2] -> [3] -> [4]   Our chain
    //                \
    //                 \-->              Real chain
    // We should restore the valid roots from the buffer at the state the moment the chain forked
    // In this case, just adding the original merkle root from empty tree
    validRootsBeforeFork := roots[0:3]
    events = []*contracts.RLNMemberRegistered{
        eventBuilder(3, true, 0xdddd, 4),
        eventBuilder(3, false, 0xdddd, 4),
        eventBuilder(3, false, 0xeeee, 5),
    }

    err = gm.handler(events, 3)
    require.NoError(t, err)

    roots = gm.rootTracker.Roots()
    require.Len(t, roots, 5)
    require.Equal(t, roots[0], root0)
    require.Equal(t, roots[1], validRootsBeforeFork[0])
    require.Equal(t, roots[2], validRootsBeforeFork[1])
    require.Equal(t, roots[3], validRootsBeforeFork[2])
    require.Len(t, rootTracker.Buffer(), 0)

    // Adding multiple events for same block
    events = []*contracts.RLNMemberRegistered{}

    err = gm.handler(events, 0)
    require.NoError(t, err)

    roots = gm.rootTracker.Roots()
    require.Len(t, roots, 5)

}