1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
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), ErrExpiredSolution)
}
}
|