@@ -791,17 +791,22 @@ def aggregate(
791791 new_payloads = new_payloads or {}
792792 known_payloads = known_payloads or {}
793793
794- # Plain aggregation: only attestation_signatures. Remove this block once
795- # bindings support recursive aggregation.
796- attestation_keys = set (gossip_signatures .keys ())
794+ attestation_keys = set (new_payloads .keys ()) | set (gossip_signatures .keys ())
797795 if not attestation_keys :
798796 return results
799797 for data in attestation_keys :
798+ child_proofs : list [AggregatedSignatureProof ] = []
799+ covered_validators : set [ValidatorIndex ] = set ()
800+ self ._extend_proofs_greedily (new_payloads .get (data ), child_proofs , covered_validators )
801+ self ._extend_proofs_greedily (known_payloads .get (data ), child_proofs , covered_validators )
800802 raw_entries = []
801803 for entry in sorted (gossip_signatures .get (data , set ()), key = lambda e : e .validator_id ):
804+ if entry .validator_id in covered_validators :
805+ continue
802806 public_key = self .validators [entry .validator_id ].get_attestation_pubkey ()
803807 raw_entries .append ((entry .validator_id , public_key , entry .signature ))
804- if not raw_entries :
808+ covered_validators .add (entry .validator_id )
809+ if not raw_entries and len (child_proofs ) < 2 :
805810 continue
806811 raw_entries = sorted (raw_entries , key = lambda e : e [0 ])
807812 raw_xmss = [(pk , sig ) for _ , pk , sig in raw_entries ]
@@ -810,7 +815,7 @@ def aggregate(
810815 )
811816 proof = AggregatedSignatureProof .aggregate (
812817 xmss_participants = xmss_participants ,
813- children = [] ,
818+ children = child_proofs ,
814819 raw_xmss = raw_xmss ,
815820 message = data .data_root_bytes (),
816821 slot = data .slot ,
0 commit comments