Compare commits

...

96 Commits

Author SHA1 Message Date
Potuz
94768a3190 Added AVX tests 2021-11-19 15:26:06 -03:00
Potuz
662d4ec6e9 First Benchmarks with Shani 2021-11-19 10:03:12 -03:00
Potuz
b206bffe15 flat array merkleyzer 2021-11-18 22:16:03 -03:00
Potuz
18b83bf445 add SSE3 version for 2 chunks 2021-11-17 11:16:08 -03:00
Potuz
cff4a01ea0 add AVX2 version 2021-11-17 11:08:02 -03:00
Potuz
3a1901d7aa Working custom assembly hasher with sha_ni extensions 2021-11-17 10:58:31 -03: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
Raul Jordan
6e731bdedd Implement List Keystores for Standard API (#9863)
* start api

* keystores list

* gaz

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-11-08 19:08:17 +00:00
Dan Loewenherz
40eb718ba2 Fix typos: repones -> response, attestion -> attestation (#9868)
* Fix typo: repones -> response

* Fix typo: attestion -> attestation
2021-11-07 11:02:01 -06:00
terence tsao
e1840f7523 Share finalized state at start up (#9843)
* Reuse finalized beacon state at startup

* Better logging for replay

* Update tests

* Fix lint

* Add `WithFinalizedStateAtStartup`

* Update service.go

* Remove unused fields

* Update service_test.go

* Update service_test.go

* Update service_test.go

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-06 13:45:16 +00:00
terence tsao
b07e1ba7a4 GenesisState when zero hash tests (#9866) 2021-11-06 06:57:54 +01:00
Raul Jordan
233171d17c [Service Config Revamp] - Sync Service With Functional Options (#9859)
* sync config refactor

* rem

* rem

* testing

* gaz

* next

* fuzz

* build

* fuzz

* rev

* log

* cfg
2021-11-05 19:08:58 +00:00
kasey
2b0e132201 fix #9851 using GenesisState when zero hash in stategen StateByRoot/StateByRootInitialSync (#9852)
Co-authored-by: Kasey Kirkham <kasey@users.noreply.github.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-11-05 18:14:37 +00:00
Raul Jordan
ad9e5331f5 Update Prysm Web to Use v1.0.1 (#9858)
* update web

* site data update

* fmt
2021-11-04 16:12:32 -04:00
terence tsao
341a2f1ea3 Use math.MaxUint64 (#9857)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-04 18:48:09 +00:00
Raul Jordan
7974fe01cd [Service Revamp] - Powchain Service With Functional Options (#9856)
* begin powchain service refactor

* begin refactor

* powchain passes

* options pkg

* gaz

* rev

* rev

* comments

* move to right place

* bazel powchain

* fix test

* log

* contract addr

* happy path and comments

* gaz

* new service
2021-11-04 14:19:44 -04:00
Raul Jordan
ae56f643eb Rename Web UI Performance Endpoint to Summary (#9855)
* rename endpoint

* rename endpoint
2021-11-04 15:13:16 +00:00
terence tsao
2ea09b621e Simplify should update justified (#9837)
* Simplify should update justified

* Update tests

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-03 22:29:03 +00:00
terence tsao
40fedee137 Use prev epoch source naming correctly (#9840)
* Use prev epoch source correctly

* Update epoch_precompute_test.go

* Update type.go

* Update tests

* Gazelle

* Move version to read only

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-11-03 21:50:41 +00:00
kasey
7cdddcb015 Weak subjectivity verification refactor (#9832)
* weak subjectivity verification refactor

This separates weak subjectivity verification into a
distinct type which does not have a dependency on
blockchain.Service

* remove unused variable

* saving enqueued init blocks before ws verify

* remove TODO, handled in previous commit

* accept suggested comment change

start comment w/ name of function NewWeakSubjectivityVerifier

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

* update log w/ Raul's suggested language

* explicit zero value for clarity

* add comments clarifying how we adhere to spec

* more clear TODO per Raul's feedback

* gofmt

Co-authored-by: kasey <kasey@users.noreply.github.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-11-03 15:07:46 +00:00
Raul Jordan
4440ac199f Empty Genesis Validators Root Check in Slashing Protection Export (#9849)
* test for empty genesis validators root

* precod

* fix test

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-03 14:16:57 +00:00
Radosław Kapka
d78428c49e Return proper responses from KeyManagement service (#9846)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-02 15:46:11 +00:00
Raul Jordan
2e45fada34 Validate Password on RPC CreateWallet Request (#9848)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-02 15:20:43 +00:00
Raul Jordan
4c18d291f4 Rename Interop-Cold-Start Package to Deterministic-Genesis (#9841)
* rename interop-cold-start

* rev

* rev

* BUILD

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-02 14:55:36 +00:00
Preston Van Loon
dfe33b0770 stateutil: Remove duplicated MerkleizeTrieLeaves method (#9847) 2021-11-02 14:31:16 +00:00
Raul Jordan
63308239d9 Define Validator Key Management Standard API Schema (#9817)
* begin service for key management

* begin defining schema

* generate bindings

* rev

* add in custom compiler

* use custom plugin with option

* goimports

* fix up proto to take in multiple passwords

* keymanagent proto edit

* rev

* rev

* dev

* builds

* comment

* indent

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-01 17:26:15 +00:00
terence tsao
712cc18ee0 Use BeaconBlockIsNil helper more (#9834)
* Replace manual checks with helper

* Rename to `BeaconBlockIsNil`

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-11-01 14:13:05 +00:00
Nishant Das
3d318cffa2 Fix Individual Votes RPC Endpoint (#9831)
* fix

* fix tests

* add terence's review

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-11-01 18:36:08 +08:00
terence tsao
026207fc16 Remove de-duplication condition for seen aggregates (#9830)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-29 21:53:49 +00:00
Raul Jordan
6b7b30ce47 Use GET Request for Slashing Protection Export (#9838) 2021-10-29 18:23:45 +00:00
Yash Bhutwala
105bb70b5e remove extra condition (#9836) 2021-10-29 09:29:33 -07:00
Potuz
9564ab1f7f Fix validator performance logs (#9828)
* Fix validator performance logs

* Add test

* Clean both phase 0 and altair calculations

* Add back total inclusion distance

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-10-28 16:56:27 +00:00
Raul Jordan
0b09e3e955 Refresh Web Backend JWT Secret Upon File Changes With FSNotify (#9810)
* refresh auth file

* refresh auth token from file changes

* gaz

* test for refresh

* rem token

* secret

* refresh

* remove wallet dir on test end
2021-10-28 10:24:39 -04:00
Radosław Kapka
bb319e02e8 Event support for contribution_and_proof and voluntary_exit (#9779)
* Event support for `contribution_and_prrof`

* event test

* fix panic in tests

* fix

* Revert "Auxiliary commit to revert individual files from dc8d01a15f0056c1fb48733219feab6461f71695"

This reverts commit f5f198564079781f80e1a045cefad7c27f89af25.

* remove receiver

* revive test

* move sending events to sync package

* remove receiver

* remove notification test

* build file

* notifier tests

* revert removal of exit event in API

* simplify exit test

* send notification in contribution API method

* test fix

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-10-28 08:56:22 +00:00
terence tsao
53c86429e4 Add altair test for RPC end point (#9829) 2021-10-27 21:00:09 -04:00
Raul Jordan
61172d5007 Add Missing Objects to Keymanager Protobuf (#9827)
* add missing objects

* update keymanager

* fix up missing sign calls

* gaz

* msg block root

* naming
2021-10-27 18:30:53 +00:00
Yash Bhutwala
1507719613 fix altair individual votes endpoint (#9825) 2021-10-27 15:15:51 +00:00
Raul Jordan
4c677e7b40 Remove JWT Expiration (#9813)
* remove expiry from claims

* fix tests

* gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-26 10:24:09 +00:00
Raul Jordan
28f50862cb Goimport All Items in Proto Folder In Bash Script (#9815)
* update goimports to format all, including gw.pb.go files

* update hack

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-26 10:07:49 +00:00
Nishant Das
2dfb0696f7 Fix Validator Exit in our V1 Method (#9819) 2021-10-26 10:14:11 +02:00
terence tsao
ae2c883aaf Generate secret key from big number test only (#9816)
* Generate secret key from big number test only

* Gazelle

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-10-25 19:14:19 +00:00
Raul Jordan
ad9ef9d803 Simplify Prysm Backend Password Requirements (#9814)
* simpler reqs

* gaz

* tidy mod
2021-10-25 13:17:47 -05:00
Kirill Fedoseev
b837f90b35 Fix GetDuties (#9811)
* Fix GetDuties

* Add regression test
2021-10-25 09:09:47 -05:00
Håvard Anda Estensen
7f3ec4221f Add errcheck and gosimple linters (#9729)
* Add errcheck linter

* Check unchecked error

* Add gosimple linter

* Remove type assertion to same type

* Omit nil check

len() for nil slices is defined as zero

* Revert "Remove type assertion to same type"

This reverts commit af69ca1ac8.

* Revert "Revert "Remove type assertion to same type""

This reverts commit 5fe8931504.

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-10-22 17:40:03 -05:00
Radosław Kapka
5b3375638a Improve description of datadir flag (#9809)
* Improve description of `datadir` flag

* improve doc
2021-10-22 12:53:13 +00:00
terence tsao
3c721418db Check participation flag offset length (#9784)
* Check participation flag offset length

* Fix test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-10-21 15:01:09 +00:00
terence tsao
d7cad27cc3 Pool returns empty contribution slice instead of nil (#9808) 2021-10-20 14:45:57 -07:00
terence tsao
290b4273dd InitializePrecomputeValidators check overflows (#9807) 2021-10-20 13:06:43 -05:00
Raul Jordan
a797a7aaac Refactor Web Authentication to Use Auth Token (#9740)
* builds

* initialize auth token from scratch

* change auth

* add improvements

* moar auth fixes

* web auth changes running

* url encode

* tests

* gaz

* navigate auth

* separate line

* auth token

* 304

* persistent auth tokens and jwts

* fixed up test

* auth token path test and integration test

* auth token test

* auth token command

* gaz

* gaz

* Radek feedback

* fix up

* test

* Update validator/rpc/auth_token.go

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

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-10-20 16:37:05 +00:00
Raul Jordan
f7c34b0fd6 Validate Keystores Validator Client RPC Endpoint (#9799)
* validate endpoint

* validate keystores proto

* wallet validate

* validate keystores endpoint

* better err message

* added in gaz
2021-10-20 09:23:59 -05:00
Nishant Das
c6874e33f7 fix transitions (#9804) 2021-10-20 19:36:08 +08:00
Radosław Kapka
13ddc171eb Ignore validators without committee assignment when fetching attester duties (#9780)
* Ignore validators without committee assignment when fetching attester duties

* simplify

* fix tests

* slice capacity

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-10-19 17:41:12 +00:00
Radosław Kapka
acde184aa7 Fill out Version for SSZ block (#9801) 2021-10-19 16:45:38 +00:00
Radosław Kapka
5fd6474e56 Allow submitting sync committee subscriptions for next period (#9798)
Co-authored-by: terence tsao <terence@prysmaticlabs.com>
2021-10-19 14:04:04 +00:00
Preston Van Loon
65db331eaf Remove bazel-go-ethereum fork, use upstream go-ethereum (#9725)
* Check in go-ethereum crypto/sepc256k1 package with proper build rules

* gaz

* Add karalabe/usb

* viz improvement

* Remove bazel-go-ethereum, use vendored libraries only

* move vendor stuff to third_party so that go mod wont be mad anymore

* fix geth e2e flags

* fix geth e2e flags

* remove old rules_foreign_cc toolchain

* Update cross compile docker image to support os x

* works for geth build

* remove copy of sepc256k1

* revert changes in tools/cross-toolchain

* gaz

* Update go-ethereum to 1.10.10

* Revert "revert changes in tools/cross-toolchain"

This reverts commit 2e8128f7c3.

* revert tags changes

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-19 00:00:22 +00:00
Radosław Kapka
7b8aedbfe4 Update Beacon API to v2.1.0 (#9797)
* `Eth-Consensus-Version` header

* rename unused receiver

* omit receiver name

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-18 18:55:18 +00:00
terence tsao
cf956c718d Update to Spectest 1.1.3 (#9786)
* Update transition spec test setup

* Update WORKSPACE

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-10-18 18:13:40 +00:00
Raul Jordan
975f0ea1af [Service Config Revamp] - Blockchain Initialization (#9783)
* viz

* unexport config

* builds

* viz

* viz

* register cfg

* fuzz

* blockchain opts

* deepsource

* rename flag opts
2021-10-18 17:48:05 +00:00
terence tsao
a80b1c252a Refactor rpc proposer into smaller files (#9796)
* Refactor rpc proposer into smaller files

* Update BUILD.bazel

* Fix test

* Update BUILD.bazel
2021-10-18 11:35:32 -05:00
Preston Van Loon
1f51e59bfd Bazel: minimal build config alias (#9794) 2021-10-18 14:22:57 +00:00
Nishant Das
bfcb113f78 Fix Doppelganger Protection (#9748)
* add fix

* fix tests

* Update beacon-chain/rpc/prysm/v1alpha1/validator/status.go

* fix tests

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-18 13:09:14 +00:00
terence tsao
20c7efda2c Process slashings return error on unknown state (#9778)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-18 12:40:47 +00:00
Radosław Kapka
f2990d8fdd Return errors for unknown block/state versions (#9781)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-18 12:18:49 +00:00
Nishant Das
d1f3050d20 Ignore G307 for Gosec (#9790) 2021-10-18 14:04:01 +02:00
Raul Jordan
4dbb5d6974 Add WebUI Security Headers (#9775) 2021-10-15 12:40:23 +02:00
Raul Jordan
59547aea66 Deregister Remote Slashing Protection Until Further Notice (#9774)
* avoid registering

* disable endpoints

* remote slasher protection register

* gaz

* fatal on external protection flag call

* radek comment

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-14 19:33:05 +00:00
Radosław Kapka
545424dd09 Fix epoch calculation when fetching sync committee duties (#9767)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-10-14 18:52:26 +00:00
Nishant Das
508b18f1bd Return Error For Batch Verifier (#9766)
* fix it

* make err check happy

* radek's review

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-13 23:52:22 +00:00
Radosław Kapka
e644e6b626 Remove special preparation of graffiti (#9770)
* add attestations to migration tests

* remove sepcial preparation of graffiti

* Revert "add attestations to migration tests"

This reverts commit adbe8cf4bf.
2021-10-13 15:32:15 +00:00
Radosław Kapka
280dc4ecf0 Register v1alpha2 endpoints in the gateway (#9768)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-10-12 15:13:52 +00:00
terence tsao
7a825a79ae E2e test: stricter participation check (#9718)
* Stricter participation check

* 0.99 is still better than 0.95...

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-10-12 11:32:36 +00:00
Nishant Das
b81f5fc7a5 Handle Invalid Number Of Leaves (#9761)
* fix bad trie

* handle edge case

* radek's review

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-10-12 10:36:57 +00:00
Nishant Das
06c084ff52 Log out Gossip Handling Errors (#9765) 2021-10-12 07:44:47 +00:00
Preston Van Loon
76e06438e9 Update bazel version to 4.x (#9763)
* Update to bazel 4.0.0

* bazel 4.2.1

* Regenerate crosstool configs

* restore manual tags

* restore manual tags
2021-10-12 06:17:24 +00:00
Nishant Das
f8f037b63d updateInterval (#9764) 2021-10-11 22:12:07 -05:00
terence tsao
f114a47b5b Improve "synced block.." log (#9760) 2021-10-09 15:27:34 +02:00
Nishant Das
65d2df4609 Add in Stronger Length Checks (#9758)
* add changes

* radek's review

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-10-08 17:41:36 +00:00
Radosław Kapka
63349d863b Do not return data for validators without sync duties (#9756)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2021-10-08 15:20:40 +00:00
Nishant Das
e2a00d3e2e Update to v1.1.2 version of the Spec (#9755) 2021-10-08 15:08:57 +02:00
terence tsao
271ee2ed32 Cleanup slot helpers into intended locations (#9752)
* Refactor slot time helpers to intended locations

* Gazelle

* Update beacon-chain/core/time/slot_epoch.go

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

* Update beacon-chain/core/time/slot_epoch_test.go

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

* Go fmt

* Update transition_fuzz_test.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2021-10-07 19:15:35 +00:00
Radosław Kapka
b5f0bd88b0 Add sync details to error messages (#9750) 2021-10-07 20:50:03 +02:00
terence tsao
e7085897ad Use BLS signature length config value (#9746)
* Use `BeaconConfig().BLSSignatureLength`

* Update BUILD.bazel

* Fix build

* Update BUILD.bazel
2021-10-07 10:37:53 -05:00
Raul Jordan
d9b98e9913 Health Endpoints Not Registered in Validator gRPC Gateway Fix (#9747) 2021-10-06 19:07:29 +00:00
terence tsao
a9f9026c78 Minor cleanups (#9743)
* Minor cleanups

* Delete slasher client files

* Revert "Delete slasher client files"

This reverts commit 0c995a1d4a.

* Update slasher_client.go
2021-10-06 13:23:40 -05:00
Nishant Das
b128d446f2 Bring Eth2FastAggregateVerify Inline With the Spec (#9742)
* fix

* tie it closer to the spec
2021-10-06 10:48:56 +08:00
Radosław Kapka
9aa50352b6 Allow fetching sync committee duties for current and next period's epochs (#9728) 2021-10-05 08:46:16 -07:00
Mohamed Zahoor
362dfa691a GetBlock() - Simple optimisations (#9541)
* GetBlock() optimizations

* addressed preston's comments

* fix fmt

* added benchmarks

* fix deepsource

* merge fix

* remove unnesesary check

* fixed terence's comments

* Update beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go

Co-authored-by: Nishant Das <nishdas93@gmail.com>

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
2021-10-05 17:28:02 +08:00
402 changed files with 14967 additions and 6571 deletions

View File

@@ -36,6 +36,9 @@ run --define blst_disabled=false
build:blst_disabled --define blst_disabled=true
build:blst_disabled --define gotags=blst_disabled
build:minimal --//proto:network=minimal
build:minimal --@io_bazel_rules_go//go/config:tags=minimal
# Release flags
build:release --compilation_mode=opt
build:release --config=llvm

View File

@@ -1 +1 @@
3.7.0
4.2.1

View File

@@ -34,12 +34,12 @@ jobs:
- name: Gosec security scanner
uses: securego/gosec@master
with:
args: '-exclude-dir=crypto/bls/herumi ./...'
args: '-exclude=G307 -exclude-dir=crypto/bls/herumi ./...'
- name: Golangci-lint
uses: golangci/golangci-lint-action@v2
with:
args: --print-issued-lines --sort-results --no-config --timeout=10m --disable-all -E deadcode --skip-files=validator/web/site_data.go
args: --print-issued-lines --sort-results --no-config --timeout=10m --disable-all -E deadcode -E errcheck -E gosimple --skip-files=validator/web/site_data.go
build:
name: Build

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

@@ -144,12 +144,6 @@ common_files = {
"//:README.md": "README.md",
}
toolchain(
name = "built_cmake_toolchain",
toolchain = "@rules_foreign_cc//tools/build_defs/native_tools:built_cmake",
toolchain_type = "@rules_foreign_cc//tools/build_defs:cmake_toolchain",
)
string_setting(
name = "gotags",
build_setting_default = "",

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.0"
consensus_spec_version = "v1.1.5"
bls_test_version = "v0.1.1"
@@ -241,7 +241,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "0f58ec1c8995ab2c0a3aada873e1a02f333c8659fdacaa1c76fbdce28b6177dc",
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 = "d2eeadef3f8885748f769a06eb916bea60fb00112a90cec3288ea78db5557df3",
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 = "bbc345432f4eaa4babe2619e16fcf3f607113ede82d1bd0fff2633c1376419f7",
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 = "787a50c2a03bebab92f089333f598780ca7b4849b36a4897e6603ddd3e86ec24",
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,
)
@@ -362,9 +362,9 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "54ce527b83d092da01127f2e3816f4d5cfbab69354caba8537f1ea55889b6d7c",
sha256 = "0a3d94428ea28916276694c517b82b364122063fdbf924f54ee9ae0bc500289f",
urls = [
"https://github.com/prysmaticlabs/prysm-web-ui/releases/download/v1.0.0-beta.4/prysm-web-ui.tar.gz",
"https://github.com/prysmaticlabs/prysm-web-ui/releases/download/v1.0.1/prysm-web-ui.tar.gz",
],
)
@@ -395,10 +395,6 @@ load(
_cc_image_repos()
load("@com_github_ethereum_go_ethereum//:deps.bzl", "geth_dependencies")
geth_dependencies()
load("@io_bazel_rules_go//extras:embed_data_deps.bzl", "go_embed_data_dependencies")
go_embed_data_dependencies()

View File

@@ -125,12 +125,12 @@ func (m *ApiProxyMiddleware) handleApiPath(gatewayRouter *mux.Router, path strin
var respJson []byte
if !GrpcResponseIsEmpty(grpcRespBody) {
if errJson := DeserializeGrpcResponseBodyIntoErrorJson(endpoint.Err, grpcRespBody); errJson != nil {
respHasError, errJson := HandleGrpcResponseError(endpoint.Err, grpcResp, grpcRespBody, w)
if errJson != nil {
WriteError(w, errJson, nil)
return
}
if endpoint.Err.Msg() != "" {
HandleGrpcResponseError(endpoint.Err, grpcResp, w)
if respHasError {
return
}

View File

@@ -97,26 +97,25 @@ func ReadGrpcResponseBody(r io.Reader) ([]byte, ErrorJson) {
return body, nil
}
// DeserializeGrpcResponseBodyIntoErrorJson deserializes the body from the grpc-gateway's response into an error struct.
// The struct can be later examined to check if the request resulted in an error.
func DeserializeGrpcResponseBodyIntoErrorJson(errJson ErrorJson, body []byte) ErrorJson {
if err := json.Unmarshal(body, errJson); err != nil {
return InternalServerErrorWithMessage(err, "could not unmarshal error")
}
return nil
}
// HandleGrpcResponseError acts on an error that resulted from a grpc-gateway's response.
func HandleGrpcResponseError(errJson ErrorJson, resp *http.Response, w http.ResponseWriter) {
// Something went wrong, but the request completed, meaning we can write headers and the error message.
for h, vs := range resp.Header {
for _, v := range vs {
w.Header().Set(h, v)
}
func HandleGrpcResponseError(errJson ErrorJson, resp *http.Response, respBody []byte, w http.ResponseWriter) (bool, ErrorJson) {
responseHasError := false
if err := json.Unmarshal(respBody, errJson); err != nil {
return false, InternalServerErrorWithMessage(err, "could not unmarshal error")
}
// Set code to HTTP code because unmarshalled body contained gRPC code.
errJson.SetCode(resp.StatusCode)
WriteError(w, errJson, resp.Header)
if errJson.Msg() != "" {
responseHasError = true
// Something went wrong, but the request completed, meaning we can write headers and the error message.
for h, vs := range resp.Header {
for _, v := range vs {
w.Header().Set(h, v)
}
}
// Set code to HTTP code because unmarshalled body contained gRPC code.
errJson.SetCode(resp.StatusCode)
WriteError(w, errJson, resp.Header)
}
return responseHasError, nil
}
// GrpcResponseIsEmpty determines whether the grpc-gateway's response body contains no data.
@@ -201,9 +200,11 @@ func WriteMiddlewareResponseHeadersAndBody(grpcResp *http.Response, responseJson
// WriteError writes the error by manipulating headers and the body of the final response.
func WriteError(w http.ResponseWriter, errJson ErrorJson, responseHeader http.Header) {
// Include custom error in the error JSON.
hasCustomError := false
if responseHeader != nil {
customError, ok := responseHeader["Grpc-Metadata-"+grpc.CustomErrorMetadataKey]
if ok {
hasCustomError = true
// Assume header has only one value and read the 0 index.
if err := json.Unmarshal([]byte(customError[0]), errJson); err != nil {
log.WithError(err).Error("Could not unmarshal custom error message")
@@ -212,10 +213,29 @@ func WriteError(w http.ResponseWriter, errJson ErrorJson, responseHeader http.He
}
}
j, err := json.Marshal(errJson)
if err != nil {
log.WithError(err).Error("Could not marshal error message")
return
var j []byte
if hasCustomError {
var err error
j, err = json.Marshal(errJson)
if err != nil {
log.WithError(err).Error("Could not marshal error message")
return
}
} else {
var err error
// We marshal the response body into a DefaultErrorJson if the custom error is not present.
// This is because the ErrorJson argument is the endpoint's error definition, which may contain custom fields.
// In such a scenario marhaling the endpoint's error would populate the resulting JSON
// with these fields even if they are not present in the gRPC header.
d := &DefaultErrorJson{
Message: errJson.Msg(),
Code: errJson.StatusCode(),
}
j, err = json.Marshal(d)
if err != nil {
log.WithError(err).Error("Could not marshal error message")
return
}
}
w.Header().Set("Content-Length", strconv.Itoa(len(j)))

View File

@@ -63,6 +63,11 @@ func (e *testErrorJson) SetCode(code int) {
e.Code = code
}
// SetMsg sets the error's underlying message.
func (e *testErrorJson) SetMsg(msg string) {
e.Message = msg
}
func TestDeserializeRequestBodyIntoContainer(t *testing.T) {
t.Run("ok", func(t *testing.T) {
var bodyJson bytes.Buffer
@@ -156,29 +161,6 @@ func TestReadGrpcResponseBody(t *testing.T) {
assert.Equal(t, "foo", string(body))
}
func TestDeserializeGrpcResponseBodyIntoErrorJson(t *testing.T) {
t.Run("ok", func(t *testing.T) {
e := &testErrorJson{
Message: "foo",
Code: 500,
}
body, err := json.Marshal(e)
require.NoError(t, err)
eToDeserialize := &testErrorJson{}
errJson := DeserializeGrpcResponseBodyIntoErrorJson(eToDeserialize, body)
require.Equal(t, true, errJson == nil)
assert.Equal(t, "foo", eToDeserialize.Msg())
assert.Equal(t, 500, eToDeserialize.StatusCode())
})
t.Run("error", func(t *testing.T) {
errJson := DeserializeGrpcResponseBodyIntoErrorJson(nil, nil)
require.NotNil(t, errJson)
assert.Equal(t, true, strings.Contains(errJson.Msg(), "could not unmarshal error"))
})
}
func TestHandleGrpcResponseError(t *testing.T) {
response := &http.Response{
StatusCode: 400,
@@ -190,10 +172,14 @@ func TestHandleGrpcResponseError(t *testing.T) {
writer := httptest.NewRecorder()
errJson := &testErrorJson{
Message: "foo",
Code: 500,
Code: 400,
}
b, err := json.Marshal(errJson)
require.NoError(t, err)
HandleGrpcResponseError(errJson, response, writer)
hasError, e := HandleGrpcResponseError(errJson, response, b, writer)
require.Equal(t, true, e == nil)
assert.Equal(t, true, hasError)
v, ok := writer.Header()["Foo"]
require.Equal(t, true, ok, "header not found")
require.Equal(t, 1, len(v), "wrong number of header values")

View File

@@ -15,6 +15,7 @@ type ErrorJson interface {
StatusCode() int
SetCode(code int)
Msg() string
SetMsg(msg string)
}
// DefaultErrorJson is a JSON representation of a simple error value, containing only a message and an error code.
@@ -54,3 +55,8 @@ func (e *DefaultErrorJson) Msg() string {
func (e *DefaultErrorJson) SetCode(code int) {
e.Code = code
}
// SetMsg sets the error's underlying message.
func (e *DefaultErrorJson) SetMsg(msg string) {
e.Message = msg
}

View File

@@ -10,6 +10,7 @@ go_library(
"init_sync_process_block.go",
"log.go",
"metrics.go",
"options.go",
"process_attestation.go",
"process_attestation_helpers.go",
"process_block.go",
@@ -22,6 +23,7 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/blockchain",
visibility = [
"//beacon-chain:__subpackages__",
"//cmd/beacon-chain:__subpackages__",
"//testing/fuzz:__pkg__",
"//testing/slasher/simulator:__pkg__",
],

View File

@@ -14,7 +14,7 @@ import (
func TestHeadSlot_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB},
cfg: &config{BeaconDB: beaconDB},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))
@@ -25,7 +25,7 @@ func TestHeadSlot_DataRace(t *testing.T) {
func TestHeadRoot_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
head: &head{root: [32]byte{'A'}},
}
go func() {
@@ -38,7 +38,7 @@ func TestHeadRoot_DataRace(t *testing.T) {
func TestHeadBlock_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
head: &head{block: wrapper.WrappedPhase0SignedBeaconBlock(&ethpb.SignedBeaconBlock{})},
}
go func() {
@@ -51,7 +51,7 @@ func TestHeadBlock_DataRace(t *testing.T) {
func TestHeadState_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))

View File

@@ -120,7 +120,7 @@ func TestHeadRoot_CanRetrieve(t *testing.T) {
func TestHeadRoot_UseDB(t *testing.T) {
beaconDB := testDB.SetupDB(t)
c := &Service{cfg: &Config{BeaconDB: beaconDB}}
c := &Service{cfg: &config{BeaconDB: beaconDB}}
c.head = &head{root: params.BeaconConfig().ZeroHash}
b := util.NewBeaconBlock()
br, err := b.Block.HashTreeRoot()
@@ -278,14 +278,14 @@ func TestService_HeadGenesisValidatorRoot(t *testing.T) {
}
func TestService_ProtoArrayStore(t *testing.T) {
c := &Service{cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}}
c := &Service{cfg: &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}}
p := c.ProtoArrayStore()
require.Equal(t, 0, int(p.FinalizedEpoch()))
}
func TestService_ChainHeads(t *testing.T) {
ctx := context.Background()
c := &Service{cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}}
c := &Service{cfg: &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}}
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 100, [32]byte{'a'}, [32]byte{}, [32]byte{}, 0, 0))
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 101, [32]byte{'b'}, [32]byte{'a'}, [32]byte{}, 0, 0))
require.NoError(t, c.cfg.ForkChoiceStore.ProcessBlock(ctx, 102, [32]byte{'c'}, [32]byte{'b'}, [32]byte{}, 0, 0))

View File

@@ -107,8 +107,8 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
if err != nil {
return err
}
if newHeadBlock == nil || newHeadBlock.IsNil() || newHeadBlock.Block().IsNil() {
return errors.New("cannot save nil head block")
if err := helpers.BeaconBlockIsNil(newHeadBlock); err != nil {
return err
}
// Get the new head state from cached state or DB.
@@ -175,7 +175,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
// root in DB. With the inception of initial-sync-cache-state flag, it uses finalized
// check point as anchors to resume sync therefore head is no longer needed to be saved on per slot basis.
func (s *Service) saveHeadNoDB(ctx context.Context, b block.SignedBeaconBlock, r [32]byte, hs state.BeaconState) error {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
if err := helpers.BeaconBlockIsNil(b); err != nil {
return err
}
cachedHeadRoot, err := s.HeadRoot(ctx)

View File

@@ -18,7 +18,7 @@ import (
func TestService_headSyncCommitteeFetcher_Errors(t *testing.T) {
beaconDB := dbtest.SetupDB(t)
c := &Service{
cfg: &Config{
cfg: &config{
StateGen: stategen.New(beaconDB),
},
}
@@ -36,7 +36,7 @@ func TestService_headSyncCommitteeFetcher_Errors(t *testing.T) {
func TestService_HeadDomainFetcher_Errors(t *testing.T) {
beaconDB := dbtest.SetupDB(t)
c := &Service{
cfg: &Config{
cfg: &config{
StateGen: stategen.New(beaconDB),
},
}

View File

@@ -153,7 +153,7 @@ func Test_notifyNewHeadEvent(t *testing.T) {
bState, _ := util.DeterministicGenesisState(t, 10)
notifier := &mock.MockStateNotifier{RecordEvents: true}
srv := &Service{
cfg: &Config{
cfg: &config{
StateNotifier: notifier,
},
genesisRoot: [32]byte{1},
@@ -182,7 +182,7 @@ func Test_notifyNewHeadEvent(t *testing.T) {
notifier := &mock.MockStateNotifier{RecordEvents: true}
genesisRoot := [32]byte{1}
srv := &Service{
cfg: &Config{
cfg: &config{
StateNotifier: notifier,
},
genesisRoot: genesisRoot,

View File

@@ -25,7 +25,7 @@ func TestService_TreeHandler(t *testing.T) {
headState, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, headState.SetBalances([]uint64{params.BeaconConfig().GweiPerEth}))
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
@@ -34,8 +34,9 @@ func TestService_TreeHandler(t *testing.T) {
),
StateGen: stategen.New(beaconDB),
}
s, err := NewService(ctx, cfg)
s, err := NewService(ctx)
require.NoError(t, err)
s.cfg = cfg
require.NoError(t, s.cfg.ForkChoiceStore.ProcessBlock(ctx, 0, [32]byte{'a'}, [32]byte{'g'}, [32]byte{'c'}, 0, 0))
require.NoError(t, s.cfg.ForkChoiceStore.ProcessBlock(ctx, 1, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'c'}, 0, 0))
s.setHead([32]byte{'a'}, wrapper.WrappedPhase0SignedBeaconBlock(util.NewBeaconBlock()), headState)

View File

@@ -55,6 +55,8 @@ func logBlockSyncStatus(block block.BeaconBlock, blockRoot [32]byte, finalized *
"epoch": slots.ToEpoch(block.Slot()),
"finalizedEpoch": finalized.Epoch,
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
"parentRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(block.ParentRoot())[:8]),
"version": version.String(block.Version()),
}).Info("Synced new block")
log.WithFields(logrus.Fields{
"slot": block.Slot,

View File

@@ -0,0 +1,139 @@
package blockchain
import (
"github.com/prysmaticlabs/prysm/async/event"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
type Option func(s *Service) error
// WithMaxGoroutines to control resource use of the blockchain service.
func WithMaxGoroutines(x int) Option {
return func(s *Service) error {
s.cfg.MaxRoutines = x
return nil
}
}
// WithWeakSubjectivityCheckpoint for checkpoint sync.
func WithWeakSubjectivityCheckpoint(c *ethpb.Checkpoint) Option {
return func(s *Service) error {
s.cfg.WeakSubjectivityCheckpt = c
return nil
}
}
// WithDatabase for head access.
func WithDatabase(beaconDB db.HeadAccessDatabase) Option {
return func(s *Service) error {
s.cfg.BeaconDB = beaconDB
return nil
}
}
// WithChainStartFetcher to retrieve information about genesis.
func WithChainStartFetcher(f powchain.ChainStartFetcher) Option {
return func(s *Service) error {
s.cfg.ChainStartFetcher = f
return nil
}
}
// WithDepositCache for deposit lifecycle after chain inclusion.
func WithDepositCache(c *depositcache.DepositCache) Option {
return func(s *Service) error {
s.cfg.DepositCache = c
return nil
}
}
// WithAttestationPool for attestation lifecycle after chain inclusion.
func WithAttestationPool(p attestations.Pool) Option {
return func(s *Service) error {
s.cfg.AttPool = p
return nil
}
}
// WithExitPool for exits lifecycle after chain inclusion.
func WithExitPool(p voluntaryexits.PoolManager) Option {
return func(s *Service) error {
s.cfg.ExitPool = p
return nil
}
}
// WithSlashingPool for slashings lifecycle after chain inclusion.
func WithSlashingPool(p slashings.PoolManager) Option {
return func(s *Service) error {
s.cfg.SlashingPool = p
return nil
}
}
// WithP2PBroadcaster to broadcast messages after appropriate processing.
func WithP2PBroadcaster(p p2p.Broadcaster) Option {
return func(s *Service) error {
s.cfg.P2p = p
return nil
}
}
// WithStateNotifier to notify an event feed of state processing.
func WithStateNotifier(n statefeed.Notifier) Option {
return func(s *Service) error {
s.cfg.StateNotifier = n
return nil
}
}
// WithForkChoiceStore to update an optimized fork-choice representation.
func WithForkChoiceStore(f forkchoice.ForkChoicer) Option {
return func(s *Service) error {
s.cfg.ForkChoiceStore = f
return nil
}
}
// WithAttestationService for dealing with attestation lifecycles.
func WithAttestationService(srv *attestations.Service) Option {
return func(s *Service) error {
s.cfg.AttService = srv
return nil
}
}
// WithStateGen for managing state regeneration and replay.
func WithStateGen(g *stategen.State) Option {
return func(s *Service) error {
s.cfg.StateGen = g
return nil
}
}
// WithSlasherAttestationsFeed to forward attestations into slasher if enabled.
func WithSlasherAttestationsFeed(f *event.Feed) Option {
return func(s *Service) error {
s.cfg.SlasherAttestationsFeed = f
return nil
}
}
// WithFinalizedStateAtStartUp to store finalized state at start up.
func WithFinalizedStateAtStartUp(st state.BeaconState) Option {
return func(s *Service) error {
s.cfg.FinalizedStateAtStartUp = st
return nil
}
}

View File

@@ -87,7 +87,7 @@ func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.Attestation
if (b == nil || b.IsNil()) && s.hasInitSyncBlock(r) {
b = s.getInitSyncBlock(r)
}
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
if err := helpers.BeaconBlockIsNil(b); err != nil {
return err
}
if b.Block().Slot() > data.Slot {

View File

@@ -24,13 +24,14 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
_, err = blockTree1(t, beaconDB, []byte{'g'})
require.NoError(t, err)
@@ -130,13 +131,14 @@ func TestStore_OnAttestation_Ok(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
genesisState, pks := util.DeterministicGenesisState(t, 64)
require.NoError(t, genesisState.SetGenesisTime(uint64(time.Now().Unix())-params.BeaconConfig().SecondsPerSlot))
require.NoError(t, service.saveGenesisData(ctx, genesisState))
@@ -155,12 +157,13 @@ func TestStore_SaveCheckpointState(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
s, err := util.NewBeaconState()
require.NoError(t, err)
@@ -227,12 +230,13 @@ func TestStore_UpdateCheckpointState(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
epoch := types.Epoch(1)
baseState, _ := util.DeterministicGenesisState(t, 1)
@@ -266,9 +270,10 @@ func TestAttEpoch_MatchPrevEpoch(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
nowTime := uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
require.NoError(t, service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Root: make([]byte, 32)}))
@@ -278,9 +283,10 @@ func TestAttEpoch_MatchCurrentEpoch(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
nowTime := uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
require.NoError(t, service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Epoch: 1}))
@@ -290,9 +296,10 @@ func TestAttEpoch_NotMatch(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
nowTime := 2 * uint64(params.BeaconConfig().SlotsPerEpoch) * params.BeaconConfig().SecondsPerSlot
err = service.verifyAttTargetEpoch(ctx, 0, nowTime, &ethpb.Checkpoint{Root: make([]byte, 32)})
@@ -303,9 +310,10 @@ func TestVerifyBeaconBlock_NoBlock(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
d := util.HydrateAttestationData(&ethpb.AttestationData{})
assert.ErrorContains(t, "signed beacon block can't be nil", service.verifyBeaconBlock(ctx, d))
@@ -315,9 +323,10 @@ func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b := util.NewBeaconBlock()
b.Block.Slot = 2
@@ -333,9 +342,10 @@ func TestVerifyBeaconBlock_OK(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b := util.NewBeaconBlock()
b.Block.Slot = 2
@@ -351,9 +361,10 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b32 := util.NewBeaconBlock()
b32.Block.Slot = 32
@@ -378,9 +389,10 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b32 := util.NewBeaconBlock()
b32.Block.Slot = 32
@@ -405,9 +417,10 @@ func TestVerifyFinalizedConsistency_IsCanonical(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b32 := util.NewBeaconBlock()
b32.Block.Slot = 32

View File

@@ -88,9 +88,8 @@ var initialSyncBlockCacheSize = uint64(2 * params.BeaconConfig().SlotsPerEpoch)
func (s *Service) onBlock(ctx context.Context, signed block.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlock")
defer span.End()
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return errors.New("nil block")
if err := helpers.BeaconBlockIsNil(signed); err != nil {
return err
}
b := signed.Block()
@@ -237,8 +236,8 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []block.SignedBeaconBlo
if len(blks) == 0 || len(blockRoots) == 0 {
return nil, nil, errors.New("no blocks provided")
}
if blks[0] == nil || blks[0].IsNil() || blks[0].Block().IsNil() {
return nil, nil, errors.New("nil block")
if err := helpers.BeaconBlockIsNil(blks[0]); err != nil {
return nil, nil, err
}
b := blks[0].Block()

View File

@@ -135,7 +135,24 @@ func (s *Service) verifyBlkFinalizedSlot(b block.BeaconBlock) error {
// shouldUpdateCurrentJustified prevents bouncing attack, by only update conflicting justified
// checkpoints in the fork choice if in the early slots of the epoch.
// Otherwise, delay incorporation of new justified checkpoint until next epoch boundary.
// See https://ethresear.ch/t/prevention-of-bouncing-attack-on-ffg/6114 for more detailed analysis and discussion.
//
// Spec code:
// def should_update_justified_checkpoint(store: Store, new_justified_checkpoint: Checkpoint) -> bool:
// """
// To address the bouncing attack, only update conflicting justified
// checkpoints in the fork choice if in the early slots of the epoch.
// Otherwise, delay incorporation of new justified checkpoint until next epoch boundary.
//
// See https://ethresear.ch/t/prevention-of-bouncing-attack-on-ffg/6114 for more detailed analysis and discussion.
// """
// if compute_slots_since_epoch_start(get_current_slot(store)) < SAFE_SLOTS_TO_UPDATE_JUSTIFIED:
// return True
//
// justified_slot = compute_start_slot_at_epoch(store.justified_checkpoint.epoch)
// if not get_ancestor(store, new_justified_checkpoint.root, justified_slot) == store.justified_checkpoint.root:
// return False
//
// return True
func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustifiedCheckpt *ethpb.Checkpoint) (bool, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.shouldUpdateCurrentJustified")
defer span.End()
@@ -143,51 +160,20 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
if slots.SinceEpochStarts(s.CurrentSlot()) < params.BeaconConfig().SafeSlotsToUpdateJustified {
return true, nil
}
var newJustifiedBlockSigned block.SignedBeaconBlock
justifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(newJustifiedCheckpt.Root))
var err error
if s.hasInitSyncBlock(justifiedRoot) {
newJustifiedBlockSigned = s.getInitSyncBlock(justifiedRoot)
} else {
newJustifiedBlockSigned, err = s.cfg.BeaconDB.Block(ctx, justifiedRoot)
if err != nil {
return false, err
}
}
if newJustifiedBlockSigned == nil || newJustifiedBlockSigned.IsNil() || newJustifiedBlockSigned.Block().IsNil() {
return false, errors.New("nil new justified block")
}
newJustifiedBlock := newJustifiedBlockSigned.Block()
jSlot, err := slots.EpochStart(s.justifiedCheckpt.Epoch)
if err != nil {
return false, err
}
if newJustifiedBlock.Slot() <= jSlot {
return false, nil
}
var justifiedBlockSigned block.SignedBeaconBlock
cachedJustifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))
if s.hasInitSyncBlock(cachedJustifiedRoot) {
justifiedBlockSigned = s.getInitSyncBlock(cachedJustifiedRoot)
} else {
justifiedBlockSigned, err = s.cfg.BeaconDB.Block(ctx, cachedJustifiedRoot)
if err != nil {
return false, err
}
}
if justifiedBlockSigned == nil || justifiedBlockSigned.IsNil() || justifiedBlockSigned.Block().IsNil() {
return false, errors.New("nil justified block")
}
justifiedBlock := justifiedBlockSigned.Block()
b, err := s.ancestor(ctx, justifiedRoot[:], justifiedBlock.Slot())
justifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(newJustifiedCheckpt.Root))
b, err := s.ancestor(ctx, justifiedRoot[:], jSlot)
if err != nil {
return false, err
}
if !bytes.Equal(b, s.justifiedCheckpt.Root) {
return false, nil
}
return true, nil
}

View File

@@ -37,13 +37,14 @@ func TestStore_OnBlock(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesis)))
@@ -133,12 +134,13 @@ func TestStore_OnBlockBatch(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
@@ -188,9 +190,10 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
params.UseMinimalConfig()
defer params.UseMainnetConfig()
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
service.genesisTime = time.Now()
update, err := service.shouldUpdateCurrentJustified(ctx, &ethpb.Checkpoint{Root: make([]byte, 32)})
@@ -222,9 +225,12 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
params.UseMinimalConfig()
defer params.UseMainnetConfig()
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
lastJustifiedBlk := util.NewBeaconBlock()
lastJustifiedBlk.Block.ParentRoot = bytesutil.PadTo([]byte{'G'}, 32)
lastJustifiedRoot, err := lastJustifiedBlk.Block.HashTreeRoot()
@@ -249,12 +255,13 @@ func TestCachedPreState_CanGetFromStateSummary(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
s, err := v1.InitializeFromProto(&ethpb.BeaconState{Slot: 1, GenesisValidatorsRoot: params.BeaconConfig().ZeroHash[:]})
require.NoError(t, err)
@@ -282,12 +289,13 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
@@ -319,9 +327,10 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
signedBlock := util.NewBeaconBlock()
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(signedBlock)))
@@ -352,9 +361,10 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.finalizedCheckpt = &ethpb.Checkpoint{Root: make([]byte, 32)}
@@ -390,9 +400,10 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
service.finalizedCheckpt = &ethpb.Checkpoint{Root: make([]byte, 32)}
@@ -431,9 +442,10 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{'A'})
// Set finalized epoch to 1.
service.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 1}
@@ -574,7 +586,7 @@ func TestCurrentSlot_HandlesOverflow(t *testing.T) {
}
func TestAncestorByDB_CtxErr(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
service, err := NewService(ctx, &Config{})
service, err := NewService(ctx)
require.NoError(t, err)
cancel()
@@ -586,9 +598,10 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b1 := util.NewBeaconBlock()
b1.Block.Slot = 1
@@ -629,9 +642,10 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
func TestAncestor_CanUseForkchoice(t *testing.T) {
ctx := context.Background()
cfg := &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b1 := util.NewBeaconBlock()
b1.Block.Slot = 1
@@ -668,9 +682,10 @@ func TestAncestor_CanUseDB(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b1 := util.NewBeaconBlock()
b1.Block.Slot = 1
@@ -705,9 +720,10 @@ func TestAncestor_CanUseDB(t *testing.T) {
func TestEnsureRootNotZeroHashes(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
service, err := NewService(ctx, cfg)
cfg := &config{}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
service.genesisRoot = [32]byte{'a'}
r := service.ensureRootNotZeros(params.BeaconConfig().ZeroHash)
@@ -760,8 +776,9 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
beaconState, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(test.args.stateCheckPoint))
service, err := NewService(ctx, &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service.justifiedCheckpt = test.args.cachedCheckPoint
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &ethpb.StateSummary{Root: bytesutil.PadTo(test.want.Root, 32)}))
genesisState, err := util.NewBeaconState()
@@ -852,8 +869,9 @@ func TestVerifyBlkDescendant(t *testing.T) {
},
}
for _, tt := range tests {
service, err := NewService(ctx, &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})})
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB), ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: tt.args.finalizedRoot[:],
}
@@ -869,9 +887,10 @@ func TestVerifyBlkDescendant(t *testing.T) {
func TestUpdateJustifiedInitSync(t *testing.T) {
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
cfg := &Config{BeaconDB: beaconDB}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
gBlk := util.NewBeaconBlock()
gRoot, err := gBlk.Block.HashTreeRoot()
@@ -897,9 +916,10 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
func TestHandleEpochBoundary_BadMetrics(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
service, err := NewService(ctx, cfg)
cfg := &config{}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
s, err := util.NewBeaconState()
require.NoError(t, err)
@@ -911,9 +931,10 @@ func TestHandleEpochBoundary_BadMetrics(t *testing.T) {
func TestHandleEpochBoundary_UpdateFirstSlot(t *testing.T) {
ctx := context.Background()
cfg := &Config{}
service, err := NewService(ctx, cfg)
cfg := &config{}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
s, _ := util.DeterministicGenesisState(t, 1024)
service.head = &head{state: s}
@@ -927,15 +948,16 @@ func TestOnBlock_CanFinalize(t *testing.T) {
beaconDB := testDB.SetupDB(t)
depositCache, err := depositcache.New()
require.NoError(t, err)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
DepositCache: depositCache,
StateNotifier: &mock.MockStateNotifier{},
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
gs, keys := util.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs))
@@ -972,14 +994,15 @@ func TestInsertFinalizedDeposits(t *testing.T) {
beaconDB := testDB.SetupDB(t)
depositCache, err := depositcache.New()
require.NoError(t, err)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
StateGen: stategen.New(beaconDB),
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
DepositCache: depositCache,
}
service, err := NewService(ctx, cfg)
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
gs, _ := util.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs))

View File

@@ -44,9 +44,10 @@ func TestVerifyLMDFFGConsistent_NotOK(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b32 := util.NewBeaconBlock()
b32.Block.Slot = 32
@@ -72,9 +73,10 @@ func TestVerifyLMDFFGConsistent_OK(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx, cfg)
cfg := &config{BeaconDB: beaconDB, ForkChoiceStore: protoarray.New(0, 0, [32]byte{})}
service, err := NewService(ctx)
require.NoError(t, err)
service.cfg = cfg
b32 := util.NewBeaconBlock()
b32.Block.Slot = 32
@@ -101,15 +103,16 @@ func TestProcessAttestations_Ok(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
StateGen: stategen.New(beaconDB),
AttPool: attestations.NewPool(),
}
service, err := NewService(ctx, cfg)
service.genesisTime = prysmTime.Now().Add(-1 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
service, err := NewService(ctx)
require.NoError(t, err)
service.genesisTime = prysmTime.Now().Add(-1 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second)
service.cfg = cfg
genesisState, pks := util.DeterministicGenesisState(t, 64)
require.NoError(t, genesisState.SetGenesisTime(uint64(prysmTime.Now().Unix())-params.BeaconConfig().SecondsPerSlot))
require.NoError(t, service.saveGenesisData(ctx, genesisState))

View File

@@ -101,7 +101,10 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []block.SignedBe
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
}
if err := s.VerifyWeakSubjectivityRoot(s.ctx); err != nil {
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
if err := s.wsVerifier.VerifyWeakSubjectivity(s.ctx, s.finalizedCheckpt.Epoch); err != nil {
// log.Fatalf will prevent defer from being called
span.End()
// Exit run time if the node failed to verify weak subjectivity checkpoint.

View File

@@ -124,7 +124,7 @@ func TestService_ReceiveBlock(t *testing.T) {
genesisBlockRoot := bytesutil.ToBytes32(nil)
require.NoError(t, beaconDB.SaveState(ctx, genesis, genesisBlockRoot))
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
@@ -136,8 +136,9 @@ func TestService_ReceiveBlock(t *testing.T) {
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(beaconDB),
}
s, err := NewService(ctx, cfg)
s, err := NewService(ctx)
require.NoError(t, err)
s.cfg = cfg
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
@@ -165,7 +166,7 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
beaconDB := testDB.SetupDB(t)
genesisBlockRoot := bytesutil.ToBytes32(nil)
require.NoError(t, beaconDB.SaveState(ctx, genesis, genesisBlockRoot))
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
@@ -177,8 +178,9 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(beaconDB),
}
s, err := NewService(ctx, cfg)
s, err := NewService(ctx)
require.NoError(t, err)
s.cfg = cfg
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
@@ -248,7 +250,7 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
beaconDB := testDB.SetupDB(t)
genesisBlockRoot, err := genesis.HashTreeRoot(ctx)
require.NoError(t, err)
cfg := &Config{
cfg := &config{
BeaconDB: beaconDB,
ForkChoiceStore: protoarray.New(
0, // justifiedEpoch
@@ -258,8 +260,9 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
StateNotifier: &blockchainTesting.MockStateNotifier{RecordEvents: true},
StateGen: stategen.New(beaconDB),
}
s, err := NewService(ctx, cfg)
s, err := NewService(ctx)
require.NoError(t, err)
s.cfg = cfg
err = s.saveGenesisData(ctx, genesis)
require.NoError(t, err)
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
@@ -284,8 +287,9 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
}
func TestService_HasInitSyncBlock(t *testing.T) {
s, err := NewService(context.Background(), &Config{StateNotifier: &blockchainTesting.MockStateNotifier{}})
s, err := NewService(context.Background())
require.NoError(t, err)
s.cfg = &config{StateNotifier: &blockchainTesting.MockStateNotifier{}}
r := [32]byte{'a'}
if s.HasInitSyncBlock(r) {
t.Error("Should not have block")
@@ -299,8 +303,9 @@ func TestService_HasInitSyncBlock(t *testing.T) {
func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
s, err := NewService(context.Background())
require.NoError(t, err)
s.cfg = &config{StateGen: stategen.New(beaconDB)}
st := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(epochsSinceFinalitySaveHotStateDB))
s.genesisTime = time.Now().Add(time.Duration(-1*int64(st)*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second)
s.finalizedCheckpt = &ethpb.Checkpoint{}
@@ -312,8 +317,9 @@ func TestCheckSaveHotStateDB_Enabling(t *testing.T) {
func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
s, err := NewService(context.Background())
require.NoError(t, err)
s.cfg = &config{StateGen: stategen.New(beaconDB)}
s.finalizedCheckpt = &ethpb.Checkpoint{}
require.NoError(t, s.checkSaveHotStateDB(context.Background()))
s.genesisTime = time.Now()
@@ -325,8 +331,9 @@ func TestCheckSaveHotStateDB_Disabling(t *testing.T) {
func TestCheckSaveHotStateDB_Overflow(t *testing.T) {
beaconDB := testDB.SetupDB(t)
hook := logTest.NewGlobal()
s, err := NewService(context.Background(), &Config{StateGen: stategen.New(beaconDB)})
s, err := NewService(context.Background())
require.NoError(t, err)
s.cfg = &config{StateGen: stategen.New(beaconDB)}
s.finalizedCheckpt = &ethpb.Checkpoint{Epoch: 10000000}
s.genesisTime = time.Now()

View File

@@ -45,7 +45,7 @@ const headSyncMinEpochsAfterCheckpoint = 128
// Service represents a service that handles the internal
// logic of managing the full PoS beacon chain.
type Service struct {
cfg *Config
cfg *config
ctx context.Context
cancel context.CancelFunc
genesisTime time.Time
@@ -64,11 +64,11 @@ type Service struct {
initSyncBlocksLock sync.RWMutex
justifiedBalances []uint64
justifiedBalancesLock sync.RWMutex
wsVerified bool
wsVerifier *WeakSubjectivityVerifier
}
// Config options for the service.
type Config struct {
// config options for the service.
type config struct {
BeaconBlockBuf int
ChainStartFetcher powchain.ChainStartFetcher
BeaconDB db.HeadAccessDatabase
@@ -84,53 +84,38 @@ type Config struct {
StateGen *stategen.State
SlasherAttestationsFeed *event.Feed
WeakSubjectivityCheckpt *ethpb.Checkpoint
FinalizedStateAtStartUp state.BeaconState
}
// NewService instantiates a new block service instance that will
// be registered into a running beacon node.
func NewService(ctx context.Context, cfg *Config) (*Service, error) {
func NewService(ctx context.Context, opts ...Option) (*Service, error) {
ctx, cancel := context.WithCancel(ctx)
return &Service{
cfg: cfg,
srv := &Service{
ctx: ctx,
cancel: cancel,
boundaryRoots: [][32]byte{},
checkpointStateCache: cache.NewCheckpointStateCache(),
initSyncBlocks: make(map[[32]byte]block.SignedBeaconBlock),
justifiedBalances: make([]uint64, 0),
}, nil
cfg: &config{},
}
for _, opt := range opts {
if err := opt(srv); err != nil {
return nil, err
}
}
var err error
srv.wsVerifier, err = NewWeakSubjectivityVerifier(srv.cfg.WeakSubjectivityCheckpt, srv.cfg.BeaconDB)
if err != nil {
return nil, err
}
return srv, nil
}
// Start a blockchain service's main event loop.
func (s *Service) Start() {
// For running initial sync with state cache, in an event of restart, we use
// last finalized check point as start point to sync instead of head
// state. This is because we no longer save state every slot during sync.
cp, err := s.cfg.BeaconDB.FinalizedCheckpoint(s.ctx)
if err != nil {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
r := bytesutil.ToBytes32(cp.Root)
// Before the first finalized epoch, in the current epoch,
// the finalized root is defined as zero hashes instead of genesis root hash.
// We want to use genesis root to retrieve for state.
if r == params.BeaconConfig().ZeroHash {
genesisBlock, err := s.cfg.BeaconDB.GenesisBlock(s.ctx)
if err != nil {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
if genesisBlock != nil && !genesisBlock.IsNil() {
r, err = genesisBlock.Block().HashTreeRoot()
if err != nil {
log.Fatalf("Could not tree hash genesis block: %v", err)
}
}
}
beaconState, err := s.cfg.StateGen.StateByRoot(s.ctx, r)
if err != nil {
log.Fatalf("Could not fetch beacon state by root: %v", err)
}
beaconState := s.cfg.FinalizedStateAtStartUp
// Make sure that attestation processor is subscribed and ready for state initializing event.
attestationProcessorSubscribed := make(chan struct{}, 1)
@@ -190,9 +175,11 @@ func (s *Service) Start() {
}
}
if err := s.VerifyWeakSubjectivityRoot(s.ctx); err != nil {
// not attempting to save initial sync blocks here, because there shouldn't be until
// after the statefeed.Initialized event is fired (below)
if err := s.wsVerifier.VerifyWeakSubjectivity(s.ctx, s.finalizedCheckpt.Epoch); err != nil {
// Exit run time if the node failed to verify weak subjectivity checkpoint.
log.Fatalf("Could not verify weak subjectivity checkpoint: %v", err)
log.Fatalf("could not verify initial checkpoint provided for chain sync, with err=: %v", err)
}
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
@@ -381,8 +368,8 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
if err != nil {
return errors.Wrap(err, "could not get genesis block from db")
}
if genesisBlock == nil || genesisBlock.IsNil() {
return errors.New("no genesis block in db")
if err := helpers.BeaconBlockIsNil(genesisBlock); err != nil {
return err
}
genesisBlkRoot, err := genesisBlock.Block().HashTreeRoot()
if err != nil {
@@ -402,7 +389,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
finalizedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(finalized.Root))
var finalizedState state.BeaconState
finalizedState, err = s.cfg.StateGen.Resume(ctx)
finalizedState, err = s.cfg.StateGen.Resume(ctx, s.cfg.FinalizedStateAtStartUp)
if err != nil {
return errors.Wrap(err, "could not get finalized state from db")
}
@@ -424,7 +411,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
if err != nil {
return errors.Wrap(err, "could not hash head block")
}
finalizedState, err := s.cfg.StateGen.Resume(ctx)
finalizedState, err := s.cfg.StateGen.Resume(ctx, s.cfg.FinalizedStateAtStartUp)
if err != nil {
return errors.Wrap(err, "could not get finalized state from db")
}

View File

@@ -18,7 +18,7 @@ func init() {
func TestChainService_SaveHead_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB},
cfg: &config{BeaconDB: beaconDB},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))

View File

@@ -94,11 +94,12 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
DepositContainers: []*ethpb.DepositContainer{},
})
require.NoError(t, err)
web3Service, err = powchain.NewService(ctx, &powchain.Web3ServiceConfig{
BeaconDB: beaconDB,
HttpEndpoints: []string{endpoint},
DepositContract: common.Address{},
})
web3Service, err = powchain.NewService(
ctx,
powchain.WithDatabase(beaconDB),
powchain.WithHttpEndpoints([]string{endpoint}),
powchain.WithDepositContractAddress(common.Address{}),
)
require.NoError(t, err, "Unable to set up web3 service")
attService, err := attestations.NewService(ctx, &attestations.Config{Pool: attestations.NewPool()})
@@ -107,7 +108,7 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
depositCache, err := depositcache.New()
require.NoError(t, err)
cfg := &Config{
cfg := &config{
BeaconBlockBuf: 0,
BeaconDB: beaconDB,
DepositCache: depositCache,
@@ -123,8 +124,9 @@ func setupBeaconChain(t *testing.T, beaconDB db.Database) *Service {
// Safe a state in stategen to purposes of testing a service stop / shutdown.
require.NoError(t, cfg.StateGen.SaveState(ctx, bytesutil.ToBytes32(bState.FinalizedCheckpoint().Root), bState))
chainService, err := NewService(ctx, cfg)
chainService, err := NewService(ctx)
require.NoError(t, err, "Unable to setup chain service")
chainService.cfg = cfg
chainService.genesisTime = time.Unix(1, 0) // non-zero time
return chainService
@@ -149,7 +151,7 @@ func TestChainStartStop_Initialized(t *testing.T) {
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, beaconDB.SaveJustifiedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
chainService.cfg.FinalizedStateAtStartUp = s
// Test the start function.
chainService.Start()
@@ -176,7 +178,7 @@ func TestChainStartStop_GenesisZeroHashes(t *testing.T) {
require.NoError(t, beaconDB.SaveState(ctx, s, blkRoot))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, beaconDB.SaveJustifiedCheckpoint(ctx, &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}))
chainService.cfg.FinalizedStateAtStartUp = s
// Test the start function.
chainService.Start()
@@ -247,7 +249,7 @@ func TestChainService_CorrectGenesisRoots(t *testing.T) {
require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, blkRoot))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, blkRoot))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Root: blkRoot[:]}))
chainService.cfg.FinalizedStateAtStartUp = s
// Test the start function.
chainService.Start()
@@ -282,7 +284,8 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(headBlock)))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Epoch: slots.ToEpoch(finalizedSlot), Root: headRoot[:]}))
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
c := &Service{cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
c.cfg.FinalizedStateAtStartUp = headState
require.NoError(t, c.initializeChainInfo(ctx))
headBlk, err := c.HeadBlock(ctx)
require.NoError(t, err)
@@ -322,7 +325,7 @@ func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(headBlock)))
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
c := &Service{cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
require.NoError(t, c.initializeChainInfo(ctx))
s, err := c.HeadState(ctx)
require.NoError(t, err)
@@ -379,8 +382,8 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
Root: finalizedRoot[:],
}))
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
c := &Service{cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
c.cfg.FinalizedStateAtStartUp = headState
require.NoError(t, c.initializeChainInfo(ctx))
s, err := c.HeadState(ctx)
require.NoError(t, err)
@@ -417,7 +420,7 @@ func TestChainService_SaveHeadNoDB(t *testing.T) {
beaconDB := testDB.SetupDB(t)
ctx := context.Background()
s := &Service{
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
}
blk := util.NewBeaconBlock()
blk.Block.Slot = 1
@@ -439,7 +442,7 @@ func TestHasBlock_ForkChoiceAndDB(t *testing.T) {
ctx := context.Background()
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
cfg: &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
finalizedCheckpt: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
block := util.NewBeaconBlock()
@@ -457,7 +460,7 @@ func TestServiceStop_SaveCachedBlocks(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
cfg: &config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
ctx: ctx,
cancel: cancel,
initSyncBlocks: make(map[[32]byte]block.SignedBeaconBlock),
@@ -488,7 +491,7 @@ func BenchmarkHasBlockDB(b *testing.B) {
beaconDB := testDB.SetupDB(b)
ctx := context.Background()
s := &Service{
cfg: &Config{BeaconDB: beaconDB},
cfg: &config{BeaconDB: beaconDB},
}
block := util.NewBeaconBlock()
require.NoError(b, s.cfg.BeaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block)))
@@ -505,7 +508,7 @@ func BenchmarkHasBlockForkChoiceStore(b *testing.B) {
ctx := context.Background()
beaconDB := testDB.SetupDB(b)
s := &Service{
cfg: &Config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
cfg: &config{ForkChoiceStore: protoarray.New(0, 0, [32]byte{}), BeaconDB: beaconDB},
finalizedCheckpt: &ethpb.Checkpoint{Root: make([]byte, 32)},
}
block := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Body: &ethpb.BeaconBlockBody{}}}

View File

@@ -4,57 +4,94 @@ import (
"context"
"fmt"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/time/slots"
)
// VerifyWeakSubjectivityRoot verifies the weak subjectivity root in the service struct.
var errWSBlockNotFound = errors.New("weak subjectivity root not found in db")
var errWSBlockNotFoundInEpoch = errors.New("weak subjectivity root not found in db within epoch")
type weakSubjectivityDB interface {
HasBlock(ctx context.Context, blockRoot [32]byte) bool
BlockRoots(ctx context.Context, f *filters.QueryFilter) ([][32]byte, error)
}
type WeakSubjectivityVerifier struct {
enabled bool
verified bool
root [32]byte
epoch types.Epoch
slot types.Slot
db weakSubjectivityDB
}
// NewWeakSubjectivityVerifier validates a checkpoint, and if valid, uses it to initialize a weak subjectivity verifier
func NewWeakSubjectivityVerifier(wsc *ethpb.Checkpoint, db weakSubjectivityDB) (*WeakSubjectivityVerifier, error) {
// TODO(7342): Weak subjectivity checks are currently optional. When we require the flag to be specified
// per 7342, a nil checkpoint, zero-root or zero-epoch should all fail validation
// and return an error instead of creating a WeakSubjectivityVerifier that permits any chain history.
if wsc == nil || len(wsc.Root) == 0 || wsc.Epoch == 0 {
return &WeakSubjectivityVerifier{
enabled: false,
}, nil
}
startSlot, err := slots.EpochStart(wsc.Epoch)
if err != nil {
return nil, err
}
return &WeakSubjectivityVerifier{
enabled: true,
verified: false,
root: bytesutil.ToBytes32(wsc.Root),
epoch: wsc.Epoch,
db: db,
slot: startSlot,
}, nil
}
// VerifyWeakSubjectivity verifies the weak subjectivity root in the service struct.
// Reference design: https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/weak-subjectivity.md#weak-subjectivity-sync-procedure
func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
// TODO(7342): Remove the following to fully use weak subjectivity in production.
if s.cfg.WeakSubjectivityCheckpt == nil || len(s.cfg.WeakSubjectivityCheckpt.Root) == 0 || s.cfg.WeakSubjectivityCheckpt.Epoch == 0 {
func (v *WeakSubjectivityVerifier) VerifyWeakSubjectivity(ctx context.Context, finalizedEpoch types.Epoch) error {
if v.verified || !v.enabled {
return nil
}
// Do nothing if the weak subjectivity has previously been verified,
// or weak subjectivity epoch is higher than last finalized epoch.
if s.wsVerified {
return nil
}
if s.cfg.WeakSubjectivityCheckpt.Epoch > s.finalizedCheckpt.Epoch {
// Two conditions are described in the specs:
// IF epoch_number > store.finalized_checkpoint.epoch,
// then ASSERT during block sync that block with root block_root
// is in the sync path at epoch epoch_number. Emit descriptive critical error if this assert fails,
// then exit client process.
// we do not handle this case ^, because we can only blocks that have been processed / are currently
// in line for finalization, we don't have the ability to look ahead. so we only satisfy the following:
// IF epoch_number <= store.finalized_checkpoint.epoch,
// then ASSERT that the block in the canonical chain at epoch epoch_number has root block_root.
// Emit descriptive critical error if this assert fails, then exit client process.
if v.epoch > finalizedEpoch {
return nil
}
log.Infof("Performing weak subjectivity check for root %#x in epoch %d", v.root, v.epoch)
r := bytesutil.ToBytes32(s.cfg.WeakSubjectivityCheckpt.Root)
log.Infof("Performing weak subjectivity check for root %#x in epoch %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
// Save initial sync cached blocks to DB.
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
return err
}
// A node should have the weak subjectivity block in the DB.
if !s.cfg.BeaconDB.HasBlock(ctx, r) {
return fmt.Errorf("node does not have root in DB: %#x", r)
}
startSlot, err := slots.EpochStart(s.cfg.WeakSubjectivityCheckpt.Epoch)
if err != nil {
return err
if !v.db.HasBlock(ctx, v.root) {
return errors.Wrap(errWSBlockNotFound, fmt.Sprintf("missing root %#x", v.root))
}
filter := filters.NewFilter().SetStartSlot(v.slot).SetEndSlot(v.slot + params.BeaconConfig().SlotsPerEpoch)
// A node should have the weak subjectivity block corresponds to the correct epoch in the DB.
filter := filters.NewFilter().SetStartSlot(startSlot).SetEndSlot(startSlot + params.BeaconConfig().SlotsPerEpoch)
roots, err := s.cfg.BeaconDB.BlockRoots(ctx, filter)
roots, err := v.db.BlockRoots(ctx, filter)
if err != nil {
return err
return errors.Wrap(err, "error while retrieving block roots to verify weak subjectivity")
}
for _, root := range roots {
if r == root {
if v.root == root {
log.Info("Weak subjectivity check has passed")
s.wsVerified = true
v.verified = true
return nil
}
}
return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
return errors.Wrap(errWSBlockNotFoundInEpoch, fmt.Sprintf("root=%#x, epoch=%d", v.root, v.epoch))
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"testing"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
@@ -23,59 +24,57 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
require.NoError(t, err)
tests := []struct {
wsVerified bool
wantErr bool
wantErr error
checkpt *ethpb.Checkpoint
finalizedEpoch types.Epoch
errString string
name string
}{
{
name: "nil root and epoch",
wantErr: false,
name: "nil root and epoch",
},
{
name: "already verified",
checkpt: &ethpb.Checkpoint{Epoch: 2},
finalizedEpoch: 2,
wsVerified: true,
wantErr: false,
},
{
name: "not yet to verify, ws epoch higher than finalized epoch",
checkpt: &ethpb.Checkpoint{Epoch: 2},
finalizedEpoch: 1,
wantErr: false,
},
{
name: "can't find the block in DB",
checkpt: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte{'a'}, 32), Epoch: 1},
finalizedEpoch: 3,
wantErr: true,
errString: "node does not have root in DB",
wantErr: errWSBlockNotFound,
},
{
name: "can't find the block corresponds to ws epoch in DB",
checkpt: &ethpb.Checkpoint{Root: r[:], Epoch: 2}, // Root belongs in epoch 1.
finalizedEpoch: 3,
wantErr: true,
errString: "node does not have root in db corresponding to epoch",
wantErr: errWSBlockNotFoundInEpoch,
},
{
name: "can verify and pass",
checkpt: &ethpb.Checkpoint{Root: r[:], Epoch: 1},
finalizedEpoch: 3,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
wv, err := NewWeakSubjectivityVerifier(tt.checkpt, beaconDB)
require.NoError(t, err)
s := &Service{
cfg: &Config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt},
wsVerified: tt.wsVerified,
cfg: &config{BeaconDB: beaconDB, WeakSubjectivityCheckpt: tt.checkpt},
finalizedCheckpt: &ethpb.Checkpoint{Epoch: tt.finalizedEpoch},
wsVerifier: wv,
}
if err := s.VerifyWeakSubjectivityRoot(context.Background()); (err != nil) != tt.wantErr {
require.ErrorContains(t, tt.errString, err)
err = s.wsVerifier.VerifyWeakSubjectivity(context.Background(), s.finalizedCheckpt.Epoch)
if tt.wantErr == nil {
require.NoError(t, err)
} else {
require.Equal(t, true, errors.Is(err, tt.wantErr))
}
})
}

View File

@@ -136,7 +136,10 @@ func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1Deposit
log.WithError(err).Error("Could not hash deposit data. Finalized deposit cache not updated.")
return
}
depositTrie.Insert(depHash[:], insertIndex)
if err = depositTrie.Insert(depHash[:], insertIndex); err != nil {
log.WithError(err).Error("Could not insert deposit hash")
return
}
insertIndex++
}

View File

@@ -25,7 +25,7 @@ func ProcessAttestationsNoVerifySignature(
beaconState state.BeaconState,
b block.SignedBeaconBlock,
) (state.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
if err := helpers.BeaconBlockIsNil(b); err != nil {
return nil, err
}
body := b.Block().Body()
@@ -142,13 +142,19 @@ func SetParticipationAndRewardProposer(
}
// HasValidatorFlag returns true if the flag at position has set.
func HasValidatorFlag(flag, flagPosition uint8) bool {
return ((flag >> flagPosition) & 1) == 1
func HasValidatorFlag(flag, flagPosition uint8) (bool, error) {
if flagPosition > 7 {
return false, errors.New("flag position exceeds length")
}
return ((flag >> flagPosition) & 1) == 1, nil
}
// AddValidatorFlag adds new validator flag to existing one.
func AddValidatorFlag(flag, flagPosition uint8) uint8 {
return flag | (1 << flagPosition)
func AddValidatorFlag(flag, flagPosition uint8) (uint8, error) {
if flagPosition > 7 {
return flag, errors.New("flag position exceeds length")
}
return flag | (1 << flagPosition), nil
}
// EpochParticipation sets and returns the proposer reward numerator and epoch participation.
@@ -174,16 +180,37 @@ func EpochParticipation(beaconState state.BeaconState, indices []uint64, epochPa
if err != nil {
return 0, nil, err
}
if participatedFlags[sourceFlagIndex] && !HasValidatorFlag(epochParticipation[index], sourceFlagIndex) {
epochParticipation[index] = AddValidatorFlag(epochParticipation[index], sourceFlagIndex)
has, err := HasValidatorFlag(epochParticipation[index], sourceFlagIndex)
if err != nil {
return 0, nil, err
}
if participatedFlags[sourceFlagIndex] && !has {
epochParticipation[index], err = AddValidatorFlag(epochParticipation[index], sourceFlagIndex)
if err != nil {
return 0, nil, err
}
proposerRewardNumerator += br * cfg.TimelySourceWeight
}
if participatedFlags[targetFlagIndex] && !HasValidatorFlag(epochParticipation[index], targetFlagIndex) {
epochParticipation[index] = AddValidatorFlag(epochParticipation[index], targetFlagIndex)
has, err = HasValidatorFlag(epochParticipation[index], targetFlagIndex)
if err != nil {
return 0, nil, err
}
if participatedFlags[targetFlagIndex] && !has {
epochParticipation[index], err = AddValidatorFlag(epochParticipation[index], targetFlagIndex)
if err != nil {
return 0, nil, err
}
proposerRewardNumerator += br * cfg.TimelyTargetWeight
}
if participatedFlags[headFlagIndex] && !HasValidatorFlag(epochParticipation[index], headFlagIndex) {
epochParticipation[index] = AddValidatorFlag(epochParticipation[index], headFlagIndex)
has, err = HasValidatorFlag(epochParticipation[index], headFlagIndex)
if err != nil {
return 0, nil, err
}
if participatedFlags[headFlagIndex] && !has {
epochParticipation[index], err = AddValidatorFlag(epochParticipation[index], headFlagIndex)
if err != nil {
return 0, nil, err
}
proposerRewardNumerator += br * cfg.TimelyHeadWeight
}
}

View File

@@ -275,9 +275,15 @@ func TestProcessAttestationNoVerify_SourceTargetHead(t *testing.T) {
indices, err := attestation.AttestingIndices(att.AggregationBits, committee)
require.NoError(t, err)
for _, index := range indices {
require.Equal(t, true, altair.HasValidatorFlag(p[index], params.BeaconConfig().TimelyHeadFlagIndex))
require.Equal(t, true, altair.HasValidatorFlag(p[index], params.BeaconConfig().TimelyTargetFlagIndex))
require.Equal(t, true, altair.HasValidatorFlag(p[index], params.BeaconConfig().TimelySourceFlagIndex))
has, err := altair.HasValidatorFlag(p[index], params.BeaconConfig().TimelyHeadFlagIndex)
require.NoError(t, err)
require.Equal(t, true, has)
has, err = altair.HasValidatorFlag(p[index], params.BeaconConfig().TimelySourceFlagIndex)
require.NoError(t, err)
require.Equal(t, true, has)
has, err = altair.HasValidatorFlag(p[index], params.BeaconConfig().TimelyTargetFlagIndex)
require.NoError(t, err)
require.Equal(t, true, has)
}
}
@@ -331,12 +337,19 @@ func TestValidatorFlag_Has(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for _, f := range tt.expected {
require.Equal(t, true, altair.HasValidatorFlag(tt.set, f))
has, err := altair.HasValidatorFlag(tt.set, f)
require.NoError(t, err)
require.Equal(t, true, has)
}
})
}
}
func TestValidatorFlag_Has_ExceedsLength(t *testing.T) {
_, err := altair.HasValidatorFlag(0, 8)
require.ErrorContains(t, "flag position exceeds length", err)
}
func TestValidatorFlag_Add(t *testing.T) {
tests := []struct {
name string
@@ -368,23 +381,33 @@ func TestValidatorFlag_Add(t *testing.T) {
expectedFalse: []uint8{},
},
}
var err error
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := uint8(0)
for _, f := range tt.set {
b = altair.AddValidatorFlag(b, f)
b, err = altair.AddValidatorFlag(b, f)
require.NoError(t, err)
}
for _, f := range tt.expectedFalse {
require.Equal(t, false, altair.HasValidatorFlag(b, f))
has, err := altair.HasValidatorFlag(b, f)
require.NoError(t, err)
require.Equal(t, false, has)
}
for _, f := range tt.expectedTrue {
require.Equal(t, true, altair.HasValidatorFlag(b, f))
has, err := altair.HasValidatorFlag(b, f)
require.NoError(t, err)
require.Equal(t, true, has)
}
})
}
}
func TestValidatorFlag_Add_ExceedsLength(t *testing.T) {
_, err := altair.AddValidatorFlag(0, 8)
require.ErrorContains(t, "flag position exceeds length", err)
}
func TestFuzzProcessAttestationsNoVerify_10000(t *testing.T) {
fuzzer := fuzz.NewWithSeed(0)
state := &ethpb.BeaconStateAltair{}

View File

@@ -42,12 +42,18 @@ func InitializePrecomputeValidators(ctx context.Context, beaconState state.Beaco
// Set validator's active status for current epoch.
if helpers.IsActiveValidatorUsingTrie(val, currentEpoch) {
v.IsActiveCurrentEpoch = true
bal.ActiveCurrentEpoch += val.EffectiveBalance()
bal.ActiveCurrentEpoch, err = math.Add64(bal.ActiveCurrentEpoch, val.EffectiveBalance())
if err != nil {
return err
}
}
// Set validator's active status for preivous epoch.
if helpers.IsActiveValidatorUsingTrie(val, prevEpoch) {
v.IsActivePrevEpoch = true
bal.ActivePrevEpoch += val.EffectiveBalance()
bal.ActivePrevEpoch, err = math.Add64(bal.ActivePrevEpoch, val.EffectiveBalance())
if err != nil {
return err
}
}
vals[idx] = v
return nil
@@ -150,7 +156,19 @@ func ProcessEpochParticipation(
sourceIdx := cfg.TimelySourceFlagIndex
headIdx := cfg.TimelyHeadFlagIndex
for i, b := range cp {
if HasValidatorFlag(b, targetIdx) && vals[i].IsActiveCurrentEpoch {
has, err := HasValidatorFlag(b, sourceIdx)
if err != nil {
return nil, nil, err
}
if has && vals[i].IsActiveCurrentEpoch {
vals[i].IsCurrentEpochAttester = true
}
has, err = HasValidatorFlag(b, targetIdx)
if err != nil {
return nil, nil, err
}
if has && vals[i].IsActiveCurrentEpoch {
vals[i].IsCurrentEpochAttester = true
vals[i].IsCurrentEpochTargetAttester = true
}
}
@@ -159,17 +177,31 @@ func ProcessEpochParticipation(
return nil, nil, err
}
for i, b := range pp {
if HasValidatorFlag(b, sourceIdx) && vals[i].IsActivePrevEpoch {
vals[i].IsPrevEpochAttester = true
has, err := HasValidatorFlag(b, sourceIdx)
if err != nil {
return nil, nil, err
}
if HasValidatorFlag(b, targetIdx) && vals[i].IsActivePrevEpoch {
if has && vals[i].IsActivePrevEpoch {
vals[i].IsPrevEpochAttester = true
vals[i].IsPrevEpochSourceAttester = true
}
has, err = HasValidatorFlag(b, targetIdx)
if err != nil {
return nil, nil, err
}
if has && vals[i].IsActivePrevEpoch {
vals[i].IsPrevEpochAttester = true
vals[i].IsPrevEpochTargetAttester = true
}
if HasValidatorFlag(b, headIdx) && vals[i].IsActivePrevEpoch {
has, err = HasValidatorFlag(b, headIdx)
if err != nil {
return nil, nil, err
}
if has && vals[i].IsActivePrevEpoch {
vals[i].IsPrevEpochHeadAttester = true
}
}
bal = precompute.UpdateBalance(vals, bal)
bal = precompute.UpdateBalance(vals, bal, beaconState.Version())
return vals, bal, nil
}
@@ -268,7 +300,7 @@ func attestationDelta(
headWeight := cfg.TimelyHeadWeight
reward, penalty = uint64(0), uint64(0)
// Process source reward / penalty
if val.IsPrevEpochAttester && !val.IsSlashed {
if val.IsPrevEpochSourceAttester && !val.IsSlashed {
if !inactivityLeak {
n := baseReward * srcWeight * (bal.PrevEpochAttested / increment)
reward += n / (activeIncrement * weightDenominator)

View File

@@ -2,6 +2,7 @@ package altair
import (
"context"
"math"
"testing"
types "github.com/prysmaticlabs/eth2-types"
@@ -62,6 +63,21 @@ func TestInitializeEpochValidators_Ok(t *testing.T) {
assert.DeepEqual(t, wantedBalances, b, "Incorrect wanted balance")
}
func TestInitializeEpochValidators_Overflow(t *testing.T) {
ffe := params.BeaconConfig().FarFutureEpoch
s, err := stateAltair.InitializeFromProto(&ethpb.BeaconStateAltair{
Slot: params.BeaconConfig().SlotsPerEpoch,
Validators: []*ethpb.Validator{
{WithdrawableEpoch: ffe, ExitEpoch: ffe, EffectiveBalance: math.MaxUint64},
{WithdrawableEpoch: ffe, ExitEpoch: ffe, EffectiveBalance: math.MaxUint64},
},
InactivityScores: []uint64{0, 1},
})
require.NoError(t, err)
_, _, err = InitializePrecomputeValidators(context.Background(), s)
require.ErrorContains(t, "could not read every validator: addition overflows", err)
}
func TestInitializeEpochValidators_BadState(t *testing.T) {
s, err := stateAltair.InitializeFromProto(&ethpb.BeaconStateAltair{
Validators: []*ethpb.Validator{{}},
@@ -90,14 +106,18 @@ func TestProcessEpochParticipation(t *testing.T) {
IsActivePrevEpoch: true,
IsWithdrawableCurrentEpoch: true,
CurrentEpochEffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
IsCurrentEpochAttester: true,
IsPrevEpochAttester: true,
IsPrevEpochSourceAttester: true,
}, validators[1])
require.DeepEqual(t, &precompute.Validator{
IsActiveCurrentEpoch: true,
IsActivePrevEpoch: true,
IsWithdrawableCurrentEpoch: true,
CurrentEpochEffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
IsCurrentEpochAttester: true,
IsPrevEpochAttester: true,
IsPrevEpochSourceAttester: true,
IsCurrentEpochTargetAttester: true,
IsPrevEpochTargetAttester: true,
}, validators[2])
@@ -106,7 +126,9 @@ func TestProcessEpochParticipation(t *testing.T) {
IsActivePrevEpoch: true,
IsWithdrawableCurrentEpoch: true,
CurrentEpochEffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
IsCurrentEpochAttester: true,
IsPrevEpochAttester: true,
IsPrevEpochSourceAttester: true,
IsCurrentEpochTargetAttester: true,
IsPrevEpochTargetAttester: true,
IsPrevEpochHeadAttester: true,
@@ -120,8 +142,10 @@ func TestProcessEpochParticipation(t *testing.T) {
func TestProcessEpochParticipation_InactiveValidator(t *testing.T) {
generateParticipation := func(flags ...uint8) byte {
b := byte(0)
var err error
for _, flag := range flags {
b = AddValidatorFlag(b, flag)
b, err = AddValidatorFlag(b, flag)
require.NoError(t, err)
}
return b
}
@@ -159,6 +183,7 @@ func TestProcessEpochParticipation_InactiveValidator(t *testing.T) {
IsActiveCurrentEpoch: false,
IsActivePrevEpoch: true,
IsPrevEpochAttester: true,
IsPrevEpochSourceAttester: true,
IsPrevEpochTargetAttester: true,
IsWithdrawableCurrentEpoch: true,
CurrentEpochEffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
@@ -168,7 +193,9 @@ func TestProcessEpochParticipation_InactiveValidator(t *testing.T) {
IsActivePrevEpoch: true,
IsWithdrawableCurrentEpoch: true,
CurrentEpochEffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
IsCurrentEpochAttester: true,
IsPrevEpochAttester: true,
IsPrevEpochSourceAttester: true,
IsCurrentEpochTargetAttester: true,
IsPrevEpochTargetAttester: true,
IsPrevEpochHeadAttester: true,
@@ -395,8 +422,12 @@ func TestProcessInactivityScores_NonEligibleValidator(t *testing.T) {
func testState() (state.BeaconState, error) {
generateParticipation := func(flags ...uint8) byte {
b := byte(0)
var err error
for _, flag := range flags {
b = AddValidatorFlag(b, flag)
b, err = AddValidatorFlag(b, flag)
if err != nil {
return 0
}
}
return b
}

View File

@@ -161,14 +161,35 @@ func TranslateParticipation(ctx context.Context, state *statealtair.BeaconState,
targetFlagIndex := cfg.TimelyTargetFlagIndex
headFlagIndex := cfg.TimelyHeadFlagIndex
for _, index := range indices {
if participatedFlags[sourceFlagIndex] && !HasValidatorFlag(epochParticipation[index], sourceFlagIndex) {
epochParticipation[index] = AddValidatorFlag(epochParticipation[index], sourceFlagIndex)
has, err := HasValidatorFlag(epochParticipation[index], sourceFlagIndex)
if err != nil {
return nil, err
}
if participatedFlags[targetFlagIndex] && !HasValidatorFlag(epochParticipation[index], targetFlagIndex) {
epochParticipation[index] = AddValidatorFlag(epochParticipation[index], targetFlagIndex)
if participatedFlags[sourceFlagIndex] && !has {
epochParticipation[index], err = AddValidatorFlag(epochParticipation[index], sourceFlagIndex)
if err != nil {
return nil, err
}
}
if participatedFlags[headFlagIndex] && !HasValidatorFlag(epochParticipation[index], headFlagIndex) {
epochParticipation[index] = AddValidatorFlag(epochParticipation[index], headFlagIndex)
has, err = HasValidatorFlag(epochParticipation[index], targetFlagIndex)
if err != nil {
return nil, err
}
if participatedFlags[targetFlagIndex] && !has {
epochParticipation[index], err = AddValidatorFlag(epochParticipation[index], targetFlagIndex)
if err != nil {
return nil, err
}
}
has, err = HasValidatorFlag(epochParticipation[index], headFlagIndex)
if err != nil {
return nil, err
}
if participatedFlags[headFlagIndex] && !has {
epochParticipation[index], err = AddValidatorFlag(epochParticipation[index], headFlagIndex)
if err != nil {
return nil, err
}
}
}
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/altair"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
"github.com/prysmaticlabs/prysm/config/params"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
@@ -62,9 +61,15 @@ func TestTranslateParticipation(t *testing.T) {
indices, err := attestation.AttestingIndices(pendingAtts[0].AggregationBits, committee)
require.NoError(t, err)
for _, index := range indices {
require.Equal(t, true, altair.HasValidatorFlag(participation[index], params.BeaconConfig().TimelyHeadFlagIndex))
require.Equal(t, true, altair.HasValidatorFlag(participation[index], params.BeaconConfig().TimelyTargetFlagIndex))
require.Equal(t, true, altair.HasValidatorFlag(participation[index], params.BeaconConfig().TimelySourceFlagIndex))
has, err := altair.HasValidatorFlag(participation[index], params.BeaconConfig().TimelySourceFlagIndex)
require.NoError(t, err)
require.Equal(t, true, has)
has, err = altair.HasValidatorFlag(participation[index], params.BeaconConfig().TimelyTargetFlagIndex)
require.NoError(t, err)
require.Equal(t, true, has)
has, err = altair.HasValidatorFlag(participation[index], params.BeaconConfig().TimelyHeadFlagIndex)
require.NoError(t, err)
require.Equal(t, true, has)
}
}
@@ -73,8 +78,6 @@ func TestUpgradeToAltair(t *testing.T) {
preForkState := st.Copy()
aState, err := altair.UpgradeToAltair(context.Background(), st)
require.NoError(t, err)
_, ok := aState.(state.BeaconStateAltair)
require.Equal(t, true, ok)
require.Equal(t, preForkState.GenesisTime(), aState.GenesisTime())
require.DeepSSZEqual(t, preForkState.GenesisValidatorRoot(), aState.GenesisValidatorRoot())

View File

@@ -25,7 +25,7 @@ func ProcessAttestationsNoVerifySignature(
beaconState state.BeaconState,
b block.SignedBeaconBlock,
) (state.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
if err := helpers.BeaconBlockIsNil(b); err != nil {
return nil, err
}
body := b.Block().Body()

View File

@@ -271,7 +271,7 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
Source: &ethpb.Checkpoint{},
}),
AttestingIndices: []uint64{1},
Signature: make([]byte, 96),
Signature: make([]byte, params.BeaconConfig().BLSSignatureLength),
}},
{attestation: &ethpb.IndexedAttestation{
Data: util.HydrateAttestationData(&ethpb.AttestationData{
@@ -280,7 +280,7 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
},
}),
AttestingIndices: []uint64{47, 99, 101},
Signature: make([]byte, 96),
Signature: make([]byte, params.BeaconConfig().BLSSignatureLength),
}},
{attestation: &ethpb.IndexedAttestation{
Data: util.HydrateAttestationData(&ethpb.AttestationData{
@@ -289,7 +289,7 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
},
}),
AttestingIndices: []uint64{21, 72},
Signature: make([]byte, 96),
Signature: make([]byte, params.BeaconConfig().BLSSignatureLength),
}},
{attestation: &ethpb.IndexedAttestation{
Data: util.HydrateAttestationData(&ethpb.AttestationData{
@@ -298,7 +298,7 @@ func TestVerifyIndexedAttestation_OK(t *testing.T) {
},
}),
AttestingIndices: []uint64{100, 121, 122},
Signature: make([]byte, 96),
Signature: make([]byte, params.BeaconConfig().BLSSignatureLength),
}},
}

View File

@@ -42,40 +42,60 @@ func ProcessAttesterSlashings(
slashings []*ethpb.AttesterSlashing,
slashFunc slashValidatorFunc,
) (state.BeaconState, error) {
for idx, slashing := range slashings {
if err := VerifyAttesterSlashing(ctx, beaconState, slashing); err != nil {
return nil, errors.Wrapf(err, "could not verify attester slashing %d", idx)
var err error
for _, slashing := range slashings {
beaconState, err = ProcessAttesterSlashing(ctx, beaconState, slashing, slashFunc)
if err != nil {
return nil, err
}
slashableIndices := slashableAttesterIndices(slashing)
sort.SliceStable(slashableIndices, func(i, j int) bool {
return slashableIndices[i] < slashableIndices[j]
})
currentEpoch := slots.ToEpoch(beaconState.Slot())
var err error
var slashedAny bool
var val state.ReadOnlyValidator
for _, validatorIndex := range slashableIndices {
val, err = beaconState.ValidatorAtIndexReadOnly(types.ValidatorIndex(validatorIndex))
}
return beaconState, nil
}
// ProcessAttesterSlashing processes individual attester slashing.
func ProcessAttesterSlashing(
ctx context.Context,
beaconState state.BeaconState,
slashing *ethpb.AttesterSlashing,
slashFunc slashValidatorFunc,
) (state.BeaconState, error) {
if err := VerifyAttesterSlashing(ctx, beaconState, slashing); err != nil {
return nil, errors.Wrap(err, "could not verify attester slashing")
}
slashableIndices := slashableAttesterIndices(slashing)
sort.SliceStable(slashableIndices, func(i, j int) bool {
return slashableIndices[i] < slashableIndices[j]
})
currentEpoch := slots.ToEpoch(beaconState.Slot())
var err error
var slashedAny bool
var val state.ReadOnlyValidator
for _, validatorIndex := range slashableIndices {
val, err = beaconState.ValidatorAtIndexReadOnly(types.ValidatorIndex(validatorIndex))
if err != nil {
return nil, err
}
if helpers.IsSlashableValidator(val.ActivationEpoch(), val.WithdrawableEpoch(), val.Slashed(), currentEpoch) {
cfg := params.BeaconConfig()
var slashingQuotient uint64
switch {
case beaconState.Version() == version.Phase0:
slashingQuotient = cfg.MinSlashingPenaltyQuotient
case beaconState.Version() == version.Altair:
slashingQuotient = cfg.MinSlashingPenaltyQuotientAltair
default:
return nil, errors.New("unknown state version")
}
beaconState, err = slashFunc(ctx, beaconState, types.ValidatorIndex(validatorIndex), slashingQuotient, cfg.ProposerRewardQuotient)
if err != nil {
return nil, err
}
if helpers.IsSlashableValidator(val.ActivationEpoch(), val.WithdrawableEpoch(), val.Slashed(), currentEpoch) {
cfg := params.BeaconConfig()
slashingQuotient := cfg.MinSlashingPenaltyQuotient
if beaconState.Version() == version.Altair {
slashingQuotient = cfg.MinSlashingPenaltyQuotientAltair
}
beaconState, err = slashFunc(ctx, beaconState, types.ValidatorIndex(validatorIndex), slashingQuotient, cfg.ProposerRewardQuotient)
if err != nil {
return nil, errors.Wrapf(err, "could not slash validator index %d",
validatorIndex)
}
slashedAny = true
return nil, errors.Wrapf(err, "could not slash validator index %d",
validatorIndex)
}
slashedAny = true
}
if !slashedAny {
return nil, errors.New("unable to slash any validator despite confirmed attester slashing")
}
}
if !slashedAny {
return nil, errors.New("unable to slash any validator despite confirmed attester slashing")
}
return beaconState, nil
}

View File

@@ -60,7 +60,7 @@ func TestProcessDeposits_MerkleBranchFailsVerification(t *testing.T) {
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{1, 2, 3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
Signature: make([]byte, params.BeaconConfig().BLSSignatureLength),
},
}
leaf, err := deposit.Data.HashTreeRoot()
@@ -139,7 +139,7 @@ func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T)
PublicKey: sk.PublicKey().Marshal(),
Amount: 1000,
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
Signature: make([]byte, params.BeaconConfig().BLSSignatureLength),
},
}
sr, err := signing.ComputeSigningRoot(deposit.Data, bytesutil.ToBytes(3, 32))

View File

@@ -16,7 +16,7 @@ func NewGenesisBlock(stateRoot []byte) *ethpb.SignedBeaconBlock {
ParentRoot: zeroHash,
StateRoot: bytesutil.PadTo(stateRoot, 32),
Body: &ethpb.BeaconBlockBody{
RandaoReveal: make([]byte, 96),
RandaoReveal: make([]byte, params.BeaconConfig().BLSSignatureLength),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),

View File

@@ -43,7 +43,7 @@ func ProcessBlockHeader(
beaconState state.BeaconState,
block block.SignedBeaconBlock,
) (state.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(block); err != nil {
if err := helpers.BeaconBlockIsNil(block); err != nil {
return nil, err
}
bodyRoot, err := block.Block().Body().HashTreeRoot()

View File

@@ -51,26 +51,46 @@ func ProcessProposerSlashings(
slashFunc slashValidatorFunc,
) (state.BeaconState, error) {
var err error
for idx, slashing := range slashings {
if slashing == nil {
return nil, errors.New("nil proposer slashings in block body")
}
if err = VerifyProposerSlashing(beaconState, slashing); err != nil {
return nil, errors.Wrapf(err, "could not verify proposer slashing %d", idx)
}
cfg := params.BeaconConfig()
slashingQuotient := cfg.MinSlashingPenaltyQuotient
if beaconState.Version() == version.Altair {
slashingQuotient = cfg.MinSlashingPenaltyQuotientAltair
}
beaconState, err = slashFunc(ctx, beaconState, slashing.Header_1.Header.ProposerIndex, slashingQuotient, cfg.ProposerRewardQuotient)
for _, slashing := range slashings {
beaconState, err = ProcessProposerSlashing(ctx, beaconState, slashing, slashFunc)
if err != nil {
return nil, errors.Wrapf(err, "could not slash proposer index %d", slashing.Header_1.Header.ProposerIndex)
return nil, err
}
}
return beaconState, nil
}
// ProcessProposerSlashing processes individual proposer slashing.
func ProcessProposerSlashing(
ctx context.Context,
beaconState state.BeaconState,
slashing *ethpb.ProposerSlashing,
slashFunc slashValidatorFunc,
) (state.BeaconState, error) {
var err error
if slashing == nil {
return nil, errors.New("nil proposer slashings in block body")
}
if err = VerifyProposerSlashing(beaconState, slashing); err != nil {
return nil, errors.Wrap(err, "could not verify proposer slashing")
}
cfg := params.BeaconConfig()
var slashingQuotient uint64
switch {
case beaconState.Version() == version.Phase0:
slashingQuotient = cfg.MinSlashingPenaltyQuotient
case beaconState.Version() == version.Altair:
slashingQuotient = cfg.MinSlashingPenaltyQuotientAltair
default:
return nil, errors.New("unknown state version")
}
beaconState, err = slashFunc(ctx, beaconState, slashing.Header_1.Header.ProposerIndex, slashingQuotient, cfg.ProposerRewardQuotient)
if err != nil {
return nil, errors.Wrapf(err, "could not slash proposer index %d", slashing.Header_1.Header.ProposerIndex)
}
return beaconState, nil
}
// VerifyProposerSlashing verifies that the data provided from slashing is valid.
func VerifyProposerSlashing(
beaconState state.ReadOnlyBeaconState,

View File

@@ -105,7 +105,7 @@ func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
Slot: 0,
BodyRoot: []byte("foo"),
},
Signature: bytesutil.PadTo([]byte("A"), 96),
Signature: bytesutil.PadTo([]byte("A"), params.BeaconConfig().BLSSignatureLength),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
@@ -113,7 +113,7 @@ func TestProcessProposerSlashings_ValidatorNotSlashable(t *testing.T) {
Slot: 0,
BodyRoot: []byte("bar"),
},
Signature: bytesutil.PadTo([]byte("B"), 96),
Signature: bytesutil.PadTo([]byte("B"), params.BeaconConfig().BLSSignatureLength),
},
},
}

View File

@@ -31,7 +31,7 @@ func ProcessRandao(
beaconState state.BeaconState,
b block.SignedBeaconBlock,
) (state.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
if err := helpers.BeaconBlockIsNil(b); err != nil {
return nil, err
}
body := b.Block().Body()

View File

@@ -24,6 +24,7 @@ go_library(
"//monitoring/tracing:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/attestation:go_default_library",
"//runtime/version:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
@@ -51,6 +52,7 @@ go_test(
"//math:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/attestation:go_default_library",
"//runtime/version:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/monitoring/tracing"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
"github.com/prysmaticlabs/prysm/runtime/version"
"go.opencensus.io/trace"
)
@@ -64,7 +65,7 @@ func ProcessAttestations(
vp = UpdateValidator(vp, v, indices, a, a.Data.Slot)
}
pBal = UpdateBalance(vp, pBal)
pBal = UpdateBalance(vp, pBal, state.Version())
return vp, pBal, nil
}
@@ -170,7 +171,7 @@ func UpdateValidator(vp []*Validator, record *Validator, indices []uint64, a *et
}
// UpdateBalance updates pre computed balance store.
func UpdateBalance(vp []*Validator, bBal *Balance) *Balance {
func UpdateBalance(vp []*Validator, bBal *Balance, stateVersion int) *Balance {
for _, v := range vp {
if !v.IsSlashed {
if v.IsCurrentEpochAttester {
@@ -179,7 +180,10 @@ func UpdateBalance(vp []*Validator, bBal *Balance) *Balance {
if v.IsCurrentEpochTargetAttester {
bBal.CurrentEpochTargetAttested += v.CurrentEpochEffectiveBalance
}
if v.IsPrevEpochAttester {
if stateVersion == version.Phase0 && v.IsPrevEpochAttester {
bBal.PrevEpochAttested += v.CurrentEpochEffectiveBalance
}
if stateVersion == version.Altair && v.IsPrevEpochSourceAttester {
bBal.PrevEpochAttested += v.CurrentEpochEffectiveBalance
}
if v.IsPrevEpochTargetAttester {

View File

@@ -10,6 +10,7 @@ import (
"github.com/prysmaticlabs/prysm/config/params"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation"
"github.com/prysmaticlabs/prysm/runtime/version"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
@@ -65,7 +66,7 @@ func TestUpdateBalance(t *testing.T) {
PrevEpochTargetAttested: 100 * params.BeaconConfig().EffectiveBalanceIncrement,
PrevEpochHeadAttested: 200 * params.BeaconConfig().EffectiveBalanceIncrement,
}
pBal := precompute.UpdateBalance(vp, &precompute.Balance{})
pBal := precompute.UpdateBalance(vp, &precompute.Balance{}, version.Phase0)
assert.DeepEqual(t, wantedPBal, pBal, "Incorrect balance calculations")
}

View File

@@ -20,12 +20,14 @@ type Validator struct {
IsCurrentEpochTargetAttester bool
// IsPrevEpochAttester is true if the validator attested previous epoch.
IsPrevEpochAttester bool
// IsPrevEpochSourceAttester is true if the validator attested to source previous epoch. [Only for Altair]
IsPrevEpochSourceAttester bool
// IsPrevEpochTargetAttester is true if the validator attested previous epoch target.
IsPrevEpochTargetAttester bool
// IsHeadAttester is true if the validator attested head.
IsPrevEpochHeadAttester bool
// CurrentEpochEffectiveBalance is how much effective balance this validator validator has current epoch.
// CurrentEpochEffectiveBalance is how much effective balance this validator has current epoch.
CurrentEpochEffectiveBalance uint64
// InclusionSlot is the slot of when the attestation gets included in the chain.
InclusionSlot types.Slot

View File

@@ -1,6 +1,4 @@
// Package operation contains types for block operation-specific events fired
// during the runtime of a beacon node such as attestations, voluntary
// exits, and slashings.
// Package operation contains types for block operation-specific events fired during the runtime of a beacon node.
package operation
import (
@@ -18,6 +16,9 @@ const (
// ExitReceived is sent after an voluntary exit object has been received from the outside world (eg in RPC or sync)
ExitReceived
// SyncCommitteeContributionReceived is sent after a sync committee contribution object has been received.
SyncCommitteeContributionReceived
)
// UnAggregatedAttReceivedData is the data sent with UnaggregatedAttReceived events.
@@ -37,3 +38,9 @@ type ExitReceivedData struct {
// Exit is the voluntary exit object.
Exit *ethpb.SignedVoluntaryExit
}
// SyncCommitteeContributionReceivedData is the data sent with SyncCommitteeContributionReceived objects.
type SyncCommitteeContributionReceivedData struct {
// Contribution is the sync committee contribution object.
Contribution *ethpb.SignedContributionAndProof
}

View File

@@ -17,6 +17,7 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers",
visibility = [
"//beacon-chain:__subpackages__",
"//cmd/beacon-chain:__subpackages__",
"//contracts/deposit:__pkg__",
"//crypto/keystore:__pkg__",
"//fuzz:__pkg__",

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

@@ -11,10 +11,10 @@ import (
"github.com/prysmaticlabs/prysm/time/slots"
)
// VerifyNilBeaconBlock checks if any composite field of input signed beacon block is nil.
// BeaconBlockIsNil checks if any composite field of input signed beacon block is nil.
// Access to these nil fields will result in run time panic,
// it is recommended to run these checks as first line of defense.
func VerifyNilBeaconBlock(b block.SignedBeaconBlock) error {
func BeaconBlockIsNil(b block.SignedBeaconBlock) error {
if b == nil || b.IsNil() {
return errors.New("signed beacon block can't be nil")
}

View File

@@ -24,7 +24,6 @@ go_test(
"//proto/prysm/v1alpha1:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//time:go_default_library",
"//time/slots:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
],

View File

@@ -59,3 +59,22 @@ func CanUpgradeToAltair(slot types.Slot) bool {
altairEpoch := slots.ToEpoch(slot) == params.BeaconConfig().AltairForkEpoch
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.
//
// Spec pseudocode definition:
// If (state.slot + 1) % SLOTS_PER_EPOCH == 0:
func CanProcessEpoch(state state.ReadOnlyBeaconState) bool {
return (state.Slot()+1)%params.BeaconConfig().SlotsPerEpoch == 0
}

View File

@@ -1,9 +1,7 @@
package time
import (
"math"
"testing"
"time"
types "github.com/prysmaticlabs/eth2-types"
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
@@ -11,7 +9,6 @@ import (
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
prysmTime "github.com/prysmaticlabs/prysm/time"
"github.com/prysmaticlabs/prysm/time/slots"
)
@@ -83,338 +80,6 @@ func TestNextEpoch_OK(t *testing.T) {
}
}
func TestEpochStartSlot_OK(t *testing.T) {
tests := []struct {
epoch types.Epoch
startSlot types.Slot
error bool
}{
{epoch: 0, startSlot: 0 * params.BeaconConfig().SlotsPerEpoch, error: false},
{epoch: 1, startSlot: 1 * params.BeaconConfig().SlotsPerEpoch, error: false},
{epoch: 10, startSlot: 10 * params.BeaconConfig().SlotsPerEpoch, error: false},
{epoch: 1 << 58, startSlot: 1 << 63, error: false},
{epoch: 1 << 59, startSlot: 1 << 63, error: true},
{epoch: 1 << 60, startSlot: 1 << 63, error: true},
}
for _, tt := range tests {
ss, err := slots.EpochStart(tt.epoch)
if !tt.error {
require.NoError(t, err)
assert.Equal(t, tt.startSlot, ss, "EpochStart(%d)", tt.epoch)
} else {
require.ErrorContains(t, "start slot calculation overflow", err)
}
}
}
func TestEpochEndSlot_OK(t *testing.T) {
tests := []struct {
epoch types.Epoch
startSlot types.Slot
error bool
}{
{epoch: 0, startSlot: 1*params.BeaconConfig().SlotsPerEpoch - 1, error: false},
{epoch: 1, startSlot: 2*params.BeaconConfig().SlotsPerEpoch - 1, error: false},
{epoch: 10, startSlot: 11*params.BeaconConfig().SlotsPerEpoch - 1, error: false},
{epoch: 1 << 59, startSlot: 1 << 63, error: true},
{epoch: 1 << 60, startSlot: 1 << 63, error: true},
{epoch: math.MaxUint64, startSlot: 0, error: true},
}
for _, tt := range tests {
ss, err := slots.EpochEnd(tt.epoch)
if !tt.error {
require.NoError(t, err)
assert.Equal(t, tt.startSlot, ss, "EpochStart(%d)", tt.epoch)
} else {
require.ErrorContains(t, "start slot calculation overflow", err)
}
}
}
func TestIsEpochStart(t *testing.T) {
epochLength := params.BeaconConfig().SlotsPerEpoch
tests := []struct {
slot types.Slot
result bool
}{
{
slot: epochLength + 1,
result: false,
},
{
slot: epochLength - 1,
result: false,
},
{
slot: epochLength,
result: true,
},
{
slot: epochLength * 2,
result: true,
},
}
for _, tt := range tests {
assert.Equal(t, tt.result, slots.IsEpochStart(tt.slot), "IsEpochStart(%d)", tt.slot)
}
}
func TestIsEpochEnd(t *testing.T) {
epochLength := params.BeaconConfig().SlotsPerEpoch
tests := []struct {
slot types.Slot
result bool
}{
{
slot: epochLength + 1,
result: false,
},
{
slot: epochLength,
result: false,
},
{
slot: epochLength - 1,
result: true,
},
}
for _, tt := range tests {
assert.Equal(t, tt.result, slots.IsEpochEnd(tt.slot), "IsEpochEnd(%d)", tt.slot)
}
}
func TestSlotsSinceEpochStarts(t *testing.T) {
tests := []struct {
slots types.Slot
wantedSlots types.Slot
}{
{slots: 0, wantedSlots: 0},
{slots: 1, wantedSlots: 1},
{slots: params.BeaconConfig().SlotsPerEpoch - 1, wantedSlots: params.BeaconConfig().SlotsPerEpoch - 1},
{slots: params.BeaconConfig().SlotsPerEpoch + 1, wantedSlots: 1},
{slots: 10*params.BeaconConfig().SlotsPerEpoch + 2, wantedSlots: 2},
}
for _, tt := range tests {
assert.Equal(t, tt.wantedSlots, slots.SinceEpochStarts(tt.slots))
}
}
func TestRoundUpToNearestEpoch_OK(t *testing.T) {
tests := []struct {
startSlot types.Slot
roundedUpSlot types.Slot
}{
{startSlot: 0 * params.BeaconConfig().SlotsPerEpoch, roundedUpSlot: 0},
{startSlot: 1*params.BeaconConfig().SlotsPerEpoch - 10, roundedUpSlot: 1 * params.BeaconConfig().SlotsPerEpoch},
{startSlot: 10*params.BeaconConfig().SlotsPerEpoch - (params.BeaconConfig().SlotsPerEpoch - 1), roundedUpSlot: 10 * params.BeaconConfig().SlotsPerEpoch},
}
for _, tt := range tests {
assert.Equal(t, tt.roundedUpSlot, slots.RoundUpToNearestEpoch(tt.startSlot), "RoundUpToNearestEpoch(%d)", tt.startSlot)
}
}
func TestSlotToTime(t *testing.T) {
type args struct {
genesisTimeSec uint64
slot types.Slot
}
tests := []struct {
name string
args args
want time.Time
wantedErr string
}{
{
name: "slot_0",
args: args{
genesisTimeSec: 0,
slot: 0,
},
want: time.Unix(0, 0),
},
{
name: "slot_1",
args: args{
genesisTimeSec: 0,
slot: 1,
},
want: time.Unix(int64(1*params.BeaconConfig().SecondsPerSlot), 0),
},
{
name: "slot_12",
args: args{
genesisTimeSec: 500,
slot: 12,
},
want: time.Unix(500+int64(12*params.BeaconConfig().SecondsPerSlot), 0),
},
{
name: "overflow",
args: args{
genesisTimeSec: 500,
slot: math.MaxUint64,
},
wantedErr: "is in the far distant future",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := slots.ToTime(tt.args.genesisTimeSec, tt.args.slot)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
assert.DeepEqual(t, tt.want, got)
}
})
}
}
func TestVerifySlotTime(t *testing.T) {
type args struct {
genesisTime int64
slot types.Slot
timeTolerance time.Duration
}
tests := []struct {
name string
args args
wantedErr string
}{
{
name: "Past slot",
args: args{
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(),
slot: 3,
},
},
{
name: "within tolerance",
args: args{
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Add(20 * time.Millisecond).Unix(),
slot: 5,
},
},
{
name: "future slot",
args: args{
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(),
slot: 6,
},
wantedErr: "could not process slot from the future",
},
{
name: "max future slot",
args: args{
genesisTime: prysmTime.Now().Add(-1 * 5 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(),
slot: types.Slot(slots.MaxSlotBuffer + 6),
},
wantedErr: "exceeds max allowed value relative to the local clock",
},
{
name: "evil future slot",
args: args{
genesisTime: prysmTime.Now().Add(-1 * 24 * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix(), // 24 slots in the past
// Gets multiplied with slot duration, and results in an overflow. Wraps around to a valid time.
// Lower than max signed int. And chosen specifically to wrap to a valid slot 24
slot: types.Slot((^uint64(0))/params.BeaconConfig().SecondsPerSlot) + 24,
},
wantedErr: "is in the far distant future",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := slots.VerifyTime(uint64(tt.args.genesisTime), tt.args.slot, tt.args.timeTolerance)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestValidateSlotClock_HandlesBadSlot(t *testing.T) {
genTime := prysmTime.Now().Add(-1 * time.Duration(slots.MaxSlotBuffer) * time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second).Unix()
assert.NoError(t, slots.ValidateClock(types.Slot(slots.MaxSlotBuffer), uint64(genTime)), "unexpected error validating slot")
assert.NoError(t, slots.ValidateClock(types.Slot(2*slots.MaxSlotBuffer), uint64(genTime)), "unexpected error validating slot")
assert.ErrorContains(t, "which exceeds max allowed value relative to the local clock", slots.ValidateClock(types.Slot(2*slots.MaxSlotBuffer+1), uint64(genTime)), "no error from bad slot")
assert.ErrorContains(t, "which exceeds max allowed value relative to the local clock", slots.ValidateClock(1<<63, uint64(genTime)), "no error from bad slot")
}
func TestPrevSlot(t *testing.T) {
tests := []struct {
name string
slot types.Slot
want types.Slot
}{
{
name: "no underflow",
slot: 0,
want: 0,
},
{
name: "slot 1",
slot: 1,
want: 0,
},
{
name: "slot 2",
slot: 2,
want: 1,
},
{
name: "max",
slot: 1<<64 - 1,
want: 1<<64 - 1 - 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := slots.PrevSlot(tt.slot); got != tt.want {
t.Errorf("PrevSlot() = %v, want %v", got, tt.want)
}
})
}
}
func TestSyncCommitteePeriod(t *testing.T) {
tests := []struct {
epoch types.Epoch
wanted uint64
}{
{epoch: 0, wanted: 0},
{epoch: 0, wanted: 0 / uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod)},
{epoch: 1, wanted: 1 / uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod)},
{epoch: 1000, wanted: 1000 / uint64(params.BeaconConfig().EpochsPerSyncCommitteePeriod)},
}
for _, test := range tests {
require.Equal(t, test.wanted, slots.SyncCommitteePeriod(test.epoch))
}
}
func TestSyncCommitteePeriodStartEpoch(t *testing.T) {
tests := []struct {
epoch types.Epoch
wanted types.Epoch
}{
{epoch: 0, wanted: 0},
{epoch: params.BeaconConfig().EpochsPerSyncCommitteePeriod + 1, wanted: params.BeaconConfig().EpochsPerSyncCommitteePeriod},
{epoch: params.BeaconConfig().EpochsPerSyncCommitteePeriod*2 + 100, wanted: params.BeaconConfig().EpochsPerSyncCommitteePeriod * 2},
{epoch: params.BeaconConfig().EpochsPerSyncCommitteePeriod*params.BeaconConfig().EpochsPerSyncCommitteePeriod + 1, wanted: params.BeaconConfig().EpochsPerSyncCommitteePeriod * params.BeaconConfig().EpochsPerSyncCommitteePeriod},
}
for _, test := range tests {
e, err := slots.SyncCommitteePeriodStartEpoch(test.epoch)
require.NoError(t, err)
require.Equal(t, test.wanted, e)
}
}
func TestCanUpgradeToAltair(t *testing.T) {
bc := params.BeaconConfig()
bc.AltairForkEpoch = 5
@@ -448,3 +113,69 @@ 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
canProcessEpoch bool
}{
{
slot: 1,
canProcessEpoch: false,
}, {
slot: 63,
canProcessEpoch: true,
},
{
slot: 64,
canProcessEpoch: false,
}, {
slot: 127,
canProcessEpoch: true,
}, {
slot: 1000000000,
canProcessEpoch: false,
},
}
for _, tt := range tests {
b := &eth.BeaconState{Slot: tt.slot}
s, err := v1.InitializeFromProto(b)
require.NoError(t, err)
assert.Equal(t, tt.canProcessEpoch, CanProcessEpoch(s), "CanProcessEpoch(%d)", tt.slot)
}
}

View File

@@ -46,7 +46,6 @@ go_library(
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/block:go_default_library",
"//runtime/version:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",

View File

@@ -213,9 +213,12 @@ func TestProcessEpoch_BadBalanceAltair(t *testing.T) {
assert.NoError(t, s.SetSlot(63))
assert.NoError(t, s.UpdateBalancesAtIndex(0, math.MaxUint64))
participation := byte(0)
participation = altair.AddValidatorFlag(participation, params.BeaconConfig().TimelyHeadFlagIndex)
participation = altair.AddValidatorFlag(participation, params.BeaconConfig().TimelySourceFlagIndex)
participation = altair.AddValidatorFlag(participation, params.BeaconConfig().TimelyTargetFlagIndex)
participation, err := altair.AddValidatorFlag(participation, params.BeaconConfig().TimelyHeadFlagIndex)
require.NoError(t, err)
participation, err = altair.AddValidatorFlag(participation, params.BeaconConfig().TimelySourceFlagIndex)
require.NoError(t, err)
participation, err = altair.AddValidatorFlag(participation, params.BeaconConfig().TimelyTargetFlagIndex)
require.NoError(t, err)
epochParticipation, err := s.CurrentEpochParticipation()
assert.NoError(t, err)

View File

@@ -22,7 +22,6 @@ import (
"github.com/prysmaticlabs/prysm/monitoring/tracing"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
"github.com/prysmaticlabs/prysm/runtime/version"
"github.com/prysmaticlabs/prysm/time/slots"
"go.opencensus.io/trace"
)
@@ -52,8 +51,8 @@ func ExecuteStateTransition(
if ctx.Err() != nil {
return nil, ctx.Err()
}
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return nil, errors.New("nil block")
if err := helpers.BeaconBlockIsNil(signed); err != nil {
return nil, err
}
ctx, span := trace.StartSpan(ctx, "core.state.ExecuteStateTransition")
@@ -237,7 +236,7 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
tracing.AnnotateError(span, err)
return nil, errors.Wrap(err, "could not process slot")
}
if CanProcessEpoch(state) {
if time.CanProcessEpoch(state) {
switch state.Version() {
case version.Phase0:
state, err = ProcessEpochPrecompute(ctx, state)
@@ -260,7 +259,7 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
return nil, errors.Wrap(err, "failed to increment state slot")
}
if CanUpgradeToAltair(state.Slot()) {
if time.CanUpgradeToAltair(state.Slot()) {
state, err = altair.UpgradeToAltair(ctx, state)
if err != nil {
tracing.AnnotateError(span, err)
@@ -279,18 +278,9 @@ func ProcessSlots(ctx context.Context, state state.BeaconState, slot types.Slot)
return state, nil
}
// CanUpgradeToAltair returns true if the input `slot` can upgrade to Altair.
// Spec code:
// If state.slot % SLOTS_PER_EPOCH == 0 and compute_epoch_at_slot(state.slot) == ALTAIR_FORK_EPOCH
func CanUpgradeToAltair(slot types.Slot) bool {
epochStart := slots.IsEpochStart(slot)
altairEpoch := slots.ToEpoch(slot) == params.BeaconConfig().AltairForkEpoch
return epochStart && altairEpoch
}
// VerifyOperationLengths verifies that block operation lengths are valid.
func VerifyOperationLengths(_ context.Context, state state.BeaconState, b block.SignedBeaconBlock) (state.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
if err := helpers.BeaconBlockIsNil(b); err != nil {
return nil, err
}
body := b.Block().Body()
@@ -343,15 +333,6 @@ func VerifyOperationLengths(_ context.Context, state state.BeaconState, b block.
return state, nil
}
// CanProcessEpoch checks the eligibility to process epoch.
// The epoch can be processed at the end of the last slot of every epoch
//
// Spec pseudocode definition:
// If (state.slot + 1) % SLOTS_PER_EPOCH == 0:
func CanProcessEpoch(state state.ReadOnlyBeaconState) bool {
return (state.Slot()+1)%params.BeaconConfig().SlotsPerEpoch == 0
}
// ProcessEpochPrecompute describes the per epoch operations that are performed on the beacon state.
// It's optimized by pre computing validator attested info and epoch total/attested balances upfront.
func ProcessEpochPrecompute(ctx context.Context, state state.BeaconState) (state.BeaconState, error) {

View File

@@ -6,6 +6,7 @@ import (
fuzz "github.com/google/gofuzz"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/time"
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
@@ -122,7 +123,7 @@ func TestFuzzCanProcessEpoch_10000(_ *testing.T) {
fuzzer.NilChance(0.1)
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
CanProcessEpoch(state)
time.CanProcessEpoch(state)
}
}

View File

@@ -185,7 +185,7 @@ func ProcessBlockNoVerifyAnySig(
) (*bls.SignatureSet, state.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.state.ProcessBlockNoVerifyAnySig")
defer span.End()
if err := helpers.VerifyNilBeaconBlock(signed); err != nil {
if err := helpers.BeaconBlockIsNil(signed); err != nil {
return nil, nil, err
}
@@ -258,7 +258,7 @@ func ProcessOperationsNoVerifyAttsSigs(
signedBeaconBlock block.SignedBeaconBlock) (state.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.state.ProcessOperationsNoVerifyAttsSigs")
defer span.End()
if err := helpers.VerifyNilBeaconBlock(signedBeaconBlock); err != nil {
if err := helpers.BeaconBlockIsNil(signedBeaconBlock); err != nil {
return nil, err
}
@@ -294,7 +294,7 @@ func ProcessBlockForStateRoot(
) (state.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.state.ProcessBlockForStateRoot")
defer span.End()
if err := helpers.VerifyNilBeaconBlock(signed); err != nil {
if err := helpers.BeaconBlockIsNil(signed); err != nil {
return nil, err
}

View File

@@ -382,38 +382,6 @@ func TestProcessEpochPrecompute_CanProcess(t *testing.T) {
assert.Equal(t, uint64(0), newState.Slashings()[2], "Unexpected slashed balance")
}
func TestCanProcessEpoch_TrueOnEpochs(t *testing.T) {
tests := []struct {
slot types.Slot
canProcessEpoch bool
}{
{
slot: 1,
canProcessEpoch: false,
}, {
slot: 63,
canProcessEpoch: true,
},
{
slot: 64,
canProcessEpoch: false,
}, {
slot: 127,
canProcessEpoch: true,
}, {
slot: 1000000000,
canProcessEpoch: false,
},
}
for _, tt := range tests {
b := &ethpb.BeaconState{Slot: tt.slot}
s, err := v1.InitializeFromProto(b)
require.NoError(t, err)
assert.Equal(t, tt.canProcessEpoch, transition.CanProcessEpoch(s), "CanProcessEpoch(%d)", tt.slot)
}
}
func TestProcessBlock_OverMaxProposerSlashings(t *testing.T) {
maxSlashings := params.BeaconConfig().MaxProposerSlashings
b := &ethpb.SignedBeaconBlock{
@@ -589,37 +557,3 @@ func TestProcessSlotsUsingNextSlotCache(t *testing.T) {
require.NoError(t, err)
require.Equal(t, types.Slot(5), s.Slot())
}
func TestCanUpgradeToAltair(t *testing.T) {
bc := params.BeaconConfig()
bc.AltairForkEpoch = 5
params.OverrideBeaconConfig(bc)
tests := []struct {
name string
slot types.Slot
want bool
}{
{
name: "not epoch start",
slot: 1,
want: false,
},
{
name: "not altair epoch",
slot: params.BeaconConfig().SlotsPerEpoch,
want: false,
},
{
name: "altair epoch",
slot: types.Slot(params.BeaconConfig().AltairForkEpoch) * params.BeaconConfig().SlotsPerEpoch,
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := transition.CanUpgradeToAltair(tt.slot); got != tt.want {
t.Errorf("canUpgradeToAltair() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -5,7 +5,7 @@ import (
"fmt"
"path"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/io/file"
bolt "go.etcd.io/bbolt"
@@ -34,8 +34,8 @@ func (s *Store) Backup(ctx context.Context, outputDir string, permissionOverride
if err != nil {
return err
}
if head == nil || head.IsNil() {
return errors.New("no head block")
if err := helpers.BeaconBlockIsNil(head); err != nil {
return err
}
// Ensure the backups directory exists.
if err := file.HandleBackupDir(backupsDir, permissionOverride); err != nil {

View File

@@ -3,8 +3,8 @@ package kv
import (
"bytes"
"context"
"fmt"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/monitoring/tracing"
@@ -84,8 +84,7 @@ func (s *Store) updateFinalizedBlockRoots(ctx context.Context, tx *bolt.Tx, chec
tracing.AnnotateError(span, err)
return err
}
if signedBlock == nil || signedBlock.IsNil() || signedBlock.Block().IsNil() {
err := fmt.Errorf("missing block in database: block root=%#x", root)
if err := helpers.BeaconBlockIsNil(signedBlock); err != nil {
tracing.AnnotateError(span, err)
return err
}

View File

@@ -568,7 +568,7 @@ func (s *Store) slotByBlockRoot(ctx context.Context, tx *bolt.Tx, blockRoot []by
if err != nil {
return 0, err
}
if err := helpers.VerifyNilBeaconBlock(wrapper.WrappedPhase0SignedBeaconBlock(b)); err != nil {
if err := helpers.BeaconBlockIsNil(wrapper.WrappedPhase0SignedBeaconBlock(b)); err != nil {
return 0, err
}
return b.Block.Slot, nil

View File

@@ -6,7 +6,7 @@ go_library(
"log.go",
"service.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/interop-cold-start",
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/deterministic-genesis",
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/cache/depositcache:go_default_library",

View File

@@ -4,4 +4,4 @@ import (
"github.com/sirupsen/logrus"
)
var log = logrus.WithField("prefix", "interop-cold-start")
var log = logrus.WithField("prefix", "deterministic-genesis")

View File

@@ -1,4 +1,4 @@
// Package interopcoldstart allows for spinning up a deterministic
// Package interopcoldstart allows for spinning up a deterministic-genesis
// local chain without the need for eth1 deposits useful for
// local client development and interoperability testing.
package interopcoldstart

View File

@@ -11,26 +11,26 @@ import (
// MuxConfig contains configuration that should be used when registering the beacon node in the gateway.
type MuxConfig struct {
Handler gateway.MuxHandler
EthPbMux *gateway.PbMux
V1Alpha1PbMux *gateway.PbMux
Handler gateway.MuxHandler
EthPbMux *gateway.PbMux
V1AlphaPbMux *gateway.PbMux
}
// DefaultConfig returns a fully configured MuxConfig with standard gateway behavior.
func DefaultConfig(enableDebugRPCEndpoints bool, httpModules string) MuxConfig {
var v1Alpha1PbHandler, ethPbHandler *gateway.PbMux
var v1AlphaPbHandler, ethPbHandler *gateway.PbMux
if flags.EnableHTTPPrysmAPI(httpModules) {
v1Alpha1Registrations := []gateway.PbHandlerRegistration{
v1AlphaRegistrations := []gateway.PbHandlerRegistration{
ethpbalpha.RegisterNodeHandler,
ethpbalpha.RegisterBeaconChainHandler,
ethpbalpha.RegisterBeaconNodeValidatorHandler,
ethpbalpha.RegisterHealthHandler,
}
if enableDebugRPCEndpoints {
v1Alpha1Registrations = append(v1Alpha1Registrations, ethpbalpha.RegisterDebugHandler)
v1AlphaRegistrations = append(v1AlphaRegistrations, ethpbalpha.RegisterDebugHandler)
}
v1Alpha1Mux := gwruntime.NewServeMux(
v1AlphaMux := gwruntime.NewServeMux(
gwruntime.WithMarshalerOption(gwruntime.MIMEWildcard, &gwruntime.HTTPBodyMarshaler{
Marshaler: &gwruntime.JSONPb{
MarshalOptions: protojson.MarshalOptions{
@@ -45,10 +45,10 @@ func DefaultConfig(enableDebugRPCEndpoints bool, httpModules string) MuxConfig {
"text/event-stream", &gwruntime.EventSourceJSONPb{},
),
)
v1Alpha1PbHandler = &gateway.PbMux{
Registrations: v1Alpha1Registrations,
Patterns: []string{"/eth/v1alpha1/"},
Mux: v1Alpha1Mux,
v1AlphaPbHandler = &gateway.PbMux{
Registrations: v1AlphaRegistrations,
Patterns: []string{"/eth/v1alpha1/", "/eth/v1alpha2/"},
Mux: v1AlphaMux,
}
}
if flags.EnableHTTPEthAPI(httpModules) {
@@ -83,7 +83,7 @@ func DefaultConfig(enableDebugRPCEndpoints bool, httpModules string) MuxConfig {
}
return MuxConfig{
EthPbMux: ethPbHandler,
V1Alpha1PbMux: v1Alpha1PbHandler,
EthPbMux: ethPbHandler,
V1AlphaPbMux: v1AlphaPbHandler,
}
}

View File

@@ -16,10 +16,11 @@ func TestDefaultConfig(t *testing.T) {
assert.Equal(t, "/internal/eth/v1/", cfg.EthPbMux.Patterns[0])
assert.Equal(t, "/internal/eth/v2/", cfg.EthPbMux.Patterns[1])
assert.Equal(t, 4, len(cfg.EthPbMux.Registrations))
assert.NotNil(t, cfg.V1Alpha1PbMux.Mux)
require.Equal(t, 1, len(cfg.V1Alpha1PbMux.Patterns))
assert.Equal(t, "/eth/v1alpha1/", cfg.V1Alpha1PbMux.Patterns[0])
assert.Equal(t, 4, len(cfg.V1Alpha1PbMux.Registrations))
assert.NotNil(t, cfg.V1AlphaPbMux.Mux)
require.Equal(t, 2, len(cfg.V1AlphaPbMux.Patterns))
assert.Equal(t, "/eth/v1alpha1/", cfg.V1AlphaPbMux.Patterns[0])
assert.Equal(t, "/eth/v1alpha2/", cfg.V1AlphaPbMux.Patterns[1])
assert.Equal(t, 4, len(cfg.V1AlphaPbMux.Registrations))
})
t.Run("With debug endpoints", func(t *testing.T) {
@@ -29,10 +30,11 @@ func TestDefaultConfig(t *testing.T) {
assert.Equal(t, "/internal/eth/v1/", cfg.EthPbMux.Patterns[0])
assert.Equal(t, "/internal/eth/v2/", cfg.EthPbMux.Patterns[1])
assert.Equal(t, 5, len(cfg.EthPbMux.Registrations))
assert.NotNil(t, cfg.V1Alpha1PbMux.Mux)
require.Equal(t, 1, len(cfg.V1Alpha1PbMux.Patterns))
assert.Equal(t, "/eth/v1alpha1/", cfg.V1Alpha1PbMux.Patterns[0])
assert.Equal(t, 5, len(cfg.V1Alpha1PbMux.Registrations))
assert.NotNil(t, cfg.V1AlphaPbMux.Mux)
require.Equal(t, 2, len(cfg.V1AlphaPbMux.Patterns))
assert.Equal(t, "/eth/v1alpha1/", cfg.V1AlphaPbMux.Patterns[0])
assert.Equal(t, "/eth/v1alpha2/", cfg.V1AlphaPbMux.Patterns[1])
assert.Equal(t, 5, len(cfg.V1AlphaPbMux.Registrations))
})
t.Run("Without Prysm API", func(t *testing.T) {
cfg := DefaultConfig(true, "eth")
@@ -40,14 +42,15 @@ func TestDefaultConfig(t *testing.T) {
require.Equal(t, 2, len(cfg.EthPbMux.Patterns))
assert.Equal(t, "/internal/eth/v1/", cfg.EthPbMux.Patterns[0])
assert.Equal(t, 5, len(cfg.EthPbMux.Registrations))
assert.Equal(t, (*gateway.PbMux)(nil), cfg.V1Alpha1PbMux)
assert.Equal(t, (*gateway.PbMux)(nil), cfg.V1AlphaPbMux)
})
t.Run("Without Eth API", func(t *testing.T) {
cfg := DefaultConfig(true, "prysm")
assert.Equal(t, (*gateway.PbMux)(nil), cfg.EthPbMux)
assert.NotNil(t, cfg.V1Alpha1PbMux.Mux)
require.Equal(t, 1, len(cfg.V1Alpha1PbMux.Patterns))
assert.Equal(t, "/eth/v1alpha1/", cfg.V1Alpha1PbMux.Patterns[0])
assert.Equal(t, 5, len(cfg.V1Alpha1PbMux.Registrations))
assert.NotNil(t, cfg.V1AlphaPbMux.Mux)
require.Equal(t, 2, len(cfg.V1AlphaPbMux.Patterns))
assert.Equal(t, "/eth/v1alpha1/", cfg.V1AlphaPbMux.Patterns[0])
assert.Equal(t, "/eth/v1alpha2/", cfg.V1AlphaPbMux.Patterns[1])
assert.Equal(t, 5, len(cfg.V1AlphaPbMux.Registrations))
})
}

View File

@@ -6,6 +6,7 @@ go_library(
"config.go",
"log.go",
"node.go",
"options.go",
"prometheus.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/node",
@@ -18,14 +19,13 @@ go_library(
"//async/event:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/cache/depositcache:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/db/kv:go_default_library",
"//beacon-chain/db/slasherkv:go_default_library",
"//beacon-chain/deterministic-genesis:go_default_library",
"//beacon-chain/forkchoice:go_default_library",
"//beacon-chain/forkchoice/protoarray:go_default_library",
"//beacon-chain/gateway:go_default_library",
"//beacon-chain/interop-cold-start:go_default_library",
"//beacon-chain/node/registration:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",
@@ -36,6 +36,7 @@ go_library(
"//beacon-chain/rpc:go_default_library",
"//beacon-chain/rpc/apimiddleware:go_default_library",
"//beacon-chain/slasher:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/sync:go_default_library",
"//beacon-chain/sync/initial-sync:go_default_library",
@@ -44,6 +45,7 @@ go_library(
"//config/features:go_default_library",
"//config/params:go_default_library",
"//container/slice:go_default_library",
"//encoding/bytesutil:go_default_library",
"//monitoring/backup:go_default_library",
"//monitoring/prometheus:go_default_library",
"//monitoring/tracing:go_default_library",
@@ -75,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

@@ -21,14 +21,13 @@ import (
"github.com/prysmaticlabs/prysm/async/event"
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/db/kv"
"github.com/prysmaticlabs/prysm/beacon-chain/db/slasherkv"
interopcoldstart "github.com/prysmaticlabs/prysm/beacon-chain/deterministic-genesis"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/gateway"
interopcoldstart "github.com/prysmaticlabs/prysm/beacon-chain/interop-cold-start"
"github.com/prysmaticlabs/prysm/beacon-chain/node/registration"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
@@ -39,6 +38,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/rpc"
"github.com/prysmaticlabs/prysm/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/beacon-chain/slasher"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
regularsync "github.com/prysmaticlabs/prysm/beacon-chain/sync"
initialsync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync"
@@ -47,6 +47,7 @@ import (
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/container/slice"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/monitoring/backup"
"github.com/prysmaticlabs/prysm/monitoring/prometheus"
"github.com/prysmaticlabs/prysm/runtime"
@@ -62,6 +63,14 @@ const testSkipPowFlag = "test-skip-pow"
// 128MB max message size when enabling debug endpoints.
const debugGrpcMaxMsgSize = 1 << 27
// Used as a struct to keep cli flag options for configuring services
// for the beacon node. We keep this as a separate struct to not pollute the actual BeaconNode
// struct, as it is merely used to pass down configuration options into the appropriate services.
type serviceFlagOpts struct {
blockchainFlagOpts []blockchain.Option
powchainFlagOpts []powchain.Option
}
// BeaconNode defines a struct that handles the services running a random beacon chain
// full PoS node. It handles the lifecycle of the entire system and registers
// services to a service registry.
@@ -87,11 +96,13 @@ type BeaconNode struct {
collector *bcnodeCollector
slasherBlockHeadersFeed *event.Feed
slasherAttestationsFeed *event.Feed
finalizedStateAtStartUp state.BeaconState
serviceFlagOpts *serviceFlagOpts
}
// New creates a new node instance, sets up configuration options, and registers
// every required service to the node.
func New(cliCtx *cli.Context) (*BeaconNode, error) {
func New(cliCtx *cli.Context, opts ...Option) (*BeaconNode, error) {
if err := configureTracing(cliCtx); err != nil {
return nil, err
}
@@ -127,9 +138,16 @@ func New(cliCtx *cli.Context) (*BeaconNode, error) {
syncCommitteePool: synccommittee.NewPool(),
slasherBlockHeadersFeed: new(event.Feed),
slasherAttestationsFeed: new(event.Feed),
serviceFlagOpts: &serviceFlagOpts{},
}
depositAddress, err := registration.DepositContractAddress()
for _, opt := range opts {
if err := opt(beacon); err != nil {
return nil, err
}
}
depositAddress, err := powchain.DepositContractAddress()
if err != nil {
return nil, err
}
@@ -141,7 +159,9 @@ func New(cliCtx *cli.Context) (*BeaconNode, error) {
return nil, err
}
beacon.startStateGen()
if err := beacon.startStateGen(); err != nil {
return nil, err
}
if err := beacon.registerP2P(cliCtx); err != nil {
return nil, err
@@ -155,7 +175,7 @@ func New(cliCtx *cli.Context) (*BeaconNode, error) {
return nil, err
}
if err := beacon.registerInteropServices(); err != nil {
if err := beacon.registerDeterminsticGenesisService(); err != nil {
return nil, err
}
@@ -414,8 +434,34 @@ func (b *BeaconNode) startSlasherDB(cliCtx *cli.Context) error {
return nil
}
func (b *BeaconNode) startStateGen() {
func (b *BeaconNode) startStateGen() error {
b.stateGen = stategen.New(b.db)
cp, err := b.db.FinalizedCheckpoint(b.ctx)
if err != nil {
return err
}
r := bytesutil.ToBytes32(cp.Root)
// Consider edge case where finalized root are zeros instead of genesis root hash.
if r == params.BeaconConfig().ZeroHash {
genesisBlock, err := b.db.GenesisBlock(b.ctx)
if err != nil {
return err
}
if genesisBlock != nil && !genesisBlock.IsNil() {
r, err = genesisBlock.Block().HashTreeRoot()
if err != nil {
return err
}
}
}
b.finalizedStateAtStartUp, err = b.stateGen.StateByRoot(b.ctx, r)
if err != nil {
return err
}
return nil
}
func (b *BeaconNode) registerP2P(cliCtx *cli.Context) error {
@@ -480,29 +526,24 @@ func (b *BeaconNode) registerBlockchainService() error {
return err
}
wsp := b.cliCtx.String(flags.WeakSubjectivityCheckpt.Name)
wsCheckpt, err := helpers.ParseWeakSubjectivityInputString(wsp)
if err != nil {
return err
}
maxRoutines := b.cliCtx.Int(cmd.MaxGoroutines.Name)
blockchainService, err := blockchain.NewService(b.ctx, &blockchain.Config{
BeaconDB: b.db,
DepositCache: b.depositCache,
ChainStartFetcher: web3Service,
AttPool: b.attestationPool,
ExitPool: b.exitPool,
SlashingPool: b.slashingsPool,
P2p: b.fetchP2P(),
MaxRoutines: maxRoutines,
StateNotifier: b,
ForkChoiceStore: b.forkChoiceStore,
AttService: attService,
StateGen: b.stateGen,
SlasherAttestationsFeed: b.slasherAttestationsFeed,
WeakSubjectivityCheckpt: wsCheckpt,
})
// skipcq: CRT-D0001
opts := append(
b.serviceFlagOpts.blockchainFlagOpts,
blockchain.WithDatabase(b.db),
blockchain.WithDepositCache(b.depositCache),
blockchain.WithChainStartFetcher(web3Service),
blockchain.WithAttestationPool(b.attestationPool),
blockchain.WithExitPool(b.exitPool),
blockchain.WithSlashingPool(b.slashingsPool),
blockchain.WithP2PBroadcaster(b.fetchP2P()),
blockchain.WithStateNotifier(b),
blockchain.WithForkChoiceStore(b.forkChoiceStore),
blockchain.WithAttestationService(attService),
blockchain.WithStateGen(b.stateGen),
blockchain.WithSlasherAttestationsFeed(b.slasherAttestationsFeed),
blockchain.WithFinalizedStateAtStartUp(b.finalizedStateAtStartUp),
)
blockchainService, err := blockchain.NewService(b.ctx, opts...)
if err != nil {
return errors.Wrap(err, "could not register blockchain service")
}
@@ -513,29 +554,27 @@ func (b *BeaconNode) registerPOWChainService() error {
if b.cliCtx.Bool(testSkipPowFlag) {
return b.services.RegisterService(&powchain.Service{})
}
depAddress, endpoints, err := registration.PowchainPreregistration(b.cliCtx)
if err != nil {
return err
}
bs, err := powchain.NewPowchainCollector(b.ctx)
if err != nil {
return err
}
cfg := &powchain.Web3ServiceConfig{
HttpEndpoints: endpoints,
DepositContract: common.HexToAddress(depAddress),
BeaconDB: b.db,
DepositCache: b.depositCache,
StateNotifier: b,
StateGen: b.stateGen,
Eth1HeaderReqLimit: b.cliCtx.Uint64(flags.Eth1HeaderReqLimit.Name),
BeaconNodeStatsUpdater: bs,
depositContractAddr, err := powchain.DepositContractAddress()
if err != nil {
return err
}
web3Service, err := powchain.NewService(b.ctx, cfg)
// skipcq: CRT-D0001
opts := append(
b.serviceFlagOpts.powchainFlagOpts,
powchain.WithDepositContractAddress(common.HexToAddress(depositContractAddr)),
powchain.WithDatabase(b.db),
powchain.WithDepositCache(b.depositCache),
powchain.WithStateNotifier(b),
powchain.WithStateGen(b.stateGen),
powchain.WithBeaconNodeStatsUpdater(bs),
powchain.WithFinalizedStateAtStartup(b.finalizedStateAtStartUp),
)
web3Service, err := powchain.NewService(b.ctx, opts...)
if err != nil {
return errors.Wrap(err, "could not register proof-of-work chain web3Service")
}
@@ -559,24 +598,24 @@ func (b *BeaconNode) registerSyncService() error {
return err
}
rs := regularsync.NewService(b.ctx, &regularsync.Config{
DB: b.db,
P2P: b.fetchP2P(),
Chain: chainService,
InitialSync: initSync,
StateNotifier: b,
BlockNotifier: b,
AttestationNotifier: b,
OperationNotifier: b,
AttPool: b.attestationPool,
ExitPool: b.exitPool,
SlashingPool: b.slashingsPool,
SyncCommsPool: b.syncCommitteePool,
StateGen: b.stateGen,
SlasherAttestationsFeed: b.slasherAttestationsFeed,
SlasherBlockHeadersFeed: b.slasherBlockHeadersFeed,
})
rs := regularsync.NewService(
b.ctx,
regularsync.WithDatabase(b.db),
regularsync.WithP2P(b.fetchP2P()),
regularsync.WithChainService(chainService),
regularsync.WithInitialSync(initSync),
regularsync.WithStateNotifier(b),
regularsync.WithBlockNotifier(b),
regularsync.WithAttestationNotifier(b),
regularsync.WithOperationNotifier(b),
regularsync.WithAttestationPool(b.attestationPool),
regularsync.WithExitPool(b.exitPool),
regularsync.WithSlashingPool(b.slashingsPool),
regularsync.WithSyncCommsPool(b.syncCommitteePool),
regularsync.WithStateGen(b.stateGen),
regularsync.WithSlasherAttestationsFeed(b.slasherAttestationsFeed),
regularsync.WithSlasherBlockHeadersFeed(b.slasherBlockHeadersFeed),
)
return b.services.RegisterService(rs)
}
@@ -778,8 +817,8 @@ func (b *BeaconNode) registerGRPCGateway() error {
gatewayConfig := gateway.DefaultConfig(enableDebugRPCEndpoints, httpModules)
muxs := make([]*apigateway.PbMux, 0)
if gatewayConfig.V1Alpha1PbMux != nil {
muxs = append(muxs, gatewayConfig.V1Alpha1PbMux)
if gatewayConfig.V1AlphaPbMux != nil {
muxs = append(muxs, gatewayConfig.V1AlphaPbMux)
}
if gatewayConfig.EthPbMux != nil {
muxs = append(muxs, gatewayConfig.EthPbMux)
@@ -801,7 +840,7 @@ func (b *BeaconNode) registerGRPCGateway() error {
return b.services.RegisterService(g)
}
func (b *BeaconNode) registerInteropServices() error {
func (b *BeaconNode) registerDeterminsticGenesisService() error {
genesisTime := b.cliCtx.Uint64(flags.InteropGenesisTimeFlag.Name)
genesisValidators := b.cliCtx.Uint64(flags.InteropNumValidatorsFlag.Name)
genesisStatePath := b.cliCtx.String(flags.InteropGenesisStateFlag.Name)

View File

@@ -0,0 +1,25 @@
package node
import (
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
)
// Option for beacon node configuration.
type Option func(bn *BeaconNode) error
// WithBlockchainFlagOptions includes functional options for the blockchain service related to CLI flags.
func WithBlockchainFlagOptions(opts []blockchain.Option) Option {
return func(bn *BeaconNode) error {
bn.serviceFlagOpts.blockchainFlagOpts = opts
return nil
}
}
// WithPowchainFlagOptions includes functional options for the powchain service related to CLI flags.
func WithPowchainFlagOptions(opts []powchain.Option) Option {
return func(bn *BeaconNode) error {
bn.serviceFlagOpts.powchainFlagOpts = opts
return nil
}
}

View File

@@ -5,15 +5,12 @@ go_library(
srcs = [
"log.go",
"p2p.go",
"powchain.go",
],
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/node/registration",
visibility = ["//beacon-chain/node:__subpackages__"],
deps = [
"//cmd:go_default_library",
"//cmd/beacon-chain/flags:go_default_library",
"//config/params:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
"@in_gopkg_yaml_v2//:go_default_library",
@@ -22,18 +19,13 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"p2p_test.go",
"powchain_test.go",
],
srcs = ["p2p_test.go"],
embed = [":go_default_library"],
deps = [
"//cmd:go_default_library",
"//cmd/beacon-chain/flags:go_default_library",
"//config/params:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
],
)

View File

@@ -1,45 +0,0 @@
package registration
import (
"errors"
"github.com/ethereum/go-ethereum/common"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/urfave/cli/v2"
)
// PowchainPreregistration prepares data for powchain.Service's registration.
func PowchainPreregistration(cliCtx *cli.Context) (depositContractAddress string, endpoints []string, err error) {
depositContractAddress, err = DepositContractAddress()
if err != nil {
return "", nil, err
}
if cliCtx.String(flags.HTTPWeb3ProviderFlag.Name) == "" && len(cliCtx.StringSlice(flags.FallbackWeb3ProviderFlag.Name)) == 0 {
log.Error(
"No ETH1 node specified to run with the beacon node. Please consider running your own Ethereum proof-of-work node for better uptime, security, and decentralization of Ethereum. Visit https://docs.prylabs.network/docs/prysm-usage/setup-eth1 for more information.",
)
log.Error(
"You will need to specify --http-web3provider and/or --fallback-web3provider to attach an eth1 node to the prysm node. Without an eth1 node block proposals for your validator will be affected and the beacon node will not be able to initialize the genesis state.",
)
}
endpoints = []string{cliCtx.String(flags.HTTPWeb3ProviderFlag.Name)}
endpoints = append(endpoints, cliCtx.StringSlice(flags.FallbackWeb3ProviderFlag.Name)...)
return
}
// DepositContractAddress returns the address of the deposit contract.
func DepositContractAddress() (string, error) {
address := params.BeaconConfig().DepositContractAddress
if address == "" {
return "", errors.New("valid deposit contract is required")
}
if !common.IsHexAddress(address) {
return "", errors.New("invalid deposit contract address given: " + address)
}
return address, nil
}

View File

@@ -1,71 +0,0 @@
package registration
import (
"flag"
"testing"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
logTest "github.com/sirupsen/logrus/hooks/test"
"github.com/urfave/cli/v2"
)
func TestPowchainPreregistration(t *testing.T) {
app := cli.App{}
set := flag.NewFlagSet("test", 0)
set.String(flags.HTTPWeb3ProviderFlag.Name, "primary", "")
fallback := cli.StringSlice{}
err := fallback.Set("fallback1")
require.NoError(t, err)
err = fallback.Set("fallback2")
require.NoError(t, err)
set.Var(&fallback, flags.FallbackWeb3ProviderFlag.Name, "")
ctx := cli.NewContext(&app, set, nil)
address, endpoints, err := PowchainPreregistration(ctx)
require.NoError(t, err)
assert.Equal(t, params.BeaconConfig().DepositContractAddress, address)
assert.DeepEqual(t, []string{"primary", "fallback1", "fallback2"}, endpoints)
}
func TestPowchainPreregistration_EmptyWeb3Provider(t *testing.T) {
hook := logTest.NewGlobal()
app := cli.App{}
set := flag.NewFlagSet("test", 0)
set.String(flags.HTTPWeb3ProviderFlag.Name, "", "")
fallback := cli.StringSlice{}
set.Var(&fallback, flags.FallbackWeb3ProviderFlag.Name, "")
ctx := cli.NewContext(&app, set, nil)
_, _, err := PowchainPreregistration(ctx)
require.NoError(t, err)
assert.LogsContain(t, hook, "No ETH1 node specified to run with the beacon node")
}
func TestDepositContractAddress_Ok(t *testing.T) {
address, err := DepositContractAddress()
require.NoError(t, err)
assert.Equal(t, params.BeaconConfig().DepositContractAddress, address)
}
func TestDepositContractAddress_EmptyAddress(t *testing.T) {
params.SetupTestConfigCleanup(t)
config := params.BeaconConfig()
config.DepositContractAddress = ""
params.OverrideBeaconConfig(config)
_, err := DepositContractAddress()
assert.ErrorContains(t, "valid deposit contract is required", err)
}
func TestDepositContractAddress_NotHexAddress(t *testing.T) {
params.SetupTestConfigCleanup(t)
config := params.BeaconConfig()
config.DepositContractAddress = "abc?!"
params.OverrideBeaconConfig(config)
_, err := DepositContractAddress()
assert.ErrorContains(t, "invalid deposit contract address given", err)
}

View File

@@ -39,6 +39,7 @@ go_test(
],
embed = [":go_default_library"],
deps = [
"//config/params:go_default_library",
"//crypto/bls:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//testing/assert:go_default_library",

View File

@@ -9,6 +9,7 @@ import (
fssz "github.com/ferranbt/fastssz"
c "github.com/patrickmn/go-cache"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/config/params"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
@@ -66,7 +67,7 @@ func TestKV_Unaggregated_SaveUnaggregatedAttestation(t *testing.T) {
assert.Equal(t, 0, len(cache.unAggregatedAtt), "Invalid start pool, atts: %d", len(cache.unAggregatedAtt))
if tt.att != nil && tt.att.Signature == nil {
tt.att.Signature = make([]byte, 96)
tt.att.Signature = make([]byte, params.BeaconConfig().BLSSignatureLength)
}
err := cache.SaveUnaggregatedAttestation(tt.att)

View File

@@ -30,14 +30,14 @@ func TestPruneExpired_Ticker(t *testing.T) {
ad2 := util.HydrateAttestationData(&ethpb.AttestationData{Slot: 1})
atts := []*ethpb.Attestation{
{Data: ad1, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, 96)},
{Data: ad2, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, 96)},
{Data: ad1, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, params.BeaconConfig().BLSSignatureLength)},
{Data: ad2, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, params.BeaconConfig().BLSSignatureLength)},
}
require.NoError(t, s.cfg.Pool.SaveUnaggregatedAttestations(atts))
require.Equal(t, 2, s.cfg.Pool.UnaggregatedAttestationCount(), "Unexpected number of attestations")
atts = []*ethpb.Attestation{
{Data: ad1, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, 96)},
{Data: ad2, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, 96)},
{Data: ad1, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, params.BeaconConfig().BLSSignatureLength)},
{Data: ad2, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, params.BeaconConfig().BLSSignatureLength)},
}
require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(atts))
assert.Equal(t, 2, s.cfg.Pool.AggregatedAttestationCount())

View File

@@ -74,7 +74,7 @@ func (s *Store) SyncCommitteeContributions(slot types.Slot) ([]*ethpb.SyncCommit
item := s.contributionCache.RetrieveByKey(syncCommitteeKey(slot))
if item == nil {
return nil, nil
return []*ethpb.SyncCommitteeContribution{}, nil
}
contributions, ok := item.Value.([]*ethpb.SyncCommitteeContribution)

View File

@@ -36,11 +36,11 @@ func TestSyncCommitteeContributionCache_RoundTrip(t *testing.T) {
conts, err := store.SyncCommitteeContributions(1)
require.NoError(t, err)
require.DeepSSZEqual(t, []*ethpb.SyncCommitteeContribution(nil), conts)
require.DeepSSZEqual(t, []*ethpb.SyncCommitteeContribution{}, conts)
conts, err = store.SyncCommitteeContributions(2)
require.NoError(t, err)
require.DeepSSZEqual(t, []*ethpb.SyncCommitteeContribution(nil), conts)
require.DeepSSZEqual(t, []*ethpb.SyncCommitteeContribution{}, conts)
conts, err = store.SyncCommitteeContributions(3)
require.NoError(t, err)
@@ -73,10 +73,10 @@ func TestSyncCommitteeContributionCache_RoundTrip(t *testing.T) {
// All the contributions should persist after get.
conts, err = store.SyncCommitteeContributions(1)
require.NoError(t, err)
require.DeepSSZEqual(t, []*ethpb.SyncCommitteeContribution(nil), conts)
require.DeepSSZEqual(t, []*ethpb.SyncCommitteeContribution{}, conts)
conts, err = store.SyncCommitteeContributions(2)
require.NoError(t, err)
require.DeepSSZEqual(t, []*ethpb.SyncCommitteeContribution(nil), conts)
require.DeepSSZEqual(t, []*ethpb.SyncCommitteeContribution{}, conts)
conts, err = store.SyncCommitteeContributions(3)
require.NoError(t, err)

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

@@ -143,7 +143,7 @@ func TestScorers_Service_Score(t *testing.T) {
s, pids := setupScorer()
// Peers start with boosted start score (new peers are boosted by block provider).
startScore := float64(0)
penalty := (-10 / float64(s.BadResponsesScorer().Params().Threshold)) * float64(0.3)
penalty := (-10 / float64(s.BadResponsesScorer().Params().Threshold)) * 0.3
// Update peers' stats and test the effect on peer order.
s.BadResponsesScorer().Increment("peer2")
@@ -197,7 +197,7 @@ func TestScorers_Service_Score(t *testing.T) {
s, _ := setupScorer()
s1 := s.BlockProviderScorer()
s2 := s.BadResponsesScorer()
penalty := (-10 / float64(s.BadResponsesScorer().Params().Threshold)) * float64(0.3)
penalty := (-10 / float64(s.BadResponsesScorer().Params().Threshold)) * 0.3
// Full score, no penalty.
s1.IncrementProcessedBlocks("peer1", batchSize*5)

View File

@@ -8,6 +8,7 @@ go_library(
"deposit.go",
"log.go",
"log_processing.go",
"options.go",
"prometheus.go",
"provider.go",
"service.go",
@@ -15,6 +16,7 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/powchain",
visibility = [
"//beacon-chain:__subpackages__",
"//cmd/beacon-chain:__subpackages__",
"//contracts:__subpackages__",
],
deps = [
@@ -94,7 +96,6 @@ go_test(
"//network:go_default_library",
"//network/authorization:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/wrapper:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",

View File

@@ -22,7 +22,7 @@ var endpoint = "http://127.0.0.1"
func setDefaultMocks(service *Service) *Service {
service.eth1DataFetcher = &goodFetcher{}
service.httpLogger = &goodLogger{}
service.cfg.StateNotifier = &goodNotifier{}
service.cfg.stateNotifier = &goodNotifier{}
return service
}
@@ -31,11 +31,11 @@ func TestLatestMainchainInfo_OK(t *testing.T) {
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "Unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -69,10 +69,10 @@ func TestLatestMainchainInfo_OK(t *testing.T) {
func TestBlockHashByHeight_ReturnsHash(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -96,10 +96,10 @@ func TestBlockHashByHeight_ReturnsHash(t *testing.T) {
func TestBlockHashByHeight_ReturnsError_WhenNoEth1Client(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -112,10 +112,10 @@ func TestBlockHashByHeight_ReturnsError_WhenNoEth1Client(t *testing.T) {
func TestBlockExists_ValidHash(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -143,10 +143,10 @@ func TestBlockExists_ValidHash(t *testing.T) {
func TestBlockExists_InvalidHash(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -157,10 +157,10 @@ func TestBlockExists_InvalidHash(t *testing.T) {
func TestBlockExists_UsesCachedBlockInfo(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
// nil eth1DataFetcher would panic if cached value not used
web3Service.eth1DataFetcher = nil
@@ -180,10 +180,10 @@ func TestBlockExists_UsesCachedBlockInfo(t *testing.T) {
func TestBlockExistsWithCache_UsesCachedHeaderInfo(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
header := &gethTypes.Header{
@@ -201,10 +201,10 @@ func TestBlockExistsWithCache_UsesCachedHeaderInfo(t *testing.T) {
func TestBlockExistsWithCache_HeaderNotCached(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
exists, height, err := web3Service.BlockExistsWithCache(context.Background(), common.BytesToHash([]byte("hash")))
@@ -217,10 +217,10 @@ func TestService_BlockNumberByTimestamp(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
@@ -244,10 +244,10 @@ func TestService_BlockNumberByTimestampLessTargetTime(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
@@ -277,10 +277,10 @@ func TestService_BlockNumberByTimestampMoreTargetTime(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
@@ -308,10 +308,10 @@ func TestService_BlockNumberByTimestampMoreTargetTime(t *testing.T) {
func TestService_BlockTimeByHeight_ReturnsError_WhenNoEth1Client(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)

View File

@@ -3,11 +3,26 @@ package powchain
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/config/params"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
// DepositContractAddress returns the deposit contract address for the given chain.
func DepositContractAddress() (string, error) {
address := params.BeaconConfig().DepositContractAddress
if address == "" {
return "", errors.New("valid deposit contract is required")
}
if !common.IsHexAddress(address) {
return "", errors.New("invalid deposit contract address given: " + address)
}
return address, nil
}
func (s *Service) processDeposit(ctx context.Context, eth1Data *ethpb.Eth1Data, deposit *ethpb.Deposit) error {
var err error
if err := s.preGenesisState.SetEth1Data(eth1Data); err != nil {

View File

@@ -22,12 +22,39 @@ import (
const pubKeyErr = "could not convert bytes to public key"
func TestDepositContractAddress_EmptyAddress(t *testing.T) {
params.SetupTestConfigCleanup(t)
config := params.BeaconConfig()
config.DepositContractAddress = ""
params.OverrideBeaconConfig(config)
_, err := DepositContractAddress()
assert.ErrorContains(t, "valid deposit contract is required", err)
}
func TestDepositContractAddress_NotHexAddress(t *testing.T) {
params.SetupTestConfigCleanup(t)
config := params.BeaconConfig()
config.DepositContractAddress = "abc?!"
params.OverrideBeaconConfig(config)
_, err := DepositContractAddress()
assert.ErrorContains(t, "invalid deposit contract address given", err)
}
func TestDepositContractAddress_OK(t *testing.T) {
params.SetupTestConfigCleanup(t)
addr, err := DepositContractAddress()
require.NoError(t, err)
assert.Equal(t, params.BeaconConfig().DepositContractAddress, addr)
}
func TestProcessDeposit_OK(t *testing.T) {
beaconDB := testDB.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "Unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -48,10 +75,10 @@ func TestProcessDeposit_OK(t *testing.T) {
func TestProcessDeposit_InvalidMerkleBranch(t *testing.T) {
beaconDB := testDB.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -74,10 +101,10 @@ func TestProcessDeposit_InvalidMerkleBranch(t *testing.T) {
func TestProcessDeposit_InvalidPublicKey(t *testing.T) {
hook := logTest.NewGlobal()
beaconDB := testDB.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -110,10 +137,10 @@ func TestProcessDeposit_InvalidPublicKey(t *testing.T) {
func TestProcessDeposit_InvalidSignature(t *testing.T) {
hook := logTest.NewGlobal()
beaconDB := testDB.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -145,10 +172,10 @@ func TestProcessDeposit_InvalidSignature(t *testing.T) {
func TestProcessDeposit_UnableToVerify(t *testing.T) {
hook := logTest.NewGlobal()
beaconDB := testDB.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
@@ -177,10 +204,10 @@ func TestProcessDeposit_UnableToVerify(t *testing.T) {
func TestProcessDeposit_IncompleteDeposit(t *testing.T) {
beaconDB := testDB.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
require.NoError(t, web3Service.preGenesisState.SetValidators([]*ethpb.Validator{}))
@@ -189,7 +216,7 @@ func TestProcessDeposit_IncompleteDeposit(t *testing.T) {
Data: &ethpb.Deposit_Data{
Amount: params.BeaconConfig().EffectiveBalanceIncrement, // incomplete deposit
WithdrawalCredentials: bytesutil.PadTo([]byte("testing"), 32),
Signature: bytesutil.PadTo([]byte("test"), 96),
Signature: bytesutil.PadTo([]byte("test"), params.BeaconConfig().BLSSignatureLength),
},
}
@@ -220,7 +247,7 @@ func TestProcessDeposit_IncompleteDeposit(t *testing.T) {
factor := params.BeaconConfig().MaxEffectiveBalance / params.BeaconConfig().EffectiveBalanceIncrement
// deposit till 31e9
for i := 0; i < int(factor-1); i++ {
trie.Insert(dataRoot[:], i)
assert.NoError(t, trie.Insert(dataRoot[:], i))
trieRoot := trie.HashTreeRoot()
eth1Data.DepositRoot = trieRoot[:]
@@ -239,10 +266,10 @@ func TestProcessDeposit_IncompleteDeposit(t *testing.T) {
func TestProcessDeposit_AllDepositedSuccessfully(t *testing.T) {
beaconDB := testDB.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)

View File

@@ -30,7 +30,7 @@ var (
depositEventSignature = hash.HashKeccak256([]byte("DepositEvent(bytes,bytes,bytes,bytes,bytes)"))
)
const eth1DataSavingInterval = 100
const eth1DataSavingInterval = 1000
const maxTolerableDifference = 50
const defaultEth1HeaderReqLimit = uint64(1000)
const depositlogRequestLimit = 10000
@@ -52,7 +52,7 @@ func (s *Service) Eth2GenesisPowchainInfo() (uint64, *big.Int) {
func (s *Service) ProcessETH1Block(ctx context.Context, blkNum *big.Int) error {
query := ethereum.FilterQuery{
Addresses: []common.Address{
s.cfg.DepositContract,
s.cfg.depositContractAddr,
},
FromBlock: blkNum,
ToBlock: blkNum,
@@ -138,7 +138,9 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog gethTypes.Lo
if s.depositTrie.NumOfItems() != int(index) {
return errors.Errorf("invalid deposit index received: wanted %d but got %d", s.depositTrie.NumOfItems(), index)
}
s.depositTrie.Insert(depositHash[:], int(index))
if err = s.depositTrie.Insert(depositHash[:], int(index)); err != nil {
return err
}
deposit := &ethpb.Deposit{
Data: depositData,
@@ -153,7 +155,7 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog gethTypes.Lo
}
// We always store all historical deposits in the DB.
err = s.cfg.DepositCache.InsertDeposit(ctx, deposit, depositLog.BlockNumber, index, s.depositTrie.HashTreeRoot())
err = s.cfg.depositCache.InsertDeposit(ctx, deposit, depositLog.BlockNumber, index, s.depositTrie.HashTreeRoot())
if err != nil {
return errors.Wrap(err, "unable to insert deposit into cache")
}
@@ -170,7 +172,7 @@ func (s *Service) ProcessDepositLog(ctx context.Context, depositLog gethTypes.Lo
validData = false
}
} else {
s.cfg.DepositCache.InsertPendingDeposit(ctx, deposit, depositLog.BlockNumber, index, s.depositTrie.HashTreeRoot())
s.cfg.depositCache.InsertPendingDeposit(ctx, deposit, depositLog.BlockNumber, index, s.depositTrie.HashTreeRoot())
}
if validData {
log.WithFields(logrus.Fields{
@@ -229,7 +231,7 @@ func (s *Service) ProcessChainStart(genesisTime uint64, eth1BlockHash [32]byte,
log.WithFields(logrus.Fields{
"ChainStartTime": chainStartTime,
}).Info("Minimum number of validators reached for beacon-chain to start")
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
s.cfg.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.ChainStarted,
Data: &statefeed.ChainStartedData{
StartTime: chainStartTime,
@@ -286,7 +288,7 @@ func (s *Service) processPastLogs(ctx context.Context) error {
return err
}
batchSize := s.cfg.Eth1HeaderReqLimit
batchSize := s.cfg.eth1HeaderReqLimit
additiveFactor := uint64(float64(batchSize) * additiveFactorMultiplier)
for currentBlockNum < latestFollowHeight {
@@ -299,7 +301,7 @@ func (s *Service) processPastLogs(ctx context.Context) error {
}
query := ethereum.FilterQuery{
Addresses: []common.Address{
s.cfg.DepositContract,
s.cfg.depositContractAddr,
},
FromBlock: big.NewInt(int64(start)),
ToBlock: big.NewInt(int64(end)),
@@ -352,18 +354,18 @@ func (s *Service) processPastLogs(ctx context.Context) error {
}
currentBlockNum = end
if batchSize < s.cfg.Eth1HeaderReqLimit {
if batchSize < s.cfg.eth1HeaderReqLimit {
// update the batchSize with additive increase
batchSize += additiveFactor
if batchSize > s.cfg.Eth1HeaderReqLimit {
batchSize = s.cfg.Eth1HeaderReqLimit
if batchSize > s.cfg.eth1HeaderReqLimit {
batchSize = s.cfg.eth1HeaderReqLimit
}
}
}
s.latestEth1Data.LastRequestedBlock = currentBlockNum
c, err := s.cfg.BeaconDB.FinalizedCheckpoint(ctx)
c, err := s.cfg.beaconDB.FinalizedCheckpoint(ctx)
if err != nil {
return err
}
@@ -372,12 +374,12 @@ func (s *Service) processPastLogs(ctx context.Context) error {
if fRoot == params.BeaconConfig().ZeroHash {
return nil
}
fState, err := s.cfg.StateGen.StateByRoot(ctx, fRoot)
fState, err := s.cfg.stateGen.StateByRoot(ctx, fRoot)
if err != nil {
return err
}
if fState != nil && !fState.IsNil() && fState.Eth1DepositIndex() > 0 {
s.cfg.DepositCache.PrunePendingDeposits(ctx, int64(fState.Eth1DepositIndex()))
s.cfg.depositCache.PrunePendingDeposits(ctx, int64(fState.Eth1DepositIndex()))
}
return nil
}
@@ -498,7 +500,7 @@ func (s *Service) savePowchainData(ctx context.Context) error {
ChainstartData: s.chainStartData,
BeaconState: pbState, // I promise not to mutate it!
Trie: s.depositTrie.ToProto(),
DepositContainers: s.cfg.DepositCache.AllDepositContainers(ctx),
DepositContainers: s.cfg.depositCache.AllDepositContainers(ctx),
}
return s.cfg.BeaconDB.SavePowchainData(ctx, eth1Data)
return s.cfg.beaconDB.SavePowchainData(ctx, eth1Data)
}

View File

@@ -33,12 +33,12 @@ func TestProcessDepositLog_OK(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
DepositCache: depositCache,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
WithDepositCache(depositCache),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -62,7 +62,7 @@ func TestProcessDepositLog_OK(t *testing.T) {
query := ethereum.FilterQuery{
Addresses: []common.Address{
web3Service.cfg.DepositContract,
web3Service.cfg.depositContractAddr,
},
}
@@ -97,12 +97,12 @@ func TestProcessDepositLog_InsertsPendingDeposit(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
DepositCache: depositCache,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
WithDepositCache(depositCache),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -129,7 +129,7 @@ func TestProcessDepositLog_InsertsPendingDeposit(t *testing.T) {
query := ethereum.FilterQuery{
Addresses: []common.Address{
web3Service.cfg.DepositContract,
web3Service.cfg.depositContractAddr,
},
}
@@ -143,7 +143,7 @@ func TestProcessDepositLog_InsertsPendingDeposit(t *testing.T) {
err = web3Service.ProcessDepositLog(context.Background(), logs[1])
require.NoError(t, err)
pendingDeposits := web3Service.cfg.DepositCache.PendingDeposits(context.Background(), nil /*blockNum*/)
pendingDeposits := web3Service.cfg.depositCache.PendingDeposits(context.Background(), nil /*blockNum*/)
require.Equal(t, 2, len(pendingDeposits), "Unexpected number of deposits")
hook.Reset()
@@ -153,11 +153,11 @@ func TestUnpackDepositLogData_OK(t *testing.T) {
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := testDB.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
DepositContract: testAcc.ContractAddr,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -179,7 +179,7 @@ func TestUnpackDepositLogData_OK(t *testing.T) {
query := ethereum.FilterQuery{
Addresses: []common.Address{
web3Service.cfg.DepositContract,
web3Service.cfg.depositContractAddr,
},
}
@@ -203,12 +203,12 @@ func TestProcessETH2GenesisLog_8DuplicatePubkeys(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
DepositCache: depositCache,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
WithDepositCache(depositCache),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -244,7 +244,7 @@ func TestProcessETH2GenesisLog_8DuplicatePubkeys(t *testing.T) {
query := ethereum.FilterQuery{
Addresses: []common.Address{
web3Service.cfg.DepositContract,
web3Service.cfg.depositContractAddr,
},
}
@@ -273,12 +273,12 @@ func TestProcessETH2GenesisLog(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
DepositCache: depositCache,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
WithDepositCache(depositCache),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -311,7 +311,7 @@ func TestProcessETH2GenesisLog(t *testing.T) {
query := ethereum.FilterQuery{
Addresses: []common.Address{
web3Service.cfg.DepositContract,
web3Service.cfg.depositContractAddr,
},
}
@@ -321,7 +321,7 @@ func TestProcessETH2GenesisLog(t *testing.T) {
// Set up our subscriber now to listen for the chain started event.
stateChannel := make(chan *feed.Event, 1)
stateSub := web3Service.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
stateSub := web3Service.cfg.stateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
for _, log := range logs {
@@ -359,12 +359,12 @@ func TestProcessETH2GenesisLog_CorrectNumOfDeposits(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: kvStore,
DepositCache: depositCache,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(kvStore),
WithDepositCache(depositCache),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -418,7 +418,7 @@ func TestProcessETH2GenesisLog_CorrectNumOfDeposits(t *testing.T) {
// Set up our subscriber now to listen for the chain started event.
stateChannel := make(chan *feed.Event, 1)
stateSub := web3Service.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
stateSub := web3Service.cfg.stateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
err = web3Service.processPastLogs(context.Background())
@@ -452,12 +452,12 @@ func TestProcessETH2GenesisLog_LargePeriodOfNoLogs(t *testing.T) {
depositCache, err := depositcache.New()
require.NoError(t, err)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: kvStore,
DepositCache: depositCache,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(kvStore),
WithDepositCache(depositCache),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -522,7 +522,7 @@ func TestProcessETH2GenesisLog_LargePeriodOfNoLogs(t *testing.T) {
// Set up our subscriber now to listen for the chain started event.
stateChannel := make(chan *feed.Event, 1)
stateSub := web3Service.cfg.StateNotifier.StateFeed().Subscribe(stateChannel)
stateSub := web3Service.cfg.stateNotifier.StateFeed().Subscribe(stateChannel)
defer stateSub.Unsubscribe()
err = web3Service.processPastLogs(context.Background())
@@ -560,13 +560,12 @@ func TestCheckForChainstart_NoValidator(t *testing.T) {
func newPowchainService(t *testing.T, eth1Backend *contracts.TestAccount, beaconDB db.Database) *Service {
depositCache, err := depositcache.New()
require.NoError(t, err)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: eth1Backend.ContractAddr,
BeaconDB: beaconDB,
DepositCache: depositCache,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(eth1Backend.ContractAddr),
WithDatabase(beaconDB),
WithDepositCache(depositCache),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(eth1Backend.ContractAddr, eth1Backend.Backend)

View File

@@ -0,0 +1,97 @@
package powchain
import (
"github.com/ethereum/go-ethereum/common"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/network"
)
type Option func(s *Service) error
// WithHttpEndpoints deduplicates and parses http endpoints for the powchain service to use,
// and sets the "current" endpoint that will be used first.
func WithHttpEndpoints(endpointStrings []string) Option {
return func(s *Service) error {
stringEndpoints := dedupEndpoints(endpointStrings)
endpoints := make([]network.Endpoint, len(stringEndpoints))
for i, e := range stringEndpoints {
endpoints[i] = HttpEndpoint(e)
}
// Select first http endpoint in the provided list.
var currEndpoint network.Endpoint
if len(endpointStrings) > 0 {
currEndpoint = endpoints[0]
}
s.cfg.httpEndpoints = endpoints
s.cfg.currHttpEndpoint = currEndpoint
return nil
}
}
// WithDepositContractAddress for the deposit contract.
func WithDepositContractAddress(addr common.Address) Option {
return func(s *Service) error {
s.cfg.depositContractAddr = addr
return nil
}
}
// WithDatabase for the beacon chain database.
func WithDatabase(database db.HeadAccessDatabase) Option {
return func(s *Service) error {
s.cfg.beaconDB = database
return nil
}
}
// WithDepositCache for caching deposits.
func WithDepositCache(cache *depositcache.DepositCache) Option {
return func(s *Service) error {
s.cfg.depositCache = cache
return nil
}
}
// WithStateNotifier for subscribing to state changes.
func WithStateNotifier(notifier statefeed.Notifier) Option {
return func(s *Service) error {
s.cfg.stateNotifier = notifier
return nil
}
}
// WithStateGen to regenerate beacon states from checkpoints.
func WithStateGen(gen *stategen.State) Option {
return func(s *Service) error {
s.cfg.stateGen = gen
return nil
}
}
// WithEth1HeaderRequestLimit to set the upper limit of eth1 header requests.
func WithEth1HeaderRequestLimit(limit uint64) Option {
return func(s *Service) error {
s.cfg.eth1HeaderReqLimit = limit
return nil
}
}
// WithBeaconNodeStatsUpdater to set the beacon node stats updater.
func WithBeaconNodeStatsUpdater(updater BeaconNodeStatsUpdater) Option {
return func(s *Service) error {
s.cfg.beaconNodeStatsUpdater = updater
return nil
}
}
// WithFinalizedStateAtStartup to set the beacon node's finalized state at startup.
func WithFinalizedStateAtStartup(st state.BeaconState) Option {
return func(s *Service) error {
s.cfg.finalizedStateAtStartup = st
return nil
}
}

View File

@@ -120,6 +120,20 @@ type RPCClient interface {
BatchCall(b []gethRPC.BatchElem) error
}
// config defines a config struct for dependencies into the service.
type config struct {
depositContractAddr common.Address
beaconDB db.HeadAccessDatabase
depositCache *depositcache.DepositCache
stateNotifier statefeed.Notifier
stateGen *stategen.State
eth1HeaderReqLimit uint64
beaconNodeStatsUpdater BeaconNodeStatsUpdater
httpEndpoints []network.Endpoint
currHttpEndpoint network.Endpoint
finalizedStateAtStartup state.BeaconState
}
// Service fetches important information about the canonical
// Ethereum ETH1.0 chain via a web3 endpoint using an ethclient. The Random
// Beacon Chain requires synchronization with the ETH1.0 chain's current
@@ -130,12 +144,10 @@ type Service struct {
connectedETH1 bool
isRunning bool
processingLock sync.RWMutex
cfg *Web3ServiceConfig
cfg *config
ctx context.Context
cancel context.CancelFunc
headTicker *time.Ticker
httpEndpoints []network.Endpoint
currHttpEndpoint network.Endpoint
httpLogger bind.ContractFilterer
eth1DataFetcher RPCDataFetcher
rpcClient RPCClient
@@ -147,24 +159,10 @@ type Service struct {
lastReceivedMerkleIndex int64 // Keeps track of the last received index to prevent log spam.
runError error
preGenesisState state.BeaconState
bsUpdater BeaconNodeStatsUpdater
}
// Web3ServiceConfig defines a config struct for web3 service to use through its life cycle.
type Web3ServiceConfig struct {
HttpEndpoints []string
DepositContract common.Address
BeaconDB db.HeadAccessDatabase
DepositCache *depositcache.DepositCache
StateNotifier statefeed.Notifier
StateGen *stategen.State
Eth1HeaderReqLimit uint64
BeaconNodeStatsUpdater BeaconNodeStatsUpdater
}
// NewService sets up a new instance with an ethclient when
// given a web3 endpoint as a string in the config.
func NewService(ctx context.Context, config *Web3ServiceConfig) (*Service, error) {
// NewService sets up a new instance with an ethclient when given a web3 endpoint as a string in the config.
func NewService(ctx context.Context, opts ...Option) (*Service, error) {
ctx, cancel := context.WithCancel(ctx)
_ = cancel // govet fix for lost cancel. Cancel is handled in service.Stop()
depositTrie, err := trie.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
@@ -177,27 +175,13 @@ func NewService(ctx context.Context, config *Web3ServiceConfig) (*Service, error
return nil, errors.Wrap(err, "could not setup genesis state")
}
if config.Eth1HeaderReqLimit == 0 {
config.Eth1HeaderReqLimit = defaultEth1HeaderReqLimit
}
stringEndpoints := dedupEndpoints(config.HttpEndpoints)
endpoints := make([]network.Endpoint, len(stringEndpoints))
for i, e := range stringEndpoints {
endpoints[i] = HttpEndpoint(e)
}
// Select first http endpoint in the provided list.
var currEndpoint network.Endpoint
if len(config.HttpEndpoints) > 0 {
currEndpoint = endpoints[0]
}
s := &Service{
ctx: ctx,
cancel: cancel,
cfg: config,
httpEndpoints: endpoints,
currHttpEndpoint: currEndpoint,
ctx: ctx,
cancel: cancel,
cfg: &config{
beaconNodeStatsUpdater: &NopBeaconNodeStatsUpdater{},
eth1HeaderReqLimit: defaultEth1HeaderReqLimit,
},
latestEth1Data: &protodb.LatestETH1Data{
BlockHeight: 0,
BlockTime: 0,
@@ -213,26 +197,25 @@ func NewService(ctx context.Context, config *Web3ServiceConfig) (*Service, error
lastReceivedMerkleIndex: -1,
preGenesisState: genState,
headTicker: time.NewTicker(time.Duration(params.BeaconConfig().SecondsPerETH1Block) * time.Second),
// use the nop updater by default, rely on upstream set up to pass in an appropriate impl
bsUpdater: config.BeaconNodeStatsUpdater,
}
if config.BeaconNodeStatsUpdater == nil {
s.bsUpdater = &NopBeaconNodeStatsUpdater{}
for _, opt := range opts {
if err := opt(s); err != nil {
return nil, err
}
}
if err := s.ensureValidPowchainData(ctx); err != nil {
return nil, errors.Wrap(err, "unable to validate powchain data")
}
eth1Data, err := config.BeaconDB.PowchainData(ctx)
eth1Data, err := s.cfg.beaconDB.PowchainData(ctx)
if err != nil {
return nil, errors.Wrap(err, "unable to retrieve eth1 data")
}
if err := s.initializeEth1Data(ctx, eth1Data); err != nil {
return nil, err
}
return s, nil
}
@@ -240,10 +223,10 @@ func NewService(ctx context.Context, config *Web3ServiceConfig) (*Service, error
func (s *Service) Start() {
// If the chain has not started already and we don't have access to eth1 nodes, we will not be
// able to generate the genesis state.
if !s.chainStartData.Chainstarted && s.currHttpEndpoint.Url == "" {
if !s.chainStartData.Chainstarted && s.cfg.currHttpEndpoint.Url == "" {
// check for genesis state before shutting down the node,
// if a genesis state exists, we can continue on.
genState, err := s.cfg.BeaconDB.GenesisState(s.ctx)
genState, err := s.cfg.beaconDB.GenesisState(s.ctx)
if err != nil {
log.Fatal(err)
}
@@ -253,7 +236,7 @@ func (s *Service) Start() {
}
// Exit early if eth1 endpoint is not set.
if s.currHttpEndpoint.Url == "" {
if s.cfg.currHttpEndpoint.Url == "" {
return
}
go func() {
@@ -314,7 +297,7 @@ func (s *Service) Status() error {
func (s *Service) updateBeaconNodeStats() {
bs := clientstats.BeaconNodeStats{}
if len(s.httpEndpoints) > 1 {
if len(s.cfg.httpEndpoints) > 1 {
bs.SyncEth1FallbackConfigured = true
}
if s.IsConnectedToETH1() {
@@ -324,11 +307,11 @@ func (s *Service) updateBeaconNodeStats() {
bs.SyncEth1FallbackConnected = true
}
}
s.bsUpdater.Update(bs)
s.cfg.beaconNodeStatsUpdater.Update(bs)
}
func (s *Service) updateCurrHttpEndpoint(endpoint network.Endpoint) {
s.currHttpEndpoint = endpoint
s.cfg.currHttpEndpoint = endpoint
s.updateBeaconNodeStats()
}
@@ -374,7 +357,7 @@ func (s *Service) AreAllDepositsProcessed() (bool, error) {
return false, errors.Wrap(err, "could not get deposit count")
}
count := bytesutil.FromBytes8(countByte)
deposits := s.cfg.DepositCache.AllDeposits(s.ctx, nil)
deposits := s.cfg.depositCache.AllDeposits(s.ctx, nil)
if count != uint64(len(deposits)) {
return false, nil
}
@@ -392,12 +375,12 @@ func (s *Service) followBlockHeight(_ context.Context) (uint64, error) {
}
func (s *Service) connectToPowChain() error {
httpClient, rpcClient, err := s.dialETH1Nodes(s.currHttpEndpoint)
httpClient, rpcClient, err := s.dialETH1Nodes(s.cfg.currHttpEndpoint)
if err != nil {
return errors.Wrap(err, "could not dial eth1 nodes")
}
depositContractCaller, err := contracts.NewDepositContractCaller(s.cfg.DepositContract, httpClient)
depositContractCaller, err := contracts.NewDepositContractCaller(s.cfg.depositContractAddr, httpClient)
if err != nil {
return errors.Wrap(err, "could not create deposit contract caller")
}
@@ -493,7 +476,7 @@ func (s *Service) waitForConnection() {
s.updateConnectedETH1(true)
s.runError = nil
log.WithFields(logrus.Fields{
"endpoint": logs.MaskCredentialsLogging(s.currHttpEndpoint.Url),
"endpoint": logs.MaskCredentialsLogging(s.cfg.currHttpEndpoint.Url),
}).Info("Connected to eth1 proof-of-work chain")
return
}
@@ -522,7 +505,7 @@ func (s *Service) waitForConnection() {
for {
select {
case <-ticker.C:
log.Debugf("Trying to dial endpoint: %s", logs.MaskCredentialsLogging(s.currHttpEndpoint.Url))
log.Debugf("Trying to dial endpoint: %s", logs.MaskCredentialsLogging(s.cfg.currHttpEndpoint.Url))
errConnect := s.connectToPowChain()
if errConnect != nil {
errorLogger(errConnect, "Could not connect to powchain endpoint")
@@ -541,7 +524,7 @@ func (s *Service) waitForConnection() {
s.updateConnectedETH1(true)
s.runError = nil
log.WithFields(logrus.Fields{
"endpoint": logs.MaskCredentialsLogging(s.currHttpEndpoint.Url),
"endpoint": logs.MaskCredentialsLogging(s.cfg.currHttpEndpoint.Url),
}).Info("Connected to eth1 proof-of-work chain")
return
}
@@ -587,32 +570,29 @@ func (s *Service) initDepositCaches(ctx context.Context, ctrs []*protodb.Deposit
if len(ctrs) == 0 {
return nil
}
s.cfg.DepositCache.InsertDepositContainers(ctx, ctrs)
s.cfg.depositCache.InsertDepositContainers(ctx, ctrs)
if !s.chainStartData.Chainstarted {
// do not add to pending cache
// if no genesis state exists.
validDepositsCount.Add(float64(s.preGenesisState.Eth1DepositIndex()))
return nil
}
genesisState, err := s.cfg.BeaconDB.GenesisState(ctx)
genesisState, err := s.cfg.beaconDB.GenesisState(ctx)
if err != nil {
return err
}
// Default to all deposits post-genesis deposits in
// the event we cannot find a finalized state.
currIndex := genesisState.Eth1DepositIndex()
chkPt, err := s.cfg.BeaconDB.FinalizedCheckpoint(ctx)
chkPt, err := s.cfg.beaconDB.FinalizedCheckpoint(ctx)
if err != nil {
return err
}
rt := bytesutil.ToBytes32(chkPt.Root)
if rt != [32]byte{} {
fState, err := s.cfg.StateGen.StateByRoot(ctx, rt)
if err != nil {
return errors.Wrap(err, "could not get finalized state")
}
fState := s.cfg.finalizedStateAtStartup
if fState == nil || fState.IsNil() {
return errors.Errorf("finalized state with root %#x does not exist in the db", rt)
return errors.Errorf("finalized state with root %#x is nil", rt)
}
// Set deposit index to the one in the current archived state.
currIndex = fState.Eth1DepositIndex()
@@ -621,9 +601,9 @@ func (s *Service) initDepositCaches(ctx context.Context, ctrs []*protodb.Deposit
// accumulates. we finalize them here before we are ready to receive a block.
// Otherwise, the first few blocks will be slower to compute as we will
// hold the lock and be busy finalizing the deposits.
s.cfg.DepositCache.InsertFinalizedDeposits(ctx, int64(currIndex))
s.cfg.depositCache.InsertFinalizedDeposits(ctx, int64(currIndex))
// Deposit proofs are only used during state transition and can be safely removed to save space.
if err = s.cfg.DepositCache.PruneProofs(ctx, int64(currIndex)); err != nil {
if err = s.cfg.depositCache.PruneProofs(ctx, int64(currIndex)); err != nil {
return errors.Wrap(err, "could not prune deposit proofs")
}
}
@@ -632,7 +612,7 @@ func (s *Service) initDepositCaches(ctx context.Context, ctrs []*protodb.Deposit
// is more than the current index in state.
if uint64(len(ctrs)) > currIndex {
for _, c := range ctrs[currIndex:] {
s.cfg.DepositCache.InsertPendingDeposit(ctx, c.Deposit, c.Eth1BlockHeight, c.Index, bytesutil.ToBytes32(c.DepositRoot))
s.cfg.depositCache.InsertPendingDeposit(ctx, c.Deposit, c.Eth1BlockHeight, c.Index, bytesutil.ToBytes32(c.DepositRoot))
}
}
return nil
@@ -918,10 +898,10 @@ func (s *Service) determineEarliestVotingBlock(ctx context.Context, followBlock
// is ready to serve we connect to it again. This method is only
// relevant if we are on our backup endpoint.
func (s *Service) checkDefaultEndpoint() {
primaryEndpoint := s.httpEndpoints[0]
primaryEndpoint := s.cfg.httpEndpoints[0]
// Return early if we are running on our primary
// endpoint.
if s.currHttpEndpoint.Equals(primaryEndpoint) {
if s.cfg.currHttpEndpoint.Equals(primaryEndpoint) {
return
}
@@ -947,11 +927,11 @@ func (s *Service) checkDefaultEndpoint() {
// This is an inefficient way to search for the next endpoint, but given N is expected to be
// small ( < 25), it is fine to search this way.
func (s *Service) fallbackToNextEndpoint() {
currEndpoint := s.currHttpEndpoint
currEndpoint := s.cfg.currHttpEndpoint
currIndex := 0
totalEndpoints := len(s.httpEndpoints)
totalEndpoints := len(s.cfg.httpEndpoints)
for i, endpoint := range s.httpEndpoints {
for i, endpoint := range s.cfg.httpEndpoints {
if endpoint.Equals(currEndpoint) {
currIndex = i
break
@@ -961,9 +941,9 @@ func (s *Service) fallbackToNextEndpoint() {
if nextIndex >= totalEndpoints {
nextIndex = 0
}
s.updateCurrHttpEndpoint(s.httpEndpoints[nextIndex])
s.updateCurrHttpEndpoint(s.cfg.httpEndpoints[nextIndex])
if nextIndex != currIndex {
log.Infof("Falling back to alternative endpoint: %s", logs.MaskCredentialsLogging(s.currHttpEndpoint.Url))
log.Infof("Falling back to alternative endpoint: %s", logs.MaskCredentialsLogging(s.cfg.currHttpEndpoint.Url))
}
}
@@ -1019,7 +999,7 @@ func (s *Service) validateDepositContainers(ctrs []*protodb.DepositContainer) bo
// validates the current powchain data saved and makes sure that any
// embedded genesis state is correctly accounted for.
func (s *Service) ensureValidPowchainData(ctx context.Context) error {
genState, err := s.cfg.BeaconDB.GenesisState(ctx)
genState, err := s.cfg.beaconDB.GenesisState(ctx)
if err != nil {
return err
}
@@ -1027,7 +1007,7 @@ func (s *Service) ensureValidPowchainData(ctx context.Context) error {
if genState == nil || genState.IsNil() {
return nil
}
eth1Data, err := s.cfg.BeaconDB.PowchainData(ctx)
eth1Data, err := s.cfg.beaconDB.PowchainData(ctx)
if err != nil {
return errors.Wrap(err, "unable to retrieve eth1 data")
}
@@ -1048,9 +1028,9 @@ func (s *Service) ensureValidPowchainData(ctx context.Context) error {
ChainstartData: s.chainStartData,
BeaconState: pbState,
Trie: s.depositTrie.ToProto(),
DepositContainers: s.cfg.DepositCache.AllDepositContainers(ctx),
DepositContainers: s.cfg.depositCache.AllDepositContainers(ctx),
}
return s.cfg.BeaconDB.SavePowchainData(ctx, eth1Data)
return s.cfg.beaconDB.SavePowchainData(ctx, eth1Data)
}
return nil
}
@@ -1077,5 +1057,5 @@ func eth1HeadIsBehind(timestamp uint64) bool {
}
func (s *Service) primaryConnected() bool {
return s.currHttpEndpoint.Equals(s.httpEndpoints[0])
return s.cfg.currHttpEndpoint.Equals(s.cfg.httpEndpoints[0])
}

View File

@@ -27,7 +27,6 @@ import (
"github.com/prysmaticlabs/prysm/network"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
protodb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
@@ -129,11 +128,11 @@ func TestStart_OK(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockPOW.RPCClient{Backend: testAcc.Backend}
@@ -158,11 +157,11 @@ func TestStart_NoHttpEndpointDefinedFails_WithoutChainStarted(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
s, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{""}, // No endpoint defined!
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
s, err := NewService(context.Background(),
WithHttpEndpoints([]string{""}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err)
// Set custom exit func so test can proceed
log.Logger.ExitFunc = func(i int) {
@@ -201,12 +200,12 @@ func TestStart_NoHttpEndpointDefinedSucceeds_WithGenesisState(t *testing.T) {
require.NoError(t, beaconDB.SaveGenesisBlockRoot(context.Background(), genRoot))
depositCache, err := depositcache.New()
require.NoError(t, err)
s, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{""}, // No endpoint defined!
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
DepositCache: depositCache,
})
s, err := NewService(context.Background(),
WithHttpEndpoints([]string{""}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
WithDepositCache(depositCache),
)
require.NoError(t, err)
wg := new(sync.WaitGroup)
@@ -232,11 +231,11 @@ func TestStart_NoHttpEndpointDefinedSucceeds_WithChainStarted(t *testing.T) {
ChainstartData: &protodb.ChainStartData{Chainstarted: true},
Trie: &protodb.SparseMerkleTrie{},
}))
s, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{""}, // No endpoint defined!
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
s, err := NewService(context.Background(),
WithHttpEndpoints([]string{""}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err)
s.Start()
@@ -249,11 +248,11 @@ func TestStop_OK(t *testing.T) {
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -274,11 +273,11 @@ func TestService_Eth1Synced(t *testing.T) {
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
@@ -299,11 +298,11 @@ func TestFollowBlock_OK(t *testing.T) {
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
// simulated backend sets eth1 block
@@ -372,10 +371,10 @@ func TestStatus(t *testing.T) {
func TestHandlePanic_OK(t *testing.T) {
hook := logTest.NewGlobal()
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
// nil eth1DataFetcher would panic if cached value not used
web3Service.eth1DataFetcher = nil
@@ -411,11 +410,11 @@ func TestLogTillGenesis_OK(t *testing.T) {
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
require.NoError(t, err)
@@ -447,24 +446,24 @@ func TestInitDepositCache_OK(t *testing.T) {
s := &Service{
chainStartData: &protodb.ChainStartData{Chainstarted: false},
preGenesisState: gs,
cfg: &Web3ServiceConfig{BeaconDB: beaconDB},
cfg: &config{beaconDB: beaconDB},
}
var err error
s.cfg.DepositCache, err = depositcache.New()
s.cfg.depositCache, err = depositcache.New()
require.NoError(t, err)
require.NoError(t, s.initDepositCaches(context.Background(), ctrs))
require.Equal(t, 0, len(s.cfg.DepositCache.PendingContainers(context.Background(), nil)))
require.Equal(t, 0, len(s.cfg.depositCache.PendingContainers(context.Background(), nil)))
blockRootA := [32]byte{'a'}
emptyState, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.cfg.BeaconDB.SaveGenesisBlockRoot(context.Background(), blockRootA))
require.NoError(t, s.cfg.BeaconDB.SaveState(context.Background(), emptyState, blockRootA))
require.NoError(t, s.cfg.beaconDB.SaveGenesisBlockRoot(context.Background(), blockRootA))
require.NoError(t, s.cfg.beaconDB.SaveState(context.Background(), emptyState, blockRootA))
s.chainStartData.Chainstarted = true
require.NoError(t, s.initDepositCaches(context.Background(), ctrs))
require.Equal(t, 3, len(s.cfg.DepositCache.PendingContainers(context.Background(), nil)))
require.Equal(t, 3, len(s.cfg.depositCache.PendingContainers(context.Background(), nil)))
}
func TestInitDepositCacheWithFinalization_OK(t *testing.T) {
@@ -508,14 +507,14 @@ func TestInitDepositCacheWithFinalization_OK(t *testing.T) {
s := &Service{
chainStartData: &protodb.ChainStartData{Chainstarted: false},
preGenesisState: gs,
cfg: &Web3ServiceConfig{BeaconDB: beaconDB},
cfg: &config{beaconDB: beaconDB},
}
var err error
s.cfg.DepositCache, err = depositcache.New()
s.cfg.depositCache, err = depositcache.New()
require.NoError(t, err)
require.NoError(t, s.initDepositCaches(context.Background(), ctrs))
require.Equal(t, 0, len(s.cfg.DepositCache.PendingContainers(context.Background(), nil)))
require.Equal(t, 0, len(s.cfg.depositCache.PendingContainers(context.Background(), nil)))
headBlock := util.NewBeaconBlock()
headRoot, err := headBlock.Block.HashTreeRoot()
@@ -524,22 +523,20 @@ func TestInitDepositCacheWithFinalization_OK(t *testing.T) {
emptyState, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.cfg.BeaconDB.SaveGenesisBlockRoot(context.Background(), headRoot))
require.NoError(t, s.cfg.BeaconDB.SaveState(context.Background(), emptyState, headRoot))
require.NoError(t, s.cfg.beaconDB.SaveGenesisBlockRoot(context.Background(), headRoot))
require.NoError(t, s.cfg.beaconDB.SaveState(context.Background(), emptyState, headRoot))
require.NoError(t, stateGen.SaveState(context.Background(), headRoot, emptyState))
s.cfg.StateGen = stateGen
s.cfg.stateGen = stateGen
require.NoError(t, emptyState.SetEth1DepositIndex(2))
ctx := context.Background()
require.NoError(t, stateGen.SaveState(ctx, headRoot, emptyState))
require.NoError(t, beaconDB.SaveState(ctx, emptyState, headRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(headBlock)))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Epoch: slots.ToEpoch(0), Root: headRoot[:]}))
s.cfg.finalizedStateAtStartup = emptyState
s.chainStartData.Chainstarted = true
require.NoError(t, s.initDepositCaches(context.Background(), ctrs))
deps := s.cfg.DepositCache.NonFinalizedDeposits(context.Background(), nil)
deps := s.cfg.depositCache.NonFinalizedDeposits(context.Background(), nil)
assert.Equal(t, 0, len(deps))
}
@@ -547,11 +544,11 @@ func TestNewService_EarliestVotingBlock(t *testing.T) {
testAcc, err := contracts.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := dbutil.SetupDB(t)
web3Service, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
web3Service, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
// simulated backend sets eth1 block
@@ -598,22 +595,21 @@ func TestNewService_Eth1HeaderRequLimit(t *testing.T) {
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := dbutil.SetupDB(t)
s1, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
})
s1, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
assert.Equal(t, defaultEth1HeaderReqLimit, s1.cfg.Eth1HeaderReqLimit, "default eth1 header request limit not set")
s2, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{endpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
Eth1HeaderReqLimit: uint64(150),
})
assert.Equal(t, defaultEth1HeaderReqLimit, s1.cfg.eth1HeaderReqLimit, "default eth1 header request limit not set")
s2, err := NewService(context.Background(),
WithHttpEndpoints([]string{endpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
WithEth1HeaderRequestLimit(uint64(150)),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
assert.Equal(t, uint64(150), s2.cfg.Eth1HeaderReqLimit, "unable to set eth1HeaderRequestLimit")
assert.Equal(t, uint64(150), s2.cfg.eth1HeaderReqLimit, "unable to set eth1HeaderRequestLimit")
}
type mockBSUpdater struct {
@@ -635,41 +631,41 @@ func TestServiceFallbackCorrectly(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
mbs := &mockBSUpdater{}
s1, err := NewService(context.Background(), &Web3ServiceConfig{
HttpEndpoints: []string{firstEndpoint},
DepositContract: testAcc.ContractAddr,
BeaconDB: beaconDB,
BeaconNodeStatsUpdater: mbs,
})
s1.bsUpdater = mbs
s1, err := NewService(context.Background(),
WithHttpEndpoints([]string{firstEndpoint}),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
WithBeaconNodeStatsUpdater(mbs),
)
s1.cfg.beaconNodeStatsUpdater = mbs
require.NoError(t, err)
assert.Equal(t, firstEndpoint, s1.currHttpEndpoint.Url, "Unexpected http endpoint")
assert.Equal(t, firstEndpoint, s1.cfg.currHttpEndpoint.Url, "Unexpected http endpoint")
// Stay at the first endpoint.
s1.fallbackToNextEndpoint()
assert.Equal(t, firstEndpoint, s1.currHttpEndpoint.Url, "Unexpected http endpoint")
assert.Equal(t, firstEndpoint, s1.cfg.currHttpEndpoint.Url, "Unexpected http endpoint")
assert.Equal(t, false, mbs.lastBS.SyncEth1FallbackConfigured, "SyncEth1FallbackConfigured in clientstats update should be false when only 1 endpoint is configured")
s1.httpEndpoints = append(s1.httpEndpoints, network.Endpoint{Url: secondEndpoint})
s1.cfg.httpEndpoints = append(s1.cfg.httpEndpoints, network.Endpoint{Url: secondEndpoint})
s1.fallbackToNextEndpoint()
assert.Equal(t, secondEndpoint, s1.currHttpEndpoint.Url, "Unexpected http endpoint")
assert.Equal(t, secondEndpoint, s1.cfg.currHttpEndpoint.Url, "Unexpected http endpoint")
assert.Equal(t, true, mbs.lastBS.SyncEth1FallbackConfigured, "SyncEth1FallbackConfigured in clientstats update should be true when > 1 endpoint is configured")
thirdEndpoint := "C"
fourthEndpoint := "D"
s1.httpEndpoints = append(s1.httpEndpoints, network.Endpoint{Url: thirdEndpoint}, network.Endpoint{Url: fourthEndpoint})
s1.cfg.httpEndpoints = append(s1.cfg.httpEndpoints, network.Endpoint{Url: thirdEndpoint}, network.Endpoint{Url: fourthEndpoint})
s1.fallbackToNextEndpoint()
assert.Equal(t, thirdEndpoint, s1.currHttpEndpoint.Url, "Unexpected http endpoint")
assert.Equal(t, thirdEndpoint, s1.cfg.currHttpEndpoint.Url, "Unexpected http endpoint")
s1.fallbackToNextEndpoint()
assert.Equal(t, fourthEndpoint, s1.currHttpEndpoint.Url, "Unexpected http endpoint")
assert.Equal(t, fourthEndpoint, s1.cfg.currHttpEndpoint.Url, "Unexpected http endpoint")
// Rollover correctly back to the first endpoint
s1.fallbackToNextEndpoint()
assert.Equal(t, firstEndpoint, s1.currHttpEndpoint.Url, "Unexpected http endpoint")
assert.Equal(t, firstEndpoint, s1.cfg.currHttpEndpoint.Url, "Unexpected http endpoint")
}
func TestDedupEndpoints(t *testing.T) {
@@ -697,19 +693,19 @@ func TestService_EnsureConsistentPowchainData(t *testing.T) {
cache, err := depositcache.New()
require.NoError(t, err)
s1, err := NewService(context.Background(), &Web3ServiceConfig{
BeaconDB: beaconDB,
DepositCache: cache,
})
s1, err := NewService(context.Background(),
WithDatabase(beaconDB),
WithDepositCache(cache),
)
require.NoError(t, err)
genState, err := util.NewBeaconState()
require.NoError(t, err)
assert.NoError(t, genState.SetSlot(1000))
require.NoError(t, s1.cfg.BeaconDB.SaveGenesisData(context.Background(), genState))
require.NoError(t, s1.cfg.beaconDB.SaveGenesisData(context.Background(), genState))
require.NoError(t, s1.ensureValidPowchainData(context.Background()))
eth1Data, err := s1.cfg.BeaconDB.PowchainData(context.Background())
eth1Data, err := s1.cfg.beaconDB.PowchainData(context.Background())
assert.NoError(t, err)
assert.NotNil(t, eth1Data)
@@ -721,19 +717,19 @@ func TestService_InitializeCorrectly(t *testing.T) {
cache, err := depositcache.New()
require.NoError(t, err)
s1, err := NewService(context.Background(), &Web3ServiceConfig{
BeaconDB: beaconDB,
DepositCache: cache,
})
s1, err := NewService(context.Background(),
WithDatabase(beaconDB),
WithDepositCache(cache),
)
require.NoError(t, err)
genState, err := util.NewBeaconState()
require.NoError(t, err)
assert.NoError(t, genState.SetSlot(1000))
require.NoError(t, s1.cfg.BeaconDB.SaveGenesisData(context.Background(), genState))
require.NoError(t, s1.cfg.beaconDB.SaveGenesisData(context.Background(), genState))
require.NoError(t, s1.ensureValidPowchainData(context.Background()))
eth1Data, err := s1.cfg.BeaconDB.PowchainData(context.Background())
eth1Data, err := s1.cfg.beaconDB.PowchainData(context.Background())
assert.NoError(t, err)
assert.NoError(t, s1.initializeEth1Data(context.Background(), eth1Data))
@@ -745,25 +741,25 @@ func TestService_EnsureValidPowchainData(t *testing.T) {
cache, err := depositcache.New()
require.NoError(t, err)
s1, err := NewService(context.Background(), &Web3ServiceConfig{
BeaconDB: beaconDB,
DepositCache: cache,
})
s1, err := NewService(context.Background(),
WithDatabase(beaconDB),
WithDepositCache(cache),
)
require.NoError(t, err)
genState, err := util.NewBeaconState()
require.NoError(t, err)
assert.NoError(t, genState.SetSlot(1000))
require.NoError(t, s1.cfg.BeaconDB.SaveGenesisData(context.Background(), genState))
require.NoError(t, s1.cfg.beaconDB.SaveGenesisData(context.Background(), genState))
err = s1.cfg.BeaconDB.SavePowchainData(context.Background(), &protodb.ETH1ChainData{
err = s1.cfg.beaconDB.SavePowchainData(context.Background(), &protodb.ETH1ChainData{
ChainstartData: &protodb.ChainStartData{Chainstarted: true},
DepositContainers: []*protodb.DepositContainer{{Index: 1}},
})
require.NoError(t, err)
require.NoError(t, s1.ensureValidPowchainData(context.Background()))
eth1Data, err := s1.cfg.BeaconDB.PowchainData(context.Background())
eth1Data, err := s1.cfg.beaconDB.PowchainData(context.Background())
assert.NoError(t, err)
assert.NotNil(t, eth1Data)
@@ -775,10 +771,10 @@ func TestService_ValidateDepositContainers(t *testing.T) {
cache, err := depositcache.New()
require.NoError(t, err)
s1, err := NewService(context.Background(), &Web3ServiceConfig{
BeaconDB: beaconDB,
DepositCache: cache,
})
s1, err := NewService(context.Background(),
WithDatabase(beaconDB),
WithDepositCache(cache),
)
require.NoError(t, err)
var tt = []struct {

View File

@@ -30,7 +30,6 @@ go_library(
"//beacon-chain/rpc/prysm/v1alpha1/beacon:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/debug:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/node:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/slasher:go_default_library",
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
"//beacon-chain/rpc/statefetcher:go_default_library",
"//beacon-chain/slasher:go_default_library",

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