@@ -531,8 +531,10 @@ func consistencyProbes(rootDir string) error {
531531 return err
532532 }
533533
534- if err := staticConsistencyProbes (staticDir ); err != nil {
535- return err
534+ for _ , p := range staticConsistencyProbes () {
535+ if err := writeConsistencyProbe (staticDir , p ); err != nil {
536+ return err
537+ }
536538 }
537539
538540 return nil
@@ -604,13 +606,13 @@ func corruptedConsistencyProbes(dir string, size1, size2 uint64, proof [][]byte,
604606 return nil
605607}
606608
607- func staticConsistencyProbes (dir string ) error {
609+ func staticConsistencyProbes () [] consistencyProbe {
608610 root1 := []byte ("don't care 1" )
609611 root2 := []byte ("don't care 2" )
610612 proof1 := [][]byte {}
611613 proof2 := [][]byte {sha256EmptyTreeHash }
612614
613- tests := []consistencyProbe {
615+ return []consistencyProbe {
614616 {0 , 0 , root1 , root2 , proof1 , "sizes are equal (zero) but roots are not" , true },
615617 {1 , 1 , root1 , root2 , proof1 , "sizes are equal (one) but roots are not" , true },
616618 {0 , 0 , root1 , root1 , proof1 , "sizes are equal (zero) and proof is empty" , true },
@@ -632,17 +634,135 @@ func staticConsistencyProbes(dir string) error {
632634 {0 , 1 , sha256EmptyTreeHash , root2 , proof1 , "size1 is zero and size2 is not zero" , true },
633635 {0 , 1 , sha256EmptyTreeHash , sha256EmptyTreeHash , proof2 , "consistency check on empty tree (size1 is zero) is useless" , true },
634636 }
637+ }
635638
636- for _ , p := range tests {
637- if err := writeConsistencyProbe (dir , p ); err != nil {
639+ func writeConsistencyProbe (dir string , probe consistencyProbe ) error {
640+ fn := fileName (probe .Desc )
641+
642+ probeJson , err := json .MarshalIndent (probe , "" , " " )
643+ if err != nil {
644+ return fmt .Errorf ("marshaling probe: %s" , err )
645+ }
646+
647+ fileLocation := filepath .Join (dir , fn )
648+ if err := os .WriteFile (fileLocation , probeJson , 0644 ); err != nil {
649+ return fmt .Errorf ("writing probe: %s: %s" , fn , err )
650+ }
651+
652+ return nil
653+ }
654+
655+ // =============================================================================
656+ // Subtree Consistency Proofs
657+ // =============================================================================
658+
659+ // subtreeConsistencyProbe is a parameter set for subtree consistency proof
660+ // verification.
661+ type subtreeConsistencyProbe struct {
662+ Start uint64 `json:"start"`
663+ End uint64 `json:"end"`
664+ Size uint64 `json:"size"`
665+ Root1 []byte `json:"root1"`
666+ Root2 []byte `json:"root2"`
667+ Proof [][]byte `json:"proof"`
668+
669+ Desc string `json:"desc"`
670+ WantError bool `json:"wantErr"`
671+ }
672+
673+ func subtreeConsistencyProbes (rootDir string ) error {
674+ for i , p := range consistencyProofs {
675+ dir := filepath .Join (rootDir , strconv .Itoa (i ))
676+ if err := os .MkdirAll (dir , 0755 ); err != nil {
677+ return err
678+ }
679+
680+ if err := corruptedSubtreeConsistencyProbes (dir , p .size1 , p .size2 , p .proof ,
681+ roots [p .size1 - 1 ], roots [p .size2 - 1 ]); err != nil {
682+ return fmt .Errorf ("write subtree consistency test data: %s" , err )
683+ }
684+ }
685+
686+ staticDir := filepath .Join (rootDir , "additional" )
687+ if err := os .MkdirAll (staticDir , 0755 ); err != nil {
688+ return err
689+ }
690+
691+ if err := staticSubtreeConsistencyProbes (staticDir ); err != nil {
692+ return err
693+ }
694+
695+ return nil
696+ }
697+
698+ func corruptedSubtreeConsistencyProbes (dir string , size1 , size2 uint64 , proof [][]byte , root1 , root2 []byte ) error {
699+ happyPath := subtreeConsistencyProbe {0 , size1 , size2 , root1 , root2 , proof , "happy path" , false }
700+ if err := writeSubtreeConsistencyProbe (dir , happyPath ); err != nil {
701+ return err
702+ }
703+
704+ if len (proof ) == 0 {
705+ return nil
706+ }
707+
708+ probes := invalidSubtreeConsistencyProof (size1 , size2 , root1 , root2 , proof )
709+ for _ , p := range probes {
710+ if err := writeSubtreeConsistencyProbe (dir , p ); err != nil {
638711 return err
639712 }
640713 }
641714
642715 return nil
643716}
644717
645- func writeConsistencyProbe (dir string , probe consistencyProbe ) error {
718+ func invalidSubtreeConsistencyProof (size1 , size2 uint64 , root1 , root2 []byte , proof [][]byte ) []subtreeConsistencyProbe {
719+ cProbes := invalidConsistencyProof (size1 , size2 , root1 , root2 , proof )
720+ ret := make ([]subtreeConsistencyProbe , 0 , len (cProbes )+ 1 )
721+ for _ , p := range cProbes {
722+ ret = append (ret , subtreeConsistencyProbe {
723+ Start : 0 ,
724+ End : p .Size1 ,
725+ Size : p .Size2 ,
726+ Root1 : p .Root1 ,
727+ Root2 : p .Root2 ,
728+ Proof : p .Proof ,
729+ Desc : p .Desc ,
730+ WantError : p .WantError ,
731+ })
732+ }
733+ ret = append (ret , subtreeConsistencyProbe {
734+ Start : 1 ,
735+ End : 15 ,
736+ Size : 15 ,
737+ Root1 : root1 ,
738+ Root2 : root2 ,
739+ Proof : proof ,
740+ Desc : "invalid subtree" ,
741+ WantError : true ,
742+ })
743+ return ret
744+ }
745+
746+ func staticSubtreeConsistencyProbes (dir string ) error {
747+ for _ , p := range staticConsistencyProbes () {
748+ sp := subtreeConsistencyProbe {
749+ Start : 0 ,
750+ End : p .Size1 ,
751+ Size : p .Size2 ,
752+ Root1 : p .Root1 ,
753+ Root2 : p .Root2 ,
754+ Proof : p .Proof ,
755+ Desc : p .Desc ,
756+ WantError : p .WantError ,
757+ }
758+ if err := writeSubtreeConsistencyProbe (dir , sp ); err != nil {
759+ return err
760+ }
761+ }
762+ return nil
763+ }
764+
765+ func writeSubtreeConsistencyProbe (dir string , probe subtreeConsistencyProbe ) error {
646766 fn := fileName (probe .Desc )
647767
648768 probeJson , err := json .MarshalIndent (probe , "" , " " )
@@ -710,4 +830,9 @@ func main() {
710830 if err := consistencyProbes (consistencyDir ); err != nil {
711831 log .Fatalf ("writing consistency test data: %s" , err )
712832 }
833+
834+ subtreeConsistencyDir := "testdata/subtreeconsistency"
835+ if err := subtreeConsistencyProbes (subtreeConsistencyDir ); err != nil {
836+ log .Fatalf ("writing subtree consistency test data: %s" , err )
837+ }
713838}
0 commit comments