From a62796ab4dd3cf2dfdf1923cd70db3c5e3deb874 Mon Sep 17 00:00:00 2001 From: Giulio rebuffo Date: Tue, 3 Oct 2023 23:50:43 +0200 Subject: [PATCH] Added block snapshot format (attempt for Caplin) (#8357) Added block snapshot format --- cl/cltypes/beacon_block.go | 19 -- cl/cltypes/solid/attestation.go | 2 +- cl/cltypes/solid/attestation_data.go | 29 ++- cl/cltypes/solid/checkpoint.go | 16 ++ cl/cltypes/solid/pending_attestation.go | 2 +- .../snapshot_format/attestations.go | 194 +++++++++++++++++ .../snapshot_format/attestations_test.go | 40 ++++ cl/persistence/snapshot_format/blocks.go | 195 ++++++++++++++++++ cl/persistence/snapshot_format/blocks_test.go | 72 +++++++ cl/persistence/snapshot_format/chunks.go | 61 ++++++ .../test_data/altair.ssz_snappy | Bin 0 -> 19953 bytes .../test_data/bellatrix.ssz_snappy | Bin 0 -> 13589 bytes .../test_data/capella.ssz_snappy | Bin 0 -> 20665 bytes .../test_data/deneb.ssz_snappy | Bin 0 -> 12263 bytes .../test_data/phase0.ssz_snappy | Bin 0 -> 12888 bytes 15 files changed, 607 insertions(+), 23 deletions(-) create mode 100644 cl/persistence/snapshot_format/attestations.go create mode 100644 cl/persistence/snapshot_format/attestations_test.go create mode 100644 cl/persistence/snapshot_format/blocks.go create mode 100644 cl/persistence/snapshot_format/blocks_test.go create mode 100644 cl/persistence/snapshot_format/chunks.go create mode 100644 cl/persistence/snapshot_format/test_data/altair.ssz_snappy create mode 100644 cl/persistence/snapshot_format/test_data/bellatrix.ssz_snappy create mode 100644 cl/persistence/snapshot_format/test_data/capella.ssz_snappy create mode 100644 cl/persistence/snapshot_format/test_data/deneb.ssz_snappy create mode 100644 cl/persistence/snapshot_format/test_data/phase0.ssz_snappy diff --git a/cl/cltypes/beacon_block.go b/cl/cltypes/beacon_block.go index 818e6d37629..cf871d72d01 100644 --- a/cl/cltypes/beacon_block.go +++ b/cl/cltypes/beacon_block.go @@ -85,25 +85,6 @@ func (b *SignedBeaconBlock) Version() clparams.StateVersion { return b.Block.Body.Version } -// Version returns beacon block version. -func (b *SignedBeaconBlock) EncodeForStorage(buf []byte) ([]byte, error) { - return ssz2.MarshalSSZ(buf, b.getSchemaForStorage()...) -} - -func (b *SignedBeaconBlock) DecodeForStorage(buf []byte, s int) error { - b.Block.Body.Version = clparams.StateVersion(s) - if len(buf) < b.EncodingSizeSSZ() { - return fmt.Errorf("[BeaconBody] err: %s", ssz.ErrLowBufferSize) - } - return ssz2.UnmarshalSSZ(buf, s, b.getSchemaForStorage()...) -} - -// Version returns beacon block version. -func (b *SignedBeaconBlock) getSchemaForStorage() []interface{} { - return append([]interface{}{b.Signature[:], &b.Block.Slot, &b.Block.ProposerIndex, b.Block.StateRoot[:], b.Block.ParentRoot[:]}, - b.Block.Body.getSchema(true)...) -} - // Version returns beacon block version. func (b *BeaconBlock) Version() clparams.StateVersion { return b.Body.Version diff --git a/cl/cltypes/solid/attestation.go b/cl/cltypes/solid/attestation.go index dd50eb3cb1e..64e99a8632b 100644 --- a/cl/cltypes/solid/attestation.go +++ b/cl/cltypes/solid/attestation.go @@ -16,7 +16,7 @@ const ( // agg bits offset: 4 bytes // attestationData: 128 // Signature: 96 bytes - attestationStaticBufferSize = 4 + attestationDataBufferSize + 96 + attestationStaticBufferSize = 4 + AttestationDataBufferSize + 96 // offset is usually always the same aggregationBitsOffset = 228 diff --git a/cl/cltypes/solid/attestation_data.go b/cl/cltypes/solid/attestation_data.go index 501f26049df..6c505f58105 100644 --- a/cl/cltypes/solid/attestation_data.go +++ b/cl/cltypes/solid/attestation_data.go @@ -17,7 +17,7 @@ import ( // beaconBlockHash: 32 bytes // source: 40 bytes // target: 40 bytes -const attestationDataBufferSize = 8 + 8 + 32 + 40*2 +const AttestationDataBufferSize = 8 + 8 + 32 + 40*2 // AttestantionData contains information about attestantion, including finalized/attested checkpoints. type AttestationData []byte @@ -74,7 +74,7 @@ func (a AttestationData) UnmarshalJSON(buf []byte) error { } func NewAttestationData() AttestationData { - return make([]byte, attestationDataBufferSize) + return make([]byte, AttestationDataBufferSize) } func (a AttestationData) Static() bool { @@ -114,6 +114,31 @@ func (a AttestationData) SetBeaconBlockRoot(beaconBlockRoot libcommon.Hash) { copy(a[16:], beaconBlockRoot[:]) } +func (a AttestationData) SetSlotWithRawBytes(b []byte) { + copy(a[:8], b) +} + +func (a AttestationData) SetValidatorIndexWithRawBytes(b []byte) { + copy(a[8:16], b) + +} + +func (a AttestationData) RawSlot() []byte { + return a[:8] +} + +func (a AttestationData) RawValidatorIndex() []byte { + return a[8:16] +} + +func (a AttestationData) RawBeaconBlockRoot() []byte { + return a[16:48] +} + +func (a AttestationData) SetBeaconBlockRootWithRawBytes(b []byte) { + copy(a[16:48], b) +} + func (a AttestationData) SetSource(c Checkpoint) { copy(a[48:88], c) } diff --git a/cl/cltypes/solid/checkpoint.go b/cl/cltypes/solid/checkpoint.go index 598686bdd1d..8db388792ce 100644 --- a/cl/cltypes/solid/checkpoint.go +++ b/cl/cltypes/solid/checkpoint.go @@ -53,6 +53,22 @@ func (c Checkpoint) UnmarshalJSON(buf []byte) error { return nil } +func (c Checkpoint) SetRawEpoch(b []byte) { + copy(c[:8], b[:8]) +} + +func (c Checkpoint) SetRawBlockRoot(b []byte) { + copy(c[8:40], b[:32]) +} + +func (c Checkpoint) RawEpoch() []byte { + return c[:8] +} + +func (c Checkpoint) RawBlockRoot() []byte { + return c[8:40] +} + // SetBlockRoot copies the given blockRoot into the correct location within the Checkpoint func (c Checkpoint) SetBlockRoot(blockRoot libcommon.Hash) { copy(c[8:], blockRoot[:]) // copy the blockRoot into the Checkpoint starting at index 8 diff --git a/cl/cltypes/solid/pending_attestation.go b/cl/cltypes/solid/pending_attestation.go index 3ea621f6979..214aa6e3781 100644 --- a/cl/cltypes/solid/pending_attestation.go +++ b/cl/cltypes/solid/pending_attestation.go @@ -14,7 +14,7 @@ const ( // attestationData: 128 // InclusionDelay: 8 bytes // ProposerIndex: 8 bytes - pendingAttestationStaticBufferSize = 4 + attestationDataBufferSize + 8 + 8 + pendingAttestationStaticBufferSize = 4 + AttestationDataBufferSize + 8 + 8 // offset is usually always the same pendingAggregationBitsOffset = 148 diff --git a/cl/persistence/snapshot_format/attestations.go b/cl/persistence/snapshot_format/attestations.go new file mode 100644 index 00000000000..f5305195675 --- /dev/null +++ b/cl/persistence/snapshot_format/attestations.go @@ -0,0 +1,194 @@ +package snapshot_format + +// TODO: Make this actually usable. +// func EncodeAttestationsForStorage(attestations *solid.ListSSZ[*solid.Attestation], buf []byte) []byte { +// if attestations.Len() == 0 { +// return nil +// } +// encoded := buf + +// referencedAttestations := []solid.AttestationData{ +// nil, // Full diff +// } +// // Pre-allocate some memory. +// attestations.Range(func(_ int, attestation *solid.Attestation, _ int) bool { +// data := attestation.AttestantionData() +// sig := attestation.Signature() +// // Encode attestation metadata +// // Also we need to keep track of aggregation bits size manually. +// encoded = append(encoded, byte(len(attestation.AggregationBits()))) +// encoded = append(encoded, attestation.AggregationBits()...) +// // Encode signature +// encoded = append(encoded, sig[:]...) +// // Encode attestation body +// var bestEncoding []byte +// bestEncodingIndex := 0 +// // try all non-repeating attestations. +// for i, att := range referencedAttestations { +// currentEncoding := encodeAttestationDataForStorage(attestation.AttestantionData(), att) +// // check if we find a better fit. +// if len(bestEncoding) == 0 || len(bestEncoding) > len(currentEncoding) { +// bestEncodingIndex = i +// bestEncoding = currentEncoding +// // cannot get lower than 1, so accept it as best. +// if len(bestEncoding) == 1 { +// break +// } +// } +// } +// // If it is not repeated then save it. +// if len(bestEncoding) != 1 { +// referencedAttestations = append(referencedAttestations, data) +// } +// encoded = append(encoded, byte(bestEncodingIndex)) +// encoded = append(encoded, bestEncoding...) +// // Encode attester index +// encoded = append(encoded, data.RawValidatorIndex()...) +// return true +// }) +// return encoded +// } + +// // EncodeAttestationsDataForStorage encodes attestation data and compress everything by defaultData. +// func encodeAttestationDataForStorage(data solid.AttestationData, defaultData solid.AttestationData) []byte { +// fieldSet := byte(0) +// var ret []byte + +// numBuffer := make([]byte, 4) + +// // Encode in slot +// if defaultData == nil || data.Slot() != defaultData.Slot() { +// slotBytes := make([]byte, 4) +// binary.LittleEndian.PutUint32(slotBytes, uint32(data.Slot())) +// ret = append(ret, slotBytes...) +// } else { +// fieldSet = 1 +// } + +// if defaultData == nil || !bytes.Equal(data.RawBeaconBlockRoot(), defaultData.RawBeaconBlockRoot()) { +// root := data.BeaconBlockRoot() +// ret = append(ret, root[:]...) +// } else { +// fieldSet |= 2 +// } + +// if defaultData == nil || data.Source().Epoch() != defaultData.Source().Epoch() { +// binary.LittleEndian.PutUint32(numBuffer, uint32(data.Source().Epoch())) +// ret = append(ret, numBuffer...) +// } else { +// fieldSet |= 4 +// } + +// if defaultData == nil || !bytes.Equal(data.Source().RawBlockRoot(), defaultData.Source().RawBlockRoot()) { +// ret = append(ret, data.Source().RawBlockRoot()...) +// } else { +// fieldSet |= 8 +// } + +// if defaultData == nil || data.Target().Epoch() != defaultData.Target().Epoch() { +// binary.LittleEndian.PutUint32(numBuffer, uint32(data.Target().Epoch())) + +// ret = append(ret, numBuffer...) +// } else { +// fieldSet |= 16 +// } + +// if defaultData == nil || !bytes.Equal(data.Target().RawBlockRoot(), defaultData.Target().RawBlockRoot()) { +// root := data.Target().BlockRoot() +// ret = append(ret, root[:]...) +// } else { +// fieldSet |= 32 +// } +// return append([]byte{fieldSet}, ret...) +// } + +// func DecodeAttestationsForStorage(buf []byte, out []byte) error { +// var signature libcommon.Bytes96 + +// if len(buf) == 0 { +// return nil +// } + +// referencedAttestations := []solid.AttestationData{ +// nil, // Full diff +// } +// // current position is how much we read. +// pos := 0 +// for pos != len(buf) { +// attestationData := solid.NewAttestationData() +// // Decode aggregations bits +// aggrBitsLength := int(buf[pos]) +// pos++ +// aggrBits := buf[pos : pos+aggrBitsLength] +// pos += aggrBitsLength +// // Decode signature +// copy(signature[:], buf[pos:]) +// pos += 96 +// // decode attestation body +// // 1) read comparison index +// comparisonIndex := int(buf[pos]) +// pos++ +// n := decodeAttestationDataForStorage(buf[pos:], referencedAttestations[comparisonIndex], attestationData) +// // field set is not null, so we need to remember it. +// if n != 1 { +// referencedAttestations = append(referencedAttestations, attestationData) +// } +// pos += n +// // decode attester index +// attestationData.SetValidatorIndexWithRawBytes(buf[pos:]) +// pos += 8 +// attestations.Append(solid.NewAttestionFromParameters(aggrBits, attestationData, signature)) +// } +// return nil +// } + +// // DecodeAttestationDataForStorage decodes attestation data and decompress everything by defaultData. +// func decodeAttestationDataForStorage(buf []byte, defaultData solid.AttestationData, target solid.AttestationData) (n int) { +// if len(buf) == 0 { +// return +// } +// fieldSet := buf[0] +// n++ +// if fieldSet&1 > 0 { +// target.SetSlotWithRawBytes(defaultData.RawSlot()) +// } else { +// target.SetSlot(uint64(binary.LittleEndian.Uint32(buf[n:]))) +// n += 4 +// } + +// if fieldSet&2 > 0 { +// target.SetBeaconBlockRootWithRawBytes(defaultData.RawBeaconBlockRoot()) +// } else { +// target.SetBeaconBlockRootWithRawBytes(buf[n : n+32]) +// n += 32 +// } + +// if fieldSet&4 > 0 { +// target.Source().SetRawEpoch(defaultData.Source().RawEpoch()) +// } else { +// target.Source().SetEpoch(uint64(binary.LittleEndian.Uint32(buf[n:]))) +// n += 4 +// } + +// if fieldSet&8 > 0 { +// target.Source().SetRawBlockRoot(defaultData.Source().RawBlockRoot()) +// } else { +// target.Source().SetRawBlockRoot(buf[n : n+32]) +// n += 32 +// } + +// if fieldSet&16 > 0 { +// target.Target().SetRawEpoch(defaultData.Target().RawEpoch()) +// } else { +// target.Target().SetEpoch(uint64(binary.LittleEndian.Uint32(buf[n:]))) +// n += 4 +// } + +// if fieldSet&32 > 0 { +// target.Target().SetRawBlockRoot(defaultData.Target().RawBlockRoot()) +// } else { +// target.Target().SetRawBlockRoot(buf[n : n+32]) +// n += 32 +// } +// return +// } diff --git a/cl/persistence/snapshot_format/attestations_test.go b/cl/persistence/snapshot_format/attestations_test.go new file mode 100644 index 00000000000..abcafdb713e --- /dev/null +++ b/cl/persistence/snapshot_format/attestations_test.go @@ -0,0 +1,40 @@ +package snapshot_format_test + +// func TestAttestationsEncoding(t *testing.T) { +// attVec := solid.NewDynamicListSSZ[*solid.Attestation](256) +// for i := 0; i < 256; i++ { +// attVec.Append(solid.NewAttestionFromParameters( +// []byte{byte(i)}, +// solid.NewAttestionDataFromParameters( +// uint64(i*i*i), +// uint64(i*i*i), +// [32]byte{}, +// solid.NewCheckpointFromParameters([32]byte{45, 67}, 219), +// solid.NewCheckpointFromParameters([32]byte{67, 98}, 219), +// ), libcommon.Bytes96{byte(i)})) +// } +// plain, err := attVec.EncodeSSZ(nil) +// require.NoError(t, err) + +// compacted := format.EncodeAttestationsForStorage(attVec, nil) +// require.Less(t, len(compacted), len(plain)) + +// // Now-decode it back. +// resAttVec := solid.NewDynamicListSSZ[*solid.Attestation](256) +// require.NoError(t, format.DecodeAttestationsForStorage(compacted, resAttVec)) + +// require.Equal(t, attVec.Len(), resAttVec.Len()) + +// for i := 0; i < 256; i++ { +// require.Equal(t, attVec.Get(i).Signature(), resAttVec.Get(i).Signature()) +// require.Equal(t, attVec.Get(i).AggregationBits(), resAttVec.Get(i).AggregationBits()) + +// require.Equal(t, attVec.Get(i).AttestantionData().Slot(), resAttVec.Get(i).AttestantionData().Slot()) +// require.Equal(t, attVec.Get(i).AttestantionData().ValidatorIndex(), resAttVec.Get(i).AttestantionData().ValidatorIndex()) +// require.Equal(t, attVec.Get(i).AttestantionData().BeaconBlockRoot(), resAttVec.Get(i).AttestantionData().BeaconBlockRoot()) +// require.Equal(t, attVec.Get(i).AttestantionData().Source(), resAttVec.Get(i).AttestantionData().Source()) +// require.Equal(t, attVec.Get(i).AttestantionData().Target(), resAttVec.Get(i).AttestantionData().Target()) + +// require.Equal(t, attVec.Get(i), resAttVec.Get(i)) +// } +// } diff --git a/cl/persistence/snapshot_format/blocks.go b/cl/persistence/snapshot_format/blocks.go new file mode 100644 index 00000000000..84624162acc --- /dev/null +++ b/cl/persistence/snapshot_format/blocks.go @@ -0,0 +1,195 @@ +package snapshot_format + +import ( + "encoding/binary" + "fmt" + "io" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" +) + +type ExecutionBlockReaderByNumber interface { + BlockByNumber(number uint64) (*cltypes.Eth1Block, error) +} + +const ( + blockBaseOffset = 100 /* Signature + Block Offset */ + + 84 /* Slot + ProposerIndex + ParentRoot + StateRoot + Body Offset */ + + 96 /*Signature*/ + 72 /*Eth1Data*/ + 32 /*Graffiti*/ + 4 /*ProposerSlashings Offset*/ + 4 /*AttesterSlashings Offset*/ + 4 /*Attestations*/ + + 4 /*Deposits Offset*/ + 4 /*VoluntaryExits Offset*/ + + altairBlockAdditionalBaseOffset = 160 /*SyncAggregate*/ + bellatrixBlockAdditionalBaseOffset = 4 /*ExecutionPayload Offset*/ + capellaBlockAdditionalBaseOffset = 4 /*ExecutionChanges Offset*/ + denebBlockAdditionalBaseOffset = 4 /*BlobKzgCommitments Offset*/ +) + +func writeChunkLength(w io.Writer, length uint64) error { + temp := make([]byte, 8) + binary.BigEndian.PutUint64(temp, length) + + if _, err := w.Write(temp); err != nil { + return err + } + + return nil +} + +func writeExecutionBlockPtr(w io.Writer, p *cltypes.Eth1Block) error { + temp := make([]byte, 8) + binary.BigEndian.PutUint64(temp, p.BlockNumber) + + return writeChunk(w, temp, pointerDataType, false) +} + +func readExecutionBlockPtr(r io.Reader) (uint64, error) { + b, dT, err := readChunk(r, false) + if err != nil { + return 0, err + } + if dT != pointerDataType { + return 0, fmt.Errorf("malformed beacon block, invalid block pointer type %d, expected: %d", dT, pointerDataType) + } + return binary.BigEndian.Uint64(b), nil +} + +func computeInitialOffset(version clparams.StateVersion) uint64 { + ret := uint64(blockBaseOffset) + if version >= clparams.AltairVersion { + ret += altairBlockAdditionalBaseOffset + } + if version >= clparams.BellatrixVersion { + ret += bellatrixBlockAdditionalBaseOffset + } + if version >= clparams.CapellaVersion { + ret += capellaBlockAdditionalBaseOffset + } + if version >= clparams.DenebVersion { + ret += denebBlockAdditionalBaseOffset + } + return ret +} + +// WriteBlockForSnapshot writes a block to the given writer in the format expected by the snapshot. +func WriteBlockForSnapshot(block *cltypes.SignedBeaconBlock, w io.Writer) error { + // Maybe reuse the buffer? + encoded, err := block.EncodeSSZ(nil) + if err != nil { + return err + } + version := block.Version() + if _, err := w.Write([]byte{byte(version)}); err != nil { + return err + } + currentChunkLength := computeInitialOffset(version) + + body := block.Block.Body + // count in body for phase0 fields + currentChunkLength += uint64(body.ProposerSlashings.EncodingSizeSSZ()) + currentChunkLength += uint64(body.AttesterSlashings.EncodingSizeSSZ()) + + // Write the chunk and chunk attestations + if err := writeChunk(w, encoded[:currentChunkLength], chunkDataType, false); err != nil { + return err + } + encoded = encoded[currentChunkLength:] + if err := writeChunk(w, encoded[:uint64(body.Attestations.EncodingSizeSSZ())], chunkDataType, true); err != nil { + return err + } + encoded = encoded[body.Attestations.EncodingSizeSSZ():] + currentChunkLength = 0 + + currentChunkLength += uint64(body.Deposits.EncodingSizeSSZ()) + currentChunkLength += uint64(body.VoluntaryExits.EncodingSizeSSZ()) + + if err := writeChunk(w, encoded[:currentChunkLength], chunkDataType, false); err != nil { + return err + } + // we are done if we are before altair + if version <= clparams.AltairVersion { + return nil + } + encoded = encoded[currentChunkLength+uint64(body.ExecutionPayload.EncodingSizeSSZ()):] + if err := writeExecutionBlockPtr(w, body.ExecutionPayload); err != nil { + return err + } + if version <= clparams.BellatrixVersion { + return nil + } + return writeChunk(w, encoded, chunkDataType, false) +} + +func ReadBlockFromrSnapshot(r io.Reader, executionReader ExecutionBlockReaderByNumber, cfg *clparams.BeaconChainConfig) (*cltypes.SignedBeaconBlock, error) { + // Metadata section is just the current hardfork of the block. TODO(give it a useful purpose) + v, err := readMetadataForBlock(r) + if err != nil { + return nil, err + } + + // Read the first chunk + chunk1, dT1, err := readChunk(r, false) + if err != nil { + return nil, err + } + if dT1 != chunkDataType { + return nil, fmt.Errorf("malformed beacon block, invalid chunk 1 type %d, expected: %d", dT1, chunkDataType) + } + // Read the attestation chunk (2nd chunk) + chunk2, dT2, err := readChunk(r, true) + if err != nil { + return nil, err + } + if dT2 != chunkDataType { + return nil, fmt.Errorf("malformed beacon block, invalid chunk 2 type %d, expected: %d", dT2, chunkDataType) + } + // Read the 3rd chunk + chunk3, dT3, err := readChunk(r, false) + if err != nil { + return nil, err + } + if dT3 != chunkDataType { + return nil, fmt.Errorf("malformed beacon block, invalid chunk 3 type %d, expected: %d", dT3, chunkDataType) + } + if v <= clparams.AltairVersion { + return blockFromChunks(v, cfg, chunk1, chunk2, chunk3) + } + // Read the block pointer and retrieve chunk4 from the execution reader + blockPointer, err := readExecutionBlockPtr(r) + if err != nil { + return nil, err + } + executionBlock, err := executionReader.BlockByNumber(blockPointer) + if err != nil { + return nil, err + } + // Read the 4th chunk + chunk4, err := executionBlock.EncodeSSZ(nil) + if err != nil { + return nil, err + } + if v <= clparams.BellatrixVersion { + return blockFromChunks(v, cfg, chunk1, chunk2, chunk3, chunk4) + } + + // Read the 5h chunk + chunk5, dT5, err := readChunk(r, false) + if err != nil { + return nil, err + } + if dT5 != chunkDataType { + return nil, fmt.Errorf("malformed beacon block, invalid chunk 5 type %d, expected: %d", dT5, chunkDataType) + } + + return blockFromChunks(v, cfg, chunk1, chunk2, chunk3, chunk4, chunk5) +} + +func blockFromChunks(v clparams.StateVersion, cfg *clparams.BeaconChainConfig, chunks ...[]byte) (*cltypes.SignedBeaconBlock, error) { + block := cltypes.NewSignedBeaconBlock(cfg) + plainSSZ := []byte{} + for _, chunk := range chunks { + plainSSZ = append(plainSSZ, chunk...) + } + return block, block.DecodeSSZ(plainSSZ, int(v)) + +} diff --git a/cl/persistence/snapshot_format/blocks_test.go b/cl/persistence/snapshot_format/blocks_test.go new file mode 100644 index 00000000000..55f3c7b5518 --- /dev/null +++ b/cl/persistence/snapshot_format/blocks_test.go @@ -0,0 +1,72 @@ +package snapshot_format_test + +import ( + "bytes" + _ "embed" + "testing" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/persistence/snapshot_format" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/stretchr/testify/require" +) + +//go:embed test_data/phase0.ssz_snappy +var phase0BlockSSZSnappy []byte + +//go:embed test_data/altair.ssz_snappy +var altairBlockSSZSnappy []byte + +//go:embed test_data/bellatrix.ssz_snappy +var bellatrixBlockSSZSnappy []byte + +//go:embed test_data/capella.ssz_snappy +var capellaBlockSSZSnappy []byte + +//go:embed test_data/deneb.ssz_snappy +var denebBlockSSZSnappy []byte + +// obtain the test blocks +func getTestBlocks(t *testing.T) []*cltypes.SignedBeaconBlock { + denebBlock := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig) + capellaBlock := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig) + bellatrixBlock := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig) + altairBlock := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig) + phase0Block := cltypes.NewSignedBeaconBlock(&clparams.MainnetBeaconConfig) + + require.NoError(t, utils.DecodeSSZSnappy(denebBlock, denebBlockSSZSnappy, int(clparams.DenebVersion))) + require.NoError(t, utils.DecodeSSZSnappy(capellaBlock, capellaBlockSSZSnappy, int(clparams.CapellaVersion))) + require.NoError(t, utils.DecodeSSZSnappy(bellatrixBlock, bellatrixBlockSSZSnappy, int(clparams.BellatrixVersion))) + require.NoError(t, utils.DecodeSSZSnappy(altairBlock, altairBlockSSZSnappy, int(clparams.AltairVersion))) + require.NoError(t, utils.DecodeSSZSnappy(phase0Block, phase0BlockSSZSnappy, int(clparams.Phase0Version))) + return []*cltypes.SignedBeaconBlock{phase0Block, altairBlock, bellatrixBlock, capellaBlock, denebBlock} +} + +type TestBlockReader struct { + Block *cltypes.Eth1Block +} + +func (t *TestBlockReader) BlockByNumber(number uint64) (*cltypes.Eth1Block, error) { + return t.Block, nil +} + +func TestBlockSnapshotEncoding(t *testing.T) { + for _, blk := range getTestBlocks(t) { + var br TestBlockReader + if blk.Version() >= clparams.BellatrixVersion { + br = TestBlockReader{Block: blk.Block.Body.ExecutionPayload} + } + var b bytes.Buffer + require.NoError(t, snapshot_format.WriteBlockForSnapshot(blk, &b)) + blk2, err := snapshot_format.ReadBlockFromrSnapshot(&b, &br, &clparams.MainnetBeaconConfig) + require.NoError(t, err) + _ = blk2 + hash1, err := blk.HashSSZ() + require.NoError(t, err) + hash2, err := blk2.HashSSZ() + require.NoError(t, err) + + require.Equal(t, hash1, hash2) + } +} diff --git a/cl/persistence/snapshot_format/chunks.go b/cl/persistence/snapshot_format/chunks.go new file mode 100644 index 00000000000..bf9960f4cda --- /dev/null +++ b/cl/persistence/snapshot_format/chunks.go @@ -0,0 +1,61 @@ +package snapshot_format + +import ( + "encoding/binary" + "fmt" + "io" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/utils" +) + +type dataType int + +const ( + chunkDataType dataType = 0 + pointerDataType dataType = 1 +) + +// writeChunk writes a chunk to the writer. +func writeChunk(w io.Writer, buf []byte, t dataType, snappy bool) error { + if snappy { + buf = utils.CompressSnappy(buf) + } + // prefix is type of chunk + length of chunk + prefix := make([]byte, 8) + binary.BigEndian.PutUint64(prefix, uint64(len(buf))) + prefix[0] = byte(t) + if _, err := w.Write(prefix); err != nil { + return err + } + if _, err := w.Write(buf); err != nil { + return err + } + return nil +} + +func readChunk(r io.Reader, snappy bool) (buf []byte, t dataType, err error) { + prefix := make([]byte, 8) + if _, err := r.Read(prefix); err != nil { + return nil, dataType(0), err + } + t = dataType(prefix[0]) + prefix[0] = 0 + fmt.Println(binary.BigEndian.Uint64(prefix)) + buf = make([]byte, binary.BigEndian.Uint64(prefix)) + if _, err := r.Read(buf); err != nil { + return nil, t, err + } + if snappy { + buf, err = utils.DecompressSnappy(buf) + } + return buf, t, err +} + +func readMetadataForBlock(r io.Reader) (clparams.StateVersion, error) { + b := []byte{0} + if _, err := r.Read(b); err != nil { + return 0, err + } + return clparams.StateVersion(b[0]), nil +} diff --git a/cl/persistence/snapshot_format/test_data/altair.ssz_snappy b/cl/persistence/snapshot_format/test_data/altair.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..6a68fb0428b94f144d03cb9ceb5d2ec10200b33a GIT binary patch literal 19953 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%0DB4O)sWAQzHiQlR)_S_Q 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 AHvj+t literal 0 HcmV?d00001 diff --git a/cl/persistence/snapshot_format/test_data/bellatrix.ssz_snappy b/cl/persistence/snapshot_format/test_data/bellatrix.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..4ea51c0359f95789d15dc21475a2ec3ec0d6f027 GIT binary patch literal 13589 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 bUX=g=&FQYH{0OkkJP2%?NTGz>t667q7a}_Z literal 0 HcmV?d00001 diff --git a/cl/persistence/snapshot_format/test_data/capella.ssz_snappy b/cl/persistence/snapshot_format/test_data/capella.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..f3301a2319539eab11f0a27ee32fb9db5f315beb GIT binary patch literal 20665 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 literal 0 HcmV?d00001 diff --git a/cl/persistence/snapshot_format/test_data/deneb.ssz_snappy b/cl/persistence/snapshot_format/test_data/deneb.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..abdebc30b65bb7d271cf09e7acfc50cc10c5b24e GIT binary patch literal 12263 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 B%4Yxo literal 0 HcmV?d00001 diff --git a/cl/persistence/snapshot_format/test_data/phase0.ssz_snappy b/cl/persistence/snapshot_format/test_data/phase0.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..dfa9c18707ac2aca4d5887c18592b34d28307440 GIT binary patch literal 12888 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 CW7qcp literal 0 HcmV?d00001