Capella: Add DB changes (#11624)

* Add Capella DB changes

* Add tests
This commit is contained in:
terencechain
2022-11-07 07:26:27 -08:00
committed by GitHub
parent 37108e6ed8
commit 19f6d3bef6
7 changed files with 285 additions and 0 deletions

View File

@@ -789,6 +789,16 @@ func unmarshalBlock(_ context.Context, enc []byte) (interfaces.SignedBeaconBlock
if err := rawBlock.UnmarshalSSZ(enc[len(bellatrixBlindKey):]); err != nil {
return nil, errors.Wrap(err, "could not unmarshal blinded Bellatrix block")
}
case hasCapellaKey(enc):
rawBlock = &ethpb.SignedBeaconBlockCapella{}
if err := rawBlock.UnmarshalSSZ(enc[len(capellaKey):]); err != nil {
return nil, errors.Wrap(err, "could not unmarshal Capella block")
}
case hasCapellaBlindKey(enc):
rawBlock = &ethpb.SignedBlindedBeaconBlockCapella{}
if err := rawBlock.UnmarshalSSZ(enc[len(capellaBlindKey):]); err != nil {
return nil, errors.Wrap(err, "could not unmarshal blinded Capella block")
}
default:
// Marshal block bytes to phase 0 beacon block.
rawBlock = &ethpb.SignedBeaconBlock{}
@@ -828,6 +838,11 @@ func marshalBlock(_ context.Context, blk interfaces.SignedBeaconBlock) ([]byte,
}
}
switch blockToSave.Version() {
case version.Capella:
if blockToSave.IsBlinded() {
return snappy.Encode(nil, append(capellaBlindKey, encodedBlock...)), nil
}
return snappy.Encode(nil, append(capellaKey, encodedBlock...)), nil
case version.Bellatrix:
if blockToSave.IsBlinded() {
return snappy.Encode(nil, append(bellatrixBlindKey, encodedBlock...)), nil

View File

@@ -67,6 +67,28 @@ var blockTests = []struct {
return blocks.NewSignedBeaconBlock(b)
},
},
{
name: "capella",
newBlock: func(slot types.Slot, root []byte) (interfaces.SignedBeaconBlock, error) {
b := util.NewBeaconBlockCapella()
b.Block.Slot = slot
if root != nil {
b.Block.ParentRoot = root
}
return blocks.NewSignedBeaconBlock(b)
},
},
{
name: "capella blind",
newBlock: func(slot types.Slot, root []byte) (interfaces.SignedBeaconBlock, error) {
b := util.NewBlindedBeaconBlockCapella()
b.Block.Slot = slot
if root != nil {
b.Block.ParentRoot = root
}
return blocks.NewSignedBeaconBlock(b)
},
},
}
func TestStore_SaveBackfillBlockRoot(t *testing.T) {
@@ -332,6 +354,10 @@ func TestStore_BlocksCRUD_NoCache(t *testing.T) {
wanted, err = blk.ToBlinded()
require.NoError(t, err)
}
if _, err := blk.PbCapellaBlock(); err == nil {
wanted, err = blk.ToBlinded()
require.NoError(t, err)
}
wantedPb, err := wanted.Proto()
require.NoError(t, err)
retrievedPb, err := retrievedBlock.Proto()
@@ -551,6 +577,10 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
if _, err := block1.PbCapellaBlock(); err == nil {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
wantedPb, err := wanted.Proto()
require.NoError(t, err)
bPb, err := b.Proto()
@@ -569,6 +599,10 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
wanted2, err = block2.ToBlinded()
require.NoError(t, err)
}
if _, err := block2.PbCapellaBlock(); err == nil {
wanted2, err = block2.ToBlinded()
require.NoError(t, err)
}
wanted2Pb, err := wanted2.Proto()
require.NoError(t, err)
bPb, err = b.Proto()
@@ -587,6 +621,10 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
if _, err := block3.PbCapellaBlock(); err == nil {
wanted, err = wanted.ToBlinded()
require.NoError(t, err)
}
wantedPb, err = wanted.Proto()
require.NoError(t, err)
bPb, err = b.Proto()
@@ -623,6 +661,10 @@ func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
wanted, err = block1.ToBlinded()
require.NoError(t, err)
}
if _, err := block1.PbCapellaBlock(); err == nil {
wanted, err = block1.ToBlinded()
require.NoError(t, err)
}
wantedPb, err := wanted.Proto()
require.NoError(t, err)
bPb, err := b.Proto()
@@ -640,6 +682,10 @@ func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
if _, err := genesisBlock.PbCapellaBlock(); err == nil {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
wantedPb, err = wanted.Proto()
require.NoError(t, err)
bPb, err = b.Proto()
@@ -657,6 +703,10 @@ func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
if _, err := genesisBlock.PbCapellaBlock(); err == nil {
wanted, err = genesisBlock.ToBlinded()
require.NoError(t, err)
}
wantedPb, err = wanted.Proto()
require.NoError(t, err)
bPb, err = b.Proto()
@@ -753,6 +803,10 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
wanted, err = b1.ToBlinded()
require.NoError(t, err)
}
if _, err := b1.PbCapellaBlock(); err == nil {
wanted, err = b1.ToBlinded()
require.NoError(t, err)
}
retrieved0Pb, err := retrievedBlocks[0].Proto()
require.NoError(t, err)
wantedPb, err := wanted.Proto()
@@ -769,6 +823,10 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
wanted, err = b2.ToBlinded()
require.NoError(t, err)
}
if _, err := b2.PbCapellaBlock(); err == nil {
wanted, err = b2.ToBlinded()
require.NoError(t, err)
}
retrieved0Pb, err = retrievedBlocks[0].Proto()
require.NoError(t, err)
wantedPb, err = wanted.Proto()
@@ -779,6 +837,10 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
wanted, err = b3.ToBlinded()
require.NoError(t, err)
}
if _, err := b3.PbCapellaBlock(); err == nil {
wanted, err = b3.ToBlinded()
require.NoError(t, err)
}
retrieved1Pb, err := retrievedBlocks[1].Proto()
require.NoError(t, err)
wantedPb, err = wanted.Proto()

View File

@@ -30,3 +30,10 @@ func hasCapellaKey(enc []byte) bool {
}
return bytes.Equal(enc[:len(capellaKey)], capellaKey)
}
func hasCapellaBlindKey(enc []byte) bool {
if len(capellaBlindKey) >= len(enc) {
return false
}
return bytes.Equal(enc[:len(capellaBlindKey)], capellaBlindKey)
}

View File

@@ -53,6 +53,8 @@ var (
bellatrixKey = []byte("merge")
bellatrixBlindKey = []byte("blind-bellatrix")
capellaKey = []byte("capella")
capellaBlindKey = []byte("blind-capella")
// block root included in the beacon state used by weak subjectivity initial sync
originCheckpointBlockRootKey = []byte("origin-checkpoint-block-root")
// block root tracking the progress of backfill, or pointing at genesis if backfill has not been initiated

View File

@@ -889,6 +889,141 @@ func HydrateV2BlindedBeaconBlockBodyBellatrix(b *v2.BlindedBeaconBlockBodyBellat
return b
}
// HydrateSignedBeaconBlockCapella hydrates a signed beacon block with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateSignedBeaconBlockCapella(b *ethpb.SignedBeaconBlockCapella) *ethpb.SignedBeaconBlockCapella {
if b.Signature == nil {
b.Signature = make([]byte, fieldparams.BLSSignatureLength)
}
b.Block = HydrateBeaconBlockCapella(b.Block)
return b
}
// HydrateBeaconBlockCapella hydrates a beacon block with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateBeaconBlockCapella(b *ethpb.BeaconBlockCapella) *ethpb.BeaconBlockCapella {
if b == nil {
b = &ethpb.BeaconBlockCapella{}
}
if b.ParentRoot == nil {
b.ParentRoot = make([]byte, fieldparams.RootLength)
}
if b.StateRoot == nil {
b.StateRoot = make([]byte, fieldparams.RootLength)
}
b.Body = HydrateBeaconBlockBodyCapella(b.Body)
return b
}
// HydrateBeaconBlockBodyCapella hydrates a beacon block body with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateBeaconBlockBodyCapella(b *ethpb.BeaconBlockBodyCapella) *ethpb.BeaconBlockBodyCapella {
if b == nil {
b = &ethpb.BeaconBlockBodyCapella{}
}
if b.RandaoReveal == nil {
b.RandaoReveal = make([]byte, fieldparams.BLSSignatureLength)
}
if b.Graffiti == nil {
b.Graffiti = make([]byte, fieldparams.RootLength)
}
if b.Eth1Data == nil {
b.Eth1Data = &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
}
}
if b.SyncAggregate == nil {
b.SyncAggregate = &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncAggregateSyncCommitteeBytesLength),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
}
}
if b.ExecutionPayload == nil {
b.ExecutionPayload = &enginev1.ExecutionPayloadCapella{
ParentHash: make([]byte, fieldparams.RootLength),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, fieldparams.RootLength),
ReceiptsRoot: make([]byte, fieldparams.RootLength),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, fieldparams.RootLength),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
Transactions: make([][]byte, 0),
ExtraData: make([]byte, 0),
}
}
return b
}
// HydrateSignedBlindedBeaconBlockCapella hydrates a signed blinded beacon block with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateSignedBlindedBeaconBlockCapella(b *ethpb.SignedBlindedBeaconBlockCapella) *ethpb.SignedBlindedBeaconBlockCapella {
if b.Signature == nil {
b.Signature = make([]byte, fieldparams.BLSSignatureLength)
}
b.Block = HydrateBlindedBeaconBlockCapella(b.Block)
return b
}
// HydrateBlindedBeaconBlockCapella hydrates a blinded beacon block with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateBlindedBeaconBlockCapella(b *ethpb.BlindedBeaconBlockCapella) *ethpb.BlindedBeaconBlockCapella {
if b == nil {
b = &ethpb.BlindedBeaconBlockCapella{}
}
if b.ParentRoot == nil {
b.ParentRoot = make([]byte, fieldparams.RootLength)
}
if b.StateRoot == nil {
b.StateRoot = make([]byte, fieldparams.RootLength)
}
b.Body = HydrateBlindedBeaconBlockBodyCapella(b.Body)
return b
}
// HydrateBlindedBeaconBlockBodyCapella hydrates a blinded beacon block body with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateBlindedBeaconBlockBodyCapella(b *ethpb.BlindedBeaconBlockBodyCapella) *ethpb.BlindedBeaconBlockBodyCapella {
if b == nil {
b = &ethpb.BlindedBeaconBlockBodyCapella{}
}
if b.RandaoReveal == nil {
b.RandaoReveal = make([]byte, fieldparams.BLSSignatureLength)
}
if b.Graffiti == nil {
b.Graffiti = make([]byte, 32)
}
if b.Eth1Data == nil {
b.Eth1Data = &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
}
}
if b.SyncAggregate == nil {
b.SyncAggregate = &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncAggregateSyncCommitteeBytesLength),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
}
}
if b.ExecutionPayloadHeader == nil {
b.ExecutionPayloadHeader = &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, fieldparams.RootLength),
ReceiptsRoot: make([]byte, fieldparams.RootLength),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, 32),
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
TransactionsRoot: make([]byte, fieldparams.RootLength),
ExtraData: make([]byte, 0),
WithdrawalsRoot: make([]byte, fieldparams.RootLength),
}
}
return b
}
func SaveBlock(tb assertions.AssertionTestingTB, ctx context.Context, db iface.NoHeadAccessDatabase, b interface{}) interfaces.SignedBeaconBlock {
wsb, err := blocks.NewSignedBeaconBlock(b)
require.NoError(tb, err)

View File

@@ -303,3 +303,57 @@ func TestHydrateV2BlindedBeaconBlockBodyBellatrix_NoError(t *testing.T) {
_, err := b.HashTreeRoot()
require.NoError(t, err)
}
func TestHydrateSignedBeaconBlockCapella_NoError(t *testing.T) {
b := &ethpbalpha.SignedBeaconBlockCapella{}
b = HydrateSignedBeaconBlockCapella(b)
_, err := b.HashTreeRoot()
require.NoError(t, err)
_, err = b.Block.HashTreeRoot()
require.NoError(t, err)
_, err = b.Block.Body.HashTreeRoot()
require.NoError(t, err)
}
func TestHydrateBeaconBlockCapella_NoError(t *testing.T) {
b := &ethpbalpha.BeaconBlockCapella{}
b = HydrateBeaconBlockCapella(b)
_, err := b.HashTreeRoot()
require.NoError(t, err)
_, err = b.Body.HashTreeRoot()
require.NoError(t, err)
}
func TestHydrateBeaconBlockBodyCapella_NoError(t *testing.T) {
b := &ethpbalpha.BeaconBlockBodyCapella{}
b = HydrateBeaconBlockBodyCapella(b)
_, err := b.HashTreeRoot()
require.NoError(t, err)
}
func TestHydrateSignedBlindedBeaconBlockCapella_NoError(t *testing.T) {
b := &ethpbalpha.SignedBlindedBeaconBlockCapella{}
b = HydrateSignedBlindedBeaconBlockCapella(b)
_, err := b.HashTreeRoot()
require.NoError(t, err)
_, err = b.Block.HashTreeRoot()
require.NoError(t, err)
_, err = b.Block.Body.HashTreeRoot()
require.NoError(t, err)
}
func TestHydrateBlindedBeaconBlockCapella_NoError(t *testing.T) {
b := &ethpbalpha.BlindedBeaconBlockCapella{}
b = HydrateBlindedBeaconBlockCapella(b)
_, err := b.HashTreeRoot()
require.NoError(t, err)
_, err = b.Body.HashTreeRoot()
require.NoError(t, err)
}
func TestHydrateBlindedBeaconBlockBodyCapella_NoError(t *testing.T) {
b := &ethpbalpha.BlindedBeaconBlockBodyCapella{}
b = HydrateBlindedBeaconBlockBodyCapella(b)
_, err := b.HashTreeRoot()
require.NoError(t, err)
}

View File

@@ -19,3 +19,13 @@ func NewBlindedBeaconBlockBellatrix() *ethpb.SignedBlindedBeaconBlockBellatrix {
func NewBlindedBeaconBlockBellatrixV2() *v2.SignedBlindedBeaconBlockBellatrix {
return HydrateV2SignedBlindedBeaconBlockBellatrix(&v2.SignedBlindedBeaconBlockBellatrix{})
}
// NewBeaconBlockCapella creates a beacon block with minimum marshalable fields.
func NewBeaconBlockCapella() *ethpb.SignedBeaconBlockCapella {
return HydrateSignedBeaconBlockCapella(&ethpb.SignedBeaconBlockCapella{})
}
// NewBlindedBeaconBlockCapella creates a blinded beacon block with minimum marshalable fields.
func NewBlindedBeaconBlockCapella() *ethpb.SignedBlindedBeaconBlockCapella {
return HydrateSignedBlindedBeaconBlockCapella(&ethpb.SignedBlindedBeaconBlockCapella{})
}