Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Data Columns By Range Request And Response Methods #13972

Merged
merged 11 commits into from
May 14, 2024

Conversation

nisdas
Copy link
Member

@nisdas nisdas commented May 9, 2024

What type of PR is this?

Feature

What does this PR do? Why is it needed?

This adds support for the newly added RPC method for columns by range here:
ethereum/consensus-specs#3750

  • Prysm nodes are now able to serve column by range methods along with all the relevant streaming, and validation of these columns.
  • During syncing we can now start utilizing the column by range request method to get the respective custodied columns from other peers.

Which issues(s) does this PR fix?

Requires #13945 to be merged first

Other notes for review

@nisdas nisdas requested a review from a team as a code owner May 9, 2024 10:54
@nisdas nisdas requested review from kasey, nalepae and prestonvanloon and removed request for a team May 9, 2024 10:54
@nisdas nisdas added Ready For Review A pull request ready for code review peerDAS labels May 9, 2024
beacon-chain/core/peerdas/helpers.go Outdated Show resolved Hide resolved
beacon-chain/core/peerdas/helpers.go Outdated Show resolved Hide resolved
// See https://golang.org/doc/faq#closures_and_goroutines for more details.
colIdx := i
sidecar := sd
eg.Go(func() error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need the to run s.internalBroadcastDataColumn in a goroutine here?

func (s *Service) BroadcastDataColumn(ctx context.Context, columnSubnet uint64, dataColumnSidecar *ethpb.DataColumnSidecar) error {
	// Add tracing to the function.
	ctx, span := trace.StartSpan(ctx, "p2p.BroadcastBlob")
	defer span.End()

	// Ensure the data column sidecar is not nil.
	if dataColumnSidecar == nil {
		return errors.Errorf("attempted to broadcast nil data column sidecar at subnet %d", columnSubnet)
	}

	// Retrieve the current fork digest.
	forkDigest, err := s.currentForkDigest()
	if err != nil {
		err := errors.Wrap(err, "current fork digest")
		tracing.AnnotateError(span, err)
		return err
	}

	// Non-blocking broadcast, with attempts to discover a column subnet peer if none available.
	go s.internalBroadcastDataColumn(ctx, columnSubnet, dataColumnSidecar, forkDigest)

	return nil
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(We now have a goroutine calling an other goroutine.)


// dataColumnSidecarsByRangeRPCHandler looks up the request data columns from the database from a given start slot index
func (s *Service) dataColumnSidecarsByRangeRPCHandler(ctx context.Context, msg interface{}, stream libp2pcore.Stream) error {
var err error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used.

maxRequest := params.MaxRequestBlock(slots.ToEpoch(current))
// Allow some wiggle room, up to double the MaxRequestBlocks past the current slot,
// to give nodes syncing close to the head of the chain some margin for error.
maxStart, err := current.SafeAdd(maxRequest * 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand this. Why this would be ever the case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The caller knows the current slot. So why would it send a request with a start > currentSlot?

if rp.end > current {
rp.end = current
}
if rp.end < rp.start {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not this be considered as an invalid request?

return roDataColumns, nil
}

func SendDataColumnsByRangeRequest(ctx context.Context, tor blockchain.TemporalOracle, p2pApi p2p.P2P, pid peer.ID, ctxMap ContextByteVersions, req *pb.DataColumnSidecarsByRangeRequest) ([]blocks.RODataColumn, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the following condition checked?

The following data column sidecars, where they exist, MUST be sent in (slot, column_index) order.

@nalepae
Copy link
Contributor

nalepae commented May 10, 2024

Some entry is probably missing here.

And probably here as well.

@@ -98,9 +98,11 @@ func (s ROBlockSlice) Len() int {

// BlockWithROBlobs is a wrapper that collects the block and blob values together.
// This is helpful because these values are collated from separate RPC requests.
// TODO: Use a more generic name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposal: BlockWithROSidecars?

if len(commits) == 0 {
return bw, errDidntPopulate
}
if len(columns) != int(params.BeaconConfig().CustodyRequirement) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could not this condition be tested at the beginning of the function as this condition only involves functions parameters and params?

return nil
}
if col.ColumnIndex >= fieldparams.NumberOfColumns {
return errors.Wrapf(ErrIncorrectColumnIndex, "index %d exceeds NUMBERS_OF_COLUMN %d", col.ColumnIndex, fieldparams.MaxBlobsPerBlock)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is fieldparams.MaxBlobsPerBlock the wanted value?

func (f *blocksFetcher) fetchColumnsFromPeer(ctx context.Context, bwb []blocks2.BlockWithROBlobs, pid peer.ID, peers []peer.ID) ([]blocks2.BlockWithROBlobs, error) {
ctx, span := trace.StartSpan(ctx, "initialsync.fetchColumnsFromPeer")
defer span.End()
if slots.ToEpoch(f.clock.CurrentSlot()) < params.BeaconConfig().DenebForkEpoch {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f.clock.CurrentSlot() is called several times in the function.
It can be factorized in a currentSlot variable.

if err != nil {
return nil, err
}
var colIdxs []uint64
Copy link
Contributor

@nalepae nalepae May 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a make with fixed size/capacity to avoid possible eventual re-allocation.

@@ -0,0 +1,151 @@
package das
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in file name. (a missing)

return nil
}

// IsDataAvailable returns nil if all the commitments in the given block are persisted to the db and have been verified.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some references to blob while they should probably be references to data columns.
I find disturbing the fact that a function named IsDataAvailable actually saves something into the database.

@nisdas nisdas force-pushed the dataColumnsbyRangeRequest branch from dc59fdf to 7b0eeab Compare May 13, 2024 08:16
@nisdas nisdas merged commit e2c64e6 into peerDAS May 14, 2024
8 of 12 checks passed
@nisdas nisdas deleted the dataColumnsbyRangeRequest branch May 14, 2024 16:01
nisdas added a commit that referenced this pull request May 16, 2024
* Add Data Structure for New Request Type

* Add Data Column By Range Handler

* Add Data Column Request Methods

* Add new validation for columns by range requests

* Fix Build

* Allow Prysm Node To Fetch Data Columns

* Allow Prysm Node To Fetch Data Columns And Sync

* Bug Fixes For Interop

* GoFmt

* Use different var

* Manu's Review
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
peerDAS Ready For Review A pull request ready for code review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants