mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
Allow SSZ-serialized blocks in publishBlindedBlock (#10679)
* SubmitBlockSSZ grpc
* SubmitBlockSSZ middleware
* test fixes
* use VersionedUnmarshaller
* use VersionedUnmarshaller
(cherry picked from commit 7388eeb963)
* tests
* fuzz: Add fuzz tests for sparse merkle trie (#10662)
* Add fuzz tests for sparse merkle trie and change HTR signature to return an error
* fix capitalization of error message
* Add engine timeout values (#10645)
* Add timeout values
* Update engine_client.go
* Update engine_client.go
* Update beacon-chain/powchain/engine_client.go
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Update beacon-chain/powchain/engine_client.go
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Update beacon-chain/powchain/engine_client.go
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Update engine_client.go
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
* Cleanup of `stategen` package (#10607)
* powchain and stategen
* revert powchain changes
* rename field to blockRootsOfSavedStates
* rename params to blockRoot
* review feedback
* fix loop
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
* Process atts and update head before proposing (#10653)
* Process atts and updeate head
* Fix ctx
* New test and old tests
* Update validator_test.go
* Update validator_test.go
* Update service.go
* Rename to UpdateHead
* Update receive_attestation.go
* Update receive_attestation.go
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
* Add link to e2e docs in `README` (#10672)
* Improve `ReceiveBlock`'s comment (#10671)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
* Call fcu on invalid payload (#10565)
* Starting
* remove finalized root
* Just call fcu
* Review feedbacks
* fix one test
* Fix conflicts
* Update execution_engine_test.go
* Add a test for invalid recursive call
* Add comprehensive recursive test
* dissallow override empty hash
Co-authored-by: Potuz <potuz@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
* Cache and use justified and finalized payload block hash (#10657)
* Cache and use justified and finalized payload block hash
* Fix tests
* Use real byte
* Fix conflicts
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
* do not export slotFromBlock
* simplify tests
* grpc
* middleware
* extract package-level consts
* Simplify SSZ handling
* fix tests
* test fixes
* test hack
Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: terencechain <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Potuz <potuz@prysmaticlabs.com>
This commit is contained in:
@@ -42,7 +42,6 @@ go_test(
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/wrapper:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
|
||||
@@ -145,19 +145,9 @@ func (cf *VersionedUnmarshaler) UnmarshalBeaconBlock(marshaled []byte) (interfac
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// heuristic to make sure block is from the same version as the VersionedUnmarshaler.
|
||||
// Look up the version for the epoch that the block is from, then ensure that it matches the Version in the
|
||||
// VersionedUnmarshaler.
|
||||
epoch := slots.ToEpoch(slot)
|
||||
fs := forks.NewOrderedSchedule(cf.Config)
|
||||
ver, err := fs.VersionForEpoch(epoch)
|
||||
if err != nil {
|
||||
if err := cf.validateVersion(slot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ver != cf.Version {
|
||||
return nil, errors.Wrapf(errBlockForkMismatch, "slot=%d, epoch=%d, version=%#x", slot, epoch, ver)
|
||||
}
|
||||
|
||||
var blk ssz.Unmarshaler
|
||||
switch cf.Fork {
|
||||
@@ -177,3 +167,50 @@ func (cf *VersionedUnmarshaler) UnmarshalBeaconBlock(marshaled []byte) (interfac
|
||||
}
|
||||
return wrapper.WrappedSignedBeaconBlock(blk)
|
||||
}
|
||||
|
||||
// UnmarshalBlindedBeaconBlock uses internal knowledge in the VersionedUnmarshaler to pick the right concrete blinded SignedBeaconBlock type,
|
||||
// then Unmarshal()s the type and returns an instance of block.SignedBeaconBlock if successful.
|
||||
// For Phase0 and Altair it works exactly line UnmarshalBeaconBlock.
|
||||
func (cf *VersionedUnmarshaler) UnmarshalBlindedBeaconBlock(marshaled []byte) (interfaces.SignedBeaconBlock, error) {
|
||||
slot, err := slotFromBlock(marshaled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := cf.validateVersion(slot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var blk ssz.Unmarshaler
|
||||
switch cf.Fork {
|
||||
case version.Phase0:
|
||||
blk = ðpb.SignedBeaconBlock{}
|
||||
case version.Altair:
|
||||
blk = ðpb.SignedBeaconBlockAltair{}
|
||||
case version.Bellatrix:
|
||||
blk = ðpb.SignedBlindedBeaconBlockBellatrix{}
|
||||
default:
|
||||
forkName := version.String(cf.Fork)
|
||||
return nil, fmt.Errorf("unable to initialize BeaconBlock for fork version=%s at slot=%d", forkName, slot)
|
||||
}
|
||||
err = blk.UnmarshalSSZ(marshaled)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal SignedBeaconBlock in UnmarshalSSZ")
|
||||
}
|
||||
return wrapper.WrappedSignedBeaconBlock(blk)
|
||||
}
|
||||
|
||||
// Heuristic to make sure block is from the same version as the VersionedUnmarshaler.
|
||||
// Look up the version for the epoch that the block is from, then ensure that it matches the Version in the
|
||||
// VersionedUnmarshaler.
|
||||
func (cf *VersionedUnmarshaler) validateVersion(slot types.Slot) error {
|
||||
epoch := slots.ToEpoch(slot)
|
||||
fs := forks.NewOrderedSchedule(cf.Config)
|
||||
ver, err := fs.VersionForEpoch(epoch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ver != cf.Version {
|
||||
return errors.Wrapf(errBlockForkMismatch, "slot=%d, epoch=%d, version=%#x", slot, epoch, ver)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -16,13 +16,12 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
v1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
)
|
||||
|
||||
func TestSlotFromBlock(t *testing.T) {
|
||||
b := testBlockGenesis()
|
||||
b := util.NewBeaconBlock()
|
||||
var slot types.Slot = 3
|
||||
b.Block.Slot = slot
|
||||
bb, err := b.MarshalSSZ()
|
||||
@@ -31,7 +30,7 @@ func TestSlotFromBlock(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, slot, sfb)
|
||||
|
||||
ba := testBlockAltair()
|
||||
ba := util.NewBeaconBlockAltair()
|
||||
ba.Block.Slot = slot
|
||||
bab, err := ba.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
@@ -39,7 +38,7 @@ func TestSlotFromBlock(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, slot, sfba)
|
||||
|
||||
bm := testBlockBellatrix()
|
||||
bm := util.NewBeaconBlockBellatrix()
|
||||
bm.Block.Slot = slot
|
||||
bmb, err := ba.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
@@ -277,125 +276,123 @@ func TestUnmarshalBlock(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalBlindedBlock(t *testing.T) {
|
||||
bc, cleanup := hackBellatrixMaxuint()
|
||||
defer cleanup()
|
||||
require.Equal(t, types.Epoch(math.MaxUint32), params.KnownConfigs[params.MainnetName]().BellatrixForkEpoch)
|
||||
genv := bytesutil.ToBytes4(bc.GenesisForkVersion)
|
||||
altairv := bytesutil.ToBytes4(bc.AltairForkVersion)
|
||||
bellav := bytesutil.ToBytes4(bc.BellatrixForkVersion)
|
||||
altairS, err := slots.EpochStart(bc.AltairForkEpoch)
|
||||
bellaS, err := slots.EpochStart(bc.BellatrixForkEpoch)
|
||||
require.NoError(t, err)
|
||||
cases := []struct {
|
||||
b func(*testing.T, types.Slot) interfaces.SignedBeaconBlock
|
||||
name string
|
||||
version [4]byte
|
||||
slot types.Slot
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "genesis - slot 0",
|
||||
b: signedTestBlockGenesis,
|
||||
version: genv,
|
||||
},
|
||||
{
|
||||
name: "last slot of phase 0",
|
||||
b: signedTestBlockGenesis,
|
||||
version: genv,
|
||||
slot: altairS - 1,
|
||||
},
|
||||
{
|
||||
name: "first slot of altair",
|
||||
b: signedTestBlockAltair,
|
||||
version: altairv,
|
||||
slot: altairS,
|
||||
},
|
||||
{
|
||||
name: "last slot of altair",
|
||||
b: signedTestBlockAltair,
|
||||
version: altairv,
|
||||
slot: bellaS - 1,
|
||||
},
|
||||
{
|
||||
name: "first slot of bellatrix",
|
||||
b: signedTestBlindedBlockBellatrix,
|
||||
version: bellav,
|
||||
slot: bellaS,
|
||||
},
|
||||
{
|
||||
name: "bellatrix block in altair slot",
|
||||
b: signedTestBlindedBlockBellatrix,
|
||||
version: bellav,
|
||||
slot: bellaS - 1,
|
||||
err: errBlockForkMismatch,
|
||||
},
|
||||
{
|
||||
name: "genesis block in altair slot",
|
||||
b: signedTestBlockGenesis,
|
||||
version: genv,
|
||||
slot: bellaS - 1,
|
||||
err: errBlockForkMismatch,
|
||||
},
|
||||
{
|
||||
name: "altair block in genesis slot",
|
||||
b: signedTestBlockAltair,
|
||||
version: altairv,
|
||||
err: errBlockForkMismatch,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
b := c.b(t, c.slot)
|
||||
marshaled, err := b.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
cf, err := FromForkVersion(c.version)
|
||||
require.NoError(t, err)
|
||||
bcf, err := cf.UnmarshalBlindedBeaconBlock(marshaled)
|
||||
if c.err != nil {
|
||||
require.ErrorIs(t, err, c.err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
expected, err := b.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
actual, err := bcf.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func signedTestBlockGenesis(t *testing.T, slot types.Slot) interfaces.SignedBeaconBlock {
|
||||
b := testBlockGenesis()
|
||||
b := util.NewBeaconBlock()
|
||||
b.Block.Slot = slot
|
||||
s, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
}
|
||||
|
||||
func testBlockGenesis() *ethpb.SignedBeaconBlock {
|
||||
return ðpb.SignedBeaconBlock{
|
||||
Block: ðpb.BeaconBlock{
|
||||
ProposerIndex: types.ValidatorIndex(0),
|
||||
ParentRoot: make([]byte, 32),
|
||||
StateRoot: make([]byte, 32),
|
||||
Body: ðpb.BeaconBlockBody{
|
||||
RandaoReveal: make([]byte, 96),
|
||||
Graffiti: make([]byte, 32),
|
||||
ProposerSlashings: []*ethpb.ProposerSlashing{},
|
||||
AttesterSlashings: []*ethpb.AttesterSlashing{},
|
||||
Attestations: []*ethpb.Attestation{},
|
||||
Deposits: []*ethpb.Deposit{},
|
||||
VoluntaryExits: []*ethpb.SignedVoluntaryExit{},
|
||||
Eth1Data: ðpb.Eth1Data{
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 0,
|
||||
BlockHash: make([]byte, 32),
|
||||
},
|
||||
},
|
||||
},
|
||||
Signature: make([]byte, 96),
|
||||
}
|
||||
}
|
||||
|
||||
func signedTestBlockAltair(t *testing.T, slot types.Slot) interfaces.SignedBeaconBlock {
|
||||
b := testBlockAltair()
|
||||
b := util.NewBeaconBlockAltair()
|
||||
b.Block.Slot = slot
|
||||
s, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
}
|
||||
|
||||
func testBlockAltair() *ethpb.SignedBeaconBlockAltair {
|
||||
return ðpb.SignedBeaconBlockAltair{
|
||||
Block: ðpb.BeaconBlockAltair{
|
||||
ProposerIndex: types.ValidatorIndex(0),
|
||||
ParentRoot: make([]byte, 32),
|
||||
StateRoot: make([]byte, 32),
|
||||
Body: ðpb.BeaconBlockBodyAltair{
|
||||
RandaoReveal: make([]byte, 96),
|
||||
Eth1Data: ðpb.Eth1Data{
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 0,
|
||||
BlockHash: make([]byte, 32),
|
||||
},
|
||||
Graffiti: make([]byte, 32),
|
||||
ProposerSlashings: []*ethpb.ProposerSlashing{},
|
||||
AttesterSlashings: []*ethpb.AttesterSlashing{},
|
||||
Attestations: []*ethpb.Attestation{},
|
||||
Deposits: []*ethpb.Deposit{},
|
||||
VoluntaryExits: []*ethpb.SignedVoluntaryExit{},
|
||||
SyncAggregate: ðpb.SyncAggregate{
|
||||
SyncCommitteeBits: make([]byte, 64),
|
||||
SyncCommitteeSignature: make([]byte, 96),
|
||||
},
|
||||
},
|
||||
},
|
||||
Signature: make([]byte, 96),
|
||||
}
|
||||
}
|
||||
|
||||
func signedTestBlockBellatrix(t *testing.T, slot types.Slot) interfaces.SignedBeaconBlock {
|
||||
b := testBlockBellatrix()
|
||||
b := util.NewBeaconBlockBellatrix()
|
||||
b.Block.Slot = slot
|
||||
s, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
}
|
||||
|
||||
func testBlockBellatrix() *ethpb.SignedBeaconBlockBellatrix {
|
||||
return ðpb.SignedBeaconBlockBellatrix{
|
||||
Block: ðpb.BeaconBlockBellatrix{
|
||||
ProposerIndex: types.ValidatorIndex(0),
|
||||
ParentRoot: make([]byte, 32),
|
||||
StateRoot: make([]byte, 32),
|
||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||
RandaoReveal: make([]byte, 96),
|
||||
Eth1Data: ðpb.Eth1Data{
|
||||
DepositRoot: make([]byte, 32),
|
||||
DepositCount: 0,
|
||||
BlockHash: make([]byte, 32),
|
||||
},
|
||||
Graffiti: make([]byte, 32),
|
||||
ProposerSlashings: []*ethpb.ProposerSlashing{},
|
||||
AttesterSlashings: []*ethpb.AttesterSlashing{},
|
||||
Attestations: []*ethpb.Attestation{},
|
||||
Deposits: []*ethpb.Deposit{},
|
||||
VoluntaryExits: []*ethpb.SignedVoluntaryExit{},
|
||||
SyncAggregate: ðpb.SyncAggregate{
|
||||
SyncCommitteeBits: make([]byte, 64),
|
||||
SyncCommitteeSignature: make([]byte, 96),
|
||||
},
|
||||
ExecutionPayload: &v1.ExecutionPayload{
|
||||
ParentHash: make([]byte, 32),
|
||||
FeeRecipient: make([]byte, 20),
|
||||
StateRoot: make([]byte, 32),
|
||||
ReceiptsRoot: make([]byte, 32),
|
||||
LogsBloom: make([]byte, 256),
|
||||
BlockNumber: 0,
|
||||
GasLimit: 0,
|
||||
GasUsed: 0,
|
||||
Timestamp: 0,
|
||||
ExtraData: make([]byte, 32),
|
||||
BaseFeePerGas: make([]byte, 32),
|
||||
BlockHash: make([]byte, 32),
|
||||
Transactions: make([][]byte, 0),
|
||||
PrevRandao: make([]byte, 32),
|
||||
},
|
||||
},
|
||||
},
|
||||
Signature: make([]byte, 96),
|
||||
}
|
||||
func signedTestBlindedBlockBellatrix(t *testing.T, slot types.Slot) interfaces.SignedBeaconBlock {
|
||||
b := util.NewBlindedBeaconBlockBellatrix()
|
||||
b.Block.Slot = slot
|
||||
s, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user