Skip to content

Commit 23329cc

Browse files
committed
Add tests
1 parent 36298b6 commit 23329cc

File tree

6 files changed

+200
-43
lines changed

6 files changed

+200
-43
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,7 @@ postcli: get-postrs-lib
8787
bench:
8888
@$(ULIMIT) CGO_LDFLAGS="$(CGO_TEST_LDFLAGS)" go test -benchmem -run='^$$' -bench 'BenchmarkVerifying|BenchmarkProving' github.com/spacemeshos/post/proving github.com/spacemeshos/post/verifying
8989
.PHONY: bench
90+
91+
fuzz:
92+
@$(ULIMIT) CGO_LDFLAGS="$(CGO_TEST_LDFLAGS)" ./scripts/fuzz.sh $(FUZZTIME)
93+
.PHONY: fuzz

initialization/initialization.go

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -227,39 +227,10 @@ func NewInitializer(opts ...OptionFunc) (*Initializer, error) {
227227
return nil, err
228228
}
229229
init.nonce.Store(m.Nonce)
230+
nonceValue := make([]byte, postrs.LabelLength)
231+
copy(nonceValue, m.NonceValue)
232+
init.nonceValue.Store(&nonceValue)
230233
init.lastPosition.Store(m.LastPosition)
231-
232-
switch {
233-
case m.NonceValue != nil:
234-
// there is already a nonce value in the metadata
235-
nonceValue := make([]byte, postrs.LabelLength)
236-
copy(nonceValue, m.NonceValue)
237-
init.nonceValue.Store(&nonceValue)
238-
case m.Nonce != nil:
239-
// there is a nonce in the metadata but no nonce value
240-
cpuProviderID := CPUProviderID()
241-
wo, err := oracle.New(
242-
oracle.WithProviderID(&cpuProviderID),
243-
oracle.WithCommitment(init.commitment),
244-
oracle.WithVRFDifficulty(make([]byte, 32)), // we are not looking for it, so set difficulty to 0
245-
oracle.WithScryptParams(init.opts.Scrypt),
246-
oracle.WithLogger(init.logger),
247-
)
248-
if err != nil {
249-
return nil, fmt.Errorf("failed to create work oracle: %w", err)
250-
}
251-
defer wo.Close()
252-
253-
result, err := wo.Position(*m.Nonce)
254-
if err != nil {
255-
return nil, fmt.Errorf("failed to compute nonce value: %w", err)
256-
}
257-
nonceValue := make([]byte, postrs.LabelLength)
258-
copy(nonceValue, result.Output)
259-
init.nonceValue.Store(&nonceValue)
260-
default:
261-
// no nonce in the metadata
262-
}
263234
}
264235

265236
if err := init.saveMetadata(); err != nil {

initialization/initialization_test.go

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package initialization
33
import (
44
"bytes"
55
"context"
6+
"encoding/json"
67
"fmt"
78
"io"
89
"math/big"
@@ -75,8 +76,9 @@ func TestInitialize(t *testing.T) {
7576
require.NoError(t, verifying.VerifyVRFNonce(init.Nonce(), m, verifying.WithLabelScryptParams(opts.Scrypt)))
7677
}
7778

78-
func TestInitialize_BeforeNonceValue(t *testing.T) {
79+
func TestInitialize_Migrate_Metadata(t *testing.T) {
7980
cfg, opts := getTestConfig(t)
81+
opts.Scrypt.N = 8192 // use default scrypt params
8082

8183
init, err := NewInitializer(
8284
WithNodeId(nodeId),
@@ -98,10 +100,27 @@ func TestInitialize_BeforeNonceValue(t *testing.T) {
98100
require.NotNil(t, meta.Nonce)
99101
require.NotNil(t, meta.NonceValue)
100102
nonceValue := meta.NonceValue
103+
nonce := meta.Nonce
104+
105+
old := postMetadataV0{
106+
NodeId: nodeId,
107+
CommitmentAtxId: commitmentAtxId,
108+
LabelsPerUnit: meta.LabelsPerUnit,
109+
NumUnits: meta.NumUnits,
110+
MaxFileSize: meta.MaxFileSize,
111+
Nonce: meta.Nonce,
112+
NonceValue: meta.NonceValue,
113+
LastPosition: meta.LastPosition,
114+
}
101115

102116
// delete nonce value
103-
meta.NonceValue = nil
104-
require.NoError(t, SaveMetadata(opts.DataDir, meta))
117+
old.NonceValue = nil
118+
119+
// store in old metadata format
120+
f, err := os.Create(filepath.Join(opts.DataDir, MetadataFileName))
121+
require.NoError(t, err)
122+
defer f.Close()
123+
require.NoError(t, json.NewEncoder(f).Encode(old))
105124

106125
// just creating a new initializer should update the metadata
107126
init, err = NewInitializer(
@@ -116,8 +135,10 @@ func TestInitialize_BeforeNonceValue(t *testing.T) {
116135

117136
meta, err = LoadMetadata(opts.DataDir)
118137
require.NoError(t, err)
138+
require.Equal(t, 1, meta.Version)
119139
require.NotNil(t, meta.Nonce)
120140
require.NotNil(t, meta.NonceValue)
141+
require.Equal(t, *nonce, *meta.Nonce)
121142
require.Equal(t, nonceValue, meta.NonceValue)
122143
}
123144

@@ -1124,3 +1145,33 @@ func TestRemoveRedundantFiles(t *testing.T) {
11241145
require.NoError(t, err)
11251146
}
11261147
}
1148+
1149+
func Test_Initialize_Migrates_Metadata(t *testing.T) {
1150+
cfg := config.DefaultConfig()
1151+
1152+
opts := config.DefaultInitOpts()
1153+
opts.DataDir = t.TempDir()
1154+
opts.NumUnits = 3
1155+
opts.MaxFileSize = 2 * cfg.UnitSize()
1156+
1157+
expectedFilesCount := opts.TotalFiles(cfg.LabelsPerUnit)
1158+
// Create 2 redundant files
1159+
for i := 0; i < expectedFilesCount+2; i++ {
1160+
f, err := os.Create(filepath.Join(opts.DataDir, shared.InitFileName(i)))
1161+
require.NoError(t, err)
1162+
_, err = f.Write([]byte("test"))
1163+
require.NoError(t, err)
1164+
require.NoError(t, f.Close())
1165+
}
1166+
1167+
removeRedundantFiles(cfg, opts, zap.NewNop())
1168+
1169+
files, err := os.ReadDir(opts.DataDir)
1170+
require.NoError(t, err)
1171+
require.Len(t, files, expectedFilesCount)
1172+
1173+
for i := 0; i < expectedFilesCount; i++ {
1174+
_, err := os.Stat(filepath.Join(opts.DataDir, shared.InitFileName(i)))
1175+
require.NoError(t, err)
1176+
}
1177+
}

initialization/migrate_metadata.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,19 @@ func migrateV0(dir string, logger *zap.Logger) (err error) {
101101
return fmt.Errorf("failed to determine metadata version: %w", err)
102102
}
103103

104-
var nodeID shared.NodeID
105104
if len(old.NodeId) != 32 {
106105
return fmt.Errorf("invalid node ID length: %d", len(old.NodeId))
107106
}
108-
copy(nodeID[:], old.NodeId)
109107

110-
var commitmentAtxID shared.ATXID
111108
if len(old.CommitmentAtxId) != 32 {
112109
return fmt.Errorf("invalid commitment ATX ID length: %d", len(old.CommitmentAtxId))
113110
}
114-
copy(commitmentAtxID[:], old.CommitmentAtxId)
115111

116112
new := shared.PostMetadata{
117113
Version: 1,
118114

119-
NodeId: nodeID,
120-
CommitmentAtxId: commitmentAtxID,
115+
NodeId: old.NodeId,
116+
CommitmentAtxId: old.CommitmentAtxId,
121117

122118
LabelsPerUnit: old.LabelsPerUnit,
123119
NumUnits: old.NumUnits,
@@ -131,7 +127,7 @@ func migrateV0(dir string, logger *zap.Logger) (err error) {
131127

132128
if new.Nonce != nil && new.NonceValue == nil {
133129
// there is a nonce in the metadata but no nonce value
134-
commitment := oracle.CommitmentBytes(new.NodeId[:], new.CommitmentAtxId[:])
130+
commitment := oracle.CommitmentBytes(new.NodeId, new.CommitmentAtxId)
135131
cpuProviderID := CPUProviderID()
136132

137133
wo, err := oracle.New(
@@ -149,7 +145,7 @@ func migrateV0(dir string, logger *zap.Logger) (err error) {
149145
if err != nil {
150146
return fmt.Errorf("failed to compute nonce value: %w", err)
151147
}
152-
copy(new.NonceValue, result.Output)
148+
new.NonceValue = result.Output
153149
}
154150

155151
tmp, err := os.Create(fmt.Sprintf("%s.tmp", filename))
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package initialization
2+
3+
import (
4+
"crypto/rand"
5+
"encoding/json"
6+
"os"
7+
"path/filepath"
8+
"testing"
9+
10+
"github.com/stretchr/testify/require"
11+
"go.uber.org/zap/zaptest"
12+
)
13+
14+
func Fuzz_MigrateMetadata(f *testing.F) {
15+
nodeId := make([]byte, 32)
16+
rand.Read(nodeId)
17+
18+
commitmentAtxId := make([]byte, 32)
19+
rand.Read(commitmentAtxId)
20+
21+
f.Add(make([]byte, 32), make([]byte, 32), []byte{1}, uint64(67), uint64(1024), uint64(1024*1024), uint64(1024), uint32(4))
22+
f.Add(nodeId, commitmentAtxId, []byte{1, 23}, uint64(128), uint64(1024*1024), uint64(1024*1024*1024), uint64(2389712), uint32(16))
23+
24+
f.Fuzz(func(t *testing.T, nodeId, commitmentAtxId, nonceValue []byte, nonce, labelsPerUnit, maxFileSize, lastPosition uint64, numUnits uint32) {
25+
if len(nodeId) != 32 || len(commitmentAtxId) != 32 {
26+
return
27+
}
28+
29+
path := t.TempDir()
30+
31+
f, err := os.Create(filepath.Join(path, MetadataFileName))
32+
require.NoError(t, err)
33+
defer f.Close()
34+
35+
old := postMetadataV0{
36+
NodeId: nodeId,
37+
CommitmentAtxId: commitmentAtxId,
38+
LabelsPerUnit: labelsPerUnit,
39+
NumUnits: numUnits,
40+
MaxFileSize: maxFileSize,
41+
Nonce: &nonce,
42+
NonceValue: nonceValue,
43+
LastPosition: &lastPosition,
44+
}
45+
46+
if len(nonceValue) == 0 {
47+
old.NonceValue = nil
48+
old.Nonce = nil
49+
}
50+
51+
require.NoError(t, json.NewEncoder(f).Encode(old))
52+
53+
log := zaptest.NewLogger(t)
54+
require.NoError(t, MigratePoST(path, log))
55+
56+
metadata, err := LoadMetadata(path)
57+
require.NoError(t, err)
58+
59+
require.Equal(t, 1, metadata.Version)
60+
61+
require.Equal(t, nodeId, metadata.NodeId)
62+
require.Equal(t, commitmentAtxId, metadata.CommitmentAtxId)
63+
require.Equal(t, labelsPerUnit, metadata.LabelsPerUnit)
64+
require.Equal(t, numUnits, metadata.NumUnits)
65+
require.Equal(t, maxFileSize, metadata.MaxFileSize)
66+
if old.NonceValue == nil {
67+
require.Nil(t, metadata.NonceValue)
68+
require.Nil(t, metadata.Nonce)
69+
} else {
70+
require.Equal(t, old.NonceValue, metadata.NonceValue)
71+
require.Equal(t, *old.Nonce, *metadata.Nonce)
72+
}
73+
require.Equal(t, lastPosition, *metadata.LastPosition)
74+
75+
require.NotNil(t, metadata.Scrypt)
76+
})
77+
}
78+
79+
func Test_Migrate_MissingMetadataFile(t *testing.T) {
80+
path := t.TempDir()
81+
log := zaptest.NewLogger(t)
82+
require.ErrorIs(t, MigratePoST(path, log), ErrStateMetadataFileMissing)
83+
}
84+
85+
func Test_Migrate_Adds_NonceValue(t *testing.T) {
86+
nonce := uint64(10)
87+
old := postMetadataV0{
88+
NodeId: make([]byte, 32),
89+
CommitmentAtxId: make([]byte, 32),
90+
LabelsPerUnit: 1024,
91+
NumUnits: 4,
92+
MaxFileSize: 1024 * 1014,
93+
Nonce: &nonce,
94+
NonceValue: nil,
95+
LastPosition: nil,
96+
}
97+
98+
path := t.TempDir()
99+
f, err := os.Create(filepath.Join(path, MetadataFileName))
100+
require.NoError(t, err)
101+
defer f.Close()
102+
require.NoError(t, json.NewEncoder(f).Encode(old))
103+
104+
log := zaptest.NewLogger(t)
105+
require.NoError(t, MigratePoST(path, log))
106+
107+
metadata, err := LoadMetadata(path)
108+
require.NoError(t, err)
109+
110+
require.Equal(t, 1, metadata.Version)
111+
112+
require.NotNil(t, metadata.NonceValue)
113+
require.NotNil(t, metadata.Nonce)
114+
}

scripts/fuzz.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
3+
# https://github.com/golang/go/issues/46312
4+
5+
set -e
6+
7+
fuzzTime=${1:-"10s"}
8+
9+
files=$(grep -r --include='**_test.go' --files-with-matches 'func Fuzz' .)
10+
11+
for file in ${files}
12+
do
13+
funcs=$(grep -oP 'func \K(Fuzz\w*)' $file)
14+
for func in ${funcs}
15+
do
16+
parentDir=$(dirname $file)
17+
command="go test $parentDir -run=$func -fuzz=^$func\$ -fuzztime=${fuzzTime}"
18+
echo $command
19+
eval $command
20+
done
21+
done

0 commit comments

Comments
 (0)