Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sign BLS_TO_EXECUTION_CHANGES with GENESIS_FORK_VERSION #11870

Merged
merged 11 commits into from
Jan 16, 2023
8 changes: 4 additions & 4 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ filegroup(
url = "https://github.com/eth-clients/slashing-protection-interchange-tests/archive/b8413ca42dc92308019d0d4db52c87e9e125c4e9.tar.gz",
)

consensus_spec_version = "v1.3.0-rc.0"
consensus_spec_version = "v1.3.0-rc.1"

bls_test_version = "v0.1.1"

Expand All @@ -204,7 +204,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "44c39a68242a4b731865040ea3009ea1a695ee3377d2891cecf8e6a721f0102b",
sha256 = "3d6fadb64674eb64a84fae6c2efa9949231ea91e7cb74ada9214097323e86569",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
)

Expand All @@ -220,7 +220,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "c9aaf6f7c1ca1264ec9a45872d5058f3377ebdd9dbcb987796f7302d86f98934",
sha256 = "54ffbcab1e77316a280e6f5a64c6ed62351e8f5678e6fa49340e49b9b5575e8e",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
)

Expand All @@ -236,7 +236,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "78400c82f1978147feeab54e3deccb29c024efa13d6753adc8687ae008bae246",
sha256 = "bb06d30ca533dc97d45f2367916ba9ff1b5af52f08a9d8c33bb7b1a61254094e",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you update sha256 at L254 for consensus_spec?

Screenshot 2023-01-13 at 10 43 25 AM

Expand Down
1 change: 0 additions & 1 deletion beacon-chain/core/blocks/exports_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
package blocks

var ProcessBLSToExecutionChange = processBLSToExecutionChange
var BLSChangesSigningDomain = blsChangesSigningDomain
28 changes: 5 additions & 23 deletions beacon-chain/core/blocks/withdrawals.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
ethpbv2 "github.com/prysmaticlabs/prysm/v3/proto/eth/v2"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/runtime/version"
"github.com/prysmaticlabs/prysm/v3/time/slots"
)

const executionToBLSPadding = 12
Expand Down Expand Up @@ -162,25 +161,6 @@ func ProcessWithdrawals(st state.BeaconState, withdrawals []*enginev1.Withdrawal
return st, nil
}

// blsChangesSigningDomain returns the signing domain to check BLSToExecutionChange messages against.
func blsChangesSigningDomain(st state.ReadOnlyBeaconState) ([]byte, error) {
var epoch types.Epoch
var fork *ethpb.Fork
if st.Version() < version.Capella {
epoch = params.BeaconConfig().CapellaForkEpoch
fork = &ethpb.Fork{
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
Epoch: epoch,
}

} else {
epoch = slots.ToEpoch(st.Slot())
fork = st.Fork()
}
return signing.Domain(fork, epoch, params.BeaconConfig().DomainBLSToExecutionChange, st.GenesisValidatorsRoot())
}

func BLSChangesSignatureBatch(
st state.ReadOnlyBeaconState,
changes []*ethpb.SignedBLSToExecutionChange,
Expand All @@ -195,9 +175,10 @@ func BLSChangesSignatureBatch(
Messages: make([][32]byte, len(changes)),
Descriptions: make([]string, len(changes)),
}
domain, err := blsChangesSigningDomain(st)
c := params.BeaconConfig()
domain, err := signing.ComputeDomain(c.DomainBLSToExecutionChange, c.GenesisForkVersion, st.GenesisValidatorsRoot())
if err != nil {
return nil, err
return nil, errors.Wrap(err, "could not compute signing domain")
}
for i, change := range changes {
batch.Signatures[i] = change.Signature
Expand All @@ -223,7 +204,8 @@ func VerifyBLSChangeSignature(
st state.BeaconState,
change *ethpbv2.SignedBLSToExecutionChange,
) error {
domain, err := blsChangesSigningDomain(st)
c := params.BeaconConfig()
domain, err := signing.ComputeDomain(c.DomainBLSToExecutionChange, c.GenesisForkVersion, st.GenesisValidatorsRoot())
if err != nil {
return errors.Wrap(err, "could not compute signing domain")
}
Expand Down
118 changes: 67 additions & 51 deletions beacon-chain/core/blocks/withdrawals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,6 @@ func TestProcessBLSToExecutionChanges(t *testing.T) {
require.Equal(t, params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, val.WithdrawalCredentials[0])
}
}

potuz marked this conversation as resolved.
Show resolved Hide resolved
func TestBLSChangesSignatureBatch(t *testing.T) {
spb := &ethpb.BeaconStateCapella{
Fork: &ethpb.Fork{
Expand Down Expand Up @@ -791,6 +790,71 @@ func TestBLSChangesSignatureBatch(t *testing.T) {
require.NoError(t, blocks.VerifyBLSChangeSignature(st, change))
}

func TestBLSChangesSignatureBatchWrongFork(t *testing.T) {
spb := &ethpb.BeaconStateCapella{
Fork: &ethpb.Fork{
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
Epoch: params.BeaconConfig().CapellaForkEpoch,
},
}
numValidators := 10
validators := make([]*ethpb.Validator, numValidators)
blsChanges := make([]*ethpb.BLSToExecutionChange, numValidators)
spb.Balances = make([]uint64, numValidators)
privKeys := make([]common.SecretKey, numValidators)
maxEffectiveBalance := params.BeaconConfig().MaxEffectiveBalance
executionAddress := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13}

for i := range validators {
v := &ethpb.Validator{}
v.EffectiveBalance = maxEffectiveBalance
v.WithdrawableEpoch = params.BeaconConfig().FarFutureEpoch
v.WithdrawalCredentials = make([]byte, 32)
priv, err := bls.RandKey()
require.NoError(t, err)
privKeys[i] = priv
pubkey := priv.PublicKey().Marshal()

message := &ethpb.BLSToExecutionChange{
ToExecutionAddress: executionAddress,
ValidatorIndex: types.ValidatorIndex(i),
FromBlsPubkey: pubkey,
}

hashFn := ssz.NewHasherFunc(hash.CustomSHA256Hasher())
digest := hashFn.Hash(pubkey)
digest[0] = params.BeaconConfig().BLSWithdrawalPrefixByte
copy(v.WithdrawalCredentials, digest[:])
validators[i] = v
blsChanges[i] = message
}
spb.Validators = validators
st, err := state_native.InitializeFromProtoCapella(spb)
require.NoError(t, err)

signedChanges := make([]*ethpb.SignedBLSToExecutionChange, numValidators)
for i, message := range blsChanges {
signature, err := signing.ComputeDomainAndSign(st, time.CurrentEpoch(st), message, params.BeaconConfig().DomainBLSToExecutionChange, privKeys[i])
require.NoError(t, err)

signed := &ethpb.SignedBLSToExecutionChange{
Message: message,
Signature: signature,
}
signedChanges[i] = signed
}
batch, err := blocks.BLSChangesSignatureBatch(st, signedChanges)
require.NoError(t, err)
verify, err := batch.Verify()
require.NoError(t, err)
require.Equal(t, false, verify)

// Verify a single change
change := migration.V1Alpha1SignedBLSToExecChangeToV2(signedChanges[0])
require.ErrorIs(t, signing.ErrSigFailedToVerify, blocks.VerifyBLSChangeSignature(st, change))
}

func TestBLSChangesSignatureBatchFromBellatrix(t *testing.T) {
cfg := params.BeaconConfig()
savedConfig := cfg.Copy()
Expand Down Expand Up @@ -847,7 +911,7 @@ func TestBLSChangesSignatureBatchFromBellatrix(t *testing.T) {
spc := &ethpb.BeaconStateCapella{
Fork: &ethpb.Fork{
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
Epoch: params.BeaconConfig().CapellaForkEpoch,
},
}
Expand All @@ -859,7 +923,7 @@ func TestBLSChangesSignatureBatchFromBellatrix(t *testing.T) {
require.NoError(t, err)

for i, message := range blsChanges {
signature, err := signing.ComputeDomainAndSign(stc, time.CurrentEpoch(stc), message, params.BeaconConfig().DomainBLSToExecutionChange, privKeys[i])
signature, err := signing.ComputeDomainAndSign(stc, 0, message, params.BeaconConfig().DomainBLSToExecutionChange, privKeys[i])
require.NoError(t, err)

signed := &ethpb.SignedBLSToExecutionChange{
Expand All @@ -879,51 +943,3 @@ func TestBLSChangesSignatureBatchFromBellatrix(t *testing.T) {
require.NoError(t, blocks.VerifyBLSChangeSignature(st, change))
params.OverrideBeaconConfig(savedConfig)
}

func TestBLSChangesSigningDomain(t *testing.T) {
cfg := params.BeaconConfig()
savedConfig := cfg.Copy()
cfg.CapellaForkEpoch = cfg.BellatrixForkEpoch.AddEpoch(2)
params.OverrideBeaconConfig(cfg)
capellaDomain := []byte{0xa, 0x0, 0x0, 0x0, 0xe7, 0xb4, 0xbb, 0x67, 0x55, 0x1d, 0xde, 0x95, 0x89, 0xc1, 0x55, 0x3d, 0xfd, 0xa3, 0x7a, 0x94, 0x2a, 0x18, 0xca, 0xf1, 0x84, 0xf9, 0xcc, 0x16, 0x29, 0xd2, 0x5c, 0xf5}

t.Run("pre-Capella fork", func(t *testing.T) {
spb := &ethpb.BeaconStateBellatrix{
Fork: &ethpb.Fork{
CurrentVersion: params.BeaconConfig().BellatrixForkVersion,
PreviousVersion: params.BeaconConfig().AltairForkVersion,
Epoch: params.BeaconConfig().BellatrixForkEpoch,
},
}
slot, err := slots.EpochStart(params.BeaconConfig().BellatrixForkEpoch)
require.NoError(t, err)
spb.Slot = slot

st, err := state_native.InitializeFromProtoBellatrix(spb)
require.NoError(t, err)

domain, err := blocks.BLSChangesSigningDomain(st)
require.NoError(t, err)
require.DeepEqual(t, capellaDomain, domain)
})
t.Run("post-Capella fork", func(t *testing.T) {
spb := &ethpb.BeaconStateCapella{
Fork: &ethpb.Fork{
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
Epoch: params.BeaconConfig().CapellaForkEpoch,
},
}
slot, err := slots.EpochStart(params.BeaconConfig().CapellaForkEpoch)
require.NoError(t, err)
spb.Slot = slot

st, err := state_native.InitializeFromProtoCapella(spb)
require.NoError(t, err)

domain, err := blocks.BLSChangesSigningDomain(st)
require.NoError(t, err)
require.DeepEqual(t, capellaDomain, domain)
})
params.OverrideBeaconConfig(savedConfig)
}