@@ -604,13 +604,13 @@ func corruptedConsistencyProbes(dir string, size1, size2 uint64, proof [][]byte,
604604 return nil
605605}
606606
607- func staticConsistencyProbes ( dir string ) error {
607+ func staticConsistencyTests () [] consistencyProbe {
608608 root1 := []byte ("don't care 1" )
609609 root2 := []byte ("don't care 2" )
610610 proof1 := [][]byte {}
611611 proof2 := [][]byte {sha256EmptyTreeHash }
612612
613- tests := []consistencyProbe {
613+ return []consistencyProbe {
614614 {0 , 0 , root1 , root2 , proof1 , "sizes are equal (zero) but roots are not" , true },
615615 {1 , 1 , root1 , root2 , proof1 , "sizes are equal (one) but roots are not" , true },
616616 {0 , 0 , root1 , root1 , proof1 , "sizes are equal (zero) and proof is empty" , true },
@@ -632,8 +632,10 @@ func staticConsistencyProbes(dir string) error {
632632 {0 , 1 , sha256EmptyTreeHash , root2 , proof1 , "size1 is zero and size2 is not zero" , true },
633633 {0 , 1 , sha256EmptyTreeHash , sha256EmptyTreeHash , proof2 , "consistency check on empty tree (size1 is zero) is useless" , true },
634634 }
635+ }
635636
636- for _ , p := range tests {
637+ func staticConsistencyProbes (dir string ) error {
638+ for _ , p := range staticConsistencyTests () {
637639 if err := writeConsistencyProbe (dir , p ); err != nil {
638640 return err
639641 }
@@ -658,6 +660,132 @@ func writeConsistencyProbe(dir string, probe consistencyProbe) error {
658660 return nil
659661}
660662
663+ // =============================================================================
664+ // Subtree Consistency Proofs
665+ // =============================================================================
666+
667+ // subtreeConsistencyProbe is a parameter set for subtree consistency proof
668+ // verification.
669+ type subtreeConsistencyProbe struct {
670+ Start uint64 `json:"start"`
671+ End uint64 `json:"end"`
672+ Size uint64 `json:"size"`
673+ Root1 []byte `json:"root1"`
674+ Root2 []byte `json:"root2"`
675+ Proof [][]byte `json:"proof"`
676+
677+ Desc string `json:"desc"`
678+ WantError bool `json:"wantErr"`
679+ }
680+
681+ func subtreeConsistencyProbes (rootDir string ) error {
682+ for i , p := range consistencyProofs {
683+ dir := filepath .Join (rootDir , strconv .Itoa (i ))
684+ if err := os .MkdirAll (dir , 0755 ); err != nil {
685+ return err
686+ }
687+
688+ if err := corruptedSubtreeConsistencyProbes (dir , p .size1 , p .size2 , p .proof ,
689+ roots [p .size1 - 1 ], roots [p .size2 - 1 ]); err != nil {
690+ return fmt .Errorf ("write subtree consistency test data: %s" , err )
691+ }
692+ }
693+
694+ staticDir := filepath .Join (rootDir , "additional" )
695+ if err := os .MkdirAll (staticDir , 0755 ); err != nil {
696+ return err
697+ }
698+
699+ if err := staticSubtreeConsistencyProbes (staticDir ); err != nil {
700+ return err
701+ }
702+
703+ return nil
704+ }
705+
706+ func corruptedSubtreeConsistencyProbes (dir string , size1 , size2 uint64 , proof [][]byte , root1 , root2 []byte ) error {
707+ happyPath := subtreeConsistencyProbe {0 , size1 , size2 , root1 , root2 , proof , "happy path" , false }
708+ if err := writeSubtreeConsistencyProbe (dir , happyPath ); err != nil {
709+ return err
710+ }
711+
712+ if len (proof ) == 0 {
713+ return nil
714+ }
715+
716+ probes := invalidSubtreeConsistencyProof (size1 , size2 , root1 , root2 , proof )
717+ for _ , p := range probes {
718+ if err := writeSubtreeConsistencyProbe (dir , p ); err != nil {
719+ return err
720+ }
721+ }
722+
723+ return nil
724+ }
725+
726+ func invalidSubtreeConsistencyProof (size1 , size2 uint64 , root1 , root2 []byte , proof [][]byte ) []subtreeConsistencyProbe {
727+ cProbes := invalidConsistencyProof (size1 , size2 , root1 , root2 , proof )
728+ ret := make ([]subtreeConsistencyProbe , 0 , len (cProbes )+ 1 )
729+ for _ , p := range cProbes {
730+ ret = append (ret , subtreeConsistencyProbe {
731+ Start : 0 ,
732+ End : p .Size1 ,
733+ Size : p .Size2 ,
734+ Root1 : p .Root1 ,
735+ Root2 : p .Root2 ,
736+ Proof : p .Proof ,
737+ Desc : p .Desc ,
738+ WantError : p .WantError ,
739+ })
740+ }
741+ ret = append (ret , subtreeConsistencyProbe {
742+ Start : 1 ,
743+ End : 15 ,
744+ Size : 15 ,
745+ Root1 : root1 ,
746+ Root2 : root2 ,
747+ Proof : proof ,
748+ Desc : "invalid subtree" ,
749+ WantError : true ,
750+ })
751+ return ret
752+ }
753+
754+ func staticSubtreeConsistencyProbes (dir string ) error {
755+ for _ , p := range staticConsistencyTests () {
756+ sp := subtreeConsistencyProbe {
757+ Start : 0 ,
758+ End : p .Size1 ,
759+ Size : p .Size2 ,
760+ Root1 : p .Root1 ,
761+ Root2 : p .Root2 ,
762+ Proof : p .Proof ,
763+ Desc : p .Desc ,
764+ WantError : p .WantError ,
765+ }
766+ if err := writeSubtreeConsistencyProbe (dir , sp ); err != nil {
767+ return err
768+ }
769+ }
770+ return nil
771+ }
772+
773+ func writeSubtreeConsistencyProbe (dir string , probe subtreeConsistencyProbe ) error {
774+ fn := fileName (probe .Desc )
775+
776+ probeJson , err := json .MarshalIndent (probe , "" , " " )
777+ if err != nil {
778+ return fmt .Errorf ("marshaling probe: %s" , err )
779+ }
780+
781+ fileLocation := filepath .Join (dir , fn )
782+ if err := os .WriteFile (fileLocation , probeJson , 0644 ); err != nil {
783+ return fmt .Errorf ("writing probe: %s: %s" , fn , err )
784+ }
785+
786+ return nil
787+ }
788+
661789// =============================================================================
662790// General Helpers
663791// =============================================================================
@@ -710,4 +838,9 @@ func main() {
710838 if err := consistencyProbes (consistencyDir ); err != nil {
711839 log .Fatalf ("writing consistency test data: %s" , err )
712840 }
841+
842+ subtreeConsistencyDir := "testdata/subtreeconsistency"
843+ if err := subtreeConsistencyProbes (subtreeConsistencyDir ); err != nil {
844+ log .Fatalf ("writing subtree consistency test data: %s" , err )
845+ }
713846}
0 commit comments