Skip to content

Commit 7bf1239

Browse files
author
Dan Laine
authored
merkledb -- add codec test and move helper (#1944)
1 parent acc9e09 commit 7bf1239

File tree

2 files changed

+97
-46
lines changed

2 files changed

+97
-46
lines changed

x/merkledb/codec_test.go

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,9 @@ import (
1212
"github.com/stretchr/testify/require"
1313

1414
"github.com/ava-labs/avalanchego/ids"
15-
"github.com/ava-labs/avalanchego/utils/hashing"
1615
"github.com/ava-labs/avalanchego/utils/maybe"
1716
)
1817

19-
// TODO add more codec tests
20-
21-
func newRandomProofNode(r *rand.Rand) ProofNode {
22-
key := make([]byte, r.Intn(32)) // #nosec G404
23-
_, _ = r.Read(key) // #nosec G404
24-
serializedKey := newPath(key).Serialize()
25-
26-
val := make([]byte, r.Intn(64)) // #nosec G404
27-
_, _ = r.Read(val) // #nosec G404
28-
29-
children := map[byte]ids.ID{}
30-
for j := 0; j < NodeBranchFactor; j++ {
31-
if r.Float64() < 0.5 {
32-
var childID ids.ID
33-
_, _ = r.Read(childID[:]) // #nosec G404
34-
children[byte(j)] = childID
35-
}
36-
}
37-
38-
hasValue := rand.Intn(2) == 1 // #nosec G404
39-
var valueOrHash maybe.Maybe[[]byte]
40-
if hasValue {
41-
// use the hash instead when length is greater than the hash length
42-
if len(val) >= HashLength {
43-
val = hashing.ComputeHash256(val)
44-
} else if len(val) == 0 {
45-
// We do this because when we encode a value of []byte{} we will later
46-
// decode it as nil.
47-
// Doing this prevents inconsistency when comparing the encoded and
48-
// decoded values.
49-
// Calling nilEmptySlices doesn't set this because it is a private
50-
// variable on the struct
51-
val = nil
52-
}
53-
valueOrHash = maybe.Some(val)
54-
}
55-
56-
return ProofNode{
57-
KeyPath: serializedKey,
58-
ValueOrHash: valueOrHash,
59-
Children: children,
60-
}
61-
}
62-
6318
func FuzzCodecBool(f *testing.F) {
6419
f.Fuzz(
6520
func(
@@ -224,7 +179,7 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) {
224179
)
225180
}
226181

227-
func TestCodec_DecodeDBNode(t *testing.T) {
182+
func TestCodecDecodeDBNode(t *testing.T) {
228183
require := require.New(t)
229184

230185
var (
@@ -260,3 +215,59 @@ func TestCodec_DecodeDBNode(t *testing.T) {
260215
err = codec.decodeDBNode(proofBytesBuf.Bytes(), &parsedDBNode)
261216
require.ErrorIs(err, errTooManyChildren)
262217
}
218+
219+
// Ensure that encodeHashValues is deterministic
220+
func FuzzEncodeHashValues(f *testing.F) {
221+
codec1 := newCodec()
222+
codec2 := newCodec()
223+
224+
f.Fuzz(
225+
func(
226+
t *testing.T,
227+
randSeed int,
228+
) {
229+
require := require.New(t)
230+
231+
// Create a random *hashValues
232+
r := rand.New(rand.NewSource(int64(randSeed))) // #nosec G404
233+
234+
children := map[byte]child{}
235+
numChildren := r.Intn(NodeBranchFactor) // #nosec G404
236+
for i := 0; i < numChildren; i++ {
237+
compressedPathLen := r.Intn(32) // #nosec G404
238+
compressedPathBytes := make([]byte, compressedPathLen)
239+
_, _ = r.Read(compressedPathBytes) // #nosec G404
240+
241+
children[byte(i)] = child{
242+
compressedPath: newPath(compressedPathBytes),
243+
id: ids.GenerateTestID(),
244+
hasValue: r.Intn(2) == 1, // #nosec G404
245+
}
246+
}
247+
248+
hasValue := r.Intn(2) == 1 // #nosec G404
249+
value := maybe.Nothing[[]byte]()
250+
if hasValue {
251+
valueBytes := make([]byte, r.Intn(64)) // #nosec G404
252+
_, _ = r.Read(valueBytes) // #nosec G404
253+
value = maybe.Some(valueBytes)
254+
}
255+
256+
key := make([]byte, r.Intn(32)) // #nosec G404
257+
_, _ = r.Read(key) // #nosec G404
258+
259+
hv := &hashValues{
260+
Children: children,
261+
Value: value,
262+
Key: newPath(key).Serialize(),
263+
}
264+
265+
// Serialize the *hashValues with both codecs
266+
hvBytes1 := codec1.encodeHashValues(hv)
267+
hvBytes2 := codec2.encodeHashValues(hv)
268+
269+
// Make sure they're the same
270+
require.Equal(hvBytes1, hvBytes2)
271+
},
272+
)
273+
}

x/merkledb/proof_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,46 @@ func writeBasicBatch(t *testing.T, db *merkleDB) {
4343
require.NoError(batch.Write())
4444
}
4545

46+
func newRandomProofNode(r *rand.Rand) ProofNode {
47+
key := make([]byte, r.Intn(32)) // #nosec G404
48+
_, _ = r.Read(key) // #nosec G404
49+
serializedKey := newPath(key).Serialize()
50+
51+
val := make([]byte, r.Intn(64)) // #nosec G404
52+
_, _ = r.Read(val) // #nosec G404
53+
54+
children := map[byte]ids.ID{}
55+
for j := 0; j < NodeBranchFactor; j++ {
56+
if r.Float64() < 0.5 {
57+
var childID ids.ID
58+
_, _ = r.Read(childID[:]) // #nosec G404
59+
children[byte(j)] = childID
60+
}
61+
}
62+
63+
hasValue := rand.Intn(2) == 1 // #nosec G404
64+
var valueOrHash maybe.Maybe[[]byte]
65+
if hasValue {
66+
// use the hash instead when length is greater than the hash length
67+
if len(val) >= HashLength {
68+
val = hashing.ComputeHash256(val)
69+
} else if len(val) == 0 {
70+
// We do this because when we encode a value of []byte{} we will later
71+
// decode it as nil.
72+
// Doing this prevents inconsistency when comparing the encoded and
73+
// decoded values.
74+
val = nil
75+
}
76+
valueOrHash = maybe.Some(val)
77+
}
78+
79+
return ProofNode{
80+
KeyPath: serializedKey,
81+
ValueOrHash: valueOrHash,
82+
Children: children,
83+
}
84+
}
85+
4686
func Test_Proof_Empty(t *testing.T) {
4787
proof := &Proof{}
4888
err := proof.Verify(context.Background(), ids.Empty)

0 commit comments

Comments
 (0)