Skip to content

Commit

Permalink
Sign BLS_TO_EXECUTION_CHANGES with GENESIS_FORK_VERSION (#11870)
Browse files Browse the repository at this point in the history
* Sign BLS_TO_EXECUTION_CHANGES with GENESIS_FORK_VERSION

* update spectests

* extra blank line

* fix consensus_specs_sha

* get rid of LightClients tests

* fix unit tests

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
  • Loading branch information
potuz and prylabs-bulldozer[bot] authored Jan 16, 2023
1 parent 179252f commit 047cae5
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 86 deletions.
10 changes: 5 additions & 5 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,
)

Expand All @@ -251,7 +251,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "531eff00498acf5965d8890d83e3561a64f7b23a75d7f312915291482da2bf52",
sha256 = "9d22246c00ec3907ef8dc3ddccdfe6f7153ce46df73deee0a0176fe7e4aa1126",
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
)
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
117 changes: 67 additions & 50 deletions beacon-chain/core/blocks/withdrawals_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,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 +912,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 +924,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 +944,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)
}
12 changes: 6 additions & 6 deletions beacon-chain/rpc/eth/beacon/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1205,8 +1205,8 @@ func TestSubmitSignedBLSToExecutionChanges_Ok(t *testing.T) {

spb := &ethpbv1alpha1.BeaconStateCapella{
Fork: &ethpbv1alpha1.Fork{
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
Epoch: params.BeaconConfig().CapellaForkEpoch,
},
}
Expand Down Expand Up @@ -1342,8 +1342,8 @@ func TestSubmitSignedBLSToExecutionChanges_Bellatrix(t *testing.T) {

spc := &ethpbv1alpha1.BeaconStateCapella{
Fork: &ethpbv1alpha1.Fork{
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
Epoch: params.BeaconConfig().CapellaForkEpoch,
},
}
Expand Down Expand Up @@ -1405,8 +1405,8 @@ func TestSubmitSignedBLSToExecutionChanges_Failures(t *testing.T) {

spb := &ethpbv1alpha1.BeaconStateCapella{
Fork: &ethpbv1alpha1.Fork{
CurrentVersion: params.BeaconConfig().CapellaForkVersion,
PreviousVersion: params.BeaconConfig().BellatrixForkVersion,
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
PreviousVersion: params.BeaconConfig().GenesisForkVersion,
Epoch: params.BeaconConfig().CapellaForkEpoch,
},
}
Expand Down
3 changes: 3 additions & 0 deletions testing/spectest/shared/altair/ssz_static/ssz_static.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ func unmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (i
obj = &ethpb.HistoricalBatch{}
case "IndexedAttestation":
obj = &ethpb.IndexedAttestation{}
case "LightClientHeader":
t.Skip("not a beacon node type, this is a light node type")
return nil, nil
case "PendingAttestation":
obj = &ethpb.PendingAttestation{}
case "ProposerSlashing":
Expand Down
3 changes: 3 additions & 0 deletions testing/spectest/shared/bellatrix/ssz_static/ssz_static.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ func unmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (i
obj = &ethpb.HistoricalBatch{}
case "IndexedAttestation":
obj = &ethpb.IndexedAttestation{}
case "LightClientHeader":
t.Skip("not a beacon node type, this is a light node type")
return nil, nil
case "PendingAttestation":
obj = &ethpb.PendingAttestation{}
case "ProposerSlashing":
Expand Down
3 changes: 3 additions & 0 deletions testing/spectest/shared/capella/ssz_static/ssz_static.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ func unmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (i
obj = &ethpb.HistoricalBatch{}
case "IndexedAttestation":
obj = &ethpb.IndexedAttestation{}
case "LightClientHeader":
t.Skip("not a beacon node type, this is a light node type")
return nil, nil
case "PendingAttestation":
obj = &ethpb.PendingAttestation{}
case "ProposerSlashing":
Expand Down
8 changes: 7 additions & 1 deletion testing/util/capella_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,16 @@ func GenerateBLSToExecutionChange(st state.BeaconState, priv bls.SecretKey, val
ValidatorIndex: val,
FromBlsPubkey: pubkey,
}
signature, err := signing.ComputeDomainAndSign(st, time.CurrentEpoch(st), message, params.BeaconConfig().DomainBLSToExecutionChange, priv)
c := params.BeaconConfig()
domain, err := signing.ComputeDomain(c.DomainBLSToExecutionChange, c.GenesisForkVersion, st.GenesisValidatorsRoot())
if err != nil {
return nil, err
}
sr, err := signing.ComputeSigningRoot(message, domain)
if err != nil {
return nil, err
}
signature := priv.Sign(sr[:]).Marshal()
return &ethpb.SignedBLSToExecutionChange{
Message: message,
Signature: signature,
Expand Down

0 comments on commit 047cae5

Please sign in to comment.