ssz detection support for deneb (#12537)

Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
This commit is contained in:
kasey
2023-06-15 15:37:01 -05:00
committed by Preston Van Loon
parent 2121d1f4f4
commit 642988f977
2 changed files with 129 additions and 7 deletions

View File

@@ -68,6 +68,8 @@ func FromForkVersion(cv [fieldparams.VersionLength]byte) (*VersionedUnmarshaler,
fork = version.Bellatrix fork = version.Bellatrix
case bytesutil.ToBytes4(cfg.CapellaForkVersion): case bytesutil.ToBytes4(cfg.CapellaForkVersion):
fork = version.Capella fork = version.Capella
case bytesutil.ToBytes4(cfg.DenebForkVersion):
fork = version.Deneb
default: default:
return nil, errors.Wrapf(ErrForkNotFound, "version=%#x", cv) return nil, errors.Wrapf(ErrForkNotFound, "version=%#x", cv)
} }
@@ -123,6 +125,16 @@ func (cf *VersionedUnmarshaler) UnmarshalBeaconState(marshaled []byte) (s state.
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to init state trie from state, detected fork=%s", forkName) 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: default:
return nil, fmt.Errorf("unable to initialize BeaconState for fork version=%s", forkName) return nil, fmt.Errorf("unable to initialize BeaconState for fork version=%s", forkName)
} }
@@ -169,6 +181,8 @@ func (cf *VersionedUnmarshaler) UnmarshalBeaconBlock(marshaled []byte) (interfac
blk = &ethpb.SignedBeaconBlockBellatrix{} blk = &ethpb.SignedBeaconBlockBellatrix{}
case version.Capella: case version.Capella:
blk = &ethpb.SignedBeaconBlockCapella{} blk = &ethpb.SignedBeaconBlockCapella{}
case version.Deneb:
blk = &ethpb.SignedBeaconBlockDeneb{}
default: default:
forkName := version.String(cf.Fork) forkName := version.String(cf.Fork)
return nil, fmt.Errorf("unable to initialize ReadOnlyBeaconBlock for fork version=%s at slot=%d", forkName, slot) return nil, fmt.Errorf("unable to initialize ReadOnlyBeaconBlock for fork version=%s at slot=%d", forkName, slot)
@@ -202,6 +216,8 @@ func (cf *VersionedUnmarshaler) UnmarshalBlindedBeaconBlock(marshaled []byte) (i
blk = &ethpb.SignedBlindedBeaconBlockBellatrix{} blk = &ethpb.SignedBlindedBeaconBlockBellatrix{}
case version.Capella: case version.Capella:
blk = &ethpb.SignedBlindedBeaconBlockCapella{} blk = &ethpb.SignedBlindedBeaconBlockCapella{}
case version.Deneb:
blk = &ethpb.SignedBlindedBeaconBlockDeneb{}
default: default:
forkName := version.String(cf.Fork) forkName := version.String(cf.Fork)
return nil, fmt.Errorf("unable to initialize ReadOnlyBeaconBlock for fork version=%s at slot=%d", forkName, slot) return nil, fmt.Errorf("unable to initialize ReadOnlyBeaconBlock for fork version=%s at slot=%d", forkName, slot)

View File

@@ -48,7 +48,7 @@ func TestSlotFromBlock(t *testing.T) {
} }
func TestByState(t *testing.T) { func TestByState(t *testing.T) {
undo, err := hackCapellaMaxuint() undo, err := hackDenebMaxuint()
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
require.NoError(t, undo()) require.NoError(t, undo())
@@ -60,6 +60,8 @@ func TestByState(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
capellaSlot, err := slots.EpochStart(bc.CapellaForkEpoch) capellaSlot, err := slots.EpochStart(bc.CapellaForkEpoch)
require.NoError(t, err) require.NoError(t, err)
denebSlot, err := slots.EpochStart(bc.DenebForkEpoch)
require.NoError(t, err)
cases := []struct { cases := []struct {
name string name string
version int version int
@@ -90,6 +92,12 @@ func TestByState(t *testing.T) {
slot: capellaSlot, slot: capellaSlot,
forkversion: bytesutil.ToBytes4(bc.CapellaForkVersion), forkversion: bytesutil.ToBytes4(bc.CapellaForkVersion),
}, },
{
name: "deneb",
version: version.Deneb,
slot: denebSlot,
forkversion: bytesutil.ToBytes4(bc.DenebForkVersion),
},
} }
for _, c := range cases { for _, c := range cases {
st, err := stateForVersion(c.version) st, err := stateForVersion(c.version)
@@ -120,6 +128,8 @@ func stateForVersion(v int) (state.BeaconState, error) {
return util.NewBeaconStateBellatrix() return util.NewBeaconStateBellatrix()
case version.Capella: case version.Capella:
return util.NewBeaconStateCapella() return util.NewBeaconStateCapella()
case version.Deneb:
return util.NewBeaconStateDeneb()
default: default:
return nil, fmt.Errorf("unrecognized version %d", v) return nil, fmt.Errorf("unrecognized version %d", v)
} }
@@ -127,7 +137,7 @@ func stateForVersion(v int) (state.BeaconState, error) {
func TestUnmarshalState(t *testing.T) { func TestUnmarshalState(t *testing.T) {
ctx := context.Background() ctx := context.Background()
undo, err := hackCapellaMaxuint() undo, err := hackDenebMaxuint()
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
require.NoError(t, undo()) require.NoError(t, undo())
@@ -137,6 +147,10 @@ func TestUnmarshalState(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
bellaSlot, err := slots.EpochStart(bc.BellatrixForkEpoch) bellaSlot, err := slots.EpochStart(bc.BellatrixForkEpoch)
require.NoError(t, err) 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 { cases := []struct {
name string name string
version int version int
@@ -161,6 +175,18 @@ func TestUnmarshalState(t *testing.T) {
slot: bellaSlot, slot: bellaSlot,
forkversion: bytesutil.ToBytes4(bc.BellatrixForkVersion), 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 { for _, c := range cases {
st, err := stateForVersion(c.version) st, err := stateForVersion(c.version)
@@ -185,19 +211,19 @@ func TestUnmarshalState(t *testing.T) {
} }
} }
func hackCapellaMaxuint() (func() error, error) { func hackDenebMaxuint() (func() error, error) {
// We monkey patch the config to use a smaller value for the bellatrix fork epoch. // 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. // 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 // 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. // breaking conformance, adding a special case to the conformance unit test, or patch it here.
bc := params.MainnetConfig().Copy() bc := params.MainnetConfig().Copy()
bc.CapellaForkEpoch = math.MaxUint32 bc.DenebForkEpoch = math.MaxUint32
undo, err := params.SetActiveWithUndo(bc) undo, err := params.SetActiveWithUndo(bc)
return undo, err return undo, err
} }
func TestUnmarshalBlock(t *testing.T) { func TestUnmarshalBlock(t *testing.T) {
undo, err := hackCapellaMaxuint() undo, err := hackDenebMaxuint()
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
require.NoError(t, undo()) require.NoError(t, undo())
@@ -205,10 +231,16 @@ func TestUnmarshalBlock(t *testing.T) {
genv := bytesutil.ToBytes4(params.BeaconConfig().GenesisForkVersion) genv := bytesutil.ToBytes4(params.BeaconConfig().GenesisForkVersion)
altairv := bytesutil.ToBytes4(params.BeaconConfig().AltairForkVersion) altairv := bytesutil.ToBytes4(params.BeaconConfig().AltairForkVersion)
bellav := bytesutil.ToBytes4(params.BeaconConfig().BellatrixForkVersion) 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) altairS, err := slots.EpochStart(params.BeaconConfig().AltairForkEpoch)
require.NoError(t, err) require.NoError(t, err)
bellaS, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch) bellaS, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch)
require.NoError(t, err) require.NoError(t, err)
capellaS, err := slots.EpochStart(params.BeaconConfig().CapellaForkEpoch)
require.NoError(t, err)
denebS, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch)
require.NoError(t, err)
cases := []struct { cases := []struct {
b func(*testing.T, primitives.Slot) interfaces.ReadOnlySignedBeaconBlock b func(*testing.T, primitives.Slot) interfaces.ReadOnlySignedBeaconBlock
name string name string
@@ -245,6 +277,24 @@ func TestUnmarshalBlock(t *testing.T) {
version: bellav, version: bellav,
slot: bellaS, 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", name: "bellatrix block in altair slot",
b: signedTestBlockBellatrix, b: signedTestBlockBellatrix,
@@ -289,7 +339,7 @@ func TestUnmarshalBlock(t *testing.T) {
} }
func TestUnmarshalBlindedBlock(t *testing.T) { func TestUnmarshalBlindedBlock(t *testing.T) {
undo, err := hackCapellaMaxuint() undo, err := hackDenebMaxuint()
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
require.NoError(t, undo()) require.NoError(t, undo())
@@ -297,10 +347,16 @@ func TestUnmarshalBlindedBlock(t *testing.T) {
genv := bytesutil.ToBytes4(params.BeaconConfig().GenesisForkVersion) genv := bytesutil.ToBytes4(params.BeaconConfig().GenesisForkVersion)
altairv := bytesutil.ToBytes4(params.BeaconConfig().AltairForkVersion) altairv := bytesutil.ToBytes4(params.BeaconConfig().AltairForkVersion)
bellav := bytesutil.ToBytes4(params.BeaconConfig().BellatrixForkVersion) 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) altairS, err := slots.EpochStart(params.BeaconConfig().AltairForkEpoch)
require.NoError(t, err) require.NoError(t, err)
bellaS, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch) bellaS, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch)
require.NoError(t, err) require.NoError(t, err)
capellaS, err := slots.EpochStart(params.BeaconConfig().CapellaForkEpoch)
require.NoError(t, err)
denebS, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch)
require.NoError(t, err)
cases := []struct { cases := []struct {
b func(*testing.T, primitives.Slot) interfaces.ReadOnlySignedBeaconBlock b func(*testing.T, primitives.Slot) interfaces.ReadOnlySignedBeaconBlock
name string name string
@@ -344,6 +400,24 @@ func TestUnmarshalBlindedBlock(t *testing.T) {
slot: bellaS - 1, slot: bellaS - 1,
err: errBlockForkMismatch, 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", name: "genesis block in altair slot",
b: signedTestBlockGenesis, b: signedTestBlockGenesis,
@@ -411,3 +485,35 @@ func signedTestBlindedBlockBellatrix(t *testing.T, slot primitives.Slot) interfa
require.NoError(t, err) require.NoError(t, err)
return s 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
}