-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR adds the new p2p containers from Deneb into Caplin #7389
- Loading branch information
Showing
2 changed files
with
345 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
package cltypes | ||
|
||
import ( | ||
gokzg4844 "github.com/crate-crypto/go-kzg-4844" | ||
libcommon "github.com/ledgerwatch/erigon-lib/common" | ||
"github.com/ledgerwatch/erigon/cl/cltypes/ssz" | ||
"github.com/ledgerwatch/erigon/cl/merkle_tree" | ||
) | ||
|
||
type Root [32]byte | ||
type Slot uint64 | ||
type Blob gokzg4844.Blob | ||
type KZGCommitment gokzg4844.KZGCommitment // [48]byte | ||
type KZGProof gokzg4844.KZGProof // [48]byte | ||
|
||
type BlobSideCar struct { | ||
BlockRoot Root | ||
Index uint64 // index of blob in block | ||
Slot Slot | ||
BlockParentRoot Root | ||
ProposerIndex uint64 // validator index | ||
Blob Blob | ||
KZGCommitment KZGCommitment | ||
KZGProof KZGProof | ||
} | ||
|
||
// https://github.com/ethereum/consensus-specs/blob/3a2304981a3b820a22b518fe4859f4bba0ebc83b/specs/deneb/polynomial-commitments.md#custom-types | ||
const BYTES_PER_FIELD_ELEMENT = 32 | ||
const FIELD_ELEMENTS_PER_BLOB = 4096 | ||
const BYTES_PER_BLOB = uint64(BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB) | ||
|
||
func (b *BlobSideCar) Copy() *BlobSideCar { | ||
copied := *b | ||
return &copied | ||
} | ||
|
||
func (b *BlobSideCar) EncodeSSZ(buf []byte) ([]byte, error) { | ||
buf = append(buf, b.BlockRoot[:]...) | ||
buf = append(buf, ssz.Uint64SSZ(b.Index)...) | ||
buf = append(buf, ssz.Uint64SSZ(uint64(b.Slot))...) | ||
buf = append(buf, b.BlockParentRoot[:]...) | ||
buf = append(buf, ssz.Uint64SSZ(b.ProposerIndex)...) | ||
buf = append(buf, b.Blob[:]...) | ||
buf = append(buf, b.KZGCommitment[:]...) | ||
buf = append(buf, b.KZGProof[:]...) | ||
|
||
return buf, nil | ||
} | ||
|
||
func (b *BlobSideCar) DecodeSSZ(buf []byte) error { | ||
pos := 0 // current position at the buffer | ||
|
||
copy(b.BlockRoot[:], buf[pos:32]) | ||
pos += 32 | ||
|
||
b.Index = ssz.UnmarshalUint64SSZ(buf[pos : pos+8]) | ||
pos += 8 | ||
|
||
b.Slot = Slot(ssz.UnmarshalUint64SSZ(buf[pos:])) | ||
pos += 8 | ||
|
||
copy(b.BlockParentRoot[:], buf[pos:pos+32]) | ||
pos += 32 | ||
|
||
b.ProposerIndex = ssz.UnmarshalUint64SSZ(buf[pos : pos+8]) | ||
pos += 8 | ||
|
||
copy(b.Blob[:], buf[pos:pos+int(BYTES_PER_BLOB)]) | ||
pos += int(BYTES_PER_BLOB) | ||
|
||
copy(b.KZGCommitment[:], buf[pos:pos+48]) | ||
pos += 48 | ||
|
||
copy(b.KZGProof[:], buf[pos:pos+48]) | ||
|
||
return nil | ||
} | ||
|
||
func (b *BlobSideCar) EncodingSizeSSZ() int { | ||
return 131_256 | ||
} | ||
|
||
func (b *BlobSideCar) HashSSZ() (libcommon.Hash, error) { | ||
KZGCommitmentLeave, err := merkle_tree.PublicKeyRoot(b.KZGCommitment) | ||
if err != nil { | ||
return libcommon.Hash{}, err | ||
} | ||
KZGProofLeave, err := merkle_tree.PublicKeyRoot(b.KZGProof) | ||
if err != nil { | ||
return libcommon.Hash{}, err | ||
} | ||
|
||
blobLeave := [][32]byte{} | ||
previous_pos := 0 | ||
for pos := 32; pos < int(BYTES_PER_BLOB)/32; pos += 32 { | ||
blobLeave = append(blobLeave, libcommon.BytesToHash(b.Blob[previous_pos:pos])) | ||
previous_pos = pos | ||
} | ||
|
||
blobRoot, err := merkle_tree.ArraysRoot(blobLeave, 4096) | ||
if err != nil { | ||
return libcommon.Hash{}, err | ||
} | ||
|
||
return merkle_tree.ArraysRoot([][32]byte{ | ||
b.BlockRoot, | ||
merkle_tree.Uint64Root(b.Index), | ||
merkle_tree.Uint64Root(uint64(b.Slot)), | ||
b.BlockParentRoot, | ||
merkle_tree.Uint64Root(b.ProposerIndex), | ||
blobRoot, | ||
KZGCommitmentLeave, | ||
KZGProofLeave, | ||
}, 8) | ||
} | ||
|
||
type SignedBlobSideCar struct { | ||
Message BlobSideCar | ||
Signature [96]byte | ||
} | ||
|
||
func (b *SignedBlobSideCar) Copy() *SignedBlobSideCar { | ||
copy := *b | ||
return © | ||
} | ||
|
||
func (b *SignedBlobSideCar) EncodeSSZ(buf []byte) ([]byte, error) { | ||
encodedMessage, _ := b.Message.EncodeSSZ([]byte{}) | ||
|
||
buf = append(buf, encodedMessage...) | ||
buf = append(buf, b.Signature[:]...) | ||
|
||
return buf, nil | ||
} | ||
|
||
func (b *SignedBlobSideCar) DecodeSSZ(buf []byte) error { | ||
pos := b.Message.EncodingSizeSSZ() | ||
err := b.Message.DecodeSSZ(buf[:pos]) | ||
if err != nil { | ||
return err | ||
} | ||
copy(b.Signature[:], buf[pos:]) | ||
|
||
return nil | ||
} | ||
|
||
func (b *SignedBlobSideCar) EncodingSizeSSZ() int { | ||
return b.Message.EncodingSizeSSZ() + 96 | ||
} | ||
|
||
func (b *SignedBlobSideCar) HashSSZ() (libcommon.Hash, error) { | ||
messageLeave, err := b.Message.HashSSZ() | ||
if err != nil { | ||
return libcommon.Hash{}, err | ||
} | ||
|
||
signatureLeave, err := merkle_tree.SignatureRoot(b.Signature) | ||
if err != nil { | ||
return libcommon.Hash{}, err | ||
} | ||
|
||
return merkle_tree.ArraysRoot([][32]byte{ | ||
messageLeave, | ||
signatureLeave, | ||
}, 2) | ||
} | ||
|
||
type BlobIdentifier struct { | ||
BlockRoot Root | ||
Index uint64 | ||
} | ||
|
||
func (b *BlobIdentifier) Copy() *BlobIdentifier { | ||
copy := *b | ||
return © | ||
} | ||
|
||
func (b *BlobIdentifier) EncodeSSZ(buf []byte) ([]byte, error) { | ||
buf = append(buf, b.BlockRoot[:]...) | ||
buf = append(buf, ssz.Uint64SSZ(b.Index)...) | ||
|
||
return buf, nil | ||
} | ||
|
||
func (b *BlobIdentifier) DecodeSSZ(buf []byte) error { | ||
copy(b.BlockRoot[:], buf[:32]) | ||
b.Index = ssz.UnmarshalUint64SSZ(buf[32:]) | ||
return nil | ||
} | ||
|
||
func (b *BlobIdentifier) EncodingSizeSSZ() int { | ||
return 40 | ||
} | ||
|
||
func (b *BlobIdentifier) HashSSZ() (libcommon.Hash, error) { | ||
return merkle_tree.ArraysRoot([][32]byte{ | ||
b.BlockRoot, | ||
merkle_tree.Uint64Root(b.Index), | ||
}, 2) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package cltypes_test | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
|
||
"github.com/ledgerwatch/erigon/cl/cltypes" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestBlobSideCar_EncodeDecodeSSZ(t *testing.T) { | ||
blockRoot := cltypes.Root{1, 2, 3} | ||
index := uint64(123) | ||
slot := cltypes.Slot(456) | ||
blockParentRoot := cltypes.Root{4, 5, 6} | ||
proposerIndex := uint64(789) | ||
blob := cltypes.Blob{} | ||
kzgCommitment := cltypes.KZGCommitment{7, 8, 9} | ||
kzgProof := cltypes.KZGProof{10, 11, 12} | ||
|
||
sideCar := &cltypes.BlobSideCar{ | ||
BlockRoot: blockRoot, | ||
Index: index, | ||
Slot: slot, | ||
BlockParentRoot: blockParentRoot, | ||
ProposerIndex: proposerIndex, | ||
Blob: blob, | ||
KZGCommitment: kzgCommitment, | ||
KZGProof: kzgProof, | ||
} | ||
|
||
encoded, err := sideCar.EncodeSSZ([]byte{}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
decoded := &cltypes.BlobSideCar{} | ||
err = decoded.DecodeSSZ(encoded) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if decoded.BlockRoot != blockRoot { | ||
t.Errorf("unexpected BlockRoot: got %v, want %v", decoded.BlockRoot, blockRoot) | ||
} | ||
if decoded.Index != index { | ||
t.Errorf("unexpected Index: got %d, want %d", decoded.Index, index) | ||
} | ||
if decoded.Slot != slot { | ||
t.Errorf("unexpected Slot: got %d, want %d", decoded.Slot, slot) | ||
} | ||
if decoded.BlockParentRoot != blockParentRoot { | ||
t.Errorf("unexpected BlockParentRoot: got %v, want %v", decoded.BlockParentRoot, blockParentRoot) | ||
} | ||
if decoded.ProposerIndex != proposerIndex { | ||
t.Errorf("unexpected ProposerIndex: got %d, want %d", decoded.ProposerIndex, proposerIndex) | ||
} | ||
if !bytes.Equal(decoded.Blob[:], blob[:]) { | ||
t.Errorf("unexpected Blob: got %v, want %v", decoded.Blob, blob) | ||
} | ||
if decoded.KZGCommitment != kzgCommitment { | ||
t.Errorf("unexpected KZGCommitment: got %v, want %v", decoded.KZGCommitment, kzgCommitment) | ||
} | ||
if decoded.KZGProof != kzgProof { | ||
t.Errorf("unexpected KZGProof: got %v, want %v", decoded.KZGProof, kzgProof) | ||
} | ||
} | ||
|
||
func TestSignedBlobSideCar(t *testing.T) { | ||
// Create a BlobSideCar to use as the message for SignedBlobSideCar | ||
blob := cltypes.Blob{1, 2, 3, 4, 5, 6, 7, 8} | ||
blobSideCar := cltypes.BlobSideCar{ | ||
BlockRoot: cltypes.Root{1}, | ||
Index: 2, | ||
Slot: 3, | ||
BlockParentRoot: cltypes.Root{4}, | ||
ProposerIndex: 5, | ||
Blob: blob, | ||
KZGCommitment: cltypes.KZGCommitment{6}, | ||
KZGProof: cltypes.KZGProof{7}, | ||
} | ||
|
||
// Create a SignedBlobSideCar with the BlobSideCar and a signature | ||
signature := [96]byte{8} | ||
signedBlobSideCar := cltypes.SignedBlobSideCar{ | ||
Message: blobSideCar, | ||
Signature: signature, | ||
} | ||
|
||
// Encode the SignedBlobSideCar | ||
encoded, err := signedBlobSideCar.EncodeSSZ(nil) | ||
assert.NoError(t, err) | ||
|
||
// Decode the encoded SignedBlobSideCar | ||
decoded := cltypes.SignedBlobSideCar{} | ||
err = decoded.DecodeSSZ(encoded) | ||
assert.NoError(t, err) | ||
|
||
// Assert that the decoded SignedBlobSideCar is equal to the original SignedBlobSideCar | ||
assert.Equal(t, signedBlobSideCar.Message.BlockRoot, decoded.Message.BlockRoot) | ||
assert.Equal(t, signedBlobSideCar.Message.Index, decoded.Message.Index) | ||
assert.Equal(t, signedBlobSideCar.Message.Slot, decoded.Message.Slot) | ||
assert.Equal(t, signedBlobSideCar.Message.BlockParentRoot, decoded.Message.BlockParentRoot) | ||
assert.Equal(t, signedBlobSideCar.Message.ProposerIndex, decoded.Message.ProposerIndex) | ||
assert.True(t, bytes.Equal(signedBlobSideCar.Message.Blob[:], decoded.Message.Blob[:])) | ||
assert.Equal(t, signedBlobSideCar.Message.KZGCommitment, decoded.Message.KZGCommitment) | ||
assert.Equal(t, signedBlobSideCar.Message.KZGProof, decoded.Message.KZGProof) | ||
assert.Equal(t, signedBlobSideCar.Signature, decoded.Signature) | ||
} | ||
|
||
func TestBlobIdentifier_EncodeDecodeSSZ(t *testing.T) { | ||
blockRoot := cltypes.Root{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32} | ||
index := uint64(123456) | ||
|
||
blobID := &cltypes.BlobIdentifier{ | ||
BlockRoot: blockRoot, | ||
Index: index, | ||
} | ||
|
||
// encode to SSZ | ||
encoded, err := blobID.EncodeSSZ(nil) | ||
if err != nil { | ||
t.Fatalf("EncodeSSZ failed: %v", err) | ||
} | ||
|
||
// decode from SSZ | ||
decoded := &cltypes.BlobIdentifier{} | ||
if err := decoded.DecodeSSZ(encoded); err != nil { | ||
t.Fatalf("DecodeSSZ failed: %v", err) | ||
} | ||
|
||
// compare original and decoded values | ||
if !bytes.Equal(blobID.BlockRoot[:], decoded.BlockRoot[:]) { | ||
t.Errorf("BlockRoot mismatch: expected %v, got %v", blobID.BlockRoot, decoded.BlockRoot) | ||
} | ||
if blobID.Index != decoded.Index { | ||
t.Errorf("Index mismatch: expected %v, got %v", blobID.Index, decoded.Index) | ||
} | ||
|
||
// check SSZ encoding size | ||
expectedSize := blobID.EncodingSizeSSZ() | ||
if len(encoded) != expectedSize { | ||
t.Errorf("Encoding size mismatch: expected %d, got %d", expectedSize, len(encoded)) | ||
} | ||
} |