Compare commits

..

22 Commits

Author SHA1 Message Date
Zahoor Mohamed
c2beb647dd fixed proto generation 2021-11-30 12:45:06 +05:30
Zahoor Mohamed
35711cac8a proto debug commit 2021-11-30 11:28:54 +05:30
Zahoor Mohamed
9238e72a91 add growth command 2021-11-17 12:07:09 +05:30
terence tsao
e3246922eb Add merge state type definitions (#9908) 2021-11-16 08:36:13 -08:00
Nishant Das
5962363847 Add in Deposit Map To Cache (#9885)
* add in map + tests

* tes

* raul's review

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-11-16 02:07:42 +00:00
Potuz
5e8cf9cd28 Monitor exits (#9899)
* Validator monitor process slashings

* Preston's comment

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>

* add test for tracked index

* Prestons requested changes

* Process voluntary exits in validator monitor

* Address Reviewers' comments

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-11-15 19:45:18 +00:00
Raul Jordan
b5ca09bce6 Add Network Flags to Slashing Protection Export Command (#9907) 2021-11-15 19:21:54 +00:00
terence tsao
720ee3f2a4 Add merge state protobuf (#9888)
* Add beacon state protobuf

* Update proto/prysm/v1alpha1/beacon_state.proto

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update proto/prysm/v1alpha1/beacon_state.proto

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Regenerate pbs

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-15 18:53:43 +00:00
Potuz
3d139d35f6 Validator monitor process slashings (#9898)
* Validator monitor process slashings

* Preston's comment

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>

* add test for tracked index

* Prestons requested changes

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
2021-11-15 17:39:55 +00:00
terence tsao
ea38969af2 Register start-up state when interop mode (#9900)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-15 16:32:54 +00:00
terence tsao
f753ce81cc Add merge block protobuf (#9887)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-15 15:42:18 +00:00
Nishant Das
9d678b0c47 Clean Up Methods In Prysm (#9903)
* clean up

* go simple
2021-11-15 10:13:52 -05:00
Nishant Das
4a4a7e97df handle canceled contexts (#9893)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-11-13 16:03:27 +08:00
Nishant Das
652b1617ed Use Next Slot Cache In More Places (#9884)
* add changes

* terence's review

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-11-12 23:46:06 +00:00
Nishant Das
42edc4f8dd Improve RNG Documentation (#9892)
* add comments

* comment

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-12 20:30:09 +00:00
terence tsao
70d5bc448f Add cli override setting for merge (#9891) 2021-11-12 12:01:14 -08:00
Preston Van Loon
d1159308c8 Update security.txt (#9896)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-12 15:55:45 +00:00
Nishant Das
e01298bd08 Remove Superflous Errors From Parameter Registration (#9894) 2021-11-12 15:28:21 +00:00
terence tsao
2bcb62db28 Remove unused import (#9890) 2021-11-11 22:54:48 +00:00
terence tsao
672fb72a7f Update spec tests to v1.1.5 (#9875)
* Update spec tests to v1.1.5

* Ignore `TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH`

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-10 02:41:16 +00:00
terence tsao
7fbd5b06da time pkg: can upgrade to merge helper (#9879)
* Helper: can upgrade to merge

* Typo
2021-11-09 18:36:50 +00:00
Raul Jordan
0fb91437fc Group Slashing Protection History Packages Idiomatically (#9873)
* rename

* gaz

* gaz

* Gaz

* rename

* edit

* gaz

* gaz

* build

* fix

* build

* fix up

* fix

* gaz

* cli import export

* gaz

* flag

* rev

* comm

* package renames

* radek
2021-11-09 16:49:28 +00:00
131 changed files with 4252 additions and 2020 deletions

View File

@@ -5,21 +5,22 @@ Contact: mailto:security@prysmaticlabs.com
Encryption: openpgp4fpr:0AE0051D647BA3C1A917AF4072E33E4DF1A5036E
Encryption: openpgp4fpr:CD08DE68C60B82D3EE2A3F7D95452A701810FEDB
Encryption: openpgp4fpr:317D6E91058F8F3C2303BA7756313E44581297A6
Encryption: openpgp4fpr:79C59A585E3FD3AFFA00F5C22940A6479DA7C9EC
Preferred-Languages: en
Canonical: https://github.com/prysmaticlabs/prysm/tree/master/.well-known/security.txt
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEECuAFHWR7o8GpF69AcuM+TfGlA24FAl++klgACgkQcuM+TfGl
A27rQw/6A29p1W20J0v+h218p8XWLSUpTIGLnZTxw6KqdyVXMzlsQK0YG4G2s2AB
0LKh7Ae/Di5E0U+Z4AjUW5nc5eaCxK36GMscH9Ah0rgJwNYxEJw7/2o8ZqVT/Ip2
+56rFihRqxFZfaCNKFVuZFaL9jKewV9FKYP38ID6/SnTcrOHiu2AoAlyZGmB03p+
iT57SPRHatygeY4xb/gwcfREFWEv+VHGyBTv8A+6ABZDxyurboCFMERHzFICrbmk
8UdHxxlWZDnHAbAUyAwpERC5znx6IHXQJwF8TMtu6XY6a6axT2XBOyJDF9/mZOz+
kdkz6loX5uxaQBGLtTv6Kqf1yUGANOZ16VhHvWwL209LmHmigIVQ+qSM6c79PsW/
vrsqdz3GBsiMC5Fq2vYgnbgzpfE8Atjn0y7E+j4R7IvwOAE/Ro/b++nqnc4YqhME
P/yTcfGftaCrdSNnQCXeoV9JxpFM5Xy8KV3eexvNKbcgA/9DtgxL5i+s5ZJkUT9A
+qJvoRrRyIym32ghkHgtFJKB3PLCdobeoOVRk6EnMo9zKSiSK2rZEJW8Ccbo515D
W9qUOn3GF7lNVuUFAU/YKEdmDp/AVaViZ7vH+8aq0LC0HBkZ8XlzWnWoArS8sMhw
fX0R9g/HMgrwNte/d0mwim5lJ2Plgv60Bh4grJqwZJeWbU0zi1U=
=uW+X
iQIzBAEBCgAdFiEECuAFHWR7o8GpF69AcuM+TfGlA24FAmGOfiYACgkQcuM+TfGl
A24YwRAAiQk3w6yzqSEggrOlNoNn04iu/rWZdn5ihkQgzACXy8XH2D1gdKLChE/X
7e5bUtgE2aCuHryQjwoKxqZakviBJFstVmHgF64rXv2zKhpqA30Mj4fI+T3zn8I+
+FpFV0TTsxNLDx+AcR1eQ1nSayO7ImUDIfOQNDDnSZZy42Bc+F+QIGKB3aH/8bpG
kT+bDTZrXvX+TE1gZTbAtZG8sH8g/zadoWEHIhfXUuYb0kTz+DRzAxoqU4j4Z4ee
1zSfFAgfJwxJP4kWD7s4xkE1sBbCgGBeD6cW/C2lbcfIei+XSizLpHW3jD9dNqh4
fLkmEspSa/LV/iXFq8nFzu/GLww4q+sQZDzzDKZyws54CrATinRitZMhzoIL0bTn
yFZVOGHosFAMEVZ36dl1Aw2+B2W6tr2CVr9c5zfV+kup5/KZH1EmT5nYY/zFwfg2
jYCFB5wmYeiyWZvuprgJXRArgVZLZaJxwWazlPVk4i/4vPvRgvfHqOwHCBe8DXy0
VHPhpewwb/ECYek1KoaNQflgR8iH2GMHkC5RjhGDAt1S0AQDtite5m4ZYt1kvO9E
k/znkv89dduhL9CKDvZvnI+DICwsTrf//4KJ8PM/qaPAJa4GvtiUU/eS/jKBivtv
OP5dZQtX6KPc9ewqqZgn622uHSezoBidgeTkdZsJ6tw2eIu0lsY=
=V7L0
-----END PGP SIGNATURE-----

View File

@@ -225,7 +225,7 @@ filegroup(
url = "https://github.com/eth2-clients/slashing-protection-interchange-tests/archive/b8413ca42dc92308019d0d4db52c87e9e125c4e9.tar.gz",
)
consensus_spec_version = "v1.1.3"
consensus_spec_version = "v1.1.5"
bls_test_version = "v0.1.1"
@@ -241,7 +241,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "e572f8c57e2dbbaeee056a600dc9d08396010dd5134a3a95e43c540470acf6f5",
sha256 = "a7d7173d953494c0dfde432c9fc064c25d46d666b024749b3474ae0cdfc50050",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
)
@@ -257,7 +257,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "7e2f62eaae9fd541690cc61d252556d0c5deb585ca1873aacbeb5b02d06f1362",
sha256 = "f86872061588c0197516b23025d39e9365b4716c112218a618739dc0d6f4666a",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
)
@@ -273,7 +273,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "05cbb89810c8acd6c57c4773ddfd167305cd4539960e9b4d7b69e1a988b35ad2",
sha256 = "7a06975360fd37fbb4694d0e06abb78d2a0835146c1d9b26d33569edff8b98f0",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
)
@@ -288,7 +288,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "0cef67b08448f7eb43bf66c464451c9e7a4852df8ef90555cca6d440e3436882",
sha256 = "87d8089200163340484d61212fbdffbb5d9d03e1244622761dcb91e641a65761",
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
)

View File

@@ -5,7 +5,6 @@
package depositcache
import (
"bytes"
"context"
"encoding/hex"
"math/big"
@@ -54,6 +53,7 @@ type DepositCache struct {
pendingDeposits []*dbpb.DepositContainer
deposits []*dbpb.DepositContainer
finalizedDeposits *FinalizedDeposits
depositsByKey map[[48]byte][]*dbpb.DepositContainer
depositsLock sync.RWMutex
}
@@ -69,6 +69,7 @@ func New() (*DepositCache, error) {
return &DepositCache{
pendingDeposits: []*dbpb.DepositContainer{},
deposits: []*dbpb.DepositContainer{},
depositsByKey: map[[48]byte][]*ethpb.DepositContainer{},
finalizedDeposits: &FinalizedDeposits{Deposits: finalizedDepositsTrie, MerkleTrieIndex: -1},
}, nil
}
@@ -95,10 +96,15 @@ func (dc *DepositCache) InsertDeposit(ctx context.Context, d *ethpb.Deposit, blo
}
// Keep the slice sorted on insertion in order to avoid costly sorting on retrieval.
heightIdx := sort.Search(len(dc.deposits), func(i int) bool { return dc.deposits[i].Index >= index })
depCtr := &dbpb.DepositContainer{Deposit: d, Eth1BlockHeight: blockNum, DepositRoot: depositRoot[:], Index: index}
newDeposits := append(
[]*dbpb.DepositContainer{{Deposit: d, Eth1BlockHeight: blockNum, DepositRoot: depositRoot[:], Index: index}},
[]*dbpb.DepositContainer{depCtr},
dc.deposits[heightIdx:]...)
dc.deposits = append(dc.deposits[:heightIdx], newDeposits...)
// Append the deposit to our map, in the event no deposits
// exist for the pubkey , it is simply added to the map.
pubkey := bytesutil.ToBytes48(d.Data.PublicKey)
dc.depositsByKey[pubkey] = append(dc.depositsByKey[pubkey], depCtr)
historicalDepositsCount.Inc()
return nil
}
@@ -112,6 +118,13 @@ func (dc *DepositCache) InsertDepositContainers(ctx context.Context, ctrs []*dbp
sort.SliceStable(ctrs, func(i int, j int) bool { return ctrs[i].Index < ctrs[j].Index })
dc.deposits = ctrs
for _, c := range ctrs {
// Use a new value, as the reference
// of c changes in the next iteration.
newPtr := c
pKey := bytesutil.ToBytes48(newPtr.Deposit.Data.PublicKey)
dc.depositsByKey[pKey] = append(dc.depositsByKey[pKey], newPtr)
}
historicalDepositsCount.Add(float64(len(ctrs)))
}
@@ -202,13 +215,15 @@ func (dc *DepositCache) DepositByPubkey(ctx context.Context, pubKey []byte) (*et
var deposit *ethpb.Deposit
var blockNum *big.Int
for _, ctnr := range dc.deposits {
if bytes.Equal(ctnr.Deposit.Data.PublicKey, pubKey) {
deposit = ctnr.Deposit
blockNum = big.NewInt(int64(ctnr.Eth1BlockHeight))
break
}
deps, ok := dc.depositsByKey[bytesutil.ToBytes48(pubKey)]
if !ok || len(deps) == 0 {
return deposit, blockNum
}
// We always return the first deposit if a particular
// validator key has multiple deposits assigned to
// it.
deposit = deps[0].Deposit
blockNum = big.NewInt(int64(deps[0].Eth1BlockHeight))
return deposit, blockNum
}

View File

@@ -44,31 +44,31 @@ func TestInsertDeposit_MaintainsSortedOrderByIndex(t *testing.T) {
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{},
deposit: &ethpb.Deposit{Data: &dbpb.Deposit_Data{PublicKey: []byte{'A'}}},
index: 0,
expectedErr: "",
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
deposit: &ethpb.Deposit{Data: &dbpb.Deposit_Data{PublicKey: []byte{'B'}}},
index: 3,
expectedErr: "wanted deposit with index 1 to be inserted but received 3",
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
deposit: &ethpb.Deposit{Data: &dbpb.Deposit_Data{PublicKey: []byte{'C'}}},
index: 1,
expectedErr: "",
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
deposit: &ethpb.Deposit{Data: &dbpb.Deposit_Data{PublicKey: []byte{'D'}}},
index: 4,
expectedErr: "wanted deposit with index 2 to be inserted but received 4",
},
{
blkNum: 0,
deposit: &ethpb.Deposit{},
deposit: &ethpb.Deposit{Data: &dbpb.Deposit_Data{PublicKey: []byte{'E'}}},
index: 2,
expectedErr: "",
},
@@ -316,8 +316,7 @@ func TestDepositsNumberAndRootAtHeight(t *testing.T) {
func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.deposits = []*dbpb.DepositContainer{
ctrs := []*dbpb.DepositContainer{
{
Eth1BlockHeight: 9,
Deposit: &ethpb.Deposit{
@@ -359,6 +358,7 @@ func TestDepositByPubkey_ReturnsFirstMatchingDeposit(t *testing.T) {
},
},
}
dc.InsertDepositContainers(context.Background(), ctrs)
pk1 := bytesutil.PadTo([]byte("pk1"), 48)
dep, blkNum := dc.DepositByPubkey(context.Background(), pk1)
@@ -626,24 +626,28 @@ func TestPruneProofs_Ok(t *testing.T) {
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 0,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk0"), 48)}},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 1,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk1"), 48)}},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 2,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk2"), 48)}},
index: 2,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 3,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk3"), 48)}},
index: 3,
},
}
@@ -669,24 +673,26 @@ func TestPruneProofs_SomeAlreadyPruned(t *testing.T) {
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: nil},
index: 0,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: nil, Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte("pk0"), 48)}},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: nil, Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte("pk1"), 48)}}, index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: nil},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
deposit: &ethpb.Deposit{Proof: makeDepositProof(), Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk2"), 48)}},
index: 2,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 3,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk3"), 48)}},
index: 3,
},
}
@@ -709,24 +715,28 @@ func TestPruneProofs_PruneAllWhenDepositIndexTooBig(t *testing.T) {
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 0,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk0"), 48)}},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 1,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk1"), 48)}},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 2,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk2"), 48)}},
index: 2,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 3,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk3"), 48)}},
index: 3,
},
}
@@ -752,24 +762,28 @@ func TestPruneProofs_CorrectlyHandleLastIndex(t *testing.T) {
index int64
}{
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 0,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk0"), 48)}},
index: 0,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 1,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk1"), 48)}},
index: 1,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 2,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk2"), 48)}},
index: 2,
},
{
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof()},
index: 3,
blkNum: 0,
deposit: &ethpb.Deposit{Proof: makeDepositProof(),
Data: &ethpb.Deposit_Data{PublicKey: bytesutil.PadTo([]byte("pk3"), 48)}},
index: 3,
},
}
@@ -785,6 +799,36 @@ func TestPruneProofs_CorrectlyHandleLastIndex(t *testing.T) {
assert.DeepEqual(t, [][]byte(nil), dc.deposits[3].Deposit.Proof)
}
func TestDepositMap_WorksCorrectly(t *testing.T) {
dc, err := New()
require.NoError(t, err)
pk0 := bytesutil.PadTo([]byte("pk0"), 48)
dep, _ := dc.DepositByPubkey(context.Background(), pk0)
var nilDep *ethpb.Deposit
assert.DeepEqual(t, nilDep, dep)
dep = &ethpb.Deposit{Proof: makeDepositProof(), Data: &ethpb.Deposit_Data{PublicKey: pk0, Amount: 1000}}
assert.NoError(t, dc.InsertDeposit(context.Background(), dep, 1000, 0, [32]byte{}))
dep, _ = dc.DepositByPubkey(context.Background(), pk0)
assert.NotEqual(t, nilDep, dep)
assert.Equal(t, uint64(1000), dep.Data.Amount)
dep = &ethpb.Deposit{Proof: makeDepositProof(), Data: &ethpb.Deposit_Data{PublicKey: pk0, Amount: 10000}}
assert.NoError(t, dc.InsertDeposit(context.Background(), dep, 1000, 1, [32]byte{}))
// Make sure we have the same deposit returned over here.
dep, _ = dc.DepositByPubkey(context.Background(), pk0)
assert.NotEqual(t, nilDep, dep)
assert.Equal(t, uint64(1000), dep.Data.Amount)
// Make sure another key doesn't work.
pk1 := bytesutil.PadTo([]byte("pk1"), 48)
dep, _ = dc.DepositByPubkey(context.Background(), pk1)
assert.DeepEqual(t, nilDep, dep)
}
func makeDepositProof() [][]byte {
proof := make([][]byte, int(params.BeaconConfig().DepositContractTreeDepth)+1)
for i := range proof {

View File

@@ -120,26 +120,22 @@ func (c *SkipSlotCache) MarkInProgress(r [32]byte) error {
// MarkNotInProgress will release the lock on a given request. This should be
// called after put.
func (c *SkipSlotCache) MarkNotInProgress(r [32]byte) error {
func (c *SkipSlotCache) MarkNotInProgress(r [32]byte) {
if c.disabled {
return nil
return
}
c.lock.Lock()
defer c.lock.Unlock()
delete(c.inProgress, r)
return nil
}
// Put the response in the cache.
func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state state.BeaconState) error {
func (c *SkipSlotCache) Put(_ context.Context, r [32]byte, state state.BeaconState) {
if c.disabled {
return nil
return
}
// Copy state so cached value is not mutated.
c.cache.Add(r, state.Copy())
return nil
}

View File

@@ -28,8 +28,8 @@ func TestSkipSlotCache_RoundTrip(t *testing.T) {
})
require.NoError(t, err)
require.NoError(t, c.Put(ctx, r, s))
require.NoError(t, c.MarkNotInProgress(r))
c.Put(ctx, r, s)
c.MarkNotInProgress(r)
res, err := c.Get(ctx, r)
require.NoError(t, err)

View File

@@ -62,7 +62,7 @@ func ProcessAttesterSlashing(
if err := VerifyAttesterSlashing(ctx, beaconState, slashing); err != nil {
return nil, errors.Wrap(err, "could not verify attester slashing")
}
slashableIndices := slashableAttesterIndices(slashing)
slashableIndices := SlashableAttesterIndices(slashing)
sort.SliceStable(slashableIndices, func(i, j int) bool {
return slashableIndices[i] < slashableIndices[j]
})
@@ -152,7 +152,8 @@ func IsSlashableAttestationData(data1, data2 *ethpb.AttestationData) bool {
return isDoubleVote || isSurroundVote
}
func slashableAttesterIndices(slashing *ethpb.AttesterSlashing) []uint64 {
// SlashableAttesterIndices returns the intersection of attester indices from both attestations in this slashing.
func SlashableAttesterIndices(slashing *ethpb.AttesterSlashing) []uint64 {
if slashing == nil || slashing.Attestation_1 == nil || slashing.Attestation_2 == nil {
return nil
}

View File

@@ -245,7 +245,7 @@ func TestFuzzslashableAttesterIndices_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(attesterSlashing)
slashableAttesterIndices(attesterSlashing)
SlashableAttesterIndices(attesterSlashing)
}
}

View File

@@ -199,7 +199,7 @@ func CommitteeAssignments(
// Each slot in an epoch has a different set of committees. This value is derived from the
// active validator set, which does not change.
numCommitteesPerSlot := SlotCommitteeCount(uint64(len(activeValidatorIndices)))
validatorIndexToCommittee := make(map[types.ValidatorIndex]*CommitteeAssignmentContainer, params.BeaconConfig().SlotsPerEpoch.Mul(numCommitteesPerSlot))
validatorIndexToCommittee := make(map[types.ValidatorIndex]*CommitteeAssignmentContainer, len(activeValidatorIndices))
// Compute all committees for all slots.
for i := types.Slot(0); i < params.BeaconConfig().SlotsPerEpoch; i++ {

View File

@@ -2,9 +2,9 @@ package signing
import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/eth2-types"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
// Domain returns the domain version for BLS private key to sign and verify.

View File

@@ -3,9 +3,9 @@ package signing
import (
"testing"
"github.com/prysmaticlabs/eth2-types"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
)

View File

@@ -60,6 +60,16 @@ func CanUpgradeToAltair(slot types.Slot) bool {
return epochStart && altairEpoch
}
// CanUpgradeToMerge returns true if the input `slot` can upgrade to Merge fork.
//
// Spec code:
// If state.slot % SLOTS_PER_EPOCH == 0 and compute_epoch_at_slot(state.slot) == MERGE_FORK_EPOCH
func CanUpgradeToMerge(slot types.Slot) bool {
epochStart := slots.IsEpochStart(slot)
mergeEpoch := slots.ToEpoch(slot) == params.BeaconConfig().MergeForkEpoch
return epochStart && mergeEpoch
}
// CanProcessEpoch checks the eligibility to process epoch.
// The epoch can be processed at the end of the last slot of every epoch.
//

View File

@@ -114,6 +114,40 @@ func TestCanUpgradeToAltair(t *testing.T) {
}
}
func TestCanUpgradeToMerge(t *testing.T) {
bc := params.BeaconConfig()
bc.MergeForkEpoch = 5
params.OverrideBeaconConfig(bc)
tests := []struct {
name string
slot types.Slot
want bool
}{
{
name: "not epoch start",
slot: 1,
want: false,
},
{
name: "not merge epoch",
slot: params.BeaconConfig().SlotsPerEpoch,
want: false,
},
{
name: "merge epoch",
slot: types.Slot(params.BeaconConfig().MergeForkEpoch) * params.BeaconConfig().SlotsPerEpoch,
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := CanUpgradeToMerge(tt.slot); got != tt.want {
t.Errorf("CanUpgradeToMerge() = %v, want %v", got, tt.want)
}
})
}
}
func TestCanProcessEpoch_TrueOnEpochsLastSlot(t *testing.T) {
tests := []struct {
slot types.Slot

View File

@@ -214,10 +214,7 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
return nil, err
}
defer func() {
if err := SkipSlotCache.MarkNotInProgress(key); err != nil {
tracing.AnnotateError(span, err)
log.WithError(err).Error("Failed to mark skip slot no longer in progress")
}
SkipSlotCache.MarkNotInProgress(key)
}()
for state.Slot() < slot {
@@ -225,7 +222,7 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
tracing.AnnotateError(span, ctx.Err())
// Cache last best value.
if highestSlot < state.Slot() {
if err := SkipSlotCache.Put(ctx, key, state); err != nil {
if SkipSlotCache.Put(ctx, key, state); err != nil {
log.WithError(err).Error("Failed to put skip slot cache value")
}
}
@@ -269,10 +266,7 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
}
if highestSlot < state.Slot() {
if err := SkipSlotCache.Put(ctx, key, state); err != nil {
log.WithError(err).Error("Failed to put skip slot cache value")
tracing.AnnotateError(span, err)
}
SkipSlotCache.Put(ctx, key, state)
}
return state, nil

View File

@@ -39,14 +39,6 @@ type ReadOnlyDatabase interface {
StateSummary(ctx context.Context, blockRoot [32]byte) (*ethpb.StateSummary, error)
HasStateSummary(ctx context.Context, blockRoot [32]byte) bool
HighestSlotStatesBelow(ctx context.Context, slot types.Slot) ([]state.ReadOnlyBeaconState, error)
// Slashing operations.
ProposerSlashing(ctx context.Context, slashingRoot [32]byte) (*eth.ProposerSlashing, error)
AttesterSlashing(ctx context.Context, slashingRoot [32]byte) (*eth.AttesterSlashing, error)
HasProposerSlashing(ctx context.Context, slashingRoot [32]byte) bool
HasAttesterSlashing(ctx context.Context, slashingRoot [32]byte) bool
// Block operations.
VoluntaryExit(ctx context.Context, exitRoot [32]byte) (*eth.VoluntaryExit, error)
HasVoluntaryExit(ctx context.Context, exitRoot [32]byte) bool
// Checkpoint operations.
JustifiedCheckpoint(ctx context.Context) (*eth.Checkpoint, error)
FinalizedCheckpoint(ctx context.Context) (*eth.Checkpoint, error)
@@ -75,11 +67,6 @@ type NoHeadAccessDatabase interface {
DeleteStates(ctx context.Context, blockRoots [][32]byte) error
SaveStateSummary(ctx context.Context, summary *ethpb.StateSummary) error
SaveStateSummaries(ctx context.Context, summaries []*ethpb.StateSummary) error
// Slashing operations.
SaveProposerSlashing(ctx context.Context, slashing *eth.ProposerSlashing) error
SaveAttesterSlashing(ctx context.Context, slashing *eth.AttesterSlashing) error
// Block operations.
SaveVoluntaryExit(ctx context.Context, exit *eth.VoluntaryExit) error
// Checkpoint operations.
SaveJustifiedCheckpoint(ctx context.Context, checkpoint *eth.Checkpoint) error
SaveFinalizedCheckpoint(ctx context.Context, checkpoint *eth.Checkpoint) error

View File

@@ -14,14 +14,13 @@ go_library(
"genesis.go",
"kv.go",
"log.go",
"migrate.go",
"migration.go",
"migration_archived_index.go",
"migration_block_slot_index.go",
"migration_state_validators.go",
"operations.go",
"powchain.go",
"schema.go",
"slashings.go",
"state.go",
"state_summary.go",
"state_summary_cache.go",
@@ -42,6 +41,7 @@ go_library(
"//beacon-chain/state/genesis:go_default_library",
"//beacon-chain/state/v1:go_default_library",
"//beacon-chain/state/v2:go_default_library",
"//cmd:go_default_library",
"//config/features:go_default_library",
"//config/params:go_default_library",
"//container/slice:go_default_library",
@@ -65,6 +65,7 @@ go_library(
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_prombbolt//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
"@io_etcd_go_bbolt//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
@@ -88,9 +89,7 @@ go_test(
"migration_archived_index_test.go",
"migration_block_slot_index_test.go",
"migration_state_validators_test.go",
"operations_test.go",
"powchain_test.go",
"slashings_test.go",
"state_summary_test.go",
"state_test.go",
"utils_test.go",

View File

@@ -150,11 +150,7 @@ func (s *Store) BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []bloc
err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(blocksBucket)
keys, err := blockRootsBySlot(ctx, tx, slot)
if err != nil {
return err
}
keys := blockRootsBySlot(ctx, tx, slot)
for i := 0; i < len(keys); i++ {
encoded := bkt.Get(keys[i])
blk, err := unmarshalBlock(ctx, encoded)
@@ -174,11 +170,7 @@ func (s *Store) BlockRootsBySlot(ctx context.Context, slot types.Slot) (bool, []
defer span.End()
blockRoots := make([][32]byte, 0)
err := s.db.View(func(tx *bolt.Tx) error {
keys, err := blockRootsBySlot(ctx, tx, slot)
if err != nil {
return err
}
keys := blockRootsBySlot(ctx, tx, slot)
for i := 0; i < len(keys); i++ {
blockRoots = append(blockRoots, bytesutil.ToBytes32(keys[i]))
}
@@ -519,7 +511,7 @@ func blockRootsBySlotRange(
}
// blockRootsBySlot retrieves the block roots by slot
func blockRootsBySlot(ctx context.Context, tx *bolt.Tx, slot types.Slot) ([][]byte, error) {
func blockRootsBySlot(ctx context.Context, tx *bolt.Tx, slot types.Slot) [][]byte {
ctx, span := trace.StartSpan(ctx, "BeaconDB.blockRootsBySlot")
defer span.End()
@@ -533,7 +525,7 @@ func blockRootsBySlot(ctx context.Context, tx *bolt.Tx, slot types.Slot) ([][]by
roots = append(roots, v[i:i+32])
}
}
return roots, nil
return roots
}
// createBlockIndicesFromBlock takes in a beacon block and returns

View File

@@ -0,0 +1,241 @@
package kv
import (
"bytes"
"fmt"
"path"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/snappy"
"github.com/prysmaticlabs/prysm/monitoring/progress"
v1alpha1 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
bolt "go.etcd.io/bbolt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/cmd"
"github.com/prysmaticlabs/prysm/io/file"
"github.com/urfave/cli/v2"
)
const batchSize = 10
var migrationStateKey = []byte("migration_state")
// MigrateStateDB normalizes the state object and saves space.
// it also saves space by not storing the already stored elements in the
// circular buffers.
func MigrateStateDB(cliCtx *cli.Context) error {
dataDir := cliCtx.String(cmd.DataDirFlag.Name)
dbDir := path.Join(dataDir, BeaconNodeDbDirName)
dbNameWithPath := path.Join(dbDir, DatabaseFileName)
// check if the database file exists
if !file.FileExists(dbNameWithPath) {
return errors.New(fmt.Sprintf("database file not found: %s", dbNameWithPath))
}
// open the raw database file. If the file is busy, then exit.
db, openErr := bolt.Open(dbNameWithPath, 0600, &bolt.Options{Timeout: 1 * time.Second})
if openErr != nil {
return errors.New(fmt.Sprintf("could not open db: , %v", openErr))
}
yes, valErr := isValidatorEntriesAlreadyMigrated(db)
if valErr != nil {
return errors.New(fmt.Sprintf("could not check if entries migrated : , %v", valErr))
}
if yes {
migrateWithValidatorEntries(db)
} else {
migrateOnlyTheValidatorEntryHashes(db)
}
log.Info("migration completed successfully")
return nil
}
func isValidatorEntriesAlreadyMigrated(db *bolt.DB) (bool, error) {
// if the flag is not enabled, but the migration is over, then
// follow the new code path as if the flag is enabled.
returnFlag := false
if err := db.View(func(tx *bolt.Tx) error {
mb := tx.Bucket(migrationsBucket)
b := mb.Get(migrationStateValidatorsKey)
returnFlag = bytes.Equal(b, migrationCompleted)
return nil
}); err != nil {
return returnFlag, err
}
return returnFlag, nil
}
func migrateWithValidatorEntries(db *bolt.DB) error {
// create the new buckets
// - stateValidatorsBucket
// - stateValidatorsHashesBucket
if err := createNewBuckets(db, stateValidatorsBucket, stateValidatorHashesBucket); err != nil {
return err
}
// get the state bucket row count.
// this is used to show the progress bar.
keys, err := getStateBucketKeys(db)
if err != nil{
return err
}
// prepare the progress bar with the total count of the keys to migrate
bar := progress.InitializeProgressBar(len(keys), "Migrating state bucket to new schema.")
// for each state, do in batches
// - store the unique validator entries in stateValidatorsBucket
// - get the ID for the validator entrypoint
// compress all the validator entry IDs and store in the "validators" field in state
batchNo := 0
for batchIndex := 0; batchIndex < len(keys); batchIndex += batchSize {
if err := db.Update(func(tx *bolt.Tx) error {
//create the source and destination buckets
stateBkt := tx.Bucket(stateBucket);
if stateBkt == nil {
return errors.New("could not open \"state\" bucket")
}
valEntryBkt := tx.Bucket(stateValidatorsBucket)
if valEntryBkt == nil {
return errors.New("could not open \"state-validators\" bucket")
}
valHashBkt := tx.Bucket(stateValidatorHashesBucket)
if valHashBkt == nil {
return errors.New("could not open \"state-validator-hashes\" bucket")
}
// migrate the key values for this batch
cursor := stateBkt.Cursor()
count := 0
index := batchIndex
for _, v := cursor.Seek(keys[index]); count < batchSize && index < len(keys); _, v = cursor.Next() {
enc, err := snappy.Decode(nil, v)
if err != nil {
return err
}
protoState := &v1alpha1.BeaconState{}
if err := protoState.UnmarshalSSZ(enc); err != nil {
return errors.Wrap(err, "failed to unmarshal encoding for phase0")
}
// no validators in state to migrate
if len(protoState.Validators) == 0 {
return fmt.Errorf("no validator entries in state key 0x%s", hexutil.Encode(keys[index]))
}
validatorHashes, err := insertValidators(ctx, protoState.Validators, valEntryBkt)
if err != nil {
return err
}
validaorIndexs, err := insertValidatorHashes(ctx, validatorHashes)
if err != nil {
return err
}
// add the validator entry indexes for a given block root.
compValidatorIndexs := snappy.Encode(nil, validaorIndexs)
// zero the validator entries in BeaconState object .
protoState.Validators = make([]*v1alpha1.Validator, 0)
rawObj, err := protoState.MarshalSSZ()
if err != nil {
return err
}
stateBytes := snappy.Encode(nil, append(altairKey, rawObj...))
if stateErr := stateBkt.Put(keys[index], stateBytes); stateErr != nil {
return stateErr
}
// add the entry indexs in validator field of BeaconState object .
protoState.Validators = compValidatorIndexs
rawObj, err := protoState.MarshalSSZ()
if err != nil {
return err
}
stateBytes, err := encode(ctx, compValidatorIndexs)
if err != nil {
return err
}
if stateErr := stateBkt.Put(keys[index], stateBytes); stateErr != nil {
return stateErr
}
count++
index++
if barErr := bar.Add(1); barErr != nil {
return barErr
}
}
return nil
}); err != nil {
return err
}
batchNo++
}
// set the migration entry to done
if err := db.Update(func(tx *bolt.Tx) error {
mb := tx.Bucket(migrationsBucket)
if mb == nil {
return nil
}
return mb.Put(migrationStateKey, migrationCompleted)
}); err != nil {
return err
}
log.Infof("migration done for bucket %s.", stateBucket)
return nil
}
func migrateOnlyTheValidatorEntryHashes(db *bolt.DB) {
}
func createNewBuckets(db *bolt.DB, buckets ...[]byte) error {
if err := db.Update(func(tx *bolt.Tx) error {
for _, bucket := range buckets {
if _, err := tx.CreateBucket(bucket); err != nil {
return err
}
}
return nil
}); err != nil {
return err
}
return nil
}
func getStateBucketKeys(db *bolt.DB) ([][]byte, error){
var keys [][]byte
if err := db.Update(func(tx *bolt.Tx) error {
stateBkt := tx.Bucket(stateBucket)
if stateBkt == nil {
return nil
}
k, err := stateBucketKeys(stateBkt)
if err != nil {
return err
}
keys = k
return nil
}); err != nil {
return nil, err
}
return keys, nil
}

View File

@@ -1,78 +0,0 @@
package kv
import (
"context"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
bolt "go.etcd.io/bbolt"
"go.opencensus.io/trace"
)
// VoluntaryExit retrieval by signing root.
func (s *Store) VoluntaryExit(ctx context.Context, exitRoot [32]byte) (*ethpb.VoluntaryExit, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.VoluntaryExit")
defer span.End()
enc, err := s.voluntaryExitBytes(ctx, exitRoot)
if err != nil {
return nil, err
}
if len(enc) == 0 {
return nil, nil
}
exit := &ethpb.VoluntaryExit{}
if err := decode(ctx, enc, exit); err != nil {
return nil, err
}
return exit, nil
}
// HasVoluntaryExit verifies if a voluntary exit is stored in the db by its signing root.
func (s *Store) HasVoluntaryExit(ctx context.Context, exitRoot [32]byte) bool {
ctx, span := trace.StartSpan(ctx, "BeaconDB.HasVoluntaryExit")
defer span.End()
enc, err := s.voluntaryExitBytes(ctx, exitRoot)
if err != nil {
panic(err)
}
return len(enc) > 0
}
// SaveVoluntaryExit to the db by its signing root.
func (s *Store) SaveVoluntaryExit(ctx context.Context, exit *ethpb.VoluntaryExit) error {
ctx, span := trace.StartSpan(ctx, "BeaconDB.SaveVoluntaryExit")
defer span.End()
exitRoot, err := exit.HashTreeRoot()
if err != nil {
return err
}
enc, err := encode(ctx, exit)
if err != nil {
return err
}
return s.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(voluntaryExitsBucket)
return bucket.Put(exitRoot[:], enc)
})
}
func (s *Store) voluntaryExitBytes(ctx context.Context, exitRoot [32]byte) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.voluntaryExitBytes")
defer span.End()
var dst []byte
err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(voluntaryExitsBucket)
dst = bkt.Get(exitRoot[:])
return nil
})
return dst, err
}
// deleteVoluntaryExit clears a voluntary exit from the db by its signing root.
func (s *Store) deleteVoluntaryExit(ctx context.Context, exitRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "BeaconDB.deleteVoluntaryExit")
defer span.End()
return s.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(voluntaryExitsBucket)
return bucket.Delete(exitRoot[:])
})
}

View File

@@ -1,31 +0,0 @@
package kv
import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"google.golang.org/protobuf/proto"
)
func TestStore_VoluntaryExits_CRUD(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
exit := &ethpb.VoluntaryExit{
Epoch: 5,
}
exitRoot, err := exit.HashTreeRoot()
require.NoError(t, err)
retrieved, err := db.VoluntaryExit(ctx, exitRoot)
require.NoError(t, err)
assert.Equal(t, (*ethpb.VoluntaryExit)(nil), retrieved, "Expected nil voluntary exit")
require.NoError(t, db.SaveVoluntaryExit(ctx, exit))
assert.Equal(t, true, db.HasVoluntaryExit(ctx, exitRoot), "Expected voluntary exit to exist in the db")
retrieved, err = db.VoluntaryExit(ctx, exitRoot)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(exit, retrieved), "Wanted %v, received %v", exit, retrieved)
require.NoError(t, db.deleteVoluntaryExit(ctx, exitRoot))
assert.Equal(t, false, db.HasVoluntaryExit(ctx, exitRoot), "Expected voluntary exit to have been deleted from the db")
}

View File

@@ -35,6 +35,7 @@ var (
attestationTargetEpochIndicesBucket = []byte("attestation-target-epoch-indices")
finalizedBlockRootsIndexBucket = []byte("finalized-block-roots-index")
blockRootValidatorHashesBucket = []byte("block-root-validator-hashes")
stateValidatorHashesBucket = []byte("state-validator-hashes")
// Specific item keys.
headBlockRootKey = []byte("head-root")

View File

@@ -1,147 +0,0 @@
package kv
import (
"context"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
bolt "go.etcd.io/bbolt"
"go.opencensus.io/trace"
)
// ProposerSlashing retrieval by slashing root.
func (s *Store) ProposerSlashing(ctx context.Context, slashingRoot [32]byte) (*ethpb.ProposerSlashing, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.ProposerSlashing")
defer span.End()
enc, err := s.proposerSlashingBytes(ctx, slashingRoot)
if err != nil {
return nil, err
}
if len(enc) == 0 {
return nil, nil
}
proposerSlashing := &ethpb.ProposerSlashing{}
if err := decode(ctx, enc, proposerSlashing); err != nil {
return nil, err
}
return proposerSlashing, nil
}
// HasProposerSlashing verifies if a slashing is stored in the db.
func (s *Store) HasProposerSlashing(ctx context.Context, slashingRoot [32]byte) bool {
ctx, span := trace.StartSpan(ctx, "BeaconDB.HasProposerSlashing")
defer span.End()
enc, err := s.proposerSlashingBytes(ctx, slashingRoot)
if err != nil {
panic(err)
}
return len(enc) > 0
}
// SaveProposerSlashing to the db by its hash tree root.
func (s *Store) SaveProposerSlashing(ctx context.Context, slashing *ethpb.ProposerSlashing) error {
ctx, span := trace.StartSpan(ctx, "BeaconDB.SaveProposerSlashing")
defer span.End()
slashingRoot, err := slashing.HashTreeRoot()
if err != nil {
return err
}
enc, err := encode(ctx, slashing)
if err != nil {
return err
}
return s.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(proposerSlashingsBucket)
return bucket.Put(slashingRoot[:], enc)
})
}
func (s *Store) proposerSlashingBytes(ctx context.Context, slashingRoot [32]byte) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.proposerSlashingBytes")
defer span.End()
var dst []byte
err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(proposerSlashingsBucket)
dst = bkt.Get(slashingRoot[:])
return nil
})
return dst, err
}
// deleteProposerSlashing clears a proposer slashing from the db by its hash tree root.
func (s *Store) deleteProposerSlashing(ctx context.Context, slashingRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "BeaconDB.deleteProposerSlashing")
defer span.End()
return s.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(proposerSlashingsBucket)
return bucket.Delete(slashingRoot[:])
})
}
// AttesterSlashing retrieval by hash tree root.
func (s *Store) AttesterSlashing(ctx context.Context, slashingRoot [32]byte) (*ethpb.AttesterSlashing, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.AttesterSlashing")
defer span.End()
enc, err := s.attesterSlashingBytes(ctx, slashingRoot)
if err != nil {
return nil, err
}
if len(enc) == 0 {
return nil, nil
}
attSlashing := &ethpb.AttesterSlashing{}
if err := decode(ctx, enc, attSlashing); err != nil {
return nil, err
}
return attSlashing, nil
}
// HasAttesterSlashing verifies if a slashing is stored in the db.
func (s *Store) HasAttesterSlashing(ctx context.Context, slashingRoot [32]byte) bool {
ctx, span := trace.StartSpan(ctx, "BeaconDB.HasAttesterSlashing")
defer span.End()
enc, err := s.attesterSlashingBytes(ctx, slashingRoot)
if err != nil {
panic(err)
}
return len(enc) > 0
}
// SaveAttesterSlashing to the db by its hash tree root.
func (s *Store) SaveAttesterSlashing(ctx context.Context, slashing *ethpb.AttesterSlashing) error {
ctx, span := trace.StartSpan(ctx, "BeaconDB.SaveAttesterSlashing")
defer span.End()
slashingRoot, err := slashing.HashTreeRoot()
if err != nil {
return err
}
enc, err := encode(ctx, slashing)
if err != nil {
return err
}
return s.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(attesterSlashingsBucket)
return bucket.Put(slashingRoot[:], enc)
})
}
func (s *Store) attesterSlashingBytes(ctx context.Context, slashingRoot [32]byte) ([]byte, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.attesterSlashingBytes")
defer span.End()
var dst []byte
err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(attesterSlashingsBucket)
dst = bkt.Get(slashingRoot[:])
return nil
})
return dst, err
}
// deleteAttesterSlashing clears an attester slashing from the db by its hash tree root.
func (s *Store) deleteAttesterSlashing(ctx context.Context, slashingRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "BeaconDB.deleteAttesterSlashing")
defer span.End()
return s.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(attesterSlashingsBucket)
return bucket.Delete(slashingRoot[:])
})
}

View File

@@ -1,67 +0,0 @@
package kv
import (
"context"
"testing"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
"google.golang.org/protobuf/proto"
)
func TestStore_ProposerSlashing_CRUD(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
prop := &ethpb.ProposerSlashing{
Header_1: util.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 5,
},
}),
Header_2: util.HydrateSignedBeaconHeader(&ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 5,
},
}),
}
slashingRoot, err := prop.HashTreeRoot()
require.NoError(t, err)
retrieved, err := db.ProposerSlashing(ctx, slashingRoot)
require.NoError(t, err)
assert.Equal(t, (*ethpb.ProposerSlashing)(nil), retrieved, "Expected nil proposer slashing")
require.NoError(t, db.SaveProposerSlashing(ctx, prop))
assert.Equal(t, true, db.HasProposerSlashing(ctx, slashingRoot), "Expected proposer slashing to exist in the db")
retrieved, err = db.ProposerSlashing(ctx, slashingRoot)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(prop, retrieved), "Wanted %v, received %v", prop, retrieved)
require.NoError(t, db.deleteProposerSlashing(ctx, slashingRoot))
assert.Equal(t, false, db.HasProposerSlashing(ctx, slashingRoot), "Expected proposer slashing to have been deleted from the db")
}
func TestStore_AttesterSlashing_CRUD(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
att := &ethpb.AttesterSlashing{
Attestation_1: util.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Slot: 5,
}}),
Attestation_2: util.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Slot: 7,
}})}
slashingRoot, err := att.HashTreeRoot()
require.NoError(t, err)
retrieved, err := db.AttesterSlashing(ctx, slashingRoot)
require.NoError(t, err)
assert.Equal(t, (*ethpb.AttesterSlashing)(nil), retrieved, "Expected nil attester slashing")
require.NoError(t, db.SaveAttesterSlashing(ctx, att))
assert.Equal(t, true, db.HasAttesterSlashing(ctx, slashingRoot), "Expected attester slashing to exist in the db")
retrieved, err = db.AttesterSlashing(ctx, slashingRoot)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(att, retrieved), "Wanted %v, received %v", att, retrieved)
require.NoError(t, db.deleteAttesterSlashing(ctx, slashingRoot))
assert.Equal(t, false, db.HasAttesterSlashing(ctx, slashingRoot), "Expected attester slashing to have been deleted from the db")
}

View File

@@ -0,0 +1,40 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"process_block.go",
"process_exit.go",
"service.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/monitor",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/core/blocks:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/block:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"process_block_test.go",
"process_exit_test.go",
"service_test.go",
],
embed = [":go_default_library"],
deps = [
"//config/params:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/wrapper:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
],
)

View File

@@ -0,0 +1,7 @@
/*
Package monitor defines a runtime service which receives
notifications triggered by events related to performance of tracked
validating keys. It then logs and emits metrics for a user to keep finely
detailed performance measures.
*/
package monitor

View File

@@ -0,0 +1,47 @@
package monitor
import (
"fmt"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
"github.com/sirupsen/logrus"
)
// processSlashings logs the event of one of our tracked validators was slashed
func (s *Service) processSlashings(blk block.BeaconBlock) {
for _, slashing := range blk.Body().ProposerSlashings() {
idx := slashing.Header_1.Header.ProposerIndex
if s.TrackedIndex(idx) {
log.WithFields(logrus.Fields{
"ProposerIndex": idx,
"Slot:": blk.Slot(),
"SlashingSlot": slashing.Header_1.Header.Slot,
"Root1": fmt.Sprintf("%#x", bytesutil.Trunc(slashing.Header_1.Header.BodyRoot)),
"Root2": fmt.Sprintf("%#x", bytesutil.Trunc(slashing.Header_2.Header.BodyRoot)),
}).Info("Proposer slashing was included")
}
}
for _, slashing := range blk.Body().AttesterSlashings() {
for _, idx := range blocks.SlashableAttesterIndices(slashing) {
if s.TrackedIndex(types.ValidatorIndex(idx)) {
log.WithFields(logrus.Fields{
"AttesterIndex": idx,
"Slot:": blk.Slot(),
"Slot1": slashing.Attestation_1.Data.Slot,
"Root1": fmt.Sprintf("%#x", bytesutil.Trunc(slashing.Attestation_1.Data.BeaconBlockRoot)),
"SourceEpoch1": slashing.Attestation_1.Data.Source.Epoch,
"TargetEpoch1": slashing.Attestation_1.Data.Target.Epoch,
"Slot2": slashing.Attestation_2.Data.Slot,
"Root2": fmt.Sprintf("%#x", bytesutil.Trunc(slashing.Attestation_2.Data.BeaconBlockRoot)),
"SourceEpoch2": slashing.Attestation_2.Data.Source.Epoch,
"TargetEpoch2": slashing.Attestation_2.Data.Target.Epoch,
}).Info("Attester slashing was included")
}
}
}
}

View File

@@ -0,0 +1,131 @@
package monitor
import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/config/params"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func TestProcessSlashings(t *testing.T) {
tests := []struct {
name string
block *ethpb.BeaconBlock
wantedErr string
}{
{
name: "Proposer slashing a tracked index",
block: &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 2,
Slot: params.BeaconConfig().SlotsPerEpoch + 1,
},
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 2,
Slot: 0,
},
},
},
},
},
},
wantedErr: "\"Proposer slashing was included\" ProposerIndex=2",
},
{
name: "Proposer slashing an untracked index",
block: &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 3,
Slot: params.BeaconConfig().SlotsPerEpoch + 4,
},
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
ProposerIndex: 3,
Slot: 0,
},
},
},
},
},
},
wantedErr: "",
},
{
name: "Attester slashing a tracked index",
block: &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: util.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1},
},
AttestingIndices: []uint64{1, 3, 4},
}),
Attestation_2: util.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
AttestingIndices: []uint64{1, 5, 6},
}),
},
},
},
},
wantedErr: "\"Attester slashing was included\" AttesterIndex=1",
},
{
name: "Attester slashing untracked index",
block: &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: util.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{
Source: &ethpb.Checkpoint{Epoch: 1},
},
AttestingIndices: []uint64{1, 3, 4},
}),
Attestation_2: util.HydrateIndexedAttestation(&ethpb.IndexedAttestation{
AttestingIndices: []uint64{3, 5, 6},
}),
},
},
},
},
wantedErr: "",
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
hook := logTest.NewGlobal()
s := &Service{
config: &ValidatorMonitorConfig{
TrackedValidators: map[types.ValidatorIndex]interface{}{
1: nil,
2: nil,
},
},
}
s.processSlashings(wrapper.WrappedPhase0BeaconBlock(tt.block))
if tt.wantedErr != "" {
require.LogsContain(t, hook, tt.wantedErr)
} else {
require.LogsDoNotContain(t, hook, "slashing")
}
})
}
}

View File

@@ -0,0 +1,31 @@
package monitor
import (
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
"github.com/sirupsen/logrus"
)
// processExitsFromBlock logs the event of one of our tracked validators' exit was
// included in a block
func (s *Service) processExitsFromBlock(blk block.BeaconBlock) {
for _, exit := range blk.Body().VoluntaryExits() {
idx := exit.Exit.ValidatorIndex
if s.TrackedIndex(idx) {
log.WithFields(logrus.Fields{
"ValidatorIndex": idx,
"Slot": blk.Slot(),
}).Info("Voluntary exit was included")
}
}
}
// processExit logs the event of one of our tracked validators' exit was processed
func (s *Service) processExit(exit *ethpb.SignedVoluntaryExit) {
idx := exit.Exit.ValidatorIndex
if s.TrackedIndex(idx) {
log.WithFields(logrus.Fields{
"ValidatorIndex": idx,
}).Info("Voluntary exit was processed")
}
}

View File

@@ -0,0 +1,126 @@
package monitor
import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/testing/require"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func TestProcessExitsFromBlockTrackedIndices(t *testing.T) {
hook := logTest.NewGlobal()
s := &Service{
config: &ValidatorMonitorConfig{
TrackedValidators: map[types.ValidatorIndex]interface{}{
1: nil,
2: nil,
},
},
}
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 3,
Epoch: 1,
},
},
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 2,
Epoch: 0,
},
},
}
block := &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
s.processExitsFromBlock(wrapper.WrappedPhase0BeaconBlock(block))
require.LogsContain(t, hook, "\"Voluntary exit was included\" Slot=0 ValidatorIndex=2")
}
func TestProcessExitsFromBlockUntrackedIndices(t *testing.T) {
hook := logTest.NewGlobal()
s := &Service{
config: &ValidatorMonitorConfig{
TrackedValidators: map[types.ValidatorIndex]interface{}{
1: nil,
2: nil,
},
},
}
exits := []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 3,
Epoch: 1,
},
},
{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 4,
Epoch: 0,
},
},
}
block := &ethpb.BeaconBlock{
Body: &ethpb.BeaconBlockBody{
VoluntaryExits: exits,
},
}
s.processExitsFromBlock(wrapper.WrappedPhase0BeaconBlock(block))
require.LogsDoNotContain(t, hook, "\"Voluntary exit was included\"")
}
func TestProcessExitP2PTrackedIndices(t *testing.T) {
hook := logTest.NewGlobal()
s := &Service{
config: &ValidatorMonitorConfig{
TrackedValidators: map[types.ValidatorIndex]interface{}{
1: nil,
2: nil,
},
},
}
exit := &ethpb.SignedVoluntaryExit{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 1,
Epoch: 1,
},
Signature: make([]byte, 96),
}
s.processExit(exit)
require.LogsContain(t, hook, "\"Voluntary exit was processed\" ValidatorIndex=1")
}
func TestProcessExitP2PUntrackedIndices(t *testing.T) {
hook := logTest.NewGlobal()
s := &Service{
config: &ValidatorMonitorConfig{
TrackedValidators: map[types.ValidatorIndex]interface{}{
1: nil,
2: nil,
},
},
}
exit := &ethpb.SignedVoluntaryExit{
Exit: &ethpb.VoluntaryExit{
ValidatorIndex: 3,
Epoch: 1,
},
}
s.processExit(exit)
require.LogsDoNotContain(t, hook, "\"Voluntary exit was processed\"")
}

View File

@@ -0,0 +1,30 @@
package monitor
import (
types "github.com/prysmaticlabs/eth2-types"
"github.com/sirupsen/logrus"
)
var (
log = logrus.WithField("prefix", "monitor")
)
// ValidatorMonitorConfig contains the list of validator indices that the
// monitor service tracks, as well as the event feed notifier that the
// monitor needs to subscribe.
type ValidatorMonitorConfig struct {
TrackedValidators map[types.ValidatorIndex]interface{}
}
// Service is the main structure that tracks validators and reports logs and
// metrics of their performances throughout their lifetime.
type Service struct {
config *ValidatorMonitorConfig
}
// TrackedIndex returns if the given validator index corresponds to one of the
// validators we follow
func (s *Service) TrackedIndex(idx types.ValidatorIndex) bool {
_, ok := s.config.TrackedValidators[idx]
return ok
}

View File

@@ -0,0 +1,21 @@
package monitor
import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/testing/require"
)
func TestTrackedIndex(t *testing.T) {
s := &Service{
config: &ValidatorMonitorConfig{
TrackedValidators: map[types.ValidatorIndex]interface{}{
1: nil,
2: nil,
},
},
}
require.Equal(t, s.TrackedIndex(types.ValidatorIndex(1)), true)
require.Equal(t, s.TrackedIndex(types.ValidatorIndex(3)), false)
}

View File

@@ -77,6 +77,7 @@ go_test(
"//config/params:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",

View File

@@ -1,6 +1,7 @@
package node
import (
"github.com/ethereum/go-ethereum/common"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/cmd"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
@@ -95,3 +96,26 @@ func configureInteropConfig(cliCtx *cli.Context) {
params.OverrideBeaconConfig(bCfg)
}
}
func configureExecutionSetting(cliCtx *cli.Context) {
if cliCtx.IsSet(flags.TerminalTotalDifficultyOverride.Name) {
c := params.BeaconConfig()
c.TerminalTotalDifficulty = cliCtx.Uint64(flags.TerminalTotalDifficultyOverride.Name)
params.OverrideBeaconConfig(c)
}
if cliCtx.IsSet(flags.TerminalBlockHashOverride.Name) {
c := params.BeaconConfig()
c.TerminalBlockHash = common.HexToHash(cliCtx.String(flags.TerminalBlockHashOverride.Name))
params.OverrideBeaconConfig(c)
}
if cliCtx.IsSet(flags.TerminalBlockHashActivationEpochOverride.Name) {
c := params.BeaconConfig()
c.TerminalBlockHashActivationEpoch = types.Epoch(cliCtx.Uint64(flags.TerminalBlockHashActivationEpochOverride.Name))
params.OverrideBeaconConfig(c)
}
if cliCtx.IsSet(flags.Coinbase.Name) {
c := params.BeaconConfig()
c.Coinbase = common.HexToAddress(cliCtx.String(flags.Coinbase.Name))
params.OverrideBeaconConfig(c)
}
}

View File

@@ -6,6 +6,7 @@ import (
"strconv"
"testing"
"github.com/ethereum/go-ethereum/common"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/cmd"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
@@ -70,6 +71,29 @@ func TestConfigureProofOfWork(t *testing.T) {
assert.Equal(t, "deposit-contract", params.BeaconConfig().DepositContractAddress)
}
func TestConfigureExecutionSetting(t *testing.T) {
params.SetupTestConfigCleanup(t)
app := cli.App{}
set := flag.NewFlagSet("test", 0)
set.Uint64(flags.TerminalTotalDifficultyOverride.Name, 0, "")
set.String(flags.TerminalBlockHashOverride.Name, "", "")
set.Uint64(flags.TerminalBlockHashActivationEpochOverride.Name, 0, "")
set.String(flags.Coinbase.Name, "", "")
require.NoError(t, set.Set(flags.TerminalTotalDifficultyOverride.Name, strconv.Itoa(100)))
require.NoError(t, set.Set(flags.TerminalBlockHashOverride.Name, "0xA"))
require.NoError(t, set.Set(flags.TerminalBlockHashActivationEpochOverride.Name, strconv.Itoa(200)))
require.NoError(t, set.Set(flags.Coinbase.Name, "0xB"))
cliCtx := cli.NewContext(&app, set, nil)
configureExecutionSetting(cliCtx)
assert.Equal(t, uint64(100), params.BeaconConfig().TerminalTotalDifficulty)
assert.Equal(t, common.HexToHash("0xA"), params.BeaconConfig().TerminalBlockHash)
assert.Equal(t, types.Epoch(200), params.BeaconConfig().TerminalBlockHashActivationEpoch)
assert.Equal(t, common.HexToAddress("0xB"), params.BeaconConfig().Coinbase)
}
func TestConfigureNetwork(t *testing.T) {
params.SetupTestConfigCleanup(t)

View File

@@ -854,6 +854,14 @@ func (b *BeaconNode) registerDeterminsticGenesisService() error {
GenesisPath: genesisStatePath,
})
// Register genesis state as start-up state when interop mode.
// The start-up state gets reused across services.
st, err := b.db.GenesisState(b.ctx)
if err != nil {
return err
}
b.finalizedStateAtStartUp = st
return b.services.RegisterService(svc)
}
return nil

View File

@@ -103,13 +103,13 @@ func (s *Service) topicScoreParams(topic string) (*pubsub.TopicScoreParams, erro
case strings.Contains(topic, GossipBlockMessage):
return defaultBlockTopicParams(), nil
case strings.Contains(topic, GossipAggregateAndProofMessage):
return defaultAggregateTopicParams(activeValidators)
return defaultAggregateTopicParams(activeValidators), nil
case strings.Contains(topic, GossipAttestationMessage):
return defaultAggregateSubnetTopicParams(activeValidators)
return defaultAggregateSubnetTopicParams(activeValidators), nil
case strings.Contains(topic, GossipSyncCommitteeMessage):
return defaultSyncSubnetTopicParams(activeValidators)
return defaultSyncSubnetTopicParams(activeValidators), nil
case strings.Contains(topic, GossipContributionAndProofMessage):
return defaultSyncContributionTopicParams()
return defaultSyncContributionTopicParams(), nil
case strings.Contains(topic, GossipExitMessage):
return defaultVoluntaryExitTopicParams(), nil
case strings.Contains(topic, GossipProposerSlashingMessage):
@@ -191,19 +191,19 @@ func defaultBlockTopicParams() *pubsub.TopicScoreParams {
}
}
func defaultAggregateTopicParams(activeValidators uint64) (*pubsub.TopicScoreParams, error) {
func defaultAggregateTopicParams(activeValidators uint64) *pubsub.TopicScoreParams {
// Determine the expected message rate for the particular gossip topic.
aggPerSlot := aggregatorsPerSlot(activeValidators)
firstMessageCap, err := decayLimit(scoreDecay(1*oneEpochDuration()), float64(aggPerSlot*2/gossipSubD))
if err != nil {
log.Warnf("skipping initializing topic scoring: %v", err)
return nil, nil
return nil
}
firstMessageWeight := maxFirstDeliveryScore / firstMessageCap
meshThreshold, err := decayThreshold(scoreDecay(1*oneEpochDuration()), float64(aggPerSlot)/dampeningFactor)
if err != nil {
log.Warnf("skipping initializing topic scoring: %v", err)
return nil, nil
return nil
}
meshWeight := -scoreByWeight(aggregateWeight, meshThreshold)
meshCap := 4 * meshThreshold
@@ -230,22 +230,22 @@ func defaultAggregateTopicParams(activeValidators uint64) (*pubsub.TopicScorePar
MeshFailurePenaltyDecay: scoreDecay(1 * oneEpochDuration()),
InvalidMessageDeliveriesWeight: -maxScore() / aggregateWeight,
InvalidMessageDeliveriesDecay: scoreDecay(invalidDecayPeriod),
}, nil
}
}
func defaultSyncContributionTopicParams() (*pubsub.TopicScoreParams, error) {
func defaultSyncContributionTopicParams() *pubsub.TopicScoreParams {
// Determine the expected message rate for the particular gossip topic.
aggPerSlot := params.BeaconConfig().SyncCommitteeSubnetCount * params.BeaconConfig().TargetAggregatorsPerSyncSubcommittee
firstMessageCap, err := decayLimit(scoreDecay(1*oneEpochDuration()), float64(aggPerSlot*2/gossipSubD))
if err != nil {
log.Warnf("skipping initializing topic scoring: %v", err)
return nil, nil
return nil
}
firstMessageWeight := maxFirstDeliveryScore / firstMessageCap
meshThreshold, err := decayThreshold(scoreDecay(1*oneEpochDuration()), float64(aggPerSlot)/dampeningFactor)
if err != nil {
log.Warnf("skipping initializing topic scoring: %v", err)
return nil, nil
return nil
}
meshWeight := -scoreByWeight(syncContributionWeight, meshThreshold)
meshCap := 4 * meshThreshold
@@ -272,23 +272,23 @@ func defaultSyncContributionTopicParams() (*pubsub.TopicScoreParams, error) {
MeshFailurePenaltyDecay: scoreDecay(1 * oneEpochDuration()),
InvalidMessageDeliveriesWeight: -maxScore() / syncContributionWeight,
InvalidMessageDeliveriesDecay: scoreDecay(invalidDecayPeriod),
}, nil
}
}
func defaultAggregateSubnetTopicParams(activeValidators uint64) (*pubsub.TopicScoreParams, error) {
func defaultAggregateSubnetTopicParams(activeValidators uint64) *pubsub.TopicScoreParams {
subnetCount := params.BeaconNetworkConfig().AttestationSubnetCount
// Get weight for each specific subnet.
topicWeight := attestationTotalWeight / float64(subnetCount)
subnetWeight := activeValidators / subnetCount
if subnetWeight == 0 {
log.Warn("Subnet weight is 0, skipping initializing topic scoring")
return nil, nil
return nil
}
// Determine the amount of validators expected in a subnet in a single slot.
numPerSlot := time.Duration(subnetWeight / uint64(params.BeaconConfig().SlotsPerEpoch))
if numPerSlot == 0 {
log.Warn("numPerSlot is 0, skipping initializing topic scoring")
return nil, nil
return nil
}
comsPerSlot := committeeCountPerSlot(activeValidators)
exceedsThreshold := comsPerSlot >= 2*subnetCount/uint64(params.BeaconConfig().SlotsPerEpoch)
@@ -301,20 +301,20 @@ func defaultAggregateSubnetTopicParams(activeValidators uint64) (*pubsub.TopicSc
rate := numPerSlot * 2 / gossipSubD
if rate == 0 {
log.Warn("rate is 0, skipping initializing topic scoring")
return nil, nil
return nil
}
// Determine expected first deliveries based on the message rate.
firstMessageCap, err := decayLimit(scoreDecay(firstDecay*oneEpochDuration()), float64(rate))
if err != nil {
log.Warnf("skipping initializing topic scoring: %v", err)
return nil, nil
return nil
}
firstMessageWeight := maxFirstDeliveryScore / firstMessageCap
// Determine expected mesh deliveries based on message rate applied with a dampening factor.
meshThreshold, err := decayThreshold(scoreDecay(meshDecay*oneEpochDuration()), float64(numPerSlot)/dampeningFactor)
if err != nil {
log.Warnf("skipping initializing topic scoring: %v", err)
return nil, nil
return nil
}
meshWeight := -scoreByWeight(topicWeight, meshThreshold)
meshCap := 4 * meshThreshold
@@ -341,10 +341,10 @@ func defaultAggregateSubnetTopicParams(activeValidators uint64) (*pubsub.TopicSc
MeshFailurePenaltyDecay: scoreDecay(meshDecay * oneEpochDuration()),
InvalidMessageDeliveriesWeight: -maxScore() / topicWeight,
InvalidMessageDeliveriesDecay: scoreDecay(invalidDecayPeriod),
}, nil
}
}
func defaultSyncSubnetTopicParams(activeValidators uint64) (*pubsub.TopicScoreParams, error) {
func defaultSyncSubnetTopicParams(activeValidators uint64) *pubsub.TopicScoreParams {
subnetCount := params.BeaconConfig().SyncCommitteeSubnetCount
// Get weight for each specific subnet.
topicWeight := syncCommitteesTotalWeight / float64(subnetCount)
@@ -356,7 +356,7 @@ func defaultSyncSubnetTopicParams(activeValidators uint64) (*pubsub.TopicScorePa
subnetWeight := activeValidators / subnetCount
if subnetWeight == 0 {
log.Warn("Subnet weight is 0, skipping initializing topic scoring")
return nil, nil
return nil
}
firstDecay := time.Duration(1)
meshDecay := time.Duration(4)
@@ -364,20 +364,20 @@ func defaultSyncSubnetTopicParams(activeValidators uint64) (*pubsub.TopicScorePa
rate := subnetWeight * 2 / gossipSubD
if rate == 0 {
log.Warn("rate is 0, skipping initializing topic scoring")
return nil, nil
return nil
}
// Determine expected first deliveries based on the message rate.
firstMessageCap, err := decayLimit(scoreDecay(firstDecay*oneEpochDuration()), float64(rate))
if err != nil {
log.WithError(err).Warn("Skipping initializing topic scoring")
return nil, nil
return nil
}
firstMessageWeight := maxFirstDeliveryScore / firstMessageCap
// Determine expected mesh deliveries based on message rate applied with a dampening factor.
meshThreshold, err := decayThreshold(scoreDecay(meshDecay*oneEpochDuration()), float64(subnetWeight)/dampeningFactor)
if err != nil {
log.WithError(err).Warn("Skipping initializing topic scoring")
return nil, nil
return nil
}
meshWeight := -scoreByWeight(topicWeight, meshThreshold)
meshCap := 4 * meshThreshold
@@ -404,7 +404,7 @@ func defaultSyncSubnetTopicParams(activeValidators uint64) (*pubsub.TopicScorePa
MeshFailurePenaltyDecay: scoreDecay(meshDecay * oneEpochDuration()),
InvalidMessageDeliveriesWeight: -maxScore() / topicWeight,
InvalidMessageDeliveriesDecay: scoreDecay(invalidDecayPeriod),
}, nil
}
}
func defaultAttesterSlashingTopicParams() *pubsub.TopicScoreParams {

View File

@@ -68,11 +68,9 @@ func TestLoggingParameters(t *testing.T) {
logGossipParameters("testing", &pubsub.TopicScoreParams{})
// Test out actual gossip parameters.
logGossipParameters("testing", defaultBlockTopicParams())
p, err := defaultAggregateSubnetTopicParams(10000)
assert.NoError(t, err)
p := defaultAggregateSubnetTopicParams(10000)
logGossipParameters("testing", p)
p, err = defaultAggregateTopicParams(10000)
assert.NoError(t, err)
p = defaultAggregateTopicParams(10000)
logGossipParameters("testing", p)
logGossipParameters("testing", defaultAttesterSlashingTopicParams())
logGossipParameters("testing", defaultProposerSlashingTopicParams())

View File

@@ -183,8 +183,16 @@ func (s *Service) loop(ctx context.Context) {
for {
select {
case <-decayBadResponsesStats.C:
// Exit early if context is canceled.
if ctx.Err() != nil {
return
}
s.scorers.badResponsesScorer.Decay()
case <-decayBlockProviderStats.C:
// Exit early if context is canceled.
if ctx.Err() != nil {
return
}
s.scorers.blockProviderScorer.Decay()
case <-ctx.Done():
return

View File

@@ -437,9 +437,9 @@ func TestLogTillGenesis_OK(t *testing.T) {
func TestInitDepositCache_OK(t *testing.T) {
ctrs := []*protodb.DepositContainer{
{Index: 0, Eth1BlockHeight: 2, Deposit: &ethpb.Deposit{Proof: [][]byte{[]byte("A")}}},
{Index: 1, Eth1BlockHeight: 4, Deposit: &ethpb.Deposit{Proof: [][]byte{[]byte("B")}}},
{Index: 2, Eth1BlockHeight: 6, Deposit: &ethpb.Deposit{Proof: [][]byte{[]byte("c")}}},
{Index: 0, Eth1BlockHeight: 2, Deposit: &ethpb.Deposit{Proof: [][]byte{[]byte("A")}, Data: &ethpb.Deposit_Data{PublicKey: []byte{}}}},
{Index: 1, Eth1BlockHeight: 4, Deposit: &ethpb.Deposit{Proof: [][]byte{[]byte("B")}, Data: &ethpb.Deposit_Data{PublicKey: []byte{}}}},
{Index: 2, Eth1BlockHeight: 6, Deposit: &ethpb.Deposit{Proof: [][]byte{[]byte("c")}, Data: &ethpb.Deposit_Data{PublicKey: []byte{}}}},
}
gs, _ := util.DeterministicGenesisState(t, 1)
beaconDB := dbutil.SetupDB(t)

View File

@@ -104,6 +104,7 @@ go_test(
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"//time/slots:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",

View File

@@ -5,6 +5,7 @@ import (
"encoding/hex"
"testing"
"github.com/ethereum/go-ethereum/common"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
@@ -96,6 +97,10 @@ func TestGetSpec(t *testing.T) {
config.ProportionalSlashingMultiplierAltair = 69
config.InactivityScoreRecoveryRate = 70
config.MinSyncCommitteeParticipants = 71
config.TerminalBlockHash = common.HexToHash("TerminalBlockHash")
config.TerminalBlockHashActivationEpoch = 72
config.TerminalTotalDifficulty = 73
config.Coinbase = common.HexToAddress("Coinbase")
var dbp [4]byte
copy(dbp[:], []byte{'0', '0', '0', '1'})
@@ -125,7 +130,7 @@ func TestGetSpec(t *testing.T) {
resp, err := server.GetSpec(context.Background(), &emptypb.Empty{})
require.NoError(t, err)
assert.Equal(t, 91, len(resp.Data))
assert.Equal(t, 94, len(resp.Data))
for k, v := range resp.Data {
switch k {
case "CONFIG_NAME":
@@ -318,6 +323,14 @@ func TestGetSpec(t *testing.T) {
assert.Equal(t, "0x09000000", v)
case "TRANSITION_TOTAL_DIFFICULTY":
assert.Equal(t, "0", v)
case "TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH":
assert.Equal(t, "72", v)
case "TERMINAL_BLOCK_HASH":
assert.Equal(t, common.HexToHash("TerminalBlockHash"), common.HexToHash(v))
case "TERMINAL_TOTAL_DIFFICULTY":
assert.Equal(t, "73", v)
case "COINBASE":
assert.Equal(t, common.HexToAddress("Coinbase"), v)
default:
t.Errorf("Incorrect key: %s", k)
}

View File

@@ -16,6 +16,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/cmd"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
@@ -674,11 +675,23 @@ func (bs *Server) GetValidatorPerformance(
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not get head state: %v", err)
}
currSlot := bs.GenesisTimeFetcher.CurrentSlot()
if bs.GenesisTimeFetcher.CurrentSlot() > headState.Slot() {
headState, err = transition.ProcessSlots(ctx, headState, bs.GenesisTimeFetcher.CurrentSlot())
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not process slots: %v", err)
if currSlot > headState.Slot() {
if features.Get().EnableNextSlotStateCache {
headRoot, err := bs.HeadFetcher.HeadRoot(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not retrieve head root: %v", err)
}
headState, err = transition.ProcessSlotsUsingNextSlotCache(ctx, headState, headRoot, currSlot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", currSlot, err)
}
} else {
headState, err = transition.ProcessSlots(ctx, headState, currSlot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not process slots: %v", err)
}
}
}
var validatorSummary []*precompute.Validator

View File

@@ -13,6 +13,7 @@ import (
coreTime "github.com/prysmaticlabs/prysm/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
beaconState "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/crypto/rand"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
@@ -124,9 +125,20 @@ func (vs *Server) duties(ctx context.Context, req *ethpb.DutiesRequest) (*ethpb.
return nil, err
}
if s.Slot() < epochStartSlot {
s, err = transition.ProcessSlots(ctx, s, epochStartSlot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", epochStartSlot, err)
if features.Get().EnableNextSlotStateCache {
headRoot, err := vs.HeadFetcher.HeadRoot(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not retrieve head root: %v", err)
}
s, err = transition.ProcessSlotsUsingNextSlotCache(ctx, s, headRoot, epochStartSlot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", epochStartSlot, err)
}
} else {
s, err = transition.ProcessSlots(ctx, s, epochStartSlot)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not process slots up to %d: %v", epochStartSlot, err)
}
}
}
committeeAssignments, proposerIndexToSlots, err := helpers.CommitteeAssignments(ctx, s, req.Epoch)

View File

@@ -148,7 +148,6 @@ type WriteOnlyBlockRoots interface {
// WriteOnlyStateRoots defines a struct which only has write access to state roots methods.
type WriteOnlyStateRoots interface {
SetStateRoots(val [][]byte) error
UpdateStateRootAtIndex(idx uint64, stateRoot [32]byte) error
}

View File

@@ -54,12 +54,12 @@ func (f FieldIndex) String(stateVersion int) string {
case Slashings:
return "slashings"
case PreviousEpochAttestations:
if version.Altair == stateVersion {
if version.Altair == stateVersion || version.Merge == stateVersion {
return "previousEpochParticipationBits"
}
return "previousEpochAttestations"
case CurrentEpochAttestations:
if version.Altair == stateVersion {
if version.Altair == stateVersion || version.Merge == stateVersion {
return "currentEpochParticipationBits"
}
return "currentEpochAttestations"
@@ -77,6 +77,8 @@ func (f FieldIndex) String(stateVersion int) string {
return "currentSyncCommittee"
case NextSyncCommittee:
return "nextSyncCommittee"
case LatestExecutionPayloadHeader:
return "latestExecutionPayloadHeader"
default:
return ""
}
@@ -114,12 +116,13 @@ const (
InactivityScores
CurrentSyncCommittee
NextSyncCommittee
// State fields added in Merge.
LatestExecutionPayloadHeader
)
// Altair fields which replaced previous phase 0 fields.
const (
// Epoch Attestations is switched with participation bits in
// Altair.
// Epoch Attestations is switched with participation bits in Altair.
PreviousEpochParticipationBits = PreviousEpochAttestations
CurrentEpochParticipationBits = CurrentEpochAttestations
)

View File

@@ -5,24 +5,6 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
)
// SetStateRoots for the beacon state. Updates the state roots
// to a new value by overwriting the previous value.
func (b *BeaconState) SetStateRoots(val [][]byte) error {
if !b.hasInnerState() {
return ErrNilInnerState
}
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[stateRoots].MinusRef()
b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1)
b.state.StateRoots = val
b.markFieldAsDirty(stateRoots)
b.rebuildTrie[stateRoots] = true
return nil
}
// UpdateStateRootAtIndex for the beacon state. Updates the state root
// at a specific index to a new value.
func (b *BeaconState) UpdateStateRootAtIndex(idx uint64, stateRoot [32]byte) error {

View File

@@ -5,24 +5,6 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
)
// SetStateRoots for the beacon state. Updates the state roots
// to a new value by overwriting the previous value.
func (b *BeaconState) SetStateRoots(val [][]byte) error {
if !b.hasInnerState() {
return ErrNilInnerState
}
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[stateRoots].MinusRef()
b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1)
b.state.StateRoots = val
b.markFieldAsDirty(stateRoots)
b.rebuildTrie[stateRoots] = true
return nil
}
// UpdateStateRootAtIndex for the beacon state. Updates the state root
// at a specific index to a new value.
func (b *BeaconState) UpdateStateRootAtIndex(idx uint64, stateRoot [32]byte) error {

View File

@@ -0,0 +1,16 @@
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["types.go"],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/v3",
visibility = ["//beacon-chain:__pkg__"],
deps = [
"//beacon-chain/state/fieldtrie:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//beacon-chain/state/types:go_default_library",
"//config/params:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],
)

View File

@@ -0,0 +1,49 @@
package v3
import (
"sync"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
"github.com/prysmaticlabs/prysm/config/params"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
func init() {
fieldMap = make(map[types.FieldIndex]types.DataType, params.BeaconConfig().BeaconStateMergeFieldCount)
// Initialize the fixed sized arrays.
fieldMap[types.BlockRoots] = types.BasicArray
fieldMap[types.StateRoots] = types.BasicArray
fieldMap[types.RandaoMixes] = types.BasicArray
// Initialize the composite arrays.
fieldMap[types.Eth1DataVotes] = types.CompositeArray
fieldMap[types.Validators] = types.CompositeArray
}
// TODO: Add field Aliases for values from the types package. It'll come in part 2.
// fieldMap keeps track of each field
// to its corresponding data type.
var fieldMap map[types.FieldIndex]types.DataType
// ErrNilInnerState returns when the inner state is nil and no copy set or get
// operations can be performed on state.
var ErrNilInnerState = errors.New("nil inner state")
// BeaconState defines a struct containing utilities for the eth2 chain state, defining
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
type BeaconState struct {
state *ethpb.BeaconStateMerge
lock sync.RWMutex
dirtyFields map[types.FieldIndex]bool
dirtyIndices map[types.FieldIndex][]uint64
stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie
rebuildTrie map[types.FieldIndex]bool
valMapHandler *stateutil.ValidatorMapHandler
merkleLayers [][][]byte
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
}

View File

@@ -7,6 +7,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/db:go_default_library",
"//beacon-chain/db/kv:go_default_library",
"//cmd:go_default_library",
"//runtime/tos:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",

View File

@@ -2,6 +2,7 @@ package db
import (
beacondb "github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/db/kv"
"github.com/prysmaticlabs/prysm/cmd"
"github.com/prysmaticlabs/prysm/runtime/tos"
"github.com/sirupsen/logrus"
@@ -31,5 +32,19 @@ var Commands = &cli.Command{
return nil
},
},
{
Name: "migrate-state",
Description: `migrate the state database to a new format`,
Flags: cmd.WrapFlags([]cli.Flag{
cmd.DataDirFlag,
}),
Before: tos.VerifyTosAcceptedOrPrompt,
Action: func(cliCtx *cli.Context) error {
if err := kv.MigrateStateDB(cliCtx); err != nil {
log.Fatalf("Could not migrate the database: %v", err)
}
return nil
},
},
},
}

View File

@@ -3,6 +3,7 @@
package flags
import (
"encoding/hex"
"strings"
"github.com/prysmaticlabs/prysm/config/params"
@@ -189,4 +190,31 @@ var (
Usage: "Sets the minimum number of peers that a node will attempt to peer with that are subscribed to a subnet.",
Value: 6,
}
// TerminalTotalDifficultyOverride specifies the total difficulty to manual overrides the `TERMINAL_TOTAL_DIFFICULTY` parameter.
TerminalTotalDifficultyOverride = &cli.Uint64Flag{
Name: "terminal-total-difficulty-override",
Usage: "Sets the total difficulty to manual overrides the default TERMINAL_TOTAL_DIFFICULTY value. " +
"WARNING: This flag should be used only if you have a clear understanding that community has decided to override the terminal difficulty. " +
"Incorrect usage will result in your node experience consensus failure.",
}
// TerminalBlockHashOverride specifies the terminal block hash to manual overrides the `TERMINAL_BLOCK_HASH` parameter.
TerminalBlockHashOverride = &cli.StringFlag{
Name: "terminal-block-hash-override",
Usage: "Sets the block hash to manual overrides the default TERMINAL_BLOCK_HASH value. " +
"WARNING: This flag should be used only if you have a clear understanding that community has decided to override the terminal block hash. " +
"Incorrect usage will result in your node experience consensus failure.",
}
// TerminalBlockHashActivationEpochOverride specifies the terminal block hash epoch to manual overrides the `TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH` parameter.
TerminalBlockHashActivationEpochOverride = &cli.Uint64Flag{
Name: "terminal-block-hash-epoch-override",
Usage: "Sets the block hash epoch to manual overrides the default TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH value. " +
"WARNING: This flag should be used only if you have a clear understanding that community has decided to override the terminal block hash activation epoch. " +
"Incorrect usage will result in your node experience consensus failure.",
}
// Coinbase specifies the fee recipient for the transaction fees.
Coinbase = &cli.StringFlag{
Name: "coinbase",
Usage: "Post merge, this address will receive the transaction fees produced by any blocks from this node. Default to junk whilst merge is in development state.",
Value: hex.EncodeToString([]byte("0x0000000000000000000000000000000000000001")),
}
)

View File

@@ -65,6 +65,10 @@ var appFlags = []cli.Flag{
flags.Eth1HeaderReqLimit,
flags.GenesisStatePath,
flags.MinPeersPerSubnet,
flags.TerminalTotalDifficultyOverride,
flags.TerminalBlockHashOverride,
flags.TerminalBlockHashActivationEpochOverride,
flags.Coinbase,
cmd.EnableBackupWebhookFlag,
cmd.BackupWebhookOutputDir,
cmd.MinimalConfigFlag,

View File

@@ -124,6 +124,15 @@ var appHelpFlagGroups = []flagGroup{
flags.MinPeersPerSubnet,
},
},
{
Name: "merge",
Flags: []cli.Flag{
flags.TerminalTotalDifficultyOverride,
flags.TerminalBlockHashOverride,
flags.TerminalBlockHashActivationEpochOverride,
flags.Coinbase,
},
},
{
Name: "p2p",
Flags: []cli.Flag{

View File

@@ -1,17 +1,44 @@
load("@prysm//tools/go:def.bzl", "go_library")
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["slashing-protection.go"],
srcs = [
"export.go",
"import.go",
"log.go",
"slashing-protection.go",
],
importpath = "github.com/prysmaticlabs/prysm/cmd/validator/slashing-protection",
visibility = ["//visibility:public"],
deps = [
"//cmd:go_default_library",
"//cmd/validator/flags:go_default_library",
"//config/features:go_default_library",
"//io/file:go_default_library",
"//runtime/tos:go_default_library",
"//validator/slashing-protection:go_default_library",
"//validator/accounts/userprompt:go_default_library",
"//validator/db/kv:go_default_library",
"//validator/slashing-protection-history:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["import_export_test.go"],
embed = [":go_default_library"],
deps = [
"//cmd:go_default_library",
"//cmd/validator/flags:go_default_library",
"//io/file:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//validator/db/kv:go_default_library",
"//validator/db/testing:go_default_library",
"//validator/slashing-protection-history/format:go_default_library",
"//validator/testing:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
],
)

View File

@@ -1,4 +1,4 @@
package slashingprotection
package historycmd
import (
"encoding/json"
@@ -11,7 +11,7 @@ import (
"github.com/prysmaticlabs/prysm/io/file"
"github.com/prysmaticlabs/prysm/validator/accounts/userprompt"
"github.com/prysmaticlabs/prysm/validator/db/kv"
export "github.com/prysmaticlabs/prysm/validator/slashing-protection/local/standard-protection-format"
slashingprotection "github.com/prysmaticlabs/prysm/validator/slashing-protection-history"
"github.com/urfave/cli/v2"
)
@@ -19,7 +19,7 @@ const (
jsonExportFileName = "slashing_protection.json"
)
// ExportSlashingProtectionJSONCli extracts a validator's slashing protection
// Extracts a validator's slashing protection
// history from their database and formats it into an EIP-3076 standard JSON
// file via a CLI entrypoint to make it easy to migrate machines or Ethereum consensus clients.
//
@@ -29,7 +29,7 @@ const (
// 3. Call the function which actually exports the data from
// from the validator's db into an EIP standard slashing protection format
// 4. Format and save the JSON file to a user's specified output directory.
func ExportSlashingProtectionJSONCli(cliCtx *cli.Context) error {
func exportSlashingProtectionJSON(cliCtx *cli.Context) error {
log.Info(
"This command exports your validator's attestation and proposal history into " +
"a file that can then be imported into any other Prysm setup across computers",
@@ -63,7 +63,7 @@ func ExportSlashingProtectionJSONCli(cliCtx *cli.Context) error {
log.WithError(err).Errorf("Could not close validator DB")
}
}()
eipJSON, err := export.ExportStandardProtectionJSON(cliCtx.Context, validatorDB)
eipJSON, err := slashingprotection.ExportStandardProtectionJSON(cliCtx.Context, validatorDB)
if err != nil {
return errors.Wrap(err, "could not export slashing protection history")
}
@@ -98,7 +98,7 @@ func ExportSlashingProtectionJSONCli(cliCtx *cli.Context) error {
}
log.Infof(
"Successfully wrote %s. You can import this file using Prysm's "+
"validator slashing-protection import command in another machine",
"validator slashing-protection-history import command in another machine",
outputFilePath,
)
return nil

View File

@@ -1,4 +1,4 @@
package slashingprotection
package historycmd
import (
"bytes"
@@ -10,11 +10,11 @@ import (
"github.com/prysmaticlabs/prysm/io/file"
"github.com/prysmaticlabs/prysm/validator/accounts/userprompt"
"github.com/prysmaticlabs/prysm/validator/db/kv"
slashingProtectionFormat "github.com/prysmaticlabs/prysm/validator/slashing-protection/local/standard-protection-format"
slashingprotection "github.com/prysmaticlabs/prysm/validator/slashing-protection-history"
"github.com/urfave/cli/v2"
)
// ImportSlashingProtectionCLI reads an input slashing protection EIP-3076
// Reads an input slashing protection EIP-3076
// standard JSON file and attempts to insert its data into our validator DB.
//
// Steps:
@@ -23,7 +23,7 @@ import (
// 3. Read the JSON file from user input.
// 4. Call the function which actually imports the data from
// from the standard slashing protection JSON file into our database.
func ImportSlashingProtectionCLI(cliCtx *cli.Context) error {
func importSlashingProtectionJSON(cliCtx *cli.Context) error {
var err error
dataDir := cliCtx.String(cmd.DataDirFlag.Name)
if !cliCtx.IsSet(cmd.DataDirFlag.Name) {
@@ -71,7 +71,7 @@ func ImportSlashingProtectionCLI(cliCtx *cli.Context) error {
}
log.Infof("Starting import of slashing protection file %s", protectionFilePath)
buf := bytes.NewBuffer(enc)
if err := slashingProtectionFormat.ImportStandardProtectionJSON(
if err := slashingprotection.ImportStandardProtectionJSON(
cliCtx.Context, valDB, buf,
); err != nil {
return err

View File

@@ -1,4 +1,4 @@
package slashingprotection
package historycmd
import (
"encoding/json"
@@ -14,7 +14,7 @@ import (
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/validator/db/kv"
dbTest "github.com/prysmaticlabs/prysm/validator/db/testing"
"github.com/prysmaticlabs/prysm/validator/slashing-protection/local/standard-protection-format/format"
"github.com/prysmaticlabs/prysm/validator/slashing-protection-history/format"
mocks "github.com/prysmaticlabs/prysm/validator/testing"
"github.com/urfave/cli/v2"
)
@@ -66,11 +66,11 @@ func TestImportExportSlashingProtectionCli_RoundTrip(t *testing.T) {
cliCtx := setupCliCtx(t, dbPath, protectionFilePath, outputPath)
// We import the slashing protection history file via CLI.
err = ImportSlashingProtectionCLI(cliCtx)
err = importSlashingProtectionJSON(cliCtx)
require.NoError(t, err)
// We export the slashing protection history file via CLI.
err = ExportSlashingProtectionJSONCli(cliCtx)
err = exportSlashingProtectionJSON(cliCtx)
require.NoError(t, err)
// Attempt to read the exported file from the output directory.
@@ -142,11 +142,11 @@ func TestImportExportSlashingProtectionCli_EmptyData(t *testing.T) {
cliCtx := setupCliCtx(t, dbPath, protectionFilePath, outputPath)
// We import the slashing protection history file via CLI.
err = ImportSlashingProtectionCLI(cliCtx)
err = importSlashingProtectionJSON(cliCtx)
require.NoError(t, err)
// We export the slashing protection history file via CLI.
err = ExportSlashingProtectionJSONCli(cliCtx)
err = exportSlashingProtectionJSON(cliCtx)
require.NoError(t, err)
// Attempt to read the exported file from the output directory.

View File

@@ -0,0 +1,5 @@
package historycmd
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "historycmd")

View File

@@ -1,19 +1,18 @@
package slashing_protection
package historycmd
import (
"github.com/prysmaticlabs/prysm/cmd"
"github.com/prysmaticlabs/prysm/cmd/validator/flags"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/runtime/tos"
slashingprotection "github.com/prysmaticlabs/prysm/validator/slashing-protection"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
// Commands for slashing protection.
var Commands = &cli.Command{
Name: "slashing-protection",
Category: "slashing-protection",
Name: "slashing-protection-history",
Category: "slashing-protection-history",
Usage: "defines commands for interacting your validator's slashing protection history",
Subcommands: []*cli.Command{
{
@@ -22,6 +21,10 @@ var Commands = &cli.Command{
Flags: cmd.WrapFlags([]cli.Flag{
cmd.DataDirFlag,
flags.SlashingProtectionExportDirFlag,
features.Mainnet,
features.PyrmontTestnet,
features.PraterTestnet,
cmd.AcceptTosFlag,
}),
Before: func(cliCtx *cli.Context) error {
if err := cmd.LoadFlagsFromConfig(cliCtx, cliCtx.Command.Flags); err != nil {
@@ -31,7 +34,7 @@ var Commands = &cli.Command{
},
Action: func(cliCtx *cli.Context) error {
features.ConfigureValidator(cliCtx)
if err := slashingprotection.ExportSlashingProtectionJSONCli(cliCtx); err != nil {
if err := exportSlashingProtectionJSON(cliCtx); err != nil {
logrus.Fatalf("Could not export slashing protection file: %v", err)
}
return nil
@@ -56,7 +59,7 @@ var Commands = &cli.Command{
},
Action: func(cliCtx *cli.Context) error {
features.ConfigureValidator(cliCtx)
err := slashingprotection.ImportSlashingProtectionCLI(cliCtx)
err := importSlashingProtectionJSON(cliCtx)
if err != nil {
logrus.Fatalf("Could not import slashing protection cli: %v", err)
}

View File

@@ -1 +0,0 @@
package wallet

View File

@@ -98,7 +98,7 @@ var (
Usage: "Disable max-cover algorithm when selecting attestations for proposer",
}
enableSlashingProtectionPruning = &cli.BoolFlag{
Name: "enable-slashing-protection-pruning",
Name: "enable-slashing-protection-history-pruning",
Usage: "Enables the pruning of the validator client's slashing protection database",
}
disableOptimizedBalanceUpdate = &cli.BoolFlag{

View File

@@ -22,6 +22,7 @@ go_library(
deps = [
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//params:go_default_library",
"@com_github_mohae_deepcopy//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",

View File

@@ -4,6 +4,7 @@ package params
import (
"time"
"github.com/ethereum/go-ethereum/common"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
)
@@ -120,6 +121,7 @@ type BeaconChainConfig struct {
GenesisCountdownInterval time.Duration // How often to log the countdown until the genesis time is reached.
BeaconStateFieldCount int // BeaconStateFieldCount defines how many fields are in beacon state.
BeaconStateAltairFieldCount int // BeaconStateAltairFieldCount defines how many fields are in beacon state hard fork 1.
BeaconStateMergeFieldCount int // BeaconStateMergeFieldCount defines how many fields are in beacon state post upgrade to the Merge.
// Slasher constants.
WeakSubjectivityPeriod types.Epoch // WeakSubjectivityPeriod defines the time period expressed in number of epochs were proof of stake network should validate block headers and attestations for slashable events.
@@ -175,6 +177,12 @@ type BeaconChainConfig struct {
// Light client
MinSyncCommitteeParticipants uint64 `yaml:"MIN_SYNC_COMMITTEE_PARTICIPANTS" spec:"true"` // MinSyncCommitteeParticipants defines the minimum amount of sync committee participants for which the light client acknowledges the signature.
// Merge
TerminalBlockHash common.Hash `yaml:"TERMINAL_BLOCK_HASH" spec:"true"` // TerminalBlockHash of beacon chain.
TerminalBlockHashActivationEpoch types.Epoch `yaml:"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH" spec:"true"` // TerminalBlockHashActivationEpoch of beacon chain.
TerminalTotalDifficulty uint64 `yaml:"TERMINAL_TOTAL_DIFFICULTY" spec:"true"` // TerminalTotalDifficulty is part of the experimental merge spec. This value is type is currently TBD: https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#transition-settings
Coinbase common.Address // Coinbase where the transaction fee goes to.
}
// InitializeForkSchedule initializes the schedules forks baked into the config.

View File

@@ -14,10 +14,7 @@ import (
"gopkg.in/yaml.v2"
)
var placeholderFields = []string{
"TERMINAL_TOTAL_DIFFICULTY",
"TERMINAL_BLOCK_HASH",
}
var placeholderFields []string
func TestLoadConfigFileMainnet(t *testing.T) {
// See https://media.githubusercontent.com/media/ethereum/consensus-spec-tests/master/tests/minimal/config/phase0.yaml

View File

@@ -178,6 +178,7 @@ var mainnetBeaconConfig = &BeaconChainConfig{
PresetBase: "mainnet",
BeaconStateFieldCount: 21,
BeaconStateAltairFieldCount: 24,
BeaconStateMergeFieldCount: 25,
// Slasher related values.
WeakSubjectivityPeriod: 54000,
@@ -233,4 +234,7 @@ var mainnetBeaconConfig = &BeaconChainConfig{
// Light client
MinSyncCommitteeParticipants: 1,
// Merge
TerminalBlockHashActivationEpoch: math.MaxUint64,
}

View File

@@ -1,5 +1,5 @@
/*
Package rand defines methods of obtaining cryptographically secure random number generators.
Package rand defines methods of obtaining random number generators.
One is expected to use randomness from this package only, without introducing any other packages.
This limits the scope of code that needs to be hardened.
@@ -13,9 +13,10 @@ There are two modes, one for deterministic and another non-deterministic randomn
In this mode, only seed is generated using cryptographically secure source (crypto/rand). So,
once seed is obtained, and generator is seeded, the next generations are deterministic, thus fast.
This method is still better than using unix time for source of randomness - since time is not a
good source of seed randomness, when you have many concurrent servers using it (and they have
coinciding random generators' start times).
However given that we only seed this 63 bits from crypto/rand and use math/rand to generate the outputs,
this method is not cryptographically secure. This is directly stated in the math/rand package,
https://github.com/golang/go/blob/release-branch.go1.17/src/math/rand/rand.go#L15. For any security
sensitive work this particular generator is NOT to be used.
2. For cryptographically secure non-deterministic mode (CSPRNG), use:
@@ -77,7 +78,8 @@ func NewGenerator() *Rand {
// but is deterministic otherwise (given seed, produces given results, deterministically).
// Panics if crypto/rand input cannot be read.
// Use this method for performance, where deterministic pseudo-random behaviour is enough.
// Otherwise, rely on NewGenerator().
// Otherwise, rely on NewGenerator(). This method is not cryptographically secure as outputs
// can be potentially predicted even without knowledge of the underlying seed.
func NewDeterministicGenerator() *Rand {
randGen := NewGenerator()
return mrand.New(mrand.NewSource(randGen.Int63())) /* #nosec G404 */

View File

@@ -76,7 +76,7 @@ func NewValidatorScraper(promExpoURL string) Scraper {
// will be used.
func scrapeProm(url string, tripper http.RoundTripper) (map[string]*dto.MetricFamily, error) {
mfChan := make(chan *dto.MetricFamily)
errChan := make(chan error)
errChan := make(chan error, 1)
go func() {
// FetchMetricFamilies handles grpc flavored prometheus ez
// but at the cost of the awkward channel select loop below

View File

@@ -0,0 +1,32 @@
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@prysm//tools/go:def.bzl", "go_library")
# gazelle:ignore
proto_library(
name = "proto",
srcs = ["beacon_wrapper.proto"],
visibility = ["//visibility:public"],
deps = [
"//proto/eth/v1:proto",
"//proto/eth/v2:proto",
],
)
go_proto_library(
name = "go_proto",
importpath = "github.com/prysmaticlabs/prysm/proto/eth/wrapper",
proto = ":proto",
visibility = ["//visibility:public"],
deps = [
"//proto/eth/v1:go_default_library",
"//proto/eth/v2:go_default_library",
],
)
go_library(
name = "go_default_library",
embed = [":go_proto"],
importpath = "github.com/prysmaticlabs/prysm/proto/eth/wrapper",
visibility = ["//visibility:public"],
)

230
proto/eth/wrapper/beacon_wrapper.pb.go generated Executable file
View File

@@ -0,0 +1,230 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.15.8
// source: proto/eth/wrapper/beacon_wrapper.proto
package ethereum_eth_wrapper
import (
reflect "reflect"
sync "sync"
proto "github.com/golang/protobuf/proto"
v1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
v2 "github.com/prysmaticlabs/prysm/proto/eth/v2"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type WrappedBeaconState struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Version v2.Version `protobuf:"varint,1001,opt,name=version,proto3,enum=ethereum.eth.v2.Version" json:"version,omitempty"`
ValidatorIndexes []byte `protobuf:"bytes,1002,opt,name=validatorIndexes,proto3" json:"validatorIndexes,omitempty"`
// Types that are assignable to State:
// *WrappedBeaconState_Phase0State
// *WrappedBeaconState_AltairState
State isWrappedBeaconState_State `protobuf_oneof:"state"`
}
func (x *WrappedBeaconState) Reset() {
*x = WrappedBeaconState{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *WrappedBeaconState) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*WrappedBeaconState) ProtoMessage() {}
func (x *WrappedBeaconState) ProtoReflect() protoreflect.Message {
mi := &file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use WrappedBeaconState.ProtoReflect.Descriptor instead.
func (*WrappedBeaconState) Descriptor() ([]byte, []int) {
return file_proto_eth_wrapper_beacon_wrapper_proto_rawDescGZIP(), []int{0}
}
func (x *WrappedBeaconState) GetVersion() v2.Version {
if x != nil {
return x.Version
}
return v2.Version_PHASE0
}
func (x *WrappedBeaconState) GetValidatorIndexes() []byte {
if x != nil {
return x.ValidatorIndexes
}
return nil
}
func (m *WrappedBeaconState) GetState() isWrappedBeaconState_State {
if m != nil {
return m.State
}
return nil
}
func (x *WrappedBeaconState) GetPhase0State() *v1.BeaconState {
if x, ok := x.GetState().(*WrappedBeaconState_Phase0State); ok {
return x.Phase0State
}
return nil
}
func (x *WrappedBeaconState) GetAltairState() *v2.BeaconStateV2 {
if x, ok := x.GetState().(*WrappedBeaconState_AltairState); ok {
return x.AltairState
}
return nil
}
type isWrappedBeaconState_State interface {
isWrappedBeaconState_State()
}
type WrappedBeaconState_Phase0State struct {
Phase0State *v1.BeaconState `protobuf:"bytes,1,opt,name=phase0_state,json=phase0State,proto3,oneof"`
}
type WrappedBeaconState_AltairState struct {
AltairState *v2.BeaconStateV2 `protobuf:"bytes,2,opt,name=altair_state,json=altairState,proto3,oneof"`
}
func (*WrappedBeaconState_Phase0State) isWrappedBeaconState_State() {}
func (*WrappedBeaconState_AltairState) isWrappedBeaconState_State() {}
var File_proto_eth_wrapper_beacon_wrapper_proto protoreflect.FileDescriptor
var file_proto_eth_wrapper_beacon_wrapper_proto_rawDesc = []byte{
0x0a, 0x26, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x77, 0x72, 0x61, 0x70,
0x70, 0x65, 0x72, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70,
0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x1a, 0x1a,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f,
0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e,
0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x87, 0x02, 0x0a,
0x12, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74,
0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0xe9,
0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x10, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0xea, 0x07, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e,
0x64, 0x65, 0x78, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0c, 0x70, 0x68, 0x61, 0x73, 0x65, 0x30, 0x5f,
0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65,
0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x68, 0x61,
0x73, 0x65, 0x30, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x61, 0x6c, 0x74, 0x61,
0x69, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32,
0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x56, 0x32, 0x48, 0x00,
0x52, 0x0b, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x07, 0x0a,
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_proto_eth_wrapper_beacon_wrapper_proto_rawDescOnce sync.Once
file_proto_eth_wrapper_beacon_wrapper_proto_rawDescData = file_proto_eth_wrapper_beacon_wrapper_proto_rawDesc
)
func file_proto_eth_wrapper_beacon_wrapper_proto_rawDescGZIP() []byte {
file_proto_eth_wrapper_beacon_wrapper_proto_rawDescOnce.Do(func() {
file_proto_eth_wrapper_beacon_wrapper_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_eth_wrapper_beacon_wrapper_proto_rawDescData)
})
return file_proto_eth_wrapper_beacon_wrapper_proto_rawDescData
}
var file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_proto_eth_wrapper_beacon_wrapper_proto_goTypes = []interface{}{
(*WrappedBeaconState)(nil), // 0: ethereum.eth.wrapper.WrappedBeaconState
(v2.Version)(0), // 1: ethereum.eth.v2.Version
(*v1.BeaconState)(nil), // 2: ethereum.eth.v1.BeaconState
(*v2.BeaconStateV2)(nil), // 3: ethereum.eth.v2.BeaconStateV2
}
var file_proto_eth_wrapper_beacon_wrapper_proto_depIdxs = []int32{
1, // 0: ethereum.eth.wrapper.WrappedBeaconState.version:type_name -> ethereum.eth.v2.Version
2, // 1: ethereum.eth.wrapper.WrappedBeaconState.phase0_state:type_name -> ethereum.eth.v1.BeaconState
3, // 2: ethereum.eth.wrapper.WrappedBeaconState.altair_state:type_name -> ethereum.eth.v2.BeaconStateV2
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_proto_eth_wrapper_beacon_wrapper_proto_init() }
func file_proto_eth_wrapper_beacon_wrapper_proto_init() {
if File_proto_eth_wrapper_beacon_wrapper_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WrappedBeaconState); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes[0].OneofWrappers = []interface{}{
(*WrappedBeaconState_Phase0State)(nil),
(*WrappedBeaconState_AltairState)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_eth_wrapper_beacon_wrapper_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proto_eth_wrapper_beacon_wrapper_proto_goTypes,
DependencyIndexes: file_proto_eth_wrapper_beacon_wrapper_proto_depIdxs,
MessageInfos: file_proto_eth_wrapper_beacon_wrapper_proto_msgTypes,
}.Build()
File_proto_eth_wrapper_beacon_wrapper_proto = out.File
file_proto_eth_wrapper_beacon_wrapper_proto_rawDesc = nil
file_proto_eth_wrapper_beacon_wrapper_proto_goTypes = nil
file_proto_eth_wrapper_beacon_wrapper_proto_depIdxs = nil
}

View File

@@ -0,0 +1,16 @@
syntax = "proto3";
package ethereum.eth.wrapper;
import "proto/eth/v2/version.proto";
import "proto/eth/v1/beacon_state.proto";
import "proto/eth/v2/beacon_state.proto";
message WrappedBeaconState {
v2.Version version = 1001;
bytes validatorIndexes = 1002;
oneof state {
v1.BeaconState phase0_state = 1;
v2.BeaconStateV2 altair_state = 2;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,9 @@ message GenericSignedBeaconBlock {
// Representing a signed, post-Altair fork beacon block.
SignedBeaconBlockAltair altair = 2;
// Representing a signed, post-Merge fork beacon block.
SignedBeaconBlockMerge merge = 3;
}
}
@@ -42,6 +45,9 @@ message GenericBeaconBlock {
// Representing a post-Altair fork beacon block.
BeaconBlockAltair altair = 2;
// Representing a post-Merge fork beacon block.
BeaconBlockMerge merge = 3;
}
}
@@ -290,3 +296,82 @@ message SyncAggregate {
// BLS aggregated signature of the sync committee for the ones that voted.
bytes sync_committee_signature = 2 [(ethereum.eth.ext.ssz_size) = "96"];
}
message SignedBeaconBlockMerge {
// The unsigned beacon block itself.
BeaconBlockMerge block = 1;
// 96 byte BLS signature from the validator that produced this block.
bytes signature = 2 [(ethereum.eth.ext.ssz_size) = "96"];
}
message BeaconBlockMerge {
// Beacon chain slot that this block represents.
uint64 slot = 1 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/eth2-types.Slot"];
// Validator index of the validator that proposed the block header.
uint64 proposer_index = 2 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/eth2-types.ValidatorIndex"];
// 32 byte root of the parent block.
bytes parent_root = 3 [(ethereum.eth.ext.ssz_size) = "32"];
// 32 byte root of the resulting state after processing this block.
bytes state_root = 4 [(ethereum.eth.ext.ssz_size) = "32"];
// The beacon block body.
BeaconBlockBodyMerge body = 5;
}
message BeaconBlockBodyMerge {
// The validators RANDAO reveal 96 byte value.
bytes randao_reveal = 1 [(ethereum.eth.ext.ssz_size) = "96"];
// A reference to the Ethereum 1.x chain.
Eth1Data eth1_data = 2;
// 32 byte field of arbitrary data. This field may contain any data and
// is not used for anything other than a fun message.
bytes graffiti = 3 [(ethereum.eth.ext.ssz_size) = "32"];
// Block operations
// Refer to spec constants at https://github.com/ethereum/consensus-specs/blob/dev/specs/core/0_beacon-chain.md#max-operations-per-block
// At most MAX_PROPOSER_SLASHINGS.
repeated ProposerSlashing proposer_slashings = 4 [(ethereum.eth.ext.ssz_max) = "16"];
// At most MAX_ATTESTER_SLASHINGS.
repeated AttesterSlashing attester_slashings = 5 [(ethereum.eth.ext.ssz_max) = "2"];
// At most MAX_ATTESTATIONS.
repeated Attestation attestations = 6 [(ethereum.eth.ext.ssz_max) = "128"];
// At most MAX_DEPOSITS.
repeated Deposit deposits = 7 [(ethereum.eth.ext.ssz_max) = "16"];
// At most MAX_VOLUNTARY_EXITS.
repeated SignedVoluntaryExit voluntary_exits = 8 [(ethereum.eth.ext.ssz_max) = "16"];
// Sync aggregate object for the beacon chain to track sync committee votes. New in Altair network upgrade.
SyncAggregate sync_aggregate = 9;
// Execution payload from the execution chain. New in Merge network upgrade.
ExecutionPayload execution_payload = 10;
}
message ExecutionPayload {
bytes parent_hash = 1 [(ethereum.eth.ext.ssz_size) = "32"];
bytes coinbase = 2 [(ethereum.eth.ext.ssz_size) = "20"]; // 'beneficiary' in the yellow paper
bytes state_root = 3 [(ethereum.eth.ext.ssz_size) = "32"];
bytes receipt_root = 4 [(ethereum.eth.ext.ssz_size) = "32"]; // 'receipts root' in the yellow paper
bytes logs_bloom = 5 [(ethereum.eth.ext.ssz_size) = "256"];
bytes random = 6 [(ethereum.eth.ext.ssz_size) = "32"]; // 'difficulty' in the yellow paper
uint64 block_number = 7; // 'number' in the yellow paper
uint64 gas_limit = 8;
uint64 gas_used = 9;
uint64 timestamp = 10;
bytes extra_data = 11 [(ethereum.eth.ext.ssz_max) = "32"];
bytes base_fee_per_gas = 12 [(ethereum.eth.ext.ssz_size) = "32"]; //base fee introduced in EIP-1559, little-endian serialized
bytes block_hash = 13 [(ethereum.eth.ext.ssz_size) = "32"]; // Hash of execution block
// Transactions are encoded with RLP, and so to software that only understands SSZ they are presented as opaque byte arrays.
repeated bytes transactions = 14 [(ethereum.eth.ext.ssz_size) = "?,?", (ethereum.eth.ext.ssz_max) = "1048576,1073741824"];
}

View File

@@ -1073,6 +1073,396 @@ func (x *SyncAggregatorSelectionData) GetSubcommitteeIndex() uint64 {
return 0
}
type BeaconStateMerge struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
GenesisTime uint64 `protobuf:"varint,1001,opt,name=genesis_time,json=genesisTime,proto3" json:"genesis_time,omitempty"`
GenesisValidatorsRoot []byte `protobuf:"bytes,1002,opt,name=genesis_validators_root,json=genesisValidatorsRoot,proto3" json:"genesis_validators_root,omitempty" ssz-size:"32"`
Slot github_com_prysmaticlabs_eth2_types.Slot `protobuf:"varint,1003,opt,name=slot,proto3" json:"slot,omitempty" cast-type:"github.com/prysmaticlabs/eth2-types.Slot"`
Fork *Fork `protobuf:"bytes,1004,opt,name=fork,proto3" json:"fork,omitempty"`
LatestBlockHeader *BeaconBlockHeader `protobuf:"bytes,2001,opt,name=latest_block_header,json=latestBlockHeader,proto3" json:"latest_block_header,omitempty"`
BlockRoots [][]byte `protobuf:"bytes,2002,rep,name=block_roots,json=blockRoots,proto3" json:"block_roots,omitempty" ssz-size:"8192,32"`
StateRoots [][]byte `protobuf:"bytes,2003,rep,name=state_roots,json=stateRoots,proto3" json:"state_roots,omitempty" ssz-size:"8192,32"`
HistoricalRoots [][]byte `protobuf:"bytes,2004,rep,name=historical_roots,json=historicalRoots,proto3" json:"historical_roots,omitempty" ssz-max:"16777216" ssz-size:"?,32"`
Eth1Data *Eth1Data `protobuf:"bytes,3001,opt,name=eth1_data,json=eth1Data,proto3" json:"eth1_data,omitempty"`
Eth1DataVotes []*Eth1Data `protobuf:"bytes,3002,rep,name=eth1_data_votes,json=eth1DataVotes,proto3" json:"eth1_data_votes,omitempty" ssz-max:"2048"`
Eth1DepositIndex uint64 `protobuf:"varint,3003,opt,name=eth1_deposit_index,json=eth1DepositIndex,proto3" json:"eth1_deposit_index,omitempty"`
Validators []*Validator `protobuf:"bytes,4001,rep,name=validators,proto3" json:"validators,omitempty" ssz-max:"1099511627776"`
Balances []uint64 `protobuf:"varint,4002,rep,packed,name=balances,proto3" json:"balances,omitempty" ssz-max:"1099511627776"`
RandaoMixes [][]byte `protobuf:"bytes,5001,rep,name=randao_mixes,json=randaoMixes,proto3" json:"randao_mixes,omitempty" ssz-size:"65536,32"`
Slashings []uint64 `protobuf:"varint,6001,rep,packed,name=slashings,proto3" json:"slashings,omitempty" ssz-size:"8192"`
PreviousEpochParticipation []byte `protobuf:"bytes,7001,opt,name=previous_epoch_participation,json=previousEpochParticipation,proto3" json:"previous_epoch_participation,omitempty" ssz-max:"1099511627776"`
CurrentEpochParticipation []byte `protobuf:"bytes,7002,opt,name=current_epoch_participation,json=currentEpochParticipation,proto3" json:"current_epoch_participation,omitempty" ssz-max:"1099511627776"`
JustificationBits github_com_prysmaticlabs_go_bitfield.Bitvector4 `protobuf:"bytes,8001,opt,name=justification_bits,json=justificationBits,proto3" json:"justification_bits,omitempty" cast-type:"github.com/prysmaticlabs/go-bitfield.Bitvector4" ssz-size:"1"`
PreviousJustifiedCheckpoint *Checkpoint `protobuf:"bytes,8002,opt,name=previous_justified_checkpoint,json=previousJustifiedCheckpoint,proto3" json:"previous_justified_checkpoint,omitempty"`
CurrentJustifiedCheckpoint *Checkpoint `protobuf:"bytes,8003,opt,name=current_justified_checkpoint,json=currentJustifiedCheckpoint,proto3" json:"current_justified_checkpoint,omitempty"`
FinalizedCheckpoint *Checkpoint `protobuf:"bytes,8004,opt,name=finalized_checkpoint,json=finalizedCheckpoint,proto3" json:"finalized_checkpoint,omitempty"`
InactivityScores []uint64 `protobuf:"varint,9001,rep,packed,name=inactivity_scores,json=inactivityScores,proto3" json:"inactivity_scores,omitempty" ssz-max:"1099511627776"`
CurrentSyncCommittee *SyncCommittee `protobuf:"bytes,9002,opt,name=current_sync_committee,json=currentSyncCommittee,proto3" json:"current_sync_committee,omitempty"`
NextSyncCommittee *SyncCommittee `protobuf:"bytes,9003,opt,name=next_sync_committee,json=nextSyncCommittee,proto3" json:"next_sync_committee,omitempty"`
LatestExecutionPayloadHeader *ExecutionPayloadHeader `protobuf:"bytes,10001,opt,name=latest_execution_payload_header,json=latestExecutionPayloadHeader,proto3" json:"latest_execution_payload_header,omitempty"`
}
func (x *BeaconStateMerge) Reset() {
*x = BeaconStateMerge{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BeaconStateMerge) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BeaconStateMerge) ProtoMessage() {}
func (x *BeaconStateMerge) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BeaconStateMerge.ProtoReflect.Descriptor instead.
func (*BeaconStateMerge) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_beacon_state_proto_rawDescGZIP(), []int{12}
}
func (x *BeaconStateMerge) GetGenesisTime() uint64 {
if x != nil {
return x.GenesisTime
}
return 0
}
func (x *BeaconStateMerge) GetGenesisValidatorsRoot() []byte {
if x != nil {
return x.GenesisValidatorsRoot
}
return nil
}
func (x *BeaconStateMerge) GetSlot() github_com_prysmaticlabs_eth2_types.Slot {
if x != nil {
return x.Slot
}
return github_com_prysmaticlabs_eth2_types.Slot(0)
}
func (x *BeaconStateMerge) GetFork() *Fork {
if x != nil {
return x.Fork
}
return nil
}
func (x *BeaconStateMerge) GetLatestBlockHeader() *BeaconBlockHeader {
if x != nil {
return x.LatestBlockHeader
}
return nil
}
func (x *BeaconStateMerge) GetBlockRoots() [][]byte {
if x != nil {
return x.BlockRoots
}
return nil
}
func (x *BeaconStateMerge) GetStateRoots() [][]byte {
if x != nil {
return x.StateRoots
}
return nil
}
func (x *BeaconStateMerge) GetHistoricalRoots() [][]byte {
if x != nil {
return x.HistoricalRoots
}
return nil
}
func (x *BeaconStateMerge) GetEth1Data() *Eth1Data {
if x != nil {
return x.Eth1Data
}
return nil
}
func (x *BeaconStateMerge) GetEth1DataVotes() []*Eth1Data {
if x != nil {
return x.Eth1DataVotes
}
return nil
}
func (x *BeaconStateMerge) GetEth1DepositIndex() uint64 {
if x != nil {
return x.Eth1DepositIndex
}
return 0
}
func (x *BeaconStateMerge) GetValidators() []*Validator {
if x != nil {
return x.Validators
}
return nil
}
func (x *BeaconStateMerge) GetBalances() []uint64 {
if x != nil {
return x.Balances
}
return nil
}
func (x *BeaconStateMerge) GetRandaoMixes() [][]byte {
if x != nil {
return x.RandaoMixes
}
return nil
}
func (x *BeaconStateMerge) GetSlashings() []uint64 {
if x != nil {
return x.Slashings
}
return nil
}
func (x *BeaconStateMerge) GetPreviousEpochParticipation() []byte {
if x != nil {
return x.PreviousEpochParticipation
}
return nil
}
func (x *BeaconStateMerge) GetCurrentEpochParticipation() []byte {
if x != nil {
return x.CurrentEpochParticipation
}
return nil
}
func (x *BeaconStateMerge) GetJustificationBits() github_com_prysmaticlabs_go_bitfield.Bitvector4 {
if x != nil {
return x.JustificationBits
}
return github_com_prysmaticlabs_go_bitfield.Bitvector4(nil)
}
func (x *BeaconStateMerge) GetPreviousJustifiedCheckpoint() *Checkpoint {
if x != nil {
return x.PreviousJustifiedCheckpoint
}
return nil
}
func (x *BeaconStateMerge) GetCurrentJustifiedCheckpoint() *Checkpoint {
if x != nil {
return x.CurrentJustifiedCheckpoint
}
return nil
}
func (x *BeaconStateMerge) GetFinalizedCheckpoint() *Checkpoint {
if x != nil {
return x.FinalizedCheckpoint
}
return nil
}
func (x *BeaconStateMerge) GetInactivityScores() []uint64 {
if x != nil {
return x.InactivityScores
}
return nil
}
func (x *BeaconStateMerge) GetCurrentSyncCommittee() *SyncCommittee {
if x != nil {
return x.CurrentSyncCommittee
}
return nil
}
func (x *BeaconStateMerge) GetNextSyncCommittee() *SyncCommittee {
if x != nil {
return x.NextSyncCommittee
}
return nil
}
func (x *BeaconStateMerge) GetLatestExecutionPayloadHeader() *ExecutionPayloadHeader {
if x != nil {
return x.LatestExecutionPayloadHeader
}
return nil
}
type ExecutionPayloadHeader struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ParentHash []byte `protobuf:"bytes,1,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty" ssz-size:"32"`
Coinbase []byte `protobuf:"bytes,2,opt,name=coinbase,proto3" json:"coinbase,omitempty" ssz-size:"20"`
StateRoot []byte `protobuf:"bytes,3,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty" ssz-size:"32"`
ReceiptRoot []byte `protobuf:"bytes,4,opt,name=receipt_root,json=receiptRoot,proto3" json:"receipt_root,omitempty" ssz-size:"32"`
LogsBloom []byte `protobuf:"bytes,5,opt,name=logs_bloom,json=logsBloom,proto3" json:"logs_bloom,omitempty" ssz-size:"256"`
Random []byte `protobuf:"bytes,6,opt,name=random,proto3" json:"random,omitempty" ssz-size:"32"`
BlockNumber uint64 `protobuf:"varint,7,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"`
GasLimit uint64 `protobuf:"varint,8,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"`
GasUsed uint64 `protobuf:"varint,9,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
Timestamp uint64 `protobuf:"varint,10,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
ExtraData []byte `protobuf:"bytes,11,opt,name=extra_data,json=extraData,proto3" json:"extra_data,omitempty" ssz-max:"32"`
BaseFeePerGas []byte `protobuf:"bytes,12,opt,name=base_fee_per_gas,json=baseFeePerGas,proto3" json:"base_fee_per_gas,omitempty" ssz-size:"32"`
BlockHash []byte `protobuf:"bytes,13,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty" ssz-size:"32"`
TransactionsRoot []byte `protobuf:"bytes,14,opt,name=transactions_root,json=transactionsRoot,proto3" json:"transactions_root,omitempty" ssz-size:"32"`
}
func (x *ExecutionPayloadHeader) Reset() {
*x = ExecutionPayloadHeader{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ExecutionPayloadHeader) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ExecutionPayloadHeader) ProtoMessage() {}
func (x *ExecutionPayloadHeader) ProtoReflect() protoreflect.Message {
mi := &file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[13]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ExecutionPayloadHeader.ProtoReflect.Descriptor instead.
func (*ExecutionPayloadHeader) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_beacon_state_proto_rawDescGZIP(), []int{13}
}
func (x *ExecutionPayloadHeader) GetParentHash() []byte {
if x != nil {
return x.ParentHash
}
return nil
}
func (x *ExecutionPayloadHeader) GetCoinbase() []byte {
if x != nil {
return x.Coinbase
}
return nil
}
func (x *ExecutionPayloadHeader) GetStateRoot() []byte {
if x != nil {
return x.StateRoot
}
return nil
}
func (x *ExecutionPayloadHeader) GetReceiptRoot() []byte {
if x != nil {
return x.ReceiptRoot
}
return nil
}
func (x *ExecutionPayloadHeader) GetLogsBloom() []byte {
if x != nil {
return x.LogsBloom
}
return nil
}
func (x *ExecutionPayloadHeader) GetRandom() []byte {
if x != nil {
return x.Random
}
return nil
}
func (x *ExecutionPayloadHeader) GetBlockNumber() uint64 {
if x != nil {
return x.BlockNumber
}
return 0
}
func (x *ExecutionPayloadHeader) GetGasLimit() uint64 {
if x != nil {
return x.GasLimit
}
return 0
}
func (x *ExecutionPayloadHeader) GetGasUsed() uint64 {
if x != nil {
return x.GasUsed
}
return 0
}
func (x *ExecutionPayloadHeader) GetTimestamp() uint64 {
if x != nil {
return x.Timestamp
}
return 0
}
func (x *ExecutionPayloadHeader) GetExtraData() []byte {
if x != nil {
return x.ExtraData
}
return nil
}
func (x *ExecutionPayloadHeader) GetBaseFeePerGas() []byte {
if x != nil {
return x.BaseFeePerGas
}
return nil
}
func (x *ExecutionPayloadHeader) GetBlockHash() []byte {
if x != nil {
return x.BlockHash
}
return nil
}
func (x *ExecutionPayloadHeader) GetTransactionsRoot() []byte {
if x != nil {
return x.TransactionsRoot
}
return nil
}
var File_proto_prysm_v1alpha1_beacon_state_proto protoreflect.FileDescriptor
var file_proto_prysm_v1alpha1_beacon_state_proto_rawDesc = []byte{
@@ -1390,17 +1780,167 @@ var file_proto_prysm_v1alpha1_beacon_state_proto_rawDesc = []byte{
0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x73, 0x75, 0x62,
0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74,
0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63,
0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b,
0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45,
0x74, 0x68, 0x2e, 0x56, 0x31, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xaf, 0x0e, 0x0a, 0x10, 0x42, 0x65, 0x61,
0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x12, 0x22, 0x0a,
0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07,
0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d,
0x65, 0x12, 0x3f, 0x0a, 0x17, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0xea, 0x07, 0x20,
0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x15, 0x67, 0x65, 0x6e,
0x65, 0x73, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x6f,
0x6f, 0x74, 0x12, 0x41, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0xeb, 0x07, 0x20, 0x01, 0x28,
0x04, 0x42, 0x2c, 0x82, 0xb5, 0x18, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
0x65, 0x74, 0x68, 0x32, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52,
0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x30, 0x0a, 0x04, 0x66, 0x6f, 0x72, 0x6b, 0x18, 0xec, 0x07,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x6f, 0x72,
0x6b, 0x52, 0x04, 0x66, 0x6f, 0x72, 0x6b, 0x12, 0x59, 0x0a, 0x13, 0x6c, 0x61, 0x74, 0x65, 0x73,
0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0xd1,
0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65,
0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52,
0x11, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64,
0x65, 0x72, 0x12, 0x2d, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74,
0x73, 0x18, 0xd2, 0x0f, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0b, 0x8a, 0xb5, 0x18, 0x07, 0x38, 0x31,
0x39, 0x32, 0x2c, 0x33, 0x32, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74,
0x73, 0x12, 0x2d, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x73,
0x18, 0xd3, 0x0f, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0b, 0x8a, 0xb5, 0x18, 0x07, 0x38, 0x31, 0x39,
0x32, 0x2c, 0x33, 0x32, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73,
0x12, 0x40, 0x0a, 0x10, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x72,
0x6f, 0x6f, 0x74, 0x73, 0x18, 0xd4, 0x0f, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a, 0xb5, 0x18,
0x04, 0x3f, 0x2c, 0x33, 0x32, 0x92, 0xb5, 0x18, 0x08, 0x31, 0x36, 0x37, 0x37, 0x37, 0x32, 0x31,
0x36, 0x52, 0x0f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x6f, 0x6f,
0x74, 0x73, 0x12, 0x3d, 0x0a, 0x09, 0x65, 0x74, 0x68, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18,
0xb9, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45,
0x74, 0x68, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x65, 0x74, 0x68, 0x31, 0x44, 0x61, 0x74,
0x61, 0x12, 0x52, 0x0a, 0x0f, 0x65, 0x74, 0x68, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x76,
0x6f, 0x74, 0x65, 0x73, 0x18, 0xba, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x45, 0x74, 0x68, 0x31, 0x44, 0x61, 0x74, 0x61, 0x42, 0x08, 0x92, 0xb5,
0x18, 0x04, 0x32, 0x30, 0x34, 0x38, 0x52, 0x0d, 0x65, 0x74, 0x68, 0x31, 0x44, 0x61, 0x74, 0x61,
0x56, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x74, 0x68, 0x31, 0x5f, 0x64, 0x65,
0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0xbb, 0x17, 0x20, 0x01,
0x28, 0x04, 0x52, 0x10, 0x65, 0x74, 0x68, 0x31, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x49,
0x6e, 0x64, 0x65, 0x78, 0x12, 0x54, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x73, 0x18, 0xa1, 0x1f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x11, 0x92, 0xb5, 0x18,
0x0d, 0x31, 0x30, 0x39, 0x39, 0x35, 0x31, 0x31, 0x36, 0x32, 0x37, 0x37, 0x37, 0x36, 0x52, 0x0a,
0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x62, 0x61,
0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0xa2, 0x1f, 0x20, 0x03, 0x28, 0x04, 0x42, 0x11, 0x92,
0xb5, 0x18, 0x0d, 0x31, 0x30, 0x39, 0x39, 0x35, 0x31, 0x31, 0x36, 0x32, 0x37, 0x37, 0x37, 0x36,
0x52, 0x08, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x0c, 0x72, 0x61,
0x6e, 0x64, 0x61, 0x6f, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x73, 0x18, 0x89, 0x27, 0x20, 0x03, 0x28,
0x0c, 0x42, 0x0c, 0x8a, 0xb5, 0x18, 0x08, 0x36, 0x35, 0x35, 0x33, 0x36, 0x2c, 0x33, 0x32, 0x52,
0x0b, 0x72, 0x61, 0x6e, 0x64, 0x61, 0x6f, 0x4d, 0x69, 0x78, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x09,
0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x18, 0xf1, 0x2e, 0x20, 0x03, 0x28, 0x04,
0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x38, 0x31, 0x39, 0x32, 0x52, 0x09, 0x73, 0x6c, 0x61, 0x73,
0x68, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x1c, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75,
0x73, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xd9, 0x36, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x11, 0x92, 0xb5,
0x18, 0x0d, 0x31, 0x30, 0x39, 0x39, 0x35, 0x31, 0x31, 0x36, 0x32, 0x37, 0x37, 0x37, 0x36, 0x52,
0x1a, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x50, 0x61,
0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x1b, 0x63,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72,
0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xda, 0x36, 0x20, 0x01, 0x28,
0x0c, 0x42, 0x11, 0x92, 0xb5, 0x18, 0x0d, 0x31, 0x30, 0x39, 0x39, 0x35, 0x31, 0x31, 0x36, 0x32,
0x37, 0x37, 0x37, 0x36, 0x52, 0x19, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x70, 0x6f,
0x63, 0x68, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x68, 0x0a, 0x12, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x5f, 0x62, 0x69, 0x74, 0x73, 0x18, 0xc1, 0x3e, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x38, 0x8a, 0xb5,
0x18, 0x01, 0x31, 0x82, 0xb5, 0x18, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
0x67, 0x6f, 0x2d, 0x62, 0x69, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x42, 0x69, 0x74, 0x76,
0x65, 0x63, 0x74, 0x6f, 0x72, 0x34, 0x52, 0x11, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x63,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x12, 0x66, 0x0a, 0x1d, 0x70, 0x72, 0x65,
0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f,
0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0xc2, 0x3e, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70,
0x6f, 0x69, 0x6e, 0x74, 0x52, 0x1b, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x4a, 0x75,
0x73, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e,
0x74, 0x12, 0x64, 0x0a, 0x1c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6a, 0x75, 0x73,
0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e,
0x74, 0x18, 0xc3, 0x3e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x1a, 0x63, 0x75, 0x72,
0x72, 0x65, 0x6e, 0x74, 0x4a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x68, 0x65,
0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x55, 0x0a, 0x14, 0x66, 0x69, 0x6e, 0x61, 0x6c,
0x69, 0x7a, 0x65, 0x64, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18,
0xc4, 0x3e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43,
0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x66, 0x69, 0x6e, 0x61, 0x6c,
0x69, 0x7a, 0x65, 0x64, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x3f,
0x0a, 0x11, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x63, 0x6f,
0x72, 0x65, 0x73, 0x18, 0xa9, 0x46, 0x20, 0x03, 0x28, 0x04, 0x42, 0x11, 0x92, 0xb5, 0x18, 0x0d,
0x31, 0x30, 0x39, 0x39, 0x35, 0x31, 0x31, 0x36, 0x32, 0x37, 0x37, 0x37, 0x36, 0x52, 0x10, 0x69,
0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x12,
0x5b, 0x0a, 0x16, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f,
0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x18, 0xaa, 0x46, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d,
0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x52, 0x14, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53,
0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x12, 0x55, 0x0a, 0x13,
0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x74, 0x65, 0x65, 0x18, 0xab, 0x46, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65,
0x52, 0x11, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x74, 0x65, 0x65, 0x12, 0x75, 0x0a, 0x1f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x65, 0x78,
0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f,
0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x91, 0x4e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e,
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50,
0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x1c, 0x6c, 0x61,
0x74, 0x65, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0xac, 0x04, 0x0a, 0x16, 0x45,
0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48,
0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f,
0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02,
0x33, 0x32, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22,
0x0a, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61,
0x73, 0x65, 0x12, 0x25, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09,
0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x29, 0x0a, 0x0c, 0x72, 0x65, 0x63,
0x65, 0x69, 0x70, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42,
0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74,
0x52, 0x6f, 0x6f, 0x74, 0x12, 0x26, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x73, 0x5f, 0x62, 0x6c, 0x6f,
0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x07, 0x8a, 0xb5, 0x18, 0x03, 0x32, 0x35,
0x36, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x73, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x12, 0x1e, 0x0a, 0x06,
0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5,
0x18, 0x02, 0x33, 0x32, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x21, 0x0a, 0x0c,
0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01,
0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12,
0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x08, 0x20, 0x01,
0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08,
0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07,
0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x64,
0x61, 0x74, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x92, 0xb5, 0x18, 0x02, 0x33,
0x32, 0x52, 0x09, 0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x10,
0x62, 0x61, 0x73, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x73,
0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0d,
0x62, 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, 0x50, 0x65, 0x72, 0x47, 0x61, 0x73, 0x12, 0x25, 0x0a,
0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28,
0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x48, 0x61, 0x73, 0x68, 0x12, 0x33, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x42,
0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72,
0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53,
0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69,
0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x45, 0x74, 0x68, 0x2e, 0x56, 0x31, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1415,7 +1955,7 @@ func file_proto_prysm_v1alpha1_beacon_state_proto_rawDescGZIP() []byte {
return file_proto_prysm_v1alpha1_beacon_state_proto_rawDescData
}
var file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
var file_proto_prysm_v1alpha1_beacon_state_proto_goTypes = []interface{}{
(*BeaconState)(nil), // 0: ethereum.eth.v1alpha1.BeaconState
(*BeaconStateAltair)(nil), // 1: ethereum.eth.v1alpha1.BeaconStateAltair
@@ -1429,40 +1969,53 @@ var file_proto_prysm_v1alpha1_beacon_state_proto_goTypes = []interface{}{
(*DepositMessage)(nil), // 9: ethereum.eth.v1alpha1.DepositMessage
(*SyncCommittee)(nil), // 10: ethereum.eth.v1alpha1.SyncCommittee
(*SyncAggregatorSelectionData)(nil), // 11: ethereum.eth.v1alpha1.SyncAggregatorSelectionData
(*BeaconBlockHeader)(nil), // 12: ethereum.eth.v1alpha1.BeaconBlockHeader
(*Eth1Data)(nil), // 13: ethereum.eth.v1alpha1.Eth1Data
(*Validator)(nil), // 14: ethereum.eth.v1alpha1.Validator
(*Checkpoint)(nil), // 15: ethereum.eth.v1alpha1.Checkpoint
(*AttestationData)(nil), // 16: ethereum.eth.v1alpha1.AttestationData
(*BeaconStateMerge)(nil), // 12: ethereum.eth.v1alpha1.BeaconStateMerge
(*ExecutionPayloadHeader)(nil), // 13: ethereum.eth.v1alpha1.ExecutionPayloadHeader
(*BeaconBlockHeader)(nil), // 14: ethereum.eth.v1alpha1.BeaconBlockHeader
(*Eth1Data)(nil), // 15: ethereum.eth.v1alpha1.Eth1Data
(*Validator)(nil), // 16: ethereum.eth.v1alpha1.Validator
(*Checkpoint)(nil), // 17: ethereum.eth.v1alpha1.Checkpoint
(*AttestationData)(nil), // 18: ethereum.eth.v1alpha1.AttestationData
}
var file_proto_prysm_v1alpha1_beacon_state_proto_depIdxs = []int32{
2, // 0: ethereum.eth.v1alpha1.BeaconState.fork:type_name -> ethereum.eth.v1alpha1.Fork
12, // 1: ethereum.eth.v1alpha1.BeaconState.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
13, // 2: ethereum.eth.v1alpha1.BeaconState.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
13, // 3: ethereum.eth.v1alpha1.BeaconState.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
14, // 4: ethereum.eth.v1alpha1.BeaconState.validators:type_name -> ethereum.eth.v1alpha1.Validator
14, // 1: ethereum.eth.v1alpha1.BeaconState.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
15, // 2: ethereum.eth.v1alpha1.BeaconState.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
15, // 3: ethereum.eth.v1alpha1.BeaconState.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
16, // 4: ethereum.eth.v1alpha1.BeaconState.validators:type_name -> ethereum.eth.v1alpha1.Validator
3, // 5: ethereum.eth.v1alpha1.BeaconState.previous_epoch_attestations:type_name -> ethereum.eth.v1alpha1.PendingAttestation
3, // 6: ethereum.eth.v1alpha1.BeaconState.current_epoch_attestations:type_name -> ethereum.eth.v1alpha1.PendingAttestation
15, // 7: ethereum.eth.v1alpha1.BeaconState.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
15, // 8: ethereum.eth.v1alpha1.BeaconState.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
15, // 9: ethereum.eth.v1alpha1.BeaconState.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
17, // 7: ethereum.eth.v1alpha1.BeaconState.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
17, // 8: ethereum.eth.v1alpha1.BeaconState.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
17, // 9: ethereum.eth.v1alpha1.BeaconState.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
2, // 10: ethereum.eth.v1alpha1.BeaconStateAltair.fork:type_name -> ethereum.eth.v1alpha1.Fork
12, // 11: ethereum.eth.v1alpha1.BeaconStateAltair.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
13, // 12: ethereum.eth.v1alpha1.BeaconStateAltair.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
13, // 13: ethereum.eth.v1alpha1.BeaconStateAltair.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
14, // 14: ethereum.eth.v1alpha1.BeaconStateAltair.validators:type_name -> ethereum.eth.v1alpha1.Validator
15, // 15: ethereum.eth.v1alpha1.BeaconStateAltair.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
15, // 16: ethereum.eth.v1alpha1.BeaconStateAltair.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
15, // 17: ethereum.eth.v1alpha1.BeaconStateAltair.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
14, // 11: ethereum.eth.v1alpha1.BeaconStateAltair.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
15, // 12: ethereum.eth.v1alpha1.BeaconStateAltair.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
15, // 13: ethereum.eth.v1alpha1.BeaconStateAltair.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
16, // 14: ethereum.eth.v1alpha1.BeaconStateAltair.validators:type_name -> ethereum.eth.v1alpha1.Validator
17, // 15: ethereum.eth.v1alpha1.BeaconStateAltair.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
17, // 16: ethereum.eth.v1alpha1.BeaconStateAltair.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
17, // 17: ethereum.eth.v1alpha1.BeaconStateAltair.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
10, // 18: ethereum.eth.v1alpha1.BeaconStateAltair.current_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
10, // 19: ethereum.eth.v1alpha1.BeaconStateAltair.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
16, // 20: ethereum.eth.v1alpha1.PendingAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData
18, // 20: ethereum.eth.v1alpha1.PendingAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData
2, // 21: ethereum.eth.v1alpha1.CheckPtInfo.fork:type_name -> ethereum.eth.v1alpha1.Fork
22, // [22:22] is the sub-list for method output_type
22, // [22:22] is the sub-list for method input_type
22, // [22:22] is the sub-list for extension type_name
22, // [22:22] is the sub-list for extension extendee
0, // [0:22] is the sub-list for field type_name
2, // 22: ethereum.eth.v1alpha1.BeaconStateMerge.fork:type_name -> ethereum.eth.v1alpha1.Fork
14, // 23: ethereum.eth.v1alpha1.BeaconStateMerge.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
15, // 24: ethereum.eth.v1alpha1.BeaconStateMerge.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
15, // 25: ethereum.eth.v1alpha1.BeaconStateMerge.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
16, // 26: ethereum.eth.v1alpha1.BeaconStateMerge.validators:type_name -> ethereum.eth.v1alpha1.Validator
17, // 27: ethereum.eth.v1alpha1.BeaconStateMerge.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
17, // 28: ethereum.eth.v1alpha1.BeaconStateMerge.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
17, // 29: ethereum.eth.v1alpha1.BeaconStateMerge.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
10, // 30: ethereum.eth.v1alpha1.BeaconStateMerge.current_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
10, // 31: ethereum.eth.v1alpha1.BeaconStateMerge.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
13, // 32: ethereum.eth.v1alpha1.BeaconStateMerge.latest_execution_payload_header:type_name -> ethereum.eth.v1alpha1.ExecutionPayloadHeader
33, // [33:33] is the sub-list for method output_type
33, // [33:33] is the sub-list for method input_type
33, // [33:33] is the sub-list for extension type_name
33, // [33:33] is the sub-list for extension extendee
0, // [0:33] is the sub-list for field type_name
}
func init() { file_proto_prysm_v1alpha1_beacon_state_proto_init() }
@@ -1618,6 +2171,30 @@ func file_proto_prysm_v1alpha1_beacon_state_proto_init() {
return nil
}
}
file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BeaconStateMerge); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_prysm_v1alpha1_beacon_state_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExecutionPayloadHeader); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -1625,7 +2202,7 @@ func file_proto_prysm_v1alpha1_beacon_state_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_prysm_v1alpha1_beacon_state_proto_rawDesc,
NumEnums: 0,
NumMessages: 12,
NumMessages: 14,
NumExtensions: 0,
NumServices: 0,
},

View File

@@ -186,3 +186,68 @@ message SyncAggregatorSelectionData {
// Subcommittee index of this signing data.
uint64 subcommittee_index = 2;
}
message BeaconStateMerge {
// Versioning [1001-2000]
uint64 genesis_time = 1001;
bytes genesis_validators_root = 1002 [(ethereum.eth.ext.ssz_size) = "32"];
uint64 slot = 1003 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/eth2-types.Slot"];
Fork fork = 1004;
// History [2001-3000]
BeaconBlockHeader latest_block_header = 2001;
repeated bytes block_roots = 2002 [(ethereum.eth.ext.ssz_size) = "block_roots.size"];
repeated bytes state_roots = 2003 [(ethereum.eth.ext.ssz_size) = "state_roots.size"];
repeated bytes historical_roots = 2004 [(ethereum.eth.ext.ssz_size) = "?,32", (ethereum.eth.ext.ssz_max) = "16777216"];
// Eth1 [3001-4000]
Eth1Data eth1_data = 3001;
repeated Eth1Data eth1_data_votes = 3002 [(ethereum.eth.ext.ssz_max) = "eth1_data_votes.size"];
uint64 eth1_deposit_index = 3003;
// Registry [4001-5000]
repeated Validator validators = 4001 [(ethereum.eth.ext.ssz_max) = "1099511627776"];
repeated uint64 balances = 4002 [(ethereum.eth.ext.ssz_max) = "1099511627776"];
// Randomness [5001-6000]
repeated bytes randao_mixes = 5001 [(ethereum.eth.ext.ssz_size) = "randao_mixes.size"];
// Slashings [6001-7000]
repeated uint64 slashings = 6001 [(ethereum.eth.ext.ssz_size) = "slashings.size"];
// Participation [7001-8000]
bytes previous_epoch_participation = 7001 [(ethereum.eth.ext.ssz_max) = "1099511627776"];
bytes current_epoch_participation = 7002 [(ethereum.eth.ext.ssz_max) = "1099511627776"];
// Finality [8001-9000]
// Spec type [4]Bitvector which means this would be a fixed size of 4 bits.
bytes justification_bits = 8001 [(ethereum.eth.ext.ssz_size) = "1", (ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/go-bitfield.Bitvector4"];
Checkpoint previous_justified_checkpoint = 8002;
Checkpoint current_justified_checkpoint = 8003;
Checkpoint finalized_checkpoint = 8004;
// Altair fields [9001-10000]
repeated uint64 inactivity_scores = 9001 [(ethereum.eth.ext.ssz_max) = "1099511627776"];
SyncCommittee current_sync_committee = 9002; // [New in Altair]
SyncCommittee next_sync_committee = 9003; // [New in Altair]
// Merge fields [10001-11000]
ExecutionPayloadHeader latest_execution_payload_header = 10001; // [New in Merge]
}
message ExecutionPayloadHeader {
bytes parent_hash = 1 [(ethereum.eth.ext.ssz_size) = "32"];
bytes coinbase = 2 [(ethereum.eth.ext.ssz_size) = "20"];
bytes state_root = 3 [(ethereum.eth.ext.ssz_size) = "32"];
bytes receipt_root = 4 [(ethereum.eth.ext.ssz_size) = "32"];
bytes logs_bloom = 5 [(ethereum.eth.ext.ssz_size) = "256"];
bytes random = 6 [(ethereum.eth.ext.ssz_size) = "32"];
uint64 block_number = 7;
uint64 gas_limit = 8;
uint64 gas_used = 9;
uint64 timestamp = 10;
bytes extra_data = 11 [(ethereum.eth.ext.ssz_max) = "32"];
bytes base_fee_per_gas = 12 [(ethereum.eth.ext.ssz_size) = "32"];
bytes block_hash = 13 [(ethereum.eth.ext.ssz_size) = "32"];
bytes transactions_root = 14 [(ethereum.eth.ext.ssz_size) = "32"];
}

View File

@@ -425,122 +425,119 @@ var file_proto_prysm_v1alpha1_validator_client_keymanager_proto_rawDesc = []byte
0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x29, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
0x74, 0x74, 0x65, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e,
0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f,
0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4e, 0x0a, 0x16, 0x4c,
0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
0x69, 0x6e, 0x67, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e,
0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x22, 0xb9, 0x07, 0x0a, 0x0b,
0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x69,
0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x29, 0x0a,
0x10, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69,
0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
0x72, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x62,
0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x53, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x7c, 0x0a, 0x1f, 0x61, 0x67, 0x67,
0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x67, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65,
0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41,
0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x67, 0x67, 0x72, 0x65,
0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41,
0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x3a, 0x0a, 0x04, 0x65, 0x78, 0x69, 0x74, 0x18,
0x68, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x56, 0x6f,
0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x65,
0x78, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x69, 0x20, 0x01, 0x28,
0x04, 0x42, 0x2c, 0x82, 0xb5, 0x18, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
0x65, 0x74, 0x68, 0x32, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x48,
0x00, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x45, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68,
0x18, 0x6a, 0x20, 0x01, 0x28, 0x04, 0x42, 0x2d, 0x82, 0xb5, 0x18, 0x29, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63,
0x6c, 0x61, 0x62, 0x73, 0x2f, 0x65, 0x74, 0x68, 0x32, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
0x45, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x44,
0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x32, 0x18, 0x6b, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x48, 0x00, 0x52, 0x07, 0x62, 0x6c, 0x6f,
0x63, 0x6b, 0x56, 0x32, 0x12, 0x79, 0x0a, 0x1e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67,
0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x6c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65,
0x74, 0x74, 0x65, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4e, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x34, 0x0a, 0x16, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52,
0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x73, 0x22, 0xb9, 0x07, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f,
0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e,
0x69, 0x6e, 0x67, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x44, 0x6f, 0x6d, 0x61,
0x69, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x65, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x53,
0x0a, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61,
0x74, 0x61, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61,
0x48, 0x00, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44,
0x61, 0x74, 0x61, 0x12, 0x7c, 0x0a, 0x1f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65,
0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64,
0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x67, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
0x74, 0x6f, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61,
0x48, 0x00, 0x52, 0x1b, 0x73, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74,
0x6f, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12,
0x63, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x6d, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75,
0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x48, 0x00, 0x52, 0x14,
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50,
0x72, 0x6f, 0x6f, 0x66, 0x12, 0x37, 0x0a, 0x17, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18,
0x6e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x14, 0x73, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x42, 0x08, 0x0a,
0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0xb7, 0x01, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
0x74, 0x75, 0x73, 0x22, 0x3c, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a,
0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55,
0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4e,
0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10,
0x03, 0x32, 0xa7, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e,
0x65, 0x72, 0x12, 0x90, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12,
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x2b,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e,
0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67,
0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x1a, 0x22, 0x18, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f,
0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x42, 0xcb, 0x01, 0x0a, 0x22,
0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74,
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f,
0x66, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74,
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f,
0x66, 0x12, 0x3a, 0x0a, 0x04, 0x65, 0x78, 0x69, 0x74, 0x18, 0x68, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72,
0x79, 0x45, 0x78, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x65, 0x78, 0x69, 0x74, 0x12, 0x42, 0x0a,
0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x69, 0x20, 0x01, 0x28, 0x04, 0x42, 0x2c, 0x82, 0xb5, 0x18,
0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x65, 0x74, 0x68, 0x32, 0x2d, 0x74,
0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x04, 0x73, 0x6c, 0x6f,
0x74, 0x12, 0x45, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x04,
0x42, 0x2d, 0x82, 0xb5, 0x18, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x65,
0x74, 0x68, 0x32, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x48,
0x00, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x44, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x56, 0x32, 0x18, 0x6b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x6c, 0x74,
0x61, 0x69, 0x72, 0x48, 0x00, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x32, 0x12, 0x79,
0x0a, 0x1e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f,
0x72, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61,
0x18, 0x6c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53,
0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x6c,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x1b, 0x73, 0x79,
0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x6c, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x63, 0x0a, 0x16, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72,
0x6f, 0x6f, 0x66, 0x18, 0x6d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e,
0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x48, 0x00, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69,
0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x37,
0x0a, 0x17, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62,
0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x0c, 0x48,
0x00, 0x52, 0x14, 0x73, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63,
0x74, 0x22, 0xb7, 0x01, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76,
0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3c, 0x0a,
0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f,
0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45,
0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12,
0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x32, 0xa7, 0x02, 0x0a, 0x0c,
0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x90, 0x01, 0x0a,
0x18, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x50,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x1a, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e,
0x76, 0x32, 0x42, 0x0f, 0x4b, 0x65, 0x79, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x50, 0x72,
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x50, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x6f, 0x72, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3b, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x70, 0x62, 0xaa, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x5c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x41, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f,
0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12,
0x83, 0x01, 0x0a, 0x04, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x18, 0x2f, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65,
0x2f, 0x73, 0x69, 0x67, 0x6e, 0x42, 0xcb, 0x01, 0x0a, 0x22, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x42, 0x0f, 0x4b, 0x65,
0x79, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
0x50, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2d, 0x63,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x70,
0x62, 0xaa, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x56, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e,
0x56, 0x32, 0xca, 0x02, 0x1e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x56, 0x61,
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x5c, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -6,7 +6,6 @@ import "proto/prysm/v1alpha1/attestation.proto";
import "proto/prysm/v1alpha1/beacon_block.proto";
import "proto/prysm/v1alpha1/beacon_state.proto";
import "proto/prysm/v1alpha1/sync_committee.proto";
import "proto/prysm/v1alpha1/validator.proto";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";

View File

@@ -3,6 +3,7 @@ package version
const (
Phase0 = iota
Altair
Merge
)
func String(version int) string {
@@ -11,6 +12,8 @@ func String(version int) string {
return "phase0"
case Altair:
return "altair"
case Merge:
return "merge"
default:
return "unknown version"
}

View File

@@ -101,6 +101,8 @@ func main() {
default:
log.Fatal("Oops, given bucket is supported for now.")
}
case "growth":
printBucketGrowth(dbNameWithPath, *bucketName)
case "migration-check":
destDbNameWithPath := filepath.Join(*destDatadir, *dbName)
if _, err := os.Stat(destDbNameWithPath); os.IsNotExist(err) {
@@ -445,6 +447,49 @@ func checkValidatorMigration(dbNameWithPath, destDbNameWithPath string) {
log.Infof("number of state that did not match: %d", failCount)
}
func printBucketGrowth(dbNameWithPath, bucketName string) {
// open the raw database file. If the file is busy, then exit.
db, openErr := bolt.Open(dbNameWithPath, 0600, &bolt.Options{Timeout: 1 * time.Second})
if openErr != nil {
log.Fatalf("could not open db while getting keys of a bucket, %v", openErr)
}
// make sure we close the database before ejecting out of this function.
defer func() {
closeErr := db.Close()
if closeErr != nil {
log.Fatalf("could not close db while getting keys of a bucket, %v", closeErr)
}
}()
// get all the keys of the given bucket.
var keys [][]byte
var sizes []uint64
if viewErr := db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(bucketName))
c := b.Cursor()
count := uint64(0)
for k, v := c.First(); k != nil; k, v = c.Next() {
actualKey := make([]byte, len(k))
actualSizes := make([]byte, len(v))
copy(actualKey, k)
copy(actualSizes, v)
keys = append(keys, actualKey)
sizes = append(sizes, uint64(len(v)))
count++
if count%25000 == 0 {
log.Infof(" row = %d, vale sizes = %d", count, sizes)
}
}
return nil
}); viewErr != nil {
log.Fatalf("could not read keys of bucket from db: %v", viewErr)
}
}
func keysOfBucket(dbNameWithPath string, bucketName []byte, rowLimit uint64) ([][]byte, []uint64) {
// open the raw database file. If the file is busy, then exit.
db, openErr := bolt.Open(dbNameWithPath, 0600, &bolt.Options{Timeout: 1 * time.Second})

View File

@@ -7,7 +7,10 @@ go_library(
"prompt.go",
],
importpath = "github.com/prysmaticlabs/prysm/validator/accounts/userprompt",
visibility = ["//validator:__subpackages__"],
visibility = [
"//cmd:__subpackages__",
"//validator:__subpackages__",
],
deps = [
"//cmd/validator/flags:go_default_library",
"//io/file:go_default_library",

View File

@@ -128,7 +128,7 @@ go_test(
"//validator/graffiti:go_default_library",
"//validator/keymanager/derived:go_default_library",
"//validator/keymanager/remote:go_default_library",
"//validator/slashing-protection/local/standard-protection-format:go_default_library",
"//validator/slashing-protection-history:go_default_library",
"//validator/testing:go_default_library",
"@com_github_golang_mock//gomock:go_default_library",
"@com_github_pkg_errors//:go_default_library",

View File

@@ -15,7 +15,7 @@ import (
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
interchangeformat "github.com/prysmaticlabs/prysm/validator/slashing-protection/local/standard-protection-format"
history "github.com/prysmaticlabs/prysm/validator/slashing-protection-history"
)
type eip3076TestCase struct {
@@ -88,7 +88,7 @@ func TestEIP3076SpecTests(t *testing.T) {
validator, _, _, _ := setup(t)
if tt.GenesisValidatorsRoot != "" {
r, err := interchangeformat.RootFromHex(tt.GenesisValidatorsRoot)
r, err := history.RootFromHex(tt.GenesisValidatorsRoot)
require.NoError(t, validator.db.SaveGenesisValidatorsRoot(context.Background(), r[:]))
require.NoError(t, err)
}
@@ -100,7 +100,7 @@ func TestEIP3076SpecTests(t *testing.T) {
t.Fatal(err)
}
b := bytes.NewBuffer(interchangeBytes)
if err := interchangeformat.ImportStandardProtectionJSON(context.Background(), validator.db, b); err != nil {
if err := history.ImportStandardProtectionJSON(context.Background(), validator.db, b); err != nil {
if step.ShouldSucceed {
t.Fatal(err)
}
@@ -110,9 +110,9 @@ func TestEIP3076SpecTests(t *testing.T) {
// This loops through a list of block signings to attempt after importing the interchange data above.
for _, sb := range step.Blocks {
bSlot, err := interchangeformat.SlotFromString(sb.Slot)
bSlot, err := history.SlotFromString(sb.Slot)
require.NoError(t, err)
pk, err := interchangeformat.PubKeyFromHex(sb.Pubkey)
pk, err := history.PubKeyFromHex(sb.Pubkey)
require.NoError(t, err)
b := util.NewBeaconBlock()
b.Block.Slot = bSlot
@@ -134,11 +134,11 @@ func TestEIP3076SpecTests(t *testing.T) {
// This loops through a list of attestation signings to attempt after importing the interchange data above.
for _, sa := range step.Attestations {
target, err := interchangeformat.EpochFromString(sa.TargetEpoch)
target, err := history.EpochFromString(sa.TargetEpoch)
require.NoError(t, err)
source, err := interchangeformat.EpochFromString(sa.SourceEpoch)
source, err := history.EpochFromString(sa.SourceEpoch)
require.NoError(t, err)
pk, err := interchangeformat.PubKeyFromHex(sa.Pubkey)
pk, err := history.PubKeyFromHex(sa.Pubkey)
require.NoError(t, err)
ia := &ethpb.IndexedAttestation{
Data: &ethpb.AttestationData{

View File

@@ -19,7 +19,10 @@ go_library(
"schema.go",
],
importpath = "github.com/prysmaticlabs/prysm/validator/db/kv",
visibility = ["//validator:__subpackages__"],
visibility = [
"//cmd:__subpackages__",
"//validator:__subpackages__",
],
deps = [
"//async/abool:go_default_library",
"//async/event:go_default_library",

View File

@@ -4,7 +4,10 @@ go_library(
name = "go_default_library",
srcs = ["setup_db.go"],
importpath = "github.com/prysmaticlabs/prysm/validator/db/testing",
visibility = ["//validator:__subpackages__"],
visibility = [
"//cmd:__subpackages__",
"//validator:__subpackages__",
],
deps = [
"//validator/db/iface:go_default_library",
"//validator/db/kv:go_default_library",

View File

@@ -0,0 +1,51 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"keymanager.go",
"log.go",
"mnemonic.go",
],
importpath = "github.com/prysmaticlabs/prysm/validator/keymanager/derived",
visibility = [
"//tools:__subpackages__",
"//validator:__subpackages__",
],
deps = [
"//async/event:go_default_library",
"//crypto/bls:go_default_library",
"//crypto/rand:go_default_library",
"//io/prompt:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/keymanager:go_default_library",
"//validator/keymanager/imported:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_tyler_smith_go_bip39//:go_default_library",
"@com_github_wealdtech_go_eth2_util//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"eip_test.go",
"keymanager_test.go",
"mnemonic_test.go",
],
embed = [":go_default_library"],
deps = [
"//crypto/bls:go_default_library",
"//crypto/rand:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//validator/accounts/testing:go_default_library",
"//validator/testing:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_tyler_smith_go_bip39//:go_default_library",
"@com_github_wealdtech_go_eth2_util//:go_default_library",
],
)

View File

@@ -1,4 +1,4 @@
package imported
package derived
import (
"encoding/hex"

View File

@@ -0,0 +1,119 @@
package derived
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/async/event"
"github.com/prysmaticlabs/prysm/crypto/bls"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/imported"
util "github.com/wealdtech/go-eth2-util"
)
const (
// DerivationPathFormat describes the structure of how keys are derived from a master key.
DerivationPathFormat = "m / purpose / coin_type / account_index / withdrawal_key / validating_key"
// ValidatingKeyDerivationPathTemplate defining the hierarchical path for validating
// keys for Prysm Ethereum validators. According to EIP-2334, the format is as follows:
// m / purpose / coin_type / account_index / withdrawal_key / validating_key
ValidatingKeyDerivationPathTemplate = "m/12381/3600/%d/0/0"
)
// SetupConfig includes configuration values for initializing
// a keymanager, such as passwords, the wallet, and more.
type SetupConfig struct {
Wallet iface.Wallet
ListenForChanges bool
}
// Keymanager implementation for derived, HD keymanager using EIP-2333 and EIP-2334.
type Keymanager struct {
importedKM *imported.Keymanager
}
// NewKeymanager instantiates a new derived keymanager from configuration options.
func NewKeymanager(
ctx context.Context,
cfg *SetupConfig,
) (*Keymanager, error) {
importedKM, err := imported.NewKeymanager(ctx, &imported.SetupConfig{
Wallet: cfg.Wallet,
ListenForChanges: cfg.ListenForChanges,
})
if err != nil {
return nil, err
}
return &Keymanager{
importedKM: importedKM,
}, nil
}
// RecoverAccountsFromMnemonic given a mnemonic phrase, is able to regenerate N accounts
// from a derived seed, encrypt them according to the EIP-2334 JSON standard, and write them
// to disk. Then, the mnemonic is never stored nor used by the validator.
func (km *Keymanager) RecoverAccountsFromMnemonic(
ctx context.Context, mnemonic, mnemonicPassphrase string, numAccounts int,
) error {
seed, err := seedFromMnemonic(mnemonic, mnemonicPassphrase)
if err != nil {
return errors.Wrap(err, "could not initialize new wallet seed file")
}
privKeys := make([][]byte, numAccounts)
pubKeys := make([][]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := util.PrivateKeyFromSeedAndPath(
seed, fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i),
)
if err != nil {
return err
}
privKeys[i] = privKey.Marshal()
pubKeys[i] = privKey.PublicKey().Marshal()
}
return km.importedKM.ImportKeypairs(ctx, privKeys, pubKeys)
}
// ExtractKeystores retrieves the secret keys for specified public keys
// in the function input, encrypts them using the specified password,
// and returns their respective EIP-2335 keystores.
func (km *Keymanager) ExtractKeystores(
ctx context.Context, publicKeys []bls.PublicKey, password string,
) ([]*keymanager.Keystore, error) {
return km.importedKM.ExtractKeystores(ctx, publicKeys, password)
}
// ValidatingAccountNames for the derived keymanager.
func (km *Keymanager) ValidatingAccountNames(_ context.Context) ([]string, error) {
return km.importedKM.ValidatingAccountNames()
}
// Sign signs a message using a validator key.
func (km *Keymanager) Sign(ctx context.Context, req *validatorpb.SignRequest) (bls.Signature, error) {
return km.importedKM.Sign(ctx, req)
}
// FetchValidatingPublicKeys fetches the list of validating public keys from the keymanager.
func (km *Keymanager) FetchValidatingPublicKeys(ctx context.Context) ([][48]byte, error) {
return km.importedKM.FetchValidatingPublicKeys(ctx)
}
// FetchValidatingPrivateKeys fetches the list of validating private keys from the keymanager.
func (km *Keymanager) FetchValidatingPrivateKeys(ctx context.Context) ([][32]byte, error) {
return km.importedKM.FetchValidatingPrivateKeys(ctx)
}
// DeleteAccounts for a derived keymanager.
func (km *Keymanager) DeleteAccounts(ctx context.Context, publicKeys [][]byte) error {
return km.importedKM.DeleteAccounts(ctx, publicKeys)
}
// SubscribeAccountChanges creates an event subscription for a channel
// to listen for public key changes at runtime, such as when new validator accounts
// are imported into the keymanager while the validator process is running.
func (km *Keymanager) SubscribeAccountChanges(pubKeysChan chan [][48]byte) event.Subscription {
return km.importedKM.SubscribeAccountChanges(pubKeysChan)
}

View File

@@ -0,0 +1,209 @@
package derived
import (
"context"
"fmt"
"testing"
"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/prysmaticlabs/prysm/crypto/rand"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
mock "github.com/prysmaticlabs/prysm/validator/accounts/testing"
constant "github.com/prysmaticlabs/prysm/validator/testing"
"github.com/tyler-smith/go-bip39"
util "github.com/wealdtech/go-eth2-util"
)
const (
password = "secretPassw0rd$1999"
)
// We test that using a '25th word' mnemonic passphrase leads to different
// public keys derived than not specifying the passphrase.
func TestDerivedKeymanager_MnemnonicPassphrase_DifferentResults(t *testing.T) {
ctx := context.Background()
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: password,
}
km, err := NewKeymanager(ctx, &SetupConfig{
Wallet: wallet,
ListenForChanges: false,
})
require.NoError(t, err)
numAccounts := 5
err = km.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "mnemonicpass", numAccounts)
require.NoError(t, err)
without25thWord, err := km.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
wallet = &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: password,
}
km, err = NewKeymanager(ctx, &SetupConfig{
Wallet: wallet,
ListenForChanges: false,
})
require.NoError(t, err)
// No mnemonic passphrase this time.
err = km.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", numAccounts)
require.NoError(t, err)
with25thWord, err := km.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
for i, k := range with25thWord {
without := without25thWord[i]
assert.DeepNotEqual(t, k, without)
}
}
func TestDerivedKeymanager_RecoverSeedRoundTrip(t *testing.T) {
mnemonicEntropy := make([]byte, 32)
n, err := rand.NewGenerator().Read(mnemonicEntropy)
require.NoError(t, err)
require.Equal(t, n, len(mnemonicEntropy))
mnemonic, err := bip39.NewMnemonic(mnemonicEntropy)
require.NoError(t, err)
wanted := bip39.NewSeed(mnemonic, "")
got, err := seedFromMnemonic(mnemonic, "" /* no passphrase */)
require.NoError(t, err)
// Ensure the derived seed matches.
assert.DeepEqual(t, wanted, got)
}
func TestDerivedKeymanager_FetchValidatingPublicKeys(t *testing.T) {
derivedSeed, err := seedFromMnemonic(constant.TestMnemonic, "")
require.NoError(t, err)
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: password,
}
ctx := context.Background()
dr, err := NewKeymanager(ctx, &SetupConfig{
Wallet: wallet,
ListenForChanges: false,
})
require.NoError(t, err)
numAccounts := 5
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", numAccounts)
require.NoError(t, err)
// Fetch the public keys.
publicKeys, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
require.Equal(t, numAccounts, len(publicKeys))
wantedPubKeys := make([][48]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := util.PrivateKeyFromSeedAndPath(derivedSeed, fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i))
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], privKey.PublicKey().Marshal())
wantedPubKeys[i] = pubKey
}
// FetchValidatingPublicKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were derived
for i, key := range wantedPubKeys {
assert.Equal(t, key, publicKeys[i])
}
}
func TestDerivedKeymanager_FetchValidatingPrivateKeys(t *testing.T) {
derivedSeed, err := seedFromMnemonic(constant.TestMnemonic, "")
require.NoError(t, err)
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: password,
}
ctx := context.Background()
dr, err := NewKeymanager(ctx, &SetupConfig{
Wallet: wallet,
ListenForChanges: false,
})
require.NoError(t, err)
numAccounts := 5
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", numAccounts)
require.NoError(t, err)
// Fetch the private keys.
privateKeys, err := dr.FetchValidatingPrivateKeys(ctx)
require.NoError(t, err)
require.Equal(t, numAccounts, len(privateKeys))
wantedPrivKeys := make([][32]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := util.PrivateKeyFromSeedAndPath(derivedSeed, fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i))
require.NoError(t, err)
privKeyBytes := [32]byte{}
copy(privKeyBytes[:], privKey.Marshal())
wantedPrivKeys[i] = privKeyBytes
}
// FetchValidatingPrivateKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were derived
for i, key := range wantedPrivKeys {
assert.Equal(t, key, privateKeys[i])
}
}
func TestDerivedKeymanager_Sign(t *testing.T) {
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: password,
}
ctx := context.Background()
dr, err := NewKeymanager(ctx, &SetupConfig{
Wallet: wallet,
ListenForChanges: false,
})
require.NoError(t, err)
numAccounts := 5
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", numAccounts)
require.NoError(t, err)
pubKeys, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
// We prepare naive data to sign.
data := []byte("eth2data")
signRequest := &validatorpb.SignRequest{
PublicKey: pubKeys[0][:],
SigningRoot: data,
}
sig, err := dr.Sign(ctx, signRequest)
require.NoError(t, err)
pubKey, err := bls.PublicKeyFromBytes(pubKeys[0][:])
require.NoError(t, err)
wrongPubKey, err := bls.PublicKeyFromBytes(pubKeys[1][:])
require.NoError(t, err)
// Check if the signature verifies.
assert.Equal(t, true, sig.Verify(pubKey, data))
// Check if the bad signature fails.
assert.Equal(t, false, sig.Verify(wrongPubKey, data))
}
func TestDerivedKeymanager_Sign_NoPublicKeySpecified(t *testing.T) {
req := &validatorpb.SignRequest{
PublicKey: nil,
}
dr := &Keymanager{}
_, err := dr.Sign(context.Background(), req)
assert.ErrorContains(t, "nil public key", err)
}
func TestDerivedKeymanager_Sign_NoPublicKeyInCache(t *testing.T) {
req := &validatorpb.SignRequest{
PublicKey: []byte("hello world"),
}
dr := &Keymanager{}
_, err := dr.Sign(context.Background(), req)
assert.ErrorContains(t, "no signing key found", err)
}

View File

@@ -0,0 +1,5 @@
package derived
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "derived-keymanager")

View File

@@ -1,4 +1,4 @@
package imported
package derived
import (
"fmt"

View File

@@ -1,4 +1,4 @@
package imported
package derived
import (
"testing"

View File

@@ -1,59 +0,0 @@
package imported
import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/validator/accounts/petnames"
"github.com/sirupsen/logrus"
)
// DeleteAccounts takes in public keys and removes the accounts entirely. This includes their disk keystore and cached keystore.
func (km *Keymanager) DeleteAccounts(ctx context.Context, publicKeys [][]byte) error {
for _, publicKey := range publicKeys {
var index int
var found bool
for i, pubKey := range km.accountsStore.PublicKeys {
if bytes.Equal(pubKey, publicKey) {
index = i
found = true
break
}
}
if !found {
return fmt.Errorf("could not find public key %#x", publicKey)
}
deletedPublicKey := km.accountsStore.PublicKeys[index]
accountName := petnames.DeterministicName(deletedPublicKey, "-")
km.accountsStore.PrivateKeys = append(km.accountsStore.PrivateKeys[:index], km.accountsStore.PrivateKeys[index+1:]...)
km.accountsStore.PublicKeys = append(km.accountsStore.PublicKeys[:index], km.accountsStore.PublicKeys[index+1:]...)
newStore, err := km.CreateAccountsKeystore(ctx, km.accountsStore.PrivateKeys, km.accountsStore.PublicKeys)
if err != nil {
return errors.Wrap(err, "could not rewrite accounts keystore")
}
// Write the encoded keystore.
encoded, err := json.MarshalIndent(newStore, "", "\t")
if err != nil {
return err
}
if err := km.wallet.WriteFileAtPath(ctx, AccountsPath, AccountsKeystoreFileName, encoded); err != nil {
return errors.Wrap(err, "could not write keystore file for accounts")
}
log.WithFields(logrus.Fields{
"name": accountName,
"publicKey": fmt.Sprintf("%#x", bytesutil.Trunc(deletedPublicKey)),
}).Info("Successfully deleted validator account")
err = km.initializeKeysCachesFromKeystore()
if err != nil {
return errors.Wrap(err, "failed to initialize keys caches")
}
}
return nil
}

View File

@@ -1,66 +0,0 @@
package imported
import (
"context"
"encoding/json"
"fmt"
"strings"
"testing"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/testing/require"
mock "github.com/prysmaticlabs/prysm/validator/accounts/testing"
"github.com/prysmaticlabs/prysm/validator/keymanager"
logTest "github.com/sirupsen/logrus/hooks/test"
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
)
func TestImportedKeymanager_DeleteKeystores(t *testing.T) {
hook := logTest.NewGlobal()
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
WalletPassword: password,
}
dr := &Keymanager{
wallet: wallet,
accountsStore: &accountStore{},
}
numAccounts := 5
ctx := context.Background()
keystores := make([]*keymanager.Keystore, numAccounts)
for i := 0; i < numAccounts; i++ {
keystores[i] = createRandomKeystore(t, password)
}
require.NoError(t, dr.ImportKeystores(ctx, keystores, password))
accounts, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
require.Equal(t, numAccounts, len(accounts))
accountToRemove := uint64(2)
accountPubKey := accounts[accountToRemove]
// Remove an account from the keystore.
require.NoError(t, dr.DeleteAccounts(ctx, [][]byte{accountPubKey[:]}))
// Ensure the keystore file was written to the wallet
// and ensure we can decrypt it using the EIP-2335 standard.
var encodedKeystore []byte
for k, v := range wallet.Files[AccountsPath] {
if strings.Contains(k, "keystore") {
encodedKeystore = v
}
}
require.NotNil(t, encodedKeystore, "could not find keystore file")
keystoreFile := &keymanager.Keystore{}
require.NoError(t, json.Unmarshal(encodedKeystore, keystoreFile))
// We extract the accounts from the keystore.
decryptor := keystorev4.New()
encodedAccounts, err := decryptor.Decrypt(keystoreFile.Crypto, password)
require.NoError(t, err, "Could not decrypt validator accounts")
store := &accountStore{}
require.NoError(t, json.Unmarshal(encodedAccounts, store))
require.Equal(t, numAccounts-1, len(store.PublicKeys))
require.Equal(t, numAccounts-1, len(store.PrivateKeys))
require.LogsContain(t, hook, fmt.Sprintf("%#x", bytesutil.Trunc(accountPubKey[:])))
require.LogsContain(t, hook, "Successfully deleted validator account")
}

View File

@@ -1,41 +0,0 @@
package imported
import (
"context"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"go.opencensus.io/trace"
)
// FetchValidatingPublicKeys fetches the list of active public keys from the imported account keystores.
func (km *Keymanager) FetchValidatingPublicKeys(ctx context.Context) ([][48]byte, error) {
ctx, span := trace.StartSpan(ctx, "keymanager.FetchValidatingPublicKeys")
defer span.End()
lock.RLock()
keys := orderedPublicKeys
result := make([][48]byte, len(keys))
copy(result, keys)
lock.RUnlock()
return result, nil
}
// FetchValidatingPrivateKeys fetches the list of private keys from the secret keys cache
func (km *Keymanager) FetchValidatingPrivateKeys(ctx context.Context) ([][32]byte, error) {
lock.RLock()
defer lock.RUnlock()
privKeys := make([][32]byte, len(secretKeysCache))
pubKeys, err := km.FetchValidatingPublicKeys(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve public keys")
}
for i, pk := range pubKeys {
seckey, ok := secretKeysCache[pk]
if !ok {
return nil, errors.New("Could not fetch private key")
}
privKeys[i] = bytesutil.ToBytes32(seckey.Marshal())
}
return privKeys, nil
}

View File

@@ -1,77 +0,0 @@
package imported
import (
"context"
"testing"
"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
mock "github.com/prysmaticlabs/prysm/validator/accounts/testing"
)
func TestImportedKeymanager_FetchValidatingPublicKeys(t *testing.T) {
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
WalletPassword: password,
}
dr := &Keymanager{
wallet: wallet,
accountsStore: &accountStore{},
}
// First, generate accounts and their keystore.json files.
ctx := context.Background()
numAccounts := 10
wantedPubKeys := make([][48]byte, 0)
for i := 0; i < numAccounts; i++ {
privKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := bytesutil.ToBytes48(privKey.PublicKey().Marshal())
wantedPubKeys = append(wantedPubKeys, pubKey)
dr.accountsStore.PublicKeys = append(dr.accountsStore.PublicKeys, pubKey[:])
dr.accountsStore.PrivateKeys = append(dr.accountsStore.PrivateKeys, privKey.Marshal())
}
require.NoError(t, dr.initializeKeysCachesFromKeystore())
publicKeys, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
assert.Equal(t, numAccounts, len(publicKeys))
// FetchValidatingPublicKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were derived
for i, key := range wantedPubKeys {
assert.Equal(t, key, publicKeys[i])
}
}
func TestImportedKeymanager_FetchValidatingPrivateKeys(t *testing.T) {
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
WalletPassword: password,
}
dr := &Keymanager{
wallet: wallet,
accountsStore: &accountStore{},
}
// First, generate accounts and their keystore.json files.
ctx := context.Background()
numAccounts := 10
wantedPrivateKeys := make([][32]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := bls.RandKey()
require.NoError(t, err)
privKeyData := privKey.Marshal()
pubKey := bytesutil.ToBytes48(privKey.PublicKey().Marshal())
wantedPrivateKeys[i] = bytesutil.ToBytes32(privKeyData)
dr.accountsStore.PublicKeys = append(dr.accountsStore.PublicKeys, pubKey[:])
dr.accountsStore.PrivateKeys = append(dr.accountsStore.PrivateKeys, privKeyData)
}
require.NoError(t, dr.initializeKeysCachesFromKeystore())
privateKeys, err := dr.FetchValidatingPrivateKeys(ctx)
require.NoError(t, err)
assert.Equal(t, numAccounts, len(privateKeys))
// FetchValidatingPrivateKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were created
for i, key := range wantedPrivateKeys {
assert.Equal(t, key, privateKeys[i])
}
}

View File

@@ -1,6 +1,7 @@
package imported
import (
"bytes"
"context"
"encoding/json"
"fmt"
@@ -12,11 +13,14 @@ import (
"github.com/prysmaticlabs/prysm/async/event"
"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/runtime/interop"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/petnames"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/sirupsen/logrus"
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
"go.opencensus.io/trace"
)
var (
@@ -25,15 +29,6 @@ var (
secretKeysCache = make(map[[48]byte]bls.SecretKey)
)
const (
// DerivationPathFormat describes the structure of how keys are derived from a master key.
DerivationPathFormat = "m / purpose / coin_type / account_index / withdrawal_key / validating_key"
// ValidatingKeyDerivationPathTemplate defining the hierarchical path for validating
// keys for Prysm Ethereum validators. According to EIP-2334, the format is as follows:
// m / purpose / coin_type / account_index / withdrawal_key / validating_key
ValidatingKeyDerivationPathTemplate = "m/12381/3600/%d/0/0"
)
const (
// KeystoreFileNameFormat exposes the filename the keystore should be formatted in.
KeystoreFileNameFormat = "keystore-%d.json"
@@ -88,12 +83,6 @@ func NewKeymanager(ctx context.Context, cfg *SetupConfig) (*Keymanager, error) {
accountsStore: &accountStore{},
accountsChangedFeed: new(event.Feed),
}
if strings.Contains(cfg.Wallet.AccountsDir(), "imported") ||
strings.Contains(cfg.Wallet.AccountsDir(), "derived") {
return nil, errors.New(
"keymanager kind found in wallet is not compatible as a local keymanager",
)
}
if err := k.initializeAccountKeystore(ctx); err != nil {
return nil, errors.Wrap(err, "failed to initialize account store")
@@ -107,8 +96,8 @@ func NewKeymanager(ctx context.Context, cfg *SetupConfig) (*Keymanager, error) {
return k, nil
}
// NewDeterministicKeymanager instantiates a new imported keymanager with the deterministically generated interop keys.
func NewDeterministicKeymanager(_ context.Context, offset, numValidatorKeys uint64) (*Keymanager, error) {
// NewInteropKeymanager instantiates a new imported keymanager with the deterministically generated interop keys.
func NewInteropKeymanager(_ context.Context, offset, numValidatorKeys uint64) (*Keymanager, error) {
k := &Keymanager{
accountsChangedFeed: new(event.Feed),
}
@@ -131,6 +120,13 @@ func NewDeterministicKeymanager(_ context.Context, offset, numValidatorKeys uint
return k, nil
}
// SubscribeAccountChanges creates an event subscription for a channel
// to listen for public key changes at runtime, such as when new validator accounts
// are imported into the keymanager while the validator process is running.
func (km *Keymanager) SubscribeAccountChanges(pubKeysChan chan [][48]byte) event.Subscription {
return km.accountsChangedFeed.Subscribe(pubKeysChan)
}
// ValidatingAccountNames for a imported keymanager.
func (km *Keymanager) ValidatingAccountNames() ([]string, error) {
lock.RLock()
@@ -142,6 +138,164 @@ func (km *Keymanager) ValidatingAccountNames() ([]string, error) {
return names, nil
}
// Initialize public and secret key caches that are used to speed up the functions
// FetchValidatingPublicKeys and Sign
func (km *Keymanager) initializeKeysCachesFromKeystore() error {
lock.Lock()
defer lock.Unlock()
count := len(km.accountsStore.PrivateKeys)
orderedPublicKeys = make([][48]byte, count)
secretKeysCache = make(map[[48]byte]bls.SecretKey, count)
for i, publicKey := range km.accountsStore.PublicKeys {
publicKey48 := bytesutil.ToBytes48(publicKey)
orderedPublicKeys[i] = publicKey48
secretKey, err := bls.SecretKeyFromBytes(km.accountsStore.PrivateKeys[i])
if err != nil {
return errors.Wrap(err, "failed to initialize keys caches from account keystore")
}
secretKeysCache[publicKey48] = secretKey
}
return nil
}
// DeleteAccounts takes in public keys and removes the accounts entirely. This includes their disk keystore and cached keystore.
func (km *Keymanager) DeleteAccounts(ctx context.Context, publicKeys [][]byte) error {
for _, publicKey := range publicKeys {
var index int
var found bool
for i, pubKey := range km.accountsStore.PublicKeys {
if bytes.Equal(pubKey, publicKey) {
index = i
found = true
break
}
}
if !found {
return fmt.Errorf("could not find public key %#x", publicKey)
}
deletedPublicKey := km.accountsStore.PublicKeys[index]
accountName := petnames.DeterministicName(deletedPublicKey, "-")
km.accountsStore.PrivateKeys = append(km.accountsStore.PrivateKeys[:index], km.accountsStore.PrivateKeys[index+1:]...)
km.accountsStore.PublicKeys = append(km.accountsStore.PublicKeys[:index], km.accountsStore.PublicKeys[index+1:]...)
newStore, err := km.CreateAccountsKeystore(ctx, km.accountsStore.PrivateKeys, km.accountsStore.PublicKeys)
if err != nil {
return errors.Wrap(err, "could not rewrite accounts keystore")
}
// Write the encoded keystore.
encoded, err := json.MarshalIndent(newStore, "", "\t")
if err != nil {
return err
}
if err := km.wallet.WriteFileAtPath(ctx, AccountsPath, AccountsKeystoreFileName, encoded); err != nil {
return errors.Wrap(err, "could not write keystore file for accounts")
}
log.WithFields(logrus.Fields{
"name": accountName,
"publicKey": fmt.Sprintf("%#x", bytesutil.Trunc(deletedPublicKey)),
}).Info("Successfully deleted validator account")
err = km.initializeKeysCachesFromKeystore()
if err != nil {
return errors.Wrap(err, "failed to initialize keys caches")
}
}
return nil
}
// FetchValidatingPublicKeys fetches the list of active public keys from the imported account keystores.
func (km *Keymanager) FetchValidatingPublicKeys(ctx context.Context) ([][48]byte, error) {
ctx, span := trace.StartSpan(ctx, "keymanager.FetchValidatingPublicKeys")
defer span.End()
lock.RLock()
keys := orderedPublicKeys
result := make([][48]byte, len(keys))
copy(result, keys)
lock.RUnlock()
return result, nil
}
// FetchValidatingPrivateKeys fetches the list of private keys from the secret keys cache
func (km *Keymanager) FetchValidatingPrivateKeys(ctx context.Context) ([][32]byte, error) {
lock.RLock()
defer lock.RUnlock()
privKeys := make([][32]byte, len(secretKeysCache))
pubKeys, err := km.FetchValidatingPublicKeys(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve public keys")
}
for i, pk := range pubKeys {
seckey, ok := secretKeysCache[pk]
if !ok {
return nil, errors.New("Could not fetch private key")
}
privKeys[i] = bytesutil.ToBytes32(seckey.Marshal())
}
return privKeys, nil
}
// Sign signs a message using a validator key.
func (km *Keymanager) Sign(ctx context.Context, req *validatorpb.SignRequest) (bls.Signature, error) {
ctx, span := trace.StartSpan(ctx, "keymanager.Sign")
defer span.End()
publicKey := req.PublicKey
if publicKey == nil {
return nil, errors.New("nil public key in request")
}
lock.RLock()
secretKey, ok := secretKeysCache[bytesutil.ToBytes48(publicKey)]
lock.RUnlock()
if !ok {
return nil, errors.New("no signing key found in keys cache")
}
return secretKey.Sign(req.SigningRoot), nil
}
func (km *Keymanager) initializeAccountKeystore(ctx context.Context) error {
encoded, err := km.wallet.ReadFileAtPath(ctx, AccountsPath, AccountsKeystoreFileName)
if err != nil && strings.Contains(err.Error(), "no files found") {
// If there are no keys to initialize at all, just exit.
return nil
} else if err != nil {
return errors.Wrapf(err, "could not read keystore file for accounts %s", AccountsKeystoreFileName)
}
keystoreFile := &AccountsKeystoreRepresentation{}
if err := json.Unmarshal(encoded, keystoreFile); err != nil {
return errors.Wrapf(err, "could not decode keystore file for accounts %s", AccountsKeystoreFileName)
}
// We extract the validator signing private key from the keystore
// by utilizing the password and initialize a new BLS secret key from
// its raw bytes.
password := km.wallet.Password()
decryptor := keystorev4.New()
enc, err := decryptor.Decrypt(keystoreFile.Crypto, password)
if err != nil && strings.Contains(err.Error(), keymanager.IncorrectPasswordErrMsg) {
return errors.Wrap(err, "wrong password for wallet entered")
} else if err != nil {
return errors.Wrap(err, "could not decrypt keystore")
}
store := &accountStore{}
if err := json.Unmarshal(enc, store); err != nil {
return err
}
if len(store.PublicKeys) != len(store.PrivateKeys) {
return errors.New("unequal number of public keys and private keys")
}
if len(store.PublicKeys) == 0 {
return nil
}
km.accountsStore = store
err = km.initializeKeysCachesFromKeystore()
if err != nil {
return errors.Wrap(err, "failed to initialize keys caches")
}
return err
}
// CreateAccountsKeystore creates a new keystore holding the provided keys.
func (km *Keymanager) CreateAccountsKeystore(
_ context.Context,
@@ -202,65 +356,3 @@ func (km *Keymanager) CreateAccountsKeystore(
Name: encryptor.Name(),
}, nil
}
// Initialize public and secret key caches that are used to speed up the functions
// FetchValidatingPublicKeys and Sign
func (km *Keymanager) initializeKeysCachesFromKeystore() error {
lock.Lock()
defer lock.Unlock()
count := len(km.accountsStore.PrivateKeys)
orderedPublicKeys = make([][48]byte, count)
secretKeysCache = make(map[[48]byte]bls.SecretKey, count)
for i, publicKey := range km.accountsStore.PublicKeys {
publicKey48 := bytesutil.ToBytes48(publicKey)
orderedPublicKeys[i] = publicKey48
secretKey, err := bls.SecretKeyFromBytes(km.accountsStore.PrivateKeys[i])
if err != nil {
return errors.Wrap(err, "failed to initialize keys caches from account keystore")
}
secretKeysCache[publicKey48] = secretKey
}
return nil
}
func (km *Keymanager) initializeAccountKeystore(ctx context.Context) error {
encoded, err := km.wallet.ReadFileAtPath(ctx, AccountsPath, AccountsKeystoreFileName)
if err != nil && strings.Contains(err.Error(), "no files found") {
// If there are no keys to initialize at all, just exit.
return nil
} else if err != nil {
return errors.Wrapf(err, "could not read keystore file for accounts %s", AccountsKeystoreFileName)
}
keystoreFile := &AccountsKeystoreRepresentation{}
if err := json.Unmarshal(encoded, keystoreFile); err != nil {
return errors.Wrapf(err, "could not decode keystore file for accounts %s", AccountsKeystoreFileName)
}
// We extract the validator signing private key from the keystore
// by utilizing the password and initialize a new BLS secret key from
// its raw bytes.
password := km.wallet.Password()
decryptor := keystorev4.New()
enc, err := decryptor.Decrypt(keystoreFile.Crypto, password)
if err != nil && strings.Contains(err.Error(), keymanager.IncorrectPasswordErrMsg) {
return errors.Wrap(err, "wrong password for wallet entered")
} else if err != nil {
return errors.Wrap(err, "could not decrypt keystore")
}
store := &accountStore{}
if err := json.Unmarshal(enc, store); err != nil {
return err
}
if len(store.PublicKeys) != len(store.PrivateKeys) {
return errors.New("unequal number of public keys and private keys")
}
if len(store.PublicKeys) == 0 {
return nil
}
km.accountsStore = store
err = km.initializeKeysCachesFromKeystore()
if err != nil {
return errors.Wrap(err, "failed to initialize keys caches")
}
return err
}

View File

@@ -1 +1,218 @@
package imported
import (
"context"
"encoding/json"
"fmt"
"strings"
"testing"
"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
mock "github.com/prysmaticlabs/prysm/validator/accounts/testing"
"github.com/prysmaticlabs/prysm/validator/keymanager"
logTest "github.com/sirupsen/logrus/hooks/test"
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
)
func TestImportedKeymanager_RemoveAccounts(t *testing.T) {
hook := logTest.NewGlobal()
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
WalletPassword: password,
}
dr := &Keymanager{
wallet: wallet,
accountsStore: &accountStore{},
}
numAccounts := 5
ctx := context.Background()
keystores := make([]*keymanager.Keystore, numAccounts)
for i := 0; i < numAccounts; i++ {
keystores[i] = createRandomKeystore(t, password)
}
require.NoError(t, dr.ImportKeystores(ctx, keystores, password))
accounts, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
require.Equal(t, numAccounts, len(accounts))
accountToRemove := uint64(2)
accountPubKey := accounts[accountToRemove]
// Remove an account from the keystore.
require.NoError(t, dr.DeleteAccounts(ctx, [][]byte{accountPubKey[:]}))
// Ensure the keystore file was written to the wallet
// and ensure we can decrypt it using the EIP-2335 standard.
var encodedKeystore []byte
for k, v := range wallet.Files[AccountsPath] {
if strings.Contains(k, "keystore") {
encodedKeystore = v
}
}
require.NotNil(t, encodedKeystore, "could not find keystore file")
keystoreFile := &keymanager.Keystore{}
require.NoError(t, json.Unmarshal(encodedKeystore, keystoreFile))
// We extract the accounts from the keystore.
decryptor := keystorev4.New()
encodedAccounts, err := decryptor.Decrypt(keystoreFile.Crypto, password)
require.NoError(t, err, "Could not decrypt validator accounts")
store := &accountStore{}
require.NoError(t, json.Unmarshal(encodedAccounts, store))
require.Equal(t, numAccounts-1, len(store.PublicKeys))
require.Equal(t, numAccounts-1, len(store.PrivateKeys))
require.LogsContain(t, hook, fmt.Sprintf("%#x", bytesutil.Trunc(accountPubKey[:])))
require.LogsContain(t, hook, "Successfully deleted validator account")
}
func TestImportedKeymanager_FetchValidatingPublicKeys(t *testing.T) {
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
WalletPassword: password,
}
dr := &Keymanager{
wallet: wallet,
accountsStore: &accountStore{},
}
// First, generate accounts and their keystore.json files.
ctx := context.Background()
numAccounts := 10
wantedPubKeys := make([][48]byte, 0)
for i := 0; i < numAccounts; i++ {
privKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := bytesutil.ToBytes48(privKey.PublicKey().Marshal())
wantedPubKeys = append(wantedPubKeys, pubKey)
dr.accountsStore.PublicKeys = append(dr.accountsStore.PublicKeys, pubKey[:])
dr.accountsStore.PrivateKeys = append(dr.accountsStore.PrivateKeys, privKey.Marshal())
}
require.NoError(t, dr.initializeKeysCachesFromKeystore())
publicKeys, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
assert.Equal(t, numAccounts, len(publicKeys))
// FetchValidatingPublicKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were derived
for i, key := range wantedPubKeys {
assert.Equal(t, key, publicKeys[i])
}
}
func TestImportedKeymanager_FetchValidatingPrivateKeys(t *testing.T) {
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
WalletPassword: password,
}
dr := &Keymanager{
wallet: wallet,
accountsStore: &accountStore{},
}
// First, generate accounts and their keystore.json files.
ctx := context.Background()
numAccounts := 10
wantedPrivateKeys := make([][32]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := bls.RandKey()
require.NoError(t, err)
privKeyData := privKey.Marshal()
pubKey := bytesutil.ToBytes48(privKey.PublicKey().Marshal())
wantedPrivateKeys[i] = bytesutil.ToBytes32(privKeyData)
dr.accountsStore.PublicKeys = append(dr.accountsStore.PublicKeys, pubKey[:])
dr.accountsStore.PrivateKeys = append(dr.accountsStore.PrivateKeys, privKeyData)
}
require.NoError(t, dr.initializeKeysCachesFromKeystore())
privateKeys, err := dr.FetchValidatingPrivateKeys(ctx)
require.NoError(t, err)
assert.Equal(t, numAccounts, len(privateKeys))
// FetchValidatingPrivateKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were created
for i, key := range wantedPrivateKeys {
assert.Equal(t, key, privateKeys[i])
}
}
func TestImportedKeymanager_Sign(t *testing.T) {
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: password,
}
dr := &Keymanager{
wallet: wallet,
accountsStore: &accountStore{},
}
// First, generate accounts and their keystore.json files.
ctx := context.Background()
numAccounts := 10
keystores := make([]*keymanager.Keystore, numAccounts)
for i := 0; i < numAccounts; i++ {
keystores[i] = createRandomKeystore(t, password)
}
require.NoError(t, dr.ImportKeystores(ctx, keystores, password))
var encodedKeystore []byte
for k, v := range wallet.Files[AccountsPath] {
if strings.Contains(k, "keystore") {
encodedKeystore = v
}
}
keystoreFile := &keymanager.Keystore{}
require.NoError(t, json.Unmarshal(encodedKeystore, keystoreFile))
// We extract the validator signing private key from the keystore
// by utilizing the password and initialize a new BLS secret key from
// its raw bytes.
decryptor := keystorev4.New()
enc, err := decryptor.Decrypt(keystoreFile.Crypto, dr.wallet.Password())
require.NoError(t, err)
store := &accountStore{}
require.NoError(t, json.Unmarshal(enc, store))
require.Equal(t, len(store.PublicKeys), len(store.PrivateKeys))
require.NotEqual(t, 0, len(store.PublicKeys))
dr.accountsStore = store
require.NoError(t, dr.initializeKeysCachesFromKeystore())
publicKeys, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
require.Equal(t, len(publicKeys), len(store.PublicKeys))
// We prepare naive data to sign.
data := []byte("hello world")
signRequest := &validatorpb.SignRequest{
PublicKey: publicKeys[0][:],
SigningRoot: data,
}
sig, err := dr.Sign(ctx, signRequest)
require.NoError(t, err)
pubKey, err := bls.PublicKeyFromBytes(publicKeys[0][:])
require.NoError(t, err)
wrongPubKey, err := bls.PublicKeyFromBytes(publicKeys[1][:])
require.NoError(t, err)
if !sig.Verify(pubKey, data) {
t.Fatalf("Expected sig to verify for pubkey %#x and data %v", pubKey.Marshal(), data)
}
if sig.Verify(wrongPubKey, data) {
t.Fatalf("Expected sig not to verify for pubkey %#x and data %v", wrongPubKey.Marshal(), data)
}
}
func TestImportedKeymanager_Sign_NoPublicKeySpecified(t *testing.T) {
req := &validatorpb.SignRequest{
PublicKey: nil,
}
dr := &Keymanager{}
_, err := dr.Sign(context.Background(), req)
assert.ErrorContains(t, "nil public key", err)
}
func TestImportedKeymanager_Sign_NoPublicKeyInCache(t *testing.T) {
req := &validatorpb.SignRequest{
PublicKey: []byte("hello world"),
}
secretKeysCache = make(map[[48]byte]bls.SecretKey)
dr := &Keymanager{}
_, err := dr.Sign(context.Background(), req)
assert.ErrorContains(t, "no signing key found in keys cache", err)
}

View File

@@ -1,34 +0,0 @@
package imported
import (
"context"
"fmt"
"github.com/pkg/errors"
util "github.com/wealdtech/go-eth2-util"
)
// RecoverKeystoresFromMnemonic given a mnemonic phrase, is able to regenerate N accounts
// from a derived seed, encrypt them according to the EIP-2334 JSON standard, and write them
// to disk. Then, the mnemonic is never stored nor used by the validator.
func (km *Keymanager) RecoverKeystoresFromMnemonic(
ctx context.Context, mnemonic, mnemonicPassphrase string, numAccounts int,
) error {
seed, err := seedFromMnemonic(mnemonic, mnemonicPassphrase)
if err != nil {
return errors.Wrap(err, "could not initialize new wallet seed file")
}
privKeys := make([][]byte, numAccounts)
pubKeys := make([][]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := util.PrivateKeyFromSeedAndPath(
seed, fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i),
)
if err != nil {
return err
}
privKeys[i] = privKey.Marshal()
pubKeys[i] = privKey.PublicKey().Marshal()
}
return nil
}

View File

@@ -1,68 +0,0 @@
package imported
import (
"context"
"testing"
"github.com/prysmaticlabs/prysm/crypto/rand"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
mock "github.com/prysmaticlabs/prysm/validator/accounts/testing"
constant "github.com/prysmaticlabs/prysm/validator/testing"
"github.com/tyler-smith/go-bip39"
)
// We test that using a '25th word' mnemonic passphrase leads to different
// public keys derived than not specifying the passphrase.
func TestImportedKeymanager_Recover_25Words(t *testing.T) {
ctx := context.Background()
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: password,
}
km, err := NewKeymanager(ctx, &SetupConfig{
Wallet: wallet,
ListenForChanges: false,
})
require.NoError(t, err)
numAccounts := 5
err = km.RecoverKeystoresFromMnemonic(ctx, constant.TestMnemonic, "mnemonicpass", numAccounts)
require.NoError(t, err)
without25thWord, err := km.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
wallet = &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: password,
}
km, err = NewKeymanager(ctx, &SetupConfig{
Wallet: wallet,
ListenForChanges: false,
})
require.NoError(t, err)
// No mnemonic passphrase this time.
err = km.RecoverKeystoresFromMnemonic(ctx, constant.TestMnemonic, "", numAccounts)
require.NoError(t, err)
with25thWord, err := km.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
for i, k := range with25thWord {
without := without25thWord[i]
assert.DeepNotEqual(t, k, without)
}
}
func TestImportedKeymanager_Recover_RoundTrip(t *testing.T) {
mnemonicEntropy := make([]byte, 32)
n, err := rand.NewGenerator().Read(mnemonicEntropy)
require.NoError(t, err)
require.Equal(t, n, len(mnemonicEntropy))
mnemonic, err := bip39.NewMnemonic(mnemonicEntropy)
require.NoError(t, err)
wanted := bip39.NewSeed(mnemonic, "")
got, err := seedFromMnemonic(mnemonic, "" /* no passphrase */)
require.NoError(t, err)
// Ensure the derived seed matches.
assert.DeepEqual(t, wanted, got)
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/async"
"github.com/prysmaticlabs/prysm/async/event"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/crypto/bls"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
@@ -18,13 +17,6 @@ import (
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
)
// SubscribeAccountChanges creates an event subscription for a channel
// to listen for public key changes at runtime, such as when new validator accounts
// are imported into the keymanager while the validator process is running.
func (km *Keymanager) SubscribeAccountChanges(pubKeysChan chan [][48]byte) event.Subscription {
return km.accountsChangedFeed.Subscribe(pubKeysChan)
}
// Listen for changes to the all-accounts.keystore.json file in our wallet
// to load in new keys we observe into our keymanager. This uses the fsnotify
// library to listen for file-system changes and debounces these events to

Some files were not shown because too many files have changed in this diff Show More