From d6bbfff8b790e5bcd191f88f8a69cad410f7ea3f Mon Sep 17 00:00:00 2001 From: Nilav Prajapati <122373295+gerceboss@users.noreply.github.com> Date: Tue, 20 May 2025 21:49:36 +0530 Subject: [PATCH] Fix cyclical dependency (#15248) * fix cyclical dependency * fix bazel file * fix comments * fix: Break cyclical dependency by importing GetRandBlob directly from crypto/random * add changelog --- beacon-chain/blockchain/kzg/BUILD.bazel | 3 +- .../blockchain/kzg/validation_test.go | 41 +------------ changelog/gerceboss_testing-util-reuse.md | 3 + crypto/random/BUILD.bazel | 24 ++++++++ crypto/random/random.go | 45 ++++++++++++++ crypto/random/random_test.go | 61 +++++++++++++++++++ testing/util/BUILD.bazel | 2 +- testing/util/deneb.go | 32 ++-------- 8 files changed, 142 insertions(+), 69 deletions(-) create mode 100644 changelog/gerceboss_testing-util-reuse.md create mode 100644 crypto/random/BUILD.bazel create mode 100644 crypto/random/random.go create mode 100644 crypto/random/random_test.go diff --git a/beacon-chain/blockchain/kzg/BUILD.bazel b/beacon-chain/blockchain/kzg/BUILD.bazel index e2cfa3d5c4..7535f490cd 100644 --- a/beacon-chain/blockchain/kzg/BUILD.bazel +++ b/beacon-chain/blockchain/kzg/BUILD.bazel @@ -29,9 +29,8 @@ go_test( embed = [":go_default_library"], deps = [ "//consensus-types/blocks:go_default_library", + "//crypto/random:go_default_library", "//testing/require:go_default_library", - "@com_github_consensys_gnark_crypto//ecc/bls12-381/fr:go_default_library", "@com_github_crate_crypto_go_kzg_4844//:go_default_library", - "@com_github_sirupsen_logrus//:go_default_library", ], ) diff --git a/beacon-chain/blockchain/kzg/validation_test.go b/beacon-chain/blockchain/kzg/validation_test.go index aeb879806b..935abdc9f0 100644 --- a/beacon-chain/blockchain/kzg/validation_test.go +++ b/beacon-chain/blockchain/kzg/validation_test.go @@ -1,16 +1,12 @@ package kzg import ( - "bytes" - "crypto/sha256" - "encoding/binary" "testing" "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" + "github.com/OffchainLabs/prysm/v6/crypto/random" "github.com/OffchainLabs/prysm/v6/testing/require" - "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" GoKZG "github.com/crate-crypto/go-kzg-4844" - "github.com/sirupsen/logrus" ) func GenerateCommitmentAndProof(blob GoKZG.Blob) (GoKZG.KZGCommitment, GoKZG.KZGProof, error) { @@ -41,7 +37,7 @@ func TestBytesToAny(t *testing.T) { } func TestGenerateCommitmentAndProof(t *testing.T) { - blob := getRandBlob(123) + blob := random.GetRandBlob(123) commitment, proof, err := GenerateCommitmentAndProof(blob) require.NoError(t, err) expectedCommitment := GoKZG.KZGCommitment{180, 218, 156, 194, 59, 20, 10, 189, 186, 254, 132, 93, 7, 127, 104, 172, 238, 240, 237, 70, 83, 89, 1, 152, 99, 0, 165, 65, 143, 62, 20, 215, 230, 14, 205, 95, 28, 245, 54, 25, 160, 16, 178, 31, 232, 207, 38, 85} @@ -49,36 +45,3 @@ func TestGenerateCommitmentAndProof(t *testing.T) { require.Equal(t, expectedCommitment, commitment) require.Equal(t, expectedProof, proof) } - -func deterministicRandomness(seed int64) [32]byte { - // Converts an int64 to a byte slice - buf := new(bytes.Buffer) - err := binary.Write(buf, binary.BigEndian, seed) - if err != nil { - logrus.WithError(err).Error("Failed to write int64 to bytes buffer") - return [32]byte{} - } - bytes := buf.Bytes() - - return sha256.Sum256(bytes) -} - -// Returns a serialized random field element in big-endian -func getRandFieldElement(seed int64) [32]byte { - bytes := deterministicRandomness(seed) - var r fr.Element - r.SetBytes(bytes[:]) - - return GoKZG.SerializeScalar(r) -} - -// Returns a random blob using the passed seed as entropy -func getRandBlob(seed int64) GoKZG.Blob { - var blob GoKZG.Blob - bytesPerBlob := GoKZG.ScalarsPerBlob * GoKZG.SerializedScalarSize - for i := 0; i < bytesPerBlob; i += GoKZG.SerializedScalarSize { - fieldElementBytes := getRandFieldElement(seed + int64(i)) - copy(blob[i:i+GoKZG.SerializedScalarSize], fieldElementBytes[:]) - } - return blob -} diff --git a/changelog/gerceboss_testing-util-reuse.md b/changelog/gerceboss_testing-util-reuse.md new file mode 100644 index 0000000000..4829dca46e --- /dev/null +++ b/changelog/gerceboss_testing-util-reuse.md @@ -0,0 +1,3 @@ +### Fixed + +- Fix cyclical dependencies issue when using testing/util package \ No newline at end of file diff --git a/crypto/random/BUILD.bazel b/crypto/random/BUILD.bazel new file mode 100644 index 0000000000..3b4adea6c5 --- /dev/null +++ b/crypto/random/BUILD.bazel @@ -0,0 +1,24 @@ +load("@prysm//tools/go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["random.go"], + importpath = "github.com/OffchainLabs/prysm/v6/crypto/random", + visibility = ["//visibility:public"], + deps = [ + "@com_github_consensys_gnark_crypto//ecc/bls12-381/fr:go_default_library", + "@com_github_crate_crypto_go_kzg_4844//:go_default_library", + "@com_github_sirupsen_logrus//:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["random_test.go"], + embed = [":go_default_library"], + deps = [ + "//testing/assert:go_default_library", + "//testing/require:go_default_library", + "@com_github_crate_crypto_go_kzg_4844//:go_default_library", + ], +) diff --git a/crypto/random/random.go b/crypto/random/random.go new file mode 100644 index 0000000000..f219ece0d8 --- /dev/null +++ b/crypto/random/random.go @@ -0,0 +1,45 @@ +package random + +import ( + "bytes" + "crypto/sha256" + "encoding/binary" + + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + GoKZG "github.com/crate-crypto/go-kzg-4844" + "github.com/sirupsen/logrus" +) + +// DeterministicRandomness creates a deterministic 32 byte array from a seed +func DeterministicRandomness(seed int64) [32]byte { + // Converts an int64 to a byte slice + buf := new(bytes.Buffer) + err := binary.Write(buf, binary.BigEndian, seed) + if err != nil { + logrus.WithError(err).Error("Failed to write int64 to bytes buffer") + return [32]byte{} + } + bytes := buf.Bytes() + + return sha256.Sum256(bytes) +} + +// GetRandFieldElement returns a serialized random field element in big-endian +func GetRandFieldElement(seed int64) [32]byte { + bytes := DeterministicRandomness(seed) + var r fr.Element + r.SetBytes(bytes[:]) + + return GoKZG.SerializeScalar(r) +} + +// GetRandBlob returns a random blob using the passed seed as entropy +func GetRandBlob(seed int64) GoKZG.Blob { + var blob GoKZG.Blob + bytesPerBlob := GoKZG.ScalarsPerBlob * GoKZG.SerializedScalarSize + for i := 0; i < bytesPerBlob; i += GoKZG.SerializedScalarSize { + fieldElementBytes := GetRandFieldElement(seed + int64(i)) + copy(blob[i:i+GoKZG.SerializedScalarSize], fieldElementBytes[:]) + } + return blob +} diff --git a/crypto/random/random_test.go b/crypto/random/random_test.go new file mode 100644 index 0000000000..b0d21ddc24 --- /dev/null +++ b/crypto/random/random_test.go @@ -0,0 +1,61 @@ +package random + +import ( + "testing" + + "github.com/OffchainLabs/prysm/v6/testing/assert" + "github.com/OffchainLabs/prysm/v6/testing/require" + GoKZG "github.com/crate-crypto/go-kzg-4844" +) + +func TestDeterministicRandomness(t *testing.T) { + seed := int64(123) + r1 := DeterministicRandomness(seed) + r2 := DeterministicRandomness(seed) + assert.DeepEqual(t, r1, r2, "Same seed should produce same output") + + // Test different seeds produce different outputs + r3 := DeterministicRandomness(seed + 1) + assert.NotEqual(t, r1, r3, "Different seeds should produce different outputs") +} + +func TestGetRandFieldElement(t *testing.T) { + seed := int64(123) + r1 := GetRandFieldElement(seed) + r2 := GetRandFieldElement(seed) + assert.DeepEqual(t, r1, r2, "Same seed should produce same output") + + // Test different seeds produce different outputs + r3 := GetRandFieldElement(seed + 1) + assert.NotEqual(t, r1, r3, "Different seeds should produce different outputs") +} + +func TestGetRandBlob(t *testing.T) { + seed := int64(123) + r1 := GetRandBlob(seed) + r2 := GetRandBlob(seed) + assert.DeepEqual(t, r1, r2, "Same seed should produce same blob") + + expectedSize := GoKZG.ScalarsPerBlob * GoKZG.SerializedScalarSize + assert.Equal(t, expectedSize, len(r1), "Blob should have correct size") + + r3 := GetRandBlob(seed + 1) + assert.NotEqual(t, r1, r3, "Different seeds should produce different blobs") +} + +func TestGetRandBlobElements(t *testing.T) { + seed := int64(123) + blob := GetRandBlob(seed) + + // Check that each field element in the blob matches what we'd get from GetRandFieldElement + for i := 0; i < GoKZG.ScalarsPerBlob; i++ { + start := i * GoKZG.SerializedScalarSize + end := start + GoKZG.SerializedScalarSize + + blobElement := [32]byte{} + copy(blobElement[:], blob[start:end]) + + expectedElement := GetRandFieldElement(seed + int64(i*GoKZG.SerializedScalarSize)) + require.DeepEqual(t, expectedElement, blobElement, "Field element in blob doesn't match expected value") + } +} diff --git a/testing/util/BUILD.bazel b/testing/util/BUILD.bazel index 9f806bb283..d527ec913d 100644 --- a/testing/util/BUILD.bazel +++ b/testing/util/BUILD.bazel @@ -54,6 +54,7 @@ go_library( "//crypto/bls:go_default_library", "//crypto/hash:go_default_library", "//crypto/rand:go_default_library", + "//crypto/random:go_default_library", "//encoding/bytesutil:go_default_library", "//encoding/ssz:go_default_library", "//network/forks:go_default_library", @@ -65,7 +66,6 @@ go_library( "//testing/assertions:go_default_library", "//testing/require:go_default_library", "//time/slots:go_default_library", - "@com_github_consensys_gnark_crypto//ecc/bls12-381/fr:go_default_library", "@com_github_crate_crypto_go_kzg_4844//:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", diff --git a/testing/util/deneb.go b/testing/util/deneb.go index 02297fb98d..f5630be68f 100644 --- a/testing/util/deneb.go +++ b/testing/util/deneb.go @@ -1,8 +1,6 @@ package util import ( - "bytes" - "crypto/sha256" "encoding/binary" "math/big" "testing" @@ -13,17 +11,16 @@ import ( "github.com/OffchainLabs/prysm/v6/consensus-types/blocks" "github.com/OffchainLabs/prysm/v6/consensus-types/primitives" "github.com/OffchainLabs/prysm/v6/crypto/bls" + "github.com/OffchainLabs/prysm/v6/crypto/random" "github.com/OffchainLabs/prysm/v6/encoding/bytesutil" "github.com/OffchainLabs/prysm/v6/network/forks" enginev1 "github.com/OffchainLabs/prysm/v6/proto/engine/v1" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "github.com/OffchainLabs/prysm/v6/testing/require" "github.com/OffchainLabs/prysm/v6/time/slots" - "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" GoKZG "github.com/crate-crypto/go-kzg-4844" "github.com/ethereum/go-ethereum/common" gethTypes "github.com/ethereum/go-ethereum/core/types" - "github.com/sirupsen/logrus" ) type DenebBlockGeneratorOption func(*denebBlockGenerator) @@ -203,35 +200,16 @@ func ExtendBlocksPlusBlobs(t *testing.T, blks []blocks.ROBlock, size int) ([]blo return blks, blobs } -func deterministicRandomness(seed int64) [32]byte { - // Converts an int64 to a byte slice - buf := new(bytes.Buffer) - err := binary.Write(buf, binary.BigEndian, seed) - if err != nil { - logrus.WithError(err).Error("Failed to write int64 to bytes buffer") - return [32]byte{} - } - bytes := buf.Bytes() - - return sha256.Sum256(bytes) +func DeterministicRandomness(seed int64) [32]byte { + return random.DeterministicRandomness(seed) } // Returns a serialized random field element in big-endian func GetRandFieldElement(seed int64) [32]byte { - bytes := deterministicRandomness(seed) - var r fr.Element - r.SetBytes(bytes[:]) - - return GoKZG.SerializeScalar(r) + return random.GetRandFieldElement(seed) } // Returns a random blob using the passed seed as entropy func GetRandBlob(seed int64) GoKZG.Blob { - var blob GoKZG.Blob - bytesPerBlob := GoKZG.ScalarsPerBlob * GoKZG.SerializedScalarSize - for i := 0; i < bytesPerBlob; i += GoKZG.SerializedScalarSize { - fieldElementBytes := GetRandFieldElement(seed + int64(i)) - copy(blob[i:i+GoKZG.SerializedScalarSize], fieldElementBytes[:]) - } - return blob + return random.GetRandBlob(seed) }