mirror of https://github.com/status-im/go-waku.git
test: rln onchain
This commit is contained in:
parent
4f71ee6f30
commit
c2ce8326ff
16
Makefile
16
Makefile
|
@ -57,7 +57,7 @@ lint:
|
|||
@golangci-lint --exclude=SA1019 run ./... --deadline=5m
|
||||
|
||||
test:
|
||||
${GOBIN} test ./waku/... -coverprofile=${GO_TEST_OUTFILE}.tmp
|
||||
${GOBIN} test -timeout 300s ./waku/... -coverprofile=${GO_TEST_OUTFILE}.tmp
|
||||
cat ${GO_TEST_OUTFILE}.tmp | grep -v ".pb.go" > ${GO_TEST_OUTFILE}
|
||||
${GOBIN} tool cover -html=${GO_TEST_OUTFILE} -o ${GO_HTML_COV}
|
||||
|
||||
|
@ -77,7 +77,7 @@ generate:
|
|||
|
||||
|
||||
coverage:
|
||||
${GOBIN} test -count 1 -coverprofile=coverage.out ./...
|
||||
${GOBIN} test -timeout 300s -count 1 -coverprofile=coverage.out ./...
|
||||
${GOBIN} tool cover -html=coverage.out -o=coverage.html
|
||||
|
||||
# build a docker image for the fleet
|
||||
|
@ -149,3 +149,15 @@ install-gomobile: install-xtools
|
|||
build-linux-pkg:
|
||||
./scripts/linux/docker-run.sh
|
||||
ls -la ./build/*.rpm ./build/*.deb
|
||||
|
||||
TEST_MNEMONIC="swim relax risk shy chimney please usual search industry board music segment"
|
||||
|
||||
start-ganache:
|
||||
docker run -p 8545:8545 --name ganache-cli --rm -d trufflesuite/ganache-cli:latest -m ${TEST_MNEMONIC}
|
||||
|
||||
stop-ganache:
|
||||
docker stop ganache-cli
|
||||
|
||||
test-rln:
|
||||
go test -timeout 30s -v -count 1 github.com/status-im/go-waku/waku/v2/protocol/rln
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
package rln
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"math/big"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
r "github.com/status-im/go-rln/rln"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/status-im/go-waku/tests"
|
||||
"github.com/status-im/go-waku/waku/v2/protocol/relay"
|
||||
"github.com/status-im/go-waku/waku/v2/protocol/rln/contracts"
|
||||
"github.com/status-im/go-waku/waku/v2/utils"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
const ETH_CLIENT_ADDRESS = "ws://localhost:8545"
|
||||
|
||||
func TestWakuRLNRelayDynamicSuite(t *testing.T) {
|
||||
suite.Run(t, new(WakuRLNRelayDynamicSuite))
|
||||
}
|
||||
|
||||
type WakuRLNRelayDynamicSuite struct {
|
||||
suite.Suite
|
||||
|
||||
backend *ethclient.Client
|
||||
chainID *big.Int
|
||||
rlnAddr common.Address
|
||||
rlnContract *contracts.RLN
|
||||
|
||||
u1PrivKey *ecdsa.PrivateKey
|
||||
u2PrivKey *ecdsa.PrivateKey
|
||||
u3PrivKey *ecdsa.PrivateKey
|
||||
u4PrivKey *ecdsa.PrivateKey
|
||||
u5PrivKey *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
func (s *WakuRLNRelayDynamicSuite) SetupTest() {
|
||||
backend, err := ethclient.Dial(ETH_CLIENT_ADDRESS)
|
||||
s.Require().NoError(err)
|
||||
|
||||
chainID, err := backend.ChainID(context.TODO())
|
||||
s.Require().NoError(err)
|
||||
|
||||
// TODO: obtain account list from ganache mnemonic or from eth_accounts
|
||||
|
||||
s.u1PrivKey, err = crypto.ToECDSA(common.FromHex("0x156ec84a451d8a2d0062993242b6c4e863647f5544ff8030f23578d4142f43f8"))
|
||||
s.Require().NoError(err)
|
||||
s.u2PrivKey, err = crypto.ToECDSA(common.FromHex("0xa00da43843ad6b5161ddbace48f293ac3f82f8a8257af34de4c32900bb6e9a97"))
|
||||
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.chainID = chainID
|
||||
|
||||
// Deploying contracts
|
||||
auth, err := bind.NewKeyedTransactorWithChainID(s.u1PrivKey, chainID)
|
||||
s.Require().NoError(err)
|
||||
|
||||
poseidonHasherAddr, _, _, err := contracts.DeployPoseidonHasher(auth, backend)
|
||||
s.Require().NoError(err)
|
||||
|
||||
rlnAddr, _, rlnContract, err := contracts.DeployRLN(auth, backend, MEMBERSHIP_FEE, big.NewInt(20), poseidonHasherAddr)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.rlnAddr = rlnAddr
|
||||
s.rlnContract = rlnContract
|
||||
}
|
||||
|
||||
func (s *WakuRLNRelayDynamicSuite) register(privKey *ecdsa.PrivateKey, commitment *big.Int) {
|
||||
auth, err := bind.NewKeyedTransactorWithChainID(privKey, s.chainID)
|
||||
s.Require().NoError(err)
|
||||
|
||||
auth.Value = MEMBERSHIP_FEE
|
||||
auth.Context = context.TODO()
|
||||
|
||||
tx, err := s.rlnContract.Register(auth, commitment)
|
||||
s.Require().NoError(err)
|
||||
_, err = bind.WaitMined(context.TODO(), s.backend, tx)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *WakuRLNRelayDynamicSuite) TestDynamicGroupManagement() {
|
||||
params, err := parametersKeyBytes()
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Create a RLN instance
|
||||
rlnInstance, err := r.NewRLN(params)
|
||||
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,
|
||||
}
|
||||
|
||||
// generate another membership key pair
|
||||
keyPair2, err := rlnInstance.MembershipKeyGen()
|
||||
s.Require().NoError(err)
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
handler := func(pubkey r.IDCommitment, index r.MembershipIndex) error {
|
||||
if pubkey == keyPair.IDCommitment || pubkey == keyPair2.IDCommitment {
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
if !rlnInstance.InsertMember(pubkey) {
|
||||
return errors.New("couldn't insert member")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// mount the handler for listening to the contract events
|
||||
go rlnPeer.HandleGroupUpdates(handler)
|
||||
|
||||
// Register first member
|
||||
s.register(s.u1PrivKey, toBigInt(keyPair.IDCommitment[:]))
|
||||
|
||||
// Register second member
|
||||
s.register(s.u2PrivKey, toBigInt(keyPair2.IDCommitment[:]))
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (s *WakuRLNRelayDynamicSuite) TestInsertKeyMembershipContract() {
|
||||
|
||||
s.register(s.u1PrivKey, big.NewInt(20))
|
||||
|
||||
// Batch Register
|
||||
auth, err := bind.NewKeyedTransactorWithChainID(s.u2PrivKey, s.chainID)
|
||||
s.Require().NoError(err)
|
||||
|
||||
auth.Value = MEMBERSHIP_FEE.Mul(big.NewInt(2), MEMBERSHIP_FEE)
|
||||
auth.Context = context.TODO()
|
||||
|
||||
tx, err := s.rlnContract.RegisterBatch(auth, []*big.Int{big.NewInt(20), big.NewInt(21)})
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = bind.WaitMined(context.TODO(), s.backend, tx)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *WakuRLNRelayDynamicSuite) TestRegistrationProcedure() {
|
||||
params, err := parametersKeyBytes()
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Create a RLN instance
|
||||
rlnInstance, err := r.NewRLN(params)
|
||||
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() {
|
||||
params, err := parametersKeyBytes()
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Create a RLN instance
|
||||
rlnInstance, err := r.NewRLN(params)
|
||||
s.Require().NoError(err)
|
||||
|
||||
keyPair1, err := rlnInstance.MembershipKeyGen()
|
||||
s.Require().NoError(err)
|
||||
|
||||
keyPair2, err := rlnInstance.MembershipKeyGen()
|
||||
s.Require().NoError(err)
|
||||
|
||||
r1 := rlnInstance.InsertMember(keyPair1.IDCommitment)
|
||||
r2 := rlnInstance.InsertMember(keyPair2.IDCommitment)
|
||||
s.Require().True(r1)
|
||||
s.Require().True(r2)
|
||||
|
||||
// get the Merkle root
|
||||
expectedRoot, err := rlnInstance.GetMerkleRoot()
|
||||
s.Require().NoError(err)
|
||||
|
||||
// register the members to the contract
|
||||
s.register(s.u1PrivKey, toBigInt(keyPair1.IDCommitment[:]))
|
||||
s.register(s.u1PrivKey, toBigInt(keyPair2.IDCommitment[:]))
|
||||
|
||||
port, err := tests.FindFreePort(s.T(), "", 5)
|
||||
s.Require().NoError(err)
|
||||
|
||||
host, err := tests.MakeHost(context.TODO(), port, rand.Reader)
|
||||
s.Require().NoError(err)
|
||||
|
||||
relay, err := relay.NewWakuRelay(context.TODO(), host, nil, 0, utils.Logger())
|
||||
defer relay.Stop()
|
||||
s.Require().NoError(err)
|
||||
|
||||
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, utils.Logger())
|
||||
s.Require().NoError(err)
|
||||
|
||||
// wait for the event to reach the group handler
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// rln pks are inserted into the rln peer's Merkle tree and the resulting root
|
||||
// is expected to be the same as the calculatedRoot i.e., the one calculated outside of the mountRlnRelayDynamic proc
|
||||
calculatedRoot, err := rlnRelay.RLN.GetMerkleRoot()
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Equal(expectedRoot, calculatedRoot)
|
||||
}
|
||||
|
||||
func (s *WakuRLNRelayDynamicSuite) TestCorrectRegistrationOfPeers() {
|
||||
|
||||
// Node 1 ============================================================
|
||||
port1, err := tests.FindFreePort(s.T(), "", 5)
|
||||
s.Require().NoError(err)
|
||||
|
||||
host1, err := tests.MakeHost(context.TODO(), port1, rand.Reader)
|
||||
s.Require().NoError(err)
|
||||
|
||||
relay1, err := relay.NewWakuRelay(context.TODO(), host1, nil, 0, utils.Logger())
|
||||
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, utils.Logger())
|
||||
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)
|
||||
s.Require().NoError(err)
|
||||
|
||||
relay2, err := relay.NewWakuRelay(context.TODO(), host2, nil, 0, utils.Logger())
|
||||
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, utils.Logger())
|
||||
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)
|
||||
}
|
|
@ -27,20 +27,20 @@ type WakuRLNRelaySuite struct {
|
|||
|
||||
func (s *WakuRLNRelaySuite) TestOffchainMode() {
|
||||
port, err := tests.FindFreePort(s.T(), "", 5)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
host, err := tests.MakeHost(context.Background(), port, rand.Reader)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
relay, err := relay.NewWakuRelay(context.Background(), host, nil, 0, utils.Logger())
|
||||
defer relay.Stop()
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
params, err := parametersKeyBytes()
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
groupKeyPairs, root, err := r.CreateMembershipList(100, params)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
var groupIDCommitments []r.IDCommitment
|
||||
for _, c := range groupKeyPairs {
|
||||
|
@ -53,16 +53,16 @@ func (s *WakuRLNRelaySuite) TestOffchainMode() {
|
|||
index := r.MembershipIndex(5)
|
||||
|
||||
wakuRLNRelay, err := RlnRelayStatic(context.TODO(), relay, groupIDCommitments, groupKeyPairs[index], index, RLNRELAY_PUBSUB_TOPIC, RLNRELAY_CONTENT_TOPIC, nil, utils.Logger())
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// get the root of Merkle tree which is constructed inside the mountRlnRelay proc
|
||||
calculatedRoot, err := wakuRLNRelay.RLN.GetMerkleRoot()
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Checks whether the Merkle tree is constructed correctly inside the mountRlnRelay func
|
||||
// this check is done by comparing the tree root resulted from mountRlnRelay i.e., calculatedRoot
|
||||
// against the root which is the expected root
|
||||
s.Equal(root[:], calculatedRoot[:])
|
||||
s.Require().Equal(root[:], calculatedRoot[:])
|
||||
}
|
||||
|
||||
func (s *WakuRLNRelaySuite) TestUpdateLogAndHasDuplicate() {
|
||||
|
@ -96,37 +96,37 @@ func (s *WakuRLNRelaySuite) TestUpdateLogAndHasDuplicate() {
|
|||
// check whether hasDuplicate correctly finds records with the same nullifiers but different secret shares
|
||||
// no duplicate for wm1 should be found, since the log is empty
|
||||
result1, err := rlnRelay.HasDuplicate(wm1)
|
||||
s.NoError(err)
|
||||
s.False(result1) // No duplicate is found
|
||||
s.Require().NoError(err)
|
||||
s.Require().False(result1) // No duplicate is found
|
||||
|
||||
// Add it to the log
|
||||
added, err := rlnRelay.UpdateLog(wm1)
|
||||
s.NoError(err)
|
||||
s.True(added)
|
||||
s.Require().NoError(err)
|
||||
s.Require().True(added)
|
||||
|
||||
// no duplicate for wm2 should be found, its nullifier differs from wm1
|
||||
result2, err := rlnRelay.HasDuplicate(wm2)
|
||||
s.NoError(err)
|
||||
s.False(result2) // No duplicate is found
|
||||
s.Require().NoError(err)
|
||||
s.Require().False(result2) // No duplicate is found
|
||||
|
||||
// Add it to the log
|
||||
added, err = rlnRelay.UpdateLog(wm2)
|
||||
s.NoError(err)
|
||||
s.True(added)
|
||||
s.Require().NoError(err)
|
||||
s.Require().True(added)
|
||||
|
||||
// wm3 has the same nullifier as wm1 but different secret shares, it should be detected as duplicate
|
||||
result3, err := rlnRelay.HasDuplicate(wm3)
|
||||
s.NoError(err)
|
||||
s.True(result3) // It's a duplicate
|
||||
s.Require().NoError(err)
|
||||
s.Require().True(result3) // It's a duplicate
|
||||
|
||||
}
|
||||
|
||||
func (s *WakuRLNRelaySuite) TestValidateMessage() {
|
||||
params, err := parametersKeyBytes()
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
groupKeyPairs, _, err := r.CreateMembershipList(100, params)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
var groupIDCommitments []r.IDCommitment
|
||||
for _, c := range groupKeyPairs {
|
||||
|
@ -140,10 +140,10 @@ func (s *WakuRLNRelaySuite) TestValidateMessage() {
|
|||
|
||||
// Create a RLN instance
|
||||
rlnInstance, err := r.NewRLN(params)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
added := rlnInstance.AddAll(groupIDCommitments)
|
||||
s.True(added)
|
||||
s.Require().True(added)
|
||||
|
||||
rlnRelay := &WakuRLNRelay{
|
||||
membershipIndex: index,
|
||||
|
@ -160,38 +160,38 @@ func (s *WakuRLNRelaySuite) TestValidateMessage() {
|
|||
|
||||
wm1 := &pb.WakuMessage{Payload: []byte("Valid message")}
|
||||
err = rlnRelay.AppendRLNProof(wm1, now)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// another message in the same epoch as wm1, it will break the messaging rate limit
|
||||
wm2 := &pb.WakuMessage{Payload: []byte("Spam")}
|
||||
err = rlnRelay.AppendRLNProof(wm2, now)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// wm3 points to the next epoch
|
||||
wm3 := &pb.WakuMessage{Payload: []byte("Valid message")}
|
||||
err = rlnRelay.AppendRLNProof(wm3, now.Add(time.Second*time.Duration(r.EPOCH_UNIT_SECONDS)))
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
wm4 := &pb.WakuMessage{Payload: []byte("Invalid message")}
|
||||
|
||||
// valid message
|
||||
msgValidate1, err := rlnRelay.ValidateMessage(wm1, &now)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// wm2 is published within the same Epoch as wm1 and should be found as spam
|
||||
msgValidate2, err := rlnRelay.ValidateMessage(wm2, &now)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// a valid message should be validated successfully
|
||||
msgValidate3, err := rlnRelay.ValidateMessage(wm3, &now)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// wm4 has no rln proof and should not be validated
|
||||
msgValidate4, err := rlnRelay.ValidateMessage(wm4, &now)
|
||||
s.NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Equal(MessageValidationResult_Valid, msgValidate1)
|
||||
s.Equal(MessageValidationResult_Spam, msgValidate2)
|
||||
s.Equal(MessageValidationResult_Valid, msgValidate3)
|
||||
s.Equal(MessageValidationResult_Invalid, msgValidate4)
|
||||
s.Require().Equal(MessageValidationResult_Valid, msgValidate1)
|
||||
s.Require().Equal(MessageValidationResult_Spam, msgValidate2)
|
||||
s.Require().Equal(MessageValidationResult_Valid, msgValidate3)
|
||||
s.Require().Equal(MessageValidationResult_Invalid, msgValidate4)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue