From 6c666b6a10aa6238b4e5be0471c9246782793c6f Mon Sep 17 00:00:00 2001 From: Potuz Date: Fri, 13 Jan 2023 09:46:07 -0300 Subject: [PATCH 1/6] Sign BLS_TO_EXECUTION_CHANGES with GENESIS_FORK_VERSION --- beacon-chain/core/blocks/exports_test.go | 1 - beacon-chain/core/blocks/withdrawals.go | 28 +---- beacon-chain/core/blocks/withdrawals_test.go | 118 +++++++++++-------- 3 files changed, 72 insertions(+), 75 deletions(-) diff --git a/beacon-chain/core/blocks/exports_test.go b/beacon-chain/core/blocks/exports_test.go index b7f60a06995d..3d92819f3449 100644 --- a/beacon-chain/core/blocks/exports_test.go +++ b/beacon-chain/core/blocks/exports_test.go @@ -1,4 +1,3 @@ package blocks var ProcessBLSToExecutionChange = processBLSToExecutionChange -var BLSChangesSigningDomain = blsChangesSigningDomain diff --git a/beacon-chain/core/blocks/withdrawals.go b/beacon-chain/core/blocks/withdrawals.go index 7dd8b1c1109e..d00076d05839 100644 --- a/beacon-chain/core/blocks/withdrawals.go +++ b/beacon-chain/core/blocks/withdrawals.go @@ -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 @@ -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 = ðpb.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, @@ -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 @@ -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") } diff --git a/beacon-chain/core/blocks/withdrawals_test.go b/beacon-chain/core/blocks/withdrawals_test.go index 5a63d5e6a0ca..5c4c22a9bd86 100644 --- a/beacon-chain/core/blocks/withdrawals_test.go +++ b/beacon-chain/core/blocks/withdrawals_test.go @@ -726,7 +726,6 @@ func TestProcessBLSToExecutionChanges(t *testing.T) { require.Equal(t, params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, val.WithdrawalCredentials[0]) } } - func TestBLSChangesSignatureBatch(t *testing.T) { spb := ðpb.BeaconStateCapella{ Fork: ðpb.Fork{ @@ -791,6 +790,71 @@ func TestBLSChangesSignatureBatch(t *testing.T) { require.NoError(t, blocks.VerifyBLSChangeSignature(st, change)) } +func TestBLSChangesSignatureBatchWrongFork(t *testing.T) { + spb := ðpb.BeaconStateCapella{ + Fork: ðpb.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 := ðpb.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 := ðpb.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 := ðpb.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() @@ -847,7 +911,7 @@ func TestBLSChangesSignatureBatchFromBellatrix(t *testing.T) { spc := ðpb.BeaconStateCapella{ Fork: ðpb.Fork{ CurrentVersion: params.BeaconConfig().CapellaForkVersion, - PreviousVersion: params.BeaconConfig().BellatrixForkVersion, + PreviousVersion: params.BeaconConfig().GenesisForkVersion, Epoch: params.BeaconConfig().CapellaForkEpoch, }, } @@ -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 := ðpb.SignedBLSToExecutionChange{ @@ -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 := ðpb.BeaconStateBellatrix{ - Fork: ðpb.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 := ðpb.BeaconStateCapella{ - Fork: ðpb.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) -} From 605406ee9042a05d99bdd145eb481bfcb9dbcc23 Mon Sep 17 00:00:00 2001 From: Potuz Date: Fri, 13 Jan 2023 15:42:10 -0300 Subject: [PATCH 2/6] update spectests --- WORKSPACE | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 1970f870a777..ee8262f1cefa 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -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" @@ -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, ) @@ -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, ) @@ -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, ) From f1dbfda7e751e79d79981b264fc3dccce74f154d Mon Sep 17 00:00:00 2001 From: Potuz Date: Fri, 13 Jan 2023 15:43:43 -0300 Subject: [PATCH 3/6] extra blank line --- beacon-chain/core/blocks/withdrawals_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/beacon-chain/core/blocks/withdrawals_test.go b/beacon-chain/core/blocks/withdrawals_test.go index 5c4c22a9bd86..0d7e291308aa 100644 --- a/beacon-chain/core/blocks/withdrawals_test.go +++ b/beacon-chain/core/blocks/withdrawals_test.go @@ -726,6 +726,7 @@ func TestProcessBLSToExecutionChanges(t *testing.T) { require.Equal(t, params.BeaconConfig().ETH1AddressWithdrawalPrefixByte, val.WithdrawalCredentials[0]) } } + func TestBLSChangesSignatureBatch(t *testing.T) { spb := ðpb.BeaconStateCapella{ Fork: ðpb.Fork{ From 0700b957841777632349678ca66d97de32e4ee32 Mon Sep 17 00:00:00 2001 From: Potuz Date: Fri, 13 Jan 2023 15:55:34 -0300 Subject: [PATCH 4/6] fix consensus_specs_sha --- WORKSPACE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WORKSPACE b/WORKSPACE index ee8262f1cefa..3522f581ee42 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -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, ) From 7fbd36fc2f192dd2b935e99915a75f46c35cd0f9 Mon Sep 17 00:00:00 2001 From: Potuz Date: Fri, 13 Jan 2023 19:52:37 -0300 Subject: [PATCH 5/6] get rid of LightClients tests --- testing/spectest/shared/altair/ssz_static/ssz_static.go | 3 +++ testing/spectest/shared/bellatrix/ssz_static/ssz_static.go | 3 +++ testing/spectest/shared/capella/ssz_static/ssz_static.go | 3 +++ 3 files changed, 9 insertions(+) diff --git a/testing/spectest/shared/altair/ssz_static/ssz_static.go b/testing/spectest/shared/altair/ssz_static/ssz_static.go index 5c87c37c6d88..fa89c8a53c02 100644 --- a/testing/spectest/shared/altair/ssz_static/ssz_static.go +++ b/testing/spectest/shared/altair/ssz_static/ssz_static.go @@ -70,6 +70,9 @@ func unmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (i obj = ðpb.HistoricalBatch{} case "IndexedAttestation": obj = ðpb.IndexedAttestation{} + case "LightClientHeader": + t.Skip("not a beacon node type, this is a light node type") + return nil, nil case "PendingAttestation": obj = ðpb.PendingAttestation{} case "ProposerSlashing": diff --git a/testing/spectest/shared/bellatrix/ssz_static/ssz_static.go b/testing/spectest/shared/bellatrix/ssz_static/ssz_static.go index 79e8a6336cb3..33fc0fb54f97 100644 --- a/testing/spectest/shared/bellatrix/ssz_static/ssz_static.go +++ b/testing/spectest/shared/bellatrix/ssz_static/ssz_static.go @@ -75,6 +75,9 @@ func unmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (i obj = ðpb.HistoricalBatch{} case "IndexedAttestation": obj = ðpb.IndexedAttestation{} + case "LightClientHeader": + t.Skip("not a beacon node type, this is a light node type") + return nil, nil case "PendingAttestation": obj = ðpb.PendingAttestation{} case "ProposerSlashing": diff --git a/testing/spectest/shared/capella/ssz_static/ssz_static.go b/testing/spectest/shared/capella/ssz_static/ssz_static.go index cffbbd741b84..8fe83834947a 100644 --- a/testing/spectest/shared/capella/ssz_static/ssz_static.go +++ b/testing/spectest/shared/capella/ssz_static/ssz_static.go @@ -75,6 +75,9 @@ func unmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (i obj = ðpb.HistoricalBatch{} case "IndexedAttestation": obj = ðpb.IndexedAttestation{} + case "LightClientHeader": + t.Skip("not a beacon node type, this is a light node type") + return nil, nil case "PendingAttestation": obj = ðpb.PendingAttestation{} case "ProposerSlashing": From eb6786d30aa3ae50c0b5c06048f889047626d8c2 Mon Sep 17 00:00:00 2001 From: Potuz Date: Mon, 16 Jan 2023 08:12:00 -0300 Subject: [PATCH 6/6] fix unit tests --- beacon-chain/rpc/eth/beacon/pool_test.go | 12 ++++++------ testing/util/capella_block.go | 8 +++++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/beacon-chain/rpc/eth/beacon/pool_test.go b/beacon-chain/rpc/eth/beacon/pool_test.go index 0e7efd68b1b6..f60f239d225e 100644 --- a/beacon-chain/rpc/eth/beacon/pool_test.go +++ b/beacon-chain/rpc/eth/beacon/pool_test.go @@ -1205,8 +1205,8 @@ func TestSubmitSignedBLSToExecutionChanges_Ok(t *testing.T) { spb := ðpbv1alpha1.BeaconStateCapella{ Fork: ðpbv1alpha1.Fork{ - CurrentVersion: params.BeaconConfig().CapellaForkVersion, - PreviousVersion: params.BeaconConfig().BellatrixForkVersion, + CurrentVersion: params.BeaconConfig().GenesisForkVersion, + PreviousVersion: params.BeaconConfig().GenesisForkVersion, Epoch: params.BeaconConfig().CapellaForkEpoch, }, } @@ -1342,8 +1342,8 @@ func TestSubmitSignedBLSToExecutionChanges_Bellatrix(t *testing.T) { spc := ðpbv1alpha1.BeaconStateCapella{ Fork: ðpbv1alpha1.Fork{ - CurrentVersion: params.BeaconConfig().CapellaForkVersion, - PreviousVersion: params.BeaconConfig().BellatrixForkVersion, + CurrentVersion: params.BeaconConfig().GenesisForkVersion, + PreviousVersion: params.BeaconConfig().GenesisForkVersion, Epoch: params.BeaconConfig().CapellaForkEpoch, }, } @@ -1405,8 +1405,8 @@ func TestSubmitSignedBLSToExecutionChanges_Failures(t *testing.T) { spb := ðpbv1alpha1.BeaconStateCapella{ Fork: ðpbv1alpha1.Fork{ - CurrentVersion: params.BeaconConfig().CapellaForkVersion, - PreviousVersion: params.BeaconConfig().BellatrixForkVersion, + CurrentVersion: params.BeaconConfig().GenesisForkVersion, + PreviousVersion: params.BeaconConfig().GenesisForkVersion, Epoch: params.BeaconConfig().CapellaForkEpoch, }, } diff --git a/testing/util/capella_block.go b/testing/util/capella_block.go index e8fdfe7d08f2..90365c06b516 100644 --- a/testing/util/capella_block.go +++ b/testing/util/capella_block.go @@ -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 ðpb.SignedBLSToExecutionChange{ Message: message, Signature: signature,