|
1 | 1 | package ics23
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
4 | 5 | "encoding/json"
|
5 | 6 | "os"
|
6 | 7 | "path/filepath"
|
@@ -40,6 +41,38 @@ func FuzzExistenceProofCalculate(f *testing.F) {
|
40 | 41 | })
|
41 | 42 | }
|
42 | 43 |
|
| 44 | +func FuzzExistenceProofCheckAgainstSpec(f *testing.F) { |
| 45 | + if testing.Short() { |
| 46 | + f.Skip("in -short mode") |
| 47 | + } |
| 48 | + |
| 49 | + seedDataMap := CheckAgainstSpecTestData(f) |
| 50 | + for _, seed := range seedDataMap { |
| 51 | + if seed.IsErr { |
| 52 | + // Erroneous data, skip it. |
| 53 | + continue |
| 54 | + } |
| 55 | + if blob, err := json.Marshal(seed); err == nil { |
| 56 | + f.Add(blob) |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + // 2. Now run the fuzzer. |
| 61 | + f.Fuzz(func(t *testing.T, fJSON []byte) { |
| 62 | + pvs := new(CheckAgainstSpecTestStruct) |
| 63 | + if err := json.Unmarshal(fJSON, pvs); err != nil { |
| 64 | + return |
| 65 | + } |
| 66 | + if pvs.Proof == nil { |
| 67 | + // No need checking from a nil ExistenceProof. |
| 68 | + return |
| 69 | + } |
| 70 | + |
| 71 | + ep, spec := pvs.Proof, pvs.Spec |
| 72 | + _ = ep.CheckAgainstSpec(spec) |
| 73 | + }) |
| 74 | +} |
| 75 | + |
43 | 76 | var batchVectorDataSeeds []*BatchVectorData
|
44 | 77 |
|
45 | 78 | func init() {
|
@@ -89,6 +122,57 @@ func FuzzVerifyNonMembership(f *testing.F) {
|
89 | 122 | })
|
90 | 123 | }
|
91 | 124 |
|
| 125 | +// verifyJSON is necessary so we already have sources of Proof, Ref and Spec |
| 126 | +// that'll be mutated by the fuzzer to get much closer to values for greater coverage. |
| 127 | +type verifyJSON struct { |
| 128 | + Proof *CommitmentProof |
| 129 | + Ref *RefData |
| 130 | + Spec *ProofSpec |
| 131 | +} |
| 132 | + |
| 133 | +func FuzzVerifyMembership(f *testing.F) { |
| 134 | + seeds := VectorsTestData() |
| 135 | + |
| 136 | + // VerifyMembership requires: |
| 137 | + // Spec, ExistenceProof, CommitmentRootref. |
| 138 | + for _, seed := range seeds { |
| 139 | + proof, ref := LoadFile(f, seed.Dir, seed.Filename) |
| 140 | + root, err := proof.Calculate() |
| 141 | + if err != nil { |
| 142 | + continue |
| 143 | + } |
| 144 | + if !bytes.Equal(ref.RootHash, root) { |
| 145 | + continue |
| 146 | + } |
| 147 | + |
| 148 | + if ref.Value == nil { |
| 149 | + continue |
| 150 | + } |
| 151 | + |
| 152 | + // Now serialize this value as a seed. |
| 153 | + // The use of already calculated values is necessary |
| 154 | + // for the fuzzers to have a basis of much better coverage |
| 155 | + // generating values. |
| 156 | + blob, err := json.Marshal(&verifyJSON{Proof: proof, Ref: ref, Spec: seed.Spec}) |
| 157 | + if err == nil { |
| 158 | + f.Add(blob) |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + // 2. Now let's run the fuzzer. |
| 163 | + f.Fuzz(func(t *testing.T, input []byte) { |
| 164 | + var con verifyJSON |
| 165 | + if err := json.Unmarshal(input, &con); err != nil { |
| 166 | + return |
| 167 | + } |
| 168 | + spec, ref, proof := con.Spec, con.Ref, con.Proof |
| 169 | + if ref == nil { |
| 170 | + return |
| 171 | + } |
| 172 | + _ = VerifyMembership(spec, ref.RootHash, proof, ref.Key, ref.Value) |
| 173 | + }) |
| 174 | +} |
| 175 | + |
92 | 176 | func FuzzCombineProofs(f *testing.F) {
|
93 | 177 | // 1. Load in the CommitmentProofs
|
94 | 178 | baseDirs := []string{"iavl", "tendermint", "smt"}
|
|
0 commit comments