Skip to content

Commit

Permalink
Add Aggregated Public Key Method (#14178)
Browse files Browse the repository at this point in the history
* Add aggregated key method

* Gazelle

* Manu's Review
  • Loading branch information
nisdas committed Jul 8, 2024
1 parent aea2a46 commit 74b5f6e
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 6 deletions.
7 changes: 1 addition & 6 deletions beacon-chain/core/blocks/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.AggregateKeyFromIndices(indices)
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/state/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions beacon-chain/state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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
AggregateKeyFromIndices(idxs []uint64) (bls.PublicKey, error)
NumValidators() int
ReadFromEveryValidator(f func(idx int, val ReadOnlyValidator) error) error
}
Expand Down
2 changes: 2 additions & 0 deletions beacon-chain/state/state-native/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -141,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",
Expand Down
31 changes: 31 additions & 0 deletions beacon-chain/state/state-native/getters_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -223,6 +224,36 @@ func (b *BeaconState) PubkeyAtIndex(idx primitives.ValidatorIndex) [fieldparams.
return bytesutil.ToBytes48(v.PublicKey)
}

// AggregateKeyFromIndices builds an aggregated public key from the provided
// validator indices.
func (b *BeaconState) AggregateKeyFromIndices(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()
Expand Down
17 changes: 17 additions & 0 deletions beacon-chain/state/state-native/getters_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -145,3 +147,18 @@ func TestPendingBalanceToWithdraw(t *testing.T) {
require.NoError(t, err)
require.Equal(t, uint64(600), ab)
}

func TestAggregateKeyFromIndices(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.AggregateKeyFromIndices([]uint64{3, 7, 9})
require.NoError(t, err)

assert.Equal(t, true, aggKey.Equals(retKey), "unequal aggregated keys")
}

0 comments on commit 74b5f6e

Please sign in to comment.