mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
6 Commits
declare-av
...
data-colum
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a0db40e76 | ||
|
|
5fcf393f3a | ||
|
|
6c7944cdfe | ||
|
|
6d3fd80035 | ||
|
|
96032555e7 | ||
|
|
4de7a24077 |
@@ -288,7 +288,7 @@ func requestDirectSidecarsFromPeers(
|
||||
roDataColumnsByPeer := fetchDataColumnSidecarsFromPeers(params, slotByRoot, slotsWithCommitments, indicesByRootByPeerToQuery)
|
||||
|
||||
// Verify the received data column sidecars.
|
||||
verifiedRoDataColumnSidecars, err := verifyDataColumnSidecarsByPeer(params.P2P, params.NewVerifier, roDataColumnsByPeer)
|
||||
verifiedRoDataColumnSidecars, err := verifyDataColumnSidecarsByPeer(params.Ctx, params.P2P, params.NewVerifier, roDataColumnsByPeer)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "verify data columns sidecars by peer")
|
||||
}
|
||||
@@ -398,7 +398,7 @@ func requestIndirectSidecarsFromPeers(
|
||||
roDataColumnsByPeer := fetchDataColumnSidecarsFromPeers(p, slotByRoot, slotsWithCommitments, indicesByRootByPeerToQuery)
|
||||
|
||||
// Verify the received data column sidecars.
|
||||
verifiedRoDataColumnSidecars, err := verifyDataColumnSidecarsByPeer(p.P2P, p.NewVerifier, roDataColumnsByPeer)
|
||||
verifiedRoDataColumnSidecars, err := verifyDataColumnSidecarsByPeer(p.Ctx, p.P2P, p.NewVerifier, roDataColumnsByPeer)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "verify data columns sidecars by peer")
|
||||
}
|
||||
@@ -942,6 +942,7 @@ func buildByRootRequest(indicesByRoot map[[fieldparams.RootLength]byte]map[uint6
|
||||
// If at least one sidecar from a peer is invalid, the peer is downscored and
|
||||
// all its sidecars are rejected. (Sidecars from other peers are still accepted.)
|
||||
func verifyDataColumnSidecarsByPeer(
|
||||
ctx context.Context,
|
||||
p2p prysmP2P.P2P,
|
||||
newVerifier verification.NewDataColumnsVerifier,
|
||||
roDataColumnsByPeer map[goPeer.ID][]blocks.RODataColumn,
|
||||
@@ -957,7 +958,7 @@ func verifyDataColumnSidecarsByPeer(
|
||||
roDataColumnSidecars = append(roDataColumnSidecars, columns...)
|
||||
}
|
||||
|
||||
verifiedRoDataColumnSidecars, err := verifyByRootDataColumnSidecars(newVerifier, roDataColumnSidecars)
|
||||
verifiedRoDataColumnSidecars, err := verifyByRPCDataColumnSidecars(ctx, newVerifier, roDataColumnSidecars)
|
||||
if err == nil {
|
||||
// This is the happy path where all sidecars are verified.
|
||||
return verifiedRoDataColumnSidecars, nil
|
||||
@@ -967,7 +968,7 @@ func verifyDataColumnSidecarsByPeer(
|
||||
// Reverify peer by peer to identify faulty peer(s), reject all its sidecars, and downscore it.
|
||||
verifiedRoDataColumnSidecars = make([]blocks.VerifiedRODataColumn, 0, count)
|
||||
for peer, columns := range roDataColumnsByPeer {
|
||||
peerVerifiedRoDataColumnSidecars, err := verifyByRootDataColumnSidecars(newVerifier, columns)
|
||||
peerVerifiedRoDataColumnSidecars, err := verifyByRPCDataColumnSidecars(ctx, newVerifier, columns)
|
||||
if err != nil {
|
||||
// This peer has invalid sidecars.
|
||||
log := log.WithError(err).WithField("peerID", peer)
|
||||
@@ -982,10 +983,14 @@ func verifyDataColumnSidecarsByPeer(
|
||||
return verifiedRoDataColumnSidecars, nil
|
||||
}
|
||||
|
||||
// verifyByRootDataColumnSidecars verifies the provided read-only data columns against the
|
||||
// verifyByRPCDataColumnSidecars verifies the provided read-only data columns against the
|
||||
// requirements for data column sidecars received via the by root request.
|
||||
func verifyByRootDataColumnSidecars(newVerifier verification.NewDataColumnsVerifier, roDataColumns []blocks.RODataColumn) ([]blocks.VerifiedRODataColumn, error) {
|
||||
verifier := newVerifier(roDataColumns, verification.ByRootRequestDataColumnSidecarRequirements)
|
||||
func verifyByRPCDataColumnSidecars(ctx context.Context, newVerifier verification.NewDataColumnsVerifier, roDataColumns []blocks.RODataColumn) ([]blocks.VerifiedRODataColumn, error) {
|
||||
verifier := newVerifier(roDataColumns, verification.ByRPCRequestDataColumnSidecarRequirements)
|
||||
|
||||
if err := verifier.ValidProposerSignature(ctx); err != nil {
|
||||
return nil, errors.Wrap(err, "valid proposer signature")
|
||||
}
|
||||
|
||||
if err := verifier.ValidFields(); err != nil {
|
||||
return nil, errors.Wrap(err, "valid fields")
|
||||
|
||||
@@ -2,6 +2,7 @@ package sync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
@@ -154,12 +155,6 @@ func TestFetchDataColumnSidecars(t *testing.T) {
|
||||
err = gs.SetClock(startup.NewClock(time.Unix(4113849600, 0), [fieldparams.RootLength]byte{}))
|
||||
require.NoError(t, err)
|
||||
|
||||
waiter := verification.NewInitializerWaiter(gs, nil, nil)
|
||||
initializer, err := waiter.WaitForInitializer(t.Context())
|
||||
require.NoError(t, err)
|
||||
|
||||
newDataColumnsVerifier := newDataColumnsVerifierFromInitializer(initializer)
|
||||
|
||||
other.SetStreamHandler(byRangeProtocol, func(stream network.Stream) {
|
||||
expectedRequest := ðpb.DataColumnSidecarsByRangeRequest{
|
||||
StartSlot: 3,
|
||||
@@ -247,7 +242,7 @@ func TestFetchDataColumnSidecars(t *testing.T) {
|
||||
RateLimiter: leakybucket.NewCollector(1., 10, time.Second, false /* deleteEmptyBuckets */),
|
||||
CtxMap: ctxMap,
|
||||
Storage: storage,
|
||||
NewVerifier: newDataColumnsVerifier,
|
||||
NewVerifier: testNewDataColumnSidecarsVerifier(verification.MockDataColumnsVerifier{}),
|
||||
}
|
||||
|
||||
expectedResult := map[[fieldparams.RootLength]byte][]blocks.VerifiedRODataColumn{
|
||||
@@ -761,6 +756,8 @@ func TestVerifyDataColumnSidecarsByPeer(t *testing.T) {
|
||||
err := kzg.Start()
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := t.Context()
|
||||
|
||||
params.SetupTestConfigCleanup(t)
|
||||
cfg := params.BeaconConfig()
|
||||
cfg.FuluForkEpoch = 0
|
||||
@@ -783,16 +780,9 @@ func TestVerifyDataColumnSidecarsByPeer(t *testing.T) {
|
||||
"peer2": roDataColumnSidecars[5:9],
|
||||
"peer3": roDataColumnSidecars[9:stop],
|
||||
}
|
||||
gs := startup.NewClockSynchronizer()
|
||||
err := gs.SetClock(startup.NewClock(time.Unix(4113849600, 0), [fieldparams.RootLength]byte{}))
|
||||
require.NoError(t, err)
|
||||
|
||||
waiter := verification.NewInitializerWaiter(gs, nil, nil)
|
||||
initializer, err := waiter.WaitForInitializer(t.Context())
|
||||
require.NoError(t, err)
|
||||
|
||||
newDataColumnsVerifier := newDataColumnsVerifierFromInitializer(initializer)
|
||||
actual, err := verifyDataColumnSidecarsByPeer(p2p, newDataColumnsVerifier, roDataColumnsByPeer)
|
||||
newDataColumnsVerifier := testNewDataColumnSidecarsVerifier(verification.MockDataColumnsVerifier{})
|
||||
actual, err := verifyDataColumnSidecarsByPeer(ctx, p2p, newDataColumnsVerifier, roDataColumnsByPeer)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, stop-start, len(actual))
|
||||
@@ -816,28 +806,14 @@ func TestVerifyDataColumnSidecarsByPeer(t *testing.T) {
|
||||
// Setup test data and expectations
|
||||
_, roDataColumnSidecars, expected := util.GenerateTestFuluBlockWithSidecars(t, blobCount)
|
||||
|
||||
// Modify one sidecar to ensure proof verification fails.
|
||||
if roDataColumnSidecars[middle].KzgProofs[0][0] == 0 {
|
||||
roDataColumnSidecars[middle].KzgProofs[0][0]++
|
||||
} else {
|
||||
roDataColumnSidecars[middle].KzgProofs[0][0]--
|
||||
}
|
||||
|
||||
roDataColumnsByPeer := map[peer.ID][]blocks.RODataColumn{
|
||||
"peer1": roDataColumnSidecars[start:middle],
|
||||
"peer2": roDataColumnSidecars[5:middle],
|
||||
"peer3": roDataColumnSidecars[middle:stop],
|
||||
}
|
||||
gs := startup.NewClockSynchronizer()
|
||||
err := gs.SetClock(startup.NewClock(time.Unix(4113849600, 0), [fieldparams.RootLength]byte{}))
|
||||
require.NoError(t, err)
|
||||
|
||||
waiter := verification.NewInitializerWaiter(gs, nil, nil)
|
||||
initializer, err := waiter.WaitForInitializer(t.Context())
|
||||
require.NoError(t, err)
|
||||
|
||||
newDataColumnsVerifier := newDataColumnsVerifierFromInitializer(initializer)
|
||||
actual, err := verifyDataColumnSidecarsByPeer(p2p, newDataColumnsVerifier, roDataColumnsByPeer)
|
||||
newDataColumnsVerifier := testNewDataColumnSidecarsVerifier(verification.MockDataColumnsVerifier{FailIndex: middle, ErrSidecarKzgProofVerifiedOnFailIndex: errors.New("an error")})
|
||||
actual, err := verifyDataColumnSidecarsByPeer(ctx, p2p, newDataColumnsVerifier, roDataColumnsByPeer)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, middle-start, len(actual))
|
||||
|
||||
@@ -218,7 +218,8 @@ func TestValidateDataColumn(t *testing.T) {
|
||||
}
|
||||
|
||||
func testNewDataColumnSidecarsVerifier(verifier verification.MockDataColumnsVerifier) verification.NewDataColumnsVerifier {
|
||||
return func([]blocks.RODataColumn, []verification.Requirement) verification.DataColumnsVerifier {
|
||||
return func(sidecars []blocks.RODataColumn, _ []verification.Requirement) verification.DataColumnsVerifier {
|
||||
verifier.Sidecars = sidecars
|
||||
return &verifier
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,19 +39,12 @@ var (
|
||||
RequireSidecarProposerExpected,
|
||||
}
|
||||
|
||||
// ByRangeRequestDataColumnSidecarRequirements defines the set of requirements that DataColumnSidecars received
|
||||
// via the by range request must satisfy in order to upgrade an RODataColumn to a VerifiedRODataColumn.
|
||||
// ByRPCRequestDataColumnSidecarRequirements defines the set of requirements that DataColumnSidecars received
|
||||
// via the by RPC request must satisfy in order to upgrade an RODataColumn to a VerifiedRODataColumn.
|
||||
// https://github.com/ethereum/consensus-specs/blob/master/specs/fulu/p2p-interface.md#datacolumnsidecarsbyrange-v1
|
||||
ByRangeRequestDataColumnSidecarRequirements = []Requirement{
|
||||
RequireValidFields,
|
||||
RequireSidecarInclusionProven,
|
||||
RequireSidecarKzgProofVerified,
|
||||
}
|
||||
|
||||
// ByRootRequestDataColumnSidecarRequirements defines the set of requirements that DataColumnSidecars received
|
||||
// via the by root request must satisfy in order to upgrade an RODataColumn to a VerifiedRODataColumn.
|
||||
// https://github.com/ethereum/consensus-specs/blob/master/specs/fulu/p2p-interface.md#datacolumnsidecarsbyroot-v1
|
||||
ByRootRequestDataColumnSidecarRequirements = []Requirement{
|
||||
ByRPCRequestDataColumnSidecarRequirements = []Requirement{
|
||||
RequireValidProposerSignature,
|
||||
RequireValidFields,
|
||||
RequireSidecarInclusionProven,
|
||||
RequireSidecarKzgProofVerified,
|
||||
|
||||
@@ -79,24 +79,34 @@ func (*MockBlobVerifier) SatisfyRequirement(_ Requirement) {}
|
||||
// --------------------
|
||||
|
||||
type MockDataColumnsVerifier struct {
|
||||
ErrValidFields error
|
||||
ErrCorrectSubnet error
|
||||
ErrNotFromFutureSlot error
|
||||
ErrSlotAboveFinalized error
|
||||
ErrSidecarParentSeen error
|
||||
ErrSidecarParentValid error
|
||||
ErrValidProposerSignature error
|
||||
ErrSidecarParentSlotLower error
|
||||
ErrSidecarDescendsFromFinalized error
|
||||
ErrSidecarInclusionProven error
|
||||
ErrSidecarKzgProofVerified error
|
||||
ErrSidecarProposerExpected error
|
||||
ErrValidFields error
|
||||
ErrCorrectSubnet error
|
||||
ErrNotFromFutureSlot error
|
||||
ErrSlotAboveFinalized error
|
||||
ErrSidecarParentSeen error
|
||||
ErrSidecarParentValid error
|
||||
ErrValidProposerSignature error
|
||||
ErrSidecarParentSlotLower error
|
||||
ErrSidecarDescendsFromFinalized error
|
||||
ErrSidecarInclusionProven error
|
||||
ErrSidecarKzgProofVerified error
|
||||
ErrSidecarKzgProofVerifiedOnFailIndex error
|
||||
ErrSidecarProposerExpected error
|
||||
|
||||
FailIndex uint64
|
||||
Sidecars []blocks.RODataColumn
|
||||
}
|
||||
|
||||
var _ DataColumnsVerifier = &MockDataColumnsVerifier{}
|
||||
|
||||
func (m *MockDataColumnsVerifier) VerifiedRODataColumns() ([]blocks.VerifiedRODataColumn, error) {
|
||||
return []blocks.VerifiedRODataColumn{{}}, nil
|
||||
verifiedSidecars := make([]blocks.VerifiedRODataColumn, 0, len(m.Sidecars))
|
||||
for _, sidecar := range m.Sidecars {
|
||||
verifiedSidecar := blocks.NewVerifiedRODataColumn(sidecar)
|
||||
verifiedSidecars = append(verifiedSidecars, verifiedSidecar)
|
||||
}
|
||||
|
||||
return verifiedSidecars, nil
|
||||
}
|
||||
|
||||
func (m *MockDataColumnsVerifier) SatisfyRequirement(_ Requirement) {}
|
||||
@@ -142,6 +152,13 @@ func (m *MockDataColumnsVerifier) SidecarInclusionProven() error {
|
||||
}
|
||||
|
||||
func (m *MockDataColumnsVerifier) SidecarKzgProofVerified() error {
|
||||
for _, sidecar := range m.Sidecars {
|
||||
if m.ErrSidecarKzgProofVerifiedOnFailIndex != nil && sidecar.Index == m.FailIndex {
|
||||
m.Sidecars = nil
|
||||
return m.ErrSidecarKzgProofVerifiedOnFailIndex
|
||||
}
|
||||
}
|
||||
|
||||
return m.ErrSidecarKzgProofVerified
|
||||
}
|
||||
|
||||
|
||||
2
changelog/manu-signature.md
Normal file
2
changelog/manu-signature.md
Normal file
@@ -0,0 +1,2 @@
|
||||
### Fixed
|
||||
- `verifyByRPCDataColumnSidecars`: Verify the proposer signature.
|
||||
Reference in New Issue
Block a user