Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

rendezvous_test.gno

3.41 Kb · 103 lines
  1package wesh
  2
  3import (
  4	"encoding/hex"
  5	"testing"
  6
  7	"gno.land/p/nt/uassert/v0"
  8)
  9
 10// Reference vectors produced by running weshnet's own algorithm
 11// (rendezvous.GenerateRendezvousPointForPeriod) against these inputs:
 12// topic = accountPK, seed = seed, interval = 24h.
 13const (
 14	testAccountPKHex = "2152f8d19b791d24453242e15f2eab6cb7cffa7b6a5ed30097960e069881db12"
 15	testSeedHex      = "abababababababababababababababababababababababababababababababab"
 16)
 17
 18func TestRoundPeriod(t *testing.T) {
 19	cases := []struct {
 20		name     string
 21		unixSec  int64
 22		interval int64
 23		want     int64
 24	}{
 25		{"epoch", 0, DefaultRotationInterval, 0},
 26		{"exactly on a boundary", 1789171200, DefaultRotationInterval, 1789171200},
 27		{"one second before the next", 1789257599, DefaultRotationInterval, 1789171200},
 28		{"one second after a boundary", 1789171201, DefaultRotationInterval, 1789171200},
 29		{"a negative interval is taken as positive", 1789257599, -DefaultRotationInterval, 1789171200},
 30		{"an hourly interval", 1789174800 + 59, 3600, 1789174800},
 31	}
 32	for _, tc := range cases {
 33		uassert.Equal(t, tc.want, RoundPeriod(tc.unixSec, tc.interval), tc.name)
 34	}
 35}
 36
 37func TestNextPeriod(t *testing.T) {
 38	uassert.Equal(t, int64(1789257600), NextPeriod(1789171200, DefaultRotationInterval))
 39	uassert.Equal(t, int64(1789257600), NextPeriod(1789257599, DefaultRotationInterval))
 40}
 41
 42// TestRendezvousPointMatchesWeshnet pins the derivation against vectors
 43// computed with weshnet's implementation. A divergence here means a gno-derived
 44// rendezvous point would not match the one the account actually announces on,
 45// which makes a published identity unverifiable.
 46func TestRendezvousPointMatchesWeshnet(t *testing.T) {
 47	pk := mustHex(t, testAccountPKHex)
 48	seed := mustHex(t, testSeedHex)
 49
 50	cases := []struct {
 51		name        string
 52		periodStart int64
 53		want        string
 54	}{
 55		{
 56			"period 0",
 57			0,
 58			"04500fdede2a684f4e61cd67968b46ecdbf10d45604041bb7e0350572b8cc9cc",
 59		},
 60		{
 61			"period starting 1789171200",
 62			1789171200,
 63			"aad2926c39dacabaabbbde48522d043557c8945b6a2dc7b08499c112c72587da",
 64		},
 65	}
 66	for _, tc := range cases {
 67		got := hex.EncodeToString(RendezvousPoint(pk, seed, tc.periodStart))
 68		uassert.Equal(t, tc.want, got, tc.name)
 69	}
 70}
 71
 72// TestRendezvousPointAtIsStableWithinAPeriod is the property that makes
 73// rotation useful: every instant inside one interval maps to the same point,
 74// and the next interval maps somewhere unrelated.
 75func TestRendezvousPointAtIsStableWithinAPeriod(t *testing.T) {
 76	c := Contact{AccountPK: mustHex(t, testAccountPKHex), Seed: mustHex(t, testSeedHex)}
 77
 78	start, err := c.RendezvousPointAt(1789171200, DefaultRotationInterval)
 79	uassert.NoError(t, err)
 80	end, err := c.RendezvousPointAt(1789257599, DefaultRotationInterval)
 81	uassert.NoError(t, err)
 82	next, err := c.RendezvousPointAt(1789257600, DefaultRotationInterval)
 83	uassert.NoError(t, err)
 84
 85	uassert.Equal(t, hex.EncodeToString(start), hex.EncodeToString(end),
 86		"the point is stable for the whole period")
 87	uassert.False(t, hex.EncodeToString(start) == hex.EncodeToString(next),
 88		"the point rotates at the period boundary")
 89}
 90
 91func TestRendezvousPointAtRejectsAnInvalidContact(t *testing.T) {
 92	_, err := Contact{AccountPK: repeat(1, 32), Seed: repeat(2, 31)}.RendezvousPointAt(0, DefaultRotationInterval)
 93	uassert.ErrorIs(t, err, ErrBadSeedLen)
 94}
 95
 96func mustHex(t *testing.T, s string) []byte {
 97	t.Helper()
 98	b, err := hex.DecodeString(s)
 99	if err != nil {
100		t.Fatalf("bad hex fixture: %v", err)
101	}
102	return b
103}