From c32a9ba9cb32fd0a152557a6e7f0fa914ef8154b Mon Sep 17 00:00:00 2001 From: nisdas Date: Wed, 3 Jul 2024 16:37:58 +0800 Subject: [PATCH 1/3] Add aggregated key method --- beacon-chain/core/blocks/signature.go | 7 +---- beacon-chain/state/BUILD.bazel | 1 + beacon-chain/state/interfaces.go | 2 ++ beacon-chain/state/state-native/BUILD.bazel | 1 + .../state/state-native/getters_validator.go | 31 +++++++++++++++++++ .../state-native/getters_validator_test.go | 17 ++++++++++ 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/beacon-chain/core/blocks/signature.go b/beacon-chain/core/blocks/signature.go index c0f9741589cf..933dd0a37f9e 100644 --- a/beacon-chain/core/blocks/signature.go +++ b/beacon-chain/core/blocks/signature.go @@ -204,12 +204,7 @@ func createAttestationSignatureBatch( return nil, err } indices := ia.GetAttestingIndices() - pubkeys := make([][]byte, len(indices)) - for i := 0; i < len(indices); i++ { - pubkeyAtIdx := beaconState.PubkeyAtIndex(primitives.ValidatorIndex(indices[i])) - pubkeys[i] = pubkeyAtIdx[:] - } - aggP, err := bls.AggregatePublicKeys(pubkeys) + aggP, err := beaconState.AggregatedKeyFromIndices(indices) if err != nil { return nil, err } diff --git a/beacon-chain/state/BUILD.bazel b/beacon-chain/state/BUILD.bazel index fa1ee84cff41..295cfa2110d5 100644 --- a/beacon-chain/state/BUILD.bazel +++ b/beacon-chain/state/BUILD.bazel @@ -13,6 +13,7 @@ go_library( "//config/fieldparams:go_default_library", "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", + "//crypto/bls:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "@com_github_prometheus_client_golang//prometheus:go_default_library", diff --git a/beacon-chain/state/interfaces.go b/beacon-chain/state/interfaces.go index 85c9bb9e25e2..b24b2207fb8d 100644 --- a/beacon-chain/state/interfaces.go +++ b/beacon-chain/state/interfaces.go @@ -11,6 +11,7 @@ import ( fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v5/crypto/bls" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ) @@ -129,6 +130,7 @@ type ReadOnlyValidators interface { ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]byte) (primitives.ValidatorIndex, bool) PublicKeys() ([][fieldparams.BLSPubkeyLength]byte, error) PubkeyAtIndex(idx primitives.ValidatorIndex) [fieldparams.BLSPubkeyLength]byte + AggregatedKeyFromIndices(idxs []uint64) (bls.PublicKey, error) NumValidators() int ReadFromEveryValidator(f func(idx int, val ReadOnlyValidator) error) error } diff --git a/beacon-chain/state/state-native/BUILD.bazel b/beacon-chain/state/state-native/BUILD.bazel index 46c8bb8e4497..9bb1f48cac91 100644 --- a/beacon-chain/state/state-native/BUILD.bazel +++ b/beacon-chain/state/state-native/BUILD.bazel @@ -68,6 +68,7 @@ go_library( "//consensus-types/primitives:go_default_library", "//container/multi-value-slice:go_default_library", "//container/slice:go_default_library", + "//crypto/bls:go_default_library", "//crypto/hash:go_default_library", "//encoding/bytesutil:go_default_library", "//encoding/ssz:go_default_library", diff --git a/beacon-chain/state/state-native/getters_validator.go b/beacon-chain/state/state-native/getters_validator.go index 0f1df58b9cef..da5624f6b6de 100644 --- a/beacon-chain/state/state-native/getters_validator.go +++ b/beacon-chain/state/state-native/getters_validator.go @@ -9,6 +9,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/config/params" consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v5/crypto/bls" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" @@ -223,6 +224,36 @@ func (b *BeaconState) PubkeyAtIndex(idx primitives.ValidatorIndex) [fieldparams. return bytesutil.ToBytes48(v.PublicKey) } +// AggregatedKeyFromIndices builds an aggregated public key from the provided +// validator indices. +func (b *BeaconState) AggregatedKeyFromIndices(idxs []uint64) (bls.PublicKey, error) { + b.lock.RLock() + defer b.lock.RUnlock() + + pubKeys := make([][]byte, len(idxs)) + for i, idx := range idxs { + var v *ethpb.Validator + if features.Get().EnableExperimentalState { + var err error + v, err = b.validatorsMultiValue.At(b, idx) + if err != nil { + return nil, err + } + } else { + if idx >= uint64(len(b.validators)) { + return nil, consensus_types.ErrOutOfBounds + } + v = b.validators[idx] + } + + if v == nil { + return nil, ErrNilWrappedValidator + } + pubKeys[i] = v.PublicKey + } + return bls.AggregatePublicKeys(pubKeys) +} + // PublicKeys builds a list of all validator public keys, with each key's index aligned to its validator index. func (b *BeaconState) PublicKeys() ([][fieldparams.BLSPubkeyLength]byte, error) { b.lock.RLock() diff --git a/beacon-chain/state/state-native/getters_validator_test.go b/beacon-chain/state/state-native/getters_validator_test.go index 81e823c19487..a0ddf8a5fecf 100644 --- a/beacon-chain/state/state-native/getters_validator_test.go +++ b/beacon-chain/state/state-native/getters_validator_test.go @@ -10,7 +10,9 @@ import ( testtmpl "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/testing" "github.com/prysmaticlabs/prysm/v5/config/params" consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" + "github.com/prysmaticlabs/prysm/v5/crypto/bls" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/testing/assert" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" ) @@ -145,3 +147,18 @@ func TestPendingBalanceToWithdraw(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(600), ab) } + +func TestAggregatedKeyFromIndices(t *testing.T) { + dState, _ := util.DeterministicGenesisState(t, 10) + pKey1 := dState.PubkeyAtIndex(3) + pKey2 := dState.PubkeyAtIndex(7) + pKey3 := dState.PubkeyAtIndex(9) + + aggKey, err := bls.AggregatePublicKeys([][]byte{pKey1[:], pKey2[:], pKey3[:]}) + require.NoError(t, err) + + retKey, err := dState.AggregatedKeyFromIndices([]uint64{3, 7, 9}) + require.NoError(t, err) + + assert.Equal(t, true, aggKey.Equals(retKey), "unequal aggregated keys") +} From 9bf8b78af3f89da07110a18f3115edf85ed3de28 Mon Sep 17 00:00:00 2001 From: nisdas Date: Wed, 3 Jul 2024 16:50:19 +0800 Subject: [PATCH 2/3] Gazelle --- beacon-chain/state/state-native/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/beacon-chain/state/state-native/BUILD.bazel b/beacon-chain/state/state-native/BUILD.bazel index 9bb1f48cac91..da2f397025f1 100644 --- a/beacon-chain/state/state-native/BUILD.bazel +++ b/beacon-chain/state/state-native/BUILD.bazel @@ -142,6 +142,7 @@ go_test( "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", "//container/trie:go_default_library", + "//crypto/bls:go_default_library", "//crypto/rand:go_default_library", "//encoding/bytesutil:go_default_library", "//proto/engine/v1:go_default_library", From d3c3ad2f145c0096cee82b950c094f3639462fdb Mon Sep 17 00:00:00 2001 From: nisdas Date: Wed, 3 Jul 2024 18:22:42 +0800 Subject: [PATCH 3/3] Manu's Review --- beacon-chain/core/blocks/signature.go | 2 +- beacon-chain/state/interfaces.go | 2 +- beacon-chain/state/state-native/getters_validator.go | 4 ++-- beacon-chain/state/state-native/getters_validator_test.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/beacon-chain/core/blocks/signature.go b/beacon-chain/core/blocks/signature.go index 933dd0a37f9e..dedd5856ec68 100644 --- a/beacon-chain/core/blocks/signature.go +++ b/beacon-chain/core/blocks/signature.go @@ -204,7 +204,7 @@ func createAttestationSignatureBatch( return nil, err } indices := ia.GetAttestingIndices() - aggP, err := beaconState.AggregatedKeyFromIndices(indices) + aggP, err := beaconState.AggregateKeyFromIndices(indices) if err != nil { return nil, err } diff --git a/beacon-chain/state/interfaces.go b/beacon-chain/state/interfaces.go index b24b2207fb8d..949d735881ea 100644 --- a/beacon-chain/state/interfaces.go +++ b/beacon-chain/state/interfaces.go @@ -130,7 +130,7 @@ type ReadOnlyValidators interface { ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]byte) (primitives.ValidatorIndex, bool) PublicKeys() ([][fieldparams.BLSPubkeyLength]byte, error) PubkeyAtIndex(idx primitives.ValidatorIndex) [fieldparams.BLSPubkeyLength]byte - AggregatedKeyFromIndices(idxs []uint64) (bls.PublicKey, error) + AggregateKeyFromIndices(idxs []uint64) (bls.PublicKey, error) NumValidators() int ReadFromEveryValidator(f func(idx int, val ReadOnlyValidator) error) error } diff --git a/beacon-chain/state/state-native/getters_validator.go b/beacon-chain/state/state-native/getters_validator.go index da5624f6b6de..cfc3779c170e 100644 --- a/beacon-chain/state/state-native/getters_validator.go +++ b/beacon-chain/state/state-native/getters_validator.go @@ -224,9 +224,9 @@ func (b *BeaconState) PubkeyAtIndex(idx primitives.ValidatorIndex) [fieldparams. return bytesutil.ToBytes48(v.PublicKey) } -// AggregatedKeyFromIndices builds an aggregated public key from the provided +// AggregateKeyFromIndices builds an aggregated public key from the provided // validator indices. -func (b *BeaconState) AggregatedKeyFromIndices(idxs []uint64) (bls.PublicKey, error) { +func (b *BeaconState) AggregateKeyFromIndices(idxs []uint64) (bls.PublicKey, error) { b.lock.RLock() defer b.lock.RUnlock() diff --git a/beacon-chain/state/state-native/getters_validator_test.go b/beacon-chain/state/state-native/getters_validator_test.go index a0ddf8a5fecf..c4938832067d 100644 --- a/beacon-chain/state/state-native/getters_validator_test.go +++ b/beacon-chain/state/state-native/getters_validator_test.go @@ -148,7 +148,7 @@ func TestPendingBalanceToWithdraw(t *testing.T) { require.Equal(t, uint64(600), ab) } -func TestAggregatedKeyFromIndices(t *testing.T) { +func TestAggregateKeyFromIndices(t *testing.T) { dState, _ := util.DeterministicGenesisState(t, 10) pKey1 := dState.PubkeyAtIndex(3) pKey2 := dState.PubkeyAtIndex(7) @@ -157,7 +157,7 @@ func TestAggregatedKeyFromIndices(t *testing.T) { aggKey, err := bls.AggregatePublicKeys([][]byte{pKey1[:], pKey2[:], pKey3[:]}) require.NoError(t, err) - retKey, err := dState.AggregatedKeyFromIndices([]uint64{3, 7, 9}) + retKey, err := dState.AggregateKeyFromIndices([]uint64{3, 7, 9}) require.NoError(t, err) assert.Equal(t, true, aggKey.Equals(retKey), "unequal aggregated keys")