From 6dae2d73caac2c0119f60c918d37bfd6ca6f854c Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 30 Sep 2025 12:58:36 -0700 Subject: [PATCH 01/13] deps: update go-libp2p-pubsub to specific commit for partial message support --- deps.bzl | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/deps.bzl b/deps.bzl index 64e6d1983aa2..0a7c64751ece 100644 --- a/deps.bzl +++ b/deps.bzl @@ -1993,8 +1993,8 @@ def prysm_deps(): name = "com_github_libp2p_go_libp2p_pubsub", build_file_proto_mode = "disable_global", importpath = "github.com/libp2p/go-libp2p-pubsub", - sum = "h1:nT5lFHPQOFJcp9CW8hpKtvbpQNdl2udJuzLQWbgRum8=", - version = "v0.14.2", + sum = "h1:g1oEz1sfyMpSoZV1ERCO6cCclzqDbFXb2CRL55/Pey0=", + version = "v0.14.4-0.20251015023843-34e9bbaae96d", ) go_repository( name = "com_github_libp2p_go_libp2p_testing", diff --git a/go.mod b/go.mod index 32759e63b765..bb90d6ef792d 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/kr/pretty v0.3.1 github.com/libp2p/go-libp2p v0.39.1 github.com/libp2p/go-libp2p-mplex v0.9.0 - github.com/libp2p/go-libp2p-pubsub v0.14.2 + github.com/libp2p/go-libp2p-pubsub v0.14.4-0.20251015023843-34e9bbaae96d github.com/libp2p/go-mplex v0.7.0 github.com/logrusorgru/aurora v2.0.3+incompatible github.com/manifoldco/promptui v0.7.0 diff --git a/go.sum b/go.sum index e5ba50cf804a..b0c148624b9b 100644 --- a/go.sum +++ b/go.sum @@ -589,8 +589,8 @@ github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl9 github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8= github.com/libp2p/go-libp2p-mplex v0.9.0/go.mod h1:ro1i4kuwiFT+uMPbIDIFkcLs1KRbNp0QwnUXM+P64Og= -github.com/libp2p/go-libp2p-pubsub v0.14.2 h1:nT5lFHPQOFJcp9CW8hpKtvbpQNdl2udJuzLQWbgRum8= -github.com/libp2p/go-libp2p-pubsub v0.14.2/go.mod h1:MKPU5vMI8RRFyTP0HfdsF9cLmL1nHAeJm44AxJGJx44= +github.com/libp2p/go-libp2p-pubsub v0.14.4-0.20251015023843-34e9bbaae96d h1:g1oEz1sfyMpSoZV1ERCO6cCclzqDbFXb2CRL55/Pey0= +github.com/libp2p/go-libp2p-pubsub v0.14.4-0.20251015023843-34e9bbaae96d/go.mod h1:lr4oE8bFgQaifRcoc2uWhWWiK6tPdOEKpUuR408GFN4= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= From e9c7428724e15f33360441e8e3cb2f69d05dfe4f Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 1 Oct 2025 13:21:09 -0700 Subject: [PATCH 02/13] proto: Add partial_data_columns --- proto/prysm/v1alpha1/BUILD.bazel | 2 + proto/prysm/v1alpha1/fulu.ssz.go | 208 ++++++++++++++++ .../prysm/v1alpha1/partial_data_columns.pb.go | 168 +++++++++++++ .../prysm/v1alpha1/partial_data_columns.proto | 37 +++ proto/ssz_proto_library.bzl | 2 + proto/testing/test.pb.go | 227 +++++------------- 6 files changed, 477 insertions(+), 167 deletions(-) create mode 100755 proto/prysm/v1alpha1/partial_data_columns.pb.go create mode 100644 proto/prysm/v1alpha1/partial_data_columns.proto diff --git a/proto/prysm/v1alpha1/BUILD.bazel b/proto/prysm/v1alpha1/BUILD.bazel index 2c6405763fc4..90e6419ec477 100644 --- a/proto/prysm/v1alpha1/BUILD.bazel +++ b/proto/prysm/v1alpha1/BUILD.bazel @@ -188,6 +188,7 @@ ssz_fulu_objs = [ "DataColumnIdentifier", "DataColumnsByRootIdentifier", "DataColumnSidecar", + "PartialDataColumnSidecar", "StatusV2", "SignedBeaconBlockContentsFulu", "SignedBeaconBlockFulu", @@ -396,6 +397,7 @@ ssz_proto_files( "beacon_state.proto", "blobs.proto", "data_columns.proto", + "partial_data_columns.proto", "light_client.proto", "sync_committee.proto", "withdrawals.proto", diff --git a/proto/prysm/v1alpha1/fulu.ssz.go b/proto/prysm/v1alpha1/fulu.ssz.go index 25e3094a0e84..a915892e5895 100644 --- a/proto/prysm/v1alpha1/fulu.ssz.go +++ b/proto/prysm/v1alpha1/fulu.ssz.go @@ -2494,3 +2494,211 @@ func (s *StatusV2) HashTreeRootWith(hh *ssz.Hasher) (err error) { hh.Merkleize(indx) return } + +// MarshalSSZ ssz marshals the PartialDataColumnSidecar object +func (p *PartialDataColumnSidecar) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(p) +} + +// MarshalSSZTo ssz marshals the PartialDataColumnSidecar object to a target array +func (p *PartialDataColumnSidecar) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(12) + + // Offset (0) 'CellsPresentBitmap' + dst = ssz.WriteOffset(dst, offset) + offset += len(p.CellsPresentBitmap) + + // Offset (1) 'PartialColumn' + dst = ssz.WriteOffset(dst, offset) + offset += len(p.PartialColumn) * 2048 + + // Offset (2) 'KzgProofs' + dst = ssz.WriteOffset(dst, offset) + offset += len(p.KzgProofs) * 48 + + // Field (0) 'CellsPresentBitmap' + if size := len(p.CellsPresentBitmap); size > 512 { + err = ssz.ErrBytesLengthFn("--.CellsPresentBitmap", size, 512) + return + } + dst = append(dst, p.CellsPresentBitmap...) + + // Field (1) 'PartialColumn' + if size := len(p.PartialColumn); size > 4096 { + err = ssz.ErrListTooBigFn("--.PartialColumn", size, 4096) + return + } + for ii := 0; ii < len(p.PartialColumn); ii++ { + if size := len(p.PartialColumn[ii]); size != 2048 { + err = ssz.ErrBytesLengthFn("--.PartialColumn[ii]", size, 2048) + return + } + dst = append(dst, p.PartialColumn[ii]...) + } + + // Field (2) 'KzgProofs' + if size := len(p.KzgProofs); size > 4096 { + err = ssz.ErrListTooBigFn("--.KzgProofs", size, 4096) + return + } + for ii := 0; ii < len(p.KzgProofs); ii++ { + if size := len(p.KzgProofs[ii]); size != 48 { + err = ssz.ErrBytesLengthFn("--.KzgProofs[ii]", size, 48) + return + } + dst = append(dst, p.KzgProofs[ii]...) + } + + return +} + +// UnmarshalSSZ ssz unmarshals the PartialDataColumnSidecar object +func (p *PartialDataColumnSidecar) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 12 { + return ssz.ErrSize + } + + tail := buf + var o0, o1, o2 uint64 + + // Offset (0) 'CellsPresentBitmap' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 != 12 { + return ssz.ErrInvalidVariableOffset + } + + // Offset (1) 'PartialColumn' + if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 { + return ssz.ErrOffset + } + + // Offset (2) 'KzgProofs' + if o2 = ssz.ReadOffset(buf[8:12]); o2 > size || o1 > o2 { + return ssz.ErrOffset + } + + // Field (0) 'CellsPresentBitmap' + { + buf = tail[o0:o1] + if err = ssz.ValidateBitlist(buf, 512); err != nil { + return err + } + if cap(p.CellsPresentBitmap) == 0 { + p.CellsPresentBitmap = make([]byte, 0, len(buf)) + } + p.CellsPresentBitmap = append(p.CellsPresentBitmap, buf...) + } + + // Field (1) 'PartialColumn' + { + buf = tail[o1:o2] + num, err := ssz.DivideInt2(len(buf), 2048, 4096) + if err != nil { + return err + } + p.PartialColumn = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(p.PartialColumn[ii]) == 0 { + p.PartialColumn[ii] = make([]byte, 0, len(buf[ii*2048:(ii+1)*2048])) + } + p.PartialColumn[ii] = append(p.PartialColumn[ii], buf[ii*2048:(ii+1)*2048]...) + } + } + + // Field (2) 'KzgProofs' + { + buf = tail[o2:] + num, err := ssz.DivideInt2(len(buf), 48, 4096) + if err != nil { + return err + } + p.KzgProofs = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(p.KzgProofs[ii]) == 0 { + p.KzgProofs[ii] = make([]byte, 0, len(buf[ii*48:(ii+1)*48])) + } + p.KzgProofs[ii] = append(p.KzgProofs[ii], buf[ii*48:(ii+1)*48]...) + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the PartialDataColumnSidecar object +func (p *PartialDataColumnSidecar) SizeSSZ() (size int) { + size = 12 + + // Field (0) 'CellsPresentBitmap' + size += len(p.CellsPresentBitmap) + + // Field (1) 'PartialColumn' + size += len(p.PartialColumn) * 2048 + + // Field (2) 'KzgProofs' + size += len(p.KzgProofs) * 48 + + return +} + +// HashTreeRoot ssz hashes the PartialDataColumnSidecar object +func (p *PartialDataColumnSidecar) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(p) +} + +// HashTreeRootWith ssz hashes the PartialDataColumnSidecar object with a hasher +func (p *PartialDataColumnSidecar) HashTreeRootWith(hh *ssz.Hasher) (err error) { + indx := hh.Index() + + // Field (0) 'CellsPresentBitmap' + if len(p.CellsPresentBitmap) == 0 { + err = ssz.ErrEmptyBitlist + return + } + hh.PutBitlist(p.CellsPresentBitmap, 512) + + // Field (1) 'PartialColumn' + { + if size := len(p.PartialColumn); size > 4096 { + err = ssz.ErrListTooBigFn("--.PartialColumn", size, 4096) + return + } + subIndx := hh.Index() + for _, i := range p.PartialColumn { + if len(i) != 2048 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(i) + } + + numItems := uint64(len(p.PartialColumn)) + hh.MerkleizeWithMixin(subIndx, numItems, 4096) + } + + // Field (2) 'KzgProofs' + { + if size := len(p.KzgProofs); size > 4096 { + err = ssz.ErrListTooBigFn("--.KzgProofs", size, 4096) + return + } + subIndx := hh.Index() + for _, i := range p.KzgProofs { + if len(i) != 48 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(i) + } + + numItems := uint64(len(p.KzgProofs)) + hh.MerkleizeWithMixin(subIndx, numItems, 4096) + } + + hh.Merkleize(indx) + return +} diff --git a/proto/prysm/v1alpha1/partial_data_columns.pb.go b/proto/prysm/v1alpha1/partial_data_columns.pb.go new file mode 100755 index 000000000000..01bb44382b19 --- /dev/null +++ b/proto/prysm/v1alpha1/partial_data_columns.pb.go @@ -0,0 +1,168 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.3 +// protoc v3.21.7 +// source: proto/prysm/v1alpha1/partial_data_columns.proto + +package eth + +import ( + reflect "reflect" + sync "sync" + + _ "github.com/OffchainLabs/prysm/v6/proto/eth/ext" + github_com_prysmaticlabs_go_bitfield "github.com/prysmaticlabs/go-bitfield" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PartialDataColumnSidecar struct { + state protoimpl.MessageState `protogen:"open.v1"` + CellsPresentBitmap github_com_prysmaticlabs_go_bitfield.Bitlist `protobuf:"bytes,1,opt,name=cells_present_bitmap,json=cellsPresentBitmap,proto3" json:"cells_present_bitmap,omitempty" cast-type:"github.com/prysmaticlabs/go-bitfield.Bitlist" ssz-max:"512"` + PartialColumn [][]byte `protobuf:"bytes,2,rep,name=partial_column,json=partialColumn,proto3" json:"partial_column,omitempty" ssz-max:"4096" ssz-size:"?,2048"` + KzgProofs [][]byte `protobuf:"bytes,3,rep,name=kzg_proofs,json=kzgProofs,proto3" json:"kzg_proofs,omitempty" ssz-max:"4096" ssz-size:"?,48"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PartialDataColumnSidecar) Reset() { + *x = PartialDataColumnSidecar{} + mi := &file_proto_prysm_v1alpha1_partial_data_columns_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PartialDataColumnSidecar) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PartialDataColumnSidecar) ProtoMessage() {} + +func (x *PartialDataColumnSidecar) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_partial_data_columns_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PartialDataColumnSidecar.ProtoReflect.Descriptor instead. +func (*PartialDataColumnSidecar) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDescGZIP(), []int{0} +} + +func (x *PartialDataColumnSidecar) GetCellsPresentBitmap() github_com_prysmaticlabs_go_bitfield.Bitlist { + if x != nil { + return x.CellsPresentBitmap + } + return github_com_prysmaticlabs_go_bitfield.Bitlist(nil) +} + +func (x *PartialDataColumnSidecar) GetPartialColumn() [][]byte { + if x != nil { + return x.PartialColumn + } + return nil +} + +func (x *PartialDataColumnSidecar) GetKzgProofs() [][]byte { + if x != nil { + return x.KzgProofs + } + return nil +} + +var File_proto_prysm_v1alpha1_partial_data_columns_proto protoreflect.FileDescriptor + +var file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDesc = []byte{ + 0x0a, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x15, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, + 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, + 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xf1, 0x01, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x44, + 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, + 0x12, 0x69, 0x0a, 0x14, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x74, 0x5f, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x37, + 0x82, 0xb5, 0x18, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x67, 0x6f, 0x2d, + 0x62, 0x69, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x42, 0x69, 0x74, 0x6c, 0x69, 0x73, 0x74, + 0x92, 0xb5, 0x18, 0x03, 0x35, 0x31, 0x32, 0x52, 0x12, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x50, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x74, 0x42, 0x69, 0x74, 0x6d, 0x61, 0x70, 0x12, 0x39, 0x0a, 0x0e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0c, 0x42, 0x12, 0x8a, 0xb5, 0x18, 0x06, 0x3f, 0x2c, 0x32, 0x30, 0x34, 0x38, 0x92, + 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, + 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x2f, 0x0a, 0x0a, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, + 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, + 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x09, 0x6b, 0x7a, + 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, + 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x3b, 0x65, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDescOnce sync.Once + file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDescData = file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDesc +) + +func file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDescGZIP() []byte { + file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDescOnce.Do(func() { + file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDescData) + }) + return file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDescData +} + +var file_proto_prysm_v1alpha1_partial_data_columns_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_proto_prysm_v1alpha1_partial_data_columns_proto_goTypes = []any{ + (*PartialDataColumnSidecar)(nil), // 0: ethereum.eth.v1alpha1.PartialDataColumnSidecar +} +var file_proto_prysm_v1alpha1_partial_data_columns_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_prysm_v1alpha1_partial_data_columns_proto_init() } +func file_proto_prysm_v1alpha1_partial_data_columns_proto_init() { + if File_proto_prysm_v1alpha1_partial_data_columns_proto != nil { + return + } + file_proto_prysm_v1alpha1_beacon_core_types_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_prysm_v1alpha1_partial_data_columns_proto_goTypes, + DependencyIndexes: file_proto_prysm_v1alpha1_partial_data_columns_proto_depIdxs, + MessageInfos: file_proto_prysm_v1alpha1_partial_data_columns_proto_msgTypes, + }.Build() + File_proto_prysm_v1alpha1_partial_data_columns_proto = out.File + file_proto_prysm_v1alpha1_partial_data_columns_proto_rawDesc = nil + file_proto_prysm_v1alpha1_partial_data_columns_proto_goTypes = nil + file_proto_prysm_v1alpha1_partial_data_columns_proto_depIdxs = nil +} diff --git a/proto/prysm/v1alpha1/partial_data_columns.proto b/proto/prysm/v1alpha1/partial_data_columns.proto new file mode 100644 index 000000000000..a6a9abdd7adf --- /dev/null +++ b/proto/prysm/v1alpha1/partial_data_columns.proto @@ -0,0 +1,37 @@ +// Copyright 2025 Offchain Labs. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +syntax = "proto3"; + +package ethereum.eth.v1alpha1; + +import "proto/eth/ext/options.proto"; +import "proto/prysm/v1alpha1/beacon_core_types.proto"; + +option go_package = "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1;eth"; + +message PartialDataColumnSidecar { + bytes cells_present_bitmap = 1 [ + (ethereum.eth.ext.ssz_max) = "max_blob_commitments_bitmap.size", + (ethereum.eth.ext.cast_type) = + "github.com/prysmaticlabs/go-bitfield.Bitlist" + ]; + repeated bytes partial_column = 2 [ + (ethereum.eth.ext.ssz_size) = "?,bytes_per_cell.size", + (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size" + ]; + repeated bytes kzg_proofs = 3 [ + (ethereum.eth.ext.ssz_size) = "?,48", + (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size" + ]; +} diff --git a/proto/ssz_proto_library.bzl b/proto/ssz_proto_library.bzl index 47033b5aa2e2..209781d783df 100644 --- a/proto/ssz_proto_library.bzl +++ b/proto/ssz_proto_library.bzl @@ -25,6 +25,7 @@ mainnet = { "extra_data.size": "32", "max_blobs_per_block.size": "6", "max_blob_commitments.size": "4096", + "max_blob_commitments_bitmap.size": "512", # MAX_BLOB_COMMITMENTS_PER_BLOCK / 8 "max_cell_proofs_length.size": "33554432", # FIELD_ELEMENTS_PER_EXT_BLOB * MAX_BLOB_COMMITMENTS_PER_BLOCK "kzg_commitment_inclusion_proof_depth.size": "17", "max_withdrawal_requests_per_payload.size": "16", @@ -64,6 +65,7 @@ minimal = { "extra_data.size": "32", "max_blobs_per_block.size": "6", "max_blob_commitments.size": "4096", + "max_blob_commitments_bitmap.size": "512", # MAX_BLOB_COMMITMENTS_PER_BLOCK / 8 "max_cell_proofs_length.size": "33554432", # FIELD_ELEMENTS_PER_EXT_BLOB * MAX_BLOB_COMMITMENTS_PER_BLOCK "kzg_commitment_inclusion_proof_depth.size": "17", "max_withdrawal_requests_per_payload.size": "16", diff --git a/proto/testing/test.pb.go b/proto/testing/test.pb.go index b5891dc142d4..7bb1f9c379c7 100755 --- a/proto/testing/test.pb.go +++ b/proto/testing/test.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.36.3 // protoc v3.21.7 // source: proto/testing/test.proto @@ -73,21 +73,18 @@ func (Person_PhoneType) EnumDescriptor() ([]byte, []int) { } type TestMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Foo string `protobuf:"bytes,1,opt,name=foo,proto3" json:"foo,omitempty"` + Bar string `protobuf:"bytes,2,opt,name=bar,proto3" json:"bar,omitempty" spec-name:"foo" ssz-size:"32"` unknownFields protoimpl.UnknownFields - - Foo string `protobuf:"bytes,1,opt,name=foo,proto3" json:"foo,omitempty"` - Bar string `protobuf:"bytes,2,opt,name=bar,proto3" json:"bar,omitempty" spec-name:"foo" ssz-size:"32"` + sizeCache protoimpl.SizeCache } func (x *TestMessage) Reset() { *x = TestMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_testing_test_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_proto_testing_test_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *TestMessage) String() string { @@ -98,7 +95,7 @@ func (*TestMessage) ProtoMessage() {} func (x *TestMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_testing_test_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -128,21 +125,18 @@ func (x *TestMessage) GetBar() string { } type TestNestedMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Fuzz string `protobuf:"bytes,1,opt,name=fuzz,proto3" json:"fuzz,omitempty"` + Msg *TestMessage `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` unknownFields protoimpl.UnknownFields - - Fuzz string `protobuf:"bytes,1,opt,name=fuzz,proto3" json:"fuzz,omitempty"` - Msg *TestMessage `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + sizeCache protoimpl.SizeCache } func (x *TestNestedMessage) Reset() { *x = TestNestedMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_testing_test_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_proto_testing_test_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *TestNestedMessage) String() string { @@ -153,7 +147,7 @@ func (*TestNestedMessage) ProtoMessage() {} func (x *TestNestedMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_testing_test_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -183,21 +177,18 @@ func (x *TestNestedMessage) GetMsg() *TestMessage { } type Puzzle struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Challenge string `protobuf:"bytes,1,opt,name=challenge,proto3" json:"challenge,omitempty"` + Answer string `protobuf:"bytes,2,opt,name=answer,proto3" json:"answer,omitempty"` unknownFields protoimpl.UnknownFields - - Challenge string `protobuf:"bytes,1,opt,name=challenge,proto3" json:"challenge,omitempty"` - Answer string `protobuf:"bytes,2,opt,name=answer,proto3" json:"answer,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Puzzle) Reset() { *x = Puzzle{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_testing_test_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_proto_testing_test_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Puzzle) String() string { @@ -208,7 +199,7 @@ func (*Puzzle) ProtoMessage() {} func (x *Puzzle) ProtoReflect() protoreflect.Message { mi := &file_proto_testing_test_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -238,24 +229,21 @@ func (x *Puzzle) GetAnswer() string { } type Person struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Id int32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` + Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + Phones []*Person_PhoneNumber `protobuf:"bytes,4,rep,name=phones,proto3" json:"phones,omitempty"` + LastUpdated *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=last_updated,json=lastUpdated,proto3" json:"last_updated,omitempty"` unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Id int32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` - Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` - Phones []*Person_PhoneNumber `protobuf:"bytes,4,rep,name=phones,proto3" json:"phones,omitempty"` - LastUpdated *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=last_updated,json=lastUpdated,proto3" json:"last_updated,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Person) Reset() { *x = Person{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_testing_test_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_proto_testing_test_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Person) String() string { @@ -266,7 +254,7 @@ func (*Person) ProtoMessage() {} func (x *Person) ProtoReflect() protoreflect.Message { mi := &file_proto_testing_test_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -317,20 +305,17 @@ func (x *Person) GetLastUpdated() *timestamppb.Timestamp { } type AddressBook struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + People []*Person `protobuf:"bytes,1,rep,name=people,proto3" json:"people,omitempty"` unknownFields protoimpl.UnknownFields - - People []*Person `protobuf:"bytes,1,rep,name=people,proto3" json:"people,omitempty"` + sizeCache protoimpl.SizeCache } func (x *AddressBook) Reset() { *x = AddressBook{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_testing_test_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_proto_testing_test_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AddressBook) String() string { @@ -341,7 +326,7 @@ func (*AddressBook) ProtoMessage() {} func (x *AddressBook) ProtoReflect() protoreflect.Message { mi := &file_proto_testing_test_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -364,21 +349,18 @@ func (x *AddressBook) GetPeople() []*Person { } type TestSimpleMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Foo []byte `protobuf:"bytes,1,opt,name=foo,proto3" json:"foo,omitempty"` + Bar uint64 `protobuf:"varint,2,opt,name=bar,proto3" json:"bar,omitempty"` unknownFields protoimpl.UnknownFields - - Foo []byte `protobuf:"bytes,1,opt,name=foo,proto3" json:"foo,omitempty"` - Bar uint64 `protobuf:"varint,2,opt,name=bar,proto3" json:"bar,omitempty"` + sizeCache protoimpl.SizeCache } func (x *TestSimpleMessage) Reset() { *x = TestSimpleMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_testing_test_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_proto_testing_test_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *TestSimpleMessage) String() string { @@ -389,7 +371,7 @@ func (*TestSimpleMessage) ProtoMessage() {} func (x *TestSimpleMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_testing_test_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -419,21 +401,18 @@ func (x *TestSimpleMessage) GetBar() uint64 { } type Person_PhoneNumber struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Number string `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty"` + Type Person_PhoneType `protobuf:"varint,2,opt,name=type,proto3,enum=testing.Person_PhoneType" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - Number string `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty"` - Type Person_PhoneType `protobuf:"varint,2,opt,name=type,proto3,enum=testing.Person_PhoneType" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Person_PhoneNumber) Reset() { *x = Person_PhoneNumber{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_testing_test_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_proto_testing_test_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Person_PhoneNumber) String() string { @@ -444,7 +423,7 @@ func (*Person_PhoneNumber) ProtoMessage() {} func (x *Person_PhoneNumber) ProtoReflect() protoreflect.Message { mi := &file_proto_testing_test_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -574,7 +553,7 @@ func file_proto_testing_test_proto_rawDescGZIP() []byte { var file_proto_testing_test_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_proto_testing_test_proto_msgTypes = make([]protoimpl.MessageInfo, 7) -var file_proto_testing_test_proto_goTypes = []interface{}{ +var file_proto_testing_test_proto_goTypes = []any{ (Person_PhoneType)(0), // 0: testing.Person.PhoneType (*TestMessage)(nil), // 1: testing.TestMessage (*TestNestedMessage)(nil), // 2: testing.TestNestedMessage @@ -606,92 +585,6 @@ func file_proto_testing_test_proto_init() { if File_proto_testing_test_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_proto_testing_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TestMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_testing_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TestNestedMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_testing_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Puzzle); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_testing_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Person); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_testing_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddressBook); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_testing_test_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TestSimpleMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_testing_test_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Person_PhoneNumber); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ From a2a1470960a69f8d06b1290b200897d10a636b7f Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 8 Oct 2025 12:08:37 -0700 Subject: [PATCH 03/13] logrusadapter for slog --- internal/logrusadapter/BUILD.bazel | 18 +++ internal/logrusadapter/adapter.go | 71 +++++++++++ internal/logrusadapter/adapter_test.go | 170 +++++++++++++++++++++++++ 3 files changed, 259 insertions(+) create mode 100644 internal/logrusadapter/BUILD.bazel create mode 100644 internal/logrusadapter/adapter.go create mode 100644 internal/logrusadapter/adapter_test.go diff --git a/internal/logrusadapter/BUILD.bazel b/internal/logrusadapter/BUILD.bazel new file mode 100644 index 000000000000..cda41fdd7439 --- /dev/null +++ b/internal/logrusadapter/BUILD.bazel @@ -0,0 +1,18 @@ +load("@prysm//tools/go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["adapter.go"], + importpath = "github.com/OffchainLabs/prysm/v6/internal/logrusadapter", + visibility = ["//:__subpackages__"], + deps = ["@com_github_sirupsen_logrus//:go_default_library"], +) + +go_test( + name = "go_default_test", + srcs = ["adapter_test.go"], + deps = [ + ":go_default_library", + "@com_github_sirupsen_logrus//:go_default_library", + ], +) diff --git a/internal/logrusadapter/adapter.go b/internal/logrusadapter/adapter.go new file mode 100644 index 000000000000..e56d3390253c --- /dev/null +++ b/internal/logrusadapter/adapter.go @@ -0,0 +1,71 @@ +package logrusadapter + +import ( + "context" + "log/slog" + + "github.com/sirupsen/logrus" +) + +// Handler wraps a logrus.Logger to satisfy slog.Handler. +type Handler struct { + Logger *logrus.Logger +} + +// Enabled implements slog.Handler. +func (h Handler) Enabled(_ context.Context, level slog.Level) bool { + switch level { + case slog.LevelDebug: + return h.Logger.Level >= logrus.DebugLevel + case slog.LevelInfo: + return h.Logger.Level >= logrus.InfoLevel + case slog.LevelWarn: + return h.Logger.Level >= logrus.WarnLevel + case slog.LevelError: + return h.Logger.Level >= logrus.ErrorLevel + default: + return true + } +} + +// Handle converts slog.Record into a logrus.Entry. +func (h Handler) Handle(_ context.Context, r slog.Record) error { + entry := h.Logger.WithTime(r.Time) + + r.Attrs(func(a slog.Attr) bool { + entry = entry.WithField(a.Key, a.Value.Any()) + return true + }) + + switch r.Level { + case slog.LevelDebug: + entry.Debug(r.Message) + case slog.LevelInfo: + entry.Info(r.Message) + case slog.LevelWarn: + entry.Warn(r.Message) + case slog.LevelError: + entry.Error(r.Message) + default: + entry.Print(r.Message) + } + + return nil +} + +// WithAttrs implements slog.Handler. +func (h Handler) WithAttrs(attrs []slog.Attr) slog.Handler { + logger := h.Logger.WithFields(toFields(attrs)) + return Handler{Logger: logger.Logger} +} + +// WithGroup implements slog.Handler (no-op for simplicity). +func (h Handler) WithGroup(_ string) slog.Handler { return h } + +func toFields(attrs []slog.Attr) logrus.Fields { + fields := logrus.Fields{} + for _, a := range attrs { + fields[a.Key] = a.Value.Any() + } + return fields +} diff --git a/internal/logrusadapter/adapter_test.go b/internal/logrusadapter/adapter_test.go new file mode 100644 index 000000000000..0f6a19458505 --- /dev/null +++ b/internal/logrusadapter/adapter_test.go @@ -0,0 +1,170 @@ +package logrusadapter_test + +import ( + "bytes" + "context" + "log/slog" + "strings" + "testing" + + "github.com/OffchainLabs/prysm/v6/internal/logrusadapter" + "github.com/sirupsen/logrus" +) + +func TestLogrusAdapter(t *testing.T) { + var outBuf bytes.Buffer + l := logrus.Logger{ + Out: &outBuf, + Formatter: &logrus.TextFormatter{}, + Level: logrus.DebugLevel, + } + + slogger := slog.New(logrusadapter.Handler{Logger: &l}) + slogger.Error("test") + + if !strings.Contains(outBuf.String(), "test") { + t.Errorf("unexpected output: %s", outBuf.String()) + } +} + +func TestLevelMapping(t *testing.T) { + tests := []struct { + name string + slogLevel slog.Level + logrusLevel logrus.Level + message string + wantInLog string + }{ + { + name: "Debug level", + slogLevel: slog.LevelDebug, + logrusLevel: logrus.DebugLevel, + message: "debug message", + wantInLog: "level=debug", + }, + { + name: "Info level", + slogLevel: slog.LevelInfo, + logrusLevel: logrus.InfoLevel, + message: "info message", + wantInLog: "level=info", + }, + { + name: "Warn level", + slogLevel: slog.LevelWarn, + logrusLevel: logrus.WarnLevel, + message: "warn message", + wantInLog: "level=warning", + }, + { + name: "Error level", + slogLevel: slog.LevelError, + logrusLevel: logrus.ErrorLevel, + message: "error message", + wantInLog: "level=error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var outBuf bytes.Buffer + l := logrus.Logger{ + Out: &outBuf, + Formatter: &logrus.TextFormatter{}, + Level: tt.logrusLevel, + } + + slogger := slog.New(logrusadapter.Handler{Logger: &l}) + + // Log at the specified level + switch tt.slogLevel { + case slog.LevelDebug: + slogger.Debug(tt.message) + case slog.LevelInfo: + slogger.Info(tt.message) + case slog.LevelWarn: + slogger.Warn(tt.message) + case slog.LevelError: + slogger.Error(tt.message) + } + + output := outBuf.String() + if !strings.Contains(output, tt.message) { + t.Errorf("expected message %q not found in output: %s", tt.message, output) + } + if !strings.Contains(output, tt.wantInLog) { + t.Errorf("expected level indicator %q not found in output: %s", tt.wantInLog, output) + } + }) + } +} + +func TestEnabledLevels(t *testing.T) { + tests := []struct { + name string + logrusLevel logrus.Level + slogLevel slog.Level + shouldBeEnabled bool + }{ + // When logrus is at DebugLevel, all levels should be enabled + {name: "Debug logger, debug level", logrusLevel: logrus.DebugLevel, slogLevel: slog.LevelDebug, shouldBeEnabled: true}, + {name: "Debug logger, info level", logrusLevel: logrus.DebugLevel, slogLevel: slog.LevelInfo, shouldBeEnabled: true}, + {name: "Debug logger, warn level", logrusLevel: logrus.DebugLevel, slogLevel: slog.LevelWarn, shouldBeEnabled: true}, + {name: "Debug logger, error level", logrusLevel: logrus.DebugLevel, slogLevel: slog.LevelError, shouldBeEnabled: true}, + + // When logrus is at InfoLevel, debug should be disabled + {name: "Info logger, debug level", logrusLevel: logrus.InfoLevel, slogLevel: slog.LevelDebug, shouldBeEnabled: false}, + {name: "Info logger, info level", logrusLevel: logrus.InfoLevel, slogLevel: slog.LevelInfo, shouldBeEnabled: true}, + {name: "Info logger, warn level", logrusLevel: logrus.InfoLevel, slogLevel: slog.LevelWarn, shouldBeEnabled: true}, + {name: "Info logger, error level", logrusLevel: logrus.InfoLevel, slogLevel: slog.LevelError, shouldBeEnabled: true}, + + // When logrus is at WarnLevel, debug and info should be disabled + {name: "Warn logger, debug level", logrusLevel: logrus.WarnLevel, slogLevel: slog.LevelDebug, shouldBeEnabled: false}, + {name: "Warn logger, info level", logrusLevel: logrus.WarnLevel, slogLevel: slog.LevelInfo, shouldBeEnabled: false}, + {name: "Warn logger, warn level", logrusLevel: logrus.WarnLevel, slogLevel: slog.LevelWarn, shouldBeEnabled: true}, + {name: "Warn logger, error level", logrusLevel: logrus.WarnLevel, slogLevel: slog.LevelError, shouldBeEnabled: true}, + + // When logrus is at ErrorLevel, only error should be enabled + {name: "Error logger, debug level", logrusLevel: logrus.ErrorLevel, slogLevel: slog.LevelDebug, shouldBeEnabled: false}, + {name: "Error logger, info level", logrusLevel: logrus.ErrorLevel, slogLevel: slog.LevelInfo, shouldBeEnabled: false}, + {name: "Error logger, warn level", logrusLevel: logrus.ErrorLevel, slogLevel: slog.LevelWarn, shouldBeEnabled: false}, + {name: "Error logger, error level", logrusLevel: logrus.ErrorLevel, slogLevel: slog.LevelError, shouldBeEnabled: true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var outBuf bytes.Buffer + l := logrus.Logger{ + Out: &outBuf, + Formatter: &logrus.TextFormatter{}, + Level: tt.logrusLevel, + } + + handler := logrusadapter.Handler{Logger: &l} + enabled := handler.Enabled(context.Background(), tt.slogLevel) + + if enabled != tt.shouldBeEnabled { + t.Errorf("Enabled() = %v, want %v for logrus level %v and slog level %v", + enabled, tt.shouldBeEnabled, tt.logrusLevel, tt.slogLevel) + } + + // Verify that disabled logs don't actually produce output + slogger := slog.New(handler) + switch tt.slogLevel { + case slog.LevelDebug: + slogger.Debug("test message") + case slog.LevelInfo: + slogger.Info("test message") + case slog.LevelWarn: + slogger.Warn("test message") + case slog.LevelError: + slogger.Error("test message") + } + + hasOutput := strings.Contains(outBuf.String(), "test message") + if hasOutput != tt.shouldBeEnabled { + t.Errorf("Log output presence = %v, want %v", hasOutput, tt.shouldBeEnabled) + } + }) + } +} From 9f0effbc7e1bcd4a44e517bb20a6d0e851214c70 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 1 Oct 2025 13:24:37 -0700 Subject: [PATCH 04/13] beacon-chain/p2p/partial: implement cell level dissemination --- beacon-chain/p2p/partial/BUILD.bazel | 35 ++ beacon-chain/p2p/partial/column.go | 248 ++++++++++++++ beacon-chain/p2p/partial/invariants_test.go | 120 +++++++ beacon-chain/p2p/partial/partial.go | 338 ++++++++++++++++++++ 4 files changed, 741 insertions(+) create mode 100644 beacon-chain/p2p/partial/BUILD.bazel create mode 100644 beacon-chain/p2p/partial/column.go create mode 100644 beacon-chain/p2p/partial/invariants_test.go create mode 100644 beacon-chain/p2p/partial/partial.go diff --git a/beacon-chain/p2p/partial/BUILD.bazel b/beacon-chain/p2p/partial/BUILD.bazel new file mode 100644 index 000000000000..49f9d41eedcb --- /dev/null +++ b/beacon-chain/p2p/partial/BUILD.bazel @@ -0,0 +1,35 @@ +load("@prysm//tools/go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "column.go", + "partial.go", + ], + importpath = "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial", + visibility = ["//visibility:public"], + deps = [ + "//beacon-chain/blockchain/kzg:go_default_library", + "//config/params:go_default_library", + "//consensus-types/blocks:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", + "@com_github_libp2p_go_libp2p//core/peer:go_default_library", + "@com_github_libp2p_go_libp2p_pubsub//:go_default_library", + "@com_github_libp2p_go_libp2p_pubsub//partialmessages:go_default_library", + "@com_github_libp2p_go_libp2p_pubsub//partialmessages/bitmap:go_default_library", + "@com_github_libp2p_go_libp2p_pubsub//pb:go_default_library", + "@com_github_prysmaticlabs_go_bitfield//:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["invariants_test.go"], + embed = [":go_default_library"], + deps = [ + "//beacon-chain/blockchain/kzg:go_default_library", + "@com_github_libp2p_go_libp2p//core/peer:go_default_library", + "@com_github_libp2p_go_libp2p_pubsub//partialmessages:go_default_library", + "@com_github_prysmaticlabs_go_bitfield//:go_default_library", + ], +) diff --git a/beacon-chain/p2p/partial/column.go b/beacon-chain/p2p/partial/column.go new file mode 100644 index 000000000000..7d7707422611 --- /dev/null +++ b/beacon-chain/p2p/partial/column.go @@ -0,0 +1,248 @@ +package partial + +import ( + "errors" + "log/slog" + + "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/kzg" + "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" + ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" + "github.com/libp2p/go-libp2p-pubsub/partialmessages" + "github.com/prysmaticlabs/go-bitfield" +) + +type CompleteColumn struct { + SignedBeaconBlockHeader *ethpb.SignedBeaconBlockHeader + KzgInclusionProof [][]byte + + BlockRoot []byte + Commitments []kzg.Commitment + Cells []kzg.Cell + Proofs []kzg.Proof +} + +type PartialColumn struct { + signedBeaconBlockHeader *ethpb.SignedBeaconBlockHeader + kzgInclusionProof [][]byte + index uint64 + + blockRoot []byte + parts bitfield.Bitlist + + commitments []kzg.Commitment + cells []kzg.Cell + proofs []kzg.Proof + + // Parts we've received before we have any commitments to validate against. + // Happens when a peer eager pushes to us. + // TODO implement. For now, not bothering to handle the eager pushes. + // quarantine []*ethpb.PartialDataColumnSidecar +} + +// const quarantineSize = 3 + +func NewPartialColumn( + signedBlockHeader *ethpb.SignedBeaconBlockHeader, + kzgInclusionProof [][]byte, + blockRoot []byte, + allCommitments []kzg.Commitment, + includedCellsBitmap bitfield.Bitlist, + columnCells []kzg.Cell, + columnProofs []kzg.Proof, +) PartialColumn { + // TODO: check + // root, err := signedBlockHeader.Header.HashTreeRoot() + cells := make([]kzg.Cell, len(allCommitments)) + proofs := make([]kzg.Proof, len(allCommitments)) + + var j int + for i := range allCommitments { + if !includedCellsBitmap.BitAt(uint64(i)) { + continue + } + + cells[i] = columnCells[j] + proofs[i] = columnProofs[j] + j++ + } + + return PartialColumn{ + signedBeaconBlockHeader: signedBlockHeader, + kzgInclusionProof: kzgInclusionProof, + + blockRoot: blockRoot, + parts: includedCellsBitmap, + + commitments: allCommitments, + cells: cells, + proofs: proofs, + } +} + +func (p *PartialColumn) GroupID() []byte { + return p.blockRoot +} +func (p *PartialColumn) PartialMessageBytes(metadata partialmessages.PartsMetadata) ([]byte, error) { + peerHas := bitfield.Bitlist(metadata) + + var cellsToReturn int + for i := range peerHas.Len() { + if !peerHas.BitAt(i) && p.parts.BitAt(i) { + cellsToReturn++ + } + } + if cellsToReturn == 0 { + return nil, nil + } + + included := bitfield.NewBitlist(p.parts.Len()) + outMessage := ethpb.PartialDataColumnSidecar{ + CellsPresentBitmap: included, + PartialColumn: make([][]byte, 0, cellsToReturn), + KzgProofs: make([][]byte, 0, cellsToReturn), + } + for i := range peerHas.Len() { + if peerHas.BitAt(i) || !p.parts.BitAt(i) { + continue + } + included.SetBitAt(i, true) + outMessage.PartialColumn = append(outMessage.PartialColumn, p.cells[i][:]) + outMessage.KzgProofs = append(outMessage.KzgProofs, p.proofs[i][:]) + } + + marshalled, err := outMessage.MarshalSSZ() + if err != nil { + return nil, err + } + + return marshalled, nil +} + +func (p *PartialColumn) PartsMetadata() partialmessages.PartsMetadata { + return partialmessages.PartsMetadata(p.parts) +} + +// PartialColumnValidator will verify the cells and proofs against allCommitments. +// The cells+proofs present are specified by the included bitmap. +// len(cells) == included.OnesCount() && len(proofs) == included.OnesCount() +type PartialColumnValidator func(included bitfield.Bitlist, allCommitments []kzg.Commitment, cells, proofs [][]byte) bool + +// extend will extend this partial column with data from the specified peer. +// +// TODO: penalize peer if bad message +func (p *PartialColumn) extend(validator PartialColumnValidator, m []byte) (extended bool, _ error) { + var message ethpb.PartialDataColumnSidecar + err := message.UnmarshalSSZ(m) + if err != nil { + return false, err + } + + included := message.CellsPresentBitmap + + // Some basic sanity checks + includedCells := included.Count() + if uint64(len(message.KzgProofs)) != includedCells { + return false, errors.New("invalid message. Missing KZG proofs") + } + if uint64(len(message.PartialColumn)) != includedCells { + return false, errors.New("invalid message. Missing cells") + } + + partsLen := p.parts.Len() + if included.Len() != partsLen { + return false, errors.New("invalid message. Wrong bitmap length.") + } + + var j, k int + for i := range included.Len() { + if !included.BitAt(i) { + continue + } + + if p.parts.BitAt(i) { + // We already have this cell, remove it from the message. + // Saves the validator from validating data we already have + included.SetBitAt(i, false) + k++ + continue + } + message.PartialColumn[j] = message.PartialColumn[k] + message.KzgProofs[j] = message.KzgProofs[k] + j++ + k++ + } + message.CellsPresentBitmap = included + message.PartialColumn = message.PartialColumn[:k] + message.KzgProofs = message.KzgProofs[:k] + if len(message.KzgProofs) == 0 { + // No new cells + return false, nil + } + + onesCount := included.Count() + if !(uint64(len(message.PartialColumn)) == onesCount && uint64(len(message.KzgProofs)) == onesCount) { + return false, errors.New("application error: unexpected length of partial column or proofs") + } + if !validator( + included, + p.commitments, + message.PartialColumn, + message.KzgProofs, + ) { + return false, errors.New("invalid message. Invalid columns") + } + + j = 0 + for i := range included.Len() { + if !included.BitAt(uint64(i)) { + continue + } + if i > partsLen { + return false, errors.New("invalid message. includes more cells than there are commitments") + } + + p.parts.SetBitAt(i, true) + + copy(p.cells[i][:], message.PartialColumn[j]) + copy(p.proofs[i][:], message.KzgProofs[j]) + j++ + } + return true, nil +} + +func (p *PartialColumn) complete(logger *slog.Logger) (blocks.VerifiedRODataColumn, bool) { + if uint64(len(p.commitments)) != p.parts.Count() { + return blocks.VerifiedRODataColumn{}, false + } + dc := ethpb.DataColumnSidecar{ + Index: p.index, + SignedBlockHeader: p.signedBeaconBlockHeader, + + Column: make([][]byte, len(p.cells)), + KzgProofs: make([][]byte, len(p.proofs)), + KzgCommitments: make([][]byte, len(p.commitments)), + + KzgCommitmentsInclusionProof: p.kzgInclusionProof, + } + + if len(p.cells) != len(p.proofs) || len(p.cells) != len(p.commitments) { + logger.Error("completed invalid partial column") + return blocks.VerifiedRODataColumn{}, false + } + + for i := range p.cells { + dc.Column[i] = p.cells[i][:] + dc.KzgProofs[i] = p.proofs[i][:] + dc.KzgCommitments[i] = p.commitments[i][:] + } + + rodc, err := blocks.NewRODataColumn(&dc) + if err != nil { + // We shouldn't get an error, as we check the hash root when creating + // the partial column + logger.Error("failed to create RODataColumn", "err", err) + return blocks.VerifiedRODataColumn{}, false + } + + return blocks.NewVerifiedRODataColumn(rodc), true +} diff --git a/beacon-chain/p2p/partial/invariants_test.go b/beacon-chain/p2p/partial/invariants_test.go new file mode 100644 index 000000000000..de3d19be81f6 --- /dev/null +++ b/beacon-chain/p2p/partial/invariants_test.go @@ -0,0 +1,120 @@ +package partial + +import ( + "bytes" + "testing" + + "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/kzg" + "github.com/libp2p/go-libp2p-pubsub/partialmessages" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/prysmaticlabs/go-bitfield" +) + +type invariantChecker struct{} + +var _ partialmessages.InvariantChecker[*PartialColumn] = (*invariantChecker)(nil) + +func (i *invariantChecker) MergePartsMetadata(left, right partialmessages.PartsMetadata) partialmessages.PartsMetadata { + return partialmessages.MergeBitmap(left, right) +} + +func (i *invariantChecker) SplitIntoParts(in *PartialColumn) ([]*PartialColumn, error) { + var parts []*PartialColumn + for idx := range in.cells { + if !in.parts.BitAt(uint64(idx)) { + continue + } + msg := i.EmptyMessage() + msg.parts.SetBitAt(uint64(idx), true) + msg.commitments = in.commitments + msg.cells[idx] = in.cells[idx] + msg.proofs[idx] = in.proofs[idx] + parts = append(parts, msg) + } + return parts, nil +} + +func (i *invariantChecker) FullMessage() (*PartialColumn, error) { + blockRoot := []byte("test-block-root") + numCells := 128 + commitments := make([]kzg.Commitment, numCells) + cells := make([]kzg.Cell, numCells) + proofs := make([]kzg.Proof, numCells) + + bitmap := bitfield.NewBitlist(uint64(numCells)) + for idx := 0; idx < numCells; idx++ { + bitmap.SetBitAt(uint64(idx), true) + } + + pc := NewPartialColumn(nil, nil, blockRoot, commitments, bitmap, cells, proofs) + return &pc, nil +} + +func (i *invariantChecker) EmptyMessage() *PartialColumn { + blockRoot := []byte("test-block-root") + numCells := 128 + commitments := make([]kzg.Commitment, numCells) + cells := make([]kzg.Cell, numCells) + proofs := make([]kzg.Proof, numCells) + + bitmap := bitfield.NewBitlist(uint64(numCells)) + + pc := NewPartialColumn(nil, nil, blockRoot, commitments, bitmap, cells, proofs) + return &pc +} + +func (i *invariantChecker) ExtendFromBytes(a *PartialColumn, data []byte) (*PartialColumn, error) { + validator := func(included bitfield.Bitlist, allCommitments []kzg.Commitment, cells, proofs [][]byte) bool { + return true + } + _, err := a.extend(validator, data) + return a, err +} + +func (i *invariantChecker) ShouldRequest(a *PartialColumn, from peer.ID, partsMetadata []byte) bool { + peerHas := bitfield.Bitlist(partsMetadata) + for i := range peerHas.Len() { + if peerHas.BitAt(i) && !a.parts.BitAt(i) { + return true + } + } + return false +} + +func (i *invariantChecker) Equal(a, b *PartialColumn) bool { + if !bytes.Equal(a.blockRoot, b.blockRoot) { + return false + } + if !bytes.Equal(a.parts, b.parts) { + return false + } + if len(a.commitments) != len(b.commitments) { + return false + } + for i := range a.commitments { + if a.commitments[i] != b.commitments[i] { + return false + } + } + if len(a.cells) != len(b.cells) { + return false + } + for i := range a.cells { + if a.cells[i] != b.cells[i] { + return false + } + } + if len(a.proofs) != len(b.proofs) { + return false + } + for i := range a.proofs { + if a.proofs[i] != b.proofs[i] { + return false + } + } + return true +} + +func TestInvariants(t *testing.T) { + partialmessages.TestPartialMessageInvariants(t, &invariantChecker{}) +} diff --git a/beacon-chain/p2p/partial/partial.go b/beacon-chain/p2p/partial/partial.go new file mode 100644 index 000000000000..21e68a0e82a0 --- /dev/null +++ b/beacon-chain/p2p/partial/partial.go @@ -0,0 +1,338 @@ +package partial + +import ( + "bytes" + "errors" + "log/slog" + "time" + + "github.com/OffchainLabs/prysm/v6/config/params" + "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" + pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p-pubsub/partialmessages" + "github.com/libp2p/go-libp2p-pubsub/partialmessages/bitmap" + pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb" + "github.com/libp2p/go-libp2p/core/peer" +) + +// TODOs: +// different eager push strategies: +// - no eager push +// - full column eager push +// - With debouncing - some factor of RTT +// - eager push missing cells + +const TTLInSlots = 3 + +type PartialColumnBroadcaster struct { + logger *slog.Logger + + ps *pubsub.PubSub + stop chan struct{} + + // map topic -> Validator + validators map[string]PartialColumnValidator + + // map topic -> handler + handlers map[string]SubHandler + + // map topic -> *pubsub.Topic + topics map[string]*pubsub.Topic + + // map topic -> map[groupID]PartialColumn + partialMsgStore map[string]map[string]*PartialColumn + + groupTTL map[string]int8 + + incomingReq chan request +} + +type requestKind uint8 + +const ( + requestKindPublish requestKind = iota + requestKindSubscribe + requestKindUnsubscribe + requestKindHandleIncomingRPC +) + +type request struct { + kind requestKind + response chan error + sub subscribe + unsub unsubscribe + publish publish + incomingRPC rpcWithFrom +} + +type publish struct { + topic string + c PartialColumn +} + +type subscribe struct { + t *pubsub.Topic + validator PartialColumnValidator + handler SubHandler +} + +type unsubscribe struct { + topic string +} + +type rpcWithFrom struct { + *pubsub_pb.PartialMessagesExtension + from peer.ID +} + +func NewBroadcaster(logger *slog.Logger) *PartialColumnBroadcaster { + return &PartialColumnBroadcaster{ + validators: make(map[string]PartialColumnValidator), + handlers: make(map[string]SubHandler), + topics: make(map[string]*pubsub.Topic), + partialMsgStore: make(map[string]map[string]*PartialColumn), + groupTTL: make(map[string]int8), + // GossipSub sends the messages to this channel. The buffer should be + // big enough to avoid dropping messages. We don't want to block the gossipsub event loop for this. + incomingReq: make(chan request, 128*8), + logger: logger, + } +} + +// AppendPubSubOpts adds the necessary pubsub options to enable partial messages. +func (p *PartialColumnBroadcaster) AppendPubSubOpts(opts []pubsub.Option) []pubsub.Option { + opts = append(opts, + pubsub.WithPartialMessagesExtension(&partialmessages.PartialMessageExtension{ + Logger: p.logger, + MergePartsMetadata: func(topic string, left, right partialmessages.PartsMetadata) partialmessages.PartsMetadata { + return partialmessages.MergeBitmap(left, right) + }, + ValidateRPC: func(from peer.ID, rpc *pubsub_pb.PartialMessagesExtension) error { + // TODO. Add some basic and fast sanity checks + return nil + }, + OnIncomingRPC: func(from peer.ID, rpc *pubsub_pb.PartialMessagesExtension) error { + select { + case p.incomingReq <- request{ + kind: requestKindHandleIncomingRPC, + incomingRPC: rpcWithFrom{rpc, from}, + }: + default: + p.logger.Warn("Dropping incoming partial RPC") + } + return nil + }, + }), + func(ps *pubsub.PubSub) error { + p.ps = ps + return nil + }, + ) + return opts +} + +// Start starts the event loop of the PartialColumnBroadcaster. Should be called +// within a goroutine (go p.Start()) +func (p *PartialColumnBroadcaster) Start() { + p.stop = make(chan struct{}) + p.loop() +} + +func (p *PartialColumnBroadcaster) loop() { + cleanup := time.NewTicker(time.Second * time.Duration(params.BeaconConfig().SecondsPerSlot)) + defer cleanup.Stop() + for { + select { + case <-p.stop: + return + case <-cleanup.C: + for groupID, ttl := range p.groupTTL { + if ttl > 0 { + p.groupTTL[groupID] = ttl - 1 + continue + } + + delete(p.groupTTL, groupID) + for topic, msgStore := range p.partialMsgStore { + delete(msgStore, groupID) + if len(msgStore) == 0 { + delete(p.partialMsgStore, topic) + } + } + } + case req := <-p.incomingReq: + switch req.kind { + case requestKindPublish: + req.response <- p.publish(req.publish.topic, req.publish.c) + case requestKindSubscribe: + req.response <- p.subscribe(req.sub.t, req.sub.validator, req.sub.handler) + case requestKindUnsubscribe: + req.response <- p.unsubscribe(req.unsub.topic) + case requestKindHandleIncomingRPC: + err := p.handleIncomingRPC(req.incomingRPC) + if err != nil { + p.logger.Error("Failed to handle incoming RPC", "err", err) + } + default: + p.logger.Error("Unknown request kind", "kind", req.kind) + } + } + } +} + +func (p *PartialColumnBroadcaster) handleIncomingRPC(rpcWithFrom rpcWithFrom) error { + if p.ps == nil { + return errors.New("pubsub not initialized") + } + + topicID := rpcWithFrom.GetTopicID() + groupID := rpcWithFrom.GroupID + logger := p.logger.With("from", rpcWithFrom.from, "topic", topicID, "group", groupID) + + topicStore, ok := p.partialMsgStore[topicID] + if !ok { + topicStore = make(map[string]*PartialColumn) + p.partialMsgStore[topicID] = topicStore + } + msg, ok := topicStore[string(groupID)] + if !ok { + // TODO: handle eager pushes + return nil + } + validator, validatorOK := p.validators[topicID] + handler, handlerOK := p.handlers[topicID] + + if !validatorOK { + return errors.New("validator not found") + } + if !handlerOK { + return errors.New("handler not found") + } + + var shouldRepublish bool + var publishOpts partialmessages.PublishOptions + if len(rpcWithFrom.PartialMessage) > 0 { + extended, err := msg.extend(validator, rpcWithFrom.PartialMessage) + if err != nil { + // TODO penalize peer. + logger.Error("failed to extend partial column. (TODO penalize peer)", "err", err) + } else if extended { + shouldRepublish = true + + // TODO: we could use the heuristic here that if this data was + // useful to us, it's likely useful to our peers and we should + // republish + + if col, ok := msg.complete(logger); ok { + logger.Info("Completed partial column", "topic", topicID, "group", groupID) + handler(topicID, col) + } else { + logger.Info("Extended partial column", "topic", topicID, "group", groupID) + } + } + } + + peerHas := bitmap.Bitmap(rpcWithFrom.PartsMetadata) + if !shouldRepublish && len(peerHas) > 0 && !bytes.Equal(peerHas, msg.PartsMetadata()) { + // Either we have something they don't or vice-versa + shouldRepublish = true + // Don't bother iterating over all mesh peers, we are just messaging one. + publishOpts.PublishToPeers = append(publishOpts.PublishToPeers, rpcWithFrom.from) + logger.Debug("republishing due to parts metadata difference") + } + + if shouldRepublish { + err := p.ps.PublishPartialMessage(topicID, msg, publishOpts) + if err != nil { + return err + } + } + return nil +} + +func (p *PartialColumnBroadcaster) Stop() { + if p.stop != nil { + close(p.stop) + p.stop = nil + } +} + +// Publish publishes the partial column. +func (p *PartialColumnBroadcaster) Publish(topic string, c PartialColumn) error { + if p.ps == nil { + return errors.New("pubsub not initialized") + } + respCh := make(chan error) + p.incomingReq <- request{ + kind: requestKindPublish, + response: respCh, + publish: publish{ + topic: topic, + c: c, + }, + } + return <-respCh +} + +func (p *PartialColumnBroadcaster) publish(topic string, c PartialColumn) error { + topicStore, ok := p.partialMsgStore[topic] + if !ok { + topicStore = make(map[string]*PartialColumn) + p.partialMsgStore[topic] = topicStore + } + topicStore[string(c.GroupID())] = &c + p.groupTTL[string(c.GroupID())] = TTLInSlots + + return p.ps.PublishPartialMessage(topic, &c, partialmessages.PublishOptions{}) +} + +type SubHandler func(topic string, col blocks.VerifiedRODataColumn) + +func (p *PartialColumnBroadcaster) Subscribe(t *pubsub.Topic, validator PartialColumnValidator, handler SubHandler) error { + respCh := make(chan error) + p.incomingReq <- request{ + kind: requestKindSubscribe, + sub: subscribe{ + t: t, + validator: validator, + handler: handler, + }, + response: respCh, + } + return <-respCh +} +func (p *PartialColumnBroadcaster) subscribe(t *pubsub.Topic, validator PartialColumnValidator, handler SubHandler) error { + topic := t.String() + if _, ok := p.topics[topic]; ok { + return errors.New("already subscribed") + } + + p.topics[topic] = t + p.validators[topic] = validator + p.handlers[topic] = handler + return nil +} + +func (p *PartialColumnBroadcaster) Unsubscribe(topic string) error { + respCh := make(chan error) + p.incomingReq <- request{ + kind: requestKindUnsubscribe, + unsub: unsubscribe{ + topic: topic, + }, + response: respCh, + } + return <-respCh +} +func (p *PartialColumnBroadcaster) unsubscribe(topic string) error { + t, ok := p.topics[topic] + if !ok { + return errors.New("topic not found") + } + delete(p.topics, topic) + delete(p.partialMsgStore, topic) + delete(p.validators, topic) + delete(p.handlers, topic) + + return t.Close() +} From 315d7dad229b2d02593284b739ccfab6b52567d2 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 1 Oct 2025 13:24:37 -0700 Subject: [PATCH 05/13] beacon-chain/core/peerdas: add support for building partial columns --- beacon-chain/core/peerdas/BUILD.bazel | 2 + beacon-chain/core/peerdas/reconstruction.go | 22 +++--- .../core/peerdas/reconstruction_test.go | 9 ++- beacon-chain/core/peerdas/validator.go | 69 ++++++++++++++++--- 4 files changed, 81 insertions(+), 21 deletions(-) diff --git a/beacon-chain/core/peerdas/BUILD.bazel b/beacon-chain/core/peerdas/BUILD.bazel index 72fcbbae9e67..9fb237b87092 100644 --- a/beacon-chain/core/peerdas/BUILD.bazel +++ b/beacon-chain/core/peerdas/BUILD.bazel @@ -15,6 +15,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//beacon-chain/blockchain/kzg:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", "//beacon-chain/state:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", @@ -33,6 +34,7 @@ go_library( "@com_github_pkg_errors//:go_default_library", "@com_github_prometheus_client_golang//prometheus:go_default_library", "@com_github_prometheus_client_golang//prometheus/promauto:go_default_library", + "@com_github_prysmaticlabs_go_bitfield//:go_default_library", "@org_golang_x_sync//errgroup:go_default_library", ], ) diff --git a/beacon-chain/core/peerdas/reconstruction.go b/beacon-chain/core/peerdas/reconstruction.go index b27247bc4ca4..7d4dfaf7a4fc 100644 --- a/beacon-chain/core/peerdas/reconstruction.go +++ b/beacon-chain/core/peerdas/reconstruction.go @@ -10,6 +10,7 @@ import ( pb "github.com/OffchainLabs/prysm/v6/proto/engine/v1" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "github.com/pkg/errors" + "github.com/prysmaticlabs/go-bitfield" "golang.org/x/sync/errgroup" ) @@ -237,35 +238,38 @@ func ComputeCellsAndProofsFromFlat(blobs [][]byte, cellProofs [][]byte) ([]kzg.C } // ComputeCellsAndProofs computes the cells and proofs from blobs and cell proofs. -func ComputeCellsAndProofsFromStructured(blobsAndProofs []*pb.BlobAndProofV2) ([]kzg.CellsAndProofs, error) { +func ComputeCellsAndProofsFromStructured(commitmentCount uint64, blobsAndProofs []*pb.BlobAndProofV2) (included bitfield.Bitlist, _ []kzg.CellsAndProofs, _ error) { numberOfColumns := params.BeaconConfig().NumberOfColumns cellsAndProofs := make([]kzg.CellsAndProofs, 0, len(blobsAndProofs)) - for _, blobAndProof := range blobsAndProofs { + included = bitfield.NewBitlist(commitmentCount) + + for i, blobAndProof := range blobsAndProofs { if blobAndProof == nil { - return nil, ErrNilBlobAndProof + continue } + included.SetBitAt(uint64(i), true) var kzgBlob kzg.Blob if copy(kzgBlob[:], blobAndProof.Blob) != len(kzgBlob) { - return nil, errors.New("wrong blob size - should never happen") + return nil, nil, errors.New("wrong blob size - should never happen") } // Compute the extended cells from the (non-extended) blob. cells, err := kzg.ComputeCells(&kzgBlob) if err != nil { - return nil, errors.Wrap(err, "compute cells") + return nil, nil, errors.Wrap(err, "compute cells") } - kzgProofs := make([]kzg.Proof, 0, numberOfColumns*kzg.BytesPerProof) + kzgProofs := make([]kzg.Proof, 0, numberOfColumns) for _, kzgProofBytes := range blobAndProof.KzgProofs { if len(kzgProofBytes) != kzg.BytesPerProof { - return nil, errors.New("wrong KZG proof size - should never happen") + return nil, nil, errors.New("wrong KZG proof size - should never happen") } var kzgProof kzg.Proof if copy(kzgProof[:], kzgProofBytes) != len(kzgProof) { - return nil, errors.New("wrong copied KZG proof size - should never happen") + return nil, nil, errors.New("wrong copied KZG proof size - should never happen") } kzgProofs = append(kzgProofs, kzgProof) @@ -275,7 +279,7 @@ func ComputeCellsAndProofsFromStructured(blobsAndProofs []*pb.BlobAndProofV2) ([ cellsAndProofs = append(cellsAndProofs, cellsProofs) } - return cellsAndProofs, nil + return included, cellsAndProofs, nil } // blobSidecarsFromDataColumnSidecars converts verified data column sidecars to verified blob sidecars. diff --git a/beacon-chain/core/peerdas/reconstruction_test.go b/beacon-chain/core/peerdas/reconstruction_test.go index 80108fd4a9dd..dce5dfb525bc 100644 --- a/beacon-chain/core/peerdas/reconstruction_test.go +++ b/beacon-chain/core/peerdas/reconstruction_test.go @@ -380,8 +380,9 @@ func TestComputeCellsAndProofsFromFlat(t *testing.T) { func TestComputeCellsAndProofsFromStructured(t *testing.T) { t.Run("nil blob and proof", func(t *testing.T) { - _, err := peerdas.ComputeCellsAndProofsFromStructured([]*pb.BlobAndProofV2{nil}) - require.ErrorIs(t, err, peerdas.ErrNilBlobAndProof) + included, _, err := peerdas.ComputeCellsAndProofsFromStructured(0, []*pb.BlobAndProofV2{nil}) + require.NoError(t, err) + require.Equal(t, uint64(0), included.Count()) }) t.Run("nominal", func(t *testing.T) { @@ -432,7 +433,8 @@ func TestComputeCellsAndProofsFromStructured(t *testing.T) { require.NoError(t, err) // Test ComputeCellsAndProofs - actualCellsAndProofs, err := peerdas.ComputeCellsAndProofsFromStructured(blobsAndProofs) + included, actualCellsAndProofs, err := peerdas.ComputeCellsAndProofsFromStructured(uint64(len(blobsAndProofs)), blobsAndProofs) + require.Equal(t, included.Count(), uint64(len(actualCellsAndProofs))) require.NoError(t, err) require.Equal(t, blobCount, len(actualCellsAndProofs)) @@ -440,6 +442,7 @@ func TestComputeCellsAndProofsFromStructured(t *testing.T) { for i := range blobCount { require.Equal(t, len(expectedCellsAndProofs[i].Cells), len(actualCellsAndProofs[i].Cells)) require.Equal(t, len(expectedCellsAndProofs[i].Proofs), len(actualCellsAndProofs[i].Proofs)) + require.Equal(t, len(expectedCellsAndProofs[i].Proofs), cap(actualCellsAndProofs[i].Proofs)) // Compare cells for j, expectedCell := range expectedCellsAndProofs[i].Cells { diff --git a/beacon-chain/core/peerdas/validator.go b/beacon-chain/core/peerdas/validator.go index 8e448aa00155..985c8205779a 100644 --- a/beacon-chain/core/peerdas/validator.go +++ b/beacon-chain/core/peerdas/validator.go @@ -1,9 +1,11 @@ package peerdas import ( + "slices" "time" "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/kzg" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" beaconState "github.com/OffchainLabs/prysm/v6/beacon-chain/state" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" "github.com/OffchainLabs/prysm/v6/config/params" @@ -11,6 +13,7 @@ import ( "github.com/OffchainLabs/prysm/v6/consensus-types/primitives" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "github.com/pkg/errors" + "github.com/prysmaticlabs/go-bitfield" ) var ( @@ -119,9 +122,9 @@ func DataColumnSidecars(rows []kzg.CellsAndProofs, src ConstructionPopulator) ([ for idx := range maxIdx { sidecar := ðpb.DataColumnSidecar{ Index: idx, - Column: cells[idx], KzgCommitments: info.kzgCommitments, - KzgProofs: proofs[idx], + Column: make([][]byte, len(cells[idx])), + KzgProofs: make([][]byte, len(proofs[idx])), SignedBlockHeader: info.signedBlockHeader, KzgCommitmentsInclusionProof: info.kzgInclusionProof, } @@ -129,6 +132,11 @@ func DataColumnSidecars(rows []kzg.CellsAndProofs, src ConstructionPopulator) ([ if len(sidecar.KzgCommitments) != len(sidecar.Column) || len(sidecar.KzgCommitments) != len(sidecar.KzgProofs) { return nil, ErrSizeMismatch } + for i := range cells[idx] { + sidecar.Column[i] = cells[idx][i][:] + // The above check verifies len(cells) == len(proofs) + sidecar.KzgProofs[i] = proofs[idx][i][:] + } roSidecar, err := blocks.NewRODataColumnWithRoot(sidecar, src.Root()) if err != nil { @@ -141,6 +149,49 @@ func DataColumnSidecars(rows []kzg.CellsAndProofs, src ConstructionPopulator) ([ return roSidecars, nil } +func PartialColumns(included bitfield.Bitlist, rows []kzg.CellsAndProofs, src ConstructionPopulator) ([]partial.PartialColumn, error) { + if len(rows) == 0 { + return nil, nil + } + numColumns := params.BeaconConfig().NumberOfColumns + cells, proofs, err := rotateRowsToCols(rows, numColumns) + if err != nil { + return nil, errors.Wrap(err, "rotate cells and proofs") + } + info, err := src.extract() + if err != nil { + return nil, errors.Wrap(err, "extract block info") + } + + cols := make([]partial.PartialColumn, numColumns) + commitments := make([]kzg.Commitment, len(info.kzgCommitments)) + for i := range commitments { + if copy(commitments[i][:], info.kzgCommitments[i]) != len(commitments[i]) { + return nil, errors.New("size mismatch of kzg commitments") + } + } + blockInfo, err := src.extract() + if err != nil { + return nil, errors.Wrap(err, "extract block info") + } + + root := src.Root() + for idx := range numColumns { + cols[idx] = partial.NewPartialColumn( + blockInfo.signedBlockHeader, + blockInfo.kzgInclusionProof, + root[:], + commitments, + // Clone because it becomes owned by the partial column. + slices.Clone(included), + cells[idx], + proofs[idx], + ) + } + + return cols, nil +} + // Slot returns the slot of the source func (s *BlockReconstructionSource) Slot() primitives.Slot { return s.Block().Slot() @@ -197,12 +248,12 @@ func (b *BlockReconstructionSource) extract() (*blockInfo, error) { // rotateRowsToCols takes a 2D slice of cells and proofs, where the x is rows (blobs) and y is columns, // and returns a 2D slice where x is columns and y is rows. -func rotateRowsToCols(rows []kzg.CellsAndProofs, numCols uint64) ([][][]byte, [][][]byte, error) { +func rotateRowsToCols(rows []kzg.CellsAndProofs, numCols uint64) ([][]kzg.Cell, [][]kzg.Proof, error) { if len(rows) == 0 { return nil, nil, nil } - cellCols := make([][][]byte, numCols) - proofCols := make([][][]byte, numCols) + cellCols := make([][]kzg.Cell, numCols) + proofCols := make([][]kzg.Proof, numCols) for i, cp := range rows { if uint64(len(cp.Cells)) != numCols { return nil, nil, errors.Wrap(ErrNotEnoughDataColumnSidecars, "not enough cells") @@ -212,11 +263,11 @@ func rotateRowsToCols(rows []kzg.CellsAndProofs, numCols uint64) ([][][]byte, [] } for j := uint64(0); j < numCols; j++ { if i == 0 { - cellCols[j] = make([][]byte, len(rows)) - proofCols[j] = make([][]byte, len(rows)) + cellCols[j] = make([]kzg.Cell, len(rows)) + proofCols[j] = make([]kzg.Proof, len(rows)) } - cellCols[j][i] = cp.Cells[j][:] - proofCols[j][i] = cp.Proofs[j][:] + cellCols[j][i] = cp.Cells[j] + proofCols[j][i] = cp.Proofs[j] } } return cellCols, proofCols, nil From 7ac78139ad3442710a140a54103eb2ce7105b94b Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 1 Oct 2025 13:24:37 -0700 Subject: [PATCH 06/13] beacon-chain/execution: add support for getBlobsV3 and partial columns --- beacon-chain/execution/BUILD.bazel | 2 + beacon-chain/execution/engine_client.go | 84 ++++++++++++++----- beacon-chain/execution/engine_client_test.go | 6 +- beacon-chain/execution/testing/BUILD.bazel | 1 + .../execution/testing/mock_engine_client.go | 5 +- 5 files changed, 70 insertions(+), 28 deletions(-) diff --git a/beacon-chain/execution/BUILD.bazel b/beacon-chain/execution/BUILD.bazel index c2445712c896..af43f611cd40 100644 --- a/beacon-chain/execution/BUILD.bazel +++ b/beacon-chain/execution/BUILD.bazel @@ -36,6 +36,7 @@ go_library( "//beacon-chain/core/transition:go_default_library", "//beacon-chain/db:go_default_library", "//beacon-chain/execution/types:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", "//beacon-chain/state:go_default_library", "//beacon-chain/state/state-native:go_default_library", "//beacon-chain/state/stategen:go_default_library", @@ -72,6 +73,7 @@ go_library( "@com_github_pkg_errors//:go_default_library", "@com_github_prometheus_client_golang//prometheus:go_default_library", "@com_github_prometheus_client_golang//prometheus/promauto:go_default_library", + "@com_github_prysmaticlabs_go_bitfield//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", "@io_k8s_client_go//tools/cache:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index c8bbcd997a80..98e627ad8ecc 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -10,6 +10,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/kzg" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" "github.com/OffchainLabs/prysm/v6/beacon-chain/execution/types" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/beacon-chain/verification" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" "github.com/OffchainLabs/prysm/v6/config/params" @@ -29,6 +30,7 @@ import ( gethRPC "github.com/ethereum/go-ethereum/rpc" "github.com/holiman/uint256" "github.com/pkg/errors" + "github.com/prysmaticlabs/go-bitfield" "github.com/sirupsen/logrus" "google.golang.org/protobuf/proto" ) @@ -57,6 +59,7 @@ var ( fuluEngineEndpoints = []string{ GetPayloadMethodV5, GetBlobsV2, + GetBlobsV3, } ) @@ -98,6 +101,8 @@ const ( GetBlobsV1 = "engine_getBlobsV1" // GetBlobsV2 request string for JSON-RPC. GetBlobsV2 = "engine_getBlobsV2" + // GetBlobsV3 request string for JSON-RPC. + GetBlobsV3 = "engine_getBlobsV3" // Defines the seconds before timing out engine endpoints with non-block execution semantics. defaultEngineTimeout = time.Second ) @@ -121,7 +126,7 @@ type Reconstructor interface { ctx context.Context, blindedBlocks []interfaces.ReadOnlySignedBeaconBlock, ) ([]interfaces.SignedBeaconBlock, error) ReconstructBlobSidecars(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock, blockRoot [fieldparams.RootLength]byte, hi func(uint64) bool) ([]blocks.VerifiedROBlob, error) - ConstructDataColumnSidecars(ctx context.Context, populator peerdas.ConstructionPopulator) ([]blocks.VerifiedRODataColumn, error) + ConstructDataColumnSidecars(ctx context.Context, populator peerdas.ConstructionPopulator) ([]blocks.VerifiedRODataColumn, []partial.PartialColumn, error) } // EngineCaller defines a client that can interact with an Ethereum @@ -541,6 +546,19 @@ func (s *Service) GetBlobsV2(ctx context.Context, versionedHashes []common.Hash) return result, handleRPCError(err) } +func (s *Service) GetBlobsV3(ctx context.Context, versionedHashes []common.Hash) ([]*pb.BlobAndProofV2, error) { + ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.GetBlobsV3") + defer span.End() + + if !s.capabilityCache.has(GetBlobsV3) { + return nil, errors.New(fmt.Sprintf("%s is not supported", GetBlobsV3)) + } + + result := make([]*pb.BlobAndProofV2, len(versionedHashes)) + err := s.rpcClient.CallContext(ctx, &result, GetBlobsV3, versionedHashes) + return result, handleRPCError(err) +} + // ReconstructFullBlock takes in a blinded beacon block and reconstructs // a beacon block with a full execution payload via the engine API. func (s *Service) ReconstructFullBlock( @@ -651,40 +669,52 @@ func (s *Service) ReconstructBlobSidecars(ctx context.Context, block interfaces. return verifiedBlobs, nil } -func (s *Service) ConstructDataColumnSidecars(ctx context.Context, populator peerdas.ConstructionPopulator) ([]blocks.VerifiedRODataColumn, error) { +func (s *Service) ConstructDataColumnSidecars(ctx context.Context, populator peerdas.ConstructionPopulator) ([]blocks.VerifiedRODataColumn, []partial.PartialColumn, error) { root := populator.Root() // Fetch cells and proofs from the execution client using the KZG commitments from the sidecar. commitments, err := populator.Commitments() if err != nil { - return nil, wrapWithBlockRoot(err, root, "commitments") + return nil, nil, wrapWithBlockRoot(err, root, "commitments") } - cellsAndProofs, err := s.fetchCellsAndProofsFromExecution(ctx, commitments) + included, cellsAndProofs, err := s.fetchCellsAndProofsFromExecution(ctx, commitments) + log.Info("Received cells and proofs from execution client", "included", included, "cellsAndProofs", len(cellsAndProofs), "err", err) if err != nil { - return nil, wrapWithBlockRoot(err, root, "fetch cells and proofs from execution client") + return nil, nil, wrapWithBlockRoot(err, root, "fetch cells and proofs from execution client") } // Return early if nothing is returned from the EL. if len(cellsAndProofs) == 0 { - return nil, nil + return nil, nil, nil } - // Construct data column sidears from the signed block and cells and proofs. - roSidecars, err := peerdas.DataColumnSidecars(cellsAndProofs, populator) - if err != nil { - return nil, wrapWithBlockRoot(err, populator.Root(), "data column sidcars from column sidecar") - } + partialColumns, err := peerdas.PartialColumns(included, cellsAndProofs, populator) + haveAllBlobs := included.Count() == uint64(len(commitments)) + log.Info("Constructed partial columns", "haveAllBlobs", haveAllBlobs) - // Upgrade the sidecars to verified sidecars. - // We trust the execution layer we are connected to, so we can upgrade the sidecar into a verified one. - verifiedROSidecars := upgradeSidecarsToVerifiedSidecars(roSidecars) + if haveAllBlobs { + // Construct data column sidears from the signed block and cells and proofs. + roSidecars, err := peerdas.DataColumnSidecars(cellsAndProofs, populator) + if err != nil { + return nil, nil, wrapWithBlockRoot(err, populator.Root(), "data column sidcars from column sidecar") + } + + // Upgrade the sidecars to verified sidecars. + // We trust the execution layer we are connected to, so we can upgrade the sidecar into a verified one. + verifiedROSidecars := upgradeSidecarsToVerifiedSidecars(roSidecars) - return verifiedROSidecars, nil + return verifiedROSidecars, partialColumns, nil + } + + if err != nil { + return nil, nil, wrapWithBlockRoot(err, populator.Root(), "partial columns from column sidecar") + } + return nil, partialColumns, nil } // fetchCellsAndProofsFromExecution fetches cells and proofs from the execution client (using engine_getBlobsV2 execution API method) -func (s *Service) fetchCellsAndProofsFromExecution(ctx context.Context, kzgCommitments [][]byte) ([]kzg.CellsAndProofs, error) { +func (s *Service) fetchCellsAndProofsFromExecution(ctx context.Context, kzgCommitments [][]byte) (included bitfield.Bitlist, _ []kzg.CellsAndProofs, err error) { // Collect KZG hashes for all blobs. versionedHashes := make([]common.Hash, 0, len(kzgCommitments)) for _, commitment := range kzgCommitments { @@ -692,24 +722,32 @@ func (s *Service) fetchCellsAndProofsFromExecution(ctx context.Context, kzgCommi versionedHashes = append(versionedHashes, versionedHash) } + var blobAndProofs []*pb.BlobAndProofV2 + + if s.capabilityCache.has(GetBlobsV3) { + // v3 can return a partial response. V2 is all or nothing + blobAndProofs, err = s.GetBlobsV3(ctx, versionedHashes) + } else { + blobAndProofs, err = s.GetBlobsV2(ctx, versionedHashes) + } + // Fetch all blobsAndCellsProofs from the execution client. - blobAndProofV2s, err := s.GetBlobsV2(ctx, versionedHashes) if err != nil { - return nil, errors.Wrapf(err, "get blobs V2") + return nil, nil, errors.Wrapf(err, "get blobs") } // Return early if nothing is returned from the EL. - if len(blobAndProofV2s) == 0 { - return nil, nil + if len(blobAndProofs) == 0 { + return nil, nil, nil } // Compute cells and proofs from the blobs and cell proofs. - cellsAndProofs, err := peerdas.ComputeCellsAndProofsFromStructured(blobAndProofV2s) + included, cellsAndProofs, err := peerdas.ComputeCellsAndProofsFromStructured(uint64(len(kzgCommitments)), blobAndProofs) if err != nil { - return nil, errors.Wrap(err, "compute cells and proofs") + return nil, nil, errors.Wrap(err, "compute cells and proofs") } - return cellsAndProofs, nil + return included, cellsAndProofs, nil } // upgradeSidecarsToVerifiedSidecars upgrades a list of data column sidecars into verified data column sidecars. diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index 649da3491438..b9ec079f36df 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -2587,7 +2587,7 @@ func TestConstructDataColumnSidecars(t *testing.T) { ctx := context.Background() t.Run("GetBlobsV2 is not supported", func(t *testing.T) { - _, err := client.ConstructDataColumnSidecars(ctx, peerdas.PopulateFromBlock(roBlock)) + _, _, err := client.ConstructDataColumnSidecars(ctx, peerdas.PopulateFromBlock(roBlock)) require.ErrorContains(t, "engine_getBlobsV2 is not supported", err) }) @@ -2598,7 +2598,7 @@ func TestConstructDataColumnSidecars(t *testing.T) { rpcClient, client := setupRpcClientV2(t, srv.URL, client) defer rpcClient.Close() - dataColumns, err := client.ConstructDataColumnSidecars(ctx, peerdas.PopulateFromBlock(roBlock)) + dataColumns, _, err := client.ConstructDataColumnSidecars(ctx, peerdas.PopulateFromBlock(roBlock)) require.NoError(t, err) require.Equal(t, 0, len(dataColumns)) }) @@ -2611,7 +2611,7 @@ func TestConstructDataColumnSidecars(t *testing.T) { rpcClient, client := setupRpcClientV2(t, srv.URL, client) defer rpcClient.Close() - dataColumns, err := client.ConstructDataColumnSidecars(ctx, peerdas.PopulateFromBlock(roBlock)) + dataColumns, _, err := client.ConstructDataColumnSidecars(ctx, peerdas.PopulateFromBlock(roBlock)) require.NoError(t, err) require.Equal(t, 128, len(dataColumns)) }) diff --git a/beacon-chain/execution/testing/BUILD.bazel b/beacon-chain/execution/testing/BUILD.bazel index a1d1b3284910..01dece639771 100644 --- a/beacon-chain/execution/testing/BUILD.bazel +++ b/beacon-chain/execution/testing/BUILD.bazel @@ -16,6 +16,7 @@ go_library( "//async/event:go_default_library", "//beacon-chain/core/peerdas:go_default_library", "//beacon-chain/execution/types:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", "//beacon-chain/state:go_default_library", "//beacon-chain/state/state-native:go_default_library", "//config/fieldparams:go_default_library", diff --git a/beacon-chain/execution/testing/mock_engine_client.go b/beacon-chain/execution/testing/mock_engine_client.go index 969a39892ab7..4746f094a86a 100644 --- a/beacon-chain/execution/testing/mock_engine_client.go +++ b/beacon-chain/execution/testing/mock_engine_client.go @@ -5,6 +5,7 @@ import ( "math/big" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" "github.com/OffchainLabs/prysm/v6/config/params" "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" @@ -118,8 +119,8 @@ func (e *EngineClient) ReconstructBlobSidecars(context.Context, interfaces.ReadO } // ConstructDataColumnSidecars is a mock implementation of the ConstructDataColumnSidecars method. -func (e *EngineClient) ConstructDataColumnSidecars(context.Context, peerdas.ConstructionPopulator) ([]blocks.VerifiedRODataColumn, error) { - return e.DataColumnSidecars, e.ErrorDataColumnSidecars +func (e *EngineClient) ConstructDataColumnSidecars(context.Context, peerdas.ConstructionPopulator) ([]blocks.VerifiedRODataColumn, []partial.PartialColumn, error) { + return e.DataColumnSidecars, nil, e.ErrorDataColumnSidecars } // GetTerminalBlockHash -- From 289dd4d0f30b00961a747f329e16da803bbb36e6 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 3 Oct 2025 17:38:11 -0700 Subject: [PATCH 07/13] cmd/beacon-chain: add flag to enable partial columns --- beacon-chain/node/node.go | 1 + beacon-chain/sync/options.go | 13 +++++++++++++ cmd/beacon-chain/flags/base.go | 6 ++++++ cmd/beacon-chain/main.go | 1 + cmd/beacon-chain/usage.go | 1 + 5 files changed, 22 insertions(+) diff --git a/beacon-chain/node/node.go b/beacon-chain/node/node.go index 6a6146e4be77..8ddb0bdc3b82 100644 --- a/beacon-chain/node/node.go +++ b/beacon-chain/node/node.go @@ -818,6 +818,7 @@ func (b *BeaconNode) registerSyncService(initialSyncComplete chan struct{}, bFil b.ctx, regularsync.WithDatabase(b.db), regularsync.WithP2P(b.fetchP2P()), + regularsync.WithPartialDataColumnRegex(b.cliCtx.String(flags.PartialDataColumnRegex.Name)), regularsync.WithChainService(chainService), regularsync.WithInitialSync(initSync), regularsync.WithBlockNotifier(b), diff --git a/beacon-chain/sync/options.go b/beacon-chain/sync/options.go index d30a8ef0215e..1a48cf74dd71 100644 --- a/beacon-chain/sync/options.go +++ b/beacon-chain/sync/options.go @@ -1,6 +1,8 @@ package sync import ( + "regexp" + "github.com/OffchainLabs/prysm/v6/async/event" "github.com/OffchainLabs/prysm/v6/beacon-chain/cache" blockfeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/block" @@ -238,3 +240,14 @@ func WithReconstructionRandGen(rg *rand.Rand) Option { return nil } } + +func WithPartialDataColumnRegex(regex string) Option { + return func(s *Service) (err error) { + if regex == "" { + return nil + } + + s.partialColumnRegex, err = regexp.Compile(regex) + return err + } +} diff --git a/cmd/beacon-chain/flags/base.go b/cmd/beacon-chain/flags/base.go index a338572bd1b5..50dc41cc9729 100644 --- a/cmd/beacon-chain/flags/base.go +++ b/cmd/beacon-chain/flags/base.go @@ -344,4 +344,10 @@ var ( Usage: "Maximum number of signatures to batch verify at once for beacon attestation p2p gossip.", Value: 1000, } + // PartialDataColumnRegex specifies the regex for enabling partial messages on datacolumns + PartialDataColumnRegex = &cli.StringFlag{ + Name: "partial-data-column-regex", + Usage: "Set the regex for enabling partial messages on PeerDAS data columns", + Value: "^$", // Nothing + } ) diff --git a/cmd/beacon-chain/main.go b/cmd/beacon-chain/main.go index 7c739696ee58..282c8311b09b 100644 --- a/cmd/beacon-chain/main.go +++ b/cmd/beacon-chain/main.go @@ -153,6 +153,7 @@ var appFlags = []cli.Flag{ bflags.BackfillWorkerCount, bflags.BackfillOldestSlot, flags.BatchVerifierLimit, + flags.PartialDataColumnRegex, } func init() { diff --git a/cmd/beacon-chain/usage.go b/cmd/beacon-chain/usage.go index 279e1c07c98a..6b883bf69660 100644 --- a/cmd/beacon-chain/usage.go +++ b/cmd/beacon-chain/usage.go @@ -73,6 +73,7 @@ var appHelpFlagGroups = []flagGroup{ flags.RPCHost, flags.RPCPort, flags.BatchVerifierLimit, + flags.PartialDataColumnRegex, }, }, { From 9be9edfe773b69d677ba8fdfb37b8b07f34a9956 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 8 Oct 2025 12:08:37 -0700 Subject: [PATCH 08/13] beacon-chain/p2p: own and start PartialColumnBroadcaster --- beacon-chain/blockchain/BUILD.bazel | 1 + beacon-chain/blockchain/setup_test.go | 3 +- beacon-chain/p2p/BUILD.bazel | 2 + beacon-chain/p2p/broadcaster.go | 17 +++- beacon-chain/p2p/broadcaster_test.go | 2 +- beacon-chain/p2p/interfaces.go | 9 +- beacon-chain/p2p/pubsub.go | 1 + beacon-chain/p2p/service.go | 92 +++++++++++--------- beacon-chain/p2p/testing/BUILD.bazel | 1 + beacon-chain/p2p/testing/fuzz_p2p.go | 7 +- beacon-chain/p2p/testing/mock_broadcaster.go | 3 +- beacon-chain/p2p/testing/p2p.go | 7 +- 12 files changed, 96 insertions(+), 49 deletions(-) diff --git a/beacon-chain/blockchain/BUILD.bazel b/beacon-chain/blockchain/BUILD.bazel index 86f0718b9bf7..97dbcfca1e94 100644 --- a/beacon-chain/blockchain/BUILD.bazel +++ b/beacon-chain/blockchain/BUILD.bazel @@ -167,6 +167,7 @@ go_test( "//beacon-chain/operations/slashings:go_default_library", "//beacon-chain/operations/voluntaryexits:go_default_library", "//beacon-chain/p2p:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", "//beacon-chain/p2p/testing:go_default_library", "//beacon-chain/startup:go_default_library", "//beacon-chain/state:go_default_library", diff --git a/beacon-chain/blockchain/setup_test.go b/beacon-chain/blockchain/setup_test.go index 875ff8aab457..3b7e2c579029 100644 --- a/beacon-chain/blockchain/setup_test.go +++ b/beacon-chain/blockchain/setup_test.go @@ -21,6 +21,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/operations/attestations" "github.com/OffchainLabs/prysm/v6/beacon-chain/operations/blstoexec" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" p2pTesting "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/testing" "github.com/OffchainLabs/prysm/v6/beacon-chain/startup" "github.com/OffchainLabs/prysm/v6/beacon-chain/state/stategen" @@ -89,7 +90,7 @@ func (mb *mockBroadcaster) BroadcastLightClientFinalityUpdate(_ context.Context, return nil } -func (mb *mockBroadcaster) BroadcastDataColumnSidecars(_ context.Context, _ []blocks.VerifiedRODataColumn) error { +func (mb *mockBroadcaster) BroadcastDataColumnSidecars(_ context.Context, _ []blocks.VerifiedRODataColumn, _ []partial.PartialColumn) error { mb.broadcastCalled = true return nil } diff --git a/beacon-chain/p2p/BUILD.bazel b/beacon-chain/p2p/BUILD.bazel index 74dc12536217..0fb4abe75063 100644 --- a/beacon-chain/p2p/BUILD.bazel +++ b/beacon-chain/p2p/BUILD.bazel @@ -51,6 +51,7 @@ go_library( "//beacon-chain/db:go_default_library", "//beacon-chain/db/kv:go_default_library", "//beacon-chain/p2p/encoder:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", "//beacon-chain/p2p/peers:go_default_library", "//beacon-chain/p2p/peers/peerdata:go_default_library", "//beacon-chain/p2p/peers/scorers:go_default_library", @@ -68,6 +69,7 @@ go_library( "//crypto/ecdsa:go_default_library", "//crypto/hash:go_default_library", "//encoding/bytesutil:go_default_library", + "//internal/logrusadapter:go_default_library", "//io/file:go_default_library", "//math:go_default_library", "//monitoring/tracing:go_default_library", diff --git a/beacon-chain/p2p/broadcaster.go b/beacon-chain/p2p/broadcaster.go index 03b38e29acb0..fb76a8e3c5bc 100644 --- a/beacon-chain/p2p/broadcaster.go +++ b/beacon-chain/p2p/broadcaster.go @@ -12,6 +12,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/core/altair" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/helpers" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" "github.com/OffchainLabs/prysm/v6/config/params" "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" @@ -342,7 +343,7 @@ func (s *Service) BroadcastLightClientFinalityUpdate(ctx context.Context, update // there is at least one peer in each needed subnet. If not, it will attempt to find one before broadcasting. // This function is non-blocking. It stops trying to broadcast a given sidecar when more than one slot has passed, or the context is // cancelled (whichever comes first). -func (s *Service) BroadcastDataColumnSidecars(ctx context.Context, sidecars []blocks.VerifiedRODataColumn) error { +func (s *Service) BroadcastDataColumnSidecars(ctx context.Context, sidecars []blocks.VerifiedRODataColumn, partialColumns []partial.PartialColumn) error { // Increase the number of broadcast attempts. dataColumnSidecarBroadcastAttempts.Add(float64(len(sidecars))) @@ -352,7 +353,7 @@ func (s *Service) BroadcastDataColumnSidecars(ctx context.Context, sidecars []bl return errors.Wrap(err, "current fork digest") } - go s.broadcastDataColumnSidecars(ctx, forkDigest, sidecars) + go s.broadcastDataColumnSidecars(ctx, forkDigest, sidecars, partialColumns) return nil } @@ -360,7 +361,7 @@ func (s *Service) BroadcastDataColumnSidecars(ctx context.Context, sidecars []bl // broadcastDataColumnSidecars broadcasts multiple data column sidecars to the p2p network, after ensuring // there is at least one peer in each needed subnet. If not, it will attempt to find one before broadcasting. // It returns when all broadcasts are complete, or the context is cancelled (whichever comes first). -func (s *Service) broadcastDataColumnSidecars(ctx context.Context, forkDigest [fieldparams.VersionLength]byte, sidecars []blocks.VerifiedRODataColumn) { +func (s *Service) broadcastDataColumnSidecars(ctx context.Context, forkDigest [fieldparams.VersionLength]byte, sidecars []blocks.VerifiedRODataColumn, partialColumns []partial.PartialColumn) { type rootAndIndex struct { root [fieldparams.RootLength]byte index uint64 @@ -374,7 +375,7 @@ func (s *Service) broadcastDataColumnSidecars(ctx context.Context, forkDigest [f logLevel := logrus.GetLevel() slotPerRoot := make(map[[fieldparams.RootLength]byte]primitives.Slot, 1) - for _, sidecar := range sidecars { + for i, sidecar := range sidecars { slotPerRoot[sidecar.BlockRoot()] = sidecar.Slot() wg.Go(func() { @@ -398,6 +399,14 @@ func (s *Service) broadcastDataColumnSidecars(ctx context.Context, forkDigest [f return } + if s.partialColumnBroadcaster != nil && i < len(partialColumns) { + fullTopicStr := topic + s.Encoding().ProtocolSuffix() + if err := s.partialColumnBroadcaster.Publish(fullTopicStr, partialColumns[i]); err != nil { + tracing.AnnotateError(span, err) + log.WithError(err).Error("Cannot partial broadcast data column sidecar") + } + } + // Broadcast the data column sidecar to the network. if err := s.broadcastObject(ctx, sidecar, topic); err != nil { tracing.AnnotateError(span, err) diff --git a/beacon-chain/p2p/broadcaster_test.go b/beacon-chain/p2p/broadcaster_test.go index 36696b85e3f2..8c3fec5af534 100644 --- a/beacon-chain/p2p/broadcaster_test.go +++ b/beacon-chain/p2p/broadcaster_test.go @@ -748,7 +748,7 @@ func TestService_BroadcastDataColumn(t *testing.T) { time.Sleep(50 * time.Millisecond) // Broadcast to peers and wait. - err = service.BroadcastDataColumnSidecars(ctx, []blocks.VerifiedRODataColumn{verifiedRoSidecar}) + err = service.BroadcastDataColumnSidecars(ctx, []blocks.VerifiedRODataColumn{verifiedRoSidecar}, nil) require.NoError(t, err) // Receive the message. diff --git a/beacon-chain/p2p/interfaces.go b/beacon-chain/p2p/interfaces.go index c45dba4b0f04..b94c45fc41ee 100644 --- a/beacon-chain/p2p/interfaces.go +++ b/beacon-chain/p2p/interfaces.go @@ -4,6 +4,7 @@ import ( "context" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/encoder" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" @@ -28,6 +29,7 @@ type ( Broadcaster SetStreamHandler PubSubProvider + PartialColumnBroadcasterProvider PubSubTopicUser SenderEncoder PeerManager @@ -52,7 +54,7 @@ type ( BroadcastBlob(ctx context.Context, subnet uint64, blob *ethpb.BlobSidecar) error BroadcastLightClientOptimisticUpdate(ctx context.Context, update interfaces.LightClientOptimisticUpdate) error BroadcastLightClientFinalityUpdate(ctx context.Context, update interfaces.LightClientFinalityUpdate) error - BroadcastDataColumnSidecars(ctx context.Context, sidecars []blocks.VerifiedRODataColumn) error + BroadcastDataColumnSidecars(ctx context.Context, sidecars []blocks.VerifiedRODataColumn, partialColumns []partial.PartialColumn) error } // SetStreamHandler configures p2p to handle streams of a certain topic ID. @@ -92,6 +94,11 @@ type ( PubSub() *pubsub.PubSub } + // PubSubProvider provides the p2p pubsub protocol. + PartialColumnBroadcasterProvider interface { + PartialColumnBroadcaster() *partial.PartialColumnBroadcaster + } + // PeerManager abstracts some peer management methods from libp2p. PeerManager interface { Disconnect(peer.ID) error diff --git a/beacon-chain/p2p/pubsub.go b/beacon-chain/p2p/pubsub.go index f2abf96e6f61..09cc64d99bfb 100644 --- a/beacon-chain/p2p/pubsub.go +++ b/beacon-chain/p2p/pubsub.go @@ -159,6 +159,7 @@ func (s *Service) pubsubOptions() []pubsub.Option { } psOpts = append(psOpts, pubsub.WithDirectPeers(directPeersAddrInfos)) } + psOpts = s.partialColumnBroadcaster.AppendPubSubOpts(psOpts) return psOpts } diff --git a/beacon-chain/p2p/service.go b/beacon-chain/p2p/service.go index eeff1a85c307..fc8e633a10e5 100644 --- a/beacon-chain/p2p/service.go +++ b/beacon-chain/p2p/service.go @@ -6,11 +6,13 @@ package p2p import ( "context" "crypto/ecdsa" + "log/slog" "sync" "time" "github.com/OffchainLabs/prysm/v6/async" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/encoder" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers/scorers" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/types" @@ -18,6 +20,7 @@ import ( "github.com/OffchainLabs/prysm/v6/config/params" "github.com/OffchainLabs/prysm/v6/consensus-types/primitives" leakybucket "github.com/OffchainLabs/prysm/v6/container/leaky-bucket" + "github.com/OffchainLabs/prysm/v6/internal/logrusadapter" "github.com/OffchainLabs/prysm/v6/monitoring/tracing/trace" prysmnetwork "github.com/OffchainLabs/prysm/v6/network" "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1/metadata" @@ -64,34 +67,35 @@ var ( // Service for managing peer to peer (p2p) networking. type Service struct { - started bool - isPreGenesis bool - pingMethod func(ctx context.Context, id peer.ID) error - pingMethodLock sync.RWMutex - cancel context.CancelFunc - cfg *Config - peers *peers.Status - addrFilter *multiaddr.Filters - ipLimiter *leakybucket.Collector - privKey *ecdsa.PrivateKey - metaData metadata.Metadata - pubsub *pubsub.PubSub - joinedTopics map[string]*pubsub.Topic - joinedTopicsLock sync.RWMutex - subnetsLock map[uint64]*sync.RWMutex - subnetsLockLock sync.Mutex // Lock access to subnetsLock - initializationLock sync.Mutex - dv5Listener ListenerRebooter - startupErr error - ctx context.Context - host host.Host - genesisTime time.Time - genesisValidatorsRoot []byte - activeValidatorCount uint64 - peerDisconnectionTime *cache.Cache - custodyInfo *custodyInfo - custodyInfoLock sync.RWMutex // Lock access to custodyInfo - allForkDigests map[[4]byte]struct{} + started bool + isPreGenesis bool + pingMethod func(ctx context.Context, id peer.ID) error + pingMethodLock sync.RWMutex + cancel context.CancelFunc + cfg *Config + peers *peers.Status + addrFilter *multiaddr.Filters + ipLimiter *leakybucket.Collector + privKey *ecdsa.PrivateKey + metaData metadata.Metadata + pubsub *pubsub.PubSub + partialColumnBroadcaster *partial.PartialColumnBroadcaster + joinedTopics map[string]*pubsub.Topic + joinedTopicsLock sync.RWMutex + subnetsLock map[uint64]*sync.RWMutex + subnetsLockLock sync.Mutex // Lock access to subnetsLock + initializationLock sync.Mutex + dv5Listener ListenerRebooter + startupErr error + ctx context.Context + host host.Host + genesisTime time.Time + genesisValidatorsRoot []byte + activeValidatorCount uint64 + peerDisconnectionTime *cache.Cache + custodyInfo *custodyInfo + custodyInfoLock sync.RWMutex // Lock access to custodyInfo + allForkDigests map[[4]byte]struct{} } type custodyInfo struct { @@ -125,18 +129,20 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) { ipLimiter := leakybucket.NewCollector(ipLimit, ipBurst, 30*time.Second, true /* deleteEmptyBuckets */) + slogger := slog.New(logrusadapter.Handler{Logger: log.Logger}) s := &Service{ - ctx: ctx, - cancel: cancel, - cfg: cfg, - addrFilter: addrFilter, - ipLimiter: ipLimiter, - privKey: privKey, - metaData: metaData, - isPreGenesis: true, - joinedTopics: make(map[string]*pubsub.Topic, len(gossipTopicMappings)), - subnetsLock: make(map[uint64]*sync.RWMutex), - peerDisconnectionTime: cache.New(1*time.Second, 1*time.Minute), + ctx: ctx, + cancel: cancel, + cfg: cfg, + addrFilter: addrFilter, + ipLimiter: ipLimiter, + privKey: privKey, + metaData: metaData, + isPreGenesis: true, + joinedTopics: make(map[string]*pubsub.Topic, len(gossipTopicMappings)), + subnetsLock: make(map[uint64]*sync.RWMutex), + peerDisconnectionTime: cache.New(1*time.Second, 1*time.Minute), + partialColumnBroadcaster: partial.NewBroadcaster(slogger), } ipAddr := prysmnetwork.IPAddr() @@ -297,6 +303,8 @@ func (s *Service) Start() { logExternalDNSAddr(s.host.ID(), p2pHostDNS, p2pTCPPort) } go s.forkWatcher() + + go s.partialColumnBroadcaster.Start() } // Stop the p2p service and terminate all peer connections. @@ -306,6 +314,8 @@ func (s *Service) Stop() error { if s.dv5Listener != nil { s.dv5Listener.Close() } + + s.partialColumnBroadcaster.Stop() return nil } @@ -342,6 +352,10 @@ func (s *Service) PubSub() *pubsub.PubSub { return s.pubsub } +func (s *Service) PartialColumnBroadcaster() *partial.PartialColumnBroadcaster { + return s.partialColumnBroadcaster +} + // Host returns the currently running libp2p // host of the service. func (s *Service) Host() host.Host { diff --git a/beacon-chain/p2p/testing/BUILD.bazel b/beacon-chain/p2p/testing/BUILD.bazel index 2728164369a9..2cf58cbdf0ef 100644 --- a/beacon-chain/p2p/testing/BUILD.bazel +++ b/beacon-chain/p2p/testing/BUILD.bazel @@ -21,6 +21,7 @@ go_library( deps = [ "//beacon-chain/core/peerdas:go_default_library", "//beacon-chain/p2p/encoder:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", "//beacon-chain/p2p/peers:go_default_library", "//beacon-chain/p2p/peers/scorers:go_default_library", "//config/fieldparams:go_default_library", diff --git a/beacon-chain/p2p/testing/fuzz_p2p.go b/beacon-chain/p2p/testing/fuzz_p2p.go index d7a4d51b3a70..26d4339863db 100644 --- a/beacon-chain/p2p/testing/fuzz_p2p.go +++ b/beacon-chain/p2p/testing/fuzz_p2p.go @@ -4,6 +4,7 @@ import ( "context" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/encoder" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" @@ -108,6 +109,10 @@ func (*FakeP2P) PubSub() *pubsub.PubSub { return nil } +func (*FakeP2P) PartialColumnBroadcaster() *partial.PartialColumnBroadcaster { + return nil +} + // MetadataSeq -- fake. func (*FakeP2P) MetadataSeq() uint64 { return 0 @@ -169,7 +174,7 @@ func (*FakeP2P) BroadcastLightClientFinalityUpdate(_ context.Context, _ interfac } // BroadcastDataColumnSidecar -- fake. -func (*FakeP2P) BroadcastDataColumnSidecars(_ context.Context, _ []blocks.VerifiedRODataColumn) error { +func (*FakeP2P) BroadcastDataColumnSidecars(_ context.Context, _ []blocks.VerifiedRODataColumn, _ []partial.PartialColumn) error { return nil } diff --git a/beacon-chain/p2p/testing/mock_broadcaster.go b/beacon-chain/p2p/testing/mock_broadcaster.go index 512b9901ea08..fa12e201185f 100644 --- a/beacon-chain/p2p/testing/mock_broadcaster.go +++ b/beacon-chain/p2p/testing/mock_broadcaster.go @@ -5,6 +5,7 @@ import ( "sync" "sync/atomic" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" "github.com/OffchainLabs/prysm/v6/consensus-types/interfaces" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" @@ -63,7 +64,7 @@ func (m *MockBroadcaster) BroadcastLightClientFinalityUpdate(_ context.Context, } // BroadcastDataColumnSidecar broadcasts a data column for mock. -func (m *MockBroadcaster) BroadcastDataColumnSidecars(context.Context, []blocks.VerifiedRODataColumn) error { +func (m *MockBroadcaster) BroadcastDataColumnSidecars(context.Context, []blocks.VerifiedRODataColumn, []partial.PartialColumn) error { m.BroadcastCalled.Store(true) return nil } diff --git a/beacon-chain/p2p/testing/p2p.go b/beacon-chain/p2p/testing/p2p.go index ca12b720bb03..6c641364fc28 100644 --- a/beacon-chain/p2p/testing/p2p.go +++ b/beacon-chain/p2p/testing/p2p.go @@ -13,6 +13,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/encoder" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers/scorers" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" @@ -233,7 +234,7 @@ func (p *TestP2P) BroadcastLightClientFinalityUpdate(_ context.Context, _ interf } // BroadcastDataColumnSidecar broadcasts a data column for mock. -func (p *TestP2P) BroadcastDataColumnSidecars(context.Context, []blocks.VerifiedRODataColumn) error { +func (p *TestP2P) BroadcastDataColumnSidecars(context.Context, []blocks.VerifiedRODataColumn, []partial.PartialColumn) error { p.BroadcastCalled.Store(true) return nil } @@ -299,6 +300,10 @@ func (p *TestP2P) PubSub() *pubsub.PubSub { return p.pubsub } +func (p *TestP2P) PartialColumnBroadcaster() *partial.PartialColumnBroadcaster { + return nil +} + // Disconnect from a peer. func (p *TestP2P) Disconnect(pid peer.ID) error { return p.BHost.Network().ClosePeer(pid) From c938e1b43d20357f18a3708c07061692efef9485 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 1 Oct 2025 13:24:37 -0700 Subject: [PATCH 09/13] beacon-chain/sync: subscribe to partial columns beacon-chain/sync: publish partial columns --- beacon-chain/sync/BUILD.bazel | 2 + beacon-chain/sync/service.go | 2 + beacon-chain/sync/subscriber.go | 63 +++++++++++++++++-- beacon-chain/sync/subscriber_beacon_blocks.go | 26 +++++++- .../sync/subscriber_data_column_sidecar.go | 51 ++++++++++++++- 5 files changed, 134 insertions(+), 10 deletions(-) diff --git a/beacon-chain/sync/BUILD.bazel b/beacon-chain/sync/BUILD.bazel index 44112d8e4f3b..6cc1691f8acc 100644 --- a/beacon-chain/sync/BUILD.bazel +++ b/beacon-chain/sync/BUILD.bazel @@ -72,6 +72,7 @@ go_library( "//async/abool:go_default_library", "//async/event:go_default_library", "//beacon-chain/blockchain:go_default_library", + "//beacon-chain/blockchain/kzg:go_default_library", "//beacon-chain/cache:go_default_library", "//beacon-chain/core/altair:go_default_library", "//beacon-chain/core/blocks:go_default_library", @@ -96,6 +97,7 @@ go_library( "//beacon-chain/operations/voluntaryexits:go_default_library", "//beacon-chain/p2p:go_default_library", "//beacon-chain/p2p/encoder:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", "//beacon-chain/p2p/peers:go_default_library", "//beacon-chain/p2p/types:go_default_library", "//beacon-chain/slasher/types:go_default_library", diff --git a/beacon-chain/sync/service.go b/beacon-chain/sync/service.go index 22edbe23dc6f..87d008daaf1a 100644 --- a/beacon-chain/sync/service.go +++ b/beacon-chain/sync/service.go @@ -6,6 +6,7 @@ package sync import ( "context" + "regexp" "sync" "time" @@ -182,6 +183,7 @@ type Service struct { dataColumnLogCh chan dataColumnLogEntry registeredNetworkEntry params.NetworkScheduleEntry subscriptionSpawner func(func()) // see Service.spawn for details + partialColumnRegex *regexp.Regexp } // NewService initializes new regular sync service. diff --git a/beacon-chain/sync/subscriber.go b/beacon-chain/sync/subscriber.go index 6518fd8d0acc..349d15462843 100644 --- a/beacon-chain/sync/subscriber.go +++ b/beacon-chain/sync/subscriber.go @@ -4,21 +4,25 @@ import ( "context" "fmt" "reflect" + "regexp" "runtime/debug" "strings" "sync" "time" + "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/kzg" "github.com/OffchainLabs/prysm/v6/beacon-chain/cache" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/altair" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/helpers" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers" "github.com/OffchainLabs/prysm/v6/beacon-chain/startup" "github.com/OffchainLabs/prysm/v6/cmd/beacon-chain/flags" "github.com/OffchainLabs/prysm/v6/config/features" "github.com/OffchainLabs/prysm/v6/config/params" + "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" "github.com/OffchainLabs/prysm/v6/consensus-types/primitives" "github.com/OffchainLabs/prysm/v6/monitoring/tracing" "github.com/OffchainLabs/prysm/v6/monitoring/tracing/trace" @@ -30,6 +34,7 @@ import ( "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" "github.com/pkg/errors" + "github.com/prysmaticlabs/go-bitfield" "github.com/sirupsen/logrus" "google.golang.org/protobuf/proto" ) @@ -61,6 +66,15 @@ type subscribeParameters struct { // getSubnetsRequiringPeers is a function that returns all subnets that require peers to be found // but for which no subscriptions are needed. getSubnetsRequiringPeers func(currentSlot primitives.Slot) map[uint64]bool + + partial *partialSubscribeParameters +} + +type partialSubscribeParameters struct { + broadcaster *partial.PartialColumnBroadcaster + enabledRegex *regexp.Regexp + validate partial.PartialColumnValidator + handle partial.SubHandler } // shortTopic is a less verbose version of topic strings used for logging. @@ -316,6 +330,27 @@ func (s *Service) registerSubscribers(epoch primitives.Epoch, digest [4]byte) { // New gossip topic in Fulu. if params.BeaconConfig().FuluForkEpoch <= epoch { s.spawn(func() { + var ps *partialSubscribeParameters + broadcaster := s.cfg.p2p.PartialColumnBroadcaster() + if broadcaster != nil { + ps = &partialSubscribeParameters{ + broadcaster: broadcaster, + enabledRegex: s.partialColumnRegex, + validate: func(included bitfield.Bitlist, allCommitments []kzg.Commitment, cells, proofs [][]byte) bool { + // TODO + return true + + }, + handle: func(topic string, col blocks.VerifiedRODataColumn) { + ctx, cancel := context.WithTimeout(s.ctx, pubsubMessageTimeout) + defer cancel() + err := s.verifiedRODataColumnSubscriber(ctx, col) + if err != nil { + log.WithError(err).Error("Failed to handle verified RO data column subscriber") + } + }, + } + } s.subscribeWithParameters(subscribeParameters{ topicFormat: p2p.DataColumnSubnetTopicFormat, validate: s.validateDataColumn, @@ -323,6 +358,7 @@ func (s *Service) registerSubscribers(epoch primitives.Epoch, digest [4]byte) { digest: digest, getSubnetsToJoin: s.dataColumnSubnetIndices, getSubnetsRequiringPeers: s.allDataColumnSubnets, + partial: ps, }) }) } @@ -342,11 +378,10 @@ func (s *Service) subscribe(topic string, validator wrappedVal, handle subHandle // Impossible condition as it would mean topic does not exist. panic(fmt.Sprintf("%s is not mapped to any message in GossipTopicMappings", topic)) // lint:nopanic -- Impossible condition. } - s.subscribeWithBase(s.addDigestToTopic(topic, digest), validator, handle) + s.subscribeWithBase(s.addDigestToTopic(topic, digest)+s.cfg.p2p.Encoding().ProtocolSuffix(), validator, handle) } func (s *Service) subscribeWithBase(topic string, validator wrappedVal, handle subHandler) *pubsub.Subscription { - topic += s.cfg.p2p.Encoding().ProtocolSuffix() log := log.WithField("topic", topic) // Do not resubscribe already seen subscriptions. @@ -510,7 +545,11 @@ func (s *Service) wrapAndReportValidation(topic string, v wrappedVal) (string, p func (s *Service) pruneSubscriptions(t *subnetTracker, wantedSubnets map[uint64]bool) { for _, subnet := range t.unwanted(wantedSubnets) { t.cancelSubscription(subnet) - s.unSubscribeFromTopic(t.fullTopic(subnet, s.cfg.p2p.Encoding().ProtocolSuffix())) + topic := t.fullTopic(subnet, s.cfg.p2p.Encoding().ProtocolSuffix()) + if t.partial != nil { + _ = t.partial.broadcaster.Unsubscribe(topic) + } + s.unSubscribeFromTopic(topic) } } @@ -535,10 +574,22 @@ func (s *Service) subscribeToSubnets(t *subnetTracker) error { subnetsToJoin := t.getSubnetsToJoin(s.cfg.clock.CurrentSlot()) s.pruneSubscriptions(t, subnetsToJoin) + for _, subnet := range t.missing(subnetsToJoin) { - // TODO: subscribeWithBase appends the protocol suffix, other methods don't. Make this consistent. - topic := t.fullTopic(subnet, "") - t.track(subnet, s.subscribeWithBase(topic, t.validate, t.handle)) + topicStr := t.fullTopic(subnet, s.cfg.p2p.Encoding().ProtocolSuffix()) + if t.partial != nil && t.partial.enabledRegex != nil && t.partial.enabledRegex.MatchString(topicStr) { + topic, err := s.cfg.p2p.JoinTopic(topicStr, pubsub.RequestPartialMessages()) + if err == nil { + log.Info("Subscribing to partial columns on", topicStr) + err = t.partial.broadcaster.Subscribe(topic, t.partial.validate, t.partial.handle) + } + + if err != nil { + log.WithError(err).Error("Failed to subscribe to partial column") + } + } else { + t.track(subnet, s.subscribeWithBase(topicStr, t.validate, t.handle)) + } } return nil diff --git a/beacon-chain/sync/subscriber_beacon_blocks.go b/beacon-chain/sync/subscriber_beacon_blocks.go index 4196dd991de8..4ef360895734 100644 --- a/beacon-chain/sync/subscriber_beacon_blocks.go +++ b/beacon-chain/sync/subscriber_beacon_blocks.go @@ -11,6 +11,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/core/helpers" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/transition/interop" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p" "github.com/OffchainLabs/prysm/v6/config/features" "github.com/OffchainLabs/prysm/v6/config/params" "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" @@ -190,6 +191,11 @@ func (s *Service) processDataColumnSidecarsFromExecution(ctx context.Context, so ctx, cancel := context.WithTimeout(ctx, secondsPerHalfSlot) defer cancel() + digest, err := s.currentForkDigest() + if err != nil { + return nil, err + } + for iteration := uint64(0); ; /*no stop condition*/ iteration++ { // Exit early if all sidecars to sample have been seen. if s.haveAllSidecarsBeenSeen(source.Slot(), source.ProposerIndex(), columnIndicesToSample) { @@ -197,11 +203,26 @@ func (s *Service) processDataColumnSidecarsFromExecution(ctx context.Context, so } // Try to reconstruct data column constructedSidecars from the execution client. - constructedSidecars, err := s.cfg.executionReconstructor.ConstructDataColumnSidecars(ctx, source) + constructedSidecars, partialColumns, err := s.cfg.executionReconstructor.ConstructDataColumnSidecars(ctx, source) if err != nil { return nil, errors.Wrap(err, "reconstruct data column sidecars") } + partialBroadcaster := s.cfg.p2p.PartialColumnBroadcaster() + if partialBroadcaster != nil { + for i := range uint64(len(partialColumns)) { + subnet := peerdas.ComputeSubnetForDataColumnSidecar(i) + topic := fmt.Sprintf(p2p.DataColumnSubnetTopicFormat, digest, subnet) + s.cfg.p2p.Encoding().ProtocolSuffix() + // Publish the partial column. This is idempotent if we republish the same data twice. + // Note, the "partial column" may indeed be complete. We still + // should publish to help our peers. + err = partialBroadcaster.Publish(topic, partialColumns[i]) + if err != nil { + log.WithError(err).Warn("Failed to publish partial column") + } + } + } + // No sidecars are retrieved from the EL, retry later sidecarCount := uint64(len(constructedSidecars)) if sidecarCount == 0 { @@ -245,6 +266,7 @@ func (s *Service) processDataColumnSidecarsFromExecution(ctx context.Context, so } // broadcastAndReceiveUnseenDataColumnSidecars broadcasts and receives unseen data column sidecars. +// TODO: have this accept a partial column type func (s *Service) broadcastAndReceiveUnseenDataColumnSidecars( ctx context.Context, slot primitives.Slot, @@ -271,7 +293,7 @@ func (s *Service) broadcastAndReceiveUnseenDataColumnSidecars( } // Broadcast all the data column sidecars we reconstructed but did not see via gossip (non blocking). - if err := s.cfg.p2p.BroadcastDataColumnSidecars(ctx, unseenSidecars); err != nil { + if err := s.cfg.p2p.BroadcastDataColumnSidecars(ctx, unseenSidecars, nil); err != nil { return nil, errors.Wrap(err, "broadcast data column sidecars") } diff --git a/beacon-chain/sync/subscriber_data_column_sidecar.go b/beacon-chain/sync/subscriber_data_column_sidecar.go index a051eab3bfc1..ee0108128947 100644 --- a/beacon-chain/sync/subscriber_data_column_sidecar.go +++ b/beacon-chain/sync/subscriber_data_column_sidecar.go @@ -3,13 +3,17 @@ package sync import ( "context" "fmt" + "strconv" + "strings" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed" opfeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/operation" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/config/params" "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" "github.com/OffchainLabs/prysm/v6/consensus-types/primitives" + ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "github.com/pkg/errors" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/proto" @@ -17,17 +21,19 @@ import ( // dataColumnSubscriber is the subscriber function for data column sidecars. func (s *Service) dataColumnSubscriber(ctx context.Context, msg proto.Message) error { - var wg errgroup.Group - sidecar, ok := msg.(blocks.VerifiedRODataColumn) if !ok { return fmt.Errorf("message was not type blocks.VerifiedRODataColumn, type=%T", msg) } + return s.verifiedRODataColumnSubscriber(ctx, sidecar) +} +func (s *Service) verifiedRODataColumnSubscriber(ctx context.Context, sidecar blocks.VerifiedRODataColumn) error { if err := s.receiveDataColumnSidecar(ctx, sidecar); err != nil { return errors.Wrap(err, "receive data column sidecar") } + var wg errgroup.Group wg.Go(func() error { if err := s.processDataColumnSidecarsFromReconstruction(ctx, sidecar); err != nil { return errors.Wrap(err, "process data column sidecars from reconstruction") @@ -110,3 +116,44 @@ func (s *Service) allDataColumnSubnets(_ primitives.Slot) map[uint64]bool { return allSubnets } + +// partialDataColumnSubscriber is the subscriber function for data column sidecars. +func (s *Service) partialDataColumnSubscriber(ctx context.Context, topic string, col partial.CompleteColumn) error { + suffix := s.cfg.p2p.Encoding().ProtocolSuffix() + if len(topic) < len(suffix) { + return fmt.Errorf("invalid topic format (missing suffix?): %s", topic) + } + topic = topic[:len(topic)-len(suffix)] + indexSep := strings.LastIndexByte(topic, '_') + if indexSep < 0 || indexSep == len(topic)-1 { + return fmt.Errorf("invalid topic format: %s", topic) + } + index, err := strconv.ParseUint(topic[indexSep+1:], 10, 64) + if err != nil { + return errors.New("invalid index format") + } + dc := ethpb.DataColumnSidecar{ + Index: index, + SignedBlockHeader: col.SignedBeaconBlockHeader, + + Column: make([][]byte, len(col.Cells)), + KzgProofs: make([][]byte, len(col.Proofs)), + KzgCommitments: make([][]byte, len(col.Commitments)), + + KzgCommitmentsInclusionProof: col.KzgInclusionProof, + } + + for i := range col.Cells { + dc.Column[i] = col.Cells[i][:] + dc.KzgProofs[i] = col.Proofs[i][:] + dc.KzgCommitments[i] = col.Commitments[i][:] + } + + rodc, err := blocks.NewRODataColumn(&dc) + if err != nil { + return err + } + + vrodc := blocks.NewVerifiedRODataColumn(rodc) + return s.verifiedRODataColumnSubscriber(ctx, vrodc) +} From d4966ba178ba7c663a7aaad21f27369877740134 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Wed, 8 Oct 2025 12:08:37 -0700 Subject: [PATCH 10/13] beacon-chain/rpc: publish partial columns when proposing --- .../rpc/prysm/v1alpha1/validator/BUILD.bazel | 1 + .../rpc/prysm/v1alpha1/validator/proposer.go | 35 ++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel b/beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel index 09b9336970d5..00f3351fa91f 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel @@ -64,6 +64,7 @@ go_library( "//beacon-chain/operations/synccommittee:go_default_library", "//beacon-chain/operations/voluntaryexits:go_default_library", "//beacon-chain/p2p:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", "//beacon-chain/rpc/core:go_default_library", "//beacon-chain/startup:go_default_library", "//beacon-chain/state:go_default_library", diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go index 868ce62e9f22..00d9821b1e8b 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go @@ -18,6 +18,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" "github.com/OffchainLabs/prysm/v6/beacon-chain/core/transition" "github.com/OffchainLabs/prysm/v6/beacon-chain/db/kv" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" "github.com/OffchainLabs/prysm/v6/beacon-chain/state" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" "github.com/OffchainLabs/prysm/v6/config/params" @@ -33,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" emptypb "github.com/golang/protobuf/ptypes/empty" "github.com/pkg/errors" + "github.com/prysmaticlabs/go-bitfield" "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" "google.golang.org/grpc/codes" @@ -310,10 +312,11 @@ func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSign } rob, err := blocks.NewROBlockWithRoot(block, root) + var partialColumns []partial.PartialColumn if block.IsBlinded() { block, blobSidecars, err = vs.handleBlindedBlock(ctx, block) } else if block.Version() >= version.Deneb { - blobSidecars, dataColumnSidecars, err = vs.handleUnblindedBlock(rob, req) + blobSidecars, dataColumnSidecars, partialColumns, err = vs.handleUnblindedBlock(rob, req) } if err != nil { return nil, status.Errorf(codes.Internal, "%s: %v", "handle block failed", err) @@ -333,7 +336,7 @@ func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSign wg.Wait() - if err := vs.broadcastAndReceiveSidecars(ctx, block, root, blobSidecars, dataColumnSidecars); err != nil { + if err := vs.broadcastAndReceiveSidecars(ctx, block, root, blobSidecars, dataColumnSidecars, partialColumns); err != nil { return nil, status.Errorf(codes.Internal, "Could not broadcast/receive sidecars: %v", err) } if err := <-errChan; err != nil { @@ -350,9 +353,10 @@ func (vs *Server) broadcastAndReceiveSidecars( root [fieldparams.RootLength]byte, blobSidecars []*ethpb.BlobSidecar, dataColumnSidecars []blocks.RODataColumn, + partialColumns []partial.PartialColumn, ) error { if block.Version() >= version.Fulu { - if err := vs.broadcastAndReceiveDataColumns(ctx, dataColumnSidecars); err != nil { + if err := vs.broadcastAndReceiveDataColumns(ctx, dataColumnSidecars, partialColumns); err != nil { return errors.Wrap(err, "broadcast and receive data columns") } return nil @@ -401,34 +405,41 @@ func (vs *Server) handleBlindedBlock(ctx context.Context, block interfaces.Signe func (vs *Server) handleUnblindedBlock( block blocks.ROBlock, req *ethpb.GenericSignedBeaconBlock, -) ([]*ethpb.BlobSidecar, []blocks.RODataColumn, error) { +) ([]*ethpb.BlobSidecar, []blocks.RODataColumn, []partial.PartialColumn, error) { rawBlobs, proofs, err := blobsAndProofs(req) if err != nil { - return nil, nil, err + return nil, nil, nil, err } if block.Version() >= version.Fulu { // Compute cells and proofs from the blobs and cell proofs. cellsAndProofs, err := peerdas.ComputeCellsAndProofsFromFlat(rawBlobs, proofs) if err != nil { - return nil, nil, errors.Wrap(err, "compute cells and proofs") + return nil, nil, nil, errors.Wrap(err, "compute cells and proofs") } // Construct data column sidecars from the signed block and cells and proofs. roDataColumnSidecars, err := peerdas.DataColumnSidecars(cellsAndProofs, peerdas.PopulateFromBlock(block)) if err != nil { - return nil, nil, errors.Wrap(err, "data column sidcars") + return nil, nil, nil, errors.Wrap(err, "data column sidcars") + } + + included := bitfield.NewBitlist(uint64(len(cellsAndProofs))) + included = included.Not() // all bits set to 1 + partialColumns, err := peerdas.PartialColumns(included, cellsAndProofs, peerdas.PopulateFromBlock(block)) + if err != nil { + return nil, nil, nil, errors.Wrap(err, "data column sidcars") } - return nil, roDataColumnSidecars, nil + return nil, roDataColumnSidecars, partialColumns, nil } blobSidecars, err := BuildBlobSidecars(block, rawBlobs, proofs) if err != nil { - return nil, nil, errors.Wrap(err, "build blob sidecars") + return nil, nil, nil, errors.Wrap(err, "build blob sidecars") } - return blobSidecars, nil, nil + return blobSidecars, nil, nil, nil } // broadcastReceiveBlock broadcasts a block and handles its reception. @@ -495,7 +506,7 @@ func (vs *Server) broadcastAndReceiveBlobs(ctx context.Context, sidecars []*ethp } // broadcastAndReceiveDataColumns handles the broadcasting and reception of data columns sidecars. -func (vs *Server) broadcastAndReceiveDataColumns(ctx context.Context, roSidecars []blocks.RODataColumn) error { +func (vs *Server) broadcastAndReceiveDataColumns(ctx context.Context, roSidecars []blocks.RODataColumn, partialColumns []partial.PartialColumn) error { // We built this block ourselves, so we can upgrade the read only data column sidecar into a verified one. verifiedSidecars := make([]blocks.VerifiedRODataColumn, 0, len(roSidecars)) for _, sidecar := range roSidecars { @@ -504,7 +515,7 @@ func (vs *Server) broadcastAndReceiveDataColumns(ctx context.Context, roSidecars } // Broadcast sidecars (non blocking). - if err := vs.P2P.BroadcastDataColumnSidecars(ctx, verifiedSidecars); err != nil { + if err := vs.P2P.BroadcastDataColumnSidecars(ctx, verifiedSidecars, partialColumns); err != nil { return errors.Wrap(err, "broadcast data column sidecars") } From e5ff0f2a4ac798ca0e75c9285d2bc106c40dfe72 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 14 Oct 2025 18:31:32 -0700 Subject: [PATCH 11/13] update go-libp2p to v0.44.0 --- deps.bzl | 250 ++++++++++++++++++++++++------------------------------- go.mod | 101 ++++++++++------------ go.sum | 227 ++++++++++++++++++++------------------------------ 3 files changed, 246 insertions(+), 332 deletions(-) diff --git a/deps.bzl b/deps.bzl index 0a7c64751ece..a21531f618bb 100644 --- a/deps.bzl +++ b/deps.bzl @@ -76,12 +76,6 @@ def prysm_deps(): sum = "h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=", version = "v1.2.1", ) - go_repository( - name = "com_github_andreasbriese_bbloom", - importpath = "github.com/AndreasBriese/bbloom", - sum = "h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=", - version = "v0.0.0-20190825152654-46b345b51c96", - ) go_repository( name = "com_github_andybalholm_brotli", importpath = "github.com/andybalholm/brotli", @@ -376,12 +370,6 @@ def prysm_deps(): sum = "h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=", version = "v1.1.1", ) - go_repository( - name = "com_github_cespare_xxhash", - importpath = "github.com/cespare/xxhash", - sum = "h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=", - version = "v1.1.0", - ) go_repository( name = "com_github_cespare_xxhash_v2", importpath = "github.com/cespare/xxhash/v2", @@ -406,12 +394,6 @@ def prysm_deps(): sum = "h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=", version = "v1.0.0", ) - go_repository( - name = "com_github_cilium_ebpf", - importpath = "github.com/cilium/ebpf", - sum = "h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4=", - version = "v0.9.1", - ) go_repository( name = "com_github_clbanning_x2j", importpath = "github.com/clbanning/x2j", @@ -615,14 +597,14 @@ def prysm_deps(): go_repository( name = "com_github_decred_dcrd_crypto_blake256", importpath = "github.com/decred/dcrd/crypto/blake256", - sum = "h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=", - version = "v1.0.1", + sum = "h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=", + version = "v1.1.0", ) go_repository( name = "com_github_decred_dcrd_dcrec_secp256k1_v4", importpath = "github.com/decred/dcrd/dcrec/secp256k1/v4", - sum = "h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=", - version = "v4.3.0", + sum = "h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=", + version = "v4.4.0", ) go_repository( name = "com_github_deepmap_oapi_codegen", @@ -630,18 +612,6 @@ def prysm_deps(): sum = "h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=", version = "v1.8.2", ) - go_repository( - name = "com_github_dgraph_io_badger", - importpath = "github.com/dgraph-io/badger", - sum = "h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8=", - version = "v1.6.2", - ) - go_repository( - name = "com_github_dgraph_io_ristretto", - importpath = "github.com/dgraph-io/ristretto", - sum = "h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po=", - version = "v0.0.2", - ) go_repository( name = "com_github_dgraph_io_ristretto_v2", importpath = "github.com/dgraph-io/ristretto/v2", @@ -1644,20 +1614,8 @@ def prysm_deps(): go_repository( name = "com_github_ipfs_go_datastore", importpath = "github.com/ipfs/go-datastore", - sum = "h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=", - version = "v0.6.0", - ) - go_repository( - name = "com_github_ipfs_go_ds_badger", - importpath = "github.com/ipfs/go-ds-badger", - sum = "h1:xREL3V0EH9S219kFFueOYJJTcjgNSZ2HY1iSvN7U1Ro=", - version = "v0.3.0", - ) - go_repository( - name = "com_github_ipfs_go_ds_leveldb", - importpath = "github.com/ipfs/go-ds-leveldb", - sum = "h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUNumo=", - version = "v0.5.0", + sum = "h1:Jy3wjqQR6sg/LhyY0NIePZC3Vux19nLtg7dx0TVqr6U=", + version = "v0.8.2", ) go_repository( name = "com_github_ipfs_go_log_v2", @@ -1684,12 +1642,6 @@ def prysm_deps(): sum = "h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=", version = "v0.1.0", ) - go_repository( - name = "com_github_jbenet_goprocess", - importpath = "github.com/jbenet/goprocess", - sum = "h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o=", - version = "v0.1.4", - ) go_repository( name = "com_github_jcmturner_gofork", importpath = "github.com/jcmturner/gofork", @@ -1850,8 +1802,8 @@ def prysm_deps(): go_repository( name = "com_github_klauspost_compress", importpath = "github.com/klauspost/compress", - sum = "h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=", - version = "v1.17.11", + sum = "h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=", + version = "v1.18.0", ) go_repository( name = "com_github_klauspost_cpuid", @@ -1862,8 +1814,8 @@ def prysm_deps(): go_repository( name = "com_github_klauspost_cpuid_v2", importpath = "github.com/klauspost/cpuid/v2", - sum = "h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=", - version = "v2.2.9", + sum = "h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=", + version = "v2.2.10", ) go_repository( name = "com_github_klauspost_reedsolomon", @@ -1886,8 +1838,8 @@ def prysm_deps(): go_repository( name = "com_github_koron_go_ssdp", importpath = "github.com/koron/go-ssdp", - sum = "h1:E1iSMxIs4WqxTbIBLtmNBeOOC+1sCIXQeqTWVnpmwhk=", - version = "v0.0.5", + sum = "h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU=", + version = "v0.0.6", ) go_repository( name = "com_github_korovkin_limiter", @@ -1974,8 +1926,8 @@ def prysm_deps(): ], build_file_proto_mode = "disable_global", importpath = "github.com/libp2p/go-libp2p", - sum = "h1:1Ur6rPCf3GR+g8jkrnaQaM0ha2IGespsnNlCqJLLALE=", - version = "v0.39.1", + sum = "h1:5Gtt8OrF8yiXmH+Mx4+/iBeFRMK1TY3a8OrEBDEqAvs=", + version = "v0.44.0", ) go_repository( name = "com_github_libp2p_go_libp2p_asn_util", @@ -1986,8 +1938,8 @@ def prysm_deps(): go_repository( name = "com_github_libp2p_go_libp2p_mplex", importpath = "github.com/libp2p/go-libp2p-mplex", - sum = "h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8=", - version = "v0.9.0", + sum = "h1:0vwpLXRSfkTzshEjETIEgJaVxXvg+orbxYoIb3Ty5qM=", + version = "v0.11.0", ) go_repository( name = "com_github_libp2p_go_libp2p_pubsub", @@ -2023,8 +1975,8 @@ def prysm_deps(): go_repository( name = "com_github_libp2p_go_netroute", importpath = "github.com/libp2p/go-netroute", - sum = "h1:Dejd8cQ47Qx2kRABg6lPwknU7+nBnFRpko45/fFPuZ8=", - version = "v0.2.2", + sum = "h1:nqPCXHmeNmgTJnktosJ/sIef9hvwYCrsLxXmfNks/oc=", + version = "v0.3.0", ) go_repository( name = "com_github_libp2p_go_reuseport", @@ -2038,6 +1990,12 @@ def prysm_deps(): sum = "h1:nrLh89LN/LEiqcFiqdKDRHjGstN300C1269K/EX0CPU=", version = "v4.0.2", ) + go_repository( + name = "com_github_libp2p_go_yamux_v5", + importpath = "github.com/libp2p/go-yamux/v5", + sum = "h1:f0WoX/bEF2E8SbE4c/k1Mo+/9z0O4oC/hWEA+nfYRSg=", + version = "v5.0.1", + ) go_repository( name = "com_github_libp2p_zeroconf_v2", importpath = "github.com/libp2p/zeroconf/v2", @@ -2104,6 +2062,12 @@ def prysm_deps(): sum = "h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4=", version = "v0.7.0", ) + go_repository( + name = "com_github_marcopolo_simnet", + importpath = "github.com/marcopolo/simnet", + sum = "h1:rSMslhPz6q9IvJeFWDoMGxMIrlsbXau3NkuIXHGJxfg=", + version = "v0.0.1", + ) go_repository( name = "com_github_mariusvanderwijden_fuzzyvm", importpath = "github.com/MariusVanDerWijden/FuzzyVM", @@ -2179,8 +2143,8 @@ def prysm_deps(): go_repository( name = "com_github_miekg_dns", importpath = "github.com/miekg/dns", - sum = "h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=", - version = "v1.1.63", + sum = "h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=", + version = "v1.1.66", ) go_repository( name = "com_github_mikioh_tcp", @@ -2323,8 +2287,8 @@ def prysm_deps(): go_repository( name = "com_github_multiformats_go_multiaddr", importpath = "github.com/multiformats/go-multiaddr", - sum = "h1:bfrHrJhrRuh/NXH5mCnemjpbGjzRw/b+tJFOD41g2tU=", - version = "v0.14.0", + sum = "h1:oGWEVKioVQcdIOBlYM8BH1rZDWOGJSqr9/BKl6zQ4qc=", + version = "v0.16.0", ) go_repository( name = "com_github_multiformats_go_multiaddr_dns", @@ -2350,8 +2314,8 @@ def prysm_deps(): "gazelle:exclude gen.go", ], importpath = "github.com/multiformats/go-multicodec", - sum = "h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=", - version = "v0.9.0", + sum = "h1:x/Fuxr7ZuR4jJV4Os5g444F7xC4XmyUaT/FWtE+9Zjo=", + version = "v0.9.1", ) go_repository( name = "com_github_multiformats_go_multihash", @@ -2362,8 +2326,8 @@ def prysm_deps(): go_repository( name = "com_github_multiformats_go_multistream", importpath = "github.com/multiformats/go-multistream", - sum = "h1:ZaHKbsL404720283o4c/IHQXiS6gb8qAN5EIJ4PN5EA=", - version = "v0.6.0", + sum = "h1:4aoX5v6T+yWmc2raBHsTvzmFhOI8WVOer28DeBBEYdQ=", + version = "v0.6.1", ) go_repository( name = "com_github_multiformats_go_varint", @@ -2446,8 +2410,8 @@ def prysm_deps(): go_repository( name = "com_github_nxadm_tail", importpath = "github.com/nxadm/tail", - sum = "h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=", - version = "v1.4.11", + sum = "h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=", + version = "v1.4.4", ) go_repository( name = "com_github_oklog_oklog", @@ -2650,8 +2614,8 @@ def prysm_deps(): go_repository( name = "com_github_pion_dtls_v3", importpath = "github.com/pion/dtls/v3", - sum = "h1:44CZekewMzfrn9pmGrj5BNnTMDCFwr+6sLH+cCuLM7U=", - version = "v3.0.4", + sum = "h1:7Hkd8WhAJNbRgq9RgdNh1aaWlZlGpYTzdqjy9x9sK2E=", + version = "v3.0.6", ) go_repository( name = "com_github_pion_ice_v2", @@ -2662,14 +2626,14 @@ def prysm_deps(): go_repository( name = "com_github_pion_ice_v4", importpath = "github.com/pion/ice/v4", - sum = "h1:jmM9HwI9lfetQV/39uD0nY4y++XZNPhvzIPCb8EwxUM=", - version = "v4.0.6", + sum = "h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4=", + version = "v4.0.10", ) go_repository( name = "com_github_pion_interceptor", importpath = "github.com/pion/interceptor", - sum = "h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI=", - version = "v0.1.37", + sum = "h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4=", + version = "v0.1.40", ) go_repository( name = "com_github_pion_logging", @@ -2704,26 +2668,26 @@ def prysm_deps(): go_repository( name = "com_github_pion_rtp", importpath = "github.com/pion/rtp", - sum = "h1:17xjnY5WO5hgO6SD3/NTIUPvSFw/PbLsIJyz1r1yNIk=", - version = "v1.8.11", + sum = "h1:jhdO/3XhL/aKm/wARFVmvTfq0lC/CvN1xwYKmduly3c=", + version = "v1.8.19", ) go_repository( name = "com_github_pion_sctp", importpath = "github.com/pion/sctp", - sum = "h1:qwtKvNK1Wc5tHMIYgTDJhfZk7vATGVHhXbUDfHbYwzA=", - version = "v1.8.35", + sum = "h1:PJma40vRHa3UTO3C4MyeJDQ+KIobVYRZQZ0Nt7SjQnE=", + version = "v1.8.39", ) go_repository( name = "com_github_pion_sdp_v3", importpath = "github.com/pion/sdp/v3", - sum = "h1:6MChLE/1xYB+CjumMw+gZ9ufp2DPApuVSnDT8t5MIgA=", - version = "v3.0.10", + sum = "h1:uN3SS2b+QDZnWXgdr69SM8KB4EbcnPnPf2Laxhty/l4=", + version = "v3.0.13", ) go_repository( name = "com_github_pion_srtp_v3", importpath = "github.com/pion/srtp/v3", - sum = "h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M=", - version = "v3.0.4", + sum = "h1:E2gyj1f5X10sB/qILUGIkL4C2CqK269Xq167PbGCc/4=", + version = "v3.0.6", ) go_repository( name = "com_github_pion_stun", @@ -2764,14 +2728,14 @@ def prysm_deps(): go_repository( name = "com_github_pion_turn_v4", importpath = "github.com/pion/turn/v4", - sum = "h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM=", - version = "v4.0.0", + sum = "h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps=", + version = "v4.0.2", ) go_repository( name = "com_github_pion_webrtc_v4", importpath = "github.com/pion/webrtc/v4", - sum = "h1:T1ZmnT9qxIJIt4d8XoiMOBrTClGHDDXNg9e/fh018Qc=", - version = "v4.0.8", + sum = "h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54=", + version = "v4.1.2", ) go_repository( name = "com_github_pkg_diff", @@ -2824,26 +2788,26 @@ def prysm_deps(): go_repository( name = "com_github_prometheus_client_golang", importpath = "github.com/prometheus/client_golang", - sum = "h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=", - version = "v1.20.5", + sum = "h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=", + version = "v1.22.0", ) go_repository( name = "com_github_prometheus_client_model", importpath = "github.com/prometheus/client_model", - sum = "h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=", - version = "v0.6.1", + sum = "h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=", + version = "v0.6.2", ) go_repository( name = "com_github_prometheus_common", importpath = "github.com/prometheus/common", - sum = "h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=", - version = "v0.62.0", + sum = "h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4=", + version = "v0.64.0", ) go_repository( name = "com_github_prometheus_procfs", importpath = "github.com/prometheus/procfs", - sum = "h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=", - version = "v0.15.1", + sum = "h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=", + version = "v0.16.1", ) go_repository( name = "com_github_prometheus_prom2json", @@ -2915,14 +2879,14 @@ def prysm_deps(): "gazelle:exclude tools.go", ], importpath = "github.com/quic-go/quic-go", - sum = "h1:x09Agz4ATTMEP3qb5P0MRxNZfd6O9wAyK3qwwqQZVQc=", - version = "v0.49.1-0.20250925085836-275c172fec2b", + sum = "h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk=", + version = "v0.55.0", ) go_repository( name = "com_github_quic_go_webtransport_go", importpath = "github.com/quic-go/webtransport-go", - sum = "h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=", - version = "v0.8.1-0.20241018022711-4ac2c9250e66", + sum = "h1:jgys+7/wm6JarGDrW+lD/r9BGqBAmqY/ssklE09bA70=", + version = "v0.9.0", ) go_repository( name = "com_github_r3labs_sse_v2", @@ -3426,8 +3390,8 @@ def prysm_deps(): go_repository( name = "com_github_urfave_cli", importpath = "github.com/urfave/cli", - sum = "h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=", - version = "v1.22.2", + sum = "h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=", + version = "v1.22.1", ) go_repository( name = "com_github_urfave_cli_v2", @@ -4347,8 +4311,8 @@ def prysm_deps(): go_repository( name = "com_lukechampine_blake3", importpath = "lukechampine.com/blake3", - sum = "h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=", - version = "v1.3.0", + sum = "h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=", + version = "v1.4.1", ) go_repository( name = "com_shuralyov_dmitri_app_changes", @@ -4772,8 +4736,8 @@ def prysm_deps(): go_repository( name = "org_golang_google_protobuf", importpath = "google.golang.org/protobuf", - sum = "h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=", - version = "v1.36.5", + sum = "h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=", + version = "v1.36.6", ) go_repository( name = "org_golang_x_build", @@ -4784,14 +4748,14 @@ def prysm_deps(): go_repository( name = "org_golang_x_crypto", importpath = "golang.org/x/crypto", - sum = "h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=", - version = "v0.36.0", + sum = "h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=", + version = "v0.41.0", ) go_repository( name = "org_golang_x_exp", importpath = "golang.org/x/exp", - sum = "h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc=", - version = "v0.0.0-20250128182459-e0ece0dbea4c", + sum = "h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4=", + version = "v0.0.0-20250606033433-dcc06ee1d476", ) go_repository( name = "org_golang_x_exp_typeparams", @@ -4820,20 +4784,20 @@ def prysm_deps(): go_repository( name = "org_golang_x_mod", importpath = "golang.org/x/mod", - sum = "h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=", - version = "v0.23.0", + sum = "h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=", + version = "v0.27.0", ) go_repository( name = "org_golang_x_net", importpath = "golang.org/x/net", - sum = "h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=", - version = "v0.38.0", + sum = "h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=", + version = "v0.43.0", ) go_repository( name = "org_golang_x_oauth2", importpath = "golang.org/x/oauth2", - sum = "h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=", - version = "v0.25.0", + sum = "h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=", + version = "v0.30.0", ) go_repository( name = "org_golang_x_perf", @@ -4844,44 +4808,50 @@ def prysm_deps(): go_repository( name = "org_golang_x_sync", importpath = "golang.org/x/sync", - sum = "h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=", - version = "v0.12.0", + sum = "h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=", + version = "v0.16.0", ) go_repository( name = "org_golang_x_sys", importpath = "golang.org/x/sys", - sum = "h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=", - version = "v0.31.0", + sum = "h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=", + version = "v0.35.0", ) go_repository( name = "org_golang_x_telemetry", importpath = "golang.org/x/telemetry", - sum = "h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk=", - version = "v0.0.0-20240521205824-bda55230c457", + sum = "h1:3doPGa+Gg4snce233aCWnbZVFsyFMo/dR40KK/6skyE=", + version = "v0.0.0-20250807160809-1a19826ec488", ) go_repository( name = "org_golang_x_term", importpath = "golang.org/x/term", - sum = "h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=", - version = "v0.30.0", + sum = "h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=", + version = "v0.34.0", ) go_repository( name = "org_golang_x_text", importpath = "golang.org/x/text", - sum = "h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=", - version = "v0.23.0", + sum = "h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=", + version = "v0.28.0", ) go_repository( name = "org_golang_x_time", importpath = "golang.org/x/time", - sum = "h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=", - version = "v0.9.0", + sum = "h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=", + version = "v0.12.0", ) go_repository( name = "org_golang_x_tools", importpath = "golang.org/x/tools", - sum = "h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=", - version = "v0.30.0", + sum = "h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=", + version = "v0.36.0", + ) + go_repository( + name = "org_golang_x_tools_go_expect", + importpath = "golang.org/x/tools/go/expect", + sum = "h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=", + version = "v0.1.1-deprecated", ) go_repository( name = "org_golang_x_xerrors", @@ -4909,14 +4879,14 @@ def prysm_deps(): go_repository( name = "org_uber_go_dig", importpath = "go.uber.org/dig", - sum = "h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=", - version = "v1.18.0", + sum = "h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4=", + version = "v1.19.0", ) go_repository( name = "org_uber_go_fx", importpath = "go.uber.org/fx", - sum = "h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=", - version = "v1.23.0", + sum = "h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg=", + version = "v1.24.0", ) go_repository( name = "org_uber_go_goleak", diff --git a/go.mod b/go.mod index bb90d6ef792d..07edf9cf46cc 100644 --- a/go.mod +++ b/go.mod @@ -41,23 +41,24 @@ require ( github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 github.com/kisielk/errcheck v1.8.0 github.com/kr/pretty v0.3.1 - github.com/libp2p/go-libp2p v0.39.1 - github.com/libp2p/go-libp2p-mplex v0.9.0 + github.com/libp2p/go-libp2p v0.44.0 + github.com/libp2p/go-libp2p-mplex v0.11.0 github.com/libp2p/go-libp2p-pubsub v0.14.4-0.20251015023843-34e9bbaae96d github.com/libp2p/go-mplex v0.7.0 github.com/logrusorgru/aurora v2.0.3+incompatible github.com/manifoldco/promptui v0.7.0 + github.com/marcopolo/simnet v0.0.1 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b github.com/minio/highwayhash v1.0.2 github.com/minio/sha256-simd v1.0.1 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 - github.com/multiformats/go-multiaddr v0.14.0 + github.com/multiformats/go-multiaddr v0.16.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/paulbellamy/ratecounter v0.2.0 github.com/pborman/uuid v1.2.1 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.20.5 - github.com/prometheus/client_model v0.6.1 + github.com/prometheus/client_golang v1.22.0 + github.com/prometheus/client_model v0.6.2 github.com/prometheus/prom2json v1.3.0 github.com/prysmaticlabs/fastssz v0.0.0-20241008181541-518c4ce73516 github.com/prysmaticlabs/go-bitfield v0.0.0-20240328144219-a1caa50c3a1e @@ -88,13 +89,13 @@ require ( go.opentelemetry.io/otel/trace v1.35.0 go.uber.org/automaxprocs v1.5.2 go.uber.org/mock v0.5.2 - golang.org/x/crypto v0.36.0 - golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c - golang.org/x/sync v0.12.0 - golang.org/x/tools v0.30.0 + golang.org/x/crypto v0.41.0 + golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 + golang.org/x/sync v0.16.0 + golang.org/x/tools v0.36.0 google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 google.golang.org/grpc v1.71.0 - google.golang.org/protobuf v1.36.5 + google.golang.org/protobuf v1.36.6 gopkg.in/d4l3k/messagediff.v1 v1.2.1 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 @@ -122,19 +123,15 @@ require ( github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.22 // indirect - github.com/containerd/cgroups v1.1.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/deepmap/oapi-codegen v1.8.2 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/docker/go-units v0.5.0 // indirect github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect - github.com/elastic/gosigar v0.14.3 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -146,10 +143,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect - github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20250202011525-fc3143867406 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect @@ -167,26 +161,25 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect - github.com/klauspost/compress v1.17.11 // indirect - github.com/klauspost/cpuid/v2 v2.2.9 // indirect - github.com/koron/go-ssdp v0.0.5 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/koron/go-ssdp v0.0.6 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.3 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-flow-metrics v0.2.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect - github.com/libp2p/go-nat v0.2.0 // indirect - github.com/libp2p/go-netroute v0.2.2 // indirect + github.com/libp2p/go-netroute v0.3.0 // indirect github.com/libp2p/go-reuseport v0.4.0 // indirect - github.com/libp2p/go-yamux/v4 v4.0.2 // indirect + github.com/libp2p/go-yamux/v5 v5.0.1 // indirect github.com/lunixbochs/vtclean v1.0.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.63 // indirect + github.com/miekg/dns v1.1.66 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect @@ -201,46 +194,41 @@ require ( github.com/multiformats/go-multiaddr-dns v0.4.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect - github.com/multiformats/go-multicodec v0.9.0 // indirect + github.com/multiformats/go-multicodec v0.9.1 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect - github.com/multiformats/go-multistream v0.6.0 // indirect + github.com/multiformats/go-multistream v0.6.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.22.2 // indirect - github.com/opencontainers/runtime-spec v1.2.0 // indirect + github.com/onsi/gomega v1.36.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pion/datachannel v1.5.10 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect - github.com/pion/dtls/v3 v3.0.4 // indirect - github.com/pion/ice/v2 v2.3.37 // indirect - github.com/pion/ice/v4 v4.0.6 // indirect - github.com/pion/interceptor v0.1.37 // indirect + github.com/pion/dtls/v3 v3.0.6 // indirect + github.com/pion/ice/v4 v4.0.10 // indirect + github.com/pion/interceptor v0.1.40 // indirect github.com/pion/logging v0.2.3 // indirect - github.com/pion/mdns v0.0.12 // indirect github.com/pion/mdns/v2 v2.0.7 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.15 // indirect - github.com/pion/rtp v1.8.11 // indirect - github.com/pion/sctp v1.8.35 // indirect - github.com/pion/sdp/v3 v3.0.10 // indirect - github.com/pion/srtp/v3 v3.0.4 // indirect + github.com/pion/rtp v1.8.19 // indirect + github.com/pion/sctp v1.8.39 // indirect + github.com/pion/sdp/v3 v3.0.13 // indirect + github.com/pion/srtp/v3 v3.0.6 // indirect github.com/pion/stun v0.6.1 // indirect github.com/pion/stun/v2 v2.0.0 // indirect github.com/pion/stun/v3 v3.0.0 // indirect github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/transport/v3 v3.0.7 // indirect - github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/turn/v4 v4.0.0 // indirect - github.com/pion/webrtc/v4 v4.0.8 // indirect + github.com/pion/turn/v4 v4.0.2 // indirect + github.com/pion/webrtc/v4 v4.1.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/common v0.64.0 // indirect + github.com/prometheus/procfs v0.16.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect - github.com/quic-go/quic-go v0.49.1-0.20250925085836-275c172fec2b // indirect - github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect - github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/quic-go/quic-go v0.55.0 // indirect + github.com/quic-go/webtransport-go v0.9.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -258,21 +246,22 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect - go.uber.org/dig v1.18.0 // indirect - go.uber.org/fx v1.23.0 // indirect + go.uber.org/dig v1.19.0 // indirect + go.uber.org/fx v1.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.9.0 // indirect + golang.org/x/mod v0.27.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/term v0.34.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/time v0.12.0 // indirect + golang.org/x/tools/go/expect v0.1.1-deprecated // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - lukechampine.com/blake3 v1.3.0 // indirect + lukechampine.com/blake3 v1.4.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect @@ -288,7 +277,7 @@ require ( github.com/go-playground/validator/v10 v10.13.0 github.com/peterh/liner v1.2.0 // indirect github.com/prysmaticlabs/gohashtree v0.0.5-beta - golang.org/x/sys v0.31.0 // indirect + golang.org/x/sys v0.35.0 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect ) diff --git a/go.sum b/go.sum index b0c148624b9b..fce0f57375ef 100644 --- a/go.sum +++ b/go.sum @@ -90,7 +90,6 @@ github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZw github.com/bazelbuild/rules_go v0.23.2 h1:Wxu7JjqnF78cKZbsBsARLSXx/jlGaSLCnUV3mTlyHvM= github.com/bazelbuild/rules_go v0.23.2/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -128,7 +127,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= -github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -154,20 +152,13 @@ github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= -github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= @@ -186,10 +177,10 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= -github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= +github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= @@ -201,9 +192,6 @@ github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUn github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= @@ -218,9 +206,6 @@ github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= -github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/emicklei/dot v0.11.0 h1:Ase39UD9T9fRBOb5ptgpixrxfx8abVzNWZi2+lr53PI= github.com/emicklei/dot v0.11.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= @@ -315,21 +300,14 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= @@ -397,8 +375,6 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -420,7 +396,6 @@ github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -540,24 +515,23 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.8.0 h1:ZX/URYa7ilESY19ik/vBmCn6zdGQLxACwjAcWbHlYlg= github.com/kisielk/errcheck v1.8.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= -github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.5 h1:E1iSMxIs4WqxTbIBLtmNBeOOC+1sCIXQeqTWVnpmwhk= -github.com/koron/go-ssdp v0.0.5/go.mod h1:Qm59B7hpKpDqfyRNWRNr00jGwLdXjDyZh6y7rH6VS0w= +github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU= +github.com/koron/go-ssdp v0.0.6/go.mod h1:0R9LfRJGek1zWTjN3JUNlm5INCDYGpRDfAptnct63fI= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -583,12 +557,12 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw= github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc= -github.com/libp2p/go-libp2p v0.39.1 h1:1Ur6rPCf3GR+g8jkrnaQaM0ha2IGespsnNlCqJLLALE= -github.com/libp2p/go-libp2p v0.39.1/go.mod h1:3zicI8Lp7Isun+Afo/JOACUbbJqqR2owK6RQWFsVAbI= +github.com/libp2p/go-libp2p v0.44.0 h1:5Gtt8OrF8yiXmH+Mx4+/iBeFRMK1TY3a8OrEBDEqAvs= +github.com/libp2p/go-libp2p v0.44.0/go.mod h1:NovCojezAt4dnDd4fH048K7PKEqH0UFYYqJRjIIu8zc= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= -github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8= -github.com/libp2p/go-libp2p-mplex v0.9.0/go.mod h1:ro1i4kuwiFT+uMPbIDIFkcLs1KRbNp0QwnUXM+P64Og= +github.com/libp2p/go-libp2p-mplex v0.11.0 h1:0vwpLXRSfkTzshEjETIEgJaVxXvg+orbxYoIb3Ty5qM= +github.com/libp2p/go-libp2p-mplex v0.11.0/go.mod h1:QrsdNY3lzjpdo9V1goJfPb0O65Nms0sUR8CDAO18f6k= github.com/libp2p/go-libp2p-pubsub v0.14.4-0.20251015023843-34e9bbaae96d h1:g1oEz1sfyMpSoZV1ERCO6cCclzqDbFXb2CRL55/Pey0= github.com/libp2p/go-libp2p-pubsub v0.14.4-0.20251015023843-34e9bbaae96d/go.mod h1:lr4oE8bFgQaifRcoc2uWhWWiK6tPdOEKpUuR408GFN4= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= @@ -597,14 +571,12 @@ github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= -github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= -github.com/libp2p/go-netroute v0.2.2 h1:Dejd8cQ47Qx2kRABg6lPwknU7+nBnFRpko45/fFPuZ8= -github.com/libp2p/go-netroute v0.2.2/go.mod h1:Rntq6jUAH0l9Gg17w5bFGhcC9a+vk4KNXs6s7IljKYE= +github.com/libp2p/go-netroute v0.3.0 h1:nqPCXHmeNmgTJnktosJ/sIef9hvwYCrsLxXmfNks/oc= +github.com/libp2p/go-netroute v0.3.0/go.mod h1:Nkd5ShYgSMS5MUKy/MU2T57xFoOKvvLR92Lic48LEyA= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= -github.com/libp2p/go-yamux/v4 v4.0.2 h1:nrLh89LN/LEiqcFiqdKDRHjGstN300C1269K/EX0CPU= -github.com/libp2p/go-yamux/v4 v4.0.2/go.mod h1:C808cCRgOs1iBwY4S71T5oxgMxgLmqUw56qh4AeBW2o= +github.com/libp2p/go-yamux/v5 v5.0.1 h1:f0WoX/bEF2E8SbE4c/k1Mo+/9z0O4oC/hWEA+nfYRSg= +github.com/libp2p/go-yamux/v5 v5.0.1/go.mod h1:en+3cdX51U0ZslwRdRLrvQsdayFt3TSUKvBGErzpWbU= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= @@ -621,6 +593,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.7.0 h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4= github.com/manifoldco/promptui v0.7.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= +github.com/marcopolo/simnet v0.0.1 h1:rSMslhPz6q9IvJeFWDoMGxMIrlsbXau3NkuIXHGJxfg= +github.com/marcopolo/simnet v0.0.1/go.mod h1:WDaQkgLAjqDUEBAOXz22+1j6wXKfGlC5sD5XWt3ddOs= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= @@ -653,8 +627,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1f github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= -github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= +github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE= +github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -703,21 +677,21 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= -github.com/multiformats/go-multiaddr v0.14.0 h1:bfrHrJhrRuh/NXH5mCnemjpbGjzRw/b+tJFOD41g2tU= -github.com/multiformats/go-multiaddr v0.14.0/go.mod h1:6EkVAxtznq2yC3QT5CM1UTAwG0GTP3EWAIcjHuzQ+r4= +github.com/multiformats/go-multiaddr v0.16.0 h1:oGWEVKioVQcdIOBlYM8BH1rZDWOGJSqr9/BKl6zQ4qc= +github.com/multiformats/go-multiaddr v0.16.0/go.mod h1:JSVUmXDjsVFiW7RjIFMP7+Ev+h1DTbiJgVeTV/tcmP0= github.com/multiformats/go-multiaddr-dns v0.4.1 h1:whi/uCLbDS3mSEUMb1MsoT4uzUeZB0N32yzufqS0i5M= github.com/multiformats/go-multiaddr-dns v0.4.1/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= -github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multicodec v0.9.1 h1:x/Fuxr7ZuR4jJV4Os5g444F7xC4XmyUaT/FWtE+9Zjo= +github.com/multiformats/go-multicodec v0.9.1/go.mod h1:LLWNMtyV5ithSBUo3vFIMaeDy+h3EbkMTek1m+Fybbo= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.6.0 h1:ZaHKbsL404720283o4c/IHQXiS6gb8qAN5EIJ4PN5EA= -github.com/multiformats/go-multistream v0.6.0/go.mod h1:MOyoG5otO24cHIg8kf9QW2/NozURlkP/rvi2FQJyCPg= +github.com/multiformats/go-multistream v0.6.1 h1:4aoX5v6T+yWmc2raBHsTvzmFhOI8WVOer28DeBBEYdQ= +github.com/multiformats/go-multistream v0.6.1/go.mod h1:ksQf6kqHAb6zIsyw7Zm+gAuVo57Qbq84E27YlYqavqw= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -733,9 +707,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= -github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -748,8 +721,6 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= -github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -759,9 +730,6 @@ github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlR github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= -github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -803,33 +771,29 @@ github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oL github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/dtls/v3 v3.0.4 h1:44CZekewMzfrn9pmGrj5BNnTMDCFwr+6sLH+cCuLM7U= -github.com/pion/dtls/v3 v3.0.4/go.mod h1:R373CsjxWqNPf6MEkfdy3aSe9niZvL/JaKlGeFphtMg= -github.com/pion/ice/v2 v2.3.37 h1:ObIdaNDu1rCo7hObhs34YSBcO7fjslJMZV0ux+uZWh0= -github.com/pion/ice/v2 v2.3.37/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= -github.com/pion/ice/v4 v4.0.6 h1:jmM9HwI9lfetQV/39uD0nY4y++XZNPhvzIPCb8EwxUM= -github.com/pion/ice/v4 v4.0.6/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw= -github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI= -github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y= +github.com/pion/dtls/v3 v3.0.6 h1:7Hkd8WhAJNbRgq9RgdNh1aaWlZlGpYTzdqjy9x9sK2E= +github.com/pion/dtls/v3 v3.0.6/go.mod h1:iJxNQ3Uhn1NZWOMWlLxEEHAN5yX7GyPvvKw04v9bzYU= +github.com/pion/ice/v4 v4.0.10 h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4= +github.com/pion/ice/v4 v4.0.10/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw= +github.com/pion/interceptor v0.1.40 h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4= +github.com/pion/interceptor v0.1.40/go.mod h1:Z6kqH7M/FYirg3frjGJ21VLSRJGBXB/KqaTIrdqnOic= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/logging v0.2.3 h1:gHuf0zpoh1GW67Nr6Gj4cv5Z9ZscU7g/EaoC/Ke/igI= github.com/pion/logging v0.2.3/go.mod h1:z8YfknkquMe1csOrxK5kc+5/ZPAzMxbKLX5aXpbpC90= -github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= -github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= github.com/pion/mdns/v2 v2.0.7 h1:c9kM8ewCgjslaAmicYMFQIde2H9/lrZpjBkN8VwoVtM= github.com/pion/mdns/v2 v2.0.7/go.mod h1:vAdSYNAT0Jy3Ru0zl2YiW3Rm/fJCwIeM0nToenfOJKA= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= github.com/pion/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo= github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0= -github.com/pion/rtp v1.8.11 h1:17xjnY5WO5hgO6SD3/NTIUPvSFw/PbLsIJyz1r1yNIk= -github.com/pion/rtp v1.8.11/go.mod h1:8uMBJj32Pa1wwx8Fuv/AsFhn8jsgw+3rUC2PfoBZ8p4= -github.com/pion/sctp v1.8.35 h1:qwtKvNK1Wc5tHMIYgTDJhfZk7vATGVHhXbUDfHbYwzA= -github.com/pion/sctp v1.8.35/go.mod h1:EcXP8zCYVTRy3W9xtOF7wJm1L1aXfKRQzaM33SjQlzg= -github.com/pion/sdp/v3 v3.0.10 h1:6MChLE/1xYB+CjumMw+gZ9ufp2DPApuVSnDT8t5MIgA= -github.com/pion/sdp/v3 v3.0.10/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E= -github.com/pion/srtp/v3 v3.0.4 h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M= -github.com/pion/srtp/v3 v3.0.4/go.mod h1:1Jx3FwDoxpRaTh1oRV8A/6G1BnFL+QI82eK4ms8EEJQ= +github.com/pion/rtp v1.8.19 h1:jhdO/3XhL/aKm/wARFVmvTfq0lC/CvN1xwYKmduly3c= +github.com/pion/rtp v1.8.19/go.mod h1:bAu2UFKScgzyFqvUKmbvzSdPr+NGbZtv6UB2hesqXBk= +github.com/pion/sctp v1.8.39 h1:PJma40vRHa3UTO3C4MyeJDQ+KIobVYRZQZ0Nt7SjQnE= +github.com/pion/sctp v1.8.39/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE= +github.com/pion/sdp/v3 v3.0.13 h1:uN3SS2b+QDZnWXgdr69SM8KB4EbcnPnPf2Laxhty/l4= +github.com/pion/sdp/v3 v3.0.13/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E= +github.com/pion/srtp/v3 v3.0.6 h1:E2gyj1f5X10sB/qILUGIkL4C2CqK269Xq167PbGCc/4= +github.com/pion/srtp/v3 v3.0.6/go.mod h1:BxvziG3v/armJHAaJ87euvkhHqWe9I7iiOy50K2QkhY= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= @@ -843,13 +807,10 @@ github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= -github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= -github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM= -github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA= -github.com/pion/webrtc/v4 v4.0.8 h1:T1ZmnT9qxIJIt4d8XoiMOBrTClGHDDXNg9e/fh018Qc= -github.com/pion/webrtc/v4 v4.0.8/go.mod h1:HHBeUVBAC+j4ZFnYhovEFStF02Arb1EyD4G7e7HBTJw= +github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps= +github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs= +github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54= +github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -872,16 +833,16 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -889,8 +850,8 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4= +github.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -899,8 +860,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/prometheus/prom2json v1.3.0 h1:BlqrtbT9lLH3ZsOVhXPsHzFrApCTKRifB7gjJuypu6Y= github.com/prometheus/prom2json v1.3.0/go.mod h1:rMN7m0ApCowcoDlypBHlkNbp5eJQf/+1isKykIP5ZnM= github.com/prysmaticlabs/fastssz v0.0.0-20241008181541-518c4ce73516 h1:xuVAdtz5ShYblG2sPyb4gw01DF8InbOI/kBCQjk7NiM= @@ -916,14 +877,12 @@ github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294 h github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.49.1-0.20250925085836-275c172fec2b h1:x09Agz4ATTMEP3qb5P0MRxNZfd6O9wAyK3qwwqQZVQc= -github.com/quic-go/quic-go v0.49.1-0.20250925085836-275c172fec2b/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s= -github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg= -github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw= +github.com/quic-go/quic-go v0.55.0 h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk= +github.com/quic-go/quic-go v0.55.0/go.mod h1:DR51ilwU1uE164KuWXhinFcKWGlEjzys2l8zUl5Ss1U= +github.com/quic-go/webtransport-go v0.9.0 h1:jgys+7/wm6JarGDrW+lD/r9BGqBAmqY/ssklE09bA70= +github.com/quic-go/webtransport-go v0.9.0/go.mod h1:4FUYIiUc75XSsF6HShcLeXXYZJ9AGwo/xh3L8M/P1ao= github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= -github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= -github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -976,7 +935,6 @@ github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5k github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -1046,7 +1004,6 @@ github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/uudashr/gocognit v1.0.5 h1:rrSex7oHr3/pPLQ0xoWq108XMU8s678FJcQ+aSfOHa4= @@ -1127,10 +1084,10 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= -go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= -go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4= +go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg= +go.uber.org/fx v1.24.0/go.mod h1:AmDeGyS+ZARGKM4tlH4FY2Jr63VjbEDJHtqXTGP5hbo= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -1173,8 +1130,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1186,8 +1143,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc= -golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4= +golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ= golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -1217,8 +1174,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1274,8 +1231,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1288,8 +1245,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1305,9 +1262,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1344,7 +1300,6 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1391,12 +1346,11 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1405,8 +1359,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1421,8 +1375,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1430,13 +1384,12 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1495,8 +1448,10 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= +golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1619,8 +1574,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= @@ -1686,8 +1641,8 @@ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7F k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= -lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= +lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 6943582a8a49dcd58bcd76cbe03f985524cb7e64 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Tue, 14 Oct 2025 17:44:00 -0700 Subject: [PATCH 12/13] add partial messages integration test This tests that two nodes in a network can exchange cells correctly --- .../p2p/partial/integrationtest/BUILD.bazel | 25 ++ .../partial/integrationtest/two_node_test.go | 244 ++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 beacon-chain/p2p/partial/integrationtest/BUILD.bazel create mode 100644 beacon-chain/p2p/partial/integrationtest/two_node_test.go diff --git a/beacon-chain/p2p/partial/integrationtest/BUILD.bazel b/beacon-chain/p2p/partial/integrationtest/BUILD.bazel new file mode 100644 index 000000000000..ffce3ab618a2 --- /dev/null +++ b/beacon-chain/p2p/partial/integrationtest/BUILD.bazel @@ -0,0 +1,25 @@ +load("@prysm//tools/go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + size = "medium", + srcs = ["two_node_test.go"], + deps = [ + "//beacon-chain/blockchain/kzg:go_default_library", + "//beacon-chain/core/peerdas:go_default_library", + "//beacon-chain/p2p:go_default_library", + "//beacon-chain/p2p/encoder:go_default_library", + "//beacon-chain/p2p/partial:go_default_library", + "//config/fieldparams:go_default_library", + "//config/params:go_default_library", + "//consensus-types/blocks:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", + "//testing/assert:go_default_library", + "//testing/require:go_default_library", + "@com_github_libp2p_go_libp2p//core/peer:go_default_library", + "@com_github_libp2p_go_libp2p//x/simlibp2p:go_default_library", + "@com_github_libp2p_go_libp2p_pubsub//:go_default_library", + "@com_github_marcopolo_simnet//:go_default_library", + "@com_github_prysmaticlabs_go_bitfield//:go_default_library", + ], +) diff --git a/beacon-chain/p2p/partial/integrationtest/two_node_test.go b/beacon-chain/p2p/partial/integrationtest/two_node_test.go new file mode 100644 index 000000000000..38bea29d6ab8 --- /dev/null +++ b/beacon-chain/p2p/partial/integrationtest/two_node_test.go @@ -0,0 +1,244 @@ +package integrationtest + +import ( + "context" + "fmt" + "log/slog" + "os" + "testing" + "testing/synctest" + "time" + + "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/kzg" + "github.com/OffchainLabs/prysm/v6/beacon-chain/core/peerdas" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/encoder" + "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/partial" + fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" + "github.com/OffchainLabs/prysm/v6/config/params" + "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" + ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" + "github.com/OffchainLabs/prysm/v6/testing/assert" + "github.com/OffchainLabs/prysm/v6/testing/require" + pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/peer" + simlibp2p "github.com/libp2p/go-libp2p/x/simlibp2p" + "github.com/marcopolo/simnet" + "github.com/prysmaticlabs/go-bitfield" +) + +// TestTwoNodePartialColumnExchange tests that two nodes can exchange partial columns +// and reconstruct the complete column. Node 1 has cells 0-2, Node 2 has cells 3-5. +// After exchange, both should have all cells. +func TestTwoNodePartialColumnExchange(t *testing.T) { + synctest.Test(t, func(t *testing.T) { + // Create a simulated libp2p network + latency := time.Millisecond * 10 + network, meta, err := simlibp2p.SimpleLibp2pNetwork([]simlibp2p.NodeLinkSettingsAndCount{ + {LinkSettings: simnet.NodeBiDiLinkSettings{ + Downlink: simnet.LinkSettings{BitsPerSecond: 20 * simlibp2p.OneMbps, Latency: latency / 2}, + Uplink: simnet.LinkSettings{BitsPerSecond: 20 * simlibp2p.OneMbps, Latency: latency / 2}, + }, Count: 2}, + }, simlibp2p.NetworkSettings{UseBlankHost: true}) + require.NoError(t, err) + require.NoError(t, network.Start()) + defer func() { + require.NoError(t, network.Close()) + }() + defer func() { + for _, node := range meta.Nodes { + err := node.Close() + if err != nil { + panic(err) + } + } + }() + + h1 := meta.Nodes[0] + h2 := meta.Nodes[1] + + // Create Broadcasters + logger1 := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) + logger2 := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) + + broadcaster1 := partial.NewBroadcaster(logger1) + broadcaster2 := partial.NewBroadcaster(logger2) + + opts1 := broadcaster1.AppendPubSubOpts([]pubsub.Option{ + pubsub.WithMessageSigning(false), + pubsub.WithStrictSignatureVerification(false), + }) + opts2 := broadcaster2.AppendPubSubOpts([]pubsub.Option{ + pubsub.WithMessageSigning(false), + pubsub.WithStrictSignatureVerification(false), + }) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ps1, err := pubsub.NewGossipSub(ctx, h1, opts1...) + require.NoError(t, err) + ps2, err := pubsub.NewGossipSub(ctx, h2, opts2...) + require.NoError(t, err) + + go broadcaster1.Start() + go broadcaster2.Start() + defer func() { + broadcaster1.Stop() + broadcaster2.Stop() + }() + + // Generate Test Data + var blockRoot [fieldparams.RootLength]byte + copy(blockRoot[:], []byte("test-block-root")) + + numCells := 6 + commitments := make([]kzg.Commitment, numCells) + cells := make([]kzg.Cell, numCells) + proofs := make([]kzg.Proof, numCells) + + for i := 0; i < numCells; i++ { + for j := 0; j < len(commitments[i]); j++ { + commitments[i][j] = byte(i) + } + for j := 0; j < len(cells[i]); j++ { + cells[i][j] = byte(i + 1) + } + for j := 0; j < len(proofs[i]); j++ { + proofs[i][j] = byte(i + 2) + } + } + + // Create signed block header + var parentRoot, stateRoot [fieldparams.RootLength]byte + signedBlockHeader := ðpb.SignedBeaconBlockHeader{ + Header: ðpb.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 0, + ParentRoot: parentRoot[:], + StateRoot: stateRoot[:], + BodyRoot: blockRoot[:], + }, + Signature: make([]byte, fieldparams.BLSSignatureLength), + } + + // Node 1 has cells 0, 1, 2 + bitmap1 := bitfield.NewBitlist(uint64(numCells)) + bitmap1.SetBitAt(0, true) + bitmap1.SetBitAt(1, true) + bitmap1.SetBitAt(2, true) + + pc1 := partial.NewPartialColumn( + signedBlockHeader, nil, blockRoot[:], commitments, bitmap1, + []kzg.Cell{cells[0], cells[1], cells[2]}, + []kzg.Proof{proofs[0], proofs[1], proofs[2]}, + ) + + // Node 2 has cells 3, 4, 5 + bitmap2 := bitfield.NewBitlist(uint64(numCells)) + bitmap2.SetBitAt(3, true) + bitmap2.SetBitAt(4, true) + bitmap2.SetBitAt(5, true) + + pc2 := partial.NewPartialColumn( + signedBlockHeader, nil, blockRoot[:], commitments, bitmap2, + []kzg.Cell{cells[3], cells[4], cells[5]}, + []kzg.Proof{proofs[3], proofs[4], proofs[5]}, + ) + + // Setup Topic and Subscriptions + digest := params.ForkDigest(0) + columnIndex := uint64(12) + subnet := peerdas.ComputeSubnetForDataColumnSidecar(columnIndex) + topicStr := fmt.Sprintf(p2p.DataColumnSubnetTopicFormat, digest, subnet) + + encoder.SszNetworkEncoder{}.ProtocolSuffix() + + time.Sleep(100 * time.Millisecond) + + topic1, err := ps1.Join(topicStr, pubsub.RequestPartialMessages()) + require.NoError(t, err) + topic2, err := ps2.Join(topicStr, pubsub.RequestPartialMessages()) + require.NoError(t, err) + + validator := func(included bitfield.Bitlist, allCommitments []kzg.Commitment, + cellsData, proofsData [][]byte) bool { + return true + } + + node1Complete := make(chan blocks.VerifiedRODataColumn, 1) + node2Complete := make(chan blocks.VerifiedRODataColumn, 1) + + handler1 := func(topic string, col blocks.VerifiedRODataColumn) { + t.Logf("Node 1: Completed! Column has %d cells", len(col.Column)) + node1Complete <- col + } + + handler2 := func(topic string, col blocks.VerifiedRODataColumn) { + t.Logf("Node 2: Completed! Column has %d cells", len(col.Column)) + node2Complete <- col + } + + // Connect hosts + err = h1.Connect(context.Background(), peer.AddrInfo{ + ID: h2.ID(), + Addrs: h2.Addrs(), + }) + require.NoError(t, err) + time.Sleep(300 * time.Millisecond) + + // Subscribe to regular GossipSub (critical for partial message RPC exchange!) + sub1, err := topic1.Subscribe() + require.NoError(t, err) + defer sub1.Cancel() + + sub2, err := topic2.Subscribe() + require.NoError(t, err) + defer sub2.Cancel() + + err = broadcaster1.Subscribe(topic1, validator, handler1) + require.NoError(t, err) + err = broadcaster2.Subscribe(topic2, validator, handler2) + require.NoError(t, err) + + // Wait for mesh to form + time.Sleep(2 * time.Second) + + // Publish + t.Log("Publishing from Node 1 (cells 0, 1, 2)...") + err = broadcaster1.Publish(topicStr, pc1) + require.NoError(t, err) + + time.Sleep(200 * time.Millisecond) + + t.Log("Publishing from Node 2 (cells 3, 4, 5)...") + err = broadcaster2.Publish(topicStr, pc2) + require.NoError(t, err) + + // Wait for Completion + timeout := time.After(10 * time.Second) + var col1, col2 blocks.VerifiedRODataColumn + receivedCount := 0 + + for receivedCount < 2 { + select { + case col1 = <-node1Complete: + t.Log("Node 1 completed reconstruction") + receivedCount++ + case col2 = <-node2Complete: + t.Log("Node 2 completed reconstruction") + receivedCount++ + case <-timeout: + t.Fatalf("Timeout: Only %d/2 nodes completed", receivedCount) + } + } + + // Verify both columns have all cells + assert.Equal(t, numCells, len(col1.Column), "Node 1 should have all cells") + assert.Equal(t, numCells, len(col2.Column), "Node 2 should have all cells") + + // Verify cells match original data + for i := 0; i < numCells; i++ { + assert.DeepEqual(t, cells[i][:], col1.Column[i], "Node 1 cell %d mismatch", i) + assert.DeepEqual(t, cells[i][:], col2.Column[i], "Node 2 cell %d mismatch", i) + } + }) +} From 0ef129af36b127f4429a032e79e986b24c638cc6 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Thu, 16 Oct 2025 16:39:37 -0700 Subject: [PATCH 13/13] fix multiaddr comparison on later go-multiaddr version --- beacon-chain/p2p/peers/status_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon-chain/p2p/peers/status_test.go b/beacon-chain/p2p/peers/status_test.go index c57344c041ae..490d2153e7f2 100644 --- a/beacon-chain/p2p/peers/status_test.go +++ b/beacon-chain/p2p/peers/status_test.go @@ -58,7 +58,7 @@ func TestPeerExplicitAdd(t *testing.T) { resAddress, err := p.Address(id) require.NoError(t, err) - assert.Equal(t, address, resAddress, "Unexpected address") + assert.Equal(t, address.Equal(resAddress), true, "Unexpected address") resDirection, err := p.Direction(id) require.NoError(t, err) @@ -72,7 +72,7 @@ func TestPeerExplicitAdd(t *testing.T) { resAddress2, err := p.Address(id) require.NoError(t, err) - assert.Equal(t, address2, resAddress2, "Unexpected address") + assert.Equal(t, address2.Equal(resAddress2), true, "Unexpected address") resDirection2, err := p.Direction(id) require.NoError(t, err)