package pow import ( "encoding/hex" "strconv" "testing" "time" "github.com/stretchr/testify/assert" "github.com/tilinna/clock" ) func TestChallengeParams(t *testing.T) { tests := []challengeParams{ {}, { Target: 1, ExpiresAt: 3, }, { Target: 2, ExpiresAt: -10, Random: []byte{0, 1, 2}, }, { Random: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, }, } t.Run("marshal_unmarshal", func(t *testing.T) { for i, test := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { b, err := test.MarshalBinary() assert.NoError(t, err) var c2 challengeParams assert.NoError(t, c2.UnmarshalBinary(b)) assert.Equal(t, test, c2) b2, err := c2.MarshalBinary() assert.NoError(t, err) assert.Equal(t, b, b2) }) } }) secret := []byte("shhh") t.Run("to_from_seed", func(t *testing.T) { for i, test := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { seed, err := newSeed(test, secret) assert.NoError(t, err) // generating seed should be deterministic seed2, err := newSeed(test, secret) assert.NoError(t, err) assert.Equal(t, seed, seed2) c, err := challengeParamsFromSeed(seed, secret) assert.NoError(t, err) assert.Equal(t, test, c) }) } }) t.Run("malformed_seed", func(t *testing.T) { tests := []string{ "", "01", "0000", "00374a1ad84d6b7a93e68042c1f850cbb100000000000000000000000000000102030405060708A0", // changed one byte from a good seed } for i, test := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { seed, err := hex.DecodeString(test) if err != nil { panic(err) } _, err = challengeParamsFromSeed(seed, secret) assert.ErrorIs(t, errMalformedSeed, err) }) } }) } func TestManager(t *testing.T) { clock := clock.NewMock(time.Now().Truncate(time.Hour)) store := NewMemoryStore(clock) defer store.Close() mgr := NewManager(ManagerParams{ Clock: clock, Store: store, Secret: []byte("shhhh"), Target: 0x00FFFFFF, ChallengeTimeout: 1 * time.Second, }) { c := mgr.NewChallenge() solution := Solve(c) assert.NoError(t, mgr.CheckSolution(c.Seed, solution)) // doing again should fail, the seed should already be marked as solved assert.ErrorIs(t, mgr.CheckSolution(c.Seed, solution), ErrSeedSolved) } { c := mgr.NewChallenge() solution := Solve(c) clock.Add(2 * time.Second) assert.ErrorIs(t, mgr.CheckSolution(c.Seed, solution), ErrExpiredSeed) } }