@@ -709,9 +709,137 @@ func (d *Dag) GetPartial(start, end int) (*Dag, error) {
709
709
return partialDag , nil
710
710
}
711
711
712
+ // getPartialLeafSequence returns an ordered sequence of leaves for transmission from a partial DAG
713
+ // This is an internal method used by GetLeafSequence when dealing with partial DAGs
714
+ func (d * Dag ) getPartialLeafSequence () []* TransmissionPacket {
715
+ var sequence []* TransmissionPacket
716
+
717
+ // Get the root leaf
718
+ rootLeaf := d .Leafs [d .Root ]
719
+ if rootLeaf == nil {
720
+ return sequence // Return empty sequence if root leaf is missing
721
+ }
722
+
723
+ // First, build a map of proofs organized by parent hash and child hash
724
+ // This will allow us to look up the proof for a specific child when creating its packet
725
+ proofMap := make (map [string ]map [string ]* ClassicTreeBranch )
726
+
727
+ // Populate the proof map from all leaves in the partial DAG
728
+ for _ , leaf := range d .Leafs {
729
+ if len (leaf .Proofs ) > 0 {
730
+ // Create an entry for this parent if it doesn't exist
731
+ if _ , exists := proofMap [leaf .Hash ]; ! exists {
732
+ proofMap [leaf .Hash ] = make (map [string ]* ClassicTreeBranch )
733
+ }
734
+
735
+ // Add all proofs from this leaf to the map
736
+ for childHash , proof := range leaf .Proofs {
737
+ proofMap [leaf.Hash ][childHash ] = proof
738
+ }
739
+ }
740
+ }
741
+
742
+ // Now perform BFS traversal similar to the full DAG method
743
+ visited := make (map [string ]bool )
744
+
745
+ // Start with the root
746
+ rootLeafClone := rootLeaf .Clone ()
747
+
748
+ // We need to preserve the original links for the root leaf
749
+ // because they're part of its identity and hash calculation
750
+ originalLinks := make (map [string ]string )
751
+ for k , v := range rootLeaf .Links {
752
+ originalLinks [k ] = v
753
+ }
754
+
755
+ // Clear links for transmission (they'll be reconstructed on the receiving end)
756
+ rootLeafClone .Links = make (map [string ]string )
757
+
758
+ // We need to preserve these fields for verification
759
+ // but clear proofs for the root packet - they'll be sent with child packets
760
+ originalMerkleRoot := rootLeafClone .ClassicMerkleRoot
761
+ originalLatestLabel := rootLeafClone .LatestLabel
762
+ originalLeafCount := rootLeafClone .LeafCount
763
+
764
+ rootLeafClone .Proofs = nil
765
+
766
+ // Restore the critical fields
767
+ rootLeafClone .ClassicMerkleRoot = originalMerkleRoot
768
+ rootLeafClone .LatestLabel = originalLatestLabel
769
+ rootLeafClone .LeafCount = originalLeafCount
770
+
771
+ rootPacket := & TransmissionPacket {
772
+ Leaf : rootLeafClone ,
773
+ ParentHash : "" , // Root has no parent
774
+ Proofs : make (map [string ]* ClassicTreeBranch ),
775
+ }
776
+ sequence = append (sequence , rootPacket )
777
+ visited [d .Root ] = true
778
+
779
+ // Restore the original links for the root leaf in the DAG
780
+ rootLeaf .Links = originalLinks
781
+
782
+ // BFS traversal
783
+ queue := []string {d .Root }
784
+ for len (queue ) > 0 {
785
+ current := queue [0 ]
786
+ queue = queue [1 :]
787
+
788
+ currentLeaf := d .Leafs [current ]
789
+
790
+ // Sort links for deterministic order
791
+ var sortedLinks []string
792
+ for _ , link := range currentLeaf .Links {
793
+ sortedLinks = append (sortedLinks , link )
794
+ }
795
+ sort .Strings (sortedLinks )
796
+
797
+ // Process each child
798
+ for _ , childHash := range sortedLinks {
799
+ if ! visited [childHash ] {
800
+ childLeaf := d .Leafs [childHash ]
801
+ if childLeaf == nil {
802
+ continue // Skip if child leaf doesn't exist in this partial DAG
803
+ }
804
+
805
+ // Clone the leaf and clear its links for transmission
806
+ leafClone := childLeaf .Clone ()
807
+ leafClone .Links = make (map [string ]string )
808
+ leafClone .Proofs = nil // Clear proofs from the leaf
809
+
810
+ packet := & TransmissionPacket {
811
+ Leaf : leafClone ,
812
+ ParentHash : current ,
813
+ Proofs : make (map [string ]* ClassicTreeBranch ),
814
+ }
815
+
816
+ // Add the proof for this specific child from the proof map
817
+ if parentProofs , exists := proofMap [current ]; exists {
818
+ if proof , hasProof := parentProofs [childHash ]; hasProof {
819
+ packet .Proofs [childHash ] = proof
820
+ }
821
+ }
822
+
823
+ sequence = append (sequence , packet )
824
+ visited [childHash ] = true
825
+ queue = append (queue , childHash )
826
+ }
827
+ }
828
+ }
829
+
830
+ return sequence
831
+ }
832
+
712
833
// GetLeafSequence returns an ordered sequence of leaves for transmission
713
834
// Each packet contains a leaf, its parent hash, and any proofs needed for verification
714
835
func (d * Dag ) GetLeafSequence () []* TransmissionPacket {
836
+ // Check if this is a partial DAG
837
+ if d .IsPartial () {
838
+ // Use specialized method for partial DAGs
839
+ return d .getPartialLeafSequence ()
840
+ }
841
+
842
+ // Original implementation for complete DAGs
715
843
var sequence []* TransmissionPacket
716
844
visited := make (map [string ]bool )
717
845
0 commit comments