Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions encoding/ssz/detect/configfork.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ func FromForkVersion(cv [fieldparams.VersionLength]byte) (*VersionedUnmarshaler,
fork = version.Bellatrix
case bytesutil.ToBytes4(cfg.CapellaForkVersion):
fork = version.Capella
case bytesutil.ToBytes4(cfg.DenebForkVersion):
fork = version.Deneb
default:
return nil, errors.Wrapf(ErrForkNotFound, "version=%#x", cv)
}
Expand Down Expand Up @@ -123,6 +125,16 @@ func (cf *VersionedUnmarshaler) UnmarshalBeaconState(marshaled []byte) (s state.
if err != nil {
return nil, errors.Wrapf(err, "failed to init state trie from state, detected fork=%s", forkName)
}
case version.Deneb:
st := &ethpb.BeaconStateDeneb{}
err = st.UnmarshalSSZ(marshaled)
if err != nil {
return nil, errors.Wrapf(err, "failed to unmarshal state, detected fork=%s", forkName)
}
s, err = state_native.InitializeFromProtoUnsafeDeneb(st)
if err != nil {
return nil, errors.Wrapf(err, "failed to init state trie from state, detected fork=%s", forkName)
}
default:
return nil, fmt.Errorf("unable to initialize BeaconState for fork version=%s", forkName)
}
Expand Down Expand Up @@ -169,6 +181,8 @@ func (cf *VersionedUnmarshaler) UnmarshalBeaconBlock(marshaled []byte) (interfac
blk = &ethpb.SignedBeaconBlockBellatrix{}
case version.Capella:
blk = &ethpb.SignedBeaconBlockCapella{}
case version.Deneb:
blk = &ethpb.SignedBeaconBlockDeneb{}
default:
forkName := version.String(cf.Fork)
return nil, fmt.Errorf("unable to initialize ReadOnlyBeaconBlock for fork version=%s at slot=%d", forkName, slot)
Expand Down Expand Up @@ -202,6 +216,8 @@ func (cf *VersionedUnmarshaler) UnmarshalBlindedBeaconBlock(marshaled []byte) (i
blk = &ethpb.SignedBlindedBeaconBlockBellatrix{}
case version.Capella:
blk = &ethpb.SignedBlindedBeaconBlockCapella{}
case version.Deneb:
blk = &ethpb.SignedBlindedBeaconBlockDeneb{}
default:
forkName := version.String(cf.Fork)
return nil, fmt.Errorf("unable to initialize ReadOnlyBeaconBlock for fork version=%s at slot=%d", forkName, slot)
Expand Down
114 changes: 107 additions & 7 deletions encoding/ssz/detect/configfork_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestSlotFromBlock(t *testing.T) {
}

func TestByState(t *testing.T) {
undo, err := hackCapellaMaxuint()
undo, err := hackDenebMaxuint()
require.NoError(t, err)
defer func() {
require.NoError(t, undo())
Expand All @@ -60,6 +60,8 @@ func TestByState(t *testing.T) {
require.NoError(t, err)
capellaSlot, err := slots.EpochStart(bc.CapellaForkEpoch)
require.NoError(t, err)
denebSlot, err := slots.EpochStart(bc.DenebForkEpoch)
require.NoError(t, err)
cases := []struct {
name string
version int
Expand Down Expand Up @@ -90,6 +92,12 @@ func TestByState(t *testing.T) {
slot: capellaSlot,
forkversion: bytesutil.ToBytes4(bc.CapellaForkVersion),
},
{
name: "deneb",
version: version.Deneb,
slot: denebSlot,
forkversion: bytesutil.ToBytes4(bc.DenebForkVersion),
},
}
for _, c := range cases {
st, err := stateForVersion(c.version)
Expand Down Expand Up @@ -120,21 +128,25 @@ func stateForVersion(v int) (state.BeaconState, error) {
return util.NewBeaconStateBellatrix()
case version.Capella:
return util.NewBeaconStateCapella()
case version.Deneb:
return util.NewBeaconStateDeneb()
default:
return nil, fmt.Errorf("unrecognized version %d", v)
}
}

func TestUnmarshalState(t *testing.T) {
ctx := context.Background()
undo, err := hackCapellaMaxuint()
undo, err := hackDenebMaxuint()
require.NoError(t, err)
defer func() {
require.NoError(t, undo())
}()
bc := params.BeaconConfig()
altairSlot, err := slots.EpochStart(bc.AltairForkEpoch)
bellaSlot, err := slots.EpochStart(bc.BellatrixForkEpoch)
capellaSlot, err := slots.EpochStart(bc.CapellaForkEpoch)
denebSlot, err := slots.EpochStart(bc.DenebForkEpoch)
require.NoError(t, err)
cases := []struct {
name string
Expand All @@ -160,6 +172,18 @@ func TestUnmarshalState(t *testing.T) {
slot: bellaSlot,
forkversion: bytesutil.ToBytes4(bc.BellatrixForkVersion),
},
{
name: "capella",
version: version.Capella,
slot: capellaSlot,
forkversion: bytesutil.ToBytes4(bc.CapellaForkVersion),
},
{
name: "deneb",
version: version.Deneb,
slot: denebSlot,
forkversion: bytesutil.ToBytes4(bc.DenebForkVersion),
},
}
for _, c := range cases {
st, err := stateForVersion(c.version)
Expand All @@ -184,28 +208,32 @@ func TestUnmarshalState(t *testing.T) {
}
}

func hackCapellaMaxuint() (func() error, error) {
// We monkey patch the config to use a smaller value for the bellatrix fork epoch.
func hackDenebMaxuint() (func() error, error) {
// We monkey patch the config to use a smaller value for the next fork epoch (which is always set to maxint).
// Upstream configs use MaxUint64, which leads to a multiplication overflow when converting epoch->slot.
// Unfortunately we have unit tests that assert our config matches the upstream config, so we have to choose between
// breaking conformance, adding a special case to the conformance unit test, or patch it here.
bc := params.MainnetConfig().Copy()
bc.CapellaForkEpoch = math.MaxUint32
bc.DenebForkEpoch = math.MaxUint32
undo, err := params.SetActiveWithUndo(bc)
return undo, err
}

func TestUnmarshalBlock(t *testing.T) {
undo, err := hackCapellaMaxuint()
undo, err := hackDenebMaxuint()
require.NoError(t, err)
defer func() {
require.NoError(t, undo())
}()
genv := bytesutil.ToBytes4(params.BeaconConfig().GenesisForkVersion)
altairv := bytesutil.ToBytes4(params.BeaconConfig().AltairForkVersion)
bellav := bytesutil.ToBytes4(params.BeaconConfig().BellatrixForkVersion)
capellaV := bytesutil.ToBytes4(params.BeaconConfig().CapellaForkVersion)
denebV := bytesutil.ToBytes4(params.BeaconConfig().DenebForkVersion)
altairS, err := slots.EpochStart(params.BeaconConfig().AltairForkEpoch)
bellaS, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch)
capellaS, err := slots.EpochStart(params.BeaconConfig().CapellaForkEpoch)
denebS, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch)
require.NoError(t, err)
cases := []struct {
b func(*testing.T, primitives.Slot) interfaces.ReadOnlySignedBeaconBlock
Expand Down Expand Up @@ -243,6 +271,24 @@ func TestUnmarshalBlock(t *testing.T) {
version: bellav,
slot: bellaS,
},
{
name: "first slot of capella",
b: signedTestBlockCapella,
version: capellaV,
slot: capellaS,
},
{
name: "last slot of capella",
b: signedTestBlockCapella,
version: capellaV,
slot: denebS - 1,
},
{
name: "first slot of deneb",
b: signedTestBlockDeneb,
version: denebV,
slot: denebS,
},
{
name: "bellatrix block in altair slot",
b: signedTestBlockBellatrix,
Expand Down Expand Up @@ -287,16 +333,20 @@ func TestUnmarshalBlock(t *testing.T) {
}

func TestUnmarshalBlindedBlock(t *testing.T) {
undo, err := hackCapellaMaxuint()
undo, err := hackDenebMaxuint()
require.NoError(t, err)
defer func() {
require.NoError(t, undo())
}()
genv := bytesutil.ToBytes4(params.BeaconConfig().GenesisForkVersion)
altairv := bytesutil.ToBytes4(params.BeaconConfig().AltairForkVersion)
bellav := bytesutil.ToBytes4(params.BeaconConfig().BellatrixForkVersion)
capellaV := bytesutil.ToBytes4(params.BeaconConfig().CapellaForkVersion)
denebV := bytesutil.ToBytes4(params.BeaconConfig().DenebForkVersion)
altairS, err := slots.EpochStart(params.BeaconConfig().AltairForkEpoch)
bellaS, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch)
capellaS, err := slots.EpochStart(params.BeaconConfig().CapellaForkEpoch)
denebS, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch)
require.NoError(t, err)
cases := []struct {
b func(*testing.T, primitives.Slot) interfaces.ReadOnlySignedBeaconBlock
Expand Down Expand Up @@ -341,6 +391,24 @@ func TestUnmarshalBlindedBlock(t *testing.T) {
slot: bellaS - 1,
err: errBlockForkMismatch,
},
{
name: "first slot of capella",
b: signedTestBlindedBlockCapella,
version: capellaV,
slot: capellaS,
},
{
name: "last slot of capella",
b: signedTestBlindedBlockCapella,
version: capellaV,
slot: denebS - 1,
},
{
name: "first slot of deneb",
b: signedTestBlindedBlockDeneb,
version: denebV,
slot: denebS,
},
{
name: "genesis block in altair slot",
b: signedTestBlockGenesis,
Expand Down Expand Up @@ -408,3 +476,35 @@ func signedTestBlindedBlockBellatrix(t *testing.T, slot primitives.Slot) interfa
require.NoError(t, err)
return s
}

func signedTestBlockCapella(t *testing.T, slot primitives.Slot) interfaces.ReadOnlySignedBeaconBlock {
b := util.NewBeaconBlockCapella()
b.Block.Slot = slot
s, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
return s
}

func signedTestBlindedBlockCapella(t *testing.T, slot primitives.Slot) interfaces.ReadOnlySignedBeaconBlock {
b := util.NewBlindedBeaconBlockCapella()
b.Block.Slot = slot
s, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
return s
}

func signedTestBlockDeneb(t *testing.T, slot primitives.Slot) interfaces.ReadOnlySignedBeaconBlock {
b := util.NewBeaconBlockDeneb()
b.Block.Slot = slot
s, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
return s
}

func signedTestBlindedBlockDeneb(t *testing.T, slot primitives.Slot) interfaces.ReadOnlySignedBeaconBlock {
b := util.NewBlindedBeaconBlockDeneb()
b.Block.Slot = slot
s, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
return s
}